后端 API:AI 对话/报告/余额告警 等服务与路由;小程序 tabBar 配置与分润相关能力;出站推送 Webhook 与管理端调试;飞书留资、小程序数据分析 等支撑;多份 数据库迁移(AI 聊天、灵魂文章、tabBar、分润等)。 管理端 / 超管:看板、用户/订单/分销/财务、设置与 小程序 tabBar 管理、分润规则、灵魂文章、AI 配置与监控 等大量页面与能力扩展;主题与布局更新。 抖音小程序:与微信侧在 结果页/购买/个人中心 等方向做了同步或优化。 另含 部署/脚本、开发文档 等配套更新。 邀请码与解锁:后端 分销/邀请码 接口与 add_invite_codes 等 SQL;小程序侧 邀请码弹窗组件、个人中心/推广/多类结果页 的填写入口与 解锁门控(inviteCodeGate、unlockGate);并补充 《小程序解锁引导与邀请码方案》 文档。 超管后台:路由与 企业中心(EnterpriseHub) 等交互与结构优化。 小程序体验:在 首页结果、推广、各测评结果页 上继续打磨;与 邀请码门控、审核门控 小步联动。
88 lines
2.1 KiB
JavaScript
88 lines
2.1 KiB
JavaScript
/**
|
|
* 支付前邀请码弹框闸门(与开发文档 §3 一致)
|
|
*/
|
|
const { shouldHideInviteCodeEntry } = require('./miniprogramAuditGate.js')
|
|
|
|
const STORAGE_BOUND = 'inviteCodeBound'
|
|
const STORAGE_SKIP = 'inviteCodeSkipped'
|
|
|
|
function shouldPromptInviteCode() {
|
|
try {
|
|
if (wx.getStorageSync(STORAGE_BOUND)) return false
|
|
if (wx.getStorageSync(STORAGE_SKIP)) return false
|
|
} catch (e) {}
|
|
return true
|
|
}
|
|
|
|
function markInviteSkipped() {
|
|
try {
|
|
wx.setStorageSync(STORAGE_SKIP, 1)
|
|
} catch (e) {}
|
|
}
|
|
|
|
function markInviteBound() {
|
|
try {
|
|
wx.setStorageSync(STORAGE_BOUND, 1)
|
|
} catch (e) {}
|
|
}
|
|
|
|
/**
|
|
* @param {WechatMiniprogram.Page.TrivialInstance | null} page
|
|
* @returns {Promise<boolean>} true 表示可继续发起支付
|
|
*/
|
|
function ensureInviteCodeGate(page) {
|
|
return new Promise((resolve) => {
|
|
try {
|
|
const app = getApp()
|
|
if (shouldHideInviteCodeEntry(app && app.globalData)) {
|
|
resolve(true)
|
|
return
|
|
}
|
|
} catch (e) {}
|
|
if (!shouldPromptInviteCode()) {
|
|
resolve(true)
|
|
return
|
|
}
|
|
if (!page || typeof page.setData !== 'function') {
|
|
resolve(true)
|
|
return
|
|
}
|
|
page._inviteCodeGateResolve = resolve
|
|
page.setData({ showInviteCodeDialog: true })
|
|
})
|
|
}
|
|
|
|
/**
|
|
* @param {WechatMiniprogram.Page.TrivialInstance | null} page
|
|
* @param {boolean} canProceed
|
|
*/
|
|
function finishInviteCodeGate(page, canProceed) {
|
|
if (page && typeof page.setData === 'function') {
|
|
page.setData({ showInviteCodeDialog: false })
|
|
}
|
|
const fn = page && page._inviteCodeGateResolve
|
|
if (page) {
|
|
page._inviteCodeGateResolve = null
|
|
}
|
|
if (typeof fn === 'function') {
|
|
fn(canProceed !== false)
|
|
}
|
|
}
|
|
|
|
/** 非支付闸门:从推广中心 / 我的 等入口主动打开填写弹框 */
|
|
function openInviteCodeDialog(page) {
|
|
if (!page || typeof page.setData !== 'function') return
|
|
page.setData({ showInviteCodeDialog: true })
|
|
}
|
|
|
|
module.exports = {
|
|
shouldPromptInviteCode,
|
|
markInviteSkipped,
|
|
markInviteBound,
|
|
ensureInviteCodeGate,
|
|
finishInviteCodeGate,
|
|
openInviteCodeDialog,
|
|
STORAGE_BOUND,
|
|
STORAGE_SKIP
|
|
}
|