| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- using Admin.NET.Plugin.AiDOP.Infrastructure;
- using Admin.NET.Plugin.AiDOP.MaterialWarehouse.Dto;
- using Microsoft.Extensions.Options;
- namespace Admin.NET.Plugin.AiDOP.MaterialWarehouse;
- /// <summary>
- /// S5 库存查询:经 IInventoryBalanceReader,优先 LIVE_165,回落 mdp_std_inventory。
- /// Domain 由 SourceDomainTenantResolver 反查,禁止回落 8010。
- /// </summary>
- [ApiDescriptionSettings(Order = 300, Description = "库存查询")]
- [Route("api/S5StockQuery")]
- [NonUnify]
- public class StockQueryService : IDynamicApiController, ITransient
- {
- private const long MainTenantId = 1300000000001L;
- private readonly ISqlSugarClient _db;
- private readonly UserManager _userManager;
- private readonly IInventoryBalanceReader _balanceReader;
- private readonly SourceDomainTenantResolver _domainTenant;
- private readonly AidopInventoryOptions _opt;
- public StockQueryService(
- ISqlSugarClient db,
- UserManager userManager,
- IInventoryBalanceReader balanceReader,
- SourceDomainTenantResolver domainTenant,
- IOptions<AidopInventoryOptions> opt)
- {
- _db = db;
- _userManager = userManager;
- _balanceReader = balanceReader;
- _domainTenant = domainTenant;
- _opt = opt.Value;
- }
- private long ResolveTenantOrThrow()
- {
- var tid = _userManager.TenantId;
- if (tid <= 0)
- throw Oops.Oh("无法确定当前租户,请重新登录或选择目标租户");
- if (_userManager.SuperAdmin && tid == MainTenantId)
- throw Oops.Oh("超级管理员操作前必须选择目标租户");
- return tid;
- }
- private async Task<string> ResolveDomainOrThrowAsync(long tenantId, CancellationToken ct = default)
- {
- var sourceCode = string.IsNullOrWhiteSpace(_opt.SourceCode) ? "DOPDEMORQ_SQLSERVER" : _opt.SourceCode.Trim();
- try
- {
- return await _domainTenant.ResolveDomainAsync(sourceCode, tenantId, ct);
- }
- catch (Exception ex)
- {
- throw Oops.Oh($"无法解析当前租户 Domain 映射:{ex.Message}");
- }
- }
- private const string LocTypeExpr = "CASE WHEN t.typed='VMI' THEN 'VMI' WHEN t.typed='Supp' THEN 'O库' ELSE '' END";
- [DisplayName("库存查询列表")]
- [HttpGet("list")]
- public async Task<object> GetList([FromQuery] StockQueryListInput input, CancellationToken ct)
- {
- var tenantId = ResolveTenantOrThrow();
- var domain = await ResolveDomainOrThrowAsync(tenantId, ct);
- var page = await _balanceReader.QueryPageAsync(new InventoryBalanceQuery
- {
- TenantId = tenantId,
- Domain = domain,
- Type = input.Type,
- Location = input.Location,
- MaterialCode = input.MaterialCode,
- BatchNo = input.BatchNo,
- StockGt = input.StockGt,
- UnrestrictedGt = input.UnrestrictedGt,
- QcStockGt = input.QcStockGt,
- FrozenGt = input.FrozenGt,
- Page = input.Page,
- PageSize = input.PageSize
- }, ct);
- return new
- {
- total = page.Total,
- page = page.Page,
- pageSize = page.PageSize,
- list = page.List.Select(x => new StockQueryListRow
- {
- Type = x.Type,
- Location = x.Location,
- LocationName = x.LocationName,
- MaterialCode = x.MaterialCode,
- MaterialName = x.MaterialName,
- BatchNo = x.BatchNo,
- Shelf = x.Shelf,
- Version = x.Version,
- UnrestrictedStock = x.UnrestrictedStock,
- QcStock = x.QcStock,
- FrozenStock = x.FrozenStock,
- QtyOnHand = x.QtyOnHand,
- Unit = x.Unit,
- Supplier = x.Supplier
- }).ToList(),
- grandTotalQtyOnHand = page.GrandTotalQtyOnHand,
- grandUnrestricted = page.GrandUnrestricted,
- grandQc = page.GrandQc,
- grandFrozen = page.GrandFrozen,
- dataSource = page.DataSource,
- asOf = page.AsOf,
- isRealtime = page.IsRealtime
- };
- }
- [DisplayName("库存查询类型选项")]
- [HttpGet("type-options")]
- public async Task<object> GetTypeOptions(CancellationToken ct)
- {
- var tenantId = ResolveTenantOrThrow();
- var domain = await ResolveDomainOrThrowAsync(tenantId, ct);
- var list = await _db.Ado.SqlQueryAsync<StockQueryTypeOption>(
- $"""
- SELECT DISTINCT {LocTypeExpr.Replace("t.typed", "typed")} AS Val
- FROM LocationMaster
- WHERE Domain = @Domain AND tenant_id = @TenantId AND {LocTypeExpr.Replace("t.typed", "typed")} <> ''
- ORDER BY Val
- """,
- new List<SugarParameter> { new("@Domain", domain), new("@TenantId", tenantId) });
- return list;
- }
- [DisplayName("库存查询库位选项")]
- [HttpGet("location-options")]
- public async Task<object> GetLocationOptions(CancellationToken ct)
- {
- var tenantId = ResolveTenantOrThrow();
- var domain = await ResolveDomainOrThrowAsync(tenantId, ct);
- var list = await _db.Ado.SqlQueryAsync<StockQueryLocationOption>(
- """
- SELECT location AS Val, descr AS Label
- FROM LocationMaster
- WHERE Domain = @Domain AND tenant_id = @TenantId AND IFNULL(location,'') <> ''
- ORDER BY location
- """,
- new List<SugarParameter> { new("@Domain", domain), new("@TenantId", tenantId) });
- return list;
- }
- }
|