feat: implement initial backend API server and frontend configuration context for the application.

This commit is contained in:
2026-01-30 09:33:52 +08:00
parent 49382c5d03
commit 23a8e7475e
2 changed files with 22 additions and 5 deletions

View File

@@ -300,11 +300,18 @@ func handleS2AProxy(w http.ResponseWriter, r *http.Request) {
} }
defer resp.Body.Close() defer resp.Body.Close()
// 记录响应状态 // 读取响应体
if resp.StatusCode != 200 { bodyBytes, err := io.ReadAll(resp.Body)
logger.Warning(fmt.Sprintf("S2A 返回 %d", resp.StatusCode), "", "proxy") if err != nil {
logger.Error(fmt.Sprintf("读取响应失败: %v", err), "", "proxy")
api.Error(w, http.StatusBadGateway, "读取响应失败")
return
} }
// 记录响应状态和内容摘要
logger.Info(fmt.Sprintf("S2A 响应: status=%d, len=%d, body=%s",
resp.StatusCode, len(bodyBytes), string(bodyBytes[:min(200, len(bodyBytes))])), "", "proxy")
// 复制响应头 // 复制响应头
for key, values := range resp.Header { for key, values := range resp.Header {
for _, value := range values { for _, value := range values {
@@ -314,7 +321,7 @@ func handleS2AProxy(w http.ResponseWriter, r *http.Request) {
// 复制响应状态和内容 // 复制响应状态和内容
w.WriteHeader(resp.StatusCode) w.WriteHeader(resp.StatusCode)
io.Copy(w, resp.Body) w.Write(bodyBytes)
} }
func handleMailServices(w http.ResponseWriter, r *http.Request) { func handleMailServices(w http.ResponseWriter, r *http.Request) {

View File

@@ -55,7 +55,7 @@ export function ConfigProvider({ children }: { children: ReactNode }) {
refreshConfig() refreshConfig()
}, [refreshConfig]) }, [refreshConfig])
// Update S2A client when config changes // Update S2A client when config changes and auto-test connection
useEffect(() => { useEffect(() => {
if (config.s2a.apiBase && config.s2a.adminKey) { if (config.s2a.apiBase && config.s2a.adminKey) {
const client = new S2AClient({ const client = new S2AClient({
@@ -63,6 +63,16 @@ export function ConfigProvider({ children }: { children: ReactNode }) {
apiKey: config.s2a.adminKey, apiKey: config.s2a.adminKey,
}) })
setS2aClient(client) setS2aClient(client)
// 自动测试连接
fetch('/api/s2a/test')
.then(res => res.json())
.then(data => {
setIsConnected(data.code === 0)
})
.catch(() => {
setIsConnected(false)
})
} else { } else {
setS2aClient(null) setS2aClient(null)
setIsConnected(false) setIsConnected(false)