const axios = require("axios"); const baseModel = require("../../middleware/baseModel"); const config = require("../../config/config"); const logs = require("../../tool/logs_proxy"); const upstreamBaseUrl = config.upstream_api_url || "http://127.0.0.1:8888"; /** * 转发请求到上游并记录调用日志 * @param {object} params * @param {string} params.api_path - 接口路径,如 /user/GetProfile * @param {string} params.method - HTTP 方法 * @param {object} params.query - query 参数(透传) * @param {object} params.body - body 参数(透传) * @param {object} params.headers - 需要透传的请求头 * @param {object} params.auth_ctx - 鉴权上下文(verifyRequest 返回的 context) * @returns {object} { status, data, headers } */ async function forwardRequest({ api_path, method, query, body, headers, auth_ctx }) { const url = `${upstreamBaseUrl}${api_path}`; const start = Date.now(); let status_code = 0; let resp_data = null; let resp_headers = {}; try { const forwardHeaders = {}; if (headers["content-type"]) forwardHeaders["content-type"] = headers["content-type"]; if (headers["user-agent"]) forwardHeaders["user-agent"] = headers["user-agent"]; const resp = await axios({ method: method.toLowerCase(), url, params: query, data: body, headers: forwardHeaders, timeout: 30000, validateStatus: () => true, }); status_code = resp.status; resp_data = resp.data; resp_headers = resp.headers; } catch (err) { status_code = 502; resp_data = { ok: false, error_code: "UPSTREAM_ERROR", message: err.message }; logs.error(`[proxy] 转发失败 ${api_path}`, err.message); } const response_time = Date.now() - start; // 异步写调用日志,不阻塞响应 writeCallLog({ user_id: auth_ctx.user_id, token_id: auth_ctx.token_id, api_path, http_method: method.toUpperCase(), status_code, response_time, }).catch((e) => logs.error("[proxy] 写调用日志失败", e.message)); return { status: status_code, data: resp_data, headers: resp_headers }; } /** * 写入 API 调用日志 */ async function writeCallLog({ user_id, token_id, api_path, http_method, status_code, response_time }) { const now = new Date(); const call_date = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}`; await baseModel.biz_api_call_log.create({ user_id, token_id, api_path, http_method, status_code, response_time, call_date, created_at: now, }); } module.exports = { forwardRequest };