From 0e214856df682998cd52df74c851502c571ba183 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期二, 28 四月 2026 23:22:23 +0800
Subject: [PATCH] feat(出库任务): 优化二深位出库的移库逻辑并添加事务支持
---
Code/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs | 231 ++++++++++++++++++++++++++++++++++-----------------------
1 files changed, 138 insertions(+), 93 deletions(-)
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs
index 9594985..d7aee6d 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs
@@ -26,6 +26,7 @@
private readonly IRepository<Dt_StockInfo> _stockInfoRepository;
private readonly IRecordService _recordService;
private readonly IRepository<Dt_Warehouse> _warehouseRepository;
+ private readonly IUnitOfWorkManage _unitOfWorkManage;
/// <summary>
/// 鏋勯�犲嚱鏁�
@@ -33,19 +34,22 @@
/// <param name="baseDal">鍩虹鏁版嵁璁块棶瀵硅薄</param>
/// <param name="taskRepository">浠诲姟浠撳偍</param>
/// <param name="stockInfoRepository">搴撳瓨淇℃伅浠撳偍</param>
+ /// <param name="unitOfWorkManage">宸ヤ綔鍗曞厓绠$悊鍣�</param>
public LocationInfoService(
IRepository<Dt_LocationInfo> baseDal,
IRepository<Dt_Task> taskRepository,
IRepository<Dt_StockInfo> stockInfoRepository,
IRepository<Dt_Warehouse> warehouseRepository,
IMapper mapper,
- IRecordService recordService) : base(baseDal)
+ IRecordService recordService,
+ IUnitOfWorkManage unitOfWorkManage) : base(baseDal)
{
_taskRepository = taskRepository;
_stockInfoRepository = stockInfoRepository;
_mapper = mapper;
_recordService = recordService;
_warehouseRepository = warehouseRepository;
+ _unitOfWorkManage = unitOfWorkManage;
}
/// <summary>
@@ -270,24 +274,29 @@
return content.Error("浠诲姟涓嶅瓨鍦�");
var location = await BaseDal.QueryFirstAsync(x => x.LocationCode == outboundTask.SourceAddress && x.RoadwayNo == outboundTask.Roadway);
+ if (location == null)
+ return content.Error("鏈壘鍒版簮璐т綅淇℃伅");
- // 妫�鏌ユ槸鍚﹂渶瑕佽繘琛岀Щ搴�
+ // 妫�鏌ユ槸鍚﹂渶瑕佽繘琛岀Щ搴擄紙浜屾繁浣嶅嚭搴撻渶瑕佸厛绉昏蛋涓�娣变綅锛�
if (CheckForInternalTransfer(location))
{
// 璁$畻瀵瑰簲浣嶇疆鐨勭浉瀵瑰簱浣嶏紙濂囨暟琛岀殑涓嬩竴琛屾垨鑰呭伓鏁拌鐨勪笂涓�琛岋級
- var newLocationID = GetRelativeLocationID(location);
+ var relativeLocationCode = GetRelativeLocationID(location);
- // 鑾峰彇鏂扮殑搴撲綅鐨勪换鍔�
- var internalTransferTask = await _taskRepository.QueryFirstAsync(x => x.SourceAddress == newLocationID && x.Roadway == outboundTask.Roadway);
+ // 鏌ユ壘鐩稿搴撲綅涓婄殑娲昏穬浠诲姟锛堟帓闄ゅ凡瀹屾垚銆佸凡鍙栨秷銆佸紓甯哥瓑缁堟�侊級
+ var activeTask = await _taskRepository.QueryFirstAsync(x =>
+ x.SourceAddress == relativeLocationCode
+ && x.Roadway == outboundTask.Roadway
+ && (x.TaskStatus == TaskOutStatusEnum.OutNew.GetHashCode()));
- // 濡傛灉鏂扮殑搴撲綅娌℃湁鎵惧埌瀵瑰簲鐨勪换鍔�
- if (internalTransferTask == null)
+ // 濡傛灉鐩稿搴撲綅娌℃湁娲昏穬浠诲姟锛屽皾璇曞垱寤虹Щ搴撲换鍔�
+ if (activeTask == null)
{
- return content.OK("鑾峰彇鍒扮Щ搴撲换鍔�", await HandleNoTaskAtLocation(newLocationID, outboundTask));
+ return await HandleNoTaskAtLocation(relativeLocationCode, outboundTask);
}
// 鐩存帴杩斿洖涓�娣变綅鍑哄簱浠诲姟
- return content.OK("鑾峰彇鍒颁竴娣变綅鍑哄簱浠诲姟", internalTransferTask);
+ return content.OK("鑾峰彇鍒颁竴娣变綅鍑哄簱浠诲姟", activeTask);
}
// 杩斿洖褰撳墠搴撲綅鐨勫嚭搴撲换鍔�
@@ -319,12 +328,13 @@
}
/// <summary>
- /// 澶勭悊娌℃湁浠诲姟鐨勫簱浣嶆儏鍐�
+ /// 澶勭悊娌℃湁娲昏穬浠诲姟鐨勫簱浣嶆儏鍐�
+ /// 鍒ゆ柇鏄惁鏈夊簱瀛橈紝鏈夊垯鐢熸垚绉诲簱浠诲姟锛屾棤鍒欑洿鎺ヨ繑鍥炲嚭搴撲换鍔�
/// </summary>
- /// <param name="newLocationID">鏂扮殑搴撲綅ID</param>
- /// <param name="outboundTask">鍑哄簱浠诲姟</param>
- /// <returns>鐢熸垚鐨勭Щ搴撲换鍔℃垨鍘熷鍑哄簱浠诲姟</returns>
- private async Task<Dt_Task> HandleNoTaskAtLocation(string newLocationID, Dt_Task outboundTask)
+ /// <param name="newLocationID">鐩稿搴撲綅缂栫爜</param>
+ /// <param name="outboundTask">鍘熷鍑哄簱浠诲姟</param>
+ /// <returns>鎿嶄綔缁撴灉锛堝寘鍚Щ搴撲换鍔℃垨鍘熷鍑哄簱浠诲姟锛�</returns>
+ private async Task<WebResponseContent> HandleNoTaskAtLocation(string newLocationID, Dt_Task outboundTask)
{
// 鍒ゆ柇璇ヤ綅缃槸鍚︽湁搴撳瓨
var stockInfo = await _stockInfoRepository.QueryDataNavFirstAsync(x =>
@@ -334,98 +344,116 @@
if (stockInfo == null)
{
// 濡傛灉娌℃湁搴撳瓨锛岀洿鎺ヨ繑鍥炲綋鍓嶅嚭搴撲换鍔�
- return outboundTask;
+ return WebResponseContent.Instance.OK("褰撳墠鍑哄簱浠诲姟", outboundTask);
}
- // 濡傛灉鏈夊簱瀛橈紝鐢熸垚绉诲簱浠诲姟
- var emptyLocation = await GetTransferLocationEmptyAsync(outboundTask.Roadway);
- var taskNo = await _taskRepository.GetTaskNo();
-
- var newTransferTask = new Dt_Task
+ // 鏈夊簱瀛樻椂锛屽湪浜嬪姟涓垱寤虹Щ搴撲换鍔″苟閿佸畾鐩稿叧璧勬簮
+ return await _unitOfWorkManage.BeginTranAsync(async () =>
{
- CreateDate = DateTime.Now,
- Creater = App.User.UserName ?? "system",
- CurrentAddress = newLocationID,
- Grade = 99,
- NextAddress = emptyLocation.LocationCode,
- PalletCode = stockInfo.PalletCode,
- Remark = "绉诲簱",
- Roadway = stockInfo.LocationDetails.RoadwayNo,
- SourceAddress = newLocationID,
- TaskNum = taskNo,
- TargetAddress = emptyLocation.LocationCode,
- TaskType = TaskRelocationTypeEnum.Relocation.GetHashCode(),
- TaskStatus = TaskRelocationStatusEnum.RelocationNew.GetHashCode(),
- WarehouseId = stockInfo.WarehouseId
- };
+ // 浜嬪姟鍐呭啀娆$‘璁ゆ病鏈夋椿璺冧换鍔★紙闃叉骞跺彂閲嶅鍒涘缓绉诲簱浠诲姟锛�
+ var existingTask = await _taskRepository.QueryFirstAsync(x =>
+ x.SourceAddress == newLocationID
+ && x.Roadway == outboundTask.Roadway
+ && (x.TaskStatus == TaskOutStatusEnum.OutNew.GetHashCode()));
+ if (existingTask != null)
+ {
+ return WebResponseContent.Instance.OK("鑾峰彇鍒板凡鏈変换鍔�", existingTask);
+ }
- var createdTask = await _taskRepository.Db.Insertable(newTransferTask).ExecuteReturnEntityAsync();
- var beforeStock = CloneStockSnapshot(stockInfo);
- var beforeSourceLocation = stockInfo.LocationDetails == null ? null : CloneLocationSnapshot(stockInfo.LocationDetails);
- var beforeTargetLocation = CloneLocationSnapshot(emptyLocation);
+ // 鑾峰彇鐩爣绌哄簱浣�
+ var emptyLocation = await GetTransferLocationEmptyAsync(outboundTask.Roadway);
+ if (emptyLocation == null)
+ {
+ return WebResponseContent.Instance.Error("鏈壘鍒板彲鐢ㄧ殑绌哄簱浣嶇敤浜庣Щ搴�");
+ }
- // 鍒涘缓绉诲簱浠诲姟鍚庯紝绔嬪嵆閿佸畾搴撳瓨鍜岀浉鍏宠揣浣嶏紝閬垮厤骞跺彂閲嶅鍒嗛厤
- stockInfo.StockStatus = StockStatusEmun.绉诲簱閿佸畾.GetHashCode();
- var updateStockResult = await _stockInfoRepository.UpdateDataAsync(stockInfo);
+ var taskNo = await _taskRepository.GetTaskNo();
+ var newTransferTask = new Dt_Task
+ {
+ CreateDate = DateTime.Now,
+ Creater = App.User.UserName ?? "system",
+ CurrentAddress = newLocationID,
+ Grade = 99,
+ NextAddress = emptyLocation.LocationCode,
+ PalletCode = stockInfo.PalletCode,
+ Remark = "绉诲簱",
+ Roadway = stockInfo.LocationDetails.RoadwayNo,
+ SourceAddress = newLocationID,
+ TaskNum = taskNo,
+ TargetAddress = emptyLocation.LocationCode,
+ TaskType = TaskRelocationTypeEnum.Relocation.GetHashCode(),
+ TaskStatus = TaskRelocationStatusEnum.RelocationNew.GetHashCode(),
+ WarehouseId = stockInfo.WarehouseId
+ };
- var locationsToUpdate = new List<Dt_LocationInfo>();
- if (stockInfo.LocationDetails != null)
- {
- stockInfo.LocationDetails.LocationStatus = LocationStatusEnum.InStockLock.GetHashCode();
- locationsToUpdate.Add(stockInfo.LocationDetails);
- }
+ var createdTask = await _taskRepository.Db.Insertable(newTransferTask).ExecuteReturnEntityAsync();
+ var beforeStock = CloneStockSnapshot(stockInfo);
+ var beforeSourceLocation = stockInfo.LocationDetails == null ? null : CloneLocationSnapshot(stockInfo.LocationDetails);
+ var beforeTargetLocation = CloneLocationSnapshot(emptyLocation);
- emptyLocation.LocationStatus = LocationStatusEnum.FreeLock.GetHashCode();
- locationsToUpdate.Add(emptyLocation);
+ // 鍒涘缓绉诲簱浠诲姟鍚庯紝绔嬪嵆閿佸畾搴撳瓨鍜岀浉鍏宠揣浣�
+ stockInfo.StockStatus = StockStatusEmun.绉诲簱閿佸畾.GetHashCode();
+ var updateStockResult = await _stockInfoRepository.UpdateDataAsync(stockInfo);
- var updateLocationResult = await BaseDal.UpdateDataAsync(locationsToUpdate);
- if (!updateStockResult || !updateLocationResult)
- {
- throw new Exception("鍒涘缓绉诲簱浠诲姟鍚庢洿鏂板簱瀛樼姸鎬佹垨璐т綅鐘舵�佸け璐�");
- }
+ var locationsToUpdate = new List<Dt_LocationInfo>();
+ if (stockInfo.LocationDetails != null)
+ {
+ stockInfo.LocationDetails.LocationStatus = LocationStatusEnum.InStockLock.GetHashCode();
+ locationsToUpdate.Add(stockInfo.LocationDetails);
+ }
- var saveStockRecordResult = await _recordService.AddStockChangeRecordAsync(
- beforeStock,
- stockInfo,
- StockChangeTypeEnum.Relocation,
- createdTask.TaskNum,
- createdTask.OrderNo,
- "绉诲簱浠诲姟棰勫崰搴撳瓨");
- if (!saveStockRecordResult)
- {
- throw new Exception("鍒涘缓绉诲簱浠诲姟鍚庤褰曞簱瀛樺彉鏇村け璐�");
- }
+ emptyLocation.LocationStatus = LocationStatusEnum.FreeLock.GetHashCode();
+ locationsToUpdate.Add(emptyLocation);
- if (beforeSourceLocation != null && stockInfo.LocationDetails != null)
- {
- var saveSourceLocationRecordResult = await _recordService.AddLocationChangeRecordAsync(
- beforeSourceLocation,
- stockInfo.LocationDetails,
+ var updateLocationResult = await BaseDal.UpdateDataAsync(locationsToUpdate);
+ if (!updateStockResult || !updateLocationResult)
+ {
+ return WebResponseContent.Instance.Error("鍒涘缓绉诲簱浠诲姟鍚庢洿鏂板簱瀛樼姸鎬佹垨璐т綅鐘舵�佸け璐�");
+ }
+
+ var saveStockRecordResult = await _recordService.AddStockChangeRecordAsync(
+ beforeStock,
+ stockInfo,
+ StockChangeTypeEnum.Relocation,
+ createdTask.TaskNum,
+ createdTask.OrderNo,
+ "绉诲簱浠诲姟棰勫崰搴撳瓨");
+ if (!saveStockRecordResult)
+ {
+ return WebResponseContent.Instance.Error("鍒涘缓绉诲簱浠诲姟鍚庤褰曞簱瀛樺彉鏇村け璐�");
+ }
+
+ if (beforeSourceLocation != null && stockInfo.LocationDetails != null)
+ {
+ var saveSourceLocationRecordResult = await _recordService.AddLocationChangeRecordAsync(
+ beforeSourceLocation,
+ stockInfo.LocationDetails,
+ LocationChangeType.RelocationAssignLocation,
+ createdTask.TaskNum,
+ createdTask.OrderNo,
+ null,
+ "绉诲簱浠诲姟閿佸畾婧愯揣浣�");
+ if (!saveSourceLocationRecordResult)
+ {
+ return WebResponseContent.Instance.Error("鍒涘缓绉诲簱浠诲姟鍚庤褰曟簮璐т綅鍙樻洿澶辫触");
+ }
+ }
+
+ var saveTargetLocationRecordResult = await _recordService.AddLocationChangeRecordAsync(
+ beforeTargetLocation,
+ emptyLocation,
LocationChangeType.RelocationAssignLocation,
createdTask.TaskNum,
createdTask.OrderNo,
null,
- "绉诲簱浠诲姟閿佸畾婧愯揣浣�");
- if (!saveSourceLocationRecordResult)
+ "绉诲簱浠诲姟閿佸畾鐩爣璐т綅");
+ if (!saveTargetLocationRecordResult)
{
- throw new Exception("鍒涘缓绉诲簱浠诲姟鍚庤褰曟簮璐т綅鍙樻洿澶辫触");
+ return WebResponseContent.Instance.Error("鍒涘缓绉诲簱浠诲姟鍚庤褰曠洰鏍囪揣浣嶅彉鏇村け璐�");
}
- }
- var saveTargetLocationRecordResult = await _recordService.AddLocationChangeRecordAsync(
- beforeTargetLocation,
- emptyLocation,
- LocationChangeType.RelocationAssignLocation,
- createdTask.TaskNum,
- createdTask.OrderNo,
- null,
- "绉诲簱浠诲姟閿佸畾鐩爣璐т綅");
- if (!saveTargetLocationRecordResult)
- {
- throw new Exception("鍒涘缓绉诲簱浠诲姟鍚庤褰曠洰鏍囪揣浣嶅彉鏇村け璐�");
- }
-
- return createdTask;
+ return WebResponseContent.Instance.OK("鑾峰彇鍒扮Щ搴撲换鍔�", createdTask);
+ });
}
private static Dt_LocationInfo CloneLocationSnapshot(Dt_LocationInfo location)
@@ -493,13 +521,30 @@
}
/// <summary>
- /// 鏍规嵁宸烽亾鑾峰彇浜屾繁浣嶇殑绌哄簱浣�
+ /// 鏍规嵁宸烽亾鑾峰彇绌哄簱浣嶇敤浜庣Щ搴擄紙浼樺厛浜屾繁浣嶏紝鏃犲垯闄嶇骇鍙栦竴娣变綅锛�
/// </summary>
/// <param name="roadway">宸烽亾缂栧彿</param>
- /// <returns>璐т綅瀵硅薄</returns>
- private async Task<Dt_LocationInfo> GetTransferLocationEmptyAsync(string roadway)
+ /// <returns>璐т綅瀵硅薄锛屾湭鎵惧埌鍒欒繑鍥瀗ull</returns>
+ private async Task<Dt_LocationInfo?> GetTransferLocationEmptyAsync(string roadway)
{
- return await BaseDal.QueryFirstAsync(x => x.Depth == 2 && x.LocationStatus == LocationStatusEnum.Free.GetHashCode() && x.RoadwayNo == roadway);
+ var freeStatus = LocationStatusEnum.Free.GetHashCode();
+
+ // 浼樺厛鑾峰彇浜屾繁浣嶇┖搴撲綅
+ var location = await BaseDal.QueryFirstAsync(x =>
+ x.Depth == 2
+ && x.LocationStatus == freeStatus
+ && x.RoadwayNo == roadway);
+
+ // 浜屾繁浣嶆棤绌洪棽鏃堕檷绾ц幏鍙栦竴娣变綅
+ if (location == null)
+ {
+ location = await BaseDal.QueryFirstAsync(x =>
+ x.Depth == 1
+ && x.LocationStatus == freeStatus
+ && x.RoadwayNo == roadway);
+ }
+
+ return location;
}
/// <summary>
--
Gitblit v1.9.3