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-11-manual-task-creation-plan.md |  434 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 434 insertions(+), 0 deletions(-)

diff --git a/Code/docs/superpowers/plans/2026-04-11-manual-task-creation-plan.md b/Code/docs/superpowers/plans/2026-04-11-manual-task-creation-plan.md
new file mode 100644
index 0000000..c1902be
--- /dev/null
+++ b/Code/docs/superpowers/plans/2026-04-11-manual-task-creation-plan.md
@@ -0,0 +1,434 @@
+# 鎵嬪姩鍒涘缓浠诲姟鍔熻兘瀹炴柦璁″垝
+
+> **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:** 鍦╓MS鐣岄潰涓婃坊鍔犳墜鍔ㄥ垱寤轰换鍔″姛鑳斤紝鏀寔鍏ュ簱/鍑哄簱/绉诲簱涓夌绫诲瀷锛屼换鍔″彂閫佽嚦WCS鍚庯紝WCS鍒ゆ柇璧风偣涓虹嚎浣撶偣浣�(11068/11010/11001)鏃跺啓鍏ヨ緭閫佺嚎浠诲姟銆�
+
+**Architecture:** WMS鍓嶇Vue椤甸潰 鈫� WMS鍚庣API 鈫� WCS ReceiveTask 鈫� WCS FlowService鍒ゆ柇骞跺啓鍏ヨ緭閫佺嚎PLC
+
+**Tech Stack:** .NET 6 (WMS/WCS Backend), Vue3 (WMS Frontend), MapsterMapper, SqlSugar
+
+---
+
+## 鏂囦欢缁撴瀯
+
+| 鏂囦欢 | 鑱岃矗 |
+|------|------|
+| `WMS/WIDESEA_WMSClient/src/extension/taskinfo/task.js` | 娣诲姞鎵嬪姩鍒涘缓浠诲姟鎸夐挳鍜屽鐞嗛�昏緫 |
+| `WMS/WIDESEA_WMSServer/WIDESEA_DTO/Task/CreateManualTaskDto.cs` | **鏂板缓** - 鎵嬪姩鍒涘缓浠诲姟璇锋眰DTO |
+| `WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs` | 娣诲姞 CreateManualTask 鎺ュ彛 |
+| `WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs` | 娣诲姞 CreateManualTaskAsync 鏂规硶 |
+| `WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/TaskService.cs` | ReceiveWMSTask 宸叉湁鍒嗗彂閫昏緫锛岀‘璁ゅ叆鍙f纭� |
+| `WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/Flows/InboundTaskFlowService.cs` | 娣诲姞绾夸綋鐐逛綅鍒ゆ柇鍜岃緭閫佺嚎浠诲姟鍐欏叆閫昏緫 |
+
+---
+
+## WMS 鍓嶇
+
+### Task 1: 娣诲姞鎵嬪姩鍒涘缓浠诲姟鎸夐挳
+
+**鏂囦欢:**
+- Modify: `WMS/WIDESEA_WMSClient/src/extension/taskinfo/task.js:16`
+
+- [ ] **Step 1: 鍦� buttons.box 娣诲姞鎵嬪姩鍒涘缓鎸夐挳**
+
+鍦� `task.js` 鐨� `buttons: { view: [], box: [], detail: [] }` 涓坊鍔狅細
+
+```javascript
+buttons: {
+  view: [],
+  box: [
+    {
+      value: 'CreateManualTask',
+      label: '鎵嬪姩鍒涘缓浠诲姟',
+      onClick: function () {
+        // 寮瑰嚭鎵嬪姩鍒涘缓浠诲姟瀵硅瘽妗�
+        this.$refs.grid.openModel('Add');
+      }
+    }
+  ],
+  detail: []
+},
+```
+
+- [ ] **Step 2: 鍦� modelFooter 娣诲姞鑷畾涔夊脊绐�**
+
+鍦� `components.modelFooter` 娣诲姞 Vue 妯℃澘锛堝鏋滄鏋舵敮鎸佽嚜瀹氫箟寮圭獥鍐呭锛夛紝鎴栦娇鐢ㄦ鏋跺唴缃殑 `openModel` 閰嶅悎 `addBefore` 澶勭悊銆�
+
+> **娉ㄦ剰:** 鍏蜂綋鐨勫脊绐楀疄鐜板彇鍐充簬褰撳墠鍓嶇妗嗘灦鐨勬墿灞曟満鍒躲�傝嫢褰撳墠椤甸潰涓嶆敮鎸佽嚜瀹氫箟瀛楁锛屽垯闇�瑕佸湪 `task.vue` 涓坊鍔犳柊鐨勯〉闈㈢粍浠讹紝鎴栭�氳繃 `modelBody` 鎵╁睍鑷畾涔夎〃鍗曘��
+
+- [ ] **Step 3: 鎻愪氦**
+
+```bash
+git add WMS/WIDESEA_WMSClient/src/extension/taskinfo/task.js
+git commit -m "feat(WMS): 娣诲姞鎵嬪姩鍒涘缓浠诲姟鎸夐挳"
+```
+
+---
+
+## WMS 鍚庣
+
+### Task 2: 鍒涘缓 DTO
+
+**鏂囦欢:**
+- Create: `WMS/WIDESEA_WMSServer/WIDESEA_DTO/Task/CreateManualTaskDto.cs`
+
+- [ ] **Step 1: 缂栧啓 CreateManualTaskDto**
+
+```csharp
+using System.ComponentModel.DataAnnotations;
+using System.Text.Json.Serialization;
+using WIDESEA_Common.TaskEnum;
+
+namespace WIDESEA_DTO.Task
+{
+    /// <summary>
+    /// 鎵嬪姩鍒涘缓浠诲姟璇锋眰DTO
+    /// </summary>
+    public class CreateManualTaskDto
+    {
+        /// <summary>
+        /// 浠诲姟绫诲瀷锛�1=鍏ュ簱, 2=鍑哄簱, 3=绉诲簱
+        /// </summary>
+        [JsonPropertyName("taskType")]
+        [Required(ErrorMessage = "浠诲姟绫诲瀷涓嶈兘涓虹┖")]
+        public TaskTypeEnum TaskType { get; set; }
+
+        /// <summary>
+        /// 璧风偣鍦板潃
+        /// </summary>
+        [JsonPropertyName("sourceAddress")]
+        [Required(ErrorMessage = "璧风偣鍦板潃涓嶈兘涓虹┖")]
+        public string SourceAddress { get; set; }
+
+        /// <summary>
+        /// 缁堢偣鍦板潃
+        /// </summary>
+        [JsonPropertyName("targetAddress")]
+        [Required(ErrorMessage = "缁堢偣鍦板潃涓嶈兘涓虹┖")]
+        public string TargetAddress { get; set; }
+
+        /// <summary>
+        /// 鏉$爜
+        /// </summary>
+        [JsonPropertyName("barcode")]
+        [Required(ErrorMessage = "鏉$爜涓嶈兘涓虹┖")]
+        public string Barcode { get; set; }
+
+        /// <summary>
+        /// 浠撳簱ID
+        /// </summary>
+        [JsonPropertyName("warehouseId")]
+        [Required(ErrorMessage = "浠撳簱ID涓嶈兘涓虹┖")]
+        public int WarehouseId { get; set; }
+
+        /// <summary>
+        /// 浼樺厛绾э紝榛樿1
+        /// </summary>
+        [JsonPropertyName("grade")]
+        public int Grade { get; set; } = 1;
+    }
+}
+```
+
+- [ ] **Step 2: 鎻愪氦**
+
+```bash
+git add WMS/WIDESEA_WMSServer/WIDESEA_DTO/Task/CreateManualTaskDto.cs
+git commit -m "feat(WMS): 鏂板CreateManualTaskDto"
+```
+
+---
+
+### Task 3: 娣诲姞 Controller 鎺ュ彛
+
+**鏂囦欢:**
+- Modify: `WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs`
+
+- [ ] **Step 1: 娣诲姞 CreateManualTask 鎺ュ彛**
+
+鍦� `TaskController` 绫讳腑娣诲姞锛�
+
+```csharp
+/// <summary>
+/// 鎵嬪姩鍒涘缓浠诲姟
+/// </summary>
+/// <param name="dto">鎵嬪姩鍒涘缓浠诲姟鍙傛暟</param>
+/// <returns></returns>
+[HttpGet, HttpPost, Route("CreateManualTask"), AllowAnonymous]
+public async Task<WebResponseContent?> CreateManualTaskAsync([FromBody] CreateManualTaskDto dto)
+{
+    return await Service.CreateManualTaskAsync(dto);
+}
+```
+
+- [ ] **Step 2: 鎻愪氦**
+
+```bash
+git add WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs
+git commit -m "feat(WMS): 娣诲姞鎵嬪姩鍒涘缓浠诲姟鎺ュ彛 CreateManualTask"
+```
+
+---
+
+### Task 4: 娣诲姞 TaskService 鏂规硶
+
+**鏂囦欢:**
+- Modify: `WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs`
+
+棣栧厛鏌ョ湅鐜版湁 `TaskService.cs` 缁撴瀯锛岀‘璁ゆ柟娉曠鍚嶆牸寮忋��
+
+- [ ] **Step 1: 娣诲姞 CreateManualTaskAsync 鏂规硶**
+
+鍦� `TaskService` 绫讳腑娣诲姞锛堝弬鑰� `CreateAutoOutboundTasksAsync` 鐨勬ā寮忥級锛�
+
+```csharp
+/// <summary>
+/// 鎵嬪姩鍒涘缓浠诲姟
+/// </summary>
+/// <param name="dto">鎵嬪姩鍒涘缓浠诲姟鍙傛暟</param>
+/// <returns></returns>
+public async Task<WebResponseContent> CreateManualTaskAsync(CreateManualTaskDto dto)
+{
+    try
+    {
+        // 1. 鐢熸垚浠诲姟鍙�
+        int taskNum = await BaseDal.GetTaskNo();
+
+        // 2. 鏍规嵁浠诲姟绫诲瀷纭畾鐘舵�佸��
+        int taskStatus = dto.TaskType switch
+        {
+            TaskTypeEnum.Inbound => TaskInStatusEnum.InNew.GetHashCode(),    // 200
+            TaskTypeEnum.Outbound => TaskOutStatusEnum.OutNew.GetHashCode(),  // 100
+            TaskTypeEnum.Relocation => TaskRelocationStatusEnum.New.GetHashCode(), // 300
+            _ => TaskStatusEnum.New.GetHashCode()
+        };
+
+        // 3. 鏋勫缓浠诲姟瀹炰綋
+        var task = new Dt_Task
+        {
+            TaskNum = taskNum,
+            PalletCode = dto.Barcode,
+            SourceAddress = dto.SourceAddress,
+            TargetAddress = dto.TargetAddress,
+            TaskType = dto.TaskType.GetHashCode(),
+            TaskStatus = taskStatus,
+            Grade = dto.Grade,
+            WarehouseId = dto.WarehouseId,
+            Creater = "manual",
+            CreateDate = DateTime.Now,
+            ModifyDate = DateTime.Now
+        };
+
+        // 4. 淇濆瓨鍒版暟鎹簱
+        var result = await BaseDal.Add(task);
+        if (!result)
+            return WebResponseContent.Instance.Error("鍒涘缓浠诲姟澶辫触");
+
+        // 5. 鍙戦�佷换鍔″埌WCS
+        var wmsTaskDto = new WMSTaskDTO
+        {
+            TaskNum = task.TaskNum,
+            PalletCode = task.PalletCode,
+            SourceAddress = task.SourceAddress,
+            TargetAddress = task.TargetAddress,
+            TaskType = task.TaskType,
+            TaskStatus = task.TaskStatus,
+            WarehouseId = task.WarehouseId ?? 0
+        };
+
+        var wcsResult = await _httpClientHelper.PostAsync<WebResponseContent>(
+            "http://localhost:9292/api/Task/ReceiveTask",
+            wmsTaskDto.ToJson());
+
+        if (!wcsResult.IsSuccess || !wcsResult.Data.Status)
+            return WebResponseContent.Instance.Error($"浠诲姟宸插垱寤轰絾鍙戦�佺粰WCS澶辫触: {wcsResult.Data?.Message}");
+
+        return WebResponseContent.Instance.OK($"鎵嬪姩鍒涘缓浠诲姟鎴愬姛锛屼换鍔″彿: {taskNum}");
+    }
+    catch (Exception ex)
+    {
+        return WebResponseContent.Instance.Error($"鎵嬪姩鍒涘缓浠诲姟寮傚父: {ex.Message}");
+    }
+}
+```
+
+> **娉ㄦ剰:** 闇�瑕佺‘璁� `TaskRelocationStatusEnum` 鏄惁瀛樺湪锛屽涓嶅瓨鍦ㄥ垯浣跨敤 `TaskStatusEnum.New`銆�
+
+- [ ] **Step 2: 娣诲姞蹇呰鐨� using**
+
+```csharp
+using WIDESEA_DTO.Task;
+using WIDESEA_Common.TaskEnum;
+using WIDESEAWCS_DTO;
+```
+
+- [ ] **Step 3: 鎻愪氦**
+
+```bash
+git add WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
+git commit -m "feat(WMS): 娣诲姞鎵嬪姩鍒涘缓浠诲姟 CreateManualTaskAsync 鏂规硶"
+```
+
+---
+
+## WCS 鍚庣
+
+### Task 5: 纭 ReceiveWMSTask 鍏ュ彛
+
+**鏂囦欢:**
+- Modify: `WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/TaskService.cs`
+
+- [ ] **Step 1: 纭 ReceiveWMSTask 鏂规硶瀛樺湪**
+
+纭 `ReceiveWMSTask` 鎺ユ敹 `WMSTaskDTO` 鍒楄〃鍚庤矾鐢卞埌瀵瑰簲 FlowService銆�
+
+```csharp
+public WebResponseContent ReceiveWMSTask([NotNull] List<WMSTaskDTO> taskDTOs)
+{
+    // 閬嶅巻浠诲姟锛屾牴鎹� TaskType 鍒嗗彂鍒颁笉鍚� FlowService
+    foreach (var item in taskDTOs)
+    {
+        // 鏍规嵁 item.TaskType 鍒ゆ柇璺敱鍒� Inbound/Outbound/Relocation
+    }
+}
+```
+
+- [ ] **Step 2: 鎻愪氦**
+
+```bash
+git add WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/TaskService.cs
+git commit -m "feat(WCS): 纭 ReceiveWMSTask 鍏ュ彛姝g‘"
+```
+
+---
+
+### Task 6: 鍦� InboundTaskFlowService 娣诲姞绾夸綋鐐逛綅澶勭悊
+
+**鏂囦欢:**
+- Modify: `WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/Flows/InboundTaskFlowService.cs`
+
+棣栧厛鏌ョ湅鐜版湁鐨� `InitializeOnReceive` 鏂规硶瀹屾暣瀹炵幇銆�
+
+- [ ] **Step 1: 娣诲姞绾夸綋鐐逛綅甯搁噺**
+
+鍦ㄧ被涓坊鍔狅細
+
+```csharp
+/// <summary>
+/// 绾夸綋鍏ュ簱鐐逛綅
+/// </summary>
+private static readonly string[] LINE_IN_POINTS = { "11068", "11010", "11001" };
+```
+
+- [ ] **Step 2: 淇敼 InitializeOnReceive 鏂规硶**
+
+鍦� `InitializeOnReceive` 鏂规硶涓紝鍒ゆ柇濡傛灉 `SourceAddress` 鏄嚎浣撶偣浣嶏紝鍒欏啓鍏ヨ緭閫佺嚎浠诲姟锛�
+
+```csharp
+public void InitializeOnReceive([NotNull] Dt_Task task, [NotNull] WMSTaskDTO source)
+{
+    // 鍏堟墽琛屽師鏈夌殑璺敱閫昏緫
+    Dt_Router routers = _routerService.QueryNextRoute(source.SourceAddress);
+    if (routers.IsNullOrEmpty())
+    {
+        return;
+    }
+
+    task.TaskStatus = (int)TaskInStatusEnum.InNew;
+    task.CurrentAddress = source.SourceAddress;
+    task.NextAddress = routers.ChildPosi;
+
+    // 濡傛灉璧风偣鏄嚎浣撶偣浣�(11068/11010/11001)锛岀洿鎺ュ啓鍏ヨ緭閫佺嚎浠诲姟
+    if (LINE_IN_POINTS.Contains(source.SourceAddress))
+    {
+        WriteConveyorLineTask(task, source.SourceAddress);
+    }
+}
+
+/// <summary>
+/// 鍐欏叆杈撻�佺嚎浠诲姟鍒癙LC
+/// </summary>
+private void WriteConveyorLineTask(Dt_Task task, string sourceAddress)
+{
+    // 1. 閫氳繃 Storage.Devices 鏌ユ壘瀵瑰簲鐨勮緭閫佺嚎璁惧
+    IDevice? device = Storage.Devices
+        .FirstOrDefault(x => x.DeviceProDTOs.Any(d => d.DeviceChildCode == sourceAddress));
+
+    if (device == null)
+    {
+        // 璁板綍鏃ュ織锛氭湭鎵惧埌瀵瑰簲鐨勮緭閫佺嚎璁惧
+        QuartzLogger.Error($"鎵嬪姩鍒涘缓浠诲姟锛氭湭鎵惧埌婧愬湴鍧�銆恵sourceAddress}銆戝搴旂殑杈撻�佺嚎璁惧", "InboundTaskFlowService");
+        return;
+    }
+
+    // 2. 杞崲涓� CommonConveyorLine 绫诲瀷
+    if (device is not CommonConveyorLine conveyorLine)
+    {
+        QuartzLogger.Error($"璁惧銆恵device.DeviceCode}銆戜笉鏄緭閫佺嚎绫诲瀷", "InboundTaskFlowService");
+        return;
+    }
+
+    // 3. 鑾峰彇瀛愯澶囩紪鐮�
+    string? childDeviceCode = device.DeviceProDTOs
+        .FirstOrDefault(d => d.DeviceChildCode == sourceAddress)?.DeviceChildCode;
+
+    if (string.IsNullOrEmpty(childDeviceCode))
+    {
+        QuartzLogger.Error($"婧愬湴鍧�銆恵sourceAddress}銆戞湭鎵惧埌瀵瑰簲鐨勫瓙璁惧缂栫爜", "InboundTaskFlowService");
+        return;
+    }
+
+    // 4. 鏋勯�� ConveyorLineTaskCommandNew
+    ConveyorLineTaskCommandNew command = new ConveyorLineTaskCommandNew
+    {
+        TaskNo = (short)task.TaskNum,
+        Source = short.Parse(sourceAddress),
+        Target = short.Parse(task.TargetAddress ?? "0"),
+        Barcode = task.PalletCode ?? string.Empty,
+        WCS_STB = 1,  // WCS宸插彂閫佹爣蹇�
+        WCS_ACK = 0,
+        PLC_STB = 0,
+        PLC_ACK = 0
+    };
+
+    // 5. 鍐欏叆PLC
+    bool success = conveyorLine.SendCommand(command, childDeviceCode);
+    if (success)
+    {
+        QuartzLogger.Info($"鎵嬪姩鍒涘缓鍏ュ簱浠诲姟宸插啓鍏ヨ緭閫佺嚎锛氫换鍔″彿銆恵task.TaskNum}銆戯紝婧愬湴鍧�銆恵sourceAddress}銆�", conveyorLine.DeviceCode);
+    }
+    else
+    {
+        QuartzLogger.Error($"鎵嬪姩鍒涘缓鍏ュ簱浠诲姟鍐欏叆杈撻�佺嚎澶辫触锛氫换鍔″彿銆恵task.TaskNum}銆戯紝婧愬湴鍧�銆恵sourceAddress}銆�", conveyorLine.DeviceCode);
+    }
+}
+```
+
+- [ ] **Step 3: 娣诲姞蹇呰鐨� using**
+
+```csharp
+using WIDESEAWCS_QuartzJob;
+using WIDESEAWCS_QuartzJob.ConveyorLine;
+using WIDESEAWCS_Tasks;
+using WIDESEAWCS_Core.LogHelper;
+```
+
+- [ ] **Step 4: 鎻愪氦**
+
+```bash
+git add WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/Flows/InboundTaskFlowService.cs
+git commit -m "feat(WCS): 鍏ュ簱浠诲姟绾夸綋鐐逛綅鏃跺啓鍏ヨ緭閫佺嚎浠诲姟"
+```
+
+---
+
+## 楠岃瘉娓呭崟
+
+- [ ] WMS 鍓嶇锛氱偣鍑�"鎵嬪姩鍒涘缓浠诲姟"鎸夐挳寮瑰嚭瀵硅瘽妗�
+- [ ] WMS 鍓嶇锛氬~鍐欒〃鍗曞悗鎻愪氦锛岃繑鍥炴垚鍔�
+- [ ] WMS 鍚庣锛氬垱寤轰换鍔″啓鍏ユ暟鎹簱
+- [ ] WMS 鍚庣锛氫换鍔℃垚鍔熷彂閫佺粰 WCS
+- [ ] WCS 鍚庣锛歊eceiveTask 鏀跺埌浠诲姟
+- [ ] WCS 鍚庣锛氳捣鐐逛负绾夸綋鐐逛綅鏃讹紝浠诲姟鍐欏叆 PLC 鎴愬姛
+- [ ] WCS 鍚庣锛氳捣鐐逛负鏅�氱偣浣嶆椂锛岃蛋鍘熸湁璺敱閫昏緫

--
Gitblit v1.9.3