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/WMS/WIDESEA_WMSServer/WIDESEA_IBasicService/IMesLogService.cs                          |   60 
 Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoDetailController.cs |    1 
 Code/WMS/WIDESEA_WMSClient/src/views/system/Mes_Log.vue                                     |  149 ++
 Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLogStatisticsDto.cs                           |   50 
 Code/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/MesService.cs                               |    2 
 Code/WMS/WIDESEA_WMSClient/src/extension/system/Mes_Log.jsx                                 |  116 +
 Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLogQueryDto.cs                                |   60 
 Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLogDetailDto.cs                               |   75 +
 Code/WMS/WIDESEA_WMSClient/src/components/MesLogStatistics.vue                              |  128 +
 Code/WMS/WIDESEA_WMSServer/Database/Scripts/20260413_MesLogPage_Config.sql                  |  189 ++
 Code/.omc/state/agent-replay-e24754b1-493a-48fb-9409-1ba4fbbf8fb3.jsonl                     |   14 
 Code/.omc/state/idle-notif-cooldown.json                                                    |    2 
 Code/docs/superpowers/specs/2026-04-13-mes-api-log-page-design.md                           |  896 +++++++++++++
 Code/WMS/WIDESEA_WMSClient/package.json                                                     |    1 
 Code/.omc/state/subagent-tracking.json                                                      |   51 
 Code/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Mes/Dt_MesApiLog.cs                         |    2 
 Code/.omc/state/mission-state.json                                                          |  106 +
 Code/WMS/WIDESEA_WMSClient/src/extension/system/Sys_Log.jsx                                 |   76 +
 Code/WMS/WIDESEA_WMSClient/src/router/viewGird.js                                           |    5 
 Code/docs/superpowers/plans/2026-04-13-mes-api-log-page-plan.md                             | 1430 +++++++++++++++++++++
 Code/WMS/WIDESEA_WMSClient/src/views/system/Sys_Log.vue                                     |   18 
 Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs       |    1 
 Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/WIDESEA_WMSServer.csproj                       |    1 
 Code/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/MesLogService.cs                            |  298 ++++
 /dev/null                                                                                   |   16 
 Code/.gitignore                                                                             |    1 
 Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLogListItemDto.cs                             |   55 
 Code/.omc/state/last-tool-error.json                                                        |   10 
 Code/WMS/WIDESEA_WMSClient/pnpm-lock.yaml                                                   |   44 
 Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Mes/MesLogController.cs            |  116 +
 30 files changed, 3,939 insertions(+), 34 deletions(-)

diff --git a/Code/.gitignore b/Code/.gitignore
new file mode 100644
index 0000000..e458ed5
--- /dev/null
+++ b/Code/.gitignore
@@ -0,0 +1 @@
+.worktrees/
diff --git a/Code/.omc/state/agent-replay-e24754b1-493a-48fb-9409-1ba4fbbf8fb3.jsonl b/Code/.omc/state/agent-replay-e24754b1-493a-48fb-9409-1ba4fbbf8fb3.jsonl
new file mode 100644
index 0000000..a15e14e
--- /dev/null
+++ b/Code/.omc/state/agent-replay-e24754b1-493a-48fb-9409-1ba4fbbf8fb3.jsonl
@@ -0,0 +1,14 @@
+{"t":0,"agent":"system","event":"skill_invoked","skill_name":"superpowers:brainstorming"}
+{"t":0,"agent":"a8f801a","agent_type":"code-reviewer","event":"agent_start","parent_mode":"none"}
+{"t":0,"agent":"a8f801a","agent_type":"code-reviewer","event":"agent_stop","success":true,"duration_ms":50944}
+{"t":0,"agent":"a51d0d4","agent_type":"code-reviewer","event":"agent_start","parent_mode":"none"}
+{"t":0,"agent":"a51d0d4","agent_type":"code-reviewer","event":"agent_stop","success":true,"duration_ms":27507}
+{"t":0,"agent":"a05bbbd","agent_type":"code-reviewer","event":"agent_start","parent_mode":"none"}
+{"t":0,"agent":"a05bbbd","agent_type":"code-reviewer","event":"agent_stop","success":true,"duration_ms":9125}
+{"t":0,"agent":"system","event":"skill_invoked","skill_name":"superpowers:writing-plans"}
+{"t":0,"agent":"a8e49fa","agent_type":"code-reviewer","event":"agent_start","parent_mode":"none"}
+{"t":0,"agent":"a8e49fa","agent_type":"code-reviewer","event":"agent_stop","success":true,"duration_ms":31352}
+{"t":0,"agent":"adb1029","agent_type":"code-reviewer","event":"agent_start","parent_mode":"none"}
+{"t":0,"agent":"adb1029","agent_type":"code-reviewer","event":"agent_stop","success":true,"duration_ms":9005}
+{"t":0,"agent":"system","event":"skill_invoked","skill_name":"superpowers:subagent-driven-development"}
+{"t":0,"agent":"system","event":"skill_invoked","skill_name":"superpowers:using-git-worktrees"}
diff --git a/Code/.omc/state/idle-notif-cooldown.json b/Code/.omc/state/idle-notif-cooldown.json
index f247f90..0c94115 100644
--- a/Code/.omc/state/idle-notif-cooldown.json
+++ b/Code/.omc/state/idle-notif-cooldown.json
@@ -1,3 +1,3 @@
 {
-  "lastSentAt": "2026-04-12T12:35:52.350Z"
+  "lastSentAt": "2026-04-13T06:33:17.906Z"
 }
\ No newline at end of file
diff --git a/Code/.omc/state/last-tool-error.json b/Code/.omc/state/last-tool-error.json
index 8644504..f5ba7de 100644
--- a/Code/.omc/state/last-tool-error.json
+++ b/Code/.omc/state/last-tool-error.json
@@ -1,7 +1,7 @@
 {
-  "tool_name": "Read",
-  "tool_input_preview": "{\"file_path\":\"D:\\\\Git\\\\ShanMeiXinNengYuan\\\\Code\\\\WMS\\\\WIDESEA_WMSServer\\\\WIDESEA_WMSServer\\\\Controllers\\\\BatteryCellController.cs\"}",
-  "error": "File does not exist. Note: your current working directory is D:\\Git\\ShanMeiXinNengYuan\\Code.",
-  "timestamp": "2026-04-12T13:48:48.578Z",
-  "retry_count": 1
+  "tool_name": "Bash",
+  "tool_input_preview": "{\"command\":\"ls \\\"D:\\\\Git\\\\ShanMeiXinNengYuan\\\\Code\\\\WMS\\\\WIDESEA_WMSClient\\\\src\\\\api\\\\\\\" 2>/dev/null | head -20\",\"description\":\"Check api directory structure\"}",
+  "error": "Exit code 2\n/usr/bin/bash: eval: line 1: unexpected EOF while looking for matching `\"'",
+  "timestamp": "2026-04-13T03:27:59.200Z",
+  "retry_count": 6
 }
\ No newline at end of file
diff --git a/Code/.omc/state/mission-state.json b/Code/.omc/state/mission-state.json
index b8b2958..c9d6d38 100644
--- a/Code/.omc/state/mission-state.json
+++ b/Code/.omc/state/mission-state.json
@@ -1,5 +1,5 @@
 {
-  "updatedAt": "2026-04-12T13:54:45.455Z",
+  "updatedAt": "2026-04-13T02:47:35.467Z",
   "missions": [
     {
       "id": "session:9007b9ea-1eb6-4d24-8fe7-2c3a949eac88:none",
@@ -324,6 +324,110 @@
           "sourceKey": "session-stop:a0ff37729a29ea04f"
         }
       ]
+    },
+    {
+      "id": "session:e24754b1-493a-48fb-9409-1ba4fbbf8fb3:none",
+      "source": "session",
+      "name": "none",
+      "objective": "Session mission",
+      "createdAt": "2026-04-13T02:37:40.066Z",
+      "updatedAt": "2026-04-13T02:47:35.467Z",
+      "status": "done",
+      "workerCount": 5,
+      "taskCounts": {
+        "total": 5,
+        "pending": 0,
+        "blocked": 0,
+        "inProgress": 0,
+        "completed": 5,
+        "failed": 0
+      },
+      "agents": [
+        {
+          "name": "code-reviewer:a8f801a",
+          "role": "code-reviewer",
+          "ownership": "a8f801a79ff5dda6f",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-13T02:38:31.010Z"
+        },
+        {
+          "name": "code-reviewer:a51d0d4",
+          "role": "code-reviewer",
+          "ownership": "a51d0d447d3482f88",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-13T02:40:32.731Z"
+        },
+        {
+          "name": "code-reviewer:a05bbbd",
+          "role": "code-reviewer",
+          "ownership": "a05bbbd6e272317db",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-13T02:41:24.944Z"
+        },
+        {
+          "name": "code-reviewer:a8e49fa",
+          "role": "code-reviewer",
+          "ownership": "a8e49fa8974f48c7e",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-13T02:44:54.211Z"
+        },
+        {
+          "name": "code-reviewer:adb1029",
+          "role": "code-reviewer",
+          "ownership": "adb1029c24100db60",
+          "status": "done",
+          "currentStep": null,
+          "latestUpdate": "completed",
+          "completedSummary": null,
+          "updatedAt": "2026-04-13T02:47:35.467Z"
+        }
+      ],
+      "timeline": [
+        {
+          "id": "session-start:a8e49fa8974f48c7e:2026-04-13T02:44:22.859Z",
+          "at": "2026-04-13T02:44:22.859Z",
+          "kind": "update",
+          "agent": "code-reviewer:a8e49fa",
+          "detail": "started code-reviewer:a8e49fa",
+          "sourceKey": "session-start:a8e49fa8974f48c7e"
+        },
+        {
+          "id": "session-stop:a8e49fa8974f48c7e:2026-04-13T02:44:54.211Z",
+          "at": "2026-04-13T02:44:54.211Z",
+          "kind": "completion",
+          "agent": "code-reviewer:a8e49fa",
+          "detail": "completed",
+          "sourceKey": "session-stop:a8e49fa8974f48c7e"
+        },
+        {
+          "id": "session-start:adb1029c24100db60:2026-04-13T02:47:26.462Z",
+          "at": "2026-04-13T02:47:26.462Z",
+          "kind": "update",
+          "agent": "code-reviewer:adb1029",
+          "detail": "started code-reviewer:adb1029",
+          "sourceKey": "session-start:adb1029c24100db60"
+        },
+        {
+          "id": "session-stop:adb1029c24100db60:2026-04-13T02:47:35.467Z",
+          "at": "2026-04-13T02:47:35.467Z",
+          "kind": "completion",
+          "agent": "code-reviewer:adb1029",
+          "detail": "completed",
+          "sourceKey": "session-stop:adb1029c24100db60"
+        }
+      ]
     }
   ]
 }
\ No newline at end of file
diff --git a/Code/.omc/state/subagent-tracking.json b/Code/.omc/state/subagent-tracking.json
index d5dd869..17d460d 100644
--- a/Code/.omc/state/subagent-tracking.json
+++ b/Code/.omc/state/subagent-tracking.json
@@ -242,10 +242,55 @@
       "status": "completed",
       "completed_at": "2026-04-12T13:54:45.455Z",
       "duration_ms": 7226
+    },
+    {
+      "agent_id": "a8f801a79ff5dda6f",
+      "agent_type": "code-reviewer",
+      "started_at": "2026-04-13T02:37:40.066Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-13T02:38:31.010Z",
+      "duration_ms": 50944
+    },
+    {
+      "agent_id": "a51d0d447d3482f88",
+      "agent_type": "code-reviewer",
+      "started_at": "2026-04-13T02:40:05.224Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-13T02:40:32.731Z",
+      "duration_ms": 27507
+    },
+    {
+      "agent_id": "a05bbbd6e272317db",
+      "agent_type": "code-reviewer",
+      "started_at": "2026-04-13T02:41:15.819Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-13T02:41:24.944Z",
+      "duration_ms": 9125
+    },
+    {
+      "agent_id": "a8e49fa8974f48c7e",
+      "agent_type": "code-reviewer",
+      "started_at": "2026-04-13T02:44:22.859Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-13T02:44:54.211Z",
+      "duration_ms": 31352
+    },
+    {
+      "agent_id": "adb1029c24100db60",
+      "agent_type": "code-reviewer",
+      "started_at": "2026-04-13T02:47:26.462Z",
+      "parent_mode": "none",
+      "status": "completed",
+      "completed_at": "2026-04-13T02:47:35.467Z",
+      "duration_ms": 9005
     }
   ],
-  "total_spawned": 27,
-  "total_completed": 27,
+  "total_spawned": 32,
+  "total_completed": 32,
   "total_failed": 0,
-  "last_updated": "2026-04-12T13:54:45.571Z"
+  "last_updated": "2026-04-13T02:47:35.573Z"
 }
\ No newline at end of file
diff --git a/Code/WMS/WIDESEA_WMSClient/package.json b/Code/WMS/WIDESEA_WMSClient/package.json
index ed3eeec..f5f2df8 100644
--- a/Code/WMS/WIDESEA_WMSClient/package.json
+++ b/Code/WMS/WIDESEA_WMSClient/package.json
@@ -26,6 +26,7 @@
     "vue-draggable-next": "^2.0.1",
     "vue-qrcode": "^2.2.2",
     "vue-router": "^4.0.0-0",
+    "vue3-json-viewer": "^2.4.1",
     "vuex": "^4.0.0-0"
   },
   "devDependencies": {
diff --git a/Code/WMS/WIDESEA_WMSClient/pnpm-lock.yaml b/Code/WMS/WIDESEA_WMSClient/pnpm-lock.yaml
index ea48169..b36c749 100644
--- a/Code/WMS/WIDESEA_WMSClient/pnpm-lock.yaml
+++ b/Code/WMS/WIDESEA_WMSClient/pnpm-lock.yaml
@@ -56,6 +56,9 @@
       vue-router:
         specifier: ^4.0.0-0
         version: 4.6.4(vue@3.5.30)
+      vue3-json-viewer:
+        specifier: ^2.4.1
+        version: 2.4.1(vue@3.5.30)
       vuex:
         specifier: ^4.0.0-0
         version: 4.1.0(vue@3.5.30)
@@ -943,6 +946,9 @@
     resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==}
     engines: {node: '>=6.0'}
 
+  clipboard@2.0.11:
+    resolution: {integrity: sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==}
+
   cliui@6.0.0:
     resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
 
@@ -1042,6 +1048,9 @@
   default-user-agent@1.0.0:
     resolution: {integrity: sha512-bDF7bg6OSNcSwFWPu4zYKpVkJZQYVrAANMYB8bc9Szem1D0yKdm4sa/rOCs2aC9+2GMqQ7KnwtZRvDhmLF0dXw==}
     engines: {node: '>= 0.10.0'}
+
+  delegate@3.2.0:
+    resolution: {integrity: sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==}
 
   destroy@1.2.0:
     resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==}
@@ -1252,6 +1261,9 @@
   glob@7.2.3:
     resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
     deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
+
+  good-listener@1.2.2:
+    resolution: {integrity: sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==}
 
   gopd@1.2.0:
     resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
@@ -1745,6 +1757,9 @@
   sdk-base@2.0.1:
     resolution: {integrity: sha512-eeG26wRwhtwYuKGCDM3LixCaxY27Pa/5lK4rLKhQa7HBjJ3U3Y+f81MMZQRsDw/8SC2Dao/83yJTXJ8aULuN8Q==}
 
+  select@1.1.2:
+    resolution: {integrity: sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==}
+
   semver@5.7.2:
     resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
     hasBin: true
@@ -1896,6 +1911,9 @@
   through@2.3.8:
     resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
 
+  tiny-emitter@2.1.0:
+    resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==}
+
   to-arraybuffer@1.0.1:
     resolution: {integrity: sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==}
 
@@ -2015,6 +2033,11 @@
     resolution: {integrity: sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==}
     peerDependencies:
       vue: ^3.5.0
+
+  vue3-json-viewer@2.4.1:
+    resolution: {integrity: sha512-Z1sunvS58lJ3ZcpNhl3jYQapBVw2wjnXbemigfMWm3QnjCeg3CPMq8R6pxHUYahxMfPKLvrbGve6mUXqhWyLaQ==}
+    peerDependencies:
+      vue: ^3.5.16
 
   vue@3.5.30:
     resolution: {integrity: sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==}
@@ -2967,6 +2990,12 @@
 
   chrome-trace-event@1.0.4: {}
 
+  clipboard@2.0.11:
+    dependencies:
+      good-listener: 1.2.2
+      select: 1.1.2
+      tiny-emitter: 2.1.0
+
   cliui@6.0.0:
     dependencies:
       string-width: 4.2.3
@@ -3050,6 +3079,8 @@
   default-user-agent@1.0.0:
     dependencies:
       os-name: 1.0.3
+
+  delegate@3.2.0: {}
 
   destroy@1.2.0: {}
 
@@ -3275,6 +3306,10 @@
       minimatch: 3.1.5
       once: 1.4.0
       path-is-absolute: 1.0.1
+
+  good-listener@1.2.2:
+    dependencies:
+      delegate: 3.2.0
 
   gopd@1.2.0: {}
 
@@ -3718,6 +3753,8 @@
     dependencies:
       get-ready: 1.0.0
 
+  select@1.1.2: {}
+
   semver@5.7.2: {}
 
   semver@6.3.1: {}
@@ -3874,6 +3911,8 @@
 
   through@2.3.8: {}
 
+  tiny-emitter@2.1.0: {}
+
   to-arraybuffer@1.0.1: {}
 
   tough-cookie@4.1.4:
@@ -3978,6 +4017,11 @@
       '@vue/devtools-api': 6.6.4
       vue: 3.5.30
 
+  vue3-json-viewer@2.4.1(vue@3.5.30):
+    dependencies:
+      clipboard: 2.0.11
+      vue: 3.5.30
+
   vue@3.5.30:
     dependencies:
       '@vue/compiler-dom': 3.5.30
diff --git a/Code/WMS/WIDESEA_WMSClient/src/components/MesLogStatistics.vue b/Code/WMS/WIDESEA_WMSClient/src/components/MesLogStatistics.vue
new file mode 100644
index 0000000..e0cf815
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient/src/components/MesLogStatistics.vue
@@ -0,0 +1,128 @@
+<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/http.js";
+
+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>
diff --git a/Code/WMS/WIDESEA_WMSClient/src/extension/system/Mes_Log.jsx b/Code/WMS/WIDESEA_WMSClient/src/extension/system/Mes_Log.jsx
new file mode 100644
index 0000000..be25098
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient/src/extension/system/Mes_Log.jsx
@@ -0,0 +1,116 @@
+import { h, createApp } from 'vue';
+import { ElDrawer, ElIcon } from 'element-plus';
+
+let extension = {
+  components: {
+    // 鍔ㄦ�佹墿鍏呯粍浠舵垨缁勪欢璺緞
+    gridHeader: "",
+    gridBody: '',
+    gridFooter: "",
+    modelHeader: "",
+    modelBody: "",
+    modelFooter: ""
+  },
+  buttons: [], // 鎵╁睍鐨勬寜閽�
+  data: {
+    jsonDrawerVisible: false,
+    currentJson: '',
+    currentJsonTitle: ''
+  },
+  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' && row.requestJson) {
+        this.showJsonDetail(row, 'request');
+      } else if (column.property === 'responseJson' && row.responseJson) {
+        this.showJsonDetail(row, 'response');
+      }
+    },
+
+    // 鏄剧ず JSON 璇︽儏鎶藉眽
+    showJsonDetail(row, type = 'request') {
+      const jsonContent = type === 'request' ? row.requestJson : row.responseJson;
+      const title = type === 'request' ? '馃搵 璇锋眰 JSON' : '馃摜 鍝嶅簲 JSON';
+
+      // 鏍煎紡鍖� JSON
+      let formattedJson = '';
+      try {
+        const obj = typeof jsonContent === 'string' ? JSON.parse(jsonContent) : jsonContent;
+        formattedJson = JSON.stringify(obj, null, 2);
+      } catch (e) {
+        formattedJson = String(jsonContent);
+      }
+
+      // 鍒涘缓涓存椂瀹瑰櫒娓叉煋鎶藉眽
+      const container = document.createElement('div');
+      document.body.appendChild(container);
+
+      const app = createApp({
+        render() {
+          return h('div', [
+            h(ElDrawer, {
+              modelValue: true,
+              'onUpdate:modelValue': (val) => {
+                if (!val) {
+                  app.unmount();
+                  document.body.removeChild(container);
+                }
+              },
+              title: title,
+              size: '30%',
+              destroyOnClose: true,
+              closeOnClickModal: true
+            }, {
+              default: () => h('div', {
+                style: {
+                  height: '100%',
+                  backgroundColor: '#f5f5f5',
+                  padding: '16px',
+                  borderRadius: '4px'
+                }
+              }, [
+                h('pre', {
+                  style: {
+                    margin: '0',
+                    fontSize: '14px',
+                    lineHeight: '1.5',
+                    fontFamily: 'Consolas, Monaco, "Courier New", monospace',
+                    whiteSpace: 'pre-wrap',
+                    wordBreak: 'break-all'
+                  }
+                }, formattedJson)
+              ])
+            })
+          ]);
+        }
+      });
+
+      app.use(window.ElementPlus);
+      app.mount(container);
+    },
+  }
+};
+
+export default extension;
diff --git a/Code/WMS/WIDESEA_WMSClient/src/extension/system/Sys_Log.jsx b/Code/WMS/WIDESEA_WMSClient/src/extension/system/Sys_Log.jsx
index 5b05c40..96340be 100644
--- a/Code/WMS/WIDESEA_WMSClient/src/extension/system/Sys_Log.jsx
+++ b/Code/WMS/WIDESEA_WMSClient/src/extension/system/Sys_Log.jsx
@@ -1,4 +1,6 @@
-import { h, resolveComponent } from 'vue';
+import { h, createApp } from 'vue';
+import { ElDrawer } from 'element-plus';
+
 let extension = {
   components: {
     //鍔ㄦ�佹墿鍏呯粍浠舵垨缁勪欢璺緞
@@ -20,6 +22,78 @@
     },
     onInited() {
       this.height = this.height - 170;
+    },
+
+    // 琛岀偣鍑讳簨浠� - 鏄剧ず鍙傛暟璇︽儏鎶藉眽
+    rowClick({ row, column }) {
+      // 濡傛灉鐐瑰嚮鐨勬槸璇锋眰鍙傛暟鎴栧搷搴斿弬鏁板垪锛屾樉绀鸿鎯呮娊灞�
+      if (column.property === 'requestParam' && row.requestParam) {
+        this.showJsonDetail(row, 'request');
+      } else if (column.property === 'responseParam' && row.responseParam) {
+        this.showJsonDetail(row, 'response');
+      }
+    },
+
+    // 鏄剧ず JSON 璇︽儏鎶藉眽
+    showJsonDetail(row, type = 'request') {
+      const content = type === 'request' ? row.requestParam : row.responseParam;
+      const title = type === 'request' ? '馃搵 璇锋眰鍙傛暟' : '馃摜 鍝嶅簲鍙傛暟';
+
+      // 鏍煎紡鍖� JSON
+      let formattedJson = '';
+      try {
+        const obj = typeof content === 'string' ? JSON.parse(content) : content;
+        formattedJson = JSON.stringify(obj, null, 2);
+      } catch (e) {
+        formattedJson = String(content);
+      }
+
+      // 鍒涘缓涓存椂瀹瑰櫒娓叉煋鎶藉眽
+      const container = document.createElement('div');
+      document.body.appendChild(container);
+
+      const app = createApp({
+        render() {
+          return h('div', [
+            h(ElDrawer, {
+              modelValue: true,
+              'onUpdate:modelValue': (val) => {
+                if (!val) {
+                  app.unmount();
+                  document.body.removeChild(container);
+                }
+              },
+              title: title,
+              size: '30%',
+              destroyOnClose: true,
+              closeOnClickModal: true
+            }, {
+              default: () => h('div', {
+                style: {
+                  height: '30%',
+                  backgroundColor: '#f5f5f5',
+                  padding: '16px',
+                  borderRadius: '4px'
+                }
+              }, [
+                h('pre', {
+                  style: {
+                    margin: '0',
+                    fontSize: '14px',
+                    lineHeight: '1.5',
+                    fontFamily: 'Consolas, Monaco, "Courier New", monospace',
+                    whiteSpace: 'pre-wrap',
+                    wordBreak: 'break-all'
+                  }
+                }, formattedJson)
+              ])
+            })
+          ]);
+        }
+      });
+
+      app.use(window.ElementPlus);
+      app.mount(container);
     }
   }
 };
diff --git a/Code/WMS/WIDESEA_WMSClient/src/router/viewGird.js b/Code/WMS/WIDESEA_WMSClient/src/router/viewGird.js
index c4da063..92b91b8 100644
--- a/Code/WMS/WIDESEA_WMSClient/src/router/viewGird.js
+++ b/Code/WMS/WIDESEA_WMSClient/src/router/viewGird.js
@@ -6,6 +6,11 @@
     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')
diff --git a/Code/WMS/WIDESEA_WMSClient/src/views/system/Mes_Log.vue b/Code/WMS/WIDESEA_WMSClient/src/views/system/Mes_Log.vue
new file mode 100644
index 0000000..f74319b
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient/src/views/system/Mes_Log.vue
@@ -0,0 +1,149 @@
+<!--
+*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: "/MesLog/",
+      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,
+        formatter: (row) => {
+          if (!row.requestJson) return '-';
+          const preview = row.requestJson.length > 50
+            ? row.requestJson.substring(0, 50) + '...'
+            : row.requestJson;
+          return `<span style="color: #409EFF; cursor: pointer;">${preview}</span>`;
+        }
+      },
+      {
+        field: "responseJson",
+        title: "鍝嶅簲鍐呭",
+        width: 200,
+        formatter: (row) => {
+          if (!row.responseJson) return '-';
+          const preview = row.responseJson.length > 50
+            ? row.responseJson.substring(0, 50) + '...'
+            : row.responseJson;
+          return `<span style="color: #409EFF; cursor: pointer;">${preview}</span>`;
+        }
+      },
+      { 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",dataKey: "mesApiType", data: [] },
+        { field: "isSuccess", title: "鐘舵��", type: "select" ,dataKey: "mesApiStatus", data: []},
+        { 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>
diff --git a/Code/WMS/WIDESEA_WMSClient/src/views/system/Sys_Log.vue b/Code/WMS/WIDESEA_WMSClient/src/views/system/Sys_Log.vue
index aae7c83..a03baa0 100644
--- a/Code/WMS/WIDESEA_WMSClient/src/views/system/Sys_Log.vue
+++ b/Code/WMS/WIDESEA_WMSClient/src/views/system/Sys_Log.vue
@@ -86,15 +86,29 @@
         field: "requestParam",
         title: "璇锋眰鍙傛暟",
         type: "string",
-        width: 100,
+        width: 150,
         align: "left",
+        formatter: (row) => {
+          if (!row.requestParam) return '-';
+          const preview = row.requestParam.length > 50
+            ? row.requestParam.substring(0, 50) + '...'
+            : row.requestParam;
+          return `<span style="color: #409EFF; cursor: pointer;">${preview}</span>`;
+        }
       },
       {
         field: "responseParam",
         title: "鍝嶅簲鍙傛暟",
         type: "string",
-        width: 100,
+        width: 150,
         align: "left",
+        formatter: (row) => {
+          if (!row.responseParam) return '-';
+          const preview = row.responseParam.length > 50
+            ? row.responseParam.substring(0, 50) + '...'
+            : row.responseParam;
+          return `<span style="color: #409EFF; cursor: pointer;">${preview}</span>`;
+        }
       },
       {
         field: "url",
diff --git a/Code/WMS/WIDESEA_WMSServer/Database/Scripts/20260413_MesLogPage_Config.sql b/Code/WMS/WIDESEA_WMSServer/Database/Scripts/20260413_MesLogPage_Config.sql
new file mode 100644
index 0000000..9009709
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSServer/Database/Scripts/20260413_MesLogPage_Config.sql
@@ -0,0 +1,189 @@
+-- =============================================
+-- MES 鎺ュ彛鏃ュ織椤甸潰鏁版嵁搴撻厤缃剼鏈�
+-- 鍒涘缓鏃ユ湡: 2026-04-13
+-- 璇存槑: 鍒涘缓鎬ц兘绱㈠紩銆佽彍鍗曡褰曘�佹暟鎹瓧鍏�
+-- =============================================
+
+-- =============================================
+-- Step 1: 鍒涘缓鎬ц兘绱㈠紩
+-- =============================================
+
+-- 鎺ュ彛绫诲瀷绱㈠紩
+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);
+    PRINT '绱㈠紩 IX_MesApiLog_ApiType 宸插垱寤�';
+END
+ELSE
+    PRINT '绱㈠紩 IX_MesApiLog_ApiType 宸插瓨鍦�';
+
+-- 鍒涘缓鏃堕棿绱㈠紩
+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);
+    PRINT '绱㈠紩 IX_MesApiLog_CreateDate 宸插垱寤�';
+END
+ELSE
+    PRINT '绱㈠紩 IX_MesApiLog_CreateDate 宸插瓨鍦�';
+
+-- 鎴愬姛鐘舵�佺储寮�
+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);
+    PRINT '绱㈠紩 IX_MesApiLog_IsSuccess 宸插垱寤�';
+END
+ELSE
+    PRINT '绱㈠紩 IX_MesApiLog_IsSuccess 宸插瓨鍦�';
+
+-- 鍒涘缓浜虹储寮�
+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);
+    PRINT '绱㈠紩 IX_MesApiLog_Creator 宸插垱寤�';
+END
+ELSE
+    PRINT '绱㈠紩 IX_MesApiLog_Creator 宸插瓨鍦�';
+
+PRINT '=====================================';
+PRINT '绱㈠紩鍒涘缓瀹屾垚';
+PRINT '=====================================';
+GO
+
+-- =============================================
+-- Step 2: 娣诲姞鑿滃崟璁板綍
+-- =============================================
+
+-- 鏌ヨ绯荤粺绠$悊鑿滃崟鐨� ID
+DECLARE @SystemMenuId INT;
+SELECT TOP 1 @SystemMenuId = Id FROM Dt_Menu WHERE MenuName LIKE '%绯荤粺%' OR MenuName LIKE '%System%';
+
+IF @SystemMenuId IS NULL
+BEGIN
+    PRINT '璀﹀憡: 鏈壘鍒扮郴缁熺鐞嗚彍鍗曪紝璇锋墜鍔ㄧ‘璁よ彍鍗� ID';
+END
+ELSE
+BEGIN
+    PRINT '绯荤粺绠$悊鑿滃崟 ID: ' + CAST(@SystemMenuId AS VARCHAR(10));
+
+    -- 妫�鏌� MES 鎺ュ彛鏃ュ織鑿滃崟鏄惁宸插瓨鍦�
+    IF NOT EXISTS (SELECT 1 FROM Dt_Menu WHERE Url = '/Mes_Log')
+    BEGIN
+        INSERT INTO Dt_Menu (ParentId, MenuName, Url, Component, Permission, Sort, Icon, CreateDate, Modifier)
+        VALUES (
+            @SystemMenuId,
+            'MES鎺ュ彛鏃ュ織',
+            '/Mes_Log',
+            'views/system/Mes_Log',
+            'Mes_Log:view',
+            (SELECT ISNULL(MAX(Sort), 0) + 1 FROM Dt_Menu WHERE ParentId = @SystemMenuId),
+            'el-icon-document',
+            GETDATE(),
+            'System'
+        );
+        PRINT 'MES鎺ュ彛鏃ュ織鑿滃崟宸叉坊鍔狅紝ID: ' + CAST(SCOPE_IDENTITY() AS VARCHAR(10));
+    END
+    ELSE
+    BEGIN
+        PRINT 'MES鎺ュ彛鏃ュ織鑿滃崟宸插瓨鍦�';
+    END
+END
+GO
+
+-- =============================================
+-- Step 3: 娣诲姞鏁版嵁瀛楀吀璁板綍
+-- =============================================
+
+-- 鎺ュ彛绫诲瀷瀛楀吀
+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();
+    PRINT 'MES鎺ュ彛绫诲瀷瀛楀吀宸插垱寤猴紝ID: ' + CAST(@DictId AS VARCHAR(10));
+END
+ELSE
+BEGIN
+    PRINT 'MES鎺ュ彛绫诲瀷瀛楀吀宸插瓨鍦紝ID: ' + CAST(@DictId AS VARCHAR(10));
+END
+
+-- 娣诲姞鎺ュ彛绫诲瀷閫夐」
+IF NOT EXISTS (SELECT 1 FROM Dt_DictionaryList WHERE DictId = @DictId AND [Key] = 'BindContainer')
+BEGIN
+    INSERT INTO Dt_DictionaryList (DictId, Value, [Key], DisplayOrder, CreateDate, Modifier)
+    VALUES (@DictId, '鐢佃姱缁戝畾', 'BindContainer', 1, GETDATE(), 'System');
+    PRINT '鎺ュ彛绫诲瀷閫夐」宸叉坊鍔�: BindContainer (鐢佃姱缁戝畾)';
+END
+
+IF NOT EXISTS (SELECT 1 FROM Dt_DictionaryList WHERE DictId = @DictId AND [Key] = 'UnBindContainer')
+BEGIN
+    INSERT INTO Dt_DictionaryList (DictId, Value, [Key], DisplayOrder, CreateDate, Modifier)
+    VALUES (@DictId, '鐢佃姱瑙g粦', 'UnBindContainer', 2, GETDATE(), 'System');
+    PRINT '鎺ュ彛绫诲瀷閫夐」宸叉坊鍔�: UnBindContainer (鐢佃姱瑙g粦)';
+END
+
+IF NOT EXISTS (SELECT 1 FROM Dt_DictionaryList WHERE DictId = @DictId AND [Key] = 'ContainerNgReport')
+BEGIN
+    INSERT INTO Dt_DictionaryList (DictId, Value, [Key], DisplayOrder, CreateDate, Modifier)
+    VALUES (@DictId, 'NG涓婃姤', 'ContainerNgReport', 3, GETDATE(), 'System');
+    PRINT '鎺ュ彛绫诲瀷閫夐」宸叉坊鍔�: ContainerNgReport (NG涓婃姤)';
+END
+
+IF NOT EXISTS (SELECT 1 FROM Dt_DictionaryList WHERE DictId = @DictId AND [Key] = 'InboundInContainer')
+BEGIN
+    INSERT INTO Dt_DictionaryList (DictId, Value, [Key], DisplayOrder, CreateDate, Modifier)
+    VALUES (@DictId, '鎵樼洏杩涚珯', 'InboundInContainer', 4, GETDATE(), 'System');
+    PRINT '鎺ュ彛绫诲瀷閫夐」宸叉坊鍔�: InboundInContainer (鎵樼洏杩涚珯)';
+END
+
+IF NOT EXISTS (SELECT 1 FROM Dt_DictionaryList WHERE DictId = @DictId AND [Key] = 'OutboundInContainer')
+BEGIN
+    INSERT INTO Dt_DictionaryList (DictId, Value, [Key], DisplayOrder, CreateDate, Modifier)
+    VALUES (@DictId, '鎵樼洏鍑虹珯', 'OutboundInContainer', 5, GETDATE(), 'System');
+    PRINT '鎺ュ彛绫诲瀷閫夐」宸叉坊鍔�: OutboundInContainer (鎵樼洏鍑虹珯)';
+END
+
+-- 璋冪敤鐘舵�佸瓧鍏�
+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();
+    PRINT 'MES鎺ュ彛鐘舵�佸瓧鍏稿凡鍒涘缓锛孖D: ' + CAST(@StatusDictId AS VARCHAR(10));
+END
+ELSE
+BEGIN
+    PRINT 'MES鎺ュ彛鐘舵�佸瓧鍏稿凡瀛樺湪锛孖D: ' + CAST(@StatusDictId AS VARCHAR(10));
+END
+
+-- 娣诲姞鐘舵�侀�夐」
+IF NOT EXISTS (SELECT 1 FROM Dt_DictionaryList WHERE DictId = @StatusDictId AND [Key] = 'true')
+BEGIN
+    INSERT INTO Dt_DictionaryList (DictId, Value, [Key], DisplayOrder, CreateDate, Modifier)
+    VALUES (@StatusDictId, '鎴愬姛', 'true', 1, GETDATE(), 'System');
+    PRINT '鐘舵�侀�夐」宸叉坊鍔�: true (鎴愬姛)';
+END
+
+IF NOT EXISTS (SELECT 1 FROM Dt_DictionaryList WHERE DictId = @StatusDictId AND [Key] = 'false')
+BEGIN
+    INSERT INTO Dt_DictionaryList (DictId, Value, [Key], DisplayOrder, CreateDate, Modifier)
+    VALUES (@StatusDictId, '澶辫触', 'false', 2, GETDATE(), 'System');
+    PRINT '鐘舵�侀�夐」宸叉坊鍔�: false (澶辫触)';
+END
+
+PRINT '=====================================';
+PRINT '鏁版嵁瀛楀吀閰嶇疆瀹屾垚';
+PRINT '=====================================';
+GO
+
+-- =============================================
+-- 鎵ц瀹屾瘯
+-- =============================================
+PRINT '=====================================';
+PRINT 'MES 鎺ュ彛鏃ュ織椤甸潰鏁版嵁搴撻厤缃墽琛屽畬姣�';
+PRINT '=====================================';
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/MesLogService.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/MesLogService.cs
new file mode 100644
index 0000000..35f73cb
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/MesLogService.cs
@@ -0,0 +1,298 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using SqlSugar;
+using WIDESEA_Core;
+using WIDESEA_Core.BaseRepository;
+using WIDESEA_Core.BaseServices;
+using WIDESEA_DTO.MES;
+using WIDESEA_IBasicService;
+using WIDESEA_Model.Models;
+
+namespace WIDESEA_BasicService
+{
+    /// <summary>
+    /// MES鎺ュ彛鏃ュ織鏈嶅姟瀹炵幇
+    /// </summary>
+    public class MesLogService : ServiceBase<Dt_MesApiLog, IRepository<Dt_MesApiLog>>, IMesLogService
+    {
+        private readonly ISqlSugarClient _db;
+
+        /// <summary>
+        /// 鏋勯�犲嚱鏁�
+        /// </summary>
+        /// <param name="db">鏁版嵁搴撳鎴风</param>
+        public MesLogService(ISqlSugarClient db, IRepository<Dt_MesApiLog> repository) : base(repository)
+        {
+            _db = db;
+        }
+
+        /// <summary>
+        /// 璁板綍MES鎺ュ彛璋冪敤鏃ュ織
+        /// </summary>
+        /// <param name="log">鏃ュ織DTO</param>
+        /// <returns>鏄惁璁板綍鎴愬姛</returns>
+        public async Task<bool> LogAsync(MesApiLogDto log)
+        {
+            try
+            {
+                var entity = new Dt_MesApiLog
+                {
+                    ApiType = log.ApiType,
+                    RequestJson = log.RequestJson,
+                    ResponseJson = log.ResponseJson,
+                    IsSuccess = log.IsSuccess,
+                    ErrorMessage = log.ErrorMessage,
+                    ElapsedMs = log.ElapsedMs,
+                    CreateDate = DateTime.Now,
+                    Creator = log.Creator
+                };
+
+                var result = await _db.Insertable(entity).ExecuteCommandAsync();
+                return result > 0;
+            }
+            catch (Exception ex)
+            {
+                // TODO: 浣跨敤椤圭洰鏃ュ織妗嗘灦璁板綍閿欒
+                Console.WriteLine($"璁板綍MES鏃ュ織澶辫触: {ex.Message}");
+                return false;
+            }
+        }
+
+        /// <summary>
+        /// 鑾峰彇鏈�杩戠殑MES鎺ュ彛璋冪敤璁板綍
+        /// </summary>
+        /// <param name="apiType">鎺ュ彛绫诲瀷</param>
+        /// <param name="count">璁板綍鏁伴噺</param>
+        /// <returns>鏃ュ織鍒楄〃</returns>
+        public async Task<List<MesApiLogDto>> GetRecentLogsAsync(string apiType, int count = 50)
+        {
+            try
+            {
+                var entities = await _db.Queryable<Dt_MesApiLog>()
+                    .Where(x => x.ApiType == apiType)
+                    .OrderByDescending(x => x.CreateDate)
+                    .Take(count)
+                    .ToListAsync();
+
+                return entities.Select(e => new MesApiLogDto
+                {
+                    ApiType = e.ApiType,
+                    RequestJson = e.RequestJson,
+                    ResponseJson = e.ResponseJson,
+                    IsSuccess = e.IsSuccess,
+                    ErrorMessage = e.ErrorMessage,
+                    ElapsedMs = e.ElapsedMs,
+                    Creator = e.Creator
+                }).ToList();
+            }
+            catch (Exception ex)
+            {
+                // TODO: 浣跨敤椤圭洰鏃ュ織妗嗘灦璁板綍閿欒
+                Console.WriteLine($"鑾峰彇MES鏃ュ織澶辫触: {ex.Message}");
+                return new List<MesApiLogDto>();
+            }
+        }
+
+        /// <summary>
+        /// 鍒嗛〉鏌ヨMES鏃ュ織
+        /// </summary>
+        public async Task<(List<MesLogListItemDto> items, int total)> GetPageAsync(MesLogQueryDto query, int page, int pageSize)
+        {
+            var dbQuery = _db.Queryable<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 != null && 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 != null && x.ErrorMessage.Contains(query.ErrorKeyword));
+            }
+
+            if (!string.IsNullOrEmpty(query.JsonRequestKeyword))
+            {
+                dbQuery = dbQuery.Where(x => x.RequestJson != null && x.RequestJson.Contains(query.JsonRequestKeyword));
+            }
+
+            if (!string.IsNullOrEmpty(query.JsonResponseKeyword))
+            {
+                dbQuery = dbQuery.Where(x => x.ResponseJson != null && x.ResponseJson.Contains(query.JsonResponseKeyword));
+            }
+
+            // 鑾峰彇鎬绘暟
+            var total = await dbQuery.CountAsync();
+
+            // 鍒嗛〉鏌ヨ
+            var entities = await dbQuery
+                .OrderByDescending(x => x.CreateDate)
+                .ToPageListAsync(page, pageSize);
+
+            var items = entities.Select(e => new MesLogListItemDto
+            {
+                Id = e.Id,
+                ApiType = e.ApiType,
+                IsSuccess = e.IsSuccess,
+                RequestJson = e.RequestJson?.Length > 200 ? e.RequestJson.Substring(0, 200) + "..." : e.RequestJson,
+                ResponseJson = 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);
+        }
+
+        /// <summary>
+        /// 鑾峰彇鍗曟潯鏃ュ織璇︽儏
+        /// </summary>
+        public async Task<MesLogDetailDto?> GetDetailAsync(long id)
+        {
+            var entity = await _db.Queryable<Dt_MesApiLog>()
+                .Where(x => x.Id == id)
+                .FirstAsync();
+
+            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
+            };
+        }
+
+        /// <summary>
+        /// 鑾峰彇缁熻鏁版嵁
+        /// </summary>
+        public async Task<MesLogStatisticsDto> GetStatisticsAsync(MesLogQueryDto query)
+        {
+            var dbQuery = _db.Queryable<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 totalCount = await dbQuery.CountAsync();
+            var successCount = await dbQuery.Where(x => x.IsSuccess).CountAsync();
+            var failedCount = totalCount - successCount;
+            var successRate = totalCount > 0 ? (successCount * 100.0 / totalCount) : 0;
+
+            // 鑾峰彇鎵�鏈夋暟鎹潵璁$畻骞冲潎鍊煎拰鏈�澶у�硷紙SqlSugar 闄愬埗锛�
+            var allData = await dbQuery.Select(x => x.ElapsedMs).ToListAsync();
+            var avgElapsed = allData.Count > 0 ? allData.Average() : 0;
+            var maxElapsed = allData.Count > 0 ? allData.Max() : 0;
+
+            // 浠婃棩鏁版嵁
+            var today = DateTime.Today;
+            var todayCount = await dbQuery.Where(x => x.CreateDate >= today).CountAsync();
+
+            return new MesLogStatisticsDto
+            {
+                TotalCount = totalCount,
+                SuccessCount = successCount,
+                FailedCount = failedCount,
+                SuccessRate = Math.Round(successRate, 2),
+                AvgElapsedMs = avgElapsed,
+                MaxElapsedMs = maxElapsed,
+                TodayCount = todayCount
+            };
+        }
+
+        /// <summary>
+        /// 瀵煎嚭鏃ュ織鏁版嵁
+        /// </summary>
+        public async Task<byte[]> ExportAsync(MesLogQueryDto query)
+        {
+            // 鑾峰彇鎵�鏈夌鍚堟潯浠剁殑鏁版嵁锛堥檺鍒�50000琛岋級
+            var (items, _) = await GetPageAsync(query, 1, 50000);
+
+            using var memoryStream = new MemoryStream();
+            using var writer = new StreamWriter(memoryStream, Encoding.UTF8);
+
+            // 鍐欏叆 UTF-8 BOM锛屼娇 Excel 鑳芥纭瘑鍒腑鏂�
+            writer.Write('\uFEFF');
+
+            // CSV 澶撮儴
+            writer.WriteLine("ID,鎺ュ彛绫诲瀷,鐘舵��,鑰楁椂(ms),閿欒淇℃伅,鍒涘缓鏃堕棿,鍒涘缓浜�");
+
+            // CSV 鏁版嵁琛�
+            foreach (var item in items)
+            {
+                var error = item.ErrorMessage?.Replace("\"", "\"\"") ?? "";
+                var status = item.IsSuccess ? "鎴愬姛" : "澶辫触";
+                writer.WriteLine($"{item.Id},{item.ApiType},{status},{item.ElapsedMs},\"{error}\",{item.CreateDate:yyyy-MM-dd HH:mm:ss},{item.Creator ?? ""}");
+            }
+
+            writer.Flush();
+            return memoryStream.ToArray();
+        }
+    }
+}
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/MesService.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/MesService.cs
index 79bd0bd..ccae68c 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/MesService.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_BasicService/MesService.cs
@@ -10,7 +10,7 @@
     /// <summary>
     /// MES鏈嶅姟瀹炵幇 - 闄曡タ椤峰埢鑳芥簮绉戞妧MES绯荤粺瀵规帴
     /// </summary>
-    public class MesService : IMesService
+    public class MesService : IMesService 
     {
         private readonly HttpClientHelper _httpClient;
         private readonly string _baseUrl;
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLogDetailDto.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLogDetailDto.cs
new file mode 100644
index 0000000..453a76a
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLogDetailDto.cs
@@ -0,0 +1,75 @@
+using System;
+
+namespace WIDESEA_DTO.MES
+{
+    /// <summary>
+    /// MES鏃ュ織璇︽儏DTO
+    /// </summary>
+    public class MesLogDetailDto
+    {
+        /// <summary>
+        /// 鏃ュ織ID
+        /// </summary>
+        public long Id { get; set; }
+
+        /// <summary>
+        /// 鎺ュ彛绫诲瀷
+        /// </summary>
+        public string ApiType { get; set; } = string.Empty;
+
+        /// <summary>
+        /// 鏄惁鎴愬姛
+        /// </summary>
+        public bool IsSuccess { get; set; }
+
+        /// <summary>
+        /// 璇锋眰JSON锛堝畬鏁达級
+        /// </summary>
+        public string? RequestJson { get; set; }
+
+        /// <summary>
+        /// 鍝嶅簲JSON锛堝畬鏁达級
+        /// </summary>
+        public string? ResponseJson { get; set; }
+
+        /// <summary>
+        /// 璇锋眰JSON棰勮
+        /// </summary>
+        public string? RequestJsonPreview { get; set; }
+
+        /// <summary>
+        /// 鍝嶅簲JSON棰勮
+        /// </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; }
+
+        /// <summary>
+        /// 淇敼鏃堕棿
+        /// </summary>
+        public DateTime? ModifyDate { get; set; }
+
+        /// <summary>
+        /// 淇敼浜�
+        /// </summary>
+        public string? Modifier { get; set; }
+    }
+}
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLogListItemDto.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLogListItemDto.cs
new file mode 100644
index 0000000..3bdd26b
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLogListItemDto.cs
@@ -0,0 +1,55 @@
+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; } = string.Empty;
+
+        /// <summary>
+        /// 鏄惁鎴愬姛
+        /// </summary>
+        public bool IsSuccess { get; set; }
+
+        /// <summary>
+        /// 璇锋眰JSON锛堥瑙堬級
+        /// </summary>
+        public string? RequestJson { get; set; }
+
+        /// <summary>
+        /// 鍝嶅簲JSON锛堥瑙堬級
+        /// </summary>
+        public string? ResponseJson { 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; }
+    }
+}
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLogQueryDto.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLogQueryDto.cs
new file mode 100644
index 0000000..205f55b
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLogQueryDto.cs
@@ -0,0 +1,60 @@
+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; }
+    }
+}
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLogStatisticsDto.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLogStatisticsDto.cs
new file mode 100644
index 0000000..6e8bcb6
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_DTO/MES/MesLogStatisticsDto.cs
@@ -0,0 +1,50 @@
+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 int FailedCount { get; set; }
+
+        /// <summary>
+        /// 鎴愬姛鐜囷紙鐧惧垎姣旓級
+        /// </summary>
+        public double SuccessRate { 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; }
+    }
+}
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_IBasicService/IMesLogService.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_IBasicService/IMesLogService.cs
new file mode 100644
index 0000000..342d446
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_IBasicService/IMesLogService.cs
@@ -0,0 +1,60 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using WIDESEA_Core;
+using WIDESEA_Core.BaseServices;
+using WIDESEA_DTO.MES;
+using WIDESEA_Model.Models;
+
+namespace WIDESEA_IBasicService
+{
+    /// <summary>
+    /// MES鎺ュ彛鏃ュ織鏈嶅姟鎺ュ彛
+    /// </summary>
+    public interface IMesLogService : IService<Dt_MesApiLog>
+    {
+        /// <summary>
+        /// 璁板綍MES鎺ュ彛璋冪敤鏃ュ織
+        /// </summary>
+        /// <param name="log">鏃ュ織DTO</param>
+        /// <returns>鏄惁璁板綍鎴愬姛</returns>
+        Task<bool> LogAsync(MesApiLogDto log);
+
+        /// <summary>
+        /// 鑾峰彇鏈�杩戠殑MES鎺ュ彛璋冪敤璁板綍
+        /// </summary>
+        /// <param name="apiType">鎺ュ彛绫诲瀷</param>
+        /// <param name="count">璁板綍鏁伴噺</param>
+        /// <returns>鏃ュ織鍒楄〃</returns>
+        Task<List<MesApiLogDto>> GetRecentLogsAsync(string apiType, int count = 50);
+
+        /// <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>CSV瀛楄妭鏁扮粍</returns>
+        Task<byte[]> ExportAsync(MesLogQueryDto query);
+    }
+}
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_IMesService/IMesLogService.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_IMesService/IMesLogService.cs
deleted file mode 100644
index 595c03f..0000000
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_IMesService/IMesLogService.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using WIDESEA_Core;
-using WIDESEA_DTO.MES;
-
-namespace WIDESEA_IMesService
-{
-    /// <summary>
-    /// MES鎺ュ彛鏃ュ織鏈嶅姟鎺ュ彛
-    /// </summary>
-    public interface IMesLogService : IDependency
-    {
-        /// <summary>
-        /// 璁板綍MES鎺ュ彛璋冪敤鏃ュ織
-        /// </summary>
-        /// <param name="log">鏃ュ織DTO</param>
-        /// <returns>鏄惁璁板綍鎴愬姛</returns>
-        Task<bool> LogAsync(MesApiLogDto log);
-
-        /// <summary>
-        /// 鑾峰彇鏈�杩戠殑MES鎺ュ彛璋冪敤璁板綍
-        /// </summary>
-        /// <param name="apiType">鎺ュ彛绫诲瀷</param>
-        /// <param name="count">璁板綍鏁伴噺</param>
-        /// <returns>鏃ュ織鍒楄〃</returns>
-        Task<List<MesApiLogDto>> GetRecentLogsAsync(string apiType, int count = 50);
-    }
-}
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_IMesService/WIDESEA_IMesService.csproj b/Code/WMS/WIDESEA_WMSServer/WIDESEA_IMesService/WIDESEA_IMesService.csproj
deleted file mode 100644
index 56e718b..0000000
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_IMesService/WIDESEA_IMesService.csproj
+++ /dev/null
@@ -1,14 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <TargetFramework>net8.0</TargetFramework>
-    <ImplicitUsings>enable</ImplicitUsings>
-    <Nullable>enable</Nullable>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\WIDESEA_DTO\WIDESEA_DTO.csproj" />
-    <ProjectReference Include="..\WIDESEA_Core\WIDESEA_Core.csproj" />
-  </ItemGroup>
-
-</Project>
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_MesService/MesLogService.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_MesService/MesLogService.cs
deleted file mode 100644
index 30b40c9..0000000
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_MesService/MesLogService.cs
+++ /dev/null
@@ -1,95 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using SqlSugar;
-using WIDESEA_Core;
-using WIDESEA_DTO.MES;
-using WIDESEA_IMesService;
-using WIDESEA_Model.Models.Mes;
-
-namespace WIDESEA_MesService
-{
-    /// <summary>
-    /// MES鎺ュ彛鏃ュ織鏈嶅姟瀹炵幇
-    /// </summary>
-    public class MesLogService : IMesLogService
-    {
-        private readonly ISqlSugarClient _db;
-
-        /// <summary>
-        /// 鏋勯�犲嚱鏁�
-        /// </summary>
-        /// <param name="db">鏁版嵁搴撳鎴风</param>
-        public MesLogService(ISqlSugarClient db)
-        {
-            _db = db;
-        }
-
-        /// <summary>
-        /// 璁板綍MES鎺ュ彛璋冪敤鏃ュ織
-        /// </summary>
-        /// <param name="log">鏃ュ織DTO</param>
-        /// <returns>鏄惁璁板綍鎴愬姛</returns>
-        public async Task<bool> LogAsync(MesApiLogDto log)
-        {
-            try
-            {
-                var entity = new Dt_MesApiLog
-                {
-                    ApiType = log.ApiType,
-                    RequestJson = log.RequestJson,
-                    ResponseJson = log.ResponseJson,
-                    IsSuccess = log.IsSuccess,
-                    ErrorMessage = log.ErrorMessage,
-                    ElapsedMs = log.ElapsedMs,
-                    CreateDate = DateTime.Now,
-                    Creator = log.Creator
-                };
-
-                var result = await _db.Insertable(entity).ExecuteCommandAsync();
-                return result > 0;
-            }
-            catch (Exception ex)
-            {
-                // 璁板綍鏃ュ織澶辫触涓嶅奖鍝嶄富娴佺▼
-                Console.WriteLine($"璁板綍MES鏃ュ織澶辫触: {ex.Message}");
-                return false;
-            }
-        }
-
-        /// <summary>
-        /// 鑾峰彇鏈�杩戠殑MES鎺ュ彛璋冪敤璁板綍
-        /// </summary>
-        /// <param name="apiType">鎺ュ彛绫诲瀷</param>
-        /// <param name="count">璁板綍鏁伴噺</param>
-        /// <returns>鏃ュ織鍒楄〃</returns>
-        public async Task<List<MesApiLogDto>> GetRecentLogsAsync(string apiType, int count = 50)
-        {
-            try
-            {
-                var entities = await _db.Queryable<Dt_MesApiLog>()
-                    .Where(x => x.ApiType == apiType)
-                    .OrderByDescending(x => x.CreateDate)
-                    .Take(count)
-                    .ToListAsync();
-
-                return entities.Select(e => new MesApiLogDto
-                {
-                    ApiType = e.ApiType,
-                    RequestJson = e.RequestJson,
-                    ResponseJson = e.ResponseJson,
-                    IsSuccess = e.IsSuccess,
-                    ErrorMessage = e.ErrorMessage,
-                    ElapsedMs = e.ElapsedMs,
-                    Creator = e.Creator
-                }).ToList();
-            }
-            catch (Exception ex)
-            {
-                Console.WriteLine($"鑾峰彇MES鏃ュ織澶辫触: {ex.Message}");
-                return new List<MesApiLogDto>();
-            }
-        }
-    }
-}
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_MesService/WIDESEA_MesService.csproj b/Code/WMS/WIDESEA_WMSServer/WIDESEA_MesService/WIDESEA_MesService.csproj
deleted file mode 100644
index 0498bd2..0000000
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_MesService/WIDESEA_MesService.csproj
+++ /dev/null
@@ -1,16 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <TargetFramework>net8.0</TargetFramework>
-    <ImplicitUsings>enable</ImplicitUsings>
-    <Nullable>enable</Nullable>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\WIDESEA_IMesService\WIDESEA_IMesService.csproj" />
-    <ProjectReference Include="..\WIDESEA_Core\WIDESEA_Core.csproj" />
-    <ProjectReference Include="..\WIDESEA_Model\WIDESEA_Model.csproj" />
-    <ProjectReference Include="..\WIDESEA_DTO\WIDESEA_DTO.csproj" />
-  </ItemGroup>
-
-</Project>
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Mes/Dt_MesApiLog.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Mes/Dt_MesApiLog.cs
index 0ec802a..a8549a1 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Mes/Dt_MesApiLog.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Mes/Dt_MesApiLog.cs
@@ -1,7 +1,7 @@
 using SqlSugar;
 using System;
 
-namespace WIDESEA_Model.Models.Mes
+namespace WIDESEA_Model.Models
 {
     /// <summary>
     /// MES鎺ュ彛璋冪敤鏃ュ織瀹炰綋
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Mes/MesLogController.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Mes/MesLogController.cs
new file mode 100644
index 0000000..e7f78ea
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Mes/MesLogController.cs
@@ -0,0 +1,116 @@
+using Autofac.Core;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using WIDESEA_Core;
+using WIDESEA_Core.BaseController;
+using WIDESEA_DTO.MES;
+using WIDESEA_IBasicService;
+using WIDESEA_Model.Models;
+
+namespace WIDESEA_WMSServer.Controllers.Mes
+{
+    /// <summary>
+    /// MES鎺ュ彛鏃ュ織鎺у埗鍣�
+    /// </summary>
+    [Route("api/MesLog")]
+    [ApiController]
+    [Authorize]
+    public class MesLogController : ApiBaseController<IMesLogService, Dt_MesApiLog>
+    {
+        private readonly IMesLogService _mesLogService;
+
+        /// <summary>
+        /// 鏋勯�犲嚱鏁�
+        /// </summary>
+        public MesLogController(IMesLogService mesLogService) : base(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>CSV鏂囦欢</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 });
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs
index 1483686..ec0c45e 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs
@@ -7,7 +7,6 @@
 using WIDESEA_DTO.MES;
 using WIDESEA_IStockService;
 using WIDESEA_IBasicService;
-using WIDESEA_IMesService;
 using WIDESEA_ISystemService;
 using WIDESEA_Model.Models;
 using WIDESEA_Common.StockEnum;
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoDetailController.cs b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoDetailController.cs
index eca38b2..4abd388 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoDetailController.cs
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoDetailController.cs
@@ -5,7 +5,6 @@
 using WIDESEA_DTO.MES;
 using WIDESEA_IStockService;
 using WIDESEA_IBasicService;
-using WIDESEA_IMesService;
 using WIDESEA_ISystemService;
 using WIDESEA_Model.Models;
 using System.Diagnostics;
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/WIDESEA_WMSServer.csproj b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/WIDESEA_WMSServer.csproj
index 89edbde..234f1e2 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/WIDESEA_WMSServer.csproj
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/WIDESEA_WMSServer.csproj
@@ -59,7 +59,6 @@
 	  <ProjectReference Include="..\WIDESEA_BasicService\WIDESEA_BasicService.csproj" />
 	  <ProjectReference Include="..\WIDESEA_CheckService\WIDESEA_CheckService.csproj" />
 	  <ProjectReference Include="..\WIDESEA_InboundService\WIDESEA_InboundService.csproj" />
-	  <ProjectReference Include="..\WIDESEA_MesService\WIDESEA_MesService.csproj" />
 	  <ProjectReference Include="..\WIDESEA_OutboundService\WIDESEA_OutboundService.csproj" />
 	  <ProjectReference Include="..\WIDESEA_RecordService\WIDESEA_RecordService.csproj" />
 	  <ProjectReference Include="..\WIDESEA_StockService\WIDESEA_StockService.csproj" />
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`
diff --git a/Code/docs/superpowers/specs/2026-04-13-mes-api-log-page-design.md b/Code/docs/superpowers/specs/2026-04-13-mes-api-log-page-design.md
new file mode 100644
index 0000000..81592ec
--- /dev/null
+++ b/Code/docs/superpowers/specs/2026-04-13-mes-api-log-page-design.md
@@ -0,0 +1,896 @@
+# MES 鎺ュ彛璋冪敤鏃ュ織椤甸潰璁捐鏂囨。
+
+**鏃ユ湡:** 2026-04-13
+**浣滆��:** Claude
+**鐗堟湰:** v0.3
+**鐘舵��:** 宸叉壒鍑�
+
+---
+
+## 1. 姒傝堪
+
+### 1.1 鐩爣
+
+鍦� WMS 绯荤粺涓坊鍔� MES 鎺ュ彛璋冪敤鏃ュ織鏌ョ湅椤甸潰锛屾彁渚涚患鍚堟�х殑鏃ュ織鏌ヨ銆佺粺璁″拰绠$悊鍔熻兘銆�
+
+### 1.2 鑼冨洿
+
+- 鍚庣锛欰PI 鎺ュ彛銆佹湇鍔″眰鎵╁睍
+- 鍓嶇锛氭棩蹇楀垪琛ㄩ〉闈€�佺粺璁″崱鐗囥�丣SON 璇︽儏鏌ョ湅鍣�
+- 鏁版嵁搴擄細鑿滃崟閰嶇疆銆佹暟鎹瓧鍏�
+
+---
+
+## 2. 鍚庣璁捐
+
+### 2.1 Controller 鎺ュ彛
+
+**鏂囦欢璺緞:** `WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Mes/MesLogController.cs`
+
+**娉ㄦ剰:** 姝ゆ帶鍒跺櫒涓嶇户鎵� `ApiBaseController`锛屽洜涓� MES 鏃ュ織鏄彧璇昏褰曪紝涓嶉渶瑕佸畬鏁寸殑 CRUD 鎿嶄綔銆備粎鎻愪緵鏌ヨ銆佺粺璁″拰瀵煎嚭鍔熻兘銆�
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | `/api/MesLog/page` | 鍒嗛〉鏌ヨ锛屾敮鎸佹墍鏈夌瓫閫夋潯浠� |
+| GET | `/api/MesLog/{id}` | 鑾峰彇鍗曟潯鏃ュ織瀹屾暣淇℃伅 |
+| GET | `/api/MesLog/statistics` | 鑾峰彇缁熻鏁版嵁 |
+| POST | `/api/MesLog/export` | 瀵煎嚭鏌ヨ缁撴灉涓� Excel (浣跨敤妗嗘灦鍐呯疆瀵煎嚭) |
+
+### 2.2 鏁版嵁浼犺緭瀵硅薄
+
+#### 2.2.1 鏌ヨ璇锋眰 DTO
+
+```csharp
+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; }
+    }
+}
+```
+
+#### 2.2.2 缁熻鏁版嵁 DTO
+
+```csharp
+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; }
+    }
+}
+```
+
+#### 2.2.3 鍒嗛〉鍝嶅簲 DTO
+
+```csharp
+namespace WIDESEA_DTO.MES
+{
+    /// <summary>
+    /// MES鏃ュ織鍒楄〃椤笵TO
+    /// </summary>
+    public class MesLogListItemDto
+    {
+        public long Id { get; set; }
+        public string ApiType { get; set; }
+        public bool IsSuccess { get; set; }
+        public string RequestJsonPreview { get; set; }  // 鍓�200瀛楃棰勮
+        public string ResponseJsonPreview { get; set; } // 鍓�200瀛楃棰勮
+        public string ErrorMessage { get; set; }
+        public int ElapsedMs { get; set; }
+        public DateTime CreateDate { get; set; }
+        public string Creator { get; set; }
+    }
+
+    /// <summary>
+    /// MES鏃ュ織璇︽儏DTO
+    /// </summary>
+    public class MesLogDetailDto : MesLogListItemDto
+    {
+        public string RequestJson { get; set; }   // 瀹屾暣JSON
+        public string ResponseJson { get; set; }  // 瀹屾暣JSON
+        public DateTime? ModifyDate { get; set; }
+        public string Modifier { get; set; }
+    }
+}
+```
+
+### 2.3 Service 鎺ュ彛鎵╁睍
+
+**鏂囦欢璺緞:** `WMS/WIDESEA_WMSServer/WIDESEA_IMesService/IMesLogService.cs`
+
+```csharp
+namespace WIDESEA_IMesService
+{
+    public interface IMesLogService : IDependency
+    {
+        // 鐜版湁鏂规硶
+        Task<bool> LogAsync(MesApiLogDto log);
+        Task<List<MesApiLogDto>> GetRecentLogsAsync(string apiType, int count = 50);
+
+        // 鏂板鏂规硶
+        /// <summary>
+        /// 鍒嗛〉鏌ヨMES鏃ュ織
+        /// </summary>
+        Task<(List<MesLogListItemDto> items, int total)> GetPageAsync(MesLogQueryDto query, int page, int pageSize);
+
+        /// <summary>
+        /// 鑾峰彇鍗曟潯鏃ュ織璇︽儏
+        /// </summary>
+        Task<MesLogDetailDto> GetDetailAsync(long id);
+
+        /// <summary>
+        /// 鑾峰彇缁熻鏁版嵁
+        /// </summary>
+        Task<MesLogStatisticsDto> GetStatisticsAsync(MesLogQueryDto query);
+
+        /// <summary>
+        /// 瀵煎嚭鏃ュ織鏁版嵁
+        /// </summary>
+        Task<byte[]> ExportAsync(MesLogQueryDto query);
+    }
+}
+```
+
+### 2.4 Controller 瀹炵幇妗嗘灦
+
+```csharp
+namespace WIDESEA_WMSServer.Controllers.Mes
+{
+    [Route("api/MesLog")]
+    [ApiController]
+    public class MesLogController : ControllerBase
+    {
+        private readonly IMesLogService _mesLogService;
+
+        public MesLogController(IMesLogService mesLogService)
+        {
+            _mesLogService = mesLogService;
+        }
+
+        /// <summary>
+        /// 鍒嗛〉鏌ヨMES鏃ュ織
+        /// </summary>
+        [HttpPost("page")]
+        public async Task<WebResponseContent> GetPage([FromBody] MesLogQueryDto query, [FromQuery] int page = 1, [FromQuery] int pageSize = 20)
+        {
+            // 瀹炵幇鍒嗛〉鏌ヨ
+        }
+
+        /// <summary>
+        /// 鑾峰彇鏃ュ織璇︽儏
+        /// </summary>
+        [HttpGet("{id}")]
+        public async Task<WebResponseContent> GetDetail(long id)
+        {
+            // 瀹炵幇璇︽儏鏌ヨ
+        }
+
+        /// <summary>
+        /// 鑾峰彇缁熻鏁版嵁
+        /// </summary>
+        [HttpGet("statistics")]
+        public async Task<WebResponseContent> GetStatistics([FromQuery] MesLogQueryDto query)
+        {
+            // 瀹炵幇缁熻鏌ヨ
+        }
+
+        /// <summary>
+        /// 瀵煎嚭鏃ュ織 - 浣跨敤妗嗘灦鍐呯疆 ServiceBase.Export() 鏂规硶
+        /// 閫氳繃 HttpHelper.Post() 璋冪敤妗嗘灦鐨勯�氱敤瀵煎嚭鎺ュ彛
+        /// </summary>
+        [HttpPost("export")]
+        public async Task<IActionResult> Export([FromBody] MesLogQueryDto query)
+        {
+            // 璋冪敤 _mesLogService.ExportAsync() 鐢熸垚鏁版嵁
+            // 浣跨敤妗嗘灦鍐呯疆鐨� ExcelExporter 瀵煎嚭
+        }
+    }
+}
+```
+
+### 2.5 鏈嶅姟娉ㄥ唽
+
+**娉ㄦ剰:** `IMesLogService` 宸插疄鐜� `IDependency` 鎺ュ彛锛屾棤闇�鎵嬪姩娉ㄥ唽銆傛鏋朵細閫氳繃 `AutofacModuleRegister` 鑷姩娉ㄥ唽鎵�鏈� `IDependency` 瀹炵幇銆�
+
+---
+
+## 3. 鍓嶇璁捐
+
+### 3.1 鏂囦欢缁撴瀯
+
+```
+src/
+鈹溾攢鈹� views/
+鈹�   鈹斺攢鈹� system/
+鈹�       鈹斺攢鈹� Mes_Log.vue              # 涓婚〉闈�
+鈹溾攢鈹� extension/
+鈹�   鈹斺攢鈹� system/
+鈹�       鈹斺攢鈹� Mes_Log.jsx              # 涓氬姟鎵╁睍閫昏緫
+鈹溾攢鈹� components/
+鈹�   鈹斺攢鈹� MesJsonViewer.vue            # JSON 璇︽儏鏌ョ湅鍣ㄧ粍浠�
+鈹斺攢鈹� router/
+    鈹斺攢鈹� viewGird.js                  # 娣诲姞璺敱閰嶇疆
+```
+
+### 3.2 Mes_Log.vue 閰嶇疆
+
+**娉ㄦ剰:** `view-grid` 缁勪欢涓嶆敮鎸� `toolbar` 鎻掓Ы锛岀粺璁″崱鐗囬渶瑕佹斁鍦� `view-grid` 澶栭儴銆�
+
+```vue
+<template>
+  <div class="mes-log-page">
+    <!-- 缁熻鍗$墖鍖哄煙锛堜綅浜� view-grid 涓婃柟锛� -->
+    <mes-log-statistics ref="statistics" @refresh="onStatsRefresh" />
+
+    <!-- 鏃ュ織鍒楄〃 -->
+    <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 { ref, defineComponent } from "vue";
+
+export default defineComponent({
+  setup() {
+    const table = ref({
+      key: "Id",
+      cnName: "MES鎺ュ彛鏃ュ織",
+      name: "Mes_Log",
+      url: "/api/MesLog/",
+      sortName: "Id DESC",
+    });
+
+    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,
+        formatter: (row) => previewJson(row.requestJson)
+      },
+      {
+        field: "responseJson",
+        title: "鍝嶅簲鍐呭",
+        width: 200,
+        link: true,
+        formatter: (row) => previewJson(row.responseJson)
+      },
+      { field: "errorMessage", title: "閿欒淇℃伅", width: 200 },
+      { field: "elapsedMs", title: "鑰楁椂(ms)", width: 100, sortable: true },
+      { field: "createDate", title: "璋冪敤鏃堕棿", width: 160, sortable: true },
+      { field: "creator", title: "鎿嶄綔浜�", width: 100 }
+    ]);
+
+    // JSON 鍐呭棰勮杈呭姪鍑芥暟锛堝湪 Mes_Log.jsx 涓疄鐜帮級
+    const 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) + '...';
+      }
+    };
+
+    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, searchFormOptions, extend, /* ... */ };
+  }
+});
+</script>
+```
+
+### 3.3 MesJsonViewer.vue 缁勪欢
+
+**娉ㄦ剰:** 涓嶄娇鐢ㄥ閮� JSON 鏌ョ湅鍣ㄥ簱锛岄噰鐢ㄥ師鐢� `<pre>` 鏍囩 + `JSON.stringify()` 鏍煎紡鍖栨樉绀恒��
+
+```vue
+<template>
+  <el-dialog
+    v-model="visible"
+    :title="title"
+    width="800px"
+    :close-on-click-modal="false"
+  >
+    <el-tabs v-model="activeTab">
+      <el-tab-pane label="璇锋眰" name="request">
+        <div class="json-container">
+          <el-button
+            size="small"
+            class="copy-btn"
+            @click="copyToClipboard(formattedRequest)"
+          >
+            澶嶅埗
+          </el-button>
+          <pre class="json-content">{{ formattedRequest }}</pre>
+        </div>
+      </el-tab-pane>
+      <el-tab-pane label="鍝嶅簲" name="response">
+        <div class="json-container">
+          <el-button
+            size="small"
+            class="copy-btn"
+            @click="copyToClipboard(formattedResponse)"
+          >
+            澶嶅埗
+          </el-button>
+          <pre class="json-content">{{ formattedResponse }}</pre>
+        </div>
+      </el-tab-pane>
+    </el-tabs>
+
+    <template #footer>
+      <el-button @click="visible = false">鍏抽棴</el-button>
+    </template>
+  </el-dialog>
+</template>
+
+<script>
+import { computed, ref } from 'vue';
+
+export default {
+  name: "MesJsonViewer",
+  props: {
+    modelValue: Boolean,
+    title: String,
+    requestJson: [String, Object],
+    responseJson: [String, Object]
+  },
+  emits: ["update:modelValue"],
+  setup(props) {
+    const activeTab = ref('request');
+
+    const formattedRequest = computed(() => {
+      try {
+        const obj = typeof props.requestJson === 'string'
+          ? JSON.parse(props.requestJson)
+          : props.requestJson;
+        return JSON.stringify(obj, null, 2);
+      } catch {
+        return props.requestJson || '{}';
+      }
+    });
+
+    const formattedResponse = computed(() => {
+      try {
+        const obj = typeof props.responseJson === 'string'
+          ? JSON.parse(props.responseJson)
+          : props.responseJson;
+        return JSON.stringify(obj, null, 2);
+      } catch {
+        return props.responseJson || '{}';
+      }
+    });
+
+    const copyToClipboard = (text) => {
+      // 浼樺厛浣跨敤鐜颁唬 Clipboard API锛堥渶瑕� HTTPS 鎴� localhost锛�
+      if (navigator.clipboard && navigator.clipboard.writeText) {
+        navigator.clipboard.writeText(text).catch(() => {
+          // 濡傛灉澶辫触锛屼娇鐢ㄩ檷绾ф柟妗�
+          fallbackCopy(text);
+        });
+      } else {
+        // 闄嶇骇鏂规锛氬吋瀹� HTTP 鐜鍜屾棫娴忚鍣�
+        fallbackCopy(text);
+      }
+    };
+
+    const fallbackCopy = (text) => {
+      const textarea = document.createElement('textarea');
+      textarea.value = text;
+      textarea.style.position = 'fixed';
+      textarea.style.opacity = '0';
+      document.body.appendChild(textarea);
+      textarea.select();
+      try {
+        document.execCommand('copy');
+      } catch (err) {
+        console.error('澶嶅埗澶辫触:', err);
+      }
+      document.body.removeChild(textarea);
+    };
+
+    return {
+      visible: props.modelValue,
+      activeTab,
+      formattedRequest,
+      formattedResponse,
+      copyToClipboard
+    };
+  }
+};
+</script>
+
+<style scoped>
+.json-container {
+  position: relative;
+}
+
+.copy-btn {
+  position: absolute;
+  top: 8px;
+  right: 8px;
+  z-index: 10;
+}
+
+.json-content {
+  background: #f5f7fa;
+  padding: 16px;
+  border-radius: 4px;
+  max-height: 500px;
+  overflow: auto;
+  font-size: 12px;
+  line-height: 1.5;
+}
+</style>
+```
+
+### 3.4 缁熻鍗$墖缁勪欢
+
+**鏂囦欢璺緞:** `src/components/MesLogStatistics.vue`
+
+**娉ㄦ剰:** 褰撳墠椤圭洰 Element Plus 鐗堟湰涓� 2.2.14锛屼笉鏀寔 `el-statistic` 缁勪欢锛堥渶瑕� 2.3+锛夈�傞噰鐢ㄨ嚜瀹氫箟鍗$墖瀹炵幇銆�
+
+```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 axios from '@/api/axios';
+
+export default {
+  name: "MesLogStatistics",
+  setup() {
+    const statistics = ref({
+      totalCount: 0,
+      successCount: 0,
+      failedCount: 0,
+      successRate: 0,
+      avgElapsedMs: 0,
+      todayCount: 0
+    });
+
+    const fetchStatistics = async () => {
+      const res = await axios.post('/api/MesLog/statistics', {});
+      if (res.status) {
+        statistics.value = res.data;
+      }
+    };
+
+    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>
+```
+
+### 3.5 鑷姩鍒锋柊鍔熻兘
+
+**UX 璇存槑:**
+- 鍒锋柊鎺у埗浣嶄簬椤甸潰鍙充笂瑙掞紝涓庢煡璇㈡潯浠跺苟鍒�
+- 褰撶敤鎴锋墦寮�绛涢�夐潰鏉裤�佺紪杈戞煡璇㈡潯浠舵垨鏌ョ湅璇︽儏鏃讹紝鑷姩鍒锋柊鏆傚仠
+- 鐢ㄦ埛鎵嬪姩鐐瑰嚮鏌ヨ/鍒锋柊鎸夐挳鍚庯紝鑷姩鍒锋柊閲嶆柊璁℃椂
+
+```javascript
+// 鍦� Mes_Log.jsx 涓疄鐜�
+const refreshOptions = [
+  { label: "鍏抽棴", value: 0 },
+  { label: "10绉�", value: 10 },
+  { label: "30绉�", value: 30 },
+  { label: "1鍒嗛挓", value: 60 },
+  { label: "5鍒嗛挓", value: 300 }
+];
+
+let refreshTimer = null;
+
+const setAutoRefresh = (interval) => {
+  if (refreshTimer) {
+    clearInterval(refreshTimer);
+    refreshTimer = null;
+  }
+  if (interval > 0) {
+    refreshTimer = setInterval(() => {
+      // 浠呭湪鐢ㄦ埛鏈氦浜掓椂鍒锋柊鍒楄〃鏁版嵁
+      if (!isUserInteracting) {
+        refresh();
+      }
+    }, interval * 1000);
+  }
+};
+
+// 鐢ㄦ埛浜や簰鏃舵殏鍋滃埛鏂�
+const onUserInteractionStart = () => {
+  isUserInteracting = true;
+};
+
+const onUserInteractionEnd = () => {
+  isUserInteracting = false;
+};
+```
+
+---
+
+## 4. 鏁版嵁瀛楀吀閰嶇疆
+
+### 4.1 鎺ュ彛绫诲瀷瀛楀吀 (mesApiType)
+
+| 鍊� | 鏄剧ず鏂囨湰 | 璇存槑 |
+|---|---------|------|
+| BindContainer | 鐢佃姱缁戝畾 | 鎵樼洏鐢佃姱缁戝畾鎿嶄綔 |
+| UnBindContainer | 鐢佃姱瑙g粦 | 鎵樼洏鐢佃姱瑙g粦鎿嶄綔 |
+| ContainerNgReport | NG涓婃姤 | 鎵樼洏NG鐢佃姱涓婃姤 |
+| InboundInContainer | 鎵樼洏杩涚珯 | 鎵樼洏杩涚珯鎿嶄綔 |
+| OutboundInContainer | 鎵樼洏鍑虹珯 | 鎵樼洏鍑虹珯鎿嶄綔 |
+
+### 4.2 璋冪敤鐘舵�佸瓧鍏� (mesApiStatus)
+
+| 鍊� | 鏄剧ず鏂囨湰 | 棰滆壊 |
+|---|---------|------|
+| true | 鎴愬姛 | 缁胯壊 |
+| false | 澶辫触 | 绾㈣壊 |
+
+---
+
+## 5. 鏉冮檺涓庤彍鍗�
+
+### 5.1 鑿滃崟閰嶇疆
+
+鍦� `Dt_Menu` 琛ㄤ腑娣诲姞锛�
+
+| 瀛楁 | 鍊� |
+|------|-----|
+| ParentId | (绯荤粺绠$悊鑿滃崟鐨� ID) |
+| MenuName | MES鎺ュ彛鏃ュ織 |
+| Url | /Mes_Log |
+| Component | views/system/Mes_Log |
+| Permission | Mes_Log:view |
+| Sort | (鎺掑湪 Sys_Log 涔嬪悗) |
+| Icon | el-icon-document |
+
+### 5.2 鏉冮檺鐐�
+
+- `Mes_Log:view` - 鏌ョ湅鏃ュ織鍒楄〃
+- `Mes_Log:detail` - 鏌ョ湅鏃ュ織璇︽儏
+- `Mes_Log:export` - 瀵煎嚭鏃ュ織
+
+---
+
+## 6. 瀹炵幇姝ラ
+
+### 6.1 鍚庣瀹炵幇
+
+1. 鎵╁睍 `IMesLogService` 鎺ュ彛锛堟坊鍔犲垎椤点�佺粺璁°�佸鍑烘柟娉曪級
+2. 瀹炵幇 `MesLogService` 鐨勬墿灞曟柟娉�
+3. 鍒涘缓 DTO 鏂囦欢锛坄MesLogQueryDto.cs`, `MesLogStatisticsDto.cs`, `MesLogListItemDto.cs`锛�
+4. 鍒涘缓 `MesLogController.cs`
+5. **娉ㄦ剰:** 鏈嶅姟娉ㄥ唽鑷姩瀹屾垚锛坄IMesLogService` 宸插疄鐜� `IDependency`锛�
+
+### 6.2 鍓嶇瀹炵幇
+
+1. 鍒涘缓 `MesJsonViewer.vue` 缁勪欢锛堜娇鐢ㄥ師鐢� `<pre>` 鏍囩锛屾棤澶栭儴渚濊禆锛�
+2. 鍒涘缓 `MesLogStatistics.vue` 缁勪欢锛堜娇鐢� `el-card` 鑷畾涔夊疄鐜帮級
+3. 鍒涘缓 `Mes_Log.jsx` 鎵╁睍閫昏緫
+4. 鍒涘缓 `Mes_Log.vue` 椤甸潰
+5. 鍦� `viewGird.js` 娣诲姞璺敱
+6. 鍦� `extension` 鐩綍娣诲姞鎵╁睍鏂囦欢
+
+### 6.3 鏁版嵁搴撻厤缃�
+
+1. 纭 `Dt_MesApiLog` 琛ㄥ凡瀛樺湪锛堝弬瑙� `Database/Scripts/20260412_MesApiLog.sql`锛�
+2. 鍒涘缓鏁版嵁搴撶储寮曪紙鍙傝 6.4 鑺傦級
+3. 鎻掑叆鑿滃崟璁板綍鍒� `Dt_Menu` 琛�
+4. 鎻掑叆鏁版嵁瀛楀吀璁板綍鍒� `Dt_Dictionary` 琛�
+5. 鍒嗛厤鏉冮檺缁欒鑹�
+
+### 6.4 鏁版嵁搴撶储寮�
+
+鎵ц浠ヤ笅 SQL 鍒涘缓绱㈠紩浠ヤ紭鍖栨煡璇㈡�ц兘锛�
+
+```sql
+-- 鎺ュ彛绫诲瀷绱㈠紩锛堢敤浜庢寜绫诲瀷绛涢�夛級
+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
+```
+
+---
+
+## 7. 鎶�鏈鐐�
+
+### 7.1 JSON 鍐呭鎼滅储
+
+鐢变簬 SQL Server 瀵� JSON 瀛楁鏀寔鏈夐檺锛岄噰鐢� `LIKE` 鎼滅储锛�
+- 閫傜敤浜庡叧閿瓧鎼滅储
+- 娉ㄦ剰鎬ц兘褰卞搷锛屽缓璁厤鍚堟椂闂磋寖鍥寸瓫閫�
+- 鎼滅储瀛楁锛歚RequestJson`銆乣ResponseJson`銆乣ErrorMessage`
+
+### 7.2 鍒嗛〉鎬ц兘
+
+- 鍒╃敤绱㈠紩锛堝弬瑙� 6.4 鑺傛暟鎹簱绱㈠紩锛�
+- 澶ф暟鎹噺鏃跺缓璁鍔犳椂闂磋寖鍥撮檺鍒讹紙榛樿鏄剧ず鏈�杩� 7 澶╋級
+- 鑰冭檻娣诲姞 `TOP 1000` 闄愬埗闃叉鍏ㄨ〃鎵弿
+
+### 7.3 瀵煎嚭鍔熻兘
+
+- 浣跨敤妗嗘灦鍐呯疆鐨� `ServiceBase.Export()` 鏂规硶
+- 閫氳繃 `Magicodes.ExporterAndImporter.Excel` 搴撳疄鐜�
+- 瀵煎嚭鏂囦欢鍛藉悕锛歚MES鎺ュ彛鏃ュ織_YYYYMMDD_HHMMSS.xlsx`
+- 鏀寔涓庡綋鍓嶆煡璇㈡潯浠朵竴鑷寸殑瀵煎嚭
+
+### 7.4 鍓嶇瀛楁鏄犲皠
+
+| 鍓嶇瀛楁 | 鍚庣 DTO 瀛楁 | 璇存槑 |
+|---------|--------------|------|
+| dateRange[0] | StartTime | 寮�濮嬫椂闂� |
+| dateRange[1] | EndTime | 缁撴潫鏃堕棿 |
+| elapsedRange[0] | MinElapsedMs | 鏈�灏忚�楁椂 |
+| elapsedRange[1] | MaxElapsedMs | 鏈�澶ц�楁椂 |
+| jsonKeyword | JsonRequestKeyword, JsonResponseKeyword | 鍚屾椂鎼滅储璇锋眰鍜屽搷搴� |
+
+---
+
+## 8. 娴嬭瘯瑕佺偣
+
+1. **鍒嗛〉鏌ヨ** - 楠岃瘉鍚勭绛涢�夋潯浠剁殑缁勫悎
+2. **缁熻鍑嗙‘鎬�** - 楠岃瘉缁熻鏁版嵁涓庡疄闄呮暟鎹竴鑷�
+3. **JSON灞曠ず** - 楠岃瘉鏍煎紡鍖栥�佹姌鍙犮�佸鍒跺姛鑳�
+4. **鑷姩鍒锋柊** - 楠岃瘉瀹氭椂鍒锋柊鍔熻兘姝e父宸ヤ綔
+5. **瀵煎嚭鍔熻兘** - 楠岃瘉 Excel 鏂囦欢鍐呭姝g‘
+6. **鏉冮檺鎺у埗** - 楠岃瘉鏃犳潈闄愮敤鎴锋棤娉曡闂�
+
+---
+
+## 9. 鍚庣画浼樺寲寤鸿
+
+1. **鏃ュ織褰掓。** - 鑰冭檻瀹氭湡褰掓。鏃ф棩蹇楋紝淇濇寔涓昏〃鎬ц兘
+2. **瀹炴椂鐩戞帶** - 闆嗘垚 SignalR 瀹炵幇瀹炴椂鏃ュ織鎺ㄩ��
+3. **寮傚父鍛婅** - 澶辫触鐜囪秴杩囬槇鍊兼椂鍙戦�佸憡璀�
+4. **鎬ц兘鍒嗘瀽** - 娣诲姞鑰楁椂瓒嬪娍鍥捐〃
+5. **鎺ュ彛瀵规瘮** - 鏀寔鍚岀被鎺ュ彛璋冪敤鐨勫姣斿垎鏋�

--
Gitblit v1.9.3