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)
};
}
}