Bläddra i källkod

revert(s0): 回退 c23c9eba6 的 S3/S4 取号改动,仅保留 S0 (server 1.0.297)

按模块边界,撤回 c23c9eba6 越界到 S3/S4 的取号链路改动,仅保留 S0 内容
(ItemPack/NbrControl 租户内唯一索引 + 控制器 dup-check + 1.0.296.sql)。

- Supply/NumberRuleService.cs (S3):恢复到 c23c9eba6 父版本(条件式租户过滤)
- ProcurementExecution/SupplierShipmentService.cs (S4):恢复父版本(WoLot 取号去 tenant 过滤)
- Infrastructure/AdoS0TenantScope.cs:移除仅 S3 使用的 ResolveRequiredOrThrow(无残留引用)

S0 的 NbrControl 表租户内唯一索引与控制器租户化保持不变,取号对真实租户仍正常。
S3/S4 取号租户硬化留待对应模块 owner 授权后另行处理。
YY968XX 5 dagar sedan
förälder
incheckning
66fcd4f03f

+ 3 - 3
server/Admin.NET.Web.Entry/Admin.NET.Web.Entry.csproj

@@ -11,9 +11,9 @@
     <GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
     <Copyright>Admin.NET</Copyright>
     <Description>Admin.NET ͨ��Ȩ�޿���ƽ̨</Description>
-    <AssemblyVersion>1.0.296</AssemblyVersion>
-    <FileVersion>1.0.296</FileVersion>
-    <Version>1.0.296</Version>
+    <AssemblyVersion>1.0.297</AssemblyVersion>
+    <FileVersion>1.0.297</FileVersion>
+    <Version>1.0.297</Version>
   </PropertyGroup>
 
   <ItemGroup>

+ 0 - 19
server/Plugins/Admin.NET.Plugin.AiDOP/Infrastructure/AdoS0TenantScope.cs

@@ -45,23 +45,4 @@ public static class AdoS0TenantScope
         tenantId = tid;
         return true;
     }
-
-    /// <summary>
-    /// Service 层(无 IActionResult 上下文,如取号/编号服务)统一的可信租户解析。
-    /// 语义与 <see cref="TryResolveRequired"/> 完全一致(同一 JWT 来源、同样拒绝无租户/超管未选),
-    /// 但解析失败时抛出业务异常而非返回错误结果。绝不回退固定默认租户、绝不读前端 tenantId。
-    /// </summary>
-    public static long ResolveRequiredOrThrow()
-    {
-        var um = App.GetRequiredService<UserManager>();
-        var tid = um.TenantId;
-
-        if (tid <= 0)
-            throw Oops.Oh("无法确定当前租户,请重新登录或选择目标租户");
-
-        if (um.SuperAdmin && tid == MainTenantId)
-            throw Oops.Oh("超级管理员操作前必须选择目标租户");
-
-        return tid;
-    }
 }

+ 5 - 9
server/Plugins/Admin.NET.Plugin.AiDOP/ProcurementExecution/SupplierShipmentService.cs

@@ -346,7 +346,7 @@ public class SupplierShipmentService : IDynamicApiController, ITransient
                     lockKey = $"scm_shpc_seq_{prefix}";
                     await AcquireMySqlLockAsync(lockKey, 10);
 
-                    var nextSerial = await GetNextDailySerialAsync(prefix, domain, tenantId);
+                    var nextSerial = await GetNextDailySerialAsync(prefix, domain);
                     var pairs = needShpc
                         .OrderBy(x => x.Wlbm ?? string.Empty)
                         .ThenBy(x => x.Scph ?? string.Empty)
@@ -411,7 +411,7 @@ public class SupplierShipmentService : IDynamicApiController, ITransient
                     // 推进 NbrControl.NextValue,确保续号(仅当没有历史 shpc 且使用了 NbrControl 作为起点时也能正确续)
                     // 这里直接推进到“本批次最后一个流水号”,下次取号将从 NextValue+1 开始。
                     var lastSerial = nextSerial + pairs.Count - 1;
-                    await BumpNbrControlNextValueAsync(domain, lastSerial, tenantId);
+                    await BumpNbrControlNextValueAsync(domain, lastSerial);
                 }
 
                 // 3) 补 jhdhh(同一发货单:为空的明细按 id 递增,起始 max(jhdhh) or 1000)
@@ -748,7 +748,7 @@ public class SupplierShipmentService : IDynamicApiController, ITransient
         }
     }
 
-    private async Task<int> GetNextDailySerialAsync(string prefix, string domain, long tenantId)
+    private async Task<int> GetNextDailySerialAsync(string prefix, string domain)
     {
         // 从已存在的批次号中取当天最大流水:yyMMdd + 3位
         // 优先 scm_shdzb,其次 scm_shbq(兼容历史数据来源)
@@ -769,7 +769,6 @@ public class SupplierShipmentService : IDynamicApiController, ITransient
                 SELECT IFNULL(NextValue, 0)
                 FROM NbrControl
                 WHERE NbrType='WoLot'
-                  AND tenant_id = @TenantId
                   AND (
                         domain_code = @d
                         OR Domain = @d
@@ -778,7 +777,7 @@ public class SupplierShipmentService : IDynamicApiController, ITransient
                 ORDER BY RecID
                 LIMIT 1
                 """,
-                new List<SugarParameter> { new("@d", domain ?? string.Empty), new("@TenantId", tenantId) });
+                new List<SugarParameter> { new("@d", domain ?? string.Empty) });
             // 用户要求:NextValue+1 为下一流水号起点
             return Math.Max(1, nv + 1);
         }
@@ -787,10 +786,9 @@ public class SupplierShipmentService : IDynamicApiController, ITransient
         return int.TryParse(suffix, out var n) ? n + 1 : 1;
     }
 
-    private async Task BumpNbrControlNextValueAsync(string domain, int lastSerial, long tenantId)
+    private async Task BumpNbrControlNextValueAsync(string domain, int lastSerial)
     {
         // 保守推进:仅当新值更大时更新,避免其它流程并发推进导致回退。
-        // 租户隔离:仅推进当前租户的 WoLot 规则,绝不写他租户序号。
         await _db.Ado.ExecuteCommandAsync(
             """
             UPDATE NbrControl
@@ -800,7 +798,6 @@ public class SupplierShipmentService : IDynamicApiController, ITransient
             END,
                 UpdateTime = NOW()
             WHERE NbrType = 'WoLot'
-              AND tenant_id = @TenantId
               AND (
                     domain_code = @d
                     OR Domain = @d
@@ -811,7 +808,6 @@ public class SupplierShipmentService : IDynamicApiController, ITransient
             {
                 new("@d", domain ?? string.Empty),
                 new("@v", lastSerial),
-                new("@TenantId", tenantId),
             });
     }
 

+ 11 - 16
server/Plugins/Admin.NET.Plugin.AiDOP/Supply/NumberRuleService.cs

@@ -1,5 +1,3 @@
-using Admin.NET.Plugin.AiDOP.Infrastructure;
-
 namespace Admin.NET.Plugin.AiDOP.Supply;
 
 /// <summary>
@@ -8,10 +6,12 @@ namespace Admin.NET.Plugin.AiDOP.Supply;
 public class NumberRuleService : ITransient
 {
     private readonly ISqlSugarClient _db;
+    private readonly UserManager _userManager;
 
-    public NumberRuleService(ISqlSugarClient db)
+    public NumberRuleService(ISqlSugarClient db, UserManager userManager)
     {
         _db = db;
+        _userManager = userManager;
     }
 
     public async Task<IReadOnlyList<string>> NextBatchAsync(string ruleCode, string domain, int count, string operatorNo)
@@ -39,17 +39,13 @@ public class NumberRuleService : ITransient
         var normalizedDomain = domain?.Trim() ?? string.Empty;
         var now = DateTime.Now;
 
-        // 可信租户硬解析:无 token / 超管未选租户一律抛错;绝不回退固定默认租户、绝不读前端 tenantId。
-        // 租户过滤在取号规则定位上强制无条件生效,杜绝跨租户读到他租户规则或落到默认规则。
-        var tenantId = AdoS0TenantScope.ResolveRequiredOrThrow();
-
-        const string tenantWhere = "\n              AND tenant_id = @TenantId";
+        var tenantWhere = _userManager.TenantId > 0 ? "\n              AND tenant_id = @TenantId" : string.Empty;
         var rulePars = new List<SugarParameter>
         {
             new("@RuleCode", normalizedRuleCode),
-            new("@Domain", normalizedDomain),
-            new("@TenantId", tenantId)
+            new("@Domain", normalizedDomain)
         };
+        if (_userManager.TenantId > 0) rulePars.Add(new SugarParameter("@TenantId", _userManager.TenantId));
 
         var rule = (await _db.Ado.SqlQueryAsync<NbrControlRuleRow>(
             $"""
@@ -98,7 +94,7 @@ public class NumberRuleService : ITransient
             throw Oops.Oh($"未找到编号规则:{normalizedRuleCode}");
 
         var sequenceDate = NumberRuleFormatter.ResolveSequenceDate(rule.DateType, rule.IsDateType, now);
-        var dayInfo = await GetDayInfoForUpdateAsync(rule, normalizedRuleCode, normalizedDomain, sequenceDate, tenantId);
+        var dayInfo = await GetDayInfoForUpdateAsync(rule, normalizedRuleCode, normalizedDomain, sequenceDate);
 
         var firstSerial = ResolveFirstSerial(rule, dayInfo);
         var lastSerial = firstSerial + count - 1;
@@ -134,18 +130,17 @@ public class NumberRuleService : ITransient
         return numbers;
     }
 
-    private async Task<NbrDayInfoRow?> GetDayInfoForUpdateAsync(NbrControlRuleRow rule, string ruleCode, string domain, DateTime? sequenceDate, long tenantId)
+    private async Task<NbrDayInfoRow?> GetDayInfoForUpdateAsync(NbrControlRuleRow rule, string ruleCode, string domain, DateTime? sequenceDate)
     {
         var dateFilter = sequenceDate.HasValue ? "AND DATE(Today) = DATE(@Today)" : string.Empty;
-        // 日流水行同样按当前租户无条件过滤,序号推进不跨租户。
-        const string tenantFilter = "AND tenant_id = @TenantId2";
+        var tenantFilter = _userManager.TenantId > 0 ? "AND tenant_id = @TenantId2" : string.Empty;
         var dayPars = new List<SugarParameter>
         {
             new("@RuleCode", rule.NbrType ?? ruleCode),
             new("@Domain", rule.Domain ?? domain),
-            new("@Today", sequenceDate ?? DateTime.Today),
-            new("@TenantId2", tenantId)
+            new("@Today", sequenceDate ?? DateTime.Today)
         };
+        if (_userManager.TenantId > 0) dayPars.Add(new SugarParameter("@TenantId2", _userManager.TenantId));
         return (await _db.Ado.SqlQueryAsync<NbrDayInfoRow>(
             $"""
             SELECT