/** * Soul创业派对 - 用户旅程规则引擎 * 在关键页面自动检查用户状态,引导完善信息 * * 规则逻辑: * 1. 注册后 → 引导填写头像和昵称 * 2. 浏览付费章节 → 引导绑定手机号 * 3. 完成匹配 → 引导填写 MBTI / 行业等 * 4. 购买全书 → 引导填写完整信息(进 VIP 群) * 5. 累计浏览 5 章 → 引导分享推广 */ const app = getApp() const RULE_COOLDOWN_KEY = 'rule_engine_cooldown' const COOLDOWN_MS = 60 * 1000 function isInCooldown(ruleId) { try { const map = wx.getStorageSync(RULE_COOLDOWN_KEY) || {} const ts = map[ruleId] if (!ts) return false return Date.now() - ts < COOLDOWN_MS } catch { return false } } function setCooldown(ruleId) { try { const map = wx.getStorageSync(RULE_COOLDOWN_KEY) || {} map[ruleId] = Date.now() wx.setStorageSync(RULE_COOLDOWN_KEY, map) } catch {} } function getUserInfo() { return app.globalData.userInfo || {} } function checkRule_FillAvatar() { const user = getUserInfo() if (!user.id) return null const avatar = user.avatar || user.avatarUrl || '' const nickname = user.nickname || '' if (avatar && !avatar.includes('default') && nickname && nickname !== '微信用户' && !nickname.startsWith('微信用户')) { return null } if (isInCooldown('fill_avatar')) return null setCooldown('fill_avatar') return { ruleId: 'fill_avatar', title: '完善个人信息', message: '设置头像和昵称,让其他创业者更容易认识你', action: 'navigate', target: '/pages/profile-edit/profile-edit' } } function checkRule_BindPhone() { const user = getUserInfo() if (!user.id) return null if (user.phone) return null if (isInCooldown('bind_phone')) return null setCooldown('bind_phone') return { ruleId: 'bind_phone', title: '绑定手机号', message: '绑定手机号解锁更多功能,保障账户安全', action: 'bind_phone', target: null } } function checkRule_FillProfile() { const user = getUserInfo() if (!user.id) return null if (user.mbti && user.industry) return null if (isInCooldown('fill_profile')) return null setCooldown('fill_profile') return { ruleId: 'fill_profile', title: '完善创业档案', message: '填写 MBTI 和行业信息,帮你精准匹配创业伙伴', action: 'navigate', target: '/pages/profile-edit/profile-edit' } } function checkRule_ShareAfter5Chapters() { const user = getUserInfo() if (!user.id) return null const readCount = app.globalData.readCount || 0 if (readCount < 5) return null if (isInCooldown('share_after_5')) return null setCooldown('share_after_5') return { ruleId: 'share_after_5', title: '邀请好友一起看', message: '你已阅读 ' + readCount + ' 个章节,分享给好友可获得分销收益', action: 'navigate', target: '/pages/referral/referral' } } /** * 在指定场景下检查规则 * @param {string} scene - 场景:after_login, before_read, after_match, after_pay, page_show * @returns {object|null} - 触发的规则,null 表示无需触发 */ function checkRules(scene) { const user = getUserInfo() if (!user.id) return null switch (scene) { case 'after_login': return checkRule_FillAvatar() case 'before_read': return checkRule_BindPhone() || checkRule_FillAvatar() case 'after_match': return checkRule_FillProfile() case 'after_pay': return checkRule_FillProfile() case 'page_show': return checkRule_FillAvatar() || checkRule_ShareAfter5Chapters() default: return null } } /** * 执行规则动作 * @param {object} rule - checkRules 返回的规则对象 * @param {object} pageInstance - 页面实例(用于绑定手机号等操作) */ function executeRule(rule, pageInstance) { if (!rule) return wx.showModal({ title: rule.title, content: rule.message, confirmText: '去完善', cancelText: '稍后再说', success: (res) => { if (res.confirm) { if (rule.action === 'navigate' && rule.target) { wx.navigateTo({ url: rule.target }) } else if (rule.action === 'bind_phone' && pageInstance) { if (typeof pageInstance.showPhoneBinding === 'function') { pageInstance.showPhoneBinding() } } } _trackRuleAction(rule.ruleId, res.confirm ? 'confirm' : 'cancel') } }) } function _trackRuleAction(ruleId, action) { const userId = getUserInfo().id if (!userId) return app.request('/api/miniprogram/track', { method: 'POST', data: { userId, action: 'rule_trigger', target: ruleId, extraData: { result: action } }, silent: true }).catch(() => {}) } /** * 在页面 onShow 中调用的便捷方法 * @param {string} scene * @param {object} pageInstance */ function checkAndExecute(scene, pageInstance) { const rule = checkRules(scene) if (rule) { setTimeout(() => executeRule(rule, pageInstance), 800) } } module.exports = { checkRules, executeRule, checkAndExecute }