소스 검색

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 일 전
부모
커밋
ad8e8d5937

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

@@ -246,7 +246,7 @@ async function remoteSearchMaterials(keyword: string) {
 			page: 1,
 			page: 1,
 			pageSize: 50,
 			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 {
 	} finally {
 		materialLoading.value = false;
 		materialLoading.value = false;
 	}
 	}

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

@@ -11,9 +11,9 @@
     <GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
     <GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
     <Copyright>Admin.NET</Copyright>
     <Copyright>Admin.NET</Copyright>
     <Description>Admin.NET ͨÓÃȨÏÞ¿ª·¢Æ½Ì¨</Description>
     <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>
   </PropertyGroup>
 
 
   <ItemGroup>
   <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);
         var fkErr = await ValidateMaterialRefsAsync(dto.CompanyRefId, dto.FactoryRefId, dto.ParentMaterialId, dto.ComponentMaterialId);
         if (fkErr != null) return BadRequest(new { message = fkErr });
         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;
         var db = _masterRep.Context;
         await db.Ado.BeginTranAsync();
         await db.Ado.BeginTranAsync();
         try
         try
         {
         {
             var entity = MapMaster(dto);
             var entity = MapMaster(dto);
+            entity.ParentItem = parentItem!;
+            entity.ComponentItem = componentItem!;
             entity.CreatedAt = DateTime.Now;
             entity.CreatedAt = DateTime.Now;
             entity = await _masterRep.AsInsertable(entity).ExecuteReturnEntityAsync();
             entity = await _masterRep.AsInsertable(entity).ExecuteReturnEntityAsync();
             await SyncOpsAsync(entity.Id, dto, entity.ParentMaterialId, entity.ComponentMaterialId);
             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);
         var fkErr = await ValidateMaterialRefsAsync(dto.CompanyRefId, dto.FactoryRefId, dto.ParentMaterialId, dto.ComponentMaterialId);
         if (fkErr != null) return BadRequest(new { message = fkErr });
         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;
         var db = _masterRep.Context;
         await db.Ado.BeginTranAsync();
         await db.Ado.BeginTranAsync();
         try
         try
         {
         {
             ApplyMaster(existing, dto);
             ApplyMaster(existing, dto);
+            existing.ParentItem = parentItem!;
+            existing.ComponentItem = componentItem!;
             existing.UpdatedAt = DateTime.Now;
             existing.UpdatedAt = DateTime.Now;
             await _masterRep.AsUpdateable(existing).ExecuteCommandAsync();
             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)
     private async Task<string?> ValidateMaterialRefsAsync(long companyRefId, long factoryRefId, long parentId, long componentId)
     {
     {
         var count = await _materialRep.AsQueryable()
         var count = await _materialRep.AsQueryable()