Prechádzať zdrojové kódy

feat: 交期确认后同步工单物料明细(物理删除); 3级计划重排移除交货计划生成

Pengxy 3 mesiacov pred
rodič
commit
05e914508e

+ 1 - 1
Web/package.json

@@ -1,7 +1,7 @@
 {
   "name": "admin.net",
   "type": "module",
-  "version": "2.4.203",
+  "version": "2.4.204",
   "packageManager": "pnpm@10.32.1",
   "lastBuildTime": "2026.03.15",
   "description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架",

+ 1 - 1
Web/src/views/aidop/business/orderList.vue

@@ -250,7 +250,7 @@ async function onReview() {
 	reviewing.value = true;
 	try {
 		const data = await reviewSeOrder(selectedIds.value);
-		const msg = data?.message || '评审成功';
+		const msg = data?.message || '订单评审完成';
 		const warns = data?.warnings?.length ? `\n注意:${data.warnings.join(';')}` : '';
 		ElMessage({ message: msg + warns, type: 'success', duration: 5000, showClose: true });
 	} catch (e: any) {

+ 5 - 12
Web/src/views/aidop/business/salesOrderChangeForm.vue

@@ -73,19 +73,19 @@
 			:bizId="form.seOrderId"
 			:bizNo="form.billNo"
 			:title="`订单变更审批-${form.billNo}`"
+			:before-start="beforeStartFlow"
 			@refresh="loadDetail"
 		/>
 
 		<div class="footer">
 			<el-button @click="$emit('cancel')">关闭</el-button>
-			<el-button :loading="saving" @click="onSave">保存</el-button>
 		</div>
 	</div>
 </template>
 
 <script setup lang="ts">
 import { computed, onMounted, reactive, ref } from 'vue';
-import { ElMessage, FormInstance, FormRules } from 'element-plus';
+import { FormInstance, FormRules } from 'element-plus';
 import ApprovalPanel from '/@/views/approvalFlow/component/ApprovalPanel.vue';
 import { createSeOrderChange, fetchSeOrderDetail, type SeOrderChangeSave } from '../api/seOrderReview';
 
@@ -93,7 +93,6 @@ const props = defineProps<{ orderId: number | null }>();
 const emit = defineEmits<{ (e: 'cancel'): void; (e: 'submitted'): void }>();
 
 const loading = ref(false);
-const saving = ref(false);
 const formRef = ref<FormInstance>();
 
 const form = reactive<SeOrderChangeSave>({
@@ -146,17 +145,11 @@ async function loadDetail() {
 	}
 }
 
-async function onSave() {
+/** 提交审批前先保存变更记录到 crm_seorder_change */
+async function beforeStartFlow() {
 	await formRef.value?.validate().catch(() => Promise.reject());
 	if (!props.orderId) return;
-	saving.value = true;
-	try {
-		await createSeOrderChange(props.orderId, form);
-		ElMessage.success('已保存');
-		emit('submitted');
-	} finally {
-		saving.value = false;
-	}
+	await createSeOrderChange(props.orderId, form);
 }
 
 onMounted(loadDetail);

+ 4 - 0
Web/src/views/approvalFlow/component/ApprovalPanel.vue

@@ -127,6 +127,7 @@ const props = defineProps<{
 	bizNo?: string;
 	title?: string;
 	currentUserId?: number;
+	beforeStart?: () => Promise<void>;
 }>();
 
 const resolvedUserId = computed(() => props.currentUserId ?? userStore.userInfos?.id ?? 0);
@@ -230,6 +231,9 @@ watch(
 const doStartFlow = async () => {
 	starting.value = true;
 	try {
+		if (props.beforeStart) {
+			await props.beforeStart();
+		}
 		const res = await startFlow({
 			bizType: props.bizType,
 			bizId: props.bizId,

+ 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.208</AssemblyVersion>
-    <FileVersion>1.0.208</FileVersion>
-    <Version>1.0.208</Version>
+    <AssemblyVersion>1.0.209</AssemblyVersion>
+    <FileVersion>1.0.209</FileVersion>
+    <Version>1.0.209</Version>
   </PropertyGroup>
 
   <ItemGroup>

+ 1 - 1
server/Plugins/Admin.NET.Plugin.AiDOP/Order/AsnShipperService.cs

@@ -96,7 +96,7 @@ public class AsnShipperService : IDynamicApiController, ITransient
         var total = await _db.Ado.GetIntAsync(
             $"SELECT COUNT(*) FROM ({baseSql}) AS t", pars);
         var list = await _db.Ado.SqlQueryAsync<AsnShipperListRow>(
-            $"SELECT * FROM ({baseSql}) AS t ORDER BY t.Id DESC LIMIT {input.PageSize} OFFSET {offset}",
+            $"SELECT * FROM ({baseSql}) AS t ORDER BY t.ShipDate DESC, t.Id DESC LIMIT {input.PageSize} OFFSET {offset}",
             pars);
 
         return new { total, page = input.Page, pageSize = input.PageSize, list };

+ 55 - 48
server/Plugins/Admin.NET.Plugin.AiDOP/Order/MaterialRequirementCalculator.cs

@@ -7,7 +7,7 @@ namespace Admin.NET.Plugin.AiDOP.Order;
 /// </summary>
 public class MaterialRequirementCalculator : ITransient
 {
-    private const int MaxBomDepth = 6;
+    private const int MaxBomDepth = 20;
     private readonly ISqlSugarClient _db;
 
     public MaterialRequirementCalculator(ISqlSugarClient db)
@@ -50,7 +50,7 @@ public class MaterialRequirementCalculator : ITransient
         if (bomId is null)
         {
             warnings.Add($"订单行 {entry.EntrySeq}({itemNum})未匹配到 BOM,仅写入成品行资源检查结果");
-            await ApplySupplyAsync(lines, entry.TenantId, bangId);
+            await ApplySupplyAsync(lines, entry.TenantId, bangId, entry.Id);
             return lines;
         }
 
@@ -58,7 +58,7 @@ public class MaterialRequirementCalculator : ITransient
         if (children.Count == 0)
         {
             warnings.Add($"订单行 {entry.EntrySeq} BOM {entry.BomNumber ?? bomId.ToString()} 无子件明细");
-            await ApplySupplyAsync(lines, entry.TenantId, bangId);
+            await ApplySupplyAsync(lines, entry.TenantId, bangId, entry.Id);
             return lines;
         }
 
@@ -69,7 +69,7 @@ public class MaterialRequirementCalculator : ITransient
                 lines, rootFid, "1", 1, orderQty, child, entry, needTime, warnings, seq, depth: 1);
         }
 
-        await ApplySupplyAsync(lines, entry.TenantId, bangId);
+        await ApplySupplyAsync(lines, entry.TenantId, bangId, entry.Id);
         return lines;
     }
 
@@ -101,59 +101,51 @@ public class MaterialRequirementCalculator : ITransient
         var fid = YitIdHelper.NextId();
         var nextSeq = seq + 1;
 
-        if (!isVirtual)
+        // 虚拟件(erp_cls=4)也写入资源检查记录,IsUse=0 标识为虚拟件,不参与缺料计算
+        lines.Add(new ResourceCheckBomLine
         {
-            lines.Add(new ResourceCheckBomLine
-            {
-                Fid = fid,
-                ParentFid = parentFid,
-                BomChildId = child.Id,
-                Num = num,
-                Level = parentLevel + 1,
-                Type = child.Type,
-                ItemNumber = child.ItemNumber ?? string.Empty,
-                ItemName = child.ItemName,
-                Model = child.Model,
-                Unit = child.Unit,
-                BomNumber = child.BomNumber,
-                ErpCls = child.ErpCls,
-                ErpClsName = MapErpClsName(child.ErpCls),
-                Backflush = child.Backflush,
-                Qty = unitQty,
-                Wastage = child.Wastage,
-                Scrap = child.Scrap,
-                NeedCount = needCount,
-                NeedCountNoLoss = RoundQty(needNoLoss),
-                KittingTime = needTime,
-                SatisfyTime = needTime,
-                IsBom = child.IsBom,
-                HaveIcSubs = child.HaveIcSubs,
-                SubstituteCode = child.SubstituteCode,
-                IsUse = 1
-            });
-        }
+            Fid = fid,
+            ParentFid = parentFid,
+            BomChildId = child.Id,
+            Num = num,
+            Level = parentLevel + 1,
+            Type = child.Type,
+            ItemNumber = child.ItemNumber ?? string.Empty,
+            ItemName = child.ItemName,
+            Model = child.Model,
+            Unit = child.Unit,
+            BomNumber = child.BomNumber,
+            ErpCls = child.ErpCls,
+            ErpClsName = MapErpClsName(child.ErpCls),
+            Backflush = child.Backflush,
+            Qty = unitQty,
+            Wastage = child.Wastage,
+            Scrap = child.Scrap,
+            NeedCount = needCount,
+            NeedCountNoLoss = RoundQty(needNoLoss),
+            KittingTime = needTime,
+            SatisfyTime = needTime,
+            IsBom = child.IsBom,
+            HaveIcSubs = child.HaveIcSubs,
+            SubstituteCode = child.SubstituteCode,
+            IsUse = isVirtual ? 0 : 1
+        });
 
         seq = nextSeq;
         var expandParentFid = isVirtual ? parentFid : fid;
         var expandParentNum = num;
         var expandNeed = needCount;
 
-        if (child.IsBom == 1 && depth < MaxBomDepth && !string.IsNullOrWhiteSpace(child.ItemNumber))
+        // 仅虚拟件(erp_cls=4)继续向下展开子阶BOM,其他类型作为叶子节点不再下钻
+        if (isVirtual && depth < MaxBomDepth && !string.IsNullOrWhiteSpace(child.ItemNumber))
         {
             var subBomId = await ResolveBomIdByItemAsync(child.ItemNumber!, entry.TenantId);
             if (subBomId is null)
-            {
-                if (!isVirtual)
-                    warnings.Add($"物料 {child.ItemNumber} 标记为 BOM 但未找到子阶 BOM,按单层处理");
                 return seq;
-            }
 
             var grandchildren = await LoadBomChildrenAsync(subBomId.Value, entry.TenantId);
             if (grandchildren.Count == 0)
-            {
-                warnings.Add($"物料 {child.ItemNumber} 子阶 BOM 无明细");
                 return seq;
-            }
 
             var childSeq = 1;
             foreach (var gc in grandchildren)
@@ -172,7 +164,7 @@ public class MaterialRequirementCalculator : ITransient
                     depth + 1);
             }
         }
-        else if (child.IsBom == 1 && depth >= MaxBomDepth)
+        else if (depth >= MaxBomDepth)
         {
             warnings.Add($"物料 {child.ItemNumber} 超过最大 BOM 展开层级 {MaxBomDepth},停止下钻");
         }
@@ -252,7 +244,7 @@ public class MaterialRequirementCalculator : ITransient
             new SugarParameter("@TenantId", tenantId));
     }
 
-    private async Task ApplySupplyAsync(List<ResourceCheckBomLine> lines, long tenantId, long bangId = 0)
+    private async Task ApplySupplyAsync(List<ResourceCheckBomLine> lines, long tenantId, long bangId = 0, long entryId = 0)
     {
         var stockMap = new Dictionary<string, decimal>(StringComparer.OrdinalIgnoreCase);
         var transitMap = new Dictionary<string, decimal>(StringComparer.OrdinalIgnoreCase);
@@ -321,6 +313,18 @@ public class MaterialRequirementCalculator : ITransient
             line.MakeQty = line.ErpCls == 1 ? line.LackQty : 0;
             line.PurchaseQty = line.ErpCls == 3 ? line.LackQty : 0;
 
+            // 虚拟件(erp_cls=4)仅展示BOM结构,不参与库存消耗与缺料计算
+            if (line.ErpCls == 4)
+            {
+                line.Sqty = 0;
+                line.LackQty = 0;
+                line.SelfLackQty = 0;
+                line.UseQty = 0;
+                line.MakeQty = 0;
+                line.PurchaseQty = 0;
+                continue;
+            }
+
             var consumedFromStock = RoundQty(Math.Min(stock, line.Sqty));
             stockMap[line.ItemNumber] = RoundQty(Math.Max(0m, stock - consumedFromStock));
             var remainingSqty = RoundQty(Math.Max(0m, line.Sqty - consumedFromStock));
@@ -343,10 +347,10 @@ public class MaterialRequirementCalculator : ITransient
                             """
                             INSERT INTO ic_item_stockoccupy (
                                 Id, icitem_number, quantity, morder_mo, bang_id,
-                                tenant_id, occupy_time, create_time, update_time
+                                orderentry_id, tenant_id, occupy_time, create_time, update_time
                             ) VALUES (
                                 @Id, @ItemNumber, @Qty, @WorkOrd, @BangId,
-                                @TenantId, @Now, @Now, @Now
+                                @EntryId, @TenantId, @Now, @Now, @Now
                             )
                             """,
                             new SugarParameter("@Id", YitIdHelper.NextId()),
@@ -354,6 +358,7 @@ public class MaterialRequirementCalculator : ITransient
                             new SugarParameter("@Qty", stockUsed),
                             new SugarParameter("@WorkOrd", ""),
                             new SugarParameter("@BangId", bangId),
+                            new SugarParameter("@EntryId", entryId),
                             new SugarParameter("@TenantId", tenantId),
                             new SugarParameter("@Now", DateTime.Now));
                     }
@@ -365,10 +370,10 @@ public class MaterialRequirementCalculator : ITransient
                             """
                             INSERT INTO srm_po_occupy (
                                 Id, ItemNumber, OccupyQty, morder_mo, bang_id,
-                                tenant_id, create_time, update_time
+                                polist_id, entry_id, tenant_id, create_time, update_time
                             ) VALUES (
                                 @Id, @ItemNumber, @Qty, @WorkOrd, @BangId,
-                                @TenantId, @Now, @Now
+                                @PolistId, @EntryId, @TenantId, @Now, @Now
                             )
                             """,
                             new SugarParameter("@Id", YitIdHelper.NextId()),
@@ -376,6 +381,8 @@ public class MaterialRequirementCalculator : ITransient
                             new SugarParameter("@Qty", transitUsed),
                             new SugarParameter("@WorkOrd", ""),
                             new SugarParameter("@BangId", bangId),
+                            new SugarParameter("@PolistId", 0),
+                            new SugarParameter("@EntryId", entryId),
                             new SugarParameter("@TenantId", tenantId),
                             new SugarParameter("@Now", DateTime.Now));
                     }

+ 2 - 1
server/Plugins/Admin.NET.Plugin.AiDOP/Order/OrderDeliveryService.cs

@@ -81,7 +81,7 @@ public class OrderDeliveryService : IDynamicApiController, ITransient
         var total = await _db.Ado.GetIntAsync(
             $"SELECT COUNT(*) FROM ({baseSql}) AS t {outerWhere}", pars);
         var list = await _db.Ado.SqlQueryAsync<OrderDeliveryListRow>(
-            $"SELECT * FROM ({baseSql}) AS t {outerWhere} ORDER BY t.id DESC LIMIT {input.PageSize} OFFSET {offset}",
+            $"SELECT * FROM ({baseSql}) AS t {outerWhere} ORDER BY t.RDate DESC, t.BillNo ASC, IFNULL(t.EntrySeq, 0) ASC LIMIT {input.PageSize} OFFSET {offset}",
             pars);
 
         return new { total, page = input.Page, pageSize = input.PageSize, list };
@@ -110,6 +110,7 @@ public class OrderDeliveryService : IDynamicApiController, ITransient
             d.plan_delivery_date                                        AS PlanDate,
             d.promised_delivery_date                                    AS SysCapacityDate,
             d.promised_delivery_date                                    AS Date,
+            d.order_date                                                 AS RDate,
             d.create_time                                               AS CreateTime,
             NULL                                                        AS CreateByName,
             NULL                                                        AS Auditor,

+ 3 - 133
server/Plugins/Admin.NET.Plugin.AiDOP/Order/OrderReviewOrchestrationService.cs

@@ -129,9 +129,6 @@ public class OrderReviewOrchestrationService : ITransient
                 warnings.Add($"物料需求同步失败:{ex.Message}");
             }
 
-            // ── 第4.5步:生成交货单(出货计划) ──
-            await GenerateShippingPlanFromOrderAsync(order, entries, account, warnings);
-
             result.EntryCount = entries.Count;
             result.Message = string.IsNullOrWhiteSpace(reason)
                 ? "3级计划重排完成"
@@ -380,6 +377,9 @@ public class OrderReviewOrchestrationService : ITransient
                         new SugarParameter("@WorkOrd", workOrd),
                         new SugarParameter("@User", account),
                         new SugarParameter("@Now", DateTime.Now));
+
+                    // 交期确认后同步工单物料明细,使其与资源检查子物料一致
+                    await _materialDetailSync.EnsureFromResourceCheckAsync(entry.TenantId, workOrd, account);
                 }
             }
             else
@@ -861,129 +861,6 @@ public class OrderReviewOrchestrationService : ITransient
             new SugarParameter("@Id", entryId));
     }
 
-    /// <summary>
-    /// 根据订单及明细行生成交货单(出货计划 ShippingPlan / ShippingPlanDetail)。
-    /// 若该订单已存在出货计划则更新明细,否则新建。
-    /// </summary>
-    private async Task GenerateShippingPlanFromOrderAsync(
-        OrderWorkOrderGenerationService.OrderHeader order,
-        List<OrderWorkOrderGenerationService.OrderEntryLine> entries,
-        string account,
-        List<string> warnings)
-    {
-        // 加载订单额外字段(客户名称、国家、日期)
-        var orderInfo = await _db.Ado.SqlQueryAsync<OrderShippingInfoRow>(
-            """
-            SELECT custom_name AS CustomName, country AS Country, date AS OrderDate
-            FROM crm_seorder
-            WHERE Id = @Id AND tenant_id = @TenantId AND IsDeleted = 0
-            LIMIT 1
-            """,
-            new SugarParameter("@Id", order.Id),
-            new SugarParameter("@TenantId", order.TenantId));
-        var info = orderInfo.FirstOrDefault() ?? new OrderShippingInfoRow();
-
-        // 检查是否已存在该订单的出货计划明细
-        var existingPlanId = await _db.Ado.GetIntAsync(
-            """
-            SELECT IFNULL(MAX(plan_id), 0) FROM ShippingPlanDetail
-            WHERE tenant_id = @TenantId AND seorder_id = @OrderId AND IFNULL(IsActive, 1) = 1
-            """,
-            new SugarParameter("@TenantId", order.TenantId),
-            new SugarParameter("@OrderId", order.Id));
-
-        var now = DateTime.Now;
-        var domain = order.TenantId.ToString();
-        if (domain.Length > 8) domain = domain[..8];
-
-        if (existingPlanId == 0)
-        {
-            // ── 新建出货计划主表 ──
-            var planId = await _db.Ado.GetIntAsync("SELECT IFNULL(MAX(RecID), 0) + 1 FROM ShippingPlan");
-            await _db.Ado.ExecuteCommandAsync(
-                """
-                INSERT INTO ShippingPlan (
-                    RecID, `Domain`, LotSerial, ShippingDate, ShippingSite,
-                    Consignee, Priority, Status, Remark,
-                    IsActive, IsConfirm, CreateUser, CreateTime, tenant_id
-                ) VALUES (
-                    @PlanId, @Domain, @LotSerial, @ShippingDate, '',
-                    @Consignee, 0, '', '3级计划重排自动生成',
-                    1, 1, @User, @Now, @TenantId
-                )
-                """,
-                new SugarParameter("@PlanId", planId),
-                new SugarParameter("@Domain", domain),
-                new SugarParameter("@LotSerial", order.BillNo ?? string.Empty),
-                new SugarParameter("@ShippingDate", info.OrderDate ?? (object)DBNull.Value),
-                new SugarParameter("@Consignee", (object?)info.CustomName ?? DBNull.Value),
-                new SugarParameter("@User", account),
-                new SugarParameter("@Now", now),
-                new SugarParameter("@TenantId", order.TenantId));
-
-            // ── 新建出货计划明细 ──
-            var nextDetailId = await _db.Ado.GetIntAsync("SELECT IFNULL(MAX(RecID), 0) + 1 FROM ShippingPlanDetail");
-            foreach (var entry in entries)
-            {
-                await _db.Ado.ExecuteCommandAsync(
-                    """
-                    INSERT INTO ShippingPlanDetail (
-                        RecID, `Domain`, plan_id, OrdNbr, bill_no,
-                        ItemNum, ItemName, Specification, Qty,
-                        OrdDate, Country, CustomNo, CustomName,
-                        seorder_id, sentry_id, Remark, Status,
-                        IsActive, IsConfirm, CreateUser, CreateTime, tenant_id
-                    ) VALUES (
-                        @RecId, @Domain, @PlanId, @OrdNbr, @BillNo,
-                        @ItemNum, @ItemName, @Spec, @Qty,
-                        @OrdDate, @Country, @CustomNo, @CustomName,
-                        @SeOrderId, @SentryId, '', '',
-                        1, 1, @User, @Now, @TenantId
-                    )
-                    """,
-                    new SugarParameter("@RecId", nextDetailId++),
-                    new SugarParameter("@Domain", domain),
-                    new SugarParameter("@PlanId", planId),
-                    new SugarParameter("@OrdNbr", order.BillNo ?? string.Empty),
-                    new SugarParameter("@BillNo", entry.BillNo ?? order.BillNo ?? string.Empty),
-                    new SugarParameter("@ItemNum", (object?)entry.ItemNumber ?? DBNull.Value),
-                    new SugarParameter("@ItemName", (object?)entry.ItemName ?? DBNull.Value),
-                    new SugarParameter("@Spec", (object?)entry.Specification ?? DBNull.Value),
-                    new SugarParameter("@Qty", entry.Qty ?? 0),
-                    new SugarParameter("@OrdDate", entry.PlanDate ?? (object)DBNull.Value),
-                    new SugarParameter("@Country", (object?)info.Country ?? DBNull.Value),
-                    new SugarParameter("@CustomNo", (object?)order.CustomNo ?? DBNull.Value),
-                    new SugarParameter("@CustomName", (object?)info.CustomName ?? DBNull.Value),
-                    new SugarParameter("@SeOrderId", order.Id),
-                    new SugarParameter("@SentryId", entry.Id),
-                    new SugarParameter("@User", account),
-                    new SugarParameter("@Now", now),
-                    new SugarParameter("@TenantId", order.TenantId));
-            }
-
-            warnings.Add($"已自动生成出货计划(ID={planId}),共 {entries.Count} 行明细");
-        }
-        else
-        {
-            // ── 更新已有出货计划明细 ──
-            await _db.Ado.ExecuteCommandAsync(
-                """
-                UPDATE ShippingPlanDetail
-                SET CustomName = @CustomName, Country = @Country,
-                    UpdateUser = @User, UpdateTime = @Now
-                WHERE tenant_id = @TenantId AND seorder_id = @OrderId AND IFNULL(IsActive, 1) = 1
-                """,
-                new SugarParameter("@CustomName", (object?)info.CustomName ?? DBNull.Value),
-                new SugarParameter("@Country", (object?)info.Country ?? DBNull.Value),
-                new SugarParameter("@User", account),
-                new SugarParameter("@Now", now),
-                new SugarParameter("@TenantId", order.TenantId),
-                new SugarParameter("@OrderId", order.Id));
-
-            warnings.Add($"已更新出货计划(ID={existingPlanId})的明细数据");
-        }
-    }
-
     // ══════════════════════════════════════════════════════════════
     // 3级计划重排 — 内部 DTO
     // ══════════════════════════════════════════════════════════════
@@ -1013,11 +890,4 @@ public class OrderReviewOrchestrationService : ITransient
         public string? ItemName { get; set; }
     }
 
-    private sealed class OrderShippingInfoRow
-    {
-        public string? CustomName { get; set; }
-        public string? Country { get; set; }
-        public DateTime? OrderDate { get; set; }
-    }
-
 }

+ 3 - 2
server/Plugins/Admin.NET.Plugin.AiDOP/Order/ResourceCheckResultWriter.cs

@@ -69,7 +69,7 @@ public class ResourceCheckResultWriter : ITransient
             new SugarParameter("@CompanyId", companyId));
 
         var activeLines = lines.Where(x => x.IsUse == 1).ToList();
-        foreach (var line in activeLines)
+        foreach (var line in lines)
         {
             var childId = YitIdHelper.NextId();
             await _db.Ado.ExecuteCommandAsync(
@@ -87,7 +87,7 @@ public class ResourceCheckResultWriter : ITransient
                     @Num, @Type, @ItemName, @Model, @Unit, @ErpCls, @ErpClsName, @Backflush,
                     @Qty, @Sqty, @UseQty, @SelfLackQty, @LackQty, @MoQty, @MakeQty, @PurchaseQty, @PurchaseOccupyQty,
                     @KittingTime, @SatisfyTime, @IsBom, @HaveIcSubs, @SubstituteCode, @NeedCount, @NeedCountNoLoss,
-                    @Wastage, @Scrap, 1, 0,
+                    @Wastage, @Scrap, @IsUse, 0,
                     @User, @Now, @User, @Now,
                     @TenantId, @FactoryId, @CompanyId, 0
                 )
@@ -127,6 +127,7 @@ public class ResourceCheckResultWriter : ITransient
                 new SugarParameter("@NeedCountNoLoss", line.NeedCountNoLoss),
                 new SugarParameter("@Wastage", line.Wastage),
                 new SugarParameter("@Scrap", line.Scrap),
+                new SugarParameter("@IsUse", line.IsUse),
                 new SugarParameter("@User", account),
                 new SugarParameter("@Now", now),
                 new SugarParameter("@TenantId", entry.TenantId),

+ 1 - 1
server/Plugins/Admin.NET.Plugin.AiDOP/Order/SeOrderService.cs

@@ -80,7 +80,7 @@ public class SeOrderService : IDynamicApiController, ITransient
         var total = await _db.Ado.GetIntAsync(
             $"SELECT COUNT(*) FROM ({baseSql}) AS t {outerWhere}", pars);
         var list = await _db.Ado.SqlQueryAsync<SeOrderListRow>(
-            $"SELECT * FROM ({baseSql}) AS t {outerWhere} ORDER BY t.Id DESC LIMIT {input.PageSize} OFFSET {offset}", pars);
+            $"SELECT * FROM ({baseSql}) AS t {outerWhere} ORDER BY t.RDate DESC, t.Id DESC LIMIT {input.PageSize} OFFSET {offset}", pars);
 
         return new { total, page = input.Page, pageSize = input.PageSize, list };
     }

+ 2 - 8
server/Plugins/Admin.NET.Plugin.AiDOP/WorkOrder/WorkOrderMaterialDetailSyncService.cs

@@ -88,17 +88,11 @@ public class WorkOrderMaterialDetailSyncService : ITransient
             }
         }
 
-        // 删除不再有缺料的旧明细
+        // 删除资源检查中没有的子物料
         foreach (var stale in existingMap.Values)
         {
             await _db.Ado.ExecuteCommandAsync(
-                """
-                UPDATE WorkOrdDetail
-                SET IsActive = 0, UpdateUser = @User, UpdateTime = @Now
-                WHERE RecID = @RecID
-                """,
-                new SugarParameter("@User", account),
-                new SugarParameter("@Now", now),
+                "DELETE FROM WorkOrdDetail WHERE RecID = @RecID",
                 new SugarParameter("@RecID", stale.RecID));
         }