From 4eecc0b4ce09f620f83109949e4c2b67b7f8ba90 Mon Sep 17 00:00:00 2001 From: tk Date: Wed, 4 Dec 2024 16:34:36 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=F0=9F=90=9B=20version=20lock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [skip ci] --- .drone/workflows/README.md | 1 + NetAdmin.sln | 10 ++++ scripts/sync.sln.files.csx | 14 ++++++ .../Services/RepositoryService.cs | 46 +++++++++++-------- .../Services/Sys/JobService.cs | 6 +-- .../Services/Sys/UserProfileService.cs | 2 +- .../Services/Sys/UserService.cs | 5 +- .../Sys/RequestLogCache.cs | 2 +- .../Extensions/ServiceCollectionExtensions.cs | 4 +- 9 files changed, 63 insertions(+), 27 deletions(-) create mode 100644 .drone/workflows/README.md diff --git a/.drone/workflows/README.md b/.drone/workflows/README.md new file mode 100644 index 00000000..3566608a --- /dev/null +++ b/.drone/workflows/README.md @@ -0,0 +1 @@ +drone workflows \ No newline at end of file diff --git a/NetAdmin.sln b/NetAdmin.sln index 4f366e3e..d8ce465e 100644 --- a/NetAdmin.sln +++ b/NetAdmin.sln @@ -3,6 +3,14 @@ Microsoft Visual Studio Solution File, Format Version 12.00 VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".drone", ".drone", "{3E408077-E73E-45CE-A53A-EF5F9DAE4B46}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{BB5BB244-E7D2-4368-8C18-C1C0ED1E12D1}" + ProjectSection(SolutionItems) = preProject + README.md = .drone/workflows/README.md + EndProjectSection +EndProject + Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{1129FE25-466B-4F4F-85FC-3752664245E1}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{3C6F049E-3EE8-4D66-9AFF-E8A369032487}" @@ -55,6 +63,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{BB0B 2.git.release.ps1 = scripts/2.git.release.ps1 3.git.recreate.branch.ps1 = scripts/3.git.recreate.branch.ps1 4.git.del.obsolete.tags.ps1 = scripts/4.git.del.obsolete.tags.ps1 + 5.git.update.submodule.ps1 = scripts/5.git.update.submodule.ps1 clean.ln.csx = scripts/clean.ln.csx code.clean.csx = scripts/code.clean.csx code.clean.ps1 = scripts/code.clean.ps1 @@ -235,5 +244,6 @@ Global {932520DF-D312-415A-A128-1117F8221D68} = {12AE5B4B-CB1A-498E-83B8-04E201E31D86} {C3DE6F6A-D1FC-4B8E-9033-980FBEBBD2BA} = {12AE5B4B-CB1A-498E-83B8-04E201E31D86} {3C6F049E-3EE8-4D66-9AFF-E8A369032487} = {1129FE25-466B-4F4F-85FC-3752664245E1} + {BB5BB244-E7D2-4368-8C18-C1C0ED1E12D1} = {3E408077-E73E-45CE-A53A-EF5F9DAE4B46} EndGlobalSection EndGlobal \ No newline at end of file diff --git a/scripts/sync.sln.files.csx b/scripts/sync.sln.files.csx index f0e256f2..fc7db233 100644 --- a/scripts/sync.sln.files.csx +++ b/scripts/sync.sln.files.csx @@ -45,6 +45,20 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ """ ); +content = Regex.Replace( + content, + "Project\\(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\"\\) = \"workflows\", \"workflows\", \"{BB5BB244-E7D2-4368-8C18-C1C0ED1E12D1}\"(?:.|\n)*?EndProject", + $$""" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{BB5BB244-E7D2-4368-8C18-C1C0ED1E12D1}" + ProjectSection(SolutionItems) = preProject +{{string.Join('\n', + Directory.GetFiles(@"../.drone/workflows", "*") + .Select(x=>$" {Path.GetFileName(x)} = .drone/workflows/{Path.GetFileName(x)}") + )}} + EndProject +""" +); + content = Regex.Replace( content, "Project\\(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\"\\) = \"scripts\", \"scripts\", \"{BB0B25C9-0901-4923-913F-00F9A6B352A5}\"(?:.|\n)*?EndProject", diff --git a/src/backend/NetAdmin/NetAdmin.Application/Services/RepositoryService.cs b/src/backend/NetAdmin/NetAdmin.Application/Services/RepositoryService.cs index 5984c6cb..9b165882 100644 --- a/src/backend/NetAdmin/NetAdmin.Application/Services/RepositoryService.cs +++ b/src/backend/NetAdmin/NetAdmin.Application/Services/RepositoryService.cs @@ -3,6 +3,7 @@ using Microsoft.Net.Http.Headers; using NetAdmin.Application.Repositories; using NetAdmin.Domain; using NetAdmin.Domain.DbMaps.Dependency; +using NetAdmin.Domain.DbMaps.Dependency.Fields; using NetAdmin.Domain.Dto.Dependency; namespace NetAdmin.Application.Services; @@ -64,17 +65,19 @@ public abstract class RepositoryService(BasicReposit /// 排除的属性 /// 查询表达式 /// 查询sql + /// 是否忽略版本锁 /// 更新行数 protected Task UpdateAsync( // TEntity newValue // - , IEnumerable includeFields // - , string[] excludeFields = null // + , List includeFields = null // + , List excludeFields = null // , Expression> whereExp = null // - , string whereSql = null) + , string whereSql = null // + , bool ignoreVersion = false) { // 默认匹配主键 whereExp ??= a => a.Id.Equals(newValue.Id); - var update = BuildUpdate(newValue, includeFields, excludeFields).Where(whereExp).Where(whereSql); + var update = BuildUpdate(newValue, includeFields, excludeFields, ignoreVersion).Where(whereExp).Where(whereSql); return update.ExecuteAffrowsAsync(); } @@ -87,17 +90,19 @@ public abstract class RepositoryService(BasicReposit /// 排除的属性 /// 查询表达式 /// 查询sql + /// 是否忽略版本锁 /// 更新后的实体列表 protected Task> UpdateReturnListAsync( // TEntity newValue // - , IEnumerable includeFields // - , string[] excludeFields = null // + , List includeFields = null // + , List excludeFields = null // , Expression> whereExp = null // - , string whereSql = null) + , string whereSql = null // + , bool ignoreVersion = false) { // 默认匹配主键 whereExp ??= a => a.Id.Equals(newValue.Id); - return BuildUpdate(newValue, includeFields, excludeFields).Where(whereExp).Where(whereSql).ExecuteUpdatedAsync(); + return BuildUpdate(newValue, includeFields, excludeFields, ignoreVersion).Where(whereExp).Where(whereSql).ExecuteUpdatedAsync(); } #endif @@ -127,17 +132,22 @@ public abstract class RepositoryService(BasicReposit return new FileStreamResult(stream, Chars.FLG_HTTP_HEADER_VALUE_APPLICATION_OCTET_STREAM); } - private IUpdate BuildUpdate( // - TEntity entity // - , IEnumerable includeFields // - , string[] excludeFields = null) + private IUpdate BuildUpdate(TEntity entity, List includeFields, List excludeFields, bool ignoreVersion) { - var updateExp = includeFields == null - ? Rpo.UpdateDiy.SetSource(entity) - : Rpo.UpdateDiy.SetDto(includeFields!.ToDictionary( - x => x, x => typeof(TEntity).GetProperty(x, BindingFlags.Public | BindingFlags.Instance)!.GetValue(entity))); - if (excludeFields != null) { - updateExp = updateExp.IgnoreColumns(excludeFields); + IUpdate updateExp; + if (includeFields.NullOrEmpty()) { + updateExp = Rpo.UpdateDiy.SetSource(entity); + if (!excludeFields.NullOrEmpty()) { + updateExp = updateExp.IgnoreColumns(excludeFields.ToArray()); + } + } + else { + updateExp = Rpo.UpdateDiy.SetDto(includeFields!.ToDictionary( + x => x + , x => typeof(TEntity).GetProperty(x, BindingFlags.Public | BindingFlags.Instance)!.GetValue(entity))); + if (!ignoreVersion && entity is IFieldVersion ver) { + updateExp = updateExp.Where($"{nameof(IFieldVersion.Version)} = {ver.Version}"); + } } return updateExp; diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/JobService.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/JobService.cs index 06f3b323..0e1a8d5c 100644 --- a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/JobService.cs +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/JobService.cs @@ -277,13 +277,13 @@ public sealed class JobService(BasicRepository rpo, IJobRecordSer { var ret1 = await UpdateAsync( // 运行中,运行时间超过超时设定;置为空闲状态 new Sys_Job { Status = JobStatues.Idle }, [nameof(Sys_Job.Status)], null - , a => a.Status == JobStatues.Running && a.LastExecTime < DateTime.Now.AddSeconds(-Numbers.SECS_TIMEOUT_JOB)) + , a => a.Status == JobStatues.Running && a.LastExecTime < DateTime.Now.AddSeconds(-Numbers.SECS_TIMEOUT_JOB), null, true) .ConfigureAwait(false); var ret2 = await UpdateAsync( // 空闲中,下次执行时间在当前时间减去超时时间以前;将下次执行时间调整到现在 new Sys_Job { NextExecTime = DateTime.Now, NextTimeId = DateTime.Now.TimeUnixUtc() } - , [nameof(Sys_Job.NextExecTime), nameof(Sys_Job.NextTimeId)], null - , a => a.Status == JobStatues.Idle && a.NextExecTime < DateTime.Now.AddSeconds(-Numbers.SECS_TIMEOUT_JOB)) + , [nameof(Sys_Job.NextExecTime), nameof(Sys_Job.NextTimeId)], null + , a => a.Status == JobStatues.Idle && a.NextExecTime < DateTime.Now.AddSeconds(-Numbers.SECS_TIMEOUT_JOB), null, true) .ConfigureAwait(false); return ret1 + ret2; } diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/UserProfileService.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/UserProfileService.cs index 1cfbca86..d9ab21cb 100644 --- a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/UserProfileService.cs +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/UserProfileService.cs @@ -160,7 +160,7 @@ public sealed class UserProfileService(BasicRepository rp req.AppConfig = BuildAppConfig(App.GetService().Roles.ToDictionary(x => x.Id, x => x.DashboardLayout)); } - return UpdateAsync(req, [nameof(req.AppConfig)], null, a => a.Id == UserToken.Id); + return UpdateAsync(req, [nameof(req.AppConfig)], null, a => a.Id == UserToken.Id, null, true); } private ISelect QueryInternal(QueryReq req) diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/UserService.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/UserService.cs index 592c04ec..c98a3161 100644 --- a/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/UserService.cs +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Application/Services/Sys/UserService.cs @@ -132,7 +132,7 @@ public sealed class UserService( ignoreCols.Add(nameof(Sys_User.Password)); } - _ = await UpdateAsync(entity, null, ignoreCols.ToArray()).ConfigureAwait(false); + _ = await UpdateAsync(entity, null, ignoreCols).ConfigureAwait(false); // 档案表 if (req.Profile != null) { @@ -453,7 +453,8 @@ public sealed class UserService( throw new NetAdminInvalidOperationException(Ln.请联系管理员激活账号); } - _ = await UpdateAsync(dbUser with { LastLoginTime = DateTime.Now }, [nameof(Sys_User.LastLoginTime)]).ConfigureAwait(false); + _ = await UpdateAsync(dbUser with { LastLoginTime = DateTime.Now }, [nameof(Sys_User.LastLoginTime)], ignoreVersion: true) + .ConfigureAwait(false); var tokenPayload = new Dictionary { { nameof(ContextUserToken), dbUser.Adapt() } }; diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/RequestLogCache.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/RequestLogCache.cs index 8ba12863..3ed1dc15 100644 --- a/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/RequestLogCache.cs +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Cache/Sys/RequestLogCache.cs @@ -18,7 +18,7 @@ public sealed class RequestLogCache(IDistributedCache cache, IRequestLogService public async Task CountAsync(QueryReq req) #else public Task CountAsync(QueryReq req) - #endif + #endif { #if !DEBUG var ret = await GetOrCreateAsync( // diff --git a/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Extensions/ServiceCollectionExtensions.cs b/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Extensions/ServiceCollectionExtensions.cs index 3015dcb2..030b3e43 100644 --- a/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Extensions/ServiceCollectionExtensions.cs +++ b/src/backend/NetAdmin/NetAdmin.SysComponent.Host/Extensions/ServiceCollectionExtensions.cs @@ -62,9 +62,9 @@ public static class ServiceCollectionExtensions /// /// 添加定时任务 /// - public static IServiceCollection AddSchedules(this IServiceCollection me) + public static IServiceCollection AddSchedules(this IServiceCollection me, bool force = false) { - return App.WebHostEnvironment.IsProduction() + return App.WebHostEnvironment.IsProduction() || force ? me.AddSchedule( // builder => builder // .AddJob(true, Triggers.PeriodSeconds(1).SetRunOnStart(true))