From f288ccc545f8cc32bc922c96dfb3cab9a1f92ec6 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期一, 20 四月 2026 00:49:55 +0800
Subject: [PATCH] feat: 初始化WMS前端项目并实现基础功能
---
Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/inbound.ts | 6
Code/WMS/WMS_Api_Design.md | 203 +
Code/WMS/WIDESEA_WMSClient_Vben/src/views/outbound/outboundOrderDetail.vue | 106
Code/WMS/WIDESEA_WMSClient_Vben/src/api/auth.ts | 50
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Controllers/Task/RobotStateController.cs | 20
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/ISocketClientGateway.cs | 1
Code/WMS/WIDESEA_WMSClient_Vben/src/views/outbound/index.vue | 267 ++
Code/WMS/WIDESEA_WMSClient_Vben/src/layouts/MainLayout.vue | 158 +
Code/WCS/WIDESEAWCS_Client/src/views/taskinfo/robotState.vue | 184 +
Code/WMS/WIDESEA_WMSClient_Vben/src/views/inbound/inboundOrderDetail.vue | 105
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotClientManager.cs | 1
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json | 2
Code/WMS/WIDESEA_WMSClient_Vben_v2 | 1
Code/WMS/WIDESEA_WMSClient_Vben/src/views/stock/index.vue | 340 ++
Code/WMS/WIDESEA_WMSClient_Vben/.env.development | 1
Code/WMS/WIDESEA_WMSClient_Vben/src/utils/menuTransform.ts | 143 +
Code/.omc/state/mission-state.json | 532 ++++
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/WIDESEAWCS_Tasks.csproj | 1
Code/WMS/WIDESEA_WMSClient_Vben/src/main.ts | 15
Code/WMS/WIDESEA_WMSClient_Vben/src/store/index.ts | 5
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/IRobotPrefixCommandHandler.cs | 1
Code/.omc/state/last-tool-error.json | 8
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/QuartzNetExtension.cs | 1
Code/WMS/WIDESEA_WMSClient_Vben/pnpm-lock.yaml | 1297 ++++++++++
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/SocketClientGateway.cs | 1
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/RobotState/Dt_RobotState.cs | 59
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/IRobotSimpleCommandHandler.cs | 2
Code/WMS/WIDESEA_WMSClient_Vben/package-lock.json | 1929 ++++++++++++++++
Code/WMS/WIDESEA_WMSClient_Vben/src/store/user.ts | 43
Code/WMS/WIDESEA_WMSClient_Vben/src/views/login/index.vue | 196 +
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/IRobotMessageRouter.cs | 1
Code/WMS/WIDESEA_WMSClient_Vben/src/api/index.ts | 6
Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/outbound.ts | 6
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoService/IRobotStateService.cs | 13
Code/WMS/WIDESEA_WMSClient_Vben/vite.config.ts | 21
Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/menu.ts | 28
Code/WMS/WIDESEA_WMSClient_Vben/tsconfig.node.json | 11
Code/WCS/WIDESEAWCS_Client/src/router/viewGird.js | 5
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.cs | 1
Code/.omc/state/subagent-tracking.json | 351 ++
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoRepository/WIDESEAWCS_ITaskInfoRepository.csproj | 1
Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/stock.ts | 6
Code/WCS/WIDESEAWCS_Client/src/extension/taskinfo/robotState.jsx | 55
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/RobotState/RobotCraneDevice.cs | 28
Code/WMS/WIDESEA_WMSClient_Vben/index.html | 13
Code/WMS/WIDESEA_WMSClient_Vben/src/store/modules/menu.ts | 57
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotMessageHandler.cs | 69
Code/WMS/WIDESEA_WMSClient_Vben/src/App.vue | 27
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotJob.cs | 5
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/WIDESEAWCS_QuartzJob.csproj | 1
Code/WMS/WIDESEA_WMSClient_Vben/src/api/client.ts | 56
/dev/null | 16
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoRepository/RobotStateRepository.cs | 39
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoRepository/IRobotStateRepository.cs | 10
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotStateManager.cs | 34
Code/WMS/WIDESEA_WMSClient_Vben/src/router/index.ts | 81
Code/WMS/WIDESEA_WMSClient_Vben/src/views/inbound/index.vue | 275 ++
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/RobotStateService.cs | 18
Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/user.ts | 8
Code/WMS/WIDESEA_WMSClient_Vben/tsconfig.json | 21
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotSimpleCommandHandler.cs | 1
Code/WMS/WIDESEA_WMSClient_Vben/package.json | 25
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/RobotState/RobotSocketState.cs | 11
Code/WMS/WIDESEA_WMSClient_Vben/src/views/dashboard/index.vue | 47
Code/WMS/WIDESEA_WMSClient_Vben/src/locales/zh-CN.ts | 21
Code/WMS/WIDESEA_WMSClient_Vben/src/views/stock/stockInfoDetail.vue | 119
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs | 1
67 files changed, 6,997 insertions(+), 169 deletions(-)
diff --git a/Code/.omc/state/last-tool-error.json b/Code/.omc/state/last-tool-error.json
index c9a8df7..85397e0 100644
--- a/Code/.omc/state/last-tool-error.json
+++ b/Code/.omc/state/last-tool-error.json
@@ -1,7 +1,7 @@
{
"tool_name": "Bash",
- "tool_input_preview": "{\"command\":\"cd D:\\\\Git\\\\ShanMeiXinNengYuan\\\\Code\\\\WCS\\\\WIDESEAWCS_Client && npm run build 2>&1 | head -30\",\"timeout\":120000}",
- "error": "Exit code 1\n/usr/bin/bash: line 1: cd: D:GitShanMeiXinNengYuanCodeWCSWIDESEAWCS_Client: No such file or directory",
- "timestamp": "2026-04-19T07:15:17.022Z",
- "retry_count": 1
+ "tool_input_preview": "{\"command\":\"cd \\\"D:/Git/ShanMeiXinNengYuan/Code/WMS\\\" && git clone --depth 1 https://ghproxy.com/https://github.com/vbenjs/vue-vben-admin.git WIDESEA_WMSClient_Vben 2>&1\",\"timeout\":300000,\"description...",
+ "error": "Exit code 128\nCloning into 'WIDESEA_WMSClient_Vben'...\nfatal: unable to access 'https://ghproxy.com/https://github.com/vbenjs/vue-vben-admin.git/': Failed to connect to ghproxy.com port 443 after 21158 ms: Could not connect to server",
+ "timestamp": "2026-04-19T13:54:19.051Z",
+ "retry_count": 4
}
\ No newline at end of file
diff --git a/Code/.omc/state/mission-state.json b/Code/.omc/state/mission-state.json
index 67025a1..c4c05bb 100644
--- a/Code/.omc/state/mission-state.json
+++ b/Code/.omc/state/mission-state.json
@@ -1,5 +1,5 @@
{
- "updatedAt": "2026-04-18T08:52:24.581Z",
+ "updatedAt": "2026-04-19T13:53:57.853Z",
"missions": [
{
"id": "session:9007b9ea-1eb6-4d24-8fe7-2c3a949eac88:none",
@@ -1268,6 +1268,536 @@
"sourceKey": "session-stop:a6a0c97facebc27a6"
}
]
+ },
+ {
+ "id": "session:4a7d9ed6-773a-4962-9881-9dcda1653389:none",
+ "source": "session",
+ "name": "none",
+ "objective": "Session mission",
+ "createdAt": "2026-04-19T11:24:03.847Z",
+ "updatedAt": "2026-04-19T12:58:38.564Z",
+ "status": "done",
+ "workerCount": 5,
+ "taskCounts": {
+ "total": 5,
+ "pending": 0,
+ "blocked": 0,
+ "inProgress": 0,
+ "completed": 5,
+ "failed": 0
+ },
+ "agents": [
+ {
+ "name": "general-purpose:af12f69",
+ "role": "general-purpose",
+ "ownership": "af12f692dd4a3fb28",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T12:58:38.564Z"
+ },
+ {
+ "name": "general-purpose:aa2a37e",
+ "role": "general-purpose",
+ "ownership": "aa2a37e07afb9d479",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T11:24:36.379Z"
+ },
+ {
+ "name": "general-purpose:a6eb9a9",
+ "role": "general-purpose",
+ "ownership": "a6eb9a903c850f24a",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T11:24:47.161Z"
+ },
+ {
+ "name": "general-purpose:a9803cf",
+ "role": "general-purpose",
+ "ownership": "a9803cf811cccaa24",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T11:25:43.000Z"
+ },
+ {
+ "name": "general-purpose:a9e37be",
+ "role": "general-purpose",
+ "ownership": "a9e37bec52fcbdaa5",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T11:26:55.341Z"
+ }
+ ],
+ "timeline": [
+ {
+ "id": "session-start:a9803cf811cccaa24:2026-04-19T11:25:09.331Z",
+ "at": "2026-04-19T11:25:09.331Z",
+ "kind": "update",
+ "agent": "general-purpose:a9803cf",
+ "detail": "started general-purpose:a9803cf",
+ "sourceKey": "session-start:a9803cf811cccaa24"
+ },
+ {
+ "id": "session-stop:a9803cf811cccaa24:2026-04-19T11:25:43.000Z",
+ "at": "2026-04-19T11:25:43.000Z",
+ "kind": "completion",
+ "agent": "general-purpose:a9803cf",
+ "detail": "completed",
+ "sourceKey": "session-stop:a9803cf811cccaa24"
+ },
+ {
+ "id": "session-start:a9e37bec52fcbdaa5:2026-04-19T11:25:51.811Z",
+ "at": "2026-04-19T11:25:51.811Z",
+ "kind": "update",
+ "agent": "general-purpose:a9e37be",
+ "detail": "started general-purpose:a9e37be",
+ "sourceKey": "session-start:a9e37bec52fcbdaa5"
+ },
+ {
+ "id": "session-stop:a9e37bec52fcbdaa5:2026-04-19T11:26:55.341Z",
+ "at": "2026-04-19T11:26:55.341Z",
+ "kind": "completion",
+ "agent": "general-purpose:a9e37be",
+ "detail": "completed",
+ "sourceKey": "session-stop:a9e37bec52fcbdaa5"
+ },
+ {
+ "id": "session-stop:a4f2a4a86620e67ac:2026-04-19T12:58:38.564Z",
+ "at": "2026-04-19T12:58:38.564Z",
+ "kind": "completion",
+ "agent": "general-purpose:af12f69",
+ "detail": "completed",
+ "sourceKey": "session-stop:a4f2a4a86620e67ac"
+ }
+ ]
+ },
+ {
+ "id": "session:d619041b-8d2b-4d40-ac1a-9c570d800e7d:none",
+ "source": "session",
+ "name": "none",
+ "objective": "Session mission",
+ "createdAt": "2026-04-19T13:39:55.243Z",
+ "updatedAt": "2026-04-19T13:53:57.853Z",
+ "status": "running",
+ "workerCount": 34,
+ "taskCounts": {
+ "total": 34,
+ "pending": 0,
+ "blocked": 0,
+ "inProgress": 3,
+ "completed": 31,
+ "failed": 0
+ },
+ "agents": [
+ {
+ "name": "agent-menu:a9260b4",
+ "role": "agent-menu",
+ "ownership": "a9260b44a0c26528b",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:41:04.664Z"
+ },
+ {
+ "name": "agent-auth:a6f1e5c",
+ "role": "agent-auth",
+ "ownership": "a6f1e5c50a57e0d5d",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:40:20.808Z"
+ },
+ {
+ "name": "agent-pages:a5a2a89",
+ "role": "agent-pages",
+ "ownership": "a5a2a89d2fb5f17ff",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:41:01.814Z"
+ },
+ {
+ "name": "agent-scaffold:a1a6151",
+ "role": "agent-scaffold",
+ "ownership": "a1a6151ba7f364cfb",
+ "status": "running",
+ "currentStep": null,
+ "latestUpdate": null,
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:39:55.484Z"
+ },
+ {
+ "name": "agent-api:a4ce4ef",
+ "role": "agent-api",
+ "ownership": "a4ce4ef36b3693f58",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:40:12.096Z"
+ },
+ {
+ "name": "agent-layout:af02a89",
+ "role": "agent-layout",
+ "ownership": "af02a89022a18c649",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:40:15.829Z"
+ },
+ {
+ "name": "agent-api:ad03467",
+ "role": "agent-api",
+ "ownership": "ad03467a75e8afc0a",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:44:15.841Z"
+ },
+ {
+ "name": "agent-auth:a3cc9be",
+ "role": "agent-auth",
+ "ownership": "a3cc9be047c9352e5",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:44:29.101Z"
+ },
+ {
+ "name": "agent-menu:a77fb32",
+ "role": "agent-menu",
+ "ownership": "a77fb323ad44a6284",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:43:03.806Z"
+ },
+ {
+ "name": "agent-layout:a81ba9f",
+ "role": "agent-layout",
+ "ownership": "a81ba9fdad4456dfd",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:42:27.425Z"
+ },
+ {
+ "name": "agent-pages:a94adb2",
+ "role": "agent-pages",
+ "ownership": "a94adb2a88c1eb29c",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:42:26.922Z"
+ },
+ {
+ "name": "agent-pages:a211822",
+ "role": "agent-pages",
+ "ownership": "a2118226e3813727c",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:42:56.060Z"
+ },
+ {
+ "name": "agent-layout:ab75021",
+ "role": "agent-layout",
+ "ownership": "ab750215093131b28",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:42:55.376Z"
+ },
+ {
+ "name": "agent-menu:ae9ed78",
+ "role": "agent-menu",
+ "ownership": "ae9ed78222ecc6cad",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:52:27.389Z"
+ },
+ {
+ "name": "agent-api:ae5c327",
+ "role": "agent-api",
+ "ownership": "ae5c327157aec2fb1",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:46:52.233Z"
+ },
+ {
+ "name": "agent-auth:adc223f",
+ "role": "agent-auth",
+ "ownership": "adc223f651f1328bd",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:44:53.789Z"
+ },
+ {
+ "name": "agent-pages:a756617",
+ "role": "agent-pages",
+ "ownership": "a756617ca874ac3c1",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:51:43.427Z"
+ },
+ {
+ "name": "agent-layout:a4c96b8",
+ "role": "agent-layout",
+ "ownership": "a4c96b89f113f809d",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:47:11.646Z"
+ },
+ {
+ "name": "agent-auth:a8a57aa",
+ "role": "agent-auth",
+ "ownership": "a8a57aa22517c31f5",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:49:10.620Z"
+ },
+ {
+ "name": "agent-api:ab1d288",
+ "role": "agent-api",
+ "ownership": "ab1d2884ac7a493bd",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:47:18.573Z"
+ },
+ {
+ "name": "agent-layout:a0cbc46",
+ "role": "agent-layout",
+ "ownership": "a0cbc46d413ef4196",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:47:31.885Z"
+ },
+ {
+ "name": "agent-api:a8d6281",
+ "role": "agent-api",
+ "ownership": "a8d6281531b04991f",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:47:38.716Z"
+ },
+ {
+ "name": "writer:a8c91fb",
+ "role": "writer",
+ "ownership": "a8c91fb2cf222b293",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:50:25.144Z"
+ },
+ {
+ "name": "agent-auth:ade32f8",
+ "role": "agent-auth",
+ "ownership": "ade32f8bf35b26757",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:52:13.860Z"
+ },
+ {
+ "name": "agent-pages:ac557d7",
+ "role": "agent-pages",
+ "ownership": "ac557d7e2a1b5f729",
+ "status": "running",
+ "currentStep": null,
+ "latestUpdate": null,
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:51:43.789Z"
+ },
+ {
+ "name": "agent-layout:a9c6179",
+ "role": "agent-layout",
+ "ownership": "a9c6179a801e0e434",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:52:12.657Z"
+ },
+ {
+ "name": "writer:a7627b0",
+ "role": "writer",
+ "ownership": "a7627b0b0e0b60be2",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:52:01.512Z"
+ },
+ {
+ "name": "agent-api:aba045f",
+ "role": "agent-api",
+ "ownership": "aba045f68cd9f61d0",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:52:03.192Z"
+ },
+ {
+ "name": "agent-auth:aeed34c",
+ "role": "agent-auth",
+ "ownership": "aeed34c94d463a92c",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:52:27.391Z"
+ },
+ {
+ "name": "agent-menu:a9271b2",
+ "role": "agent-menu",
+ "ownership": "a9271b2a5525f053a",
+ "status": "running",
+ "currentStep": null,
+ "latestUpdate": null,
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:53:39.468Z"
+ },
+ {
+ "name": "agent-api:ae5d5fc",
+ "role": "agent-api",
+ "ownership": "ae5d5fcffcb393b67",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:53:47.265Z"
+ },
+ {
+ "name": "agent-auth:ad92b78",
+ "role": "agent-auth",
+ "ownership": "ad92b7876bc72bf7e",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:53:57.853Z"
+ },
+ {
+ "name": "agent-layout:affcaab",
+ "role": "agent-layout",
+ "ownership": "affcaabcac0234d22",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:53:49.029Z"
+ },
+ {
+ "name": "writer:ac6c4a2",
+ "role": "writer",
+ "ownership": "ac6c4a28a6422e89d",
+ "status": "done",
+ "currentStep": null,
+ "latestUpdate": "completed",
+ "completedSummary": null,
+ "updatedAt": "2026-04-19T13:53:49.217Z"
+ }
+ ],
+ "timeline": [
+ {
+ "id": "session-start:ad92b7876bc72bf7e:2026-04-19T13:53:42.036Z",
+ "at": "2026-04-19T13:53:42.036Z",
+ "kind": "update",
+ "agent": "agent-auth:ad92b78",
+ "detail": "started agent-auth:ad92b78",
+ "sourceKey": "session-start:ad92b7876bc72bf7e"
+ },
+ {
+ "id": "session-start:affcaabcac0234d22:2026-04-19T13:53:42.701Z",
+ "at": "2026-04-19T13:53:42.701Z",
+ "kind": "update",
+ "agent": "agent-layout:affcaab",
+ "detail": "started agent-layout:affcaab",
+ "sourceKey": "session-start:affcaabcac0234d22"
+ },
+ {
+ "id": "session-start:ac6c4a28a6422e89d:2026-04-19T13:53:43.519Z",
+ "at": "2026-04-19T13:53:43.519Z",
+ "kind": "update",
+ "agent": "writer:ac6c4a2",
+ "detail": "started writer:ac6c4a2",
+ "sourceKey": "session-start:ac6c4a28a6422e89d"
+ },
+ {
+ "id": "session-stop:ae5d5fcffcb393b67:2026-04-19T13:53:47.265Z",
+ "at": "2026-04-19T13:53:47.265Z",
+ "kind": "completion",
+ "agent": "agent-api:ae5d5fc",
+ "detail": "completed",
+ "sourceKey": "session-stop:ae5d5fcffcb393b67"
+ },
+ {
+ "id": "session-stop:affcaabcac0234d22:2026-04-19T13:53:49.029Z",
+ "at": "2026-04-19T13:53:49.029Z",
+ "kind": "completion",
+ "agent": "agent-layout:affcaab",
+ "detail": "completed",
+ "sourceKey": "session-stop:affcaabcac0234d22"
+ },
+ {
+ "id": "session-stop:ac6c4a28a6422e89d:2026-04-19T13:53:49.217Z",
+ "at": "2026-04-19T13:53:49.217Z",
+ "kind": "completion",
+ "agent": "writer:ac6c4a2",
+ "detail": "completed",
+ "sourceKey": "session-stop:ac6c4a28a6422e89d"
+ },
+ {
+ "id": "session-stop:ad92b7876bc72bf7e:2026-04-19T13:53:57.853Z",
+ "at": "2026-04-19T13:53:57.853Z",
+ "kind": "completion",
+ "agent": "agent-auth:ad92b78",
+ "detail": "completed",
+ "sourceKey": "session-stop:ad92b7876bc72bf7e"
+ }
+ ]
}
]
}
\ No newline at end of file
diff --git a/Code/.omc/state/subagent-tracking.json b/Code/.omc/state/subagent-tracking.json
index 27a37ae..1b42f04 100644
--- a/Code/.omc/state/subagent-tracking.json
+++ b/Code/.omc/state/subagent-tracking.json
@@ -767,10 +767,355 @@
"status": "completed",
"completed_at": "2026-04-18T08:52:24.581Z",
"duration_ms": 1093052
+ },
+ {
+ "agent_id": "af12f692dd4a3fb28",
+ "agent_type": "general-purpose",
+ "started_at": "2026-04-19T11:24:03.847Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T11:24:57.433Z",
+ "duration_ms": 53586
+ },
+ {
+ "agent_id": "aa2a37e07afb9d479",
+ "agent_type": "general-purpose",
+ "started_at": "2026-04-19T11:24:03.863Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T11:24:36.379Z",
+ "duration_ms": 32516
+ },
+ {
+ "agent_id": "a6eb9a903c850f24a",
+ "agent_type": "general-purpose",
+ "started_at": "2026-04-19T11:24:03.887Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T11:24:47.161Z",
+ "duration_ms": 43274
+ },
+ {
+ "agent_id": "a9803cf811cccaa24",
+ "agent_type": "general-purpose",
+ "started_at": "2026-04-19T11:25:09.331Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T11:25:43.000Z",
+ "duration_ms": 33669
+ },
+ {
+ "agent_id": "a9e37bec52fcbdaa5",
+ "agent_type": "general-purpose",
+ "started_at": "2026-04-19T11:25:51.811Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T11:26:55.341Z",
+ "duration_ms": 63530
+ },
+ {
+ "agent_id": "a9260b44a0c26528b",
+ "agent_type": "agent-menu",
+ "started_at": "2026-04-19T13:39:55.243Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:41:04.664Z",
+ "duration_ms": 69421
+ },
+ {
+ "agent_id": "a6f1e5c50a57e0d5d",
+ "agent_type": "agent-auth",
+ "started_at": "2026-04-19T13:39:55.328Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:40:20.808Z",
+ "duration_ms": 25480
+ },
+ {
+ "agent_id": "a5a2a89d2fb5f17ff",
+ "agent_type": "agent-pages",
+ "started_at": "2026-04-19T13:39:55.416Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:41:01.814Z",
+ "duration_ms": 66398
+ },
+ {
+ "agent_id": "a1a6151ba7f364cfb",
+ "agent_type": "agent-scaffold",
+ "started_at": "2026-04-19T13:39:55.484Z",
+ "parent_mode": "none",
+ "status": "running"
+ },
+ {
+ "agent_id": "a4ce4ef36b3693f58",
+ "agent_type": "agent-api",
+ "started_at": "2026-04-19T13:39:55.588Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:40:12.096Z",
+ "duration_ms": 16508
+ },
+ {
+ "agent_id": "af02a89022a18c649",
+ "agent_type": "agent-layout",
+ "started_at": "2026-04-19T13:39:55.655Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:40:15.829Z",
+ "duration_ms": 20174
+ },
+ {
+ "agent_id": "ad03467a75e8afc0a",
+ "agent_type": "agent-api",
+ "started_at": "2026-04-19T13:41:42.785Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:44:15.841Z",
+ "duration_ms": 153056
+ },
+ {
+ "agent_id": "a3cc9be047c9352e5",
+ "agent_type": "agent-auth",
+ "started_at": "2026-04-19T13:41:43.216Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:44:29.101Z",
+ "duration_ms": 165885
+ },
+ {
+ "agent_id": "a77fb323ad44a6284",
+ "agent_type": "agent-menu",
+ "started_at": "2026-04-19T13:41:43.564Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:43:03.806Z",
+ "duration_ms": 80242
+ },
+ {
+ "agent_id": "a81ba9fdad4456dfd",
+ "agent_type": "agent-layout",
+ "started_at": "2026-04-19T13:41:43.726Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:42:27.425Z",
+ "duration_ms": 43699
+ },
+ {
+ "agent_id": "a94adb2a88c1eb29c",
+ "agent_type": "agent-pages",
+ "started_at": "2026-04-19T13:41:44.247Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:42:26.922Z",
+ "duration_ms": 42675
+ },
+ {
+ "agent_id": "a2118226e3813727c",
+ "agent_type": "agent-pages",
+ "started_at": "2026-04-19T13:42:27.222Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:42:56.060Z",
+ "duration_ms": 28838
+ },
+ {
+ "agent_id": "ab750215093131b28",
+ "agent_type": "agent-layout",
+ "started_at": "2026-04-19T13:42:27.736Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:42:55.376Z",
+ "duration_ms": 27640
+ },
+ {
+ "agent_id": "ae9ed78222ecc6cad",
+ "agent_type": "agent-menu",
+ "started_at": "2026-04-19T13:43:04.113Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:53:39.187Z",
+ "duration_ms": 635074
+ },
+ {
+ "agent_id": "ae5c327157aec2fb1",
+ "agent_type": "agent-api",
+ "started_at": "2026-04-19T13:44:16.103Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:46:52.232Z",
+ "duration_ms": 156129
+ },
+ {
+ "agent_id": "adc223f651f1328bd",
+ "agent_type": "agent-auth",
+ "started_at": "2026-04-19T13:44:29.361Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:44:53.787Z",
+ "duration_ms": 24426
+ },
+ {
+ "agent_id": "a756617ca874ac3c1",
+ "agent_type": "agent-pages",
+ "started_at": "2026-04-19T13:44:31.425Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:51:43.425Z",
+ "duration_ms": 432000
+ },
+ {
+ "agent_id": "a4c96b89f113f809d",
+ "agent_type": "agent-layout",
+ "started_at": "2026-04-19T13:44:31.949Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:47:11.645Z",
+ "duration_ms": 159696
+ },
+ {
+ "agent_id": "a8a57aa22517c31f5",
+ "agent_type": "agent-auth",
+ "started_at": "2026-04-19T13:44:54.061Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:49:10.619Z",
+ "duration_ms": 256558
+ },
+ {
+ "agent_id": "ab1d2884ac7a493bd",
+ "agent_type": "agent-api",
+ "started_at": "2026-04-19T13:46:52.504Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:47:18.572Z",
+ "duration_ms": 26068
+ },
+ {
+ "agent_id": "a0cbc46d413ef4196",
+ "agent_type": "agent-layout",
+ "started_at": "2026-04-19T13:47:11.911Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:47:31.883Z",
+ "duration_ms": 19972
+ },
+ {
+ "agent_id": "a8d6281531b04991f",
+ "agent_type": "agent-api",
+ "started_at": "2026-04-19T13:47:18.855Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:47:38.715Z",
+ "duration_ms": 19860
+ },
+ {
+ "agent_id": "a8c91fb2cf222b293",
+ "agent_type": "writer",
+ "started_at": "2026-04-19T13:48:10.651Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:50:25.143Z",
+ "duration_ms": 134492
+ },
+ {
+ "agent_id": "ade32f8bf35b26757",
+ "agent_type": "agent-auth",
+ "started_at": "2026-04-19T13:49:10.886Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:52:13.858Z",
+ "duration_ms": 182972
+ },
+ {
+ "agent_id": "ac557d7e2a1b5f729",
+ "agent_type": "agent-pages",
+ "started_at": "2026-04-19T13:51:43.789Z",
+ "parent_mode": "none",
+ "status": "running"
+ },
+ {
+ "agent_id": "a9c6179a801e0e434",
+ "agent_type": "agent-layout",
+ "started_at": "2026-04-19T13:51:48.859Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:52:12.656Z",
+ "duration_ms": 23797
+ },
+ {
+ "agent_id": "a7627b0b0e0b60be2",
+ "agent_type": "writer",
+ "started_at": "2026-04-19T13:51:48.925Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:52:01.510Z",
+ "duration_ms": 12585
+ },
+ {
+ "agent_id": "aba045f68cd9f61d0",
+ "agent_type": "agent-api",
+ "started_at": "2026-04-19T13:51:48.986Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:52:03.190Z",
+ "duration_ms": 14204
+ },
+ {
+ "agent_id": "aeed34c94d463a92c",
+ "agent_type": "agent-auth",
+ "started_at": "2026-04-19T13:52:14.179Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:52:27.389Z",
+ "duration_ms": 13210
+ },
+ {
+ "agent_id": "a9271b2a5525f053a",
+ "agent_type": "agent-menu",
+ "started_at": "2026-04-19T13:53:39.468Z",
+ "parent_mode": "none",
+ "status": "running"
+ },
+ {
+ "agent_id": "ae5d5fcffcb393b67",
+ "agent_type": "agent-api",
+ "started_at": "2026-04-19T13:53:41.992Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:53:47.263Z",
+ "duration_ms": 5271
+ },
+ {
+ "agent_id": "ad92b7876bc72bf7e",
+ "agent_type": "agent-auth",
+ "started_at": "2026-04-19T13:53:42.036Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:53:57.851Z",
+ "duration_ms": 15815
+ },
+ {
+ "agent_id": "affcaabcac0234d22",
+ "agent_type": "agent-layout",
+ "started_at": "2026-04-19T13:53:42.701Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:53:49.028Z",
+ "duration_ms": 6327
+ },
+ {
+ "agent_id": "ac6c4a28a6422e89d",
+ "agent_type": "writer",
+ "started_at": "2026-04-19T13:53:43.519Z",
+ "parent_mode": "none",
+ "status": "completed",
+ "completed_at": "2026-04-19T13:53:49.216Z",
+ "duration_ms": 5697
}
],
- "total_spawned": 83,
- "total_completed": 83,
+ "total_spawned": 115,
+ "total_completed": 119,
"total_failed": 0,
- "last_updated": "2026-04-18T14:41:25.052Z"
+ "last_updated": "2026-04-19T13:53:57.967Z"
}
\ No newline at end of file
diff --git a/Code/WCS/WIDESEAWCS_Client/src/extension/taskinfo/robotState.jsx b/Code/WCS/WIDESEAWCS_Client/src/extension/taskinfo/robotState.jsx
new file mode 100644
index 0000000..0dfb0c9
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Client/src/extension/taskinfo/robotState.jsx
@@ -0,0 +1,55 @@
+// 璇ユ墿灞曟枃浠剁敤浜庢満姊版墜鐘舵�佺鐞嗛〉闈㈢殑涓氬姟鎵╁睍銆�
+
+let extension = {
+ components: {
+ gridHeader: "",
+ gridBody: "",
+ gridFooter: "",
+ modelHeader: "",
+ modelBody: "",
+ modelFooter: "",
+ },
+ tableAction: "",
+ buttons: { view: [], box: [], detail: [] },
+ methods: {
+ onInit() {},
+
+ onInited() {},
+
+ searchBefore(param) {
+ return true;
+ },
+
+ searchAfter(result) {
+ return true;
+ },
+
+ addBefore(formData) {
+ return true;
+ },
+
+ addAfter(result) {
+ return true;
+ },
+
+ updateBefore(formData) {
+ return true;
+ },
+
+ updateAfter(result) {
+ return true;
+ },
+
+ deleteBefore(ids) {
+ return true;
+ },
+
+ deleteAfter(ids) {
+ return true;
+ },
+
+ modelOpenAfter(row) {},
+ },
+};
+
+export default extension;
diff --git a/Code/WCS/WIDESEAWCS_Client/src/router/viewGird.js b/Code/WCS/WIDESEAWCS_Client/src/router/viewGird.js
index 584bb6c..9915346 100644
--- a/Code/WCS/WIDESEAWCS_Client/src/router/viewGird.js
+++ b/Code/WCS/WIDESEAWCS_Client/src/router/viewGird.js
@@ -69,6 +69,11 @@
component: () => import('@/views/taskinfo/robotTask.vue')
},
{
+ path: '/robotState',
+ name: 'robotState',
+ component: () => import('@/views/taskinfo/robotState.vue')
+ },
+ {
path: '/task',
name: 'task',
component: () => import('@/views/taskinfo/task.vue')
diff --git a/Code/WCS/WIDESEAWCS_Client/src/views/taskinfo/robotState.vue b/Code/WCS/WIDESEAWCS_Client/src/views/taskinfo/robotState.vue
new file mode 100644
index 0000000..462827e
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Client/src/views/taskinfo/robotState.vue
@@ -0,0 +1,184 @@
+<template>
+ <view-grid
+ ref="grid"
+ :columns="columns"
+ :detail="detail"
+ :editFormFields="editFormFields"
+ :editFormOptions="editFormOptions"
+ :searchFormFields="searchFormFields"
+ :searchFormOptions="searchFormOptions"
+ :table="table"
+ :extend="extend"
+ >
+ </view-grid>
+</template>
+
+<script>
+import extend from "@/extension/taskinfo/robotState.jsx";
+import { ref, defineComponent } from "vue";
+
+export default defineComponent({
+ setup() {
+ const table = ref({
+ key: "Id",
+ footer: "Foots",
+ cnName: "鏈烘鎵嬬姸鎬佺鐞�",
+ name: "robotState",
+ url: "/robotState/",
+ sortName: "IPAddress",
+ });
+
+ // 缂栬緫琛ㄥ崟瀛楁
+ const editFormFields = ref({
+ IPAddress: "",
+ Version: "",
+ IsEventSubscribed: false,
+ RobotRunMode: "",
+ RobotControlMode: "",
+ RobotArmObject: "",
+ Homed: "",
+ CurrentAction: "",
+ OperStatus: "",
+ RobotTaskTotalNum: 0,
+ IsSplitPallet: false,
+ IsGroupPallet: false,
+ IsInFakeBatteryMode: false,
+ CurrentBatchIndex: 1,
+ ChangePalletPhase: 0,
+ IsScanNG: false,
+ BatteryArrived: false,
+ });
+
+ // 缂栬緫琛ㄥ崟閰嶇疆
+ const editFormOptions = ref([
+ [
+ { title: "IP鍦板潃", field: "IPAddress", type: "string", readonly: true },
+ { title: "鐗堟湰鍙�", field: "Version", type: "int", readonly: true },
+ ],
+ [
+ {
+ title: "杩愯妯″紡",
+ field: "RobotRunMode",
+ type: "select",
+ data: [
+ { key: 1, value: "鎵嬪姩妯″紡" },
+ { key: 2, value: "鑷姩妯″紡" },
+ ],
+ },
+ {
+ title: "鎺у埗妯″紡",
+ field: "RobotControlMode",
+ type: "select",
+ data: [
+ { key: 1, value: "瀹㈡埛绔帶鍒�" },
+ { key: 2, value: "鍏朵粬" },
+ ],
+ },
+ {
+ title: "鎵嬭噦鐘舵��",
+ field: "RobotArmObject",
+ type: "select",
+ data: [
+ { key: 0, value: "绌洪棽" },
+ { key: 1, value: "鏈夌墿鏂�" },
+ ],
+ },
+ ],
+ [
+ { title: "鍥為浂鐘舵��", field: "Homed", type: "string" },
+ { title: "褰撳墠鍔ㄤ綔", field: "CurrentAction", type: "string" },
+ { title: "杩愯鐘舵��", field: "OperStatus", type: "string" },
+ ],
+ [
+ { title: "浠诲姟鎬绘暟", field: "RobotTaskTotalNum", type: "int" },
+ { title: "褰撳墠鎵规", field: "CurrentBatchIndex", type: "int" },
+ { title: "鎹㈢洏闃舵", field: "ChangePalletPhase", type: "int" },
+ ],
+ [
+ {
+ title: "鏄惁鎷嗙洏",
+ field: "IsSplitPallet",
+ type: "checkbox",
+ },
+ {
+ title: "鏄惁缁勭洏",
+ field: "IsGroupPallet",
+ type: "checkbox",
+ },
+ {
+ title: "鍋囩數鑺ā寮�",
+ field: "IsInFakeBatteryMode",
+ type: "checkbox",
+ },
+ ],
+ [
+ {
+ title: "鏄惁鎵爜NG",
+ field: "IsScanNG",
+ type: "checkbox",
+ },
+ {
+ title: "鐢佃姱鏄惁鍒颁綅",
+ field: "BatteryArrived",
+ type: "checkbox",
+ },
+ {
+ title: "娑堟伅宸茶闃�",
+ field: "IsEventSubscribed",
+ type: "checkbox",
+ },
+ ],
+ ]);
+
+ // 鎼滅储琛ㄥ崟瀛楁
+ const searchFormFields = ref({
+ IPAddress: "",
+ CurrentAction: "",
+ OperStatus: "",
+ });
+
+ // 鎼滅储琛ㄥ崟閰嶇疆
+ const searchFormOptions = ref([
+ [
+ { title: "IP鍦板潃", field: "IPAddress", type: "string" },
+ { title: "褰撳墠鍔ㄤ綔", field: "CurrentAction", type: "string" },
+ { title: "杩愯鐘舵��", field: "OperStatus", type: "string" },
+ ],
+ ]);
+
+ // 鍒楀畾涔�
+ const columns = ref([
+ { field: "IPAddress", title: "IP鍦板潃", type: "string", width: 140, align: "left" },
+ { field: "Version", title: "鐗堟湰", type: "int", width: 80, align: "left" },
+ { field: "RobotRunMode", title: "杩愯妯″紡", type: "int", width: 100, bind: { key: "robotRunMode", data: [] }, align: "center" },
+ { field: "RobotControlMode", title: "鎺у埗妯″紡", type: "int", width: 100, bind: { key: "robotControlMode", data: [] }, align: "center" },
+ { field: "RobotArmObject", title: "鎵嬭噦鐘舵��", type: "int", width: 90, bind: { key: "robotArmObject", data: [] }, align: "center" },
+ { field: "Homed", title: "鍥為浂鐘舵��", type: "string", width: 100, align: "center" },
+ { field: "CurrentAction", title: "褰撳墠鍔ㄤ綔", type: "string", width: 100, align: "center" },
+ { field: "OperStatus", title: "杩愯鐘舵��", type: "string", width: 100, align: "center" },
+ { field: "RobotTaskTotalNum", title: "浠诲姟鎬绘暟", type: "int", width: 90, align: "center" },
+ { field: "IsSplitPallet", title: "鎷嗙洏", type: "byte", width: 60, align: "center" },
+ { field: "IsGroupPallet", title: "缁勭洏", type: "byte", width: 60, align: "center" },
+ { field: "IsInFakeBatteryMode", title: "鍋囩數鑺�", type: "byte", width: 70, align: "center" },
+ { field: "CurrentBatchIndex", title: "鎵规", type: "int", width: 60, align: "center" },
+ { field: "ChangePalletPhase", title: "鎹㈢洏闃舵", type: "int", width: 80, align: "center" },
+ { field: "IsScanNG", title: "鎵爜NG", type: "byte", width: 80, align: "center" },
+ { field: "BatteryArrived", title: "鐢佃姱鍒颁綅", type: "byte", width: 80, align: "center" },
+ { field: "IsEventSubscribed", title: "宸茶闃�", type: "byte", width: 70, align: "center" },
+ ]);
+
+ const detail = ref({});
+
+ return {
+ table,
+ columns,
+ detail,
+ editFormFields,
+ editFormOptions,
+ searchFormFields,
+ searchFormOptions,
+ extend,
+ };
+ },
+});
+</script>
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoRepository/IRobotStateRepository.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoRepository/IRobotStateRepository.cs
index 2ee6a06..60a7100 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoRepository/IRobotStateRepository.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoRepository/IRobotStateRepository.cs
@@ -1,3 +1,5 @@
+using WIDESEAWCS_Core;
+using WIDESEAWCS_Core.BaseRepository;
using WIDESEAWCS_Model.Models;
namespace WIDESEAWCS_ITaskInfoRepository
@@ -10,7 +12,7 @@
/// 澶嶆潅瀵硅薄锛圧obotCrane銆丆urrentTask銆佹暟缁勭瓑锛夊湪璋冪敤鏂逛娇鐢ㄥ己绫诲瀷锛�
/// 鍦ㄦ鎺ュ彛灞傞潰浠� Dt_RobotState 瀹炰綋涓烘搷浣滃崟浣嶃��
/// </remarks>
- public interface IRobotStateRepository
+ public interface IRobotStateRepository : IRepository<Dt_RobotState>
{
/// <summary>
/// 鏍规嵁 IP 鍦板潃鑾峰彇鏈烘鎵嬬姸鎬�
@@ -31,10 +33,10 @@
/// 瀹夊叏鏇存柊鏈烘鎵嬬姸鎬侊紙涔愯閿侊級
/// </summary>
/// <param name="ipAddress">璁惧 IP 鍦板潃</param>
- /// <param name="newState">鏂扮姸鎬佸疄浣擄紙RowVersion 浼氳鏇存柊锛�</param>
- /// <param name="expectedRowVersion">鏈熸湜鐨勮鐗堟湰鍙凤紙鏇存柊鍓嶇殑鐗堟湰锛�</param>
+ /// <param name="newState">鏂扮姸鎬佸疄浣擄紙Version 浼氳嚜澧烇級</param>
+ /// <param name="expectedVersion">鏈熸湜鐨勭増鏈彿锛堟洿鏂板墠鐨勭増鏈級</param>
/// <returns>鏄惁鏇存柊鎴愬姛锛沠alse 琛ㄧず鐗堟湰鍐茬獊鎴栬褰曚笉瀛樺湪</returns>
- bool TryUpdate(string ipAddress, Dt_RobotState newState, byte[] expectedRowVersion);
+ bool TryUpdate(string ipAddress, Dt_RobotState newState, long expectedVersion);
/// <summary>
/// 灏� Dt_RobotState 瀹炰綋杞崲涓� RobotSocketState 鍐呭瓨瀵硅薄
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoRepository/WIDESEAWCS_ITaskInfoRepository.csproj b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoRepository/WIDESEAWCS_ITaskInfoRepository.csproj
index b81dff8..34104db 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoRepository/WIDESEAWCS_ITaskInfoRepository.csproj
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoRepository/WIDESEAWCS_ITaskInfoRepository.csproj
@@ -8,6 +8,7 @@
<ItemGroup>
<ProjectReference Include="..\WIDESEAWCS_DTO\WIDESEAWCS_DTO.csproj" />
+ <ProjectReference Include="..\WIDESEAWCS_Model\WIDESEAWCS_Model.csproj" />
</ItemGroup>
</Project>
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoService/IRobotStateService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoService/IRobotStateService.cs
new file mode 100644
index 0000000..b8dd92c
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoService/IRobotStateService.cs
@@ -0,0 +1,13 @@
+using WIDESEAWCS_Core;
+using WIDESEAWCS_Core.BaseServices;
+using WIDESEAWCS_Model.Models;
+
+namespace WIDESEAWCS_ITaskInfoService
+{
+ /// <summary>
+ /// 鏈烘鎵嬬姸鎬佹湇鍔℃帴鍙�
+ /// </summary>
+ public interface IRobotStateService : IService<Dt_RobotState>
+ {
+ }
+}
\ No newline at end of file
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/RobotState/Dt_RobotState.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/RobotState/Dt_RobotState.cs
index efcaac0..8477545 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/RobotState/Dt_RobotState.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/RobotState/Dt_RobotState.cs
@@ -1,4 +1,3 @@
-using Newtonsoft.Json;
using SqlSugar;
using WIDESEAWCS_Core.DB.Models;
@@ -8,7 +7,7 @@
/// 鏈烘鎵嬬姸鎬佹暟鎹簱瀹炰綋
/// </summary>
/// <remarks>
- /// 瀵瑰簲鏁版嵁搴撹〃 Dt_RobotState锛屼娇鐢� RowVersion 瀹炵幇涔愯骞跺彂鎺у埗銆�
+ /// 瀵瑰簲鏁版嵁搴撹〃 Dt_RobotState锛屼娇鐢� Version 瀛楁瀹炵幇涔愯骞跺彂鎺у埗銆�
/// 澶嶆潅瀵硅薄锛圧obotCrane銆丆urrentTask銆佹暟缁勭瓑锛変互 JSON 瀛楃涓插瓨鍌ㄣ��
/// </remarks>
[SugarTable(nameof(Dt_RobotState), "鏈烘鎵嬬姸鎬佽〃")]
@@ -23,141 +22,141 @@
/// <summary>
/// 鏈烘鎵� IP 鍦板潃锛屽敮涓�绱㈠紩
/// </summary>
- [SugarColumn(Length = 50, ColumnDescription = "鏈烘鎵婭P鍦板潃", IsJsonKey = true)]
+ [SugarColumn(Length = 50, ColumnDescription = "鏈烘鎵婭P鍦板潃")]
public string IPAddress { get; set; } = string.Empty;
/// <summary>
- /// 琛岀増鏈紝鐢ㄤ簬涔愯骞跺彂鎺у埗
+ /// 鐗堟湰鍙凤紝鐢ㄤ簬涔愯骞跺彂鎺у埗
/// </summary>
/// <remarks>
- /// SqlSugar 浼氳嚜鍔ㄧ鐞嗘瀛楁锛屾瘡娆℃洿鏂版椂鏁版嵁搴撹嚜鍔ㄩ�掑銆�
- /// 鏇存柊鏃� WHERE RowVersion = @expectedRowVersion锛屾鏌ュ奖鍝嶈鏁板垽鏂槸鍚﹀啿绐併��
+ /// 姣忔鏇存柊鏃惰嚜澧炪�傛洿鏂版椂 WHERE IPAddress = @ip AND Version = @expectedVersion銆�
+ /// 濡傛灉褰卞搷琛屾暟涓� 0锛岃鏄庣増鏈笉鍖归厤锛岃繑鍥� false銆�
/// </remarks>
- [SugarColumn(ColumnDescription = "琛岀増鏈紙涔愯閿侊級", IsJsonKey = true)]
- public byte[] RowVersion { get; set; } = Array.Empty<byte>();
+ [SugarColumn(ColumnDescription = "鐗堟湰鍙凤紙涔愯閿侊級")]
+ public long Version { get; set; }
/// <summary>
/// 鏄惁宸茶闃呮秷鎭簨浠�
/// </summary>
- [SugarColumn(ColumnDescription = "鏄惁宸茶闃呮秷鎭簨浠�", IsJsonKey = true)]
+ [SugarColumn(ColumnDescription = "鏄惁宸茶闃呮秷鎭簨浠�")]
public bool IsEventSubscribed { get; set; }
/// <summary>
/// 鏈烘鎵嬭繍琛屾ā寮�
/// </summary>
/// <remarks>1: 鎵嬪姩妯″紡, 2: 鑷姩妯″紡</remarks>
- [SugarColumn(ColumnDescription = "杩愯妯″紡", IsNullable = true, IsJsonKey = true)]
+ [SugarColumn(ColumnDescription = "杩愯妯″紡", IsNullable = true)]
public int? RobotRunMode { get; set; }
/// <summary>
/// 鏈烘鎵嬫帶鍒舵ā寮�
/// </summary>
/// <remarks>1: 瀹㈡埛绔帶鍒�, 2: 鍏朵粬</remarks>
- [SugarColumn(ColumnDescription = "鎺у埗妯″紡", IsNullable = true, IsJsonKey = true)]
+ [SugarColumn(ColumnDescription = "鎺у埗妯″紡", IsNullable = true)]
public int? RobotControlMode { get; set; }
/// <summary>
/// 鏈烘鎵嬫墜鑷傛姄鍙栧璞$姸鎬�
/// </summary>
/// <remarks>0: 鏃犵墿鏂欙紙鎵嬭噦绌洪棽锛�, 1: 鏈夌墿鏂欙紙宸叉姄鍙栬揣鐗╋級</remarks>
- [SugarColumn(ColumnDescription = "鎵嬭噦鎶撳彇鐘舵��", IsNullable = true, IsJsonKey = true)]
+ [SugarColumn(ColumnDescription = "鎵嬭噦鎶撳彇鐘舵��", IsNullable = true)]
public int? RobotArmObject { get; set; }
/// <summary>
/// 鏈烘鎵嬭澶囧熀纭�淇℃伅锛圝SON 搴忓垪鍖栵級
/// </summary>
- [SugarColumn(Length = 2000, ColumnDescription = "璁惧淇℃伅JSON", IsJsonKey = true)]
- public string RobotCraneJson { get; set; } = string.Empty;
+ [SugarColumn(Length = 2000, ColumnDescription = "璁惧淇℃伅JSON", IsNullable = true)]
+ public string? RobotCraneJson { get; set; }
/// <summary>
/// 鏈烘鎵嬪垵濮嬪寲瀹屾垚鍥炲埌寰呮満浣嶇姸鎬�
/// </summary>
/// <remarks>Possible values: "Homed", "Homing"</remarks>
- [SugarColumn(Length = 50, ColumnDescription = "鍥為浂鐘舵��", IsNullable = true, IsJsonKey = true)]
+ [SugarColumn(Length = 50, ColumnDescription = "鍥為浂鐘舵��", IsNullable = true)]
public string? Homed { get; set; }
/// <summary>
/// 鏈烘鎵嬪綋鍓嶆鍦ㄦ墽琛岀殑鍔ㄤ綔
/// </summary>
- [SugarColumn(Length = 50, ColumnDescription = "褰撳墠鍔ㄤ綔", IsNullable = true, IsJsonKey = true)]
+ [SugarColumn(Length = 50, ColumnDescription = "褰撳墠鍔ㄤ綔", IsNullable = true)]
public string? CurrentAction { get; set; }
/// <summary>
/// 鏈烘鎵嬪綋鍓嶈繍琛岀姸鎬�
/// </summary>
- [SugarColumn(Length = 50, ColumnDescription = "杩愯鐘舵��", IsNullable = true, IsJsonKey = true)]
+ [SugarColumn(Length = 50, ColumnDescription = "杩愯鐘舵��", IsNullable = true)]
public string? OperStatus { get; set; }
/// <summary>
/// 鏈�杩戜竴娆″彇璐у畬鎴愮殑浣嶇疆鏁扮粍锛圝SON锛�
/// </summary>
- [SugarColumn(Length = 500, ColumnDescription = "鍙栬揣浣嶇疆鏁扮粍JSON", IsNullable = true, IsJsonKey = true)]
+ [SugarColumn(Length = 500, ColumnDescription = "鍙栬揣浣嶇疆鏁扮粍JSON", IsNullable = true)]
public string? LastPickPositionsJson { get; set; }
/// <summary>
/// 鏈�杩戜竴娆℃斁璐у畬鎴愮殑浣嶇疆鏁扮粍锛圝SON锛�
/// </summary>
- [SugarColumn(Length = 500, ColumnDescription = "鏀捐揣浣嶇疆鏁扮粍JSON", IsNullable = true, IsJsonKey = true)]
+ [SugarColumn(Length = 500, ColumnDescription = "鏀捐揣浣嶇疆鏁扮粍JSON", IsNullable = true)]
public string? LastPutPositionsJson { get; set; }
/// <summary>
/// 鐢垫睜/璐т綅鏉$爜鍒楄〃锛圝SON锛�
/// </summary>
- [SugarColumn(Length = 2000, ColumnDescription = "鐢佃姱鏉$爜鍒楄〃JSON", IsNullable = true, IsJsonKey = true)]
+ [SugarColumn(Length = 2000, ColumnDescription = "鐢佃姱鏉$爜鍒楄〃JSON", IsNullable = true)]
public string? CellBarcodeJson { get; set; }
/// <summary>
/// 鏈烘鎵嬪綋鍓嶆鍦ㄦ墽琛岀殑浠诲姟锛圝SON 搴忓垪鍖栵級
/// </summary>
- [SugarColumn(Length = 2000, ColumnDescription = "褰撳墠浠诲姟JSON", IsNullable = true, IsJsonKey = true)]
+ [SugarColumn(Length = 2000, ColumnDescription = "褰撳墠浠诲姟JSON", IsNullable = true)]
public string? CurrentTaskJson { get; set; }
/// <summary>
/// 鏄惁闇�瑕佹墽琛屾媶鐩樹换鍔�
/// </summary>
- [SugarColumn(ColumnDescription = "鏄惁鎷嗙洏浠诲姟", IsJsonKey = true)]
+ [SugarColumn(ColumnDescription = "鏄惁鎷嗙洏浠诲姟")]
public bool IsSplitPallet { get; set; }
/// <summary>
/// 鏄惁闇�瑕佹墽琛岀粍鐩樹换鍔�
/// </summary>
- [SugarColumn(ColumnDescription = "鏄惁缁勭洏浠诲姟", IsJsonKey = true)]
+ [SugarColumn(ColumnDescription = "鏄惁缁勭洏浠诲姟")]
public bool IsGroupPallet { get; set; }
/// <summary>
/// 鏈哄櫒浜哄凡澶勭悊鐨勪换鍔℃�绘暟
/// </summary>
- [SugarColumn(ColumnDescription = "宸插鐞嗕换鍔℃�绘暟", IsJsonKey = true)]
+ [SugarColumn(ColumnDescription = "宸插鐞嗕换鍔℃�绘暟")]
public int RobotTaskTotalNum { get; set; }
/// <summary>
/// 鏄惁澶勪簬鍋囩數鑺ˉ鍏呮ā寮�
/// </summary>
- [SugarColumn(ColumnDescription = "鏄惁鍋囩數鑺ā寮�", IsJsonKey = true)]
+ [SugarColumn(ColumnDescription = "鏄惁鍋囩數鑺ā寮�")]
public bool IsInFakeBatteryMode { get; set; }
/// <summary>
/// 褰撳墠鎵规璧峰缂栧彿
/// </summary>
- [SugarColumn(ColumnDescription = "褰撳墠鎵规缂栧彿", IsJsonKey = true)]
+ [SugarColumn(ColumnDescription = "褰撳墠鎵规缂栧彿")]
public int CurrentBatchIndex { get; set; } = 1;
/// <summary>
/// 鎹㈢洏浠诲姟褰撳墠闃舵
/// </summary>
- [SugarColumn(ColumnDescription = "鎹㈢洏闃舵", IsJsonKey = true)]
+ [SugarColumn(ColumnDescription = "鎹㈢洏闃舵")]
public int ChangePalletPhase { get; set; }
/// <summary>
/// 鏄惁鎵爜NG
/// </summary>
- [SugarColumn(ColumnDescription = "鏄惁鎵爜NG", IsJsonKey = true)]
+ [SugarColumn(ColumnDescription = "鏄惁鎵爜NG")]
public bool IsScanNG { get; set; }
/// <summary>
/// 鏄惁鐢佃姱鍒颁綅
/// </summary>
- [SugarColumn(ColumnDescription = "鐢佃姱鏄惁鍒颁綅", IsJsonKey = true)]
+ [SugarColumn(ColumnDescription = "鐢佃姱鏄惁鍒颁綅")]
public bool BatteryArrived { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/RobotState/RobotCraneDevice.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/RobotState/RobotCraneDevice.cs
new file mode 100644
index 0000000..5e77ab3
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/RobotState/RobotCraneDevice.cs
@@ -0,0 +1,28 @@
+namespace WIDESEAWCS_Model.Models
+{
+ /// <summary>
+ /// 鏈哄櫒浜鸿澶囧熀纭�淇℃伅
+ /// </summary>
+ public class RobotCraneDevice
+ {
+ /// <summary>
+ /// 璁惧鏍囪瘑
+ /// </summary>
+ public string Device { get; set; } = string.Empty;
+
+ /// <summary>
+ /// 璁惧缂栫爜
+ /// </summary>
+ public string DeviceCode { get; set; } = string.Empty;
+
+ /// <summary>
+ /// 璁惧鍚嶇О
+ /// </summary>
+ public string DeviceName { get; set; } = string.Empty;
+
+ /// <summary>
+ /// IP 鍦板潃
+ /// </summary>
+ public string IPAddress { get; set; } = string.Empty;
+ }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotSocketState.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/RobotState/RobotSocketState.cs
similarity index 96%
rename from Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotSocketState.cs
rename to Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/RobotState/RobotSocketState.cs
index 06c8d92..de75b1d 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotSocketState.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Model/Models/RobotState/RobotSocketState.cs
@@ -1,13 +1,10 @@
-using WIDESEAWCS_Model.Models;
-using WIDESEAWCS_QuartzJob;
-
-namespace WIDESEAWCS_Tasks
+namespace WIDESEAWCS_Model.Models
{
/// <summary>
/// 鏈烘鎵� Socket 閫氫俊鐘舵�佹暟鎹被
/// </summary>
/// <remarks>
- /// 璇ョ被鐢ㄤ簬鍦� Redis 缂撳瓨涓瓨鍌ㄦ満姊版墜鐨勫疄鏃剁姸鎬侊紝鍖呮嫭浣嶇疆銆佷换鍔°�佹墜鑷傚璞$瓑淇℃伅銆�
+ /// 璇ョ被鐢ㄤ簬鍦ㄦ暟鎹簱涓瓨鍌ㄦ満姊版墜鐨勫疄鏃剁姸鎬侊紝鍖呮嫭浣嶇疆銆佷换鍔°�佹墜鑷傚璞$瓑淇℃伅銆�
/// 鎵�鏈夊睘鎬у潎璁捐涓虹嚎绋嬪畨鍏ㄦ洿鏂帮紝閫氳繃 <see cref="RobotStateManager"/> 鐨勭増鏈帶鍒舵満鍒舵潵闃叉骞跺彂瑕嗙洊銆�
/// </remarks>
public class RobotSocketState
@@ -21,7 +18,7 @@
/// 鐗堟湰鍙凤紝鐢ㄤ簬涔愯骞跺彂鎺у埗
/// </summary>
/// <remarks>
- /// 姣忔淇敼鐘舵�佹椂鏇存柊涓� DateTime.UtcNow.Ticks銆�
+ /// 姣忔淇敼鐘舵�佹椂鑷銆�
/// <see cref="RobotStateManager"/> 浣跨敤姝ゅ瓧娈靛疄鐜颁箰瑙傞攣锛岄槻姝㈠苟鍙戞洿鏂版椂鏃у�艰鐩栨柊鍊笺��
/// </remarks>
public long Version { get; set; } = DateTime.UtcNow.Ticks;
@@ -212,8 +209,6 @@
/// 鎷夊甫绾夸笂鐢佃姱鎵爜鏄惁NG銆�
/// </remarks>
public bool IsScanNG { get; set; } = false;
-
-
/// <summary>
/// 鏄惁鐢佃姱鍒颁綅
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/QuartzNetExtension.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/QuartzNetExtension.cs
index 3225212..41e3e7e 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/QuartzNetExtension.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/QuartzNetExtension.cs
@@ -4,6 +4,7 @@
using WIDESEAWCS_Core.Caches;
using WIDESEAWCS_Core.Helper;
using WIDESEAWCS_Core.LogHelper;
+using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob.DTO;
using WIDESEAWCS_QuartzJob.Service;
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Robot/RobotCraneDevice.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Robot/RobotCraneDevice.cs
deleted file mode 100644
index d251e27..0000000
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Robot/RobotCraneDevice.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-锘縰sing System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace WIDESEAWCS_QuartzJob
-{
- public class RobotCraneDevice
- {
- public string Device { get; set; }
- public string DeviceCode { get; set; }
- public string DeviceName { get; set; }
- public string IPAddress { get; set; }
- }
-}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/WIDESEAWCS_QuartzJob.csproj b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/WIDESEAWCS_QuartzJob.csproj
index 9c20899..9d66919 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/WIDESEAWCS_QuartzJob.csproj
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/WIDESEAWCS_QuartzJob.csproj
@@ -43,6 +43,7 @@
<ProjectReference Include="..\WIDESEAWCS_Common\WIDESEAWCS_Common.csproj" />
<ProjectReference Include="..\WIDESEAWCS_Communicator\WIDESEAWCS_Communicator.csproj" />
<ProjectReference Include="..\WIDESEAWCS_Core\WIDESEAWCS_Core.csproj" />
+ <ProjectReference Include="..\WIDESEAWCS_Model\WIDESEAWCS_Model.csproj" />
</ItemGroup>
</Project>
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Controllers/Task/RobotStateController.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Controllers/Task/RobotStateController.cs
new file mode 100644
index 0000000..4f20f11
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Controllers/Task/RobotStateController.cs
@@ -0,0 +1,20 @@
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using WIDESEAWCS_Core.BaseController;
+using WIDESEAWCS_ITaskInfoService;
+using WIDESEAWCS_Model.Models;
+
+namespace WIDESEAWCS_WCSServer.Controllers.Task
+{
+ /// <summary>
+ /// 鏈烘鎵嬬姸鎬佺鐞嗘帶鍒跺櫒
+ /// </summary>
+ [Route("api/RobotState")]
+ [ApiController]
+ public class RobotStateController : ApiBaseController<IRobotStateService, Dt_RobotState>
+ {
+ public RobotStateController(IRobotStateService service) : base(service)
+ {
+ }
+ }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json
index 2907e3e..f2d2bbf 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json
@@ -54,7 +54,7 @@
"ApiName": "WIDESEAWCS",
"ExpMinutes": 120,
"QuartzJobAutoStart": true,
- "DBSeedEnable": false,
+ "DBSeedEnable": true,
"QuartzDBSeedEnable": false,
"LogDeubgEnable": false, //鏄惁璁板綍璋冭瘯鏃ュ織
"PrintSql": false, //鎵撳嵃SQL璇彞
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoRepository/RobotStateRepository.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoRepository/RobotStateRepository.cs
index d282af4..012d9ad 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoRepository/RobotStateRepository.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoRepository/RobotStateRepository.cs
@@ -1,7 +1,6 @@
using Newtonsoft.Json;
using SqlSugar;
using WIDESEAWCS_Core.BaseRepository;
-using WIDESEAWCS_Core.UnitOfWork;
using WIDESEAWCS_ITaskInfoRepository;
using WIDESEAWCS_Model.Models;
@@ -10,20 +9,15 @@
/// <summary>
/// 鏈烘鎵嬬姸鎬� SqlSugar 浠撳偍瀹炵幇
/// </summary>
- public class RobotStateRepository : IUnitOfWork, IRobotStateRepository
+ public class RobotStateRepository : RepositoryBase<Dt_RobotState>, IRobotStateRepository
{
- private readonly IUnitOfWorkManage _unitOfWork;
- private readonly SqlSugarClient _db;
-
- public RobotStateRepository(IUnitOfWorkManage unitOfWork)
+ public RobotStateRepository(IUnitOfWorkManage unitOfWork) : base(unitOfWork)
{
- _unitOfWork = unitOfWork;
- _db = unitOfWork.GetDbClient();
}
public Dt_RobotState? GetByIp(string ipAddress)
{
- return _db.Queryable<Dt_RobotState>()
+ return Db.Queryable<Dt_RobotState>()
.Where(x => x.IPAddress == ipAddress)
.First();
}
@@ -39,22 +33,23 @@
var newState = new Dt_RobotState
{
IPAddress = ipAddress,
+ Version = DateTime.UtcNow.Ticks,
RobotCraneJson = JsonConvert.SerializeObject(robotCrane),
- CreateTime = DateTime.Now,
- UpdateTime = DateTime.Now
+ CreateDate = DateTime.Now,
+ ModifyDate = DateTime.Now
};
- _db.Insertable(newState).ExecuteCommand();
+ Db.Insertable(newState).ExecuteCommand();
return newState;
}
- public bool TryUpdate(string ipAddress, Dt_RobotState newState, byte[] expectedRowVersion)
+ public bool TryUpdate(string ipAddress, Dt_RobotState newState, long expectedVersion)
{
- newState.UpdateTime = DateTime.Now;
+ newState.ModifyDate = DateTime.Now;
- var affectedRows = _db.Updateable<Dt_RobotState>(newState)
- .Where(x => x.IPAddress == ipAddress)
- .WhereRowVersion(x => x.RowVersion, expectedRowVersion)
+ // 涔愯閿侊細WHERE IPAddress = @ip AND Version = @expectedVersion锛岀増鏈尮閰嶆墠鏇存柊
+ var affectedRows = Db.Updateable<Dt_RobotState>(newState)
+ .Where(x => x.IPAddress == ipAddress && x.Version == expectedVersion)
.ExecuteCommand();
return affectedRows > 0;
@@ -65,7 +60,7 @@
var state = new RobotSocketState
{
IPAddress = entity.IPAddress,
- Version = BitConverter.ToInt64(entity.RowVersion.Length >= 8 ? entity.RowVersion.Take(8).ToArray() : new byte[8], 0),
+ Version = entity.Version,
IsEventSubscribed = entity.IsEventSubscribed,
RobotRunMode = entity.RobotRunMode,
RobotControlMode = entity.RobotControlMode,
@@ -162,13 +157,5 @@
return entity;
}
-
- public SqlSugarClient GetDbClient() => _db;
-
- public void BeginTran() => _unitOfWork.BeginTran();
-
- public void CommitTran() => _unitOfWork.CommitTran();
-
- public void RollbackTran() => _unitOfWork.RollbackTran();
}
}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/RobotStateService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/RobotStateService.cs
new file mode 100644
index 0000000..d836367
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/RobotStateService.cs
@@ -0,0 +1,18 @@
+using WIDESEA_Core;
+using WIDESEAWCS_Core.BaseServices;
+using WIDESEAWCS_ITaskInfoRepository;
+using WIDESEAWCS_ITaskInfoService;
+using WIDESEAWCS_Model.Models;
+
+namespace WIDESEAWCS_TaskInfoService
+{
+ /// <summary>
+ /// 鏈烘鎵嬬姸鎬佹湇鍔″疄鐜�
+ /// </summary>
+ public class RobotStateService : ServiceBase<Dt_RobotState, IRobotStateRepository>, IRobotStateService
+ {
+ public RobotStateService(IRobotStateRepository repository) : base(repository)
+ {
+ }
+ }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/IRobotMessageRouter.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/IRobotMessageRouter.cs
index 7a2731a..d5fe523 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/IRobotMessageRouter.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/IRobotMessageRouter.cs
@@ -1,4 +1,5 @@
using System.Net.Sockets;
+using WIDESEAWCS_Model.Models;
namespace WIDESEAWCS_Tasks.Workflow.Abstractions
{
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/IRobotPrefixCommandHandler.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/IRobotPrefixCommandHandler.cs
index a2ee74b..25cf6f7 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/IRobotPrefixCommandHandler.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/IRobotPrefixCommandHandler.cs
@@ -1,4 +1,5 @@
using System.Net.Sockets;
+using WIDESEAWCS_Model.Models;
namespace WIDESEAWCS_Tasks.Workflow.Abstractions
{
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/IRobotSimpleCommandHandler.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/IRobotSimpleCommandHandler.cs
index af6e6a2..477137a 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/IRobotSimpleCommandHandler.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/IRobotSimpleCommandHandler.cs
@@ -1,3 +1,5 @@
+using WIDESEAWCS_Model.Models;
+
namespace WIDESEAWCS_Tasks.Workflow.Abstractions
{
/// <summary>
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/ISocketClientGateway.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/ISocketClientGateway.cs
index b238bb0..0d56122 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/ISocketClientGateway.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Abstractions/ISocketClientGateway.cs
@@ -1,4 +1,5 @@
using System.Net.Sockets;
+using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob;
namespace WIDESEAWCS_Tasks.Workflow.Abstractions
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotClientManager.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotClientManager.cs
index 942a8d3..1d952e3 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotClientManager.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotClientManager.cs
@@ -2,6 +2,7 @@
using System.Net.Sockets;
using Microsoft.Extensions.Logging;
using WIDESEAWCS_Core.LogHelper;
+using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob;
using WIDESEAWCS_Tasks.SocketServer;
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotJob.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotJob.cs
index f472356..ead2ab1 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotJob.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotJob.cs
@@ -7,7 +7,8 @@
using WIDESEAWCS_Core.LogHelper;
using WIDESEAWCS_ITaskInfoService;
using WIDESEAWCS_QuartzJob;
-using WIDESEAWCS_RedisService;
+using WIDESEAWCS_ITaskInfoRepository;
+using WIDESEAWCS_Model.Models;
using WIDESEAWCS_Tasks.SocketServer;
using WIDESEAWCS_Tasks.Workflow;
using WIDESEAWCS_Tasks.Workflow.Abstractions;
@@ -129,7 +130,7 @@
var prefixCommandHandler = new RobotPrefixCommandHandler(robotTaskService, _taskProcessor, _stateManager, socketGateway, fakeBatteryPositionService);
// 鍒濆鍖栨秷鎭矾鐢卞櫒
- _messageRouter = new RobotMessageHandler(socketGateway, _stateManager, cache, simpleCommandHandler, prefixCommandHandler, logger);
+ _messageRouter = new RobotMessageHandler(socketGateway, _stateManager, simpleCommandHandler, prefixCommandHandler, logger);
// 鍒濆鍖栧伐浣滄祦缂栨帓鍣�
_workflowOrchestrator = new RobotWorkflowOrchestrator(_stateManager, _clientManager, _taskProcessor, robotTaskService, _logger);
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotMessageHandler.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotMessageHandler.cs
index f8155cc..9bcf06b 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotMessageHandler.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotMessageHandler.cs
@@ -1,8 +1,8 @@
using Microsoft.Extensions.Logging;
using System.Net.Sockets;
using WIDESEAWCS_Common;
-using WIDESEAWCS_Core.Caches;
using WIDESEAWCS_Core.LogHelper;
+using WIDESEAWCS_Model.Models;
using WIDESEAWCS_Tasks.Workflow.Abstractions;
namespace WIDESEAWCS_Tasks
@@ -12,7 +12,7 @@
/// </summary>
/// <remarks>
/// 鏍稿績鑱岃矗锛�
- /// 1. 缂撳瓨鐘舵�佽鍙栵細浠� Redis 涓幏鍙栨満鍣ㄤ汉鏈�鏂扮殑鐘舵��
+ /// 1. 鐘舵�佹帴鏀讹細浠庤皟鐢ㄦ柟鑾峰彇鏈哄櫒浜烘渶鏂扮殑鐘舵��
/// 2. 鍛戒护鍒嗗彂锛氭牴鎹秷鎭被鍨嬪垎鍙戠粰涓嶅悓鐨勫鐞嗗櫒
/// - 绠�鍗曞懡浠わ紙濡� homing銆乺unning锛夛細鐢� <see cref="IRobotSimpleCommandHandler"/> 澶勭悊
/// - 鍓嶇紑鍛戒护锛堝 pickfinished銆乸utfinished锛夛細鐢� <see cref="IRobotPrefixCommandHandler"/> 澶勭悊
@@ -25,41 +25,21 @@
/// <summary>
/// Socket 瀹㈡埛绔綉鍏虫帴鍙�
/// </summary>
- /// <remarks>
- /// 鐢ㄤ簬鍚戝鎴风鍙戦�佸搷搴旀秷鎭��
- /// </remarks>
private readonly ISocketClientGateway _socketClientGateway;
/// <summary>
/// 鏈烘鎵嬬姸鎬佺鐞嗗櫒
/// </summary>
- /// <remarks>
- /// 鐢ㄤ簬璇诲彇鍜屾洿鏂版満鍣ㄤ汉鐨勭姸鎬併��
- /// </remarks>
private readonly RobotStateManager _stateManager;
-
- /// <summary>
- /// 缂撳瓨鏈嶅姟
- /// </summary>
- /// <remarks>
- /// 鐩存帴浣跨敤缂撳瓨鏈嶅姟妫�鏌ョ姸鎬佹槸鍚﹀瓨鍦ㄣ��
- /// </remarks>
- private readonly ICacheService _cache;
/// <summary>
/// 绠�鍗曞懡浠ゅ鐞嗗櫒
/// </summary>
- /// <remarks>
- /// 澶勭悊绠�鍗曠殑鐘舵�佹洿鏂板懡浠わ紝濡傝繍琛岀姸鎬併�佹ā寮忓垏鎹㈢瓑銆�
- /// </remarks>
private readonly IRobotSimpleCommandHandler _simpleCommandHandler;
/// <summary>
/// 鍓嶇紑鍛戒护澶勭悊鍣�
/// </summary>
- /// <remarks>
- /// 澶勭悊甯﹀弬鏁扮殑鍓嶇紑鍛戒护锛屽 pickfinished锛堝彇璐у畬鎴愶級銆乸utfinished锛堟斁璐у畬鎴愶級銆�
- /// </remarks>
private readonly IRobotPrefixCommandHandler _prefixCommandHandler;
/// <summary>
@@ -72,21 +52,18 @@
/// </summary>
/// <param name="socketClientGateway">Socket 缃戝叧</param>
/// <param name="stateManager">鐘舵�佺鐞嗗櫒</param>
- /// <param name="cache">缂撳瓨鏈嶅姟</param>
/// <param name="simpleCommandHandler">绠�鍗曞懡浠ゅ鐞嗗櫒</param>
/// <param name="prefixCommandHandler">鍓嶇紑鍛戒护澶勭悊鍣�</param>
/// <param name="logger">鏃ュ織璁板綍鍣�</param>
public RobotMessageHandler(
ISocketClientGateway socketClientGateway,
RobotStateManager stateManager,
- ICacheService cache,
IRobotSimpleCommandHandler simpleCommandHandler,
IRobotPrefixCommandHandler prefixCommandHandler,
ILogger<RobotJob> logger)
{
_socketClientGateway = socketClientGateway;
_stateManager = stateManager;
- _cache = cache;
_simpleCommandHandler = simpleCommandHandler;
_prefixCommandHandler = prefixCommandHandler;
_logger = logger;
@@ -98,12 +75,11 @@
/// <remarks>
/// 澶勭悊娴佺▼锛�
/// 1. 璁板綍鏃ュ織锛堣褰曞師濮嬫秷鎭唴瀹癸級
- /// 2. 楠岃瘉缂撳瓨涓槸鍚﹀瓨鍦ㄨ璁惧鐨勭姸鎬�
- /// 3. 灏濊瘯鐢ㄧ畝鍗曞懡浠ゅ鐞嗗櫒澶勭悊锛堢姸鎬佹洿鏂扮被鍛戒护锛�
+ /// 2. 灏濊瘯鐢ㄧ畝鍗曞懡浠ゅ鐞嗗櫒澶勭悊锛堢姸鎬佹洿鏂扮被鍛戒护锛�
/// - 濡傛灉澶勭悊鎴愬姛锛屽洖鍐欏師娑堟伅骞舵洿鏂扮姸鎬�
- /// 4. 濡傛灉涓嶆槸绠�鍗曞懡浠わ紝妫�鏌ユ槸鍚︽槸鍓嶇紑鍛戒护锛坧ickfinished/putfinished锛�
+ /// 3. 濡傛灉涓嶆槸绠�鍗曞懡浠わ紝妫�鏌ユ槸鍚︽槸鍓嶇紑鍛戒护锛坧ickfinished/putfinished锛�
/// - 濡傛灉鏄紝璋冪敤鍓嶇紑鍛戒护澶勭悊鍣ㄥ鐞�
- /// 5. 淇濇寔鍘熸湁琛屼负锛氱畝鍗曞懡浠ゅ拰鍓嶇紑鍛戒护閮藉洖鍐欏師娑堟伅
+ /// 4. 淇濇寔鍘熸湁琛屼负锛氱畝鍗曞懡浠ゅ拰鍓嶇紑鍛戒护閮藉洖鍐欏師娑堟伅
///
/// 娉ㄦ剰锛氭鏂规硶鍙兘鍦� TCP 娑堟伅鎺ユ敹鐨勪笂涓嬫枃涓棰戠箒璋冪敤锛岄渶娉ㄦ剰鎬ц兘銆�
/// </remarks>
@@ -115,46 +91,31 @@
public async Task<string?> HandleMessageReceivedAsync(string message, bool isJson, TcpClient client, RobotSocketState state)
{
// 璁板綍鎺ユ敹鍒扮殑娑堟伅鏃ュ織
- _logger.LogInformation($"鎺ユ敹鍒板鎴风銆恵state.RobotCrane.DeviceName}銆戝彂閫佹秷鎭�恵message}銆�");
- QuartzLogger.Info($"鎺ユ敹鍒板鎴风娑堟伅銆恵message}銆�", state.RobotCrane.DeviceName);
+ _logger.LogInformation($"鎺ユ敹鍒板鎴风銆恵state.RobotCrane?.DeviceName}銆戝彂閫佹秷鎭�恵message}銆�");
+ QuartzLogger.Info($"鎺ユ敹鍒板鎴风娑堟伅銆恵message}銆�", state.RobotCrane?.DeviceName);
// 妫�鏌ヤ换鍔℃�绘暟鏄惁鏈揪鍒颁笂闄�
if (state.RobotTaskTotalNum > RobotConst.MaxTaskTotalNum)
{
- // 璁板綍鎺ユ敹鍒扮殑娑堟伅鏃ュ織
- _logger.LogInformation($"鎺ユ敹鍒板鎴风銆恵state.RobotCrane.DeviceName}銆戝彂閫佹秷鎭�恵message}銆�");
- QuartzLogger.Info($"鎺ユ敹鍒板鎴风娑堟伅銆恵message}銆�", state.RobotCrane.DeviceName);
- // 澶勭悊鎴愬姛鍚庯紝灏嗗師娑堟伅鍥炲啓鍒板鎴风锛堜繚鎸佸師鏈夎涓猴級
+ _logger.LogInformation($"鎺ユ敹鍒板鎴风銆恵state.RobotCrane?.DeviceName}銆戝彂閫佹秷鎭�恵message}銆�");
+ QuartzLogger.Info($"鎺ユ敹鍒板鎴风娑堟伅銆恵message}銆�", state.RobotCrane?.DeviceName);
await _socketClientGateway.SendMessageAsync(client, message);
return null;
}
-
- // 鏋勫缓缂撳瓨閿紝妫�鏌� Redis 涓槸鍚﹀瓨鍦ㄨ璁惧鐨勭姸鎬�
- var cacheKey = $"{RedisPrefix.Code}:{RedisName.SocketDevices}:{client.Client.RemoteEndPoint}";
-
- // 濡傛灉缂撳瓨涓笉瀛樺湪鎴栫姸鎬佷负 null锛屽拷鐣ユ娑堟伅
- if (!_cache.TryGetValue(cacheKey, out RobotSocketState? cachedState) || cachedState == null)
- {
- _logger.LogInformation($"缂撳瓨涓笉瀛樺湪鎴栫姸鎬佷负 null锛屽拷鐣ユ娑堟伅");
- return null;
- }
-
- // 浣跨敤缂撳瓨涓幏鍙栫殑鐘舵��
- var activeState = cachedState;
// 灏嗘秷鎭浆鎹负灏忓啓锛堢敤浜庣畝鍗曞懡浠ゅ尮閰嶏級
string messageLower = message.ToLowerInvariant();
// 灏濊瘯鐢ㄧ畝鍗曞懡浠ゅ鐞嗗櫒澶勭悊
// 绠�鍗曞懡浠ゅ寘鎷細homing銆乭omed銆乺unning銆乸ausing銆乺unmode銆乧ontrolmode 绛�
- if (await _simpleCommandHandler.HandleAsync(messageLower, activeState))
+ if (await _simpleCommandHandler.HandleAsync(messageLower, state))
{
// 澶勭悊鎴愬姛鍚庯紝灏嗗師娑堟伅鍥炲啓鍒板鎴风锛堜繚鎸佸師鏈夎涓猴級
await _socketClientGateway.SendMessageAsync(client, message);
- QuartzLogger.Info($"鍙戦�佹秷鎭細銆恵message}銆�", state.RobotCrane.DeviceName);
+ QuartzLogger.Info($"鍙戦�佹秷鎭細銆恵message}銆�", state.RobotCrane?.DeviceName);
- // 瀹夊叏鏇存柊鐘舵�佸埌 Redis
- _stateManager.TryUpdateStateSafely(activeState.IPAddress, activeState);
+ // 瀹夊叏鏇存柊鐘舵�佸埌鏁版嵁搴�
+ _stateManager.TryUpdateStateSafely(state.IPAddress, state);
return null;
}
@@ -163,11 +124,9 @@
if (_prefixCommandHandler.IsPrefixCommand(messageLower))
{
// 璋冪敤鍓嶇紑鍛戒护澶勭悊鍣�
- // 鍓嶇紑鍛戒护澶勭悊鍣ㄤ細瑙f瀽浣嶇疆鍙傛暟骞舵洿鏂扮姸鎬�
- await _prefixCommandHandler.HandleAsync(message, activeState, client);
+ await _prefixCommandHandler.HandleAsync(message, state, client);
}
- // 榛樿杩斿洖 null锛屼笉浜х敓鍝嶅簲娑堟伅
return null;
}
}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotStateManager.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotStateManager.cs
index 028305d..4aaae62 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotStateManager.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotStateManager.cs
@@ -1,6 +1,5 @@
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
-using WIDESEAWCS_Common;
using WIDESEAWCS_Core.LogHelper;
using WIDESEAWCS_ITaskInfoRepository;
using WIDESEAWCS_Model.Models;
@@ -12,7 +11,7 @@
/// </summary>
/// <remarks>
/// 鏍稿績鍔熻兘鏄�氳繃 IRobotStateRepository 绠$悊鏁版嵁搴撲腑鐨勬満姊版墜鐘舵�併��
- /// 鎻愪緵涔愯骞跺彂鎺у埗锛岄�氳繃 RowVersion 闃叉骞跺彂鏇存柊鏃剁殑鏁版嵁瑕嗙洊闂銆�
+ /// 鎻愪緵涔愯骞跺彂鎺у埗锛岄�氳繃 Version 瀛楁闃叉骞跺彂鏇存柊鏃剁殑鏁版嵁瑕嗙洊闂銆�
/// </remarks>
public class RobotStateManager
{
@@ -38,11 +37,11 @@
}
/// <summary>
- /// 瀹夊叏鏇存柊 RobotSocketState 缂撳瓨锛岄槻姝㈠苟鍙戣鐩�
+ /// 瀹夊叏鏇存柊 RobotSocketState锛岄槻姝㈠苟鍙戣鐩�
/// </summary>
/// <remarks>
- /// 浣跨敤涔愯骞跺彂妯″紡锛氬厛璇诲彇褰撳墠 RowVersion锛屾墽琛屾洿鏂版椂妫�鏌ョ増鏈槸鍚︿竴鑷淬��
- /// 濡傛灉 RowVersion 涓嶅尮閰嶏紙璇存槑鏈夊叾浠栫嚎绋嬪凡鏇存柊锛夛紝鍒欐洿鏂板け璐ヨ繑鍥� false銆�
+ /// 浣跨敤涔愯骞跺彂妯″紡锛氬厛璇诲彇褰撳墠 Version锛屾墽琛屾洿鏂版椂妫�鏌ョ増鏈槸鍚︿竴鑷淬��
+ /// 濡傛灉 Version 涓嶅尮閰嶏紙璇存槑鏈夊叾浠栫嚎绋嬪凡鏇存柊锛夛紝鍒欐洿鏂板け璐ヨ繑鍥� false銆�
/// </remarks>
/// <param name="ipAddress">璁惧 IP 鍦板潃</param>
/// <param name="updateAction">鏇存柊鐘舵�佺殑濮旀墭鍑芥暟锛屼紶鍏ュ綋鍓嶇姸鎬佸壇鏈紝杩斿洖淇敼鍚庣殑鏂扮姸鎬�</param>
@@ -57,8 +56,8 @@
return false;
}
- // 璁板綍褰撳墠瀛樺偍鐨� RowVersion锛屼綔涓烘洿鏂版椂鐨勬湡鏈涚増鏈�
- var expectedRowVersion = currentEntity.RowVersion;
+ // 璁板綍褰撳墠瀛樺偍鐨� Version锛屼綔涓烘洿鏂版椂鐨勬湡鏈涚増鏈�
+ var expectedVersion = currentEntity.Version;
// 鍒涘缓鐘舵�佺殑娣辨嫹璐濆壇鏈紙浣跨敤 JSON 搴忓垪鍖栧疄鐜帮級
var stateCopy = CloneState(_repository.ToSocketState(currentEntity));
@@ -68,12 +67,12 @@
// 灏嗘柊鐘舵�佽浆鎹负鏁版嵁搴撳疄浣�
var newEntity = _repository.ToEntity(newState);
- newEntity.RowVersion = Array.Empty<byte>(); // SqlSugar 浼氳嚜鍔ㄧ鐞�
newEntity.Id = currentEntity.Id;
+ newEntity.Version = expectedVersion + 1; // 鐗堟湰鑷
- // 璋冪敤浠撳偍鐨勫畨鍏ㄦ洿鏂版柟娉曪紝浼犲叆鏈熸湜 RowVersion
- // 濡傛灉 RowVersion 涓嶄竴鑷达紙宸茶鍏朵粬绾跨▼鏇存柊锛夛紝鍒欐洿鏂板け璐�
- return _repository.TryUpdate(ipAddress, newEntity, expectedRowVersion);
+ // 璋冪敤浠撳偍鐨勫畨鍏ㄦ洿鏂版柟娉曪紝浼犲叆鏈熸湜 Version
+ // 濡傛灉 Version 涓嶄竴鑷达紙宸茶鍏朵粬绾跨▼鏇存柊锛夛紝鍒欐洿鏂板け璐�
+ return _repository.TryUpdate(ipAddress, newEntity, expectedVersion);
}
/// <summary>
@@ -94,29 +93,26 @@
// 濡傛灉褰撳墠涓嶅瓨鍦ㄨ璁惧鐨勭姸鎬侊紝鍒涘缓鏂拌褰�
if (currentEntity == null)
{
- var entity = _repository.ToEntity(newState);
- entity.CreateTime = DateTime.Now;
- entity.UpdateTime = DateTime.Now;
_repository.GetOrCreate(newState.IPAddress, newState.RobotCrane ?? new RobotCraneDevice());
_logger.LogDebug("TryUpdateStateSafely锛氬垱寤烘柊鐘舵�侊紝IP: {IpAddress}", ipAddress);
QuartzLogger.Debug($"鍒涘缓鏂扮姸鎬侊紝IP: {ipAddress}", ipAddress);
return true;
}
- // 褰撳墠瀛樺湪鐘舵�侊紝璁板綍鏈熸湜 RowVersion 鐢ㄤ簬涔愯閿佹鏌�
- var expectedRowVersion = currentEntity.RowVersion;
+ // 褰撳墠瀛樺湪鐘舵�侊紝璁板綍鏈熸湜 Version 鐢ㄤ簬涔愯閿佹鏌�
+ var expectedVersion = currentEntity.Version;
// 灏嗘柊鐘舵�佽浆鎹负鏁版嵁搴撳疄浣�
var newEntity = _repository.ToEntity(newState);
newEntity.Id = currentEntity.Id;
- newEntity.RowVersion = Array.Empty<byte>();
+ newEntity.Version = expectedVersion + 1; // 鐗堟湰鑷
// 灏濊瘯瀹夊叏鏇存柊锛屽鏋滅増鏈啿绐佸垯杩斿洖 false
- bool success = _repository.TryUpdate(ipAddress, newEntity, expectedRowVersion);
+ bool success = _repository.TryUpdate(ipAddress, newEntity, expectedVersion);
if (!success)
{
- _logger.LogWarning("TryUpdateStateSafely锛氱増鏈啿绐侊紝鏇存柊澶辫触锛孖P: {IpAddress}锛屾湡鏈涚増鏈瓧鑺傞暱搴�: {ExpectedLength}", ipAddress, expectedRowVersion.Length);
+ _logger.LogWarning("TryUpdateStateSafely锛氱増鏈啿绐侊紝鏇存柊澶辫触锛孖P: {IpAddress}锛屾湡鏈涚増鏈�: {ExpectedVersion}", ipAddress, expectedVersion);
QuartzLogger.Warn($"鐗堟湰鍐茬獊锛屾洿鏂板け璐ワ紝IP: {ipAddress}", ipAddress);
}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotSimpleCommandHandler.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotSimpleCommandHandler.cs
index 6f7515c..f623791 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotSimpleCommandHandler.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/Workflow/RobotSimpleCommandHandler.cs
@@ -1,5 +1,6 @@
using WIDESEAWCS_Common.TaskEnum;
using WIDESEAWCS_Core.LogHelper;
+using WIDESEAWCS_Model.Models;
using WIDESEAWCS_Tasks.Workflow.Abstractions;
namespace WIDESEAWCS_Tasks.Workflow
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/SocketClientGateway.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/SocketClientGateway.cs
index feef4f1..7142a7b 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/SocketClientGateway.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/SocketClientGateway.cs
@@ -1,4 +1,5 @@
using System.Net.Sockets;
+using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob;
using WIDESEAWCS_Tasks.Workflow.Abstractions;
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs
index 5b0ba27..6a5fca3 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs
@@ -2,6 +2,7 @@
using System.Text;
using System.Text.Json;
using System.IO;
+using WIDESEAWCS_Model.Models;
namespace WIDESEAWCS_Tasks.SocketServer
{
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.cs
index 1999ffd..723464b 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.cs
@@ -6,6 +6,7 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob;
namespace WIDESEAWCS_Tasks.SocketServer
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/WIDESEAWCS_Tasks.csproj b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/WIDESEAWCS_Tasks.csproj
index a5bcd6d..cba6df7 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/WIDESEAWCS_Tasks.csproj
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/WIDESEAWCS_Tasks.csproj
@@ -7,6 +7,7 @@
</PropertyGroup>
<ItemGroup>
+ <ProjectReference Include="..\WIDESEAWCS_Model\WIDESEAWCS_Model.csproj" />
<ProjectReference Include="..\WIDESEAWCS_QuartzJob\WIDESEAWCS_QuartzJob.csproj" />
<ProjectReference Include="..\WIDESEAWCS_TaskInfoService\WIDESEAWCS_TaskInfoService.csproj" />
</ItemGroup>
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/.env.development b/Code/WMS/WIDESEA_WMSClient_Vben/.env.development
new file mode 100644
index 0000000..0b322fb
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/.env.development
@@ -0,0 +1 @@
+VITE_API_BASE_URL=http://localhost:9291
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/index.html b/Code/WMS/WIDESEA_WMSClient_Vben/index.html
new file mode 100644
index 0000000..d4c7c50
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/index.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+ <head>
+ <meta charset="UTF-8" />
+ <link rel="icon" type="image/svg+xml" href="/favicon.ico" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>WMS绠$悊绯荤粺</title>
+ </head>
+ <body>
+ <div id="app"></div>
+ <script type="module" src="/src/main.ts"></script>
+ </body>
+</html>
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/package-lock.json b/Code/WMS/WIDESEA_WMSClient_Vben/package-lock.json
new file mode 100644
index 0000000..99c69ac
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/package-lock.json
@@ -0,0 +1,1929 @@
+{
+ "name": "widesea-wms-client-vben",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "widesea-wms-client-vben",
+ "version": "1.0.0",
+ "dependencies": {
+ "@element-plus/icons-vue": "^2.3.1",
+ "axios": "^1.6.7",
+ "element-plus": "^2.5.6",
+ "pinia": "^2.1.7",
+ "vue": "^3.4.21",
+ "vue-router": "^4.3.0"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "^5.0.4",
+ "typescript": "^5.4.2",
+ "vite": "^5.1.6",
+ "vue-tsc": "^2.0.6"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
+ "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.29.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz",
+ "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.29.0"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
+ "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@ctrl/tinycolor": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-4.2.0.tgz",
+ "integrity": "sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@element-plus/icons-vue": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.3.2.tgz",
+ "integrity": "sha512-OzIuTaIfC8QXEPmJvB4Y4kw34rSXdCJzxcD1kFStBvr8bK6X1zQAYDo0CNMjojnfTqRQCJ0I7prlErcoRiET2A==",
+ "license": "MIT",
+ "peerDependencies": {
+ "vue": "^3.2.0"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+ "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+ "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+ "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+ "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+ "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+ "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+ "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+ "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+ "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+ "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+ "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+ "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+ "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+ "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+ "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+ "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+ "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+ "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+ "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@floating-ui/core": {
+ "version": "1.7.5",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz",
+ "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/utils": "^0.2.11"
+ }
+ },
+ "node_modules/@floating-ui/dom": {
+ "version": "1.7.6",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz",
+ "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/core": "^1.7.5",
+ "@floating-ui/utils": "^0.2.11"
+ }
+ },
+ "node_modules/@floating-ui/utils": {
+ "version": "0.2.11",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz",
+ "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==",
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "license": "MIT"
+ },
+ "node_modules/@popperjs/core": {
+ "name": "@sxzz/popperjs-es",
+ "version": "2.11.8",
+ "resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.8.tgz",
+ "integrity": "sha512-wOwESXvvED3S8xBmcPWHs2dUuzrE4XiZeFu7e1hROIJkm02a49N120pmOXxY33sBb6hArItm5W5tcg1cBtV+HQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/popperjs"
+ }
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.2.tgz",
+ "integrity": "sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.2.tgz",
+ "integrity": "sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.2.tgz",
+ "integrity": "sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.2.tgz",
+ "integrity": "sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.2.tgz",
+ "integrity": "sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.2.tgz",
+ "integrity": "sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.2.tgz",
+ "integrity": "sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.2.tgz",
+ "integrity": "sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.2.tgz",
+ "integrity": "sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.2.tgz",
+ "integrity": "sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.2.tgz",
+ "integrity": "sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-musl": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.2.tgz",
+ "integrity": "sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.2.tgz",
+ "integrity": "sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-musl": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.2.tgz",
+ "integrity": "sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.2.tgz",
+ "integrity": "sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.2.tgz",
+ "integrity": "sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.2.tgz",
+ "integrity": "sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.2.tgz",
+ "integrity": "sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.2.tgz",
+ "integrity": "sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openbsd-x64": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.2.tgz",
+ "integrity": "sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.2.tgz",
+ "integrity": "sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.2.tgz",
+ "integrity": "sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.2.tgz",
+ "integrity": "sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.2.tgz",
+ "integrity": "sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.2.tgz",
+ "integrity": "sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/lodash": {
+ "version": "4.17.24",
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.24.tgz",
+ "integrity": "sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==",
+ "license": "MIT"
+ },
+ "node_modules/@types/lodash-es": {
+ "version": "4.17.12",
+ "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz",
+ "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/lodash": "*"
+ }
+ },
+ "node_modules/@types/web-bluetooth": {
+ "version": "0.0.20",
+ "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz",
+ "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==",
+ "license": "MIT"
+ },
+ "node_modules/@vitejs/plugin-vue": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz",
+ "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^5.0.0 || ^6.0.0",
+ "vue": "^3.2.25"
+ }
+ },
+ "node_modules/@volar/language-core": {
+ "version": "2.4.15",
+ "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.15.tgz",
+ "integrity": "sha512-3VHw+QZU0ZG9IuQmzT68IyN4hZNd9GchGPhbD9+pa8CVv7rnoOZwo7T8weIbrRmihqy3ATpdfXFnqRrfPVK6CA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@volar/source-map": "2.4.15"
+ }
+ },
+ "node_modules/@volar/source-map": {
+ "version": "2.4.15",
+ "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.15.tgz",
+ "integrity": "sha512-CPbMWlUN6hVZJYGcU/GSoHu4EnCHiLaXI9n8c9la6RaI9W5JHX+NqG+GSQcB0JdC2FIBLdZJwGsfKyBB71VlTg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@volar/typescript": {
+ "version": "2.4.15",
+ "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.15.tgz",
+ "integrity": "sha512-2aZ8i0cqPGjXb4BhkMsPYDkkuc2ZQ6yOpqwAuNwUoncELqoy5fRgOQtLR9gB0g902iS0NAkvpIzs27geVyVdPg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@volar/language-core": "2.4.15",
+ "path-browserify": "^1.0.1",
+ "vscode-uri": "^3.0.8"
+ }
+ },
+ "node_modules/@vue/compiler-core": {
+ "version": "3.5.32",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.32.tgz",
+ "integrity": "sha512-4x74Tbtqnda8s/NSD6e1Dr5p1c8HdMU5RWSjMSUzb8RTcUQqevDCxVAitcLBKT+ie3o0Dl9crc/S/opJM7qBGQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.2",
+ "@vue/shared": "3.5.32",
+ "entities": "^7.0.1",
+ "estree-walker": "^2.0.2",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-dom": {
+ "version": "3.5.32",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.32.tgz",
+ "integrity": "sha512-ybHAu70NtiEI1fvAUz3oXZqkUYEe5J98GjMDpTGl5iHb0T15wQYLR4wE3h9xfuTNA+Cm2f4czfe8B4s+CCH57Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-core": "3.5.32",
+ "@vue/shared": "3.5.32"
+ }
+ },
+ "node_modules/@vue/compiler-sfc": {
+ "version": "3.5.32",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.32.tgz",
+ "integrity": "sha512-8UYUYo71cP/0YHMO814TRZlPuUUw3oifHuMR7Wp9SNoRSrxRQnhMLNlCeaODNn6kNTJsjFoQ/kqIj4qGvya4Xg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.2",
+ "@vue/compiler-core": "3.5.32",
+ "@vue/compiler-dom": "3.5.32",
+ "@vue/compiler-ssr": "3.5.32",
+ "@vue/shared": "3.5.32",
+ "estree-walker": "^2.0.2",
+ "magic-string": "^0.30.21",
+ "postcss": "^8.5.8",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-ssr": {
+ "version": "3.5.32",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.32.tgz",
+ "integrity": "sha512-Gp4gTs22T3DgRotZ8aA/6m2jMR+GMztvBXUBEUOYOcST+giyGWJ4WvFd7QLHBkzTxkfOt8IELKNdpzITLbA2rw==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.32",
+ "@vue/shared": "3.5.32"
+ }
+ },
+ "node_modules/@vue/compiler-vue2": {
+ "version": "2.7.16",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz",
+ "integrity": "sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "de-indent": "^1.0.2",
+ "he": "^1.2.0"
+ }
+ },
+ "node_modules/@vue/devtools-api": {
+ "version": "6.6.4",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
+ "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
+ "license": "MIT"
+ },
+ "node_modules/@vue/language-core": {
+ "version": "2.2.12",
+ "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.2.12.tgz",
+ "integrity": "sha512-IsGljWbKGU1MZpBPN+BvPAdr55YPkj2nB/TBNGNC32Vy2qLG25DYu/NBN2vNtZqdRbTRjaoYrahLrToim2NanA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@volar/language-core": "2.4.15",
+ "@vue/compiler-dom": "^3.5.0",
+ "@vue/compiler-vue2": "^2.7.16",
+ "@vue/shared": "^3.5.0",
+ "alien-signals": "^1.0.3",
+ "minimatch": "^9.0.3",
+ "muggle-string": "^0.4.1",
+ "path-browserify": "^1.0.1"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vue/reactivity": {
+ "version": "3.5.32",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.32.tgz",
+ "integrity": "sha512-/ORasxSGvZ6MN5gc+uE364SxFdJ0+WqVG0CENXaGW58TOCdrAW76WWaplDtECeS1qphvtBZtR+3/o1g1zL4xPQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/shared": "3.5.32"
+ }
+ },
+ "node_modules/@vue/runtime-core": {
+ "version": "3.5.32",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.32.tgz",
+ "integrity": "sha512-pDrXCejn4UpFDFmMd27AcJEbHaLemaE5o4pbb7sLk79SRIhc6/t34BQA7SGNgYtbMnvbF/HHOftYBgFJtUoJUQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.32",
+ "@vue/shared": "3.5.32"
+ }
+ },
+ "node_modules/@vue/runtime-dom": {
+ "version": "3.5.32",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.32.tgz",
+ "integrity": "sha512-1CDVv7tv/IV13V8Nip1k/aaObVbWqRlVCVezTwx3K07p7Vxossp5JU1dcPNhJk3w347gonIUT9jQOGutyJrSVQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.32",
+ "@vue/runtime-core": "3.5.32",
+ "@vue/shared": "3.5.32",
+ "csstype": "^3.2.3"
+ }
+ },
+ "node_modules/@vue/server-renderer": {
+ "version": "3.5.32",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.32.tgz",
+ "integrity": "sha512-IOjm2+JQwRFS7W28HNuJeXQle9KdZbODFY7hFGVtnnghF51ta20EWAZJHX+zLGtsHhaU6uC9BGPV52KVpYryMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-ssr": "3.5.32",
+ "@vue/shared": "3.5.32"
+ },
+ "peerDependencies": {
+ "vue": "3.5.32"
+ }
+ },
+ "node_modules/@vue/shared": {
+ "version": "3.5.32",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.32.tgz",
+ "integrity": "sha512-ksNyrmRQzWJJ8n3cRDuSF7zNNontuJg1YHnmWRJd2AMu8Ij2bqwiiri2lH5rHtYPZjj4STkNcgcmiQqlOjiYGg==",
+ "license": "MIT"
+ },
+ "node_modules/@vueuse/core": {
+ "version": "12.0.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-12.0.0.tgz",
+ "integrity": "sha512-C12RukhXiJCbx4MGhjmd/gH52TjJsc3G0E0kQj/kb19H3Nt6n1CA4DRWuTdWWcaFRdlTe0npWDS942mvacvNBw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/web-bluetooth": "^0.0.20",
+ "@vueuse/metadata": "12.0.0",
+ "@vueuse/shared": "12.0.0",
+ "vue": "^3.5.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@vueuse/metadata": {
+ "version": "12.0.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.0.0.tgz",
+ "integrity": "sha512-Yzimd1D3sjxTDOlF05HekU5aSGdKjxhuhRFHA7gDWLn57PRbBIh+SF5NmjhJ0WRgF3my7T8LBucyxdFJjIfRJQ==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@vueuse/shared": {
+ "version": "12.0.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-12.0.0.tgz",
+ "integrity": "sha512-3i6qtcq2PIio5i/vVYidkkcgvmTjCqrf26u+Fd4LhnbBmIT6FN8y6q/GJERp8lfcB9zVEfjdV0Br0443qZuJpw==",
+ "license": "MIT",
+ "dependencies": {
+ "vue": "^3.5.13"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/alien-signals": {
+ "version": "1.0.13",
+ "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-1.0.13.tgz",
+ "integrity": "sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/async-validator": {
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
+ "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==",
+ "license": "MIT"
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "license": "MIT"
+ },
+ "node_modules/axios": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz",
+ "integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==",
+ "license": "MIT",
+ "dependencies": {
+ "follow-redirects": "^1.15.11",
+ "form-data": "^4.0.5",
+ "proxy-from-env": "^2.1.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/brace-expansion": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz",
+ "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "license": "MIT"
+ },
+ "node_modules/dayjs": {
+ "version": "1.11.20",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz",
+ "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==",
+ "license": "MIT"
+ },
+ "node_modules/de-indent": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
+ "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/element-plus": {
+ "version": "2.13.7",
+ "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.13.7.tgz",
+ "integrity": "sha512-XdHATFZOyzVFL1DaHQ90IOJQSg9UnSAV+bhDW+YB5UoZ0Hxs50mwqjqfwXkuwpSag+VXXizVcErBR6Movo5daw==",
+ "license": "MIT",
+ "dependencies": {
+ "@ctrl/tinycolor": "^4.2.0",
+ "@element-plus/icons-vue": "^2.3.2",
+ "@floating-ui/dom": "^1.0.1",
+ "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7",
+ "@types/lodash": "^4.17.20",
+ "@types/lodash-es": "^4.17.12",
+ "@vueuse/core": "12.0.0",
+ "async-validator": "^4.2.5",
+ "dayjs": "^1.11.19",
+ "lodash": "^4.17.23",
+ "lodash-es": "^4.17.23",
+ "lodash-unified": "^1.0.3",
+ "memoize-one": "^6.0.0",
+ "normalize-wheel-es": "^1.2.0",
+ "vue-component-type-helpers": "^3.2.4"
+ },
+ "peerDependencies": {
+ "vue": "^3.3.0"
+ }
+ },
+ "node_modules/entities": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
+ "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+ "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.21.5",
+ "@esbuild/android-arm": "0.21.5",
+ "@esbuild/android-arm64": "0.21.5",
+ "@esbuild/android-x64": "0.21.5",
+ "@esbuild/darwin-arm64": "0.21.5",
+ "@esbuild/darwin-x64": "0.21.5",
+ "@esbuild/freebsd-arm64": "0.21.5",
+ "@esbuild/freebsd-x64": "0.21.5",
+ "@esbuild/linux-arm": "0.21.5",
+ "@esbuild/linux-arm64": "0.21.5",
+ "@esbuild/linux-ia32": "0.21.5",
+ "@esbuild/linux-loong64": "0.21.5",
+ "@esbuild/linux-mips64el": "0.21.5",
+ "@esbuild/linux-ppc64": "0.21.5",
+ "@esbuild/linux-riscv64": "0.21.5",
+ "@esbuild/linux-s390x": "0.21.5",
+ "@esbuild/linux-x64": "0.21.5",
+ "@esbuild/netbsd-x64": "0.21.5",
+ "@esbuild/openbsd-x64": "0.21.5",
+ "@esbuild/sunos-x64": "0.21.5",
+ "@esbuild/win32-arm64": "0.21.5",
+ "@esbuild/win32-ia32": "0.21.5",
+ "@esbuild/win32-x64": "0.21.5"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "license": "MIT"
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.16.0",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz",
+ "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
+ "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz",
+ "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "he": "bin/he"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
+ "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
+ "license": "MIT"
+ },
+ "node_modules/lodash-es": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz",
+ "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==",
+ "license": "MIT"
+ },
+ "node_modules/lodash-unified": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.3.tgz",
+ "integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/lodash-es": "*",
+ "lodash": "*",
+ "lodash-es": "*"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/memoize-one": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
+ "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==",
+ "license": "MIT"
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/muggle-string": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz",
+ "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/normalize-wheel-es": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz",
+ "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/path-browserify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
+ "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
+ "node_modules/pinia": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.3.1.tgz",
+ "integrity": "sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-api": "^6.6.3",
+ "vue-demi": "^0.14.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/posva"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.4.4",
+ "vue": "^2.7.0 || ^3.5.11"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.10",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz",
+ "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/proxy-from-env": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz",
+ "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.60.2",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.2.tgz",
+ "integrity": "sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.8"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.60.2",
+ "@rollup/rollup-android-arm64": "4.60.2",
+ "@rollup/rollup-darwin-arm64": "4.60.2",
+ "@rollup/rollup-darwin-x64": "4.60.2",
+ "@rollup/rollup-freebsd-arm64": "4.60.2",
+ "@rollup/rollup-freebsd-x64": "4.60.2",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.60.2",
+ "@rollup/rollup-linux-arm-musleabihf": "4.60.2",
+ "@rollup/rollup-linux-arm64-gnu": "4.60.2",
+ "@rollup/rollup-linux-arm64-musl": "4.60.2",
+ "@rollup/rollup-linux-loong64-gnu": "4.60.2",
+ "@rollup/rollup-linux-loong64-musl": "4.60.2",
+ "@rollup/rollup-linux-ppc64-gnu": "4.60.2",
+ "@rollup/rollup-linux-ppc64-musl": "4.60.2",
+ "@rollup/rollup-linux-riscv64-gnu": "4.60.2",
+ "@rollup/rollup-linux-riscv64-musl": "4.60.2",
+ "@rollup/rollup-linux-s390x-gnu": "4.60.2",
+ "@rollup/rollup-linux-x64-gnu": "4.60.2",
+ "@rollup/rollup-linux-x64-musl": "4.60.2",
+ "@rollup/rollup-openbsd-x64": "4.60.2",
+ "@rollup/rollup-openharmony-arm64": "4.60.2",
+ "@rollup/rollup-win32-arm64-msvc": "4.60.2",
+ "@rollup/rollup-win32-ia32-msvc": "4.60.2",
+ "@rollup/rollup-win32-x64-gnu": "4.60.2",
+ "@rollup/rollup-win32-x64-msvc": "4.60.2",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.9.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+ "devOptional": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/vite": {
+ "version": "5.4.21",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz",
+ "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.21.3",
+ "postcss": "^8.4.43",
+ "rollup": "^4.20.0"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || >=20.0.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vscode-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz",
+ "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/vue": {
+ "version": "3.5.32",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.32.tgz",
+ "integrity": "sha512-vM4z4Q9tTafVfMAK7IVzmxg34rSzTFMyIe0UUEijUCkn9+23lj0WRfA83dg7eQZIUlgOSGrkViIaCfqSAUXsMw==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.32",
+ "@vue/compiler-sfc": "3.5.32",
+ "@vue/runtime-dom": "3.5.32",
+ "@vue/server-renderer": "3.5.32",
+ "@vue/shared": "3.5.32"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue-component-type-helpers": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-3.2.7.tgz",
+ "integrity": "sha512-+gPp5YGmhfsj1IN+xUo7y0fb4clfnOiiUA39y07yW1VzCRjzVgwLbtmdWlghh7mXrPsEaYc7rrIir/HT6C8vYQ==",
+ "license": "MIT"
+ },
+ "node_modules/vue-demi": {
+ "version": "0.14.10",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
+ "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "vue-demi-fix": "bin/vue-demi-fix.js",
+ "vue-demi-switch": "bin/vue-demi-switch.js"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.0.0-rc.1",
+ "vue": "^3.0.0-0 || ^2.6.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue-router": {
+ "version": "4.6.4",
+ "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.6.4.tgz",
+ "integrity": "sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-api": "^6.6.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/posva"
+ },
+ "peerDependencies": {
+ "vue": "^3.5.0"
+ }
+ },
+ "node_modules/vue-tsc": {
+ "version": "2.2.12",
+ "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.2.12.tgz",
+ "integrity": "sha512-P7OP77b2h/Pmk+lZdJ0YWs+5tJ6J2+uOQPo7tlBnY44QqQSPYvS0qVT4wqDJgwrZaLe47etJLLQRFia71GYITw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@volar/typescript": "2.4.15",
+ "@vue/language-core": "2.2.12"
+ },
+ "bin": {
+ "vue-tsc": "bin/vue-tsc.js"
+ },
+ "peerDependencies": {
+ "typescript": ">=5.0.0"
+ }
+ }
+ }
+}
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/package.json b/Code/WMS/WIDESEA_WMSClient_Vben/package.json
new file mode 100644
index 0000000..9dc9179
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "widesea-wms-client-vben",
+ "version": "1.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@element-plus/icons-vue": "^2.3.1",
+ "axios": "^1.6.7",
+ "element-plus": "^2.5.6",
+ "pinia": "^2.1.7",
+ "vue": "^3.4.21",
+ "vue-router": "^4.3.0"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "^5.0.4",
+ "typescript": "^5.4.2",
+ "vite": "^5.1.6",
+ "vue-tsc": "^2.0.6"
+ }
+}
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/pnpm-lock.yaml b/Code/WMS/WIDESEA_WMSClient_Vben/pnpm-lock.yaml
new file mode 100644
index 0000000..35beac5
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/pnpm-lock.yaml
@@ -0,0 +1,1297 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ dependencies:
+ '@element-plus/icons-vue':
+ specifier: ^2.3.1
+ version: 2.3.2(vue@3.5.32(typescript@5.9.3))
+ axios:
+ specifier: ^1.6.7
+ version: 1.15.0
+ element-plus:
+ specifier: ^2.5.6
+ version: 2.13.7(typescript@5.9.3)(vue@3.5.32(typescript@5.9.3))
+ pinia:
+ specifier: ^2.1.7
+ version: 2.3.1(typescript@5.9.3)(vue@3.5.32(typescript@5.9.3))
+ vue:
+ specifier: ^3.4.21
+ version: 3.5.32(typescript@5.9.3)
+ vue-router:
+ specifier: ^4.3.0
+ version: 4.6.4(vue@3.5.32(typescript@5.9.3))
+ devDependencies:
+ '@vitejs/plugin-vue':
+ specifier: ^5.0.4
+ version: 5.2.4(vite@5.4.21)(vue@3.5.32(typescript@5.9.3))
+ typescript:
+ specifier: ^5.4.2
+ version: 5.9.3
+ vite:
+ specifier: ^5.1.6
+ version: 5.4.21
+ vue-tsc:
+ specifier: ^2.0.6
+ version: 2.2.12(typescript@5.9.3)
+
+packages:
+
+ '@babel/helper-string-parser@7.27.1':
+ resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-identifier@7.28.5':
+ resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/parser@7.29.2':
+ resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/types@7.29.0':
+ resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==}
+ engines: {node: '>=6.9.0'}
+
+ '@ctrl/tinycolor@4.2.0':
+ resolution: {integrity: sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==}
+ engines: {node: '>=14'}
+
+ '@element-plus/icons-vue@2.3.2':
+ resolution: {integrity: sha512-OzIuTaIfC8QXEPmJvB4Y4kw34rSXdCJzxcD1kFStBvr8bK6X1zQAYDo0CNMjojnfTqRQCJ0I7prlErcoRiET2A==}
+ peerDependencies:
+ vue: ^3.2.0
+
+ '@esbuild/aix-ppc64@0.21.5':
+ resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.21.5':
+ resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.21.5':
+ resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.21.5':
+ resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.21.5':
+ resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.21.5':
+ resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.21.5':
+ resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.21.5':
+ resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.21.5':
+ resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.21.5':
+ resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.21.5':
+ resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.21.5':
+ resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
+ engines: {node: '>=12'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.21.5':
+ resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
+ engines: {node: '>=12'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.21.5':
+ resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.21.5':
+ resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
+ engines: {node: '>=12'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.21.5':
+ resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
+ engines: {node: '>=12'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.21.5':
+ resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-x64@0.21.5':
+ resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-x64@0.21.5':
+ resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/sunos-x64@0.21.5':
+ resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.21.5':
+ resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.21.5':
+ resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.21.5':
+ resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [win32]
+
+ '@floating-ui/core@1.7.5':
+ resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==}
+
+ '@floating-ui/dom@1.7.6':
+ resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==}
+
+ '@floating-ui/utils@0.2.11':
+ resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==}
+
+ '@jridgewell/sourcemap-codec@1.5.5':
+ resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+
+ '@rollup/rollup-android-arm-eabi@4.60.2':
+ resolution: {integrity: sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.60.2':
+ resolution: {integrity: sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-darwin-arm64@4.60.2':
+ resolution: {integrity: sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-x64@4.60.2':
+ resolution: {integrity: sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rollup/rollup-freebsd-arm64@4.60.2':
+ resolution: {integrity: sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@rollup/rollup-freebsd-x64@4.60.2':
+ resolution: {integrity: sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.60.2':
+ resolution: {integrity: sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-arm-musleabihf@4.60.2':
+ resolution: {integrity: sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==}
+ cpu: [arm]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-arm64-gnu@4.60.2':
+ resolution: {integrity: sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-arm64-musl@4.60.2':
+ resolution: {integrity: sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-loong64-gnu@4.60.2':
+ resolution: {integrity: sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==}
+ cpu: [loong64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-loong64-musl@4.60.2':
+ resolution: {integrity: sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==}
+ cpu: [loong64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-ppc64-gnu@4.60.2':
+ resolution: {integrity: sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-ppc64-musl@4.60.2':
+ resolution: {integrity: sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.60.2':
+ resolution: {integrity: sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-riscv64-musl@4.60.2':
+ resolution: {integrity: sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-s390x-gnu@4.60.2':
+ resolution: {integrity: sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-x64-gnu@4.60.2':
+ resolution: {integrity: sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-x64-musl@4.60.2':
+ resolution: {integrity: sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-openbsd-x64@4.60.2':
+ resolution: {integrity: sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@rollup/rollup-openharmony-arm64@4.60.2':
+ resolution: {integrity: sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@rollup/rollup-win32-arm64-msvc@4.60.2':
+ resolution: {integrity: sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rollup/rollup-win32-ia32-msvc@4.60.2':
+ resolution: {integrity: sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-gnu@4.60.2':
+ resolution: {integrity: sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==}
+ cpu: [x64]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-msvc@4.60.2':
+ resolution: {integrity: sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==}
+ cpu: [x64]
+ os: [win32]
+
+ '@sxzz/popperjs-es@2.11.8':
+ resolution: {integrity: sha512-wOwESXvvED3S8xBmcPWHs2dUuzrE4XiZeFu7e1hROIJkm02a49N120pmOXxY33sBb6hArItm5W5tcg1cBtV+HQ==}
+
+ '@types/estree@1.0.8':
+ resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
+
+ '@types/lodash-es@4.17.12':
+ resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==}
+
+ '@types/lodash@4.17.24':
+ resolution: {integrity: sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==}
+
+ '@types/web-bluetooth@0.0.20':
+ resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
+
+ '@vitejs/plugin-vue@5.2.4':
+ resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ peerDependencies:
+ vite: ^5.0.0 || ^6.0.0
+ vue: ^3.2.25
+
+ '@volar/language-core@2.4.15':
+ resolution: {integrity: sha512-3VHw+QZU0ZG9IuQmzT68IyN4hZNd9GchGPhbD9+pa8CVv7rnoOZwo7T8weIbrRmihqy3ATpdfXFnqRrfPVK6CA==}
+
+ '@volar/source-map@2.4.15':
+ resolution: {integrity: sha512-CPbMWlUN6hVZJYGcU/GSoHu4EnCHiLaXI9n8c9la6RaI9W5JHX+NqG+GSQcB0JdC2FIBLdZJwGsfKyBB71VlTg==}
+
+ '@volar/typescript@2.4.15':
+ resolution: {integrity: sha512-2aZ8i0cqPGjXb4BhkMsPYDkkuc2ZQ6yOpqwAuNwUoncELqoy5fRgOQtLR9gB0g902iS0NAkvpIzs27geVyVdPg==}
+
+ '@vue/compiler-core@3.5.32':
+ resolution: {integrity: sha512-4x74Tbtqnda8s/NSD6e1Dr5p1c8HdMU5RWSjMSUzb8RTcUQqevDCxVAitcLBKT+ie3o0Dl9crc/S/opJM7qBGQ==}
+
+ '@vue/compiler-dom@3.5.32':
+ resolution: {integrity: sha512-ybHAu70NtiEI1fvAUz3oXZqkUYEe5J98GjMDpTGl5iHb0T15wQYLR4wE3h9xfuTNA+Cm2f4czfe8B4s+CCH57Q==}
+
+ '@vue/compiler-sfc@3.5.32':
+ resolution: {integrity: sha512-8UYUYo71cP/0YHMO814TRZlPuUUw3oifHuMR7Wp9SNoRSrxRQnhMLNlCeaODNn6kNTJsjFoQ/kqIj4qGvya4Xg==}
+
+ '@vue/compiler-ssr@3.5.32':
+ resolution: {integrity: sha512-Gp4gTs22T3DgRotZ8aA/6m2jMR+GMztvBXUBEUOYOcST+giyGWJ4WvFd7QLHBkzTxkfOt8IELKNdpzITLbA2rw==}
+
+ '@vue/compiler-vue2@2.7.16':
+ resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==}
+
+ '@vue/devtools-api@6.6.4':
+ resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==}
+
+ '@vue/language-core@2.2.12':
+ resolution: {integrity: sha512-IsGljWbKGU1MZpBPN+BvPAdr55YPkj2nB/TBNGNC32Vy2qLG25DYu/NBN2vNtZqdRbTRjaoYrahLrToim2NanA==}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ '@vue/reactivity@3.5.32':
+ resolution: {integrity: sha512-/ORasxSGvZ6MN5gc+uE364SxFdJ0+WqVG0CENXaGW58TOCdrAW76WWaplDtECeS1qphvtBZtR+3/o1g1zL4xPQ==}
+
+ '@vue/runtime-core@3.5.32':
+ resolution: {integrity: sha512-pDrXCejn4UpFDFmMd27AcJEbHaLemaE5o4pbb7sLk79SRIhc6/t34BQA7SGNgYtbMnvbF/HHOftYBgFJtUoJUQ==}
+
+ '@vue/runtime-dom@3.5.32':
+ resolution: {integrity: sha512-1CDVv7tv/IV13V8Nip1k/aaObVbWqRlVCVezTwx3K07p7Vxossp5JU1dcPNhJk3w347gonIUT9jQOGutyJrSVQ==}
+
+ '@vue/server-renderer@3.5.32':
+ resolution: {integrity: sha512-IOjm2+JQwRFS7W28HNuJeXQle9KdZbODFY7hFGVtnnghF51ta20EWAZJHX+zLGtsHhaU6uC9BGPV52KVpYryMQ==}
+ peerDependencies:
+ vue: 3.5.32
+
+ '@vue/shared@3.5.32':
+ resolution: {integrity: sha512-ksNyrmRQzWJJ8n3cRDuSF7zNNontuJg1YHnmWRJd2AMu8Ij2bqwiiri2lH5rHtYPZjj4STkNcgcmiQqlOjiYGg==}
+
+ '@vueuse/core@12.0.0':
+ resolution: {integrity: sha512-C12RukhXiJCbx4MGhjmd/gH52TjJsc3G0E0kQj/kb19H3Nt6n1CA4DRWuTdWWcaFRdlTe0npWDS942mvacvNBw==}
+
+ '@vueuse/metadata@12.0.0':
+ resolution: {integrity: sha512-Yzimd1D3sjxTDOlF05HekU5aSGdKjxhuhRFHA7gDWLn57PRbBIh+SF5NmjhJ0WRgF3my7T8LBucyxdFJjIfRJQ==}
+
+ '@vueuse/shared@12.0.0':
+ resolution: {integrity: sha512-3i6qtcq2PIio5i/vVYidkkcgvmTjCqrf26u+Fd4LhnbBmIT6FN8y6q/GJERp8lfcB9zVEfjdV0Br0443qZuJpw==}
+
+ alien-signals@1.0.13:
+ resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==}
+
+ async-validator@4.2.5:
+ resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==}
+
+ asynckit@0.4.0:
+ resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+
+ axios@1.15.0:
+ resolution: {integrity: sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==}
+
+ balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
+ brace-expansion@2.1.0:
+ resolution: {integrity: sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==}
+
+ call-bind-apply-helpers@1.0.2:
+ resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
+ engines: {node: '>= 0.4'}
+
+ combined-stream@1.0.8:
+ resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
+ engines: {node: '>= 0.8'}
+
+ csstype@3.2.3:
+ resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
+
+ dayjs@1.11.20:
+ resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==}
+
+ de-indent@1.0.2:
+ resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
+
+ delayed-stream@1.0.0:
+ resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
+ engines: {node: '>=0.4.0'}
+
+ dunder-proto@1.0.1:
+ resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
+ engines: {node: '>= 0.4'}
+
+ element-plus@2.13.7:
+ resolution: {integrity: sha512-XdHATFZOyzVFL1DaHQ90IOJQSg9UnSAV+bhDW+YB5UoZ0Hxs50mwqjqfwXkuwpSag+VXXizVcErBR6Movo5daw==}
+ peerDependencies:
+ vue: ^3.3.0
+
+ entities@7.0.1:
+ resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==}
+ engines: {node: '>=0.12'}
+
+ es-define-property@1.0.1:
+ resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
+ engines: {node: '>= 0.4'}
+
+ es-errors@1.3.0:
+ resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
+ engines: {node: '>= 0.4'}
+
+ es-object-atoms@1.1.1:
+ resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
+ engines: {node: '>= 0.4'}
+
+ es-set-tostringtag@2.1.0:
+ resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
+ engines: {node: '>= 0.4'}
+
+ esbuild@0.21.5:
+ resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==}
+ engines: {node: '>=12'}
+ hasBin: true
+
+ estree-walker@2.0.2:
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+ follow-redirects@1.16.0:
+ resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==}
+ engines: {node: '>=4.0'}
+ peerDependencies:
+ debug: '*'
+ peerDependenciesMeta:
+ debug:
+ optional: true
+
+ form-data@4.0.5:
+ resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==}
+ engines: {node: '>= 6'}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+
+ get-intrinsic@1.3.0:
+ resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
+ engines: {node: '>= 0.4'}
+
+ get-proto@1.0.1:
+ resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
+ engines: {node: '>= 0.4'}
+
+ gopd@1.2.0:
+ resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
+ engines: {node: '>= 0.4'}
+
+ has-symbols@1.1.0:
+ resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
+ engines: {node: '>= 0.4'}
+
+ has-tostringtag@1.0.2:
+ resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
+ engines: {node: '>= 0.4'}
+
+ hasown@2.0.3:
+ resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==}
+ engines: {node: '>= 0.4'}
+
+ he@1.2.0:
+ resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
+ hasBin: true
+
+ lodash-es@4.18.1:
+ resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==}
+
+ lodash-unified@1.0.3:
+ resolution: {integrity: sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==}
+ peerDependencies:
+ '@types/lodash-es': '*'
+ lodash: '*'
+ lodash-es: '*'
+
+ lodash@4.18.1:
+ resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==}
+
+ magic-string@0.30.21:
+ resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+
+ math-intrinsics@1.1.0:
+ resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
+ engines: {node: '>= 0.4'}
+
+ memoize-one@6.0.0:
+ resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==}
+
+ mime-db@1.52.0:
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@2.1.35:
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+ engines: {node: '>= 0.6'}
+
+ minimatch@9.0.9:
+ resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ muggle-string@0.4.1:
+ resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==}
+
+ nanoid@3.3.11:
+ resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ normalize-wheel-es@1.2.0:
+ resolution: {integrity: sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==}
+
+ path-browserify@1.0.1:
+ resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ pinia@2.3.1:
+ resolution: {integrity: sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==}
+ peerDependencies:
+ typescript: '>=4.4.4'
+ vue: ^2.7.0 || ^3.5.11
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ postcss@8.5.10:
+ resolution: {integrity: sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ proxy-from-env@2.1.0:
+ resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==}
+ engines: {node: '>=10'}
+
+ rollup@4.60.2:
+ resolution: {integrity: sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ typescript@5.9.3:
+ resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ vite@5.4.21:
+ resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^18.0.0 || >=20.0.0
+ less: '*'
+ lightningcss: ^1.21.0
+ sass: '*'
+ sass-embedded: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.4.0
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+
+ vscode-uri@3.1.0:
+ resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==}
+
+ vue-component-type-helpers@3.2.7:
+ resolution: {integrity: sha512-+gPp5YGmhfsj1IN+xUo7y0fb4clfnOiiUA39y07yW1VzCRjzVgwLbtmdWlghh7mXrPsEaYc7rrIir/HT6C8vYQ==}
+
+ vue-demi@0.14.10:
+ resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
+ engines: {node: '>=12'}
+ hasBin: true
+ peerDependencies:
+ '@vue/composition-api': ^1.0.0-rc.1
+ vue: ^3.0.0-0 || ^2.6.0
+ peerDependenciesMeta:
+ '@vue/composition-api':
+ optional: true
+
+ vue-router@4.6.4:
+ resolution: {integrity: sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==}
+ peerDependencies:
+ vue: ^3.5.0
+
+ vue-tsc@2.2.12:
+ resolution: {integrity: sha512-P7OP77b2h/Pmk+lZdJ0YWs+5tJ6J2+uOQPo7tlBnY44QqQSPYvS0qVT4wqDJgwrZaLe47etJLLQRFia71GYITw==}
+ hasBin: true
+ peerDependencies:
+ typescript: '>=5.0.0'
+
+ vue@3.5.32:
+ resolution: {integrity: sha512-vM4z4Q9tTafVfMAK7IVzmxg34rSzTFMyIe0UUEijUCkn9+23lj0WRfA83dg7eQZIUlgOSGrkViIaCfqSAUXsMw==}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+snapshots:
+
+ '@babel/helper-string-parser@7.27.1': {}
+
+ '@babel/helper-validator-identifier@7.28.5': {}
+
+ '@babel/parser@7.29.2':
+ dependencies:
+ '@babel/types': 7.29.0
+
+ '@babel/types@7.29.0':
+ dependencies:
+ '@babel/helper-string-parser': 7.27.1
+ '@babel/helper-validator-identifier': 7.28.5
+
+ '@ctrl/tinycolor@4.2.0': {}
+
+ '@element-plus/icons-vue@2.3.2(vue@3.5.32(typescript@5.9.3))':
+ dependencies:
+ vue: 3.5.32(typescript@5.9.3)
+
+ '@esbuild/aix-ppc64@0.21.5':
+ optional: true
+
+ '@esbuild/android-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/android-arm@0.21.5':
+ optional: true
+
+ '@esbuild/android-x64@0.21.5':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/darwin-x64@0.21.5':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-arm@0.21.5':
+ optional: true
+
+ '@esbuild/linux-ia32@0.21.5':
+ optional: true
+
+ '@esbuild/linux-loong64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.21.5':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-s390x@0.21.5':
+ optional: true
+
+ '@esbuild/linux-x64@0.21.5':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/sunos-x64@0.21.5':
+ optional: true
+
+ '@esbuild/win32-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/win32-ia32@0.21.5':
+ optional: true
+
+ '@esbuild/win32-x64@0.21.5':
+ optional: true
+
+ '@floating-ui/core@1.7.5':
+ dependencies:
+ '@floating-ui/utils': 0.2.11
+
+ '@floating-ui/dom@1.7.6':
+ dependencies:
+ '@floating-ui/core': 1.7.5
+ '@floating-ui/utils': 0.2.11
+
+ '@floating-ui/utils@0.2.11': {}
+
+ '@jridgewell/sourcemap-codec@1.5.5': {}
+
+ '@rollup/rollup-android-arm-eabi@4.60.2':
+ optional: true
+
+ '@rollup/rollup-android-arm64@4.60.2':
+ optional: true
+
+ '@rollup/rollup-darwin-arm64@4.60.2':
+ optional: true
+
+ '@rollup/rollup-darwin-x64@4.60.2':
+ optional: true
+
+ '@rollup/rollup-freebsd-arm64@4.60.2':
+ optional: true
+
+ '@rollup/rollup-freebsd-x64@4.60.2':
+ optional: true
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.60.2':
+ optional: true
+
+ '@rollup/rollup-linux-arm-musleabihf@4.60.2':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-gnu@4.60.2':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-musl@4.60.2':
+ optional: true
+
+ '@rollup/rollup-linux-loong64-gnu@4.60.2':
+ optional: true
+
+ '@rollup/rollup-linux-loong64-musl@4.60.2':
+ optional: true
+
+ '@rollup/rollup-linux-ppc64-gnu@4.60.2':
+ optional: true
+
+ '@rollup/rollup-linux-ppc64-musl@4.60.2':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-gnu@4.60.2':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-musl@4.60.2':
+ optional: true
+
+ '@rollup/rollup-linux-s390x-gnu@4.60.2':
+ optional: true
+
+ '@rollup/rollup-linux-x64-gnu@4.60.2':
+ optional: true
+
+ '@rollup/rollup-linux-x64-musl@4.60.2':
+ optional: true
+
+ '@rollup/rollup-openbsd-x64@4.60.2':
+ optional: true
+
+ '@rollup/rollup-openharmony-arm64@4.60.2':
+ optional: true
+
+ '@rollup/rollup-win32-arm64-msvc@4.60.2':
+ optional: true
+
+ '@rollup/rollup-win32-ia32-msvc@4.60.2':
+ optional: true
+
+ '@rollup/rollup-win32-x64-gnu@4.60.2':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.60.2':
+ optional: true
+
+ '@sxzz/popperjs-es@2.11.8': {}
+
+ '@types/estree@1.0.8': {}
+
+ '@types/lodash-es@4.17.12':
+ dependencies:
+ '@types/lodash': 4.17.24
+
+ '@types/lodash@4.17.24': {}
+
+ '@types/web-bluetooth@0.0.20': {}
+
+ '@vitejs/plugin-vue@5.2.4(vite@5.4.21)(vue@3.5.32(typescript@5.9.3))':
+ dependencies:
+ vite: 5.4.21
+ vue: 3.5.32(typescript@5.9.3)
+
+ '@volar/language-core@2.4.15':
+ dependencies:
+ '@volar/source-map': 2.4.15
+
+ '@volar/source-map@2.4.15': {}
+
+ '@volar/typescript@2.4.15':
+ dependencies:
+ '@volar/language-core': 2.4.15
+ path-browserify: 1.0.1
+ vscode-uri: 3.1.0
+
+ '@vue/compiler-core@3.5.32':
+ dependencies:
+ '@babel/parser': 7.29.2
+ '@vue/shared': 3.5.32
+ entities: 7.0.1
+ estree-walker: 2.0.2
+ source-map-js: 1.2.1
+
+ '@vue/compiler-dom@3.5.32':
+ dependencies:
+ '@vue/compiler-core': 3.5.32
+ '@vue/shared': 3.5.32
+
+ '@vue/compiler-sfc@3.5.32':
+ dependencies:
+ '@babel/parser': 7.29.2
+ '@vue/compiler-core': 3.5.32
+ '@vue/compiler-dom': 3.5.32
+ '@vue/compiler-ssr': 3.5.32
+ '@vue/shared': 3.5.32
+ estree-walker: 2.0.2
+ magic-string: 0.30.21
+ postcss: 8.5.10
+ source-map-js: 1.2.1
+
+ '@vue/compiler-ssr@3.5.32':
+ dependencies:
+ '@vue/compiler-dom': 3.5.32
+ '@vue/shared': 3.5.32
+
+ '@vue/compiler-vue2@2.7.16':
+ dependencies:
+ de-indent: 1.0.2
+ he: 1.2.0
+
+ '@vue/devtools-api@6.6.4': {}
+
+ '@vue/language-core@2.2.12(typescript@5.9.3)':
+ dependencies:
+ '@volar/language-core': 2.4.15
+ '@vue/compiler-dom': 3.5.32
+ '@vue/compiler-vue2': 2.7.16
+ '@vue/shared': 3.5.32
+ alien-signals: 1.0.13
+ minimatch: 9.0.9
+ muggle-string: 0.4.1
+ path-browserify: 1.0.1
+ optionalDependencies:
+ typescript: 5.9.3
+
+ '@vue/reactivity@3.5.32':
+ dependencies:
+ '@vue/shared': 3.5.32
+
+ '@vue/runtime-core@3.5.32':
+ dependencies:
+ '@vue/reactivity': 3.5.32
+ '@vue/shared': 3.5.32
+
+ '@vue/runtime-dom@3.5.32':
+ dependencies:
+ '@vue/reactivity': 3.5.32
+ '@vue/runtime-core': 3.5.32
+ '@vue/shared': 3.5.32
+ csstype: 3.2.3
+
+ '@vue/server-renderer@3.5.32(vue@3.5.32(typescript@5.9.3))':
+ dependencies:
+ '@vue/compiler-ssr': 3.5.32
+ '@vue/shared': 3.5.32
+ vue: 3.5.32(typescript@5.9.3)
+
+ '@vue/shared@3.5.32': {}
+
+ '@vueuse/core@12.0.0(typescript@5.9.3)':
+ dependencies:
+ '@types/web-bluetooth': 0.0.20
+ '@vueuse/metadata': 12.0.0
+ '@vueuse/shared': 12.0.0(typescript@5.9.3)
+ vue: 3.5.32(typescript@5.9.3)
+ transitivePeerDependencies:
+ - typescript
+
+ '@vueuse/metadata@12.0.0': {}
+
+ '@vueuse/shared@12.0.0(typescript@5.9.3)':
+ dependencies:
+ vue: 3.5.32(typescript@5.9.3)
+ transitivePeerDependencies:
+ - typescript
+
+ alien-signals@1.0.13: {}
+
+ async-validator@4.2.5: {}
+
+ asynckit@0.4.0: {}
+
+ axios@1.15.0:
+ dependencies:
+ follow-redirects: 1.16.0
+ form-data: 4.0.5
+ proxy-from-env: 2.1.0
+ transitivePeerDependencies:
+ - debug
+
+ balanced-match@1.0.2: {}
+
+ brace-expansion@2.1.0:
+ dependencies:
+ balanced-match: 1.0.2
+
+ call-bind-apply-helpers@1.0.2:
+ dependencies:
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+
+ combined-stream@1.0.8:
+ dependencies:
+ delayed-stream: 1.0.0
+
+ csstype@3.2.3: {}
+
+ dayjs@1.11.20: {}
+
+ de-indent@1.0.2: {}
+
+ delayed-stream@1.0.0: {}
+
+ dunder-proto@1.0.1:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-errors: 1.3.0
+ gopd: 1.2.0
+
+ element-plus@2.13.7(typescript@5.9.3)(vue@3.5.32(typescript@5.9.3)):
+ dependencies:
+ '@ctrl/tinycolor': 4.2.0
+ '@element-plus/icons-vue': 2.3.2(vue@3.5.32(typescript@5.9.3))
+ '@floating-ui/dom': 1.7.6
+ '@popperjs/core': '@sxzz/popperjs-es@2.11.8'
+ '@types/lodash': 4.17.24
+ '@types/lodash-es': 4.17.12
+ '@vueuse/core': 12.0.0(typescript@5.9.3)
+ async-validator: 4.2.5
+ dayjs: 1.11.20
+ lodash: 4.18.1
+ lodash-es: 4.18.1
+ lodash-unified: 1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.18.1)(lodash@4.18.1)
+ memoize-one: 6.0.0
+ normalize-wheel-es: 1.2.0
+ vue: 3.5.32(typescript@5.9.3)
+ vue-component-type-helpers: 3.2.7
+ transitivePeerDependencies:
+ - typescript
+
+ entities@7.0.1: {}
+
+ es-define-property@1.0.1: {}
+
+ es-errors@1.3.0: {}
+
+ es-object-atoms@1.1.1:
+ dependencies:
+ es-errors: 1.3.0
+
+ es-set-tostringtag@2.1.0:
+ dependencies:
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ has-tostringtag: 1.0.2
+ hasown: 2.0.3
+
+ esbuild@0.21.5:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.21.5
+ '@esbuild/android-arm': 0.21.5
+ '@esbuild/android-arm64': 0.21.5
+ '@esbuild/android-x64': 0.21.5
+ '@esbuild/darwin-arm64': 0.21.5
+ '@esbuild/darwin-x64': 0.21.5
+ '@esbuild/freebsd-arm64': 0.21.5
+ '@esbuild/freebsd-x64': 0.21.5
+ '@esbuild/linux-arm': 0.21.5
+ '@esbuild/linux-arm64': 0.21.5
+ '@esbuild/linux-ia32': 0.21.5
+ '@esbuild/linux-loong64': 0.21.5
+ '@esbuild/linux-mips64el': 0.21.5
+ '@esbuild/linux-ppc64': 0.21.5
+ '@esbuild/linux-riscv64': 0.21.5
+ '@esbuild/linux-s390x': 0.21.5
+ '@esbuild/linux-x64': 0.21.5
+ '@esbuild/netbsd-x64': 0.21.5
+ '@esbuild/openbsd-x64': 0.21.5
+ '@esbuild/sunos-x64': 0.21.5
+ '@esbuild/win32-arm64': 0.21.5
+ '@esbuild/win32-ia32': 0.21.5
+ '@esbuild/win32-x64': 0.21.5
+
+ estree-walker@2.0.2: {}
+
+ follow-redirects@1.16.0: {}
+
+ form-data@4.0.5:
+ dependencies:
+ asynckit: 0.4.0
+ combined-stream: 1.0.8
+ es-set-tostringtag: 2.1.0
+ hasown: 2.0.3
+ mime-types: 2.1.35
+
+ fsevents@2.3.3:
+ optional: true
+
+ function-bind@1.1.2: {}
+
+ get-intrinsic@1.3.0:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-define-property: 1.0.1
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.1
+ function-bind: 1.1.2
+ get-proto: 1.0.1
+ gopd: 1.2.0
+ has-symbols: 1.1.0
+ hasown: 2.0.3
+ math-intrinsics: 1.1.0
+
+ get-proto@1.0.1:
+ dependencies:
+ dunder-proto: 1.0.1
+ es-object-atoms: 1.1.1
+
+ gopd@1.2.0: {}
+
+ has-symbols@1.1.0: {}
+
+ has-tostringtag@1.0.2:
+ dependencies:
+ has-symbols: 1.1.0
+
+ hasown@2.0.3:
+ dependencies:
+ function-bind: 1.1.2
+
+ he@1.2.0: {}
+
+ lodash-es@4.18.1: {}
+
+ lodash-unified@1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.18.1)(lodash@4.18.1):
+ dependencies:
+ '@types/lodash-es': 4.17.12
+ lodash: 4.18.1
+ lodash-es: 4.18.1
+
+ lodash@4.18.1: {}
+
+ magic-string@0.30.21:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ math-intrinsics@1.1.0: {}
+
+ memoize-one@6.0.0: {}
+
+ mime-db@1.52.0: {}
+
+ mime-types@2.1.35:
+ dependencies:
+ mime-db: 1.52.0
+
+ minimatch@9.0.9:
+ dependencies:
+ brace-expansion: 2.1.0
+
+ muggle-string@0.4.1: {}
+
+ nanoid@3.3.11: {}
+
+ normalize-wheel-es@1.2.0: {}
+
+ path-browserify@1.0.1: {}
+
+ picocolors@1.1.1: {}
+
+ pinia@2.3.1(typescript@5.9.3)(vue@3.5.32(typescript@5.9.3)):
+ dependencies:
+ '@vue/devtools-api': 6.6.4
+ vue: 3.5.32(typescript@5.9.3)
+ vue-demi: 0.14.10(vue@3.5.32(typescript@5.9.3))
+ optionalDependencies:
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+
+ postcss@8.5.10:
+ dependencies:
+ nanoid: 3.3.11
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ proxy-from-env@2.1.0: {}
+
+ rollup@4.60.2:
+ dependencies:
+ '@types/estree': 1.0.8
+ optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.60.2
+ '@rollup/rollup-android-arm64': 4.60.2
+ '@rollup/rollup-darwin-arm64': 4.60.2
+ '@rollup/rollup-darwin-x64': 4.60.2
+ '@rollup/rollup-freebsd-arm64': 4.60.2
+ '@rollup/rollup-freebsd-x64': 4.60.2
+ '@rollup/rollup-linux-arm-gnueabihf': 4.60.2
+ '@rollup/rollup-linux-arm-musleabihf': 4.60.2
+ '@rollup/rollup-linux-arm64-gnu': 4.60.2
+ '@rollup/rollup-linux-arm64-musl': 4.60.2
+ '@rollup/rollup-linux-loong64-gnu': 4.60.2
+ '@rollup/rollup-linux-loong64-musl': 4.60.2
+ '@rollup/rollup-linux-ppc64-gnu': 4.60.2
+ '@rollup/rollup-linux-ppc64-musl': 4.60.2
+ '@rollup/rollup-linux-riscv64-gnu': 4.60.2
+ '@rollup/rollup-linux-riscv64-musl': 4.60.2
+ '@rollup/rollup-linux-s390x-gnu': 4.60.2
+ '@rollup/rollup-linux-x64-gnu': 4.60.2
+ '@rollup/rollup-linux-x64-musl': 4.60.2
+ '@rollup/rollup-openbsd-x64': 4.60.2
+ '@rollup/rollup-openharmony-arm64': 4.60.2
+ '@rollup/rollup-win32-arm64-msvc': 4.60.2
+ '@rollup/rollup-win32-ia32-msvc': 4.60.2
+ '@rollup/rollup-win32-x64-gnu': 4.60.2
+ '@rollup/rollup-win32-x64-msvc': 4.60.2
+ fsevents: 2.3.3
+
+ source-map-js@1.2.1: {}
+
+ typescript@5.9.3: {}
+
+ vite@5.4.21:
+ dependencies:
+ esbuild: 0.21.5
+ postcss: 8.5.10
+ rollup: 4.60.2
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ vscode-uri@3.1.0: {}
+
+ vue-component-type-helpers@3.2.7: {}
+
+ vue-demi@0.14.10(vue@3.5.32(typescript@5.9.3)):
+ dependencies:
+ vue: 3.5.32(typescript@5.9.3)
+
+ vue-router@4.6.4(vue@3.5.32(typescript@5.9.3)):
+ dependencies:
+ '@vue/devtools-api': 6.6.4
+ vue: 3.5.32(typescript@5.9.3)
+
+ vue-tsc@2.2.12(typescript@5.9.3):
+ dependencies:
+ '@volar/typescript': 2.4.15
+ '@vue/language-core': 2.2.12(typescript@5.9.3)
+ typescript: 5.9.3
+
+ vue@3.5.32(typescript@5.9.3):
+ dependencies:
+ '@vue/compiler-dom': 3.5.32
+ '@vue/compiler-sfc': 3.5.32
+ '@vue/runtime-dom': 3.5.32
+ '@vue/server-renderer': 3.5.32(vue@3.5.32(typescript@5.9.3))
+ '@vue/shared': 3.5.32
+ optionalDependencies:
+ typescript: 5.9.3
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/App.vue b/Code/WMS/WIDESEA_WMSClient_Vben/src/App.vue
new file mode 100644
index 0000000..1dd8312
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/App.vue
@@ -0,0 +1,27 @@
+<template>
+ <router-view />
+</template>
+
+<script setup lang="ts">
+import { onMounted } from 'vue';
+
+onMounted(() => {
+ console.log('WMS Vben Admin App mounted');
+});
+</script>
+
+<style>
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+html,
+body,
+#app {
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+}
+</style>
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/api/auth.ts b/Code/WMS/WIDESEA_WMSClient_Vben/src/api/auth.ts
new file mode 100644
index 0000000..d3a04a7
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/api/auth.ts
@@ -0,0 +1,50 @@
+import axios from 'axios';
+import type { AxiosInstance, AxiosResponse } from 'axios';
+
+const baseURL = import.meta.env.VITE_APP_API_URL || 'http://localhost:9291';
+
+const http: AxiosInstance = axios.create({
+ baseURL,
+ timeout: 30000,
+});
+
+http.interceptors.request.use(
+ (config) => {
+ const token = localStorage.getItem('token');
+ if (token) {
+ config.headers.Authorization = `Bearer ${token}`;
+ }
+ return config;
+ },
+ (error) => Promise.reject(error)
+);
+
+http.interceptors.response.use(
+ (response: AxiosResponse) => response.data,
+ (error) => {
+ if (error.response?.status === 401) {
+ localStorage.removeItem('token');
+ window.location.href = '/login';
+ }
+ return Promise.reject(error);
+ }
+);
+
+export interface LoginRequest {
+ username: string;
+ password: string;
+}
+
+export interface LoginResponse {
+ success: boolean;
+ message?: string;
+ data?: {
+ token: string;
+ };
+}
+
+export const login = (data: LoginRequest): Promise<LoginResponse> => {
+ return http.post('/api/Login', data);
+};
+
+export default http;
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/api/client.ts b/Code/WMS/WIDESEA_WMSClient_Vben/src/api/client.ts
new file mode 100644
index 0000000..4743309
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/api/client.ts
@@ -0,0 +1,56 @@
+/**
+ * axios 瀹㈡埛绔皝瑁�
+ * 缁熶竴閰嶇疆锛歜aseURL銆乼imeout銆佽姹�/鍝嶅簲鎷︽埅鍣�
+ */
+import axios from 'axios';
+import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
+
+const BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:9291';
+
+/** 鍒涘缓 axios 瀹炰緥 */
+const client: AxiosInstance = axios.create({
+ baseURL: BASE_URL,
+ timeout: 30000,
+ headers: { 'Content-Type': 'application/json' },
+});
+
+let isRefreshing = false;
+let refreshQueue: Array<(token?: string) => void> = [];
+
+/** 璇锋眰鎷︽埅鍣細娉ㄥ叆 Bearer Token */
+client.interceptors.request.use(
+ (config: InternalAxiosRequestConfig) => {
+ const userStr = localStorage.getItem('user');
+ if (userStr) {
+ try {
+ const userData = JSON.parse(userStr);
+ if (userData.token) {
+ config.headers.Authorization = `Bearer ${userData.token}`;
+ }
+ } catch {}
+ }
+ return config;
+ },
+ (error) => Promise.reject(error)
+);
+
+/** 鍝嶅簲鎷︽埅鍣細缁熶竴閿欒澶勭悊 + 401 Token 杩囨湡璺宠浆鐧诲綍 */
+client.interceptors.response.use(
+ (response: AxiosResponse) => response.data,
+ async (error) => {
+ const status = error.response?.status;
+ const data = error.response?.data;
+
+ // 401 鏈巿鏉�
+ if (status === 401 || data?.code === 401) {
+ localStorage.removeItem('user');
+ window.location.href = '/#/login';
+ return Promise.reject(error);
+ }
+
+ return Promise.reject(error);
+ }
+);
+
+export { client };
+export type { AxiosRequestConfig };
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/api/index.ts b/Code/WMS/WIDESEA_WMSClient_Vben/src/api/index.ts
new file mode 100644
index 0000000..1db51da
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/api/index.ts
@@ -0,0 +1,6 @@
+export { client } from './client';
+export { userApi } from './modules/user';
+export { menuApi } from './modules/menu';
+export { stockApi } from './modules/stock';
+export { inboundApi } from './modules/inbound';
+export { outboundApi } from './modules/outbound';
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/inbound.ts b/Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/inbound.ts
new file mode 100644
index 0000000..f33daec
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/inbound.ts
@@ -0,0 +1,6 @@
+import { client } from '../client';
+
+export const inboundApi = {
+ getPageList: (params: any) => client.get('/api/InboundOrder/getPageList', { params }),
+ getDetail: (id: number) => client.get(`/api/InboundOrderDetail/${id}`),
+};
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/menu.ts b/Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/menu.ts
new file mode 100644
index 0000000..3d181d0
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/menu.ts
@@ -0,0 +1,28 @@
+/**
+ * 鑿滃崟 API 妯″潡
+ * 瀵规帴 WMS 鍚庣 /api/Sys_Menu/getTreeMenu 鎺ュ彛
+ */
+import { client } from '../client';
+
+/** 鍚庣杩斿洖鐨勮彍鍗曡妭鐐� */
+export interface BackendMenuNode {
+ id: string | number;
+ name?: string;
+ text?: string;
+ url?: string;
+ path?: string;
+ icon?: string;
+ children?: BackendMenuNode[];
+ [key: string]: unknown;
+}
+
+export const menuApi = {
+ /**
+ * 鑾峰彇鏍戝舰鑿滃崟
+ * GET /api/Sys_Menu/getTreeMenu
+ */
+ getTreeMenu: async (): Promise<BackendMenuNode[]> => {
+ const res = await client.get('/api/Sys_Menu/getTreeMenu');
+ return res || [];
+ },
+};
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/outbound.ts b/Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/outbound.ts
new file mode 100644
index 0000000..100f1ef
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/outbound.ts
@@ -0,0 +1,6 @@
+import { client } from '../client';
+
+export const outboundApi = {
+ getPageList: (params: any) => client.get('/api/OutboundOrder/getPageList', { params }),
+ getDetail: (id: number) => client.get(`/api/OutboundOrderDetail/${id}`),
+};
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/stock.ts b/Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/stock.ts
new file mode 100644
index 0000000..aa3c9dd
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/stock.ts
@@ -0,0 +1,6 @@
+import { client } from '../client';
+
+export const stockApi = {
+ getPageList: (params: any) => client.get('/api/StockInfo/getDetailPageList', { params }),
+ getDetail: (id: number) => client.get(`/api/StockInfoDetail/${id}`),
+};
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/user.ts b/Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/user.ts
new file mode 100644
index 0000000..394b60c
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/api/modules/user.ts
@@ -0,0 +1,8 @@
+import { client } from '../client';
+
+export const userApi = {
+ getCaptcha: () => client.get('/api/User/getVierificationCode'),
+ login: (params: any) => client.post('/api/User/login', params),
+ getCurrentUser: () => client.post('/api/User/getCurrentUserInfo'),
+ replaceToken: () => client.post('/api/User/replaceToken'),
+};
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/layouts/MainLayout.vue b/Code/WMS/WIDESEA_WMSClient_Vben/src/layouts/MainLayout.vue
new file mode 100644
index 0000000..fa5bab6
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/layouts/MainLayout.vue
@@ -0,0 +1,158 @@
+<template>
+ <el-container class="main-layout">
+ <el-aside :width="collapsed ? '64px' : '200px'">
+ <div class="logo" @click="collapsed = !collapsed">
+ <span v-if="!collapsed">WMS绠$悊绯荤粺</span>
+ <span v-else>W</span>
+ </div>
+ <el-scrollbar>
+ <el-menu
+ :default-active="activeMenu"
+ class="el-menu-vertical"
+ :collapse="collapsed"
+ :router="true"
+ @select="handleMenuSelect"
+ >
+ <template v-for="item in menuList" :key="item.id">
+ <el-sub-menu v-if="item.children?.length" :index="String(item.id)">
+ <template #title>
+ <span>{{ item.name || item.text }}</span>
+ </template>
+ <el-menu-item
+ v-for="child in item.children"
+ :key="child.id"
+ :index="child.path || String(child.id)"
+ >
+ <span>{{ child.name || child.text }}</span>
+ </el-menu-item>
+ </el-sub-menu>
+ <el-menu-item v-else :index="item.path || String(item.id)">
+ <span>{{ item.name || item.text }}</span>
+ </el-menu-item>
+ </template>
+ </el-menu>
+ </el-scrollbar>
+ </el-aside>
+ <el-container>
+ <el-header>
+ <div class="header-left">
+ <span class="project-title">WIDESEA WMS</span>
+ </div>
+ <div class="header-right">
+ <span class="username">{{ username }}</span>
+ <el-button link @click="handleLogout">閫�鍑�</el-button>
+ </div>
+ </el-header>
+ <el-main>
+ <router-view />
+ </el-main>
+ </el-container>
+ </el-container>
+</template>
+
+<script setup lang="ts">
+import { ref, computed, onMounted } from 'vue';
+import { useRoute, useRouter } from 'vue-router';
+import { useMenuStore } from '@/store/modules/menu';
+import { ElMessage } from 'element-plus';
+
+const route = useRoute();
+const router = useRouter();
+const menuStore = useMenuStore();
+
+const collapsed = ref(false);
+const menuList = ref<any[]>([]);
+
+const username = computed(() => {
+ const userStr = localStorage.getItem('user');
+ if (userStr) {
+ try {
+ const user = JSON.parse(userStr);
+ return user.userTrueName || user.userName || '鏈櫥褰�';
+ } catch {}
+ }
+ return '鏈櫥褰�';
+});
+
+const activeMenu = computed(() => route.path);
+
+function handleMenuSelect(index: string) {
+ const menu = menuStore.findMenuByPath(index);
+ if (menu?.path) {
+ router.push(menu.path);
+ }
+}
+
+async function loadMenus() {
+ try {
+ const menus = await menuStore.loadMenus();
+ menuList.value = menus || [];
+ } catch (error) {
+ console.error('鍔犺浇鑿滃崟澶辫触:', error);
+ ElMessage.error('鍔犺浇鑿滃崟澶辫触');
+ }
+}
+
+function handleLogout() {
+ localStorage.removeItem('user');
+ menuStore.resetMenus();
+ router.push('/login');
+}
+
+onMounted(() => {
+ loadMenus();
+});
+</script>
+
+<style scoped>
+.main-layout {
+ height: 100%;
+}
+.el-aside {
+ background-color: #304156;
+ color: #fff;
+ transition: width 0.3s;
+}
+.logo {
+ height: 60px;
+ line-height: 60px;
+ text-align: center;
+ font-size: 18px;
+ color: #fff;
+ cursor: pointer;
+ background-color: #263445;
+}
+.el-menu-vertical {
+ border-right: none;
+ background-color: transparent;
+}
+.el-menu-vertical:not(.el-menu--collapse) {
+ width: 200px;
+}
+.el-header {
+ background-color: #fff;
+ box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
+ line-height: 60px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0 20px;
+}
+.project-title {
+ font-weight: 600;
+ font-size: 16px;
+ color: #333;
+}
+.header-right {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+}
+.username {
+ color: #666;
+}
+.el-main {
+ background-color: #f0f2f5;
+ padding: 16px;
+}
+</style>
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/locales/zh-CN.ts b/Code/WMS/WIDESEA_WMSClient_Vben/src/locales/zh-CN.ts
new file mode 100644
index 0000000..5e1c2ea
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/locales/zh-CN.ts
@@ -0,0 +1,21 @@
+export default {
+ common: {
+ ok: '纭畾',
+ cancel: '鍙栨秷',
+ save: '淇濆瓨',
+ delete: '鍒犻櫎',
+ edit: '缂栬緫',
+ add: '鏂板',
+ search: '鎼滅储',
+ reset: '閲嶇疆',
+ },
+ login: {
+ title: 'WMS绠$悊绯荤粺',
+ username: '鐢ㄦ埛鍚�',
+ password: '瀵嗙爜',
+ loginBtn: '鐧诲綍',
+ },
+ menu: {
+ dashboard: '棣栭〉',
+ },
+};
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/main.ts b/Code/WMS/WIDESEA_WMSClient_Vben/src/main.ts
new file mode 100644
index 0000000..9d96edf
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/main.ts
@@ -0,0 +1,15 @@
+import { createApp } from 'vue';
+import { createPinia } from 'pinia';
+import ElementPlus from 'element-plus';
+import 'element-plus/dist/index.css';
+import App from './App.vue';
+import router from './router';
+
+const app = createApp(App);
+const pinia = createPinia();
+
+app.use(pinia);
+app.use(router);
+app.use(ElementPlus);
+
+app.mount('#app');
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/router/index.ts b/Code/WMS/WIDESEA_WMSClient_Vben/src/router/index.ts
new file mode 100644
index 0000000..9a71d7d
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/router/index.ts
@@ -0,0 +1,81 @@
+/**
+ * 璺敱閰嶇疆
+ * 鏀寔鍔ㄦ�佽彍鍗曡矾鐢辨敞鍐�
+ */
+import { createRouter, createWebHashHistory } from 'vue-router';
+import type { RouteRecordRaw } from 'vue-router';
+import { useMenuStore } from '@/store/modules/menu';
+import { transformMenuToRoutes } from '@/utils/menuTransform';
+
+const routes: RouteRecordRaw[] = [
+ {
+ path: '/login',
+ name: 'Login',
+ component: () => import('@/views/login/index.vue'),
+ meta: { anonymous: true },
+ },
+ {
+ path: '/',
+ name: 'root',
+ component: () => import('@/layouts/MainLayout.vue'),
+ redirect: '/home',
+ children: [
+ { path: '/home', name: 'Home', component: () => import('@/views/dashboard/index.vue'), meta: { title: '棣栭〉', icon: 'el-icon-home' } },
+ ],
+ },
+ { path: '/:pathMatch(.*)*', redirect: '/home' },
+];
+
+const router = createRouter({
+ history: createWebHashHistory(),
+ routes,
+});
+
+/**
+ * 鍔ㄦ�佹敞鍐岃矾鐢�
+ */
+export async function registerDynamicRoutes() {
+ const menuStore = useMenuStore();
+
+ if (!menuStore.loaded) {
+ await menuStore.loadMenus();
+ }
+
+ const dynamicRoutes = transformMenuToRoutes(menuStore.menus);
+ const rootRoute = router.getRoutes().find((r) => r.name === 'root');
+ if (!rootRoute) return;
+
+ dynamicRoutes.forEach((route) => {
+ const exists = router.getRoutes().some((r) => r.name === route.name);
+ if (!exists && route.name) {
+ router.addRoute('root', route);
+ }
+ });
+
+ return dynamicRoutes;
+}
+
+router.beforeEach(async (to, from, next) => {
+ if (to.meta?.anonymous) {
+ return next();
+ }
+
+ const userStr = localStorage.getItem('user');
+ if (!userStr) {
+ return next('/login');
+ }
+
+ const menuStore = useMenuStore();
+ if (!menuStore.loaded) {
+ try {
+ await registerDynamicRoutes();
+ } catch (error) {
+ console.error('娉ㄥ唽鍔ㄦ�佽矾鐢卞け璐�:', error);
+ }
+ }
+
+ next();
+});
+
+export { router };
+export default router;
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/store/index.ts b/Code/WMS/WIDESEA_WMSClient_Vben/src/store/index.ts
new file mode 100644
index 0000000..2fcfbda
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/store/index.ts
@@ -0,0 +1,5 @@
+/**
+ * Store 缁熶竴瀵煎嚭
+ */
+export { useMenuStore } from './modules/menu';
+export { useUserStore } from './user';
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/store/modules/menu.ts b/Code/WMS/WIDESEA_WMSClient_Vben/src/store/modules/menu.ts
new file mode 100644
index 0000000..34ed521
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/store/modules/menu.ts
@@ -0,0 +1,57 @@
+/**
+ * 鑿滃崟鐘舵�佺鐞�
+ */
+import { defineStore } from 'pinia';
+import { menuApi, type BackendMenuNode } from '@/api/modules/menu';
+import { normalizeMenus, addHomeMenu } from '@/utils/menuTransform';
+
+interface MenuState {
+ menus: BackendMenuNode[];
+ loaded: boolean;
+}
+
+export const useMenuStore = defineStore('menu', {
+ state: (): MenuState => ({
+ menus: [],
+ loaded: false,
+ }),
+
+ getters: {
+ flatMenus: (state) => {
+ const flat: BackendMenuNode[] = [];
+ const flatten = (items: BackendMenuNode[]) => {
+ items.forEach((item) => {
+ flat.push(item);
+ if (item.children?.length) {
+ flatten(item.children);
+ }
+ });
+ };
+ flatten(state.menus);
+ return flat;
+ },
+ },
+
+ actions: {
+ async loadMenus() {
+ try {
+ const data = await menuApi.getTreeMenu();
+ this.menus = addHomeMenu(data || []);
+ this.loaded = true;
+ return this.menus;
+ } catch (error) {
+ console.error('鍔犺浇鑿滃崟澶辫触:', error);
+ throw error;
+ }
+ },
+
+ findMenuByPath(path: string): BackendMenuNode | null {
+ return this.flatMenus.find((m) => m.path === path) || null;
+ },
+
+ resetMenus() {
+ this.menus = [];
+ this.loaded = false;
+ },
+ },
+});
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/store/user.ts b/Code/WMS/WIDESEA_WMSClient_Vben/src/store/user.ts
new file mode 100644
index 0000000..028f1f6
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/store/user.ts
@@ -0,0 +1,43 @@
+import { defineStore } from 'pinia';
+import { ref, computed } from 'vue';
+
+interface UserInfo {
+ token: string;
+ userName: string;
+ userTrueName: string;
+ img: string;
+}
+
+export const useUserStore = defineStore('user', () => {
+ const userInfo = ref<UserInfo | null>(null);
+ const token = ref<string>('');
+ const isLogin = computed(() => !!token.value);
+
+ function init() {
+ const stored = localStorage.getItem('user');
+ if (stored) {
+ try {
+ const info = JSON.parse(stored) as UserInfo;
+ userInfo.value = info;
+ token.value = info?.token || '';
+ } catch {
+ token.value = '';
+ }
+ }
+ }
+
+ function setUserInfo(info: UserInfo) {
+ userInfo.value = info;
+ token.value = info?.token || '';
+ localStorage.setItem('user', JSON.stringify(info));
+ }
+
+ function clearUserInfo() {
+ userInfo.value = null;
+ token.value = '';
+ localStorage.removeItem('user');
+ }
+
+ init();
+ return { userInfo, token, isLogin, setUserInfo, clearUserInfo };
+});
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/utils/menuTransform.ts b/Code/WMS/WIDESEA_WMSClient_Vben/src/utils/menuTransform.ts
new file mode 100644
index 0000000..cef9744
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/utils/menuTransform.ts
@@ -0,0 +1,143 @@
+/**
+ * 鑿滃崟鏁版嵁杞崲宸ュ叿
+ * 灏嗗悗绔彍鍗曟牸寮忚浆鎹负 Vben Admin 鑿滃崟鏍煎紡
+ */
+import type { RouteRecordRaw } from 'vue-router';
+import type { BackendMenuNode } from '@/api/modules/menu';
+
+/** Element Plus 鍥炬爣鍚嶇О鏄犲皠 */
+const iconMap: Record<string, string> = {
+ 'el-icon-menu': 'Menu',
+ 'el-icon-user': 'User',
+ 'el-icon-setting': 'Setting',
+ 'el-icon-home': 'HomeFilled',
+ 'el-icon-document': 'Document',
+ 'el-icon-edit': 'Edit',
+ 'el-icon-view': 'View',
+ 'el-icon-delete': 'Delete',
+ 'el-icon-search': 'Search',
+ 'el-icon-refresh': 'Refresh',
+ 'el-icon-download': 'Download',
+ 'el-icon-upload': 'Upload',
+ 'el-icon-goods': 'Goods',
+ 'el-icon-box': 'Box',
+ 'el-icon-truck': 'Van',
+ 'el-icon-shop': 'Shop',
+ 'el-icon-list': 'List',
+ 'el-icon-grid': 'Grid',
+ 'el-icon-s-custom': 'UserFilled',
+ 'el-icon-s-order': 'List',
+ 'el-icon-s-grid': 'Grid',
+ 'el-icon-s-home': 'HomeFilled',
+ 'el-icon-s-data': 'DataLine',
+ 'el-icon-s-check': 'CircleCheck',
+ 'el-icon-s-management': 'Management',
+};
+
+/**
+ * 杞崲鍥炬爣鍚嶇О
+ * el-icon-menu -> Menu
+ */
+export function transformIcon(icon?: string): string {
+ if (!icon) return 'Menu';
+ return iconMap[icon] || 'Menu';
+}
+
+/**
+ * 鏍囧噯鍖栬彍鍗曡矾寰�
+ * "/Manager/home" -> "/home"
+ */
+export function normalizePath(url?: string): string {
+ if (!url) return '/';
+ let path = url.replace('/Manager', '') || '/';
+ if (!path.startsWith('/')) {
+ path = '/' + path;
+ }
+ return path;
+}
+
+/**
+ * 妫�鏌ユ槸鍚︿负澶栭儴閾炬帴
+ */
+function isExternalUrl(url?: string): boolean {
+ if (!url) return false;
+ return url.startsWith('http://') || url.startsWith('https://');
+}
+
+/**
+ * 灏嗗悗绔彍鍗曡妭鐐硅浆鎹负 Vben 鑿滃崟椤�
+ */
+export function transformMenuItem(menu: BackendMenuNode): RouteRecordRaw | null {
+ const name = menu.name || menu.text || '鏈懡鍚�';
+ const url = menu.url || menu.path || '';
+ const path = normalizePath(url);
+
+ // 璺宠繃澶栭儴閾炬帴
+ if (isExternalUrl(url)) {
+ return null;
+ }
+
+ const route: RouteRecordRaw = {
+ path,
+ name: path.replace(/\//g, '_').replace(/^_/, '') || 'root',
+ meta: {
+ title: name,
+ icon: menu.icon || 'el-icon-menu',
+ },
+ };
+
+ // 閫掑綊澶勭悊瀛愯彍鍗�
+ if (menu.children?.length) {
+ const children = menu.children
+ .map((child) => transformMenuItem(child))
+ .filter((r): r is RouteRecordRaw => r !== null);
+ if (children.length > 0) {
+ route.children = children;
+ }
+ }
+
+ return route;
+}
+
+/**
+ * 灏嗗悗绔彍鍗曟暟缁勮浆鎹负璺敱鏁扮粍
+ */
+export function transformMenuToRoutes(menus: BackendMenuNode[]): RouteRecordRaw[] {
+ const routes: RouteRecordRaw[] = [];
+
+ menus.forEach((menu) => {
+ const route = transformMenuItem(menu);
+ if (route) {
+ routes.push(route);
+ }
+ });
+
+ return routes;
+}
+
+/**
+ * 灏嗗悗绔彍鍗曟暟缁勬爣鍑嗗寲
+ */
+export function normalizeMenus(menus: BackendMenuNode[]): BackendMenuNode[] {
+ return menus.map((menu) => ({
+ ...menu,
+ path: normalizePath(menu.url || menu.path),
+ icon: menu.icon || 'el-icon-menu',
+ children: menu.children ? normalizeMenus(menu.children) : undefined,
+ }));
+}
+
+/**
+ * 涓鸿彍鍗曞垪琛ㄦ坊鍔犻椤甸」
+ */
+export function addHomeMenu(menus: BackendMenuNode[]): BackendMenuNode[] {
+ const normalized = normalizeMenus(menus);
+ normalized.push({
+ id: 'home',
+ name: '棣栭〉',
+ text: '棣栭〉',
+ path: '/home',
+ icon: 'el-icon-home',
+ });
+ return normalized;
+}
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/views/dashboard/index.vue b/Code/WMS/WIDESEA_WMSClient_Vben/src/views/dashboard/index.vue
new file mode 100644
index 0000000..1745f6a
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/views/dashboard/index.vue
@@ -0,0 +1,47 @@
+<template>
+ <div class="dashboard">
+ <h1>娆㈣繋浣跨敤WMS绠$悊绯荤粺</h1>
+ <el-row :gutter="20">
+ <el-col :span="6">
+ <el-card>
+ <template #header>鎬诲簱瀛�</template>
+ <div class="stat-value">10,000</div>
+ </el-card>
+ </el-col>
+ <el-col :span="6">
+ <el-card>
+ <template #header>浠婃棩鍏ュ簱</template>
+ <div class="stat-value">150</div>
+ </el-card>
+ </el-col>
+ <el-col :span="6">
+ <el-card>
+ <template #header>浠婃棩鍑哄簱</template>
+ <div class="stat-value">120</div>
+ </el-card>
+ </el-col>
+ <el-col :span="6">
+ <el-card>
+ <template #header>寰呭鐞嗕换鍔�</template>
+ <div class="stat-value">25</div>
+ </el-card>
+ </el-col>
+ </el-row>
+ </div>
+</template>
+
+<script setup lang="ts">
+</script>
+
+<style scoped>
+.dashboard h1 {
+ margin-bottom: 20px;
+ color: #333;
+}
+.stat-value {
+ font-size: 28px;
+ font-weight: bold;
+ text-align: center;
+ color: #409eff;
+}
+</style>
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/views/inbound/inboundOrderDetail.vue b/Code/WMS/WIDESEA_WMSClient_Vben/src/views/inbound/inboundOrderDetail.vue
new file mode 100644
index 0000000..4f5ae51
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/views/inbound/inboundOrderDetail.vue
@@ -0,0 +1,105 @@
+<template>
+ <div class="inbound-detail-page">
+ <el-card shadow="never">
+ <template #header>
+ <span>鍏ュ簱鍗曟槑缁� - {{ route.query.inboundOrderNo || '' }}</span>
+ </template>
+
+ <el-form :inline="true" :model="queryForm" class="search-form">
+ <el-form-item label="鐗╂枡缂栧彿">
+ <el-input v-model="queryForm.materielCode" placeholder="璇疯緭鍏ョ墿鏂欑紪鍙�" clearable />
+ </el-form-item>
+ <el-form-item label="鐗╂枡鍚嶇О">
+ <el-input v-model="queryForm.materielName" placeholder="璇疯緭鍏ョ墿鏂欏悕绉�" clearable />
+ </el-form-item>
+ <el-form-item label="鎵规鍙�">
+ <el-input v-model="queryForm.batchNo" placeholder="璇疯緭鍏ユ壒娆″彿" clearable />
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary" @click="handleSearch">鏌ヨ</el-button>
+ <el-button @click="handleReset">閲嶇疆</el-button>
+ </el-form-item>
+ </el-form>
+
+ <el-table v-loading="loading" :data="tableData" border stripe>
+ <el-table-column prop="materielCode" label="鐗╂枡缂栧彿" min-width="150" show-overflow-tooltip />
+ <el-table-column prop="materielName" label="鐗╂枡鍚嶇О" min-width="160" show-overflow-tooltip />
+ <el-table-column prop="batchNo" label="鎵规鍙�" min-width="120" align="center" />
+ <el-table-column prop="orderQuantity" label="鍗曟嵁鏁伴噺" min-width="100" align="center" />
+ <el-table-column prop="receiptQuantity" label="缁勭洏鏁伴噺" min-width="120" align="center" />
+ <el-table-column prop="overInQuantity" label="涓婃灦鏁伴噺" min-width="120" align="center" />
+ <el-table-column prop="orderDetailStatus" label="鏄庣粏鐘舵��" min-width="110" align="center">
+ <template #default="{ row }">
+ {{ getDetailStatusText(row.orderDetailStatus) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="creater" label="鍒涘缓浜�" min-width="90" align="center" />
+ <el-table-column prop="createDate" label="鍒涘缓鏃堕棿" min-width="160" align="center" />
+ </el-table>
+
+ <el-pagination
+ v-model:current-page="pagination.page"
+ v-model:page-size="pagination.pageSize"
+ :total="pagination.total"
+ :page-sizes="[10, 20, 50, 100]"
+ layout="total, sizes, prev, pager, next, jumper"
+ @size-change="handleSizeChange"
+ @current-change="handlePageChange"
+ style="margin-top: 16px; justify-content: flex-end"
+ />
+ </el-card>
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from 'vue';
+import { useRoute } from 'vue-router';
+import { ElMessage } from 'element-plus';
+import { client } from '@/api/client';
+
+const route = useRoute();
+const loading = ref(false);
+const tableData = ref([]);
+const detailStatusOptions = ref([]);
+
+const queryForm = reactive({ materielCode: '', materielName: '', batchNo: '' });
+const pagination = reactive({ page: 1, pageSize: 20, total: 0 });
+
+async function loadData() {
+ loading.value = true;
+ try {
+ const orderId = route.query.id;
+ const wheres = [{ name: 'orderId', value: String(orderId), displayType: 'int' }];
+ if (queryForm.materielCode) wheres.push({ name: 'materielCode', value: queryForm.materielCode, displayType: 'like' });
+ if (queryForm.materielName) wheres.push({ name: 'materielName', value: queryForm.materielName, displayType: 'like' });
+ if (queryForm.batchNo) wheres.push({ name: 'batchNo', value: queryForm.batchNo, displayType: 'like' });
+ const res = await client.post('/api/InboundOrderDetail/getPageList', {
+ page: pagination.page, rows: pagination.pageSize, sort: 'id', order: 'asc',
+ wheres: JSON.stringify(wheres),
+ });
+ tableData.value = res?.rows || [];
+ pagination.total = res?.total || 0;
+ } catch { ElMessage.error('鍔犺浇鏁版嵁澶辫触'); }
+ finally { loading.value = false; }
+}
+
+async function loadDictionary() {
+ try {
+ const res = await client.post('/api/Sys_Dictionary/GetVueDictionary', ['orderDetailStatusEnum']);
+ detailStatusOptions.value = res?.find(item => item.dicNo === 'orderDetailStatusEnum')?.data || [];
+ } catch { detailStatusOptions.value = []; }
+}
+
+function handleSearch() { pagination.page = 1; loadData(); }
+function handleReset() { queryForm.materielCode = ''; queryForm.materielName = ''; queryForm.batchNo = ''; handleSearch(); }
+function handleSizeChange() { loadData(); }
+function handlePageChange() { loadData(); }
+const getDetailStatusText = (val) => detailStatusOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
+
+onMounted(() => { loadDictionary(); loadData(); });
+</script>
+
+<style scoped>
+.inbound-detail-page { padding: 16px; }
+.search-form { margin-bottom: 12px; }
+</style>
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/views/inbound/index.vue b/Code/WMS/WIDESEA_WMSClient_Vben/src/views/inbound/index.vue
new file mode 100644
index 0000000..e71026b
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/views/inbound/index.vue
@@ -0,0 +1,275 @@
+<template>
+ <div class="inbound-page">
+ <!-- 鎼滅储 -->
+ <el-card class="search-card" shadow="never">
+ <el-form :inline="true" :model="queryForm" label-width="90px">
+ <el-form-item label="鍗曟嵁缂栧彿">
+ <el-input v-model="queryForm.inboundOrderNo" placeholder="璇疯緭鍏ュ崟鎹紪鍙�" clearable style="width: 170px" />
+ </el-form-item>
+ <el-form-item label="涓婃父鍗曟嵁">
+ <el-input v-model="queryForm.upperOrderNo" placeholder="璇疯緭鍏ヤ笂娓稿崟鎹紪鍙�" clearable style="width: 170px" />
+ </el-form-item>
+ <el-form-item label="鍗曟嵁绫诲瀷">
+ <el-select v-model="queryForm.orderType" placeholder="璇烽�夋嫨" clearable style="width: 150px">
+ <el-option v-for="item in orderTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="鍗曟嵁鐘舵��">
+ <el-select v-model="queryForm.orderStatus" placeholder="璇烽�夋嫨" clearable style="width: 140px">
+ <el-option v-for="item in orderStatusOptions" :key="item.key" :label="item.value" :value="item.key" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="鍒涘缓鏃堕棿">
+ <el-date-picker v-model="queryForm.createDate" type="daterange" range-separator="鑷�" start-placeholder="寮�濮�" end-placeholder="缁撴潫" value-format="YYYY-MM-DD" />
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary" @click="handleSearch">鏌ヨ</el-button>
+ <el-button @click="handleReset">閲嶇疆</el-button>
+ </el-form-item>
+ </el-form>
+ </el-card>
+
+ <!-- 琛ㄦ牸 -->
+ <el-card class="table-card" shadow="never">
+ <div class="toolbar">
+ <el-button type="primary" @click="handleAdd">鏂板</el-button>
+ <el-button type="danger" :disabled="!selectedRows.length" @click="handleBatchDelete">鎵归噺鍒犻櫎</el-button>
+ </div>
+
+ <el-table v-loading="loading" :data="tableData" border stripe @selection-change="handleSelectionChange">
+ <el-table-column type="selection" width="50" align="center" />
+ <el-table-column prop="inboundOrderNo" label="鍗曟嵁缂栧彿" min-width="140" show-overflow-tooltip />
+ <el-table-column prop="upperOrderNo" label="涓婃父鍗曟嵁缂栧彿" min-width="150" show-overflow-tooltip />
+ <el-table-column prop="warehouseId" label="浠撳簱" min-width="100" align="center">
+ <template #default="{ row }">
+ {{ getWarehouseText(row.warehouseId) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="orderType" label="鍗曟嵁绫诲瀷" min-width="140" align="center">
+ <template #default="{ row }">
+ {{ getOrderTypeText(row.orderType) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="orderStatus" label="鍗曟嵁鐘舵��" min-width="100" align="center">
+ <template #default="{ row }">
+ {{ getOrderStatusText(row.orderStatus) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="createType" label="鍒涘缓鏂瑰紡" min-width="110" align="center">
+ <template #default="{ row }">
+ {{ getCreateTypeText(row.createType) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="creater" label="鍒涘缓浜�" min-width="90" align="center" />
+ <el-table-column prop="createDate" label="鍒涘缓鏃堕棿" min-width="160" align="center" />
+ <el-table-column label="鎿嶄綔" width="180" align="center" fixed="right">
+ <template #default="{ row }">
+ <el-button link type="primary" size="small" @click="goDetail(row)">鏄庣粏</el-button>
+ <el-button link type="primary" size="small" @click="handleEdit(row)">缂栬緫</el-button>
+ <el-button link type="danger" size="small" @click="handleDelete(row)">鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <el-pagination
+ v-model:current-page="pagination.page"
+ v-model:page-size="pagination.pageSize"
+ :total="pagination.total"
+ :page-sizes="[10, 20, 50, 100]"
+ layout="total, sizes, prev, pager, next, jumper"
+ @size-change="handleSizeChange"
+ @current-change="handlePageChange"
+ style="margin-top: 16px; justify-content: flex-end"
+ />
+ </el-card>
+
+ <!-- 鏄庣粏鎶藉眽 -->
+ <el-drawer v-model="detailDrawerVisible" title="鍏ュ簱鍗曟槑缁�" size="70%" direction="rtl" destroy-on-close>
+ <el-table :data="detailTableData" border stripe max-height="600">
+ <el-table-column prop="materielCode" label="鐗╂枡缂栧彿" min-width="150" show-overflow-tooltip />
+ <el-table-column prop="materielName" label="鐗╂枡鍚嶇О" min-width="150" show-overflow-tooltip />
+ <el-table-column prop="batchNo" label="鎵规鍙�" min-width="120" align="center" />
+ <el-table-column prop="orderQuantity" label="鍗曟嵁鏁伴噺" min-width="100" align="center" />
+ <el-table-column prop="receiptQuantity" label="缁勭洏鏁伴噺" min-width="120" align="center" />
+ <el-table-column prop="overInQuantity" label="涓婃灦鏁伴噺" min-width="120" align="center" />
+ <el-table-column prop="orderDetailStatus" label="鏄庣粏鐘舵��" min-width="110" align="center">
+ <template #default="{ row }">
+ {{ getDetailStatusText(row.orderDetailStatus) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="creater" label="鍒涘缓浜�" min-width="90" align="center" />
+ <el-table-column prop="createDate" label="鍒涘缓鏃堕棿" min-width="160" align="center" />
+ </el-table>
+ </el-drawer>
+
+ <!-- 缂栬緫寮圭獥 -->
+ <el-dialog v-model="dialogVisible" :title="dialogTitle" width="560px" destroy-on-close>
+ <el-form :model="editForm" :rules="editRules" ref="editFormRef" label-width="100px">
+ <el-form-item label="鍗曟嵁绫诲瀷" prop="orderType">
+ <el-select v-model="editForm.orderType" placeholder="璇烽�夋嫨鍗曟嵁绫诲瀷" style="width: 100%">
+ <el-option v-for="item in orderTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="鍗曟嵁缂栧彿" prop="inboundOrderNo">
+ <el-input v-model="editForm.inboundOrderNo" placeholder="璇疯緭鍏ュ崟鎹紪鍙�" />
+ </el-form-item>
+ <el-form-item label="涓婃父鍗曟嵁">
+ <el-input v-model="editForm.upperOrderNo" placeholder="璇疯緭鍏ヤ笂娓稿崟鎹紪鍙�" />
+ </el-form-item>
+ <el-form-item label="浠撳簱" prop="warehouseId">
+ <el-select v-model="editForm.warehouseId" placeholder="璇烽�夋嫨浠撳簱" style="width: 100%">
+ <el-option v-for="item in warehouseOptions" :key="item.key" :label="item.value" :value="item.key" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="澶囨敞">
+ <el-input v-model="editForm.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉�" />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="handleSubmit" :loading="submitLoading">纭畾</el-button>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from 'vue';
+import { useRouter } from 'vue-router';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import { inboundApi } from '@/api/modules/inbound';
+import { client } from '@/api/client';
+
+const router = useRouter();
+
+// 鎼滅储
+const queryForm = reactive({ inboundOrderNo: '', upperOrderNo: '', orderType: undefined, orderStatus: undefined, createDate: '' });
+
+// 琛ㄦ牸
+const loading = ref(false);
+const tableData = ref([]);
+const selectedRows = ref([]);
+
+// 瀛楀吀
+const orderTypeOptions = ref([]);
+const orderStatusOptions = ref([]);
+const warehouseOptions = ref([]);
+const createTypeOptions = ref([]);
+const detailStatusOptions = ref([]);
+
+// 鍒嗛〉
+const pagination = reactive({ page: 1, pageSize: 20, total: 0 });
+
+// 鏄庣粏鎶藉眽
+const detailDrawerVisible = ref(false);
+const detailTableData = ref([]);
+const currentRow = ref(null);
+
+// 缂栬緫寮圭獥
+const dialogVisible = ref(false);
+const dialogTitle = ref('鏂板鍏ュ簱鍗�');
+const editFormRef = ref(null);
+const submitLoading = ref(false);
+const editForm = reactive({ id: undefined, orderType: undefined, inboundOrderNo: '', upperOrderNo: '', warehouseId: undefined, remark: '' });
+const editRules = {
+ orderType: [{ required: true, message: '璇烽�夋嫨鍗曟嵁绫诲瀷', trigger: 'change' }],
+ inboundOrderNo: [{ required: true, message: '璇疯緭鍏ュ崟鎹紪鍙�', trigger: 'blur' }],
+ warehouseId: [{ required: true, message: '璇烽�夋嫨浠撳簱', trigger: 'change' }],
+};
+
+async function loadData() {
+ loading.value = true;
+ try {
+ const wheres = [
+ queryForm.inboundOrderNo ? { name: 'inboundOrderNo', value: queryForm.inboundOrderNo, displayType: 'like' } : null,
+ queryForm.upperOrderNo ? { name: 'upperOrderNo', value: queryForm.upperOrderNo, displayType: 'like' } : null,
+ queryForm.orderType !== undefined ? { name: 'orderType', value: queryForm.orderType, displayType: 'int' } : null,
+ queryForm.orderStatus !== undefined ? { name: 'orderStatus', value: queryForm.orderStatus, displayType: 'int' } : null,
+ ].filter(Boolean);
+ const res = await inboundApi.getPageList({ page: pagination.page, rows: pagination.pageSize, sort: 'id', order: 'desc', wheres: JSON.stringify(wheres) });
+ tableData.value = res?.rows || [];
+ pagination.total = res?.total || 0;
+ } catch { ElMessage.error('鍔犺浇鏁版嵁澶辫触'); }
+ finally { loading.value = false; }
+}
+
+async function loadDetail(row) {
+ try {
+ const res = await client.post('/api/InboundOrderDetail/getPageList', {
+ page: 1, rows: 200, sort: 'id', order: 'asc',
+ wheres: JSON.stringify([{ name: 'orderId', value: row.id, displayType: 'int' }]),
+ });
+ detailTableData.value = res?.rows || [];
+ } catch { detailTableData.value = []; ElMessage.error('鍔犺浇鏄庣粏澶辫触'); }
+}
+
+async function loadDictionary() {
+ try {
+ const res = await client.post('/api/Sys_Dictionary/GetVueDictionary', ['inOrderType', 'inboundState', 'warehouses', 'createType', 'orderDetailStatusEnum']);
+ const findData = (dicNo) => res?.find(item => item.dicNo === dicNo)?.data || [];
+ orderTypeOptions.value = findData('inOrderType');
+ orderStatusOptions.value = findData('inboundState');
+ warehouseOptions.value = findData('warehouses');
+ createTypeOptions.value = findData('createType');
+ detailStatusOptions.value = findData('orderDetailStatusEnum');
+ } catch {
+ orderTypeOptions.value = []; orderStatusOptions.value = []; warehouseOptions.value = [];
+ }
+}
+
+function goDetail(row) { router.push({ path: '/inbound/inboundOrderDetail', query: { id: row.id, inboundOrderNo: row.inboundOrderNo } }); }
+
+function handleSearch() { pagination.page = 1; loadData(); }
+function handleReset() { queryForm.inboundOrderNo = ''; queryForm.upperOrderNo = ''; queryForm.orderType = undefined; queryForm.orderStatus = undefined; queryForm.createDate = ''; handleSearch(); }
+
+function handleAdd() {
+ editForm.id = undefined; editForm.orderType = undefined; editForm.inboundOrderNo = ''; editForm.upperOrderNo = ''; editForm.warehouseId = undefined; editForm.remark = '';
+ dialogTitle.value = '鏂板鍏ュ簱鍗�'; dialogVisible.value = true;
+}
+
+function handleEdit(row) {
+ Object.assign(editForm, { id: row.id, orderType: row.orderType, inboundOrderNo: row.inboundOrderNo, upperOrderNo: row.upperOrderNo, warehouseId: row.warehouseId, remark: row.remark });
+ dialogTitle.value = '缂栬緫鍏ュ簱鍗�'; dialogVisible.value = true;
+}
+
+async function handleSubmit() {
+ await editFormRef.value.validate();
+ submitLoading.value = true;
+ try {
+ if (editForm.id) { await inboundApi.update(editForm); ElMessage.success('鏇存柊鎴愬姛'); }
+ else { await inboundApi.add(editForm); ElMessage.success('鏂板鎴愬姛'); }
+ dialogVisible.value = false; loadData();
+ } catch { ElMessage.error('鎿嶄綔澶辫触'); }
+ finally { submitLoading.value = false; }
+}
+
+function handleDelete(row) {
+ ElMessageBox.confirm(`纭畾鍒犻櫎鍏ュ簱鍗曘��${row.inboundOrderNo}銆嶅悧锛焋, '鎻愮ず', { type: 'warning' })
+ .then(async () => { await inboundApi.deleteById(row.id); ElMessage.success('鍒犻櫎鎴愬姛'); loadData(); }).catch(() => {});
+}
+
+function handleBatchDelete() {
+ const ids = selectedRows.value.map(r => r.id);
+ ElMessageBox.confirm(`纭畾鍒犻櫎閫変腑鐨� ${ids.length} 鏉¤褰曞悧锛焋, '鎻愮ず', { type: 'warning' })
+ .then(async () => { await Promise.all(ids.map(id => inboundApi.deleteById(id))); ElMessage.success('鍒犻櫎鎴愬姛'); loadData(); }).catch(() => {});
+}
+
+function handleSelectionChange(rows) { selectedRows.value = rows; }
+function handleSizeChange() { loadData(); }
+function handlePageChange() { loadData(); }
+
+const getWarehouseText = (val) => warehouseOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
+const getOrderTypeText = (val) => orderTypeOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
+const getOrderStatusText = (val) => orderStatusOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
+const getCreateTypeText = (val) => createTypeOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
+const getDetailStatusText = (val) => detailStatusOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
+
+onMounted(() => { loadDictionary(); loadData(); });
+</script>
+
+<style scoped>
+.inbound-page { padding: 16px; }
+.search-card { margin-bottom: 12px; }
+.table-card { margin-bottom: 12px; }
+.toolbar { margin-bottom: 12px; }
+</style>
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/views/login/index.vue b/Code/WMS/WIDESEA_WMSClient_Vben/src/views/login/index.vue
new file mode 100644
index 0000000..03312f9
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/views/login/index.vue
@@ -0,0 +1,196 @@
+<template>
+ <div class="login-container">
+ <div class="login-box">
+ <div class="login-header">
+ <h2>WIDESEA WMS</h2>
+ <p>浠撳簱绠$悊绯荤粺</p>
+ </div>
+
+ <el-form ref="loginFormRef" :model="loginForm" :rules="loginRules" class="login-form">
+ <el-form-item prop="username">
+ <el-input
+ v-model="loginForm.username"
+ placeholder="璇疯緭鍏ヨ处鍙�"
+ size="large"
+ prefix-icon="User"
+ />
+ </el-form-item>
+ <el-form-item prop="password">
+ <el-input
+ v-model="loginForm.password"
+ type="password"
+ placeholder="璇疯緭鍏ュ瘑鐮�"
+ size="large"
+ prefix-icon="Lock"
+ show-password
+ />
+ </el-form-item>
+ <el-form-item prop="verificationCode">
+ <el-input
+ v-model="loginForm.verificationCode"
+ placeholder="璇疯緭鍏ラ獙璇佺爜"
+ size="large"
+ prefix-icon="CircleCheck"
+ style="width: 60%"
+ @keyup.enter="handleLogin"
+ />
+ <div class="captcha-box" @click="loadCaptcha">
+ <img v-if="captchaImg" :src="captchaImg" alt="楠岃瘉鐮�" />
+ <span v-else class="captcha-placeholder">鐐瑰嚮鍒锋柊</span>
+ </div>
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary" size="large" style="width: 100%" :loading="loading" @click="handleLogin">
+ {{ loading ? '鐧诲綍涓�...' : '鐧� 褰�' }}
+ </el-button>
+ </el-form-item>
+ </el-form>
+
+ <div class="login-footer">
+ <span>婕旂ず璐﹀彿锛歛dmin666 瀵嗙爜锛�123456</span>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script setup lang="ts">
+import { reactive, ref, onMounted } from 'vue';
+import { useRouter } from 'vue-router';
+import { ElMessage } from 'element-plus';
+import { User, Lock, CircleCheck } from '@element-plus/icons-vue';
+import { userApi } from '@/api/modules/user';
+import { useUserStore } from '@/store';
+
+const router = useRouter();
+const userStore = useUserStore();
+const loginFormRef = ref();
+const loading = ref(false);
+const captchaImg = ref('');
+const uuid = ref('');
+
+const loginForm = reactive({
+ username: 'admin',
+ password: '123456',
+ verificationCode: '',
+});
+
+const loginRules = {
+ username: [{ required: true, message: '璇疯緭鍏ヨ处鍙�', trigger: 'blur' }],
+ password: [{ required: true, message: '璇疯緭鍏ュ瘑鐮�', trigger: 'blur' }],
+ verificationCode: [{ required: true, message: '璇疯緭鍏ラ獙璇佺爜', trigger: 'blur' }],
+};
+
+async function loadCaptcha() {
+ try {
+ const res = await userApi.getCaptcha();
+ if (res?.img) {
+ captchaImg.value = `data:image/png;base64,${res.img}`;
+ uuid.value = res.uuid;
+ }
+ } catch {
+ ElMessage.error('鑾峰彇楠岃瘉鐮佸け璐�');
+ }
+}
+
+async function handleLogin() {
+ if (!loginFormRef.value) return;
+ await loginFormRef.value.validate(async (valid) => {
+ if (!valid) return;
+ loading.value = true;
+ try {
+ const res = await userApi.login({
+ userName: loginForm.username,
+ password: loginForm.password,
+ verificationCode: loginForm.verificationCode,
+ UUID: uuid.value,
+ });
+ if (res?.status === false) {
+ ElMessage.error(res.message || '鐧诲綍澶辫触');
+ loadCaptcha();
+ return;
+ }
+ const userData = res.data || res;
+ userStore.setUserInfo({
+ token: userData.token || userData.access_token || '',
+ userName: userData.userName || loginForm.username,
+ userTrueName: userData.userTrueName || userData.name || '',
+ img: userData.img || '',
+ });
+ ElMessage.success('鐧诲綍鎴愬姛');
+ router.push('/');
+ } catch {
+ ElMessage.error('鐧诲綍寮傚父');
+ loadCaptcha();
+ } finally {
+ loading.value = false;
+ }
+ });
+}
+
+onMounted(() => {
+ loadCaptcha();
+});
+</script>
+
+<style scoped>
+.login-container {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ min-height: 100vh;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+}
+.login-box {
+ width: 420px;
+ padding: 40px;
+ background: #fff;
+ border-radius: 12px;
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
+}
+.login-header {
+ text-align: center;
+ margin-bottom: 30px;
+}
+.login-header h2 {
+ margin: 0 0 8px;
+ font-size: 28px;
+ color: #333;
+ font-weight: 600;
+}
+.login-header p {
+ margin: 0;
+ font-size: 14px;
+ color: #999;
+}
+.login-form {
+ margin-top: 20px;
+}
+.captcha-box {
+ width: 38%;
+ height: 40px;
+ margin-left: 10px;
+ border: 1px solid #dcdfe6;
+ border-radius: 4px;
+ overflow: hidden;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ background: #f5f7fa;
+}
+.captcha-box img {
+ width: 100%;
+ height: 100%;
+ object-fit: fill;
+}
+.captcha-placeholder {
+ font-size: 12px;
+ color: #999;
+}
+.login-footer {
+ margin-top: 20px;
+ text-align: center;
+ font-size: 12px;
+ color: #999;
+}
+</style>
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/views/outbound/index.vue b/Code/WMS/WIDESEA_WMSClient_Vben/src/views/outbound/index.vue
new file mode 100644
index 0000000..5d5a1f9
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/views/outbound/index.vue
@@ -0,0 +1,267 @@
+<template>
+ <div class="outbound-page">
+ <!-- 鎼滅储 -->
+ <el-card class="search-card" shadow="never">
+ <el-form :inline="true" :model="queryForm" label-width="90px">
+ <el-form-item label="鍗曟嵁缂栧彿">
+ <el-input v-model="queryForm.orderNo" placeholder="璇疯緭鍏ュ崟鎹紪鍙�" clearable style="width: 170px" />
+ </el-form-item>
+ <el-form-item label="涓婃父鍗曟嵁">
+ <el-input v-model="queryForm.upperOrderNo" placeholder="璇疯緭鍏ヤ笂娓稿崟鎹紪鍙�" clearable style="width: 170px" />
+ </el-form-item>
+ <el-form-item label="鍗曟嵁绫诲瀷">
+ <el-select v-model="queryForm.orderType" placeholder="璇烽�夋嫨" clearable style="width: 150px">
+ <el-option v-for="item in orderTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="鍗曟嵁鐘舵��">
+ <el-select v-model="queryForm.orderStatus" placeholder="璇烽�夋嫨" clearable style="width: 140px">
+ <el-option v-for="item in orderStatusOptions" :key="item.key" :label="item.value" :value="item.key" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="鍒涘缓鏃堕棿">
+ <el-date-picker v-model="queryForm.createDate" type="daterange" range-separator="鑷�" start-placeholder="寮�濮�" end-placeholder="缁撴潫" value-format="YYYY-MM-DD" />
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary" @click="handleSearch">鏌ヨ</el-button>
+ <el-button @click="handleReset">閲嶇疆</el-button>
+ </el-form-item>
+ </el-form>
+ </el-card>
+
+ <!-- 琛ㄦ牸 -->
+ <el-card class="table-card" shadow="never">
+ <div class="toolbar">
+ <el-button type="primary" @click="handleAdd">鏂板</el-button>
+ <el-button type="danger" :disabled="!selectedRows.length" @click="handleBatchDelete">鎵归噺鍒犻櫎</el-button>
+ </div>
+
+ <el-table v-loading="loading" :data="tableData" border stripe @selection-change="handleSelectionChange">
+ <el-table-column type="selection" width="50" align="center" />
+ <el-table-column prop="orderNo" label="鍗曟嵁缂栧彿" min-width="160" show-overflow-tooltip />
+ <el-table-column prop="upperOrderNo" label="涓婃父鍗曟嵁缂栧彿" min-width="160" show-overflow-tooltip />
+ <el-table-column prop="warehouseId" label="浠撳簱" min-width="100" align="center">
+ <template #default="{ row }">
+ {{ getWarehouseText(row.warehouseId) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="orderType" label="鍗曟嵁绫诲瀷" min-width="150" align="center">
+ <template #default="{ row }">
+ {{ getOrderTypeText(row.orderType) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="orderStatus" label="鍗曟嵁鐘舵��" min-width="100" align="center">
+ <template #default="{ row }">
+ {{ getOrderStatusText(row.orderStatus) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="createType" label="鍒涘缓鏂瑰紡" min-width="110" align="center">
+ <template #default="{ row }">
+ {{ getCreateTypeText(row.createType) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="departmentName" label="閮ㄩ棬鍚嶇О" min-width="160" show-overflow-tooltip />
+ <el-table-column prop="creater" label="鍒涘缓浜�" min-width="90" align="center" />
+ <el-table-column prop="createDate" label="鍒涘缓鏃堕棿" min-width="160" align="center" />
+ <el-table-column label="鎿嶄綔" width="180" align="center" fixed="right">
+ <template #default="{ row }">
+ <el-button link type="primary" size="small" @click="goDetail(row)">鏄庣粏</el-button>
+ <el-button link type="primary" size="small" @click="handleEdit(row)">缂栬緫</el-button>
+ <el-button link type="danger" size="small" @click="handleDelete(row)">鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <el-pagination
+ v-model:current-page="pagination.page"
+ v-model:page-size="pagination.pageSize"
+ :total="pagination.total"
+ :page-sizes="[10, 20, 50, 100]"
+ layout="total, sizes, prev, pager, next, jumper"
+ @size-change="handleSizeChange"
+ @current-change="handlePageChange"
+ style="margin-top: 16px; justify-content: flex-end"
+ />
+ </el-card>
+
+ <!-- 鏄庣粏鎶藉眽 -->
+ <el-drawer v-model="detailDrawerVisible" title="鍑哄簱鍗曟槑缁�" size="70%" direction="rtl" destroy-on-close>
+ <el-table :data="detailTableData" border stripe max-height="600">
+ <el-table-column prop="materielCode" label="鐗╂枡缂栧彿" min-width="150" show-overflow-tooltip />
+ <el-table-column prop="materielName" label="鐗╂枡鍚嶇О" min-width="150" show-overflow-tooltip />
+ <el-table-column prop="batchNo" label="鎵规鍙�" min-width="120" align="center" />
+ <el-table-column prop="orderQuantity" label="鍗曟嵁鏁伴噺" min-width="100" align="center" />
+ <el-table-column prop="rowNo" label="琛屽彿" min-width="80" align="center" />
+ <el-table-column prop="lockQuantity" label="閿佸畾鏁伴噺" min-width="120" align="center" />
+ <el-table-column prop="overOutQuantity" label="宸插嚭鏁伴噺" min-width="120" align="center" />
+ <el-table-column prop="orderDetailStatus" label="鏄庣粏鐘舵��" min-width="110" align="center">
+ <template #default="{ row }">
+ {{ getDetailStatusText(row.orderDetailStatus) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="creater" label="鍒涘缓浜�" min-width="90" align="center" />
+ <el-table-column prop="createDate" label="鍒涘缓鏃堕棿" min-width="160" align="center" />
+ </el-table>
+ </el-drawer>
+
+ <!-- 缂栬緫寮圭獥 -->
+ <el-dialog v-model="dialogVisible" :title="dialogTitle" width="560px" destroy-on-close>
+ <el-form :model="editForm" :rules="editRules" ref="editFormRef" label-width="100px">
+ <el-form-item label="鍗曟嵁绫诲瀷" prop="orderType">
+ <el-select v-model="editForm.orderType" placeholder="璇烽�夋嫨鍗曟嵁绫诲瀷" style="width: 100%">
+ <el-option v-for="item in orderTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="鍗曟嵁缂栧彿" prop="orderNo">
+ <el-input v-model="editForm.orderNo" placeholder="璇疯緭鍏ュ崟鎹紪鍙�" readonly />
+ </el-form-item>
+ <el-form-item label="涓婃父鍗曟嵁">
+ <el-input v-model="editForm.upperOrderNo" placeholder="璇疯緭鍏ヤ笂娓稿崟鎹紪鍙�" />
+ </el-form-item>
+ <el-form-item label="浠撳簱" prop="warehouseId">
+ <el-select v-model="editForm.warehouseId" placeholder="璇烽�夋嫨浠撳簱" style="width: 100%">
+ <el-option v-for="item in warehouseOptions" :key="item.key" :label="item.value" :value="item.key" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="澶囨敞">
+ <el-input v-model="editForm.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉�" />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="handleSubmit" :loading="submitLoading">纭畾</el-button>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from 'vue';
+import { useRouter } from 'vue-router';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import { outboundApi } from '@/api/modules/outbound';
+import { client } from '@/api/client';
+
+const router = useRouter();
+
+const queryForm = reactive({ orderNo: '', upperOrderNo: '', orderType: undefined, orderStatus: undefined, createDate: '' });
+const loading = ref(false);
+const tableData = ref([]);
+const selectedRows = ref([]);
+
+const orderTypeOptions = ref([]);
+const orderStatusOptions = ref([]);
+const warehouseOptions = ref([]);
+const createTypeOptions = ref([]);
+const detailStatusOptions = ref([]);
+
+const pagination = reactive({ page: 1, pageSize: 20, total: 0 });
+
+const detailDrawerVisible = ref(false);
+const detailTableData = ref([]);
+
+const dialogVisible = ref(false);
+const dialogTitle = ref('鏂板鍑哄簱鍗�');
+const editFormRef = ref(null);
+const submitLoading = ref(false);
+const editForm = reactive({ id: undefined, orderType: undefined, orderNo: '', upperOrderNo: '', warehouseId: undefined, remark: '' });
+const editRules = {
+ orderType: [{ required: true, message: '璇烽�夋嫨鍗曟嵁绫诲瀷', trigger: 'change' }],
+ orderNo: [{ required: true, message: '璇疯緭鍏ュ崟鎹紪鍙�', trigger: 'blur' }],
+ warehouseId: [{ required: true, message: '璇烽�夋嫨浠撳簱', trigger: 'change' }],
+};
+
+async function loadData() {
+ loading.value = true;
+ try {
+ const wheres = [
+ queryForm.orderNo ? { name: 'orderNo', value: queryForm.orderNo, displayType: 'like' } : null,
+ queryForm.upperOrderNo ? { name: 'upperOrderNo', value: queryForm.upperOrderNo, displayType: 'like' } : null,
+ queryForm.orderType !== undefined ? { name: 'orderType', value: queryForm.orderType, displayType: 'int' } : null,
+ queryForm.orderStatus !== undefined ? { name: 'orderStatus', value: queryForm.orderStatus, displayType: 'int' } : null,
+ ].filter(Boolean);
+ const res = await outboundApi.getPageList({ page: pagination.page, rows: pagination.pageSize, sort: 'id', order: 'desc', wheres: JSON.stringify(wheres) });
+ tableData.value = res?.rows || [];
+ pagination.total = res?.total || 0;
+ } catch { ElMessage.error('鍔犺浇鏁版嵁澶辫触'); }
+ finally { loading.value = false; }
+}
+
+async function loadDetail(row) {
+ try {
+ const res = await client.post('/api/OutboundOrderDetail/getPageList', {
+ page: 1, rows: 200, sort: 'id', order: 'asc',
+ wheres: JSON.stringify([{ name: 'orderId', value: row.id, displayType: 'int' }]),
+ });
+ detailTableData.value = res?.rows || [];
+ } catch { detailTableData.value = []; ElMessage.error('鍔犺浇鏄庣粏澶辫触'); }
+}
+
+async function loadDictionary() {
+ try {
+ const res = await client.post('/api/Sys_Dictionary/GetVueDictionary', ['outOrderType', 'outboundStatusEnum', 'warehouses', 'createType', 'orderDetailStatusEnum']);
+ const findData = (dicNo) => res?.find(item => item.dicNo === dicNo)?.data || [];
+ orderTypeOptions.value = findData('outOrderType');
+ orderStatusOptions.value = findData('outboundStatusEnum');
+ warehouseOptions.value = findData('warehouses');
+ createTypeOptions.value = findData('createType');
+ detailStatusOptions.value = findData('orderDetailStatusEnum');
+ } catch { orderTypeOptions.value = []; orderStatusOptions.value = []; warehouseOptions.value = []; }
+}
+
+function goDetail(row) { router.push({ path: '/outbound/outboundOrderDetail', query: { id: row.id, orderNo: row.orderNo } }); }
+
+function handleSearch() { pagination.page = 1; loadData(); }
+function handleReset() { queryForm.orderNo = ''; queryForm.upperOrderNo = ''; queryForm.orderType = undefined; queryForm.orderStatus = undefined; queryForm.createDate = ''; handleSearch(); }
+
+function handleAdd() {
+ editForm.id = undefined; editForm.orderType = undefined; editForm.orderNo = ''; editForm.upperOrderNo = ''; editForm.warehouseId = undefined; editForm.remark = '';
+ dialogTitle.value = '鏂板鍑哄簱鍗�'; dialogVisible.value = true;
+}
+
+function handleEdit(row) {
+ Object.assign(editForm, { id: row.id, orderType: row.orderType, orderNo: row.orderNo, upperOrderNo: row.upperOrderNo, warehouseId: row.warehouseId, remark: row.remark });
+ dialogTitle.value = '缂栬緫鍑哄簱鍗�'; dialogVisible.value = true;
+}
+
+async function handleSubmit() {
+ await editFormRef.value.validate();
+ submitLoading.value = true;
+ try {
+ if (editForm.id) { await outboundApi.update(editForm); ElMessage.success('鏇存柊鎴愬姛'); }
+ else { await outboundApi.add(editForm); ElMessage.success('鏂板鎴愬姛'); }
+ dialogVisible.value = false; loadData();
+ } catch { ElMessage.error('鎿嶄綔澶辫触'); }
+ finally { submitLoading.value = false; }
+}
+
+function handleDelete(row) {
+ ElMessageBox.confirm(`纭畾鍒犻櫎鍑哄簱鍗曘��${row.orderNo}銆嶅悧锛焋, '鎻愮ず', { type: 'warning' })
+ .then(async () => { await outboundApi.deleteById(row.id); ElMessage.success('鍒犻櫎鎴愬姛'); loadData(); }).catch(() => {});
+}
+
+function handleBatchDelete() {
+ const ids = selectedRows.value.map(r => r.id);
+ ElMessageBox.confirm(`纭畾鍒犻櫎閫変腑鐨� ${ids.length} 鏉¤褰曞悧锛焋, '鎻愮ず', { type: 'warning' })
+ .then(async () => { await Promise.all(ids.map(id => outboundApi.deleteById(id))); ElMessage.success('鍒犻櫎鎴愬姛'); loadData(); }).catch(() => {});
+}
+
+function handleSelectionChange(rows) { selectedRows.value = rows; }
+function handleSizeChange() { loadData(); }
+function handlePageChange() { loadData(); }
+
+const getWarehouseText = (val) => warehouseOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
+const getOrderTypeText = (val) => orderTypeOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
+const getOrderStatusText = (val) => orderStatusOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
+const getCreateTypeText = (val) => createTypeOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
+const getDetailStatusText = (val) => detailStatusOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
+
+onMounted(() => { loadDictionary(); loadData(); });
+</script>
+
+<style scoped>
+.outbound-page { padding: 16px; }
+.search-card { margin-bottom: 12px; }
+.table-card { margin-bottom: 12px; }
+.toolbar { margin-bottom: 12px; }
+</style>
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/views/outbound/outboundOrderDetail.vue b/Code/WMS/WIDESEA_WMSClient_Vben/src/views/outbound/outboundOrderDetail.vue
new file mode 100644
index 0000000..5c34d7d
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/views/outbound/outboundOrderDetail.vue
@@ -0,0 +1,106 @@
+<template>
+ <div class="outbound-detail-page">
+ <el-card shadow="never">
+ <template #header>
+ <span>鍑哄簱鍗曟槑缁� - {{ route.query.orderNo || '' }}</span>
+ </template>
+
+ <el-form :inline="true" :model="queryForm" class="search-form">
+ <el-form-item label="鐗╂枡缂栧彿">
+ <el-input v-model="queryForm.materielCode" placeholder="璇疯緭鍏ョ墿鏂欑紪鍙�" clearable />
+ </el-form-item>
+ <el-form-item label="鐗╂枡鍚嶇О">
+ <el-input v-model="queryForm.materielName" placeholder="璇疯緭鍏ョ墿鏂欏悕绉�" clearable />
+ </el-form-item>
+ <el-form-item label="鎵规鍙�">
+ <el-input v-model="queryForm.batchNo" placeholder="璇疯緭鍏ユ壒娆″彿" clearable />
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary" @click="handleSearch">鏌ヨ</el-button>
+ <el-button @click="handleReset">閲嶇疆</el-button>
+ </el-form-item>
+ </el-form>
+
+ <el-table v-loading="loading" :data="tableData" border stripe>
+ <el-table-column prop="materielCode" label="鐗╂枡缂栧彿" min-width="150" show-overflow-tooltip />
+ <el-table-column prop="materielName" label="鐗╂枡鍚嶇О" min-width="160" show-overflow-tooltip />
+ <el-table-column prop="batchNo" label="鎵规鍙�" min-width="120" align="center" />
+ <el-table-column prop="orderQuantity" label="鍗曟嵁鏁伴噺" min-width="100" align="center" />
+ <el-table-column prop="rowNo" label="琛屽彿" min-width="80" align="center" />
+ <el-table-column prop="lockQuantity" label="閿佸畾鏁伴噺" min-width="120" align="center" />
+ <el-table-column prop="overOutQuantity" label="宸插嚭鏁伴噺" min-width="120" align="center" />
+ <el-table-column prop="orderDetailStatus" label="鏄庣粏鐘舵��" min-width="110" align="center">
+ <template #default="{ row }">
+ {{ getDetailStatusText(row.orderDetailStatus) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="creater" label="鍒涘缓浜�" min-width="90" align="center" />
+ <el-table-column prop="createDate" label="鍒涘缓鏃堕棿" min-width="160" align="center" />
+ </el-table>
+
+ <el-pagination
+ v-model:current-page="pagination.page"
+ v-model:page-size="pagination.pageSize"
+ :total="pagination.total"
+ :page-sizes="[10, 20, 50, 100]"
+ layout="total, sizes, prev, pager, next, jumper"
+ @size-change="handleSizeChange"
+ @current-change="handlePageChange"
+ style="margin-top: 16px; justify-content: flex-end"
+ />
+ </el-card>
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from 'vue';
+import { useRoute } from 'vue-router';
+import { ElMessage } from 'element-plus';
+import { client } from '@/api/client';
+
+const route = useRoute();
+const loading = ref(false);
+const tableData = ref([]);
+const detailStatusOptions = ref([]);
+
+const queryForm = reactive({ materielCode: '', materielName: '', batchNo: '' });
+const pagination = reactive({ page: 1, pageSize: 20, total: 0 });
+
+async function loadData() {
+ loading.value = true;
+ try {
+ const orderId = route.query.id;
+ const wheres = [{ name: 'orderId', value: String(orderId), displayType: 'int' }];
+ if (queryForm.materielCode) wheres.push({ name: 'materielCode', value: queryForm.materielCode, displayType: 'like' });
+ if (queryForm.materielName) wheres.push({ name: 'materielName', value: queryForm.materielName, displayType: 'like' });
+ if (queryForm.batchNo) wheres.push({ name: 'batchNo', value: queryForm.batchNo, displayType: 'like' });
+ const res = await client.post('/api/OutboundOrderDetail/getPageList', {
+ page: pagination.page, rows: pagination.pageSize, sort: 'id', order: 'asc',
+ wheres: JSON.stringify(wheres),
+ });
+ tableData.value = res?.rows || [];
+ pagination.total = res?.total || 0;
+ } catch { ElMessage.error('鍔犺浇鏁版嵁澶辫触'); }
+ finally { loading.value = false; }
+}
+
+async function loadDictionary() {
+ try {
+ const res = await client.post('/api/Sys_Dictionary/GetVueDictionary', ['orderDetailStatusEnum']);
+ detailStatusOptions.value = res?.find(item => item.dicNo === 'orderDetailStatusEnum')?.data || [];
+ } catch { detailStatusOptions.value = []; }
+}
+
+function handleSearch() { pagination.page = 1; loadData(); }
+function handleReset() { queryForm.materielCode = ''; queryForm.materielName = ''; queryForm.batchNo = ''; handleSearch(); }
+function handleSizeChange() { loadData(); }
+function handlePageChange() { loadData(); }
+const getDetailStatusText = (val) => detailStatusOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
+
+onMounted(() => { loadDictionary(); loadData(); });
+</script>
+
+<style scoped>
+.outbound-detail-page { padding: 16px; }
+.search-form { margin-bottom: 12px; }
+</style>
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/views/stock/index.vue b/Code/WMS/WIDESEA_WMSClient_Vben/src/views/stock/index.vue
new file mode 100644
index 0000000..8359717
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/views/stock/index.vue
@@ -0,0 +1,340 @@
+<template>
+ <div class="stock-page">
+ <!-- 鎼滅储鍖哄煙 -->
+ <el-card class="search-card" shadow="never">
+ <el-form :inline="true" :model="queryForm" label-width="80px">
+ <el-form-item label="鎵樼洏缂栧彿">
+ <el-input v-model="queryForm.palletCode" placeholder="璇疯緭鍏ユ墭鐩樼紪鍙�" clearable style="width: 180px" />
+ </el-form-item>
+ <el-form-item label="璐т綅缂栧彿">
+ <el-input v-model="queryForm.locationCode" placeholder="璇疯緭鍏ヨ揣浣嶇紪鍙�" clearable style="width: 180px" />
+ </el-form-item>
+ <el-form-item label="浠撳簱">
+ <el-select v-model="queryForm.warehouseId" placeholder="璇烽�夋嫨浠撳簱" clearable style="width: 160px">
+ <el-option v-for="item in warehouseOptions" :key="item.key" :label="item.value" :value="item.key" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="搴撳瓨鐘舵��">
+ <el-select v-model="queryForm.stockStatus" placeholder="璇烽�夋嫨鐘舵��" clearable style="width: 140px">
+ <el-option v-for="item in stockStatusOptions" :key="item.key" :label="item.value" :value="item.key" />
+ </el-select>
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary" @click="handleSearch">鏌ヨ</el-button>
+ <el-button @click="handleReset">閲嶇疆</el-button>
+ </el-form-item>
+ </el-form>
+ </el-card>
+
+ <!-- 鏁版嵁琛ㄦ牸 -->
+ <el-card class="table-card" shadow="never">
+ <div class="toolbar">
+ <el-button type="primary" @click="handleAdd">鏂板</el-button>
+ <el-button type="danger" :disabled="!selectedRows.length" @click="handleBatchDelete">鎵归噺鍒犻櫎</el-button>
+ </div>
+
+ <el-table
+ v-loading="loading"
+ :data="tableData"
+ border
+ stripe
+ @selection-change="handleSelectionChange"
+ @expand-change="handleExpandChange"
+ :expand-row-keys="expandedRows"
+ row-key="id"
+ >
+ <el-table-column type="selection" width="50" align="center" />
+ <el-table-column type="expand" width="50">
+ <template #default="{ row }">
+ <div class="expand-panel">
+ <div class="expand-header">
+ <span class="expand-title">搴撳瓨鏄庣粏</span>
+ <span class="expand-subtitle">鎵樼洏锛歿{ row.palletCode }} / 璐т綅锛歿{ row.locationCode }}</span>
+ </div>
+ <el-table :data="detailData[row.id] || []" border stripe size="small" max-height="400">
+ <el-table-column prop="materielName" label="鐗╂枡鍚嶇О" min-width="160" show-overflow-tooltip />
+ <el-table-column prop="serialNumber" label="鐢佃姱鐮�" min-width="160" show-overflow-tooltip />
+ <el-table-column prop="stockQuantity" label="搴撳瓨鏁伴噺" min-width="120" align="center" />
+ <el-table-column prop="status" label="鐘舵��" min-width="120" align="center">
+ <template #default="{ row: dr }">
+ {{ getStatusText(dr.status) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="inboundOrderRowNo" label="閫氶亾鍙�" min-width="120" align="center" />
+ </el-table>
+ <div v-if="!detailData[row.id] && !detailLoading[row.id]" class="expand-empty">鏆傛棤鏄庣粏鏁版嵁</div>
+ <div v-if="detailLoading[row.id]" class="expand-loading">鍔犺浇涓�...</div>
+ </div>
+ </template>
+ </el-table-column>
+ <el-table-column prop="palletCode" label="鎵樼洏缂栧彿" min-width="130" show-overflow-tooltip />
+ <el-table-column prop="locationCode" label="璐т綅缂栧彿" min-width="150" show-overflow-tooltip />
+ <el-table-column prop="warehouseId" label="浠撳簱" min-width="110" align="center">
+ <template #default="{ row }">
+ {{ getWarehouseText(row.warehouseId) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="stockStatus" label="搴撳瓨鐘舵��" min-width="120" align="center">
+ <template #default="{ row }">
+ {{ getStockStatusText(row.stockStatus) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="outboundDate" label="鍑哄簱鏃ユ湡" min-width="160" align="center" />
+ <el-table-column prop="creater" label="鍒涘缓浜�" min-width="100" align="center" />
+ <el-table-column prop="createDate" label="鍒涘缓鏃堕棿" min-width="160" align="center" />
+ <el-table-column label="鎿嶄綔" width="150" align="center" fixed="right">
+ <template #default="{ row }">
+ <el-button link type="primary" size="small" @click="handleEdit(row)">缂栬緫</el-button>
+ <el-button link type="danger" size="small" @click="handleDelete(row)">鍒犻櫎</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <el-pagination
+ v-model:current-page="pagination.page"
+ v-model:page-size="pagination.pageSize"
+ :total="pagination.total"
+ :page-sizes="[10, 20, 50, 100]"
+ layout="total, sizes, prev, pager, next, jumper"
+ @size-change="handleSizeChange"
+ @current-change="handlePageChange"
+ style="margin-top: 16px; justify-content: flex-end"
+ />
+ </el-card>
+
+ <!-- 缂栬緫寮圭獥 -->
+ <el-dialog v-model="dialogVisible" :title="dialogTitle" width="560px" destroy-on-close>
+ <el-form :model="editForm" :rules="editRules" ref="editFormRef" label-width="100px">
+ <el-form-item label="鎵樼洏缂栧彿" prop="palletCode">
+ <el-input v-model="editForm.palletCode" placeholder="璇疯緭鍏ユ墭鐩樼紪鍙�" />
+ </el-form-item>
+ <el-form-item label="璐т綅缂栧彿" prop="locationCode">
+ <el-input v-model="editForm.locationCode" placeholder="璇疯緭鍏ヨ揣浣嶇紪鍙�" />
+ </el-form-item>
+ <el-form-item label="浠撳簱" prop="warehouseId">
+ <el-select v-model="editForm.warehouseId" placeholder="璇烽�夋嫨浠撳簱" style="width: 100%">
+ <el-option v-for="item in warehouseOptions" :key="item.key" :label="item.value" :value="item.key" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="搴撳瓨鐘舵��" prop="stockStatus">
+ <el-select v-model="editForm.stockStatus" placeholder="璇烽�夋嫨搴撳瓨鐘舵��" style="width: 100%">
+ <el-option v-for="item in stockStatusOptions" :key="item.key" :label="item.value" :value="item.key" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="澶囨敞">
+ <el-input v-model="editForm.remark" type="textarea" :rows="3" placeholder="璇疯緭鍏ュ娉�" />
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+ <el-button type="primary" @click="handleSubmit" :loading="submitLoading">纭畾</el-button>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from 'vue';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import { stockApi } from '@/api/modules/stock';
+import { client } from '@/api/client';
+
+const BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:9291';
+
+// 鎼滅储
+const queryForm = reactive({
+ palletCode: '',
+ locationCode: '',
+ warehouseId: undefined,
+ stockStatus: undefined,
+});
+
+// 琛ㄦ牸
+const loading = ref(false);
+const tableData = ref([]);
+const selectedRows = ref([]);
+const expandedRows = ref([]);
+const detailData = ref({});
+const detailLoading = ref({});
+
+// 瀛楀吀
+const warehouseOptions = ref([]);
+const stockStatusOptions = ref([]);
+
+// 鍒嗛〉
+const pagination = reactive({ page: 1, pageSize: 20, total: 0 });
+
+// 缂栬緫寮圭獥
+const dialogVisible = ref(false);
+const dialogTitle = ref('鏂板搴撳瓨');
+const editFormRef = ref(null);
+const submitLoading = ref(false);
+const editForm = reactive({
+ id: undefined,
+ palletCode: '',
+ locationCode: '',
+ warehouseId: undefined,
+ stockStatus: undefined,
+ remark: '',
+});
+const editRules = {
+ palletCode: [{ required: true, message: '璇疯緭鍏ユ墭鐩樼紪鍙�', trigger: 'blur' }],
+ locationCode: [{ required: true, message: '璇疯緭鍏ヨ揣浣嶇紪鍙�', trigger: 'blur' }],
+ warehouseId: [{ required: true, message: '璇烽�夋嫨浠撳簱', trigger: 'change' }],
+};
+
+async function loadData() {
+ loading.value = true;
+ try {
+ const params = buildQueryParams();
+ const res = await stockApi.getPageList(params);
+ tableData.value = res?.rows || [];
+ pagination.total = res?.total || 0;
+ } catch {
+ ElMessage.error('鍔犺浇鏁版嵁澶辫触');
+ } finally {
+ loading.value = false;
+ }
+}
+
+function buildQueryParams() {
+ const wheres = [
+ queryForm.palletCode ? { name: 'palletCode', value: queryForm.palletCode, displayType: 'like' } : null,
+ queryForm.locationCode ? { name: 'locationCode', value: queryForm.locationCode, displayType: 'like' } : null,
+ queryForm.warehouseId ? { name: 'warehouseId', value: queryForm.warehouseId, displayType: 'int' } : null,
+ queryForm.stockStatus !== undefined ? { name: 'stockStatus', value: queryForm.stockStatus, displayType: 'int' } : null,
+ ].filter(Boolean);
+ return {
+ page: pagination.page,
+ rows: pagination.pageSize,
+ sort: 'id',
+ order: 'desc',
+ wheres: JSON.stringify(wheres),
+ };
+}
+
+async function loadDetailData(row) {
+ if (detailData.value[row.id] || detailLoading.value[row.id]) return;
+ detailLoading.value[row.id] = true;
+ try {
+ const res = await client.post('/api/StockInfoDetail/getPageData', {
+ page: 1, rows: 200, sort: 'id', order: 'asc',
+ wheres: JSON.stringify([{ name: 'stockId', value: String(row.id), displayType: 'int' }]),
+ });
+ detailData.value[row.id] = res?.rows || [];
+ } catch {
+ detailData.value[row.id] = [];
+ ElMessage.error('鍔犺浇鏄庣粏澶辫触');
+ } finally {
+ detailLoading.value[row.id] = false;
+ }
+}
+
+async function loadDictionary() {
+ try {
+ const res = await client.post('/api/Sys_Dictionary/GetVueDictionary', ['warehouseEnum', 'stockStatusEmun']);
+ const wh = res?.find(item => item.dicNo === 'warehouseEnum');
+ warehouseOptions.value = wh?.data || [];
+ const ss = res?.find(item => item.dicNo === 'stockStatusEmun');
+ stockStatusOptions.value = ss?.data || [];
+ } catch {
+ warehouseOptions.value = [];
+ stockStatusOptions.value = [];
+ }
+}
+
+function handleSearch() { pagination.page = 1; loadData(); }
+
+function handleReset() {
+ queryForm.palletCode = '';
+ queryForm.locationCode = '';
+ queryForm.warehouseId = undefined;
+ queryForm.stockStatus = undefined;
+ handleSearch();
+}
+
+function handleAdd() {
+ editForm.id = undefined;
+ editForm.palletCode = '';
+ editForm.locationCode = '';
+ editForm.warehouseId = undefined;
+ editForm.stockStatus = undefined;
+ editForm.remark = '';
+ dialogTitle.value = '鏂板搴撳瓨';
+ dialogVisible.value = true;
+}
+
+function handleEdit(row) {
+ Object.assign(editForm, { id: row.id, palletCode: row.palletCode, locationCode: row.locationCode, warehouseId: row.warehouseId, stockStatus: row.stockStatus, remark: row.remark });
+ dialogTitle.value = '缂栬緫搴撳瓨';
+ dialogVisible.value = true;
+}
+
+async function handleSubmit() {
+ await editFormRef.value.validate();
+ submitLoading.value = true;
+ try {
+ if (editForm.id) {
+ await stockApi.updateStock(editForm);
+ ElMessage.success('鏇存柊鎴愬姛');
+ } else {
+ await stockApi.addStock(editForm);
+ ElMessage.success('鏂板鎴愬姛');
+ }
+ dialogVisible.value = false;
+ loadData();
+ } catch { ElMessage.error('鎿嶄綔澶辫触'); }
+ finally { submitLoading.value = false; }
+}
+
+function handleDelete(row) {
+ ElMessageBox.confirm(`纭畾鍒犻櫎搴撳瓨銆�${row.palletCode}銆嶅悧锛焋, '鎻愮ず', { type: 'warning' })
+ .then(async () => {
+ await stockApi.deleteStock(row.id);
+ ElMessage.success('鍒犻櫎鎴愬姛');
+ loadData();
+ }).catch(() => {});
+}
+
+function handleBatchDelete() {
+ const ids = selectedRows.value.map(r => r.id);
+ ElMessageBox.confirm(`纭畾鍒犻櫎閫変腑鐨� ${ids.length} 鏉¤褰曞悧锛焋, '鎻愮ず', { type: 'warning' })
+ .then(async () => {
+ await Promise.all(ids.map(id => stockApi.deleteStock(id)));
+ ElMessage.success('鍒犻櫎鎴愬姛');
+ loadData();
+ }).catch(() => {});
+}
+
+function handleSelectionChange(rows) { selectedRows.value = rows; }
+
+function handleExpandChange(row, expanded) {
+ if (expanded) {
+ expandedRows.value.push(row.id);
+ loadDetailData(row);
+ } else {
+ expandedRows.value = expandedRows.value.filter(id => id !== row.id);
+ }
+}
+
+function handleSizeChange() { loadData(); }
+function handlePageChange() { loadData(); }
+
+const getWarehouseText = (val) => warehouseOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
+const getStockStatusText = (val) => stockStatusOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
+const getStatusText = (val) => stockStatusOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
+
+onMounted(() => { loadDictionary(); loadData(); });
+</script>
+
+<style scoped>
+.stock-page { padding: 16px; }
+.search-card { margin-bottom: 12px; }
+.table-card { margin-bottom: 12px; }
+.toolbar { margin-bottom: 12px; }
+.expand-panel { margin: 8px 16px 16px; padding: 12px; background: #fafafa; border-radius: 8px; }
+.expand-header { margin-bottom: 12px; }
+.expand-title { font-size: 15px; font-weight: 700; color: #303133; margin-right: 12px; }
+.expand-subtitle { font-size: 13px; color: #606266; }
+.expand-empty, .expand-loading { padding: 14px 12px; color: #909399; text-align: center; }
+</style>
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/src/views/stock/stockInfoDetail.vue b/Code/WMS/WIDESEA_WMSClient_Vben/src/views/stock/stockInfoDetail.vue
new file mode 100644
index 0000000..a4715bd
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/src/views/stock/stockInfoDetail.vue
@@ -0,0 +1,119 @@
+<template>
+ <div class="stock-detail-page">
+ <el-card shadow="never">
+ <template #header>
+ <span>搴撳瓨鏄庣粏 - {{ route.query.palletCode || '' }}</span>
+ </template>
+
+ <!-- 鎼滅储 -->
+ <el-form :inline="true" :model="queryForm" class="search-form">
+ <el-form-item label="鐗╂枡鍚嶇О">
+ <el-input v-model="queryForm.materielName" placeholder="璇疯緭鍏ョ墿鏂欏悕绉�" clearable />
+ </el-form-item>
+ <el-form-item label="鐢佃姱鐮�">
+ <el-input v-model="queryForm.serialNumber" placeholder="璇疯緭鍏ョ數鑺爜" clearable />
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary" @click="handleSearch">鏌ヨ</el-button>
+ <el-button @click="handleReset">閲嶇疆</el-button>
+ </el-form-item>
+ </el-form>
+
+ <!-- 琛ㄦ牸 -->
+ <el-table v-loading="loading" :data="tableData" border stripe>
+ <el-table-column prop="materielCode" label="鐗╂枡缂栫爜" min-width="140" show-overflow-tooltip />
+ <el-table-column prop="materielName" label="鐗╂枡鍚嶇О" min-width="160" show-overflow-tooltip />
+ <el-table-column prop="serialNumber" label="鐢佃姱鐮�" min-width="180" show-overflow-tooltip />
+ <el-table-column prop="stockQuantity" label="搴撳瓨鏁伴噺" min-width="120" align="center" />
+ <el-table-column prop="status" label="鐘舵��" min-width="120" align="center">
+ <template #default="{ row }">
+ {{ getStatusText(row.status) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="inboundOrderRowNo" label="閫氶亾鍙�" min-width="120" align="center" />
+ <el-table-column prop="creater" label="鍒涘缓浜�" min-width="100" align="center" />
+ <el-table-column prop="createDate" label="鍒涘缓鏃堕棿" min-width="160" align="center" />
+ </el-table>
+
+ <el-pagination
+ v-model:current-page="pagination.page"
+ v-model:page-size="pagination.pageSize"
+ :total="pagination.total"
+ :page-sizes="[10, 20, 50, 100]"
+ layout="total, sizes, prev, pager, next, jumper"
+ @size-change="handleSizeChange"
+ @current-change="handlePageChange"
+ style="margin-top: 16px; justify-content: flex-end"
+ />
+ </el-card>
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from 'vue';
+import { useRoute } from 'vue-router';
+import { ElMessage } from 'element-plus';
+import { client } from '@/api/client';
+
+const route = useRoute();
+const loading = ref(false);
+const tableData = ref([]);
+const stockStatusOptions = ref([]);
+
+const queryForm = reactive({
+ materielName: '',
+ serialNumber: '',
+});
+
+const pagination = reactive({ page: 1, pageSize: 20, total: 0 });
+
+async function loadData() {
+ loading.value = true;
+ try {
+ const stockId = route.query.id;
+ const wheres = [{ name: 'stockId', value: String(stockId), displayType: 'int' }];
+ if (queryForm.materielName) wheres.push({ name: 'materielName', value: queryForm.materielName, displayType: 'like' });
+ if (queryForm.serialNumber) wheres.push({ name: 'serialNumber', value: queryForm.serialNumber, displayType: 'like' });
+ const res = await client.post('/api/StockInfoDetail/getPageData', {
+ page: pagination.page,
+ rows: pagination.pageSize,
+ sort: 'id',
+ order: 'asc',
+ wheres: JSON.stringify(wheres),
+ });
+ tableData.value = res?.rows || [];
+ pagination.total = res?.total || 0;
+ } catch {
+ ElMessage.error('鍔犺浇鏁版嵁澶辫触');
+ } finally {
+ loading.value = false;
+ }
+}
+
+async function loadDictionary() {
+ try {
+ const res = await client.post('/api/Sys_Dictionary/GetVueDictionary', ['stockStatusEmun']);
+ const ss = res?.find(item => item.dicNo === 'stockStatusEmun');
+ stockStatusOptions.value = ss?.data || [];
+ } catch {
+ stockStatusOptions.value = [];
+ }
+}
+
+function handleSearch() { pagination.page = 1; loadData(); }
+function handleReset() {
+ queryForm.materielName = '';
+ queryForm.serialNumber = '';
+ handleSearch();
+}
+function handleSizeChange() { loadData(); }
+function handlePageChange() { loadData(); }
+const getStatusText = (val) => stockStatusOptions.value.find(o => `${o.key}` === `${val}`)?.value || val || '-';
+
+onMounted(() => { loadDictionary(); loadData(); });
+</script>
+
+<style scoped>
+.stock-detail-page { padding: 16px; }
+.search-form { margin-bottom: 12px; }
+</style>
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/tsconfig.json b/Code/WMS/WIDESEA_WMSClient_Vben/tsconfig.json
new file mode 100644
index 0000000..db9261f
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/tsconfig.json
@@ -0,0 +1,21 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "module": "ESNext",
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "skipLibCheck": true,
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "preserve",
+ "strict": false,
+ "noUnusedLocals": false,
+ "noUnusedParameters": false,
+ "baseUrl": ".",
+ "paths": { "@/*": ["src/*"] }
+ },
+ "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
+}
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/tsconfig.node.json b/Code/WMS/WIDESEA_WMSClient_Vben/tsconfig.node.json
new file mode 100644
index 0000000..97ede7e
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/tsconfig.node.json
@@ -0,0 +1,11 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "skipLibCheck": true,
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "allowSyntheticDefaultImports": true,
+ "strict": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben/vite.config.ts b/Code/WMS/WIDESEA_WMSClient_Vben/vite.config.ts
new file mode 100644
index 0000000..626de4f
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben/vite.config.ts
@@ -0,0 +1,21 @@
+import { defineConfig } from 'vite';
+import vue from '@vitejs/plugin-vue';
+import { resolve } from 'path';
+
+export default defineConfig({
+ plugins: [vue()],
+ resolve: {
+ alias: {
+ '@': resolve(__dirname, 'src'),
+ },
+ },
+ server: {
+ port: 3000,
+ proxy: {
+ '/api': {
+ target: 'http://localhost:9291',
+ changeOrigin: true,
+ },
+ },
+ },
+});
diff --git a/Code/WMS/WIDESEA_WMSClient_Vben_v2 b/Code/WMS/WIDESEA_WMSClient_Vben_v2
new file mode 160000
index 0000000..07c4ad0
--- /dev/null
+++ b/Code/WMS/WIDESEA_WMSClient_Vben_v2
@@ -0,0 +1 @@
+Subproject commit 07c4ad05f40507d7d797619814bf75a47c29a9f4
diff --git a/Code/WMS/WMS_Api_Design.md b/Code/WMS/WMS_Api_Design.md
new file mode 100644
index 0000000..5f24b9d
--- /dev/null
+++ b/Code/WMS/WMS_Api_Design.md
@@ -0,0 +1,203 @@
+# WMS 鍓嶇 API 璁捐鏂囨。
+
+> 鏈枃妗d负 Vben Admin 鍓嶇椤圭洰锛圵IDESEA_WMSClient_Vben锛夋彁渚� API 閫傞厤灞傝璁″弬鑰冦��
+
+## 鐩綍缁撴瀯
+
+```
+WIDESEA_WMSClient_Vben/
+鈹溾攢鈹� src/
+鈹� 鈹溾攢鈹� api/
+鈹� 鈹� 鈹溾攢鈹� client.ts # axios 瀹炰緥灏佽
+鈹� 鈹� 鈹溾攢鈹� modules/
+鈹� 鈹� 鈹� 鈹溾攢鈹� user.ts # 鐢ㄦ埛璁よ瘉妯″潡
+鈹� 鈹� 鈹� 鈹溾攢鈹� menu.ts # 鑿滃崟妯″潡
+鈹� 鈹� 鈹� 鈹溾攢鈹� stock.ts # 搴撳瓨妯″潡
+鈹� 鈹� 鈹� 鈹溾攢鈹� inbound.ts # 鍏ュ簱妯″潡
+鈹� 鈹� 鈹� 鈹溾攢鈹� outbound.ts # 鍑哄簱妯″潡
+鈹� 鈹� 鈹� 鈹斺攢鈹� check.ts # 鐩樼偣妯″潡
+鈹� 鈹� 鈹斺攢鈹� index.ts # 缁熶竴瀵煎嚭
+```
+
+## 1. axios 瀹㈡埛绔皝瑁� (`api/client.ts`)
+
+```typescript
+import axios from 'axios';
+import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
+import { useUserStore } from '@/store/modules/user';
+import { useAuthStore } from '@/store/modules/auth';
+
+const BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:9291';
+
+const client: AxiosInstance = axios.create({
+ baseURL: BASE_URL,
+ timeout: 30000,
+ headers: { 'Content-Type': 'application/json' },
+});
+
+// 璇锋眰鎷︽埅鍣細娉ㄥ叆 Bearer Token
+client.interceptors.request.use(
+ (config) => {
+ const userStore = useUserStore();
+ const token = userStore.token;
+ if (token) {
+ config.headers.Authorization = `Bearer ${token}`;
+ }
+ return config;
+ },
+ (error) => Promise.reject(error)
+);
+
+// 鍝嶅簲鎷︽埅鍣細缁熶竴閿欒澶勭悊 + 401 token 杩囨湡璺宠浆鐧诲綍
+client.interceptors.response.use(
+ (response: AxiosResponse) => response.data,
+ async (error) => {
+ const status = error.response?.status;
+ const raw = error.response?.data;
+
+ // 涓氬姟閿欒鐮侊紙闈� HTTP 鐘舵�佺爜锛夊彲浠� raw.code 鍒ゆ柇
+ if (raw?.code === 401 || status === 401) {
+ const authStore = useAuthStore();
+ authStore.logout(true); // true = token 杩囨湡琚姩鐧诲嚭
+ }
+
+ return Promise.reject(error);
+ }
+);
+
+export default client;
+```
+
+## 2. 璇锋眰鎷︽埅鍣ㄩ�昏緫
+
+| 鍦烘櫙 | 澶勭悊鏂瑰紡 |
+|------|---------|
+| 鏈� Token | `Authorization: Bearer <token>` 娉ㄥ叆璇锋眰澶� |
+| 鏃� Token | 鏀捐锛岃鍚庣杩斿洖 401 |
+| 涓诲姩鐧诲嚭 | 娓呯┖ token 璺宠浆鐧诲綍椤� |
+
+## 3. 鍝嶅簲鎷︽埅鍣ㄩ�昏緫
+
+| 鍦烘櫙 | 澶勭悊鏂瑰紡 |
+|------|---------|
+| 2xx 鍝嶅簲 | 杩斿洖 `response.data` |
+| HTTP 401 / 涓氬姟 code 401 | 璋冪敤 `authStore.logout(true)` 璺宠浆鐧诲綍 |
+| 鍏朵粬閿欒 | 鎶涘嚭寮傚父锛岀敱鍚勬ā鍧楄嚜琛屽鐞� |
+
+## 4. 鎺ュ彛绛惧悕
+
+### 4.1 鐢ㄦ埛妯″潡 (`modules/user.ts`)
+
+```typescript
+/** 鑾峰彇楠岃瘉鐮侊紝杩斿洖 { img: string, uuid: string } */
+export function getVerificationCode(): Promise<{ img: string; uuid: string }>;
+
+/** 鐧诲綍 */
+export function login(params: {
+ userName: string;
+ password: string;
+ verificationCode: string;
+ UUID: string;
+}): Promise<{ token: string; expires: number }>;
+
+/** 褰撳墠鐢ㄦ埛淇℃伅 */
+export function getCurrentUserInfo(): Promise<UserInfo>;
+
+/** 鍒锋柊 Token */
+export function replaceToken(): Promise<{ token: string; expires: number }>;
+```
+
+### 4.2 鑿滃崟妯″潡 (`modules/menu.ts`)
+
+```typescript
+/** 鑾峰彇鏍戝舰鑿滃崟 */
+export function getTreeMenu(): Promise<MenuTreeNode[]>;
+
+interface MenuTreeNode {
+ id: string;
+ name: string;
+ path: string;
+ component?: string;
+ icon?: string;
+ children?: MenuTreeNode[];
+}
+```
+
+### 4.3 搴撳瓨妯″潡 (`modules/stock.ts`)
+
+```typescript
+/** 搴撳瓨鍒楄〃锛堝垎椤碉級 */
+export function getStockList(params: StockQuery): Promise<PageResult<StockItem>>;
+
+/** 搴撳瓨璇︽儏 */
+export function getStockDetail(id: string): Promise<StockItem>;
+```
+
+### 4.4 鍏ュ簱妯″潡 (`modules/inbound.ts`)
+
+```typescript
+/** 鍏ュ簱鍗曞垪琛� */
+export function getInboundOrderList(params: InboundQuery): Promise<PageResult<InboundOrder>>;
+
+/** 鍒涘缓鍏ュ簱鍗� */
+export function createInboundOrder(data: CreateInboundOrder): Promise<{ id: string }>;
+
+/** 鎻愪氦鍏ュ簱鍗� */
+export function submitInboundOrder(id: string): Promise<void>;
+```
+
+### 4.5 鍑哄簱妯″潡 (`modules/outbound.ts`)
+
+```typescript
+/** 鍑哄簱鍗曞垪琛� */
+export function getOutboundOrderList(params: OutboundQuery): Promise<PageResult<OutboundOrder>>;
+
+/** 鍒涘缓鍑哄簱鍗� */
+export function createOutboundOrder(data: CreateOutboundOrder): Promise<{ id: string }>;
+
+/** 鎻愪氦鍑哄簱鍗� */
+export function submitOutboundOrder(id: string): Promise<void>;
+```
+
+### 4.6 鐩樼偣妯″潡 (`modules/check.ts`)
+
+```typescript
+/** 鐩樼偣鍗曞垪琛� */
+export function getCheckOrderList(params: CheckQuery): Promise<PageResult<CheckOrder>>;
+
+/** 鍒涘缓鐩樼偣鍗� */
+export function createCheckOrder(data: CreateCheckOrder): Promise<{ id: string }>;
+
+/** 鎻愪氦鐩樼偣鍗� */
+export function submitCheckOrder(id: string): Promise<void>;
+```
+
+## 5. 閫氱敤绫诲瀷瀹氫箟
+
+```typescript
+/** 鍒嗛〉缁撴灉 */
+interface PageResult<T> {
+ items: T[];
+ total: number;
+ page: number;
+ pageSize: number;
+}
+
+/** 閫氱敤鎿嶄綔缁撴灉锛堟棤鏁版嵁杩斿洖鏃讹級 */
+interface OpResult {
+ code: number;
+ message: string;
+}
+```
+
+## 6. 鐜鍙橀噺
+
+```env
+# .env.development
+VITE_API_BASE_URL=http://localhost:9291
+
+# .env.production
+VITE_API_BASE_URL=/api
+```
+
+> **娉ㄦ剰**: 鐢熶骇鐜浣跨敤 `/api` 浠g悊锛岄伩鍏嶈法鍩熴��
--
Gitblit v1.9.3