diff --git a/.claude/settings.local.json b/.claude/settings.local.json
new file mode 100644
index 0000000..61a5292
--- /dev/null
+++ b/.claude/settings.local.json
@@ -0,0 +1,7 @@
+{
+ "permissions": {
+ "allow": [
+ "Bash(dotnet build *)"
+ ]
+ }
+}
diff --git a/Sln.Wcs.Business.Tests/Sln.Wcs.Business.Tests.csproj b/Sln.Wcs.Business.Tests/Sln.Wcs.Business.Tests.csproj
deleted file mode 100644
index 63712b7..0000000
--- a/Sln.Wcs.Business.Tests/Sln.Wcs.Business.Tests.csproj
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
- net8.0
- enable
- enable
- false
- true
-
-
-
-
-
-
-
- runtime; build; native; contentfiles; analyzers; buildtransitive
- all
-
-
- runtime; build; native; contentfiles; analyzers; buildtransitive
- all
-
-
-
-
-
-
-
-
diff --git a/Sln.Wcs.Business.Tests/StoreTaskBusinessTests.cs b/Sln.Wcs.Business.Tests/StoreTaskBusinessTests.cs
deleted file mode 100644
index 9ff1ed1..0000000
--- a/Sln.Wcs.Business.Tests/StoreTaskBusinessTests.cs
+++ /dev/null
@@ -1,515 +0,0 @@
-#region << 版 本 注 释 >>
-/*--------------------------------------------------------------------
-|* 版权所有 (c) 2026 WenJY 保留所有权利。
-|* CLR版本:4.0.30319.42000
-|* 机器名称:Mr.Wen's MacBook Pro
-|* 命名空间:Sln.Wcs.Business.Tests
-|* 唯一标识:
-|*
-|* 创建者:WenJY
-|* 电子邮箱:
-|* 创建时间:2026-05-17
-|* 版本:V1.0.0
-|* 描述:StoreTaskBusiness 单元测试
-|*
-|*--------------------------------------------------------------------
-|* 修改人:
-|* 时间:
-|* 修改说明:
-|*
-|* 版本:V1.0.0
-|*--------------------------------------------------------------------*/
-#endregion << 版 本 注 释 >>
-
-using Moq;
-using Sln.Wcs.Business.Domain.Dto.CreateTask;
-using Sln.Wcs.Business.Domain.Dto.FilterLocation;
-using Sln.Wcs.Business.Domain.Dto.SaveTask;
-using Sln.Wcs.Business.Domain.Enum;
-using Sln.Wcs.Model.Domain;
-using Sln.Wcs.Repository.service;
-using Xunit;
-
-namespace Sln.Wcs.Business.Tests;
-
-///
-/// 可测试的 StoreTaskBusiness 子类,用于访问 protected 方法
-///
-public class TestableStoreTaskBusiness : StoreTaskBusiness
-{
- public TestableStoreTaskBusiness(
- IBasePathInfoService basePathInfoService,
- ILiveTaskQueueService liveTaskQueueService,
- IBaseStoreInfoService baseStoreInfoService)
- : base(basePathInfoService, liveTaskQueueService, baseStoreInfoService)
- {
- }
-
- public void PublicValidateCreateTaskParams(CreateTaskDto dto) =>
- ValidateCreateTaskParams(dto);
-
- public void PublicValidateFilterLocationParams(FilterLocationDto dto) =>
- ValidateFilterLocationParams(dto);
-
- public string PublicGenerateTaskCode() => GenerateTaskCode();
-
- public string PublicGetCategoryName(TaskCategoryEnum category) =>
- GetCategoryName(category);
-
- public string PublicGetTaskTypeName(TaskTypeEnum taskType) =>
- GetTaskTypeName(taskType);
-
- public string PublicGetTaskSuccessMessage(
- string taskCode, string pathName, TaskTypeEnum taskType, TaskCategoryEnum taskCategory) =>
- GetTaskSuccessMessage(taskCode, pathName, taskType, taskCategory);
-
- public BasePathInfo PublicGetPathInfo(
- CreateTaskDto createTaskDto, TaskTypeEnum taskType, TaskCategoryEnum taskCategory) =>
- GetPathInfo(createTaskDto, taskType, taskCategory);
-}
-
-public class StoreTaskBusinessTests
-{
- private readonly Mock _mockBasePathInfoService;
- private readonly Mock _mockLiveTaskQueueService;
- private readonly Mock _mockBaseStoreInfoService;
- private readonly TestableStoreTaskBusiness _storeTaskBusiness;
-
- public StoreTaskBusinessTests()
- {
- _mockBasePathInfoService = new Mock();
- _mockLiveTaskQueueService = new Mock();
- _mockBaseStoreInfoService = new Mock();
- _storeTaskBusiness = new TestableStoreTaskBusiness(
- _mockBasePathInfoService.Object,
- _mockLiveTaskQueueService.Object,
- _mockBaseStoreInfoService.Object);
- }
-
- #region GetCategoryName 测试
-
- [Theory]
- [InlineData(TaskCategoryEnum.Material, "包材")]
- [InlineData(TaskCategoryEnum.Product, "成品")]
- [InlineData(TaskCategoryEnum.Pallet, "托盘")]
- public void GetCategoryName_ValidCategory_ReturnsCorrectName(TaskCategoryEnum category, string expected)
- {
- var result = _storeTaskBusiness.PublicGetCategoryName(category);
- Assert.Equal(expected, result);
- }
-
- #endregion
-
- #region GetTaskTypeName 测试
-
- [Theory]
- [InlineData(TaskTypeEnum.InStore, "入库")]
- [InlineData(TaskTypeEnum.OutStore, "出库")]
- public void GetTaskTypeName_ValidType_ReturnsCorrectName(TaskTypeEnum taskType, string expected)
- {
- var result = _storeTaskBusiness.PublicGetTaskTypeName(taskType);
- Assert.Equal(expected, result);
- }
-
- #endregion
-
- #region ValidateCreateTaskParams 测试
-
- [Fact]
- public void ValidateCreateTaskParams_NullMaterialCode_ThrowsException()
- {
- var dto = new CreateTaskDto
- {
- materialCode = null!,
- palletBarcode = "PLT001",
- startPoint = "A",
- endPoint = "B"
- };
-
- var exception = Assert.Throws(() =>
- _storeTaskBusiness.PublicValidateCreateTaskParams(dto));
-
- Assert.Contains("物料编号不允许为 NULL", exception.Message);
- }
-
- [Fact]
- public void ValidateCreateTaskParams_NullPalletBarcode_ThrowsException()
- {
- var dto = new CreateTaskDto
- {
- materialCode = "MAT001",
- palletBarcode = null!,
- startPoint = "A",
- endPoint = "B",
- taskCategory = TaskCategoryEnum.Material
- };
-
- var exception = Assert.Throws(() =>
- _storeTaskBusiness.PublicValidateCreateTaskParams(dto));
-
- Assert.Contains("条码不允许为 NULL", exception.Message);
- }
-
- [Fact]
- public void ValidateCreateTaskParams_NullStartPoint_ThrowsException()
- {
- var dto = new CreateTaskDto
- {
- materialCode = "MAT001",
- palletBarcode = "PLT001",
- startPoint = null!,
- endPoint = "B"
- };
-
- var exception = Assert.Throws(() =>
- _storeTaskBusiness.PublicValidateCreateTaskParams(dto));
-
- Assert.Contains("起始位置、终点位置不允许为 NULL", exception.Message);
- }
-
- [Fact]
- public void ValidateCreateTaskParams_EmptyEndPoint_ThrowsException()
- {
- var dto = new CreateTaskDto
- {
- materialCode = "MAT001",
- palletBarcode = "PLT001",
- startPoint = "A",
- endPoint = ""
- };
-
- var exception = Assert.Throws(() =>
- _storeTaskBusiness.PublicValidateCreateTaskParams(dto));
-
- Assert.Contains("起始位置、终点位置不允许为 NULL", exception.Message);
- }
-
- [Fact]
- public void ValidateCreateTaskParams_ValidParams_NoException()
- {
- var dto = new CreateTaskDto
- {
- materialCode = "MAT001",
- palletBarcode = "PLT001",
- startPoint = "A",
- endPoint = "B",
- taskCategory = TaskCategoryEnum.Material
- };
-
- var exception = Record.Exception(() =>
- _storeTaskBusiness.PublicValidateCreateTaskParams(dto));
-
- Assert.Null(exception);
- }
-
- #endregion
-
- #region ValidateFilterLocationParams 测试
-
- [Fact]
- public void ValidateFilterLocationParams_NullMaterialCode_ThrowsException()
- {
- var dto = new FilterLocationDto
- {
- materialCode = null!
- };
-
- var exception = Assert.Throws(() =>
- _storeTaskBusiness.PublicValidateFilterLocationParams(dto));
-
- Assert.Contains("物料编号不允许为 NULL", exception.Message);
- }
-
- [Fact]
- public void ValidateFilterLocationParams_ValidParams_NoException()
- {
- var dto = new FilterLocationDto
- {
- materialCode = "MAT001"
- };
-
- var exception = Record.Exception(() =>
- _storeTaskBusiness.PublicValidateFilterLocationParams(dto));
-
- Assert.Null(exception);
- }
-
- #endregion
-
- #region GenerateTaskCode 测试
-
- [Fact]
- public void GenerateTaskCode_ReturnsCorrectFormat()
- {
- var taskCode = _storeTaskBusiness.PublicGenerateTaskCode();
-
- Assert.NotNull(taskCode);
- Assert.Equal(18, taskCode.Length);
- Assert.True(long.TryParse(taskCode[..14], out _));
- Assert.True(int.TryParse(taskCode[14..], out var randomPart));
- Assert.InRange(randomPart, 1000, 9999);
- }
-
- [Fact]
- public void GenerateTaskCode_MultipleCalls_GeneratesUniqueCodes()
- {
- var codes = new HashSet();
- for (int i = 0; i < 100; i++)
- {
- codes.Add(_storeTaskBusiness.PublicGenerateTaskCode());
- }
-
- Assert.Equal(100, codes.Count);
- }
-
- #endregion
-
- #region CreateTask 测试
-
- [Fact]
- public void CreateTask_ValidInput_ReturnsSuccessResult()
- {
- var dto = new CreateTaskDto
- {
- materialCode = "MAT001",
- materialBarcode = "MAT001BAR",
- palletBarcode = "PLT001",
- amount = 100,
- startPoint = "START",
- endPoint = "END",
- taskType = TaskTypeEnum.InStore,
- taskCategory = TaskCategoryEnum.Material
- };
-
- var pathDetails = new List
- {
- new BasePathDetails
- {
- objId = 1,
- pathCode = "PATH1",
- startPoint = "START",
- endPoint = "MID",
- deviceType = 0
- },
- new BasePathDetails
- {
- objId = 2,
- pathCode = "PATH2",
- startPoint = "MID",
- endPoint = "END",
- deviceType = 0
- }
- };
-
- var pathInfo = new BasePathInfo
- {
- objId = 1,
- pathCode = "MAIN_PATH",
- pathName = "主输送线",
- pathType = 1,
- pathCategory = 1,
- startPoint = "START",
- endPoint = "END",
- pathDetails = pathDetails
- };
-
- _mockBasePathInfoService
- .Setup(x => x.GetBasePathInfo(It.IsAny>>()))
- .Returns(new List { pathInfo });
-
- var result = _storeTaskBusiness.CreateTask(dto);
-
- Assert.Equal(BusinessStatusEnum.成功, result.code);
- Assert.NotNull(result.data);
- Assert.NotNull(result.data.taskCode);
- Assert.Equal(2, result.data.taskDetails.Count);
- Assert.Equal(2, result.data.taskQueue.taskSteps);
- }
-
- [Fact]
- public void CreateTask_PathNotFound_ReturnsErrorResult()
- {
- var dto = new CreateTaskDto
- {
- materialCode = "MAT001",
- palletBarcode = "PLT001",
- startPoint = "INVALID",
- endPoint = "INVALID",
- taskType = TaskTypeEnum.InStore,
- taskCategory = TaskCategoryEnum.Material
- };
-
- _mockBasePathInfoService
- .Setup(x => x.GetBasePathInfo(It.IsAny>>()))
- .Returns(new List());
-
- var result = _storeTaskBusiness.CreateTask(dto);
-
- Assert.Equal(BusinessStatusEnum.方法执行异常, result.code);
- Assert.Contains("输送路径为 NULL", result.msg);
- }
-
- #endregion
-
- #region FilterLocation 测试
-
- [Fact]
- public void FilterLocation_ValidInput_ReturnsSuccessResult()
- {
- var dto = new FilterLocationDto
- {
- materialCode = "MAT001",
- taskType = TaskTypeEnum.InStore,
- taskCategory = TaskCategoryEnum.Material
- };
-
- var locationInfos = new List
- {
- new BaseLocationInfo
- {
- locationCode = "LOC001",
- locationRows = 1,
- locationColumns = 1,
- locationLayers = 1,
- locationStatus = 0,
- materialCode = "MAT001",
- isFlag = 1
- }
- };
-
- var storeInfo = new BaseStoreInfo
- {
- storeCode = "STORE001",
- storeName = "测试仓库",
- storeType = 1,
- isFlag = 1,
- locationInfos = locationInfos
- };
-
- _mockBaseStoreInfoService
- .Setup(x => x.GetBasePathInfo(
- It.IsAny>>(),
- It.IsAny>>()))
- .Returns(new List { storeInfo });
-
- var result = _storeTaskBusiness.FilterLocation(dto);
-
- Assert.Equal(BusinessStatusEnum.成功, result.code);
- Assert.NotNull(result.data);
- Assert.NotNull(result.data.storeInfo);
- Assert.NotNull(result.data.locationInfo);
- Assert.Single(result.data.locationInfos);
- }
-
- [Fact]
- public void FilterLocation_NoAvailableStore_ReturnsErrorResult()
- {
- var dto = new FilterLocationDto
- {
- materialCode = "MAT001",
- taskType = TaskTypeEnum.InStore,
- taskCategory = TaskCategoryEnum.Material
- };
-
- _mockBaseStoreInfoService
- .Setup(x => x.GetBasePathInfo(
- It.IsAny>>(),
- It.IsAny>>()))
- .Returns(new List());
-
- var result = _storeTaskBusiness.FilterLocation(dto);
-
- Assert.Equal(BusinessStatusEnum.方法执行异常, result.code);
- Assert.Contains("未获取到可用仓库", result.msg);
- }
-
- #endregion
-
- #region SaveTask 测试
-
- [Fact]
- public void SaveTask_ValidInput_ReturnsSuccessResult()
- {
- var dto = new SaveTaskDto
- {
- taskQueue = new LiveTaskQueue
- {
- taskCode = "TASK001",
- materialCode = "MAT001",
- palletBarcode = "PLT001",
- startPoint = "A",
- endPoint = "B",
- taskType = 1,
- taskCategory = 1
- }
- };
-
- _mockLiveTaskQueueService
- .Setup(x => x.InsertTaskQueue(It.IsAny()))
- .Returns(true);
-
- var result = _storeTaskBusiness.SaveTask(dto);
-
- Assert.Equal(BusinessStatusEnum.成功, result.code);
- Assert.NotNull(result.data);
- Assert.True(result.data.isRes);
- }
-
- [Fact]
- public void SaveTask_InsertFails_ReturnsFalse()
- {
- var dto = new SaveTaskDto
- {
- taskQueue = new LiveTaskQueue
- {
- taskCode = "TASK001",
- materialCode = "MAT001",
- palletBarcode = "PLT001",
- startPoint = "A",
- endPoint = "B",
- taskType = 1,
- taskCategory = 1
- }
- };
-
- _mockLiveTaskQueueService
- .Setup(x => x.InsertTaskQueue(It.IsAny()))
- .Returns(false);
-
- var result = _storeTaskBusiness.SaveTask(dto);
-
- Assert.Equal(BusinessStatusEnum.成功, result.code);
- Assert.NotNull(result.data);
- Assert.False(result.data.isRes);
- }
-
- #endregion
-
- #region GetTaskSuccessMessage 测试
-
- [Fact]
- public void GetTaskSuccessMessage_ReturnsCorrectMessage()
- {
- var message = _storeTaskBusiness.PublicGetTaskSuccessMessage(
- "TASK001",
- "主输送线",
- TaskTypeEnum.InStore,
- TaskCategoryEnum.Material);
-
- Assert.Equal("包材入库任务创建成功:TASK001;关联路径:主输送线", message);
- }
-
- [Fact]
- public void GetTaskSuccessMessage_ProductOutStore_ReturnsCorrectMessage()
- {
- var message = _storeTaskBusiness.PublicGetTaskSuccessMessage(
- "TASK002",
- "成品出库线",
- TaskTypeEnum.OutStore,
- TaskCategoryEnum.Product);
-
- Assert.Equal("成品出库任务创建成功:TASK002;关联路径:成品出库线", message);
- }
-
- #endregion
-}
diff --git a/Sln.Wcs.Business/BaseBusiness.cs b/Sln.Wcs.Business/BaseBusiness.cs
deleted file mode 100644
index 309f6b8..0000000
--- a/Sln.Wcs.Business/BaseBusiness.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-#region << 版 本 注 释 >>
-
-/*--------------------------------------------------------------------
-* 版权所有 (c) 2026 WenJY 保留所有权利。
-* CLR版本:4.0.30319.42000
-* 机器名称:Mr.Wen's MacBook Pro
-* 命名空间:Sln.Wcs.Business.InStore
-* 唯一标识:6D5BA916-0FBB-4B9D-BBE9-692F39B7F962
-*
-* 创建者:WenJY
-* 电子邮箱:
-* 创建时间:2026-05-07 08:48:17
-* 版本:V1.0.0
-* 描述:
-*
-*--------------------------------------------------------------------
-* 修改人:
-* 时间:
-* 修改说明:
-*
-* 版本:V1.0.0
-*--------------------------------------------------------------------*/
-
-#endregion << 版 本 注 释 >>
-
-using Sln.Wcs.Business.Domain.Dto.CreateTask;
-using Sln.Wcs.Business.Domain.Dto.FilterLocation;
-using Sln.Wcs.Business.Domain.Dto.SaveTask;
-using Sln.Wcs.Business.Domain.Dto.ValidateMaterial;
-using Sln.Wcs.Business.Util;
-
-namespace Sln.Wcs.Business;
-
-public abstract class BaseBusiness:EntityWrapper
-{
-
- ///
- /// 校验物料
- ///
- ///
- ///
- public abstract ValidateMaterialResultDto ValidateMaterial(ValidateMaterialDto validateMaterialDto);
-
- ///
- /// 创建任务
- ///
- ///
- public abstract CreateTaskResultDto CreateTask(CreateTaskDto createTaskDto );
-
- ///
- /// 筛选目标库位
- ///
- ///
- ///
- public abstract FilterLocationResultDto FilterLocation(FilterLocationDto filterLocationDto);
-
- ///
- /// 保存任务
- ///
- ///
- ///
- public abstract SaveTaskResultDto SaveTask(SaveTaskDto saveTaskDto);
-
-}
\ No newline at end of file
diff --git a/Sln.Wcs.Business/InStore/MaterialInStore.cs b/Sln.Wcs.Business/InStore/MaterialInStore.cs
deleted file mode 100644
index 8d0e12d..0000000
--- a/Sln.Wcs.Business/InStore/MaterialInStore.cs
+++ /dev/null
@@ -1,203 +0,0 @@
-#region << 版 本 注 释 >>
-
-/*--------------------------------------------------------------------
-* 版权所有 (c) 2026 WenJY 保留所有权利。
-* CLR版本:4.0.30319.42000
-* 机器名称:Mr.Wen's MacBook Pro
-* 命名空间:Sln.Wcs.Business
-* 唯一标识:A6C78343-F3B7-49DB-A582-768186595E02
-*
-* 创建者:WenJY
-* 电子邮箱:
-* 创建时间:2026-05-06 18:13:10
-* 版本:V1.0.0
-* 描述:
-*
-*--------------------------------------------------------------------
-* 修改人:
-* 时间:
-* 修改说明:
-*
-* 版本:V1.0.0
-*--------------------------------------------------------------------*/
-
-#endregion << 版 本 注 释 >>
-
-using System.Linq.Expressions;
-using Sln.Wcs.Business.Domain.Dto.CreateTask;
-using Sln.Wcs.Business.Domain.Dto.FilterLocation;
-using Sln.Wcs.Business.Domain.Dto.SaveTask;
-using Sln.Wcs.Business.Domain.Dto.ValidateMaterial;
-using Sln.Wcs.Business.Domain.Enum;
-using Sln.Wcs.Business.Domain.Model.CreateTask;
-using Sln.Wcs.Business.Domain.Model.FilterLocation;
-using Sln.Wcs.Business.Domain.Model.SaveTask;
-using Sln.Wcs.Model.Domain;
-using Sln.Wcs.Repository.service;
-
-namespace Sln.Wcs.Business.InStore;
-
-///
-/// 包材入库
-///
-public class MaterialInStore:BaseBusiness
-{
- private readonly IBasePathInfoService _basePathInfoService;
- private readonly ILiveTaskQueueService _liveTaskQueueService;
- private readonly IBaseStoreInfoService _baseStoreInfoService;
-
- public MaterialInStore(IBasePathInfoService basePathInfoService, ILiveTaskQueueService liveTaskQueueService, IBaseStoreInfoService baseStoreInfoService)
- {
- _basePathInfoService = basePathInfoService;
- _liveTaskQueueService = liveTaskQueueService;
- _baseStoreInfoService = baseStoreInfoService;
- }
-
- public override ValidateMaterialResultDto ValidateMaterial(ValidateMaterialDto validateMaterialDto)
- {
- throw new NotImplementedException();
- }
-
- ///
- /// 创建任务
- ///
- ///
- ///
- ///
- public override CreateTaskResultDto CreateTask(CreateTaskDto createTaskDto)
- {
- CreateTaskResultDto resultDto = new CreateTaskResultDto();
- try
- {
- #region CreateTaskDto 参数校验
-
- if (string.IsNullOrEmpty(createTaskDto.materialCode))
- {
- throw new InvalidOperationException($"物料编号不允许为 NULL");
- }
-
- if (string.IsNullOrEmpty(createTaskDto.palletBarcode))
- {
- throw new InvalidOperationException($"托盘条码不允许为 NULL");
- }
-
- if (string.IsNullOrEmpty(createTaskDto.startPoint) || string.IsNullOrEmpty(createTaskDto.endPoint))
- {
- throw new InvalidOperationException($"起始位置、终点位置不允许为 NULL");
- }
-
- #endregion
-
- createTaskDto.taskType = TaskTypeEnum.InStore;
- createTaskDto.taskCategory = TaskCategoryEnum.Material;
- //获取包材入库路径
- Expression> exp = x=>x.startPoint == createTaskDto.startPoint && x.endPoint == createTaskDto.endPoint && x.pathType == (int)createTaskDto.taskType && x.pathCategory == (int)createTaskDto.taskCategory;
- BasePathInfo pathInfo = _basePathInfoService.GetBasePathInfo(exp).FirstOrDefault() ?? throw new InvalidOperationException($"包材入库输送路径为 NULL");
-
- #region 路径转为任务
-
- string taskCode = "2026050700001"; //需根据现场实际定义生成规则
-
- List taskDetails = pathInfo.pathDetails.Select( item => base.LiveTaskDetailWrapper(taskCode,createTaskDto,item)).ToList();
-
- var taskQueue = base.LiveTaskQueueWrapper(taskCode, createTaskDto, pathInfo);
- taskQueue.taskSteps = taskDetails.Count;
- taskQueue.taskDetails = taskDetails;
- #endregion
-
- resultDto.code = BusinessStatusEnum.成功;
- resultDto.msg = $"包材入库任务创建成功:{taskCode};关联路径:{pathInfo.pathName}";
- resultDto.data = new CreateTaskResultModel()
- {
- taskCode = taskCode,
- taskQueue = taskQueue,
- taskDetails = taskDetails,
- };
- }
- catch (Exception e)
- {
- resultDto.code = BusinessStatusEnum.方法执行异常;
- resultDto.msg = e.Message;
- }
- return resultDto;
- }
-
- ///
- /// 筛选库位
- ///
- ///
- ///
- ///
- public override FilterLocationResultDto FilterLocation(FilterLocationDto filterLocationDto)
- {
- FilterLocationResultDto resultDto = new FilterLocationResultDto();
- try
- {
-
- #region 参数校验
-
- if (string.IsNullOrEmpty(filterLocationDto.materialCode))
- {
- throw new InvalidOperationException($"物料编号不允许为 NULL");
- }
-
- #endregion
-
- Expression> storeWhere = x => x.storeType == (int)StoreTypeEnum.Material;
- Expression> locationWhere = x=>x.materialCode==filterLocationDto.materialCode && x.locationStatus == 0 && x.isFlag == 1;
-
- List storeInfos = _baseStoreInfoService.GetBasePathInfo(storeWhere,locationWhere);
-
- //先对仓库进行排序
- BaseStoreInfo? storeInfo = storeInfos.Where(s => s.locationInfos.Count > 0).OrderBy(x=>x.storeCode).FirstOrDefault() ?? throw new ArgumentNullException($"未获取到可用仓库");
-
- BaseLocationInfo? locationInfo = storeInfo.locationInfos.OrderBy(x => x.locationRows).ThenBy(x=>x.locationColumns).ThenBy(x=>x.locationLayers).FirstOrDefault() ?? throw new ArgumentNullException($"目标仓库:{storeInfo.storeName}中未获取到可用库位");
-
- resultDto.code = BusinessStatusEnum.成功;
- resultDto.msg = "执行完成";
- resultDto.data = new FilterLocationResultModel()
- {
- storeInfo = storeInfo,
-
- locationInfos = storeInfo.locationInfos,
-
- locationInfo = locationInfo,
- };
- }
- catch (Exception e)
- {
- resultDto.code = BusinessStatusEnum.方法执行异常;
- resultDto.msg = e.Message;
- }
-
- return resultDto;
- }
-
- ///
- /// 保存任务
- ///
- ///
- ///
- public override SaveTaskResultDto SaveTask(SaveTaskDto saveTaskDto)
- {
- SaveTaskResultDto resultDto = new SaveTaskResultDto();
- try
- {
- var inRes = _liveTaskQueueService.InsertTaskQueue(saveTaskDto.taskQueue);
-
- resultDto.code = BusinessStatusEnum.成功;
- resultDto.msg = "执行完成";
- resultDto.data = new SaveTaskResultModel()
- {
- isRes = inRes
- };
- }
- catch (Exception e)
- {
- resultDto.code = BusinessStatusEnum.方法执行异常;
- resultDto.msg = e.Message;
- }
-
- return resultDto;
- }
-}
\ No newline at end of file
diff --git a/Sln.Wcs.Business/InStore/PalletInStore.cs b/Sln.Wcs.Business/InStore/PalletInStore.cs
deleted file mode 100644
index 24ad1ae..0000000
--- a/Sln.Wcs.Business/InStore/PalletInStore.cs
+++ /dev/null
@@ -1,199 +0,0 @@
-#region << 版 本 注 释 >>
-
-/*--------------------------------------------------------------------
-* 版权所有 (c) 2026 WenJY 保留所有权利。
-* CLR版本:4.0.30319.42000
-* 机器名称:Mr.Wen's MacBook Pro
-* 命名空间:Sln.Wcs.Business
-* 唯一标识:B0E9FC96-6FA3-48E1-9BD9-9CF0360B168D
-*
-* 创建者:WenJY
-* 电子邮箱:
-* 创建时间:2026-05-06 18:15:32
-* 版本:V1.0.0
-* 描述:
-*
-*--------------------------------------------------------------------
-* 修改人:
-* 时间:
-* 修改说明:
-*
-* 版本:V1.0.0
-*--------------------------------------------------------------------*/
-
-#endregion << 版 本 注 释 >>
-
-using System.Linq.Expressions;
-using Sln.Wcs.Business.Domain.Dto.CreateTask;
-using Sln.Wcs.Business.Domain.Dto.FilterLocation;
-using Sln.Wcs.Business.Domain.Dto.SaveTask;
-using Sln.Wcs.Business.Domain.Dto.ValidateMaterial;
-using Sln.Wcs.Business.Domain.Enum;
-using Sln.Wcs.Business.Domain.Model.CreateTask;
-using Sln.Wcs.Business.Domain.Model.FilterLocation;
-using Sln.Wcs.Business.Domain.Model.SaveTask;
-using Sln.Wcs.Model.Domain;
-using Sln.Wcs.Repository.service;
-
-namespace Sln.Wcs.Business.InStore;
-
-public class PalletInStore:BaseBusiness
-{private readonly IBasePathInfoService _basePathInfoService;
- private readonly ILiveTaskQueueService _liveTaskQueueService;
- private readonly IBaseStoreInfoService _baseStoreInfoService;
-
- public PalletInStore(IBasePathInfoService basePathInfoService, ILiveTaskQueueService liveTaskQueueService, IBaseStoreInfoService baseStoreInfoService)
- {
- _basePathInfoService = basePathInfoService;
- _liveTaskQueueService = liveTaskQueueService;
- _baseStoreInfoService = baseStoreInfoService;
- }
-
- public override ValidateMaterialResultDto ValidateMaterial(ValidateMaterialDto validateMaterialDto)
- {
- throw new NotImplementedException();
- }
-
- ///
- /// 创建任务
- ///
- ///
- ///
- ///
- public override CreateTaskResultDto CreateTask(CreateTaskDto createTaskDto)
- {
- CreateTaskResultDto resultDto = new CreateTaskResultDto();
- try
- {
- #region CreateTaskDto 参数校验
-
- if (string.IsNullOrEmpty(createTaskDto.materialCode))
- {
- throw new InvalidOperationException($"物料编号不允许为 NULL");
- }
-
- if (string.IsNullOrEmpty(createTaskDto.palletBarcode))
- {
- throw new InvalidOperationException($"托盘条码不允许为 NULL");
- }
-
- if (string.IsNullOrEmpty(createTaskDto.startPoint) || string.IsNullOrEmpty(createTaskDto.endPoint))
- {
- throw new InvalidOperationException($"起始位置、终点位置不允许为 NULL");
- }
-
- #endregion
-
- createTaskDto.taskType = TaskTypeEnum.InStore;
- createTaskDto.taskCategory = TaskCategoryEnum.Pallet;
- //获取托盘入库路径
- Expression> exp = x=>x.startPoint == createTaskDto.startPoint && x.endPoint == createTaskDto.endPoint && x.pathType == (int)createTaskDto.taskType && x.pathCategory == (int)createTaskDto.taskCategory;
- BasePathInfo pathInfo = _basePathInfoService.GetBasePathInfo(exp).FirstOrDefault() ?? throw new InvalidOperationException($"托盘入库输送路径为 NULL");
-
- #region 路径转为任务
-
- string taskCode = "2026050700001"; //需根据现场实际定义生成规则
-
- List taskDetails = pathInfo.pathDetails.Select( item => base.LiveTaskDetailWrapper(taskCode,createTaskDto,item)).ToList();
-
- var taskQueue = base.LiveTaskQueueWrapper(taskCode, createTaskDto, pathInfo);
- taskQueue.taskSteps = taskDetails.Count;
- taskQueue.taskDetails = taskDetails;
- #endregion
-
- resultDto.code = BusinessStatusEnum.成功;
- resultDto.msg = $"托盘入库任务创建成功:{taskCode};关联路径:{pathInfo.pathName}";
- resultDto.data = new CreateTaskResultModel()
- {
- taskCode = taskCode,
- taskQueue = taskQueue,
- taskDetails = taskDetails,
- };
- }
- catch (Exception e)
- {
- resultDto.code = BusinessStatusEnum.方法执行异常;
- resultDto.msg = e.Message;
- }
- return resultDto;
- }
-
- ///
- /// 筛选库位
- ///
- ///
- ///
- ///
- public override FilterLocationResultDto FilterLocation(FilterLocationDto filterLocationDto)
- {
- FilterLocationResultDto resultDto = new FilterLocationResultDto();
- try
- {
-
- #region 参数校验
-
- if (string.IsNullOrEmpty(filterLocationDto.materialCode))
- {
- throw new InvalidOperationException($"物料编号不允许为 NULL");
- }
-
- #endregion
-
- Expression> storeWhere = x => x.storeType == (int)StoreTypeEnum.Material;
- Expression> locationWhere = x=>x.materialCode==filterLocationDto.materialCode && x.locationStatus == 0 && x.isFlag == 1;
-
- List storeInfos = _baseStoreInfoService.GetBasePathInfo(storeWhere,locationWhere);
-
- //先对仓库进行排序
- BaseStoreInfo? storeInfo = storeInfos.Where(s => s.locationInfos.Count > 0).OrderBy(x=>x.storeCode).FirstOrDefault() ?? throw new ArgumentNullException($"未获取到可用仓库");
-
- BaseLocationInfo? locationInfo = storeInfo.locationInfos.OrderBy(x => x.locationRows).ThenBy(x=>x.locationColumns).ThenBy(x=>x.locationLayers).FirstOrDefault() ?? throw new ArgumentNullException($"目标仓库:{storeInfo.storeName}中未获取到可用库位");
-
- resultDto.code = BusinessStatusEnum.成功;
- resultDto.msg = "执行完成";
- resultDto.data = new FilterLocationResultModel()
- {
- storeInfo = storeInfo,
-
- locationInfos = storeInfo.locationInfos,
-
- locationInfo = locationInfo,
- };
- }
- catch (Exception e)
- {
- resultDto.code = BusinessStatusEnum.方法执行异常;
- resultDto.msg = e.Message;
- }
-
- return resultDto;
- }
-
- ///
- /// 保存任务
- ///
- ///
- ///
- public override SaveTaskResultDto SaveTask(SaveTaskDto saveTaskDto)
- {
- SaveTaskResultDto resultDto = new SaveTaskResultDto();
- try
- {
- var inRes = _liveTaskQueueService.InsertTaskQueue(saveTaskDto.taskQueue);
-
- resultDto.code = BusinessStatusEnum.成功;
- resultDto.msg = "执行完成";
- resultDto.data = new SaveTaskResultModel()
- {
- isRes = inRes
- };
- }
- catch (Exception e)
- {
- resultDto.code = BusinessStatusEnum.方法执行异常;
- resultDto.msg = e.Message;
- }
-
- return resultDto;
- }
-}
\ No newline at end of file
diff --git a/Sln.Wcs.Business/InStore/ProductInStore.cs b/Sln.Wcs.Business/InStore/ProductInStore.cs
deleted file mode 100644
index e047a16..0000000
--- a/Sln.Wcs.Business/InStore/ProductInStore.cs
+++ /dev/null
@@ -1,200 +0,0 @@
-#region << 版 本 注 释 >>
-
-/*--------------------------------------------------------------------
-* 版权所有 (c) 2026 WenJY 保留所有权利。
-* CLR版本:4.0.30319.42000
-* 机器名称:Mr.Wen's MacBook Pro
-* 命名空间:Sln.Wcs.Business
-* 唯一标识:1DC1227B-C3E0-4E56-803E-0C42C7065515
-*
-* 创建者:WenJY
-* 电子邮箱:
-* 创建时间:2026-05-06 18:13:44
-* 版本:V1.0.0
-* 描述:
-*
-*--------------------------------------------------------------------
-* 修改人:
-* 时间:
-* 修改说明:
-*
-* 版本:V1.0.0
-*--------------------------------------------------------------------*/
-
-#endregion << 版 本 注 释 >>
-
-using System.Linq.Expressions;
-using Sln.Wcs.Business.Domain.Dto.CreateTask;
-using Sln.Wcs.Business.Domain.Dto.FilterLocation;
-using Sln.Wcs.Business.Domain.Dto.SaveTask;
-using Sln.Wcs.Business.Domain.Dto.ValidateMaterial;
-using Sln.Wcs.Business.Domain.Enum;
-using Sln.Wcs.Business.Domain.Model.CreateTask;
-using Sln.Wcs.Business.Domain.Model.FilterLocation;
-using Sln.Wcs.Business.Domain.Model.SaveTask;
-using Sln.Wcs.Model.Domain;
-using Sln.Wcs.Repository.service;
-
-namespace Sln.Wcs.Business.InStore;
-
-public class ProductInStore:BaseBusiness
-{
- private readonly IBasePathInfoService _basePathInfoService;
- private readonly ILiveTaskQueueService _liveTaskQueueService;
- private readonly IBaseStoreInfoService _baseStoreInfoService;
-
- public ProductInStore(IBasePathInfoService basePathInfoService, ILiveTaskQueueService liveTaskQueueService, IBaseStoreInfoService baseStoreInfoService)
- {
- _basePathInfoService = basePathInfoService;
- _liveTaskQueueService = liveTaskQueueService;
- _baseStoreInfoService = baseStoreInfoService;
- }
-
- public override ValidateMaterialResultDto ValidateMaterial(ValidateMaterialDto validateMaterialDto)
- {
- throw new NotImplementedException();
- }
-
- ///
- /// 创建任务
- ///
- ///
- ///
- ///
- public override CreateTaskResultDto CreateTask(CreateTaskDto createTaskDto)
- {
- CreateTaskResultDto resultDto = new CreateTaskResultDto();
- try
- {
- #region CreateTaskDto 参数校验
-
- if (string.IsNullOrEmpty(createTaskDto.materialCode))
- {
- throw new InvalidOperationException($"物料编号不允许为 NULL");
- }
-
- if (string.IsNullOrEmpty(createTaskDto.palletBarcode))
- {
- throw new InvalidOperationException($"成品条码不允许为 NULL");
- }
-
- if (string.IsNullOrEmpty(createTaskDto.startPoint) || string.IsNullOrEmpty(createTaskDto.endPoint))
- {
- throw new InvalidOperationException($"起始位置、终点位置不允许为 NULL");
- }
-
- #endregion
-
- createTaskDto.taskType = TaskTypeEnum.InStore;
- createTaskDto.taskCategory = TaskCategoryEnum.Product;
- //获取成品入库路径
- Expression> exp = x=>x.startPoint == createTaskDto.startPoint && x.endPoint == createTaskDto.endPoint && x.pathType == (int)createTaskDto.taskType && x.pathCategory == (int)createTaskDto.taskCategory;
- BasePathInfo pathInfo = _basePathInfoService.GetBasePathInfo(exp).FirstOrDefault() ?? throw new InvalidOperationException($"成品入库输送路径为 NULL");
-
- #region 路径转为任务
-
- string taskCode = "2026050700001"; //需根据现场实际定义生成规则
-
- List taskDetails = pathInfo.pathDetails.Select( item => base.LiveTaskDetailWrapper(taskCode,createTaskDto,item)).ToList();
-
- var taskQueue = base.LiveTaskQueueWrapper(taskCode, createTaskDto, pathInfo);
- taskQueue.taskSteps = taskDetails.Count;
- taskQueue.taskDetails = taskDetails;
- #endregion
-
- resultDto.code = BusinessStatusEnum.成功;
- resultDto.msg = $"成品入库任务创建成功:{taskCode};关联路径:{pathInfo.pathName}";
- resultDto.data = new CreateTaskResultModel()
- {
- taskCode = taskCode,
- taskQueue = taskQueue,
- taskDetails = taskDetails,
- };
- }
- catch (Exception e)
- {
- resultDto.code = BusinessStatusEnum.方法执行异常;
- resultDto.msg = e.Message;
- }
- return resultDto;
- }
-
- ///
- /// 筛选库位
- ///
- ///
- ///
- ///
- public override FilterLocationResultDto FilterLocation(FilterLocationDto filterLocationDto)
- {
- FilterLocationResultDto resultDto = new FilterLocationResultDto();
- try
- {
-
- #region 参数校验
-
- if (string.IsNullOrEmpty(filterLocationDto.materialCode))
- {
- throw new InvalidOperationException($"物料编号不允许为 NULL");
- }
-
- #endregion
-
- Expression> storeWhere = x => x.storeType == (int)StoreTypeEnum.Material;
- Expression> locationWhere = x=>x.materialCode==filterLocationDto.materialCode && x.locationStatus == 0 && x.isFlag == 1;
-
- List storeInfos = _baseStoreInfoService.GetBasePathInfo(storeWhere,locationWhere);
-
- //先对仓库进行排序
- BaseStoreInfo? storeInfo = storeInfos.Where(s => s.locationInfos.Count > 0).OrderBy(x=>x.storeCode).FirstOrDefault() ?? throw new ArgumentNullException($"未获取到可用仓库");
-
- BaseLocationInfo? locationInfo = storeInfo.locationInfos.OrderBy(x => x.locationRows).ThenBy(x=>x.locationColumns).ThenBy(x=>x.locationLayers).FirstOrDefault() ?? throw new ArgumentNullException($"目标仓库:{storeInfo.storeName}中未获取到可用库位");
-
- resultDto.code = BusinessStatusEnum.成功;
- resultDto.msg = "执行完成";
- resultDto.data = new FilterLocationResultModel()
- {
- storeInfo = storeInfo,
-
- locationInfos = storeInfo.locationInfos,
-
- locationInfo = locationInfo,
- };
- }
- catch (Exception e)
- {
- resultDto.code = BusinessStatusEnum.方法执行异常;
- resultDto.msg = e.Message;
- }
-
- return resultDto;
- }
-
- ///
- /// 保存任务
- ///
- ///
- ///
- public override SaveTaskResultDto SaveTask(SaveTaskDto saveTaskDto)
- {
- SaveTaskResultDto resultDto = new SaveTaskResultDto();
- try
- {
- var inRes = _liveTaskQueueService.InsertTaskQueue(saveTaskDto.taskQueue);
-
- resultDto.code = BusinessStatusEnum.成功;
- resultDto.msg = "执行完成";
- resultDto.data = new SaveTaskResultModel()
- {
- isRes = inRes
- };
- }
- catch (Exception e)
- {
- resultDto.code = BusinessStatusEnum.方法执行异常;
- resultDto.msg = e.Message;
- }
-
- return resultDto;
- }
-}
\ No newline at end of file
diff --git a/Sln.Wcs.Business/OutStore/MaterialOutStore.cs b/Sln.Wcs.Business/OutStore/MaterialOutStore.cs
deleted file mode 100644
index dccf002..0000000
--- a/Sln.Wcs.Business/OutStore/MaterialOutStore.cs
+++ /dev/null
@@ -1,203 +0,0 @@
-#region << 版 本 注 释 >>
-
-/*--------------------------------------------------------------------
-* 版权所有 (c) 2026 WenJY 保留所有权利。
-* CLR版本:4.0.30319.42000
-* 机器名称:Mr.Wen's MacBook Pro
-* 命名空间:Sln.Wcs.Business
-* 唯一标识:F9D6319A-1B6A-4036-A197-6D5EAE31D711
-*
-* 创建者:WenJY
-* 电子邮箱:
-* 创建时间:2026-05-06 18:13:28
-* 版本:V1.0.0
-* 描述:
-*
-*--------------------------------------------------------------------
-* 修改人:
-* 时间:
-* 修改说明:
-*
-* 版本:V1.0.0
-*--------------------------------------------------------------------*/
-
-#endregion << 版 本 注 释 >>
-
-using System.Linq.Expressions;
-using Sln.Wcs.Business.Domain.Dto.CreateTask;
-using Sln.Wcs.Business.Domain.Dto.FilterLocation;
-using Sln.Wcs.Business.Domain.Dto.SaveTask;
-using Sln.Wcs.Business.Domain.Dto.ValidateMaterial;
-using Sln.Wcs.Business.Domain.Enum;
-using Sln.Wcs.Business.Domain.Model.CreateTask;
-using Sln.Wcs.Business.Domain.Model.FilterLocation;
-using Sln.Wcs.Business.Domain.Model.SaveTask;
-using Sln.Wcs.Model.Domain;
-using Sln.Wcs.Repository.service;
-
-namespace Sln.Wcs.Business.OutStore;
-
-///
-/// 包材出库
-///
-public class MaterialOutStore:BaseBusiness
-{
- private readonly IBasePathInfoService _basePathInfoService;
- private readonly ILiveTaskQueueService _liveTaskQueueService;
- private readonly IBaseStoreInfoService _baseStoreInfoService;
-
- public MaterialOutStore(IBasePathInfoService basePathInfoService, ILiveTaskQueueService liveTaskQueueService, IBaseStoreInfoService baseStoreInfoService)
- {
- _basePathInfoService = basePathInfoService;
- _liveTaskQueueService = liveTaskQueueService;
- _baseStoreInfoService = baseStoreInfoService;
- }
-
- public override ValidateMaterialResultDto ValidateMaterial(ValidateMaterialDto validateMaterialDto)
- {
- throw new NotImplementedException();
- }
-
- ///
- /// 创建任务
- ///
- ///
- ///
- ///
- public override CreateTaskResultDto CreateTask(CreateTaskDto createTaskDto)
- {
- CreateTaskResultDto resultDto = new CreateTaskResultDto();
- try
- {
- #region CreateTaskDto 参数校验
-
- if (string.IsNullOrEmpty(createTaskDto.materialCode))
- {
- throw new InvalidOperationException($"物料编号不允许为 NULL");
- }
-
- if (string.IsNullOrEmpty(createTaskDto.palletBarcode))
- {
- throw new InvalidOperationException($"托盘条码不允许为 NULL");
- }
-
- if (string.IsNullOrEmpty(createTaskDto.startPoint) || string.IsNullOrEmpty(createTaskDto.endPoint))
- {
- throw new InvalidOperationException($"起始位置、终点位置不允许为 NULL");
- }
-
- #endregion
-
- createTaskDto.taskType = TaskTypeEnum.OutStore;
- createTaskDto.taskCategory = TaskCategoryEnum.Material;
- //获取包材出库路径
- Expression> exp = x=>x.startPoint == createTaskDto.startPoint && x.endPoint == createTaskDto.endPoint && x.pathType == (int)createTaskDto.taskType && x.pathCategory == (int)createTaskDto.taskCategory;
- BasePathInfo pathInfo = _basePathInfoService.GetBasePathInfo(exp).FirstOrDefault() ?? throw new InvalidOperationException($"包材出库输送路径为 NULL");
-
- #region 路径转为任务
-
- string taskCode = "2026050700001"; //需根据现场实际定义生成规则
-
- List taskDetails = pathInfo.pathDetails.Select( item => base.LiveTaskDetailWrapper(taskCode,createTaskDto,item)).ToList();
-
- var taskQueue = base.LiveTaskQueueWrapper(taskCode, createTaskDto, pathInfo);
- taskQueue.taskSteps = taskDetails.Count;
- taskQueue.taskDetails = taskDetails;
- #endregion
-
- resultDto.code = BusinessStatusEnum.成功;
- resultDto.msg = $"包材出库任务创建成功:{taskCode};关联路径:{pathInfo.pathName}";
- resultDto.data = new CreateTaskResultModel()
- {
- taskCode = taskCode,
- taskQueue = taskQueue,
- taskDetails = taskDetails,
- };
- }
- catch (Exception e)
- {
- resultDto.code = BusinessStatusEnum.方法执行异常;
- resultDto.msg = e.Message;
- }
- return resultDto;
- }
-
- ///
- /// 筛选库位
- ///
- ///
- ///
- ///
- public override FilterLocationResultDto FilterLocation(FilterLocationDto filterLocationDto)
- {
- FilterLocationResultDto resultDto = new FilterLocationResultDto();
- try
- {
-
- #region 参数校验
-
- if (string.IsNullOrEmpty(filterLocationDto.materialCode))
- {
- throw new InvalidOperationException($"物料编号不允许为 NULL");
- }
-
- #endregion
-
- Expression> storeWhere = x => x.storeType == (int)StoreTypeEnum.Material;
- Expression> locationWhere = x=>x.materialCode==filterLocationDto.materialCode && x.locationStatus == 1 && x.isFlag == 1;
-
- List storeInfos = _baseStoreInfoService.GetBasePathInfo(storeWhere,locationWhere);
-
- //先对仓库进行排序
- BaseStoreInfo? storeInfo = storeInfos.Where(s => s.locationInfos.Count > 0).OrderBy(x=>x.storeCode).FirstOrDefault() ?? throw new ArgumentNullException($"未获取到可用仓库");
-
- BaseLocationInfo? locationInfo = storeInfo.locationInfos.OrderBy(x => x.locationRows).ThenBy(x=>x.locationColumns).ThenBy(x=>x.locationLayers).FirstOrDefault() ?? throw new ArgumentNullException($"目标仓库:{storeInfo.storeName}中未获取到可用库位");
-
- resultDto.code = BusinessStatusEnum.成功;
- resultDto.msg = "执行完成";
- resultDto.data = new FilterLocationResultModel()
- {
- storeInfo = storeInfo,
-
- locationInfos = storeInfo.locationInfos,
-
- locationInfo = locationInfo,
- };
- }
- catch (Exception e)
- {
- resultDto.code = BusinessStatusEnum.方法执行异常;
- resultDto.msg = e.Message;
- }
-
- return resultDto;
- }
-
- ///
- /// 保存任务
- ///
- ///
- ///
- public override SaveTaskResultDto SaveTask(SaveTaskDto saveTaskDto)
- {
- SaveTaskResultDto resultDto = new SaveTaskResultDto();
- try
- {
- var inRes = _liveTaskQueueService.InsertTaskQueue(saveTaskDto.taskQueue);
-
- resultDto.code = BusinessStatusEnum.成功;
- resultDto.msg = "执行完成";
- resultDto.data = new SaveTaskResultModel()
- {
- isRes = inRes
- };
- }
- catch (Exception e)
- {
- resultDto.code = BusinessStatusEnum.方法执行异常;
- resultDto.msg = e.Message;
- }
-
- return resultDto;
- }
-}
\ No newline at end of file
diff --git a/Sln.Wcs.Business/OutStore/PalletOutStore.cs b/Sln.Wcs.Business/OutStore/PalletOutStore.cs
deleted file mode 100644
index bedb8e9..0000000
--- a/Sln.Wcs.Business/OutStore/PalletOutStore.cs
+++ /dev/null
@@ -1,200 +0,0 @@
-#region << 版 本 注 释 >>
-
-/*--------------------------------------------------------------------
-* 版权所有 (c) 2026 WenJY 保留所有权利。
-* CLR版本:4.0.30319.42000
-* 机器名称:Mr.Wen's MacBook Pro
-* 命名空间:Sln.Wcs.Business
-* 唯一标识:1377DAE2-C6B2-4B2D-A553-905D3588649F
-*
-* 创建者:WenJY
-* 电子邮箱:
-* 创建时间:2026-05-06 18:15:46
-* 版本:V1.0.0
-* 描述:
-*
-*--------------------------------------------------------------------
-* 修改人:
-* 时间:
-* 修改说明:
-*
-* 版本:V1.0.0
-*--------------------------------------------------------------------*/
-
-#endregion << 版 本 注 释 >>
-
-using System.Linq.Expressions;
-using Sln.Wcs.Business.Domain.Dto.CreateTask;
-using Sln.Wcs.Business.Domain.Dto.FilterLocation;
-using Sln.Wcs.Business.Domain.Dto.SaveTask;
-using Sln.Wcs.Business.Domain.Dto.ValidateMaterial;
-using Sln.Wcs.Business.Domain.Enum;
-using Sln.Wcs.Business.Domain.Model.CreateTask;
-using Sln.Wcs.Business.Domain.Model.FilterLocation;
-using Sln.Wcs.Business.Domain.Model.SaveTask;
-using Sln.Wcs.Model.Domain;
-using Sln.Wcs.Repository.service;
-
-namespace Sln.Wcs.Business.OutStore;
-
-public class PalletOutStore:BaseBusiness
-{
- private readonly IBasePathInfoService _basePathInfoService;
- private readonly ILiveTaskQueueService _liveTaskQueueService;
- private readonly IBaseStoreInfoService _baseStoreInfoService;
-
- public PalletOutStore(IBasePathInfoService basePathInfoService, ILiveTaskQueueService liveTaskQueueService, IBaseStoreInfoService baseStoreInfoService)
- {
- _basePathInfoService = basePathInfoService;
- _liveTaskQueueService = liveTaskQueueService;
- _baseStoreInfoService = baseStoreInfoService;
- }
-
- public override ValidateMaterialResultDto ValidateMaterial(ValidateMaterialDto validateMaterialDto)
- {
- throw new NotImplementedException();
- }
-
- ///
- /// 创建任务
- ///
- ///
- ///
- ///
- public override CreateTaskResultDto CreateTask(CreateTaskDto createTaskDto)
- {
- CreateTaskResultDto resultDto = new CreateTaskResultDto();
- try
- {
- #region CreateTaskDto 参数校验
-
- if (string.IsNullOrEmpty(createTaskDto.materialCode))
- {
- throw new InvalidOperationException($"物料编号不允许为 NULL");
- }
-
- if (string.IsNullOrEmpty(createTaskDto.palletBarcode))
- {
- throw new InvalidOperationException($"托盘条码不允许为 NULL");
- }
-
- if (string.IsNullOrEmpty(createTaskDto.startPoint) || string.IsNullOrEmpty(createTaskDto.endPoint))
- {
- throw new InvalidOperationException($"起始位置、终点位置不允许为 NULL");
- }
-
- #endregion
-
- createTaskDto.taskType = TaskTypeEnum.OutStore;
- createTaskDto.taskCategory = TaskCategoryEnum.Material;
- //获取托盘出库路径
- Expression> exp = x=>x.startPoint == createTaskDto.startPoint && x.endPoint == createTaskDto.endPoint && x.pathType == (int)createTaskDto.taskType && x.pathCategory == (int)createTaskDto.taskCategory;
- BasePathInfo pathInfo = _basePathInfoService.GetBasePathInfo(exp).FirstOrDefault() ?? throw new InvalidOperationException($"托盘出库输送路径为 NULL");
-
- #region 路径转为任务
-
- string taskCode = "2026050700001"; //需根据现场实际定义生成规则
-
- List taskDetails = pathInfo.pathDetails.Select( item => base.LiveTaskDetailWrapper(taskCode,createTaskDto,item)).ToList();
-
- var taskQueue = base.LiveTaskQueueWrapper(taskCode, createTaskDto, pathInfo);
- taskQueue.taskSteps = taskDetails.Count;
- taskQueue.taskDetails = taskDetails;
- #endregion
-
- resultDto.code = BusinessStatusEnum.成功;
- resultDto.msg = $"托盘出库任务创建成功:{taskCode};关联路径:{pathInfo.pathName}";
- resultDto.data = new CreateTaskResultModel()
- {
- taskCode = taskCode,
- taskQueue = taskQueue,
- taskDetails = taskDetails,
- };
- }
- catch (Exception e)
- {
- resultDto.code = BusinessStatusEnum.方法执行异常;
- resultDto.msg = e.Message;
- }
- return resultDto;
- }
-
- ///
- /// 筛选库位
- ///
- ///
- ///
- ///
- public override FilterLocationResultDto FilterLocation(FilterLocationDto filterLocationDto)
- {
- FilterLocationResultDto resultDto = new FilterLocationResultDto();
- try
- {
-
- #region 参数校验
-
- if (string.IsNullOrEmpty(filterLocationDto.materialCode))
- {
- throw new InvalidOperationException($"物料编号不允许为 NULL");
- }
-
- #endregion
-
- Expression> storeWhere = x => x.storeType == (int)StoreTypeEnum.Pallet;
- Expression> locationWhere = x=>x.materialCode==filterLocationDto.materialCode && x.locationStatus == 1 && x.isFlag == 1;
-
- List storeInfos = _baseStoreInfoService.GetBasePathInfo(storeWhere,locationWhere);
-
- //先对仓库进行排序
- BaseStoreInfo? storeInfo = storeInfos.Where(s => s.locationInfos.Count > 0).OrderBy(x=>x.storeCode).FirstOrDefault() ?? throw new ArgumentNullException($"未获取到可用仓库");
-
- BaseLocationInfo? locationInfo = storeInfo.locationInfos.OrderBy(x => x.locationRows).ThenBy(x=>x.locationColumns).ThenBy(x=>x.locationLayers).FirstOrDefault() ?? throw new ArgumentNullException($"目标仓库:{storeInfo.storeName}中未获取到可用库位");
-
- resultDto.code = BusinessStatusEnum.成功;
- resultDto.msg = "执行完成";
- resultDto.data = new FilterLocationResultModel()
- {
- storeInfo = storeInfo,
-
- locationInfos = storeInfo.locationInfos,
-
- locationInfo = locationInfo,
- };
- }
- catch (Exception e)
- {
- resultDto.code = BusinessStatusEnum.方法执行异常;
- resultDto.msg = e.Message;
- }
-
- return resultDto;
- }
-
- ///
- /// 保存任务
- ///
- ///
- ///
- public override SaveTaskResultDto SaveTask(SaveTaskDto saveTaskDto)
- {
- SaveTaskResultDto resultDto = new SaveTaskResultDto();
- try
- {
- var inRes = _liveTaskQueueService.InsertTaskQueue(saveTaskDto.taskQueue);
-
- resultDto.code = BusinessStatusEnum.成功;
- resultDto.msg = "执行完成";
- resultDto.data = new SaveTaskResultModel()
- {
- isRes = inRes
- };
- }
- catch (Exception e)
- {
- resultDto.code = BusinessStatusEnum.方法执行异常;
- resultDto.msg = e.Message;
- }
-
- return resultDto;
- }
-}
\ No newline at end of file
diff --git a/Sln.Wcs.Business/OutStore/ProductOutStore.cs b/Sln.Wcs.Business/OutStore/ProductOutStore.cs
deleted file mode 100644
index 125d364..0000000
--- a/Sln.Wcs.Business/OutStore/ProductOutStore.cs
+++ /dev/null
@@ -1,200 +0,0 @@
-#region << 版 本 注 释 >>
-
-/*--------------------------------------------------------------------
-* 版权所有 (c) 2026 WenJY 保留所有权利。
-* CLR版本:4.0.30319.42000
-* 机器名称:Mr.Wen's MacBook Pro
-* 命名空间:Sln.Wcs.Business
-* 唯一标识:CA9C52F5-4F55-406E-BD31-EF2856EB75DE
-*
-* 创建者:WenJY
-* 电子邮箱:
-* 创建时间:2026-05-06 18:14:10
-* 版本:V1.0.0
-* 描述:
-*
-*--------------------------------------------------------------------
-* 修改人:
-* 时间:
-* 修改说明:
-*
-* 版本:V1.0.0
-*--------------------------------------------------------------------*/
-
-#endregion << 版 本 注 释 >>
-
-using System.Linq.Expressions;
-using Sln.Wcs.Business.Domain.Dto.CreateTask;
-using Sln.Wcs.Business.Domain.Dto.FilterLocation;
-using Sln.Wcs.Business.Domain.Dto.SaveTask;
-using Sln.Wcs.Business.Domain.Dto.ValidateMaterial;
-using Sln.Wcs.Business.Domain.Enum;
-using Sln.Wcs.Business.Domain.Model.CreateTask;
-using Sln.Wcs.Business.Domain.Model.FilterLocation;
-using Sln.Wcs.Business.Domain.Model.SaveTask;
-using Sln.Wcs.Model.Domain;
-using Sln.Wcs.Repository.service;
-
-namespace Sln.Wcs.Business.OutStore;
-
-public class ProductOutStore:BaseBusiness
-{
- private readonly IBasePathInfoService _basePathInfoService;
- private readonly ILiveTaskQueueService _liveTaskQueueService;
- private readonly IBaseStoreInfoService _baseStoreInfoService;
-
- public ProductOutStore(IBasePathInfoService basePathInfoService, ILiveTaskQueueService liveTaskQueueService, IBaseStoreInfoService baseStoreInfoService)
- {
- _basePathInfoService = basePathInfoService;
- _liveTaskQueueService = liveTaskQueueService;
- _baseStoreInfoService = baseStoreInfoService;
- }
-
- public override ValidateMaterialResultDto ValidateMaterial(ValidateMaterialDto validateMaterialDto)
- {
- throw new NotImplementedException();
- }
-
- ///
- /// 创建任务
- ///
- ///
- ///
- ///
- public override CreateTaskResultDto CreateTask(CreateTaskDto createTaskDto)
- {
- CreateTaskResultDto resultDto = new CreateTaskResultDto();
- try
- {
- #region CreateTaskDto 参数校验
-
- if (string.IsNullOrEmpty(createTaskDto.materialCode))
- {
- throw new InvalidOperationException($"物料编号不允许为 NULL");
- }
-
- if (string.IsNullOrEmpty(createTaskDto.palletBarcode))
- {
- throw new InvalidOperationException($"托盘条码不允许为 NULL");
- }
-
- if (string.IsNullOrEmpty(createTaskDto.startPoint) || string.IsNullOrEmpty(createTaskDto.endPoint))
- {
- throw new InvalidOperationException($"起始位置、终点位置不允许为 NULL");
- }
-
- #endregion
-
- createTaskDto.taskType = TaskTypeEnum.OutStore;
- createTaskDto.taskCategory = TaskCategoryEnum.Material;
- //获取托盘成品路径
- Expression> exp = x=>x.startPoint == createTaskDto.startPoint && x.endPoint == createTaskDto.endPoint && x.pathType == (int)createTaskDto.taskType && x.pathCategory == (int)createTaskDto.taskCategory;
- BasePathInfo pathInfo = _basePathInfoService.GetBasePathInfo(exp).FirstOrDefault() ?? throw new InvalidOperationException($"托盘成品输送路径为 NULL");
-
- #region 路径转为任务
-
- string taskCode = "2026050700001"; //需根据现场实际定义生成规则
-
- List taskDetails = pathInfo.pathDetails.Select( item => base.LiveTaskDetailWrapper(taskCode,createTaskDto,item)).ToList();
-
- var taskQueue = base.LiveTaskQueueWrapper(taskCode, createTaskDto, pathInfo);
- taskQueue.taskSteps = taskDetails.Count;
- taskQueue.taskDetails = taskDetails;
- #endregion
-
- resultDto.code = BusinessStatusEnum.成功;
- resultDto.msg = $"托盘成品任务创建成功:{taskCode};关联路径:{pathInfo.pathName}";
- resultDto.data = new CreateTaskResultModel()
- {
- taskCode = taskCode,
- taskQueue = taskQueue,
- taskDetails = taskDetails,
- };
- }
- catch (Exception e)
- {
- resultDto.code = BusinessStatusEnum.方法执行异常;
- resultDto.msg = e.Message;
- }
- return resultDto;
- }
-
- ///
- /// 筛选库位
- ///
- ///
- ///
- ///
- public override FilterLocationResultDto FilterLocation(FilterLocationDto filterLocationDto)
- {
- FilterLocationResultDto resultDto = new FilterLocationResultDto();
- try
- {
-
- #region 参数校验
-
- if (string.IsNullOrEmpty(filterLocationDto.materialCode))
- {
- throw new InvalidOperationException($"物料编号不允许为 NULL");
- }
-
- #endregion
-
- Expression> storeWhere = x => x.storeType == (int)StoreTypeEnum.Product;
- Expression> locationWhere = x=>x.materialCode==filterLocationDto.materialCode && x.locationStatus == 1 && x.isFlag == 1;
-
- List storeInfos = _baseStoreInfoService.GetBasePathInfo(storeWhere,locationWhere);
-
- //先对仓库进行排序
- BaseStoreInfo? storeInfo = storeInfos.Where(s => s.locationInfos.Count > 0).OrderBy(x=>x.storeCode).FirstOrDefault() ?? throw new ArgumentNullException($"未获取到可用仓库");
-
- BaseLocationInfo? locationInfo = storeInfo.locationInfos.OrderBy(x => x.locationRows).ThenBy(x=>x.locationColumns).ThenBy(x=>x.locationLayers).FirstOrDefault() ?? throw new ArgumentNullException($"目标仓库:{storeInfo.storeName}中未获取到可用库位");
-
- resultDto.code = BusinessStatusEnum.成功;
- resultDto.msg = "执行完成";
- resultDto.data = new FilterLocationResultModel()
- {
- storeInfo = storeInfo,
-
- locationInfos = storeInfo.locationInfos,
-
- locationInfo = locationInfo,
- };
- }
- catch (Exception e)
- {
- resultDto.code = BusinessStatusEnum.方法执行异常;
- resultDto.msg = e.Message;
- }
-
- return resultDto;
- }
-
- ///
- /// 保存任务
- ///
- ///
- ///
- public override SaveTaskResultDto SaveTask(SaveTaskDto saveTaskDto)
- {
- SaveTaskResultDto resultDto = new SaveTaskResultDto();
- try
- {
- var inRes = _liveTaskQueueService.InsertTaskQueue(saveTaskDto.taskQueue);
-
- resultDto.code = BusinessStatusEnum.成功;
- resultDto.msg = "执行完成";
- resultDto.data = new SaveTaskResultModel()
- {
- isRes = inRes
- };
- }
- catch (Exception e)
- {
- resultDto.code = BusinessStatusEnum.方法执行异常;
- resultDto.msg = e.Message;
- }
-
- return resultDto;
- }
-}
\ No newline at end of file
diff --git a/Sln.Wcs.Business/StoreTaskBusiness.cs b/Sln.Wcs.Business/StoreTaskBusiness.cs
index 366aa73..705793b 100644
--- a/Sln.Wcs.Business/StoreTaskBusiness.cs
+++ b/Sln.Wcs.Business/StoreTaskBusiness.cs
@@ -44,9 +44,9 @@ namespace Sln.Wcs.Business;
///
public class StoreTaskBusiness : EntityWrapper
{
- protected readonly IBasePathInfoService _basePathInfoService;
- protected readonly ILiveTaskQueueService _liveTaskQueueService;
- protected readonly IBaseStoreInfoService _baseStoreInfoService;
+ private readonly IBasePathInfoService _basePathInfoService;
+ private readonly ILiveTaskQueueService _liveTaskQueueService;
+ private readonly IBaseStoreInfoService _baseStoreInfoService;
///
/// 构造函数
@@ -83,16 +83,12 @@ public class StoreTaskBusiness : EntityWrapper
CreateTaskResultDto resultDto = new CreateTaskResultDto();
try
{
- // 1. 参数校验(可扩展)
ValidateCreateTaskParams(createTaskDto);
- // 2. 获取输送路径
- BasePathInfo pathInfo = GetPathInfo(createTaskDto, createTaskDto.taskType, createTaskDto.taskCategory);
+ BasePathInfo pathInfo = GetPathInfo(createTaskDto);
- // 4. 生成任务编号
string taskCode = GenerateTaskCode();
- // 5. 路径转为任务
List taskDetails = pathInfo.pathDetails
.Select(item => LiveTaskDetailWrapper(taskCode, createTaskDto, item))
.ToList();
@@ -101,9 +97,8 @@ public class StoreTaskBusiness : EntityWrapper
taskQueue.taskSteps = taskDetails.Count;
taskQueue.taskDetails = taskDetails;
- // 6. 返回结果
resultDto.code = Domain.Enum.BusinessStatusEnum.成功;
- resultDto.msg = GetTaskSuccessMessage(taskCode, pathInfo.pathName, createTaskDto.taskType, createTaskDto.taskCategory);
+ resultDto.msg = $"{GetCategoryName(createTaskDto.taskCategory)}{GetTaskTypeName(createTaskDto.taskType)}任务创建成功:{taskCode};关联路径:{pathInfo.pathName}";
resultDto.data = new CreateTaskResultModel()
{
taskCode = taskCode,
@@ -128,20 +123,15 @@ public class StoreTaskBusiness : EntityWrapper
FilterLocationResultDto resultDto = new FilterLocationResultDto();
try
{
- // 1. 参数校验(可扩展)
ValidateFilterLocationParams(filterLocationDto);
- // 2. 获取库位状态(入库:未使用=0,出库:已使用=1)
int locationStatus = filterLocationDto.taskType == TaskTypeEnum.InStore ? 0 : 1;
- // 3. 构建查询条件
Expression> storeWhere = GetStoreWhere(filterLocationDto.taskType, filterLocationDto.taskCategory);
Expression> locationWhere = GetLocationWhere(filterLocationDto, locationStatus);
- // 4. 查询仓库和库位
List storeInfos = _baseStoreInfoService.GetBasePathInfo(storeWhere, locationWhere);
- // 5. 选择最优仓库和库位
BaseStoreInfo? storeInfo = storeInfos
.Where(s => s.locationInfos.Count > 0)
.OrderBy(x => x.storeCode)
@@ -235,16 +225,16 @@ public class StoreTaskBusiness : EntityWrapper
///
/// 获取路径信息(可被子类重写定制路径查询逻辑)
///
- protected virtual BasePathInfo GetPathInfo(CreateTaskDto createTaskDto, TaskTypeEnum taskType, TaskCategoryEnum taskCategory)
+ protected virtual BasePathInfo GetPathInfo(CreateTaskDto createTaskDto)
{
Expression> exp = x =>
x.startPoint == createTaskDto.startPoint &&
x.endPoint == createTaskDto.endPoint &&
- x.pathType == (int)taskType &&
- x.pathCategory == (int)taskCategory;
+ x.pathType == (int)createTaskDto.taskType &&
+ x.pathCategory == (int)createTaskDto.taskCategory;
return _basePathInfoService.GetBasePathInfo(exp)
- .FirstOrDefault() ?? throw new InvalidOperationException($"{GetCategoryName(taskCategory)}{GetTaskTypeName(taskType)}输送路径为 NULL");
+ .FirstOrDefault() ?? throw new InvalidOperationException($"{GetCategoryName(createTaskDto.taskCategory)}{GetTaskTypeName(createTaskDto.taskType)}输送路径为 NULL");
}
///
@@ -252,15 +242,7 @@ public class StoreTaskBusiness : EntityWrapper
///
protected virtual string GenerateTaskCode()
{
- return DateTime.Now.ToString("yyyyMMddHHmmss") + new Random().Next(1000, 9999);
- }
-
- ///
- /// 获取任务成功的消息(可被子类重写)
- ///
- protected virtual string GetTaskSuccessMessage(string taskCode, string pathName, TaskTypeEnum taskType, TaskCategoryEnum taskCategory)
- {
- return $"{GetCategoryName(taskCategory)}{GetTaskTypeName(taskType)}任务创建成功:{taskCode};关联路径:{pathName}";
+ return DateTime.Now.ToString("yyyyMMddHHmmss") + new Random().Next(10, 99);
}
///
@@ -283,12 +265,10 @@ public class StoreTaskBusiness : EntityWrapper
#endregion
- #region 辅助方法
-
///
/// 获取分类名称
///
- protected string GetCategoryName(TaskCategoryEnum taskCategory)
+ private string GetCategoryName(TaskCategoryEnum taskCategory)
{
return taskCategory switch
{
@@ -302,7 +282,7 @@ public class StoreTaskBusiness : EntityWrapper
///
/// 获取任务类型名称
///
- protected string GetTaskTypeName(TaskTypeEnum taskType)
+ private string GetTaskTypeName(TaskTypeEnum taskType)
{
return taskType switch
{
@@ -311,6 +291,4 @@ public class StoreTaskBusiness : EntityWrapper
_ => "未知"
};
}
-
- #endregion
}
diff --git a/Sln.Wcs.HikRoBotApi/Service/Impl/HikRoBotService.cs b/Sln.Wcs.HikRoBotApi/Service/Impl/HikRoBotService.cs
index ecdd3d2..7ddd699 100644
--- a/Sln.Wcs.HikRoBotApi/Service/Impl/HikRoBotService.cs
+++ b/Sln.Wcs.HikRoBotApi/Service/Impl/HikRoBotService.cs
@@ -1,6 +1,5 @@
using Sln.Wcs.HikRoBotApi.Domain.Dto.CancelTask;
using Sln.Wcs.HikRoBotApi.Domain.Dto.ContinueTask;
-using Sln.Wcs.HikRoBotApi.Domain.Dto.GenAgvSchedulingTask;
using Sln.Wcs.HikRoBotApi.Enum;
using Sln.Wcs.HikRoBotApi.Util;
using Sln.Wcs.HikRoBotSdk;
@@ -10,6 +9,9 @@ using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
+using Sln.Wcs.HikRoBotSdk.Dto.GenAgvSchedulingTask;
+using GenAgvSchedulingTaskDto = Sln.Wcs.HikRoBotApi.Domain.Dto.GenAgvSchedulingTask.GenAgvSchedulingTaskDto;
+using GenAgvSchedulingTaskResultDto = Sln.Wcs.HikRoBotApi.Domain.Dto.GenAgvSchedulingTask.GenAgvSchedulingTaskResultDto;
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
@@ -65,10 +67,19 @@ namespace Sln.Wcs.HikRoBotApi.Service.Impl
throw new ArgumentException($"输入参数为空。");
}
+ // var data = new HikRoBotSdk.Dto.GenAgvSchedulingTask.GenAgvSchedulingTaskDto()
+ // {
+ // reqCode = genAgvSchedulingTask.reqCode,
+ // taskTyp = genAgvSchedulingTask.taskTyp,
+ // };
var data = new HikRoBotSdk.Dto.GenAgvSchedulingTask.GenAgvSchedulingTaskDto()
{
- reqCode = genAgvSchedulingTask.reqCode,
- taskTyp = genAgvSchedulingTask.taskTyp,
+ taskType = "PF-FMR-COMMON",
+ targetRoutes = new List()
+ {
+ new targetRoute(){type = "STORAGE",code = "R5001A02011"},
+ new targetRoute(){type = "STORAGE",code = "R5001A01011"}
+ }
};
var resp = this.hikRoBotSdk.GenAgvSchedulingTask(data);
@@ -83,8 +94,8 @@ namespace Sln.Wcs.HikRoBotApi.Service.Impl
{
code = resp.code,
message = resp.message,
- reqCode = resp.reqCode,
- data = resp.data
+ //reqCode = resp.reqCode,
+ //data = resp.data
},
};
diff --git a/Sln.Wcs.HikRoBotSdk/Config/HikRoBotConfig.cs b/Sln.Wcs.HikRoBotSdk/Config/HikRoBotConfig.cs
index 8183542..0e43bed 100644
--- a/Sln.Wcs.HikRoBotSdk/Config/HikRoBotConfig.cs
+++ b/Sln.Wcs.HikRoBotSdk/Config/HikRoBotConfig.cs
@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using Flurl.Http;
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
@@ -32,11 +33,10 @@ namespace Sln.Wcs.HikRoBotSdk.Config
public class HikRoBotConfig
{
public readonly string api = "";
- public readonly string partnerId;
- public readonly string accesskey;
- public readonly string secretkey;
- public readonly string version;
- public readonly string test;
+ public readonly string contentType = "";
+ public readonly string userAgent="";
+ public readonly string xlrRequestId="";//随机生成
+ public readonly string xlrVersion="";
///
/// 注入海康 SDK 配置参数
@@ -45,36 +45,26 @@ namespace Sln.Wcs.HikRoBotSdk.Config
/// IConfiguration configuration
public HikRoBotConfig(IConfiguration configuration)
{
- if (string.IsNullOrEmpty(configuration["sdk_api"]))
+ if (string.IsNullOrEmpty(configuration["HikRoBot_Url"]))
{
- throw new Exception("sdk_api 配置不正确,请检查Apollo配置.");
+ throw new Exception("HikRoBot_Url 配置不正确,请检查Apollo配置.");
}
- if (string.IsNullOrEmpty(configuration["sdk_json_str"]))
+ if (string.IsNullOrEmpty(configuration["HikRoBot_Content-Type"]))
{
- throw new Exception("sdk_partner_id 配置不正确,请检查Apollo配置.");
+ throw new Exception("HikRoBot_Content-Type 配置不正确,请检查Apollo配置.");
}
- //if (string.IsNullOrEmpty(configuration["sdk_accesskey"]))
- //{
- // throw new Exception("sdk_accesskey 配置不正确,请检查Apollo配置.");
- //}
- //if (string.IsNullOrEmpty(configuration["sdk_secretkey"]))
- //{
- // throw new Exception("sdk_secretkey 配置不正确,请检查Apollo配置.");
- //}
- //if (string.IsNullOrEmpty(configuration["sdk_partner_id"]))
- //{
- // throw new Exception("sdk_partner_id 配置不正确,请检查Apollo配置.");
- //}
- //if (string.IsNullOrEmpty(configuration["sdk_version"]))
- //{
- // throw new Exception("sdk_version 配置不正确,请检查Apollo配置.");
- //}
-
- api = configuration["sdk_json_str"];
- //accesskey = configuration["sdk_accesskey"];
- //secretkey = configuration["sdk_secretkey"];
- //version = configuration["sdk_version"];
- //test = configuration["sdk_test"];
+ if (string.IsNullOrEmpty(configuration["HikRoBot_User-Agent"]))
+ {
+ throw new Exception("HikRoBot_User-Agent 配置不正确,请检查Apollo配置.");
+ }
+ if (string.IsNullOrEmpty(configuration["HikRoBot_X-lr-version"]))
+ {
+ throw new Exception("HikRoBot_X-lr-version 配置不正确,请检查Apollo配置.");
+ }
+ api = configuration["HikRoBot_Url"];
+ contentType = configuration["HikRoBot_ContentType"];
+ userAgent = configuration["HikRoBot_User-Agent"];
+ xlrVersion = configuration["HikRoBot_X-lr-version"];
}
}
diff --git a/Sln.Wcs.HikRoBotSdk/Dto/GenAgvSchedulingTask/GenAgvSchedulingTaskDto.cs b/Sln.Wcs.HikRoBotSdk/Dto/GenAgvSchedulingTask/GenAgvSchedulingTaskDto.cs
index 0113ea8..4b3f7a1 100644
--- a/Sln.Wcs.HikRoBotSdk/Dto/GenAgvSchedulingTask/GenAgvSchedulingTaskDto.cs
+++ b/Sln.Wcs.HikRoBotSdk/Dto/GenAgvSchedulingTask/GenAgvSchedulingTaskDto.cs
@@ -30,129 +30,139 @@ namespace Sln.Wcs.HikRoBotSdk.Dto.GenAgvSchedulingTask
{
public class GenAgvSchedulingTaskDto
{
- //这里写请求参数
- ///
- /// 请求编号,每个请求都要一个唯一编号, 同一个请求重复提交, 使用同一编号。;
- ///
- public string reqCode { get; set; }
+
+ public string taskType{get;set;}
+
+ public List targetRoutes{get;set;}
+
+ // ///
+ // /// 请求编号,每个请求都要一个唯一编号, 同一个请求重复提交, 使用同一编号。;
+ // ///
+ // public string reqCode { get; set; }
+ //
+ // ///
+ // /// 请求时间截 格式: “yyyy-MM-dd HH:mm:ss”。
+ // ///
+ // public string reqTime { get; set; }
+ //
+ // ///
+ // /// 客户端编号,如PDA,HCWMS等。
+ // ///
+ // public string clientCode { get; set; }
+ //
+ // ///
+ // /// 令牌号, 由调度系统颁发
+ // ///
+ // public string tokenCode { get; set; }
+ //
+ // ///
+ // /// 任务类型,
+ // /// 业务流程
+ // /// 5层柜体来料验收拆分 柜体物料 提升机输送线对接位-验收拆分区 WMS F501 2
+ // /// 5层柜体来料入库 柜体物料 验收拆分区-原材料周转区 WMS F502 2
+ // /// 5层辅料立体库物料入库 辅料料箱 回转输送线回库口-辅料库货架 WMS F503 1
+ // /// 5层辅料立体库分拣出库 辅料料箱 辅料库货架-回转输送线出库口 WMS F504 1
+ // /// 5层辅料立体库分拣回库 辅料料箱 回转输送线回库口-辅料库货架 WMS F505 1
+ // /// 5层辅料配送流程 辅料料箱 物料分拣位-装配区领料工位 WMS F506 空值
+ // /// 5层背板安装区物料配送 柜体物料 原材料周转区-背板安装区 WMS F507 2
+ // /// 5层半成品下线 半成品柜 背板安装区-半成品周转区 WMS F508 2
+ // /// 5层半成品检验 半成品柜 半成品周转区-检测台 WMS F509 2
+ // /// 5层成品柜体入库 成品柜体 检验台-成品区 WMS F510 2
+ // /// 5层成品柜体出库 成品柜体 成品区-提升机输送线对接点 WMS F511 2
+ // ///
+ // public string taskTyp { get; set; }
+ //
+ // ///
+ // /// 容器类型(叉车/CTU专用)叉车项目必传
+ // ///
+ // public string ctnrTyp { get; set; }
+ //
+ // ///
+ // /// 容器编号(叉车/CTU专用)
+ // ///
+ // public string ctnrCode { get; set; }
+ //
+ // ///
+ // /// 容器数量(叉车堆叠专用),默认值1,仅记录堆叠的数量不记录堆叠的每个容器号
+ // ///
+ // public string ctnrNum { get; set; }
+ //
+ // ///
+ // /// 任务模式 0-普通move 1-出库move 2-入库move 3-移库move
+ // ///
+ // public string taskMode { get; set; }
+ //
+ // ///
+ // /// 工作位,一般为机台或工作台位置,与RCS-2000端配置的位置名称一致, 工作位名称为字母\数字\或组合, 不超过32位。
+ // ///
+ // public string wbCode { get; set; }
+ //
+ // ///
+ // /// 位置路径:AGV关键路径位置集合,与任务类型中模板配置的位置路径一一对应。待现场地图部署、配置完成后可获取。
+ // ///
+ // public List positionCodePath { get; set; }
+ //
+ // ///
+ // /// “180”,”0”,”90”,”-90” 分别对应地图的”左”,”右”,”上”,”下” ,不指定方向可以为空
+ // ///
+ // public string podDir { get; set; }
+ //
+ // ///
+ // /// “180”,”0”,”90”,”-90” 分别对应地图的”左”,”右”,”上”,”下” ,不指定方向可以为空
+ // ///
+ // public string podTyp { get; set; }
+ //
+ // ///
+ // /// “180”,”0”,”90”,”-90” 分别对应地图的”左”,”右”,”上”,”下” ,不指定方向可以为空
+ // ///
+ // public string podCode { get; set; }
+ //
+ // ///
+ // /// 物料批次或货架上的物料唯一编码,
+ // ///
+ // public string materialLot { get; set; }
+ //
+ // ///
+ // /// 物料类型, 仅移载机器人协议专用必填, 其它车型任务不填
+ // ///
+ // public string materialType { get; set; }
+ //
+ // ///
+ // /// 优先级,从(1~127)级,最大优先级最高。为空时,采用任务模板的优先级。
+ // ///
+ // public string priority { get; set; }
+ //
+ // ///
+ // /// 任务单号,选填, 不填系统自动生成,UUID小于等于64位
+ // ///
+ // public string taskCode { get; set; }
+ //
+ // ///
+ // /// AGV编号,填写表示指定某一编号的AGV执行该任务
+ // ///
+ // public string agvCode { get; set; }
+ //
+ // ///
+ // /// 组编号
+ // ///
+ // public string groupId { get; set; }
+ //
+ // ///
+ // /// 设备类型
+ // ///
+ // public string agvTyp { get; set; }
+ //
+ // ///
+ // /// 区域/策略中挑选货架以及根据物料批次挑选货架时的先进先出规则
+ // ///
+ // public string positionSelStrategy { get; set; }
+ //
+ // public string data { get; set; }
+ }
- ///
- /// 请求时间截 格式: “yyyy-MM-dd HH:mm:ss”。
- ///
- public string reqTime { get; set; }
-
- ///
- /// 客户端编号,如PDA,HCWMS等。
- ///
- public string clientCode { get; set; }
-
- ///
- /// 令牌号, 由调度系统颁发
- ///
- public string tokenCode { get; set; }
-
- ///
- /// 任务类型,
- /// 业务流程
- /// 5层柜体来料验收拆分 柜体物料 提升机输送线对接位-验收拆分区 WMS F501 2
- /// 5层柜体来料入库 柜体物料 验收拆分区-原材料周转区 WMS F502 2
- /// 5层辅料立体库物料入库 辅料料箱 回转输送线回库口-辅料库货架 WMS F503 1
- /// 5层辅料立体库分拣出库 辅料料箱 辅料库货架-回转输送线出库口 WMS F504 1
- /// 5层辅料立体库分拣回库 辅料料箱 回转输送线回库口-辅料库货架 WMS F505 1
- /// 5层辅料配送流程 辅料料箱 物料分拣位-装配区领料工位 WMS F506 空值
- /// 5层背板安装区物料配送 柜体物料 原材料周转区-背板安装区 WMS F507 2
- /// 5层半成品下线 半成品柜 背板安装区-半成品周转区 WMS F508 2
- /// 5层半成品检验 半成品柜 半成品周转区-检测台 WMS F509 2
- /// 5层成品柜体入库 成品柜体 检验台-成品区 WMS F510 2
- /// 5层成品柜体出库 成品柜体 成品区-提升机输送线对接点 WMS F511 2
- ///
- public string taskTyp { get; set; }
-
- ///
- /// 容器类型(叉车/CTU专用)叉车项目必传
- ///
- public string ctnrTyp { get; set; }
-
- ///
- /// 容器编号(叉车/CTU专用)
- ///
- public string ctnrCode { get; set; }
-
- ///
- /// 容器数量(叉车堆叠专用),默认值1,仅记录堆叠的数量不记录堆叠的每个容器号
- ///
- public string ctnrNum { get; set; }
-
- ///
- /// 任务模式 0-普通move 1-出库move 2-入库move 3-移库move
- ///
- public string taskMode { get; set; }
-
- ///
- /// 工作位,一般为机台或工作台位置,与RCS-2000端配置的位置名称一致, 工作位名称为字母\数字\或组合, 不超过32位。
- ///
- public string wbCode { get; set; }
-
- ///
- /// 位置路径:AGV关键路径位置集合,与任务类型中模板配置的位置路径一一对应。待现场地图部署、配置完成后可获取。
- ///
- public List positionCodePath { get; set; }
-
- ///
- /// “180”,”0”,”90”,”-90” 分别对应地图的”左”,”右”,”上”,”下” ,不指定方向可以为空
- ///
- public string podDir { get; set; }
-
- ///
- /// “180”,”0”,”90”,”-90” 分别对应地图的”左”,”右”,”上”,”下” ,不指定方向可以为空
- ///
- public string podTyp { get; set; }
-
- ///
- /// “180”,”0”,”90”,”-90” 分别对应地图的”左”,”右”,”上”,”下” ,不指定方向可以为空
- ///
- public string podCode { get; set; }
-
- ///
- /// 物料批次或货架上的物料唯一编码,
- ///
- public string materialLot { get; set; }
-
- ///
- /// 物料类型, 仅移载机器人协议专用必填, 其它车型任务不填
- ///
- public string materialType { get; set; }
-
- ///
- /// 优先级,从(1~127)级,最大优先级最高。为空时,采用任务模板的优先级。
- ///
- public string priority { get; set; }
-
- ///
- /// 任务单号,选填, 不填系统自动生成,UUID小于等于64位
- ///
- public string taskCode { get; set; }
-
- ///
- /// AGV编号,填写表示指定某一编号的AGV执行该任务
- ///
- public string agvCode { get; set; }
-
- ///
- /// 组编号
- ///
- public string groupId { get; set; }
-
- ///
- /// 设备类型
- ///
- public string agvTyp { get; set; }
-
- ///
- /// 区域/策略中挑选货架以及根据物料批次挑选货架时的先进先出规则
- ///
- public string positionSelStrategy { get; set; }
-
- public string data { get; set; }
+ public class targetRoute
+ {
+ public string type{get;set;}
+ public string code{get;set;}
}
}
diff --git a/Sln.Wcs.HikRoBotSdk/Dto/GenAgvSchedulingTask/GenAgvSchedulingTaskResultDto.cs b/Sln.Wcs.HikRoBotSdk/Dto/GenAgvSchedulingTask/GenAgvSchedulingTaskResultDto.cs
index d386294..6fbc3c6 100644
--- a/Sln.Wcs.HikRoBotSdk/Dto/GenAgvSchedulingTask/GenAgvSchedulingTaskResultDto.cs
+++ b/Sln.Wcs.HikRoBotSdk/Dto/GenAgvSchedulingTask/GenAgvSchedulingTaskResultDto.cs
@@ -43,14 +43,21 @@ namespace Sln.Wcs.HikRoBotSdk.Dto.GenAgvSchedulingTask
///
public string message { get; set; }
+ public data data { get; set; }
+
///
/// 请求编号
///
- public string reqCode { get; set; }
+ public string errorCode { get; set; }
///
/// 自定义返回(返回任务单号)
///
- public string data { get; set; }
+ public bool success { get; set; }
+ }
+
+ public class data
+ {
+ public string robotTaskCode { get; set; }
}
}
diff --git a/Sln.Wcs.HikRoBotSdk/HIkRoBotSdk.cs b/Sln.Wcs.HikRoBotSdk/HIkRoBotSdk.cs
index 31ceae6..88d636a 100644
--- a/Sln.Wcs.HikRoBotSdk/HIkRoBotSdk.cs
+++ b/Sln.Wcs.HikRoBotSdk/HIkRoBotSdk.cs
@@ -7,6 +7,7 @@ using Sln.Wcs.HikRoBotSdk.Dto.GenAgvSchedulingTask;
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Security.Authentication;
using System.Text;
using System.Threading.Tasks;
@@ -55,10 +56,15 @@ namespace Sln.Wcs.HikRoBotSdk
///
public GenAgvSchedulingTaskResultDto GenAgvSchedulingTask(GenAgvSchedulingTaskDto genAgvSchedulingTask)
{
-
+ string url = $"{hikRoBotConfig.api}/task/submit";
+ var request = url
+ .WithHeader("Content-Type", hikRoBotConfig.contentType)
+ .WithHeader("User-Agent",hikRoBotConfig.userAgent)
+ .WithHeader("X-lr-request-id", System.Guid.NewGuid().ToString("N"))
+ .WithHeader("X-lr-version", hikRoBotConfig.xlrVersion);
Console.WriteLine($"请求报文:{JsonConvert.SerializeObject(genAgvSchedulingTask)}");
- return this.hikRoBotConfig.api.PostJsonAsync(genAgvSchedulingTask).Result.GetJsonAsync().Result;
+ return request.PostJsonAsync(genAgvSchedulingTask).Result.GetJsonAsync().Result;
}
///
diff --git a/Sln.Wcs.Model/Domain/LiveTaskQueue.cs b/Sln.Wcs.Model/Domain/LiveTaskQueue.cs
index 4aaa20b..e22b6a0 100644
--- a/Sln.Wcs.Model/Domain/LiveTaskQueue.cs
+++ b/Sln.Wcs.Model/Domain/LiveTaskQueue.cs
@@ -155,7 +155,8 @@ public class LiveTaskQueue
///
/// 明细集合
- ///
+ /// x
[SugarColumn(IsIgnore = true)]
+ [Navigate(NavigateType.OneToMany, nameof(LiveTaskDetail.taskCode), nameof(taskCode))]
public List taskDetails { get; set; }
}
\ No newline at end of file
diff --git a/Sln.Wcs.Repository/Repository.cs b/Sln.Wcs.Repository/Repository.cs
index 4c82bfc..80f56d8 100644
--- a/Sln.Wcs.Repository/Repository.cs
+++ b/Sln.Wcs.Repository/Repository.cs
@@ -37,6 +37,7 @@ namespace Sln.Wcs.Repository
{
itenant = db.AsTenant(); //用来处理事务
base.Context = db.AsTenant().GetConnectionScopeWithAttr(); //获取子Db
+ //base.Context = db.AsTenant().GetConnectionScope("core");
//如果不想通过注入多个仓储
//用到ChangeRepository或者Db.GetMyRepository需要看标题4写法
diff --git a/Sln.Wcs.Repository/service/ILiveTaskQueueService.cs b/Sln.Wcs.Repository/service/ILiveTaskQueueService.cs
index 4eb70cb..e02b5d8 100644
--- a/Sln.Wcs.Repository/service/ILiveTaskQueueService.cs
+++ b/Sln.Wcs.Repository/service/ILiveTaskQueueService.cs
@@ -23,6 +23,7 @@
#endregion << 版 本 注 释 >>
+using System.Linq.Expressions;
using Sln.Wcs.Model.Domain;
using Sln.Wcs.Repository.service.@base;
@@ -31,4 +32,12 @@ namespace Sln.Wcs.Repository.service;
public interface ILiveTaskQueueService:IBaseService
{
bool InsertTaskQueue(LiveTaskQueue taskQueue);
+
+ ///
+ /// 获取任务队列:关联任务明细
+ ///
+ ///
+ ///
+ ///
+ List getLiveTaskQueues(Expression> exp);
}
\ No newline at end of file
diff --git a/Sln.Wcs.Repository/service/Impl/LiveTaskQueueServiceImpl.cs b/Sln.Wcs.Repository/service/Impl/LiveTaskQueueServiceImpl.cs
index 89718db..6d4ebf7 100644
--- a/Sln.Wcs.Repository/service/Impl/LiveTaskQueueServiceImpl.cs
+++ b/Sln.Wcs.Repository/service/Impl/LiveTaskQueueServiceImpl.cs
@@ -23,6 +23,7 @@
#endregion << 版 本 注 释 >>
+using System.Linq.Expressions;
using Sln.Wcs.Model.Domain;
using Sln.Wcs.Repository.service.@base;
@@ -56,4 +57,42 @@ public class LiveTaskQueueServiceImpl: BaseServiceImpl, ILiveTask
}
return res;
}
+
+ public List getLiveTaskQueues(Expression> exp = null)
+ {
+ try
+ {
+ var res = _rep.Context.Queryable()
+ .Includes(x => x.taskDetails) // 先加载所有
+ .Where(exp)
+ .ToList()
+ .Select(task => new LiveTaskQueue
+ {
+ objId = task.objId,
+ taskCode = task.taskCode,
+ materialCode = task.materialCode,
+ palletBarcode = task.palletBarcode,
+ materialBarcode = task.materialBarcode,
+ materialCount = task.materialCount,
+ taskType = task.taskType,
+ taskCategory = task.taskCategory,
+ startPoint = task.startPoint,
+ endPoint = task.endPoint,
+ pathCode = task.pathCode,
+ taskSteps = task.taskSteps,
+ isFlag = task.isFlag,
+ remark = task.remark,
+ taskDetails = task.taskDetails.AsQueryable()
+ //.Where(detailWhere) // 应用子表查询条件
+ .Where(p => p.isFlag == 1)
+ .ToList()
+ }).ToList();
+
+ return res;
+ }
+ catch (Exception ex)
+ {
+ throw new InvalidOperationException($"通过导航查询方式获取任务信息及下属参数执行异常:{ex.Message}");
+ }
+ }
}
\ No newline at end of file
diff --git a/Sln.Wcs.Strategy/ITaskExecuteStrategy.cs b/Sln.Wcs.Strategy/ITaskExecuteStrategy.cs
deleted file mode 100644
index 2a0e0bb..0000000
--- a/Sln.Wcs.Strategy/ITaskExecuteStrategy.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Sln.Wcs.Strategy;
-
-///
-/// 任务执行策略接口 - 从任务队列中取出待执行任务,根据设备类型下发到对应 SDK
-///
-public interface ITaskExecuteStrategy
-{
- ///
- /// 执行一轮任务调度:查询待执行任务,按设备类型下发
- ///
- /// 本次下发的任务数量
- Task ExecuteAsync();
-}
diff --git a/Sln.Wcs.Strategy/MaterialStrategy.cs b/Sln.Wcs.Strategy/MaterialStrategy.cs
new file mode 100644
index 0000000..6d9ed83
--- /dev/null
+++ b/Sln.Wcs.Strategy/MaterialStrategy.cs
@@ -0,0 +1,175 @@
+using Sln.Wcs.Model.Domain;
+using Sln.Wcs.Repository.service;
+using Sln.Wcs.Serilog;
+
+namespace Sln.Wcs.Strategy;
+
+public class MaterialStrategy
+{
+ private readonly SerilogHelper _logger;
+ private readonly ILiveTaskQueueService _taskQueueService;
+ private readonly ILiveTaskDetailService _taskDetailService;
+
+ private CancellationTokenSource? _cts;
+ private bool _isRunning;
+
+ public MaterialStrategy(
+ SerilogHelper logger,
+ ILiveTaskQueueService taskQueueService,
+ ILiveTaskDetailService taskDetailService)
+ {
+ _logger = logger;
+ _taskQueueService = taskQueueService;
+ _taskDetailService = taskDetailService;
+ }
+
+ public void Run()
+ {
+ _logger.Info("包材任务调度就绪,输入 start 启动,stop 停止,quit 退出");
+
+ while (true)
+ {
+ var input = Console.ReadLine()?.Trim().ToLower();
+
+ switch (input)
+ {
+ case "start":
+ Start();
+ break;
+ case "stop":
+ Stop();
+ break;
+ case "quit":
+ Stop();
+ return;
+ default:
+ _logger.Info("未知指令,可用: start | stop | quit");
+ break;
+ }
+ }
+ }
+
+ private void Start()
+ {
+ if (_isRunning)
+ {
+ _logger.Info("调度已在运行中");
+ return;
+ }
+
+ _cts = new CancellationTokenSource();
+ _isRunning = true;
+
+ Task.Run(() => SchedulingLoop(_cts.Token));
+
+ _logger.Info("调度已启动");
+ }
+
+ private void Stop()
+ {
+ if (!_isRunning)
+ {
+ _logger.Info("调度未在运行");
+ return;
+ }
+
+ _cts?.Cancel();
+ _isRunning = false;
+ _logger.Info("调度已停止");
+ }
+
+ private void SchedulingLoop(CancellationToken ct)
+ {
+ while (!ct.IsCancellationRequested)
+ {
+ var taskQueues = _taskQueueService.getLiveTaskQueues(x =>
+ x.taskCategory == 1 && x.taskStatus == 1);
+
+ _logger.Info($"查询待执行包材任务,共 {taskQueues.Count} 条");
+
+ if (taskQueues.Count > 0)
+ {
+ Parallel.ForEach(taskQueues, task =>
+ {
+ ProcessTask(task, ct);
+ });
+ }
+
+ Thread.Sleep(1000);
+ }
+
+ _logger.Info("调度循环已退出");
+ }
+
+ private void ProcessTask(LiveTaskQueue task, CancellationToken ct)
+ {
+ if (ct.IsCancellationRequested) return;
+
+ _logger.Info($"开始执行任务 {task.taskCode},子任务数 {task.taskDetails.Count}");
+
+ task.taskStatus = 2;
+ _taskQueueService.Update(task);
+
+ foreach (var detail in task.taskDetails.OrderBy(x => x.objId))
+ {
+ if (ct.IsCancellationRequested)
+ {
+ _logger.Info($"任务 {task.taskCode} 被中断,当前步骤 {detail.objId} 未执行");
+ return;
+ }
+
+ _logger.Info($"子任务 {task.taskCode}-{detail.objId},设备类型 {detail.deviceType}");
+
+ if (detail.taskStatus == 2 || detail.taskStatus == 3)
+ {
+ _logger.Info($"子任务 {task.taskCode}-{detail.objId},已下发,不再重复下发");
+ continue;
+ }
+
+ var success = detail.deviceType switch
+ {
+ 1 => DispatchToAgv(detail),
+ 2 => DispatchToHoist(detail),
+ _ => true
+ };
+
+ if (success)
+ {
+ detail.taskStatus = 2;
+ _taskDetailService.Update(detail);
+ _logger.Info($"子任务 {task.taskCode}-{detail.objId} 下发成功");
+ }
+ else
+ {
+ _logger.Error($"子任务 {task.taskCode}-{detail.objId} 下发失败,中断后续步骤");
+ break;
+ }
+ }
+
+ if (ct.IsCancellationRequested) return;
+
+ task.taskStatus = 3;
+ _taskQueueService.Update(task);
+ _logger.Info($"任务 {task.taskCode} 执行完成");
+ }
+
+ private bool DispatchToAgv(LiveTaskDetail detail)
+ {
+ if (detail.taskCode == "2026051816004580")
+ {
+ Task.Delay(1000 * 3).Wait();
+ }
+ _logger.Info($"AGV 下发: {detail.taskCode}-{detail.objId},起点 {detail.startPoint} → 终点 {detail.endPoint}");
+ return true;
+ }
+
+ private bool DispatchToHoist(LiveTaskDetail detail)
+ {
+ if (detail.taskCode == "2026050700001")
+ {
+ Task.Delay(1000 * 3).Wait();
+ }
+ _logger.Info($"提升机下发: {detail.taskCode}-{detail.objId},起点 {detail.startPoint} → 终点 {detail.endPoint}");
+ return true;
+ }
+}
diff --git a/Sln.Wcs.Strategy/Sln.Wcs.Strategy.csproj b/Sln.Wcs.Strategy/Sln.Wcs.Strategy.csproj
index 428753c..8370e97 100644
--- a/Sln.Wcs.Strategy/Sln.Wcs.Strategy.csproj
+++ b/Sln.Wcs.Strategy/Sln.Wcs.Strategy.csproj
@@ -9,8 +9,8 @@
-
-
+
+
diff --git a/Sln.Wcs.Strategy/TaskExecuteStrategy.cs b/Sln.Wcs.Strategy/TaskExecuteStrategy.cs
deleted file mode 100644
index 61f559f..0000000
--- a/Sln.Wcs.Strategy/TaskExecuteStrategy.cs
+++ /dev/null
@@ -1,169 +0,0 @@
-using Sln.Wcs.HikRoBotSdk;
-using Sln.Wcs.HikRoBotSdk.Dto.GenAgvSchedulingTask;
-using Sln.Wcs.HoistSdk;
-using Sln.Wcs.HoistSdk.Dto.HoistTaskExecutor;
-using Sln.Wcs.Model.Domain;
-using Sln.Wcs.Repository.service;
-
-namespace Sln.Wcs.Strategy;
-
-///
-/// 任务执行策略 - 轮询数据库中待执行的任务,根据设备类型调用对应 SDK 下发
-///
-public class TaskExecuteStrategy : ITaskExecuteStrategy
-{
- private readonly ILiveTaskQueueService _taskQueueService;
- private readonly ILiveTaskDetailService _taskDetailService;
- private readonly IHIKRoBotSdk _hikRobotSdk;
- private readonly IHoistSdk _hoistSdk;
-
- public TaskExecuteStrategy(
- ILiveTaskQueueService taskQueueService,
- ILiveTaskDetailService taskDetailService,
- IHIKRoBotSdk hikRobotSdk,
- IHoistSdk hoistSdk)
- {
- _taskQueueService = taskQueueService;
- _taskDetailService = taskDetailService;
- _hikRobotSdk = hikRobotSdk;
- _hoistSdk = hoistSdk;
- }
-
- ///
- /// 执行一轮任务调度:查询所有待执行任务,按设备类型下发
- ///
- public Task ExecuteAsync()
- {
- return Task.Run(() =>
- {
- // 1. 查询所有待执行的任务队列(task_status = 1)
- var pendingTasks = _taskQueueService.Query(x => x.taskStatus == 1);
-
- if (pendingTasks.Count == 0)
- return 0;
-
- int dispatchedCount = 0;
-
- foreach (var task in pendingTasks)
- {
- try
- {
- // 2. 查询任务明细
- var details = _taskDetailService.Query(x => x.taskCode == task.taskCode);
-
- if (details.Count == 0)
- continue;
-
- // 3. 取第一个未执行的明细步骤
- var currentDetail = details
- .Where(x => x.taskStatus == 1)
- .OrderBy(x => x.objId)
- .FirstOrDefault();
-
- if (currentDetail == null)
- continue;
-
- // 4. 根据设备类型下发任务
- var success = DispatchByDeviceType(currentDetail);
-
- if (success)
- {
- // 5. 更新明细状态为执行中
- currentDetail.taskStatus = 2;
- _taskDetailService.Update(currentDetail);
-
- // 6. 更新队列状态为执行中
- task.taskStatus = 2;
- _taskQueueService.Update(task);
-
- dispatchedCount++;
- }
- }
- catch (Exception ex)
- {
- Console.WriteLine($"任务 {task.taskCode} 下发失败: {ex.Message}");
- }
- }
-
- return dispatchedCount;
- });
- }
-
- ///
- /// 根据设备类型分发到对应 SDK
- ///
- private bool DispatchByDeviceType(LiveTaskDetail detail)
- {
- return detail.deviceType switch
- {
- 1 => DispatchToAgv(detail),
- 2 => DispatchToHoist(detail),
- _ => throw new NotSupportedException($"不支持的设备类型: {detail.deviceType}")
- };
- }
-
- ///
- /// 下发 AGV 任务(海康机器人 SDK)
- ///
- private bool DispatchToAgv(LiveTaskDetail detail)
- {
- var dto = new GenAgvSchedulingTaskDto
- {
- reqCode = detail.taskCode,
- reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
- clientCode = "WCS",
- taskCode = detail.taskCode,
- taskTyp = detail.taskType switch
- {
- 1 => "1", // 入库
- 2 => "2", // 出库
- _ => "0"
- },
- taskMode = detail.taskType switch
- {
- 1 => "2", // 入库 move
- 2 => "1", // 出库 move
- _ => "0"
- },
- wbCode = detail.startPoint,
- ctnrCode = detail.palletBarcode,
- materialLot = detail.materialBarcode,
- positionCodePath = new List
- {
- new() { positionCode = detail.startPoint, type = "00" },
- new() { positionCode = detail.endPoint, type = "00" }
- }
- };
-
- var result = _hikRobotSdk.GenAgvSchedulingTask(dto);
- return result.code == "0";
- }
-
- ///
- /// 下发提升机任务(Hoist SDK)
- ///
- private bool DispatchToHoist(LiveTaskDetail detail)
- {
- var dto = new HoistTaskExeDto
- {
- hoistCode = detail.startPoint,
- taskCode = detail.taskCode,
- startPoint = ParseIntPoint(detail.startPoint),
- endPoint = ParseIntPoint(detail.endPoint)
- };
-
- var result = _hoistSdk.HoistTaskExecutor(dto);
- return result.code == "0";
- }
-
- ///
- /// 将位置字符串转为整数楼层/层号
- ///
- private static int ParseIntPoint(string? point)
- {
- if (string.IsNullOrEmpty(point))
- return 0;
-
- return int.TryParse(point, out var val) ? val : 0;
- }
-}
diff --git a/Sln.Wcs.sln b/Sln.Wcs.sln
index 67a0951..554a345 100644
--- a/Sln.Wcs.sln
+++ b/Sln.Wcs.sln
@@ -28,8 +28,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sln.Wcs.Business", "Sln.Wcs
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sln.Wcs.Strategy", "Sln.Wcs.Strategy\Sln.Wcs.Strategy.csproj", "{F7658F97-F78A-4612-A1A5-490F2CDE49DD}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sln.Wcs.Business.Tests", "Sln.Wcs.Business.Tests\Sln.Wcs.Business.Tests.csproj", "{0911EA85-F152-453E-BB7D-4C7079361443}"
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -88,10 +86,6 @@ Global
{F7658F97-F78A-4612-A1A5-490F2CDE49DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F7658F97-F78A-4612-A1A5-490F2CDE49DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F7658F97-F78A-4612-A1A5-490F2CDE49DD}.Release|Any CPU.Build.0 = Release|Any CPU
- {0911EA85-F152-453E-BB7D-4C7079361443}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0911EA85-F152-453E-BB7D-4C7079361443}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0911EA85-F152-453E-BB7D-4C7079361443}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0911EA85-F152-453E-BB7D-4C7079361443}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Sln.Wcs/MaterialInStoreTest.cs b/Sln.Wcs/MaterialInStoreTest.cs
index 585df70..3673eeb 100644
--- a/Sln.Wcs/MaterialInStoreTest.cs
+++ b/Sln.Wcs/MaterialInStoreTest.cs
@@ -23,18 +23,19 @@
#endregion << 版 本 注 释 >>
+using Sln.Wcs.Business;
using Sln.Wcs.Business.Domain.Dto.CreateTask;
using Sln.Wcs.Business.Domain.Dto.FilterLocation;
using Sln.Wcs.Business.Domain.Dto.SaveTask;
-using Sln.Wcs.Business.InStore;
+using Sln.Wcs.Business.Domain.Enum;
namespace Sln.Wcs;
public class MaterialInStoreTest
{
- private readonly MaterialInStore _service;
+ private readonly StoreTaskBusiness _service;
- public MaterialInStoreTest(MaterialInStore service)
+ public MaterialInStoreTest(StoreTaskBusiness service)
{
_service = service;
}
@@ -47,22 +48,31 @@ public class MaterialInStoreTest
palletBarcode = "20260507000001"
});
- var info = _service.CreateTask(new CreateTaskDto()
+ for (int i = 0; i < 10; i++)
{
- materialCode = "20260507000001",
- materialBarcode = "20260507000001",
- palletBarcode = "20260507000001",
- amount = 1,
- startPoint = "13#_L1_01",
- endPoint = "15#_L3_03",
- });
+ var materialBarcode = $"2026050700000{i + 1}";
+ var palletBarcode = $"PALLET{i + 1:D2}";
- var res = _service.SaveTask(new SaveTaskDto()
- {
- taskCode = info.data.taskCode,
- taskQueue = info.data.taskQueue,
- taskDetails = info.data.taskDetails,
- });
+ var info = _service.CreateTask(new CreateTaskDto()
+ {
+ materialCode = "20260507000001",
+ materialBarcode = materialBarcode,
+ palletBarcode = palletBarcode,
+ amount = 1,
+ startPoint = "13#_L1_01",
+ endPoint = "15#_L3_03",
+ taskCategory = TaskCategoryEnum.Material,
+ taskType = TaskTypeEnum.InStore
+ });
+ _service.SaveTask(new SaveTaskDto()
+ {
+ taskCode = info.data.taskCode,
+ taskQueue = info.data.taskQueue,
+ taskDetails = info.data.taskDetails,
+ });
+
+ Console.WriteLine($"[MaterialInStoreTest] 第 {i + 1} 条任务创建完成: {info.data.taskCode}");
+ }
}
}
\ No newline at end of file
diff --git a/Sln.Wcs/Program.cs b/Sln.Wcs/Program.cs
index 042944d..6050bfb 100644
--- a/Sln.Wcs/Program.cs
+++ b/Sln.Wcs/Program.cs
@@ -1,11 +1,17 @@
using System.Reflection;
using Com.Ctrip.Framework.Apollo;
+using Flurl.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
using NeoSmart.Caching.Sqlite;
+using Sln.Wcs.HikRoBotApi.Domain.Dto.GenAgvSchedulingTask;
+using Sln.Wcs.HikRoBotApi.Service;
+using Sln.Wcs.HikRoBotApi.Service.Impl;
using Sln.Wcs.Repository;
using Sln.Wcs.Serilog;
using Sln.Wcs.Plc;
+using Sln.Wcs.Strategy;
using ZiggyCreatures.Caching.Fusion;
using ZiggyCreatures.Caching.Fusion.Serialization.NewtonsoftJson;
@@ -16,6 +22,11 @@ namespace Sln.Wcs
static async Task Main(string[] args)
{
+ TimeZoneInfo chinaZone = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time");
+ DateTimeOffset utcNow = DateTimeOffset.UtcNow;
+ DateTimeOffset beijingTime = TimeZoneInfo.ConvertTime(utcNow, chinaZone);
+ string beijingTimeString = beijingTime.ToString("yyyy-MM-dd HH:mm");
+ Console.WriteLine(beijingTimeString);
var services = new ServiceCollection();
ConfigureServices(services);
@@ -28,6 +39,20 @@ namespace Sln.Wcs
log.Info($"系统启动成功,日志存放位置:{config["logPath"]}");
+ // MaterialInStoreTest? service = serviceProvider.GetService();
+ // service?.Run();
+
+ //禁用 SSL
+ FlurlHttp.ConfigureClientForUrl("https://172.16.12.11")
+ .ConfigureInnerHandler(handler =>
+ {
+ handler.ServerCertificateCustomValidationCallback = (_, _, _, _) => true;
+ });
+
+ // var service = serviceProvider.GetService();
+ // var res = service.GetGenAgvSchedulingTask(new GenAgvSchedulingTaskDto());
+
+ Task.Delay(-1).Wait();
}
private static void ConfigureServices(IServiceCollection services)
@@ -46,6 +71,7 @@ namespace Sln.Wcs
Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.HoistSdk.dll")),
Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.Plc.dll")),
Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.Business.dll")),
+ Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.Strategy.dll")),
};
services.Scan(scan => scan.FromAssemblies(assemblies)
@@ -55,6 +81,8 @@ namespace Sln.Wcs
.WithTransientLifetime());
services.AddSingleton(typeof(SerilogHelper));
+
+ services.AddSingleton(typeof(MaterialInStoreTest));
services.AddSqlSugarSetup();
diff --git a/Sln.Wcs/Sln.Wcs.csproj b/Sln.Wcs/Sln.Wcs.csproj
index f049ba9..b6568e1 100644
--- a/Sln.Wcs/Sln.Wcs.csproj
+++ b/Sln.Wcs/Sln.Wcs.csproj
@@ -35,6 +35,7 @@
+