using Admin.NET.Plugin.AiDOP.MaterialWarehouse.Dto;
namespace Admin.NET.Plugin.AiDOP.MaterialWarehouse;
///
/// S5 标签查询 只读 list 服务。
///
/// 数据源:aidopdev.MissedPrint(legacy 标签/条码记录表)。状态描述经 GeneralizedCodeMaster(FldName='BarcodeStatus') 解码。
/// 参考本仓既有同表只读投影先例:Controllers/S0/Manufacturing/AdoS0MfgProcessFlowCardsController(同解 BarcodeStatus)。
///
/// 本服务仅 SELECT:无新增/编辑/删除/库位转移/库存事务/状态流转/物料卡写入;扁平列表,无 detail。
///
/// 【租户边界的现状,勿误读】MissedPrint 的 tenant_id 列存在但实测**全为 NULL**,
/// 且 152 行中 150 行 Location 为空 —— 既不能按 tenant_id 过滤(会把页面整体查空),
/// 也不能拿 Location 当租户边界(会误删绝大多数合法标签)。
/// 故业务行的租户归属仍是**未解决的数据模型债**,本服务不伪造租户边界;
/// 已做的收敛是:① 类级去 [AllowAnonymous](原先可被完全未认证调用,实测匿名 GET 返回 200 + 152 行真实数据);
/// ② 状态码表 JOIN 按 Domain + 当前租户限定(见下)。
///
[ApiDescriptionSettings(Order = 302, Description = "标签查询")]
[Route("api/S5LabelQuery")]
[NonUnify]
public class LabelQueryService : IDynamicApiController, ITransient
{
/// 主/系统租户哨兵:超管未选择目标租户时其 JWT TenantId 即此值,拒绝作为业务租户。
private const long MainTenantId = 1300000000001L;
private readonly ISqlSugarClient _db;
private readonly UserManager _userManager;
public LabelQueryService(ISqlSugarClient db, UserManager userManager)
{
_db = db;
_userManager = userManager;
}
/// 严格可信租户解析:只来自认证后 JWT;无 Token 或超管未选目标租户 → 拒绝,无默认回退。
private long ResolveTenantOrThrow()
{
var tid = _userManager.TenantId;
if (tid <= 0)
throw Oops.Oh("无法确定当前租户,请重新登录或选择目标租户");
if (_userManager.SuperAdmin && tid == MainTenantId)
throw Oops.Oh("超级管理员操作前必须选择目标租户");
return tid;
}
///
/// 标签查询列表(只读分页查询)。
///
[DisplayName("标签查询列表")]
[HttpGet("list")]
public async Task