文件
shanghaipeiwan/pwuniapp/common/api.js

996 行
28 KiB
JavaScript

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

// pwuniapp/common/api.js
// 同城生活陪伴业务API接口层与数据适配器
import http from './request.js';
/**
* 格式化活动数据,使其在 MySQL 与前端展示组件间无缝互通
*/
export function formatActivityData(raw) {
if (!raw) return null;
const payTypeStr = raw.payType === 2 || raw.payType === 'PROJECT' ? 'PROJECT' : 'AA';
const totalFee = raw.totalFeeCents != null ? raw.totalFeeCents / 100 : (raw.totalFee || 0);
const perPerson = raw.perPersonFeeCents != null ? raw.perPersonFeeCents / 100 : (raw.perPersonFee || (payTypeStr === 'AA' ? totalFee / (raw.maxParticipants || 4) : 500));
const participants = (raw.participants || []).map((p) => ({
id: p.id,
userId: p.userId,
nickname: p.nickname || `搭子_${p.userId || p.id}`,
avatar: p.avatar || 'https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=100',
verifyCode: p.verifyCode || '8392',
checkedIn: Boolean(p.checkinStatus || p.checkedIn),
payAmount: p.payAmountCents != null ? p.payAmountCents / 100 : (p.payAmount || 0),
}));
const joinedCount = raw.joinedCount != null ? raw.joinedCount : participants.length;
return {
id: String(raw.id),
title: raw.title || '同城生活组局',
game: raw.gameCategory || raw.game || '美食陪吃',
track: raw.track || 'OFFLINE_MEAL',
payType: payTypeStr,
totalFee,
perPersonFee: perPerson,
aaFee: raw.aaFee != null ? raw.aaFee : perPerson,
maxParticipants: raw.maxParticipants || 4,
currentParticipants: joinedCount || 1,
startTime: raw.startTime || '今天 19:30',
location: raw.location || '北京市朝阳区公开商业街区',
creatorId: raw.creatorId != null ? Number(raw.creatorId) : (raw.creator_id != null ? Number(raw.creator_id) : 1001),
creatorNickname: raw.creatorNickname || '同城局长',
creatorAvatar: raw.creatorAvatar || 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=100',
status: raw.status || (joinedCount >= (raw.maxParticipants || 4) ? 'FULL' : 'RECRUITING'),
allowDynamicPrice: Boolean(raw.allowDynamicPrice),
priceAdjustRule: raw.priceAdjustRule || 'UNIFIED_HIGH',
participants,
priceAdjustHistory: raw.priceAdjustHistory || [],
};
}
/**
* 获取组局活动列表 (真实请求 MySQL,异常时返回空列表)
*/
export async function getActivities() {
try {
const list = await http.get('/activities');
if (Array.isArray(list) && list.length > 0) {
return list.map(formatActivityData);
}
} catch (err) {
console.warn('[API] 获取后端活动列表异常:', err.message);
}
return [];
}
/**
* 获取指定活动详情 (真实请求 MySQL,不存在或异常时返回 null)
*/
export async function getActivityDetail(id) {
try {
const detail = await http.get(`/activities/${id}`);
if (detail) {
return formatActivityData(detail);
}
} catch (err) {
console.warn(`[API] 获取活动 [${id}] 详情异常:`, err.message);
}
return null;
}
/**
* 发起新组局活动 (实时写入 MySQL)
*/
export async function createActivity(payload) {
const body = {
creatorId: payload.creatorId || 1001,
title: payload.title,
gameCategory: payload.game || '美食陪吃',
location: payload.location,
payType: payload.payType === 'AA' ? 1 : 2,
totalFeeCents: Math.round((Number(payload.totalFee) || 0) * 100),
perPersonFeeCents: Math.round((Number(payload.perPersonFee || payload.aaFee) || 0) * 100),
maxParticipants: Number(payload.maxParticipants) || 4,
};
try {
const res = await http.post('/activities', body);
return formatActivityData(res);
} catch (err) {
console.warn('[API] 后端创建活动接口未响应:', err.message);
throw err;
}
}
/**
* 报名活动并获取 4 位唯一核销码
*/
export async function joinActivity(activityId, params = {}) {
const body = {
userId: params.userId || 2008,
payAmountCents: Math.round((Number(params.payAmount) || 50) * 100),
};
try {
const res = await http.post(`/activities/${activityId}/join`, body);
return res;
} catch (err) {
console.warn('[API] 报名接口异常:', err.message);
throw err;
}
}
/**
* 房主/管理员核销 4 位核销码
*/
export async function verifyActivityCheckin(activityId, verifyCode, operatorId = 1001) {
return http.post(`/activities/${activityId}/verify`, {
operatorId,
verifyCode,
});
}
/**
* 房主调整出价/追加金额
*/
export async function adjustActivityPrice(activityId, newPriceYuan, operatorId = 1001) {
const newPriceCents = Math.round(Number(newPriceYuan) * 100);
try {
const res = await http.post(`/activities/${activityId}/adjust-price`, {
operatorId,
newPriceCents,
});
return formatActivityData(res);
} catch (err) {
console.warn('[API] 调价请求异常:', err.message);
throw err;
}
}
/**
* 房主取消/解散组局 (原路退款已报名成员)
*/
export async function cancelActivity(activityId, hostId = 1001, reason = '房主主动解散') {
return http.post(`/activities/${activityId}/cancel`, {
hostId,
reason,
});
}
/**
* 成员主动退出组局 (原路退款)
*/
export async function leaveActivity(activityId, userId = 2001) {
return http.post(`/activities/${activityId}/leave`, {
userId,
});
}
/**
* 获取“我的组局”(发起的 + 报名的)
*/
export async function getMyActivities(userId = 1001) {
try {
const res = await http.get(`/users/${userId}/my-activities`);
if (res) {
return {
created: (res.created || []).map(formatActivityData),
joined: (res.joined || []).map(formatActivityData),
};
}
} catch (err) {
console.warn('[API] 获取我的组局异常:', err.message);
}
return { created: [], joined: [] };
}
/**
* 获取同城大神列表
*/
export async function getCompanions() {
try {
const list = await http.get('/companions');
if (Array.isArray(list) && list.length > 0) {
return list.map((c) => ({
id: String(c.id),
nickname: c.name || c.nickname || '同城大神',
avatar: c.avatar || 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=300',
gender: c.gender === '男' ? 'male' : 'female',
age: Number(c.age) || 22,
game: c.track === 'OFFLINE_MEAL' ? '美食陪吃' : (c.track === 'OFFLINE_SING' ? '同城陪唱' : (c.track === 'OFFLINE_DRINK' ? '下午茶陪喝' : (c.game || '同城陪伴'))),
track: c.track || 'OFFLINE_MEAL',
city: '北京市 · 朝阳/海淀',
rankTag: c.rank || '同城认证陪伴师',
levelTag: '认证大神',
price: Number(c.hourlyRate) || 68,
rating: Number(c.rating) || 5.0,
orderCount: Number(c.orderCount) || 120,
isOnline: c.status === '接单中',
voiceDuration: Number(c.voiceDuration) || 15,
voiceType: 'voice',
voiceTitle: c.voiceTitle || '语音招呼',
bio: '专业同城生活陪伴,阳光健康公开。'
}));
}
} catch (err) {
console.warn('[API] 获取大神列表异常:', err.message);
}
return [];
}
/**
* 获取单个大神详情 (真实从 MySQL 读取)
*/
export async function getCompanionDetail(id) {
try {
const res = await http.get(`/companions/${id}`);
if (res && res.id) {
return res;
}
} catch (err) {
console.warn(`[API] 获取大神 [${id}] 详情异常:`, err.message);
}
return null;
}
/**
* 格式化订单数据,使 MySQL 表字段与移动端视图无缝映射
*/
export function formatOrderData(raw) {
if (!raw) return null;
let statusKey = raw.status || 'IN_SERVICE';
if (statusKey === '待支付' || statusKey === '待付款') statusKey = 'PENDING_PAY';
else if (statusKey === '已到场核销' || statusKey === '履约中' || statusKey === '服务中') statusKey = 'IN_SERVICE';
else if (statusKey === '已完成') statusKey = 'COMPLETED';
else if (statusKey === '争议仲裁中' || statusKey === '退款中' || statusKey === '已全额退款') statusKey = 'REFUNDING';
else if (statusKey === '已取消') statusKey = 'CANCELLED';
const companionAvatar = raw.expertAvatar || raw.expert_avatar || raw.avatar ||
'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=120';
const companionNickname = raw.companionName || raw.companion_name || raw.expertNickname || (raw.expert && raw.expert.nickname) || '同城大神';
const game = raw.track || (raw.expert && raw.expert.game) || '同城陪伴';
return {
id: String(raw.id),
orderSn: raw.orderNo || raw.order_no || raw.orderSn || String(raw.id),
expert: {
id: String(raw.expertId || raw.expert_id || (raw.expert && raw.expert.id) || 'exp_101'),
nickname: companionNickname,
avatar: companionAvatar,
game: game,
},
serviceTitle: raw.serviceTitle || raw.service_title || `${game} · 专业陪伴服务`,
quantity: Number(raw.durationHours || raw.duration_hours || raw.quantity || 2),
totalAmount: Number(raw.amount || raw.totalAmount || 0),
status: statusKey,
meetVenue: raw.location || raw.meetVenue || '北京市公开商圈',
expenseBurden: raw.expenseBurden || raw.expense_burden || 'AA制各自付',
payType: raw.payType || raw.pay_type || 'WECHAT',
couponDiscount: Number(raw.couponDiscount || raw.coupon_discount || 0),
verifyCode: raw.verifyCode || raw.verify_code || '',
remark: raw.remark || '',
createdAt: raw.createdAt || raw.created_at || '刚刚'
};
}
/**
* 获取订单列表 (真实读取 MySQL)
*/
export async function getOrders() {
try {
const list = await http.get('/orders');
if (Array.isArray(list) && list.length > 0) {
return list.map(formatOrderData);
}
} catch (err) {
console.warn('[API] 获取订单列表异常:', err.message);
}
return [];
}
/**
* 创建新订单 (真实写入 MySQL orders 表)
*/
export async function createOrder(payload) {
try {
const res = await http.post('/orders', payload);
return formatOrderData(res);
} catch (err) {
console.warn('[API] 后端下单未响应:', err.message);
throw err;
}
}
/**
* 取消订单
*/
export async function cancelOrder(orderId) {
try {
const res = await http.post(`/orders/${orderId}/cancel`);
return formatOrderData(res);
} catch (err) {
console.warn('[API] 取消订单网络异常:', err.message);
}
return null;
}
/**
* 支付订单
*/
export async function payOrder(orderId) {
try {
const res = await http.post(`/orders/${orderId}/pay`);
return formatOrderData(res);
} catch (err) {
console.warn('[API] 支付订单网络异常:', err.message);
}
return null;
}
/**
* 确认验收订单
*/
export async function completeOrder(orderId) {
try {
const res = await http.post(`/orders/${orderId}/complete`);
return formatOrderData(res);
} catch (err) {
console.warn('[API] 确认完成网络异常:', err.message);
}
return null;
}
/**
* 申请退款/售后仲裁工单 (支持理由、详细说明与图片凭证)
*/
export async function refundOrder(orderId, data = {}) {
try {
const res = await http.post(`/orders/${orderId}/refund`, data);
return formatOrderData(res);
} catch (err) {
console.warn('[API] 申请退款网络异常:', err.message);
throw err;
}
}
/**
* 提交不良陪玩举报工单 (涉黄、涉赌、线下违规等)
*/
export async function submitReport(payload = {}) {
try {
const res = await http.post('/reports', payload);
return res;
} catch (err) {
console.warn('[API] 提交举报网络异常:', err.message);
throw err;
}
}
/**
* 通用4位核销码反查信息 (支持组局活动与同城线下订单)
*/
export async function queryCheckinCode(code) {
try {
const res = await http.get(`/verify/query/${code}`);
return res;
} catch (err) {
console.warn('[API] 反查核销码失败:', err.message);
throw err;
}
}
/**
* 通用4位核销码现场核销 (支持组局活动与同城线下订单)
*/
export async function universalVerifyCheckin(code, operatorId = 1001) {
try {
const res = await http.post('/verify/universal', { verifyCode: code, operatorId });
return res;
} catch (err) {
console.warn('[API] 通用核销接口异常:', err.message);
throw err;
}
}
/**
* 获取友圈广场动态列表 (真实读取 MySQL posts 表)
*/
export async function getPosts(category) {
try {
const query = category && category !== 'all' ? `?category=${encodeURIComponent(category)}` : '';
const res = await http.get(`/posts${query}`);
if (Array.isArray(res) && res.length > 0) {
return res.map(p => ({
id: p.id,
author: p.author || '神秘同好',
avatar: p.avatar || 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=150',
tag: p.tag || '同城认证',
tagType: p.tagType || 'warm-tag',
location: p.location || '同城热门商圈',
distance: p.distance || '1km内',
time: p.createdAt ? '刚刚' : '近期',
content: p.content || '',
topics: Array.isArray(p.topics) ? p.topics : [],
images: Array.isArray(p.images) ? p.images : [],
actionText: p.actionText || '聊一聊',
likes: Number(p.likes) || 0,
liked: false,
comments: Number(p.comments) || 0,
views: Number(p.views) || 1,
category: p.category || 'partner'
}));
}
} catch (err) {
console.warn('[API] 获取友圈动态列表异常:', err.message);
}
return null;
}
/**
* 发布新动态 (真实写入 MySQL posts 表)
*/
export async function createPost(payload) {
try {
const res = await http.post('/posts', payload);
return res;
} catch (err) {
console.warn('[API] 发布动态异常:', err.message);
throw err;
}
}
/**
* 动态点赞 (落盘 MySQL)
*/
export async function likePost(id) {
try {
const res = await http.post(`/posts/${id}/like`);
return res;
} catch (err) {
console.warn('[API] 点赞动态异常:', err.message);
return null;
}
}
/**
* 获取用户个人资料与钱包资产 (真实读取 MySQL users 表)
*/
export async function getUserProfile(userId = 1001) {
try {
const res = await http.get(`/users/${userId}`);
if (res && res.id) {
return res;
}
} catch (err) {
console.warn('[API] 获取用户信息异常,降级读取本地默认配置:', err.message);
}
return null;
}
/**
* 修改用户个人资料 (昵称、头像、手机号)
*/
export async function updateUserProfile(userId = 1001, data = {}) {
try {
const res = await http.post(`/users/${userId}/profile`, data);
return res;
} catch (err) {
console.warn('[API] 修改个人资料网络异常:', err.message);
throw err;
}
}
/**
* 钱包充值 (落盘 MySQL 并记录财务入账流水)
*/
export async function rechargeBalance(userId = 1001, amount) {
try {
const res = await http.post(`/users/${userId}/recharge`, { amount });
return res;
} catch (err) {
console.warn('[API] 钱包充值接口异常:', err.message);
throw err;
}
}
/**
* 佣金提现申请 (支持微信零钱、支付宝、银行卡多渠道及账号信息)
*/
export async function withdrawCommission(userId = 1001, amount, options = {}) {
try {
const payload = typeof options === 'string'
? { amount, channel: options }
: { amount, ...options };
const res = await http.post(`/users/${userId}/withdraw`, payload);
return res;
} catch (err) {
console.warn('[API] 提现申请接口异常:', err.message);
throw err;
}
}
/**
* 查询用户提现记录与审批状态 (待审核/处理中/已打款/已驳回)
*/
export async function getUserWithdrawals(userId = 1001) {
try {
const res = await http.get(`/users/${userId}/withdrawals`);
return res || [];
} catch (err) {
console.warn('[API] 获取提现记录异常:', err.message);
return [];
}
}
/**
* 查询用户财务收支流水
*/
export async function getUserFinanceRecords(userId = 1001) {
try {
const res = await http.get(`/users/${userId}/finance-records`);
return res || [];
} catch (err) {
console.warn('[API] 获取财务流水异常:', err.message);
return [];
}
}
/**
* 获取可抢订单池 (真实读取 MySQL orders 待接单列表)
*/
export async function getOrdersPool() {
try {
const res = await http.get('/orders/pool');
if (Array.isArray(res) && res.length > 0) {
return res;
}
} catch (err) {
console.warn('[API] 获取可抢订单池异常:', err.message);
}
return null;
}
/**
* 大神抢单认领
*/
export async function claimOrder(orderId, expertData = {}) {
try {
const res = await http.post(`/orders/${orderId}/claim`, expertData);
return res;
} catch (err) {
console.warn('[API] 大神抢单异常:', err.message);
throw err;
}
}
/**
* 获取大神今日接单数据汇总 (落盘 MySQL)
*/
export async function getExpertStats(expertId = 101) {
try {
const res = await http.get(`/expert/stats/${expertId}`);
if (res && typeof res.income !== 'undefined') {
return res;
}
} catch (err) {
console.warn('[API] 获取大神今日统计异常:', err.message);
}
return null;
}
/**
* 获取首页运营 Banner 列表 (配置化接口)
*/
export async function getBanners() {
try {
const res = await http.get('/banners');
if (Array.isArray(res) && res.length > 0) {
return res;
}
} catch (err) {
console.warn('[API] 获取Banner异常:', err.message);
}
return null;
}
/**
* 获取首页金刚区活动品类导航列表 (配置化接口)
*/
export async function getNavCategories() {
try {
const res = await http.get('/nav-categories');
if (Array.isArray(res) && res.length > 0) {
return res;
}
} catch (err) {
console.warn('[API] 获取金刚区品类导航异常:', err.message);
}
return null;
}
/**
* 获取钱包充值阶梯与赠送配置列表 (真实从 MySQL 读取)
*/
export async function getRechargeTiers() {
try {
const res = await http.get('/marketing/recharge-tiers');
if (Array.isArray(res) && res.length > 0) {
return res;
}
} catch (err) {
console.warn('[API] 获取充值阶梯异常:', err.message);
}
return null;
}
/**
* 获取可用优惠券列表 (支持品类过滤)
*/
export async function getMarketingCoupons(category) {
try {
const query = category ? `?category=${category}` : '';
const res = await http.get(`/marketing/coupons${query}`);
if (Array.isArray(res) && res.length > 0) {
return res;
}
} catch (err) {
console.warn('[API] 获取营销优惠券异常:', err.message);
}
return null;
}
/**
* 提交订单服务评价与星级打分 (落盘 MySQL order_reviews)
*/
export async function submitOrderReview(orderId, reviewData = {}) {
try {
const res = await http.post(`/orders/${orderId}/review`, reviewData);
return res;
} catch (err) {
console.warn('[API] 提交订单评价异常:', err.message);
throw err;
}
}
/**
* 获取大神真实历史评价列表
*/
export async function getExpertReviews(expertId) {
try {
const res = await http.get(`/companions/${expertId}/reviews`);
if (Array.isArray(res)) {
return res;
}
} catch (err) {
console.warn('[API] 获取大神评价列表异常:', err.message);
}
return [];
}
/**
* 获取友圈动态评论区列表 (落盘 MySQL post_comments)
*/
export async function getPostComments(postId) {
try {
const res = await http.get(`/posts/${postId}/comments`);
if (Array.isArray(res)) {
return res;
}
} catch (err) {
console.warn('[API] 获取动态评论异常:', err.message);
}
return [];
}
/**
* 发表友圈动态评论
*/
export async function addPostComment(postId, commentData = {}) {
try {
const res = await http.post(`/posts/${postId}/comments`, commentData);
return res;
} catch (err) {
console.warn('[API] 发表动态评论异常:', err.message);
throw err;
}
}
/**
* 申请友圈搭子互动上车
*/
export async function applyPostParty(postId, applyData = {}) {
try {
const res = await http.post(`/posts/${postId}/apply`, applyData);
return res;
} catch (err) {
console.warn('[API] 申请搭子上车异常:', err.message);
throw err;
}
}
/**
* 真实上传本地图片至服务端持久化静态存储
* @param {string} tempFilePath 本地图片临时路径 (如 wxfile://tmp_xxx 或 blob:xxx)
* @returns {Promise<string>} 返回持久化公网图片访问路径 (形如 /uploads/img_xxx.png)
*/
export function uploadImage(tempFilePath) {
return new Promise((resolve, reject) => {
if (!tempFilePath) return reject(new Error('图片路径为空'));
// 微信开发者工具临时路径形如 http://tmp/ 或 http://usr/
// 微信真机临时路径形如 wxfile://tmp_xxx 或 wxfile://clientdata/xxx
// H5 临时路径形如 blob:xxx
const isLocalTemp =
tempFilePath.startsWith('http://tmp/') ||
tempFilePath.startsWith('http://usr/') ||
tempFilePath.startsWith('wxfile://') ||
tempFilePath.startsWith('blob:');
// 只有真正的公网远程地址或相对静态路径,才无需上传直接返回
if (
!isLocalTemp &&
(tempFilePath.startsWith('http://') ||
tempFilePath.startsWith('https://') ||
tempFilePath.startsWith('/uploads/'))
) {
// 若是小程序端且为 /uploads/ 开头,补全完整公网域名
// #ifndef H5
if (tempFilePath.startsWith('/uploads/')) {
return resolve(`https://peiww.gynhc.com${tempFilePath}`);
}
// #endif
return resolve(tempFilePath);
}
// #ifdef H5
const uploadUrl = '/api/upload';
// #endif
// #ifndef H5
const uploadUrl = 'https://peiww.gynhc.com/api/upload';
// #endif
uni.uploadFile({
url: uploadUrl,
filePath: tempFilePath,
name: 'file',
success: (uploadRes) => {
try {
const data = JSON.parse(uploadRes.data);
if (data && data.code === 20000 && data.data && data.data.url) {
let finalUrl = data.data.url;
// 非H5平台(小程序端)图片访问需补全公网域名
// #ifndef H5
if (finalUrl.startsWith('/uploads/')) {
finalUrl = `https://peiww.gynhc.com${finalUrl}`;
}
// #endif
resolve(finalUrl);
} else {
reject(new Error((data && data.message) || '上传解析异常'));
}
} catch (e) {
reject(new Error('上传数据返回格式错误'));
}
},
fail: (err) => {
reject(new Error(err.errMsg || '图片上传网络异常'));
}
});
});
}
/**
* 客户端前端前置检测文本安全 (对接 security.msgSecCheck)
*/
export async function checkTextSecurity(content) {
try {
const res = await http.post('/security/msg-sec-check', { content });
return res;
} catch (err) {
throw err;
}
}
/**
* 获取平台通用配置(官方客服、履约公告指引、平台规范协议等)
*/
export async function getPlatformConfigs() {
try {
const res = await http.get('/system/configs');
return res;
} catch (err) {
console.warn('[API] 获取平台通用配置降级:', err.message);
return null;
}
}
/**
* 获取平台合规商圈场所白名单库
*/
export async function getSafetyPlaces() {
try {
const res = await http.get('/safety/places');
return res;
} catch (err) {
console.warn('[API] 获取合规商圈场所降级:', err.message);
return [];
}
}
/**
* 提交大神实名资质入驻认证申请
*/
export async function applyExpertCert(data) {
try {
const res = await http.post('/companions/apply', data);
return res;
} catch (err) {
throw err;
}
}
/**
* 获取大神多维收益走势统计分析 (近7天/近4周/近6个月)
*/
export async function getExpertRevenueTrends(expertId = 101) {
try {
const res = await http.get(`/expert/stats/${expertId}/trends`);
return res || { daily: [], weekly: [], monthly: [] };
} catch (err) {
console.warn('[API] 获取大神收益走势异常:', err.message);
return { daily: [], weekly: [], monthly: [] };
}
}
/**
* 大神感谢回复买家评价
*/
export async function replyOrderReview(reviewId, replyContent) {
try {
const res = await http.post(`/reviews/${reviewId}/reply`, { replyContent });
return res;
} catch (err) {
console.warn('[API] 回复评价异常:', err.message);
throw err;
}
}
/**
* 友圈本人动态删除
*/
export async function deletePost(postId, userId = 1001) {
try {
const res = await http.delete(`/posts/${postId}?userId=${userId}`);
return res;
} catch (err) {
console.warn('[API] 删除动态异常:', err.message);
throw err;
}
}
/**
* 获取大神专属细分服务包列表
*/
export async function getExpertServices(expertId = 101) {
try {
const res = await http.get(`/companions/${expertId}/services`);
return res || [];
} catch (err) {
console.warn('[API] 获取服务包异常:', err.message);
return [];
}
}
/**
* 切换大神单个服务包上下架状态
*/
export async function updateExpertServiceStatus(expertId = 101, serviceId, status) {
try {
const res = await http.put(`/companions/${expertId}/services/${serviceId}/status`, { status });
return res;
} catch (err) {
console.warn('[API] 切换服务包状态异常:', err.message);
throw err;
}
}
/**
* 获取用户收藏的陪玩列表
*/
export async function getFavorites(userId = 1001) {
try {
const res = await http.get(`/favorites?userId=${userId}`);
return res || [];
} catch (err) {
console.warn('[API] 获取收藏列表异常:', err.message);
return [];
}
}
/**
* 探测是否已收藏特定陪玩
*/
export async function checkFavorite(expertId, userId = 1001) {
try {
const res = await http.get(`/favorites/check?userId=${userId}&expertId=${expertId}`);
return res && res.isFavorite;
} catch (err) {
console.warn('[API] 探测收藏状态异常:', err.message);
return false;
}
}
/**
* 添加收藏
*/
export async function addFavorite(expertId, userId = 1001) {
try {
const res = await http.post('/favorites', { userId, expertId });
return res;
} catch (err) {
console.warn('[API] 添加收藏异常:', err.message);
throw err;
}
}
/**
* 取消收藏
*/
export async function removeFavorite(expertId, userId = 1001) {
try {
const res = await http.delete(`/favorites/${expertId}?userId=${userId}`);
return res;
} catch (err) {
console.warn('[API] 取消收藏异常:', err.message);
throw err;
}
}
/**
* 获取分销团队列表 (一级与二级成员)
*/
export async function getDistributionTeam(userId = 1001) {
try {
const res = await http.get(`/distribution/team?userId=${userId}`);
return res || { directCount: 0, indirectCount: 0, totalTeamCount: 0, directList: [], indirectList: [] };
} catch (err) {
console.warn('[API] 获取分销团队异常:', err.message);
return { directCount: 0, indirectCount: 0, totalTeamCount: 0, directList: [], indirectList: [] };
}
}
/**
* 获取分销返佣订单记录
*/
export async function getDistributionRecords(userId = 1001) {
try {
const res = await http.get(`/distribution/records?userId=${userId}`);
return res || [];
} catch (err) {
console.warn('[API] 获取分销返佣记录异常:', err.message);
return [];
}
}
/**
* 佣金提现申请
*/
export async function withdrawCommission(amount, channel = 'WECHAT', userId = 1001) {
try {
const res = await http.post(`/users/${userId}/withdraw`, { amount, channel });
return res;
} catch (err) {
console.warn('[API] 佣金提现申请异常:', err.message);
throw err;
}
}