JewelryMall/miniprogram/utils/request.ts
2026-02-14 19:29:15 +08:00

114 lines
3.4 KiB
TypeScript

// 后端 API 基础地址 - 根据环境自动切换
// 开发环境使用本地服务器,生产环境使用线上地址
const ENV_BASE_URL: Record<string, string> = {
development: 'http://localhost:3000',
production: 'https://api.example.com', // 部署时替换为真实域名
}
const BASE_URL = ENV_BASE_URL[process.env.NODE_ENV || 'development'] || 'http://localhost:3000'
interface RequestOptions {
url: string
method?: 'GET' | 'POST' | 'PUT' | 'DELETE'
data?: Record<string, unknown>
header?: Record<string, string>
}
interface ApiResponse<T = unknown> {
code: number
data: T
message: string
}
function getToken(): string {
return uni.getStorageSync('token') || ''
}
export function request<T = unknown>(options: RequestOptions): Promise<T> {
const { url, method = 'GET', data, header = {} } = options
const token = getToken()
return new Promise((resolve, reject) => {
uni.request({
url: `${BASE_URL}${url}`,
method,
data,
header: {
'Content-Type': 'application/json',
...(token ? { Authorization: `Bearer ${token}` } : {}),
...header,
},
success(res) {
const statusCode = res.statusCode
if (statusCode === 401) {
uni.removeStorageSync('token')
uni.showToast({ title: '请重新登录', icon: 'none' })
autoLogin()
reject(new Error('未授权'))
return
}
if (statusCode >= 200 && statusCode < 300) {
const body = res.data as ApiResponse<T>
if (body.code === 0) {
resolve(body.data)
} else {
uni.showToast({ title: body.message || '请求失败', icon: 'none' })
reject(new Error(body.message))
}
} else {
uni.showToast({ title: '网络异常,请稍后重试', icon: 'none' })
reject(new Error(`HTTP ${statusCode}`))
}
},
fail(err) {
uni.showToast({ title: '网络异常,请稍后重试', icon: 'none' })
reject(err)
},
})
})
}
/** 微信小程序自动登录 */
export function autoLogin(): Promise<void> {
return new Promise((resolve, reject) => {
uni.login({
provider: 'weixin',
success: async (loginRes) => {
if (loginRes.code) {
try {
const data = await request<{ token: string; userId: number }>({
url: '/api/auth/wx-login',
method: 'POST',
data: { code: loginRes.code },
})
uni.setStorageSync('token', data.token)
resolve()
} catch (err) {
console.error('登录接口调用失败:', err)
reject(err)
}
} else {
console.error('微信登录获取 code 失败')
reject(new Error('获取微信 code 失败'))
}
},
fail: (err) => {
console.error('uni.login 失败:', err)
reject(err)
},
})
})
}
export const get = <T = unknown>(url: string, data?: Record<string, unknown>) =>
request<T>({ url, method: 'GET', data })
export const post = <T = unknown>(url: string, data?: Record<string, unknown>) =>
request<T>({ url, method: 'POST', data })
export const put = <T = unknown>(url: string, data?: Record<string, unknown>) =>
request<T>({ url, method: 'PUT', data })
export const del = <T = unknown>(url: string, data?: Record<string, unknown>) =>
request<T>({ url, method: 'DELETE', data })