Browse Source

feat: add Python service connection testing functionality

- Implemented a new IPC handler in the Electron main process to test connections to a Python service.
- Updated the preload script to expose the new connection testing method to the renderer process.
- Modified the Vue component to utilize the new method for checking the Python service connection, enhancing user feedback on connection status.
Ethanfly 22 giờ trước cách đây
mục cha
commit
70f2bfe057
3 tập tin đã thay đổi với 42 bổ sung13 xóa
  1. 13 0
      client/electron/main.ts
  2. 3 0
      client/electron/preload.ts
  3. 26 13
      client/src/views/ServerConfig/index.vue

+ 13 - 0
client/electron/main.ts

@@ -366,6 +366,19 @@ ipcMain.handle('test-server-connection', async (_event: unknown, args: { url: st
   }
 });
 
+// Python 服务测试连接(主进程发起,支持 HTTP/HTTPS,无跨域限制)
+ipcMain.handle('test-python-service-connection', async (_event: unknown, args: { url: string }) => {
+  try {
+    const baseUrl = normalizeBaseUrl(args?.url);
+    if (!baseUrl) return { ok: false, error: '未填写 Python 服务地址' };
+    const result = await requestJson(`${baseUrl}/health`, 5000);
+    if (!result.ok) return { ok: false, error: result.error || '连接失败' };
+    return { ok: true };
+  } catch (e: any) {
+    return { ok: false, error: e?.message || '连接失败' };
+  }
+});
+
 // IPC 处理
 ipcMain.handle('get-app-version', () => {
   return app.getVersion();

+ 3 - 0
client/electron/preload.ts

@@ -68,6 +68,8 @@ contextBridge.exposeInMainWorld('electronAPI', {
 
   testServerConnection: (url: string) =>
     ipcRenderer.invoke('test-server-connection', { url }),
+  testPythonServiceConnection: (url: string) =>
+    ipcRenderer.invoke('test-python-service-connection', { url }),
 });
 
 // 类型声明
@@ -101,6 +103,7 @@ declare global {
       onNetworkInterceptData: (callback: (data: { webContentsId: number; key: string; url: string; data: unknown }) => void) => void;
       removeNetworkInterceptListener: () => void;
       testServerConnection: (url: string) => Promise<{ ok: boolean; error?: string }>;
+      testPythonServiceConnection: (url: string) => Promise<{ ok: boolean; error?: string }>;
     };
   }
 }

+ 26 - 13
client/src/views/ServerConfig/index.vue

@@ -120,6 +120,7 @@ import { ref, reactive, onMounted, computed, watch } from 'vue';
 import { useRouter } from 'vue-router';
 import { Setting, Link } from '@element-plus/icons-vue';
 import { ElMessage, type FormInstance, type FormRules } from 'element-plus';
+import axios from 'axios';
 import { useServerStore } from '@/stores/server';
 import { useAuthStore } from '@/stores/auth';
 import request from '@/api/request';
@@ -236,26 +237,38 @@ async function checkPythonService() {
     ElMessage.warning('请先填写服务器地址');
     return;
   }
-  if (!apiBaseUrl.value) {
-    ElMessage.warning('请先填写服务器地址');
+  const url = pythonService.url ? normalizeBaseUrl(pythonService.url) : '';
+  if (!url) {
+    ElMessage.warning('请先填写 Python 服务地址');
     return;
   }
   checkingPython.value = true;
   pythonCheckResult.value = null;
   try {
-    const result = await request.post(
-      '/api/system/python-service/check',
-      { url: pythonService.url ? normalizeBaseUrl(pythonService.url) : undefined },
-      { baseURL: apiBaseUrl.value }
-    );
-    pythonCheckResult.value = result;
-    if (result.ok) {
-      ElMessage.success('连接成功');
+    const electronApi = (window as any)?.electronAPI;
+    if (electronApi?.testPythonServiceConnection) {
+      const result = await electronApi.testPythonServiceConnection(url);
+      pythonCheckResult.value = { ok: result?.ok ?? false, error: result?.error };
+      if (result?.ok) {
+        ElMessage.success('连接成功');
+      } else {
+        ElMessage.error('连接失败');
+      }
     } else {
-      ElMessage.error('连接失败');
+      const healthUrl = `${url.replace(/\/$/, '')}/health`;
+      const res = await axios.get(healthUrl, { timeout: 5000 });
+      const ok = res.status >= 200 && res.status < 300;
+      pythonCheckResult.value = { ok, error: ok ? undefined : `HTTP ${res.status}` };
+      if (ok) {
+        ElMessage.success('连接成功');
+      } else {
+        ElMessage.error('连接失败');
+      }
     }
-  } catch {
-    pythonCheckResult.value = { ok: false, error: '请求失败' };
+  } catch (e: unknown) {
+    const err = e as { message?: string };
+    const error = err?.message || '请求失败';
+    pythonCheckResult.value = { ok: false, error };
     ElMessage.error('连接失败');
   } finally {
     checkingPython.value = false;