From 0500b9903e5b7fcdbdc5b3bd0cc9b373779d64d8 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期五, 13 三月 2026 12:47:10 +0800
Subject: [PATCH] feat: implement DB region (Data Blocks)
---
Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs | 287 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 261 insertions(+), 26 deletions(-)
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
index 5606824..7cf29a4 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
@@ -1,4 +1,5 @@
-锘縰sing AutoMapper;
+using MapsterMapper;
+using Microsoft.Extensions.Configuration;
using SqlSugar;
using System.Text.Json;
using WIDESEA_Common.LocationEnum;
@@ -7,7 +8,9 @@
using WIDESEA_Core;
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.BaseServices;
-using WIDESEA_DTO;
+using WIDESEA_Core.Core;
+using WIDESEA_Core.Helper;
+using WIDESEA_DTO.GradingMachine;
using WIDESEA_DTO.Task;
using WIDESEA_IBasicService;
using WIDESEA_IStockService;
@@ -22,6 +25,8 @@
private readonly IStockInfoService _stockInfoService;
private readonly ILocationInfoService _locationInfoService;
private readonly HttpClientHelper _httpClientHelper;
+ private readonly IConfiguration _configuration;
+ private readonly RoundRobinService _roundRobinService;
public IRepository<Dt_Task> Repository => BaseDal;
@@ -39,12 +44,16 @@
IMapper mapper,
IStockInfoService stockInfoService,
ILocationInfoService locationInfoService,
- HttpClientHelper httpClientHelper) : base(BaseDal)
+ HttpClientHelper httpClientHelper,
+ IConfiguration configuration,
+ RoundRobinService roundRobinService) : base(BaseDal)
{
_mapper = mapper;
_stockInfoService = stockInfoService;
_locationInfoService = locationInfoService;
_httpClientHelper = httpClientHelper;
+ _configuration = configuration;
+ _roundRobinService = roundRobinService;
}
#region WCS閫昏緫澶勭悊
@@ -165,7 +174,7 @@
task.CurrentAddress = task.SourceAddress;
task.NextAddress = locationInfo.LocationCode;
task.TargetAddress = locationInfo.LocationCode;
- task.TaskStatus = TaskStatusEnum.Line_Finish.GetHashCode();
+ task.TaskStatus = TaskInStatusEnum.Line_InFinish.GetHashCode();
var updateResult = await BaseDal.UpdateDataAsync(task);
var locationResult = await _locationInfoService.UpdateLocationInfoAsync(locationInfo);
@@ -202,6 +211,7 @@
var r when r.Contains("CW") => DateTime.Now.AddHours(1),
_ => DateTime.Now
};
+ stockInfo.StockStatus = StockStatusEmun.鍏ュ簱瀹屾垚.GetHashCode();
location.LocationStatus = LocationStatusEnum.InStock.GetHashCode();
@@ -209,14 +219,7 @@
var updateStockResult = await _stockInfoService.UpdateStockAsync(stockInfo);
if (!updateLocationResult || !updateStockResult)
return WebResponseContent.Instance.Error("浠诲姟瀹屾垚澶辫触");
-
- var deleteTaskResult = await BaseDal.DeleteDataAsync(task);
- if (!deleteTaskResult) return WebResponseContent.Instance.Error("浠诲姟瀹屾垚澶辫触");
-
- var historyTask = _mapper.Map<Dt_Task_Hty>(task);
- historyTask.InsertTime = DateTime.Now;
-
- return WebResponseContent.Instance.OK("浠诲姟瀹屾垚");
+ return await CompleteTaskAsync(task);
}
catch (Exception ex)
{
@@ -247,14 +250,50 @@
var updateStockResult = await _stockInfoService.UpdateStockAsync(stockInfo);
if (!updateLocationResult || !updateStockResult)
return WebResponseContent.Instance.Error("浠诲姟瀹屾垚澶辫触");
+ return await CompleteTaskAsync(task);
+ }
+ catch (Exception ex)
+ {
+ return WebResponseContent.Instance.Error($"瀹屾垚浠诲姟澶辫触: {ex.Message}");
+ }
+ }
- var deleteTaskResult = await BaseDal.DeleteDataAsync(task);
- if (!deleteTaskResult) return WebResponseContent.Instance.Error("浠诲姟瀹屾垚澶辫触");
+ /// <summary>
+ /// 绉诲簱浠诲姟瀹屾垚锛氫慨鏀瑰簱瀛樹綅缃笌鐘舵�侊紝淇敼婧�/鐩爣璐т綅鐘舵�侊紝鍒犻櫎浠诲姟鏁版嵁
+ /// </summary>
+ public async Task<WebResponseContent> RelocationFinishTaskAsync(CreateTaskDto taskDto)
+ {
+ try
+ {
+ var task = await BaseDal.QueryFirstAsync(s =>
+ s.PalletCode == taskDto.PalletCode &&
+ s.TaskType == TaskRelocationTypeEnum.Relocation.GetHashCode());
+ if (task == null) return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑绉诲簱浠诲姟");
- var historyTask = _mapper.Map<Dt_Task_Hty>(task);
- historyTask.InsertTime = DateTime.Now;
+ var sourceLocation = await _locationInfoService.GetLocationInfo(task.Roadway, task.SourceAddress);
+ if (sourceLocation == null) return WebResponseContent.Instance.Error("鏈壘鍒扮Щ搴撴簮璐т綅");
- return WebResponseContent.Instance.OK("浠诲姟瀹屾垚");
+ var targetLocation = await _locationInfoService.GetLocationInfo(task.Roadway, task.TargetAddress);
+ if (targetLocation == null) return WebResponseContent.Instance.Error("鏈壘鍒扮Щ搴撶洰鏍囪揣浣�");
+
+ var stockInfo = await _stockInfoService.GetStockInfoAsync(taskDto.PalletCode);
+ if (stockInfo == null) return WebResponseContent.Instance.Error("鏈壘鍒板搴斿簱瀛樹俊鎭�");
+
+ stockInfo.LocationCode = targetLocation.LocationCode;
+ stockInfo.LocationId = targetLocation.Id;
+ stockInfo.StockStatus = StockStatusEmun.鍏ュ簱瀹屾垚.GetHashCode();
+
+ sourceLocation.LocationStatus = LocationStatusEnum.Free.GetHashCode();
+ targetLocation.LocationStatus = LocationStatusEnum.InStock.GetHashCode();
+
+ var updateSourceResult = await _locationInfoService.UpdateLocationInfoAsync(sourceLocation);
+ var updateTargetResult = await _locationInfoService.UpdateLocationInfoAsync(targetLocation);
+ var updateStockResult = await _stockInfoService.UpdateStockAsync(stockInfo);
+
+ if (!updateSourceResult || !updateTargetResult || !updateStockResult)
+ return WebResponseContent.Instance.Error("绉诲簱浠诲姟瀹屾垚澶辫触");
+
+ return await CompleteTaskAsync(task);
}
catch (Exception ex)
{
@@ -338,7 +377,7 @@
{
try
{
- var tasks = await BaseDal.QueryFirstAsync(s => s.TaskId == taskId);
+ var tasks = await BaseDal.QueryFirstAsync(s => s.TaskNum == taskId);
if (tasks == null)
return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑浠诲姟");
@@ -375,6 +414,202 @@
}
}
+ /// <summary>
+ /// 瀹屾垚浠诲姟鍚庣粺涓�澶勭悊锛堝垹闄や换鍔℃暟鎹級
+ /// </summary>
+ private async Task<WebResponseContent> CompleteTaskAsync(Dt_Task task)
+ {
+ var deleteTaskResult = await BaseDal.DeleteDataAsync(task);
+ if (!deleteTaskResult) return WebResponseContent.Instance.Error("浠诲姟瀹屾垚澶辫触");
+
+ // 淇濈暀鍘嗗彶瀵硅薄鏋勫缓閫昏緫锛屽悗缁彲鎺ュ叆鍘嗗彶琛ㄨ惤搴�
+ var historyTask = _mapper.Map<Dt_Task_Hty>(task);
+ historyTask.InsertTime = DateTime.Now;
+
+ return WebResponseContent.Instance.OK("浠诲姟瀹屾垚");
+ }
+
+ /// <summary>
+ /// 鏍规嵁宸烽亾纭畾鐩爣鍦板潃锛堟敮鎸佸鍑哄簱鍙h疆璇級
+ /// </summary>
+ private string DetermineTargetAddress(string roadway, Dictionary<string, List<string>> addressMap)
+ {
+ if (string.IsNullOrWhiteSpace(roadway))
+ return "10080";
+
+ // 鏌ユ壘鍖归厤鐨勫贩閬撳墠缂�
+ string matchedPrefix = null;
+ foreach (var kvp in addressMap)
+ {
+ if (roadway.Contains(kvp.Key))
+ {
+ matchedPrefix = kvp.Key;
+ break;
+ }
+ }
+
+ if (matchedPrefix == null)
+ return "10080";
+
+ var addresses = addressMap[matchedPrefix];
+ if (addresses == null || addresses.Count == 0)
+ return "10080";
+
+ // 鍗曚釜鍦板潃锛岀洿鎺ヨ繑鍥�
+ if (addresses.Count == 1)
+ return addresses[0];
+
+ // 澶氫釜鍦板潃锛屼娇鐢ㄨ疆璇㈡湇鍔�
+ return _roundRobinService.GetNextAddress(matchedPrefix, addresses);
+ }
+
+ /// <summary>
+ /// 鑷姩鍒涘缓鍑哄簱浠诲姟 - 鏌ヨ鍒版湡搴撳瓨骞跺垱寤轰换鍔�
+ /// </summary>
+ public async Task<WebResponseContent> CreateAutoOutboundTasksAsync()
+ {
+ try
+ {
+ // 1. 鏌ヨ鍒版湡搴撳瓨
+ var expiredStocks = await _stockInfoService.Repository
+ .QueryDataNavAsync(s => s.OutboundDate <= DateTime.Now
+ && s.StockStatus == StockStatusEmun.鍏ュ簱瀹屾垚.GetHashCode());
+
+ if (expiredStocks == null || !expiredStocks.Any())
+ {
+ return WebResponseContent.Instance.OK("鏃犲埌鏈熷簱瀛橀渶瑕佸鐞�");
+ }
+
+ // 杩囨护鏈変綅缃笖浣嶇疆鏈夊簱瀛樼殑璁板綍
+ expiredStocks = expiredStocks
+ .Where(s => s.LocationDetails != null
+ && s.LocationDetails.LocationStatus == LocationStatusEnum.InStock.GetHashCode())
+ .ToList();
+
+ if (!expiredStocks.Any())
+ {
+ return WebResponseContent.Instance.OK("鏃犵鍚堟潯浠剁殑鍒版湡搴撳瓨");
+ }
+
+ // 2. 妫�鏌ュ凡瀛樺湪鐨勪换鍔�
+ var palletCodes = expiredStocks.Select(s => s.PalletCode).ToList();
+ var existingTasks = await Repository.QueryDataAsync(t =>
+ palletCodes.Contains(t.PalletCode)
+ && (t.TaskStatus == TaskStatusEnum.New.GetHashCode()
+ || t.TaskStatus == TaskStatusEnum.SC_Executing.GetHashCode()
+ || t.TaskStatus == TaskInStatusEnum.InNew.GetHashCode()));
+
+ var processedPallets = existingTasks.Select(t => t.PalletCode).ToHashSet();
+
+ // 3. 绛涢�夐渶瑕佸鐞嗙殑搴撳瓨
+ var stocksToProcess = expiredStocks
+ .Where(s => !processedPallets.Contains(s.PalletCode))
+ .ToList();
+
+ if (!stocksToProcess.Any())
+ {
+ return WebResponseContent.Instance.OK("鎵�鏈夊埌鏈熷簱瀛樺凡瀛樺湪浠诲姟");
+ }
+
+ // 4. 鑾峰彇閰嶇疆鐨勭洰鏍囧湴鍧�鏄犲皠
+ var targetAddressMap = _configuration.GetSection("AutoOutboundTask:TargetAddresses")
+ .Get<Dictionary<string, List<string>>>()
+ ?? new Dictionary<string, List<string>>();
+
+ // 5. 鎵归噺鍒涘缓浠诲姟
+ var taskList = new List<Dt_Task>();
+ foreach (var stock in stocksToProcess)
+ {
+ // 鏍规嵁宸烽亾纭畾鐩爣鍦板潃
+ var targetAddress = DetermineTargetAddress(
+ stock.LocationDetails?.RoadwayNo ?? "",
+ targetAddressMap);
+
+ var task = new Dt_Task
+ {
+ WarehouseId = stock.WarehouseId,
+ PalletCode = stock.PalletCode,
+ PalletType = stock.PalletType,
+ SourceAddress = stock.LocationCode,
+ CurrentAddress = stock.LocationCode,
+ NextAddress = targetAddress,
+ TargetAddress = targetAddress,
+ Roadway = stock.LocationDetails?.RoadwayNo ?? "",
+ TaskType = TaskTypeEnum.Outbound.GetHashCode(),
+ TaskStatus = TaskStatusEnum.New.GetHashCode(),
+ Grade = 1,
+ TaskNum = await BaseDal.GetTaskNo(),
+ Creater = "system_auto"
+ };
+ taskList.Add(task);
+ }
+
+ var addResult = await BaseDal.AddDataAsync(taskList) > 0;
+ if (!addResult)
+ {
+ return WebResponseContent.Instance.Error($"鎵归噺鍒涘缓浠诲姟澶辫触锛屽叡 {taskList.Count} 涓换鍔�");
+ }
+
+ // 浠诲姟鍒涘缓鎴愬姛鍚庯紝鍚屾閿佸畾搴撳瓨鍜岃揣浣嶇姸鎬侊紝閬垮厤閲嶅鍒嗛厤
+ var stocksToUpdate = stocksToProcess
+ .Select(s =>
+ {
+ s.StockStatus = StockStatusEmun.鍑哄簱閿佸畾.GetHashCode();
+ return s;
+ })
+ .ToList();
+
+ var updateStockResult = await _stockInfoService.Repository.UpdateDataAsync(stocksToUpdate);
+ if (!updateStockResult)
+ {
+ return WebResponseContent.Instance.Error($"浠诲姟鍒涘缓鎴愬姛锛屼絾搴撳瓨鐘舵�佹洿鏂板け璐ワ紝鍏� {stocksToUpdate.Count} 鏉�");
+ }
+
+ var locationsToUpdate = stocksToProcess
+ .Where(s => s.LocationDetails != null)
+ .GroupBy(s => s.LocationDetails.Id)
+ .Select(g =>
+ {
+ var location = g.First().LocationDetails;
+ location.LocationStatus = LocationStatusEnum.InStockLock.GetHashCode();
+ return location;
+ })
+ .ToList();
+
+ if (locationsToUpdate.Any())
+ {
+ var updateLocationResult = await _locationInfoService.Repository.UpdateDataAsync(locationsToUpdate);
+ if (!updateLocationResult)
+ {
+ return WebResponseContent.Instance.Error($"浠诲姟鍒涘缓鎴愬姛锛屼絾璐т綅鐘舵�佹洿鏂板け璐ワ紝鍏� {locationsToUpdate.Count} 鏉�");
+ }
+ }
+
+ // 6. 閫氱煡 WCS锛堝紓姝ワ紝涓嶅奖鍝嶄富娴佺▼锛�
+ _ = Task.Run(() =>
+ {
+ try
+ {
+ var wmstaskDtos = _mapper.Map<List<WMSTaskDTO>>(taskList);
+ _httpClientHelper.Post<WebResponseContent>(
+ "http://localhost:9292/api/Task/ReceiveTask",
+ wmstaskDtos.ToJson());
+ }
+ catch (Exception ex)
+ {
+ // WCS 閫氱煡澶辫触涓嶅奖鍝嶄换鍔″垱寤猴紝璁板綍鏃ュ織鍗冲彲
+ Console.WriteLine($"WCS 鎵归噺閫氱煡澶辫触锛屼换鍔℃暟閲�: {taskList.Count}, 閿欒: {ex.Message}");
+ }
+ });
+
+ return WebResponseContent.Instance.OK($"鎴愬姛鍒涘缓 {taskList.Count} 涓嚭搴撲换鍔�", taskList.Count);
+ }
+ catch (Exception ex)
+ {
+ return WebResponseContent.Instance.Error($"鑷姩鍒涘缓鍑哄簱浠诲姟澶辫触: {ex.Message}");
+ }
+ }
+
#endregion WCS閫昏緫澶勭悊
#region 鍒嗗鏌滄帴鍙�
@@ -382,7 +617,7 @@
/// <summary>
/// 鍫嗗灈鏈哄彇鏀捐揣瀹屾垚鍚庣墿娴侀�氱煡鍖栨垚鍒嗗鏌滃畬鎴愪俊鍙�
/// </summary>
- public async Task<WebResponseContent> InOrOutCompletedAsync(InputDto input)
+ public async Task<WebResponseContent> InOrOutCompletedAsync(GradingMachineInputDto input)
{
WebResponseContent content = new WebResponseContent();
if (string.IsNullOrWhiteSpace(input.PalletCode) || string.IsNullOrWhiteSpace(input.LocationCode))
@@ -397,7 +632,7 @@
{
var location = await _locationInfoService.GetLocationInfoAsync(input.LocationCode);
- OutPutDto outPutDto = new OutPutDto()
+ OutputDto outPutDto = new OutputDto()
{
LocationCode = input.LocationCode,
PalletCode = input.PalletCode,
@@ -408,7 +643,7 @@
}
else
{
- OutPutDto outPutDto = new OutPutDto()
+ OutputDto outPutDto = new OutputDto()
{
LocationCode = input.LocationCode,
PalletCode = input.PalletCode,
@@ -431,7 +666,7 @@
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
- public async Task<WebResponseContent> SendLocationStatusAsync(InputDto input)
+ public async Task<WebResponseContent> SendLocationStatusAsync(GradingMachineInputDto input)
{
WebResponseContent content = new WebResponseContent();
if (string.IsNullOrWhiteSpace(input.LocationCode))
@@ -468,7 +703,7 @@
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
- public async Task<WebResponseContent> RequestOutboundAsync(InputDto input)
+ public async Task<WebResponseContent> RequestOutboundAsync(GradingMachineInputDto input)
{
WebResponseContent content = new WebResponseContent();
if (string.IsNullOrWhiteSpace(input.LocationCode) || string.IsNullOrWhiteSpace(input.PalletCode))
@@ -527,7 +762,7 @@
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
- public async Task<WebResponseContent> GetPalletCodeCellAsync(InputDto input)
+ public async Task<WebResponseContent> GetPalletCodeCellAsync(GradingMachineInputDto input)
{
WebResponseContent content = new WebResponseContent();
if (string.IsNullOrWhiteSpace(input.PalletCode) || string.IsNullOrWhiteSpace(input.LocationCode))
@@ -541,7 +776,7 @@
{
return content.Error("鏈壘鍒板搴旂殑鎵樼洏");
}
- var outPutDtos = stockInfo.Details.Select(x => new OutPutDto()
+ var outPutDtos = stockInfo.Details.Select(x => new OutputDto()
{
LocationCode = input.LocationCode,
PalletCode = input.PalletCode,
@@ -560,4 +795,4 @@
#endregion 鍒嗗鏌滄帴鍙�
}
-}
\ No newline at end of file
+}
--
Gitblit v1.9.3