From 623db4ffdba3a6a71cb1170cddcae781efdb1ff4 Mon Sep 17 00:00:00 2001 From: zzh <1368735060@qq.com> Date: Tue, 22 Sep 2026 19:00:12 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=9C=8D=E5=8A=A1=E6=B8=A0=E9=81=93?= =?UTF-8?q?=E5=88=86=E7=BB=84=E8=BD=AF=E5=88=A0=E5=90=8C=E5=90=8D=E5=8F=AF?= =?UTF-8?q?=E6=81=A2=E5=A4=8D=EF=BC=8C=E5=B9=B6=E4=BF=AE=E6=AD=A3=20COS=20?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E5=9F=9F=E5=90=8D=E7=AD=BE=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 同名软删分组创建时恢复记录,更新时释放唯一键冲突;COS 自定义 CDN 域名关闭 signHost,并补充常见图片 Content-Type。 Co-authored-by: Cursor --- .../Channels/ServiceChannelService.Helpers.cs | 15 +++++++++++ .../Channels/ServiceChannelService.cs | 18 +++++++++++-- .../Services/Storage/FileStorageService.cs | 26 +++++++++++++++++++ .../Storage/TencentCosFileStorage.cs | 5 +++- .../IServiceChannelGroupRepository.cs | 5 ++++ .../Channels/ServiceChannelGroupRepository.cs | 14 ++++++++++ 6 files changed, 80 insertions(+), 3 deletions(-) diff --git a/src/Oms.Application/Services/Channels/ServiceChannelService.Helpers.cs b/src/Oms.Application/Services/Channels/ServiceChannelService.Helpers.cs index af3ea5f..2a00598 100644 --- a/src/Oms.Application/Services/Channels/ServiceChannelService.Helpers.cs +++ b/src/Oms.Application/Services/Channels/ServiceChannelService.Helpers.cs @@ -64,6 +64,21 @@ public partial class ServiceChannelService } } + /// + /// 更新时若目标名称被软删记录占用,则改名释放唯一键,避免 uk_scg_name 冲突。 + /// + private async Task FreeSoftDeletedNameIfNeededAsync(string name, int currentId) + { + var conflict = await ServiceChannelGroupRepository.GetByNameIncludingDeletedAsync(name); + if (conflict == null || !conflict.IsDeleted || conflict.Id == currentId) + { + return; + } + + conflict.Name = $"{name}__deleted_{conflict.Id}"; + await ServiceChannelGroupRepository.UpdateAsync(conflict); + } + /// /// 校验渠道编码唯一性。 /// diff --git a/src/Oms.Application/Services/Channels/ServiceChannelService.cs b/src/Oms.Application/Services/Channels/ServiceChannelService.cs index dea8476..7188468 100644 --- a/src/Oms.Application/Services/Channels/ServiceChannelService.cs +++ b/src/Oms.Application/Services/Channels/ServiceChannelService.cs @@ -128,9 +128,21 @@ public partial class ServiceChannelService : ApplicationService public async Task CreateGroupAsync(ServiceChannelGroupSaveInput input) { await ValidateGroupInputAsync(input, null); + var name = input.Name.Trim(); + var deleted = await ServiceChannelGroupRepository.GetByNameIncludingDeletedAsync(name); + if (deleted != null && deleted.IsDeleted) + { + deleted.IsDeleted = false; + deleted.Name = name; + deleted.AppId = input.AppId; + deleted.ApiServiceProviderId = input.ApiServiceProviderId; + await ServiceChannelGroupRepository.UpdateAsync(deleted); + return; + } + await ServiceChannelGroupRepository.InsertAsync(new ServiceChannelGroup { - Name = input.Name.Trim(), + Name = name, AppId = input.AppId, ApiServiceProviderId = input.ApiServiceProviderId }); @@ -146,7 +158,9 @@ public partial class ServiceChannelService : ApplicationService { var group = await GetGroupOrThrowAsync(input.Id); await ValidateGroupInputAsync(input, group.Id); - group.Name = input.Name.Trim(); + var name = input.Name.Trim(); + await FreeSoftDeletedNameIfNeededAsync(name, group.Id); + group.Name = name; group.AppId = input.AppId; group.ApiServiceProviderId = input.ApiServiceProviderId; await ServiceChannelGroupRepository.UpdateAsync(group); diff --git a/src/Oms.Application/Services/Storage/FileStorageService.cs b/src/Oms.Application/Services/Storage/FileStorageService.cs index 9223b0e..1c256d0 100644 --- a/src/Oms.Application/Services/Storage/FileStorageService.cs +++ b/src/Oms.Application/Services/Storage/FileStorageService.cs @@ -245,6 +245,32 @@ public class FileStorageService : ApplicationService return "text/html; charset=utf-8"; } + if (path.EndsWith(".png", StringComparison.OrdinalIgnoreCase)) + { + return "image/png"; + } + + if (path.EndsWith(".webp", StringComparison.OrdinalIgnoreCase)) + { + return "image/webp"; + } + + if (path.EndsWith(".gif", StringComparison.OrdinalIgnoreCase)) + { + return "image/gif"; + } + + if (path.EndsWith(".bmp", StringComparison.OrdinalIgnoreCase)) + { + return "image/bmp"; + } + + if (path.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase) + || path.EndsWith(".jpeg", StringComparison.OrdinalIgnoreCase)) + { + return "image/jpeg"; + } + return "application/octet-stream"; } diff --git a/src/Oms.Application/Storage/TencentCosFileStorage.cs b/src/Oms.Application/Storage/TencentCosFileStorage.cs index 9f152d7..017c170 100644 --- a/src/Oms.Application/Storage/TencentCosFileStorage.cs +++ b/src/Oms.Application/Storage/TencentCosFileStorage.cs @@ -365,8 +365,11 @@ public sealed class TencentCosFileStorage : IFileStorage, IDisposable if (!string.IsNullOrWhiteSpace(_customHost) && !_customHost.EndsWith(".myqcloud.com", StringComparison.OrdinalIgnoreCase)) { + // 自定义 CDN 域名:URL 走 cos.ideship.com,但不要把 Host 签进 q-header-list。 + // signHost=true 时浏览器直开签名链常因 CDN 回源 Host 不一致而 403(img naturalWidth=0), + // 对象其实在桶里(/file-storage/stream 可读)。 preSign.host = _customHost; - preSign.signHost = true; + preSign.signHost = false; } } diff --git a/src/Oms.Domain/ChannelsAggregate/Repositories/IServiceChannelGroupRepository.cs b/src/Oms.Domain/ChannelsAggregate/Repositories/IServiceChannelGroupRepository.cs index 749f4a0..021cd8f 100644 --- a/src/Oms.Domain/ChannelsAggregate/Repositories/IServiceChannelGroupRepository.cs +++ b/src/Oms.Domain/ChannelsAggregate/Repositories/IServiceChannelGroupRepository.cs @@ -6,4 +6,9 @@ namespace Oms.Domain.ChannelsAggregate.Repositories; public interface IServiceChannelGroupRepository : IRepository { Task GetByNameAsync(string name, CancellationToken cancellationToken = default); + + /// + /// 按名称查询分组(含软删除),用于唯一名冲突时恢复或释放名称。 + /// + Task GetByNameIncludingDeletedAsync(string name, CancellationToken cancellationToken = default); } diff --git a/src/Oms.SqlSugarCore/Channels/ServiceChannelGroupRepository.cs b/src/Oms.SqlSugarCore/Channels/ServiceChannelGroupRepository.cs index 22c5b78..cf6ddd2 100644 --- a/src/Oms.SqlSugarCore/Channels/ServiceChannelGroupRepository.cs +++ b/src/Oms.SqlSugarCore/Channels/ServiceChannelGroupRepository.cs @@ -2,6 +2,7 @@ using Fake.DependencyInjection; using Oms.Domain.ChannelsAggregate.Entities; using Oms.Domain.ChannelsAggregate.Repositories; using Oms.SqlSugarCore.Repositories; +using SqlSugar; namespace Oms.SqlSugarCore.Channels; @@ -11,4 +12,17 @@ public class ServiceChannelGroupRepository : OmsSqlSugarRepository x.Name == name, cancellationToken); } + + public async Task GetByNameIncludingDeletedAsync( + string name, + CancellationToken cancellationToken = default) + { + var db = await GetDbContextAsync(cancellationToken); + var rows = await db.Queryable() + .ClearFilter() + .Where(x => x.Name == name) + .Take(1) + .ToListAsync(cancellationToken); + return rows.FirstOrDefault(); + } }