fix: 地址簿管理端可查全部,修复 SqlSugar 条件翻译
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
9a48ec1a63
commit
1cf55b2669
@ -13,6 +13,12 @@ public class CustomerSenderAddressPaginatedInput
|
||||
[Newtonsoft.Json.JsonProperty("pageSize")]
|
||||
public int PageSize { get; set; } = 30;
|
||||
|
||||
/// <summary>
|
||||
/// 客户 ID(管理端可选;不传则查全部)。
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("customerId")]
|
||||
public int? CustomerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地址类型:all / sender / return / receiver。
|
||||
/// </summary>
|
||||
@ -31,6 +37,11 @@ public class CustomerSenderAddressPaginatedInput
|
||||
/// </summary>
|
||||
public class CreateCustomerSenderAddressInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 客户 ID(管理端代操作必传;客户门户可省略)。
|
||||
/// </summary>
|
||||
public int? CustomerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 地址类型:sender 发件 / return 退件 / receiver 收件。
|
||||
/// </summary>
|
||||
|
||||
@ -17,26 +17,27 @@ public partial class OrderService
|
||||
|
||||
/// <summary>
|
||||
/// 客户地址分页列表(发件/退件/收件)。
|
||||
/// 管理端未传 customerId 时查询全部;客户门户仅查自身。
|
||||
/// </summary>
|
||||
[HttpPost("/order/sender-address/list")]
|
||||
public async Task<OmsPageResult<CustomerSenderAddressOutput>> GetSenderAddressListAsync(
|
||||
[FromBody] CustomerSenderAddressPaginatedInput input)
|
||||
{
|
||||
var customer = await OmsSessionHelper.ResolveSessionCustomerAsync(CustomerRepository, CurrentUser);
|
||||
var customerId = await WarehouseCustomerHelper.ResolveListCustomerIdAsync(
|
||||
CustomerRepository,
|
||||
CurrentUser,
|
||||
input.CustomerId);
|
||||
var pageIndex = OmsDocHelper.NormalizePage(input.Page);
|
||||
var pageSize = OmsDocHelper.NormalizePageSize(input.PageSize);
|
||||
var predicate = BuildSenderAddressPredicate(customer.Id, input);
|
||||
var predicate = BuildSenderAddressPredicate(customerId, input);
|
||||
|
||||
var entities = await CustomerSenderAddressRepository.GetPagedListAsync(
|
||||
// 避免 Fake GetPagedListAsync(sorting) 丢失 Where / SqlSugar 错误翻译表达式
|
||||
var (entities, total) = await RepositoryPageHelper.GetPageAsync(
|
||||
CustomerSenderAddressRepository,
|
||||
predicate,
|
||||
pageIndex,
|
||||
pageSize,
|
||||
new Dictionary<string, bool>
|
||||
{
|
||||
[nameof(CustomerSenderAddress.IsDefault)] = false,
|
||||
[nameof(CustomerSenderAddress.Id)] = false
|
||||
});
|
||||
var total = await CustomerSenderAddressRepository.CountAsync(predicate);
|
||||
q => q.OrderByDescending(x => x.IsDefault).ThenByDescending(x => x.Id));
|
||||
var countryMap = await LoadCountryCodeMapAsync(entities.Select(x => x.Country).Where(x => x.HasValue).Select(x => x!.Value));
|
||||
|
||||
return new OmsPageResult<CustomerSenderAddressOutput>
|
||||
@ -50,9 +51,11 @@ public partial class OrderService
|
||||
/// 客户地址详情。
|
||||
/// </summary>
|
||||
[HttpGet("/order/sender-address/detail")]
|
||||
public async Task<CustomerSenderAddressOutput> GetSenderAddressDetailAsync([FromQuery] int id)
|
||||
public async Task<CustomerSenderAddressOutput> GetSenderAddressDetailAsync(
|
||||
[FromQuery] int id,
|
||||
[FromQuery] int? customerId = null)
|
||||
{
|
||||
var entity = await GetOwnedSenderAddressOrThrowAsync(id);
|
||||
var entity = await GetOwnedSenderAddressOrThrowAsync(id, customerId);
|
||||
var countryMap = await LoadCountryCodeMapAsync(entity.Country.HasValue ? [entity.Country.Value] : []);
|
||||
return MapSenderAddressOutput(entity, countryMap);
|
||||
}
|
||||
@ -63,19 +66,22 @@ public partial class OrderService
|
||||
[HttpPost("/order/sender-address/create")]
|
||||
public async Task<object> CreateSenderAddressAsync([FromBody] CreateCustomerSenderAddressInput input)
|
||||
{
|
||||
var customer = await OmsSessionHelper.ResolveSessionCustomerAsync(CustomerRepository, CurrentUser);
|
||||
var customerId = await WarehouseCustomerHelper.ResolveRequiredCustomerIdAsync(
|
||||
CustomerRepository,
|
||||
CurrentUser,
|
||||
input.CustomerId);
|
||||
var addressType = NormalizeAddressTypeOrThrow(input.AddressType);
|
||||
ValidateSenderAddressInput(input);
|
||||
var countryId = await ResolveSenderCountryIdAsync(input.CountryCode);
|
||||
|
||||
if (input.IsDefault)
|
||||
{
|
||||
await CustomerSenderAddressRepository.ClearDefaultAsync(customer.Id, addressType);
|
||||
await CustomerSenderAddressRepository.ClearDefaultAsync(customerId, addressType);
|
||||
}
|
||||
|
||||
var entity = new CustomerSenderAddress
|
||||
{
|
||||
CustomerId = customer.Id,
|
||||
CustomerId = customerId,
|
||||
AddressType = addressType,
|
||||
AddressName = TrimOrNull(input.AddressName),
|
||||
SenderName = input.SenderName.Trim(),
|
||||
@ -104,7 +110,7 @@ public partial class OrderService
|
||||
[HttpPost("/order/sender-address/update")]
|
||||
public async Task UpdateSenderAddressAsync([FromBody] UpdateCustomerSenderAddressInput input)
|
||||
{
|
||||
var entity = await GetOwnedSenderAddressOrThrowAsync(input.Id);
|
||||
var entity = await GetOwnedSenderAddressOrThrowAsync(input.Id, input.CustomerId);
|
||||
var addressType = NormalizeAddressTypeOrThrow(input.AddressType);
|
||||
ValidateSenderAddressInput(input);
|
||||
var countryId = await ResolveSenderCountryIdAsync(input.CountryCode);
|
||||
@ -140,7 +146,7 @@ public partial class OrderService
|
||||
[HttpPost("/order/sender-address/delete")]
|
||||
public async Task DeleteSenderAddressAsync([FromBody] IdInput input)
|
||||
{
|
||||
var entity = await GetOwnedSenderAddressOrThrowAsync(input.Id);
|
||||
var entity = await GetOwnedSenderAddressOrThrowAsync(input.Id, null);
|
||||
await CustomerSenderAddressRepository.DeleteAsync(entity);
|
||||
}
|
||||
|
||||
@ -150,7 +156,7 @@ public partial class OrderService
|
||||
[HttpPost("/order/sender-address/set-default")]
|
||||
public async Task SetDefaultSenderAddressAsync([FromBody] IdInput input)
|
||||
{
|
||||
var entity = await GetOwnedSenderAddressOrThrowAsync(input.Id);
|
||||
var entity = await GetOwnedSenderAddressOrThrowAsync(input.Id, null);
|
||||
var addressType = string.IsNullOrWhiteSpace(entity.AddressType)
|
||||
? CustomerAddressTypeCodes.Sender
|
||||
: entity.AddressType;
|
||||
@ -159,10 +165,17 @@ public partial class OrderService
|
||||
await CustomerSenderAddressRepository.UpdateAsync(entity);
|
||||
}
|
||||
|
||||
private async Task<CustomerSenderAddress> GetOwnedSenderAddressOrThrowAsync(int id)
|
||||
private async Task<CustomerSenderAddress> GetOwnedSenderAddressOrThrowAsync(int id, int? requestedCustomerId)
|
||||
{
|
||||
var customer = await OmsSessionHelper.ResolveSessionCustomerAsync(CustomerRepository, CurrentUser);
|
||||
var entity = await CustomerSenderAddressRepository.GetOwnedAsync(id, customer.Id);
|
||||
var customerId = await WarehouseCustomerHelper.ResolveListCustomerIdAsync(
|
||||
CustomerRepository,
|
||||
CurrentUser,
|
||||
requestedCustomerId);
|
||||
var (hasCustomerFilter, customerIdValue) = WarehouseCustomerHelper.ToCustomerFilter(customerId);
|
||||
|
||||
var entity = hasCustomerFilter
|
||||
? await CustomerSenderAddressRepository.GetOwnedAsync(id, customerIdValue)
|
||||
: await CustomerSenderAddressRepository.FirstOrDefaultAsync(x => x.Id == id);
|
||||
if (entity == null)
|
||||
{
|
||||
throw new BusinessException("地址不存在");
|
||||
@ -204,24 +217,28 @@ public partial class OrderService
|
||||
}
|
||||
|
||||
private static Expression<Func<CustomerSenderAddress, bool>> BuildSenderAddressPredicate(
|
||||
int customerId,
|
||||
int? customerId,
|
||||
CustomerSenderAddressPaginatedInput input)
|
||||
{
|
||||
var (hasCustomerFilter, customerIdValue) = WarehouseCustomerHelper.ToCustomerFilter(customerId);
|
||||
var keyword = input.Keyword?.Trim();
|
||||
var hasKeyword = !string.IsNullOrWhiteSpace(keyword);
|
||||
var onlyDefault = input.OnlyDefault;
|
||||
var addressType = input.AddressType?.Trim();
|
||||
var filterByType = !string.IsNullOrWhiteSpace(addressType)
|
||||
&& !string.Equals(addressType, "all", StringComparison.OrdinalIgnoreCase);
|
||||
var addressTypeValue = filterByType ? addressType! : string.Empty;
|
||||
|
||||
// 布尔/关键字先算成局部变量;避免 SqlSugar 翻译 IsNullOrWhiteSpace / ?? / HasValue 生成非法 SQL
|
||||
return x =>
|
||||
x.CustomerId == customerId
|
||||
&& (!filterByType || x.AddressType == addressType)
|
||||
(!hasCustomerFilter || x.CustomerId == customerIdValue)
|
||||
&& (!filterByType || x.AddressType == addressTypeValue)
|
||||
&& (!onlyDefault || x.IsDefault == 1)
|
||||
&& (string.IsNullOrWhiteSpace(keyword)
|
||||
|| (x.AddressName ?? string.Empty).Contains(keyword)
|
||||
|| x.SenderName.Contains(keyword)
|
||||
|| (x.Phone ?? string.Empty).Contains(keyword)
|
||||
|| x.StreetAddress1.Contains(keyword));
|
||||
&& (!hasKeyword
|
||||
|| (x.AddressName != null && x.AddressName.Contains(keyword!))
|
||||
|| x.SenderName.Contains(keyword!)
|
||||
|| (x.Phone != null && x.Phone.Contains(keyword!))
|
||||
|| x.StreetAddress1.Contains(keyword!));
|
||||
}
|
||||
|
||||
private async Task<Dictionary<int, string>> LoadCountryCodeMapAsync(IEnumerable<int> countryIds)
|
||||
|
||||
@ -19,11 +19,13 @@ public class CustomerSenderAddressRepository : OmsSqlSugarRepository<CustomerSen
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var type = addressType.Trim();
|
||||
var hasExcludeId = excludeId.HasValue;
|
||||
var excludeIdValue = excludeId.GetValueOrDefault();
|
||||
var list = await GetListAsync(
|
||||
x => x.CustomerId == customerId
|
||||
&& x.AddressType == type
|
||||
&& x.IsDefault == 1
|
||||
&& (!excludeId.HasValue || x.Id != excludeId.Value),
|
||||
&& (!hasExcludeId || x.Id != excludeIdValue),
|
||||
cancellationToken: cancellationToken);
|
||||
if (list.Count == 0)
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user