diff --git a/admin-system/src/pages/Login.vue b/admin-system/src/pages/Login.vue index 5052ece..858d9a4 100644 --- a/admin-system/src/pages/Login.vue +++ b/admin-system/src/pages/Login.vue @@ -98,6 +98,8 @@ const onFinish = async (values: FormState) => { // 保存token if (response?.data?.token) { localStorage.setItem('admin_token', response.data.token) + } else if (response?.token) { + localStorage.setItem('admin_token', response.token) } else { throw new Error('登录响应中缺少token') } @@ -105,6 +107,8 @@ const onFinish = async (values: FormState) => { // 更新用户状态 if (response?.data?.admin) { appStore.setUser(response.data.admin) + } else if (response?.admin) { + appStore.setUser(response.admin) } else { throw new Error('登录响应中缺少用户信息') } diff --git a/backend/src/controllers/authControllerMySQL.js b/backend/src/controllers/authControllerMySQL.js index 57e91a6..437eee4 100644 --- a/backend/src/controllers/authControllerMySQL.js +++ b/backend/src/controllers/authControllerMySQL.js @@ -296,9 +296,10 @@ const adminLogin = async (req, res, next) => { // 更新最后登录时间 await UserMySQL.updateLastLogin(user.id); + // 调整返回数据结构以匹配前端期望的格式 res.json(success({ - user: UserMySQL.sanitize(user), token, + admin: UserMySQL.sanitize(user), message: '管理员登录成功' })); } catch (error) { diff --git a/mini-program/unpackage/dist/dev/.sourcemap/mp-weixin/api/config.js.map b/mini-program/unpackage/dist/dev/.sourcemap/mp-weixin/api/config.js.map index 7d1d873..6a43add 100644 --- a/mini-program/unpackage/dist/dev/.sourcemap/mp-weixin/api/config.js.map +++ b/mini-program/unpackage/dist/dev/.sourcemap/mp-weixin/api/config.js.map @@ -1 +1 @@ -{"version":3,"file":"config.js","sources":["api/config.js"],"sourcesContent":["// API基础配置\nconst config = {\n // 开发环境\n development: {\n baseURL: 'http://localhost:3100/api',\n timeout: 10000\n },\n // 生产环境\n production: {\n baseURL: 'https://api.jiebanke.com/api',\n timeout: 15000\n }\n}\n\n// 获取当前环境配置\nconst getConfig = () => {\n const env = process.env.NODE_ENV || 'development'\n return config[env]\n}\n\n// API端点\nconst endpoints = {\n // 用户相关\n USER: {\n LOGIN: '/auth/login',\n REGISTER: '/auth/register',\n PROFILE: '/user/profile',\n UPDATE_PROFILE: '/user/profile',\n UPLOAD_AVATAR: '/user/avatar'\n },\n \n // 旅行计划\n TRAVEL: {\n LIST: '/travel/list',\n DETAIL: '/travel/detail',\n CREATE: '/travel/create',\n JOIN: '/travel/join',\n MY_PLANS: '/travel/my-plans',\n SEARCH: '/travel/search'\n },\n \n // 动物认养\n ANIMAL: {\n LIST: '/animal/list',\n DETAIL: '/animal/detail',\n ADOPT: '/animal/adopt',\n MY_ANIMALS: '/animal/my-animals',\n CATEGORIES: '/animal/categories'\n },\n \n // 送花服务\n FLOWER: {\n LIST: '/flower/list',\n DETAIL: '/flower/detail',\n ORDER: '/flower/order',\n MY_ORDERS: '/flower/my-orders',\n CATEGORIES: '/flower/categories'\n },\n \n // 订单管理\n ORDER: {\n LIST: '/order/list',\n DETAIL: '/order/detail',\n CANCEL: '/order/cancel',\n PAY: '/order/pay',\n CONFIRM: '/order/confirm'\n },\n \n // 支付相关\n PAYMENT: {\n CREATE: '/payment/create',\n QUERY: '/payment/query',\n REFUND: '/payment/refund'\n },\n \n // 系统相关\n SYSTEM: {\n CONFIG: '/system/config',\n NOTICE: '/system/notice',\n FEEDBACK: '/system/feedback'\n }\n}\n\nexport default {\n ...getConfig(),\n endpoints\n}"],"names":[],"mappings":";AACA,MAAM,SAAS;AAAA;AAAA,EAEb,aAAa;AAAA,IACX,SAAS;AAAA,IACT,SAAS;AAAA,EACX;AAAA;AAAA,EAEA,YAAY;AAAA,IACV,SAAS;AAAA,IACT,SAAS;AAAA,EACX;AACF;AAGA,MAAM,YAAY,MAAM;AACtB,QAAM,MAAM;AACZ,SAAO,OAAO,GAAG;AACnB;AAGA,MAAM,YAAY;AAAA;AAAA,EAEhB,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAGA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ;AAAA,EACV;AAAA;AAAA,EAGA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AAAA;AAAA,EAGA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,WAAW;AAAA,IACX,YAAY;AAAA,EACd;AAAA;AAAA,EAGA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,SAAS;AAAA,EACX;AAAA;AAAA,EAGA,SAAS;AAAA,IACP,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAAA;AAAA,EAGA,QAAQ;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,UAAU;AAAA,EACZ;AACF;AAEA,MAAe,WAAA;AAAA,EACb,GAAG,UAAU;AAAA,EACb;AACF;;"} \ No newline at end of file +{"version":3,"file":"config.js","sources":["api/config.js"],"sourcesContent":["// API基础配置\r\nconst config = {\r\n // 开发环境\r\n development: {\r\n baseURL: 'http://localhost:3100/api',\r\n timeout: 10000\r\n },\r\n // 生产环境\r\n production: {\r\n baseURL: 'https://api.jiebanke.com/api',\r\n timeout: 15000\r\n }\r\n}\r\n\r\n// 获取当前环境配置\r\nconst getConfig = () => {\r\n const env = process.env.NODE_ENV || 'development'\r\n return config[env]\r\n}\r\n\r\n// API端点\r\nconst endpoints = {\r\n // 用户相关\r\n USER: {\r\n LOGIN: '/auth/login',\r\n REGISTER: '/auth/register',\r\n PROFILE: '/user/profile',\r\n UPDATE_PROFILE: '/user/profile',\r\n UPLOAD_AVATAR: '/user/avatar'\r\n },\r\n \r\n // 旅行计划\r\n TRAVEL: {\r\n LIST: '/travel/list',\r\n DETAIL: '/travel/detail',\r\n CREATE: '/travel/create',\r\n JOIN: '/travel/join',\r\n MY_PLANS: '/travel/my-plans',\r\n SEARCH: '/travel/search'\r\n },\r\n \r\n // 动物认养\r\n ANIMAL: {\r\n LIST: '/animal/list',\r\n DETAIL: '/animal/detail',\r\n ADOPT: '/animal/adopt',\r\n MY_ANIMALS: '/animal/my-animals',\r\n CATEGORIES: '/animal/categories'\r\n },\r\n \r\n // 送花服务\r\n FLOWER: {\r\n LIST: '/flower/list',\r\n DETAIL: '/flower/detail',\r\n ORDER: '/flower/order',\r\n MY_ORDERS: '/flower/my-orders',\r\n CATEGORIES: '/flower/categories'\r\n },\r\n \r\n // 订单管理\r\n ORDER: {\r\n LIST: '/order/list',\r\n DETAIL: '/order/detail',\r\n CANCEL: '/order/cancel',\r\n PAY: '/order/pay',\r\n CONFIRM: '/order/confirm'\r\n },\r\n \r\n // 支付相关\r\n PAYMENT: {\r\n CREATE: '/payment/create',\r\n QUERY: '/payment/query',\r\n REFUND: '/payment/refund'\r\n },\r\n \r\n // 系统相关\r\n SYSTEM: {\r\n CONFIG: '/system/config',\r\n NOTICE: '/system/notice',\r\n FEEDBACK: '/system/feedback'\r\n }\r\n}\r\n\r\nexport default {\r\n ...getConfig(),\r\n endpoints\r\n}"],"names":[],"mappings":";AACA,MAAM,SAAS;AAAA;AAAA,EAEb,aAAa;AAAA,IACX,SAAS;AAAA,IACT,SAAS;AAAA,EACX;AAAA;AAAA,EAEA,YAAY;AAAA,IACV,SAAS;AAAA,IACT,SAAS;AAAA,EACX;AACF;AAGA,MAAM,YAAY,MAAM;AACtB,QAAM,MAAM;AACZ,SAAO,OAAO,GAAG;AACnB;AAGA,MAAM,YAAY;AAAA;AAAA,EAEhB,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,UAAU;AAAA,IACV,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAAA;AAAA,EAGA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ;AAAA,EACV;AAAA;AAAA,EAGA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AAAA;AAAA,EAGA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,WAAW;AAAA,IACX,YAAY;AAAA,EACd;AAAA;AAAA,EAGA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,SAAS;AAAA,EACX;AAAA;AAAA,EAGA,SAAS;AAAA,IACP,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAAA;AAAA,EAGA,QAAQ;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,UAAU;AAAA,EACZ;AACF;AAEA,MAAe,WAAA;AAAA,EACb,GAAG,UAAU;AAAA,EACb;AACF;;"} \ No newline at end of file diff --git a/mini-program/unpackage/dist/dev/.sourcemap/mp-weixin/api/request.js.map b/mini-program/unpackage/dist/dev/.sourcemap/mp-weixin/api/request.js.map index cf5f776..4e8069c 100644 --- a/mini-program/unpackage/dist/dev/.sourcemap/mp-weixin/api/request.js.map +++ b/mini-program/unpackage/dist/dev/.sourcemap/mp-weixin/api/request.js.map @@ -1 +1 @@ -{"version":3,"file":"request.js","sources":["api/request.js"],"sourcesContent":["import config from './config.js'\n\n// 请求队列(用于处理token刷新)\nconst requestQueue = []\nlet isRefreshing = false\n\nclass Request {\n constructor() {\n this.baseURL = config.baseURL\n this.timeout = config.timeout\n this.interceptors = {\n request: [],\n response: []\n }\n }\n\n // 添加请求拦截器\n addRequestInterceptor(interceptor) {\n this.interceptors.request.push(interceptor)\n }\n\n // 添加响应拦截器\n addResponseInterceptor(interceptor) {\n this.interceptors.response.push(interceptor)\n }\n\n // 执行请求拦截器\n async runRequestInterceptors(config) {\n for (const interceptor of this.interceptors.request) {\n config = await interceptor(config)\n }\n return config\n }\n\n // 执行响应拦截器\n async runResponseInterceptors(response) {\n for (const interceptor of this.interceptors.response) {\n response = await interceptor(response)\n }\n return response\n }\n\n // 核心请求方法\n async request(options) {\n try {\n // 合并配置\n const requestConfig = {\n url: options.url.startsWith('http') ? options.url : `${this.baseURL}${options.url}`,\n method: options.method || 'GET',\n header: {\n 'Content-Type': 'application/json',\n ...options.header\n },\n data: options.data,\n timeout: this.timeout\n }\n\n // 执行请求拦截器\n const finalConfig = await this.runRequestInterceptors(requestConfig)\n\n // 发起请求\n const response = await uni.request(finalConfig)\n\n // 执行响应拦截器\n const finalResponse = await this.runResponseInterceptors(response)\n\n return finalResponse[1] // uni.request返回的是数组[error, success]\n } catch (error) {\n console.error('Request error:', error)\n throw error\n }\n }\n\n // GET请求\n get(url, data = {}, options = {}) {\n return this.request({\n url,\n method: 'GET',\n data,\n ...options\n })\n }\n\n // POST请求\n post(url, data = {}, options = {}) {\n return this.request({\n url,\n method: 'POST',\n data,\n ...options\n })\n }\n\n // PUT请求\n put(url, data = {}, options = {}) {\n return this.request({\n url,\n method: 'PUT',\n data,\n ...options\n })\n }\n\n // DELETE请求\n delete(url, data = {}, options = {}) {\n return this.request({\n url,\n method: 'DELETE',\n data,\n ...options\n })\n }\n\n // 上传文件\n upload(url, filePath, formData = {}, options = {}) {\n return new Promise((resolve, reject) => {\n uni.uploadFile({\n url: `${this.baseURL}${url}`,\n filePath,\n name: 'file',\n formData,\n success: resolve,\n fail: reject,\n ...options\n })\n })\n }\n\n // 下载文件\n download(url, options = {}) {\n return new Promise((resolve, reject) => {\n uni.downloadFile({\n url: `${this.baseURL}${url}`,\n success: resolve,\n fail: reject,\n ...options\n })\n })\n }\n}\n\n// 创建请求实例\nconst request = new Request()\n\n// 添加请求拦截器 - Token处理\nrequest.addRequestInterceptor(async (config) => {\n const token = uni.getStorageSync('token')\n if (token) {\n config.header.Authorization = `Bearer ${token}`\n }\n return config\n})\n\n// 添加响应拦截器 - 错误处理\nrequest.addResponseInterceptor(async (response) => {\n const { statusCode, data } = response\n \n if (statusCode === 200) {\n if (data.code === 0) {\n return data.data\n } else {\n // 业务错误\n const error = new Error(data.message || '业务错误')\n error.code = data.code\n throw error\n }\n } else if (statusCode === 401) {\n // Token过期,尝试刷新\n return handleTokenExpired(response)\n } else {\n // 网络错误\n throw new Error(`网络错误: ${statusCode}`)\n }\n})\n\n// Token过期处理\nasync function handleTokenExpired(response) {\n if (isRefreshing) {\n // 如果正在刷新,将请求加入队列\n return new Promise((resolve) => {\n requestQueue.push(() => resolve(request.request(response.config)))\n })\n }\n\n isRefreshing = true\n const refreshToken = uni.getStorageSync('refreshToken')\n \n if (!refreshToken) {\n // 没有refreshToken,跳转到登录页\n uni.navigateTo({ url: '/pages/auth/login' })\n throw new Error('请重新登录')\n }\n\n try {\n // 尝试刷新Token\n const result = await request.post(config.endpoints.USER.REFRESH_TOKEN, {\n refreshToken\n })\n\n // 保存新Token\n uni.setStorageSync('token', result.token)\n uni.setStorageSync('refreshToken', result.refreshToken)\n\n // 重试原始请求\n const retryResponse = await request.request(response.config)\n \n // 处理队列中的请求\n processRequestQueue()\n \n return retryResponse\n } catch (error) {\n // 刷新失败,清空Token并跳转登录\n uni.removeStorageSync('token')\n uni.removeStorageSync('refreshToken')\n uni.navigateTo({ url: '/pages/auth/login' })\n throw error\n } finally {\n isRefreshing = false\n }\n}\n\n// 处理请求队列\nfunction processRequestQueue() {\n while (requestQueue.length > 0) {\n const retry = requestQueue.shift()\n retry()\n }\n}\n\nexport default request"],"names":["config","uni"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"request.js","sources":["api/request.js"],"sourcesContent":["import config from './config.js'\r\n\r\n// 请求队列(用于处理token刷新)\r\nconst requestQueue = []\r\nlet isRefreshing = false\r\n\r\nclass Request {\r\n constructor() {\r\n this.baseURL = config.baseURL\r\n this.timeout = config.timeout\r\n this.interceptors = {\r\n request: [],\r\n response: []\r\n }\r\n }\r\n\r\n // 添加请求拦截器\r\n addRequestInterceptor(interceptor) {\r\n this.interceptors.request.push(interceptor)\r\n }\r\n\r\n // 添加响应拦截器\r\n addResponseInterceptor(interceptor) {\r\n this.interceptors.response.push(interceptor)\r\n }\r\n\r\n // 执行请求拦截器\r\n async runRequestInterceptors(config) {\r\n for (const interceptor of this.interceptors.request) {\r\n config = await interceptor(config)\r\n }\r\n return config\r\n }\r\n\r\n // 执行响应拦截器\r\n async runResponseInterceptors(response) {\r\n for (const interceptor of this.interceptors.response) {\r\n response = await interceptor(response)\r\n }\r\n return response\r\n }\r\n\r\n // 核心请求方法\r\n async request(options) {\r\n try {\r\n // 合并配置\r\n const requestConfig = {\r\n url: options.url.startsWith('http') ? options.url : `${this.baseURL}${options.url}`,\r\n method: options.method || 'GET',\r\n header: {\r\n 'Content-Type': 'application/json',\r\n ...options.header\r\n },\r\n data: options.data,\r\n timeout: this.timeout\r\n }\r\n\r\n // 执行请求拦截器\r\n const finalConfig = await this.runRequestInterceptors(requestConfig)\r\n\r\n // 发起请求\r\n const response = await uni.request(finalConfig)\r\n\r\n // 执行响应拦截器\r\n const finalResponse = await this.runResponseInterceptors(response)\r\n\r\n return finalResponse[1] // uni.request返回的是数组[error, success]\r\n } catch (error) {\r\n console.error('Request error:', error)\r\n throw error\r\n }\r\n }\r\n\r\n // GET请求\r\n get(url, data = {}, options = {}) {\r\n return this.request({\r\n url,\r\n method: 'GET',\r\n data,\r\n ...options\r\n })\r\n }\r\n\r\n // POST请求\r\n post(url, data = {}, options = {}) {\r\n return this.request({\r\n url,\r\n method: 'POST',\r\n data,\r\n ...options\r\n })\r\n }\r\n\r\n // PUT请求\r\n put(url, data = {}, options = {}) {\r\n return this.request({\r\n url,\r\n method: 'PUT',\r\n data,\r\n ...options\r\n })\r\n }\r\n\r\n // DELETE请求\r\n delete(url, data = {}, options = {}) {\r\n return this.request({\r\n url,\r\n method: 'DELETE',\r\n data,\r\n ...options\r\n })\r\n }\r\n\r\n // 上传文件\r\n upload(url, filePath, formData = {}, options = {}) {\r\n return new Promise((resolve, reject) => {\r\n uni.uploadFile({\r\n url: `${this.baseURL}${url}`,\r\n filePath,\r\n name: 'file',\r\n formData,\r\n success: resolve,\r\n fail: reject,\r\n ...options\r\n })\r\n })\r\n }\r\n\r\n // 下载文件\r\n download(url, options = {}) {\r\n return new Promise((resolve, reject) => {\r\n uni.downloadFile({\r\n url: `${this.baseURL}${url}`,\r\n success: resolve,\r\n fail: reject,\r\n ...options\r\n })\r\n })\r\n }\r\n}\r\n\r\n// 创建请求实例\r\nconst request = new Request()\r\n\r\n// 添加请求拦截器 - Token处理\r\nrequest.addRequestInterceptor(async (config) => {\r\n const token = uni.getStorageSync('token')\r\n if (token) {\r\n config.header.Authorization = `Bearer ${token}`\r\n }\r\n return config\r\n})\r\n\r\n// 添加响应拦截器 - 错误处理\r\nrequest.addResponseInterceptor(async (response) => {\r\n const { statusCode, data } = response\r\n \r\n if (statusCode === 200) {\r\n if (data.code === 0) {\r\n return data.data\r\n } else {\r\n // 业务错误\r\n const error = new Error(data.message || '业务错误')\r\n error.code = data.code\r\n throw error\r\n }\r\n } else if (statusCode === 401) {\r\n // Token过期,尝试刷新\r\n return handleTokenExpired(response)\r\n } else {\r\n // 网络错误\r\n throw new Error(`网络错误: ${statusCode}`)\r\n }\r\n})\r\n\r\n// Token过期处理\r\nasync function handleTokenExpired(response) {\r\n if (isRefreshing) {\r\n // 如果正在刷新,将请求加入队列\r\n return new Promise((resolve) => {\r\n requestQueue.push(() => resolve(request.request(response.config)))\r\n })\r\n }\r\n\r\n isRefreshing = true\r\n const refreshToken = uni.getStorageSync('refreshToken')\r\n \r\n if (!refreshToken) {\r\n // 没有refreshToken,跳转到登录页\r\n uni.navigateTo({ url: '/pages/auth/login' })\r\n throw new Error('请重新登录')\r\n }\r\n\r\n try {\r\n // 尝试刷新Token\r\n const result = await request.post(config.endpoints.USER.REFRESH_TOKEN, {\r\n refreshToken\r\n })\r\n\r\n // 保存新Token\r\n uni.setStorageSync('token', result.token)\r\n uni.setStorageSync('refreshToken', result.refreshToken)\r\n\r\n // 重试原始请求\r\n const retryResponse = await request.request(response.config)\r\n \r\n // 处理队列中的请求\r\n processRequestQueue()\r\n \r\n return retryResponse\r\n } catch (error) {\r\n // 刷新失败,清空Token并跳转登录\r\n uni.removeStorageSync('token')\r\n uni.removeStorageSync('refreshToken')\r\n uni.navigateTo({ url: '/pages/auth/login' })\r\n throw error\r\n } finally {\r\n isRefreshing = false\r\n }\r\n}\r\n\r\n// 处理请求队列\r\nfunction processRequestQueue() {\r\n while (requestQueue.length > 0) {\r\n const retry = requestQueue.shift()\r\n retry()\r\n }\r\n}\r\n\r\nexport default request"],"names":["config","uni"],"mappings":"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"} \ No newline at end of file diff --git a/mini-program/unpackage/dist/dev/.sourcemap/mp-weixin/api/services.js.map b/mini-program/unpackage/dist/dev/.sourcemap/mp-weixin/api/services.js.map index 75e10f9..e0531bb 100644 --- a/mini-program/unpackage/dist/dev/.sourcemap/mp-weixin/api/services.js.map +++ b/mini-program/unpackage/dist/dev/.sourcemap/mp-weixin/api/services.js.map @@ -1 +1 @@ -{"version":3,"file":"services.js","sources":["api/services.js"],"sourcesContent":["import request from './request.js'\nimport config from './config.js'\n\nconst { endpoints } = config\n\n// 用户服务\nexport const userService = {\n // 登录\n login: (data) => request.post(endpoints.USER.LOGIN, data),\n \n // 注册\n register: (data) => request.post(endpoints.USER.REGISTER, data),\n \n // 获取用户信息\n getProfile: () => request.get(endpoints.USER.PROFILE),\n \n // 更新用户信息\n updateProfile: (data) => request.put(endpoints.USER.UPDATE_PROFILE, data),\n \n // 上传头像\n uploadAvatar: (filePath) => request.upload(endpoints.USER.UPLOAD_AVATAR, filePath),\n \n // 退出登录\n logout: () => {\n uni.removeStorageSync('token')\n uni.removeStorageSync('refreshToken')\n return Promise.resolve()\n }\n}\n\n// 旅行计划服务\nexport const travelService = {\n // 获取旅行计划列表\n getList: (params = {}) => request.get(endpoints.TRAVEL.LIST, params),\n \n // 获取旅行计划详情\n getDetail: (id) => request.get(`${endpoints.TRAVEL.DETAIL}/${id}`),\n \n // 创建旅行计划\n create: (data) => request.post(endpoints.TRAVEL.CREATE, data),\n \n // 加入旅行计划\n join: (travelId) => request.post(`${endpoints.TRAVEL.JOIN}/${travelId}`),\n \n // 获取我的旅行计划\n getMyPlans: (params = {}) => request.get(endpoints.TRAVEL.MY_PLANS, params),\n \n // 搜索旅行计划\n search: (keyword, params = {}) => request.get(endpoints.TRAVEL.SEARCH, { keyword, ...params })\n}\n\n// 动物认养服务\nexport const animalService = {\n // 获取动物列表\n getList: (params = {}) => request.get(endpoints.ANIMAL.LIST, params),\n \n // 获取动物详情\n getDetail: (id) => request.get(`${endpoints.ANIMAL.DETAIL}/${id}`),\n \n // 认养动物\n adopt: (animalId, data) => request.post(`${endpoints.ANIMAL.ADOPT}/${animalId}`, data),\n \n // 获取我的动物\n getMyAnimals: (params = {}) => request.get(endpoints.ANIMAL.MY_ANIMALS, params),\n \n // 获取动物分类\n getCategories: () => request.get(endpoints.ANIMAL.CATEGORIES)\n}\n\n// 送花服务\nexport const flowerService = {\n // 获取花束列表\n getList: (params = {}) => request.get(endpoints.FLOWER.LIST, params),\n \n // 获取花束详情\n getDetail: (id) => request.get(`${endpoints.FLOWER.DETAIL}/${id}`),\n \n // 下单\n order: (data) => request.post(endpoints.FLOWER.ORDER, data),\n \n // 获取我的订单\n getMyOrders: (params = {}) => request.get(endpoints.FLOWER.MY_ORDERS, params),\n \n // 获取花束分类\n getCategories: () => request.get(endpoints.FLOWER.CATEGORIES)\n}\n\n// 订单服务\nexport const orderService = {\n // 获取订单列表\n getList: (params = {}) => request.get(endpoints.ORDER.LIST, params),\n \n // 获取订单详情\n getDetail: (id) => request.get(`${endpoints.ORDER.DETAIL}/${id}`),\n \n // 取消订单\n cancel: (id) => request.post(`${endpoints.ORDER.CANCEL}/${id}`),\n \n // 支付订单\n pay: (id) => request.post(`${endpoints.ORDER.PAY}/${id}`),\n \n // 确认收货\n confirm: (id) => request.post(`${endpoints.ORDER.CONFIRM}/${id}`)\n}\n\n// 支付服务\nexport const paymentService = {\n // 创建支付\n create: (data) => request.post(endpoints.PAYMENT.CREATE, data),\n \n // 查询支付状态\n query: (paymentId) => request.get(`${endpoints.PAYMENT.QUERY}/${paymentId}`),\n \n // 退款\n refund: (paymentId, data) => request.post(`${endpoints.PAYMENT.REFUND}/${paymentId}`, data)\n}\n\n// 系统服务\nexport const systemService = {\n // 获取系统配置\n getConfig: () => request.get(endpoints.SYSTEM.CONFIG),\n \n // 获取公告列表\n getNotices: (params = {}) => request.get(endpoints.SYSTEM.NOTICE, params),\n \n // 提交反馈\n submitFeedback: (data) => request.post(endpoints.SYSTEM.FEEDBACK, data)\n}\n\n// 首页数据服务\nexport const homeService = {\n // 获取首页数据\n getHomeData: () => request.get('/home/data'),\n \n // 获取轮播图\n getBanners: () => request.get('/home/banners'),\n \n // 获取推荐旅行计划\n getRecommendedTravels: () => request.get('/home/recommended-travels'),\n \n // 获取热门动物\n getHotAnimals: () => request.get('/home/hot-animals'),\n \n // 获取精选花束\n getFeaturedFlowers: () => request.get('/home/featured-flowers')\n}\n\n// 工具函数\nexport const apiUtils = {\n // 生成分页参数\n generatePagination: (page = 1, pageSize = 10) => ({\n page,\n pageSize,\n skip: (page - 1) * pageSize\n }),\n \n // 处理上传进度\n handleUploadProgress: (progressEvent) => {\n const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total)\n return percent\n },\n \n // 处理下载进度\n handleDownloadProgress: (progressEvent) => {\n const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total)\n return percent\n },\n \n // 格式化错误信息\n formatError: (error) => {\n if (error.code) {\n return error.message\n }\n return '网络连接失败,请检查网络设置'\n }\n}\n\n// 默认导出所有服务\nexport default {\n userService,\n travelService,\n animalService,\n flowerService,\n orderService,\n paymentService,\n systemService,\n homeService,\n apiUtils\n}"],"names":["request"],"mappings":";;;;AAkIY,MAAC,cAAc;AAAA;AAAA,EAEzB,aAAa,MAAMA,YAAAA,QAAQ,IAAI,YAAY;AAAA;AAAA,EAG3C,YAAY,MAAMA,YAAAA,QAAQ,IAAI,eAAe;AAAA;AAAA,EAG7C,uBAAuB,MAAMA,YAAAA,QAAQ,IAAI,2BAA2B;AAAA;AAAA,EAGpE,eAAe,MAAMA,YAAAA,QAAQ,IAAI,mBAAmB;AAAA;AAAA,EAGpD,oBAAoB,MAAMA,YAAAA,QAAQ,IAAI,wBAAwB;AAChE;;"} \ No newline at end of file +{"version":3,"file":"services.js","sources":["api/services.js"],"sourcesContent":["import request from './request.js'\r\nimport config from './config.js'\r\n\r\nconst { endpoints } = config\r\n\r\n// 用户服务\r\nexport const userService = {\r\n // 登录\r\n login: (data) => request.post(endpoints.USER.LOGIN, data),\r\n \r\n // 注册\r\n register: (data) => request.post(endpoints.USER.REGISTER, data),\r\n \r\n // 获取用户信息\r\n getProfile: () => request.get(endpoints.USER.PROFILE),\r\n \r\n // 更新用户信息\r\n updateProfile: (data) => request.put(endpoints.USER.UPDATE_PROFILE, data),\r\n \r\n // 上传头像\r\n uploadAvatar: (filePath) => request.upload(endpoints.USER.UPLOAD_AVATAR, filePath),\r\n \r\n // 退出登录\r\n logout: () => {\r\n uni.removeStorageSync('token')\r\n uni.removeStorageSync('refreshToken')\r\n return Promise.resolve()\r\n }\r\n}\r\n\r\n// 旅行计划服务\r\nexport const travelService = {\r\n // 获取旅行计划列表\r\n getList: (params = {}) => request.get(endpoints.TRAVEL.LIST, params),\r\n \r\n // 获取旅行计划详情\r\n getDetail: (id) => request.get(`${endpoints.TRAVEL.DETAIL}/${id}`),\r\n \r\n // 创建旅行计划\r\n create: (data) => request.post(endpoints.TRAVEL.CREATE, data),\r\n \r\n // 加入旅行计划\r\n join: (travelId) => request.post(`${endpoints.TRAVEL.JOIN}/${travelId}`),\r\n \r\n // 获取我的旅行计划\r\n getMyPlans: (params = {}) => request.get(endpoints.TRAVEL.MY_PLANS, params),\r\n \r\n // 搜索旅行计划\r\n search: (keyword, params = {}) => request.get(endpoints.TRAVEL.SEARCH, { keyword, ...params })\r\n}\r\n\r\n// 动物认养服务\r\nexport const animalService = {\r\n // 获取动物列表\r\n getList: (params = {}) => request.get(endpoints.ANIMAL.LIST, params),\r\n \r\n // 获取动物详情\r\n getDetail: (id) => request.get(`${endpoints.ANIMAL.DETAIL}/${id}`),\r\n \r\n // 认养动物\r\n adopt: (animalId, data) => request.post(`${endpoints.ANIMAL.ADOPT}/${animalId}`, data),\r\n \r\n // 获取我的动物\r\n getMyAnimals: (params = {}) => request.get(endpoints.ANIMAL.MY_ANIMALS, params),\r\n \r\n // 获取动物分类\r\n getCategories: () => request.get(endpoints.ANIMAL.CATEGORIES)\r\n}\r\n\r\n// 送花服务\r\nexport const flowerService = {\r\n // 获取花束列表\r\n getList: (params = {}) => request.get(endpoints.FLOWER.LIST, params),\r\n \r\n // 获取花束详情\r\n getDetail: (id) => request.get(`${endpoints.FLOWER.DETAIL}/${id}`),\r\n \r\n // 下单\r\n order: (data) => request.post(endpoints.FLOWER.ORDER, data),\r\n \r\n // 获取我的订单\r\n getMyOrders: (params = {}) => request.get(endpoints.FLOWER.MY_ORDERS, params),\r\n \r\n // 获取花束分类\r\n getCategories: () => request.get(endpoints.FLOWER.CATEGORIES)\r\n}\r\n\r\n// 订单服务\r\nexport const orderService = {\r\n // 获取订单列表\r\n getList: (params = {}) => request.get(endpoints.ORDER.LIST, params),\r\n \r\n // 获取订单详情\r\n getDetail: (id) => request.get(`${endpoints.ORDER.DETAIL}/${id}`),\r\n \r\n // 取消订单\r\n cancel: (id) => request.post(`${endpoints.ORDER.CANCEL}/${id}`),\r\n \r\n // 支付订单\r\n pay: (id) => request.post(`${endpoints.ORDER.PAY}/${id}`),\r\n \r\n // 确认收货\r\n confirm: (id) => request.post(`${endpoints.ORDER.CONFIRM}/${id}`)\r\n}\r\n\r\n// 支付服务\r\nexport const paymentService = {\r\n // 创建支付\r\n create: (data) => request.post(endpoints.PAYMENT.CREATE, data),\r\n \r\n // 查询支付状态\r\n query: (paymentId) => request.get(`${endpoints.PAYMENT.QUERY}/${paymentId}`),\r\n \r\n // 退款\r\n refund: (paymentId, data) => request.post(`${endpoints.PAYMENT.REFUND}/${paymentId}`, data)\r\n}\r\n\r\n// 系统服务\r\nexport const systemService = {\r\n // 获取系统配置\r\n getConfig: () => request.get(endpoints.SYSTEM.CONFIG),\r\n \r\n // 获取公告列表\r\n getNotices: (params = {}) => request.get(endpoints.SYSTEM.NOTICE, params),\r\n \r\n // 提交反馈\r\n submitFeedback: (data) => request.post(endpoints.SYSTEM.FEEDBACK, data)\r\n}\r\n\r\n// 首页数据服务\r\nexport const homeService = {\r\n // 获取首页数据\r\n getHomeData: () => request.get('/home/data'),\r\n \r\n // 获取轮播图\r\n getBanners: () => request.get('/home/banners'),\r\n \r\n // 获取推荐旅行计划\r\n getRecommendedTravels: () => request.get('/home/recommended-travels'),\r\n \r\n // 获取热门动物\r\n getHotAnimals: () => request.get('/home/hot-animals'),\r\n \r\n // 获取精选花束\r\n getFeaturedFlowers: () => request.get('/home/featured-flowers')\r\n}\r\n\r\n// 工具函数\r\nexport const apiUtils = {\r\n // 生成分页参数\r\n generatePagination: (page = 1, pageSize = 10) => ({\r\n page,\r\n pageSize,\r\n skip: (page - 1) * pageSize\r\n }),\r\n \r\n // 处理上传进度\r\n handleUploadProgress: (progressEvent) => {\r\n const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total)\r\n return percent\r\n },\r\n \r\n // 处理下载进度\r\n handleDownloadProgress: (progressEvent) => {\r\n const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total)\r\n return percent\r\n },\r\n \r\n // 格式化错误信息\r\n formatError: (error) => {\r\n if (error.code) {\r\n return error.message\r\n }\r\n return '网络连接失败,请检查网络设置'\r\n }\r\n}\r\n\r\n// 默认导出所有服务\r\nexport default {\r\n userService,\r\n travelService,\r\n animalService,\r\n flowerService,\r\n orderService,\r\n paymentService,\r\n systemService,\r\n homeService,\r\n apiUtils\r\n}"],"names":["request"],"mappings":";;;;AAkIY,MAAC,cAAc;AAAA;AAAA,EAEzB,aAAa,MAAMA,YAAAA,QAAQ,IAAI,YAAY;AAAA;AAAA,EAG3C,YAAY,MAAMA,YAAAA,QAAQ,IAAI,eAAe;AAAA;AAAA,EAG7C,uBAAuB,MAAMA,YAAAA,QAAQ,IAAI,2BAA2B;AAAA;AAAA,EAGpE,eAAe,MAAMA,YAAAA,QAAQ,IAAI,mBAAmB;AAAA;AAAA,EAGpD,oBAAoB,MAAMA,YAAAA,QAAQ,IAAI,wBAAwB;AAChE;;"} \ No newline at end of file