wanshenmean
13 小时以前 234bec78dd54ca0e2952b8d31d0c17ee1dc89ba9
feat: 添加MES设备动态凭证支持

实现MES设备配置管理功能,支持根据不同设备动态获取凭证:
1. 新增MES设备配置实体和服务接口
2. 在拆盘/组盘确认接口中添加设备名称参数
3. 实现MES接口的动态Token调用
4. 完善入库出站时的设备凭证处理
5. 添加设备配置SQL脚本和测试数据
已添加6个文件
已修改15个文件
658 ■■■■■ 文件已修改
Code/.omc/state/last-tool-error.json 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/.omc/state/mission-state.json 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/.omc/state/subagent-tracking.json 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotSimpleCommandHandler.cs 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/MesService.cs 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/Stock/GroupPalletConfirmRequestDto.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/Stock/SplitPalletConfirmRequestDto.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_IBasicService/IMESDeviceConfigService.cs 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_IBasicService/IMesService.cs 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_IStockService/IStockService.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Mes/Dt_MESDeviceConfig.cs 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Mes/Dt_MESDeviceConfig.sql 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/MESDeviceConfigService.cs 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs 94 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Inbound.cs 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Outbound.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockController.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目资料/设备协议/上位系统对接/~$高温2常温1及机械手设备账号信息表(1).xlsx 补丁 | 查看 | 原始文档 | blame | 历史
项目资料/设备协议/上位系统对接/高温2常温1及机械手设备账号信息表(1).xlsx 补丁 | 查看 | 原始文档 | blame | 历史
Code/.omc/state/last-tool-error.json
@@ -1,7 +1,7 @@
{
  "tool_name": "Bash",
  "tool_input_preview": "{\"command\":\"node -e \\\"\\nconst f=require('fs'),p=require('path'),h=require('os').homedir();\\nconst d=process.env.CLAUDE_CONFIG_DIR||p.join(h,'.claude');\\nconst cf=p.join(d,'.omc-config.json');\\nconst e...",
  "error": "Exit code 1\n<anonymous_script>:1\r\n\r\n\r\nSyntaxError: Unexpected end of JSON input\r\n    at JSON.parse (<anonymous>)\r\n    at [eval]:5:38\r\n    at runScriptInThisContext (node:internal/vm:219:10)\r\n    at node:internal/process/execution:451:12\r\n    at [eval]-wrapper:6:24\r\n    at runScriptInContext (node:internal/process/execution:449:60)\r\n    at evalFunction (node:internal/process/execution:283:30)\r\n    at evalTypeScript (node:internal/process/execution:295:3)\r\n    at node:internal/main/eval_string:71:...",
  "timestamp": "2026-04-18T06:15:45.665Z",
  "tool_name": "Read",
  "tool_input_preview": "{\"file_path\":\"D:\\\\Git\\\\ShanMeiXinNengYuan\\\\Code\\\\WMS\\\\WIDESEA_WMSServer\\\\WIDESEA_TaskInfoService\\\\WCS\\\\TaskService.cs\"}",
  "error": "File does not exist. Note: your current working directory is D:\\Git\\ShanMeiXinNengYuan\\Code.",
  "timestamp": "2026-04-18T07:45:29.125Z",
  "retry_count": 1
}
Code/.omc/state/mission-state.json
@@ -1,5 +1,5 @@
{
  "updatedAt": "2026-04-16T13:59:54.835Z",
  "updatedAt": "2026-04-18T07:46:50.058Z",
  "missions": [
    {
      "id": "session:9007b9ea-1eb6-4d24-8fe7-2c3a949eac88:none",
@@ -1070,6 +1070,148 @@
          "sourceKey": "session-stop:a93149b10e8b430e7"
        }
      ]
    },
    {
      "id": "session:f36717d7-c4c4-4816-8723-6f7d562203f6:none",
      "source": "session",
      "name": "none",
      "objective": "Session mission",
      "createdAt": "2026-04-18T06:36:59.451Z",
      "updatedAt": "2026-04-18T07:46:50.058Z",
      "status": "done",
      "workerCount": 8,
      "taskCounts": {
        "total": 8,
        "pending": 0,
        "blocked": 0,
        "inProgress": 0,
        "completed": 8,
        "failed": 0
      },
      "agents": [
        {
          "name": "Explore:a1ab626",
          "role": "Explore",
          "ownership": "a1ab62633715919c8",
          "status": "done",
          "currentStep": null,
          "latestUpdate": "completed",
          "completedSummary": null,
          "updatedAt": "2026-04-18T06:39:31.702Z"
        },
        {
          "name": "general-purpose:ae116cb",
          "role": "general-purpose",
          "ownership": "ae116cb86a435866d",
          "status": "done",
          "currentStep": null,
          "latestUpdate": "completed",
          "completedSummary": null,
          "updatedAt": "2026-04-18T06:50:41.503Z"
        },
        {
          "name": "general-purpose:a4e061e",
          "role": "general-purpose",
          "ownership": "a4e061e4a6d17c682",
          "status": "done",
          "currentStep": null,
          "latestUpdate": "completed",
          "completedSummary": null,
          "updatedAt": "2026-04-18T06:52:02.047Z"
        },
        {
          "name": "general-purpose:afdf6ef",
          "role": "general-purpose",
          "ownership": "afdf6efad435c036a",
          "status": "done",
          "currentStep": null,
          "latestUpdate": "completed",
          "completedSummary": null,
          "updatedAt": "2026-04-18T06:50:50.428Z"
        },
        {
          "name": "general-purpose:ab1f8d2",
          "role": "general-purpose",
          "ownership": "ab1f8d2625bd8a667",
          "status": "done",
          "currentStep": null,
          "latestUpdate": "completed",
          "completedSummary": null,
          "updatedAt": "2026-04-18T06:54:35.702Z"
        },
        {
          "name": "general-purpose:a99f2fa",
          "role": "general-purpose",
          "ownership": "a99f2fa258ad9b5a1",
          "status": "done",
          "currentStep": null,
          "latestUpdate": "completed",
          "completedSummary": null,
          "updatedAt": "2026-04-18T06:50:30.602Z"
        },
        {
          "name": "general-purpose:aa71986",
          "role": "general-purpose",
          "ownership": "aa71986c72a8dd1f4",
          "status": "done",
          "currentStep": null,
          "latestUpdate": "completed",
          "completedSummary": null,
          "updatedAt": "2026-04-18T07:46:50.058Z"
        },
        {
          "name": "general-purpose:aadbd70",
          "role": "general-purpose",
          "ownership": "aadbd702e8fdf756c",
          "status": "done",
          "currentStep": null,
          "latestUpdate": "completed",
          "completedSummary": null,
          "updatedAt": "2026-04-18T07:46:15.279Z"
        }
      ],
      "timeline": [
        {
          "id": "session-stop:ab1f8d2625bd8a667:2026-04-18T06:54:35.702Z",
          "at": "2026-04-18T06:54:35.702Z",
          "kind": "completion",
          "agent": "general-purpose:ab1f8d2",
          "detail": "completed",
          "sourceKey": "session-stop:ab1f8d2625bd8a667"
        },
        {
          "id": "session-start:aa71986c72a8dd1f4:2026-04-18T07:45:17.089Z",
          "at": "2026-04-18T07:45:17.089Z",
          "kind": "update",
          "agent": "general-purpose:aa71986",
          "detail": "started general-purpose:aa71986",
          "sourceKey": "session-start:aa71986c72a8dd1f4"
        },
        {
          "id": "session-start:aadbd702e8fdf756c:2026-04-18T07:45:17.153Z",
          "at": "2026-04-18T07:45:17.153Z",
          "kind": "update",
          "agent": "general-purpose:aadbd70",
          "detail": "started general-purpose:aadbd70",
          "sourceKey": "session-start:aadbd702e8fdf756c"
        },
        {
          "id": "session-stop:aadbd702e8fdf756c:2026-04-18T07:46:15.279Z",
          "at": "2026-04-18T07:46:15.279Z",
          "kind": "completion",
          "agent": "general-purpose:aadbd70",
          "detail": "completed",
          "sourceKey": "session-stop:aadbd702e8fdf756c"
        },
        {
          "id": "session-stop:aa71986c72a8dd1f4:2026-04-18T07:46:50.058Z",
          "at": "2026-04-18T07:46:50.058Z",
          "kind": "completion",
          "agent": "general-purpose:aa71986",
          "detail": "completed",
          "sourceKey": "session-stop:aa71986c72a8dd1f4"
        }
      ]
    }
  ]
}
Code/.omc/state/subagent-tracking.json
@@ -686,10 +686,82 @@
      "status": "completed",
      "completed_at": "2026-04-16T13:59:54.835Z",
      "duration_ms": 111569
    },
    {
      "agent_id": "a1ab62633715919c8",
      "agent_type": "Explore",
      "started_at": "2026-04-18T06:36:59.451Z",
      "parent_mode": "none",
      "status": "completed",
      "completed_at": "2026-04-18T06:39:31.702Z",
      "duration_ms": 152251
    },
    {
      "agent_id": "ae116cb86a435866d",
      "agent_type": "general-purpose",
      "started_at": "2026-04-18T06:49:33.031Z",
      "parent_mode": "none",
      "status": "completed",
      "completed_at": "2026-04-18T06:50:41.503Z",
      "duration_ms": 68472
    },
    {
      "agent_id": "a4e061e4a6d17c682",
      "agent_type": "general-purpose",
      "started_at": "2026-04-18T06:49:33.090Z",
      "parent_mode": "none",
      "status": "completed",
      "completed_at": "2026-04-18T06:52:02.047Z",
      "duration_ms": 148957
    },
    {
      "agent_id": "afdf6efad435c036a",
      "agent_type": "general-purpose",
      "started_at": "2026-04-18T06:49:33.151Z",
      "parent_mode": "none",
      "status": "completed",
      "completed_at": "2026-04-18T06:50:50.428Z",
      "duration_ms": 77277
    },
    {
      "agent_id": "ab1f8d2625bd8a667",
      "agent_type": "general-purpose",
      "started_at": "2026-04-18T06:49:33.209Z",
      "parent_mode": "none",
      "status": "completed",
      "completed_at": "2026-04-18T06:54:35.702Z",
      "duration_ms": 302493
    },
    {
      "agent_id": "a99f2fa258ad9b5a1",
      "agent_type": "general-purpose",
      "started_at": "2026-04-18T06:49:33.266Z",
      "parent_mode": "none",
      "status": "completed",
      "completed_at": "2026-04-18T06:50:30.602Z",
      "duration_ms": 57336
    },
    {
      "agent_id": "aa71986c72a8dd1f4",
      "agent_type": "general-purpose",
      "started_at": "2026-04-18T07:45:17.089Z",
      "parent_mode": "none",
      "status": "completed",
      "completed_at": "2026-04-18T07:46:50.058Z",
      "duration_ms": 92969
    },
    {
      "agent_id": "aadbd702e8fdf756c",
      "agent_type": "general-purpose",
      "started_at": "2026-04-18T07:45:17.153Z",
      "parent_mode": "none",
      "status": "completed",
      "completed_at": "2026-04-18T07:46:15.279Z",
      "duration_ms": 58126
    }
  ],
  "total_spawned": 77,
  "total_completed": 74,
  "total_spawned": 82,
  "total_completed": 82,
  "total_failed": 0,
  "last_updated": "2026-04-16T13:59:54.939Z"
  "last_updated": "2026-04-18T07:46:50.164Z"
}
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs
@@ -647,10 +647,11 @@
        /// å½“拆盘任务全部取完时调用,一次性上传整个托盘的解绑数据到 MES。
        /// </remarks>
        /// <param name="palletCode">源托盘号</param>
        /// <param name="deviceName">设备名称,用于传递到 WMS</param>
        /// <returns>HTTP å“åº”结果</returns>
        public HttpResponseResult<WebResponseContent> PostSplitPalletConfirmAsync(string palletCode)
        public HttpResponseResult<WebResponseContent> PostSplitPalletConfirmAsync(string palletCode, string deviceName)
        {
            var request = new { PalletCode = palletCode };
            var request = new { PalletCode = palletCode, DeviceName = deviceName };
            return _httpClientHelper.Post<WebResponseContent>(nameof(ConfigKey.SplitPalletConfirm), request.ToJson());
        }
@@ -661,10 +662,11 @@
        /// å½“组盘任务全部放完时调用,一次性上传整个托盘的绑定数据到 MES。
        /// </remarks>
        /// <param name="palletCode">目标托盘号</param>
        /// <param name="deviceName">设备名称,用于传递到 WMS</param>
        /// <returns>HTTP å“åº”结果</returns>
        public HttpResponseResult<WebResponseContent> PostGroupPalletConfirmAsync(string palletCode)
        public HttpResponseResult<WebResponseContent> PostGroupPalletConfirmAsync(string palletCode, string deviceName)
        {
            var request = new { PalletCode = palletCode };
            var request = new { PalletCode = palletCode, DeviceName = deviceName };
            return _httpClientHelper.Post<WebResponseContent>(nameof(ConfigKey.GroupPalletConfirm), request.ToJson());
        }
    }
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotSimpleCommandHandler.cs
@@ -150,7 +150,7 @@
                            {
                                // è°ƒç”¨æ‰¹é‡æ‹†ç›˜ç¡®è®¤æŽ¥å£ï¼ˆæ¢ç›˜å–完阶段)
                                var sourcePallet = state.CurrentTask.RobotSourceAddressPalletCode;
                                var confirmResult = _taskProcessor.PostSplitPalletConfirmAsync(sourcePallet);
                                var confirmResult = _taskProcessor.PostSplitPalletConfirmAsync(sourcePallet, state.RobotCrane?.DeviceName);
                                if (!confirmResult.IsSuccess)
                                {
                                    QuartzLogger.Error($"批量拆盘确认失败: {confirmResult.ErrorMessage}", state.RobotCrane?.DeviceName ?? "Unknown");
@@ -180,7 +180,7 @@
                        {
                            // è°ƒç”¨æ‰¹é‡æ‹†ç›˜ç¡®è®¤æŽ¥å£
                            var sourcePallet = state.CurrentTask.RobotSourceAddressPalletCode;
                            var confirmResult = _taskProcessor.PostSplitPalletConfirmAsync(sourcePallet);
                            var confirmResult = _taskProcessor.PostSplitPalletConfirmAsync(sourcePallet, state.RobotCrane?.DeviceName);
                            if (!confirmResult.IsSuccess)
                            {
                                QuartzLogger.Error($"批量拆盘确认失败: {confirmResult.ErrorMessage}", state.RobotCrane?.DeviceName ?? "Unknown");
@@ -221,7 +221,7 @@
                            {
                                // è°ƒç”¨æ‰¹é‡ç»„盘确认接口(换盘放完阶段)
                                var targetPallet = state.CurrentTask.RobotTargetAddressPalletCode;
                                var confirmResult = _taskProcessor.PostGroupPalletConfirmAsync(targetPallet);
                                var confirmResult = _taskProcessor.PostGroupPalletConfirmAsync(targetPallet, state.RobotCrane?.DeviceName);
                                if (!confirmResult.IsSuccess)
                                {
                                    QuartzLogger.Error($"批量组盘确认失败: {confirmResult.ErrorMessage}", state.RobotCrane?.DeviceName ?? "Unknown");
@@ -257,11 +257,7 @@
                        {
                            // è°ƒç”¨æ‰¹é‡ç»„盘确认接口
                            //var targetPallet = state.CurrentTask.RobotTargetAddressPalletCode;
                            //var confirmResult = _taskProcessor.PostGroupPalletConfirmAsync(targetPallet);
                            //if (!confirmResult.IsSuccess)
                            //{
                            //    QuartzLogger.Error($"批量组盘确认失败: {confirmResult.ErrorMessage}", state.RobotCrane?.DeviceName ?? "Unknown");
                            //}
                            //_taskProcessor.PostGroupPalletConfirmAsync(targetPallet, state.RobotCrane?.DeviceName);
                            // å¤„理入库任务回传
                            // useSourceAddress: false è¡¨ç¤ºä½¿ç”¨ç›®æ ‡åœ°å€ï¼ˆç»„盘场景)
Code/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/MesService.cs
@@ -43,10 +43,30 @@
            };
        }
        private HttpRequestConfig BuildConfig(string token)
        {
            return new HttpRequestConfig
            {
                Headers = new Dictionary<string, string>
                {
                    { "Authorization", token }
                },
                TimeoutMs = 30000,
                MaxRetryCount = 0,
                EnableLogging = true
            };
        }
        private HttpResponseResult<MesResponse> Post<T>(string url, T request)
        {
            string json = JsonConvert.SerializeObject(request);
            return _httpClient.Post<MesResponse>(url, json, "application/json", BuildConfig());
        }
        private HttpResponseResult<MesResponse> Post<T>(string url, T request, HttpRequestConfig config)
        {
            string json = JsonConvert.SerializeObject(request);
            return _httpClient.Post<MesResponse>(url, json, "application/json", config);
        }
        public HttpResponseResult<MesResponse> BindContainer(BindContainerRequest request)
@@ -57,6 +77,16 @@
        public HttpResponseResult<MesResponse> UnBindContainer(UnBindContainerRequest request)
        {
            return Post(_baseUrl + UnBindContainerPath, request);
        }
        public HttpResponseResult<MesResponse> BindContainer(BindContainerRequest request, string token)
        {
            return Post(_baseUrl + BindContainerPath, request, BuildConfig(token));
        }
        public HttpResponseResult<MesResponse> UnBindContainer(UnBindContainerRequest request, string token)
        {
            return Post(_baseUrl + UnBindContainerPath, request, BuildConfig(token));
        }
        public HttpResponseResult<MesResponse> ContainerNgReport(ContainerNgReportRequest request)
@@ -73,5 +103,15 @@
        {
            return Post(_baseUrl + OutboundInContainerPath, request);
        }
        public HttpResponseResult<MesResponse> InboundInContainer(InboundInContainerRequest request, string token)
        {
            return Post(_baseUrl + InboundInContainerPath, request, BuildConfig(token));
        }
        public HttpResponseResult<MesResponse> OutboundInContainer(OutboundInContainerRequest request, string token)
        {
            return Post(_baseUrl + OutboundInContainerPath, request, BuildConfig(token));
        }
    }
}
Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/Stock/GroupPalletConfirmRequestDto.cs
@@ -9,5 +9,10 @@
        /// ç›®æ ‡æ‰˜ç›˜å·
        /// </summary>
        public string PalletCode { get; set; }
        /// <summary>
        /// è®¾å¤‡åç§°ï¼ˆç”¨äºŽåŠ¨æ€MES凭证查询)
        /// </summary>
        public string DeviceName { get; set; }
    }
}
Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/Stock/SplitPalletConfirmRequestDto.cs
@@ -9,5 +9,10 @@
        /// æºæ‰˜ç›˜å·
        /// </summary>
        public string PalletCode { get; set; }
        /// <summary>
        /// è®¾å¤‡åç§°ï¼ˆç”¨äºŽåŠ¨æ€MES凭证查询)
        /// </summary>
        public string DeviceName { get; set; }
    }
}
Code/WMS/WIDESEA_WMSServer/WIDESEA_IBasicService/IMESDeviceConfigService.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
using WIDESEA_Core;
using WIDESEA_Model.Models;
namespace WIDESEA_IBasicService
{
    /// <summary>
    /// MES设备配置信息服务接口
    /// </summary>
    public interface IMESDeviceConfigService : IDependency
    {
        /// <summary>
        /// æ ¹æ®è®¾å¤‡åç§°èŽ·å–MES设备配置(精确匹配)
        /// </summary>
        /// <param name="deviceName">设备名称</param>
        /// <returns>MES设备配置,如果未找到则返回null</returns>
        Dt_MESDeviceConfig? GetByDeviceName(string deviceName);
        /// <summary>
        /// æ ¹æ®è®¾å¤‡åç§°å’Œä»“库编码获取MES设备配置
        /// åŒ¹é…æ¡ä»¶ï¼šDeviceName精确匹配且(WarehouseCode为空或等于指定的仓库编码)
        /// </summary>
        /// <param name="deviceName">设备名称</param>
        /// <param name="warehouseCode">仓库编码</param>
        /// <returns>MES设备配置,如果未找到则返回null</returns>
        Dt_MESDeviceConfig? GetByDeviceNameAndWarehouse(string deviceName, string warehouseCode);
    }
}
Code/WMS/WIDESEA_WMSServer/WIDESEA_IBasicService/IMesService.cs
@@ -20,6 +20,16 @@
        HttpResponseResult<MesResponse> UnBindContainer(UnBindContainerRequest request);
        /// <summary>
        /// æ‰˜ç›˜ç”µèŠ¯ç»‘å®šï¼ˆæ”¯æŒåŠ¨æ€Token)
        /// </summary>
        HttpResponseResult<MesResponse> BindContainer(BindContainerRequest request, string token);
        /// <summary>
        /// æ‰˜ç›˜ç”µèŠ¯è§£ç»‘ï¼ˆæ”¯æŒåŠ¨æ€Token)
        /// </summary>
        HttpResponseResult<MesResponse> UnBindContainer(UnBindContainerRequest request, string token);
        /// <summary>
        /// æ‰˜ç›˜NG电芯上报
        /// </summary>
        HttpResponseResult<MesResponse> ContainerNgReport(ContainerNgReportRequest request);
@@ -30,8 +40,18 @@
        HttpResponseResult<MesResponse> InboundInContainer(InboundInContainerRequest request);
        /// <summary>
        /// æ‰˜ç›˜è¿›ç«™ï¼ˆæ”¯æŒåŠ¨æ€Token)
        /// </summary>
        HttpResponseResult<MesResponse> InboundInContainer(InboundInContainerRequest request, string token);
        /// <summary>
        /// æ‰˜ç›˜å‡ºç«™
        /// </summary>
        HttpResponseResult<MesResponse> OutboundInContainer(OutboundInContainerRequest request);
        /// <summary>
        /// æ‰˜ç›˜å‡ºç«™ï¼ˆæ”¯æŒåŠ¨æ€Token)
        /// </summary>
        HttpResponseResult<MesResponse> OutboundInContainer(OutboundInContainerRequest request, string token);
    }
}
Code/WMS/WIDESEA_WMSServer/WIDESEA_IStockService/IStockService.cs
@@ -60,14 +60,16 @@
        /// æ‰¹é‡æ‹†ç›˜ç¡®è®¤ - ä¸€æ¬¡æ€§è°ƒç”¨MES解绑整个托盘
        /// </summary>
        /// <param name="palletCode">源托盘号</param>
        /// <param name="deviceName">设备名称(用于动态MES凭证查询)</param>
        /// <returns>操作结果</returns>
        Task<WebResponseContent> SplitPalletConfirmAsync(string palletCode);
        Task<WebResponseContent> SplitPalletConfirmAsync(string palletCode, string deviceName);
        /// <summary>
        /// æ‰¹é‡ç»„盘确认 - ä¸€æ¬¡æ€§è°ƒç”¨MES绑定整个托盘
        /// </summary>
        /// <param name="palletCode">目标托盘号</param>
        /// <param name="deviceName">设备名称(用于动态MES凭证查询)</param>
        /// <returns>操作结果</returns>
        Task<WebResponseContent> GroupPalletConfirmAsync(string palletCode);
        Task<WebResponseContent> GroupPalletConfirmAsync(string palletCode, string deviceName);
    }
}
Code/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Mes/Dt_MESDeviceConfig.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,49 @@
using SqlSugar;
using System;
using WIDESEA_Core.DB.Models;
namespace WIDESEA_Model.Models
{
    /// <summary>
    /// MES设备配置实体
    /// </summary>
    [SugarTable(nameof(Dt_MESDeviceConfig))]
    public class Dt_MESDeviceConfig : BaseEntity
    {
        /// <summary>
        /// ä¸»é”®ID,自增
        /// </summary>
        [SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnDescription = "主键ID")]
        public int Id { get; set; }
        /// <summary>
        /// è®¾å¤‡åç§°ï¼Œå¦‚"注液组盘机械手"
        /// </summary>
        [SugarColumn(Length = 50, IsNullable = false, ColumnDescription = "设备名称")]
        public string DeviceName { get; set; }
        /// <summary>
        /// MES设备编码,如"A02-YZHJJS-001"
        /// </summary>
        [SugarColumn(Length = 50, IsNullable = false, ColumnDescription = "MES设备编码")]
        public string EquipmentCode { get; set; }
        /// <summary>
        /// MES资源编码,如"ZY25091001"
        /// </summary>
        [SugarColumn(Length = 50, IsNullable = false, ColumnDescription = "MES资源编码")]
        public string ResourceCode { get; set; }
        /// <summary>
        /// MES API JWT令牌
        /// </summary>
        [SugarColumn(Length = 500, IsNullable = false, ColumnDescription = "MES API JWT令牌")]
        public string Token { get; set; }
        /// <summary>
        /// ä»“库编码,用于需要区分仓库的机械手(可为空)
        /// </summary>
        [SugarColumn(Length = 50, IsNullable = true, ColumnDescription = "仓库编码")]
        public string WarehouseCode { get; set; }
    }
}
Code/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Mes/Dt_MESDeviceConfig.sql
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
-- Dt_MESDeviceConfig SQL Script
-- å¯¹åº”实体 Dt_MESDeviceConfig,继承自 BaseEntity(包含 Creater, CreateDate, Modifier, ModifyDate)
DROP TABLE IF EXISTS Dt_MESDeviceConfig;
CREATE TABLE Dt_MESDeviceConfig (
    Id INT IDENTITY(1,1) PRIMARY KEY,
    DeviceName NVARCHAR(50) NOT NULL,
    EquipmentCode NVARCHAR(50) NOT NULL,
    ResourceCode NVARCHAR(50) NOT NULL,
    Token NVARCHAR(500) NOT NULL,
    WarehouseCode NVARCHAR(50) NULL,
    Creater NVARCHAR(50) NOT NULL,
    CreateDate DATETIME NOT NULL,
    Modifier NVARCHAR(50) NULL,
    ModifyDate DATETIME NULL
);
-- INSERT device configuration data
INSERT INTO Dt_MESDeviceConfig (DeviceName, EquipmentCode, ResourceCode, Token, WarehouseCode, Creater, CreateDate)
VALUES
(N'注液组盘机械手', N'A02-YZHJJS-001', N'ZY25091001', N'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEwODkyNjQ4MzYzODUzODI0MCIsIm5hbWUiOiLkuIDms6jlkI7mnLrmorDmiYsiLCJGYWN0b3J5SWQiOiI0Mjg3NDU2MTc3ODI1MzgyNCIsIlNpdGVJZCI6IjQyODc0NTYxNzc4MjUzODI0IiwiQ29kZSI6IkEwMi1ZWkhKSlMtMDAxIiwibmJmIjoxNzc2NDExODk0LCJleHAiOjIyMTc5MTU4OTQsImlzcyI6Imh0dHBzOi8vd3d3Lmh5bXNvbi5jb20iLCJhdWQiOiJodHRwczovL3d3dy5oeW1zb24uY29tIn0.HCBK-mq7zrbn6s335Ddn1ZwUffCXdFAmflgHFtOyOXg', NULL, N'Admin', GETDATE()),
(N'高温1换盘机械手', N'A02-GW1HJJS-001', N'ZY25091002', N'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEwODkyNjUxOTA3NDExNTU4NCIsIm5hbWUiOiLpq5jmuKkx5ZCO5py65qKw5omLIiwiRmFjdG9yeUlkIjoiNDI4NzQ1NjE3NzgyNTM4MjQiLCJTaXRlSWQiOiI0Mjg3NDU2MTc3ODI1MzgyNCIsIkNvZGUiOiJBMDItR1cxSEpKUy0wMDEiLCJuYmYiOjE3NzY0MTE5MDgsImV4cCI6MjIxNzkxNTkwOCwiaXNzIjoiaHR0cHM6Ly93d3cuaHltc29uLmNvbSIsImF1ZCI6Imh0dHBzOi8vd3d3Lmh5bXNvbi5jb20ifQ.A8frl5Txy6F3hCM2AuMbrPk_0x-rYmwjvL4a1RbxdeY', NULL, N'Admin', GETDATE()),
(N'化成换盘机械手', N'A02-HCHJJS-001', N'ZY25091003', N'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEwODkyNjU0ODk2NTg3MTYxNiIsIm5hbWUiOiLljJbmiJDlkI7mnLrmorDmiYvvvIjpq5jmuKky77yJIiwiRmFjdG9yeUlkIjoiNDI4NzQ1NjE3NzgyNTM4MjQiLCJTaXRlSWQiOiI0Mjg3NDU2MTc3ODI1MzgyNCIsIkNvZGUiOiJBMDItSENISkpTLTAwMSIsIm5iZiI6MTc3NjQxMTkxNiwiZXhwIjoyMjE3OTE1OTE2LCJpc3MiOiJodHRwczovL3d3dy5oeW1zb24uLmNvbSIsImF1ZCI6Imh0dHBzOi8vd3d3Lmh5bXNvbi5jb20ifQ.SHxbsdYoV2m4oUkaJauOBu4A-TfuX__J8-W-mqghg_A', NULL, N'Admin', GETDATE()),
(N'常温机械手', N'A02-CW1JJS-001', N'ZY25091004', N'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEwODkyNjU4MDA2ODczMjkyOCIsIm5hbWUiOiLluLjmuKkx5py65qKw5omLIiwiRmFjdG9yeUlkIjoiNDI4NzQ1NjE3NzgyNTM4MjQiLCJTaXRlSWQiOiI0Mjg3NDU2MTc3ODI1MzgyNCIsIkNvZGUiOiJBMDItQ1cxSkpTLTAwMSIsIm5iZiI6MTc3NjQxMTkyNCwiZXhwIjoyMjE3OTE1OTI0LCJpc3MiOiJodHRwczovL3d3dy5oeW1zb24uY29tIiwiYXVkIjoiaHR0cHM6Ly93d3cuaHltc29uLmNvbSJ9.CnBUKdmdSGURyW-YzW_JZvtP93o17zG2r5ZxHx867PQ', NULL, N'Admin', GETDATE()),
(N'成品组盘机械手', N'A02-EHJJS-001', N'ZY25091005', N'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEwODkyNjYwOTU1OTkzMjkyOCIsIm5hbWUiOiLkuozmrKHmsKbmo4DlkI7mnLrmorDmiYsiLCJGYWN0b3J5SWQiOiI0Mjg3NDU2MTc3ODI1MzgyNCIsIlNpdGVJZCI6IjQyODc0NTYxNzc4MjUzODI0IiwiQ29kZSI6IkEwMi1FSEpKUy0wMDEiLCJuYmYiOjE3NzY0MTE5MzIsImV4cCI6MjIxNzkxNTkzMiwiaXNzIjoiaHR0cHM6Ly93d3cuaHltc29uLmNvbSIsImF1ZCI6Imh0dHRwczovL3d3dy5oeW1zb24uY29tIn0.Imc2-8pDFrXgPrE_ro9Riasb8eGJ3Vi6gDyUDnUTpfY', NULL, N'Admin', GETDATE()),
(N'高温静置1', N'A02-GWJZ-001', N'ZY25030001', N'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEwNzU0NjM1MTU4NDY5NDI3MiIsIm5hbWUiOiLpq5jmuKnpnZnnva4xIiwiRmFjdG9yeUlkIjoiNDI4NzQ1NjE3NzgyNTM4MjQiLCJTaXRlSWQiOiI0Mjg3NDU2MTc3ODI1MzgyNCIsIkNvZGUiOiJBMDItR1dKWi0wMDEiLCJuYmYiOjE3NzUwOTkzMDEsImV4cCI6MjIxNjYwMzMwMSwiaXNzIjoiaHR0cHM6Ly93d3cuaHltc29uLmNvbSIsImF1ZCI6Imh0dHBzOi8vd3d3Lmh5bXNvbi5jb20ifQ.EI3Q6kHieKk5q4a6Nmf9fozi0haan0WuqkA9QNA-bHk', NULL, N'Admin', GETDATE()),
(N'高温静置2', N'A02-GWJZ-002', N'ZY25060001', N'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEwNzU0NjUxNTA0NTEwNTY2NCIsIm5hbWUiOiLpq5jmuKnpnZnnva4yIiwiRmFjdG9yeUlkIjoiNDI4NzQ1NjE3NzgyNTM4MjQiLCJTaXRlSWQiOiI0Mjg3NDU2MTc3ODI1MzgyNCIsIkNvZGUiOiJBMDItR1dKWi0wMDIiLCJuYmYiOjE3NzUwOTkzNDAsImV4cCI6MjIxNjYwMzM0MCwiaXNzIjoiaHR0cHM6Ly93d3cuaHltc29uLmNvbSIsImF1ZCI6Imh0dHBzOi8vd3d3Lmh5bXNvbi5jb20ifQ.imaa_1Xd9bHZKF3cy6c82Lb1ODXJC2MVytks4_eIyR4', NULL, N'Admin', GETDATE()),
(N'常温静置1', N'A02-CWJZ-001', N'ZY25070001', N'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEwNzU0NjU1ODU5OTgxMTA3MiIsIm5hbWUiOiLluLjmuKnpnZnnva4xIiwiRmFjdG9yeUlkIjoiNDI4NzQ1NjE3NzgyNTM4MjQiLCJTaXRlSWQiOiI0Mjg3NDU2MTc3ODI1MzgyNCIsIkNvZGUiOiJBMDItQ1dKWi0wMDEiLCJuYmYiOjE3NzUwOTkzNDgsImV4cCI6MjIxNjYwMzM0OCwiaXNzIjoiaHR0cHM6Ly93d3cuaHltc29uLmNvbSIsImF1ZCI6Imh0dHRzOi8vd3d3Lmh5bXNvbi5jb20ifQ.-WmBS4g4T0ZpJZ2qHszZMfe2pseMWCh6zyVeYgzsho4', NULL, N'Admin', GETDATE());
Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/MESDeviceConfigService.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,61 @@
using WIDESEA_Core;
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.BaseServices;
using WIDESEA_IBasicService;
using WIDESEA_Model.Models;
namespace WIDESEA_StockService
{
    /// <summary>
    /// MES设备配置服务实现类
    /// </summary>
    public class MESDeviceConfigService : ServiceBase<Dt_MESDeviceConfig, IRepository<Dt_MESDeviceConfig>>, IMESDeviceConfigService
    {
        /// <summary>
        /// èŽ·å–MES设备配置仓储接口
        /// </summary>
        public IRepository<Dt_MESDeviceConfig> Repository => BaseDal;
        /// <summary>
        /// æž„造函数
        /// </summary>
        /// <param name="baseDal">基础数据访问对象</param>
        public MESDeviceConfigService(IRepository<Dt_MESDeviceConfig> baseDal) : base(baseDal)
        {
        }
        /// <summary>
        /// æ ¹æ®è®¾å¤‡åç§°èŽ·å–MES设备配置(精确匹配)
        /// </summary>
        /// <param name="deviceName">设备名称</param>
        /// <returns>MES设备配置,如果未找到则返回null</returns>
        public Dt_MESDeviceConfig? GetByDeviceName(string deviceName)
        {
            if (string.IsNullOrWhiteSpace(deviceName))
            {
                return null;
            }
            return BaseDal.QueryFirst(x => x.DeviceName == deviceName);
        }
        /// <summary>
        /// æ ¹æ®è®¾å¤‡åç§°å’Œä»“库编码获取MES设备配置
        /// åŒ¹é…æ¡ä»¶ï¼šDeviceName精确匹配且(WarehouseCode为空或等于指定的仓库编码)
        /// </summary>
        /// <param name="deviceName">设备名称</param>
        /// <param name="warehouseCode">仓库编码</param>
        /// <returns>MES设备配置,如果未找到则返回null</returns>
        public Dt_MESDeviceConfig? GetByDeviceNameAndWarehouse(string deviceName, string warehouseCode)
        {
            if (string.IsNullOrWhiteSpace(deviceName))
            {
                return null;
            }
            return BaseDal.QueryFirst(x =>
                x.DeviceName == deviceName &&
                (string.IsNullOrEmpty(x.WarehouseCode) || x.WarehouseCode == warehouseCode));
        }
    }
}
Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs
@@ -392,8 +392,9 @@
        /// æ‰¹é‡æ‹†ç›˜ç¡®è®¤ - ä¸€æ¬¡æ€§è°ƒç”¨MES解绑整个托盘
        /// </summary>
        /// <param name="palletCode">源托盘号</param>
        /// <param name="deviceName">设备名称(用于动态MES凭证查询)</param>
        /// <returns>操作结果</returns>
        public async Task<WebResponseContent> SplitPalletConfirmAsync(string palletCode)
        public async Task<WebResponseContent> SplitPalletConfirmAsync(string palletCode, string deviceName)
        {
            WebResponseContent content = new WebResponseContent();
            try
@@ -412,22 +413,40 @@
                if (sfcList == null || !sfcList.Any())
                    return content.Error("临时表中电芯列表为空");
                // 2. è°ƒç”¨MES解绑
                // 2. èŽ·å–MES设备配置(动态凭证)
                string equipmentCode = StockConstants.MES_EQUIPMENT_CODE;
                string resourceCode = StockConstants.MES_RESOURCE_CODE;
                string token = null;
                if (!string.IsNullOrWhiteSpace(deviceName))
                {
                    var mesConfig = ResolveMesConfig(deviceName, palletCode);
                    if (mesConfig != null)
                    {
                        equipmentCode = mesConfig.EquipmentCode;
                        resourceCode = mesConfig.ResourceCode;
                        token = mesConfig.Token;
                    }
                }
                // 3. è°ƒç”¨MES解绑
                var unbindRequest = new UnBindContainerRequest
                {
                    EquipmentCode = StockConstants.MES_EQUIPMENT_CODE,
                    ResourceCode = StockConstants.MES_RESOURCE_CODE,
                    EquipmentCode = equipmentCode,
                    ResourceCode = resourceCode,
                    LocalTime = DateTime.Now,
                    ContainCode = palletCode,
                    SfcList = sfcList
                };
                var unbindResult = _mesService.UnBindContainer(unbindRequest);
                var unbindResult = string.IsNullOrWhiteSpace(token)
                    ? _mesService.UnBindContainer(unbindRequest)
                    : _mesService.UnBindContainer(unbindRequest, token);
                if (unbindResult == null || unbindResult.Data == null || !unbindResult.Data.IsSuccess)
                {
                    return content.Error($"MES解绑失败: {unbindResult?.Data?.Msg ?? unbindResult?.ErrorMessage ?? "未知错误"}");
                }
                // 3. åˆ é™¤ä¸´æ—¶è¡¨è®°å½•
                // 4. åˆ é™¤ä¸´æ—¶è¡¨è®°å½•
                await SqlSugarClient.Deleteable<Dt_SplitTemp>().Where(t => t.PalletCode == palletCode).ExecuteCommandAsync();
                return content.OK("批量拆盘确认成功");
@@ -442,8 +461,9 @@
        /// æ‰¹é‡ç»„盘确认 - ä¸€æ¬¡æ€§è°ƒç”¨MES绑定整个托盘
        /// </summary>
        /// <param name="palletCode">目标托盘号</param>
        /// <param name="deviceName">设备名称(用于动态MES凭证查询)</param>
        /// <returns>操作结果</returns>
        public async Task<WebResponseContent> GroupPalletConfirmAsync(string palletCode)
        public async Task<WebResponseContent> GroupPalletConfirmAsync(string palletCode, string deviceName)
        {
            WebResponseContent content = new WebResponseContent();
            try
@@ -460,12 +480,28 @@
                if (details == null || !details.Any())
                    return content.Error("托盘下无电芯数据");
                // 2. è°ƒç”¨MES绑定
                // 2. èŽ·å–MES设备配置(动态凭证)
                string equipmentCode = StockConstants.MES_EQUIPMENT_CODE;
                string resourceCode = StockConstants.MES_RESOURCE_CODE;
                string token = null;
                if (!string.IsNullOrWhiteSpace(deviceName))
                {
                    var mesConfig = ResolveMesConfig(deviceName, palletCode);
                    if (mesConfig != null)
                    {
                        equipmentCode = mesConfig.EquipmentCode;
                        resourceCode = mesConfig.ResourceCode;
                        token = mesConfig.Token;
                    }
                }
                // 3. è°ƒç”¨MES绑定
                var bindRequest = new BindContainerRequest
                {
                    ContainerCode = palletCode,
                    EquipmentCode = StockConstants.MES_EQUIPMENT_CODE,
                    ResourceCode = StockConstants.MES_RESOURCE_CODE,
                    EquipmentCode = equipmentCode,
                    ResourceCode = resourceCode,
                    LocalTime = DateTime.Now,
                    OperationType = StockConstants.MES_BIND_OPERATION_TYPE,
                    ContainerSfcList = details.Select(d => new ContainerSfcItem
@@ -474,7 +510,9 @@
                        Location = d.InboundOrderRowNo.ToString()
                    }).ToList()
                };
                var bindResult = _mesService.BindContainer(bindRequest);
                var bindResult = string.IsNullOrWhiteSpace(token)
                    ? _mesService.BindContainer(bindRequest)
                    : _mesService.BindContainer(bindRequest, token);
                if (bindResult == null || bindResult.Data == null || !bindResult.Data.IsSuccess)
                {
                    return content.Error($"MES绑定失败: {bindResult?.Data?.Msg ?? bindResult?.ErrorMessage ?? "未知错误"}");
@@ -487,5 +525,39 @@
                return content.Error($"批量组盘确认失败: {ex.Message}");
            }
        }
        /// <summary>
        /// æ ¹æ®è®¾å¤‡åç§°å’Œæ‰˜ç›˜å·è§£æžMES设备配置
        /// </summary>
        /// <param name="deviceName">设备名称</param>
        /// <param name="palletCode">托盘号(用于查询仓库编码)</param>
        /// <returns>MES设备配置,不存在时返回null</returns>
        private Dt_MESDeviceConfig ResolveMesConfig(string deviceName, string palletCode)
        {
            // æ¢ç›˜æœºæ¢°æ‰‹éœ€è¦åŒºåˆ†ä»“库
            if (deviceName.Contains("换盘"))
            {
                // æŸ¥è¯¢æ‰˜ç›˜å¯¹åº”的仓库编码
                var stockInfo = StockInfoService.Repository.QueryFirst(s => s.PalletCode == palletCode);
                if (stockInfo != null && stockInfo.WarehouseId > 0)
                {
                    var warehouse = _warehouseService.Repository.QureyDataById(stockInfo.WarehouseId);
                    if (warehouse != null && !string.IsNullOrWhiteSpace(warehouse.WarehouseCode))
                    {
                        // å…ˆæŒ‰è®¾å¤‡å+仓库编码查询
                        var config = SqlSugarClient.Queryable<Dt_MESDeviceConfig>()
                            .Where(c => c.DeviceName == deviceName && c.WarehouseCode == warehouse.WarehouseCode)
                            .First();
                        if (config != null)
                            return config;
                    }
                }
            }
            // æŒ‰è®¾å¤‡åç§°æŸ¥è¯¢ï¼ˆé€‚用于组盘机械手或换盘机械手未找到仓库匹配的情况)
            return SqlSugarClient.Queryable<Dt_MESDeviceConfig>()
                .Where(c => c.DeviceName == deviceName)
                .First();
        }
    }
}
Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
@@ -40,6 +40,7 @@
        private readonly IStockInfo_HtyService _stockInfo_HtyService;
        private readonly IUnitOfWorkManage _unitOfWorkManage;
        private readonly IRecordService _recordService;
        private readonly IMESDeviceConfigService _mesDeviceConfigService;
        public IRepository<Dt_Task> Repository => BaseDal;
@@ -64,7 +65,8 @@
            ITask_HtyService task_HtyService,
            IStockInfo_HtyService stockInfo_HtyService,
            IUnitOfWorkManage unitOfWorkManage,
            IRecordService recordService) : base(BaseDal)
            IRecordService recordService,
            IMESDeviceConfigService mesDeviceConfigService) : base(BaseDal)
        {
            _mapper = mapper;
            _stockInfoService = stockInfoService;
@@ -77,6 +79,7 @@
            _stockInfo_HtyService = stockInfo_HtyService;
            _unitOfWorkManage = unitOfWorkManage;
            _recordService = recordService;
            _mesDeviceConfigService = mesDeviceConfigService;
        }
        /// <summary>
Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Inbound.cs
@@ -6,6 +6,7 @@
using WIDESEA_Core;
using WIDESEA_DTO.MES;
using WIDESEA_DTO.Task;
using WIDESEA_IBasicService;
using WIDESEA_Model.Models;
namespace WIDESEA_TaskInfoService
@@ -150,19 +151,30 @@
                    var updateStockResult = await _stockInfoService.UpdateStockAsync(stockInfo);
                    if (!updateLocationResult || !updateStockResult)
                        return WebResponseContent.Instance.Error("任务完成失败");
                    // æ ¹æ®åº“å­˜Remark选择静置设备,查MES动态凭证
                    string deviceName = stockInfo.Remark == "GW_1" ? "高温静置1"
                        : stockInfo.Remark == "GW_2" ? "高温静置2"
                        : "常温静置1";
                    var mesConfig = _mesDeviceConfigService.GetByDeviceName(deviceName);
                    string equipmentCode = mesConfig?.EquipmentCode ?? StockConstants.MES_EQUIPMENT_CODE;
                    string resourceCode = mesConfig?.ResourceCode ?? StockConstants.MES_RESOURCE_CODE;
                    string token = mesConfig?.Token;
                    // è°ƒç”¨MES托盘进站
                    //var inboundRequest = new InboundInContainerRequest
                    //{
                    //    EquipmentCode = "STK-GROUP-001",
                    //    ResourceCode = "STK-GROUP-001",
                    //    LocalTime = DateTime.Now,
                    //    ContainerCode = taskDto.PalletCode
                    //};
                    //var inboundResult = _mesService.InboundInContainer(inboundRequest);
                    //if (inboundResult == null || inboundResult.Data == null || !inboundResult.Data.IsSuccess)
                    //{
                    //    return content.Error($"任务完成失败:MES进站失败: {inboundResult?.Data?.Msg ?? inboundResult?.ErrorMessage ?? "未知错误"}");
                    //}
                    var inboundRequest = new InboundInContainerRequest
                    {
                        EquipmentCode = equipmentCode,
                        ResourceCode = resourceCode,
                        LocalTime = DateTime.Now,
                        ContainerCode = taskDto.PalletCode
                    };
                    var inboundResult = string.IsNullOrWhiteSpace(token)
                        ? _mesService.InboundInContainer(inboundRequest)
                        : _mesService.InboundInContainer(inboundRequest, token);
                    if (inboundResult == null || inboundResult.Data == null || !inboundResult.Data.IsSuccess)
                    {
                        return content.Error($"任务完成失败:MES进站失败: {inboundResult?.Data?.Msg ?? inboundResult?.ErrorMessage ?? "未知错误"}");
                    }
                    return await CompleteTaskAsync(task, "入库完成");
                });
            }
Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Outbound.cs
@@ -4,7 +4,9 @@
using WIDESEA_Common.TaskEnum;
using WIDESEA_Common.WareHouseEnum;
using WIDESEA_Core;
using WIDESEA_DTO.MES;
using WIDESEA_DTO.Task;
using WIDESEA_IBasicService;
using WIDESEA_Model.Models;
namespace WIDESEA_TaskInfoService
@@ -117,6 +119,30 @@
                        inboundTaskDto = _mapper.Map<WMSTaskDTO>(inboundTask);
                    }
                    // è°ƒç”¨MES托盘出站
                    string deviceName = stockInfo.Remark == "GW_1" ? "高温静置1"
                        : stockInfo.Remark == "GW_2" ? "高温静置2"
                        : "常温静置1";
                    var mesConfig = _mesDeviceConfigService.GetByDeviceName(deviceName);
                    string equipmentCode = mesConfig?.EquipmentCode ?? StockConstants.MES_EQUIPMENT_CODE;
                    string resourceCode = mesConfig?.ResourceCode ?? StockConstants.MES_RESOURCE_CODE;
                    string token = mesConfig?.Token;
                    var outboundRequest = new OutboundInContainerRequest
                    {
                        EquipmentCode = equipmentCode,
                        ResourceCode = resourceCode,
                        LocalTime = DateTime.Now,
                        ContainerCode = taskDto.PalletCode
                    };
                    var outboundResult = string.IsNullOrWhiteSpace(token)
                        ? _mesService.OutboundInContainer(outboundRequest)
                        : _mesService.OutboundInContainer(outboundRequest, token);
                    if (outboundResult == null || outboundResult.Data == null || !outboundResult.Data.IsSuccess)
                    {
                        return content.Error($"出库完成失败:MES出站失败: {outboundResult?.Data?.Msg ?? outboundResult?.ErrorMessage ?? "未知错误"}");
                    }
                    var completeResult = await CompleteTaskAsync(task, "出库完成");
                    if (!completeResult.Status)
                        return completeResult;
Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockController.cs
@@ -72,7 +72,7 @@
        [HttpPost("SplitPalletConfirm"), AllowAnonymous]
        public async Task<WebResponseContent> SplitPalletConfirm([FromBody] SplitPalletConfirmRequestDto dto)
        {
            return await Service.SplitPalletConfirmAsync(dto.PalletCode);
            return await Service.SplitPalletConfirmAsync(dto.PalletCode, dto.DeviceName);
        }
        /// <summary>
@@ -83,7 +83,7 @@
        [HttpPost("GroupPalletConfirm"), AllowAnonymous]
        public async Task<WebResponseContent> GroupPalletConfirm([FromBody] GroupPalletConfirmRequestDto dto)
        {
            return await Service.GroupPalletConfirmAsync(dto.PalletCode);
            return await Service.GroupPalletConfirmAsync(dto.PalletCode, dto.DeviceName);
        }
    }
}
ÏîÄ¿×ÊÁÏ/É豸ЭÒé/ÉÏλϵͳ¶Ô½Ó/~$¸ßÎÂ2³£ÎÂ1¼°»úеÊÖÉ豸Õ˺ÅÐÅÏ¢±í(1).xlsx
Binary files differ
ÏîÄ¿×ÊÁÏ/É豸ЭÒé/ÉÏλϵͳ¶Ô½Ó/¸ßÎÂ2³£ÎÂ1¼°»úеÊÖÉ豸Õ˺ÅÐÅÏ¢±í(1).xlsx
Binary files differ