瀏覽代碼

状态查询

moki 3 周之前
父節點
當前提交
8f9a82bd17
共有 3 個文件被更改,包括 196 次插入1 次删除
  1. 175 0
      docs/api.md
  2. 6 0
      src/api/client.ts
  3. 15 1
      src/views/Dashboard.vue

+ 175 - 0
docs/api.md

@@ -0,0 +1,175 @@
+# 后端 API 文档
+
+基础地址:`http://localhost:8045`
+
+所有接口返回统一格式:
+
+```json
+{
+  "code": 0,
+  "message": "success",
+  "data": ...
+}
+```
+
+`code` 为 0 表示成功,非 0 表示失败。
+
+---
+
+## 1. 获取监控客户端列表
+
+获取当前所有被监控的 AI 客户端(端口)及其状态。
+
+```
+GET /api/clients
+```
+
+### 响应
+
+`data` 为数组,每个元素结构如下:
+
+| 字段      | 类型   | 说明                                         |
+| --------- | ------ | -------------------------------------------- |
+| port      | number | 客户端端口号                                 |
+| status    | string | 状态描述文本                                 |
+| code      | string | 状态码(见下方枚举)                         |
+| timestamp | string | 最后更新时间,ISO 8601 格式                 |
+
+### 状态码枚举
+
+| code              | 说明           |
+| ----------------- | -------------- |
+| idle              | 空闲           |
+| busy              | 忙碌           |
+| retry             | 重试中         |
+| pending           | 修改中         |
+| reasoning         | 思考中         |
+| using_tool        | 使用工具中     |
+| running           | 运行中         |
+| completed         | 工具执行完成   |
+| session_completed | 会话完成       |
+| permission        | 等待权限       |
+| error             | 错误           |
+
+### 示例
+
+**请求**
+
+```
+GET /api/clients
+```
+
+**响应**
+
+```json
+{
+  "code": 0,
+  "message": "success",
+  "data": [
+    {
+      "port": 8001,
+      "status": "空闲",
+      "code": "idle",
+      "timestamp": "2026-06-04T10:00:00Z"
+    },
+    {
+      "port": 8002,
+      "status": "运行中",
+      "code": "running",
+      "timestamp": "2026-06-04T10:05:00Z"
+    }
+  ]
+}
+```
+
+---
+
+## 2. MQTT 配置管理
+
+### 2.1 获取所有配置
+
+```
+GET /api/mqtt
+```
+
+**响应**
+
+```json
+{
+  "code": 0,
+  "message": "success",
+  "data": [
+    {
+      "id": 1,
+      "broker": "mqtt://broker.example.com:1883",
+      "client_id": "opencode-monitor",
+      "username": "admin",
+      "password": "secret",
+      "topic": "opencode/status",
+      "enabled": true
+    }
+  ]
+}
+```
+
+### 2.2 获取单个配置
+
+```
+GET /api/mqtt/:id
+```
+
+### 2.3 创建配置
+
+```
+POST /api/mqtt
+Content-Type: application/json
+```
+
+| 字段      | 类型    | 必填 | 说明         |
+| --------- | ------- | ---- | ------------ |
+| broker    | string  | 是   | MQTT 地址    |
+| client_id | string  | 是   | 客户端 ID    |
+| username  | string  | 否   | 用户名       |
+| password  | string  | 否   | 密码         |
+| topic     | string  | 是   | 订阅主题     |
+| enabled   | boolean | 否   | 是否启用     |
+
+### 2.4 更新配置
+
+```
+PUT /api/mqtt/:id
+Content-Type: application/json
+```
+
+请求体同创建。
+
+### 2.5 删除配置
+
+```
+DELETE /api/mqtt/:id
+```
+
+---
+
+## 3. WebSocket
+
+前端通过 WebSocket 接收实时端口状态推送。
+
+```
+ws://localhost:8045/ws
+```
+
+### 消息格式
+
+后端主动推送 JSON 消息:
+
+```json
+{
+  "port": 8001,
+  "status": "运行中",
+  "code": "running",
+  "timestamp": "2026-06-04T10:05:00Z"
+}
+```
+
+字段说明同 `GET /api/clients` 响应中的元素结构。

+ 6 - 0
src/api/client.ts

@@ -0,0 +1,6 @@
+import http from './index'
+import type { PortState, ApiResponse } from '@/types'
+
+export function getClients() {
+  return http.get<ApiResponse<PortState[]>>('/clients')
+}

+ 15 - 1
src/views/Dashboard.vue

@@ -1,6 +1,7 @@
 <script setup lang="ts">
-import { ref, reactive, computed, onUnmounted } from 'vue'
+import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
 import { useWebSocket } from '@/composables/useWebSocket'
+import { getClients } from '@/api/client'
 import type { PortState, StatusMessage } from '@/types'
 import PortStatusCard from '@/components/PortStatusCard.vue'
 
@@ -17,6 +18,19 @@ const removeListener = onMessage((msg: StatusMessage) => {
   })
 })
 
+onMounted(async () => {
+  try {
+    const { data: res } = await getClients()
+    if (res.data) {
+      for (const client of res.data) {
+        ports.set(client.port, client)
+      }
+    }
+  } catch {
+    // 接口失败不影响 WebSocket 实时推送
+  }
+})
+
 const portList = computed(() =>
   Array.from(ports.values()).sort((a, b) => a.port - b.port),
 )