feat: security hardening, wechat pay v3 platform cert integration, companion certification revocation, and audit closed-loop
这个提交包含在:
@@ -85,12 +85,15 @@ export async function createActivity(payload) {
|
||||
const body = {
|
||||
creatorId: payload.creatorId || 1001,
|
||||
title: payload.title,
|
||||
gameCategory: payload.game || '美食陪吃',
|
||||
gameCategory: payload.game || payload.gameCategory || '美食陪吃',
|
||||
location: payload.location,
|
||||
startTime: payload.startTime,
|
||||
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,
|
||||
allowDynamicPrice: payload.allowDynamicPrice !== undefined ? (payload.allowDynamicPrice ? 1 : 0) : 1,
|
||||
priceAdjustRule: payload.priceAdjustRule || 'UNIFIED_HIGH',
|
||||
};
|
||||
|
||||
try {
|
||||
@@ -123,9 +126,9 @@ export async function joinActivity(activityId, params = {}) {
|
||||
/**
|
||||
* 房主/管理员核销 4 位核销码
|
||||
*/
|
||||
export async function verifyActivityCheckin(activityId, verifyCode, operatorId = 1001) {
|
||||
export async function verifyActivityCheckin(activityId, verifyCode, operatorId) {
|
||||
return http.post(`/activities/${activityId}/verify`, {
|
||||
operatorId,
|
||||
operatorId: normalizeUserId(operatorId),
|
||||
verifyCode,
|
||||
});
|
||||
}
|
||||
@@ -133,11 +136,11 @@ export async function verifyActivityCheckin(activityId, verifyCode, operatorId =
|
||||
/**
|
||||
* 房主调整出价/追加金额
|
||||
*/
|
||||
export async function adjustActivityPrice(activityId, newPriceYuan, operatorId = 1001) {
|
||||
export async function adjustActivityPrice(activityId, newPriceYuan, operatorId) {
|
||||
const newPriceCents = Math.round(Number(newPriceYuan) * 100);
|
||||
try {
|
||||
const res = await http.post(`/activities/${activityId}/adjust-price`, {
|
||||
operatorId,
|
||||
operatorId: normalizeUserId(operatorId),
|
||||
newPriceCents,
|
||||
});
|
||||
return formatActivityData(res);
|
||||
@@ -192,26 +195,28 @@ 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: '专业同城生活陪伴,阳光健康公开。'
|
||||
}));
|
||||
return list
|
||||
.filter((c) => !c.auditStatus || c.auditStatus === '已通过')
|
||||
.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);
|
||||
@@ -311,7 +316,8 @@ export async function getOrders() {
|
||||
*/
|
||||
export async function createOrder(payload) {
|
||||
try {
|
||||
const res = await http.post('/orders', payload);
|
||||
const uid = normalizeUserId(payload && (payload.buyerId || payload.userId));
|
||||
const res = await http.post('/orders', { ...payload, buyerId: uid });
|
||||
return formatOrderData(res);
|
||||
} catch (err) {
|
||||
console.warn('[API] 后端下单未响应:', err.message);
|
||||
@@ -324,7 +330,7 @@ export async function createOrder(payload) {
|
||||
*/
|
||||
export async function cancelOrder(orderId) {
|
||||
try {
|
||||
const res = await http.post(`/orders/${orderId}/cancel`);
|
||||
const res = await http.post(`/orders/${orderId}/cancel`, { userId: normalizeUserId() });
|
||||
return formatOrderData(res);
|
||||
} catch (err) {
|
||||
console.warn('[API] 取消订单网络异常:', err.message);
|
||||
@@ -335,14 +341,14 @@ export async function cancelOrder(orderId) {
|
||||
/**
|
||||
* 支付订单
|
||||
*/
|
||||
export async function payOrder(orderId) {
|
||||
export async function payOrder(orderId, payload = {}) {
|
||||
try {
|
||||
const res = await http.post(`/orders/${orderId}/pay`);
|
||||
const res = await http.post(`/orders/${orderId}/pay`, payload);
|
||||
return formatOrderData(res);
|
||||
} catch (err) {
|
||||
console.warn('[API] 支付订单网络异常:', err.message);
|
||||
throw err;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -350,7 +356,7 @@ export async function payOrder(orderId) {
|
||||
*/
|
||||
export async function rejectOrder(orderId, payload = {}) {
|
||||
try {
|
||||
const res = await http.post(`/orders/${orderId}/reject`, payload);
|
||||
const res = await http.post(`/orders/${orderId}/reject`, { ...payload, userId: normalizeUserId(payload.userId) });
|
||||
return formatOrderData(res);
|
||||
} catch (err) {
|
||||
console.warn('[API] 拒单接口网络异常:', err.message);
|
||||
@@ -363,7 +369,7 @@ export async function rejectOrder(orderId, payload = {}) {
|
||||
*/
|
||||
export async function applyCompleteOrder(orderId, payload = {}) {
|
||||
try {
|
||||
const res = await http.post(`/orders/${orderId}/apply-complete`, payload);
|
||||
const res = await http.post(`/orders/${orderId}/apply-complete`, { ...payload, userId: normalizeUserId(payload.userId) });
|
||||
return formatOrderData(res);
|
||||
} catch (err) {
|
||||
console.warn('[API] 申请完成服务网络异常:', err.message);
|
||||
@@ -376,7 +382,7 @@ export async function applyCompleteOrder(orderId, payload = {}) {
|
||||
*/
|
||||
export async function completeOrder(orderId) {
|
||||
try {
|
||||
const res = await http.post(`/orders/${orderId}/complete`);
|
||||
const res = await http.post(`/orders/${orderId}/complete`, { userId: normalizeUserId() });
|
||||
return formatOrderData(res);
|
||||
} catch (err) {
|
||||
console.warn('[API] 确认完成网络异常:', err.message);
|
||||
@@ -389,7 +395,7 @@ export async function completeOrder(orderId) {
|
||||
*/
|
||||
export async function refundOrder(orderId, data = {}) {
|
||||
try {
|
||||
const res = await http.post(`/orders/${orderId}/refund`, data);
|
||||
const res = await http.post(`/orders/${orderId}/refund`, { ...data, userId: normalizeUserId(data.userId) });
|
||||
return formatOrderData(res);
|
||||
} catch (err) {
|
||||
console.warn('[API] 申请退款网络异常:', err.message);
|
||||
@@ -402,7 +408,7 @@ export async function refundOrder(orderId, data = {}) {
|
||||
*/
|
||||
export async function submitReport(payload = {}) {
|
||||
try {
|
||||
const res = await http.post('/reports', payload);
|
||||
const res = await http.post('/reports', { ...payload, reporterId: normalizeUserId(payload.reporterId || payload.userId) });
|
||||
return res;
|
||||
} catch (err) {
|
||||
console.warn('[API] 提交举报网络异常:', err.message);
|
||||
@@ -426,9 +432,9 @@ export async function queryCheckinCode(code) {
|
||||
/**
|
||||
* 通用4位核销码现场核销 (支持组局活动与同城线下订单)
|
||||
*/
|
||||
export async function universalVerifyCheckin(code, operatorId = 1001) {
|
||||
export async function universalVerifyCheckin(code, operatorId) {
|
||||
try {
|
||||
const res = await http.post('/verify/universal', { verifyCode: code, operatorId });
|
||||
const res = await http.post('/verify/universal', { verifyCode: code, operatorId: normalizeUserId(operatorId) });
|
||||
return res;
|
||||
} catch (err) {
|
||||
console.warn('[API] 通用核销接口异常:', err.message);
|
||||
@@ -449,6 +455,8 @@ export async function getPosts(category, userId) {
|
||||
const res = await http.get(`/posts${query}`);
|
||||
let localLikedIds = uni.getStorageSync('COMMUNITY_LIKED_POST_IDS') || [];
|
||||
if (!Array.isArray(localLikedIds)) localLikedIds = [];
|
||||
let viewsMap = uni.getStorageSync('COMMUNITY_POST_VIEWS_MAP') || {};
|
||||
if (typeof viewsMap !== 'object' || viewsMap === null) viewsMap = {};
|
||||
|
||||
if (Array.isArray(res) && res.length > 0) {
|
||||
return res.map(p => {
|
||||
@@ -456,6 +464,7 @@ export async function getPosts(category, userId) {
|
||||
const isLocallyLiked = localLikedIds.includes(strId);
|
||||
const isServerLiked = p.liked === true || p.liked === 1;
|
||||
const finalLiked = p.liked !== undefined ? isServerLiked : isLocallyLiked;
|
||||
const finalViews = Math.max(Number(p.views) || 1, Number(viewsMap[strId]) || 0);
|
||||
|
||||
return {
|
||||
id: p.id,
|
||||
@@ -474,7 +483,7 @@ export async function getPosts(category, userId) {
|
||||
likes: Number(p.likes) || 0,
|
||||
liked: finalLiked || isLocallyLiked,
|
||||
comments: Number(p.comments) || 0,
|
||||
views: Number(p.views) || 1,
|
||||
views: finalViews,
|
||||
category: p.category || 'partner',
|
||||
applyCount: Number(p.applyCount) || 0,
|
||||
pendingApplyCount: Number(p.pendingApplyCount) || 0,
|
||||
@@ -519,6 +528,26 @@ export async function likePost(id, action, userId) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态浏览次数累加 (落盘 MySQL 并同步本地缓存)
|
||||
*/
|
||||
export async function viewPost(id) {
|
||||
try {
|
||||
const strId = String(id);
|
||||
const res = await http.post(`/posts/${id}/view`, {});
|
||||
if (res && res.views !== undefined) {
|
||||
let viewsMap = uni.getStorageSync('COMMUNITY_POST_VIEWS_MAP') || {};
|
||||
if (typeof viewsMap !== 'object' || viewsMap === null) viewsMap = {};
|
||||
viewsMap[strId] = Math.max(Number(viewsMap[strId] || 0), Number(res.views));
|
||||
uni.setStorageSync('COMMUNITY_POST_VIEWS_MAP', viewsMap);
|
||||
}
|
||||
return res;
|
||||
} catch (err) {
|
||||
console.warn('[API] 累加动态浏览次数异常:', err.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 规范化用户ID,自动兼容历史测试账号映射 (将虚拟陪伴师 101 映射至真实用户 2006)
|
||||
*/
|
||||
@@ -567,10 +596,10 @@ export async function updateUserProfile(userId = 1001, data = {}) {
|
||||
/**
|
||||
* 钱包充值 (落盘 MySQL 并记录财务入账流水)
|
||||
*/
|
||||
export async function rechargeBalance(userId = 1001, amount) {
|
||||
export async function rechargeBalance(userId = 1001, amount, bonusAmount = 0) {
|
||||
const safeId = normalizeUserId(userId);
|
||||
try {
|
||||
const res = await http.post(`/users/${safeId}/recharge`, { amount });
|
||||
const res = await http.post(`/users/${safeId}/recharge`, { amount, bonusAmount });
|
||||
return res;
|
||||
} catch (err) {
|
||||
console.warn('[API] 钱包充值接口异常:', err.message);
|
||||
@@ -794,7 +823,7 @@ export async function getPostComments(postId) {
|
||||
*/
|
||||
export async function addPostComment(postId, commentData = {}) {
|
||||
try {
|
||||
const res = await http.post(`/posts/${postId}/comments`, commentData);
|
||||
const res = await http.post(`/posts/${postId}/comments`, { ...commentData, userId: normalizeUserId(commentData.userId) });
|
||||
return res;
|
||||
} catch (err) {
|
||||
console.warn('[API] 发表动态评论异常:', err.message);
|
||||
@@ -929,7 +958,7 @@ export async function getSafetyPlaces() {
|
||||
*/
|
||||
export async function applyExpertCert(data) {
|
||||
try {
|
||||
const res = await http.post('/companions/apply', data);
|
||||
const res = await http.post('/companions/apply', { ...data, userId: normalizeUserId(data && data.userId) });
|
||||
return res;
|
||||
} catch (err) {
|
||||
throw err;
|
||||
@@ -954,7 +983,7 @@ export async function getExpertRevenueTrends(expertId = 101) {
|
||||
*/
|
||||
export async function replyOrderReview(reviewId, replyContent) {
|
||||
try {
|
||||
const res = await http.post(`/reviews/${reviewId}/reply`, { replyContent });
|
||||
const res = await http.post(`/reviews/${reviewId}/reply`, { replyContent, userId: normalizeUserId() });
|
||||
return res;
|
||||
} catch (err) {
|
||||
console.warn('[API] 回复评价异常:', err.message);
|
||||
@@ -965,9 +994,10 @@ export async function replyOrderReview(reviewId, replyContent) {
|
||||
/**
|
||||
* 友圈本人动态删除
|
||||
*/
|
||||
export async function deletePost(postId, userId = 1001) {
|
||||
export async function deletePost(postId, userId) {
|
||||
try {
|
||||
const res = await http.delete(`/posts/${postId}?userId=${userId}`);
|
||||
const uid = userId || uni.getStorageSync('userId') || 1001;
|
||||
const res = await http.delete(`/posts/${postId}?userId=${uid}`);
|
||||
return res;
|
||||
} catch (err) {
|
||||
console.warn('[API] 删除动态异常:', err.message);
|
||||
@@ -993,7 +1023,7 @@ export async function getExpertServices(expertId = 101) {
|
||||
*/
|
||||
export async function updateExpertServiceStatus(expertId = 101, serviceId, status) {
|
||||
try {
|
||||
const res = await http.put(`/companions/${expertId}/services/${serviceId}/status`, { status });
|
||||
const res = await http.put(`/companions/${expertId}/services/${serviceId}/status`, { status, userId: normalizeUserId() });
|
||||
return res;
|
||||
} catch (err) {
|
||||
console.warn('[API] 切换服务包状态异常:', err.message);
|
||||
@@ -1111,7 +1141,7 @@ export async function getPostApplies(postId) {
|
||||
* 房主或管理员处置搭子上车申请 (ACCEPTED | REJECTED)
|
||||
*/
|
||||
export async function handlePostApply(applyId, status) {
|
||||
const res = await http.post(`/post-applies/${applyId}/handle`, { status });
|
||||
const res = await http.post(`/post-applies/${applyId}/handle`, { status, userId: normalizeUserId() });
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -1134,7 +1164,7 @@ export async function getMyReports(userId) {
|
||||
*/
|
||||
export async function updateCompanionProfile(expertId = 101, profileData = {}) {
|
||||
try {
|
||||
const res = await http.put(`/companions/${expertId}/profile`, profileData);
|
||||
const res = await http.put(`/companions/${expertId}`, { ...profileData, userId: normalizeUserId(profileData.userId) });
|
||||
return res;
|
||||
} catch (err) {
|
||||
console.warn('[API] 更新大神资料/接单状态异常:', err.message);
|
||||
@@ -1142,4 +1172,172 @@ export async function updateCompanionProfile(expertId = 101, profileData = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户隐私与通知订阅设置 (支持服务端持久化与本地缓存同步)
|
||||
*/
|
||||
export async function getUserSettings(userId) {
|
||||
const uid = normalizeUserId(userId);
|
||||
try {
|
||||
const res = await http.get(`/users/${uid}/settings`);
|
||||
if (res && typeof res === 'object') {
|
||||
if (typeof res.privacyHidePhone === 'boolean') {
|
||||
uni.setStorageSync('privacy_hide_phone', res.privacyHidePhone ? '1' : '0');
|
||||
}
|
||||
if (typeof res.noticeSubscribe === 'boolean') {
|
||||
uni.setStorageSync('notice_subscribe', res.noticeSubscribe ? '1' : '0');
|
||||
}
|
||||
return res;
|
||||
}
|
||||
} catch (_) {}
|
||||
return {
|
||||
userId: uid,
|
||||
privacyHidePhone: uni.getStorageSync('privacy_hide_phone') === '1',
|
||||
noticeSubscribe: uni.getStorageSync('notice_subscribe') !== '0'
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存用户隐私与通知订阅设置 (同步落盘服务端与本地存储)
|
||||
*/
|
||||
export async function updateUserSettings(userId, settings = {}) {
|
||||
const uid = normalizeUserId(userId);
|
||||
if (typeof settings.privacyHidePhone === 'boolean') {
|
||||
uni.setStorageSync('privacy_hide_phone', settings.privacyHidePhone ? '1' : '0');
|
||||
}
|
||||
if (typeof settings.noticeSubscribe === 'boolean') {
|
||||
uni.setStorageSync('notice_subscribe', settings.noticeSubscribe ? '1' : '0');
|
||||
}
|
||||
try {
|
||||
const res = await http.post(`/users/${uid}/settings`, settings);
|
||||
return res;
|
||||
} catch (_) {
|
||||
return {
|
||||
userId: uid,
|
||||
privacyHidePhone: uni.getStorageSync('privacy_hide_phone') === '1',
|
||||
noticeSubscribe: uni.getStorageSync('notice_subscribe') !== '0'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据隐私开关格式化手机号/联系方式脱敏展示
|
||||
*/
|
||||
export function formatPrivacyPhone(phone, forceHide) {
|
||||
if (!phone) return '';
|
||||
const str = String(phone).trim();
|
||||
const shouldHide = typeof forceHide === 'boolean'
|
||||
? forceHide
|
||||
: uni.getStorageSync('privacy_hide_phone') === '1';
|
||||
if (!shouldHide) return str;
|
||||
if (/^\d{11}$/.test(str)) {
|
||||
return str.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
|
||||
}
|
||||
if (str.length >= 7) {
|
||||
const head = str.slice(0, 3);
|
||||
const tail = str.slice(-2);
|
||||
return `${head}****${tail}`;
|
||||
}
|
||||
return str.slice(0, 2) + '****';
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一调起微信小程序支付 (对接 /api/pay/wechat/prepay,支持 LIVE 原生 requestPayment 与 SANDBOX 模拟收银台)
|
||||
*/
|
||||
export async function requestWechatPayment({ amount, title = '同城陪伴担保服务', orderId = '', scene = 'ORDER', userId = 1001 } = {}) {
|
||||
const uid = normalizeUserId(userId);
|
||||
const numAmount = Number(amount || 0);
|
||||
let prepayData = null;
|
||||
|
||||
let wxCode = '';
|
||||
try {
|
||||
if (typeof uni !== 'undefined' && typeof uni.login === 'function') {
|
||||
wxCode = await new Promise((resolve) => {
|
||||
uni.login({
|
||||
provider: 'weixin',
|
||||
success: (res) => resolve((res && res.code) || ''),
|
||||
fail: () => resolve('')
|
||||
});
|
||||
});
|
||||
}
|
||||
} catch (_) {}
|
||||
|
||||
try {
|
||||
prepayData = await http.post('/pay/wechat/prepay', {
|
||||
orderId,
|
||||
amount: numAmount,
|
||||
title,
|
||||
scene,
|
||||
userId: uid,
|
||||
wxCode
|
||||
});
|
||||
} catch (_) {
|
||||
prepayData = {
|
||||
mode: 'SANDBOX',
|
||||
timeStamp: String(Math.floor(Date.now() / 1000)),
|
||||
nonceStr: `pw_${Date.now()}`,
|
||||
package: `prepay_id=wx${Date.now()}`,
|
||||
signType: 'RSA',
|
||||
paySign: 'SANDBOX_FALLBACK',
|
||||
outTradeNo: orderId || `WX_${Date.now()}`
|
||||
};
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (prepayData && prepayData.mode === 'LIVE' && typeof uni.requestPayment === 'function') {
|
||||
uni.requestPayment({
|
||||
provider: 'wxpay',
|
||||
timeStamp: String(prepayData.timeStamp),
|
||||
nonceStr: String(prepayData.nonceStr),
|
||||
package: String(prepayData.package),
|
||||
signType: prepayData.signType || 'RSA',
|
||||
paySign: String(prepayData.paySign),
|
||||
success: (res) => {
|
||||
resolve({ paid: true, mode: 'LIVE', raw: res, outTradeNo: prepayData.outTradeNo });
|
||||
},
|
||||
fail: (err) => {
|
||||
const isCancel = err && err.errMsg && err.errMsg.includes('cancel');
|
||||
const errorObj = new Error(isCancel ? '已取消微信支付' : (err?.errMsg || '微信支付未完成'));
|
||||
errorObj.cancelled = isCancel;
|
||||
reject(errorObj);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 沙盒/开发联调收银台确认弹窗(未配置正式商户证书时自动接管,支持模拟确认支付与取消支付)
|
||||
uni.showModal({
|
||||
title: '微信支付收银台',
|
||||
content: `收款商户:同城陪伴官方担保托管\n商品名称:${title}\n支付金额:¥${numAmount.toFixed(2)}\n\n是否确认完成本次微信支付?`,
|
||||
confirmText: '确认支付',
|
||||
cancelText: '取消支付',
|
||||
confirmColor: '#10B981',
|
||||
success: (modalRes) => {
|
||||
if (modalRes.confirm) {
|
||||
resolve({
|
||||
paid: true,
|
||||
mode: 'SANDBOX',
|
||||
outTradeNo: (prepayData && prepayData.outTradeNo) || orderId
|
||||
});
|
||||
} else {
|
||||
const cancelErr = new Error('已取消微信支付');
|
||||
cancelErr.cancelled = true;
|
||||
reject(cancelErr);
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
const cancelErr = new Error('已取消微信支付');
|
||||
cancelErr.cancelled = true;
|
||||
reject(cancelErr);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 微信小程序真实手机号一键授权登录 (调用后端换取真实手机号并登录/注册)
|
||||
*/
|
||||
export async function loginWithWechatPhone({ phoneCode, wxCode } = {}) {
|
||||
return http.post('/auth/wechat-phone', {
|
||||
phoneCode,
|
||||
wxCode
|
||||
});
|
||||
}
|
||||
|
||||
在新工单中引用
屏蔽一个用户