diff --git a/src/Oms.Application/Dtos/Agents/AgentDtos.cs b/src/Oms.Application/Dtos/Agents/AgentDtos.cs
index 8e849e3..8781ac0 100644
--- a/src/Oms.Application/Dtos/Agents/AgentDtos.cs
+++ b/src/Oms.Application/Dtos/Agents/AgentDtos.cs
@@ -30,10 +30,16 @@ public class AgentOutput
public string BaseType { get; set; } = string.Empty;
+ /// 基数类型展示名(运费/应收)。
+ public string? BaseTypeName { get; set; }
+
public decimal CommissionRate { get; set; }
public string? SalesProductIds { get; set; }
+ /// 适用销售产品名称;空表示不限产品。
+ public List SalesProductNames { get; set; } = [];
+
public string? Remark { get; set; }
public DateTime CreateTime { get; set; }
@@ -195,6 +201,33 @@ public class AgentPortalCustomerOutput
public DateTime? AgentBindTime { get; set; }
public DateTime CreateTime { get; set; }
+
+ /// 最近下单时间(含名下子客户)。
+ public DateTime? LastOrderTime { get; set; }
+
+ /// 近 30 天运单数(含名下子客户,不含已删除)。
+ public int OrderCount30d { get; set; }
+
+ /// 待付款运单数(含名下子客户)。
+ public int PendingPaymentCount { get; set; }
+}
+
+/// 代理门户返佣明细分页筛选。
+public class AgentPortalCommissionListInput
+{
+ public int Page { get; set; } = 1;
+
+ public int PageSize { get; set; } = 50;
+
+ /// pending / paid;空=全部。
+ public string? Status { get; set; }
+
+ /// 运单号关键字。
+ public string? Keyword { get; set; }
+
+ public DateTime? CreateTimeStart { get; set; }
+
+ public DateTime? CreateTimeEnd { get; set; }
}
public class AgentPortalOrderOutput
@@ -232,3 +265,92 @@ public class AgentPortalPageInput
public string? Keyword { get; set; }
}
+
+/// 匿名校验代理编号(客户注册归因)。
+public class AgentValidateCodeOutput
+{
+ public bool Valid { get; set; }
+
+ public string? AgentCode { get; set; }
+
+ /// 脱敏代理名称,供注册页展示。
+ public string? AgentNameMasked { get; set; }
+
+ public string? Message { get; set; }
+}
+
+///
+/// 代理工作台统计概览。
+///
+public class AgentWorkplaceStatsOutput
+{
+ /// 名下主客户数。
+ public int CustomerCount { get; set; }
+
+ /// 今日代客下单数。
+ public int TodayCreated { get; set; }
+
+ /// 昨日代客下单数。
+ public int YesterdayCreated { get; set; }
+
+ /// 较昨日新增百分比。
+ public decimal? DayOverDayGrowthPercent { get; set; }
+
+ /// 待付款运单数。
+ public int PendingPayment { get; set; }
+
+ /// 运输中运单数。
+ public int Shipping { get; set; }
+
+ /// 问题件运单数。
+ public int Problematic { get; set; }
+
+ /// 派送成功运单数(全量状态桶)。
+ public int DeliverySuccess { get; set; }
+
+ /// 待结算返佣笔数。
+ public int PendingCommissionCount { get; set; }
+
+ /// 待结算返佣金额。
+ public decimal PendingCommissionAmount { get; set; }
+
+ /// 已打款返佣金额(累计)。
+ public decimal PaidCommissionAmount { get; set; }
+
+ /// 本周新增绑定主客户数(按 AgentBindTime)。
+ public int WeekNewCustomers { get; set; }
+
+ /// 派送失败运单数。
+ public int DeliveryFailed { get; set; }
+
+ /// 按 OrderStatus 分组数量。
+ public Dictionary Counts { get; set; } = new(StringComparer.OrdinalIgnoreCase);
+}
+
+///
+/// 代理工作台趋势点。
+///
+public class AgentWorkplaceTrendPoint
+{
+ public string Label { get; set; } = string.Empty;
+
+ public DateTime Start { get; set; }
+
+ public DateTime End { get; set; }
+
+ /// 区间内代客下单数。
+ public int OrderCount { get; set; }
+
+ /// 区间内计提返佣金额。
+ public decimal CommissionAmount { get; set; }
+}
+
+///
+/// 代理工作台趋势。
+///
+public class AgentWorkplaceTrendOutput
+{
+ public string Dimension { get; set; } = "day";
+
+ public List Points { get; set; } = [];
+}
diff --git a/src/Oms.Application/Dtos/Customers/CustomerOutput.cs b/src/Oms.Application/Dtos/Customers/CustomerOutput.cs
index 014262e..71dc952 100644
--- a/src/Oms.Application/Dtos/Customers/CustomerOutput.cs
+++ b/src/Oms.Application/Dtos/Customers/CustomerOutput.cs
@@ -78,7 +78,7 @@ public class CustomerOutput
public string? Remark { get; set; }
///
- /// 销售人员。
+ /// 销售人员(遗留字段,管理端已改用 AgentId)。
///
public string? Salesman { get; set; }
@@ -87,6 +87,15 @@ public class CustomerOutput
///
public string? CustomerService { get; set; }
+ /// 绑定渠道代理 Id。
+ public int? AgentId { get; set; }
+
+ /// 绑定代理编号。
+ public string? AgentCode { get; set; }
+
+ /// 绑定代理名称。
+ public string? AgentName { get; set; }
+
///
/// 客户分组。
///
diff --git a/src/Oms.Application/Dtos/Customers/CustomerPaginatedInput.cs b/src/Oms.Application/Dtos/Customers/CustomerPaginatedInput.cs
index a765c86..301170e 100644
--- a/src/Oms.Application/Dtos/Customers/CustomerPaginatedInput.cs
+++ b/src/Oms.Application/Dtos/Customers/CustomerPaginatedInput.cs
@@ -33,7 +33,7 @@ public class CustomerPaginatedInput
public CustomerGroup? CustomerGroup { get; set; }
///
- /// 销售人员。
+ /// 销售人员(遗留筛选)。
///
public string? Salesman { get; set; }
@@ -42,6 +42,9 @@ public class CustomerPaginatedInput
///
public string? CustomerService { get; set; }
+ /// 按绑定代理 Id 筛选。
+ public int? AgentId { get; set; }
+
///
/// 排序字段:createTime / updateTime / customerCode / customerName / balance。
///
diff --git a/src/Oms.Application/Dtos/Customers/CustomerPaginatedOutput.cs b/src/Oms.Application/Dtos/Customers/CustomerPaginatedOutput.cs
index 63fb35e..c20b23d 100644
--- a/src/Oms.Application/Dtos/Customers/CustomerPaginatedOutput.cs
+++ b/src/Oms.Application/Dtos/Customers/CustomerPaginatedOutput.cs
@@ -78,7 +78,7 @@ public class CustomerPaginatedOutput
public string? Remark { get; set; }
///
- /// 销售人员。
+ /// 销售人员(遗留字段,管理端已改用 AgentId)。
///
public string? Salesman { get; set; }
@@ -87,6 +87,15 @@ public class CustomerPaginatedOutput
///
public string? CustomerService { get; set; }
+ /// 绑定渠道代理 Id。
+ public int? AgentId { get; set; }
+
+ /// 绑定代理编号。
+ public string? AgentCode { get; set; }
+
+ /// 绑定代理名称。
+ public string? AgentName { get; set; }
+
///
/// 客户分组。
///
diff --git a/src/Oms.Application/Dtos/Customers/UpdateCustomerInput.cs b/src/Oms.Application/Dtos/Customers/UpdateCustomerInput.cs
index 2bd683d..7e9fc36 100644
--- a/src/Oms.Application/Dtos/Customers/UpdateCustomerInput.cs
+++ b/src/Oms.Application/Dtos/Customers/UpdateCustomerInput.cs
@@ -81,7 +81,7 @@ public class UpdateCustomerInput
public string? Remark { get; set; }
///
- /// 销售人员。
+ /// 销售人员(遗留;新流程请用 AgentCode)。
///
[StringLength(32)]
public string? Salesman { get; set; }
@@ -92,6 +92,12 @@ public class UpdateCustomerInput
[StringLength(32)]
public string? CustomerService { get; set; }
+ ///
+ /// 渠道代理编号;传空串解绑;不传则保留原绑定。仅主客户可改。
+ ///
+ [StringLength(32)]
+ public string? AgentCode { get; set; }
+
///
/// 客户分组(遗留字段,计价优先 MemberLevelId)。
///
diff --git a/src/Oms.Application/Services/Agents/AgentAdminService.cs b/src/Oms.Application/Services/Agents/AgentAdminService.cs
index a92323f..4b1b670 100644
--- a/src/Oms.Application/Services/Agents/AgentAdminService.cs
+++ b/src/Oms.Application/Services/Agents/AgentAdminService.cs
@@ -6,6 +6,7 @@ using Fake.Rbac.Application.Dtos.User;
using Fake.Rbac.Application.Services;
using Fake.Rbac.Infrastructure;
using Fake.EntityFrameworkCore;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Oms.Application.Dtos.Agents;
@@ -43,6 +44,42 @@ public class AgentAdminService : ApplicationService
private FakeRbacDbContext RbacDbContext => LazyServiceProvider.GetRequiredService();
+ ///
+ /// 匿名校验代理编号(客户注册页归因 / 手填兜底)。
+ ///
+ [AllowAnonymous]
+ [HttpGet("/agent/public/validate-code")]
+ public async Task ValidateCodeAsync([FromQuery] string code)
+ {
+ var trimmed = code?.Trim();
+ if (string.IsNullOrWhiteSpace(trimmed))
+ {
+ return new AgentValidateCodeOutput
+ {
+ Valid = false,
+ Message = "代理编号不能为空"
+ };
+ }
+
+ var agent = await AgentRepository.GetByAgentCodeAsync(trimmed);
+ if (agent == null || agent.Status != EnableStatus.Enabled)
+ {
+ return new AgentValidateCodeOutput
+ {
+ Valid = false,
+ Message = "代理编号无效或已停用"
+ };
+ }
+
+ return new AgentValidateCodeOutput
+ {
+ Valid = true,
+ AgentCode = agent.AgentCode,
+ AgentNameMasked = MaskAgentName(agent.AgentName),
+ Message = null
+ };
+ }
+
/// 分页查询代理。
[HttpPost("/agent/admin/list")]
public async Task> GetListAsync(AgentListInput input)
@@ -411,4 +448,15 @@ public class AgentAdminService : ApplicationService
return mapId.Value;
}
+
+ private static string MaskAgentName(string? name)
+ {
+ if (string.IsNullOrWhiteSpace(name))
+ {
+ return "渠道代理";
+ }
+
+ var text = name.Trim();
+ return text.Length <= 1 ? "*" : text[0] + new string('*', Math.Min(2, text.Length - 1));
+ }
}
diff --git a/src/Oms.Application/Services/Agents/AgentPortalService.cs b/src/Oms.Application/Services/Agents/AgentPortalService.cs
index ba05bf9..20c43ba 100644
--- a/src/Oms.Application/Services/Agents/AgentPortalService.cs
+++ b/src/Oms.Application/Services/Agents/AgentPortalService.cs
@@ -1,22 +1,26 @@
using System.Linq.Expressions;
using Fake.Application;
using Fake.Domain.Exceptions;
-using Fake.Security.Claims;
using Microsoft.AspNetCore.Mvc;
+using MiniExcelLibs;
using Oms.Application.Dtos.Agents;
using Oms.Application.Dtos.Shared;
using Oms.Application.Shared;
+using Oms.Domain.AgentsAggregate.Consts;
using Oms.Domain.AgentsAggregate.Entities;
using Oms.Domain.AgentsAggregate.Repositories;
+using Oms.Domain.ChannelsAggregate.Repositories;
using Oms.Domain.CustomersAggregate.Entities;
using Oms.Domain.CustomersAggregate.Repositories;
+using Oms.Domain.OrdersAggregate;
+using Oms.Domain.OrdersAggregate.Consts;
using Oms.Domain.OrdersAggregate.Entities;
using Oms.Domain.OrdersAggregate.Repositories;
namespace Oms.Application.Services.Agents;
///
-/// 渠道代理门户只读 API(名下客户 / 订单 / 返佣)。
+/// 渠道代理门户 API(名下客户 / 订单 / 返佣 / 工作台)。
///
[ApiExplorerSettings(GroupName = "OMS-Agent")]
public class AgentPortalService : ApplicationService
@@ -30,11 +34,15 @@ public class AgentPortalService : ApplicationService
private IOrderRepository OrderRepository => LazyServiceProvider.GetRequiredService();
- /// 当前代理资料。
+ private ISalesProductRepository SalesProductRepository =>
+ LazyServiceProvider.GetRequiredService();
+
+ /// 当前代理资料(含返佣规则展示字段)。
[HttpGet("/agent/portal/profile")]
public async Task GetProfileAsync()
{
var agent = await GetCurrentAgentOrThrowAsync();
+ var productNames = await ResolveSalesProductNamesAsync(agent.SalesProductIds);
return new AgentOutput
{
Id = agent.Id,
@@ -44,14 +52,16 @@ public class AgentPortalService : ApplicationService
Email = agent.Email,
Status = agent.Status,
BaseType = agent.BaseType,
+ BaseTypeName = ResolveBaseTypeName(agent.BaseType),
CommissionRate = agent.CommissionRate,
SalesProductIds = agent.SalesProductIds,
+ SalesProductNames = productNames,
Remark = agent.Remark,
CreateTime = agent.CreateTime
};
}
- /// 名下客户分页(含主客户 AgentId=我)。
+ /// 名下客户分页(含活跃度:最近下单 / 近30天票数 / 待付款数)。
[HttpPost("/agent/portal/customers/list")]
public async Task> GetCustomersAsync(AgentPortalPageInput input)
{
@@ -77,16 +87,25 @@ public class AgentPortalService : ApplicationService
[nameof(Customer.Id)] = false
});
var total = await CustomerRepository.CountAsync(predicate);
+ var activityMap = await BuildCustomerActivityMapAsync(agent.Id, entities.Select(x => x.Id).ToList());
+
return new OmsPageResult
{
- Items = entities.Select(x => new AgentPortalCustomerOutput
+ Items = entities.Select(x =>
{
- Id = x.Id,
- CustomerCode = x.CustomerCode,
- CustomerName = MaskName(x.CustomerName) ?? string.Empty,
- Phone = MaskPhone(x.Phone),
- AgentBindTime = x.AgentBindTime,
- CreateTime = x.CreateTime
+ activityMap.TryGetValue(x.Id, out var activity);
+ return new AgentPortalCustomerOutput
+ {
+ Id = x.Id,
+ CustomerCode = x.CustomerCode,
+ CustomerName = MaskName(x.CustomerName) ?? string.Empty,
+ Phone = MaskPhone(x.Phone),
+ AgentBindTime = x.AgentBindTime,
+ CreateTime = x.CreateTime,
+ LastOrderTime = activity.LastOrderTime,
+ OrderCount30d = activity.OrderCount30d,
+ PendingPaymentCount = activity.PendingPaymentCount
+ };
}).ToList(),
Total = total
};
@@ -141,7 +160,6 @@ public class AgentPortalService : ApplicationService
OrderStatus = x.OrderStatus,
ConsigneeCountryName = x.ConsigneeCountryName,
ReceivableSubtotal = x.ReceivableSubtotal,
- // 门户不返回应付:固定 null
PayableAmount = null,
CreateTime = x.CreateTime
};
@@ -150,72 +168,384 @@ public class AgentPortalService : ApplicationService
};
}
- /// 名下返佣明细。
- [HttpPost("/agent/portal/commission/list")]
- public async Task> GetCommissionListAsync(AgentPortalPageInput input)
+ ///
+ /// 代理工作台统计:名下客户、运单状态桶、待结算/已打款返佣、本周新增绑定。
+ ///
+ [HttpGet("/agent/portal/workplace/stats")]
+ public async Task GetWorkplaceStatsAsync()
{
var agent = await GetCurrentAgentOrThrowAsync();
- Expression> predicate = x => x.AgentId == agent.Id;
+ var filter = new OrderListFilter { AgentId = agent.Id };
+ var rows = await OrderRepository.GetStatusCountsByFilterAsync(filter);
+ var counts = rows
+ .Where(x => !string.Equals(x.Status, OrderStatusCodes.Deleted, StringComparison.OrdinalIgnoreCase))
+ .ToDictionary(x => x.Status, x => x.Count, StringComparer.OrdinalIgnoreCase);
+
+ int GetCount(string status) =>
+ counts.TryGetValue(status, out var value) ? value : 0;
+
+ var today = DateTime.Today;
+ var tomorrow = today.AddDays(1);
+ var yesterday = today.AddDays(-1);
+ var todayCreated = await OrderRepository.CountByFilterAndCreateTimeRangeAsync(filter, today, tomorrow);
+ var yesterdayCreated = await OrderRepository.CountByFilterAndCreateTimeRangeAsync(filter, yesterday, today);
+
+ decimal? growth = null;
+ if (yesterdayCreated > 0)
+ {
+ growth = Math.Round((todayCreated - yesterdayCreated) * 100m / yesterdayCreated, 1);
+ }
+ else if (todayCreated > 0)
+ {
+ growth = 100m;
+ }
+
+ var customerCount = await CustomerRepository.CountAsync(x =>
+ x.AgentId == agent.Id && x.ParentCustomerId == null);
+
+ var weekStart = today.AddDays(-(((int)today.DayOfWeek + 6) % 7));
+ var weekNewCustomers = await CustomerRepository.CountAsync(x =>
+ x.AgentId == agent.Id
+ && x.ParentCustomerId == null
+ && x.AgentBindTime != null
+ && x.AgentBindTime >= weekStart
+ && x.AgentBindTime < tomorrow);
+
+ var pendingDetails = await DetailRepository.GetListAsync(x =>
+ x.AgentId == agent.Id && x.Status == AgentCommissionStatusCodes.Pending);
+ var paidDetails = await DetailRepository.GetListAsync(x =>
+ x.AgentId == agent.Id && x.Status == AgentCommissionStatusCodes.Paid);
+
+ return new AgentWorkplaceStatsOutput
+ {
+ CustomerCount = customerCount,
+ TodayCreated = todayCreated,
+ YesterdayCreated = yesterdayCreated,
+ DayOverDayGrowthPercent = growth,
+ PendingPayment = GetCount(OrderStatusCodes.PendingPayment),
+ Shipping = GetCount(OrderStatusCodes.Shipping) + GetCount(OrderStatusCodes.PendingOnline),
+ Problematic = GetCount(OrderStatusCodes.Problematic),
+ DeliverySuccess = GetCount(OrderStatusCodes.DeliverySuccess),
+ DeliveryFailed = GetCount(OrderStatusCodes.DeliveryFailed),
+ PendingCommissionCount = pendingDetails.Count,
+ PendingCommissionAmount = pendingDetails.Sum(x => x.CommissionAmount),
+ PaidCommissionAmount = paidDetails.Sum(x => x.CommissionAmount),
+ WeekNewCustomers = weekNewCustomers,
+ Counts = counts,
+ };
+ }
+
+ ///
+ /// 代理工作台趋势:按日统计代客下单数与计提返佣金额。
+ ///
+ /// 天数,默认 7,最大 31。
+ [HttpGet("/agent/portal/workplace/trend")]
+ public async Task GetWorkplaceTrendAsync([FromQuery] int days = 7)
+ {
+ var agent = await GetCurrentAgentOrThrowAsync();
+ days = Math.Clamp(days, 1, 31);
+ var filter = new OrderListFilter { AgentId = agent.Id };
+ var today = DateTime.Today;
+ var rangeStart = today.AddDays(-(days - 1));
+ var rangeEnd = today.AddDays(1);
+
+ var commissions = await DetailRepository.GetListAsync(x =>
+ x.AgentId == agent.Id
+ && x.CreateTime >= rangeStart
+ && x.CreateTime < rangeEnd);
+
+ var points = new List(days);
+ for (var i = 0; i < days; i++)
+ {
+ var start = rangeStart.AddDays(i);
+ var end = start.AddDays(1);
+ var orderCount = await OrderRepository.CountByFilterAndCreateTimeRangeAsync(filter, start, end);
+ var commissionAmount = commissions
+ .Where(x => x.CreateTime >= start && x.CreateTime < end)
+ .Sum(x => x.CommissionAmount);
+ points.Add(new AgentWorkplaceTrendPoint
+ {
+ Label = start.ToString("MM-dd"),
+ Start = start,
+ End = end,
+ OrderCount = orderCount,
+ CommissionAmount = commissionAmount,
+ });
+ }
+
+ return new AgentWorkplaceTrendOutput
+ {
+ Dimension = "day",
+ Points = points,
+ };
+ }
+
+ /// 名下返佣明细(支持状态 / 运单号 / 计提时间筛选)。
+ [HttpPost("/agent/portal/commission/list")]
+ public async Task> GetCommissionListAsync(
+ AgentPortalCommissionListInput input)
+ {
+ var agent = await GetCurrentAgentOrThrowAsync();
+ var details = await QueryCommissionDetailsAsync(agent, input);
var page = OmsDocHelper.NormalizePage(input.Page);
var pageSize = OmsDocHelper.NormalizePageSize(input.PageSize);
- var entities = await DetailRepository.GetPagedListAsync(
- predicate,
- page,
- pageSize,
- new Dictionary
- {
- [nameof(AgentCommissionDetail.CreateTime)] = false,
- [nameof(AgentCommissionDetail.Id)] = false
- });
- var total = await DetailRepository.CountAsync(predicate);
-
- var customerIds = entities.Select(x => x.CustomerId).Distinct().ToList();
- var orderIds = entities.Select(x => x.OrderId).Distinct().ToList();
- var customers = customerIds.Count == 0
- ? []
- : await CustomerRepository.GetListAsync(x => customerIds.Contains(x.Id));
- var orders = orderIds.Count == 0
- ? []
- : await OrderRepository.GetListAsync(x => orderIds.Contains(x.Id));
- var customerMap = customers.ToDictionary(x => x.Id);
- var orderMap = orders.ToDictionary(x => x.Id);
+ var total = details.Count;
+ var pageItems = details
+ .Skip((page - 1) * pageSize)
+ .Take(pageSize)
+ .ToList();
return new OmsPageResult
{
- Items = entities.Select(x =>
- {
- customerMap.TryGetValue(x.CustomerId, out var customer);
- orderMap.TryGetValue(x.OrderId, out var order);
- return new AgentCommissionDetailOutput
- {
- Id = x.Id,
- AgentId = x.AgentId,
- AgentCode = agent.AgentCode,
- AgentName = agent.AgentName,
- OrderId = x.OrderId,
- ServiceNo = order?.ServiceNo,
- CustomerId = x.CustomerId,
- CustomerCode = customer?.CustomerCode,
- CustomerName = MaskName(customer?.CustomerName),
- SalesProductId = x.SalesProductId,
- BaseType = x.BaseType,
- BaseAmount = x.BaseAmount,
- CommissionRate = x.CommissionRate,
- CommissionAmount = x.CommissionAmount,
- Status = x.Status,
- TriggerOrderStatus = x.TriggerOrderStatus,
- PaidTime = x.PaidTime,
- Remark = x.Remark,
- CreateTime = x.CreateTime
- };
- }).ToList(),
+ Items = await MapCommissionOutputsAsync(agent, pageItems),
Total = total
};
}
+ /// 导出名下返佣明细(Excel,最多 5000 条)。
+ [HttpPost("/agent/portal/commission/export")]
+ public async Task ExportCommissionAsync(AgentPortalCommissionListInput input)
+ {
+ var agent = await GetCurrentAgentOrThrowAsync();
+ var details = await QueryCommissionDetailsAsync(agent, input);
+ const int maxRows = 5000;
+ if (details.Count > maxRows)
+ {
+ throw new BusinessException($"导出结果超过 {maxRows} 条(当前 {details.Count}),请缩小筛选条件后再导出");
+ }
+
+ var outputs = await MapCommissionOutputsAsync(agent, details);
+ var rows = outputs.Select(x => new
+ {
+ 运单号 = x.ServiceNo,
+ 客户编号 = x.CustomerCode,
+ 客户名称 = x.CustomerName,
+ 基数类型 = ResolveBaseTypeName(x.BaseType),
+ 基数金额 = x.BaseAmount,
+ 返佣比例 = x.CommissionRate,
+ 返佣金额 = x.CommissionAmount,
+ 状态 = string.Equals(x.Status, AgentCommissionStatusCodes.Paid, StringComparison.OrdinalIgnoreCase)
+ ? "已打款"
+ : "待结算",
+ 触发状态 = x.TriggerOrderStatus,
+ 计提时间 = x.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"),
+ 打款时间 = x.PaidTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "",
+ }).ToList();
+
+ await using var stream = new MemoryStream();
+ await MiniExcel.SaveAsAsync(stream, rows);
+ return new FileContentResult(
+ stream.ToArray(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
+ {
+ FileDownloadName = $"agent-commission-{DateTime.Now:yyyyMMddHHmmss}.xlsx"
+ };
+ }
+
+ private async Task> QueryCommissionDetailsAsync(
+ Agent agent,
+ AgentPortalCommissionListInput input)
+ {
+ var status = input.Status?.Trim();
+ var keyword = input.Keyword?.Trim();
+ var start = input.CreateTimeStart;
+ var end = input.CreateTimeEnd;
+
+ Expression> predicate = x => x.AgentId == agent.Id;
+ if (!string.IsNullOrWhiteSpace(status))
+ {
+ predicate = x => x.AgentId == agent.Id && x.Status == status;
+ }
+
+ var list = await DetailRepository.GetListAsync(predicate);
+ if (start.HasValue)
+ {
+ list = list.Where(x => x.CreateTime >= start.Value).ToList();
+ }
+
+ if (end.HasValue)
+ {
+ var endExclusive = end.Value.Date.AddDays(1);
+ list = list.Where(x => x.CreateTime < endExclusive).ToList();
+ }
+
+ if (!string.IsNullOrWhiteSpace(keyword))
+ {
+ var orderIds = list.Select(x => x.OrderId).Distinct().ToList();
+ var orders = orderIds.Count == 0
+ ? []
+ : await OrderRepository.GetListAsync(x => orderIds.Contains(x.Id));
+ var matchedOrderIds = orders
+ .Where(o => o.ServiceNo.Contains(keyword, StringComparison.OrdinalIgnoreCase)
+ || (o.TrackNo != null && o.TrackNo.Contains(keyword, StringComparison.OrdinalIgnoreCase)))
+ .Select(o => o.Id)
+ .ToHashSet();
+ list = list.Where(x => matchedOrderIds.Contains(x.OrderId)).ToList();
+ }
+
+ return list
+ .OrderByDescending(x => x.CreateTime)
+ .ThenByDescending(x => x.Id)
+ .ToList();
+ }
+
+ private async Task> MapCommissionOutputsAsync(
+ Agent agent,
+ IReadOnlyCollection entities)
+ {
+ if (entities.Count == 0)
+ {
+ return [];
+ }
+
+ var customerIds = entities.Select(x => x.CustomerId).Distinct().ToList();
+ var orderIds = entities.Select(x => x.OrderId).Distinct().ToList();
+ var customers = await CustomerRepository.GetListAsync(x => customerIds.Contains(x.Id));
+ var orders = await OrderRepository.GetListAsync(x => orderIds.Contains(x.Id));
+ var customerMap = customers.ToDictionary(x => x.Id);
+ var orderMap = orders.ToDictionary(x => x.Id);
+
+ return entities.Select(x =>
+ {
+ customerMap.TryGetValue(x.CustomerId, out var customer);
+ orderMap.TryGetValue(x.OrderId, out var order);
+ return new AgentCommissionDetailOutput
+ {
+ Id = x.Id,
+ AgentId = x.AgentId,
+ AgentCode = agent.AgentCode,
+ AgentName = agent.AgentName,
+ OrderId = x.OrderId,
+ ServiceNo = order?.ServiceNo,
+ CustomerId = x.CustomerId,
+ CustomerCode = customer?.CustomerCode,
+ CustomerName = MaskName(customer?.CustomerName),
+ SalesProductId = x.SalesProductId,
+ BaseType = x.BaseType,
+ BaseAmount = x.BaseAmount,
+ CommissionRate = x.CommissionRate,
+ CommissionAmount = x.CommissionAmount,
+ Status = x.Status,
+ TriggerOrderStatus = x.TriggerOrderStatus,
+ PaidTime = x.PaidTime,
+ Remark = x.Remark,
+ CreateTime = x.CreateTime
+ };
+ }).ToList();
+ }
+
+ private async Task>
+ BuildCustomerActivityMapAsync(int agentId, List mainCustomerIds)
+ {
+ var result = mainCustomerIds.ToDictionary(
+ id => id,
+ _ => ((DateTime?)null, 0, 0));
+ if (mainCustomerIds.Count == 0)
+ {
+ return result;
+ }
+
+ var children = await CustomerRepository.GetListAsync(x =>
+ x.ParentCustomerId != null && mainCustomerIds.Contains(x.ParentCustomerId.Value));
+ var mainByCustomerId = new Dictionary();
+ foreach (var id in mainCustomerIds)
+ {
+ mainByCustomerId[id] = id;
+ }
+
+ foreach (var child in children)
+ {
+ if (child.ParentCustomerId is > 0)
+ {
+ mainByCustomerId[child.Id] = child.ParentCustomerId.Value;
+ }
+ }
+
+ var allIds = mainByCustomerId.Keys.ToList();
+ var since30 = DateTime.Today.AddDays(-30);
+ var orders = await OrderRepository.GetListAsync(x =>
+ x.AgentId == agentId
+ && x.CustomerId != null
+ && allIds.Contains(x.CustomerId.Value)
+ && x.OrderStatus != OrderStatusCodes.Deleted);
+
+ foreach (var group in orders.GroupBy(o => mainByCustomerId[o.CustomerId!.Value]))
+ {
+ var list = group.ToList();
+ result[group.Key] = (
+ list.Max(o => (DateTime?)o.CreateTime),
+ list.Count(o => o.CreateTime >= since30),
+ list.Count(o => string.Equals(
+ o.OrderStatus,
+ OrderStatusCodes.PendingPayment,
+ StringComparison.OrdinalIgnoreCase)));
+ }
+
+ return result;
+ }
+
+ private async Task> ResolveSalesProductNamesAsync(string? salesProductIds)
+ {
+ var ids = ParseSalesProductIds(salesProductIds);
+ if (ids.Count == 0)
+ {
+ return [];
+ }
+
+ var products = await SalesProductRepository.GetListAsync(x => ids.Contains(x.Id));
+ var map = products.ToDictionary(x => x.Id);
+ return ids
+ .Select(id => map.TryGetValue(id, out var p) ? $"{p.ProductName}({p.ProductCode})" : $"#{id}")
+ .ToList();
+ }
+
+ private static List ParseSalesProductIds(string? raw)
+ {
+ if (string.IsNullOrWhiteSpace(raw))
+ {
+ return [];
+ }
+
+ var text = raw.Trim();
+ if (text.StartsWith('['))
+ {
+ try
+ {
+ var arr = global::System.Text.Json.JsonSerializer.Deserialize>(text);
+ return arr?.Where(x => x > 0).Distinct().ToList() ?? [];
+ }
+ catch
+ {
+ // fall through
+ }
+ }
+
+ return text
+ .Split([',', ';', '|', ' '], StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
+ .Select(x => int.TryParse(x, out var id) ? id : 0)
+ .Where(x => x > 0)
+ .Distinct()
+ .ToList();
+ }
+
+ private static string ResolveBaseTypeName(string? baseType)
+ {
+ if (string.Equals(baseType, "receivable", StringComparison.OrdinalIgnoreCase))
+ {
+ return "应收";
+ }
+
+ if (string.Equals(baseType, "freight", StringComparison.OrdinalIgnoreCase))
+ {
+ return "运费";
+ }
+
+ return string.IsNullOrWhiteSpace(baseType) ? "运费" : baseType;
+ }
+
private async Task GetCurrentAgentOrThrowAsync()
{
- var mapId = CurrentUser.GetId();
+ var mapId = OmsSessionHelper.ResolveMapUserId(CurrentUser);
if (mapId <= 0)
{
throw new BusinessException("代理未登录");
diff --git a/src/Oms.Application/Services/Customers/CustomerService.cs b/src/Oms.Application/Services/Customers/CustomerService.cs
index fe27eed..19ab5ac 100644
--- a/src/Oms.Application/Services/Customers/CustomerService.cs
+++ b/src/Oms.Application/Services/Customers/CustomerService.cs
@@ -78,6 +78,8 @@ public class CustomerService : ApplicationService
entities.SelectMany(x => new[] { x.CreateUserId, x.UpdateUserId }));
var memberLevelNameMap = await ResolveMemberLevelNameMapAsync(
entities.Where(x => x.MemberLevelId.HasValue).Select(x => x.MemberLevelId!.Value));
+ var agentMap = await ResolveAgentDisplayMapAsync(
+ entities.Where(x => x.AgentId.HasValue).Select(x => x.AgentId!.Value));
var items = entities.Select(entity =>
{
var output = ObjectMapper.Map(entity);
@@ -90,6 +92,7 @@ public class CustomerService : ApplicationService
output.MemberLevelName = levelName;
}
+ FillAgentDisplay(output, entity.AgentId, agentMap);
return output;
}).ToList();
@@ -121,6 +124,12 @@ public class CustomerService : ApplicationService
output.MemberLevelName = level?.LevelName;
}
+ if (entity.AgentId.HasValue)
+ {
+ var agentMap = await ResolveAgentDisplayMapAsync([entity.AgentId.Value]);
+ FillAgentDisplay(output, entity.AgentId, agentMap);
+ }
+
return output;
}
@@ -401,6 +410,11 @@ public class CustomerService : ApplicationService
entity.CustomerService = NormalizeOptionalText(input.CustomerService);
}
+ if (input.AgentCode != null)
+ {
+ await AgentBinder.ApplyAgentBindingAsync(entity, input.AgentCode, AgentRepository);
+ }
+
if (input.CustomerGroup.HasValue)
{
entity.CustomerGroup = input.CustomerGroup;
@@ -500,6 +514,8 @@ public class CustomerService : ApplicationService
var statusValue = input.Status.GetValueOrDefault();
var hasCustomerGroupFilter = input.CustomerGroup.HasValue;
var customerGroupValue = input.CustomerGroup.GetValueOrDefault();
+ var hasAgentFilter = input.AgentId is > 0;
+ var agentId = input.AgentId.GetValueOrDefault();
return customer =>
(string.IsNullOrWhiteSpace(keyword) ||
@@ -510,7 +526,47 @@ public class CustomerService : ApplicationService
(!hasStatusFilter || customer.Status == statusValue) &&
(!hasCustomerGroupFilter || customer.CustomerGroup == customerGroupValue) &&
(string.IsNullOrWhiteSpace(salesman) || customer.Salesman == salesman) &&
- (string.IsNullOrWhiteSpace(customerService) || customer.CustomerService == customerService);
+ (string.IsNullOrWhiteSpace(customerService) || customer.CustomerService == customerService) &&
+ (!hasAgentFilter || customer.AgentId == agentId);
+ }
+
+ private async Task> ResolveAgentDisplayMapAsync(
+ IEnumerable agentIds)
+ {
+ var ids = agentIds.Distinct().ToList();
+ if (ids.Count == 0)
+ {
+ return new Dictionary();
+ }
+
+ var agents = await AgentRepository.GetListAsync(x => ids.Contains(x.Id));
+ return agents.ToDictionary(x => x.Id, x => (x.AgentCode, x.AgentName));
+ }
+
+ private static void FillAgentDisplay(
+ CustomerPaginatedOutput output,
+ int? agentId,
+ IReadOnlyDictionary agentMap)
+ {
+ output.AgentId = agentId;
+ if (agentId.HasValue && agentMap.TryGetValue(agentId.Value, out var agent))
+ {
+ output.AgentCode = agent.Code;
+ output.AgentName = agent.Name;
+ }
+ }
+
+ private static void FillAgentDisplay(
+ CustomerOutput output,
+ int? agentId,
+ IReadOnlyDictionary agentMap)
+ {
+ output.AgentId = agentId;
+ if (agentId.HasValue && agentMap.TryGetValue(agentId.Value, out var agent))
+ {
+ output.AgentCode = agent.Code;
+ output.AgentName = agent.Name;
+ }
}
private static Dictionary BuildCustomerSortDictionary(CustomerPaginatedInput input)
diff --git a/src/Oms.Application/Services/Orders/OrderService.Helpers.cs b/src/Oms.Application/Services/Orders/OrderService.Helpers.cs
index c64ecff..b1ed712 100644
--- a/src/Oms.Application/Services/Orders/OrderService.Helpers.cs
+++ b/src/Oms.Application/Services/Orders/OrderService.Helpers.cs
@@ -1208,6 +1208,12 @@ public partial class OrderService
return;
}
+ if (OmsSessionHelper.IsAgentLogin(CurrentUser))
+ {
+ await ApplyAgentOrderScopeAsync(filter);
+ return;
+ }
+
var userGuidRaw = CurrentUser.FindClaimValueOrNull(global::System.Security.Claims.ClaimTypes.NameIdentifier);
if (string.IsNullOrWhiteSpace(userGuidRaw) || !Guid.TryParse(userGuidRaw, out var userGuid))
{
@@ -1217,4 +1223,41 @@ public partial class OrderService
var context = await DataScopeBuilder.BuildAsync(userGuid, DataScopeApplier.OrderResourceCode);
DataScopeApplier.ApplyToOrderListFilter(filter, context);
}
+
+ ///
+ /// 渠道代理门户:列表仅可见下单快照 AgentId=本代理的运单。
+ ///
+ private async Task ApplyAgentOrderScopeAsync(OrderListFilter filter)
+ {
+ var agentRepository =
+ LazyServiceProvider.GetRequiredService();
+ var userId = OmsSessionHelper.ResolveMapUserId(CurrentUser);
+ if (userId <= 0)
+ {
+ throw new BusinessException("代理未登录");
+ }
+
+ var agent = await agentRepository.GetByUserIdAsync(userId);
+ if (agent == null)
+ {
+ throw new BusinessException("代理不存在");
+ }
+
+ filter.AgentId = agent.Id;
+
+ if (filter.CustomerId is > 0)
+ {
+ var customer = await CustomerRepository.FirstOrDefaultAsync(x => x.Id == filter.CustomerId.Value);
+ if (customer == null)
+ {
+ throw new BusinessException("客户不存在");
+ }
+
+ await OmsSessionHelper.EnsureAgentOwnsCustomerAsync(
+ CustomerRepository,
+ agentRepository,
+ CurrentUser,
+ customer);
+ }
+ }
}
diff --git a/src/Oms.Application/Services/Orders/OrderService.ParcelBilling.cs b/src/Oms.Application/Services/Orders/OrderService.ParcelBilling.cs
index a2237c3..e7bfc51 100644
--- a/src/Oms.Application/Services/Orders/OrderService.ParcelBilling.cs
+++ b/src/Oms.Application/Services/Orders/OrderService.ParcelBilling.cs
@@ -3508,13 +3508,19 @@ public partial class OrderService
}
///
- /// 从会话解析有效客户(客户登录自动补全;管理员须传 customerId)。
+ /// 从会话解析有效客户(客户登录自动补全;管理员/代理须传 customerId;代理仅限名下客户)。
///
- private Task ResolveEffectiveCustomerAsync(int? requestedCustomerId = null) =>
- OmsSessionHelper.ResolveSessionCustomerAsync(
+ private Task ResolveEffectiveCustomerAsync(int? requestedCustomerId = null)
+ {
+ var agentRepository = OmsSessionHelper.IsAgentLogin(CurrentUser)
+ ? LazyServiceProvider.GetRequiredService()
+ : null;
+ return OmsSessionHelper.ResolveSessionCustomerAsync(
CustomerRepository,
CurrentUser,
- requestedCustomerId);
+ requestedCustomerId,
+ agentRepository);
+ }
private async Task ApplyMarketingSnapshotOnCreateAsync(Order order, int? couponInstanceId)
{
diff --git a/src/Oms.Application/Services/Orders/OrderService.cs b/src/Oms.Application/Services/Orders/OrderService.cs
index 1938010..154f1b7 100644
--- a/src/Oms.Application/Services/Orders/OrderService.cs
+++ b/src/Oms.Application/Services/Orders/OrderService.cs
@@ -704,6 +704,25 @@ public partial class OrderService : ApplicationService
{
input.CustomerId = await ResolvePriceCheckCustomerIdAsync();
}
+ else if (OmsSessionHelper.IsAgentLogin(CurrentUser))
+ {
+ // 代理代客查价:仅允许名下绑定客户
+ var agentRepository =
+ LazyServiceProvider.GetRequiredService();
+ var customer = await CustomerRepository.FirstOrDefaultAsync(x => x.Id == input.CustomerId.Value);
+ if (customer == null)
+ {
+ throw new BusinessException("客户不存在");
+ }
+
+ await OmsSessionHelper.EnsureAgentOwnsCustomerAsync(
+ CustomerRepository,
+ agentRepository,
+ CurrentUser,
+ customer);
+ input.CustomerId =
+ await MarketingCustomerHelper.ResolveMarketingMainCustomerIdAsync(CustomerRepository, customer);
+ }
return await BuildPriceCheckResultAsync(input);
}
@@ -1335,6 +1354,20 @@ public partial class OrderService : ApplicationService
private async Task EnsureCustomerCanAccessOrderAsync(Order order)
{
+ if (OmsSessionHelper.IsAgentLogin(CurrentUser))
+ {
+ var agentRepository =
+ LazyServiceProvider.GetRequiredService();
+ var userId = OmsSessionHelper.ResolveMapUserId(CurrentUser);
+ var agent = userId > 0 ? await agentRepository.GetByUserIdAsync(userId) : null;
+ if (agent == null || order.AgentId != agent.Id)
+ {
+ throw new BusinessException("订单不存在");
+ }
+
+ return;
+ }
+
var customerId = await OmsSessionHelper.ResolveListCustomerIdAsync(
CustomerRepository,
CurrentUser,
diff --git a/src/Oms.Application/Shared/AgentBinder.cs b/src/Oms.Application/Shared/AgentBinder.cs
index d4abe01..0613642 100644
--- a/src/Oms.Application/Shared/AgentBinder.cs
+++ b/src/Oms.Application/Shared/AgentBinder.cs
@@ -37,4 +37,36 @@ public static class AgentBinder
entity.AgentId = agent.Id;
entity.AgentBindTime = DateTime.Now;
}
+
+ ///
+ /// 运营改绑:按代理编号覆盖;空串解绑。子客户不可改(跟主客户)。
+ ///
+ public static async Task ApplyAgentBindingAsync(
+ Customer entity,
+ string? agentCode,
+ IAgentRepository agentRepository,
+ CancellationToken cancellationToken = default)
+ {
+ if (entity.ParentCustomerId.HasValue)
+ {
+ throw new BusinessException("请改绑主客户");
+ }
+
+ var code = agentCode?.Trim();
+ if (string.IsNullOrEmpty(code))
+ {
+ entity.AgentId = null;
+ entity.AgentBindTime = null;
+ return;
+ }
+
+ var agent = await agentRepository.GetByAgentCodeAsync(code, cancellationToken);
+ if (agent == null || agent.Status != EnableStatus.Enabled)
+ {
+ throw new BusinessException("代理编号无效或已停用");
+ }
+
+ entity.AgentId = agent.Id;
+ entity.AgentBindTime = DateTime.Now;
+ }
}
diff --git a/src/Oms.Application/Shared/OmsSessionHelper.cs b/src/Oms.Application/Shared/OmsSessionHelper.cs
index c5ff2b4..0351e04 100644
--- a/src/Oms.Application/Shared/OmsSessionHelper.cs
+++ b/src/Oms.Application/Shared/OmsSessionHelper.cs
@@ -1,13 +1,14 @@
using System.Security.Claims;
using Fake.Application;
using Fake.Users;
+using Oms.Domain.AgentsAggregate.Repositories;
using Oms.Domain.CustomersAggregate.Entities;
using Oms.Domain.CustomersAggregate.Repositories;
namespace Oms.Application.Shared;
///
-/// 从 JWT Claims 解析当前会话类型(管理员 / 客户)。
+/// 从 JWT Claims 解析当前会话类型(管理员 / 客户 / 渠道代理)。
///
public static class OmsSessionHelper
{
@@ -22,7 +23,9 @@ public static class OmsSessionHelper
public const string MapIdClaim = "mapId";
private const string CustomerLoginType = "1";
+ private const string AgentLoginType = "2";
private const string CustomerRoleName = "Customer";
+ private const string AgentRoleName = "Agent";
///
/// 当前会话是否为客户门户登录。
@@ -43,6 +46,24 @@ public static class OmsSessionHelper
return string.Equals(role, CustomerRoleName, StringComparison.OrdinalIgnoreCase);
}
+ ///
+ /// 当前会话是否为渠道代理门户登录。
+ ///
+ public static bool IsAgentLogin(ICurrentUser currentUser)
+ {
+ if (string.Equals(
+ currentUser.FindClaimOrNull(LoginTypeClaim)?.Value,
+ AgentLoginType,
+ StringComparison.Ordinal))
+ {
+ return true;
+ }
+
+ var role = currentUser.FindClaimOrNull(ClaimTypes.Role)?.Value
+ ?? currentUser.FindClaimOrNull("role")?.Value;
+ return string.Equals(role, AgentRoleName, StringComparison.OrdinalIgnoreCase);
+ }
+
///
/// 解析当前会话的 RBAC mapId(user.userid)。
/// JWT nameidentifier 多为 Guid,GetId<int> 常为 0,需回退读 mapId claim。
@@ -85,12 +106,14 @@ public static class OmsSessionHelper
TryGetCustomerMapId(currentUser);
///
- /// 解析当前会话对应的 t_customer 记录(客户按 UserId=mapId;管理员可按 CustomerId 代提交)。
+ /// 解析当前会话对应的 t_customer 记录(客户按 UserId=mapId;管理员/代理可按 CustomerId 代提交)。
+ /// 代理须传入 ,且仅允许操作名下绑定客户。
///
public static async Task ResolveSessionCustomerAsync(
ICustomerRepository customerRepository,
ICurrentUser currentUser,
- int? requestedCustomerId = null)
+ int? requestedCustomerId = null,
+ IAgentRepository? agentRepository = null)
{
var mapId = TryGetCustomerMapId(currentUser);
if (mapId.HasValue)
@@ -121,9 +144,53 @@ public static class OmsSessionHelper
throw new BusinessException("客户不存在");
}
+ if (IsAgentLogin(currentUser))
+ {
+ await EnsureAgentOwnsCustomerAsync(customerRepository, agentRepository, currentUser, customer);
+ }
+
return customer;
}
+ ///
+ /// 渠道代理仅可操作名下绑定客户(主客户 AgentId=本代理;子客户跟主客户)。
+ ///
+ public static async Task EnsureAgentOwnsCustomerAsync(
+ ICustomerRepository customerRepository,
+ IAgentRepository? agentRepository,
+ ICurrentUser currentUser,
+ Customer customer)
+ {
+ if (agentRepository == null)
+ {
+ throw new BusinessException("代理会话缺少代理仓储");
+ }
+
+ var userId = ResolveMapUserId(currentUser);
+ if (userId <= 0)
+ {
+ throw new BusinessException("代理未登录");
+ }
+
+ var agent = await agentRepository.GetByUserIdAsync(userId);
+ if (agent == null)
+ {
+ throw new BusinessException("代理不存在");
+ }
+
+ int? bindAgentId = customer.AgentId;
+ if (customer.ParentCustomerId is > 0)
+ {
+ var main = await customerRepository.FirstOrDefaultAsync(x => x.Id == customer.ParentCustomerId.Value);
+ bindAgentId = main?.AgentId;
+ }
+
+ if (bindAgentId != agent.Id)
+ {
+ throw new BusinessException("只能为名下绑定客户操作");
+ }
+ }
+
///
/// 客户登录时强制返回 t_customer.Id;管理员返回入参 customerId。
///
diff --git a/src/Oms.Domain/OrdersAggregate/OrderListFilter.cs b/src/Oms.Domain/OrdersAggregate/OrderListFilter.cs
index 0cbfc0e..419d536 100644
--- a/src/Oms.Domain/OrdersAggregate/OrderListFilter.cs
+++ b/src/Oms.Domain/OrdersAggregate/OrderListFilter.cs
@@ -34,6 +34,11 @@ public class OrderListFilter
public int? CustomerId { get; set; }
+ ///
+ /// 渠道代理 Id(门户列表强制按下单快照 AgentId 过滤)。
+ ///
+ public int? AgentId { get; set; }
+
///
/// 发货仓 ID(订单或绑定行所属仓)。
///
diff --git a/src/Oms.SqlSugarCore/Orders/OrderRepository.cs b/src/Oms.SqlSugarCore/Orders/OrderRepository.cs
index df1e482..9ef3900 100644
--- a/src/Oms.SqlSugarCore/Orders/OrderRepository.cs
+++ b/src/Oms.SqlSugarCore/Orders/OrderRepository.cs
@@ -47,6 +47,12 @@ public class OrderRepository : OmsSqlSugarRepository, IOrderRepository, I
query = query.Where(x => x.CustomerId == customerId);
}
+ if (filter.AgentId.HasValue)
+ {
+ var agentId = filter.AgentId.Value;
+ query = query.Where(x => x.AgentId == agentId);
+ }
+
var status = filter.Status?.Trim();
var isDeletedTab = string.Equals(status, OrderStatusCodes.Deleted, StringComparison.OrdinalIgnoreCase);
if (isDeletedTab)
@@ -1503,6 +1509,7 @@ public class OrderRepository : OmsSqlSugarRepository, IOrderRepository, I
CreateTimeStart = filter.CreateTimeStart,
CreateTimeEnd = filter.CreateTimeEnd,
CustomerId = filter.CustomerId,
+ AgentId = filter.AgentId,
FieldFilters = filter.FieldFilters,
SortField = filter.SortField,
SortOrder = filter.SortOrder,
@@ -1549,6 +1556,7 @@ public class OrderRepository : OmsSqlSugarRepository, IOrderRepository, I
CreateTimeStart = filter.CreateTimeStart,
CreateTimeEnd = filter.CreateTimeEnd,
CustomerId = filter.CustomerId,
+ AgentId = filter.AgentId,
WarehouseId = filter.WarehouseId,
FulfillmentType = filter.FulfillmentType,
StockBindStatus = filter.StockBindStatus,