From c72a990162850f8aa5f5a10fe3cf5604c0e19896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= <454313500@qq.com> Date: Sat, 17 Feb 2024 16:59:57 +0800 Subject: [PATCH 01/24] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0freeredis?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Yi.Abp.Net8/Yi.Abp.sln | 7 ++++ .../FreeSqlOptions.cs | 17 ++++++++++ .../Yi.Framework.Caching.FreeRedis.csproj | 16 ++++++++++ .../YiFrameworkCachingFreeRedisModule.cs | 32 +++++++++++++++++++ Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.json | 9 +++++- 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 Yi.Abp.Net8/framework/Yi.Framework.Caching.FreeRedis/FreeSqlOptions.cs create mode 100644 Yi.Abp.Net8/framework/Yi.Framework.Caching.FreeRedis/Yi.Framework.Caching.FreeRedis.csproj create mode 100644 Yi.Abp.Net8/framework/Yi.Framework.Caching.FreeRedis/YiFrameworkCachingFreeRedisModule.cs diff --git a/Yi.Abp.Net8/Yi.Abp.sln b/Yi.Abp.Net8/Yi.Abp.sln index 03343e50..68fdb662 100644 --- a/Yi.Abp.Net8/Yi.Abp.sln +++ b/Yi.Abp.Net8/Yi.Abp.sln @@ -115,6 +115,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.CodeGen.Domain EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.CodeGen.Domain.Shared", "module\code-gen\Yi.Framework.Codegen.Domain.Shared\Yi.Framework.CodeGen.Domain.Shared.csproj", "{EEFF0F05-2709-4151-A8CE-667935CEAE0B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.Caching.FreeRedis", "framework\Yi.Framework.Caching.FreeRedis\Yi.Framework.Caching.FreeRedis.csproj", "{862BB0EF-3D4E-44FF-AB15-0EB74CE553D3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -289,6 +291,10 @@ Global {EEFF0F05-2709-4151-A8CE-667935CEAE0B}.Debug|Any CPU.Build.0 = Debug|Any CPU {EEFF0F05-2709-4151-A8CE-667935CEAE0B}.Release|Any CPU.ActiveCfg = Release|Any CPU {EEFF0F05-2709-4151-A8CE-667935CEAE0B}.Release|Any CPU.Build.0 = Release|Any CPU + {862BB0EF-3D4E-44FF-AB15-0EB74CE553D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {862BB0EF-3D4E-44FF-AB15-0EB74CE553D3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {862BB0EF-3D4E-44FF-AB15-0EB74CE553D3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {862BB0EF-3D4E-44FF-AB15-0EB74CE553D3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -341,6 +347,7 @@ Global {882BC563-2F75-4B95-AC96-F4BF23F5E69D} = {4FFE7212-21F2-476D-B628-3C65E6C5075E} {85CB8517-2B80-42D8-B954-081079AC9BA0} = {4FFE7212-21F2-476D-B628-3C65E6C5075E} {EEFF0F05-2709-4151-A8CE-667935CEAE0B} = {4FFE7212-21F2-476D-B628-3C65E6C5075E} + {862BB0EF-3D4E-44FF-AB15-0EB74CE553D3} = {77B949E9-530E-45A5-9657-20F7D5C6875C} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {23D6FBC9-C970-4641-BC1E-2AEA59F51C18} diff --git a/Yi.Abp.Net8/framework/Yi.Framework.Caching.FreeRedis/FreeSqlOptions.cs b/Yi.Abp.Net8/framework/Yi.Framework.Caching.FreeRedis/FreeSqlOptions.cs new file mode 100644 index 00000000..f87d54ec --- /dev/null +++ b/Yi.Abp.Net8/framework/Yi.Framework.Caching.FreeRedis/FreeSqlOptions.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FreeRedis; + +namespace Yi.Framework.Caching.FreeRedis +{ + /// + /// 便于转到定义 + /// + public class FreeSqlOptions: ConnectionStringBuilder + { + + } +} diff --git a/Yi.Abp.Net8/framework/Yi.Framework.Caching.FreeRedis/Yi.Framework.Caching.FreeRedis.csproj b/Yi.Abp.Net8/framework/Yi.Framework.Caching.FreeRedis/Yi.Framework.Caching.FreeRedis.csproj new file mode 100644 index 00000000..fe61ba31 --- /dev/null +++ b/Yi.Abp.Net8/framework/Yi.Framework.Caching.FreeRedis/Yi.Framework.Caching.FreeRedis.csproj @@ -0,0 +1,16 @@ + + + + + net8.0 + enable + enable + + + + + + + + + diff --git a/Yi.Abp.Net8/framework/Yi.Framework.Caching.FreeRedis/YiFrameworkCachingFreeRedisModule.cs b/Yi.Abp.Net8/framework/Yi.Framework.Caching.FreeRedis/YiFrameworkCachingFreeRedisModule.cs new file mode 100644 index 00000000..85b65e44 --- /dev/null +++ b/Yi.Abp.Net8/framework/Yi.Framework.Caching.FreeRedis/YiFrameworkCachingFreeRedisModule.cs @@ -0,0 +1,32 @@ +using FreeRedis; +using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Volo.Abp.Caching; + +namespace Yi.Framework.Caching.FreeRedis +{ + /// + /// 此模块得益于FreeRedis作者支持IDistributedCache,使用湿滑 + /// + [DependsOn(typeof(AbpCachingModule))] + public class YiFrameworkCachingFreeRedisModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + + var configuration = context.Services.GetConfiguration(); + + var redisEnabled = configuration["Redis:IsEnabled"]; + if (redisEnabled.IsNullOrEmpty() || bool.Parse(redisEnabled)) + { + var redisConfiguration = configuration["Redis:Configuration"]; + RedisClient redisClient = new RedisClient(redisConfiguration); + + context.Services.AddSingleton(redisClient); + context.Services.Replace(ServiceDescriptor.Singleton(new + DistributedCache(redisClient))); + } + } + } +} diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.json b/Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.json index b841aa14..05bb666b 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.json +++ b/Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.json @@ -23,7 +23,7 @@ "EnabledSqlLog": true, "EnabledDbSeed": true, //SAAS多租户 - "EnabledSaasMultiTenancy":false + "EnabledSaasMultiTenancy": false //读写分离地址 //"ReadUrl": [ // "DataSource=[xxxx]", //Sqlite @@ -32,6 +32,12 @@ //] }, + //redis使用freeesql参数在“FreeSqlOptions的ConnectionStringBuilder中” + "Redis": { + "IsEnabled": false, + "Configuration": "127.0.0.1:6379,password=123,defaultDatabase=13" + }, + //鉴权 "JwtOptions": { "Issuer": "https://ccnetcore.com", @@ -47,6 +53,7 @@ "ExpiresMinuteTime": 172800 }, + //第三方登录 "OAuth": { //QQ From 46733989767272db7613f6c25958dd3297e48ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= <454313500@qq.com> Date: Sat, 17 Feb 2024 17:37:24 +0800 Subject: [PATCH 02/24] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84sql=E8=80=97?= =?UTF-8?q?=E6=97=B6Aop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/Yi.Framework.SqlSugarCore/SqlSugarDbContext.cs | 5 +++++ Yi.Abp.Net8/src/Yi.Abp.SqlSugarCore/YiDbContext.cs | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/SqlSugarDbContext.cs b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/SqlSugarDbContext.cs index a2b5016c..96c1c765 100644 --- a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/SqlSugarDbContext.cs +++ b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/SqlSugarDbContext.cs @@ -242,6 +242,11 @@ namespace Yi.Framework.SqlSugarCore /// protected virtual void OnLogExecuted(string sql, SugarParameter[] pars) { + if (Options.EnabledSqlLog) + { + var sqllog = $"=========Yi-SQL耗时{SqlSugarClient.Ado.SqlExecutionTime.TotalMilliseconds}毫秒====="; + Logger.CreateLogger().LogDebug(sqllog.ToString()); + } } /// diff --git a/Yi.Abp.Net8/src/Yi.Abp.SqlSugarCore/YiDbContext.cs b/Yi.Abp.Net8/src/Yi.Abp.SqlSugarCore/YiDbContext.cs index 0e8404b5..28fd4436 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.SqlSugarCore/YiDbContext.cs +++ b/Yi.Abp.Net8/src/Yi.Abp.SqlSugarCore/YiDbContext.cs @@ -1,6 +1,8 @@ -using SqlSugar; +using Microsoft.Extensions.Logging; +using SqlSugar; using Volo.Abp.DependencyInjection; using Yi.Framework.Rbac.SqlSugarCore; +using Yi.Framework.SqlSugarCore; namespace Yi.Abp.SqlSugarCore { From 26dd107f484b98762c0ecbbd9c0ee26b07d55515 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= <454313500@qq.com> Date: Sun, 18 Feb 2024 09:35:35 +0800 Subject: [PATCH 03/24] =?UTF-8?q?style:=20=E4=BF=AE=E6=94=B9rbac=20service?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/LoginLogService.cs | 37 ---------------- .../{ => Monitor}/MonitorCacheService.cs | 2 +- .../{ => Monitor}/MonitorServerService.cs | 2 +- .../Services/{ => Monitor}/OnlineService.cs | 4 +- .../Services/{ => Monitor}/TaskService.cs | 14 +++--- .../Services/OperationLogService.cs | 40 ----------------- .../00.快速上手/00.模块与项目.md | 41 ++++++++++++++++++ .../00.快速上手/01.依赖关系.md | 0 .../00.快速上手/image-1.png | Bin 0 -> 10131 bytes .../01.框架快速开始教程/00.快速上手/image.png | Bin 0 -> 18863 bytes .../01.框架快速开始教程/05.脚手架使用.md | 34 +++++++++++++++ 11 files changed, 86 insertions(+), 88 deletions(-) delete mode 100644 Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/LoginLogService.cs rename Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/{ => Monitor}/MonitorCacheService.cs (96%) rename Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/{ => Monitor}/MonitorServerService.cs (97%) rename Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/{ => Monitor}/OnlineService.cs (97%) rename Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/{ => Monitor}/TaskService.cs (95%) delete mode 100644 Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/OperationLogService.cs create mode 100644 Yi.Doc.Md/01.框架快速开始教程/00.快速上手/00.模块与项目.md create mode 100644 Yi.Doc.Md/01.框架快速开始教程/00.快速上手/01.依赖关系.md create mode 100644 Yi.Doc.Md/01.框架快速开始教程/00.快速上手/image-1.png create mode 100644 Yi.Doc.Md/01.框架快速开始教程/00.快速上手/image.png create mode 100644 Yi.Doc.Md/01.框架快速开始教程/05.脚手架使用.md diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/LoginLogService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/LoginLogService.cs deleted file mode 100644 index 9ff45657..00000000 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/LoginLogService.cs +++ /dev/null @@ -1,37 +0,0 @@ -using SqlSugar; -using Volo.Abp; -using Volo.Abp.Application.Dtos; -using Volo.Abp.Application.Services; -using Yi.Framework.Ddd.Application; -using Yi.Framework.Rbac.Application.Contracts.Dtos.LoginLog; -using Yi.Framework.Rbac.Domain.Entities; -using Yi.Framework.SqlSugarCore.Abstractions; - -namespace Yi.Framework.Rbac.Application.Services -{ - public class LoginLogService : YiCrudAppService - { - private readonly ISqlSugarRepository _repository; - public LoginLogService(ISqlSugarRepository repository) : base(repository) - { - _repository = repository; - } - - public override async Task> GetListAsync(LoginLogGetListInputVo input) - { - RefAsync total = 0; - - var entities = await _repository._DbQueryable.WhereIF(!string.IsNullOrEmpty(input.LoginIp), x => x.LoginIp.Contains(input.LoginIp!)) - .WhereIF(!string.IsNullOrEmpty(input.LoginUser), x => x.LoginUser!.Contains(input.LoginUser!)) - .WhereIF(input.StartTime is not null && input.EndTime is not null, x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime) - .ToPageListAsync(input.SkipCount, input.MaxResultCount, total); - return new PagedResultDto(total, await MapToGetListOutputDtosAsync(entities)); - } - - [RemoteService(false)] - public override Task UpdateAsync(Guid id, LoginLogGetListOutputDto input) - { - return base.UpdateAsync(id, input); - } - } -} diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/MonitorCacheService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/MonitorCacheService.cs similarity index 96% rename from Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/MonitorCacheService.cs rename to Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/MonitorCacheService.cs index 0d02cee6..2862d243 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/MonitorCacheService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/MonitorCacheService.cs @@ -3,7 +3,7 @@ using Volo.Abp.Application.Services; using Yi.Framework.Rbac.Application.Contracts.Dtos.MonitorCache; using Yi.Framework.Rbac.Application.Contracts.IServices; -namespace Yi.Framework.Rbac.Application.Services +namespace Yi.Framework.Rbac.Application.Services.Monitor { public class MonitorCacheService : ApplicationService, IMonitorCacheService { diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/MonitorServerService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/MonitorServerService.cs similarity index 97% rename from Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/MonitorServerService.cs rename to Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/MonitorServerService.cs index 7ab64101..55af86d3 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/MonitorServerService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/MonitorServerService.cs @@ -7,7 +7,7 @@ using Volo.Abp.Application.Services; using Yi.Framework.Core.Helper; using Yi.Framework.Rbac.Application.Contracts.IServices; -namespace Yi.Framework.Rbac.Application.Services +namespace Yi.Framework.Rbac.Application.Services.Monitor { public class MonitorServerService : ApplicationService, IMonitorServerService { diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/OnlineService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/OnlineService.cs similarity index 97% rename from Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/OnlineService.cs rename to Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/OnlineService.cs index 257d3e54..c0395e4d 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/OnlineService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/OnlineService.cs @@ -7,7 +7,7 @@ using Yi.Framework.Rbac.Application.Contracts.IServices; using Yi.Framework.Rbac.Application.SignalRHubs; using Yi.Framework.Rbac.Domain.Shared.Model; -namespace Yi.Framework.Rbac.Application.Services +namespace Yi.Framework.Rbac.Application.Services.Monitor { public class OnlineService : ApplicationService, IOnlineService { @@ -37,7 +37,7 @@ namespace Yi.Framework.Rbac.Application.Services { dataWhere = dataWhere.Where((u) => u.UserName!.Contains(online.UserName)); } - return Task.FromResult(new PagedResultDto() { TotalCount = data.Count, Items = dataWhere.ToList() }) ; + return Task.FromResult(new PagedResultDto() { TotalCount = data.Count, Items = dataWhere.ToList() }); } diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/TaskService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/TaskService.cs similarity index 95% rename from Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/TaskService.cs rename to Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/TaskService.cs index b8f79698..ab857fb6 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/TaskService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/TaskService.cs @@ -11,7 +11,7 @@ using Yi.Framework.Rbac.Application.Contracts.Dtos.Task; using Yi.Framework.Rbac.Application.Contracts.IServices; using Yi.Framework.Rbac.Domain.Shared.Enums; -namespace Yi.Framework.Rbac.Application.Services +namespace Yi.Framework.Rbac.Application.Services.Monitor { public class TaskService : ApplicationService, ITaskService { @@ -19,7 +19,7 @@ namespace Yi.Framework.Rbac.Application.Services private readonly IClock _clock; public TaskService(ISchedulerFactory schedulerFactory, IClock clock) { - _clock=clock; + _clock = clock; _schedulerFactory = schedulerFactory; } @@ -39,7 +39,7 @@ namespace Yi.Framework.Rbac.Application.Services //状态 var state = await scheduler.GetTriggerState(trigger.Key); - + var output = new TaskGetOutput { JobId = jobDetail.Key.Name, @@ -48,7 +48,7 @@ namespace Yi.Framework.Rbac.Application.Services Properties = Newtonsoft.Json.JsonConvert.SerializeObject(jobDetail.JobDataMap), Concurrent = !jobDetail.ConcurrentExecutionDisallowed, Description = jobDetail.Description, - LastRunTime = _clock.Normalize( trigger.GetPreviousFireTimeUtc()?.DateTime??DateTime.MinValue), + LastRunTime = _clock.Normalize(trigger.GetPreviousFireTimeUtc()?.DateTime ?? DateTime.MinValue), NextRunTime = _clock.Normalize(trigger.GetNextFireTimeUtc()?.DateTime ?? DateTime.MinValue), AssemblyName = jobDetail.JobType.Assembly.GetName().Name, Status = state.ToString() @@ -56,7 +56,7 @@ namespace Yi.Framework.Rbac.Application.Services if (trigger is ISimpleTrigger simple) { - output.TriggerArgs =Math.Round(simple.RepeatInterval.TotalMinutes,2) .ToString() + "分钟"; + output.TriggerArgs = Math.Round(simple.RepeatInterval.TotalMinutes, 2).ToString() + "分钟"; output.Type = JobTypeEnum.Millisecond; output.Millisecond = simple.RepeatInterval.TotalMilliseconds; } @@ -64,7 +64,7 @@ namespace Yi.Framework.Rbac.Application.Services { output.TriggerArgs = cron.CronExpressionString!; output.Type = JobTypeEnum.Cron; - output.Cron=cron.CronExpressionString; + output.Cron = cron.CronExpressionString; } return output; } @@ -159,7 +159,7 @@ namespace Yi.Framework.Rbac.Application.Services /// /// public async Task DeleteAsync(IEnumerable id) - { + { var scheduler = await _schedulerFactory.GetScheduler(); await scheduler.DeleteJobs(id.Select(x => new JobKey(x)).ToList()); } diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/OperationLogService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/OperationLogService.cs deleted file mode 100644 index c12af05d..00000000 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/OperationLogService.cs +++ /dev/null @@ -1,40 +0,0 @@ -using SqlSugar; -using Volo.Abp; -using Volo.Abp.Application.Dtos; -using Yi.Framework.Ddd.Application; -using Yi.Framework.Rbac.Application.Contracts.Dtos.OperLog; -using Yi.Framework.Rbac.Application.Contracts.IServices; -using Yi.Framework.Rbac.Domain.Operlog; -using Yi.Framework.SqlSugarCore.Abstractions; - -namespace Yi.Framework.Rbac.Application.Services -{ - /// - /// OperationLog服务实现 - /// - public class OperationLogService : YiCrudAppService, - IOperationLogService - { - private ISqlSugarRepository _repository; - public OperationLogService(ISqlSugarRepository repository) : base(repository) - { - _repository=repository; - } - - public override async Task> GetListAsync(OperationLogGetListInputVo input) - { - RefAsync total = 0; - var entities = await _repository._DbQueryable.WhereIF(!string.IsNullOrEmpty(input.OperUser), x => x.OperUser.Contains(input.OperUser!)) - .WhereIF(input.OperType is not null, x => x.OperType == input.OperType) - .WhereIF(input.StartTime is not null && input.EndTime is not null, x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime) - .ToPageListAsync(input.SkipCount, input.MaxResultCount, total); - return new PagedResultDto(total, await MapToGetListOutputDtosAsync(entities)); - } - - [RemoteService(false)] - public override Task UpdateAsync(Guid id, OperationLogGetListOutputDto input) - { - return base.UpdateAsync(id, input); - } - } -} diff --git a/Yi.Doc.Md/01.框架快速开始教程/00.快速上手/00.模块与项目.md b/Yi.Doc.Md/01.框架快速开始教程/00.快速上手/00.模块与项目.md new file mode 100644 index 00000000..7d16b8fa --- /dev/null +++ b/Yi.Doc.Md/01.框架快速开始教程/00.快速上手/00.模块与项目.md @@ -0,0 +1,41 @@ +## 模块与项目 +意框架是一个基于Abp.VNext的框架,完美使用模块化理念进行开发。既然是模块化开发,就有`项目`与`项目`的概念。 + +很多人问到了我,我的代码应该放到哪里,其实是没有分清楚模块与项目,弄清楚这个,再下手撸码,才更有方向。 + +其实不必一堆概念,只需要心中思考一下 + +> 我接下来要开发的业务是否有必要被其他项目依赖使用? + +例如:内置的Rbac模块、Bbs模块,单独具备权限管理和社区论坛的功能,公开给大家复用引用,这就可以当成一个模块 + +`但是`,有时候如果我不认为他有必要复用,就是公司的一个内部系统,想要快速开发并交付,要同时具备权限管理、商城、审批等各种功能,那就直接当一个项目开发即可,不一定需要将各个模块拆的太散 + +> 这个划分的界限,是由项目来决定 + +注意:模块的代码与项目的代码结构几乎没有区别 + +这意味,有一个最好的方式,先将业务全部写在项目中,等稳定之后,在复制抽象到模块中,完全没有问题。 + +### 模块的优缺点 +- 优点:高度抽象复用 +- 缺点:肉眼可见的程序集增加、维护成本更高 + +### 模块 +![Alt text](image.png) + +代码位置放在`module`目录下,单独建立一个自己的模块名称,可使用`脚手架使用`将默认代码生成在这里。 + +### 项目 +![Alt text](image-1.png) + +框架内置一个host项目,代码位置存放在`src`中,直接使用即可,如果想更换命名,可以使用上一节的`脚手架使用`。 + +## 总结 +> 由于很多人询问我这个问题,所以单独写一篇,方便大家理解。 + +先区分模块还是项目,然后代码写到对应的位置即可 + +理论上,按这套规则意味着,只有在自己的`module`、`src`下才需要写代码,其他地方都是内置好了的,通过继承、实现等方式扩展即可 + +当然,你可以不按这套规则出发,目录结构按自己的舒服的方式去设计,当然也是可以的,不过这得花费一些时间了。 diff --git a/Yi.Doc.Md/01.框架快速开始教程/00.快速上手/01.依赖关系.md b/Yi.Doc.Md/01.框架快速开始教程/00.快速上手/01.依赖关系.md new file mode 100644 index 00000000..e69de29b diff --git a/Yi.Doc.Md/01.框架快速开始教程/00.快速上手/image-1.png b/Yi.Doc.Md/01.框架快速开始教程/00.快速上手/image-1.png new file mode 100644 index 0000000000000000000000000000000000000000..e2d30f8e428410c7435c283dd215f4512154062b GIT binary patch literal 10131 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 Q*Y7~e@@jH5GN$nV1zwxDPXGV_ literal 0 HcmV?d00001 diff --git a/Yi.Doc.Md/01.框架快速开始教程/00.快速上手/image.png b/Yi.Doc.Md/01.框架快速开始教程/00.快速上手/image.png new file mode 100644 index 0000000000000000000000000000000000000000..2cc8d2840217d371812d648486d5fc6d4450577e GIT binary patch literal 18863 zcmce;Wmr{j+wMz9i+~bJBOub!ol?>%0k5SCz-dCC5cULBW5cAft(bf;s{G zVZ_D+{-uJ|{Qw1p7UhkM6v#bwf5FGbU^8v&sx+TWNyDb=2uwNgFh0FIEaW3}kYRt} zM@LcqAU@iXY?#C0VA?0InP&3p#ezmOC$V&%T@2D0A@I{ScS2%j!wrr&ln7TH9Ex$P z*)wjAImfXV$yoyLDd&V-zpV;f$=0y#PCPa_CpcCQS^F;YhCx=bl|YhV&G|AlB;@$& z$iv=2IE^`cx&gwvIhe+p$fo0O#{GsR;qJ*tE32O?4s4ELL4;YZeC!ZZ8Cz#TN{0A1 z$98KT`&mCLt zr66-Pw%+TkChuKbzETL-4IpmamV5+EuKM2AIj#4F;}%Y4emnMdq&A4SB@jC$G(pTxSy{8de%bLU|AIWt$&2WiHC()=dX=zIsA~a+Y>mM zhV$J)e}}x}A!Fjb+a6x#MYr`~qw$v8^Umkm)$mtw3a_}h+NP(cn`oXqdBX5GY*ckk zM`+D0K>qa<mLpXzQVZo)K5Ux~t)bo9Z;PxH z19}tW;@4KRor3KzH9QBuKay(DnVFvcCf5Bhc*a+&R#EUP1qS?Q3M{PKB}?)&hqjqo zV(A{id3zif_vyvU)A*LSi*6fh zwH7M(NZLiGx39n;TW==guMVNFcZdq$;T3uyb=y`q5rdW^pKeZHnU2m^2KTr3-TU8_ zB29#Wk`!S%+kiux?(Yx}2?%&ZMMV#tVaClV)!-?o-AR~U%n1gss6W$>55Z-p_wwoq z*?YsHGUL?h9b3tM6LNoY2Jjm*s7s{t7ilYA=$cFnj_FW*h?|R zYZ@QV^3S$=2*0H@KjB&$phV`HM4ap7+!ozAPrd~(^J_$P5J_;}^zq~lRnu4e{4z}j1bv}U+earM^Bgn1sg%1AGWNm8 zckOBLQVf{l>#0&38SO&*w{78H^FKOv3Ldw*(V&XmUZiaF-maLlIX>~s#hD;Shzj}L z&%9+{=ifNk$xl9H2zM0>FqsQfgBBs=Lr2*-@_i5bm17<`t-Hq-7)-fuiQErRUEJZU zCaJy7awzQi^$VLxEj@K=G^BvI*iJ8|V}*8vcktJ*J*nze`A`0X(b>41%*nnJNyP1R z5-A6CSt-@S^R(YcCbsZg9j)>xRCc9$@09v?wJHkOIdscgsu6rHMjvc!BDc3c9yIKh zq?*x}w&s8T{>hBHx0lEA%KbWf4<+wT+4ijUo*=5}On7I9cQiGky%~J6f>v!yosI z0nKz42p&>Xankv`*}B5Cny8C0NpyCwL{H(_h16?w*sc*T?{v=&h^6cFlvhhjD@V*u zt-QdNB4z=RAT*i%J>*6(ERzLS-p%Y9&F53rEwcv9D-JHT zEv}d+0UD065O=z!M|e3QIwNU~l_X}8T22|MZ~Na0iTJqYa!%*A!YM;fKb_;dwz!+- zG7A>F&9YC{Fd24#`w2KQ;2IYWJOf z-lK<*+q@R{77?w1ceF?XRd}sdf>a`d8h?z238L>`cSloubwn<`Eq8%5!kQG=)h9<_UGIBdkM-ly!&nWDm#aA zS{mH0`Om-y=J`tg6t;;xhyieBxFl?Bh7idm@~G7xv-CoZzNx? zHY-5KW_i31RJ8QwegwOY_*of4pJ^Ms6%OX-A-=`v$n%x;Hf2CulMb0wS}$y7qP~2O z(LBLUadp#BIx;=nnM~2Ty0OMc?(nC++GH&bK2)|ci0~(7&g>nD%vNBpBNjRT;djO& zcH0Go&5LZKx$yZPaN0oo4z)&IsMuQ%`(exN%inAx%q@P{vR&})x`d^Q7lrn{z87k1 z^Sd&+T#~qZ3ad{xRSB*CH-Kd{?18zcXW z@78d6*~gVaZg3S3UwU^|h@aYUWAGwRUY*~^))-k97AT>?2dJSAb@IK>9=z{quEdKz z8!46DuAOfh&Gusc*iztSNv68`RGzzM22KaZLGuv!@@(6;xYh3m^!~VW_lE2xIj@r5 zINd_+Y*#tPxaQHmf{B`1Lxw<7Uhwq~?!Yn>zqU+r%WHY{IFD2f7{x?RHp$hi4eZ6M zUo=1Y4eCkAI->{gdbHW<%$zkkzLpl5Ftrx>9eh%p9*Boc9m<4W863lw$gP%Ly;Idn zZqm;aAEi6&qmh4$j5)cplvrO?B04a*Hy3YRDSzzjl3h2-S5GejLr-Yf!r!$L>bPVV zK&KC_MPP4#OL6=gH_yf`Y^CHDt0_ z?==_<&iyr!GM!$}JR2~{(u|<7;z~)tbpEh0n4ZEB$V&~GvZb@=(!*<^BFvE-{YTvCx zG^t%F_wmChBQuB2pCiKqg}Ea2LcVb)uW7i1A%QX#ow79kF2mv9$>w7}P#)Br+7`ym zqe?B1Yb;UUl;5C=ilfmrp&4M zo@bfiF#`AI<&7(hWt8{gSaurskCyY4$5bI+M5qYZL6HR_02 zO}4O_puj&Q$rtpH#8X@ScClqWsx()Vp*{3czPL(8FYoI&9HtfX8@;*X_56Bp>b(<7 z^PHv9;Siol8W!b=pp>dsovP|CEAwEWQ4=Y`U>SN6h%Bm3GoWW0LGw^>9W^9>8D zG>H_&9IHzj*JZk3AJ(OTCRzF|+3lG`y{0T^l54P#b9e7$LC4L+AQ`JSx}fX;t%%=f zEt8n%wL>{V|6b#HO7N0!?;>_qx2JPTxGj`JNz9J)R-WFfdHd6g9FwGhR5PR6@yzG> zif*#jDqYq-7Ob+WMS*~j-aVbIl3}Y;n}98+?2E8j=e9~@v8=fmHK-kZ$@=q!T-DDn zBK@tw!XX2D^S3Y!C6xzRC47QugIO!~fHIQZ{K{Wbl3RYJ3OEd?u(|DlF{NCYu?HPIQ!8=dul-+EyWW~ra z|G?;)DA5K86M_Aea|$Ip@9@uGYs;xp5N5!G1TeF`*gbf)v6xq(VxTWXw&+&$UfQU~ z+W!3oIae!5i_W8Z4pXkZgIjHieBy{MtB)U74jKDOa?VSVumi5*Xd%DUS7hOp0J+P8S+$Z zmIO2RV;0~>-P8LNyaLt7y$MUsK6~EP;i8-~;$uyjRtt%6ZwA1Z+D;D;wM&kWmwrz)O4#>i;SH>sM18#}$4{u3u3Jq#(-cOYn?Jc#ovV1y= z3prRpEZqr1C*58N2^qyMj*fO#@6z9}-4HPi84k8kt1&q63OWdq*9md=epY&|yqM0> zApAJC^1NhW5EcAtcBRo4lX+%RKMB>?C%pDK))aa2u_^;@~f7<*{thXzPNo*1Zzs&seDZOej76 z5Ddui}ZiLFo;p!yc^gdeAezPAni}1A@ zP+HAi7Z%`RTU%Qak*RS|K>w7SAo$^i=&4$%)4?bq8K&LF1CW9Mg_=sw8wMx&Eq%_0 zZK%X$?9%xyPOTlRi)M7>>{X%2LPmawwm0DO)$Us<6b}6g@=V4cE@J*ePLE6^Uv3#m@w6uA}vOIXa6=hgAs z*2{(uho1c8hqk%)7%4(={BRm==#D?>Jm}oUUz$ei6 zB|NsG%;NNk6aZxNlhL!&7h~Z803Z32sh17q^rznW{cY-tfUk6N6Cy_L=SjoAsSlus$8 zd1@ti6z=cuSJl??@bY$!kAwJBaU_+T>G$1=vvP965))t8sdeGSeEeu3oc@l5lig4D zM{qDEWzno&?EwcR27I4ryeY0!17`VR>#?i|C2C%T?POpit%vJL@D6St$@i+XlMoc9rKM4dy2n0Y zQgvAViTYT3FTTo^zm_+zF(xn9IWVtd^&lJ;zxz4e&vj5GRgT#myZm@)wma7m~G!^s1E%W8Q*)W3$9R_;b0QX(FAySpb zE)Uwnq)jf4kYu}FRQnug&5i*YD^y;xz6&*x-;hqU|0t!@nrpBg+v;$)cXM{4Is9{* zU_E*OQWON^l!G^MNsIO%|&zJmO`-^3@0PP4F9M`DZ!k`8_;5?PQghyFpF4OGw%%=X5e|_@KE`fQO8kcES3AsQw7E z08r?*SM|c3Ax1@pFNUo`irF1fEErVa*>B%MPj)B{i7tCZA~-66jjoG%eX*4=OvcpW^$~9I zh;dw|zUt(yLd5=yvIZX#lR7_o1O5_b=GN`)2S+jixw+kYnK{tf7lOCj+9k#`umLP0 z;PEOn4{lG)jd=aIt_E^91ej~1rz;*s)kF`IQ)T=PjNv>U+5RMSQrR+fjmMa*OmbR@ z4(K5$OFnp5WYdCHfq{YZXnZe2e0+RWRn;)iQvNIg1g22C2&K*k!GGkQ3aEns?;v1TiC*_SslnI0VlwilL!=hQJ{^YagXv<3laYEJZj zT!1-0Ix^DXY-d6-=`+ChpU3?&ep$4=y&aH-HsDdF@$ia~5{C0;OFMEWoDe(!afE;;dy&PC-%Gs$ATW0S{}~$S*zKdqEF;O3Iex$ z#KN~6kYjr_ z%gf_ro=dSL^xZiz*XVozEAgm2!pbme>h0?9z}R+!eO&!MWWOeIzxqL$Ob@c%S54%5 zeeW~C>391^Pa*>NL5~hxESf|VQiG5n-EN_wE1AdALTpgDt@dlgYxrrVexDvRK{O^@KJv}e;{I2u# zVw4yj18>5^XgI9*<6wH@;PSA$ls2 zU)6h!aT+UM7#uH5Ss1Sx8G9=-=3$+-9Ujm24>^{u=eU`8hX>e=TJkRX-Z}P5m7aJW zpjz2WsBP{x&YX3OCDtYkhoqPUM~rT=1m#oV)n81d6y6YjQd?u>4Z51x8L`^FZ(78Kcu&85E4)7g;dou0XS`-az3H)^oO~ggeRK}odZjCm zyXVK!+||uo)A<6HbBx!W<6<@C#q*(~`R31E-)fOhbOpY#t4+SJGu{+3_T6t36})Kt zOqliC+J{h+nS~m(Nuds2?3%j5stk6&4!OBB@^|y#GFZRCxIg9?_Aq&&D;9Wuvufz= z<7NjtJtepbnc{RhbYA+MtQU>=+yI^8mE!Ihi^thqunOq34lkhJL!Q=iPG`i*!+UnzWyvhj1zM)cjmgx7J#)P{V0z ztq5F?s=ZbgHn+$0nz%7Ah+?h4qcc$g0vtRZ*{EQy(c#;d7$Dq89o%gx8@ zh|#2$&Jv?WhD@~7yGT6AO`p%U#RQ8}IEKrWW0h2H5*hv5TDMdi)D7smdxT7!9fmKkE`W(#HcO^C1-2}Wf zxyLj1Jut5tV&m(wA=V{{mr$00c_KsK=wrLK27Yy+(4sMS%{n~BJsCY;jV3M!)>70M4^@e}Q z+}P`)YoTfJ%IVzWx^7|qVzyuO{(Md}Lp+ph$tQJFgn8$bz^xoQ#>?db2KDzUxvm=jC5j)9jiy~=N{~f z2(ZRT#^Vju9TecL_LcN}TS^5VKr9!!nx|Xb6P%9sv>)A?+_&eRxp4@_02jJCZMro@ z0E$4fbM?rk%*M`caB&HI1ay>eOzo5B$)6@x9LzZ1-Ek6DMlBTI8E`uAMXD(~@9go3 zhv5U40O8ItKKx8*%GkRU082c)t$s-XI;ov5KOlW~cl@#@tXOZN*7%RL@i+)6wgVDw z(cfUxZNO(aakmjoLR-I-izdAM*sTLjKXZv>pP+-Cop}HQVKZMxMxQCaV+F)XCNE`0s@s5aPkx=^rN-4si$X3K>;(c zBYgb$v0yIkK@g#-5Kmy{Gh&rVNvlUPDe39C)z#IslB&wezncBhQ;tJqHU%((q`&W( z0nEEs(VmA)I#l1{Kt9EhkEM{q?~{nGlv9#}B=I zGGH5q4xqla_!HD_CtiQ?Hn_uc1Qzf1-hx_lL$crik4}cFmmqPHR%otyNna_!>;6Wt z7>*{X>g+$GOxvmo>{H^&TBgTv*TbaT#n1hZKo#dXDfdRby8^)ITC9S9MSnA9mf7`? z3@-`4P+icZfE42D>a^1SxiGcp1BAk4(U-J6@YOn|$!gZ3;B3!=Xb3F}F+u6`k4Ef^$`n{|4MzKpkJRYJRH z7qx}vWVnau&(Z0llYx~jcASuzl|kR?t6kiA#__0CQ}goimD?|gKcW;=Kl(X4IV;Vb z@Ov$}->`w(Ft){93+n*u@csP-V8mnZ^*+SX++I>eH)p@CD$a4vu1joqxL#%`9zwXz zH6{IU<4ZuV88=hxWPfw3@%Z|pC^|a2HeNBs6l~)=7Jq!%_LjYi;8RNS^;*ABM~K4@ z+S~Lf@O0UM>OsqHbaH zIT4_F3Loo+$iH}6=NUmE(1SbrxR;@WK7PJV$gc6JU(XKzmp51Fq|#sI?+i7;l_gid zT9?*_#Ec3IDzudr&XrrQHlR(%eXM(PwJ}WT?pdar$=^~p01z-p9*7Y$G`O^U9aYY~ zZ?`Ikzq{3Ng}vOLdxgCv{C*MyU<%5*Q9 zLt?^cBUW1Sao?F``=EB3V$SYG#N`siVOKJE|<~r6u{UzE~N=T^n zMt0`!oxvP^EtSVLLuU^_C6}Sf+OlwPk;{V`$3& z0`%N{n61r8!vnAU!2lmRt=my>{p8bEG^3h2Mi43xD!=V4U|oq{zkaP`^i?*@T5O=R z;^piLwxE#>s}L3qDm;+rbmKJQ{K6fF+??I|&E~)7OlH>M$T=?K*V6IT@K*t+=A32{ zoEZ3j_P$v@3(6PkB6TQhu`BU4!!*&;FT38UP@5Q^o9iD_lYrmdB7_`&cWRPZj(DR| z!9VygYFT0nr`fC<5%-9Bh}I%gF7_* z$sAKlihA(A2#Hb=2h=aa=X}PTSRHlgk?7M0fSbdubAItY{ketz7@yJy2M`lx-ParA zY1=xM857;prVY!`@A8`(EsDO;ISq2sUuokMP}X>tHaLS#io01N7N?>cZb+3(;F;r1p0HvPJ!l!Mz95ML&_d4o?(pAdnvsqd%Br;Q0sF2x<1>- z2UXgaiD=^HySnui>AjEzD|r2w)YP#!+w*f zf7nLBTcM?Y`g%A|?)Xt}BsPCuz@DJuA{`Ja$R}dD8y;|pqmoy87Br?7L*BMcz;30e z0@{_+pyydf8h6>@qBVSM7MM5QJ*9Jz*`oAXW%PV?1@!t$>wZeTRwN{Xf7gpKb}|<; zZ%ofc_17fKK*;UDkguO74@eg1*#0;aa1(7`^4{IGSuC4%mCdQ=6{a+7;cq7}zQvai zyMB+MSVu`*qS92i$^sOCqNP!6n?7{lPyoK<1owvPf8aZb_18!2*kx++@!|?cI!f z#{{-O!gbTMbF_M|#1x89s1jC6^~eoumf_oEOau6i+TXw|e~V!}l@zg-I3N zyo0uK7CsoielDerP1iTjAevdtN%9iA(BdbbNfNF8(vIC}Dd5Zs0b!M9Z!IoB0<}z` zaUtuVw6zgP(guZ`767}+vl(_zdzF3@l3ro;kKd1>Nhk8u5j$~30E0E>ev3b%&&mhR zU7!5|Zz%jy&8cGzn_&EVJFA*%57-ddm|MzHr084#V%egenj0O^I zTyJx)b|1_&%Y#B5XwwC~jK5*T`0k+B_8C)amp1kINpv-_7OohT?AwL7A5di(RVmy(VG3(e=-@?tT+lz}(AK z2D5m9h3Iy;2sf~A?mAlSVf8IxqH#X5U3$B%>x>0ZnSj$tZ540N17V5#2^`bS(zy+! zTl+cj{`b)g)C5`fB%O0Gk|i@Q>K+`rM7cZK?@pK%^~V(lrXQ$K%uD7OSV|89thKbB z0F-z2=O=U$f?``3JA)RpYI^-Z4l7{H4EQ0-zJI9C{SH6=#z9C-S9a4%Tpx*0ddZhs z>3t@w&ND>i^P7>TwQR%QbKohn-s~rckeQ-KS5R-CPYtvTFe<)lT$sy43WFq zr!h68qGVQRwOl3VFK&!)JZ#9$G6$fa{gqFyg^G)~61n1-J!ITmJxb7=*nEY#gy6up0>I=kez9cbI5x|%a05ol<5k`aGJ`#z!By`EF8FHvLT()n zbTYT)264UK3&ILGPT<;#SAJ*XXKG0TOWyHsjXgg5AkL3EpQwTMM0?G`-JgF%yaY=^ zu5qXW#AT7&i9KOQHj&Q4i6{q^x{;KdPQqmP*(NRQZMTBq2YXlrkdf zVWPkOf7lp6+5()Vsn~@OkUc1y(`xzjuuULibspKQhaw3Mrp&6!2&;dl+6&LkYk(_l zTTD?kG3h6Q8y*!lH#dvko{j;NfDC{wvOye4he91$4s-IU(G6c7cu+5J#9Vl0pjj1UlEwglLRt!>A zb9Ad0yXy5R7@yp_!aGg3fu9V}(k+uLB_R#di5Fk&L$D%0P=;|V*C8_wnfXKx*E6fH z0q$1(sbab!AjjIq=D|kEMEFi&f9CA$Y{Ly23kr3WKjZNgniX{@<=`Pf+Nxl!BCVgp z6U_1({tt9A+S9g&{23F8r25$;6K~zLth<3u{817klGeJI%xJ2Db4K-Z@@`#z_lTIV zrz;UtU}i0aiX01$hGQ2$7H7@qh+*3VB_mt)$o25Di*Q7Zgv~-jg7fB}cBQDZexs}H zgxs~Sa}WIuytZX<1HZ`jEht4PyQ6I#OnBhbFSRE?`V;fFy4> zsQ$D}QlZ^^Dpodj=W=zmo?$U3Y4FV zk5797-rqkIHM{#MRI!#c%|od0`x*KrwiR_`W>RWfqefIq=BKe%Caua!iIUbHrQw&N zCNldL8!j4EEwsUv5owij+B9A_gU9I|*rQ2e`58$8nC`9$w%XVlZvV9^UHK=o;SjgY zVTVCRIF^m^=3gqbE2dH;Lu+iLy4`GwpEe~qI3DIh{-Alm%3Mr-a_hj+q&Z0H0LyXDRcH!A>d-F6XxoG8#fY1C3%G)O1o1(urfBGJ!x|H{B_8Xbv~TY zyJ__x_3rgrw9)9FuTJ8%itdA`(i4Iqz*5Qsqzn}ejfn*+A3G4|+(LB$)0oM~ZYMKR z1!lf&6Rs&hrW~V5M~^Hkj~=^xt{8&fGzH=4o$v&>H*VS$!Mc%8K>ar{;VfNax6oJb zyjiH1E(9}btg)u|X{}!+y4x@?u{;T$s9|M+=Zvf@9|Lgo&yM}&_6Py1db|GfT|B^i zFHC@ngdiJJhiUJZXJ1hqv^ckU7&dbCF|ocUgVxKv!lUcNRd?)MaWBWvi1^xJ!9p?_=Blt5$zL&J*rQBb+Sug*Z`9Ldkz8Ai$db9%wn$6^2JJwl zT4*>@l}YgdxZlAw2q>peeeEPIYXEnL>N6l^RM5*OIE4UYmPuAn2jD$jpG-g@05&vU zJpTK?xeFRSkOMKpI*0Epn>)G--AT1e{kH~FGr2L*3mY*sCNd^CtUwbC`lhvjF#$|- zPbLlQ9d9m=!ZUVzdknqjF0_Rw=iA0XO|;Dr?I#%ks~z%#1WaG;)_6R86vg8J`R4BZ z9#7#CO*n-$wALU#stI`3ZlD|60@!4!#fMVRA@ldAYFPDWGnTGio}_vg^Ez6e{@h3N z1dAPahhi$C?`e34$OCV-dJY}-s22E*u<1IFHU1BT4Ymfw|Es-LZO_dG0Ctoaw=7@~ zyZV@b_24?bzqR!LvEOX=BZK5D;(U=MdG|}UVn2bX>X}PQNj8?ZhftkHN1}_Es6 z{X01QJtdO;=hy|ZfH=!u#54a6`>{`-%(7Zzrz(-M`zkyuQy1%n&~4Bosf?^2V@*;I zW8`$xaKh{$1gGYsB%D$mffo2FKs>)>1=o|O=jBVEvdUM-$N^3!phZxi{I;gn)`f-8 zq_?UMCR`C!*oAz*> zlV`oNzrVhnmtk>#cbh8cXj%|a=?)~!8C$3)KKSEx;agOl0m;IcvwVeXiGws3Av!1B z=lO)vAkBqIP?C|P(N`Cff{n1u6qQD6vjRNEAVOAEqe&28L-hdP_*PXC&bz8l=J#j+ zk3Z3x0`Z^ypMgL`Jy4Gf0m4?m<6PrV})3Jmr^#lm0L0QgjaMb@>8QdUK7~glRLtI=$9wTg6NAh97VNiaiDzI{P0!tDz{Q&VFtBM z0426gv{VI8mB3~dmh2DQgIcd9r)HYoSMLK8u#YZ+b>6l?G)>nOzMiKYxL?(QXJ#+> z?-Yu3D9Lv~?DOH{tNke*IpGy1T|7(uYvAf6k+qw`C9E-NY-P;!pt@ zU$PsdU3-So?s*L{ngVK`r@(H!ESma{`7u`v-g3W~(zW2+Y5mE!%1C~1RH!JAd8wJ+ z<{-U+q*8;b?wR??AR@q`{x0Gw)p^}0`A`;HLkL0v`tJFOFIkyLjlmWe8~v_@L;wpj zT=79@K5lr{FidtVtOdmrIRCMDx*PtRF*HMcF^Vdto9>#s=WpI4Akbg|-6v7>A;GNZ z@we*8%JPkEd{e>OAeXe*U5BndeMM?JpfhB>jO4q6D z2s^;LW^*7wD*wqr^$j6`h#()85v#JRE&70$t+Hjwbr@%6wnuTPj1$32Is&M4R`BaY z@^qAPLvP6a_eX`F1# z4scZBj8ID3b1TGUEE^8@zC-d^^IqJSYI^+$4>G^oq!;#dGG`O!Cx?|o;*H#B)_*yf z>?6^mzwHW&^UB}A5q_P>s1;o?m>@s0+kl@`tyXO~wWP{;LMqLc42WA84A#$|xv^+A zc5A8X7n+J%V3*)1F z*y!GSeaHZRaR#Xg%SX z3yGG-k8CaMaukSwdO?borSI+HGt3hF%9R5Vvecexifr%ajnm^H1EKT3-s9v;hkh>j zkKii$bL|(VFK-@)b#W5X_4WTFe7--R`4mf&NAyF@w2;vB(|@pIb2aP&|JFSo>VI`l zgqEAnUx5QFZ2YG|!u~%sNRV0j|A_vXW<8!Ev$6-bHQVA5utIIdnCyClj(SmO(wjgD z$AE~^O=fuvsmeTxaWvM;^F^dI5@ zz4j!AY!U>_U*Z*B07+>U9dV?9H<6XUe}s=;4&X1FsA^z2n{KA0C^}rtVp~SF1<3E+ zK!C_eHGcldDt+dV%}c63dSmnX@B1yrJW;?EK&@f{UGvWX*LxCywHAwuma_0U*yEa1 zgCVi{=9>$%L8QjwW)aWH)&InY0r0MWgplFhIdV)A%(?~iDq`7{eC{Vd=69&Kw75SS z2LxlWON4sxJ{n09@22Qju5uTb47P$vLrM5l)xr3J((jd4| z{S`-o4yPDUH(c7ud9#a)s$O0qfXY)=QPE!gy1x0hS6JBCw(|3g@)w@PE~Lc&Yc5c^ z@&3U!4?+09`r2I7nKLh1-Pfj{WKz}9J5koB$SJ^2@!|#zFEN?%gL&?MI^|d7l$=E4 z=oTa*A|mAehn7h-br~Rg43E!*%s+1tML+YsNr_$rOF+7SN0L>Hi0j-WXI~W4W+vZom&TJ~VG7p0CxXxMu4M7_*u8t*!1Sp1%Y5 z%GbYmzNGgbJU`#Wv%j_V&c&t58uhGK!ppyP?iT-G*HB3`F7*OIK|%F!A$55|V3Gb$ zyc>&p`{#H*q*d|-{m2y-6*UaAiMY0>F?n|{ahJ+YF~uer^G}3of;&+Wa2bkPN6dT^ zuY|?BuxL!yvd7Tz2I&E4sVm72ypEt(>=Bv3F@R7eO}xLkD7wC!=YKmVPRG8y6y6&3-!W<~%7*Q93rTg=#nW~n+-rntiQy_;~VnnlIxe_Dju~A`5 z4NMLVpVsw`yFeycIW|*TD#U@*#dvTyEWgSJ;cD!@@);m6+U#&%K7OZ-N-)5QI2BA< zYtlHyT{!&^X?fw8a6k!p>_=T7BLD-w+yMVL84wjn6#iDvyg3PTjzi%HBJ9$3Np6ph zjxNNQtOn1zU!FicZj?SFzVY)5*YR=p9^P9y938_0P9fmA?Rjr9im4@`U7>mFZ?O`= zg)e8|zm71li|iVzt%IJ@pc)0H+AbmY;`Lec5>fNVz^g>AzQe_4Ah}rvbWE2U{=7ls zmA+*KWGu+k%;rnmcgNpH?J3qkOcEHDK9cWXv;0SJoX0&8x%S#JcG*U*LM#%hTM;0< zy4dVh$v0V3Qxl#Bwq`*h$5cK{JZhl-)_eMl^JfkwjaAzo1kSU(HkCYyR7}n;8|5kteF?g@Q8qTU3P0BUqzgV+5-#Oo< z4jB|HZ|`c)R+C7F?i5^pO|iz9B#u?iaVsqMVu+W$z<;SBAy4lw|2kuz;{a$^H=Q61 z*KX<3_<-BUL0nr44yCt%C8doB(EYTor;l~m5IG%k^~UP0dQg)k~7^b z+l#gS69$GzmvqSXeYLZ5#b}-xas~DFYhlwRDrj#M)YR6FEiMiY4-*1M9VZ0MWq~1@ zd!U?f*-nFs!x_=A=u;_syL;1rA#mn;(mIC|wm_mEoD`{uzrwHQdH=TD{u!Z0V{#bc z-{ff$+e*w2wCeDHHXw!Fd!r{(=?#`@Z2(^AHjl*1Yrbc^j6wPM|2cviwxg_9@KyE} zc7uX~V~qU0051E=QhZ>T=Qo@6p^e}Sp9~~JPbkrZ*FNNGzCrB;WZ|ZAyu&%s@oMKA zRlJ6UtEi`WY-(y<5Boy|+qvlD-F#s{ktXT_4bllOU*}dV`GrbHm;}gEVomXJIlqJf zbp!=tD)qjNElc7ukli8y_Qrm`%)!vCoHkUAl_eNcpAlpZ@f zm3~A-!uMOMUyr>YgBpU>Kq`HaH)Jb-=KkGW_bGx~w%QKKy!zigICACW{vpp7eK0ao zX%YaKZ=+8`fK5M{Lc;n%zM20e&8owmDSl;1@W-vOwaq6D9LDtJ#MkdbcHnpDlcwu# zuLr)zsu+q$tIC+Kpbo2<*e|+lzonR|aD)e()Ommd#xji8cg{w*6P1y@Rdd7~x5(VZ zJDfng<(GUO7HO(Hck=UcfBg~wPrcVCmE!xGIVBxGWktGOC2buL;8W>z(EeMT^}lpj z7H&1j?e!Tjz2f5H(g@qbtE#PDUaa{XlAuzv{iJp^_0r6rK+U*N(F3?gvGV`sagG}J z2f$V0p$jCZ7;{jdAdj2W{2w+|P!*s{=n_lAIkcunMl`B_Hn^%#5cv7>#Q62<#ZFFd zEl>VpXuZ#F>*^N(1R~5f&-uj2#?a4FwjcS%J&OM8lNOq>iORW8pFzz4>hIoEmOI-} zm@LB`)-j@9ehe@@-Mjzp6a}d$FvfH~yUw?jOrtUJj6WWrU#|S|z~!_oTn#^Otb^s? z`C-4x6M+01g1i+~s?or>3b~^q6VqZ}db8%b6Mq5d{VydC$a+bseH@TI7PBFos(LsX ziUx!{JPx(4-{lS6u>s%r&RgvoU$DJ>UUPHWkT@a|i1S*fR^0p@y2)2^o`LljrHIDU zeRrYiUSfnA+mjZH@}Q1u;1o{hvHDSpwWTE!aK>b6b>89Y)t*{rF}HAXlNH$SP*a)R*D=cXg)& zM`g2xxqjv-Yyq7+A@e^-plIL-LXEuT>A#Zdk;L6(zkGmw&{QvfS~3Ti#&Bl%;}T8? zHpt6Q!O0#5EFK79Q3AzBEaqRby|q!78yY^U)mDKdc8~wECd2rDu_h18*^!a9tu3nw zw4Hdra}>W?1jYPReWLqwp~DLSe&MGLLTyF%P4df3hag}+1{6g=_=5>+gN2rG&iU53 z|EOe;VQ}^jy~x$g0Ek}wkJ+nQ-hYl{#f8PnmPG;CABHjR1ni60V-?tiNZ|CmIy2V< z$(0OQS}p^D56U(FYjFI(RNB8N)cyNnw z<#9Y2M)aJG>)%)H@-@UHp4n?(jt&D;B5ZJzHh@$l-Gs_&n;pN`{m1r3ZsOpx( zs+D_jbxVWKVcen@3xtnE(x8W?tJfl%f)O$PC7%k1$4qhq-tr>f)dUDwPi}|CkElg; z6MhN{`$DxWOC8LC_!oP!G8Z?0FOXk5a(}N<4bkR7o^HziZn};vn;UJH(?ehf20R&j zQg?24mc_NCpx{ALX_Uj{Q#N-%hi&ehY0UZSv-~@OH8uiCE8D4|mef^iE!h?J)a^=( z4~+3=6kBHHLOuy3`?r>LA&IV*BzMAMLH9wNGU)<;4FhmgT2>xw z@@S653sSj}>wu?&9Ig$h|7`DV6((b`!_3HWPuIoY-){rBOn@2(pkqCXRbZ=RW~{r44MieW$Cya-KeZuSM{k*ksmspaIG@&`=)-B1U^h+D$G%5fmaXP>(r2k1{)?B!!+Q@s(->?}t44 z(8D7}^;cO_w64}Q-oR2HhlXQJAj`AEfA*iC(7Lh@0DuAY|Nq*rC-ZF&+<*Iz?R)7u)p;Jk zV|IFb`P%aQK0x<$h-xeZbq5wGIc~ibwtf90?(g|2r;nL(pL_glEvH|7)zsD3-A_jt z0b@|x6SPz8@QWWJ@-;OR`~CQVof6<=L=xlH7@+K-EjmqEz)7Ha9=a=Df;u4@(^suo r0X!tgX$=c>LI-=kgpLkR{x9#hH0iKPnz=dfASMP+S3j3^P6我们只需要安装一次即可,如果模板文件发生变化,我们生成出来的文件也是一样会变化的 + +当模板安装完成,接下来我们可以选择一个自己想要的空白文件夹,输入命令: + +``` shell +dotnet new yi --name=Acme.BookStore +#Acme.BookStore可以替换成你想要生成的名称即可 +``` + +![image.png](/prod-api/file/55536e5a-ef47-1593-3701-3a100333df31/true) + +最后查看目录: +![image.png](/prod-api/file/20286d62-a9d1-6ab0-7fc0-3a1003348554/true) +这个便是我们想要的结果了 \ No newline at end of file From efa87e0e1a99ec071b6c2933bafc410f88485fff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= <454313500@qq.com> Date: Sun, 18 Feb 2024 09:52:11 +0800 Subject: [PATCH 04/24] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E8=A7=A3=E5=86=B3=E6=95=B0=E6=8D=AE=E5=BA=93=E5=BC=80?= =?UTF-8?q?=E5=90=AF=E4=BA=86=E5=A4=A7=E5=B0=8F=E5=86=99=E4=B8=8D=E6=95=8F?= =?UTF-8?q?=E6=84=9F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Yi.Framework.Rbac.Domain/Managers/AccountManager.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/AccountManager.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/AccountManager.cs index db6d809f..8b6ad546 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/AccountManager.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/AccountManager.cs @@ -175,11 +175,12 @@ namespace Yi.Framework.Rbac.Domain.Managers { userAction.Invoke(user); } - if (user == null) + //这里为了兼容解决数据库开启了大小写不敏感问题,还要将用户名进行二次效验 + if (user != null&&user.UserName==userName) { - return false; + return true; } - return true; + return false; } /// From 9477ca0373e6d868133dc34f27096b062d6c378e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= <454313500@qq.com> Date: Sun, 18 Feb 2024 11:41:43 +0800 Subject: [PATCH 05/24] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=BF=A1=E6=81=AF=E7=BC=93=E5=AD=98=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/AccountService.cs | 61 ++++++++++++++----- .../Caches/UserInfoCacheItem.cs | 29 +++++++++ .../Managers/AccountManager.cs | 7 ++- 3 files changed, 78 insertions(+), 19 deletions(-) create mode 100644 Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Caches/UserInfoCacheItem.cs diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs index 3d7c79e2..116d27c5 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs @@ -3,6 +3,7 @@ using Lazy.Captcha.Core; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using SqlSugar; using Volo.Abp; @@ -33,15 +34,17 @@ namespace Yi.Framework.Rbac.Application.Services private readonly IGuidGenerator _guidGenerator; private readonly RbacOptions _rbacOptions; private readonly IAliyunManger _aliyunManger; + private IDistributedCache _userCache; public AccountService(IUserRepository userRepository, ICurrentUser currentUser, IAccountManager accountManager, ISqlSugarRepository menuRepository, IDistributedCache phoneCache, + IDistributedCache userCache, ICaptcha captcha, IGuidGenerator guidGenerator, IOptions options, - IAliyunManger aliyunManger ) + IAliyunManger aliyunManger) { _userRepository = userRepository; _currentUser = currentUser; @@ -52,6 +55,7 @@ namespace Yi.Framework.Rbac.Application.Services _guidGenerator = guidGenerator; _rbacOptions = options.Value; _aliyunManger = aliyunManger; + _userCache = userCache; } @@ -113,10 +117,10 @@ namespace Yi.Framework.Rbac.Application.Services [Authorize(AuthenticationSchemes = TokenTypeConst.Refresh)] public async Task PostRefreshAsync([FromQuery] string refresh_token) { - var userId = CurrentUser.Id.Value; - var accessToken = await _accountManager.GetTokenByUserIdAsync(userId); - var refreshToken = _accountManager.CreateRefreshToken(userId); - return new { Token = accessToken, RefreshToken = refreshToken }; + var userId = CurrentUser.Id.Value; + var accessToken = await _accountManager.GetTokenByUserIdAsync(userId); + var refreshToken = _accountManager.CreateRefreshToken(userId); + return new { Token = accessToken, RefreshToken = refreshToken }; } /// @@ -249,7 +253,7 @@ namespace Yi.Framework.Rbac.Application.Services /// - /// 查询已登录的账户信息 + /// 查询已登录的账户信息,已缓存 /// /// [Route("account")] @@ -263,16 +267,33 @@ namespace Yi.Framework.Rbac.Application.Services { throw new UserFriendlyException("用户未登录"); } - //此处从缓存中获取也行 - //var data = _cacheManager.Get($"Yi:UserInfo:{userId}"); - var data = await _userRepository.GetUserAllInfoAsync(userId ?? Guid.Empty); - //系统用户数据被重置,老前端访问重新授权 - if (data is null) + //此处优先从缓存中获取 + UserRoleMenuDto output = null; + var cacheData = await _userCache.GetAsync(new UserInfoCacheKey(userId.Value)); + if (cacheData is not null) { - throw new AbpAuthorizationException(); + output = cacheData.Info; } - data.Menus.Clear(); - return data; + else + { + var data = await _userRepository.GetUserAllInfoAsync(userId.Value); + //系统用户数据被重置,老前端访问重新授权 + if (data is null) + { + throw new AbpAuthorizationException(); + } + data.Menus.Clear(); + + output = data; + + var tokenExpiresMinuteTime = LazyServiceProvider.GetRequiredService>().Value.ExpiresMinuteTime; + //将用户信息放入缓存,下次获取直接从缓存中获取即可,过期时间为token过期时间 + await _userCache.SetAsync(new UserInfoCacheKey(userId.Value), new UserInfoCacheItem(data), new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(tokenExpiresMinuteTime) }); + } + + + + return output; } @@ -307,10 +328,18 @@ namespace Yi.Framework.Rbac.Application.Services /// 退出登录 /// /// - public Task PostLogout() + public async Task PostLogout() { + //通过鉴权jwt获取到用户的id + var userId = _currentUser.Id; + if (userId is null) + { + return false; + // throw new UserFriendlyException("用户已退出"); + } + await _userCache.RemoveAsync(new UserInfoCacheKey(userId.Value)); //Jwt去中心化登出,只需用记录日志即可 - return Task.FromResult(true); + return true; } /// diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Caches/UserInfoCacheItem.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Caches/UserInfoCacheItem.cs new file mode 100644 index 00000000..6be1ff3a --- /dev/null +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Caches/UserInfoCacheItem.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Rbac.Domain.Shared.Dtos; + +namespace Yi.Framework.Rbac.Domain.Shared.Caches +{ + public class UserInfoCacheItem + { + public UserInfoCacheItem(UserRoleMenuDto info) { Info = info; } + /// + /// 存储的用户信息 + /// + public UserRoleMenuDto Info { get; set; } + } + public class UserInfoCacheKey + { + public UserInfoCacheKey(Guid userId) { UserId = userId; } + + public Guid UserId { get; set; } + + public override string ToString() + { + return $"Yi:User:{UserId}"; + } + } +} diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/AccountManager.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/AccountManager.cs index 8b6ad546..dfe4ba03 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/AccountManager.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/AccountManager.cs @@ -6,15 +6,15 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json; -using Volo.Abp; +using Volo.Abp.Caching; using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Services; using Volo.Abp.EventBus.Local; using Volo.Abp.Security.Claims; -using Volo.Abp.Users; using Yi.Framework.Core.Helper; using Yi.Framework.Rbac.Domain.Entities; using Yi.Framework.Rbac.Domain.Repositories; +using Yi.Framework.Rbac.Domain.Shared.Caches; using Yi.Framework.Rbac.Domain.Shared.Consts; using Yi.Framework.Rbac.Domain.Shared.Dtos; using Yi.Framework.Rbac.Domain.Shared.Etos; @@ -38,6 +38,7 @@ namespace Yi.Framework.Rbac.Domain.Managers private UserManager _userManager; private ISqlSugarRepository _roleRepository; private RefreshJwtOptions _refreshJwtOptions; + public AccountManager(IUserRepository repository , IHttpContextAccessor httpContextAccessor , IOptions jwtOptions @@ -87,9 +88,9 @@ namespace Yi.Framework.Rbac.Domain.Managers loginEto.UserId = userInfo.User.Id; await _localEventBus.PublishAsync(loginEto); } + var accessToken = CreateToken(this.UserInfoToClaim(userInfo)); //将用户信息添加到缓存中,需要考虑的是更改了用户、角色、菜单等整个体系都需要将缓存进行刷新,看具体业务进行选择 - var accessToken = CreateToken(this.UserInfoToClaim(userInfo)); return accessToken; } From 798cb92f50364a2b315786532860f6658597e19b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= <454313500@qq.com> Date: Sun, 18 Feb 2024 15:02:23 +0800 Subject: [PATCH 06/24] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E7=9B=91=E6=8E=A7=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../YiDistributedCacheKeyNormalizer.cs | 40 ++++++++ .../Consts/LevelConst.cs | 2 +- .../Services/Monitor/MonitorCacheService.cs | 97 +++++++++++++++---- .../Caches/CaptchaPhoneCacheItem.cs | 2 +- .../Caches/UserInfoCacheItem.cs | 2 +- .../Yi.Framework.Rbac.Domain.csproj | 1 + .../YiFrameworkRbacDomainModule.cs | 2 + Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs | 2 + 8 files changed, 125 insertions(+), 23 deletions(-) create mode 100644 Yi.Abp.Net8/framework/Yi.Framework.Caching.FreeRedis/YiDistributedCacheKeyNormalizer.cs diff --git a/Yi.Abp.Net8/framework/Yi.Framework.Caching.FreeRedis/YiDistributedCacheKeyNormalizer.cs b/Yi.Abp.Net8/framework/Yi.Framework.Caching.FreeRedis/YiDistributedCacheKeyNormalizer.cs new file mode 100644 index 00000000..e3e0e22e --- /dev/null +++ b/Yi.Abp.Net8/framework/Yi.Framework.Caching.FreeRedis/YiDistributedCacheKeyNormalizer.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; +using Volo.Abp.MultiTenancy; + +namespace Yi.Framework.Caching.FreeRedis +{ + [Dependency(ReplaceServices =true)] + public class YiDistributedCacheKeyNormalizer : IDistributedCacheKeyNormalizer, ITransientDependency + { + protected ICurrentTenant CurrentTenant { get; } + + protected AbpDistributedCacheOptions DistributedCacheOptions { get; } + + public YiDistributedCacheKeyNormalizer( + ICurrentTenant currentTenant, + IOptions distributedCacheOptions) + { + CurrentTenant = currentTenant; + DistributedCacheOptions = distributedCacheOptions.Value; + } + + public virtual string NormalizeKey(DistributedCacheKeyNormalizeArgs args) + { + var normalizedKey = $"{DistributedCacheOptions.KeyPrefix}{args.Key}"; + + //if (!args.IgnoreMultiTenancy && CurrentTenant.Id.HasValue) + //{ + // normalizedKey = $"t:{CurrentTenant.Id.Value},{normalizedKey}"; + //} + + return normalizedKey; + } + } +} diff --git a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Consts/LevelConst.cs b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Consts/LevelConst.cs index e62d9afc..b5bb0b81 100644 --- a/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Consts/LevelConst.cs +++ b/Yi.Abp.Net8/module/bbs/Yi.Framework.Bbs.Domain.Shared/Consts/LevelConst.cs @@ -8,7 +8,7 @@ namespace Yi.Framework.Bbs.Domain.Shared.Consts { public class LevelConst { - public const string LevelCacheKey=nameof(LevelCacheKey); + public const string LevelCacheKey="Level:All"; public const string Level_Low_Zero = "经验提升等级低于或等于0"; } diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/MonitorCacheService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/MonitorCacheService.cs index 2862d243..c6adc05f 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/MonitorCacheService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/MonitorCacheService.cs @@ -1,5 +1,12 @@ -using Microsoft.AspNetCore.Mvc; +using FreeRedis; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; +using Microsoft.VisualBasic; +using TencentCloud.Mna.V20210119.Models; using Volo.Abp.Application.Services; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; using Yi.Framework.Rbac.Application.Contracts.Dtos.MonitorCache; using Yi.Framework.Rbac.Application.Contracts.IServices; @@ -7,37 +14,87 @@ namespace Yi.Framework.Rbac.Application.Services.Monitor { public class MonitorCacheService : ApplicationService, IMonitorCacheService { - private static List monitorCacheNames => new List() - { - new MonitorCacheNameGetListOutputDto{ CacheName="Yi:Login",Remark="登录验证码"}, - new MonitorCacheNameGetListOutputDto{ CacheName="Yi:User",Remark="用户信息"} - }; - private Dictionary monitorCacheNamesDic => monitorCacheNames.ToDictionary(x => x.CacheName, x => x.Remark); - //private CSRedisClient _cacheClient; - public MonitorCacheService() - { - //_cacheClient = redisCacheClient.Client; - } - //cacheKey value为空,只要name和备注 + public IAbpLazyServiceProvider LazyServiceProvider { get; set; } - public List GetName() + /// + /// 缓存前缀 + /// + private string CacheKeyPrefix => LazyServiceProvider.LazyGetRequiredService>().Value.KeyPrefix; + + private bool EnableRedisCache { - //固定的 - return monitorCacheNames; + get + { + var redisEnabled = LazyServiceProvider.LazyGetRequiredService()["Redis:IsEnabled"]; + return redisEnabled.IsNullOrEmpty() || bool.Parse(redisEnabled); + } } + /// + /// 使用懒加载防止报错 + /// + private IRedisClient RedisClient => LazyServiceProvider.LazyGetRequiredService(); + + /// + /// 获取所有key并分组 + /// + /// + public List GetName() + { + VerifyRedisCacheEnable(); + var keys = RedisClient.Keys(CacheKeyPrefix + "*"); + var result = GroupedKeys(keys.ToList()); + var output = result.Select(x => new MonitorCacheNameGetListOutputDto { CacheName = x }).ToList(); + return output; + } + + private List GroupedKeys(List keys) + { + HashSet resultSet = new HashSet(); + foreach (string str in keys) + { + string[] parts = str.Split(':'); + + // 如果字符串中包含冒号,则将第一部分和第二部分进行分组 + if (parts.Length >= 2) + { + string group = $"{parts[0]}:{parts[1]}"; + resultSet.Add(group); + } + // 如果字符串中不包含冒号,则直接进行分组 + else + { + resultSet.Add(str); + } + } + return resultSet.ToList(); + + } + + + + private void VerifyRedisCacheEnable() + { + if (!EnableRedisCache) + { + throw new UserFriendlyException("后端程序未使用Redis缓存,无法对Redis进行监控"); + } + + } + [HttpGet("key/{cacaheName}")] public List GetKey(string cacaheName) { - //var output = _cacheClient.Keys($"{cacaheName}:*"); - return new List() { "1233124", "3124", "1231251", "12312412" }; + VerifyRedisCacheEnable(); + var output = RedisClient.Keys($"{cacaheName}:*").Select(x => x.RemovePreFix(cacaheName+ ":")); + return output.ToList(); } //全部不为空 [HttpGet("value/{cacaheName}/{cacaheKey}")] public MonitorCacheGetListOutputDto GetValue(string cacaheName, string cacaheKey) { - //var value = _cacheClient.Get($"{cacaheName}:{cacaheKey}"); - return new MonitorCacheGetListOutputDto() { CacheKey = cacaheKey, CacheName = cacaheName, CacheValue = "ttt", Remark = monitorCacheNamesDic[cacaheName] }; + var value = RedisClient.HGet($"{cacaheName}:{cacaheKey}", "data"); + return new MonitorCacheGetListOutputDto() { CacheKey = cacaheKey, CacheName = cacaheName, CacheValue = value }; } } diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Caches/CaptchaPhoneCacheItem.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Caches/CaptchaPhoneCacheItem.cs index c18432fa..5ec63192 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Caches/CaptchaPhoneCacheItem.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Caches/CaptchaPhoneCacheItem.cs @@ -20,7 +20,7 @@ namespace Yi.Framework.Rbac.Domain.Shared.Caches public override string ToString() { - return $"Yi:Phone:{Phone}"; + return $"Phone:{Phone}"; } } } diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Caches/UserInfoCacheItem.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Caches/UserInfoCacheItem.cs index 6be1ff3a..6bbc113e 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Caches/UserInfoCacheItem.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Caches/UserInfoCacheItem.cs @@ -23,7 +23,7 @@ namespace Yi.Framework.Rbac.Domain.Shared.Caches public override string ToString() { - return $"Yi:User:{UserId}"; + return $"User:{UserId}"; } } } diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Yi.Framework.Rbac.Domain.csproj b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Yi.Framework.Rbac.Domain.csproj index 124133c1..3617a7e8 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Yi.Framework.Rbac.Domain.csproj +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Yi.Framework.Rbac.Domain.csproj @@ -21,6 +21,7 @@ + diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/YiFrameworkRbacDomainModule.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/YiFrameworkRbacDomainModule.cs index 7d185398..a5568c1e 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/YiFrameworkRbacDomainModule.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/YiFrameworkRbacDomainModule.cs @@ -3,6 +3,7 @@ using Volo.Abp.AspNetCore.SignalR; using Volo.Abp.Caching; using Volo.Abp.Domain; using Volo.Abp.Modularity; +using Yi.Framework.Caching.FreeRedis; using Yi.Framework.Mapster; using Yi.Framework.Rbac.Domain.Authorization; using Yi.Framework.Rbac.Domain.Operlog; @@ -13,6 +14,7 @@ namespace Yi.Framework.Rbac.Domain { [DependsOn( typeof(YiFrameworkRbacDomainSharedModule), + typeof(YiFrameworkCachingFreeRedisModule), typeof(AbpAspNetCoreSignalRModule), typeof(AbpDddDomainModule), diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs b/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs index 65b0d18c..787600a0 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs +++ b/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs @@ -87,6 +87,8 @@ namespace Yi.Abp.Web Configure(cacheOptions => { cacheOptions.GlobalCacheEntryOptions.SlidingExpiration =null; + //缓存key前缀 + cacheOptions.KeyPrefix = "Yi:"; }); From 7fb5cb72f52142a891f59f77c828e801d8f75e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= <454313500@qq.com> Date: Sun, 18 Feb 2024 15:29:35 +0800 Subject: [PATCH 07/24] =?UTF-8?q?feat:=E5=89=8D=E7=AB=AF=E5=AF=B9=E6=8E=A5?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E7=BC=93=E5=AD=98=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/Monitor/MonitorCacheService.cs | 33 ++++++++++++++++--- Yi.RuoYi.Vue3/src/api/monitor/cache.js | 8 ++--- .../src/views/monitor/cache/list.vue | 2 +- 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/MonitorCacheService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/MonitorCacheService.cs index c6adc05f..34c0dc34 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/MonitorCacheService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/MonitorCacheService.cs @@ -38,7 +38,8 @@ namespace Yi.Framework.Rbac.Application.Services.Monitor /// 获取所有key并分组 /// /// - public List GetName() + [HttpGet("monitor-cache/name")] + public List GetName() { VerifyRedisCacheEnable(); var keys = RedisClient.Keys(CacheKeyPrefix + "*"); @@ -81,21 +82,45 @@ namespace Yi.Framework.Rbac.Application.Services.Monitor } - [HttpGet("key/{cacaheName}")] + [HttpGet("monitor-cache/key/{cacaheName}")] public List GetKey(string cacaheName) { VerifyRedisCacheEnable(); - var output = RedisClient.Keys($"{cacaheName}:*").Select(x => x.RemovePreFix(cacaheName+ ":")); + var output = RedisClient.Keys($"{cacaheName}:*").Select(x => x.RemovePreFix(cacaheName + ":")); return output.ToList(); } //全部不为空 - [HttpGet("value/{cacaheName}/{cacaheKey}")] + [HttpGet("monitor-cache/value/{cacaheName}/{cacaheKey}")] public MonitorCacheGetListOutputDto GetValue(string cacaheName, string cacaheKey) { var value = RedisClient.HGet($"{cacaheName}:{cacaheKey}", "data"); return new MonitorCacheGetListOutputDto() { CacheKey = cacaheKey, CacheName = cacaheName, CacheValue = value }; } + + + + [HttpDelete("monitor-cache/key/{cacaheName}")] + public bool DeleteKey(string cacaheName) + { + VerifyRedisCacheEnable(); + RedisClient.Del($"{cacaheName}:*"); + return true; + } + + [HttpDelete("monitor-cache/value/{cacaheName}/{cacaheKey}")] + public bool DeleteValue(string cacaheName, string cacaheKey) + { + RedisClient.Del($"{cacaheName}:{cacaheKey}"); + return true; + } + + [HttpDelete("monitor-cache/clear")] + public bool DeleteClear() + { + RedisClient.FlushDb(); + return true; + } } diff --git a/Yi.RuoYi.Vue3/src/api/monitor/cache.js b/Yi.RuoYi.Vue3/src/api/monitor/cache.js index cf495d4c..c2c034b5 100644 --- a/Yi.RuoYi.Vue3/src/api/monitor/cache.js +++ b/Yi.RuoYi.Vue3/src/api/monitor/cache.js @@ -35,15 +35,15 @@ export function getCacheValue(cacheName, cacheKey) { // 清理指定名称缓存 export function clearCacheName(cacheName) { return request({ - url: '/monitor/cache/clearCacheName/' + cacheName, + url: '/monitor-cache/key/' + cacheName, method: 'delete' }) } // 清理指定键名缓存 -export function clearCacheKey(cacheKey) { +export function clearCacheKey(cacheName,cacheKey) { return request({ - url: '/monitor/cache/clearCacheKey/' + cacheKey, + url: '/monitor-cache/value/'+cacheName+'/' + cacheKey, method: 'delete' }) } @@ -51,7 +51,7 @@ export function clearCacheKey(cacheKey) { // 清理全部缓存 export function clearCacheAll() { return request({ - url: '/monitor/cache/clearCacheAll', + url: '/monitor-cache/clear', method: 'delete' }) } diff --git a/Yi.RuoYi.Vue3/src/views/monitor/cache/list.vue b/Yi.RuoYi.Vue3/src/views/monitor/cache/list.vue index 49ba7cdd..8db15e9c 100644 --- a/Yi.RuoYi.Vue3/src/views/monitor/cache/list.vue +++ b/Yi.RuoYi.Vue3/src/views/monitor/cache/list.vue @@ -207,7 +207,7 @@ function refreshCacheKeys() { /** 清理指定键名缓存 */ function handleClearCacheKey(cacheKey) { - clearCacheKey(cacheKey).then(response => { + clearCacheKey(nowCacheName.value,cacheKey).then(response => { proxy.$modal.msgSuccess("清理缓存键名[" + cacheKey + "]成功"); getCacheKeys(); }); From b239a4ff562eeeacbc21551283324b50719d9d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= <454313500@qq.com> Date: Sun, 18 Feb 2024 15:32:00 +0800 Subject: [PATCH 08/24] =?UTF-8?q?style:=20=E5=AE=8C=E5=96=84=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/Monitor/MonitorCacheService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/MonitorCacheService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/MonitorCacheService.cs index 34c0dc34..a8173d93 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/MonitorCacheService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/Monitor/MonitorCacheService.cs @@ -77,7 +77,7 @@ namespace Yi.Framework.Rbac.Application.Services.Monitor { if (!EnableRedisCache) { - throw new UserFriendlyException("后端程序未使用Redis缓存,无法对Redis进行监控"); + throw new UserFriendlyException("后端程序未使用Redis缓存,无法对Redis进行监控,可切换使用Redis"); } } From 609c7c821f720458690014ae281b1444153bed57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= <454313500@qq.com> Date: Sun, 18 Feb 2024 16:34:55 +0800 Subject: [PATCH 09/24] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DExtraProperties?= =?UTF-8?q?=E5=BF=BD=E7=95=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entities/TableAggregateRoot.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Yi.Abp.Net8/module/code-gen/Yi.Framework.CodeGen.Domain/Entities/TableAggregateRoot.cs b/Yi.Abp.Net8/module/code-gen/Yi.Framework.CodeGen.Domain/Entities/TableAggregateRoot.cs index bee9af39..48ba4165 100644 --- a/Yi.Abp.Net8/module/code-gen/Yi.Framework.CodeGen.Domain/Entities/TableAggregateRoot.cs +++ b/Yi.Abp.Net8/module/code-gen/Yi.Framework.CodeGen.Domain/Entities/TableAggregateRoot.cs @@ -1,4 +1,5 @@ using SqlSugar; +using Volo.Abp.Data; using Volo.Abp.Domain.Entities; namespace Yi.Framework.CodeGen.Domain.Entities @@ -24,5 +25,8 @@ namespace Yi.Framework.CodeGen.Domain.Entities /// [Navigate(NavigateType.OneToMany, nameof(FieldEntity.TableId))] public List Fields { get; set; } + + [SugarColumn(IsIgnore =true)] + public override ExtraPropertyDictionary ExtraProperties { get; protected set; } } } From 2dbfdc67c500c23d26f8c47563d2b7108e98e930 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= <454313500@qq.com> Date: Sun, 18 Feb 2024 16:44:32 +0800 Subject: [PATCH 10/24] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E9=85=8D=E7=BD=AE=EF=BC=8C=E5=8F=AF=E7=9C=81=E7=95=A5?= =?UTF-8?q?=E7=B9=81=E7=90=90=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Yi.Framework.SqlSugarCore/SqlSugarDbContext.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/SqlSugarDbContext.cs b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/SqlSugarDbContext.cs index 96c1c765..34f2ec21 100644 --- a/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/SqlSugarDbContext.cs +++ b/Yi.Abp.Net8/framework/Yi.Framework.SqlSugarCore/SqlSugarDbContext.cs @@ -256,7 +256,14 @@ namespace Yi.Framework.SqlSugarCore /// protected virtual void EntityService(PropertyInfo property, EntityColumnInfo column) { - + if (property.PropertyType == typeof(ExtraPropertyDictionary)) + { + column.IsIgnore = true; + } + if (property.Name == nameof(Entity.Id)) + { + column.IsPrimarykey = true; + } } public void BackupDataBase() From 02fc86af4fde77d4a53d44530a973ee32f3677f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= <454313500@qq.com> Date: Mon, 19 Feb 2024 17:12:33 +0800 Subject: [PATCH 11/24] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=94=9F=E6=88=90=E5=99=A8=E6=A8=A1=E6=9D=BF=E7=A7=8D?= =?UTF-8?q?=E5=AD=90=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Yi.Abp.Net8/Yi.Abp.sln | 9 +- .../Enums/FieldTypeEnum.cs | 3 + .../TemplateDataSeed.cs | 106 ++++++++++++++++++ .../Yi.Framework.CodeGen.SqlSugarCore.csproj | 13 +++ .../YiFrameworkCodeGenSqlSugarCoreModule.cs | 10 ++ .../Yi.Abp.SqlSugarCore.csproj | 1 + .../YiAbpSqlSugarCoreModule.cs | 2 + .../Yi.Abp.Web/Properties/launchSettings.json | 4 +- Yi.RuoYi.Vue3/src/views/code/table/index.vue | 3 +- 9 files changed, 147 insertions(+), 4 deletions(-) create mode 100644 Yi.Abp.Net8/module/code-gen/Yi.Framework.CodeGen.SqlSugarCore/TemplateDataSeed.cs create mode 100644 Yi.Abp.Net8/module/code-gen/Yi.Framework.CodeGen.SqlSugarCore/Yi.Framework.CodeGen.SqlSugarCore.csproj create mode 100644 Yi.Abp.Net8/module/code-gen/Yi.Framework.CodeGen.SqlSugarCore/YiFrameworkCodeGenSqlSugarCoreModule.cs diff --git a/Yi.Abp.Net8/Yi.Abp.sln b/Yi.Abp.Net8/Yi.Abp.sln index 68fdb662..0403da9e 100644 --- a/Yi.Abp.Net8/Yi.Abp.sln +++ b/Yi.Abp.Net8/Yi.Abp.sln @@ -115,7 +115,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.CodeGen.Domain EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.CodeGen.Domain.Shared", "module\code-gen\Yi.Framework.Codegen.Domain.Shared\Yi.Framework.CodeGen.Domain.Shared.csproj", "{EEFF0F05-2709-4151-A8CE-667935CEAE0B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.Caching.FreeRedis", "framework\Yi.Framework.Caching.FreeRedis\Yi.Framework.Caching.FreeRedis.csproj", "{862BB0EF-3D4E-44FF-AB15-0EB74CE553D3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Caching.FreeRedis", "framework\Yi.Framework.Caching.FreeRedis\Yi.Framework.Caching.FreeRedis.csproj", "{862BB0EF-3D4E-44FF-AB15-0EB74CE553D3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.CodeGen.SqlSugarCore", "module\code-gen\Yi.Framework.CodeGen.SqlSugarCore\Yi.Framework.CodeGen.SqlSugarCore.csproj", "{FB09ACC2-A27D-4D87-8D85-1435FDED4D04}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -295,6 +297,10 @@ Global {862BB0EF-3D4E-44FF-AB15-0EB74CE553D3}.Debug|Any CPU.Build.0 = Debug|Any CPU {862BB0EF-3D4E-44FF-AB15-0EB74CE553D3}.Release|Any CPU.ActiveCfg = Release|Any CPU {862BB0EF-3D4E-44FF-AB15-0EB74CE553D3}.Release|Any CPU.Build.0 = Release|Any CPU + {FB09ACC2-A27D-4D87-8D85-1435FDED4D04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FB09ACC2-A27D-4D87-8D85-1435FDED4D04}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FB09ACC2-A27D-4D87-8D85-1435FDED4D04}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FB09ACC2-A27D-4D87-8D85-1435FDED4D04}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -348,6 +354,7 @@ Global {85CB8517-2B80-42D8-B954-081079AC9BA0} = {4FFE7212-21F2-476D-B628-3C65E6C5075E} {EEFF0F05-2709-4151-A8CE-667935CEAE0B} = {4FFE7212-21F2-476D-B628-3C65E6C5075E} {862BB0EF-3D4E-44FF-AB15-0EB74CE553D3} = {77B949E9-530E-45A5-9657-20F7D5C6875C} + {FB09ACC2-A27D-4D87-8D85-1435FDED4D04} = {4FFE7212-21F2-476D-B628-3C65E6C5075E} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {23D6FBC9-C970-4641-BC1E-2AEA59F51C18} diff --git a/Yi.Abp.Net8/module/code-gen/Yi.Framework.CodeGen.Domain.Shared/Enums/FieldTypeEnum.cs b/Yi.Abp.Net8/module/code-gen/Yi.Framework.CodeGen.Domain.Shared/Enums/FieldTypeEnum.cs index 4713f2a9..8a08cca9 100644 --- a/Yi.Abp.Net8/module/code-gen/Yi.Framework.CodeGen.Domain.Shared/Enums/FieldTypeEnum.cs +++ b/Yi.Abp.Net8/module/code-gen/Yi.Framework.CodeGen.Domain.Shared/Enums/FieldTypeEnum.cs @@ -26,6 +26,9 @@ namespace Yi.Framework.CodeGen.Domain.Shared.Enums [Display(Name = "DateTime", Description = "DateTime")] DateTime, + + [Display(Name = "Guid", Description = "Guid")] + Guid } } diff --git a/Yi.Abp.Net8/module/code-gen/Yi.Framework.CodeGen.SqlSugarCore/TemplateDataSeed.cs b/Yi.Abp.Net8/module/code-gen/Yi.Framework.CodeGen.SqlSugarCore/TemplateDataSeed.cs new file mode 100644 index 00000000..348cdaf9 --- /dev/null +++ b/Yi.Abp.Net8/module/code-gen/Yi.Framework.CodeGen.SqlSugarCore/TemplateDataSeed.cs @@ -0,0 +1,106 @@ +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Guids; +using Yi.Framework.CodeGen.Domain.Entities; +using Yi.Framework.SqlSugarCore.Abstractions; + +namespace Yi.Framework.CodeGen.SqlSugarCore +{ + public class TemplateDataSeed : IDataSeedContributor, ITransientDependency + { + private ISqlSugarRepository _repository; + public TemplateDataSeed(ISqlSugarRepository repository) + { + _repository = repository; + } + public async Task SeedAsync(DataSeedContext context) + { + if (!await _repository.IsAnyAsync(x => true)) + { + await _repository.InsertManyAsync(GetSeedData()); + } + } + public List GetSeedData() + { + var entities = new List(); + TemplateEntity entityTemplate = new TemplateEntity() + { + Name= "Entity", + BuildPath= "D:\\code\\Entities\\@ModelEntity.cs", + Remarks= "实体", + TemplateStr= "using SqlSugar;\r\nusing Volo.Abp;\r\nusing Volo.Abp.Auditing;\r\nusing Volo.Abp.Domain.Entities;\r\nusing Yi.Framework.Core.Data;\r\n\r\nnamespace Yi.Framework.Rbac.Domain.Entities\r\n{\r\n /// \r\n /// 实体\r\n /// \r\n [SugarTable(\"@Model\")]\r\n public class @ModelEntity : Entity\r\n {\r\n@field\r\n }\r\n}\r\n" + }; + entities.Add(entityTemplate); + + + TemplateEntity getListInputTemplate = new TemplateEntity() + { + Name = "GetListInput", + BuildPath = "D:\\code\\Dtos\\@Model\\@ModelGetListInput.cs", + Remarks = "列表查询参数", + TemplateStr = "using Yi.Framework.Ddd;\r\nusing Yi.Framework.Ddd.Application.Contracts;\r\n\r\nnamespace Yi.Framework.Rbac.Application.Contracts.Dtos.@Model\r\n{\r\n /// \r\n /// 查询参数\r\n /// \r\n public class @ModelGetListInputVo : PagedAllResultRequestDto\r\n {\r\n@field\r\n }\r\n}\r\n" + }; + entities.Add(getListInputTemplate); + + + TemplateEntity getListOutputDtoTemplate = new TemplateEntity() + { + Name = "GetListOutputDto", + BuildPath = "D:\\code\\Dtos\\@Model\\@ModelGetListOutputDto.cs", + Remarks = "列表返回dto", + TemplateStr = "using Volo.Abp.Application.Dtos;\r\n\r\nnamespace Yi.Framework.Rbac.Application.Contracts.Dtos.@Model\r\n{\r\n public class @ModelGetListOutputDto : EntityDto\r\n {\r\n@field\r\n }\r\n}\r\n" + }; + entities.Add(getListOutputDtoTemplate); + + + TemplateEntity getOutputDtoTemplate = new TemplateEntity() + { + Name = "GetOutputDto", + BuildPath = "D:\\code\\Dtos\\@Model\\@ModelGetOutputDto.cs", + Remarks = "单返回dto", + TemplateStr = "using Volo.Abp.Application.Dtos;\r\n\r\nnamespace Yi.Framework.Rbac.Application.Contracts.Dtos.@Model\r\n{\r\n public class @ModelGetOutputDto : EntityDto\r\n {\r\n@field\r\n }\r\n}\r\n" + }; + entities.Add(getOutputDtoTemplate); + + TemplateEntity updateInputTemplate = new TemplateEntity() + { + Name = "UpdateInput", + BuildPath = "D:\\code\\Dtos\\@Model\\@ModelUpdateInput.cs", + Remarks = "更新输入", + TemplateStr = "namespace Yi.Framework.Rbac.Application.Contracts.Dtos.@Model\r\n{\r\n public class @ModelUpdateInput\r\n {\r\n@field\r\n }\r\n}\r\n" + }; + entities.Add(updateInputTemplate); + + TemplateEntity createInputTemplate = new TemplateEntity() + { + Name = "CreateInput", + BuildPath = "D:\\code\\Dtos\\@Model\\@ModelCreateInput.cs", + Remarks = "创建dto", + TemplateStr = "namespace Yi.Framework.Rbac.Application.Contracts.Dtos.@Model\r\n{\r\n /// \r\n /// @Model输入创建对象\r\n /// \r\n public class @ModelCreateInput\r\n {\r\n@field\r\n }\r\n}\r\n" + }; + entities.Add(createInputTemplate); + + + TemplateEntity iServicesTemplate = new TemplateEntity() + { + Name = "IServices", + BuildPath = "D:\\code\\IServices\\I@ModelService.cs", + Remarks = "应用服务抽象", + TemplateStr = "using Volo.Abp.Application.Services;\r\nusing Yi.Framework.Ddd.Application.Contracts;\r\nusing Yi.Framework.Rbac.Application.Contracts.Dtos.@Model;\r\n\r\nnamespace Yi.Framework.Rbac.Application.Contracts.IServices\r\n{\r\n /// \r\n /// @Model服务抽象\r\n /// \r\n public interface I@ModelService : IYiCrudAppService<@ModelGetOutputDto, @ModelGetListOutputDto, Guid, @ModelGetListInputVo, @ModelCreateInputVo, @ModelUpdateInputVo>\r\n {\r\n\r\n }\r\n}\r\n" + }; + entities.Add(iServicesTemplate); + + + + TemplateEntity servicesTemplate = new TemplateEntity() + { + Name = "Service", + BuildPath = "D:\\code\\Services\\@ModelService.cs", + Remarks = "应用服务", + TemplateStr = "using SqlSugar;\r\nusing Volo.Abp.Application.Dtos;\r\nusing Volo.Abp.Application.Services;\r\nusing Yi.Framework.Ddd.Application;\r\nusing Yi.Framework.Rbac.Application.Contracts.Dtos.@Model;\r\nusing Yi.Framework.Rbac.Application.Contracts.IServices;\r\nusing Yi.Framework.Rbac.Domain.Entities;\r\nusing Yi.Framework.SqlSugarCore.Abstractions;\r\n\r\nnamespace Yi.Framework.Rbac.Application.Services\r\n{\r\n /// \r\n /// @Model服务实现\r\n /// \r\n public class @ModelService : YiCrudAppService<@ModelEntity, @ModelGetOutputDto, @ModelGetListOutputDto, Guid, @ModelGetListInputVo, @ModelCreateInputVo, @ModelUpdateInputVo>,\r\n I@ModelService\r\n {\r\n private ISqlSugarRepository<@ModelEntity, Guid> _repository;\r\n public @ModelService(ISqlSugarRepository<@ModelEntity, Guid> repository) : base(repository)\r\n {\r\n _repository = repository;\r\n }\r\n\r\n /// \r\n /// 多查\r\n /// \r\n /// \r\n /// \r\n public override async Task> GetListAsync(@ModelGetListInputVo input)\r\n {\r\n RefAsync total = 0;\r\n\r\n var entities = await _repository._DbQueryable.WhereIF(!string.IsNullOrEmpty(input.@ModelKey), x => x.@ModelKey.Contains(input.@ModelKey!))\r\n .WhereIF(!string.IsNullOrEmpty(input.@ModelName), x => x.@ModelName!.Contains(input.@ModelName!))\r\n .WhereIF(input.StartTime is not null && input.EndTime is not null, x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime)\r\n .ToPageListAsync(input.SkipCount, input.MaxResultCount, total);\r\n return new PagedResultDto<@ModelGetListOutputDto>(total, await MapToGetListOutputDtosAsync(entities));\r\n }\r\n }\r\n}\r\n" + }; + entities.Add(servicesTemplate); + return entities; + } + } +} diff --git a/Yi.Abp.Net8/module/code-gen/Yi.Framework.CodeGen.SqlSugarCore/Yi.Framework.CodeGen.SqlSugarCore.csproj b/Yi.Abp.Net8/module/code-gen/Yi.Framework.CodeGen.SqlSugarCore/Yi.Framework.CodeGen.SqlSugarCore.csproj new file mode 100644 index 00000000..e32e0691 --- /dev/null +++ b/Yi.Abp.Net8/module/code-gen/Yi.Framework.CodeGen.SqlSugarCore/Yi.Framework.CodeGen.SqlSugarCore.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + diff --git a/Yi.Abp.Net8/module/code-gen/Yi.Framework.CodeGen.SqlSugarCore/YiFrameworkCodeGenSqlSugarCoreModule.cs b/Yi.Abp.Net8/module/code-gen/Yi.Framework.CodeGen.SqlSugarCore/YiFrameworkCodeGenSqlSugarCoreModule.cs new file mode 100644 index 00000000..7e47a1d6 --- /dev/null +++ b/Yi.Abp.Net8/module/code-gen/Yi.Framework.CodeGen.SqlSugarCore/YiFrameworkCodeGenSqlSugarCoreModule.cs @@ -0,0 +1,10 @@ +using Yi.Framework.SqlSugarCore; + +namespace Yi.Framework.CodeGen.SqlSugarCore +{ + [DependsOn(typeof(YiFrameworkSqlSugarCoreModule))] + public class YiFrameworkCodeGenSqlSugarCoreModule:AbpModule + { + + } +} diff --git a/Yi.Abp.Net8/src/Yi.Abp.SqlSugarCore/Yi.Abp.SqlSugarCore.csproj b/Yi.Abp.Net8/src/Yi.Abp.SqlSugarCore/Yi.Abp.SqlSugarCore.csproj index c948284e..81fe397a 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.SqlSugarCore/Yi.Abp.SqlSugarCore.csproj +++ b/Yi.Abp.Net8/src/Yi.Abp.SqlSugarCore/Yi.Abp.SqlSugarCore.csproj @@ -6,6 +6,7 @@ + diff --git a/Yi.Abp.Net8/src/Yi.Abp.SqlSugarCore/YiAbpSqlSugarCoreModule.cs b/Yi.Abp.Net8/src/Yi.Abp.SqlSugarCore/YiAbpSqlSugarCoreModule.cs index 004f7512..6cfd4b59 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.SqlSugarCore/YiAbpSqlSugarCoreModule.cs +++ b/Yi.Abp.Net8/src/Yi.Abp.SqlSugarCore/YiAbpSqlSugarCoreModule.cs @@ -4,6 +4,7 @@ using Yi.Abp.Domain; using Yi.Abp.SqlSugarCore; using Yi.Framework.AuditLogging.SqlSugarCore; using Yi.Framework.Bbs.SqlSugarCore; +using Yi.Framework.CodeGen.SqlSugarCore; using Yi.Framework.Mapster; using Yi.Framework.Rbac.SqlSugarCore; using Yi.Framework.SqlSugarCore; @@ -17,6 +18,7 @@ namespace Yi.Abp.SqlsugarCore typeof(YiFrameworkRbacSqlSugarCoreModule), typeof(YiFrameworkBbsSqlSugarCoreModule), + typeof(YiFrameworkCodeGenSqlSugarCoreModule), typeof(YiFrameworkAuditLoggingSqlSugarCoreModule), typeof(YiFrameworkTenantManagementSqlSugarCoreModule), diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/Properties/launchSettings.json b/Yi.Abp.Net8/src/Yi.Abp.Web/Properties/launchSettings.json index 44097413..8f58fa9b 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.Web/Properties/launchSettings.json +++ b/Yi.Abp.Net8/src/Yi.Abp.Web/Properties/launchSettings.json @@ -5,8 +5,8 @@ "launchBrowser": true, "launchUrl": "swagger", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development", - //"ASPNETCORE_ENVIRONMENT": "Staging" + //"ASPNETCORE_ENVIRONMENT": "Development", + "ASPNETCORE_ENVIRONMENT": "Staging" }, "dotnetRunMessages": true, "applicationUrl": "http://localhost:19001" diff --git a/Yi.RuoYi.Vue3/src/views/code/table/index.vue b/Yi.RuoYi.Vue3/src/views/code/table/index.vue index 8afbd4d9..a3f14c2f 100644 --- a/Yi.RuoYi.Vue3/src/views/code/table/index.vue +++ b/Yi.RuoYi.Vue3/src/views/code/table/index.vue @@ -374,7 +374,8 @@ const handleCodeToWeb = async () => { /** CodeToWeb */ const handleWebToCode = async () => { const response= await webToCode(ids.value); - if(response.statusCode==200) + console.log(response,"response"); + if(response.status==200||response.status==204) { proxy.$modal.msgSuccess("代码生成成功"); } From 071ca9462add91d648a4b9acb4c5d8869266cba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= <454313500@qq.com> Date: Mon, 19 Feb 2024 17:29:43 +0800 Subject: [PATCH 12/24] =?UTF-8?q?chore:=20=E6=9E=84=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Yi.Abp.Net8/src/Yi.Abp.Web/Properties/launchSettings.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/Properties/launchSettings.json b/Yi.Abp.Net8/src/Yi.Abp.Web/Properties/launchSettings.json index 8f58fa9b..44097413 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.Web/Properties/launchSettings.json +++ b/Yi.Abp.Net8/src/Yi.Abp.Web/Properties/launchSettings.json @@ -5,8 +5,8 @@ "launchBrowser": true, "launchUrl": "swagger", "environmentVariables": { - //"ASPNETCORE_ENVIRONMENT": "Development", - "ASPNETCORE_ENVIRONMENT": "Staging" + "ASPNETCORE_ENVIRONMENT": "Development", + //"ASPNETCORE_ENVIRONMENT": "Staging" }, "dotnetRunMessages": true, "applicationUrl": "http://localhost:19001" From 5416ba1048ed6c61178ddbaecfc680370ccbfc1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= <454313500@qq.com> Date: Mon, 19 Feb 2024 17:51:54 +0800 Subject: [PATCH 13/24] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=85=AC?= =?UTF-8?q?=E5=91=8A=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Enums/NoticeTypeEnum.cs | 17 +++++ .../Entities/NoticeEntity.cs | 50 ++++++++++++ .../Entities/PostEntity.cs | 2 +- .../Entities/RoleDeptEntity.cs | 2 +- .../DataSeeds/MenuDataSeed.cs | 71 +++++++++++++++++- .../Yi.Abp.Web/Properties/launchSettings.json | 4 +- Yi.Abp.Net8/src/Yi.Abp.Web/yi-abp-dev.db | Bin 499712 -> 438272 bytes 7 files changed, 141 insertions(+), 5 deletions(-) create mode 100644 Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Enums/NoticeTypeEnum.cs create mode 100644 Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Entities/NoticeEntity.cs diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Enums/NoticeTypeEnum.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Enums/NoticeTypeEnum.cs new file mode 100644 index 00000000..ae5fbff3 --- /dev/null +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Enums/NoticeTypeEnum.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Yi.Framework.Rbac.Domain.Shared.Enums +{ + public enum NoticeTypeEnum + { + [Description("走马灯")] + MerryGoRound = 0, + [Description("提示弹窗")] + Popup = 1 + } +} diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Entities/NoticeEntity.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Entities/NoticeEntity.cs new file mode 100644 index 00000000..f25aa89f --- /dev/null +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Entities/NoticeEntity.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; +using Yi.Framework.Core.Data; +using Yi.Framework.Rbac.Domain.Shared.Enums; + +namespace Yi.Framework.Rbac.Domain.Entities +{ + [SugarTable("Notice")] + public class NoticeEntity : Entity, ISoftDelete, IAuditedObject, IOrderNum, IState + { + + [SugarColumn(IsPrimaryKey = true)] + public override Guid Id { get; protected set; } + + /// + /// 公告标题 + /// + public string Title { get; set; } + + /// + /// 类型 + /// + public NoticeTypeEnum Type { get; set; } + + /// + /// 内容 + /// + [SugarColumn(ColumnDataType = StaticConfig.CodeFirst_BigString)] + public string Content { get; set; } + + public bool IsDeleted { get; set; } + + public DateTime CreationTime { get; set; } + + public Guid? CreatorId { get; set; } + + public Guid? LastModifierId { get; set; } + + public DateTime? LastModificationTime { get; set; } + + public int OrderNum { get; set; } + public bool State { get; set; } + } +} diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Entities/PostEntity.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Entities/PostEntity.cs index 1cdd3bd1..a88457e7 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Entities/PostEntity.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Entities/PostEntity.cs @@ -10,7 +10,7 @@ namespace Yi.Framework.Rbac.Domain.Entities /// 岗位表 /// [SugarTable("Post")] - public partial class PostEntity : Entity, ISoftDelete, IAuditedObject, IOrderNum, IState + public class PostEntity : Entity, ISoftDelete, IAuditedObject, IOrderNum, IState { /// diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Entities/RoleDeptEntity.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Entities/RoleDeptEntity.cs index 52720653..9cfbe84b 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Entities/RoleDeptEntity.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Entities/RoleDeptEntity.cs @@ -7,7 +7,7 @@ namespace Yi.Framework.Rbac.Domain.Entities; /// 角色部门关系表 /// [SugarTable("RoleDept")] -public partial class RoleDeptEntity : Entity +public class RoleDeptEntity : Entity { /// /// 主键 diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.SqlSugarCore/DataSeeds/MenuDataSeed.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.SqlSugarCore/DataSeeds/MenuDataSeed.cs index 8c19cbcf..002db1be 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.SqlSugarCore/DataSeeds/MenuDataSeed.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.SqlSugarCore/DataSeeds/MenuDataSeed.cs @@ -1125,6 +1125,75 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds + //通知公告 + MenuEntity notice = new MenuEntity(_guidGenerator.Create()) + { + + MenuName = "通知公告", + PermissionCode = "system:notice:list", + MenuType = MenuTypeEnum.Menu, + Router = "notice", + IsShow = true, + IsLink = false, + IsCache = true, + Component = "system/notice/index", + MenuIcon = "message", + OrderNum = 93, + ParentId = system.Id, + IsDeleted = false + }; + entities.Add(notice); + + MenuEntity noticeQuery = new MenuEntity(_guidGenerator.Create()) + { + + MenuName = "通知查询", + PermissionCode = "system:notice:query", + MenuType = MenuTypeEnum.Component, + OrderNum = 100, + ParentId = notice.Id, + IsDeleted = false + }; + entities.Add(noticeQuery); + + MenuEntity noticeAdd = new MenuEntity(_guidGenerator.Create()) + { + + MenuName = "通知新增", + PermissionCode = "system:notice:add", + MenuType = MenuTypeEnum.Component, + OrderNum = 100, + ParentId = notice.Id, + IsDeleted = false + }; + entities.Add(noticeAdd); + + MenuEntity noticeEdit = new MenuEntity(_guidGenerator.Create()) + { + + MenuName = "通知修改", + PermissionCode = "system:notice:edit", + MenuType = MenuTypeEnum.Component, + OrderNum = 100, + ParentId = notice.Id, + IsDeleted = false + }; + entities.Add(noticeEdit); + + MenuEntity noticeRemove = new MenuEntity(_guidGenerator.Create()) + { + + MenuName = "通知删除", + PermissionCode = "system:notice:remove", + MenuType = MenuTypeEnum.Component, + OrderNum = 100, + ParentId = notice.Id, + IsDeleted = false + }; + entities.Add(noticeRemove); + + + //日志管理 MenuEntity log = new MenuEntity(_guidGenerator.Create()) { @@ -1135,7 +1204,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds IsShow = true, IsLink = false, MenuIcon = "log", - OrderNum = 93, + OrderNum = 92, ParentId = system.Id, IsDeleted = false }; diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/Properties/launchSettings.json b/Yi.Abp.Net8/src/Yi.Abp.Web/Properties/launchSettings.json index 44097413..8f58fa9b 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.Web/Properties/launchSettings.json +++ b/Yi.Abp.Net8/src/Yi.Abp.Web/Properties/launchSettings.json @@ -5,8 +5,8 @@ "launchBrowser": true, "launchUrl": "swagger", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development", - //"ASPNETCORE_ENVIRONMENT": "Staging" + //"ASPNETCORE_ENVIRONMENT": "Development", + "ASPNETCORE_ENVIRONMENT": "Staging" }, "dotnetRunMessages": true, "applicationUrl": "http://localhost:19001" diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/yi-abp-dev.db b/Yi.Abp.Net8/src/Yi.Abp.Web/yi-abp-dev.db index bb9541207e8b5050808fe36a6e963f88a7015e6f..13e994f3bd919130b5bda1930af3b72ffbe64f60 100644 GIT binary patch literal 438272 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�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 Dr9r;l literal 499712 zcmeFa3wRvIb)Y+g*I@7(z3354OB_;WNQ5e}-w(;M41$mZ2?Qw+phVdeRNYk#js?ts zGXsf~ZybTt%XVbR@k5d=KV(a>v#}&Qe&}Ue*<|lyH_3N%zkHi$zrFV+@f83n@%Lqu zyYc38_U_(O-7|xp;mn|kRn`LcK;mGg`*hW*zfPSxb*iUv__pzEiD$fgVV;&UYV4v| zJRbW{CKHRrEckan{Hy$!@TQ~k0e;6r@0-1~V%K`+A#}`p0HPoJsX3(p$E~AC8x(Gskbt2LA>|CP#;-Ml(~x`^HBz zJH+7~yZd`~jIkY=#a#BpBF{3OD`mYbFJvYTPGu&h$Hy~=CdUp8Pae(OI(js7HAsug z4rlM@J2H&B*?Bs*CR#l|LFeK8y|mySr-j{$t`9X3Iz&syTMCU7I4x!Kxv8uujnNV> z!MnPWe4%`yaT|pGzEb0~SUQkre$yh0x(#cumN}Boxr>DY&$*`#m+1UL)3#(XL%RmL z(${T?$Fe!bPZm$ifdS3X#Zun?JR^|K$l^71=HtDI^w3cJ5!3Iw{aIHKpoLRYrxtka zr@q?mtUbAbjvXuR=X1Qo!5W-wsSfkO0^@~=#rYkXY_7y-!v^951_CAMB>%!HA)(T` zrXYkw+RM_QSvKI=h2I@3h6ei(v{M zc0Mk&W$_198p*TPwm8lyxbdb2eTc$rR%$#y)@amXh>FRsyVYbTS_1|HugNoo z&O~}}F#gC5zNx^3>Sbqx*REP~2@Y<+V1f(Rr5A|Z%1_m^scCi~wf>L~AJ(1qIGycd`zJ(lI-~~S@8_&;% z-*?nnOZe0VY-TE3g2=cod|m4~&>`sB#*xq@hd>&lO

lhfu0E2(Bq*y4YeYiZ+a$ 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 mM9ZCT`%~0U-Bq(?T^M7D!C>tp5k9pMB2& From d2ae803ecc5c04885eb7b6de55a3cf2089d8eae7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= <454313500@qq.com> Date: Mon, 19 Feb 2024 18:32:44 +0800 Subject: [PATCH 14/24] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=E5=8A=A8=E7=94=BB=E5=88=87=E6=8D=A2=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Yi.Abp.Net8/src/Yi.Abp.Web/yi-abp-dev.db | Bin 438272 -> 450560 bytes .../src/layout/components/AppMain.vue | 20 +++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/yi-abp-dev.db b/Yi.Abp.Net8/src/Yi.Abp.Web/yi-abp-dev.db index 13e994f3bd919130b5bda1930af3b72ffbe64f60..89ecce23e5f4fa429c6b8b1be7ab5f736312a891 100644 GIT binary patch delta 589 zcmZ9HU1(Ba7{}lD^?i>X_4pofrOrmDF}zVk8N<4$d7756{9w31#%5mzg43vVQ8!zR zJXb<8>bZ)tpt>kVlQ;xjbictU=mUxff(8+zpd5X7rUlUh&;NP&|KRzUd)+(t(09S- zj3R_8M*fYRjo_d!ibBWVF~eefZ4*@ZH{RwS`Fp;0_v|$1hBZEJh?+FSKQ!OwTAO3N z&50vs^59Eg&XO7xE@M$^WQpF$noccRU3eXlTO@_oFIuQ_FGTw=MF`)945nA~dX|V- z+aOfmAk4ZuLJ5+HhUkD}*8av`wcW8G^RjtVSfrnXlQcs#M*%NOc}EyMl?G4~H5Z(6 zRiFgF9ri-A2YX!U>P+cqu@LFjX#?Gd$1(PW8lxY;s>%YJU0wgFGD-wvNPl4$JW^RN zNmO8k(14zavnLk8xN&0tjt+r%ifu8DCO7rT6eCzMSkvwE;hJma@R4#cU)onHmXG}@ zQzK*gD5mEywzjbRYxtTHUQ%edMdk0?Z^**cC7CK7tC&Q*#r@KG>7aeqp0!Qb{Niab z*>cK3kpv10s%_hz|6Z97O_|+ZFRn#9Tf4NY<&m+3noB4-b?CDI-^ zRb_P`ahCcGc2%Pt delta 330 zcmZoTAl>jlYJ#+&83O}DHW0&r`9vLKX)^}Bv{$S^Ar}5OAc;`^-~8YBKk~m}m)}^G z%g-N@nwOXd6nFFj5^5IB-}u|V@iT7!#?Qp(z%0$sJDoj%scri^Mix%S_Gy7k+ouIG z=dEKAV)SO1%EzL>#&m|!n{)P7Jr-HU?e%`Fjf`xXo^0Z_;?oz3FiP+STqm?ximEe8YpX?Ab6^(w>V`=0HXW#zMk(Gss%{z=uJl=BpMMqYt>6h=b>2CLT zVZF-1W*o~V?yd+CcDv0cHof5v+x6*&eyn=iTko

- + @@ -19,6 +19,24 @@ const tagsViewStore = useTagsViewStore() \ No newline at end of file diff --git a/Yi.Bbs.Vue3/src/views/signIn/Index.vue b/Yi.Bbs.Vue3/src/views/signIn/Index.vue index 6f7b51bf..80d65a0e 100644 --- a/Yi.Bbs.Vue3/src/views/signIn/Index.vue +++ b/Yi.Bbs.Vue3/src/views/signIn/Index.vue @@ -34,6 +34,7 @@ import { onMounted, ref, reactive, computed, nextTick, watch } from "vue"; import { signIn, signInRecord } from "@/apis/integralApi.js"; import useAuths from "@/hooks/useAuths"; + const { isLogin } = useAuths(); const number=ref(0); const signInData=ref([]); diff --git a/Yi.Bbs.Vue3/yarn.lock b/Yi.Bbs.Vue3/yarn.lock index 0559ec71..02a08f2f 100644 --- a/Yi.Bbs.Vue3/yarn.lock +++ b/Yi.Bbs.Vue3/yarn.lock @@ -286,6 +286,15 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" +"@lucky-canvas/vue@^0.1.11": + "integrity" "sha512-5vm0txSKRBtMgrE/HZEvw1joSTx9NTdAkc8tBp/aX0LxyhQtiTVBLsRgdYUK/OiURCL8bo+046BTGnV+Q4JFlg==" + "resolved" "https://registry.npmmirror.com/@lucky-canvas/vue/-/vue-0.1.11.tgz" + "version" "0.1.11" + dependencies: + "@vue/composition-api" "^1.0.0" + "lucky-canvas" "^1.7.23" + "vue-demi" "^0.7.4" + "@microsoft/signalr@^8.0.0": "integrity" "sha512-K/wS/VmzRWePCGqGh8MU8OWbS1Zvu7DG7LSJS62fBB8rJUXwwj4axQtqrAAwKGUZHQF6CuteuQR9xMsVpM2JNA==" "resolved" "https://registry.npmmirror.com/@microsoft/signalr/-/signalr-8.0.0.tgz" @@ -475,6 +484,11 @@ "@vue/compiler-dom" "3.2.47" "@vue/shared" "3.2.47" +"@vue/composition-api@^1.0.0", "@vue/composition-api@^1.0.0-beta.1": + "integrity" "sha512-M8jm9J/laYrYT02665HkZ5l2fWTK4dcVg3BsDHm/pfz+MjDYwX+9FUaZyGwEyXEDonQYRCo0H7aLgdklcIELjw==" + "resolved" "https://registry.npmmirror.com/@vue/composition-api/-/composition-api-1.7.2.tgz" + "version" "1.7.2" + "@vue/devtools-api@^6.4.5", "@vue/devtools-api@^6.5.0": "integrity" "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==" "resolved" "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.5.0.tgz" @@ -1499,6 +1513,11 @@ dependencies: "yallist" "^4.0.0" +"lucky-canvas@^1.7.23": + "integrity" "sha512-Ftz6qD+863bI7xijBmZg3dw3cNEc7odPr70EZQcGA14y3TgTAzH65HPosOCd6kKUlMwhntBaHMx3onoj9MtJRQ==" + "resolved" "https://registry.npmmirror.com/lucky-canvas/-/lucky-canvas-1.7.27.tgz" + "version" "1.7.27" + "magic-string@^0.25.7": "integrity" "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==" "resolved" "https://registry.npmmirror.com/magic-string/-/magic-string-0.25.9.tgz" @@ -2239,6 +2258,11 @@ "resolved" "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.13.11.tgz" "version" "0.13.11" +"vue-demi@^0.7.4": + "integrity" "sha512-eFSQSvbQdY7C9ujOzvM6tn7XxwLjn0VQDXQsiYBLBwf28Na+2nTQR4BBBcomhmdP6mmHlBKAwarq6a0BPG87hQ==" + "resolved" "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.7.5.tgz" + "version" "0.7.5" + "vue-router@^4.1.6": "integrity" "sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ==" "resolved" "https://registry.npmmirror.com/vue-router/-/vue-router-4.1.6.tgz" @@ -2246,7 +2270,7 @@ dependencies: "@vue/devtools-api" "^6.4.5" -"vue@^2.6.14 || ^3.2.0", "vue@^3.0.0-0 || ^2.6.0", "vue@^3.2.0", "vue@^3.2.23", "vue@^3.2.25", "vue@^3.2.47", "vue@2 || 3", "vue@3.2.47": +"vue@^2.0.0 || >=3.0.0-rc.0", "vue@^2.6.0 || >=3.0.0-rc.1", "vue@^2.6.14 || ^3.2.0", "vue@^3.0.0-0 || ^2.6.0", "vue@^3.2.0", "vue@^3.2.23", "vue@^3.2.25", "vue@^3.2.47", "vue@>= 2.5 < 2.7", "vue@2 || 3", "vue@3.2.47": "integrity" "sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==" "resolved" "https://registry.npmmirror.com/vue/-/vue-3.2.47.tgz" "version" "3.2.47"