using System.Linq.Expressions;
using Fake.Application;
using Microsoft.AspNetCore.Mvc;
using Oms.Application.Dtos.Shared;
using Oms.Application.Dtos.System;
using Oms.Application.Shared;
using Oms.Domain.SystemAggregate.Consts;
using Oms.Domain.SystemAggregate.Entities;
using Oms.Domain.SystemAggregate.Repositories;
namespace Oms.Application.Services.System;
///
/// 仓库 API 服务。
///
[ApiExplorerSettings(GroupName = "OMS-System")]
public class WarehouseService : ApplicationService
{
private IWarehouseAddressRepository WarehouseAddressRepository => LazyServiceProvider.GetRequiredService();
private OmsRbacUserDisplayNameResolver UserDisplayNameResolver =>
LazyServiceProvider.GetRequiredService();
///
/// 查询仓库列表。
///
/// 入参:仓库分页查询条件。
/// 仓库分页结果,包含列表数据和总记录数。
[HttpGet("/system/warehouse/list")]
public async Task> GetPaginatedListAsync([FromQuery] WarehousePaginatedInput input)
{
var predicate = BuildPaginatedPredicate(input);
var pageIndex = OmsDocHelper.NormalizePage(input.Page);
var pageSize = OmsDocHelper.NormalizePageSize(input.PageSize);
var entities = await WarehouseAddressRepository.GetPagedListAsync(
predicate,
pageIndex,
pageSize,
new Dictionary { [nameof(WarehouseAddress.UpdateTime)] = false, [nameof(WarehouseAddress.Id)] = false });
var totalCount = await WarehouseAddressRepository.CountAsync(predicate);
var items = entities.Select(entity =>
{
var output = ObjectMapper.Map(entity);
output.WarehouseTypeName = OmsDocHelper.GetWarehouseTypeName(entity.WarehouseType);
output.UpdateTime = OmsDocHelper.NullIfDefault(entity.UpdateTime);
return output;
}).ToList();
return new OmsPageResult
{
Items = items,
Total = totalCount
};
}
///
/// 查询仓库详情。
///
/// 入参:目标主键。
/// 仓库详情。
[HttpGet("/system/warehouse/detail")]
public async Task GetByIdAsync([FromQuery] int id)
{
var entity = await GetWarehouseOrThrowAsync(id);
var output = ObjectMapper.Map(entity);
var auditUserNameMap = await UserDisplayNameResolver.ResolveManyAsync(
[entity.CreateUserId, entity.UpdateUserId]);
output.CreateBy = OmsRbacUserDisplayNameResolver.FormatUserId(entity.CreateUserId, auditUserNameMap);
output.UpdateBy = OmsRbacUserDisplayNameResolver.FormatUserId(entity.UpdateUserId, auditUserNameMap);
output.UpdateTime = OmsDocHelper.NullIfDefault(entity.UpdateTime);
return output;
}
///
/// 新增仓库。
///
/// 入参:仓库创建参数。
/// 无返回体,仅完成新增仓库。
[HttpPost("/system/warehouse/create")]
public async Task CreateAsync(CreateWarehouseInput input)
{
var warehouseName = input.WarehouseName.Trim();
var duplicatedWarehouse = await WarehouseAddressRepository.GetByWarehouseNameAsync(warehouseName);
if (duplicatedWarehouse != null)
{
throw new BusinessException("仓库名称已存在");
}
var deleted = await WarehouseAddressRepository.GetByWarehouseNameIncludingDeletedAsync(warehouseName);
if (deleted != null && deleted.IsDeleted)
{
deleted.IsDeleted = false;
deleted.WarehouseName = warehouseName;
deleted.WarehouseType = input.WarehouseType;
deleted.Recipient = input.Recipient;
deleted.ContactPhone = input.ContactPhone;
deleted.ShippingAddress = input.ShippingAddress;
await WarehouseAddressRepository.UpdateAsync(deleted);
return;
}
var entity = new WarehouseAddress
{
WarehouseName = warehouseName,
WarehouseType = input.WarehouseType,
Recipient = input.Recipient,
ContactPhone = input.ContactPhone,
ShippingAddress = input.ShippingAddress,
};
await WarehouseAddressRepository.InsertAsync(entity);
}
///
/// 更新仓库。
///
/// 入参:仓库更新参数。
/// 无返回体,仅完成更新仓库。
[HttpPost("/system/warehouse/update")]
public async Task UpdateAsync(UpdateWarehouseInput input)
{
var entity = await GetWarehouseOrThrowAsync(input.Id);
var warehouseName = input.WarehouseName.Trim();
var duplicatedWarehouse = await WarehouseAddressRepository.GetByWarehouseNameAsync(warehouseName);
if (duplicatedWarehouse != null && duplicatedWarehouse.Id != entity.Id)
{
throw new BusinessException("仓库名称已存在");
}
var softDeleted = await WarehouseAddressRepository.GetByWarehouseNameIncludingDeletedAsync(warehouseName);
if (softDeleted != null && softDeleted.IsDeleted && softDeleted.Id != entity.Id)
{
softDeleted.WarehouseName = $"{warehouseName}__deleted_{softDeleted.Id}";
await WarehouseAddressRepository.UpdateAsync(softDeleted);
}
entity.WarehouseName = warehouseName;
entity.WarehouseType = input.WarehouseType;
entity.Recipient = input.Recipient;
entity.ContactPhone = input.ContactPhone;
entity.ShippingAddress = input.ShippingAddress;
await WarehouseAddressRepository.UpdateAsync(entity);
}
///
/// 删除仓库。
///
/// 入参:目标主键。
/// 无返回体,仅完成删除仓库。
[HttpPost("/system/warehouse/delete")]
public async Task DeleteAsync(IdInput input)
{
var entity = await GetWarehouseOrThrowAsync(input.Id);
await WarehouseAddressRepository.DeleteAsync(entity);
}
private Expression> BuildPaginatedPredicate(WarehousePaginatedInput input)
{
var keyword = input.Keyword?.Trim();
var warehouseType = input.WarehouseType?.Trim();
return warehouse =>
(string.IsNullOrWhiteSpace(warehouseType) || warehouse.WarehouseType == warehouseType) &&
(string.IsNullOrWhiteSpace(keyword) ||
warehouse.WarehouseName.Contains(keyword) ||
(warehouse.Recipient ?? string.Empty).Contains(keyword) ||
(warehouse.ContactPhone ?? string.Empty).Contains(keyword));
}
private async Task GetWarehouseOrThrowAsync(int id)
{
var entity = await WarehouseAddressRepository.FirstOrDefaultAsync(x => x.Id == id);
if (entity == null)
{
throw new BusinessException("仓库不存在");
}
return entity;
}
}