213 lines
9.4 KiB
C#
213 lines
9.4 KiB
C#
using Fake.DependencyInjection;
|
||
using Oms.Domain.ChannelsAggregate.Entities;
|
||
using Oms.Domain.ChannelsAggregate.Repositories;
|
||
using Oms.Domain.Shared.Enums;
|
||
using Oms.SqlSugarCore.Repositories;
|
||
|
||
namespace Oms.SqlSugarCore.Channels;
|
||
|
||
public class ServiceChannelRepository : OmsSqlSugarRepository<ServiceChannel>, IServiceChannelRepository, IScopedDependency
|
||
{
|
||
public Task<ServiceChannel?> GetByChannelCodeAsync(string channelCode, CancellationToken cancellationToken = default)
|
||
{
|
||
return FirstOrDefaultAsync(x => x.ChannelCode == channelCode, cancellationToken);
|
||
}
|
||
|
||
public Task<bool> HasChannelCodeAsync(string channelCode, CancellationToken cancellationToken = default)
|
||
{
|
||
return AnyAsync(x => x.ChannelCode == channelCode, cancellationToken);
|
||
}
|
||
|
||
public async Task<List<ServiceChannelGroup>> GetGroupsAsync(CancellationToken cancellationToken = default)
|
||
{
|
||
var db = await GetDbContextAsync(cancellationToken);
|
||
return await db.Queryable<ServiceChannelGroup>().ToListAsync(cancellationToken);
|
||
}
|
||
|
||
public async Task<List<ServiceChannelPrice>> GetPricesAsync(int serviceChannelId, CancellationToken cancellationToken = default)
|
||
{
|
||
var db = await GetDbContextAsync(cancellationToken);
|
||
return await db.Queryable<ServiceChannelPrice>()
|
||
.Where(x => x.ServiceChannelId == serviceChannelId)
|
||
.OrderBy(x => x.SerialNumber)
|
||
.ToListAsync(cancellationToken);
|
||
}
|
||
|
||
public async Task<ServiceChannelPrice?> GetPriceByIdAsync(int id, CancellationToken cancellationToken = default)
|
||
{
|
||
var db = await GetDbContextAsync(cancellationToken);
|
||
return await db.Queryable<ServiceChannelPrice>()
|
||
.FirstAsync(x => x.Id == id, cancellationToken);
|
||
}
|
||
|
||
public async Task<List<ServiceChannelPriceFactor>> GetPriceFactorsAsync(IEnumerable<int> priceIds, CancellationToken cancellationToken = default)
|
||
{
|
||
var ids = priceIds.Distinct().ToArray();
|
||
if (ids.Length == 0) return [];
|
||
var db = await GetDbContextAsync(cancellationToken);
|
||
return await db.Queryable<ServiceChannelPriceFactor>()
|
||
.Where(x => ids.Contains(x.PriceId))
|
||
.OrderBy(x => x.SerialNumber)
|
||
.ToListAsync(cancellationToken);
|
||
}
|
||
|
||
public async Task<List<ServiceChannelPriceDetail>> GetPriceDetailsAsync(IEnumerable<int> priceIds, CancellationToken cancellationToken = default)
|
||
{
|
||
var ids = priceIds.Distinct().ToArray();
|
||
if (ids.Length == 0) return [];
|
||
var db = await GetDbContextAsync(cancellationToken);
|
||
return await db.Queryable<ServiceChannelPriceDetail>()
|
||
.Where(x => ids.Contains(x.PriceId))
|
||
.ToListAsync(cancellationToken);
|
||
}
|
||
|
||
public async Task<ServiceChannelPrice> InsertPriceAsync(ServiceChannelPrice price, IEnumerable<ServiceChannelPriceFactor> factors, IEnumerable<ServiceChannelPriceDetail> details, CancellationToken cancellationToken = default)
|
||
{
|
||
var db = await GetDbContextAsync(cancellationToken);
|
||
price.Id = 0;
|
||
var savedPrice = await db.Insertable(price).ExecuteReturnEntityAsync();
|
||
await InsertPriceChildrenAsync(db, savedPrice.Id, factors, details, cancellationToken);
|
||
return savedPrice;
|
||
}
|
||
|
||
public async Task UpdatePriceAsync(ServiceChannelPrice price, IEnumerable<ServiceChannelPriceFactor> factors, IEnumerable<ServiceChannelPriceDetail> details, CancellationToken cancellationToken = default)
|
||
{
|
||
var db = await GetDbContextAsync(cancellationToken);
|
||
await db.Updateable(price).ExecuteCommandAsync(cancellationToken);
|
||
await db.Deleteable<ServiceChannelPriceFactor>()
|
||
.Where(x => x.PriceId == price.Id)
|
||
.ExecuteCommandAsync(cancellationToken);
|
||
await db.Deleteable<ServiceChannelPriceDetail>()
|
||
.Where(x => x.PriceId == price.Id)
|
||
.ExecuteCommandAsync(cancellationToken);
|
||
await InsertPriceChildrenAsync(db, price.Id, factors, details, cancellationToken);
|
||
}
|
||
|
||
public async Task DeletePriceAsync(int id, CancellationToken cancellationToken = default)
|
||
{
|
||
var db = await GetDbContextAsync(cancellationToken);
|
||
await db.Deleteable<ServiceChannelPrice>()
|
||
.Where(x => x.Id == id)
|
||
.ExecuteCommandAsync(cancellationToken);
|
||
await db.Deleteable<ServiceChannelPriceFactor>()
|
||
.Where(x => x.PriceId == id)
|
||
.ExecuteCommandAsync(cancellationToken);
|
||
await db.Deleteable<ServiceChannelPriceDetail>()
|
||
.Where(x => x.PriceId == id)
|
||
.ExecuteCommandAsync(cancellationToken);
|
||
}
|
||
|
||
public async Task UpdatePriceStatusAsync(int id, EnableStatus status, CancellationToken cancellationToken = default)
|
||
{
|
||
var db = await GetDbContextAsync(cancellationToken);
|
||
await db.Updateable<ServiceChannelPrice>()
|
||
.SetColumns(x => x.Status, status)
|
||
.Where(x => x.Id == id)
|
||
.ExecuteCommandAsync(cancellationToken);
|
||
}
|
||
|
||
public async Task ReplacePricesAsync(int serviceChannelId, IEnumerable<ServiceChannelPrice> prices, IEnumerable<ServiceChannelPriceFactor> factors, IEnumerable<ServiceChannelPriceDetail> details, CancellationToken cancellationToken = default)
|
||
{
|
||
var db = await GetDbContextAsync(cancellationToken);
|
||
var oldPrices = await db.Queryable<ServiceChannelPrice>()
|
||
.Where(x => x.ServiceChannelId == serviceChannelId)
|
||
.ToListAsync(cancellationToken);
|
||
var oldPriceIds = oldPrices.Select(x => x.Id).ToArray();
|
||
|
||
if (oldPriceIds.Length > 0)
|
||
{
|
||
// 批量保存时先整棵旧买价树软删,再写入新的快照数据。
|
||
await db.Deleteable<ServiceChannelPrice>().Where(x => oldPriceIds.Contains(x.Id)).ExecuteCommandAsync(cancellationToken);
|
||
await db.Deleteable<ServiceChannelPriceFactor>().Where(x => oldPriceIds.Contains(x.PriceId)).ExecuteCommandAsync(cancellationToken);
|
||
await db.Deleteable<ServiceChannelPriceDetail>().Where(x => oldPriceIds.Contains(x.PriceId)).ExecuteCommandAsync(cancellationToken);
|
||
}
|
||
|
||
var priceList = prices.Select(x => new
|
||
{
|
||
TempId = x.Id,
|
||
Entity = x
|
||
}).ToList();
|
||
|
||
if (priceList.Count == 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
var factorList = factors.ToList();
|
||
var detailList = details.ToList();
|
||
foreach (var item in priceList)
|
||
{
|
||
item.Entity.Id = 0;
|
||
item.Entity.ServiceChannelId = serviceChannelId;
|
||
var savedPrice = await db.Insertable(item.Entity).ExecuteReturnEntityAsync();
|
||
// 通过临时 PriceId 将因子和明细绑定回真实买价项主键。
|
||
await InsertPriceChildrenAsync(
|
||
db,
|
||
savedPrice.Id,
|
||
factorList.Where(x => x.PriceId == item.TempId),
|
||
detailList.Where(x => x.PriceId == item.TempId),
|
||
cancellationToken);
|
||
}
|
||
}
|
||
|
||
public async Task<List<ServiceChannelPublishRecord>> GetPublishRecordsAsync(int serviceChannelId, string operatorType, int pageIndex, int pageSize, CancellationToken cancellationToken = default)
|
||
{
|
||
var db = await GetDbContextAsync(cancellationToken);
|
||
return await db.Queryable<ServiceChannelPublishRecord>()
|
||
.Where(x => x.ServiceChannelId == serviceChannelId && x.OperatorType == operatorType)
|
||
.OrderBy(x => x.PublishTime, SqlSugar.OrderByType.Desc)
|
||
.ToPageListAsync(pageIndex, pageSize, cancellationToken);
|
||
}
|
||
|
||
public async Task<int> CountPublishRecordsAsync(int serviceChannelId, string operatorType, CancellationToken cancellationToken = default)
|
||
{
|
||
var db = await GetDbContextAsync(cancellationToken);
|
||
return await db.Queryable<ServiceChannelPublishRecord>()
|
||
.Where(x => x.ServiceChannelId == serviceChannelId && x.OperatorType == operatorType)
|
||
.CountAsync(cancellationToken);
|
||
}
|
||
|
||
public async Task<ServiceChannelPublishRecord> InsertPublishRecordAsync(ServiceChannelPublishRecord record, CancellationToken cancellationToken = default)
|
||
{
|
||
var db = await GetDbContextAsync(cancellationToken);
|
||
return await db.Insertable(record).ExecuteReturnEntityAsync();
|
||
}
|
||
|
||
public async Task<ServiceChannelPublishRecord?> GetPublishRecordByIdAsync(int id, CancellationToken cancellationToken = default)
|
||
{
|
||
var db = await GetDbContextAsync(cancellationToken);
|
||
return await db.Queryable<ServiceChannelPublishRecord>().FirstAsync(x => x.Id == id, cancellationToken);
|
||
}
|
||
|
||
private static async Task InsertPriceChildrenAsync(
|
||
SqlSugar.ISqlSugarClient db,
|
||
int priceId,
|
||
IEnumerable<ServiceChannelPriceFactor> factors,
|
||
IEnumerable<ServiceChannelPriceDetail> details,
|
||
CancellationToken cancellationToken)
|
||
{
|
||
// 子表在仓储层统一重写 PriceId,应用层只需要维护临时关联关系。
|
||
var factorArray = factors.Select(x =>
|
||
{
|
||
x.Id = 0;
|
||
x.PriceId = priceId;
|
||
return x;
|
||
}).ToArray();
|
||
if (factorArray.Length > 0)
|
||
{
|
||
await db.Insertable(factorArray).ExecuteCommandAsync(cancellationToken);
|
||
}
|
||
|
||
var detailArray = details.Select(x =>
|
||
{
|
||
x.Id = 0;
|
||
x.PriceId = priceId;
|
||
return x;
|
||
}).ToArray();
|
||
if (detailArray.Length > 0)
|
||
{
|
||
await db.Insertable(detailArray).ExecuteCommandAsync(cancellationToken);
|
||
}
|
||
}
|
||
}
|