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, IServiceChannelRepository, IScopedDependency { public Task GetByChannelCodeAsync(string channelCode, CancellationToken cancellationToken = default) { return FirstOrDefaultAsync(x => x.ChannelCode == channelCode, cancellationToken); } public Task HasChannelCodeAsync(string channelCode, CancellationToken cancellationToken = default) { return AnyAsync(x => x.ChannelCode == channelCode, cancellationToken); } public async Task> GetGroupsAsync(CancellationToken cancellationToken = default) { var db = await GetDbContextAsync(cancellationToken); return await db.Queryable().ToListAsync(cancellationToken); } public async Task> GetPricesAsync(int serviceChannelId, CancellationToken cancellationToken = default) { var db = await GetDbContextAsync(cancellationToken); return await db.Queryable() .Where(x => x.ServiceChannelId == serviceChannelId) .OrderBy(x => x.SerialNumber) .ToListAsync(cancellationToken); } public async Task GetPriceByIdAsync(int id, CancellationToken cancellationToken = default) { var db = await GetDbContextAsync(cancellationToken); return await db.Queryable() .FirstAsync(x => x.Id == id, cancellationToken); } public async Task> GetPriceFactorsAsync(IEnumerable priceIds, CancellationToken cancellationToken = default) { var ids = priceIds.Distinct().ToArray(); if (ids.Length == 0) return []; var db = await GetDbContextAsync(cancellationToken); return await db.Queryable() .Where(x => ids.Contains(x.PriceId)) .OrderBy(x => x.SerialNumber) .ToListAsync(cancellationToken); } public async Task> GetPriceDetailsAsync(IEnumerable priceIds, CancellationToken cancellationToken = default) { var ids = priceIds.Distinct().ToArray(); if (ids.Length == 0) return []; var db = await GetDbContextAsync(cancellationToken); return await db.Queryable() .Where(x => ids.Contains(x.PriceId)) .ToListAsync(cancellationToken); } public async Task InsertPriceAsync(ServiceChannelPrice price, IEnumerable factors, IEnumerable 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 factors, IEnumerable details, CancellationToken cancellationToken = default) { var db = await GetDbContextAsync(cancellationToken); await db.Updateable(price).ExecuteCommandAsync(cancellationToken); await db.Deleteable() .Where(x => x.PriceId == price.Id) .ExecuteCommandAsync(cancellationToken); await db.Deleteable() .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() .Where(x => x.Id == id) .ExecuteCommandAsync(cancellationToken); await db.Deleteable() .Where(x => x.PriceId == id) .ExecuteCommandAsync(cancellationToken); await db.Deleteable() .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() .SetColumns(x => x.Status, status) .Where(x => x.Id == id) .ExecuteCommandAsync(cancellationToken); } public async Task ReplacePricesAsync(int serviceChannelId, IEnumerable prices, IEnumerable factors, IEnumerable details, CancellationToken cancellationToken = default) { var db = await GetDbContextAsync(cancellationToken); var oldPrices = await db.Queryable() .Where(x => x.ServiceChannelId == serviceChannelId) .ToListAsync(cancellationToken); var oldPriceIds = oldPrices.Select(x => x.Id).ToArray(); if (oldPriceIds.Length > 0) { // 批量保存时先整棵旧买价树软删,再写入新的快照数据。 await db.Deleteable().Where(x => oldPriceIds.Contains(x.Id)).ExecuteCommandAsync(cancellationToken); await db.Deleteable().Where(x => oldPriceIds.Contains(x.PriceId)).ExecuteCommandAsync(cancellationToken); await db.Deleteable().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> GetPublishRecordsAsync(int serviceChannelId, string operatorType, int pageIndex, int pageSize, CancellationToken cancellationToken = default) { var db = await GetDbContextAsync(cancellationToken); return await db.Queryable() .Where(x => x.ServiceChannelId == serviceChannelId && x.OperatorType == operatorType) .OrderBy(x => x.PublishTime, SqlSugar.OrderByType.Desc) .ToPageListAsync(pageIndex, pageSize, cancellationToken); } public async Task CountPublishRecordsAsync(int serviceChannelId, string operatorType, CancellationToken cancellationToken = default) { var db = await GetDbContextAsync(cancellationToken); return await db.Queryable() .Where(x => x.ServiceChannelId == serviceChannelId && x.OperatorType == operatorType) .CountAsync(cancellationToken); } public async Task InsertPublishRecordAsync(ServiceChannelPublishRecord record, CancellationToken cancellationToken = default) { var db = await GetDbContextAsync(cancellationToken); return await db.Insertable(record).ExecuteReturnEntityAsync(); } public async Task GetPublishRecordByIdAsync(int id, CancellationToken cancellationToken = default) { var db = await GetDbContextAsync(cancellationToken); return await db.Queryable().FirstAsync(x => x.Id == id, cancellationToken); } private static async Task InsertPriceChildrenAsync( SqlSugar.ISqlSugarClient db, int priceId, IEnumerable factors, IEnumerable 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); } } }