From ce1292c9cf37195b6abd2699dfc5d6cb3e143c9b Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期日, 12 四月 2026 23:38:19 +0800
Subject: [PATCH] feat(MES): 添加MES接口相关实体和DTO JS扩展文件至JSX格式并更新配置

---
 Code/docs/superpowers/plans/2026-04-12-manual-dispatch-tasks-to-wcs-plan.md |  723 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 723 insertions(+), 0 deletions(-)

diff --git a/Code/docs/superpowers/plans/2026-04-12-manual-dispatch-tasks-to-wcs-plan.md b/Code/docs/superpowers/plans/2026-04-12-manual-dispatch-tasks-to-wcs-plan.md
new file mode 100644
index 0000000..2f0f3f7
--- /dev/null
+++ b/Code/docs/superpowers/plans/2026-04-12-manual-dispatch-tasks-to-wcs-plan.md
@@ -0,0 +1,723 @@
+# 鎵嬪姩涓嬪彂浠诲姟鍒� WCS 鍔熻兘瀹炴柦璁″垝
+
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
+
+**Goal:** 鍦� WMS 鍓嶇浠诲姟绠$悊椤甸潰娣诲姞宸ュ叿鏍忔寜閽紝鏀寔閫変腑涓�涓垨澶氫釜浠诲姟鍚庯紝缂栬緫鍦板潃锛堣捣鐐�/缁堢偣锛夊拰浼樺厛绾у悗鎵嬪姩涓嬪彂鍒� WCS銆�
+
+**Architecture:**
+- 鍓嶇锛氭柊澧� `dispatchTasksToWCS.vue` 寮圭獥缁勪欢锛屽鐢� `task.js` 鎵╁睍鏈哄埗娣诲姞宸ュ叿鏍忔寜閽�
+- 鍚庣锛氭柊澧� `DispatchTasksToWCSAsync` 鏂规硶锛屽鐢� `ReceiveManualTask` 鎺ュ彛涓嬪彂鍒� WCS
+
+**Tech Stack:** Vue 3 + Element Plus锛堝墠绔級锛孉SP.NET Core + SqlSugar锛堝悗绔級
+
+---
+
+## 鏂囦欢缁撴瀯
+
+| 鏀瑰姩绫诲瀷 | 鏂囦欢璺緞 |
+|----------|----------|
+| 鏂板 | `WMS/WIDESEA_WMSClient/src/extension/taskinfo/extend/dispatchTasksToWCS.vue` |
+| 淇敼 | `WMS/WIDESEA_WMSClient/src/extension/taskinfo/task.js` |
+| 鏂板 | `WMS/WIDESEA_WMSServer/WIDESEA_DTO/Task/DispatchTaskDto.cs` |
+| 淇敼 | `WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_WCS.cs` |
+| 淇敼 | `WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs` |
+
+---
+
+## Task 1: 鍚庣 - 鏂板 DispatchTaskDto
+
+**鏂囦欢:**
+- 鍒涘缓: `WMS/WIDESEA_WMSServer/WIDESEA_DTO/Task/DispatchTaskDto.cs`
+
+- [ ] **鍒涘缓 DispatchTaskDto.cs**
+
+```csharp
+using System.Text.Json.Serialization;
+
+namespace WIDESEA_DTO.Task
+{
+    /// <summary>
+    /// 鎵嬪姩涓嬪彂浠诲姟Dto
+    /// </summary>
+    public class DispatchTaskDto
+    {
+        /// <summary>
+        /// 浠诲姟ID
+        /// </summary>
+        [JsonPropertyName("taskId")]
+        public long TaskId { get; set; }
+
+        /// <summary>
+        /// 璧风偣鍦板潃
+        /// </summary>
+        [JsonPropertyName("sourceAddress")]
+        public string SourceAddress { get; set; }
+
+        /// <summary>
+        /// 缁堢偣鍦板潃
+        /// </summary>
+        [JsonPropertyName("targetAddress")]
+        public string TargetAddress { get; set; }
+
+        /// <summary>
+        /// 浼樺厛绾�
+        /// </summary>
+        [JsonPropertyName("grade")]
+        public int Grade { get; set; }
+    }
+
+    /// <summary>
+    /// 浠诲姟涓嬪彂缁撴灉Dto
+    /// </summary>
+    public class DispatchTaskResultDto
+    {
+        /// <summary>
+        /// 浠诲姟ID
+        /// </summary>
+        [JsonPropertyName("taskId")]
+        public long TaskId { get; set; }
+
+        /// <summary>
+        /// 浠诲姟鍙�
+        /// </summary>
+        [JsonPropertyName("taskNum")]
+        public int TaskNum { get; set; }
+
+        /// <summary>
+        /// 鏄惁鎴愬姛
+        /// </summary>
+        [JsonPropertyName("success")]
+        public bool Success { get; set; }
+
+        /// <summary>
+        /// 閿欒淇℃伅
+        /// </summary>
+        [JsonPropertyName("errorMessage")]
+        public string ErrorMessage { get; set; }
+    }
+
+    /// <summary>
+    /// 鎵归噺涓嬪彂缁撴灉Dto
+    /// </summary>
+    public class DispatchResultDto
+    {
+        /// <summary>
+        /// 鎴愬姛鏁伴噺
+        /// </summary>
+        [JsonPropertyName("successCount")]
+        public int SuccessCount { get; set; }
+
+        /// <summary>
+        /// 澶辫触鏁伴噺
+        /// </summary>
+        [JsonPropertyName("failCount")]
+        public int FailCount { get; set; }
+
+        /// <summary>
+        /// 澶辫触浠诲姟鍒楄〃
+        /// </summary>
+        [JsonPropertyName("failResults")]
+        public List<DispatchTaskResultDto> FailResults { get; set; }
+    }
+}
+```
+
+- [ ] **Commit**
+
+```bash
+git add WMS/WIDESEA_WMSServer/WIDESEA_DTO/Task/DispatchTaskDto.cs
+git commit -m "feat(WMS): 鏂板鎵嬪姩涓嬪彂浠诲姟Dto
+- DispatchTaskDto: 涓嬪彂璇锋眰鍙傛暟
+- DispatchTaskResultDto: 鍗曚釜浠诲姟涓嬪彂缁撴灉
+- DispatchResultDto: 鎵归噺涓嬪彂缁撴灉
+
+Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
+```
+
+---
+
+## Task 2: 鍚庣 - TaskService 鏂板 DispatchTasksToWCSAsync
+
+**鏂囦欢:**
+- 淇敼: `WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_WCS.cs`
+
+**鍓嶇疆浜嗚В:**
+- 浠诲姟鐘舵�佹灇涓撅細`TaskInStatusEnum.InNew`锛堝叆搴撴柊鍗曪級銆乣TaskOutStatusEnum.OutNew`锛堝嚭搴撴柊鍗曪級銆乣TaskRelocationStatusEnum.RelocationNew`锛堢Щ搴撴柊鍗曪級
+- 宸叉湁 WCS 璋冪敤鏂瑰紡锛歚_httpClientHelper.Post<WebResponseContent>("http://localhost:9292/api/Task/ReceiveManualTask", json)`
+- 宸叉湁浜嬪姟澶勭悊锛歚await _unitOfWorkManage.BeginTranAsync(async () => { ... })`
+- 宸叉湁 `WMSTaskDTO` 鐢ㄤ簬缁� WCS 鍙戦�佷换鍔�
+
+**鍦� `TaskService_WCS.cs` 鏈熬 `#endregion WCS閫昏緫澶勭悊` 涔嬪墠娣诲姞锛�**
+
+```csharp
+/// <summary>
+/// 鎵嬪姩涓嬪彂浠诲姟鍒癢CS
+/// </summary>
+/// <param name="dtos">涓嬪彂浠诲姟鍙傛暟鍒楄〃</param>
+/// <returns>鎵归噺涓嬪彂缁撴灉</returns>
+public async Task<WebResponseContent> DispatchTasksToWCSAsync(List<DispatchTaskDto> dtos)
+{
+    try
+    {
+        if (dtos == null || !dtos.Any())
+            return WebResponseContent.Instance.Error("璇烽�夋嫨瑕佷笅鍙戠殑浠诲姟");
+
+        var resultDto = new DispatchResultDto
+        {
+            SuccessCount = 0,
+            FailCount = 0,
+            FailResults = new List<DispatchTaskResultDto>()
+        };
+
+        foreach (var dto in dtos)
+        {
+            var task = await BaseDal.QueryFirstAsync(t => t.TaskId == dto.TaskId);
+            if (task == null)
+            {
+                resultDto.FailResults.Add(new DispatchTaskResultDto
+                {
+                    TaskId = dto.TaskId,
+                    TaskNum = 0,
+                    Success = false,
+                    ErrorMessage = "浠诲姟涓嶅瓨鍦�"
+                });
+                resultDto.FailCount++;
+                continue;
+            }
+
+            // 鏍¢獙浠诲姟鐘舵�侊細浠呭叆搴撴柊鍗�/鍑哄簱鏂板崟/绉诲簱鏂板崟鍙笅鍙�
+            bool canDispatch = false;
+            if (task.TaskType == TaskInboundTypeEnum.Inbound.GetHashCode()
+                && task.TaskStatus == TaskInStatusEnum.InNew.GetHashCode())
+                canDispatch = true;
+            else if (task.TaskType == TaskOutboundTypeEnum.Outbound.GetHashCode()
+                && task.TaskStatus == TaskOutStatusEnum.OutNew.GetHashCode())
+                canDispatch = true;
+            else if (task.TaskType == TaskRelocationTypeEnum.Relocation.GetHashCode()
+                && task.TaskStatus == TaskRelocationStatusEnum.RelocationNew.GetHashCode())
+                canDispatch = true;
+
+            if (!canDispatch)
+            {
+                var statusName = GetTaskStatusName(task.TaskType, task.TaskStatus);
+                resultDto.FailResults.Add(new DispatchTaskResultDto
+                {
+                    TaskId = dto.TaskId,
+                    TaskNum = task.TaskNum,
+                    Success = false,
+                    ErrorMessage = $"浠诲姟鐘舵�乕{statusName}]涓嶅厑璁镐笅鍙�"
+                });
+                resultDto.FailCount++;
+                continue;
+            }
+
+            // 鏇存柊浠诲姟鐨勫湴鍧�鍜屼紭鍏堢骇
+            task.SourceAddress = dto.SourceAddress;
+            task.TargetAddress = dto.TargetAddress;
+            task.CurrentAddress = dto.SourceAddress;
+            task.NextAddress = dto.TargetAddress;
+            task.Grade = dto.Grade;
+            task.Dispatchertime = DateTime.Now;
+
+            await BaseDal.UpdateDataAsync(task);
+
+            // 鏋勯�燱MSTaskDTO鍙戦�佺粰WCS
+            var wmsTaskDto = new WMSTaskDTO
+            {
+                Id = task.TaskId,
+                TaskNum = task.TaskNum,
+                PalletCode = task.PalletCode,
+                SourceAddress = task.SourceAddress,
+                TargetAddress = task.TargetAddress,
+                CurrentAddress = task.CurrentAddress,
+                NextAddress = task.NextAddress,
+                TaskType = task.TaskType,
+                TaskStatus = task.TaskStatus,
+                Roadway = task.Roadway,
+                Grade = task.Grade,
+                WarehouseId = task.WarehouseId,
+                PalletType = task.PalletType
+            };
+
+            var wcsResult = _httpClientHelper.Post<WebResponseContent>(
+                "http://localhost:9292/api/Task/ReceiveManualTask",
+                new List<WMSTaskDTO> { wmsTaskDto }.ToJson());
+
+            if (wcsResult != null && wcsResult.IsSuccess)
+            {
+                resultDto.SuccessCount++;
+            }
+            else
+            {
+                resultDto.FailResults.Add(new DispatchTaskResultDto
+                {
+                    TaskId = dto.TaskId,
+                    TaskNum = task.TaskNum,
+                    Success = false,
+                    ErrorMessage = wcsResult?.Message ?? "WCS鍝嶅簲寮傚父"
+                });
+                resultDto.FailCount++;
+            }
+        }
+
+        if (resultDto.FailCount == 0)
+            return WebResponseContent.Instance.OK($"鎴愬姛涓嬪彂{resultDto.SuccessCount}涓换鍔�", resultDto);
+
+        if (resultDto.SuccessCount == 0)
+            return WebResponseContent.Instance.Error($"涓嬪彂澶辫触锛屽叡{resultDto.FailCount}涓换鍔�", resultDto);
+
+        return WebResponseContent.Instance.Error($"閮ㄥ垎涓嬪彂鎴愬姛{resultDto.SuccessCount}涓紝澶辫触{resultDto.FailCount}涓�", resultDto);
+    }
+    catch (Exception ex)
+    {
+        return WebResponseContent.Instance.Error($"涓嬪彂浠诲姟寮傚父: {ex.Message}");
+    }
+}
+
+/// <summary>
+/// 鑾峰彇浠诲姟鐘舵�佸悕绉�
+/// </summary>
+private string GetTaskStatusName(int taskType, int taskStatus)
+{
+    if (taskType == TaskInboundTypeEnum.Inbound.GetHashCode())
+        return ((TaskInStatusEnum)taskStatus).ToString();
+    if (taskType == TaskOutboundTypeEnum.Outbound.GetHashCode())
+        return ((TaskOutStatusEnum)taskStatus).ToString();
+    if (taskType == TaskRelocationTypeEnum.Relocation.GetHashCode())
+        return ((TaskRelocationStatusEnum)taskStatus).ToString();
+    return taskStatus.ToString();
+}
+```
+
+**娉ㄦ剰锛�** 闇�瑕佸湪鏂囦欢椤堕儴纭宸叉湁浠ヤ笅 using锛�
+```csharp
+using WIDESEA_DTO.Task;
+
+> **鐘舵�佸悓姝ヨ鏄�**锛歐MS 涓嬪彂鎴愬姛鍚庯紝WMS 绔换鍔$姸鎬佷繚鎸�"New"涓嶅彉锛屼笉鍒囨崲鍒版墽琛屼腑鐘舵�併�傝繖鏄幇鏈� `CreateManualTaskAsync` 鐨勮璁℃ā寮忥紙鍥犱负 WCS 渚ф湁鐙珛鐨勪换鍔$敓鍛藉懆鏈燂級锛屼笉璺熻繘姝� PR 鏀瑰彉銆傚闇� WMS 绔篃鍚屾鐘舵�侊紝闇�鍙﹁璇勪及 WCS鈫扺MS 鐨勭姸鎬佸洖璋冩満鍒躲��
+using WIDESEA_Model.Models;
+```
+
+- [ ] **Commit**
+
+```bash
+git add WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_WCS.cs
+git commit -m "feat(WMS): TaskService鏂板DispatchTasksToWCSAsync鏂规硶
+- 鏍¢獙浠诲姟鐘舵�侊紝浠呭叆搴撴柊鍗�/鍑哄簱鏂板崟/绉诲簱鏂板崟鍙笅鍙�
+- 鏇存柊浠诲姟鍦板潃鍜屼紭鍏堢骇鍚庤皟鐢╓CS ReceiveManualTask鎺ュ彛
+- 杩斿洖鎵归噺涓嬪彂缁撴灉锛堟垚鍔�/澶辫触鍒楄〃鍙婂師鍥狅級
+
+Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
+```
+
+---
+
+## Task 3: 鍚庣 - TaskController 鏂板涓嬪彂鎺ュ彛
+
+**鏂囦欢:**
+- 淇敼: `WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs`
+
+**鍦� Controller 涓坊鍔犱互涓嬫柟娉曪紙鏀惧湪鍏朵粬鏂规硶闄勮繎锛屽缓璁湪 CreateManualTaskAsync 涔嬪悗锛夛細**
+
+```csharp
+/// <summary>
+/// 鎵嬪姩涓嬪彂浠诲姟鍒癢CS
+/// </summary>
+/// <param name="dtos">涓嬪彂浠诲姟鍙傛暟鍒楄〃</param>
+/// <returns>鎵归噺涓嬪彂缁撴灉</returns>
+[HttpGet, HttpPost, Route("DispatchTasksToWCS"), AllowAnonymous]
+public async Task<WebResponseContent?> DispatchTasksToWCSAsync([FromBody] List<DispatchTaskDto> dtos)
+{
+    return await Service.DispatchTasksToWCSAsync(dtos);
+}
+```
+
+- [ ] **Commit**
+
+```bash
+git add WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs
+git commit -m "feat(WMS): TaskController鏂板DispatchTasksToWCS鎺ュ彛
+POST /api/TaskInfo/DispatchTasksToWCS
+
+Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
+```
+
+---
+
+## Task 4: 鍓嶇 - 鏂板 dispatchTasksToWCS.vue 寮圭獥缁勪欢
+
+**鏂囦欢:**
+- 鍒涘缓: `WMS/WIDESEA_WMSClient/src/extension/taskinfo/extend/dispatchTasksToWCS.vue`
+
+**鍙傝�冪幇鏈� addManualTask.vue 鐨勬ā寮忥紝浣跨敤 el-table 瀹炵幇鎵归噺缂栬緫锛�**
+
+```vue
+<template>
+  <div>
+    <vol-box v-model="showBox" :lazy="true" width="900px" :padding="15" title="鎵嬪姩涓嬪彂浠诲姟鍒� WCS">
+      <div v-if="selectedRows.length > 0" class="dispatch-info">
+        宸查�変换鍔℃暟: <span class="count">{{ selectedRows.length }}</span> 涓�
+      </div>
+
+      <el-table :data="tableData" border style="width: 100%; margin-top: 10px" max-height="400">
+        <el-table-column prop="taskNum" label="浠诲姟鍙�" width="120"></el-table-column>
+        <el-table-column prop="sourceAddress" label="璧风偣鍦板潃" width="160">
+          <template slot-scope="scope">
+            <el-input
+              v-if="scope.row.editable"
+              v-model="scope.row.sourceAddress"
+              size="small"
+              placeholder="璇疯緭鍏�"
+            ></el-input>
+            <span v-else>{{ scope.row.sourceAddress }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="targetAddress" label="缁堢偣鍦板潃" width="160">
+          <template slot-scope="scope">
+            <el-input
+              v-if="scope.row.editable"
+              v-model="scope.row.targetAddress"
+              size="small"
+              placeholder="璇疯緭鍏�"
+            ></el-input>
+            <span v-else>{{ scope.row.targetAddress }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="grade" label="浼樺厛绾�" width="100">
+          <template slot-scope="scope">
+            <el-input-number
+              v-if="scope.row.editable"
+              v-model="scope.row.grade"
+              :min="1"
+              :max="99"
+              size="small"
+              style="width: 80px"
+            ></el-input-number>
+            <span v-else>{{ scope.row.grade }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="statusName" label="鐘舵��" width="120">
+          <template slot-scope="scope">
+            <span :class="{ 'status-error': !scope.row.editable }">{{ scope.row.statusName }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="palletCode" label="鎵樼洏鍙�"></el-table-column>
+      </el-table>
+
+      <!-- 澶辫触缁撴灉 -->
+      <div v-if="failResults.length > 0" class="fail-results">
+        <div class="fail-title">涓嬪彂澶辫触浠诲姟锛�</div>
+        <el-table :data="failResults" border style="width: 100%; margin-top: 10px" max-height="200">
+          <el-table-column prop="taskNum" label="浠诲姟鍙�" width="120"></el-table-column>
+          <el-table-column prop="errorMessage" label="澶辫触鍘熷洜"></el-table-column>
+        </el-table>
+      </div>
+
+      <template #footer>
+        <el-button type="primary" size="small" @click="submit" :loading="loading">纭涓嬪彂</el-button>
+        <el-button type="danger" size="small" @click="showBox = false">鍏抽棴</el-button>
+      </template>
+    </vol-box>
+  </div>
+</template>
+
+<script>
+import VolBox from "@/components/basic/VolBox.vue";
+
+export default {
+  components: { VolBox },
+  data() {
+    return {
+      showBox: false,
+      loading: false,
+      selectedRows: [],
+      tableData: [],
+      failResults: [],
+      // 鍙笅鍙戠姸鎬佺殑浠诲姟绫诲瀷鍜岀姸鎬佸�硷紙闇�涓庡悗绔� TaskTypeEnum 鏋氫妇涓�鑷达級
+      // Inbound=200, Outbound=100, Relocation=300
+      // 鐘舵��: InNew=200, OutNew=100, RelocationNew=300
+      dispatchableStatuses: {
+        inbound: { taskType: 200, status: 200 },    // 鍏ュ簱鏂板崟
+        outbound: { taskType: 100, status: 100 },  // 鍑哄簱鏂板崟
+        relocation: { taskType: 300, status: 300 } // 绉诲簱鏂板崟
+      }
+    };
+  },
+  methods: {
+    open(rows) {
+      this.showBox = true;
+      this.selectedRows = rows || [];
+      this.failResults = [];
+      this.initTableData();
+    },
+    initTableData() {
+      // 浠诲姟鐘舵�佸悕绉版槧灏勶紙闇�涓庡悗绔灇涓句竴鑷达級
+      // taskType: Inbound=200, Outbound=100, Relocation=300
+      // status: InNew=200, OutNew=100, RelocationNew=300, SC_OutExecuting=110, etc.
+      const statusNames = {
+        'inbound_200': '鍏ュ簱鏂板崟',
+        'outbound_100': '鍑哄簱鏂板崟',
+        'relocation_300': '绉诲簱鏂板崟',
+        'outbound_110': '鍫嗗灈鏈哄嚭搴撴墽琛屼腑',
+        'outbound_115': '鍫嗗灈鏈哄嚭搴撳畬鎴�',
+        'inbound_220': '杈撻�佺嚎鍏ュ簱鎵ц涓�',
+        'inbound_230': '鍫嗗灈鏈哄叆搴撴墽琛屼腑',
+        'inbound_290': '鍏ュ簱浠诲姟瀹屾垚',
+        'outbound_120': '杈撻�佺嚎鍑哄簱鎵ц涓�',
+        'outbound_125': '杈撻�佺嚎鍑哄簱瀹屾垚',
+        'outbound_200': '鍑哄簱浠诲姟瀹屾垚',
+        'relocation_310': '鍫嗗灈鏈虹Щ搴撴墽琛屼腑'
+      };
+
+      this.tableData = this.selectedRows.map(row => {
+        const taskType = row.taskType || 0;
+        const taskStatus = row.taskStatus || 0;
+        const statusKey = this.getStatusKey(taskType, taskStatus);
+        const statusName = statusNames[statusKey] || `鐘舵��${taskStatus}`;
+
+        // 鍒ゆ柇鏄惁鍙紪杈戯細浠呭叆搴撴柊鍗�/鍑哄簱鏂板崟/绉诲簱鏂板崟鍙紪杈�
+        const editable = this.isEditable(taskType, taskStatus);
+
+        return {
+          taskId: row.taskId,
+          taskNum: row.taskNum,
+          sourceAddress: row.sourceAddress || '',
+          targetAddress: row.targetAddress || '',
+          grade: row.grade || 1,
+          statusName: statusName,
+          palletCode: row.palletCode || '',
+          editable: editable,
+          taskType: taskType,
+          taskStatus: taskStatus
+        };
+      });
+    },
+    getStatusKey(taskType, taskStatus) {
+      if (taskType === 200) return `inbound_${taskStatus}`;
+      if (taskType === 100) return `outbound_${taskStatus}`;
+      if (taskType === 300) return `relocation_${taskStatus}`;
+      return `other_${taskStatus}`;
+    },
+    isEditable(taskType, taskStatus) {
+      if (taskType === 200 && taskStatus === 200) return true;  // 鍏ュ簱鏂板崟
+      if (taskType === 100 && taskStatus === 100) return true;  // 鍑哄簱鏂板崟
+      if (taskType === 300 && taskStatus === 300) return true;  // 绉诲簱鏂板崟
+      return false;
+    },
+    submit() {
+      if (this.tableData.length === 0) return this.$message.error("璇峰厛閫夋嫨浠诲姟");
+
+      const dispatchData = this.tableData.map(row => ({
+        taskId: row.taskId,
+        sourceAddress: row.sourceAddress,
+        targetAddress: row.targetAddress,
+        grade: row.grade
+      }));
+
+      this.loading = true;
+      this.http
+        .post("/api/TaskInfo/DispatchTasksToWCS", dispatchData, "鏁版嵁澶勭悊涓�...")
+        .then((res) => {
+          this.loading = false;
+          if (!res.status) {
+            this.$message.error(res.message);
+            // 鏄剧ず澶辫触鍒楄〃
+            if (res.data && res.data.failResults) {
+              this.failResults = res.data.failResults;
+            }
+            return;
+          }
+
+          // 鍏ㄩ儴鎴愬姛
+          if (res.data && res.data.failCount === 0) {
+            this.$message.success(res.message);
+            this.showBox = false;
+            this.$emit("parentCall", ($vue) => {
+              $vue.refresh();
+            });
+            return;
+          }
+
+          // 閮ㄥ垎鎴愬姛鎴栧叏閮ㄥけ璐�
+          if (res.data && res.data.failResults) {
+            this.failResults = res.data.failResults;
+          }
+
+          if (res.data && res.data.failCount > 0 && res.data.successCount > 0) {
+            this.$message.warning(res.message);
+          } else {
+            this.$message.error(res.message);
+          }
+        })
+        .catch(() => {
+          this.loading = false;
+        });
+    }
+  }
+};
+</script>
+
+<style scoped>
+.dispatch-info {
+  font-size: 14px;
+  color: #606266;
+  margin-bottom: 10px;
+}
+.dispatch-info .count {
+  color: #409eff;
+  font-weight: bold;
+}
+.status-error {
+  color: #f56c6c;
+}
+.fail-results {
+  margin-top: 15px;
+  padding: 10px;
+  background: #fef0f0;
+  border-radius: 4px;
+}
+.fail-title {
+  font-size: 14px;
+  color: #f56c6c;
+  margin-bottom: 5px;
+}
+</style>
+```
+
+- [ ] **Commit**
+
+```bash
+git add WMS/WIDESEA_WMSClient/src/extension/taskinfo/extend/dispatchTasksToWCS.vue
+git commit -m "feat(WMS): 鏂板dispatchTasksToWCS.vue鎵归噺涓嬪彂寮圭獥缁勪欢
+- 宸ュ叿鏍忔寜閽Е鍙戝脊绐�
+- 琛ㄦ牸灞曠ず閫変腑浠诲姟锛屽彲缂栬緫鍦板潃鍜屼紭鍏堢骇
+- 闈炲彲涓嬪彂鐘舵�佷换鍔¤鏍囩孩涓斾笉鍙紪杈�
+- 鏄剧ず涓嬪彂澶辫触浠诲姟鍒楄〃
+
+Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
+```
+
+---
+
+## Task 5: 鍓嶇 - task.js 娣诲姞宸ュ叿鏍忔寜閽�
+
+**鏂囦欢:**
+- 淇敼: `WMS/WIDESEA_WMSClient/src/extension/taskinfo/task.js`
+
+**闇�瑕佷慨鏀逛袱澶勶細**
+
+1. 鍦� `components` 閮ㄥ垎寮曞叆寮圭獥缁勪欢锛�
+```javascript
+import addManualTask from './extend/addManualTask.vue'
+import dispatchTasksToWCS from './extend/dispatchTasksToWCS.vue'  // 鏂板
+```
+
+2. 鍦� `components` 瀵硅薄涓敞鍐岋細
+```javascript
+components: {
+  gridBody: addManualTask,
+  dispatchBody: dispatchTasksToWCS,  // 鏂板
+},
+```
+
+3. 鍦� `onInit()` 鏂规硶涓坊鍔犳墜鍔ㄤ笅鍙戞寜閽紙鍦ㄦ墜鍔ㄥ垱寤轰换鍔℃寜閽箣鍚庯級锛�
+
+```javascript
+// 娣诲姞"鎵嬪姩涓嬪彂"鎸夐挳
+this.buttons.push({
+  name: '鎵嬪姩涓嬪彂',
+  icon: 'el-icon-s-promotion',
+  type: 'primary',
+  value: 'DispatchTasksToWCS',
+  onClick: () => {
+    let rows = this.$refs.table.getSelected();
+    if (rows.length == 0) return this.$error("璇峰厛閫夋嫨浠诲姟");
+    this.$refs.dispatchBody.open(rows);
+  }
+});
+```
+
+**瀹屾暣淇敼鍚庣殑 task.js 鍏抽敭閮ㄥ垎锛�**
+
+```javascript
+import addManualTask from './extend/addManualTask.vue'
+import dispatchTasksToWCS from './extend/dispatchTasksToWCS.vue'
+
+let extension = {
+    components: {
+      gridBody: addManualTask,
+      dispatchBody: dispatchTasksToWCS,
+    },
+    buttons: { view: [], box: [], detail: [] },
+    methods: {
+      onInit() {
+        //娣诲姞"鎵嬪姩鍒涘缓浠诲姟"鎸夐挳
+        this.buttons.push({
+          name: '鎵嬪姩鍒涘缓浠诲姟',
+          icon: 'el-icon-plus',
+          type: 'primary',
+          value: 'ManualCreateTask',
+          onClick: () => {
+            this.$refs.gridBody.open();
+          }
+        });
+
+        // 娣诲姞"鎵嬪姩涓嬪彂"鎸夐挳
+        this.buttons.push({
+          name: '鎵嬪姩涓嬪彂',
+          icon: 'el-icon-s-promotion',
+          type: 'primary',
+          value: 'DispatchTasksToWCS',
+          onClick: () => {
+            let rows = this.$refs.table.getSelected();
+            if (rows.length == 0) return this.$error("璇峰厛閫夋嫨浠诲姟");
+            this.$refs.dispatchBody.open(rows);
+          }
+        });
+        // ... 鍏朵綑鐜版湁鎸夐挳閫昏緫淇濇寔涓嶅彉
+      },
+      // ... 鍏朵綑鏂规硶淇濇寔涓嶅彉
+    }
+};
+export default extension;
+```
+
+- [ ] **Commit**
+
+```bash
+git add WMS/WIDESEA_WMSClient/src/extension/taskinfo/task.js
+git commit -m "feat(WMS): task.js娣诲姞宸ュ叿鏍�'鎵嬪姩涓嬪彂'鎸夐挳
+- 寮曞叆dispatchTasksToWCS.vue缁勪欢
+- 鐐瑰嚮鎸夐挳鑾峰彇閫変腑浠诲姟骞舵墦寮�涓嬪彂寮圭獥
+
+Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
+```
+
+---
+
+## Task 6: 楠岃瘉鏋勫缓
+
+- [ ] **WMS 鍚庣鏋勫缓**
+
+```bash
+cd D:/Git/ShanMeiXinNengYuan/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer
+dotnet build
+```
+
+- [ ] **WMS 鍓嶇鏋勫缓**
+
+```bash
+cd D:/Git/ShanMeiXinNengYuan/Code/WMS/WIDESEA_WMSClient
+npm run serve
+```
+
+---
+
+## 楠屾敹鏍囧噯
+
+- [ ] 宸ュ叿鏍忔坊鍔�"鎵嬪姩涓嬪彂"鎸夐挳锛屾湭閫変腑浠诲姟鏃剁偣鍑绘彁绀�"璇峰厛閫夋嫨浠诲姟"
+- [ ] 寮圭獥姝g‘鏄剧ず鎵�鏈夐�変腑浠诲姟
+- [ ] 浠呭叆搴撴柊鍗�/鍑哄簱鏂板崟/绉诲簱鏂板崟鐘舵�佺殑浠诲姟鍙紪杈戝湴鍧�鍜屼紭鍏堢骇
+- [ ] 鍏朵粬鐘舵�佷换鍔¤鏍囩孩锛屽湴鍧�/浼樺厛绾т笉鍙紪杈�
+- [ ] 纭涓嬪彂鍚庤皟鐢ㄥ悗绔帴鍙�
+- [ ] 鎴愬姛鏃跺脊绐楀叧闂苟鍒锋柊鍒楄〃锛涘け璐ユ椂鏄剧ず澶辫触浠诲姟鍙婂師鍥�
+- [ ] 鎵归噺涓嬪彂鏃舵纭粺璁℃垚鍔�/澶辫触鏁伴噺

--
Gitblit v1.9.3