Files
vueapp/api/auth.ts
T
2026-06-01 14:49:14 +08:00

114 lines
2.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
let apiBaseUrl = 'http://192.168.2.76:8000/api'
// #ifdef H5
apiBaseUrl = '/backend-api'
// #endif
export const API_BASE_URL = apiBaseUrl
export type SendCodePayload = {
phone: string
scene: 'register' | 'login' | 'reset'
}
export type SendCodeResponse = {
message: string
}
export type LoginCodePayload = {
phone: string
code: string
}
export type BackendUser = {
id: number
username: string
phone: string
real_name: string
role_type: string
institution: string | null
department: string | null
}
export type LoginResponse = {
message: string
user?: Partial<BackendUser> & Record<string, unknown>
tokens: {
access: string
refresh: string
}
}
export class ApiRequestError extends Error {
code?: string
statusCode?: number
constructor(message: string, code?: string, statusCode?: number) {
super(message)
this.name = 'ApiRequestError'
this.code = code
this.statusCode = statusCode
}
}
function readErrorMessage(data: unknown, fallback: string) {
if (data && typeof data === 'object') {
const payload = data as Record<string, unknown>
const message = payload.message || payload.detail || payload.error
if (typeof message === 'string' && message.trim()) return message
}
return fallback
}
function request<T>(url: string, data: unknown): Promise<T> {
return new Promise((resolve, reject) => {
uni.request({
url: `${API_BASE_URL}${url}`,
method: 'POST',
timeout: 10000,
header: {
'Content-Type': 'application/json'
},
data,
success: response => {
if (response.statusCode >= 200 && response.statusCode < 300) {
resolve(response.data as T)
return
}
const payload = response.data as Record<string, unknown> | undefined
const code = typeof payload?.code === 'string' ? payload.code : undefined
reject(new ApiRequestError(readErrorMessage(response.data, `请求失败(${response.statusCode}`), code, response.statusCode))
},
fail: error => {
reject(new ApiRequestError(error.errMsg || '无法连接服务'))
}
})
})
}
function isLoginResponse(data: unknown): data is LoginResponse {
if (!data || typeof data !== 'object') return false
const payload = data as Partial<LoginResponse>
const tokens = payload.tokens as Partial<LoginResponse['tokens']> | undefined
return Boolean(
payload.tokens &&
typeof tokens?.access === 'string' &&
typeof tokens?.refresh === 'string'
)
}
export function sendLoginCode(phone: string, scene: SendCodePayload['scene'] = 'login'): Promise<SendCodeResponse> {
return request<SendCodeResponse>('/user/auth/send-code/', {
phone,
scene
})
}
export function loginWithCode(payload: LoginCodePayload): Promise<LoginResponse> {
return request<LoginResponse>('/user/auth/login-code/', payload).then(response => {
if (isLoginResponse(response)) return response
throw new Error('登录接口返回数据格式异常')
})
}