/** Mobile API adapter with deterministic local mocks. */ export const API_BASE_URL = '' const REQUEST_TIMEOUT = 10000 const SESSION_KEY = 'aiFinanceSession' const wait = (duration: number) => new Promise((resolve) => { setTimeout(() => resolve(), duration) }) export function saveSession(token: string, phone: string): void { uni.setStorageSync(SESSION_KEY, { token, phone, loggedInAt: Date.now() }) } export function getSession(): UTSJSONObject | null { const value = uni.getStorageSync(SESSION_KEY) if (value == null) return null return value as UTSJSONObject } export function isLoggedIn(): boolean { return getSession() != null } export function clearSession(): void { uni.removeStorageSync(SESSION_KEY) } const apiMessage = (error: unknown, fallback: string): string => { if (error == null) return fallback const text = error.toString() return text.length > 0 ? text : fallback } const requestJson = (path: string, method: RequestMethod, payload: UTSJSONObject): Promise => { return new Promise((resolve, reject) => { uni.request({ url: API_BASE_URL + path, method, data: payload, timeout: REQUEST_TIMEOUT, success: (response) => { if (response.statusCode >= 200 && response.statusCode < 300) { if (response.data == null) resolve(new UTSJSONObject()) else resolve(response.data as UTSJSONObject) } else { reject('请求失败(' + response.statusCode.toString() + ')') } }, fail: (error) => { reject(apiMessage(error, '网络请求失败,请稍后重试')) } }) }) } export async function requestSmsCode(phone: string): Promise { if (API_BASE_URL.length == 0) { await wait(350) return phone.length == 11 } await requestJson('/auth/sms-code', 'POST', { phone }) return true } export async function loginWithSms(phone: string, code: string): Promise { if (API_BASE_URL.length == 0) { await wait(300) if (code.length != 6) throw '验证码应为 6 位数字' return 'demo-sms-token' } const result = await requestJson('/auth/sms-login', 'POST', { phone, code }) const token = result['token'] as string | null if (token == null || token.length == 0) throw '登录响应缺少 token' return token } export async function loginWithPassword(phone: string, password: string): Promise { if (API_BASE_URL.length == 0) { await wait(300) return 'demo-password-token' } const result = await requestJson('/auth/password-login', 'POST', { phone, password }) const token = result['token'] as string | null if (token == null || token.length == 0) throw '登录响应缺少 token' return token } export async function submitAssessment(payload: UTSJSONObject): Promise { if (API_BASE_URL.length == 0) { await wait(650) uni.setStorageSync('latestAssessment', payload) return 'ASSESSMENT-DEMO-001' } const result = await requestJson('/assessments', 'POST', payload) const id = result['id'] as string | null if (id == null || id.length == 0) throw '评估提交成功但未返回编号' return id } export async function fetchMatches(): Promise { if (API_BASE_URL.length == 0) { await wait(320) return [ { rank: 1, bank: '招商银行·闪电贷', amount: '50万', rate: '3.85%', term: '12-36期', score: 96 }, { rank: 2, bank: '平安银行·新一贷', amount: '30万', rate: '4.20%', term: '12-60期', score: 91 }, { rank: 3, bank: '建设银行·快e贷', amount: '20万', rate: '4.35%', term: '12-36期', score: 88 } ] } const result = await requestJson('/matches', 'GET', new UTSJSONObject()) const items = result['items'] as UTSJSONObject[] | null return items == null ? [] : items } export async function sendAssistantMessage(message: string): Promise { if (API_BASE_URL.length == 0) { await wait(600) return '结合您的评估结果,建议优先选择年化利率较低、可随借随还的产品,并重点确认提前还款规则。' } const result = await requestJson('/assistant/messages', 'POST', { message }) const reply = result['reply'] as string | null if (reply == null || reply.length == 0) throw '助手暂时没有返回内容' return reply } export { apiMessage }