diff --git a/src/Oms.Application/Dtos/Channels/SalesProductPublishListInput.cs b/src/Oms.Application/Dtos/Channels/SalesProductPublishListInput.cs index a13648b..f50dc74 100644 --- a/src/Oms.Application/Dtos/Channels/SalesProductPublishListInput.cs +++ b/src/Oms.Application/Dtos/Channels/SalesProductPublishListInput.cs @@ -19,4 +19,9 @@ public class SalesProductPublishListInput /// 每页条数。 /// public int PageSize { get; set; } + + /// + /// 是否返回发布快照正文。版本头只展示版本号和时间时传 false,避免传输并反序列化整份价格矩阵。 + /// + public bool IncludeContent { get; set; } = true; } diff --git a/src/Oms.Application/Dtos/Channels/ServiceChannelOptionOutput.cs b/src/Oms.Application/Dtos/Channels/ServiceChannelOptionOutput.cs new file mode 100644 index 0000000..1bb6205 --- /dev/null +++ b/src/Oms.Application/Dtos/Channels/ServiceChannelOptionOutput.cs @@ -0,0 +1,22 @@ +namespace Oms.Application.Dtos.Channels; + +/// +/// 服务渠道下拉项。只含展示所需字段,不分页。 +/// +public class ServiceChannelOptionOutput +{ + /// + /// 主键。 + /// + public int Id { get; set; } + + /// + /// 分组名称。 + /// + public string? GroupName { get; set; } + + /// + /// 渠道名称。 + /// + public string ChannelName { get; set; } = string.Empty; +} diff --git a/src/Oms.Application/Services/Channels/SalesProductService.Helpers.cs b/src/Oms.Application/Services/Channels/SalesProductService.Helpers.cs index 7e2de52..ff29681 100644 --- a/src/Oms.Application/Services/Channels/SalesProductService.Helpers.cs +++ b/src/Oms.Application/Services/Channels/SalesProductService.Helpers.cs @@ -213,32 +213,65 @@ public partial class SalesProductService private async Task> GetPublishListAsync(SalesProductPublishListInput input, string operatorType) { await GetProductOrThrowAsync(input.SalesProductId); + // 版本列表不传正文时一次返回全部版本头,页面没有分页。 + if (!input.IncludeContent) + { + var headers = await SalesProductRepository.GetAllPublishRecordHeadersAsync(input.SalesProductId, operatorType); + return new OmsPageResult + { + Items = headers.Select(entity => MapPublishRecordOutput(entity, includeContent: false)).ToList(), + Total = headers.Count + }; + } + var pageIndex = OmsDocHelper.NormalizePage(input.Page); var pageSize = OmsDocHelper.NormalizePageSize(input.PageSize); var entities = await SalesProductRepository.GetPublishRecordsAsync(input.SalesProductId, operatorType, pageIndex, pageSize); var total = await SalesProductRepository.CountPublishRecordsAsync(input.SalesProductId, operatorType); return new OmsPageResult { - Items = entities.Select(entity => new SalesProductPublishRecordOutput - { - Id = entity.Id, - SalesProductId = entity.SalesProductId, - Version = entity.Version, - OperatorType = entity.OperatorType, - Status = EnumDisplayNames.Of(entity.Status), - PublishUser = entity.PublishUser, - PublishTime = entity.PublishTime, - Description = entity.Description, - AiAnalysisReport = entity.AiAnalysisReport, - Content = operatorType == PriceOperatorType - ? OmsDocHelper.ParseSalesProductPricePublishContentForApi(entity.Content) - : OmsDocHelper.ToSnapshotApiContent(OmsDocHelper.DeserializeRulesSnapshot(entity.Content)), - CreateTime = entity.CreateTime - }).ToList(), + Items = entities.Select(entity => MapPublishRecordOutput(entity, includeContent: true)).ToList(), Total = total }; } + private SalesProductPublishRecordOutput MapPublishRecordOutput(SalesProductPublishRecord entity, bool includeContent) + { + var operatorType = entity.OperatorType; + return new SalesProductPublishRecordOutput + { + Id = entity.Id, + SalesProductId = entity.SalesProductId, + Version = entity.Version, + OperatorType = operatorType, + Status = EnumDisplayNames.Of(entity.Status), + PublishUser = entity.PublishUser, + PublishTime = entity.PublishTime, + Description = entity.Description, + AiAnalysisReport = includeContent ? entity.AiAnalysisReport : null, + Content = !includeContent + ? null + : string.Equals(operatorType, PriceOperatorType, StringComparison.OrdinalIgnoreCase) + ? OmsDocHelper.ParseSalesProductPricePublishContentForApi(entity.Content) + : OmsDocHelper.ToSnapshotApiContent(OmsDocHelper.DeserializeRulesSnapshot(entity.Content)), + CreateTime = entity.CreateTime + }; + } + + /// + /// 单条发布记录(含快照正文),供版本详情按需加载。 + /// + private async Task GetPublishRecordCoreAsync(int id) + { + var entity = await SalesProductRepository.GetPublishRecordByIdAsync(id); + if (entity == null) + { + throw new Fake.Application.BusinessException("发布记录不存在"); + } + + return MapPublishRecordOutput(entity, includeContent: true); + } + /// /// 组装规则发布快照(不落库),含黑名单/偏远/计重/进位明细。 /// diff --git a/src/Oms.Application/Services/Channels/SalesProductService.cs b/src/Oms.Application/Services/Channels/SalesProductService.cs index 5647829..e8e7fd1 100644 --- a/src/Oms.Application/Services/Channels/SalesProductService.cs +++ b/src/Oms.Application/Services/Channels/SalesProductService.cs @@ -386,6 +386,15 @@ public partial class SalesProductService : ApplicationService return GetPublishListAsync(input, RulesOperatorType); } + /// + /// 查询单条发布记录,含快照正文。 + /// + [HttpGet("/channel/sales-product/publish/get")] + public Task GetPublishRecordAsync([FromQuery] int id) + { + return GetPublishRecordCoreAsync(id); + } + /// /// 预览即将发布的快照 JSON(不落库),用于核对黑名单/计重等是否已固化进 Content。 /// diff --git a/src/Oms.Application/Services/Channels/ServiceChannelService.cs b/src/Oms.Application/Services/Channels/ServiceChannelService.cs index fdad653..a3b535d 100644 --- a/src/Oms.Application/Services/Channels/ServiceChannelService.cs +++ b/src/Oms.Application/Services/Channels/ServiceChannelService.cs @@ -25,6 +25,22 @@ public partial class ServiceChannelService : ApplicationService private OmsRbacUserDisplayNameResolver UserDisplayNameResolver => LazyServiceProvider.GetRequiredService(); + /// + /// 服务渠道下拉。返回全部渠道的名称,不分页。 + /// + [HttpGet("/channel/service-channel/options")] + public async Task> GetOptionsAsync() + { + var channels = await ServiceChannelRepository.GetOptionRowsAsync(); + var groupMap = await GetGroupMapAsync(); + return channels.Select(channel => new ServiceChannelOptionOutput + { + Id = channel.Id, + ChannelName = channel.ChannelName, + GroupName = channel.GroupId.HasValue && groupMap.TryGetValue(channel.GroupId.Value, out var name) ? name : null + }).ToList(); + } + /// /// 查询服务渠道列表。 /// diff --git a/src/Oms.Domain/ChannelsAggregate/Repositories/ISalesProductRepository.cs b/src/Oms.Domain/ChannelsAggregate/Repositories/ISalesProductRepository.cs index 5ba942a..e72dc7f 100644 --- a/src/Oms.Domain/ChannelsAggregate/Repositories/ISalesProductRepository.cs +++ b/src/Oms.Domain/ChannelsAggregate/Repositories/ISalesProductRepository.cs @@ -50,6 +50,16 @@ public interface ISalesProductRepository : IRepository Task> GetPublishRecordsAsync(int salesProductId, string operatorType, int pageIndex, int pageSize, CancellationToken cancellationToken = default); + /// + /// 发布记录头(不含 Content / AI 报告),供版本号展示。 + /// + Task> GetPublishRecordHeadersAsync(int salesProductId, string operatorType, int pageIndex, int pageSize, CancellationToken cancellationToken = default); + + /// + /// 某产品某类发布记录的全部版本头,不含快照正文。 + /// + Task> GetAllPublishRecordHeadersAsync(int salesProductId, string operatorType, CancellationToken cancellationToken = default); + Task CountPublishRecordsAsync(int salesProductId, string operatorType, CancellationToken cancellationToken = default); Task InsertPublishRecordAsync(SalesProductPublishRecord record, CancellationToken cancellationToken = default); diff --git a/src/Oms.Domain/ChannelsAggregate/Repositories/IServiceChannelRepository.cs b/src/Oms.Domain/ChannelsAggregate/Repositories/IServiceChannelRepository.cs index bb090e5..15fb005 100644 --- a/src/Oms.Domain/ChannelsAggregate/Repositories/IServiceChannelRepository.cs +++ b/src/Oms.Domain/ChannelsAggregate/Repositories/IServiceChannelRepository.cs @@ -15,6 +15,11 @@ public interface IServiceChannelRepository : IRepository Task> GetGroupsAsync(CancellationToken cancellationToken = default); + /// + /// 下拉选项:仅主键、分组、渠道名,不分页。 + /// + Task> GetOptionRowsAsync(CancellationToken cancellationToken = default); + Task> GetPricesAsync(int serviceChannelId, CancellationToken cancellationToken = default); Task GetPriceByIdAsync(int id, CancellationToken cancellationToken = default); diff --git a/src/Oms.SqlSugarCore/Channels/SalesProductRepository.cs b/src/Oms.SqlSugarCore/Channels/SalesProductRepository.cs index fdc3af9..6fcf92a 100644 --- a/src/Oms.SqlSugarCore/Channels/SalesProductRepository.cs +++ b/src/Oms.SqlSugarCore/Channels/SalesProductRepository.cs @@ -186,6 +186,48 @@ public class SalesProductRepository : OmsSqlSugarRepository, ISale .ToPageListAsync(pageIndex, pageSize, cancellationToken); } + public async Task> GetPublishRecordHeadersAsync(int salesProductId, string operatorType, int pageIndex, int pageSize, CancellationToken cancellationToken = default) + { + var db = await GetDbContextAsync(cancellationToken); + return await db.Queryable() + .Where(x => x.SalesProductId == salesProductId && x.OperatorType == operatorType) + .OrderBy(x => x.PublishTime, SqlSugar.OrderByType.Desc) + .Select(x => new SalesProductPublishRecord + { + Id = x.Id, + SalesProductId = x.SalesProductId, + Version = x.Version, + OperatorType = x.OperatorType, + Status = x.Status, + PublishUser = x.PublishUser, + PublishTime = x.PublishTime, + Description = x.Description, + CreateTime = x.CreateTime + }) + .ToPageListAsync(pageIndex, pageSize, cancellationToken); + } + + public async Task> GetAllPublishRecordHeadersAsync(int salesProductId, string operatorType, CancellationToken cancellationToken = default) + { + var db = await GetDbContextAsync(cancellationToken); + return await db.Queryable() + .Where(x => x.SalesProductId == salesProductId && x.OperatorType == operatorType) + .OrderBy(x => x.PublishTime, SqlSugar.OrderByType.Desc) + .Select(x => new SalesProductPublishRecord + { + Id = x.Id, + SalesProductId = x.SalesProductId, + Version = x.Version, + OperatorType = x.OperatorType, + Status = x.Status, + PublishUser = x.PublishUser, + PublishTime = x.PublishTime, + Description = x.Description, + CreateTime = x.CreateTime + }) + .ToListAsync(cancellationToken); + } + public async Task CountPublishRecordsAsync(int salesProductId, string operatorType, CancellationToken cancellationToken = default) { var db = await GetDbContextAsync(cancellationToken); diff --git a/src/Oms.SqlSugarCore/Channels/ServiceChannelRepository.cs b/src/Oms.SqlSugarCore/Channels/ServiceChannelRepository.cs index c0c6e49..f7f9c4a 100644 --- a/src/Oms.SqlSugarCore/Channels/ServiceChannelRepository.cs +++ b/src/Oms.SqlSugarCore/Channels/ServiceChannelRepository.cs @@ -35,6 +35,20 @@ public class ServiceChannelRepository : OmsSqlSugarRepository, I return await db.Queryable().ToListAsync(cancellationToken); } + public async Task> GetOptionRowsAsync(CancellationToken cancellationToken = default) + { + var db = await GetDbContextAsync(cancellationToken); + return await db.Queryable() + .OrderBy(x => x.Id) + .Select(x => new ServiceChannel + { + Id = x.Id, + GroupId = x.GroupId, + ChannelName = x.ChannelName + }) + .ToListAsync(cancellationToken); + } + public async Task> GetPricesAsync(int serviceChannelId, CancellationToken cancellationToken = default) { var db = await GetDbContextAsync(cancellationToken);