From ffa73784805fc394bede4c9a7c33ab31f7d5c6bd Mon Sep 17 00:00:00 2001 From: smail Date: Sun, 30 Aug 2026 20:03:37 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=88=9D=E5=A7=8B=E5=8C=96?= =?UTF-8?q?=E8=AF=B7=E6=B1=82=E9=93=BE=E8=B7=AF=E4=B8=8E=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E5=93=8D=E5=BA=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fe/src/utils/axios.js | 2 ++ fe/vite.config.js | 19 ++++++++++--- server/controllers/setup.go | 3 ++ server/controllers/setup_contract_test.go | 34 +++++++++++++++++++++++ 4 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 server/controllers/setup_contract_test.go diff --git a/fe/src/utils/axios.js b/fe/src/utils/axios.js index 70a69c7..c7eed91 100644 --- a/fe/src/utils/axios.js +++ b/fe/src/utils/axios.js @@ -6,6 +6,8 @@ import {router} from "@/router"; const http = axios.create({ baseURL: import.meta.env.VITE_APP_URL, //接口统一域名 timeout: 60000, + // 初始化授权和登录会话都依赖服务端 Cookie;开发代理或反向代理跨源时也必须携带 Cookie。 + withCredentials: true, xsrfCookieName: 'smail_csrf', xsrfHeaderName: 'X-CSRF-Token', withXSRFToken: true, //设置超时 diff --git a/fe/vite.config.js b/fe/vite.config.js index 209e9db..f20bc33 100644 --- a/fe/vite.config.js +++ b/fe/vite.config.js @@ -1,12 +1,16 @@ import { fileURLToPath, URL } from 'node:url' -import { defineConfig } from 'vite' +import { defineConfig, loadEnv } from 'vite' import AutoImport from 'unplugin-auto-import/vite' import Components from 'unplugin-vue-components/vite' import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' import vue from '@vitejs/plugin-vue' // https://vitejs.dev/config/ -export default defineConfig({ +export default defineConfig(({ mode }) => { + const env = loadEnv(mode, process.cwd(), '') + const backendUrl = (env.VITE_DEV_BACKEND_URL || 'http://127.0.0.1:9001').replace(/\/$/, '') + + return { plugins: [ vue(), AutoImport({ @@ -24,8 +28,15 @@ export default defineConfig({ server: { cors: true, proxy: { - "/api": "http://127.0.0.1/", - "/attachments":"http://127.0.0.1/" + "/api": { + target: backendUrl, + changeOrigin: false + }, + "/attachments": { + target: backendUrl, + changeOrigin: false + } } } + } }) diff --git a/server/controllers/setup.go b/server/controllers/setup.go index 1ef17fe..37475f1 100644 --- a/server/controllers/setup.go +++ b/server/controllers/setup.go @@ -204,4 +204,7 @@ func Setup(ctx *context.Context, w http.ResponseWriter, req *http.Request) { return } + // 初始化接口必须始终返回统一 JSON,避免未知步骤被当成空响应, + // 进而让前端误判请求已完成并进入错误页面。 + response.NewErrorResponse(response.ParamsError, "不支持的初始化操作", "").FPrint(w) } diff --git a/server/controllers/setup_contract_test.go b/server/controllers/setup_contract_test.go new file mode 100644 index 0000000..9b7c72d --- /dev/null +++ b/server/controllers/setup_contract_test.go @@ -0,0 +1,34 @@ +package controllers + +import ( + "encoding/json" + "net/http/httptest" + "strings" + "testing" + + appcontext "git.pcux.cn/xuans/Smail/utils/context" +) + +func TestSetupReturnsJSONForUnsupportedOperation(t *testing.T) { + request := httptest.NewRequest("POST", "/api/v1/setup", strings.NewReader(`{"step":"unknown","action":"unknown"}`)) + response := httptest.NewRecorder() + + Setup(&appcontext.Context{}, response, request) + + if response.Code != 200 { + t.Fatalf("setup status = %d, want 200", response.Code) + } + if contentType := response.Header().Get("Content-Type"); !strings.HasPrefix(contentType, "application/json") { + t.Fatalf("setup content type = %q, want JSON", contentType) + } + var payload struct { + ErrorNo int `json:"errorNo"` + ErrorMsg string `json:"errorMsg"` + } + if err := json.Unmarshal(response.Body.Bytes(), &payload); err != nil { + t.Fatalf("decode setup response: %v", err) + } + if payload.ErrorNo != 100 || payload.ErrorMsg != "不支持的初始化操作" { + t.Fatalf("unexpected setup response: %+v", payload) + } +}