/** Mobile API adapter with deterministic local mocks. */ import { demoProducts, parseProduct, FinanceProduct } from '@/services/finance.uts' 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 || typeof value != 'object') return null return value as UTSJSONObject } export function isLoggedIn(): boolean { return getSession() != null } export function clearSession(): void { uni.removeStorageSync(SESSION_KEY) } const apiMessage = (error: any | null, 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 new Error('验证码应为 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 new Error('登录响应缺少 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 new Error('登录响应缺少 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 new Error('评估提交成功但未返回编号') return id } export async function fetchMatches(): Promise { if (API_BASE_URL.length == 0) { await wait(320) return demoProducts.slice() } const result = await requestJson('/matches', 'GET', new UTSJSONObject()) const items = result['items'] as UTSJSONObject[] | null return items == null ? [] : items.map((item: UTSJSONObject): FinanceProduct => parseProduct(item)) } export async function fetchProduct(id: string): Promise { if (API_BASE_URL.length == 0) { await wait(180) const products = demoProducts.filter((item: FinanceProduct): boolean => item.id == id) return products.length > 0 ? products[0] : null } const result = await requestJson('/products/' + encodeURIComponent(id), 'GET', new UTSJSONObject()) return parseProduct(result) } 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 new Error('助手暂时没有返回内容') return reply } export { apiMessage }