164 lines
6.0 KiB
JavaScript
164 lines
6.0 KiB
JavaScript
/**
|
||
* 分销 / 微信支付 / 代付链路 / 存客宝留资 — 小程序侧统一桥接
|
||
* 阅读页 @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<boolean>} 是否提交成功
|
||
*/
|
||
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
|
||
}
|