wanshenmean
3 小时以前 f423e1277f91427f0a767bd1224c1260dcb73086
feat: 添加空箱入库功能及相关优化

refactor(WCS): 重构机器人任务处理逻辑
fix(WCS): 修复机器人状态更新问题
feat(WCS): 添加NG线命令处理器
perf(WMS): 优化MES接口调用性能
style: 清理未使用的Vben客户端代码
chore: 更新数据库连接配置
已添加2个文件
已删除34个文件
已修改33个文件
6376 ■■■■■ 文件已修改
Code/.omc/state/last-tool-error.json 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/.omc/state/mission-state.json 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/.omc/state/subagent-tracking.json 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Client/src/views/taskinfo/robotState.vue 74 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/Constants/StackerCraneConst.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskEnumHelper.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskTypeEnum.cs 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Properties/PublishProfiles/FolderProfile.pubxml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoRepository/RobotStateRepository.cs 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/TaskService/TaskService.Query.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/CommonConveyorLineNewJob.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/ManualInbound/ManualInboundTaskHandler.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/IRobotMessageRouter.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/IRobotNgLineCommandHandler.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotMessageHandler.cs 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotNgLineCommandHandler.cs 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotPrefixCommandHandler.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotSimpleCommandHandler.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotWorkflowOrchestrator.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneCommandBuilder.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskSelector.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient/src/api/http.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient/src/extension/taskinfo/extend/addManualTask.vue 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient/src/extension/taskinfo/extend/gridBodyExtension.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/.env.development 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/index.html 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/package-lock.json 1929 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/package.json 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/pnpm-lock.yaml 1297 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/App.vue 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/api/auth.ts 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/api/client.ts 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/api/index.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/inbound.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/menu.ts 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/outbound.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/stock.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/user.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/layouts/MainLayout.vue 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/locales/zh-CN.ts 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/main.ts 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/router/index.ts 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/store/index.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/store/modules/menu.ts 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/store/user.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/utils/menuTransform.ts 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/views/dashboard/index.vue 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/views/inbound/inboundOrderDetail.vue 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/views/inbound/index.vue 275 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/views/login/index.vue 196 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/views/outbound/index.vue 267 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/views/outbound/outboundOrderDetail.vue 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/views/stock/index.vue 340 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/src/views/stock/stockInfoDetail.vue 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/tsconfig.json 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/tsconfig.node.json 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSClient_Vben/vite.config.ts 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/MesService.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Inbound.cs 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Manual.cs 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Outbound.cs 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/WMS/WMS_Api_Design.md 203 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Code/.omc/state/last-tool-error.json
@@ -1,7 +1,7 @@
{
  "tool_name": "Bash",
  "tool_input_preview": "{\"command\":\"cd \\\"D:/Git/ShanMeiXinNengYuan/Code/WMS\\\" && git clone --depth 1 https://ghproxy.com/https://github.com/vbenjs/vue-vben-admin.git WIDESEA_WMSClient_Vben 2>&1\",\"timeout\":300000,\"description...",
  "error": "Exit code 128\nCloning into 'WIDESEA_WMSClient_Vben'...\nfatal: unable to access 'https://ghproxy.com/https://github.com/vbenjs/vue-vben-admin.git/': Failed to connect to ghproxy.com port 443 after 21158 ms: Could not connect to server",
  "timestamp": "2026-04-19T13:54:19.051Z",
  "retry_count": 4
  "tool_name": "Read",
  "tool_input_preview": "{\"file_path\":\"D:\\\\Git\\\\ShanMeiXinNengYuan\\\\Code\\\\WMS\\\\WIDESEA_WMSClient_Vben_v2\\\\apps\\\\web-ele\\\\src\\\\views\\\\dashboard\\\\index.vue\"}",
  "error": "File does not exist. Note: your current working directory is D:\\Git\\ShanMeiXinNengYuan\\Code.",
  "timestamp": "2026-04-20T01:28:36.836Z",
  "retry_count": 1
}
Code/.omc/state/mission-state.json
@@ -1,5 +1,5 @@
{
  "updatedAt": "2026-04-19T13:53:57.853Z",
  "updatedAt": "2026-04-20T02:13:36.765Z",
  "missions": [
    {
      "id": "session:9007b9ea-1eb6-4d24-8fe7-2c3a949eac88:none",
@@ -1798,6 +1798,172 @@
          "sourceKey": "session-stop:ad92b7876bc72bf7e"
        }
      ]
    },
    {
      "id": "session:ab8c4305-0c84-43a9-bd5d-b68d5471801b:none",
      "source": "session",
      "name": "none",
      "objective": "Session mission",
      "createdAt": "2026-04-20T01:18:33.678Z",
      "updatedAt": "2026-04-20T02:13:36.765Z",
      "status": "done",
      "workerCount": 8,
      "taskCounts": {
        "total": 8,
        "pending": 0,
        "blocked": 0,
        "inProgress": 0,
        "completed": 8,
        "failed": 0
      },
      "agents": [
        {
          "name": "general-purpose:af20345",
          "role": "general-purpose",
          "ownership": "af20345f5b7efdbb8",
          "status": "done",
          "currentStep": null,
          "latestUpdate": "completed",
          "completedSummary": null,
          "updatedAt": "2026-04-20T02:13:36.765Z"
        },
        {
          "name": "general-purpose:a9cc35c",
          "role": "general-purpose",
          "ownership": "a9cc35c00ad32b233",
          "status": "done",
          "currentStep": null,
          "latestUpdate": "completed",
          "completedSummary": null,
          "updatedAt": "2026-04-20T01:21:33.668Z"
        },
        {
          "name": "general-purpose:a3499a6",
          "role": "general-purpose",
          "ownership": "a3499a67931cba616",
          "status": "done",
          "currentStep": null,
          "latestUpdate": "completed",
          "completedSummary": null,
          "updatedAt": "2026-04-20T01:21:25.687Z"
        },
        {
          "name": "general-purpose:addde47",
          "role": "general-purpose",
          "ownership": "addde47ba39361d9d",
          "status": "done",
          "currentStep": null,
          "latestUpdate": "completed",
          "completedSummary": null,
          "updatedAt": "2026-04-20T01:34:11.276Z"
        },
        {
          "name": "general-purpose:a883f88",
          "role": "general-purpose",
          "ownership": "a883f88b2839bb064",
          "status": "done",
          "currentStep": null,
          "latestUpdate": "completed",
          "completedSummary": null,
          "updatedAt": "2026-04-20T02:09:43.301Z"
        },
        {
          "name": "general-purpose:a1cccc1",
          "role": "general-purpose",
          "ownership": "a1cccc11f34b62da4",
          "status": "done",
          "currentStep": null,
          "latestUpdate": "completed",
          "completedSummary": null,
          "updatedAt": "2026-04-20T02:09:46.017Z"
        },
        {
          "name": "general-purpose:a85bc7a",
          "role": "general-purpose",
          "ownership": "a85bc7aac2726a6fa",
          "status": "done",
          "currentStep": null,
          "latestUpdate": "completed",
          "completedSummary": null,
          "updatedAt": "2026-04-20T02:10:09.142Z"
        },
        {
          "name": "general-purpose:a921902",
          "role": "general-purpose",
          "ownership": "a9219020fa6ba0ef0",
          "status": "done",
          "currentStep": null,
          "latestUpdate": "completed",
          "completedSummary": null,
          "updatedAt": "2026-04-20T02:08:23.745Z"
        }
      ],
      "timeline": [
        {
          "id": "session-start:a1cccc11f34b62da4:2026-04-20T02:07:02.639Z",
          "at": "2026-04-20T02:07:02.639Z",
          "kind": "update",
          "agent": "general-purpose:a1cccc1",
          "detail": "started general-purpose:a1cccc1",
          "sourceKey": "session-start:a1cccc11f34b62da4"
        },
        {
          "id": "session-start:a85bc7aac2726a6fa:2026-04-20T02:07:02.655Z",
          "at": "2026-04-20T02:07:02.655Z",
          "kind": "update",
          "agent": "general-purpose:a85bc7a",
          "detail": "started general-purpose:a85bc7a",
          "sourceKey": "session-start:a85bc7aac2726a6fa"
        },
        {
          "id": "session-start:a9219020fa6ba0ef0:2026-04-20T02:07:02.700Z",
          "at": "2026-04-20T02:07:02.700Z",
          "kind": "update",
          "agent": "general-purpose:a921902",
          "detail": "started general-purpose:a921902",
          "sourceKey": "session-start:a9219020fa6ba0ef0"
        },
        {
          "id": "session-stop:a9219020fa6ba0ef0:2026-04-20T02:08:23.745Z",
          "at": "2026-04-20T02:08:23.745Z",
          "kind": "completion",
          "agent": "general-purpose:a921902",
          "detail": "completed",
          "sourceKey": "session-stop:a9219020fa6ba0ef0"
        },
        {
          "id": "session-stop:a883f88b2839bb064:2026-04-20T02:09:43.301Z",
          "at": "2026-04-20T02:09:43.301Z",
          "kind": "completion",
          "agent": "general-purpose:a883f88",
          "detail": "completed",
          "sourceKey": "session-stop:a883f88b2839bb064"
        },
        {
          "id": "session-stop:a1cccc11f34b62da4:2026-04-20T02:09:46.017Z",
          "at": "2026-04-20T02:09:46.017Z",
          "kind": "completion",
          "agent": "general-purpose:a1cccc1",
          "detail": "completed",
          "sourceKey": "session-stop:a1cccc11f34b62da4"
        },
        {
          "id": "session-stop:a85bc7aac2726a6fa:2026-04-20T02:10:09.142Z",
          "at": "2026-04-20T02:10:09.142Z",
          "kind": "completion",
          "agent": "general-purpose:a85bc7a",
          "detail": "completed",
          "sourceKey": "session-stop:a85bc7aac2726a6fa"
        },
        {
          "id": "session-stop:a6eae12446c31bdfe:2026-04-20T02:13:36.765Z",
          "at": "2026-04-20T02:13:36.765Z",
          "kind": "completion",
          "agent": "general-purpose:af20345",
          "detail": "completed",
          "sourceKey": "session-stop:a6eae12446c31bdfe"
        }
      ]
    }
  ]
}
Code/.omc/state/subagent-tracking.json
@@ -1112,10 +1112,82 @@
      "status": "completed",
      "completed_at": "2026-04-19T13:53:49.216Z",
      "duration_ms": 5697
    },
    {
      "agent_id": "af20345f5b7efdbb8",
      "agent_type": "general-purpose",
      "started_at": "2026-04-20T01:18:33.678Z",
      "parent_mode": "none",
      "status": "completed",
      "completed_at": "2026-04-20T01:20:19.477Z",
      "duration_ms": 105799
    },
    {
      "agent_id": "a9cc35c00ad32b233",
      "agent_type": "general-purpose",
      "started_at": "2026-04-20T01:18:33.716Z",
      "parent_mode": "none",
      "status": "completed",
      "completed_at": "2026-04-20T01:21:33.665Z",
      "duration_ms": 179949
    },
    {
      "agent_id": "a3499a67931cba616",
      "agent_type": "general-purpose",
      "started_at": "2026-04-20T01:18:33.755Z",
      "parent_mode": "none",
      "status": "completed",
      "completed_at": "2026-04-20T01:21:25.686Z",
      "duration_ms": 171931
    },
    {
      "agent_id": "addde47ba39361d9d",
      "agent_type": "general-purpose",
      "started_at": "2026-04-20T01:27:42.165Z",
      "parent_mode": "none",
      "status": "completed",
      "completed_at": "2026-04-20T01:34:11.275Z",
      "duration_ms": 389110
    },
    {
      "agent_id": "a883f88b2839bb064",
      "agent_type": "general-purpose",
      "started_at": "2026-04-20T02:07:02.615Z",
      "parent_mode": "none",
      "status": "completed",
      "completed_at": "2026-04-20T02:09:43.299Z",
      "duration_ms": 160684
    },
    {
      "agent_id": "a1cccc11f34b62da4",
      "agent_type": "general-purpose",
      "started_at": "2026-04-20T02:07:02.639Z",
      "parent_mode": "none",
      "status": "completed",
      "completed_at": "2026-04-20T02:09:46.016Z",
      "duration_ms": 163377
    },
    {
      "agent_id": "a85bc7aac2726a6fa",
      "agent_type": "general-purpose",
      "started_at": "2026-04-20T02:07:02.655Z",
      "parent_mode": "none",
      "status": "completed",
      "completed_at": "2026-04-20T02:10:09.140Z",
      "duration_ms": 186485
    },
    {
      "agent_id": "a9219020fa6ba0ef0",
      "agent_type": "general-purpose",
      "started_at": "2026-04-20T02:07:02.700Z",
      "parent_mode": "none",
      "status": "completed",
      "completed_at": "2026-04-20T02:08:23.744Z",
      "duration_ms": 81044
    }
  ],
  "total_spawned": 115,
  "total_completed": 119,
  "total_spawned": 118,
  "total_completed": 127,
  "total_failed": 0,
  "last_updated": "2026-04-19T13:53:57.967Z"
  "last_updated": "2026-04-20T02:13:36.867Z"
}
Code/WCS/WIDESEAWCS_Client/src/views/taskinfo/robotState.vue
@@ -52,13 +52,13 @@
    // ç¼–辑表单配置
    const editFormOptions = ref([
      [
        { title: "IP地址", field: "IPAddress", type: "string", readonly: true },
        { title: "版本号", field: "Version", type: "int", readonly: true },
        { title: "IP地址", field: "ipAddress", type: "string", readonly: true },
        { title: "版本号", field: "version", type: "int", readonly: true },
      ],
      [
        {
          title: "运行模式",
          field: "RobotRunMode",
          field: "robotRunMode",
          type: "select",
          data: [
            { key: 1, value: "手动模式" },
@@ -67,7 +67,7 @@
        },
        {
          title: "控制模式",
          field: "RobotControlMode",
          field: "robotControlMode",
          type: "select",
          data: [
            { key: 1, value: "客户端控制" },
@@ -76,7 +76,7 @@
        },
        {
          title: "手臂状态",
          field: "RobotArmObject",
          field: "robotArmObject",
          type: "select",
          data: [
            { key: 0, value: "空闲" },
@@ -85,46 +85,46 @@
        },
      ],
      [
        { title: "回零状态", field: "Homed", type: "string" },
        { title: "当前动作", field: "CurrentAction", type: "string" },
        { title: "运行状态", field: "OperStatus", type: "string" },
        { title: "回零状态", field: "homed", type: "string" },
        { title: "当前动作", field: "currentAction", type: "string" },
        { title: "运行状态", field: "operStatus", type: "string" },
      ],
      [
        { title: "任务总数", field: "RobotTaskTotalNum", type: "int" },
        { title: "当前批次", field: "CurrentBatchIndex", type: "int" },
        { title: "换盘阶段", field: "ChangePalletPhase", type: "int" },
        { title: "任务总数", field: "robotTaskTotalNum", type: "int" },
        { title: "当前批次", field: "currentBatchIndex", type: "int" },
        { title: "换盘阶段", field: "changePalletPhase", type: "int" },
      ],
      [
        {
          title: "是否拆盘",
          field: "IsSplitPallet",
          field: "isSplitPallet",
          type: "checkbox",
        },
        {
          title: "是否组盘",
          field: "IsGroupPallet",
          field: "isGroupPallet",
          type: "checkbox",
        },
        {
          title: "假电芯模式",
          field: "IsInFakeBatteryMode",
          field: "isInFakeBatteryMode",
          type: "checkbox",
        },
      ],
      [
        {
          title: "是否扫码NG",
          field: "IsScanNG",
          field: "isScanNG",
          type: "checkbox",
        },
        {
          title: "电芯是否到位",
          field: "BatteryArrived",
          field: "batteryArrived",
          type: "checkbox",
        },
        {
          title: "消息已订阅",
          field: "IsEventSubscribed",
          field: "isEventSubscribed",
          type: "checkbox",
        },
      ],
@@ -140,31 +140,31 @@
    // æœç´¢è¡¨å•配置
    const searchFormOptions = ref([
      [
        { title: "IP地址", field: "IPAddress", type: "string" },
        { title: "当前动作", field: "CurrentAction", type: "string" },
        { title: "运行状态", field: "OperStatus", type: "string" },
        { title: "IP地址", field: "ipAddress", type: "string" },
        { title: "当前动作", field: "currentAction", type: "string" },
        { title: "运行状态", field: "operStatus", type: "string" },
      ],
    ]);
    // åˆ—定义
    const columns = ref([
      { field: "IPAddress", title: "IP地址", type: "string", width: 140, align: "left" },
      { field: "Version", title: "版本", type: "int", width: 80, align: "left" },
      { field: "RobotRunMode", title: "运行模式", type: "int", width: 100, bind: { key: "robotRunMode", data: [] }, align: "center" },
      { field: "RobotControlMode", title: "控制模式", type: "int", width: 100, bind: { key: "robotControlMode", data: [] }, align: "center" },
      { field: "RobotArmObject", title: "手臂状态", type: "int", width: 90, bind: { key: "robotArmObject", data: [] }, align: "center" },
      { field: "Homed", title: "回零状态", type: "string", width: 100, align: "center" },
      { field: "CurrentAction", title: "当前动作", type: "string", width: 100, align: "center" },
      { field: "OperStatus", title: "运行状态", type: "string", width: 100, align: "center" },
      { field: "RobotTaskTotalNum", title: "任务总数", type: "int", width: 90, align: "center" },
      { field: "IsSplitPallet", title: "拆盘", type: "byte", width: 60, align: "center" },
      { field: "IsGroupPallet", title: "组盘", type: "byte", width: 60, align: "center" },
      { field: "IsInFakeBatteryMode", title: "假电芯", type: "byte", width: 70, align: "center" },
      { field: "CurrentBatchIndex", title: "批次", type: "int", width: 60, align: "center" },
      { field: "ChangePalletPhase", title: "换盘阶段", type: "int", width: 80, align: "center" },
      { field: "IsScanNG", title: "扫码NG", type: "byte", width: 80, align: "center" },
      { field: "BatteryArrived", title: "电芯到位", type: "byte", width: 80, align: "center" },
      { field: "IsEventSubscribed", title: "已订阅", type: "byte", width: 70, align: "center" },
      { field: "ipAddress", title: "IP地址", type: "string", width: 140, align: "left" },
      { field: "version", title: "版本", type: "int", width: 80, align: "left" },
      { field: "robotRunMode", title: "运行模式", type: "int", width: 100, bind: { key: "robotRunMode", data: [{ key: 1, value: "手动模式" },{ key: 2, value: "自动模式" }] }, align: "center" },
      { field: "robotControlMode", title: "控制模式", type: "int", width: 100, bind: { key: "robotControlMode", data: [{ key: 1, value: "客户端控制" },{ key: 2, value: "其他" }] }, align: "center" },
      { field: "robotArmObject", title: "手臂状态", type: "int", width: 90, bind: { key: "robotArmObject", data: [{ key: 0, value: "空闲"}, { key: 1, value: "有物料" }] }, align: "center" },
      { field: "homed", title: "回零状态", type: "string", width: 100, align: "center" },
      { field: "currentAction", title: "当前动作", type: "string", width: 100, align: "center" },
      { field: "operStatus", title: "运行状态", type: "string", width: 100, align: "center" },
      { field: "robotTaskTotalNum", title: "任务总数", type: "int", width: 90, align: "center" },
      { field: "isSplitPallet", title: "拆盘", type: "byte", width: 60, align: "center" },
      { field: "isGroupPallet", title: "组盘", type: "byte", width: 60, align: "center" },
      { field: "isInFakeBatteryMode", title: "假电芯", type: "byte", width: 70, align: "center" },
      { field: "currentBatchIndex", title: "批次", type: "int", width: 60, align: "center" },
      { field: "changePalletPhase", title: "换盘阶段", type: "int", width: 80, align: "center" },
      { field: "isScanNG", title: "扫码NG", type: "byte", width: 80, align: "center" },
      { field: "batteryArrived", title: "电芯到位", type: "byte", width: 80, align: "center" },
      { field: "isEventSubscribed", title: "已订阅", type: "byte", width: 70, align: "center" },
    ]);
    const detail = ref({});
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/Constants/StackerCraneConst.cs
@@ -15,6 +15,15 @@
        public const int EmptyPalletTaskType = 100;
        /// <summary>
        /// ç©ºæ‰˜ç›˜ä»»åŠ¡ç±»åž‹
        /// </summary>
        /// <remarks>
        /// å½“任务类型为空托盘出库/入库时,使用此特殊类型值代替原任务类型。
        /// ç”¨äºŽä¸Žç«™å°è·¯ç”±é…ç½®åŒ¹é…ã€‚
        /// </remarks>
        public const int EmptyInPalletTaskType = 200;
        /// <summary>
        /// ç«è­¦çŠ¶æ€æ­£å¸¸
        /// </summary>
        /// <remarks>
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskEnumHelper.cs
@@ -32,7 +32,7 @@
                return TaskTypeGroup.OutbondGroup;
            }
            // å°è¯•将任务类型转换为TaskInStatusEnum枚举类型,如果成功,返回InboundGroup
            else if (!int.TryParse(Enum.Parse<TaskInStatusEnum>(taskTypeStr).ToString(), out result))
            else if (!int.TryParse(Enum.Parse<TaskInboundTypeEnum>(taskTypeStr).ToString(), out result))
            {
                return TaskTypeGroup.InboundGroup;
            }
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskTypeEnum.cs
@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
namespace WIDESEAWCS_Common.TaskEnum
{
@@ -14,16 +9,19 @@
        /// </summary>
        [Description("入库")]
        Inbound = 200,
        /// <summary>
        /// ç›˜ç‚¹å…¥åº“
        /// </summary>
        [Description("盘点入库")]
        InInventory = 201,
        /// <summary>
        /// åˆ†æ‹£å…¥åº“
        /// </summary>
        [Description("分拣入库")]
        InPick = 202,
        /// <summary>
        /// è´¨æ£€å…¥åº“
        /// </summary>
@@ -34,7 +32,7 @@
        /// ç©ºç®±å…¥åº“
        /// </summary>
        [Description("空箱入库")]
        InEmpty = 600,
        InEmpty = 204,
    }
    public enum TaskOutboundTypeEnum
@@ -44,16 +42,19 @@
        /// </summary>
        [Description("出库")]
        Outbound = 100,
        /// <summary>
        /// ç›˜ç‚¹å‡ºåº“
        /// </summary>
        [Description("盘点出库")]
        OutInventory = 101,
        /// <summary>
        /// åˆ†æ‹£å‡ºåº“
        /// </summary>
        [Description("分拣出库")]
        OutPick = 102,
        /// <summary>
        /// è´¨æ£€å‡ºåº“
        /// </summary>
@@ -74,6 +75,7 @@
        /// </summary>
        [Description("库内移库")]
        Relocation = 300,
        /// <summary>
        /// åº“外移库
        /// </summary>
@@ -118,16 +120,19 @@
        /// </summary>
        [Description("领料出库")]
        Outbound = 100,
        /// <summary>
        /// ç›˜ç‚¹å‡ºåº“
        /// </summary>
        [Description("盘点出库")]
        OutInventory = 110,
        /// <summary>
        /// åˆ†æ‹£å‡ºåº“
        /// </summary>
        [Description("分拣出库")]
        OutPick = 120,
        /// <summary>
        /// è´¨æ£€å‡ºåº“
        /// </summary>
@@ -163,16 +168,19 @@
        /// </summary>
        [Description("采购入库")]
        Inbound = 510,
        /// <summary>
        /// ç›˜ç‚¹å…¥åº“
        /// </summary>
        [Description("盘点入库")]
        InInventory = 520,
        /// <summary>
        /// åˆ†æ‹£å…¥åº“
        /// </summary>
        [Description("分拣入库")]
        InPick = 530,
        /// <summary>
        /// è´¨æ£€å…¥åº“
        /// </summary>
@@ -202,6 +210,5 @@
        /// </summary>
        [Description("巷道内移库")]
        Relocation = 900
    }
}
}
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Properties/PublishProfiles/FolderProfile.pubxml
@@ -4,13 +4,13 @@
-->
<Project>
  <PropertyGroup>
    <DeleteExistingFiles>true</DeleteExistingFiles>
    <DeleteExistingFiles>false</DeleteExistingFiles>
    <ExcludeApp_Data>false</ExcludeApp_Data>
    <LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
    <LastUsedBuildConfiguration>Debug</LastUsedBuildConfiguration>
    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <PublishProvider>FileSystem</PublishProvider>
    <PublishUrl>bin\Debug\net6.0\publish\</PublishUrl>
    <PublishUrl>E:\IISText\HuanAn\WCS</PublishUrl>
    <WebPublishMethod>FileSystem</WebPublishMethod>
    <_TargetId>Folder</_TargetId>
    <SiteUrlToLaunchAfterPublish />
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json
@@ -32,7 +32,7 @@
  //5.PostgreSQL
  "DBType": "SqlServer",
  //连接字符串
  "ConnectionString": "Data Source=.;Initial Catalog=WIDESEAWCS_ShanMei;User ID=sa;Password=P@ssw0rd;Integrated Security=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
  "ConnectionString": "Data Source=192.168.60.30;Initial Catalog=WIDESEAWCS_ShanMei;User ID=sa;Password=P@ssw0rd;Integrated Security=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
  //"ConnectionString": "Data Source=.;Initial Catalog=WIDESEAWCS_ShanMei;User ID=sa;Password=123456;Integrated Security=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
  //跨域
@@ -54,7 +54,7 @@
  "ApiName": "WIDESEAWCS",
  "ExpMinutes": 120,
  "QuartzJobAutoStart": true,
  "DBSeedEnable": true,
  "DBSeedEnable": false,
  "QuartzDBSeedEnable": false,
  "LogDeubgEnable": false, //是否记录调试日志
  "PrintSql": false, //打印SQL语句
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoRepository/RobotStateRepository.cs
@@ -1,6 +1,7 @@
using Newtonsoft.Json;
using SqlSugar;
using WIDESEAWCS_Core.BaseRepository;
using WIDESEAWCS_Core.Helper;
using WIDESEAWCS_ITaskInfoRepository;
using WIDESEAWCS_Model.Models;
@@ -49,7 +50,7 @@
            // ä¹è§‚锁:WHERE IPAddress = @ip AND Version = @expectedVersion,版本匹配才更新
            var affectedRows = Db.Updateable<Dt_RobotState>(newState)
                .Where(x => x.IPAddress == ipAddress && x.Version == expectedVersion)
                .Where(x => x.IPAddress == ipAddress)
                .ExecuteCommand();
            return affectedRows > 0;
@@ -126,7 +127,11 @@
                CurrentBatchIndex = state.CurrentBatchIndex,
                ChangePalletPhase = state.ChangePalletPhase,
                IsScanNG = state.IsScanNG,
                BatteryArrived = state.BatteryArrived
                BatteryArrived = state.BatteryArrived,
                CellBarcodeJson = state.CellBarcode.ToJson(),
                LastPickPositionsJson = state.LastPickPositions.ToJson(),
                CurrentTaskJson = state.CurrentTask.ToJson(),
                LastPutPositionsJson = state.LastPutPositions.ToJson(),
            };
            // åºåˆ—化复杂对象为 JSON
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/TaskService/TaskService.Query.cs
@@ -149,7 +149,7 @@
    public Dt_Task QueryManualInboundTask(string sourceAddress)
    {
        return BaseDal.QueryFirst(x =>
            x.TaskType == (int)TaskInboundTypeEnum.Inbound &&
            (x.TaskType == (int)TaskInboundTypeEnum.Inbound || x.TaskType == (int)TaskInboundTypeEnum.InEmpty) &&
            x.TaskStatus == (int)TaskInStatusEnum.InNew &&
            x.SourceAddress == sourceAddress);
    }
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/CommonConveyorLineNewJob.cs
@@ -188,7 +188,7 @@
                                    {
                                        // æ²¡æœ‰ä»»åŠ¡ï¼Œå‘ WMS è¯·æ±‚出库托盘任务
                                        var position = checkPalletPositions.FirstOrDefault(x => x.Code == childDeviceCode);
                                        QuartzLogHelper.LogInfo(_logger, "Execute:检查托盘位置 {ChildDeviceCode},请求WMS出库托盘任务", $"检查托盘位置 {childDeviceCode},请求WMS出库托盘任务", conveyorLine.DeviceCode, childDeviceCode);
                                        //QuartzLogHelper.LogInfo(_logger, "Execute:检查托盘位置 {ChildDeviceCode},请求WMS出库托盘任务", $"检查托盘位置 {childDeviceCode},请求WMS出库托盘任务", conveyorLine.DeviceCode, childDeviceCode);
                                        var responseResult = _httpClientHelper.Post<WebResponseContent>("GetOutBoundTrayTaskAsync", new CreateTaskDto()
                                        {
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineNewJob/ManualInbound/ManualInboundTaskHandler.cs
@@ -50,6 +50,8 @@
                conveyorLine.SetValue(ConveyorLineDBNameNew.Source, short.Parse(task.SourceAddress ?? "0"), childDeviceCode);
                // å†™å…¥ç›®æ ‡åœ°å€
                conveyorLine.SetValue(ConveyorLineDBNameNew.Target, short.Parse(task.NextAddress ?? "0"), childDeviceCode);
                // å†™å…¥æ‰˜ç›˜å·
                conveyorLine.SetValue(ConveyorLineDBNameNew.Barcode, task.PalletCode, childDeviceCode);
                // æ›´æ–°ä»»åŠ¡çŠ¶æ€åˆ°ä¸‹ä¸€é˜¶æ®µ
                var updateResult = _taskService.UpdateTaskStatusToNext(task);
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/IRobotMessageRouter.cs
@@ -16,6 +16,6 @@
        /// <param name="client">TCP å®¢æˆ·ç«¯è¿žæŽ¥</param>
        /// <param name="state">机器人当前状态</param>
        /// <returns>响应消息,如果无需回复则返回 null</returns>
        Task<string?> HandleMessageReceivedAsync(string message, bool isJson, TcpClient client, RobotSocketState state);
        Task<string?> HandleMessageReceivedAsync(string message, bool isJson, TcpClient client);
    }
}
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/IRobotNgLineCommandHandler.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,9 @@
using WIDESEAWCS_Model.Models;
namespace WIDESEAWCS_Tasks.Workflow.Abstractions
{
    public interface IRobotNgLineCommandHandler
    {
        Task<bool> HandleAsync(string message, RobotSocketState state);
    }
}
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotMessageHandler.cs
@@ -88,8 +88,14 @@
        /// <param name="client">TCP å®¢æˆ·ç«¯è¿žæŽ¥</param>
        /// <param name="state">机器人当前状态</param>
        /// <returns>响应消息,如果无需回复则返回 null</returns>
        public async Task<string?> HandleMessageReceivedAsync(string message, bool isJson, TcpClient client, RobotSocketState state)
        public async Task<string?> HandleMessageReceivedAsync(string message, bool isJson, TcpClient client)
        {
            var state = _stateManager.GetState(client.Client.RemoteEndPoint.ToString());
            if(state.OperStatus == message)
            {
                // å¤„理成功后,将原消息回写到客户端(保持原有行为)
                await _socketClientGateway.SendMessageAsync(client, message);
            }
            // è®°å½•接收到的消息日志
            _logger.LogInformation($"接收到客户端【{state.RobotCrane?.DeviceName}】发送消息【{message}】");
            QuartzLogger.Info($"接收到客户端消息【{message}】", state.RobotCrane?.DeviceName);
@@ -110,9 +116,12 @@
            // ç®€å•命令包括:homing、homed、running、pausing、runmode、controlmode ç­‰
            if (await _simpleCommandHandler.HandleAsync(messageLower, state))
            {
                // å¤„理成功后,将原消息回写到客户端(保持原有行为)
                await _socketClientGateway.SendMessageAsync(client, message);
                QuartzLogger.Info($"发送消息:【{message}】", state.RobotCrane?.DeviceName);
                if(messageLower != "batteryarrived")
                {
                    // å¤„理成功后,将原消息回写到客户端(保持原有行为)
                    await _socketClientGateway.SendMessageAsync(client, message);
                    QuartzLogger.Info($"发送消息:【{message}】", state.RobotCrane?.DeviceName);
                }
                // å®‰å…¨æ›´æ–°çŠ¶æ€åˆ°æ•°æ®åº“
                _stateManager.TryUpdateStateSafely(state.IPAddress, state);
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotTaskProcessor.cs
@@ -632,7 +632,7 @@
            //    }
            //}
            return false;
            return true;
        }
        /// <summary>
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotNgLineCommandHandler.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_Tasks.Workflow.Abstractions;
namespace WIDESEAWCS_Tasks.Workflow
{
    public class RobotNgLineCommandHandler : IRobotNgLineCommandHandler
    {
        public Task<bool> HandleAsync(string message, RobotSocketState state)
        {
            // ä½¿ç”¨ switch è¡¨è¾¾å¼è¿›è¡Œæ¨¡å¼åŒ¹é…ï¼Œæé«˜å¯è¯»æ€§å’Œæ€§èƒ½
            switch (message)
            {
                case "PutNGFinished1":
                    return Task.FromResult(true);
                case "PutNGFinished2":
                    return Task.FromResult(true);
                case "PickNGFinished1":
                    return Task.FromResult(true);
                case "PickNGFinished2":
                    return Task.FromResult(true);
                default:
                    return Task.FromResult(true);
            }
        }
    }
}
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotPrefixCommandHandler.cs
@@ -126,7 +126,7 @@
                var parts = message.Split(',');
                // æ£€æŸ¥æ¶ˆæ¯æ ¼å¼æ˜¯å¦æœ‰æ•ˆï¼šè‡³å°‘要有命令前缀,且状态中有当前任务
                if (parts.Length < 1 || state.CurrentTask == null)
                if (parts.Length < 1)
                {
                    return;
                }
@@ -143,7 +143,7 @@
                    .ToArray();
                // ä»Žæ•°æ®åº“重新查询当前任务(确保获取最新状态)
                var task = await _robotTaskService.Repository.QueryFirstAsync(x => x.RobotTaskId == state.CurrentTask.RobotTaskId);
                var task = await _robotTaskService.Repository.QueryFirstAsync(x => x.RobotTaskState == TaskRobotStatusEnum.RobotExecuting.GetHashCode() && x.RobotRoadway == state.RobotCrane.DeviceName);
                if (task != null)
                {
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotSimpleCommandHandler.cs
@@ -125,6 +125,11 @@
                    state.BatteryArrived = true;
                    return true;
                // æ˜¯å¦ç”µèŠ¯åˆ°ä½
                case "batteryarrivedno":
                    state.BatteryArrived = false;
                    return true;
                // ==================== å…¨éƒ¨å®Œæˆå‘½ä»¤ ====================
                // å…¨éƒ¨å–货完成
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotWorkflowOrchestrator.cs
@@ -112,7 +112,7 @@
            // 1. è¿è¡Œæ¨¡å¼ä¸ºè‡ªåŠ¨ï¼ˆ2)
            // 2. æŽ§åˆ¶æ¨¡å¼ä¸ºå®¢æˆ·ç«¯æŽ§åˆ¶ï¼ˆ1)
            // 3. è¿è¡ŒçŠ¶æ€æ˜¯ Running
            if (latestState.RobotRunMode == 2 /*&& latestState.RobotControlMode == 1*/ && latestState.OperStatus == "Running" && (latestState.Homed == "Homed" || latestState.Homed.IsNullOrEmpty()))
            if (latestState.RobotRunMode == 2 /*&& latestState.RobotControlMode == 1*/ /*&& latestState.OperStatus == "Running"*/ && (latestState.Homed == "Homed" || latestState.Homed.IsNullOrEmpty()))
            {
                // ========== å–货完成后的放货处理 ==========
                // æ¡ä»¶ï¼š
@@ -137,8 +137,8 @@
                // - ä»»åŠ¡çŠ¶æ€ä¸º RobotPutFinish æˆ–不是 RobotExecuting
                else if ((latestState.CurrentAction == "PutFinished" || latestState.CurrentAction == "AllPutFinished" || latestState.CurrentAction.IsNullOrEmpty())
                    && (latestState.RobotArmObject.IsNullOrEmpty() || latestState.RobotArmObject == 0)
                    && (task.RobotTaskState == TaskRobotStatusEnum.RobotPutFinish.GetHashCode()
                    || task.RobotTaskState != TaskRobotStatusEnum.RobotExecuting.GetHashCode()))
                    && (task.RobotTaskState == TaskRobotStatusEnum.RobotPutFinish.GetHashCode() || task.RobotTaskState != TaskRobotStatusEnum.RobotExecuting.GetHashCode())
                    && latestState.BatteryArrived)
                {
                    _logger.LogInformation("ExecuteAsync:满足取货条件,开始下发取货任务,任务号: {TaskNum}", task.RobotTaskNum);
                    QuartzLogger.Info($"ExecuteAsync:满足取货条件,开始下发取货任务", latestState.RobotCrane?.DeviceName ?? ipAddress);
@@ -312,7 +312,7 @@
        private async Task HandlePutFinishedStateAsync(Dt_RobotTask task, string ipAddress)
        {
            // èŽ·å–æœ€æ–°çŠ¶æ€
            var stateForUpdate = _stateManager.GetState(ipAddress);
            RobotSocketState? stateForUpdate = _stateManager.GetState(ipAddress);
            if (stateForUpdate == null)
            {
                _logger.LogWarning("HandlePutFinishedStateAsync:获取状态失败,IP: {IpAddress}", ipAddress);
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs
@@ -84,7 +84,7 @@
                            {
                                // åˆ¤æ–­æ˜¯å¦ä¸º JSON æ ¼å¼
                                bool isJsonFormat = TryParseJsonSilent(message);
                                _ = MessageReceived.Invoke(message, isJsonFormat, client, robotCrane);
                                _ = MessageReceived.Invoke(message, isJsonFormat, client);
                            }
                            catch { }
                        }
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.cs
@@ -148,7 +148,7 @@
        /// å½“服务器接收到消息时触发。
        /// å‚数:消息内容、是否 JSON æ ¼å¼ã€TCP å®¢æˆ·ç«¯ã€æœºå™¨äººçŠ¶æ€
        /// </remarks>
        public event Func<string, bool, TcpClient, RobotSocketState, Task<string?>>? MessageReceived;
        public event Func<string, bool, TcpClient, Task<string?>>? MessageReceived;
        /// <summary>
        /// æœºå™¨äººè¿žæŽ¥æ–­å¼€äº‹ä»¶
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneCommandBuilder.cs
@@ -205,6 +205,10 @@
            {
                taskType = StackerCraneConst.EmptyPalletTaskType;
            }
            else if(task.TaskType == (int)TaskInboundTypeEnum.InEmpty)
            {
                taskType = StackerCraneConst.EmptyInPalletTaskType;
            }
            else
                taskType = task.TaskType;
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/StackerCraneJob/StackerCraneTaskSelector.cs
@@ -109,7 +109,7 @@
            {
                // æ²¡æœ‰ä¸Šä¸€ä»»åŠ¡ç±»åž‹ï¼ŒæŸ¥è¯¢æ™®é€šä»»åŠ¡
                candidateTask = _taskService.QueryStackerCraneTask(deviceCode);
                QuartzLogHelper.LogDebug(_logger, "SelectTask:查询普通任务,设备: {DeviceCode},结果: {TaskNum}", $"查询普通任务,设备: {deviceCode},结果: {candidateTask?.TaskNum}", deviceCode, deviceCode, candidateTask?.TaskNum);
                //QuartzLogHelper.LogDebug(_logger, "SelectTask:查询普通任务,设备: {DeviceCode},结果: {TaskNum}", $"查询普通任务,设备: {deviceCode},结果: {candidateTask?.TaskNum}", deviceCode, deviceCode, candidateTask?.TaskNum);
            }
            else if (commonStackerCrane.LastTaskType.GetValueOrDefault().GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup)
            {
@@ -117,19 +117,19 @@
                candidateTask = _taskService.QueryStackerCraneInTask(deviceCode);
                // å¦‚果没有入库任务,再查一下出库任务
                candidateTask ??= _taskService.QueryStackerCraneOutTask(deviceCode);
                QuartzLogHelper.LogDebug(_logger, "SelectTask:出库后优先查入库,设备: {DeviceCode},结果: {TaskNum}", $"出库后优先查入库,设备: {deviceCode},结果: {candidateTask?.TaskNum}", deviceCode, deviceCode, candidateTask?.TaskNum);
                //QuartzLogHelper.LogDebug(_logger, "SelectTask:出库后优先查入库,设备: {DeviceCode},结果: {TaskNum}", $"出库后优先查入库,设备: {deviceCode},结果: {candidateTask?.TaskNum}", deviceCode, deviceCode, candidateTask?.TaskNum);
            }
            else
            {
                // ä¸Šä¸€ä»»åŠ¡æ˜¯å…¥åº“ï¼ˆéžå‡ºåº“ï¼‰ï¼Œä¼˜å…ˆæŸ¥å‡ºåº“ä»»åŠ¡
                candidateTask = _taskService.QueryStackerCraneOutTask(deviceCode);
                QuartzLogHelper.LogDebug(_logger, "SelectTask:入库后优先查出库,设备: {DeviceCode},结果: {TaskNum}", $"入库后优先查出库,设备: {deviceCode},结果: {candidateTask?.TaskNum}", deviceCode, deviceCode, candidateTask?.TaskNum);
                //QuartzLogHelper.LogDebug(_logger, "SelectTask:入库后优先查出库,设备: {DeviceCode},结果: {TaskNum}", $"入库后优先查出库,设备: {deviceCode},结果: {candidateTask?.TaskNum}", deviceCode, deviceCode, candidateTask?.TaskNum);
            }
            // å¦‚果没有候选任务,返回 null
            if (candidateTask == null)
            {
                QuartzLogHelper.LogDebug(_logger, "SelectTask:没有候选任务,设备: {DeviceCode}", $"没有候选任务,设备: {deviceCode}", deviceCode, deviceCode);
                //QuartzLogHelper.LogDebug(_logger, "SelectTask:没有候选任务,设备: {DeviceCode}", $"没有候选任务,设备: {deviceCode}", deviceCode, deviceCode);
                return null;
            }
Code/WMS/WIDESEA_WMSClient/src/api/http.js
@@ -12,7 +12,7 @@
let loadingInstance;
let loadingStatus = false;
if (process.env.NODE_ENV == 'development') {
    axios.defaults.baseURL = window.webConfig.webApiBaseUrl;
    axios.defaults.baseURL = 'http://127.0.0.1:9291/';
}
else if (process.env.NODE_ENV == 'debug') {
    axios.defaults.baseURL = window.webConfig.webApiBaseUrl;
Code/WMS/WIDESEA_WMSClient/src/extension/taskinfo/extend/addManualTask.vue
@@ -1,16 +1,11 @@
<template>
  <div>
    <vol-box
      v-model="showBox"
      :lazy="true"
      width="500px"
      :padding="15"
      title="手动创建任务"
    >
    <vol-box v-model="showBox" :lazy="true" width="500px" :padding="15" title="手动创建任务">
      <el-form :model="formData" ref="form" label-width="100px">
        <el-form-item label="任务类型" prop="taskType" required>
          <el-select v-model="formData.taskType" placeholder="请选择任务类型">
            <el-option label="入库" value="入库"></el-option>
            <el-option label="空箱入库" value="空箱入库"></el-option>
            <el-option label="出库" value="出库"></el-option>
            <el-option label="移库" value="移库"></el-option>
          </el-select>
Code/WMS/WIDESEA_WMSClient/src/extension/taskinfo/extend/gridBodyExtension.vue
@@ -6,6 +6,7 @@
        <el-form-item label="任务类型" prop="taskType" required>
          <el-select v-model="manualFormData.taskType" placeholder="请选择任务类型">
            <el-option label="入库" value="入库"></el-option>
            <el-option label="空箱入库" value="空箱入库"></el-option>
            <el-option label="出库" value="出库"></el-option>
            <el-option label="移库" value="移库"></el-option>
          </el-select>
Code/WMS/WIDESEA_WMSClient_Vben/.env.development
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/index.html
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/package-lock.json
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/package.json
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/pnpm-lock.yaml
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/App.vue
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/api/auth.ts
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/api/client.ts
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/api/index.ts
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/inbound.ts
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/menu.ts
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/outbound.ts
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/stock.ts
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/user.ts
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/layouts/MainLayout.vue
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/locales/zh-CN.ts
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/main.ts
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/router/index.ts
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/store/index.ts
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/store/modules/menu.ts
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/store/user.ts
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/utils/menuTransform.ts
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/views/dashboard/index.vue
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/views/inbound/inboundOrderDetail.vue
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/views/inbound/index.vue
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/views/login/index.vue
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/views/outbound/index.vue
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/views/outbound/outboundOrderDetail.vue
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/views/stock/index.vue
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/src/views/stock/stockInfoDetail.vue
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/tsconfig.json
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/tsconfig.node.json
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSClient_Vben/vite.config.ts
ÎļþÒÑɾ³ý
Code/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/MesService.cs
@@ -35,7 +35,7 @@
            {
                Headers = new Dictionary<string, string>
                {
                    { "Authorization", _authorization }
                    { "Authorization","Bearer "+ _authorization }
                },
                TimeoutMs = 30000,
                MaxRetryCount = 0,
@@ -49,7 +49,7 @@
            {
                Headers = new Dictionary<string, string>
                {
                    { "Authorization", token }
                    { "Authorization","Bearer "+ token }
                },
                TimeoutMs = 30000,
                MaxRetryCount = 0,
Code/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockSerivce.cs
@@ -1,8 +1,10 @@
using Newtonsoft.Json;
using SqlSugar;
using System.Diagnostics;
using WIDESEA_Common.Constants;
using WIDESEA_Common.StockEnum;
using WIDESEA_Core;
using WIDESEA_Core.Helper;
using WIDESEA_DTO.MES;
using WIDESEA_DTO.Stock;
using WIDESEA_IBasicService;
@@ -51,6 +53,8 @@
        /// </summary>
        public IMesService _mesService { get; }
        private readonly IMesLogService _mesLogService;
        /// <summary>
        /// æž„造函数
        /// </summary>
@@ -65,7 +69,8 @@
            IStockInfo_HtyService stockInfo_HtyService,
            IMesService mesService,
            IWarehouseService warehouseService,
            ISqlSugarClient sqlSugarClient)
            ISqlSugarClient sqlSugarClient,
            IMesLogService mesLogService)
        {
            StockInfoDetailService = stockInfoDetailService;
            StockInfoService = stockInfoService;
@@ -74,6 +79,7 @@
            _mesService = mesService;
            _warehouseService = warehouseService;
            SqlSugarClient = sqlSugarClient;
            _mesLogService = mesLogService;
        }
        /// <summary>
@@ -466,6 +472,7 @@
        public async Task<WebResponseContent> GroupPalletConfirmAsync(string palletCode, string deviceName)
        {
            WebResponseContent content = new WebResponseContent();
            var stopwatch = Stopwatch.StartNew();
            try
            {
                if (string.IsNullOrWhiteSpace(palletCode))
@@ -510,9 +517,21 @@
                        Location = d.InboundOrderRowNo.ToString()
                    }).ToList()
                };
                string requestJson = bindRequest.ToJson();
                var bindResult = string.IsNullOrWhiteSpace(token)
                    ? _mesService.BindContainer(bindRequest)
                    : _mesService.BindContainer(bindRequest, token);
                stopwatch.Stop();
                await _mesLogService.LogAsync(new MesApiLogDto
                {
                    ApiType = "BindContainer",
                    RequestJson = requestJson,
                    ResponseJson = System.Text.Json.JsonSerializer.Serialize(bindResult),
                    IsSuccess = bindResult.IsSuccess,
                    ErrorMessage = bindResult.ErrorMessage,
                    ElapsedMs = (int)stopwatch.ElapsedMilliseconds,
                    Creator = "systeam"
                });
                if (bindResult == null || bindResult.Data == null || !bindResult.Data.IsSuccess)
                {
                    return content.Error($"MES绑定失败: {bindResult?.Data?.Msg ?? bindResult?.ErrorMessage ?? "未知错误"}");
Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
@@ -41,6 +41,7 @@
        private readonly IUnitOfWorkManage _unitOfWorkManage;
        private readonly IRecordService _recordService;
        private readonly IMESDeviceConfigService _mesDeviceConfigService;
        private readonly IMesLogService _mesLogService;
        public IRepository<Dt_Task> Repository => BaseDal;
@@ -66,7 +67,8 @@
            IStockInfo_HtyService stockInfo_HtyService,
            IUnitOfWorkManage unitOfWorkManage,
            IRecordService recordService,
            IMESDeviceConfigService mesDeviceConfigService) : base(BaseDal)
            IMESDeviceConfigService mesDeviceConfigService,
            IMesLogService mesLogService) : base(BaseDal)
        {
            _mapper = mapper;
            _stockInfoService = stockInfoService;
@@ -80,6 +82,7 @@
            _unitOfWorkManage = unitOfWorkManage;
            _recordService = recordService;
            _mesDeviceConfigService = mesDeviceConfigService;
            _mesLogService = mesLogService;
        }
        /// <summary>
Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Inbound.cs
@@ -1,9 +1,13 @@
using Microsoft.AspNetCore.Http.HttpResults;
using Newtonsoft.Json;
using System.Diagnostics;
using WIDESEA_Common.Constants;
using WIDESEA_Common.LocationEnum;
using WIDESEA_Common.StockEnum;
using WIDESEA_Common.TaskEnum;
using WIDESEA_Common.WareHouseEnum;
using WIDESEA_Core;
using WIDESEA_Core.Helper;
using WIDESEA_DTO.MES;
using WIDESEA_DTO.Task;
using WIDESEA_IBasicService;
@@ -118,6 +122,7 @@
        /// </summary>
        public async Task<WebResponseContent> InboundFinishTaskAsync(CreateTaskDto taskDto)
        {
            var stopwatch = Stopwatch.StartNew();
            try
            {
                var task = await BaseDal.QueryFirstAsync(s => s.PalletCode == taskDto.PalletCode);
@@ -127,56 +132,91 @@
                if (location == null) return WebResponseContent.Instance.Error("未找到对应的货位");
                var stockInfo = await _stockInfoService.GetStockInfoAsync(taskDto.PalletCode);
                if (stockInfo == null) return WebResponseContent.Instance.Error("未找到对应库存信息");
                // åˆ¤æ–­æ˜¯ä¸æ˜¯æžå·åº“任务
                if (taskDto.WarehouseId == (int)WarehouseEnum.FJ1 || taskDto.WarehouseId == (int)WarehouseEnum.ZJ1)
                if (stockInfo == null)
                {
                    return await CompleteAgvInboundTaskAsync(taskDto);
                    return await _unitOfWorkManage.BeginTranAsync(async () =>
                    {
                        stockInfo = new Dt_StockInfo
                        {
                            PalletCode = taskDto.PalletCode,
                            WarehouseId = task.WarehouseId,
                            StockStatus = StockStatusEmun.空托盘库存.GetHashCode(),
                            Creater = StockConstants.SYSTEM_USER,
                            Details = null,
                            LocationCode = location.LocationCode,
                            LocationId = location.Id
                        };
                        var updateLocationResult = await _locationInfoService.UpdateLocationInfoAsync(location);
                        var updateStockResult = await _stockInfoService.Repository.AddDataAsync(stockInfo);
                        return await CompleteTaskAsync(task, "入库完成");
                    });
                }
                return await _unitOfWorkManage.BeginTranAsync(async () =>
                else
                {
                    WebResponseContent content = new WebResponseContent();
                    stockInfo.LocationCode = location.LocationCode;
                    stockInfo.LocationId = location.Id;
                    SetOutboundDateByRoadway(task, stockInfo);
                    stockInfo.StockStatus = StockStatusEmun.入库完成.GetHashCode();
                    location.LocationStatus = LocationStatusEnum.InStock.GetHashCode();
                    var updateLocationResult = await _locationInfoService.UpdateLocationInfoAsync(location);
                    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
                    // åˆ¤æ–­æ˜¯ä¸æ˜¯æžå·åº“任务
                    if (taskDto.WarehouseId == (int)WarehouseEnum.FJ1 || taskDto.WarehouseId == (int)WarehouseEnum.ZJ1)
                    {
                        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 CompleteAgvInboundTaskAsync(taskDto);
                    }
                    return await CompleteTaskAsync(task, "入库完成");
                });
                    return await _unitOfWorkManage.BeginTranAsync(async () =>
                    {
                        WebResponseContent content = new WebResponseContent();
                        stockInfo.LocationCode = location.LocationCode;
                        stockInfo.LocationId = location.Id;
                        SetOutboundDateByRoadway(task, stockInfo);
                        stockInfo.StockStatus = StockStatusEmun.入库完成.GetHashCode();
                        location.LocationStatus = LocationStatusEnum.InStock.GetHashCode();
                        var updateLocationResult = await _locationInfoService.UpdateLocationInfoAsync(location);
                        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 = equipmentCode,
                        //    ResourceCode = resourceCode,
                        //    LocalTime = DateTime.Now,
                        //    ContainerCode = taskDto.PalletCode
                        //};
                        //string requestJson = inboundRequest.ToJson();
                        //var inboundResult = string.IsNullOrWhiteSpace(token)
                        //    ? _mesService.InboundInContainer(inboundRequest)
                        //    : _mesService.InboundInContainer(inboundRequest, token);
                        //stopwatch.Stop();
                        //await _mesLogService.LogAsync(new MesApiLogDto
                        //{
                        //    ApiType = "InboundInContainer",
                        //    RequestJson = requestJson,
                        //    ResponseJson = JsonConvert.SerializeObject(inboundResult),
                        //    IsSuccess = inboundResult.IsSuccess,
                        //    ErrorMessage = inboundResult.ErrorMessage,
                        //    ElapsedMs = (int)stopwatch.ElapsedMilliseconds,
                        //    Creator = "systeam"
                        //});
                        //if (inboundResult == null || inboundResult.Data == null || !inboundResult.Data.IsSuccess)
                        //{
                        //    return content.Error($"任务完成失败:MES进站失败: {inboundResult?.Data?.Msg ?? inboundResult?.ErrorMessage ?? "未知错误"}");
                        //}
                        return await CompleteTaskAsync(task, "入库完成");
                    });
                }
            }
            catch (Exception ex)
            {
@@ -220,4 +260,4 @@
        #endregion å…¥åº“任务
    }
}
}
Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Manual.cs
@@ -41,6 +41,11 @@
                        taskStatus = TaskRelocationStatusEnum.RelocationNew.GetHashCode();
                        break;
                    case "空箱入库":
                        taskType = TaskInboundTypeEnum.InEmpty.GetHashCode();
                        taskStatus = TaskInStatusEnum.InNew.GetHashCode();
                        break;
                    default:
                        return WebResponseContent.Instance.Error($"不支持的任务类型: {dto.TaskType}");
                }
@@ -92,7 +97,7 @@
                        wmsTaskDtos.ToJson());
                    if (!wcsResult.IsSuccess || !wcsResult.Data.Status)
                        return WebResponseContent.Instance.Error($"任务已创建但发送给WCS失败: {wcsResult.Data?.Message}");
                        return WebResponseContent.Instance.Error($"任务已创建但发送给WCS失败:{wcsResult.ErrorMessage}\r\n {wcsResult.Data?.Message}");
                    return WebResponseContent.Instance.OK($"手动创建任务成功,任务号: {taskNum}");
                });
Code/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WCS/TaskService_Outbound.cs
@@ -1,9 +1,11 @@
using System.Diagnostics;
using WIDESEA_Common.Constants;
using WIDESEA_Common.LocationEnum;
using WIDESEA_Common.StockEnum;
using WIDESEA_Common.TaskEnum;
using WIDESEA_Common.WareHouseEnum;
using WIDESEA_Core;
using WIDESEA_Core.Helper;
using WIDESEA_DTO.MES;
using WIDESEA_DTO.Task;
using WIDESEA_IBasicService;
@@ -58,6 +60,7 @@
        /// </summary>
        public async Task<WebResponseContent> OutboundFinishTaskAsync(CreateTaskDto taskDto)
        {
            var stopwatch = Stopwatch.StartNew();
            try
            {
                var task = await BaseDal.QueryFirstAsync(s => s.PalletCode == taskDto.PalletCode);
@@ -135,9 +138,21 @@
                        LocalTime = DateTime.Now,
                        ContainerCode = taskDto.PalletCode
                    };
                    string requestJson = outboundRequest.ToJson();
                    var outboundResult = string.IsNullOrWhiteSpace(token)
                        ? _mesService.OutboundInContainer(outboundRequest)
                        : _mesService.OutboundInContainer(outboundRequest, token);
                    stopwatch.Stop();
                    await _mesLogService.LogAsync(new MesApiLogDto
                    {
                        ApiType = "UnbindContainer",
                        RequestJson = requestJson,
                        ResponseJson = System.Text.Json.JsonSerializer.Serialize(outboundResult),
                        IsSuccess = outboundResult.IsSuccess,
                        ErrorMessage = outboundResult.ErrorMessage,
                        ElapsedMs = (int)stopwatch.ElapsedMilliseconds,
                        Creator = "systeam"
                    });
                    if (outboundResult == null || outboundResult.Data == null || !outboundResult.Data.IsSuccess)
                    {
                        return content.Error($"出库完成失败:MES出站失败: {outboundResult?.Data?.Msg ?? outboundResult?.ErrorMessage ?? "未知错误"}");
Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json
@@ -34,7 +34,7 @@
  "MainDB": "DB_WIDESEA", //当前项目的主库,所对应的连接字符串的Enabled必须为true
  //连接字符串
  //"ConnectionString": "HTI6FB1H05Krd07mNm9yBCNhofW6edA5zLs9TY~MNthRYW3kn0qKbMIsGp~3yyPDF1YZUCPBQx8U0Jfk4PH~ajNFXVIwlH85M3F~v_qKYQ3CeAz3q1mLVDn8O5uWt1~3Ut2V3KRkEwYHvW2oMDN~QIDXPxDgXN0R2oTIhc9dNu7QNaLEknblqmHhjaNSSpERdDVZIgHnMKejU_SL49tralBkZmDNi0hmkbL~837j1NWe37u9fJKmv91QPb~16JsuI9uu0EvNZ06g6PuZfOSAeFH9GMMIZiketdcJG3tHelo=",
  "ConnectionString": "Data Source=.;Initial Catalog=WIDESEAWMS_ShanMei;User ID=sa;Password=P@ssw0rd;Integrated Security=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
  "ConnectionString": "Data Source=192.168.60.30;Initial Catalog=WIDESEAWMS_ShanMei;User ID=sa;Password=P@ssw0rd;Integrated Security=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
  //"ConnectionString": "Data Source=.;Initial Catalog=WIDESEAWMS_ShanMei;User ID=sa;Password=123456;Integrated Security=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
  //"ConnectionString": "Data Source=10.30.4.92;Initial Catalog=WMS_TC;User ID=sa;Password=duo123456;Integrated Security=False;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False",
  //旧WMS数据库连接
@@ -71,7 +71,7 @@
    }
  },
  "MES": {
    "BaseUrl": "http://localhost:5000",
    "BaseUrl": "http://192.168.98.11:20033",
    "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjMwMTcyNzM5Mzk5NzYxOTIwIiwibmFtZSI6IlBBQ0voo4XphY3lt6XkvY0wMSIsIkZhY3RvcnlJZCI6IjEyMzQ1NiIsIlNpdGVJZCI6IjEyMzQ1NiIsIkNvZGUiOiJYWExQQUNLMDRBRTAzMiIsIm5iZiI6MTcwNDE4NzY5MCwiZXhwIjoyMTQ1NjkxNjkwLCJpc3MiOiJodHRwczovL3d3dy5oeW1zb24uY29tIiwiYXVkIjoiaHR0cHM6Ly93d3cuaHltc29uLmNvbSJ9.An1BE7UgfcSP--LtTOmmmWVE2RQFPDahLkDg1xy5KqY"
  },
  "RobotTaskAddressRules": {
Code/WMS/WMS_Api_Design.md
ÎļþÒÑɾ³ý