60c63850ee
- 修复 Redis 超时:添加 commons-pool2 依赖,启用 Lettuce 连接池,超时提升至 15s - 固定 mini-program H5 端口为 5175,避免与 web 项目端口冲突 - 新增人生事件(life-event)模块:表单和详情页面 - 新增 EpicScript 灵感接口(Controller/Service/DTO) - 优化登录、引导、主页、记录、剧本详情等多个页面 - 优化服务管理脚本和 Nginx 配置 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
159 lines
4.1 KiB
JavaScript
159 lines
4.1 KiB
JavaScript
import { getEnvValue, getConfig } from '../config/env.js'
|
|
|
|
const API_BASE_URL = getEnvValue('API_BASE_URL')
|
|
|
|
const AUTH_PATH_PREFIX = '/auth/'
|
|
|
|
const isAuthPath = (path = '') => path.startsWith(AUTH_PATH_PREFIX)
|
|
|
|
const createRequestError = (message, meta = {}) => {
|
|
const error = new Error(message || 'Request failed')
|
|
Object.assign(error, meta)
|
|
return error
|
|
}
|
|
|
|
const clearAuthStorage = () => {
|
|
uni.removeStorageSync('access_token')
|
|
uni.removeStorageSync('refresh_token')
|
|
}
|
|
|
|
const logApi = (level, label, payload, force = false) => {
|
|
const debug = getEnvValue('DEBUG')
|
|
if (!debug && !force) return
|
|
const logger = level === 'error' ? console.error : console.log
|
|
logger(`[API] ${label}`, payload)
|
|
}
|
|
|
|
export const logRuntimeEnv = (source = 'startup') => {
|
|
const config = getConfig()
|
|
console.log('[ENV] runtime', {
|
|
source,
|
|
rawEnv: import.meta.env.VITE_APP_ENV,
|
|
mode: import.meta.env.MODE,
|
|
apiBaseUrl: config.API_BASE_URL,
|
|
wsUrl: config.WS_URL,
|
|
debug: config.DEBUG,
|
|
platform: typeof uni !== 'undefined' ? uni.getSystemInfoSync?.()?.platform : 'unknown'
|
|
})
|
|
}
|
|
|
|
const getHeaders = () => {
|
|
const token = uni.getStorageSync('access_token')
|
|
const headers = {
|
|
'Content-Type': 'application/json'
|
|
}
|
|
if (token) {
|
|
headers.Authorization = `Bearer ${token}`
|
|
}
|
|
return headers
|
|
}
|
|
|
|
const request = (options) => {
|
|
const method = options.method || 'GET'
|
|
const fullUrl = `${API_BASE_URL}${options.url}`
|
|
const forceLog = isAuthPath(options.url)
|
|
|
|
logApi('log', 'request', {
|
|
method,
|
|
url: fullUrl,
|
|
path: options.url,
|
|
env: import.meta.env.VITE_APP_ENV || import.meta.env.MODE
|
|
}, forceLog)
|
|
|
|
return new Promise((resolve, reject) => {
|
|
uni.request({
|
|
url: fullUrl,
|
|
method,
|
|
data: options.data,
|
|
header: getHeaders(),
|
|
timeout: 30000,
|
|
success: (res) => {
|
|
const { data, statusCode } = res
|
|
const success = statusCode >= 200 && statusCode < 300 && (data?.code === 200 || data?.code === 0)
|
|
|
|
logApi('log', 'response', {
|
|
path: options.url,
|
|
status: statusCode,
|
|
code: data?.code,
|
|
success
|
|
}, forceLog || statusCode >= 400)
|
|
|
|
if (statusCode === 401) {
|
|
if (!forceLog) {
|
|
clearAuthStorage()
|
|
uni.reLaunch({ url: '/pages/login/index' })
|
|
}
|
|
reject(createRequestError('Login expired, please login again', {
|
|
statusCode,
|
|
code: data?.code,
|
|
path: options.url,
|
|
isAuthRejected: true
|
|
}))
|
|
return
|
|
}
|
|
|
|
if (success) {
|
|
resolve(data)
|
|
return
|
|
}
|
|
|
|
reject(createRequestError(data?.message || 'Request failed', {
|
|
statusCode,
|
|
code: data?.code,
|
|
path: options.url,
|
|
response: data,
|
|
isAuthRejected: statusCode === 403 || data?.code === 401 || data?.code === 403
|
|
}))
|
|
},
|
|
fail: (err) => {
|
|
logApi('error', 'fail', {
|
|
path: options.url,
|
|
url: fullUrl,
|
|
error: err.errMsg,
|
|
env: import.meta.env.VITE_APP_ENV || import.meta.env.MODE
|
|
}, true)
|
|
|
|
reject(createRequestError(err.errMsg || 'Network request failed', {
|
|
path: options.url,
|
|
isNetworkError: true,
|
|
originalError: err
|
|
}))
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
export const get = (url, params = {}) => {
|
|
const queryString = Object.keys(params)
|
|
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
|
|
.join('&')
|
|
const fullUrl = queryString ? `${url}?${queryString}` : url
|
|
|
|
return request({ url: fullUrl, method: 'GET' })
|
|
}
|
|
|
|
export const post = (url, data = {}) => {
|
|
return request({ url, method: 'POST', data })
|
|
}
|
|
|
|
export const put = (url, data = {}) => {
|
|
return request({ url, method: 'PUT', data })
|
|
}
|
|
|
|
export const del = (url, params = {}) => {
|
|
const queryString = Object.keys(params)
|
|
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
|
|
.join('&')
|
|
const fullUrl = queryString ? `${url}?${queryString}` : url
|
|
|
|
return request({ url: fullUrl, method: 'DELETE' })
|
|
}
|
|
|
|
export default {
|
|
get,
|
|
post,
|
|
put,
|
|
del,
|
|
logRuntimeEnv
|
|
}
|