From 5e851678cc02257bbbd179446de36082430ca5bc Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期一, 13 四月 2026 15:12:04 +0800
Subject: [PATCH] feat(MES): 添加Mes_Log扩展逻辑

---
 Code/docs/superpowers/plans/2026-04-13-mes-api-log-page-plan.md | 1430 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 1,430 insertions(+), 0 deletions(-)

diff --git a/Code/docs/superpowers/plans/2026-04-13-mes-api-log-page-plan.md b/Code/docs/superpowers/plans/2026-04-13-mes-api-log-page-plan.md
new file mode 100644
index 0000000..37ae211
--- /dev/null
+++ b/Code/docs/superpowers/plans/2026-04-13-mes-api-log-page-plan.md
@@ -0,0 +1,1430 @@
+# MES 鎺ュ彛璋冪敤鏃ュ織椤甸潰瀹炴柦璁″垝
+
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task.
+
+**鐩爣:** 鍦� WMS 绯荤粺涓坊鍔� MES 鎺ュ彛璋冪敤鏃ュ織鏌ョ湅椤甸潰锛屾彁渚涚患鍚堟�х殑鏃ュ織鏌ヨ銆佺粺璁″拰绠$悊鍔熻兘銆�
+
+**鏋舵瀯:** 鍚庣浣跨敤 C# / ASP.NET Core锛屽墠绔娇鐢� Vue 3 + Element Plus銆傚鐢ㄧ幇鏈� view-grid 妯″紡锛屾坊鍔犺嚜瀹氫箟缁熻鍗$墖銆�
+
+**鎶�鏈爤:** .NET 8, SqlSugar, Vue 3, Element Plus 2.2.14, Vite
+
+**鐗堟湰:** v0.3 (淇鐗� - 淇瀹℃煡闂)
+
+---
+
+## 璁捐鏂囨。
+
+鍙傝��: `docs/superpowers/specs/2026-04-13-mes-api-log-page-design.md`
+
+---
+
+## 鏂囦欢缁撴瀯
+
+### 鍚庣鏂板缓鏂囦欢
+```
+WMS/WIDESEA_WMSServer/
+鈹溾攢鈹� WIDESEA_DTO/MES/
+鈹�   鈹溾攢鈹� MesLogQueryDto.cs           # 鏌ヨ璇锋眰 DTO
+鈹�   鈹溾攢鈹� MesLogStatisticsDto.cs       # 缁熻鏁版嵁 DTO
+鈹�   鈹溾攢鈹� MesLogListItemDto.cs         # 鍒楄〃椤� DTO
+鈹�   鈹斺攢鈹� MesLogDetailDto.cs           # 璇︽儏 DTO
+鈹溾攢鈹� WIDESEA_IMesService/
+鈹�   鈹斺攢鈹� IMesLogService.cs            # 鎵╁睍鏈嶅姟鎺ュ彛
+鈹溾攢鈹� WIDESEA_MesService/
+鈹�   鈹斺攢鈹� MesLogService.cs             # 鏈嶅姟瀹炵幇
+鈹斺攢鈹� WIDESEA_WMSServer/Controllers/Mes/
+    鈹斺攢鈹� MesLogController.cs          # API 鎺у埗鍣�
+```
+
+### 鍓嶇鏂板缓鏂囦欢
+```
+WMS/WIDESEA_WMSClient/src/
+鈹溾攢鈹� components/
+鈹�   鈹斺攢鈹� MesLogStatistics.vue         # 缁熻鍗$墖缁勪欢
+鈹溾攢鈹� views/system/
+鈹�   鈹斺攢鈹� Mes_Log.vue                  # 鏃ュ織椤甸潰
+鈹斺攢鈹� extension/system/
+    鈹斺攢鈹� Mes_Log.jsx                  # 涓氬姟鎵╁睍閫昏緫
+```
+
+### 淇敼鏂囦欢
+```
+WMS/WIDESEA_WMSClient/src/
+鈹斺攢鈹� router/viewGird.js               # 娣诲姞璺敱閰嶇疆
+```
+
+---
+
+## Task 1: 鍒涘缓鍚庣 DTO 鏂囦欢
+
+**Files:**
+- Create: `WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLogQueryDto.cs`
+- Create: `WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLogStatisticsDto.cs`
+- Create: `WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLogListItemDto.cs`
+- Create: `WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLogDetailDto.cs`
+
+### Step 1: 鍒涘缓 MesLogQueryDto.cs
+
+```csharp
+using System;
+
+namespace WIDESEA_DTO.MES
+{
+    /// <summary>
+    /// MES鏃ュ織鏌ヨ璇锋眰DTO
+    /// </summary>
+    public class MesLogQueryDto
+    {
+        /// <summary>
+        /// 鎺ュ彛绫诲瀷: BindContainer, UnBindContainer, ContainerNgReport, InboundInContainer, OutboundInContainer
+        /// </summary>
+        public string ApiType { get; set; }
+
+        /// <summary>
+        /// 鎴愬姛鐘舵��: null-鍏ㄩ儴, true-鎴愬姛, false-澶辫触
+        /// </summary>
+        public bool? IsSuccess { get; set; }
+
+        /// <summary>
+        /// 寮�濮嬫椂闂达紙鍓嶇 dateRange 瀛楁鏄犲皠锛歞ateRange[0] 鈫� StartTime锛�
+        /// </summary>
+        public DateTime? StartTime { get; set; }
+
+        /// <summary>
+        /// 缁撴潫鏃堕棿锛堝墠绔� dateRange 瀛楁鏄犲皠锛歞ateRange[1] 鈫� EndTime锛�
+        /// </summary>
+        public DateTime? EndTime { get; set; }
+
+        /// <summary>
+        /// 鍒涘缓浜猴紙鎿嶄綔浜猴級
+        /// </summary>
+        public string Creator { get; set; }
+
+        /// <summary>
+        /// 鏈�灏忚�楁椂锛堟绉掞級锛堝墠绔� elapsedRange 瀛楁鏄犲皠锛歟lapsedRange[0] 鈫� MinElapsedMs锛�
+        /// </summary>
+        public int? MinElapsedMs { get; set; }
+
+        /// <summary>
+        /// 鏈�澶ц�楁椂锛堟绉掞級锛堝墠绔� elapsedRange 瀛楁鏄犲皠锛歟lapsedRange[1] 鈫� MaxElapsedMs锛�
+        /// </summary>
+        public int? MaxElapsedMs { get; set; }
+
+        /// <summary>
+        /// 閿欒淇℃伅鍏抽敭瀛�
+        /// </summary>
+        public string ErrorKeyword { get; set; }
+
+        /// <summary>
+        /// 璇锋眰JSON鍏抽敭瀛�
+        /// </summary>
+        public string JsonRequestKeyword { get; set; }
+
+        /// <summary>
+        /// 鍝嶅簲JSON鍏抽敭瀛�
+        /// </summary>
+        public string JsonResponseKeyword { get; set; }
+    }
+}
+```
+
+### Step 2: 鍒涘缓 MesLogStatisticsDto.cs
+
+```csharp
+using System;
+using System.Collections.Generic;
+
+namespace WIDESEA_DTO.MES
+{
+    /// <summary>
+    /// MES鏃ュ織缁熻鏁版嵁DTO
+    /// </summary>
+    public class MesLogStatisticsDto
+    {
+        /// <summary>
+        /// 鎬昏皟鐢ㄦ鏁�
+        /// </summary>
+        public int TotalCount { get; set; }
+
+        /// <summary>
+        /// 鎴愬姛娆℃暟
+        /// </summary>
+        public int SuccessCount { get; set; }
+
+        /// <summary>
+        /// 鎴愬姛鐜囷紙鐧惧垎姣旓級
+        /// </summary>
+        public double SuccessRate { get; set; }
+
+        /// <summary>
+        /// 澶辫触娆℃暟
+        /// </summary>
+        public int FailedCount { get; set; }
+
+        /// <summary>
+        /// 骞冲潎鑰楁椂锛堟绉掞級
+        /// </summary>
+        public double AvgElapsedMs { get; set; }
+
+        /// <summary>
+        /// 鏈�澶ц�楁椂锛堟绉掞級
+        /// </summary>
+        public int MaxElapsedMs { get; set; }
+
+        /// <summary>
+        /// 浠婃棩璋冪敤娆℃暟
+        /// </summary>
+        public int TodayCount { get; set; }
+
+        /// <summary>
+        /// 鍚勬帴鍙g被鍨嬭皟鐢ㄦ鏁扮粺璁�
+        /// </summary>
+        public Dictionary<string, int> ApiTypeCounts { get; set; }
+    }
+}
+```
+
+### Step 3: 鍒涘缓 MesLogListItemDto.cs
+
+```csharp
+using System;
+
+namespace WIDESEA_DTO.MES
+{
+    /// <summary>
+    /// MES鏃ュ織鍒楄〃椤笵TO
+    /// </summary>
+    public class MesLogListItemDto
+    {
+        /// <summary>
+        /// 涓婚敭ID
+        /// </summary>
+        public long Id { get; set; }
+
+        /// <summary>
+        /// 鎺ュ彛绫诲瀷
+        /// </summary>
+        public string ApiType { get; set; }
+
+        /// <summary>
+        /// 鏄惁鎴愬姛
+        /// </summary>
+        public bool IsSuccess { get; set; }
+
+        /// <summary>
+        /// 璇锋眰JSON棰勮锛堝墠200瀛楃锛�
+        /// </summary>
+        public string RequestJsonPreview { get; set; }
+
+        /// <summary>
+        /// 鍝嶅簲JSON棰勮锛堝墠200瀛楃锛�
+        /// </summary>
+        public string ResponseJsonPreview { get; set; }
+
+        /// <summary>
+        /// 閿欒淇℃伅
+        /// </summary>
+        public string ErrorMessage { get; set; }
+
+        /// <summary>
+        /// 鑰楁椂锛堟绉掞級
+        /// </summary>
+        public int ElapsedMs { get; set; }
+
+        /// <summary>
+        /// 鍒涘缓鏃堕棿
+        /// </summary>
+        public DateTime CreateDate { get; set; }
+
+        /// <summary>
+        /// 鍒涘缓浜�
+        /// </summary>
+        public string Creator { get; set; }
+    }
+}
+```
+
+### Step 4: 鍒涘缓 MesLogDetailDto.cs
+
+```csharp
+using System;
+
+namespace WIDESEA_DTO.MES
+{
+    /// <summary>
+    /// MES鏃ュ織璇︽儏DTO
+    /// </summary>
+    public class MesLogDetailDto : MesLogListItemDto
+    {
+        /// <summary>
+        /// 瀹屾暣璇锋眰JSON
+        /// </summary>
+        public string RequestJson { get; set; }
+
+        /// <summary>
+        /// 瀹屾暣鍝嶅簲JSON
+        /// </summary>
+        public string ResponseJson { get; set; }
+
+        /// <summary>
+        /// 淇敼鏃堕棿
+        /// </summary>
+        public DateTime? ModifyDate { get; set; }
+
+        /// <summary>
+        /// 淇敼浜�
+        /// </summary>
+        public string Modifier { get; set; }
+    }
+}
+```
+
+### Step 5: 鎻愪氦 DTO 鏂囦欢
+
+```bash
+git add WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLog*.cs
+git commit -m "feat(MES): 娣诲姞MES鏃ュ織鏌ヨDTO鏂囦欢
+
+- MesLogQueryDto: 鏌ヨ璇锋眰鍙傛暟
+- MesLogStatisticsDto: 缁熻鏁版嵁
+- MesLogListItemDto: 鍒楄〃椤�
+- MesLogDetailDto: 璇︽儏
+
+Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
+```
+
+---
+
+## Task 2: 鎵╁睍 IMesLogService 鎺ュ彛
+
+**Files:**
+- Modify: `WMS/WIDESEA_WMSServer/WIDESEA_IMesService/IMesLogService.cs`
+
+### Step 1: 璇诲彇鐜版湁鎺ュ彛
+
+```bash
+cat WMS/WIDESEA_WMSServer/WIDESEA_IMesService/IMesLogService.cs
+```
+
+### Step 2: 娣诲姞鏂版柟娉曞埌鎺ュ彛
+
+鍦ㄧ幇鏈夋帴鍙d腑娣诲姞浠ヤ笅鏂规硶锛�
+
+```csharp
+/// <summary>
+/// 鍒嗛〉鏌ヨMES鏃ュ織
+/// </summary>
+/// <param name="query">鏌ヨ鏉′欢</param>
+/// <param name="page">椤电爜</param>
+/// <param name="pageSize">姣忛〉鏁伴噺</param>
+/// <returns>鏃ュ織鍒楄〃鍜屾�绘暟</returns>
+Task<(List<MesLogListItemDto> items, int total)> GetPageAsync(MesLogQueryDto query, int page, int pageSize);
+
+/// <summary>
+/// 鑾峰彇鍗曟潯鏃ュ織璇︽儏
+/// </summary>
+/// <param name="id">鏃ュ織ID</param>
+/// <returns>鏃ュ織璇︽儏</returns>
+Task<MesLogDetailDto> GetDetailAsync(long id);
+
+/// <summary>
+/// 鑾峰彇缁熻鏁版嵁
+/// </summary>
+/// <param name="query">鏌ヨ鏉′欢</param>
+/// <returns>缁熻鏁版嵁</returns>
+Task<MesLogStatisticsDto> GetStatisticsAsync(MesLogQueryDto query);
+
+/// <summary>
+/// 瀵煎嚭鏃ュ織鏁版嵁
+/// </summary>
+/// <param name="query">鏌ヨ鏉′欢</param>
+/// <returns>Excel鏂囦欢瀛楄妭鏁扮粍</returns>
+Task<byte[]> ExportAsync(MesLogQueryDto query);
+```
+
+### Step 3: 娣诲姞 using 璇彞
+
+纭繚鏂囦欢椤堕儴鏈夛細
+```csharp
+using WIDESEA_DTO.MES;
+```
+
+### Step 4: 鎻愪氦鎺ュ彛鎵╁睍
+
+```bash
+git add WMS/WIDESEA_WMSServer/WIDESEA_IMesService/IMesLogService.cs
+git commit -m "feat(MES): 鎵╁睍IMesLogService鎺ュ彛
+
+- 娣诲姞鍒嗛〉鏌ヨ鏂规硶 GetPageAsync
+- 娣诲姞璇︽儏鏌ヨ鏂规硶 GetDetailAsync
+- 娣诲姞缁熻鏌ヨ鏂规硶 GetStatisticsAsync
+- 娣诲姞瀵煎嚭鏂规硶 ExportAsync
+
+Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
+```
+
+---
+
+## Task 3: 瀹炵幇 MesLogService 鏂规硶
+
+**Files:**
+- Modify: `WMS/WIDESEA_WMSServer/WIDESEA_MesService/MesLogService.cs`
+
+### Step 1: 璇诲彇鐜版湁鏈嶅姟瀹炵幇
+
+```bash
+cat WMS/WIDESEA_WMSServer/WIDESEA_MesService/MesLogService.cs
+```
+
+### Step 2: 娣诲姞 GetPageAsync 瀹炵幇
+
+```csharp
+/// <summary>
+/// 鍒嗛〉鏌ヨMES鏃ュ織
+/// </summary>
+public async Task<(List<MesLogListItemDto> items, int total)> GetPageAsync(MesLogQueryDto query, int page, int pageSize)
+{
+    var dbQuery = _db.Queryable<WIDESEA_Model.Models.Mes.Dt_MesApiLog>();
+
+    // 鍔ㄦ�佹潯浠剁瓫閫�
+    if (!string.IsNullOrEmpty(query.ApiType))
+    {
+        dbQuery = dbQuery.Where(x => x.ApiType == query.ApiType);
+    }
+
+    if (query.IsSuccess.HasValue)
+    {
+        dbQuery = dbQuery.Where(x => x.IsSuccess == query.IsSuccess.Value);
+    }
+
+    if (query.StartTime.HasValue)
+    {
+        dbQuery = dbQuery.Where(x => x.CreateDate >= query.StartTime.Value);
+    }
+
+    if (query.EndTime.HasValue)
+    {
+        dbQuery = dbQuery.Where(x => x.CreateDate <= query.EndTime.Value);
+    }
+
+    if (!string.IsNullOrEmpty(query.Creator))
+    {
+        dbQuery = dbQuery.Where(x => x.Creator.Contains(query.Creator));
+    }
+
+    if (query.MinElapsedMs.HasValue)
+    {
+        dbQuery = dbQuery.Where(x => x.ElapsedMs >= query.MinElapsedMs.Value);
+    }
+
+    if (query.MaxElapsedMs.HasValue)
+    {
+        dbQuery = dbQuery.Where(x => x.ElapsedMs <= query.MaxElapsedMs.Value);
+    }
+
+    if (!string.IsNullOrEmpty(query.ErrorKeyword))
+    {
+        dbQuery = dbQuery.Where(x => x.ErrorMessage.Contains(query.ErrorKeyword));
+    }
+
+    if (!string.IsNullOrEmpty(query.JsonRequestKeyword))
+    {
+        dbQuery = dbQuery.Where(x => x.RequestJson.Contains(query.JsonRequestKeyword));
+    }
+
+    if (!string.IsNullOrEmpty(query.JsonResponseKeyword))
+    {
+        dbQuery = dbQuery.Where(x => x.ResponseJson.Contains(query.JsonResponseKeyword));
+    }
+
+    // 鑾峰彇鎬绘暟
+    var total = await dbQuery.CountAsync();
+
+    // 鍒嗛〉鏌ヨ
+    var entities = await dbQuery
+        .OrderByDescending(x => x.CreateDate)
+        .Skip((page - 1) * pageSize)
+        .Take(pageSize)
+        .ToListAsync();
+
+    // 鏄犲皠鍒� DTO
+    var items = entities.Select(e => new MesLogListItemDto
+    {
+        Id = e.Id,
+        ApiType = e.ApiType,
+        IsSuccess = e.IsSuccess,
+        RequestJsonPreview = e.RequestJson?.Length > 200 ? e.RequestJson.Substring(0, 200) + "..." : e.RequestJson,
+        ResponseJsonPreview = e.ResponseJson?.Length > 200 ? e.ResponseJson.Substring(0, 200) + "..." : e.ResponseJson,
+        ErrorMessage = e.ErrorMessage,
+        ElapsedMs = e.ElapsedMs,
+        CreateDate = e.CreateDate,
+        Creator = e.Creator
+    }).ToList();
+
+    return (items, total);
+}
+```
+
+### Step 3: 娣诲姞 GetDetailAsync 瀹炵幇
+
+```csharp
+/// <summary>
+/// 鑾峰彇鍗曟潯鏃ュ織璇︽儏
+/// </summary>
+public async Task<MesLogDetailDto> GetDetailAsync(long id)
+{
+    var entity = await _db.Queryable<WIDESEA_Model.Models.Mes.Dt_MesApiLog>()
+        .FirstAsync(x => x.Id == id);
+
+    if (entity == null)
+    {
+        return null;
+    }
+
+    return new MesLogDetailDto
+    {
+        Id = entity.Id,
+        ApiType = entity.ApiType,
+        IsSuccess = entity.IsSuccess,
+        RequestJson = entity.RequestJson,
+        ResponseJson = entity.ResponseJson,
+        RequestJsonPreview = entity.RequestJson?.Length > 200 ? entity.RequestJson.Substring(0, 200) + "..." : entity.RequestJson,
+        ResponseJsonPreview = entity.ResponseJson?.Length > 200 ? entity.ResponseJson.Substring(0, 200) + "..." : entity.ResponseJson,
+        ErrorMessage = entity.ErrorMessage,
+        ElapsedMs = entity.ElapsedMs,
+        CreateDate = entity.CreateDate,
+        Creator = entity.Creator,
+        ModifyDate = entity.ModifyDate,
+        Modifier = entity.Modifier
+    };
+}
+```
+
+### Step 4: 娣诲姞 GetStatisticsAsync 瀹炵幇
+
+```csharp
+/// <summary>
+/// 鑾峰彇缁熻鏁版嵁
+/// </summary>
+public async Task<MesLogStatisticsDto> GetStatisticsAsync(MesLogQueryDto query)
+{
+    var dbQuery = _db.Queryable<WIDESEA_Model.Models.Mes.Dt_MesApiLog>();
+
+    // 搴旂敤鐩稿悓鐨勭瓫閫夋潯浠讹紙浣嗕笉鍒嗛〉锛�
+    if (!string.IsNullOrEmpty(query.ApiType))
+    {
+        dbQuery = dbQuery.Where(x => x.ApiType == query.ApiType);
+    }
+
+    if (query.IsSuccess.HasValue)
+    {
+        dbQuery = dbQuery.Where(x => x.IsSuccess == query.IsSuccess.Value);
+    }
+
+    if (query.StartTime.HasValue)
+    {
+        dbQuery = dbQuery.Where(x => x.CreateDate >= query.StartTime.Value);
+    }
+
+    if (query.EndTime.HasValue)
+    {
+        dbQuery = dbQuery.Where(x => x.CreateDate <= query.EndTime.Value);
+    }
+
+    var allData = await dbQuery.ToListAsync();
+
+    // 浠婃棩鏁版嵁
+    var today = DateTime.Today;
+    var todayData = allData.Where(x => x.CreateDate >= today).ToList();
+
+    // 璁$畻缁熻鏁版嵁
+    var totalCount = allData.Count;
+    var successCount = allData.Count(x => x.IsSuccess);
+    var failedCount = totalCount - successCount;
+    var successRate = totalCount > 0 ? (successCount * 100.0 / totalCount) : 0;
+
+    return new MesLogStatisticsDto
+    {
+        TotalCount = totalCount,
+        SuccessCount = successCount,
+        FailedCount = failedCount,
+        SuccessRate = Math.Round(successRate, 2),
+        AvgElapsedMs = totalCount > 0 ? allData.Average(x => x.ElapsedMs) : 0,
+        MaxElapsedMs = totalCount > 0 ? allData.Max(x => x.ElapsedMs) : 0,
+        TodayCount = todayData.Count,
+        ApiTypeCounts = allData.GroupBy(x => x.ApiType)
+            .ToDictionary(g => g.Key, g => g.Count())
+    };
+}
+```
+
+### Step 5: 娣诲姞 ExportAsync 瀹炵幇
+
+```csharp
+/// <summary>
+/// 瀵煎嚭鏃ュ織鏁版嵁
+/// </summary>
+public async Task<byte[]> ExportAsync(MesLogQueryDto query)
+{
+    // 鑾峰彇鎵�鏈夌鍚堟潯浠剁殑鏁版嵁锛堜笉鍒嗛〉锛�
+    var (items, _) = await GetPageAsync(query, 1, int.MaxValue);
+
+    // 浣跨敤妗嗘灦鍐呯疆鐨� Excel 瀵煎嚭鍔熻兘
+    // 娉ㄦ剰锛氳繖閲岄渶瑕佹牴鎹」鐩疄闄呬娇鐢ㄧ殑瀵煎嚭搴撹皟鏁�
+    // 鍙傝�� ServiceBase.Export() 鐨勫疄鐜版柟寮�
+
+    // 涓存椂鏂规锛氫娇鐢� CSV 鏍煎紡
+    using var memoryStream = new MemoryStream();
+    using var writer = new StreamWriter(memoryStream, System.Text.Encoding.UTF8);
+
+    // CSV 澶撮儴
+    writer.WriteLine("ID,鎺ュ彛绫诲瀷,鐘舵��,鑰楁椂(ms),閿欒淇℃伅,鍒涘缓鏃堕棿,鍒涘缓浜�");
+
+    // CSV 鏁版嵁琛�
+    foreach (var item in items)
+    {
+        writer.WriteLine($"{item.Id},{item.ApiType},{(item.IsSuccess ? "鎴愬姛" : "澶辫触")},{item.ElapsedMs},\"{item.ErrorMessage?.Replace("\"", "\"\"")}\",{item.CreateDate:yyyy-MM-dd HH:mm:ss},{item.Creator}");
+    }
+
+    writer.Flush();
+    return memoryStream.ToArray();
+}
+```
+
+### Step 6: 娣诲姞 using 璇彞
+
+纭繚鏂囦欢椤堕儴鏈夛細
+```csharp
+using WIDESEA_DTO.MES;
+```
+
+### Step 7: 鎻愪氦鏈嶅姟瀹炵幇
+
+```bash
+git add WMS/WIDESEA_WMSServer/WIDESEA_MesService/MesLogService.cs
+git commit -m "feat(MES): 瀹炵幇MesLogService鏌ヨ鏂规硶
+
+- 瀹炵幇鍒嗛〉鏌ヨ GetPageAsync
+- 瀹炵幇璇︽儏鏌ヨ GetDetailAsync
+- 瀹炵幇缁熻鏌ヨ GetStatisticsAsync
+- 瀹炵幇瀵煎嚭 ExportAsync (CSV鏍煎紡)
+
+Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
+```
+
+---
+
+## Task 4: 鍒涘缓 MesLogController
+
+**Files:**
+- Create: `WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Mes/MesLogController.cs`
+
+### Step 1: 鍒涘缓鎺у埗鍣ㄦ枃浠�
+
+```csharp
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using WIDESEA_Core;
+using WIDESEA_DTO.MES;
+using WIDESEA_IBasicService;
+using WIDESEA_IMesService;
+
+namespace WIDESEA_WMSServer.Controllers.Mes
+{
+    /// <summary>
+    /// MES鎺ュ彛鏃ュ織鎺у埗鍣�
+    /// </summary>
+    [Route("api/MesLog")]
+    [ApiController]
+    [Authorize]
+    public class MesLogController : ControllerBase
+    {
+        private readonly IMesLogService _mesLogService;
+
+        /// <summary>
+        /// 鏋勯�犲嚱鏁�
+        /// </summary>
+        public MesLogController(IMesLogService mesLogService)
+        {
+            _mesLogService = mesLogService;
+        }
+
+        /// <summary>
+        /// 鍒嗛〉鏌ヨMES鏃ュ織
+        /// </summary>
+        /// <param name="query">鏌ヨ鏉′欢</param>
+        /// <param name="page">椤电爜锛岄粯璁�1</param>
+        /// <param name="pageSize">姣忛〉鏁伴噺锛岄粯璁�20</param>
+        /// <returns>鍒嗛〉缁撴灉</returns>
+        [HttpPost("page")]
+        public async Task<WebResponseContent> GetPage([FromBody] MesLogQueryDto query, [FromQuery] int page = 1, [FromQuery] int pageSize = 20)
+        {
+            var response = new WebResponseContent();
+            try
+            {
+                var (items, total) = await _mesLogService.GetPageAsync(query, page, pageSize);
+                return response.OK(null, new { rows = items, total = total });
+            }
+            catch (Exception ex)
+            {
+                return response.Error($"鏌ヨ澶辫触: {ex.Message}");
+            }
+        }
+
+        /// <summary>
+        /// 鑾峰彇鏃ュ織璇︽儏
+        /// </summary>
+        /// <param name="id">鏃ュ織ID</param>
+        /// <returns>鏃ュ織璇︽儏</returns>
+        [HttpGet("{id}")]
+        public async Task<WebResponseContent> GetDetail(long id)
+        {
+            var response = new WebResponseContent();
+            try
+            {
+                var detail = await _mesLogService.GetDetailAsync(id);
+                if (detail == null)
+                {
+                    return response.Error("鏃ュ織涓嶅瓨鍦�");
+                }
+                return response.OK(null, detail);
+            }
+            catch (Exception ex)
+            {
+                return response.Error($"鏌ヨ澶辫触: {ex.Message}");
+            }
+        }
+
+        /// <summary>
+        /// 鑾峰彇缁熻鏁版嵁
+        /// </summary>
+        /// <param name="query">鏌ヨ鏉′欢锛堝彲閫夛級</param>
+        /// <returns>缁熻鏁版嵁</returns>
+        [HttpGet("statistics")]
+        public async Task<WebResponseContent> GetStatistics([FromQuery] MesLogQueryDto query)
+        {
+            var response = new WebResponseContent();
+            try
+            {
+                var statistics = await _mesLogService.GetStatisticsAsync(query ?? new MesLogQueryDto());
+                return response.OK(null, statistics);
+            }
+            catch (Exception ex)
+            {
+                return response.Error($"鏌ヨ澶辫触: {ex.Message}");
+            }
+        }
+
+        /// <summary>
+        /// 瀵煎嚭鏃ュ織
+        /// </summary>
+        /// <param name="query">鏌ヨ鏉′欢</param>
+        /// <returns>Excel鏂囦欢</returns>
+        [HttpPost("export")]
+        public async Task<IActionResult> Export([FromBody] MesLogQueryDto query)
+        {
+            try
+            {
+                var data = await _mesLogService.ExportAsync(query ?? new MesLogQueryDto());
+                var fileName = $"MES鎺ュ彛鏃ュ織_{DateTime.Now:yyyyMMdd_HHmmss}.csv";
+                return File(data, "text/csv; charset=utf-8", fileName);
+            }
+            catch (Exception ex)
+            {
+                return BadRequest(new { error = ex.Message });
+            }
+        }
+    }
+}
+```
+
+### Step 2: 鎻愪氦鎺у埗鍣�
+
+```bash
+git add WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Mes/MesLogController.cs
+git commit -m "feat(MES): 娣诲姞MesLogController鎺у埗鍣�
+
+- POST /api/MesLog/page - 鍒嗛〉鏌ヨ
+- GET /api/MesLog/{id} - 璇︽儏鏌ヨ
+- GET /api/MesLog/statistics - 缁熻鏁版嵁
+- POST /api/MesLog/export - 瀵煎嚭CSV
+
+Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
+```
+
+---
+
+## Task 5: 鍒涘缓鍓嶇缁熻鍗$墖缁勪欢
+
+**Files:**
+- Create: `WMS/WIDESEA_WMSClient/src/components/MesLogStatistics.vue`
+
+### Step 1: 鍒涘缓缁勪欢鏂囦欢
+
+```vue
+<template>
+  <div class="mes-log-statistics">
+    <el-row :gutter="16">
+      <el-col :span="6">
+        <el-card shadow="hover" class="stat-card stat-primary">
+          <div class="stat-content">
+            <div class="stat-label">鎬昏皟鐢ㄦ鏁�</div>
+            <div class="stat-value">{{ statistics.totalCount }}</div>
+            <div class="stat-unit">娆�</div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card shadow="hover" class="stat-card" :class="statistics.successRate >= 90 ? 'stat-success' : 'stat-warning'">
+          <div class="stat-content">
+            <div class="stat-label">鎴愬姛鐜�</div>
+            <div class="stat-value">{{ statistics.successRate }}%</div>
+            <div class="stat-sub">
+              鎴愬姛: {{ statistics.successCount }} / 澶辫触: {{ statistics.failedCount }}
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card shadow="hover" class="stat-card stat-info">
+          <div class="stat-content">
+            <div class="stat-label">骞冲潎鑰楁椂</div>
+            <div class="stat-value">{{ Math.round(statistics.avgElapsedMs) }}</div>
+            <div class="stat-unit">ms</div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card shadow="hover" class="stat-card stat-secondary">
+          <div class="stat-content">
+            <div class="stat-label">浠婃棩璋冪敤</div>
+            <div class="stat-value">{{ statistics.todayCount }}</div>
+            <div class="stat-unit">娆�</div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { ref, onMounted } from "vue";
+import http from "@/api/axios";
+
+export default {
+  name: "MesLogStatistics",
+  emits: ["refresh"],
+  setup(props, { emit }) {
+    const statistics = ref({
+      totalCount: 0,
+      successCount: 0,
+      failedCount: 0,
+      successRate: 0,
+      avgElapsedMs: 0,
+      todayCount: 0
+    });
+
+    const fetchStatistics = async () => {
+      try {
+        const res = await http.get("/api/MesLog/statistics");
+        if (res.status) {
+          statistics.value = res.data;
+          emit("refresh");
+        }
+      } catch (error) {
+        console.error("鑾峰彇缁熻鏁版嵁澶辫触:", error);
+      }
+    };
+
+    onMounted(() => {
+      fetchStatistics();
+    });
+
+    return {
+      statistics,
+      fetchStatistics
+    };
+  }
+};
+</script>
+
+<style scoped>
+.mes-log-statistics {
+  margin-bottom: 16px;
+}
+
+.stat-card {
+  text-align: center;
+}
+
+.stat-content {
+  padding: 8px 0;
+}
+
+.stat-label {
+  font-size: 14px;
+  color: #909399;
+  margin-bottom: 8px;
+}
+
+.stat-value {
+  font-size: 28px;
+  font-weight: bold;
+  margin-bottom: 4px;
+}
+
+.stat-unit {
+  font-size: 12px;
+  color: #909399;
+}
+
+.stat-sub {
+  font-size: 12px;
+  color: #606266;
+  margin-top: 4px;
+}
+
+.stat-primary .stat-value { color: #409EFF; }
+.stat-success .stat-value { color: #67C23A; }
+.stat-warning .stat-value { color: #E6A23C; }
+.stat-info .stat-value { color: #909399; }
+.stat-secondary .stat-value { color: #909399; }
+</style>
+```
+
+### Step 2: 鎻愪氦缁勪欢
+
+```bash
+git add WMS/WIDESEA_WMSClient/src/components/MesLogStatistics.vue
+git commit -m "feat(MES): 娣诲姞MesLogStatistics缁熻鍗$墖缁勪欢
+
+- 鏄剧ず鎬昏皟鐢ㄦ鏁般�佹垚鍔熺巼銆佸钩鍧囪�楁椂銆佷粖鏃ヨ皟鐢�
+- 浣跨敤 el-card 鑷畾涔夊疄鐜帮紙鍏煎 Element Plus 2.2.14锛�
+- 棰滆壊鏍囪瘑锛氳摑鑹�/缁胯壊/姗欒壊/鐏拌壊
+
+Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
+```
+
+---
+
+## Task 7: 鍒涘缓鍓嶇鎵╁睍閫昏緫
+
+**Files:**
+- Create: `WMS/WIDESEA_WMSClient/src/extension/system/Mes_Log.jsx`
+
+### Step 1: 鍒涘缓鎵╁睍鏂囦欢
+
+```jsx
+import { h, resolveComponent } from 'vue';
+
+let extension = {
+  components: {
+    // 鍔ㄦ�佹墿鍏呯粍浠舵垨缁勪欢璺緞
+    gridHeader: "",
+    gridBody: '',
+    gridFooter: "",
+    modelHeader: "",
+    modelBody: "",
+    modelFooter: ""
+  },
+  buttons: [], // 鎵╁睍鐨勬寜閽�
+  methods: {
+    // 浜嬩欢鎵╁睍
+    onInit() {
+      console.log("mes_log init");
+      this.setFiexdSearchForm(true);
+    },
+
+    onInited() {
+      this.height = this.height - 240; // 涓虹粺璁″崱鐗囬鐣欑┖闂�
+
+      // 娣诲姞棰勮鏂规硶
+      this.previewJson = (jsonStr) => {
+        if (!jsonStr) return '-';
+        try {
+          const obj = JSON.parse(jsonStr);
+          return JSON.stringify(obj, null, 2).substring(0, 200) + '...';
+        } catch {
+          return String(jsonStr).substring(0, 200) + '...';
+        }
+      };
+    },
+
+    // 琛岀偣鍑讳簨浠� - 鏄剧ず JSON 璇︽儏
+    rowClick({ row, column }) {
+      // 濡傛灉鐐瑰嚮鐨勬槸璇锋眰鎴栧搷搴斿垪锛屾樉绀鸿鎯呭脊绐�
+      if (column.property === 'requestJson' || column.property === 'responseJson') {
+        this.showJsonDetail(row);
+      }
+    },
+
+    // 鏄剧ず JSON 璇︽儏寮圭獥
+    showJsonDetail(row) {
+      const elDialog = resolveComponent('el-dialog');
+
+      // 鍒涘缓涓存椂寮圭獥
+      this.$alert('', 'JSON 璇︽儏', {
+        message: h('div', { class: 'json-detail-dialog' }, [
+          h('el-tabs', { modelValue: 'request' }, [
+            h('el-tab-pane', { label: '璇锋眰', name: 'request' }, [
+              h('pre', { class: 'json-content' }, this.formatJson(row.requestJson))
+            ]),
+            h('el-tab-pane', { label: '鍝嶅簲', name: 'response' }, [
+              h('pre', { class: 'json-content' }, this.formatJson(row.responseJson))
+            ])
+          ])
+        ]),
+        customClass: 'mes-json-detail-dialog',
+        dangerouslyUseHTMLString: false
+      });
+    },
+
+    // 鏍煎紡鍖� JSON
+    formatJson(jsonStr) {
+      if (!jsonStr) return '{}';
+      try {
+        const obj = typeof jsonStr === 'string' ? JSON.parse(jsonStr) : jsonStr;
+        return JSON.stringify(obj, null, 2);
+      } catch {
+        return String(jsonStr);
+      }
+    }
+  }
+};
+
+export default extension;
+```
+
+### Step 2: 鎻愪氦鎵╁睍鏂囦欢
+
+```bash
+git add WMS/WIDESEA_WMSClient/src/extension/system/Mes_Log.jsx
+git commit -m "feat(MES): 娣诲姞Mes_Log鎵╁睍閫昏緫
+
+- 娣诲姞 previewJson 杈呭姪鍑芥暟
+- 娣诲姞琛岀偣鍑讳簨浠跺鐞�
+- 娣诲姞 JSON 璇︽儏鏄剧ず鍔熻兘
+- 璋冩暣楂樺害涓虹粺璁″崱鐗囬鐣欑┖闂�
+
+Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
+```
+
+---
+
+## Task 8: 鍒涘缓鍓嶇椤甸潰
+
+**Files:**
+- Create: `WMS/WIDESEA_WMSClient/src/views/system/Mes_Log.vue`
+
+### Step 1: 鍒涘缓椤甸潰鏂囦欢
+
+```vue
+<!--
+*Author锛歋ystem
+ *Contact锛�-
+ *浠g爜鐢辨鏋剁敓鎴�,浠讳綍鏇存敼閮藉彲鑳藉鑷磋浠g爜鐢熸垚鍣ㄨ鐩�
+ *涓氬姟璇峰湪@/extension/system/Mes_Log.jsx姝ゅ缂栧啓
+ -->
+<template>
+  <div class="mes-log-page">
+    <!-- 缁熻鍗$墖鍖哄煙 -->
+    <mes-log-statistics ref="statistics" />
+
+    <!-- 鏃ュ織鍒楄〃 -->
+    <view-grid
+      ref="grid"
+      :columns="columns"
+      :detail="detail"
+      :editFormFields="editFormFields"
+      :editFormOptions="editFormOptions"
+      :searchFormFields="searchFormFields"
+      :searchFormOptions="searchFormOptions"
+      :table="table"
+      :extend="extend"
+    />
+  </div>
+</template>
+
+<script>
+import extend from "@/extension/system/Mes_Log.jsx";
+import MesLogStatistics from "@/components/MesLogStatistics.vue";
+import { ref, defineComponent } from "vue";
+
+export default defineComponent({
+  name: "Mes_Log",
+  components: {
+    MesLogStatistics
+  },
+  setup() {
+    const table = ref({
+      key: "Id",
+      cnName: "MES鎺ュ彛鏃ュ織",
+      name: "Mes_Log",
+      url: "/Mes_Log/",
+      sortName: "Id"
+    });
+
+    const columns = ref([
+      { field: "id", title: "ID", width: 80, hidden: true },
+      {
+        field: "apiType",
+        title: "鎺ュ彛绫诲瀷",
+        width: 130,
+        bind: { key: "mesApiType", data: [] }
+      },
+      {
+        field: "isSuccess",
+        title: "鐘舵��",
+        width: 80,
+        bind: { key: "mesApiStatus", data: [] }
+      },
+      {
+        field: "requestJson",
+        title: "璇锋眰鍐呭",
+        width: 200,
+        link: true
+      },
+      {
+        field: "responseJson",
+        title: "鍝嶅簲鍐呭",
+        width: 200,
+        link: true
+      },
+      { field: "errorMessage", title: "閿欒淇℃伅", width: 250 },
+      { field: "elapsedMs", title: "鑰楁椂(ms)", width: 100, sortable: true },
+      { field: "createDate", title: "璋冪敤鏃堕棿", width: 160, sortable: true },
+      { field: "creator", title: "鎿嶄綔浜�", width: 100 }
+    ]);
+
+    const detail = ref({
+      cnName: "MES鏃ュ織璇︽儏",
+      columns: [],
+      sortName: "Id",
+      key: "Id"
+    });
+
+    const editFormFields = ref({});
+    const editFormOptions = ref([]);
+
+    const searchFormFields = ref({
+      apiType: "",
+      isSuccess: "",
+      dateRange: "",
+      creator: "",
+      elapsedRange: "",
+      errorKeyword: "",
+      jsonKeyword: ""
+    });
+
+    const searchFormOptions = ref([
+      [
+        { field: "apiType", title: "鎺ュ彛绫诲瀷", type: "select" },
+        { field: "isSuccess", title: "鐘舵��", type: "select" },
+        { field: "dateRange", title: "鏃堕棿鑼冨洿", type: "datetimeRange" }
+      ],
+      [
+        { field: "creator", title: "鎿嶄綔浜�", type: "text" },
+        {
+          field: "elapsedRange",
+          title: "鑰楁椂鑼冨洿(ms)",
+          type: "numberRange",
+          placeholder: ["鏈�灏�", "鏈�澶�"]
+        }
+      ],
+      [
+        { field: "errorKeyword", title: "閿欒鍏抽敭瀛�", type: "text" },
+        { field: "jsonKeyword", title: "JSON鍐呭鍏抽敭瀛�", type: "text" }
+      ]
+    ]);
+
+    return {
+      table,
+      columns,
+      detail,
+      editFormFields,
+      editFormOptions,
+      searchFormFields,
+      searchFormOptions,
+      extend
+    };
+  }
+});
+</script>
+
+<style scoped>
+.mes-log-page {
+  padding: 16px;
+}
+</style>
+```
+
+### Step 2: 鎻愪氦椤甸潰鏂囦欢
+
+```bash
+git add WMS/WIDESEA_WMSClient/src/views/system/Mes_Log.vue
+git commit -m "feat(MES): 娣诲姞Mes_Log鏃ュ織椤甸潰
+
+- 浣跨敤 view-grid 缁勪欢
+- 闆嗘垚缁熻鍗$墖缁勪欢
+- 閰嶇疆鎼滅储琛ㄥ崟鍜屽垪琛ㄥ垪
+- 鏀寔澶氱淮搴︾瓫閫�
+
+Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
+```
+
+---
+
+## Task 9: 娣诲姞璺敱閰嶇疆
+
+**Files:**
+- Modify: `WMS/WIDESEA_WMSClient/src/router/viewGird.js`
+
+### Step 1: 璇诲彇璺敱鏂囦欢
+
+```bash
+cat WMS/WIDESEA_WMSClient/src/router/viewGird.js | head -50
+```
+
+### Step 2: 鍦� Sys_Log 璺敱鍚庢坊鍔� Mes_Log 璺敱
+
+鍦� `viewGird.js` 鐨勮矾鐢辨暟缁勪腑锛屾壘鍒� `path: '/Sys_Log'` 閰嶇疆鍧楋紙澶х害鍦ㄦ枃浠跺紑澶达級锛屽湪鍏跺悗娣诲姞锛�
+
+```javascript
+  {
+    path: '/Sys_Log',
+    name: 'sys_Log',
+    component: () => import('@/views/system/Sys_Log.vue')
+  },
+  {
+    path: '/Mes_Log',           // 鈫� 娣诲姞姝ゅ潡
+    name: 'mes_Log',
+    component: () => import('@/views/system/Mes_Log.vue')
+  },
+  {
+    path: '/Sys_User',          // 涓嬩竴涓矾鐢�
+    name: 'Sys_User',
+    component: () => import('@/views/system/Sys_User.vue')
+  },
+```
+
+鎻掑叆浣嶇疆锛氬湪 `Sys_Log` 璺敱鍧椾箣鍚庯紝`Sys_User` 璺敱鍧椾箣鍓�
+
+### Step 3: 鎻愪氦璺敱閰嶇疆
+
+```bash
+git add WMS/WIDESEA_WMSClient/src/router/viewGird.js
+git commit -m "feat(MES): 娣诲姞Mes_Log璺敱閰嶇疆
+
+- 娣诲姞 /Mes_Log 璺敱
+- 鎸囧悜 views/system/Mes_Log.vue
+
+Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
+```
+
+---
+
+## Task 10: 鏁版嵁搴撻厤缃�
+
+### Step 1: 鎵ц绱㈠紩鍒涘缓鑴氭湰
+
+```sql
+-- 鍦� SQL Server Management Studio 涓墽琛�
+
+-- 鎺ュ彛绫诲瀷绱㈠紩
+IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_MesApiLog_ApiType' AND object_id = OBJECT_ID('Dt_MesApiLog'))
+BEGIN
+    CREATE INDEX IX_MesApiLog_ApiType ON Dt_MesApiLog(ApiType);
+END
+
+-- 鍒涘缓鏃堕棿绱㈠紩
+IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_MesApiLog_CreateDate' AND object_id = OBJECT_ID('Dt_MesApiLog'))
+BEGIN
+    CREATE INDEX IX_MesApiLog_CreateDate ON Dt_MesApiLog(CreateDate DESC);
+END
+
+-- 鎴愬姛鐘舵�佺储寮�
+IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_MesApiLog_IsSuccess' AND object_id = OBJECT_ID('Dt_MesApiLog'))
+BEGIN
+    CREATE INDEX IX_MesApiLog_IsSuccess ON Dt_MesApiLog(IsSuccess);
+END
+
+-- 鍒涘缓浜虹储寮�
+IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_MesApiLog_Creator' AND object_id = OBJECT_ID('Dt_MesApiLog'))
+BEGIN
+    CREATE INDEX IX_MesApiLog_Creator ON Dt_MesApiLog(Creator);
+END
+```
+
+### Step 2: 娣诲姞鑿滃崟璁板綍
+
+```sql
+-- 鍏堟煡璇㈢郴缁熺鐞嗚彍鍗曠殑 ID
+SELECT Id, MenuName FROM Dt_Menu WHERE MenuName LIKE '%绯荤粺%' OR MenuName LIKE '%System%';
+
+-- 鍋囪绯荤粺绠$悊鑿滃崟 ID 涓� XXX锛屾彃鍏� MES 鎺ュ彛鏃ュ織鑿滃崟
+INSERT INTO Dt_Menu (ParentId, MenuName, Url, Component, Permission, Sort, Icon, CreateDate, Modifier)
+VALUES (
+    XXX,  -- 鏇挎崲涓哄疄闄呯殑绯荤粺绠$悊鑿滃崟 ID
+    'MES鎺ュ彛鏃ュ織',
+    '/Mes_Log',
+    'views/system/Mes_Log',
+    'Mes_Log:view',
+    (SELECT ISNULL(MAX(Sort), 0) + 1 FROM Dt_Menu WHERE ParentId = XXX),
+    'el-icon-document',
+    GETDATE(),
+    'System'
+);
+```
+
+### Step 3: 娣诲姞鏁版嵁瀛楀吀璁板綍
+
+```sql
+-- 鎺ュ彛绫诲瀷瀛楀吀
+DECLARE @DictId INT;
+SELECT @DictId = Id FROM Dt_Dictionary WHERE DictKey = 'mesApiType';
+
+IF @DictId IS NULL
+BEGIN
+    INSERT INTO Dt_Dictionary (DictKey, DictValue, CreateDate, Modifier)
+    VALUES ('mesApiType', 'MES鎺ュ彛绫诲瀷', GETDATE(), 'System');
+    SET @DictId = SCOPE_IDENTITY();
+END
+
+-- 娣诲姞鎺ュ彛绫诲瀷閫夐」
+INSERT INTO Dt_DictionaryList (DictId, Value, Key, DisplayOrder, CreateDate, Modifier)
+SELECT @DictId, '鐢佃姱缁戝畾', 'BindContainer', 1, GETDATE(), 'System'
+WHERE NOT EXISTS (SELECT 1 FROM Dt_DictionaryList WHERE DictId = @DictId AND [Key] = 'BindContainer');
+
+INSERT INTO Dt_DictionaryList (DictId, Value, Key, DisplayOrder, CreateDate, Modifier)
+SELECT @DictId, '鐢佃姱瑙g粦', 'UnBindContainer', 2, GETDATE(), 'System'
+WHERE NOT EXISTS (SELECT 1 FROM Dt_DictionaryList WHERE DictId = @DictId AND [Key] = 'UnBindContainer');
+
+INSERT INTO Dt_DictionaryList (DictId, Value, Key, DisplayOrder, CreateDate, Modifier)
+SELECT @DictId, 'NG涓婃姤', 'ContainerNgReport', 3, GETDATE(), 'System'
+WHERE NOT EXISTS (SELECT 1 FROM Dt_DictionaryList WHERE DictId = @DictId AND [Key] = 'ContainerNgReport');
+
+INSERT INTO Dt_DictionaryList (DictId, Value, Key, DisplayOrder, CreateDate, Modifier)
+SELECT @DictId, '鎵樼洏杩涚珯', 'InboundInContainer', 4, GETDATE(), 'System'
+WHERE NOT EXISTS (SELECT 1 FROM Dt_DictionaryList WHERE DictId = @DictId AND [Key] = 'InboundInContainer');
+
+INSERT INTO Dt_DictionaryList (DictId, Value, Key, DisplayOrder, CreateDate, Modifier)
+SELECT @DictId, '鎵樼洏鍑虹珯', 'OutboundInContainer', 5, GETDATE(), 'System'
+WHERE NOT EXISTS (SELECT 1 FROM Dt_DictionaryList WHERE DictId = @DictId AND [Key] = 'OutboundInContainer');
+
+-- 璋冪敤鐘舵�佸瓧鍏�
+DECLARE @StatusDictId INT;
+SELECT @StatusDictId = Id FROM Dt_Dictionary WHERE DictKey = 'mesApiStatus';
+
+IF @StatusDictId IS NULL
+BEGIN
+    INSERT INTO Dt_Dictionary (DictKey, DictValue, CreateDate, Modifier)
+    VALUES ('mesApiStatus', 'MES鎺ュ彛鐘舵��', GETDATE(), 'System');
+    SET @StatusDictId = SCOPE_IDENTITY();
+END
+
+-- 娣诲姞鐘舵�侀�夐」
+INSERT INTO Dt_DictionaryList (DictId, Value, Key, DisplayOrder, CreateDate, Modifier)
+SELECT @StatusDictId, '鎴愬姛', 'true', 1, GETDATE(), 'System'
+WHERE NOT EXISTS (SELECT 1 FROM Dt_DictionaryList WHERE DictId = @StatusDictId AND [Key] = 'true');
+
+INSERT INTO Dt_DictionaryList (DictId, Value, Key, DisplayOrder, CreateDate, Modifier)
+SELECT @StatusDictId, '澶辫触', 'false', 2, GETDATE(), 'System'
+WHERE NOT EXISTS (SELECT 1 FROM Dt_DictionaryList WHERE DictId = @StatusDictId AND [Key] = 'false');
+```
+
+### Step 4: 淇濆瓨鏁版嵁搴撹剼鏈�
+
+```bash
+# 灏嗕笂杩� SQL 鑴氭湰淇濆瓨鍒版枃浠�
+cat > WMS/WIDESEA_WMSServer/Database/Scripts/20260413_MesLogPage_Config.sql << 'EOF'
+-- 杩欓噷绮樿创涓婇潰鐨� SQL 鑴氭湰
+EOF
+```
+
+### Step 5: 鎻愪氦鏁版嵁搴撹剼鏈�
+
+```bash
+git add WMS/WIDESEA_WMSServer/Database/Scripts/20260413_MesLogPage_Config.sql
+git commit -m "feat(MES): 娣诲姞MES鏃ュ織椤甸潰鏁版嵁搴撻厤缃�
+
+- 鍒涘缓鎬ц兘绱㈠紩
+- 娣诲姞鑿滃崟璁板綍
+- 娣诲姞鏁版嵁瀛楀吀锛堟帴鍙g被鍨嬨�佺姸鎬侊級
+
+Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"
+```
+
+---
+
+## Task 11: 鍚庣缂栬瘧娴嬭瘯
+
+### Step 1: 缂栬瘧鍚庣椤圭洰
+
+```bash
+cd WMS/WIDESEA_WMSServer
+dotnet build WIDESEA_WMSServer.sln
+```
+
+### Step 2: 妫�鏌ョ紪璇戠粨鏋�
+
+棰勬湡杈撳嚭锛氱紪璇戞垚鍔燂紝鏃犻敊璇�
+
+### Step 3: 濡傛灉鏈夐敊璇紝淇骞堕噸鏂扮紪璇�
+
+---
+
+## Task 12: 鍓嶇缂栬瘧娴嬭瘯
+
+### Step 1: 瀹夎渚濊禆锛堝闇�瑕侊級
+
+```bash
+cd WMS/WIDESEA_WMSClient
+npm install
+```
+
+### Step 2: 缂栬瘧鍓嶇椤圭洰
+
+```bash
+npm run build
+```
+
+### Step 3: 妫�鏌ョ紪璇戠粨鏋�
+
+棰勬湡杈撳嚭锛氱紪璇戞垚鍔燂紝鏃犻敊璇�
+
+---
+
+## Task 13: 鎵嬪姩鍔熻兘娴嬭瘯
+
+### 娴嬭瘯娓呭崟
+
+- [ ] **鍒嗛〉鏌ヨ**: 鑳芥甯告樉绀烘棩蹇楀垪琛�
+- [ ] **绛涢�夊姛鑳�**: 鎺ュ彛绫诲瀷銆佺姸鎬併�佹椂闂磋寖鍥寸瓫閫夋甯�
+- [ ] **缁熻鍗$墖**: 鏄剧ず姝g‘鐨勭粺璁℃暟鎹�
+- [ ] **JSON 璇︽儏**: 鐐瑰嚮璇锋眰/鍝嶅簲鍒楄兘鏌ョ湅瀹屾暣 JSON
+- [ ] **瀵煎嚭鍔熻兘**: 鑳藉鍑� CSV 鏂囦欢
+
+---
+
+## Task 14: 浠g爜瀹℃煡涓庢渶缁堟彁浜�
+
+### Step 1: 鏌ョ湅鎵�鏈夊彉鏇�
+
+```bash
+git status
+git log --oneline -10
+```
+
+### Step 2: 鏈�缁堢‘璁�
+
+纭鎵�鏈変换鍔″凡瀹屾垚锛屽姛鑳芥祴璇曢�氳繃
+
+---
+
+## 闄勫綍: 鍙傝�冩枃妗�
+
+- 璁捐鏂囨。: `docs/superpowers/specs/2026-04-13-mes-api-log-page-design.md`
+- 鐜版湁绯荤粺鏃ュ織: `WMS/WIDESEA_WMSClient/src/views/system/Sys_Log.vue`
+- 鐜版湁鎵╁睍: `WMS/WIDESEA_WMSClient/src/extension/system/Sys_Log.jsx`
+- MES 瀹炰綋: `WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Mes/Dt_MesApiLog.cs`

--
Gitblit v1.9.3