/* 碰盏日记 - API 服务层 * 基于 HaveADrink SDK 封装后端接口 */ import HaveADrink from 'HaveADrink' // ========================================== // 后端服务地址(切换环境只需改这里) // ========================================== const API_HOST = 'https://dev.wash-painting.cn' // ========================================== // HTTP 请求函数(供 SDK 内部调用) // 参考 goodBooth 项目的 fetchsomething // ========================================== function httpRequest(url, params) { // 支持静默模式(如后台刷新token),不弹 toast 不跳转 const silent = params.silent === true return new Promise((resolve, reject) => { // 自动注入 Authorization token const headers = Object.assign({}, params.headers || {}) const token = uni.getStorageSync('auth_token') if (token) { headers['Authorization'] = `Bearer ${token}` } uni.request({ url: url, method: params.method, params: params.query || undefined, data: params.data, header: headers, success: (res) => { const code = res.statusCode if (code === 200 || code === 201 || code === 204) { resolve(res.data) } else if (code === 401 || code === 418) { // token/refresh_token 过期或无效,清除登录态 uni.removeStorageSync('auth_token') uni.removeStorageSync('refresh_token') uni.removeStorageSync('is_logged_in') if (!silent) { uni.reLaunch({ url: '/pages/login/login' }) uni.showToast({ title: '登录已过期,请重新登录', icon: 'none', duration: 2500 }) } reject({ msg: '登录已过期,请重新登录', code }) } else { const rawMsg = (res.data && res.data.msg) || (res.data && res.data.errmsg) || '请求失败' const errMsg = `[${code}] ${rawMsg}` if (!silent) { uni.showToast({ title: errMsg, icon: 'none', duration: 2500 }) } reject({ msg: errMsg, code }) } }, fail: (err) => { const msg = (err && err.errMsg) || '网络请求失败' if (!silent) { uni.showToast({ title: msg, icon: 'none', duration: 2500 }) } reject({ msg }) } }) }) } // ========================================== // 文件上传函数(供 SDK 内部调用) // ========================================== function uploadRequest(url, params) { return new Promise((resolve, reject) => { const headers = Object.assign({}, params.headers || {}) const token = uni.getStorageSync('auth_token') if (token) { headers['Authorization'] = `Bearer ${token}` } uni.uploadFile({ url: url, filePath: params.data.fileName || params.data.filePath, name: params.data.name || 'file', header: headers, formData: params.data.formData || {}, success: (uploadRes) => { try { const data = typeof uploadRes.data === 'string' ? JSON.parse(uploadRes.data) : uploadRes.data resolve(data) } catch (e) { resolve(uploadRes.data) } }, fail: (err) => { reject({ msg: err.errMsg || '上传失败' }) } }) }) } // ========================================== // 初始化 SDK 实例 // ========================================== const client = new HaveADrink({ host: API_HOST, http_request: httpRequest, upload: uploadRequest, token: uni.getStorageSync('auth_token') || '' }) // ========================================== // 导出 SDK 实例(各页面直接 import 使用) // ========================================== export default client // ========================================== // Token 管理辅助函数 // ========================================== /** 登录成功后保存 token 并同步到 SDK */ export function saveAuthTokens(data) { if (data.token) { uni.setStorageSync('auth_token', data.token) client.setToken(data.token) } if (data.refresh_token) { uni.setStorageSync('refresh_token', data.refresh_token) } } /** 清除所有认证信息 */ export function clearAuth() { uni.removeStorageSync('auth_token') uni.removeStorageSync('refresh_token') uni.removeStorageSync('is_logged_in') uni.removeStorageSync('is_guest') uni.removeStorageSync('user_info') client.setToken('') } /** 尝试用 refresh_token 刷新 token(静默,不弹提示不跳转) */ export async function refreshAuthToken() { const refreshToken = uni.getStorageSync('refresh_token') if (!refreshToken) return false try { const res = await client.RefreshToken({ refresh_token: refreshToken, silent: true }) if (res && res.token) { saveAuthTokens(res) return true } return false } catch (e) { // 静默失败:refresh token 无效时清除残留凭证 uni.removeStorageSync('refresh_token') return false } } // ========================================== // 酒友圈 API(当前返回 Mock 数据,后端就绪后切换为 SDK 调用) // ========================================== import { MOCK_FEEDS, MOCK_COMMENTS, MOCK_FRIENDS, MOCK_FRIEND_REQUESTS, MOCK_EVENTS, MOCK_CONVERSATIONS, MOCK_MESSAGES } from './mock-data' /** 模拟网络延迟 */ function mockDelay(data, ms = 300) { return new Promise(resolve => setTimeout(() => resolve({ data }), ms)) } /** 获取动态信息流 */ export function GetCircleFeeds({ page = 1, pageSize = 10 } = {}) { // TODO: 后端就绪后替换为 client.GetCircleFeeds(...) const start = (page - 1) * pageSize const list = MOCK_FEEDS.slice(start, start + pageSize) return mockDelay({ list, total: MOCK_FEEDS.length, hasMore: start + pageSize < MOCK_FEEDS.length }) } /** 点赞动态 */ export function LikeFeed({ feedId }) { return mockDelay({ success: true }) } /** 取消点赞 */ export function UnlikeFeed({ feedId }) { return mockDelay({ success: true }) } /** 获取动态评论 */ export function GetFeedComments({ feedId }) { const list = MOCK_COMMENTS[feedId] || [] return mockDelay({ list }) } /** 发表评论 */ export function AddComment({ feedId, content }) { return mockDelay({ success: true, comment: { id: 'c_' + Date.now(), content, time: '刚刚' } }) } /** 发布动态 */ export function PublishFeed({ text, images, recordId, visibility }) { return mockDelay({ success: true, feedId: 'feed_' + Date.now() }) } /** 获取酒友列表 */ export function GetFriends({ keyword = '' } = {}) { const list = keyword ? MOCK_FRIENDS.filter(f => f.nickname.includes(keyword)) : MOCK_FRIENDS return mockDelay({ list }) } /** 获取好友请求 */ export function GetFriendRequests() { return mockDelay({ list: MOCK_FRIEND_REQUESTS }) } /** 发送好友请求 */ export function SendFriendRequest({ userId }) { return mockDelay({ success: true }) } /** 接受好友请求 */ export function AcceptFriendRequest({ requestId }) { return mockDelay({ success: true }) } /** 删除酒友 */ export function RemoveFriend({ userId }) { return mockDelay({ success: true }) } /** 获取酒局列表 */ export function GetEvents({ status = '' } = {}) { const list = status ? MOCK_EVENTS.filter(e => e.status === status) : MOCK_EVENTS return mockDelay({ list }) } /** 获取酒局详情 */ export function GetEventDetail({ eventId }) { const evt = MOCK_EVENTS.find(e => e.id === eventId) || MOCK_EVENTS[0] return mockDelay(evt) } /** 发起酒局 */ export function CreateEvent({ title, time, location, maxPeople, note }) { return mockDelay({ success: true, eventId: 'evt_' + Date.now() }) } /** 报名酒局 */ export function JoinEvent({ eventId }) { return mockDelay({ success: true }) } /** 取消报名 */ export function QuitEvent({ eventId }) { return mockDelay({ success: true }) } /** 酒局签到 */ export function CheckInEvent({ eventId }) { return mockDelay({ success: true }) } // ========================================== // 私信 API(当前返回 Mock 数据,后端就绪后切换为 SDK 调用) // ========================================== /** 获取会话列表 */ export function GetConversations() { // TODO: 后端就绪后替换为 client.GetConversations(...) return mockDelay({ list: MOCK_CONVERSATIONS }) } /** 获取历史消息 */ export function GetMessages({ conversationId, page = 1, pageSize = 20 } = {}) { // TODO: 后端就绪后替换为 client.GetMessages(...) const all = MOCK_MESSAGES[conversationId] || [] const start = (page - 1) * pageSize const list = all.slice(start, start + pageSize) return mockDelay({ list, hasMore: start + pageSize < all.length }) } /** 标记会话已读 */ export function MarkRead({ conversationId }) { // TODO: 后端就绪后替换为 client.MarkRead(...) return mockDelay({ success: true }) } /** 获取未读消息总数 */ export function GetUnreadCount() { // TODO: 后端就绪后替换为 client.GetUnreadCount(...) const total = MOCK_CONVERSATIONS.reduce((sum, c) => sum + c.unread, 0) return mockDelay({ total }) }