diff --git a/src/Oms.Application/Dtos/Channels/KpiAreaInfoListInput.cs b/src/Oms.Application/Dtos/Channels/KpiAreaInfoListInput.cs
index 120c115..6f9152c 100644
--- a/src/Oms.Application/Dtos/Channels/KpiAreaInfoListInput.cs
+++ b/src/Oms.Application/Dtos/Channels/KpiAreaInfoListInput.cs
@@ -19,4 +19,39 @@ public class KpiAreaInfoListInput
/// 每页条数。
///
public int PageSize { get; set; }
+
+ ///
+ /// 国家/地区(匹配国家名称或国家代码,模糊)。
+ ///
+ public string? Country { get; set; }
+
+ ///
+ /// 匹配维度(如 zip/state/city/country,模糊)。
+ ///
+ public string? MatchDim { get; set; }
+
+ ///
+ /// 匹配方式(如 prefix/exact/range/all,模糊)。
+ ///
+ public string? MatchMode { get; set; }
+
+ ///
+ /// 州/省(模糊)。
+ ///
+ public string? Province { get; set; }
+
+ ///
+ /// 城市(模糊)。
+ ///
+ public string? City { get; set; }
+
+ ///
+ /// 起始邮编(模糊)。
+ ///
+ public string? LeftPostcode { get; set; }
+
+ ///
+ /// 截止邮编(模糊)。
+ ///
+ public string? RightPostcode { get; set; }
}
diff --git a/src/Oms.Application/Services/Channels/KpiAreaService.cs b/src/Oms.Application/Services/Channels/KpiAreaService.cs
index 95f6061..6ec6e34 100644
--- a/src/Oms.Application/Services/Channels/KpiAreaService.cs
+++ b/src/Oms.Application/Services/Channels/KpiAreaService.cs
@@ -106,8 +106,9 @@ public class KpiAreaService : ApplicationService
await GetAreaOrThrowAsync(input.AreaId);
var pageIndex = OmsDocHelper.NormalizePage(input.Page);
var pageSize = OmsDocHelper.NormalizePageSize(input.PageSize);
- var entities = await KpiAreaRepository.GetInfosAsync(input.AreaId, pageIndex, pageSize);
- var total = await KpiAreaRepository.CountInfosAsync(input.AreaId);
+ var filter = BuildInfoQueryFilter(input);
+ var entities = await KpiAreaRepository.GetInfosAsync(input.AreaId, pageIndex, pageSize, filter);
+ var total = await KpiAreaRepository.CountInfosAsync(input.AreaId, filter);
return new OmsPageResult
{
Items = entities.Select(MapInfoOutput).ToList(),
@@ -115,6 +116,18 @@ public class KpiAreaService : ApplicationService
};
}
+ private static KpiAreaInfoQueryFilter BuildInfoQueryFilter(KpiAreaInfoListInput input) =>
+ new()
+ {
+ Country = input.Country,
+ MatchDim = input.MatchDim,
+ MatchMode = input.MatchMode,
+ Province = input.Province,
+ City = input.City,
+ LeftPostcode = input.LeftPostcode,
+ RightPostcode = input.RightPostcode
+ };
+
///
/// 新增KPI分区明细。
///
diff --git a/src/Oms.Domain/ChannelsAggregate/Repositories/IKpiAreaRepository.cs b/src/Oms.Domain/ChannelsAggregate/Repositories/IKpiAreaRepository.cs
index 6dce96b..183980d 100644
--- a/src/Oms.Domain/ChannelsAggregate/Repositories/IKpiAreaRepository.cs
+++ b/src/Oms.Domain/ChannelsAggregate/Repositories/IKpiAreaRepository.cs
@@ -3,15 +3,37 @@ using Oms.Domain.ChannelsAggregate.Entities;
namespace Oms.Domain.ChannelsAggregate.Repositories;
+///
+/// KPI 分区明细列表筛选条件(字段均为可选,模糊匹配)。
+///
+public class KpiAreaInfoQueryFilter
+{
+ public string? Country { get; set; }
+ public string? MatchDim { get; set; }
+ public string? MatchMode { get; set; }
+ public string? Province { get; set; }
+ public string? City { get; set; }
+ public string? LeftPostcode { get; set; }
+ public string? RightPostcode { get; set; }
+}
+
public interface IKpiAreaRepository : IRepository, IKpiAreaPublishRepository
{
Task GetByAppKeyTypeAndNameAsync(string appKey, string areaType, string name, CancellationToken cancellationToken = default);
Task ExistsNameAsync(string appKey, string areaType, string name, CancellationToken cancellationToken = default);
- Task> GetInfosAsync(int areaId, int pageIndex, int pageSize, CancellationToken cancellationToken = default);
+ Task> GetInfosAsync(
+ int areaId,
+ int pageIndex,
+ int pageSize,
+ KpiAreaInfoQueryFilter? filter = null,
+ CancellationToken cancellationToken = default);
- Task CountInfosAsync(int areaId, CancellationToken cancellationToken = default);
+ Task CountInfosAsync(
+ int areaId,
+ KpiAreaInfoQueryFilter? filter = null,
+ CancellationToken cancellationToken = default);
Task InsertInfoAsync(KpiAreaInfo info, CancellationToken cancellationToken = default);
diff --git a/src/Oms.SqlSugarCore/Channels/KpiAreaRepository.cs b/src/Oms.SqlSugarCore/Channels/KpiAreaRepository.cs
index e50b197..057a9dd 100644
--- a/src/Oms.SqlSugarCore/Channels/KpiAreaRepository.cs
+++ b/src/Oms.SqlSugarCore/Channels/KpiAreaRepository.cs
@@ -18,20 +18,91 @@ public class KpiAreaRepository : OmsSqlSugarRepository, IKpiAreaReposit
return AnyAsync(x => x.AppKey == appKey && x.AreaType == areaType && x.Name == name, cancellationToken);
}
- public async Task> GetInfosAsync(int areaId, int pageIndex, int pageSize, CancellationToken cancellationToken = default)
+ public async Task> GetInfosAsync(
+ int areaId,
+ int pageIndex,
+ int pageSize,
+ KpiAreaInfoQueryFilter? filter = null,
+ CancellationToken cancellationToken = default)
{
var db = await GetDbContextAsync(cancellationToken);
// 依赖 idx_kpi_info_area_id (AreaId, Id),避免大分区 filesort
- return await db.Queryable()
- .Where(x => x.AreaId == areaId)
+ return await BuildInfoQueryable(db, areaId, filter)
.OrderBy(x => x.Id, OrderByType.Desc)
.ToPageListAsync(pageIndex, pageSize, cancellationToken);
}
- public async Task CountInfosAsync(int areaId, CancellationToken cancellationToken = default)
+ public async Task CountInfosAsync(
+ int areaId,
+ KpiAreaInfoQueryFilter? filter = null,
+ CancellationToken cancellationToken = default)
{
var db = await GetDbContextAsync(cancellationToken);
- return await db.Queryable().Where(x => x.AreaId == areaId).CountAsync(cancellationToken);
+ return await BuildInfoQueryable(db, areaId, filter).CountAsync(cancellationToken);
+ }
+
+ private static ISugarQueryable BuildInfoQueryable(
+ ISqlSugarClient db,
+ int areaId,
+ KpiAreaInfoQueryFilter? filter)
+ {
+ var query = db.Queryable().Where(x => x.AreaId == areaId);
+ if (filter == null)
+ {
+ return query;
+ }
+
+ var country = TrimOrNull(filter.Country);
+ if (country != null)
+ {
+ query = query.Where(x =>
+ (x.CountryName != null && x.CountryName.Contains(country))
+ || (x.CountryCode != null && x.CountryCode.Contains(country)));
+ }
+
+ var matchDim = TrimOrNull(filter.MatchDim);
+ if (matchDim != null)
+ {
+ query = query.Where(x => x.MatchDim != null && x.MatchDim.Contains(matchDim));
+ }
+
+ var matchMode = TrimOrNull(filter.MatchMode);
+ if (matchMode != null)
+ {
+ query = query.Where(x => x.MatchMode != null && x.MatchMode.Contains(matchMode));
+ }
+
+ var province = TrimOrNull(filter.Province);
+ if (province != null)
+ {
+ query = query.Where(x => x.Province != null && x.Province.Contains(province));
+ }
+
+ var city = TrimOrNull(filter.City);
+ if (city != null)
+ {
+ query = query.Where(x => x.City != null && x.City.Contains(city));
+ }
+
+ var leftPostcode = TrimOrNull(filter.LeftPostcode);
+ if (leftPostcode != null)
+ {
+ query = query.Where(x => x.LeftPostcode != null && x.LeftPostcode.Contains(leftPostcode));
+ }
+
+ var rightPostcode = TrimOrNull(filter.RightPostcode);
+ if (rightPostcode != null)
+ {
+ query = query.Where(x => x.RightPostcode != null && x.RightPostcode.Contains(rightPostcode));
+ }
+
+ return query;
+ }
+
+ private static string? TrimOrNull(string? value)
+ {
+ var trimmed = value?.Trim();
+ return string.IsNullOrEmpty(trimmed) ? null : trimmed;
}
public async Task InsertInfoAsync(KpiAreaInfo info, CancellationToken cancellationToken = default)