From b1f5b17a608d3d9c06ce216c7e1effc5edcc7b74 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期一, 06 四月 2026 19:53:31 +0800
Subject: [PATCH] 更新机器人工作流逻辑、配置并添加电子表格
---
Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs | 242 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 240 insertions(+), 2 deletions(-)
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs
index 8e4027b..0fd9881 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs
@@ -1,6 +1,10 @@
using WIDESEA_Common.StockEnum;
+using WIDESEA_Core;
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.BaseServices;
+using WIDESEA_DTO.Stock;
+using WIDESEA_IBasicService;
+using WIDESEA_IRecordService;
using WIDESEA_IStockService;
using WIDESEA_Model.Models;
@@ -17,11 +21,29 @@
public IRepository<Dt_StockInfo> Repository => BaseDal;
/// <summary>
+ /// 璐т綅淇℃伅鏈嶅姟鎺ュ彛锛堢敤浜庤幏鍙栦粨搴撹揣浣嶄俊鎭級
+ /// </summary>
+ private readonly ILocationInfoService _locationInfoService;
+
+ /// <summary>
+ /// 浠撳簱淇℃伅鏈嶅姟鎺ュ彛锛堢敤浜庤幏鍙栦粨搴撳熀鏈俊鎭級
+ /// </summary>
+ private readonly IWarehouseService _warehouseService;
+ private readonly IRecordService _recordService;
+
+ /// <summary>
/// 鏋勯�犲嚱鏁�
/// </summary>
/// <param name="baseDal">鍩虹鏁版嵁璁块棶瀵硅薄</param>
- public StockInfoService(IRepository<Dt_StockInfo> baseDal) : base(baseDal)
+ public StockInfoService(
+ IRepository<Dt_StockInfo> baseDal,
+ ILocationInfoService locationInfoService,
+ IWarehouseService warehouseService,
+ IRecordService recordService) : base(baseDal)
{
+ _locationInfoService = locationInfoService;
+ _warehouseService = warehouseService;
+ _recordService = recordService;
}
/// <summary>
@@ -65,7 +87,100 @@
/// <returns>鏇存柊鏄惁鎴愬姛</returns>
public async Task<bool> UpdateStockAsync(Dt_StockInfo stockInfo)
{
- return await BaseDal.UpdateDataAsync(stockInfo);
+ var beforeStock = await BaseDal.QueryDataNavFirstAsync(x => x.Id == stockInfo.Id);
+ var result = await BaseDal.UpdateDataAsync(stockInfo);
+ if (!result)
+ return false;
+
+ var afterStock = await BaseDal.QueryDataNavFirstAsync(x => x.Id == stockInfo.Id) ?? stockInfo;
+ var changeType = ResolveChangeType(beforeStock, afterStock);
+ return await _recordService.AddStockChangeRecordAsync(beforeStock, afterStock, changeType, remark: "搴撳瓨鏇存柊");
+ }
+
+ public override WebResponseContent AddData(Dt_StockInfo entity)
+ {
+ var result = base.AddData(entity);
+ if (!result.Status)
+ return result;
+
+ var saveRecordResult = _recordService.AddStockChangeRecordAsync(null, entity, StockChangeTypeEnum.Inbound, remark: "搴撳瓨鏂板").GetAwaiter().GetResult();
+ return saveRecordResult ? result : WebResponseContent.Instance.Error("搴撳瓨鍙樻洿璁板綍淇濆瓨澶辫触");
+ }
+
+ public override WebResponseContent UpdateData(Dt_StockInfo entity)
+ {
+ var beforeStock = BaseDal.QueryFirst(x => x.Id == entity.Id);
+ var result = base.UpdateData(entity);
+ if (!result.Status)
+ return result;
+
+ var changeType = ResolveChangeType(beforeStock, entity);
+ var saveRecordResult = _recordService.AddStockChangeRecordAsync(beforeStock, entity, changeType, remark: "搴撳瓨鏇存柊").GetAwaiter().GetResult();
+ return saveRecordResult ? result : WebResponseContent.Instance.Error("搴撳瓨鍙樻洿璁板綍淇濆瓨澶辫触");
+ }
+
+ public override WebResponseContent DeleteData(Dt_StockInfo entity)
+ {
+ var beforeStock = CloneStockSnapshot(entity);
+ var result = base.DeleteData(entity);
+ if (!result.Status)
+ return result;
+
+ var saveRecordResult = _recordService.AddStockChangeRecordAsync(beforeStock, null, StockChangeTypeEnum.Outbound, remark: "搴撳瓨鍒犻櫎").GetAwaiter().GetResult();
+ return saveRecordResult ? result : WebResponseContent.Instance.Error("搴撳瓨鍙樻洿璁板綍淇濆瓨澶辫触");
+ }
+
+ private static StockChangeTypeEnum ResolveChangeType(Dt_StockInfo? beforeStock, Dt_StockInfo? afterStock)
+ {
+ if (beforeStock == null)
+ return StockChangeTypeEnum.Inbound;
+
+ if (afterStock == null)
+ return StockChangeTypeEnum.Outbound;
+
+ if (!string.Equals(beforeStock.LocationCode, afterStock.LocationCode, StringComparison.OrdinalIgnoreCase))
+ return StockChangeTypeEnum.Relocation;
+
+ if (beforeStock.StockStatus != afterStock.StockStatus)
+ return StockChangeTypeEnum.StockLock;
+
+ var beforeQuantity = beforeStock.Details?.Sum(x => x.StockQuantity) ?? 0;
+ var afterQuantity = afterStock.Details?.Sum(x => x.StockQuantity) ?? 0;
+ return afterQuantity >= beforeQuantity ? StockChangeTypeEnum.Inbound : StockChangeTypeEnum.Outbound;
+ }
+
+ private static Dt_StockInfo CloneStockSnapshot(Dt_StockInfo stockInfo)
+ {
+ return new Dt_StockInfo
+ {
+ Id = stockInfo.Id,
+ PalletCode = stockInfo.PalletCode,
+ PalletType = stockInfo.PalletType,
+ LocationId = stockInfo.LocationId,
+ LocationCode = stockInfo.LocationCode,
+ WarehouseId = stockInfo.WarehouseId,
+ StockStatus = stockInfo.StockStatus,
+ Remark = stockInfo.Remark,
+ OutboundDate = stockInfo.OutboundDate,
+ Details = stockInfo.Details?.Select(detail => new Dt_StockInfoDetail
+ {
+ Id = detail.Id,
+ StockId = detail.StockId,
+ MaterielCode = detail.MaterielCode,
+ MaterielName = detail.MaterielName,
+ OrderNo = detail.OrderNo,
+ BatchNo = detail.BatchNo,
+ ProductionDate = detail.ProductionDate,
+ EffectiveDate = detail.EffectiveDate,
+ SerialNumber = detail.SerialNumber,
+ StockQuantity = detail.StockQuantity,
+ OutboundQuantity = detail.OutboundQuantity,
+ Status = detail.Status,
+ Unit = detail.Unit,
+ InboundOrderRowNo = detail.InboundOrderRowNo,
+ Remark = detail.Remark
+ }).ToList()
+ };
}
/// <summary>
@@ -78,5 +193,128 @@
{
return await BaseDal.QueryFirstAsync(x => x.PalletCode == palletCode && x.LocationCode == locationCode);
}
+
+ /// <summary>
+ /// 鑾峰彇浠撳簱3D甯冨眬鏁版嵁
+ /// </summary>
+ /// <param name="warehouseId">浠撳簱ID</param>
+ /// <returns>3D甯冨眬DTO</returns>
+ public async Task<Stock3DLayoutDTO> Get3DLayoutAsync(int warehouseId)
+ {
+ // 1. 鏌ヨ浠撳簱淇℃伅
+ var warehouse = await _warehouseService.Repository.QueryFirstAsync(x => x.WarehouseId == warehouseId);
+
+ // 2. 鏌ヨ璇ヤ粨搴撴墍鏈夎揣浣�
+ var locations = await _locationInfoService.Repository.QueryDataAsync(x => x.WarehouseId == warehouseId);
+
+ // 3. 鏌ヨ璇ヤ粨搴撴墍鏈夊簱瀛樹俊鎭紙鍖呭惈Details瀵艰埅灞炴�э級
+ var stockInfos = await Repository.QueryDataNavAsync(x => x.WarehouseId == warehouseId && x.LocationId != 0);
+
+ // 4. 鎻愬彇鐗╂枡缂栧彿鍜屾壒娆″彿鍒楄〃锛堝幓閲嶏級
+ var materielCodeList = stockInfos
+ .Where(s => s.Details != null)
+ .SelectMany(s => s.Details)
+ .Select(d => d.MaterielCode)
+ .Where(c => !string.IsNullOrEmpty(c))
+ .Distinct()
+ .ToList();
+
+ var batchNoList = stockInfos
+ .Where(s => s.Details != null)
+ .SelectMany(s => s.Details)
+ .Select(d => d.BatchNo)
+ .Where(b => !string.IsNullOrEmpty(b))
+ .Distinct()
+ .ToList();
+
+ // 5. 鍒涘缓搴撳瓨瀛楀吀鐢ㄤ簬蹇�熸煡鎵撅紙浠ocationId涓洪敭锛�
+ var stockDict = stockInfos.ToDictionary(s => s.LocationId, s => s);
+
+ // 6. 鏄犲皠姣忎釜璐т綅鍒癓ocation3DItemDTO
+ const float defaultMaxCapacity = 100f;
+ var locationItems = locations.Select(loc =>
+ {
+ var item = new Location3DItemDTO
+ {
+ LocationId = loc.Id,
+ LocationCode = loc.LocationCode,
+ Row = loc.Row,
+ Column = loc.Column,
+ Layer = loc.Layer,
+ LocationStatus = loc.LocationStatus,
+ MaxCapacity = defaultMaxCapacity
+ };
+
+ // 灏濊瘯浠庡簱瀛樺瓧鍏镐腑鑾峰彇搴撳瓨淇℃伅
+ if (stockDict.TryGetValue(loc.Id, out var stockInfo))
+ {
+ // 绌烘墭鐩樹篃鏈夊簱瀛樿褰曪紝鍙槸涓嶅寘鍚槑缁�
+ item.PalletCode = stockInfo.PalletCode;
+ item.StockStatus = stockInfo.StockStatus; // 鐩存帴浣跨敤鍚庣搴撳瓨鐘舵��
+
+ // 鍙湁褰揇etails涓嶄负null涓旀湁鏁版嵁鏃舵墠澶勭悊搴撳瓨鏄庣粏
+ if (stockInfo.Details != null && stockInfo.Details.Any())
+ {
+ item.StockQuantity = stockInfo.Details.Sum(d => d.StockQuantity);
+
+ // 鑾峰彇绗竴涓槑缁嗙殑鐗╂枡淇℃伅锛堝鏋滃瓨鍦級
+ var firstDetail = stockInfo.Details.FirstOrDefault();
+ if (firstDetail != null)
+ {
+ item.MaterielCode = firstDetail.MaterielCode;
+ item.MaterielName = firstDetail.MaterielName;
+ item.BatchNo = firstDetail.BatchNo;
+ }
+
+ // 濉厖搴撳瓨鏄庣粏鍒楄〃
+ item.Details = stockInfo.Details.Select(d => new StockDetailItemDTO
+ {
+ Id = d.Id,
+ MaterielCode = d.MaterielCode,
+ MaterielName = d.MaterielName,
+ BatchNo = d.BatchNo,
+ StockQuantity = d.StockQuantity,
+ Unit = d.Unit,
+ ProductionDate = d.ProductionDate,
+ EffectiveDate = d.EffectiveDate,
+ OrderNo = d.OrderNo,
+ Status = d.Status
+ }).ToList();
+ }
+ else
+ {
+ // 绌烘墭鐩橈紙鏃犳槑缁嗭級
+ item.StockQuantity = 0;
+ item.Details = new List<StockDetailItemDTO>(); // 纭繚鏄┖鍒楄〃鑰岄潪null
+ }
+ }
+ else
+ {
+ // 鏃犲簱瀛樿褰曪紝璐т綅涓虹┖
+ item.StockStatus = 0; // 绌洪棽
+ item.StockQuantity = 0;
+ }
+
+ return item;
+ }).ToList();
+
+ // 7. 璁$畻浠撳簱灏哄
+ var maxRow = locations.Any() ? locations.Max(l => l.Row) : 0;
+ var maxColumn = locations.Any() ? locations.Max(l => l.Column) : 0;
+ var maxLayer = locations.Any() ? locations.Max(l => l.Layer) : 0;
+
+ // 8. 鏋勫缓杩斿洖缁撴灉
+ return new Stock3DLayoutDTO
+ {
+ WarehouseId = warehouseId,
+ WarehouseName = warehouse?.WarehouseName ?? string.Empty,
+ MaxRow = maxRow,
+ MaxColumn = maxColumn,
+ MaxLayer = maxLayer,
+ MaterielCodeList = materielCodeList,
+ BatchNoList = batchNoList,
+ Locations = locationItems
+ };
+ }
}
}
--
Gitblit v1.9.3