/** * 分销 / 微信支付 / 代付链路 / 存客宝留资 — 小程序侧统一桥接 * 阅读页 @mention、会员详情点头像、章节与代付支付等共用。 */ /** * 支付订单携带的推荐码:优先落地页写入的 storage,否则当前用户自己的码(便于自购归因一致) */ function getReferralCodeForPay(app) { try { const s = wx.getStorageSync('referral_code') if (s != null && String(s).trim() !== '') return String(s).trim() } catch (e) {} if (app && typeof app.getMyReferralCode === 'function') { const c = app.getMyReferralCode() if (c) return String(c).trim() } return '' } /** 章节 / 全书支付描述(与 read 页原逻辑一致) */ function buildSectionPayDescription(productType, sectionId, sectionTitle) { if (productType === 'fullbook') return '《一场Soul的创业实验》全书' if (productType === 'section') { const t = sectionTitle || sectionId || '' const short = t.length > 20 ? t.slice(0, 20) + '...' : t return `章节${sectionId}-${short}` } return '' } /** * 调起微信 JSAPI 支付(字段与 soul-api GetJSAPIPayParams 一致,勿 spread 全对象以免带入多余字段) */ function requestWxJsapiPayment(payParams) { return new Promise((resolve, reject) => { if (!payParams || payParams.timeStamp == null) { reject(new Error('支付参数异常')) return } wx.requestPayment({ timeStamp: String(payParams.timeStamp), nonceStr: payParams.nonceStr, package: payParams.package, signType: payParams.signType || 'RSA', paySign: payParams.paySign, success: resolve, fail: reject }) }) } /** 支付成功后主动查单,缓解回调延迟导致订单长期 created */ function syncOrderStatusQuery(app, orderSn) { if (!app || !orderSn) return Promise.resolve() return app.request(`/api/miniprogram/pay?orderSn=${encodeURIComponent(orderSn)}`, { silent: true }).catch(() => null) } /** * 提交存客宝 lead(与阅读页 @、会员详情点头像同接口) * @param {object} app getApp() * @param {{ targetUserId?: string, targetNickname?: string, targetMemberId?: string, targetMemberName?: string, source: string, phoneModalContent?: string }} opts * @returns {Promise} 是否提交成功 */ async function submitCkbLead(app, opts) { const targetUserId = ((opts && opts.targetUserId) || '').trim() const targetMemberId = ((opts && opts.targetMemberId) || '').trim() let targetNickname = (opts && opts.targetNickname != null) ? String(opts.targetNickname).trim() : '' if (targetUserId && !targetNickname) targetNickname = 'TA' const targetMemberName = ((opts && opts.targetMemberName) || '').trim() const source = (opts && opts.source) || 'article_mention' const phoneModalContent = (opts && opts.phoneModalContent) || '请先填写手机号(必填),以便对方联系您' // 文章 @ 为 token;会员详情无 token 时用 targetMemberId 走全局获客计划(与后端 CKBLead 一致) if (!targetUserId && !targetMemberId) return false if (!app.globalData.isLoggedIn || !app.globalData.userInfo) { return await new Promise((resolve) => { wx.showModal({ title: '提示', content: '请先登录后再添加好友', confirmText: '去登录', cancelText: '取消', success: (res) => { if (res.confirm) wx.switchTab({ url: '/pages/my/my' }) resolve(false) } }) }) } const myUserId = app.globalData.userInfo.id let phone = (app.globalData.userInfo.phone || wx.getStorageSync('user_phone') || '').trim().replace(/\s/g, '') let wechatId = (app.globalData.userInfo.wechatId || app.globalData.userInfo.wechat_id || wx.getStorageSync('user_wechat') || '').trim() if (!phone || !/^1[3-9]\d{9}$/.test(phone)) { try { const profileRes = await app.request({ url: `/api/miniprogram/user/profile?userId=${myUserId}`, silent: true }) if (profileRes && profileRes.success && profileRes.data) { phone = (profileRes.data.phone || wx.getStorageSync('user_phone') || '').trim().replace(/\s/g, '') wechatId = (profileRes.data.wechatId || profileRes.data.wechat_id || wx.getStorageSync('user_wechat') || '').trim() } } catch (e) {} } if (!phone || !/^1[3-9]\d{9}$/.test(phone)) { return await new Promise((resolve) => { wx.showModal({ title: '完善资料', content: phoneModalContent, confirmText: '去填写', cancelText: '取消', success: (res) => { if (res.confirm) wx.navigateTo({ url: '/pages/profile-edit/profile-edit' }) resolve(false) } }) }) } wx.showLoading({ title: '提交中...', mask: true }) try { const res = await app.request({ url: '/api/miniprogram/ckb/lead', method: 'POST', data: { userId: myUserId, phone: phone || undefined, wechatId: wechatId || undefined, name: (app.globalData.userInfo.nickname || '').trim() || undefined, targetUserId: targetUserId || undefined, targetNickname: targetNickname !== '' ? targetNickname : undefined, targetMemberId: targetMemberId || undefined, targetMemberName: targetMemberName || undefined, source } }) wx.hideLoading() if (res && res.success) { try { wx.setStorageSync('lead_last_submit_ts', Date.now()) } catch (e) {} wx.showToast({ title: res.message || '提交成功,对方会尽快联系您', icon: 'success' }) return true } wx.showToast({ title: (res && res.message) || '提交失败', icon: 'none' }) return false } catch (e) { wx.hideLoading() const resp = e && e.response const hint = (resp && (resp.message || resp.error)) || (e && e.message) || '提交失败' wx.showToast({ title: String(hint), icon: 'none' }) return false } } module.exports = { getReferralCodeForPay, buildSectionPayDescription, requestWxJsapiPayment, syncOrderStatusQuery, submitCkbLead }