| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- using Admin.NET.Plugin.AiDOP.FinishedWarehouse.Dto;
- namespace Admin.NET.Plugin.AiDOP.FinishedWarehouse;
- /// <summary>
- /// S7 生产入库单列表 只读 list 服务。
- ///
- /// 数据源(2026-07-30 起):DOP 数据中台标准层 mdp_std_production_receipt(扁平,一行=一条 NbrDetail 明细)。
- /// 该 std 由 ProductionReceiptMdpSyncService 从 aidopdev.NbrMaster/NbrDetail Type='WOI'(生产入库)同步标准化而来,且已双源(dopdemorq)。
- /// S7 成品入库与 S5 生产收货读同一批 WOI 数据(过滤逐字相同)→ CTO 拍板复用该 std、不另建管线/实体(S5-list 与 S7-list 展示同一 WOI 单据的两个视角)。
- ///
- /// 口径映射(std 列 → 列表列):入库单号=nbr;行号=line;入库日期=receipt_date;状态=status;入库类型=remark;
- /// 生产线=prod_line;工单号=work_ord;ERP工单号=erp_work_ord;物料编码=item_num;名称=item_name;规格=item_spec;
- /// 入库库位=location_to;批次=lot_serial;入库数量=qty_rec;单位=um;相关单号=ord_nbr。
- ///
- /// 本服务仅 SELECT:无新增/编辑/删除/入库写入/库存事务/状态流转。租户口径对齐 ProductionReceiptService:
- /// 仅当 input.TenantId>0 才按 m.tenant_id 过滤(receipt std tenant 由同步入站上下文赋值,默认租户可能空态)。
- /// </summary>
- [ApiDescriptionSettings(Order = 310, Description = "生产入库单列表")]
- [Route("api/S7ProductionInbound")]
- [NonUnify]
- public class ProductionInboundService : IDynamicApiController, ITransient
- {
- /// <summary>主/系统租户哨兵:超管未选择目标租户时其 JWT TenantId 即此值,拒绝作为业务租户。</summary>
- private const long MainTenantId = 1300000000001L;
- private readonly ISqlSugarClient _db;
- private readonly UserManager _userManager;
- public ProductionInboundService(ISqlSugarClient db, UserManager userManager)
- {
- _db = db;
- _userManager = userManager;
- }
- /// <summary>严格可信租户解析:只来自认证后 JWT;无 Token(<=0) 或超管未选主租户 → 拒绝;不读前端 tenantId、无默认回退。</summary>
- private long ResolveTenantOrThrow()
- {
- var tid = _userManager.TenantId;
- if (tid <= 0)
- throw Oops.Oh("无法确定当前租户,请重新登录或选择目标租户");
- if (_userManager.SuperAdmin && tid == MainTenantId)
- throw Oops.Oh("超级管理员操作前必须选择目标租户");
- return tid;
- }
- /// <summary>
- /// 生产入库单列表(只读分页查询,扁平:一行=一条明细;读数据中台标准层 mdp_std_production_receipt)。
- /// </summary>
- [DisplayName("生产入库单列表")]
- [HttpGet("list")]
- public async Task<object> GetList([FromQuery] ProductionInboundListInput input)
- {
- var page = input.Page <= 0 ? 1 : input.Page;
- var pageSize = input.PageSize <= 0 ? 10 : input.PageSize;
- var offset = (page - 1) * pageSize;
- // 强制租户过滤:租户只来自认证后的可信上下文(严格 JWT),忽略前端传入的 input.TenantId,杜绝跨租户可见。
- var tid = ResolveTenantOrThrow();
- var where = new List<string> { "1=1" };
- var pars = new List<SugarParameter>();
- where.Add("m.tenant_id = @TenantId");
- pars.Add(new SugarParameter("@TenantId", tid));
- if (!string.IsNullOrWhiteSpace(input.InboundNo))
- {
- where.Add("m.nbr LIKE @InboundNo");
- pars.Add(new SugarParameter("@InboundNo", $"%{input.InboundNo.Trim()}%"));
- }
- if (!string.IsNullOrWhiteSpace(input.WorkOrderNo))
- {
- where.Add("m.work_ord LIKE @WorkOrderNo");
- pars.Add(new SugarParameter("@WorkOrderNo", $"%{input.WorkOrderNo.Trim()}%"));
- }
- if (!string.IsNullOrWhiteSpace(input.ErpWorkOrderNo))
- {
- where.Add("m.erp_work_ord LIKE @ErpWorkOrderNo");
- pars.Add(new SugarParameter("@ErpWorkOrderNo", $"%{input.ErpWorkOrderNo.Trim()}%"));
- }
- if (!string.IsNullOrWhiteSpace(input.Batch))
- {
- where.Add("m.lot_serial LIKE @Batch");
- pars.Add(new SugarParameter("@Batch", $"%{input.Batch.Trim()}%"));
- }
- if (!string.IsNullOrWhiteSpace(input.InboundDateStart))
- {
- where.Add("m.receipt_date >= @InboundDateStart");
- pars.Add(new SugarParameter("@InboundDateStart", $"{input.InboundDateStart.Trim()} 00:00:00"));
- }
- if (!string.IsNullOrWhiteSpace(input.InboundDateEnd))
- {
- where.Add("m.receipt_date <= @InboundDateEnd");
- pars.Add(new SugarParameter("@InboundDateEnd", $"{input.InboundDateEnd.Trim()} 23:59:59"));
- }
- var whereSql = string.Join(" AND ", where);
- var total = await _db.Ado.GetIntAsync(
- $"SELECT COUNT(1) FROM mdp_std_production_receipt m WHERE {whereSql}", pars);
- var list = await _db.Ado.SqlQueryAsync<ProductionInboundListRow>(
- $"""
- SELECT
- m.nbr AS InboundNo,
- m.line AS LineNo,
- m.receipt_date AS InboundDate,
- m.status AS Status,
- m.remark AS InboundType,
- m.prod_line AS ProductionLine,
- m.work_ord AS WorkOrderNo,
- m.erp_work_ord AS ErpWorkOrderNo,
- m.item_num AS MaterialCode,
- m.item_name AS MaterialName,
- m.item_spec AS Spec,
- m.location_to AS InboundLocation,
- m.lot_serial AS Batch,
- m.qty_rec AS Qty,
- m.um AS Unit,
- m.ord_nbr AS RelatedBillNo,
- m.create_time AS CreateTime
- FROM mdp_std_production_receipt m
- WHERE {whereSql}
- ORDER BY m.nbr DESC, m.line
- LIMIT {pageSize} OFFSET {offset}
- """,
- pars);
- return new { total, page, pageSize, list };
- }
- }
|