Просмотр исходного кода

fix(s0): correct standard BOM item mapping and create flow

Map standard BOM material options from real item master fields.
Populate ParentItem and ComponentItem from material ItemNum during create and update to avoid null inserts and keep text keys in sync.
YY968XX 2 дней назад
Родитель
Сommit
ad8e8d5937

+ 1 - 1
Web/src/views/aidop/s0/manufacturing/StandardBomManagement.vue

@@ -246,7 +246,7 @@ async function remoteSearchMaterials(keyword: string) {
 			page: 1,
 			pageSize: 50,
 		});
-		materialOptions.value = (data.list as any[]).map((m) => ({ id: m.id, code: m.code, name: m.name }));
+		materialOptions.value = (data.list as any[]).map((m) => ({ id: m.id, code: m.itemNum, name: m.descr }));
 	} finally {
 		materialLoading.value = false;
 	}

+ 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.169</AssemblyVersion>
-    <FileVersion>1.0.169</FileVersion>
-    <Version>1.0.169</Version>
+    <AssemblyVersion>1.0.170</AssemblyVersion>
+    <FileVersion>1.0.170</FileVersion>
+    <Version>1.0.170</Version>
   </PropertyGroup>
 
   <ItemGroup>

+ 32 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/Controllers/S0/Manufacturing/AdoS0ProductStructuresController.cs

@@ -156,11 +156,16 @@ public class AdoS0ProductStructuresController : ControllerBase
         var fkErr = await ValidateMaterialRefsAsync(dto.CompanyRefId, dto.FactoryRefId, dto.ParentMaterialId, dto.ComponentMaterialId);
         if (fkErr != null) return BadRequest(new { message = fkErr });
 
+        var (parentItem, componentItem, itemErr) = await ResolveItemNumsAsync(dto.ParentMaterialId, dto.ComponentMaterialId);
+        if (itemErr != null) return BadRequest(new { message = itemErr });
+
         var db = _masterRep.Context;
         await db.Ado.BeginTranAsync();
         try
         {
             var entity = MapMaster(dto);
+            entity.ParentItem = parentItem!;
+            entity.ComponentItem = componentItem!;
             entity.CreatedAt = DateTime.Now;
             entity = await _masterRep.AsInsertable(entity).ExecuteReturnEntityAsync();
             await SyncOpsAsync(entity.Id, dto, entity.ParentMaterialId, entity.ComponentMaterialId);
@@ -186,11 +191,16 @@ public class AdoS0ProductStructuresController : ControllerBase
         var fkErr = await ValidateMaterialRefsAsync(dto.CompanyRefId, dto.FactoryRefId, dto.ParentMaterialId, dto.ComponentMaterialId);
         if (fkErr != null) return BadRequest(new { message = fkErr });
 
+        var (parentItem, componentItem, itemErr) = await ResolveItemNumsAsync(dto.ParentMaterialId, dto.ComponentMaterialId);
+        if (itemErr != null) return BadRequest(new { message = itemErr });
+
         var db = _masterRep.Context;
         await db.Ado.BeginTranAsync();
         try
         {
             ApplyMaster(existing, dto);
+            existing.ParentItem = parentItem!;
+            existing.ComponentItem = componentItem!;
             existing.UpdatedAt = DateTime.Now;
             await _masterRep.AsUpdateable(existing).ExecuteCommandAsync();
 
@@ -287,6 +297,28 @@ public class AdoS0ProductStructuresController : ControllerBase
         }
     }
 
+    /// <summary>
+    /// 解析父/子物料的真实 ItemNum 文本,落 ProductStructureMaster.ParentItem/ComponentItem(NOT NULL)。
+    /// 物料不存在或编码为空时返回业务错误(400),避免插 NULL 导致裸 500。
+    /// </summary>
+    private async Task<(string? ParentItem, string? ComponentItem, string? Error)> ResolveItemNumsAsync(long parentId, long componentId)
+    {
+        var mats = await _materialRep.AsQueryable()
+            .Where(m => m.Id == parentId || m.Id == componentId)
+            .Select(m => new { m.Id, m.ItemNum })
+            .ToListAsync();
+
+        var parentItem = mats.FirstOrDefault(x => x.Id == parentId)?.ItemNum;
+        if (string.IsNullOrWhiteSpace(parentItem))
+            return (null, null, "父项物料不存在或编码为空");
+
+        var componentItem = mats.FirstOrDefault(x => x.Id == componentId)?.ItemNum;
+        if (string.IsNullOrWhiteSpace(componentItem))
+            return (null, null, "子项物料不存在或编码为空");
+
+        return (parentItem, componentItem, null);
+    }
+
     private async Task<string?> ValidateMaterialRefsAsync(long companyRefId, long factoryRefId, long parentId, long componentId)
     {
         var count = await _materialRep.AsQueryable()