11
tjx
7 天以前 fbddf8270dffec0192fa40c8b78a714e72f64c6f
StandardPda/MES.Service/service/Warehouse/MesInvItemStocksManager.cs
@@ -28,21 +28,21 @@
            throw new Exception("每页条数必须为10、20或50");
        }
        // 1. 优化:使用原生SQL获取每个条码的最新记录(避免全表加载到内存)
        // 使用窗口函数ROW_NUMBER在数据库层面完成分组取最新记录
        var sql = @"
            SELECT ITEM_BARCODE, PalletCode, Code, Id
            FROM (SELECT ITEM_BARCODE,
                         PalletCode,
                         Code,
                         Id,
                         ROW_NUMBER() OVER (PARTITION BY ITEM_BARCODE ORDER BY Id DESC) as rn
                  FROM XB_RACKING_TASK_SYXT_LOG
                  WHERE ITEM_BARCODE IS NOT NULL
                    AND Code != '500') t
            WHERE rn = 1";
        // 1. 查询XB_RACKING_TASK_SYXT_LOG中ItemBarcode和PalletCode的映射关系
        var allRackingTaskData = Db.Queryable<XbRackingTaskSyxtLog>()
            .Where(x => !string.IsNullOrEmpty(x.ItemBarcode))
            .Select(x => new { x.ItemBarcode, x.PalletCode, x.Code, x.Id })
            .ToList();
        
        var rackingTaskData = Db.Ado.SqlQuery<RackingTaskInfo>(sql);
        // ReturnableStockDto增加一个库存状态的字段
        // 当allRackingTaskData中的Code为null时,库存状态为立库入库中
        // 当allRackingTaskData中的Code为200时,库存状态为已经在立库内
        // 对每个条码,取最新ID的记录,并过滤掉Code为500(表示失败)的记录
        var rackingTaskData = allRackingTaskData
            .GroupBy(x => x.ItemBarcode) // 按条码分组
            .Select(g => g.OrderByDescending(x => x.Id).First()) // 取每个条码最新的一条记录
            .Where(x => x.Code != "500") // 过滤掉Code为500的失败记录
            .ToList();
        if (rackingTaskData == null || !rackingTaskData.Any())
        {
@@ -63,18 +63,7 @@
        var distinctBarcodes = rackingTaskData.Select(x => x.ItemBarcode)
            .Distinct().ToList();
        // 1.2 提取搜索条件(提升作用域)
        var conditions = searchDto.Conditions;
        // 2. 优化:分批处理条码列表(避免IN查询过大)
        const int batchSize = 500; // 每批处理500条
        var allQueryResults = new List<StockQueryResult>();
        for (int i = 0; i < distinctBarcodes.Count; i += batchSize)
        {
            var batchBarcodes = distinctBarcodes.Skip(i).Take(batchSize).ToList();
            // 2.1 构建查询条件
        // 2. 构建查询条件
            var query = Db.Queryable<MesInvItemStocks>()
                .LeftJoin<MesItems>((stock, item) => stock.ItemId == item.Id)
                .LeftJoin<MesDepots>((stock, item, depot) =>
@@ -84,11 +73,12 @@
                .LeftJoin<MesUnit>((stock, item, depot, org, unit) =>
                    item.ItemUnit == unit.Id.ToString())
                .Where((stock, item, depot, org, unit) =>
                    (batchBarcodes.Contains(stock.ItemBarcode) ||
                     batchBarcodes.Contains(stock.StackCode)) &&
                (distinctBarcodes.Contains(stock.ItemBarcode) ||
                 distinctBarcodes.Contains(stock.StackCode)) &&
                    stock.Quantity > 0);
            // 2.2 应用搜索条件(在数据库层面过滤)
        // 3. 应用搜索条件
        var conditions = searchDto.Conditions;
            if (conditions != null)
            {
                //当conditions.IqcStatus为1时查询的值就要是特采直接使用,已检,免检,1的值
@@ -206,39 +196,29 @@
                }
            }
            // 2.3 执行当前批次查询
            var batchQueryResult = query
        // 4. 查询所有符合条件的数据(不分页)
        var queryResult = query
                .OrderByDescending((stock, item, depot, org, unit) =>
                    stock.IndepDate)
                .Select((stock, item, depot, org, unit) => new StockQueryResult
            .Select((stock, item, depot, org, unit) => new
                {
                    IqcStatus = stock.IqcStatus,
                stock.IqcStatus,
                    DepotCode = stock.DepotsCode,
                    DepotName = depot.DepotName,
                    DepotSectionsCode = stock.DepotSectionsCode,
                    ItemNo = item.ItemNo,
                    ItemName = item.ItemName,
                    ItemModel = item.ItemModel,
                    Quantity = stock.Quantity,
                    ItemUnit = item.ItemUnit,
                depot.DepotName,
                stock.DepotSectionsCode,
                item.ItemNo,
                item.ItemName,
                item.ItemModel,
                stock.Quantity,
                item.ItemUnit,
                    ItemUnitName = unit.Fname,
                    IndepDate = stock.IndepDate,
                stock.IndepDate,
                    OrgCode = org.Fnumber,
                    OrgName = org.Fname,
                    ItemBarcode = stock.ItemBarcode,
                stock.ItemBarcode,
                    StockStackCode = stock.StackCode
                })
                .ToList();
            allQueryResults.AddRange(batchQueryResult);
        }
        // 3. 合并所有批次的查询结果
        var queryResult = allQueryResults;
        // 4. 优化:构建条码映射字典(提高查找效率)
        var rackingTaskDict = rackingTaskData
            .ToDictionary(x => x.ItemBarcode, x => x);
        // 5. 在内存中转换为DTO,关联PalletCode并赋值ItemBarcode(优先使用箱条码StockStackCode)
        var tempDataList = queryResult.Select(x =>
@@ -247,12 +227,12 @@
            var barcodeToMatch = !string.IsNullOrEmpty(x.StockStackCode)
                ? x.StockStackCode
                : x.ItemBarcode;
            // 使用字典查找,性能更优
            rackingTaskDict.TryGetValue(barcodeToMatch, out var rackingTask);
            var rackingTask = rackingTaskData
                .Where(r => r.ItemBarcode == barcodeToMatch)
                .FirstOrDefault();
            // 根据Code值确定库存状态: null为立库入库中(0), 200为已在立库内(1)
            string? stockStatus = "进入立库的路上"; // 默认为立库入库中
            string stockStatus = "进入立库的路上"; // 默认为立库入库中
            if (rackingTask?.Code != null)
            {
                stockStatus = rackingTask.Code == "200" ? "已在立库中" : "进入立库的路上";
@@ -371,39 +351,6 @@
    }
    /// <summary>
    ///     辅助类:立库任务信息
    /// </summary>
    private class RackingTaskInfo
    {
        public string? ItemBarcode { get; set; }
        public string? PalletCode { get; set; }
        public string? Code { get; set; }
        public decimal Id { get; set; }
    }
    /// <summary>
    ///     辅助类:库存查询中间结果
    /// </summary>
    private class StockQueryResult
    {
        public string? IqcStatus { get; set; }
        public string? DepotCode { get; set; }
        public string? DepotName { get; set; }
        public string? DepotSectionsCode { get; set; }
        public string? ItemNo { get; set; }
        public string? ItemName { get; set; }
        public string? ItemModel { get; set; }
        public decimal? Quantity { get; set; }
        public string? ItemUnit { get; set; }
        public string? ItemUnitName { get; set; }
        public DateTime? IndepDate { get; set; }
        public string? OrgCode { get; set; }
        public string? OrgName { get; set; }
        public string? ItemBarcode { get; set; }
        public string? StockStackCode { get; set; }
    }
    /// <summary>
    ///     查询可以退货的物料(旧版本,保留兼容)
    /// </summary>
    /// <returns>可退货物料库存列表</returns>
@@ -473,7 +420,7 @@
                .FirstOrDefault();
            // 根据Code值确定库存状态: null为立库入库中(0), 200为已在立库内(1)
            string? stockStatus = "0"; // 默认为立库入库中
            string stockStatus = "0"; // 默认为立库入库中
            if (rackingTask?.Code != null)
            {
                stockStatus =
@@ -542,7 +489,7 @@
                }
                decimal messageId = 0;
                string? taskCode = "";
                string taskCode = "";
                // 根据条码查询XB_RACKING_TASK_SYXT_LOG表,查询max(PALLETCODE)和对应的widthType
                var rackingTaskInfo = Db.Queryable<XbRackingTaskSyxtLog>()
@@ -647,8 +594,8 @@
                        throw new Exception($"解析响应失败: {responseStr}");
                    }
                    var code = responseJson?.Code?.ToString()();
                    var jsonMessage = responseJson?.JsonMessage?.ToString()();
                    var code = responseJson?.Code?.ToString();
                    var jsonMessage = responseJson?.JsonMessage?.ToString();
                    // 7. 根据Code判断成功或失败
                    if (code == "200")
@@ -688,7 +635,7 @@
                            ? "任务请求失败"
                            : jsonMessage;
                        var failureMessage =
                            (string?)("立库任务下发失败: " + errorMessage);
                            (string)("立库任务下发失败: " + errorMessage);
                        Db.Updateable<MessageCenter>()
                            .SetColumns(it => it.Result == 0)
@@ -707,7 +654,7 @@
                    if (messageId > 0)
                    {
                        var exceptionMessage =
                            (string?)("立库任务异常: " + ex.Message);
                            (string)("立库任务异常: " + ex.Message);
                        Db.Updateable<MessageCenter>()
                            .SetColumns(it => it.Result == 0)
                            .SetColumns(it =>