/** * AppServer API调用封装 * @constructor */ import Config from '../Config.js' function objectToQueryParams(obj) { return Object.keys(obj).map(key => encodeURIComponent(key) + '=' + encodeURIComponent(obj[key])).join('&'); } var AppServer = function() {} var serverConfig = {} // API基础地址(从配置文件读取) var baseUrl = Config.API_BASE_URL // ==================== 认证相关接口 ==================== serverConfig.apiUrl_Auth_WechatLogin = baseUrl + '/api/v1/auth/wechat-login' // 微信登录 serverConfig.apiUrl_Auth_RefreshToken = baseUrl + '/api/v1/auth/refresh-token' // 刷新Token serverConfig.apiUrl_Auth_Logout = baseUrl + '/api/v1/auth/logout' // 登出 // ==================== 用户相关接口 ==================== serverConfig.apiUrl_User_GetProfile = baseUrl + '/api/v1/users/profile' // 获取用户信息 serverConfig.apiUrl_User_UpdateProfile = baseUrl + '/api/v1/users/profile' // 更新用户信息 serverConfig.apiUrl_User_SetLanguage = baseUrl + '/api/v1/users/language' // 设置语言 // ==================== 服务相关接口 ==================== serverConfig.apiUrl_Service_GetCategories = baseUrl + '/api/v1/categories' // 获取分类列表 serverConfig.apiUrl_Service_GetServices = baseUrl + '/api/v1/services' // 获取服务列表 serverConfig.apiUrl_Service_GetServiceByKey = baseUrl + '/api/v1/services' // 获取服务详情(通过key) // ==================== 预约相关接口 ==================== serverConfig.apiUrl_Appointment_Create = baseUrl + '/api/v1/appointments' // 创建预约 serverConfig.apiUrl_Appointment_GetList = baseUrl + '/api/v1/appointments' // 获取预约列表 serverConfig.apiUrl_Appointment_Stats = baseUrl + '/api/v1/appointments/stats' // 获取预约统计 serverConfig.apiUrl_Appointment_GetById = baseUrl + '/api/v1/appointments' // 获取预约详情 serverConfig.apiUrl_Appointment_Update = baseUrl + '/api/v1/appointments' // 更新预约 serverConfig.apiUrl_Appointment_Cancel = baseUrl + '/api/v1/appointments' // 取消预约 // ==================== 通知相关接口 ==================== serverConfig.apiUrl_Notification_GetList = baseUrl + '/api/v1/notifications' // 获取通知列表 serverConfig.apiUrl_Notification_UnreadCount = baseUrl + '/api/v1/notifications/unread-count' // 获取未读数量 serverConfig.apiUrl_Notification_MarkAsRead = baseUrl + '/api/v1/notifications' // 标记已读 serverConfig.apiUrl_Notification_MarkAllAsRead = baseUrl + '/api/v1/notifications/read-all' // 全部标记已读 serverConfig.apiUrl_Notification_Delete = baseUrl + '/api/v1/notifications' // 删除通知 // ==================== 邀请相关接口 ==================== serverConfig.apiUrl_Invitation_Generate = baseUrl + '/api/v1/invitations/generate' // 生成邀请码 serverConfig.apiUrl_Invitation_GetStats = baseUrl + '/api/v1/invitations/stats' // 获取邀请统计 serverConfig.apiUrl_Invitation_GetRecords = baseUrl + '/api/v1/invitations/records' // 获取邀请记录 // ==================== 佣金相关接口 ==================== serverConfig.apiUrl_Commission_GetList = baseUrl + '/api/v1/commissions' // 获取佣金记录 serverConfig.apiUrl_Commission_GetStats = baseUrl + '/api/v1/commissions/stats' // 获取佣金统计 // ==================== 提现相关接口 ==================== serverConfig.apiUrl_Withdrawal_Create = baseUrl + '/api/v1/withdrawals' // 申请提现 serverConfig.apiUrl_Withdrawal_GetList = baseUrl + '/api/v1/withdrawals' // 获取提现记录 serverConfig.apiUrl_Withdrawal_GetById = baseUrl + '/api/v1/withdrawals' // 获取提现详情 // ==================== 上传相关接口 ==================== serverConfig.apiUrl_Upload_Image = baseUrl + '/api/v1/upload/image' // 上传图片 // ==================== 小程序码相关接口 ==================== serverConfig.apiUrl_QRCode_GetMiniProgram = baseUrl + '/api/v1/qrcode/miniprogram' // 获取小程序码 /** * 获取完整的application/x-www-form-urlencoded请求参数 * 1)填充必要的请求参数 * 2)填充签名 * @param postData */ AppServer.prototype.getPostFormBody = function(postData) { var fullPostData = Object.assign({}, postData) } /** * @param {Object} postData * 获取参数签名 */ AppServer.prototype.getSign = function(postData) { let arr = []; for (let key in postData) { if (key == 'sign') continue; arr.push(key) } arr.sort(); let str = ''; for (let i in arr) { let value = postData[arr[i]] if (value || value == 0) { str += value } } //添加saltKey let saltKey = "" try { let token = uni.getStorageSync("token") if (token) { saltKey = token.split('.')[2]; } } catch (e) { saltKey = "" } str += saltKey let sign = md5(str) // console.log("要签名的字符串:" + str + ",sign=" + sign) return sign } /** * 接口请求 */ AppServer.prototype.postData = async function(url, postData) { // var formBody = this.getPostFormBody(postData) // console.log(formBody); // 优先从globalData获取token,如果没有再从storage获取 let authToken = ""; try { const app = getApp(); if (app && app.globalData && app.globalData.token) { authToken = app.globalData.token; } else { authToken = uni.getStorageSync("token") || ""; } } catch (e) { authToken = uni.getStorageSync("token") || ""; } return uni.request({ url: url, method: 'POST', header: { 'Content-Type': "application/json", 'Authorization': authToken }, data: JSON.stringify(postData) }) .then((res) => { // 此处的 res 参数,与使用默认方式调用时 success 回调中的 res 参数一致 console.log(`post,url=${url},form=${JSON.stringify(postData)},response=${res.data}`); //在这里处理验签失败等问题 return res.data; }) .catch((err) => { // 此处的 err 参数,与使用默认方式调用时 fail 回调中的 err 参数一致 console.error(err); return err; }); } AppServer.prototype.getData = async function(url, postData) { // 优先从globalData获取token,如果没有再从storage获取 let authToken = ""; try { const app = getApp(); if (app && app.globalData && app.globalData.token) { authToken = app.globalData.token; } else { authToken = uni.getStorageSync("token") || ""; } } catch (e) { authToken = uni.getStorageSync("token") || ""; } if (postData != null) { var parmat = objectToQueryParams(postData); if (url.indexOf("?") > -1) { url += "&" + parmat; } else { url += "?" + parmat; } } return uni.request({ url: url, method: 'GET', header: { 'Authorization': authToken }, }) .then((res) => { console.log(`GET,url=${url},response=${JSON.stringify(res.data)}`); return res.data; }) .catch((err) => { console.error(err); return err; }); } /** * PUT请求 */ AppServer.prototype.putData = async function(url, postData) { let authToken = ""; try { const app = getApp(); if (app && app.globalData && app.globalData.token) { authToken = app.globalData.token; } else { authToken = uni.getStorageSync("token") || ""; } } catch (e) { authToken = uni.getStorageSync("token") || ""; } return uni.request({ url: url, method: 'PUT', header: { 'Content-Type': "application/json", 'Authorization': authToken }, data: JSON.stringify(postData) }) .then((res) => { console.log(`PUT,url=${url},form=${JSON.stringify(postData)},response=${JSON.stringify(res.data)}`); return res.data; }) .catch((err) => { console.error(err); return err; }); } /** * DELETE请求 */ AppServer.prototype.deleteData = async function(url) { let authToken = ""; try { const app = getApp(); if (app && app.globalData && app.globalData.token) { authToken = app.globalData.token; } else { authToken = uni.getStorageSync("token") || ""; } } catch (e) { authToken = uni.getStorageSync("token") || ""; } return uni.request({ url: url, method: 'DELETE', header: { 'Authorization': authToken }, }) .then((res) => { console.log(`DELETE,url=${url},response=${JSON.stringify(res.data)}`); return res.data; }) .catch((err) => { console.error(err); return err; }); } // ==================== 认证相关方法 ==================== /** * 微信登录 * @param {String} code - 微信登录code * @param {String} invitationCode - 邀请码(可选) */ AppServer.prototype.WechatLogin = async function(code, invitationCode) { var url = serverConfig.apiUrl_Auth_WechatLogin var postData = { code } if (invitationCode) { postData.invitationCode = invitationCode } return this.postData(url, postData).then((data) => { return data; }) } /** * 刷新Token * @param {String} refreshToken - 刷新令牌 */ AppServer.prototype.RefreshToken = async function(refreshToken) { var url = serverConfig.apiUrl_Auth_RefreshToken return this.postData(url, { refreshToken }).then((data) => { if (data.success && data.data && data.data.token) { const token = "Bearer " + data.data.token; const app = getApp(); app.globalData.token = token; uni.setStorageSync("token", token); } return data; }); } /** * 登出 */ AppServer.prototype.Logout = async function() { var url = serverConfig.apiUrl_Auth_Logout return this.postData(url, {}).then((data) => { // 清除本地token const app = getApp(); app.globalData.token = ""; uni.setStorageSync("token", ""); return data; }); } // ==================== 用户相关方法 ==================== /** * 获取用户信息 */ AppServer.prototype.GetUserProfile = async function() { var url = serverConfig.apiUrl_User_GetProfile return this.getData(url).then((data) => { return data; }) } /** * 更新用户信息 * @param {Object} profileData - 用户信息 { nickname, avatar, realName, phone, whatsapp, wechatId } */ AppServer.prototype.UpdateUserProfile = async function(profileData) { var url = serverConfig.apiUrl_User_UpdateProfile return this.putData(url, profileData).then((data) => { return data; }) } /** * 设置语言偏好 * @param {String} language - 语言代码 (zh, en, pt) */ AppServer.prototype.SetLanguage = async function(language) { var url = serverConfig.apiUrl_User_SetLanguage return this.putData(url, { language }).then((data) => { return data; }) } // ==================== 服务相关方法 ==================== /** * 获取服务分类列表 * @param {Object} params - { language } */ AppServer.prototype.GetCategories = async function(params = {}) { var url = serverConfig.apiUrl_Service_GetCategories return this.getData(url, params).then((data) => { return data; }) } /** * 获取服务列表 * @param {Object} params - { page, limit, categoryId, language } */ AppServer.prototype.GetServices = async function(params = {}) { var url = serverConfig.apiUrl_Service_GetServices return this.getData(url, params).then((data) => { return data; }) } /** * 获取服务详情 * @param {String} serviceKey - 服务key * @param {String} language - 语言代码 (可选) */ AppServer.prototype.GetServiceByKey = async function(serviceKey, language) { var url = serverConfig.apiUrl_Service_GetServiceByKey + '/' + serviceKey var params = language ? { language } : null return this.getData(url, params).then((data) => { return data; }) } // ==================== 预约相关方法 ==================== /** * 创建预约 * @param {Object} appointmentData - { serviceId, realName, contactMethod, contactValue, appointmentDate, appointmentTime, notes, amount } */ AppServer.prototype.CreateAppointment = async function(appointmentData) { var url = serverConfig.apiUrl_Appointment_Create return this.postData(url, appointmentData).then((data) => { return data; }) } /** * 获取预约列表 * @param {Object} params - { page, limit, status } */ AppServer.prototype.GetAppointments = async function(params = {}) { var url = serverConfig.apiUrl_Appointment_GetList return this.getData(url, params).then((data) => { return data; }) } /** * 获取预约统计(按状态分组的数量) */ AppServer.prototype.GetAppointmentStats = async function() { var url = serverConfig.apiUrl_Appointment_Stats return this.getData(url, {}).then((data) => { return data; }) } /** * 获取预约详情 * @param {String} appointmentId - 预约ID */ AppServer.prototype.GetAppointmentById = async function(appointmentId) { var url = serverConfig.apiUrl_Appointment_GetById + '/' + appointmentId return this.getData(url).then((data) => { return data; }) } /** * 更新预约 * @param {String} appointmentId - 预约ID * @param {Object} updateData - 更新数据 */ AppServer.prototype.UpdateAppointment = async function(appointmentId, updateData) { var url = serverConfig.apiUrl_Appointment_Update + '/' + appointmentId return this.putData(url, updateData).then((data) => { return data; }) } /** * 取消预约 * @param {String} appointmentId - 预约ID */ AppServer.prototype.CancelAppointment = async function(appointmentId) { var url = serverConfig.apiUrl_Appointment_Cancel + '/' + appointmentId return this.deleteData(url).then((data) => { return data; }) } // ==================== 通知相关方法 ==================== /** * 获取通知列表 * @param {Object} params - { page, limit, type } */ AppServer.prototype.GetNotifications = async function(params = {}) { var url = serverConfig.apiUrl_Notification_GetList return this.getData(url, params).then((data) => { return data; }) } /** * 获取未读通知数量(按类型分组) */ AppServer.prototype.GetNotificationUnreadCount = async function() { var url = serverConfig.apiUrl_Notification_UnreadCount return this.getData(url, {}).then((data) => { return data; }) } /** * 标记通知为已读 * @param {String} notificationId - 通知ID */ AppServer.prototype.MarkNotificationAsRead = async function(notificationId) { var url = serverConfig.apiUrl_Notification_MarkAsRead + '/' + notificationId + '/read' return this.putData(url, {}).then((data) => { return data; }) } /** * 全部标记为已读 */ AppServer.prototype.MarkAllNotificationsAsRead = async function() { var url = serverConfig.apiUrl_Notification_MarkAllAsRead return this.putData(url, {}).then((data) => { return data; }) } /** * 删除通知 * @param {String} notificationId - 通知ID */ AppServer.prototype.DeleteNotification = async function(notificationId) { var url = serverConfig.apiUrl_Notification_Delete + '/' + notificationId return this.deleteData(url).then((data) => { return data; }) } // ==================== 邀请相关方法 ==================== /** * 生成邀请码 */ AppServer.prototype.GenerateInvitationCode = async function() { var url = serverConfig.apiUrl_Invitation_Generate return this.postData(url, {}).then((data) => { return data; }) } /** * 获取邀请统计 */ AppServer.prototype.GetInvitationStats = async function() { var url = serverConfig.apiUrl_Invitation_GetStats return this.getData(url).then((data) => { return data; }) } /** * 获取邀请记录 */ AppServer.prototype.GetInvitationRecords = async function() { var url = serverConfig.apiUrl_Invitation_GetRecords return this.getData(url).then((data) => { return data; }) } // ==================== 佣金相关方法 ==================== /** * 获取佣金记录 * @param {Object} params - { page, limit } */ AppServer.prototype.GetCommissions = async function(params = {}) { var url = serverConfig.apiUrl_Commission_GetList return this.getData(url, params).then((data) => { return data; }) } /** * 获取佣金统计 */ AppServer.prototype.GetCommissionStats = async function() { var url = serverConfig.apiUrl_Commission_GetStats return this.getData(url).then((data) => { return data; }) } // ==================== 提现相关方法 ==================== /** * 申请提现 * @param {Object} withdrawalData - { amount, paymentMethod, paymentDetails } */ AppServer.prototype.CreateWithdrawal = async function(withdrawalData) { var url = serverConfig.apiUrl_Withdrawal_Create return this.postData(url, withdrawalData).then((data) => { return data; }) } /** * 获取提现记录 * @param {Object} params - { page, limit, status } */ AppServer.prototype.GetWithdrawals = async function(params = {}) { var url = serverConfig.apiUrl_Withdrawal_GetList return this.getData(url, params).then((data) => { return data; }) } /** * 获取提现详情 * @param {String} withdrawalId - 提现ID */ AppServer.prototype.GetWithdrawalById = async function(withdrawalId) { var url = serverConfig.apiUrl_Withdrawal_GetById + '/' + withdrawalId return this.getData(url).then((data) => { return data; }) } // ==================== 上传相关方法 ==================== /** * 获取小程序码 * @param {Object} params - { path, width } */ AppServer.prototype.GetMiniProgramQRCode = async function(params = {}) { var url = serverConfig.apiUrl_QRCode_GetMiniProgram return this.postData(url, params).then((data) => { return data; }) } /** * 上传图片 * @param {String} filePath - 本地文件路径 */ AppServer.prototype.UploadImage = async function(filePath) { var url = serverConfig.apiUrl_Upload_Image // 获取token let authToken = ""; try { const app = getApp(); if (app && app.globalData && app.globalData.token) { authToken = app.globalData.token; } else { authToken = uni.getStorageSync("token") || ""; } } catch (e) { authToken = uni.getStorageSync("token") || ""; } return new Promise((resolve, reject) => { uni.uploadFile({ url: url, filePath: filePath, name: 'image', header: { 'Authorization': authToken }, success: (res) => { try { const data = JSON.parse(res.data); console.log('Upload image success:', data); resolve(data); } catch (e) { console.error('Parse upload response error:', e); reject(e); } }, fail: (err) => { console.error('Upload image failed:', err); reject(err); } }); }); } // AppServer.prototype.GetMiniProgramUserInfo = async function(encryptedData, iv, userId) { // return this.postData(serverConfig.apiUrl_Music_GetMiniProgramUserInfo, { // "encryptedData": encryptedData, // "iv": iv, // "userId": userId // }).then(data => { // console.log((data)); // return data; // }) // } /** * 运行平台 */ AppServer.prototype.GetPlatformIsAndroid = function() { let port = uni.getSystemInfoSync().platform switch (port) { case 'android': console.log('运行Android上', port); return true; break; //android case 'ios': console.log('运行iOS上', port); return false; break; default: console.log('运行在开发者工具上'); return false; break; //devtools } } export { AppServer }