import { STORAGE_KEYS, PAGES } from '@/config.js' export const BASE_URL = '/api/v1' const getAuthHeader = () => { const token = uni.getStorageSync(STORAGE_KEYS.TOKEN) return token ? { Authorization: `Bearer ${token}` } : {} } const request = (url, method = 'GET', data = {}) => { return new Promise((resolve, reject) => { uni.request({ url: `${BASE_URL}${url}`, method, data, header: { 'Content-Type': 'application/json', ...getAuthHeader(), }, success: (res) => { if (res.statusCode === 200) { resolve(res.data) } else if (res.statusCode === 401) { uni.removeStorageSync(STORAGE_KEYS.TOKEN) uni.reLaunch({ url: PAGES.LOGIN }) reject(new Error('Unauthorized')) } else { reject(new Error(res.data?.detail || 'Request failed')) } }, fail: (err) => { reject(err) }, }) }) } const requestWithoutAuth = (url, method = 'GET', data = {}) => { return new Promise((resolve, reject) => { uni.request({ url: `${BASE_URL}${url}`, method, data, header: { 'Content-Type': 'application/json', }, success: (res) => { if (res.statusCode === 200) { resolve(res.data) } else { reject(new Error(res.data?.detail || 'Request failed')) } }, fail: (err) => { reject(err) }, }) }) } export const authApi = { login: (phone, password) => request('/auth/login', 'POST', { username: phone, password }), register: (phone, password, username) => request('/auth/register', 'POST', { phone, password, username }), getUserInfo: () => request('/auth/me'), updateProfile: (data) => request('/auth/me', 'PUT', data), changePassword: (oldPassword, newPassword) => request('/auth/password', 'PUT', { old_password: oldPassword, new_password: newPassword }), wechatLogin: (code) => request('/auth/wechat-login', 'POST', { code }), wechatConfig: () => request('/auth/wechat/config'), guestLogin: () => requestWithoutAuth('/auth/login/guest', 'POST'), } export const marketingApi = { generate: (productName, description, category, target = 'US importers', style = 'professional') => request('/marketing/generate', 'POST', { product_name: productName, description, category, target, style, }), getKeywords: (productName, description, category = '', language = 'en', count = 10) => request('/marketing/keywords', 'POST', { product_name: productName, description, category, language, count, }), competitorAnalysis: (productName, description, category = '', market = 'US') => request('/marketing/competitor-analysis', 'POST', { product_name: productName, description, category, market, }), } export const quotationApi = { list: (page = 1, size = 20) => request(`/quotations?page=${page}&size=${size}`), get: (id) => request(`/quotations/${id}`), create: (data) => request('/quotations', 'POST', data), updateStatus: (id, status) => request(`/quotations/${id}/status`, 'PATCH', { status }), exportPdf: (id) => `${BASE_URL}/quotations/${id}/pdf`, exportCsv: () => `${BASE_URL}/quotations/export/csv`, exportXlsx: () => `${BASE_URL}/quotations/export/xlsx`, generateFromInquiry: (inquiryText, customerId = null) => request('/quotations/generate-from-inquiry', 'POST', { inquiry_text: inquiryText, customer_id: customerId }), importQuotations: (file) => { return new Promise((resolve, reject) => { const token = uni.getStorageSync(STORAGE_KEYS.TOKEN) uni.uploadFile({ url: `${BASE_URL}/quotations/import`, filePath: file, name: 'file', header: token ? { Authorization: `Bearer ${token}` } : {}, success: (res) => { try { resolve(JSON.parse(res.data)) } catch (e) { resolve(res.data) } }, fail: reject, }) }) }, } export const productApi = { list: (page = 1, size = 20) => request(`/products?page=${page}&size=${size}`), get: (id) => request(`/products/${id}`), create: (data) => request('/products', 'POST', data), update: (id, data) => request(`/products/${id}`, 'PATCH', data), delete: (id) => request(`/products/${id}`, 'DELETE'), exportCsv: () => `${BASE_URL}/products/export/csv`, exportXlsx: () => `${BASE_URL}/products/export/xlsx`, importProducts: (file) => { return new Promise((resolve, reject) => { const token = uni.getStorageSync(STORAGE_KEYS.TOKEN) uni.uploadFile({ url: `${BASE_URL}/products/import`, filePath: file, name: 'file', header: token ? { Authorization: `Bearer ${token}` } : {}, success: (res) => { try { resolve(JSON.parse(res.data)) } catch (e) { resolve(res.data) } }, fail: reject, }) }) }, } export const adminApi = { getDashboard: () => request('/admin/dashboard'), listUsers: (page = 1, size = 20, role) => { let url = `/admin/users?page=${page}&size=${size}` if (role) url += `&role=${role}` return request(url) }, updateUserTier: (userId, tier) => request(`/admin/users/${userId}/tier`, 'PATCH', { tier }), updateUserRole: (userId, role) => request(`/admin/users/${userId}/role`, 'PATCH', { role }), toggleUserActive: (userId) => request(`/admin/users/${userId}/toggle-active`, 'POST'), getUserDetail: (userId) => request(`/admin/users/${userId}`), searchUsers: (q) => request(`/admin/users/search?q=${encodeURIComponent(q)}`), getUsageStats: () => request('/admin/usage-stats'), getLogs: (page = 1, size = 50, filters = {}) => { let url = `/admin/logs?page=${page}&size=${size}` if (filters.action) url += `&action=${encodeURIComponent(filters.action)}` if (filters.user_id) url += `&user_id=${encodeURIComponent(filters.user_id)}` if (filters.date_from) url += `&date_from=${filters.date_from}` if (filters.date_to) url += `&date_to=${filters.date_to}` return request(url) }, getConfig: () => request('/admin/config'), updateConfig: (key, value) => request(`/admin/config/${key}`, 'PUT', { value }), getTranslationQuotas: () => request('/admin/translation-quotas'), updateTranslationQuota: (version, data) => request(`/admin/translation-quotas/${encodeURIComponent(version)}`, 'PUT', data), resetTranslationQuota: (version) => request(`/admin/translation-quotas/${encodeURIComponent(version)}/reset`, 'POST'), listCertifications: (page = 1, size = 20, status) => { let url = `/admin/certifications?page=${page}&size=${size}` if (status) url += `&status=${status}` return request(url) }, reviewCertification: (id, action, reason) => request(`/admin/certifications/${id}/review`, 'POST', { action, reason }), listInvoices: (page = 1, size = 20, status) => { let url = `/admin/invoices?page=${page}&size=${size}` if (status) url += `&status=${status}` return request(url) }, processInvoice: (id, action, reason) => request(`/admin/invoices/${id}/process`, 'POST', { action, reason }), } export const aiChatApi = { chat: (message, history = []) => request('/ai/chat', 'POST', { message, history }), quickQuestions: () => request('/ai/quick-questions'), } export const analyticsApi = { getOverview: () => request('/analytics/overview'), getCustomers: () => request('/analytics/customers'), getTranslations: () => request('/analytics/translations'), getQuotations: () => request('/analytics/quotations'), getMessages: () => request('/analytics/messages'), } export const teamApi = { list: () => request('/teams'), get: (id) => request(`/teams/${id}`), create: (name, description) => request('/teams', 'POST', { name, description }), invite: (teamId, userId) => request(`/teams/${teamId}/invite`, 'POST', { user_id: userId }), removeMember: (teamId, memberId) => request(`/teams/${teamId}/members/${memberId}`, 'DELETE'), leave: (teamId) => request(`/teams/${teamId}/leave`, 'POST'), updateRole: (teamId, memberId, role) => request(`/teams/${teamId}/members/${memberId}/role`, 'PATCH', { role }), } export const translateApi = { translate: (text, targetLang, sourceLang = 'auto') => request('/translate', 'POST', { text, target_lang: targetLang, source_lang: sourceLang }), getReply: (inquiry, tone = 'professional', count = 3) => request('/translate/reply', 'POST', { inquiry, tone, count }), extract: (text, extractType = 'auto') => request('/translate/extract', 'POST', { text, extract_type: extractType }), sendFeedback: (entryId, rating) => request('/translate/feedback', 'POST', { entry_id: entryId, rating }), publicTranslate: (text, targetLang, sourceLang = 'auto') => requestWithoutAuth('/translate/public/translate', 'POST', { text, target_lang: targetLang, source_lang: sourceLang }), publicExtract: (text, extractType = 'auto') => requestWithoutAuth('/translate/public/extract', 'POST', { text, extract_type: extractType }), } export const notificationApi = { list: (page = 1, size = 20, unreadOnly = false) => request(`/notifications?page=${page}&size=${size}&unread_only=${unreadOnly}`), unreadCount: () => request('/notifications/unread-count'), markRead: (id) => request(`/notifications/${id}/read`, 'PATCH'), markAllRead: () => request('/notifications/read-all', 'POST'), delete: (id) => request(`/notifications/${id}`, 'DELETE'), } export const paymentApi = { plans: () => request('/payment/plans'), subscription: () => request('/payment/subscription'), createOrder: (plan, payType = 'jsapi') => request('/payment/create-order', 'POST', { plan, pay_type: payType }), } export const feedbackApi = { submit: (content, category = 'general', contact = '') => request('/feedback', 'POST', { content, category, contact }), } export const onboardingApi = { status: () => request('/onboarding/status'), createProduct: (name, description, category, target) => request('/onboarding/product', 'POST', { name, description, category, target }), } export const interactionApi = { selectSuggestion: (messageId, selectedIndex) => request('/interaction/select', 'POST', { message_id: messageId, selected_index: selectedIndex }), recordEdit: (messageId, editedText) => request('/interaction/edit', 'POST', { message_id: messageId, edited_text: editedText }), analyzePreferences: () => request('/interaction/analyze', 'POST'), getPreferences: () => request('/interaction/preferences'), trackMarketingEffect: (data) => request('/interaction/marketing-effect', 'POST', data), getMarketingEffects: (page = 1, size = 20) => request(`/interaction/marketing-effects?page=${page}&size=${size}`), getMarketingEffectStats: () => request('/interaction/marketing-effects/stats'), } export const exchangeApi = { convert: (fromCurrency = 'USD', toCurrency = 'CNY', amount = 1) => request(`/exchange/convert?from_currency=${fromCurrency}&to_currency=${toCurrency}&amount=${amount}`), rates: (base = 'USD') => request(`/exchange/rates?base=${base}`), } export const pushApi = { register: (clientId, platform = 'weapp', pushToken = null, deviceInfo = null) => request('/push/register', 'POST', { client_id: clientId, platform, push_token: pushToken, device_info: deviceInfo }), unregister: (clientId) => request('/push/unregister', 'POST', { client_id: clientId }), listDevices: () => request('/push/devices'), } export const silentPatternApi = { getRiskAnalysis: () => request('/silent-pattern/risk-analysis'), getSuggestions: (customerId) => request(`/silent-pattern/${customerId}/suggestions`), } export const followupApi = { strategies: () => request('/followup/strategies'), pending: (page = 1) => request(`/followup/pending?page=${page}`), logs: (page = 1) => request(`/followup/logs?page=${page}`), markSent: (id) => request(`/followup/${id}/send`, 'POST'), editAndSend: (id, editedText) => request(`/followup/${id}/edit`, 'POST', { edited_text: editedText }), stats: () => request('/followup/stats'), scan: () => request('/followup/scan', 'POST'), } export const healthApi = { overview: () => request('/customers/health-overview'), allScores: () => request('/customers/health-scores'), customerHealth: (id) => request(`/customers/${id}/health`), } export const whatsappApi = { send: (to, text, templateName = null, templateParams = null, mediaUrl = null, mediaType = null) => request('/whatsapp/send', 'POST', { to, text, template_name: templateName, template_params: templateParams, media_url: mediaUrl, media_type: mediaType }), } export const certificationApi = { submit: (data) => request('/certification/submit', 'POST', data), status: () => request('/certification/status'), } export const invoiceApi = { apply: (data) => request('/invoices/apply', 'POST', data), list: () => request('/invoices/list'), } export const customerApi = { list: (page = 1, size = 20, status) => { let params = `page=${page}&size=${size}` if (status) params += `&status=${status}` return request(`/customers?${params}`) }, get: (id) => request(`/customers/${id}`), create: (data) => request('/customers', 'POST', data), update: (id, data) => request(`/customers/${id}`, 'PATCH', data), delete: (id) => request(`/customers/${id}`, 'DELETE'), getSilent: (days = 3) => request(`/customers/silent?days=${days}`), getConversation: (id, page = 1, size = 50) => request(`/customers/${id}/conversation?page=${page}&size=${size}`), exportCsv: () => `${BASE_URL}/customers/export/csv`, exportXlsx: () => `${BASE_URL}/customers/export/xlsx`, importCustomers: (file) => { return new Promise((resolve, reject) => { const token = uni.getStorageSync(STORAGE_KEYS.TOKEN) uni.uploadFile({ url: `${BASE_URL}/customers/import`, filePath: file, name: 'file', header: token ? { Authorization: `Bearer ${token}` } : {}, success: (res) => { try { resolve(JSON.parse(res.data)) } catch (e) { resolve(res.data) } }, fail: reject, }) }) }, }