feat: 卖价/买价列表支持按需加载明细,缩短切换卡顿
All checks were successful
Build and Deploy / deploy (push) Successful in 1m6s
All checks were successful
Build and Deploy / deploy (push) Successful in 1m6s
列表接口增加 includeDetails,并新增单条 price/get,供编辑弹窗按需拉取完整矩阵。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
6faadcf2a1
commit
a164d8c837
@ -101,17 +101,20 @@ public partial class SalesProductService
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 一次性装配价格项、因子和明细,避免接口层 N+1 查询。
|
/// 一次性装配价格项、因子和明细,避免接口层 N+1 查询。
|
||||||
|
/// includeDetails=false 时跳过明细(列表页首屏),显著减小载荷。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task<List<SalesProductPriceListOutput>> GetPriceOutputsAsync(int salesProductId)
|
private async Task<List<SalesProductPriceListOutput>> GetPriceOutputsAsync(int salesProductId, bool includeDetails = true)
|
||||||
{
|
{
|
||||||
var prices = await SalesProductRepository.GetPricesAsync(salesProductId);
|
var prices = await SalesProductRepository.GetPricesAsync(salesProductId);
|
||||||
var priceIds = prices.Select(x => x.Id).ToArray();
|
var priceIds = prices.Select(x => x.Id).ToArray();
|
||||||
var factorMap = (await SalesProductRepository.GetPriceFactorsAsync(priceIds))
|
var factorMap = (await SalesProductRepository.GetPriceFactorsAsync(priceIds))
|
||||||
.GroupBy(x => x.PriceId)
|
.GroupBy(x => x.PriceId)
|
||||||
.ToDictionary(x => x.Key, x => x.OrderBy(item => item.SerialNumber).ToList());
|
.ToDictionary(x => x.Key, x => x.OrderBy(item => item.SerialNumber).ToList());
|
||||||
var detailMap = (await SalesProductRepository.GetPriceDetailsAsync(priceIds))
|
var detailMap = includeDetails
|
||||||
|
? (await SalesProductRepository.GetPriceDetailsAsync(priceIds))
|
||||||
.GroupBy(x => x.PriceId)
|
.GroupBy(x => x.PriceId)
|
||||||
.ToDictionary(x => x.Key, x => x.OrderBy(item => item.Id).ToList());
|
.ToDictionary(x => x.Key, x => x.OrderBy(item => item.Id).ToList())
|
||||||
|
: new Dictionary<int, List<SalesProductPriceDetail>>();
|
||||||
|
|
||||||
var auditUserNameMap = await UserDisplayNameResolver.ResolveManyAsync(
|
var auditUserNameMap = await UserDisplayNameResolver.ResolveManyAsync(
|
||||||
prices.SelectMany(x => new[] { x.CreateUserId, x.UpdateUserId }));
|
prices.SelectMany(x => new[] { x.CreateUserId, x.UpdateUserId }));
|
||||||
@ -128,7 +131,9 @@ public partial class SalesProductService
|
|||||||
Currency = price.Currency,
|
Currency = price.Currency,
|
||||||
ChargingCondition = price.ChargingCondition,
|
ChargingCondition = price.ChargingCondition,
|
||||||
Factors = factorMap.TryGetValue(price.Id, out var factors) ? factors.Select(MapPriceFactorOutput).ToList() : [],
|
Factors = factorMap.TryGetValue(price.Id, out var factors) ? factors.Select(MapPriceFactorOutput).ToList() : [],
|
||||||
Details = detailMap.TryGetValue(price.Id, out var details) ? details.Select(MapPriceDetailOutput).ToList() : [],
|
Details = includeDetails && detailMap.TryGetValue(price.Id, out var details)
|
||||||
|
? details.Select(MapPriceDetailOutput).ToList()
|
||||||
|
: [],
|
||||||
CreateTime = price.CreateTime,
|
CreateTime = price.CreateTime,
|
||||||
CreateBy = OmsRbacUserDisplayNameResolver.FormatUserId(price.CreateUserId, auditUserNameMap),
|
CreateBy = OmsRbacUserDisplayNameResolver.FormatUserId(price.CreateUserId, auditUserNameMap),
|
||||||
UpdateTime = OmsDocHelper.NullIfDefault(price.UpdateTime),
|
UpdateTime = OmsDocHelper.NullIfDefault(price.UpdateTime),
|
||||||
@ -136,6 +141,38 @@ public partial class SalesProductService
|
|||||||
}).ToList();
|
}).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 单条价格项(含因子+明细),供编辑弹窗按需加载。
|
||||||
|
/// </summary>
|
||||||
|
private async Task<SalesProductPriceListOutput> GetPriceOutputByIdAsync(int priceId)
|
||||||
|
{
|
||||||
|
var price = await GetPriceOrThrowAsync(priceId);
|
||||||
|
var priceIds = new[] { price.Id };
|
||||||
|
var factors = await SalesProductRepository.GetPriceFactorsAsync(priceIds);
|
||||||
|
var details = await SalesProductRepository.GetPriceDetailsAsync(priceIds);
|
||||||
|
var auditUserNameMap = await UserDisplayNameResolver.ResolveManyAsync(
|
||||||
|
[price.CreateUserId, price.UpdateUserId]);
|
||||||
|
|
||||||
|
return new SalesProductPriceListOutput
|
||||||
|
{
|
||||||
|
Id = price.Id,
|
||||||
|
SalesProductId = price.SalesProductId,
|
||||||
|
SerialNumber = price.SerialNumber,
|
||||||
|
Status = (byte)price.Status,
|
||||||
|
PriceName = price.PriceName,
|
||||||
|
CostItem = price.CostItem,
|
||||||
|
CostUnit = price.CostUnit,
|
||||||
|
Currency = price.Currency,
|
||||||
|
ChargingCondition = price.ChargingCondition,
|
||||||
|
Factors = factors.OrderBy(item => item.SerialNumber).Select(MapPriceFactorOutput).ToList(),
|
||||||
|
Details = details.OrderBy(item => item.Id).Select(MapPriceDetailOutput).ToList(),
|
||||||
|
CreateTime = price.CreateTime,
|
||||||
|
CreateBy = OmsRbacUserDisplayNameResolver.FormatUserId(price.CreateUserId, auditUserNameMap),
|
||||||
|
UpdateTime = OmsDocHelper.NullIfDefault(price.UpdateTime),
|
||||||
|
UpdateBy = OmsRbacUserDisplayNameResolver.FormatUserId(price.UpdateUserId, auditUserNameMap)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取排货方案,并补充服务渠道名称。
|
/// 获取排货方案,并补充服务渠道名称。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -169,17 +169,29 @@ public partial class SalesProductService : ApplicationService
|
|||||||
/// 查询销售产品价格项列表。
|
/// 查询销售产品价格项列表。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="salesProductId">入参:销售产品主键。</param>
|
/// <param name="salesProductId">入参:销售产品主键。</param>
|
||||||
|
/// <param name="includeDetails">是否返回价格明细矩阵;列表页建议 false。</param>
|
||||||
/// <returns>销售产品价格项列表结果。</returns>
|
/// <returns>销售产品价格项列表结果。</returns>
|
||||||
[HttpGet("/channel/sales-product/price/list")]
|
[HttpGet("/channel/sales-product/price/list")]
|
||||||
public async Task<OmsItemsResult<SalesProductPriceListOutput>> GetPriceListAsync([FromQuery] int salesProductId)
|
public async Task<OmsItemsResult<SalesProductPriceListOutput>> GetPriceListAsync(
|
||||||
|
[FromQuery] int salesProductId,
|
||||||
|
[FromQuery] bool includeDetails = true)
|
||||||
{
|
{
|
||||||
await GetProductOrThrowAsync(salesProductId);
|
await GetProductOrThrowAsync(salesProductId);
|
||||||
return new OmsItemsResult<SalesProductPriceListOutput>
|
return new OmsItemsResult<SalesProductPriceListOutput>
|
||||||
{
|
{
|
||||||
Items = await GetPriceOutputsAsync(salesProductId)
|
Items = await GetPriceOutputsAsync(salesProductId, includeDetails)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取单条销售产品价格项(含计费因子与价格明细)。
|
||||||
|
/// </summary>
|
||||||
|
[HttpGet("/channel/sales-product/price/get")]
|
||||||
|
public async Task<SalesProductPriceListOutput> GetPriceAsync([FromQuery] int id)
|
||||||
|
{
|
||||||
|
return await GetPriceOutputByIdAsync(id);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 新增销售产品价格项。
|
/// 新增销售产品价格项。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -146,17 +146,22 @@ public partial class ServiceChannelService
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 一次性装配买价项、因子和明细,避免接口层 N+1 查询。
|
/// 一次性装配买价项、因子和明细,避免接口层 N+1 查询。
|
||||||
|
/// includeDetails=false 时跳过明细(列表页首屏),显著减小载荷。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task<List<ServiceChannelPriceListOutput>> GetPriceOutputsAsync(int serviceChannelId)
|
private async Task<List<ServiceChannelPriceListOutput>> GetPriceOutputsAsync(
|
||||||
|
int serviceChannelId,
|
||||||
|
bool includeDetails = true)
|
||||||
{
|
{
|
||||||
var prices = await ServiceChannelRepository.GetPricesAsync(serviceChannelId);
|
var prices = await ServiceChannelRepository.GetPricesAsync(serviceChannelId);
|
||||||
var priceIds = prices.Select(x => x.Id).ToArray();
|
var priceIds = prices.Select(x => x.Id).ToArray();
|
||||||
var factorMap = (await ServiceChannelRepository.GetPriceFactorsAsync(priceIds))
|
var factorMap = (await ServiceChannelRepository.GetPriceFactorsAsync(priceIds))
|
||||||
.GroupBy(x => x.PriceId)
|
.GroupBy(x => x.PriceId)
|
||||||
.ToDictionary(x => x.Key, x => x.OrderBy(item => item.SerialNumber).ToList());
|
.ToDictionary(x => x.Key, x => x.OrderBy(item => item.SerialNumber).ToList());
|
||||||
var detailMap = (await ServiceChannelRepository.GetPriceDetailsAsync(priceIds))
|
var detailMap = includeDetails
|
||||||
|
? (await ServiceChannelRepository.GetPriceDetailsAsync(priceIds))
|
||||||
.GroupBy(x => x.PriceId)
|
.GroupBy(x => x.PriceId)
|
||||||
.ToDictionary(x => x.Key, x => x.OrderBy(item => item.Id).ToList());
|
.ToDictionary(x => x.Key, x => x.OrderBy(item => item.Id).ToList())
|
||||||
|
: new Dictionary<int, List<ServiceChannelPriceDetail>>();
|
||||||
|
|
||||||
return prices.Select(price => new ServiceChannelPriceListOutput
|
return prices.Select(price => new ServiceChannelPriceListOutput
|
||||||
{
|
{
|
||||||
@ -170,12 +175,42 @@ public partial class ServiceChannelService
|
|||||||
Currency = price.Currency,
|
Currency = price.Currency,
|
||||||
ChargingCondition = price.ChargingCondition,
|
ChargingCondition = price.ChargingCondition,
|
||||||
Factors = factorMap.TryGetValue(price.Id, out var factors) ? factors.Select(MapPriceFactorOutput).ToList() : [],
|
Factors = factorMap.TryGetValue(price.Id, out var factors) ? factors.Select(MapPriceFactorOutput).ToList() : [],
|
||||||
Details = detailMap.TryGetValue(price.Id, out var details) ? details.Select(MapPriceDetailOutput).ToList() : [],
|
Details = includeDetails && detailMap.TryGetValue(price.Id, out var details)
|
||||||
|
? details.Select(MapPriceDetailOutput).ToList()
|
||||||
|
: [],
|
||||||
CreateTime = price.CreateTime,
|
CreateTime = price.CreateTime,
|
||||||
UpdateTime = OmsDocHelper.NullIfDefault(price.UpdateTime)
|
UpdateTime = OmsDocHelper.NullIfDefault(price.UpdateTime)
|
||||||
}).ToList();
|
}).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 单条买价项(含因子+明细),供编辑弹窗按需加载。
|
||||||
|
/// </summary>
|
||||||
|
private async Task<ServiceChannelPriceListOutput> GetPriceOutputByIdAsync(int priceId)
|
||||||
|
{
|
||||||
|
var price = await GetPriceOrThrowAsync(priceId);
|
||||||
|
var priceIds = new[] { price.Id };
|
||||||
|
var factors = await ServiceChannelRepository.GetPriceFactorsAsync(priceIds);
|
||||||
|
var details = await ServiceChannelRepository.GetPriceDetailsAsync(priceIds);
|
||||||
|
|
||||||
|
return new ServiceChannelPriceListOutput
|
||||||
|
{
|
||||||
|
Id = price.Id,
|
||||||
|
ServiceChannelId = price.ServiceChannelId,
|
||||||
|
SerialNumber = price.SerialNumber,
|
||||||
|
Status = (byte)price.Status,
|
||||||
|
PriceName = price.PriceName,
|
||||||
|
CostItem = price.CostItem,
|
||||||
|
CostUnit = price.CostUnit,
|
||||||
|
Currency = price.Currency,
|
||||||
|
ChargingCondition = price.ChargingCondition,
|
||||||
|
Factors = factors.OrderBy(item => item.SerialNumber).Select(MapPriceFactorOutput).ToList(),
|
||||||
|
Details = details.OrderBy(item => item.Id).Select(MapPriceDetailOutput).ToList(),
|
||||||
|
CreateTime = price.CreateTime,
|
||||||
|
UpdateTime = OmsDocHelper.NullIfDefault(price.UpdateTime)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取指定类型的发布记录。
|
/// 获取指定类型的发布记录。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -215,17 +215,29 @@ public partial class ServiceChannelService : ApplicationService
|
|||||||
/// 查询服务渠道价格项列表。
|
/// 查询服务渠道价格项列表。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="serviceChannelId">入参:serviceChannelId。</param>
|
/// <param name="serviceChannelId">入参:serviceChannelId。</param>
|
||||||
|
/// <param name="includeDetails">是否返回价格明细矩阵;列表页建议 false。</param>
|
||||||
/// <returns>服务渠道价格项列表结果。</returns>
|
/// <returns>服务渠道价格项列表结果。</returns>
|
||||||
[HttpGet("/channel/service-channel/price/list")]
|
[HttpGet("/channel/service-channel/price/list")]
|
||||||
public async Task<OmsItemsResult<ServiceChannelPriceListOutput>> GetPriceListAsync([FromQuery] int serviceChannelId)
|
public async Task<OmsItemsResult<ServiceChannelPriceListOutput>> GetPriceListAsync(
|
||||||
|
[FromQuery] int serviceChannelId,
|
||||||
|
[FromQuery] bool includeDetails = true)
|
||||||
{
|
{
|
||||||
await GetEntityOrThrowAsync(serviceChannelId);
|
await GetEntityOrThrowAsync(serviceChannelId);
|
||||||
return new OmsItemsResult<ServiceChannelPriceListOutput>
|
return new OmsItemsResult<ServiceChannelPriceListOutput>
|
||||||
{
|
{
|
||||||
Items = await GetPriceOutputsAsync(serviceChannelId)
|
Items = await GetPriceOutputsAsync(serviceChannelId, includeDetails)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取单条服务渠道价格项(含计费因子与价格明细)。
|
||||||
|
/// </summary>
|
||||||
|
[HttpGet("/channel/service-channel/price/get")]
|
||||||
|
public async Task<ServiceChannelPriceListOutput> GetPriceAsync([FromQuery] int id)
|
||||||
|
{
|
||||||
|
return await GetPriceOutputByIdAsync(id);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 新增服务渠道价格项。
|
/// 新增服务渠道价格项。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user