using System.Linq.Expressions; using Fake.Application; using Microsoft.AspNetCore.Mvc; using Oms.Application.Dtos.Channels; using Oms.Application.Dtos.Shared; using Oms.Application.Shared; using Oms.Domain.ChannelsAggregate.Entities; using Oms.Domain.ChannelsAggregate.Repositories; namespace Oms.Application.Services.Channels; /// /// 重量规则 API 服务。 /// [ApiExplorerSettings(GroupName = "OMS-Channel")] public class WeightRuleService : ApplicationService { private IWeightRuleRepository WeightRuleRepository => LazyServiceProvider.GetRequiredService(); /// /// 查询计重规则列表。 /// /// 入参:计重规则列表查询条件。 /// 计重规则分页结果,包含列表数据和总记录数。 /// /// 核心业务逻辑: /// 1. 根据查询条件构造筛选规则。 /// 2. 查询目标数据并补齐关联展示字段。 /// 3. 按接口约定返回列表结果。 /// [HttpPost("/channel/weight-rule/list")] public async Task> GetListAsync(WeightRuleListInput input) { var predicate = BuildPredicate(input); var pageIndex = OmsDocHelper.NormalizePage(input.Page); var pageSize = OmsDocHelper.NormalizePageSize(input.PageSize); var entities = await WeightRuleRepository.GetPagedListAsync( predicate, pageIndex, pageSize, new Dictionary { [nameof(WeightRule.UpdateTime)] = false, [nameof(WeightRule.Id)] = false }); var total = await WeightRuleRepository.CountAsync(predicate); return new OmsPageResult { Items = entities.Select(MapOutput).ToList(), Total = total }; } /// /// 新增计重规则。 /// /// 入参:计重规则保存参数。 /// 无返回体,仅完成新增计重规则。 /// /// 核心业务逻辑: /// 1. 校验入参与关联对象、唯一性等前置条件。 /// 2. 组装目标实体及相关明细数据。 /// 3. 写入审计字段并持久化结果。 /// [HttpPost("/channel/weight-rule/create")] public async Task CreateAsync(WeightRuleSaveInput input) { await ValidateNameAsync(input.AppKey, input.Name, null); await WeightRuleRepository.InsertAsync(new WeightRule { AppKey = input.AppKey, Name = input.Name }); } /// /// 更新计重规则。 /// /// 入参:计重规则保存参数。 /// 无返回体,仅完成更新计重规则。 /// /// 核心业务逻辑: /// 1. 查询并校验目标对象。 /// 2. 按入参更新主体数据和关联配置。 /// 3. 写入更新审计字段并保存结果。 /// [HttpPost("/channel/weight-rule/update")] public async Task UpdateAsync(WeightRuleSaveInput input) { var entity = await GetEntityOrThrowAsync(input.Id); await ValidateNameAsync(input.AppKey, input.Name, entity.Id); entity.AppKey = input.AppKey; entity.Name = input.Name; await WeightRuleRepository.UpdateAsync(entity); } /// /// 删除计重规则。 /// /// 入参:目标主键。 /// 无返回体,仅完成删除计重规则。 /// /// 核心业务逻辑: /// 1. 查询并校验目标对象。 /// 2. 执行软删除或删除关联明细。 /// 3. 持久化删除结果。 /// [HttpPost("/channel/weight-rule/delete")] public async Task DeleteAsync(IdInput input) { var entity = await GetEntityOrThrowAsync(input.Id); await WeightRuleRepository.DeleteAsync(entity); } /// /// 查询计重规则明细列表。 /// /// 入参:计重规则明细列表查询条件。 /// 计重规则明细分页结果,包含列表数据和总记录数。 /// /// 核心业务逻辑: /// 1. 根据查询条件构造筛选规则。 /// 2. 查询目标数据并补齐关联展示字段。 /// 3. 按接口约定返回列表结果。 /// [HttpPost("/channel/weight-rule/info/list")] public async Task> GetInfoListAsync(WeightRuleInfoListInput input) { await GetEntityOrThrowAsync(input.RuleId); var pageIndex = OmsDocHelper.NormalizePage(input.Page); var pageSize = OmsDocHelper.NormalizePageSize(input.PageSize); var entities = await WeightRuleRepository.GetInfosAsync(input.RuleId, pageIndex, pageSize); var total = await WeightRuleRepository.CountInfosAsync(input.RuleId); return new OmsPageResult { Items = entities.Select(MapInfoOutput).ToList(), Total = total }; } /// /// 新增计重规则明细。 /// /// 入参:计重规则明细保存参数。 /// 无返回体,仅完成新增计重规则明细。 /// /// 核心业务逻辑: /// 1. 校验入参与关联对象、唯一性等前置条件。 /// 2. 组装目标实体及相关明细数据。 /// 3. 写入审计字段并持久化结果。 /// [HttpPost("/channel/weight-rule/info/add")] public async Task AddInfoAsync(WeightRuleInfoSaveInput input) { await GetEntityOrThrowAsync(input.RuleId); await WeightRuleRepository.InsertInfoAsync(new WeightRuleInfo { RuleId = input.RuleId, Client = input.Client, Condition = input.Condition, BillableWeight = input.BillableWeight, VolumetricFactor = input.VolumetricFactor }); } /// /// 更新计重规则明细。 /// /// 入参:计重规则明细保存参数。 /// 无返回体,仅完成更新计重规则明细。 /// /// 核心业务逻辑: /// 1. 查询并校验目标对象。 /// 2. 按入参更新主体数据和关联配置。 /// 3. 写入更新审计字段并保存结果。 /// [HttpPost("/channel/weight-rule/info/update")] public async Task UpdateInfoAsync(WeightRuleInfoSaveInput input) { var entity = await GetInfoOrThrowAsync(input.Id); await GetEntityOrThrowAsync(input.RuleId); entity.RuleId = input.RuleId; entity.Client = input.Client; entity.Condition = input.Condition; entity.BillableWeight = input.BillableWeight; entity.VolumetricFactor = input.VolumetricFactor; await WeightRuleRepository.UpdateInfoAsync(entity); } /// /// 删除计重规则明细。 /// /// 入参:目标主键。 /// 无返回体,仅完成删除计重规则明细。 /// /// 核心业务逻辑: /// 1. 查询并校验目标对象。 /// 2. 执行软删除或删除关联明细。 /// 3. 持久化删除结果。 /// [HttpPost("/channel/weight-rule/info/delete")] public async Task DeleteInfoAsync(IdInput input) { await GetInfoOrThrowAsync(input.Id); await WeightRuleRepository.DeleteInfoAsync(input.Id); } private static Expression> BuildPredicate(WeightRuleListInput input) { var appKey = input.AppKey?.Trim(); return entity => string.IsNullOrWhiteSpace(appKey) || entity.AppKey == appKey; } private async Task ValidateNameAsync(string appKey, string name, int? id) { var existed = await WeightRuleRepository.GetByAppKeyAndNameAsync(appKey, name); if (existed != null && existed.Id != id) { throw new BusinessException("计重规则名称已存在"); } } private async Task GetEntityOrThrowAsync(int? id) { if (!id.HasValue || id.Value <= 0) { throw new BusinessException("计重规则不存在"); } var entity = await WeightRuleRepository.FirstOrDefaultAsync(x => x.Id == id.Value); if (entity == null) { throw new BusinessException("计重规则不存在"); } return entity; } private async Task GetInfoOrThrowAsync(int? id) { if (!id.HasValue || id.Value <= 0) { throw new BusinessException("计重规则明细不存在"); } var entity = await WeightRuleRepository.GetInfoByIdAsync(id.Value); if (entity == null) { throw new BusinessException("计重规则明细不存在"); } return entity; } private static WeightRuleOutput MapOutput(WeightRule entity) { return new WeightRuleOutput { Id = entity.Id, AppKey = entity.AppKey, Name = entity.Name, CreateTime = entity.CreateTime, UpdateTime = OmsDocHelper.NullIfDefault(entity.UpdateTime) }; } private static WeightRuleInfoOutput MapInfoOutput(WeightRuleInfo entity) { return new WeightRuleInfoOutput { Id = entity.Id, RuleId = entity.RuleId, Client = entity.Client, Condition = entity.Condition, BillableWeight = entity.BillableWeight, VolumetricFactor = entity.VolumetricFactor, CreateTime = entity.CreateTime, UpdateTime = OmsDocHelper.NullIfDefault(entity.UpdateTime) }; } }