// pages/index/result.js - AI分析结果页(按旧版模板重构) const app = getApp() const payment = require('../../utils/payment') const { hasPhone, bindPhoneByCode, isProfileComplete, needsResultProfileGate, navigateToCompleteProfileAfterPhoneIfNeeded } = require('../../utils/phoneAuth.js') const unlockGate = require('../../utils/unlockGate.js') const inviteCodeGate = require('../../utils/inviteCodeGate.js') const { shouldHideInviteCodeEntry } = require('../../utils/miniprogramAuditGate.js') const { mbtiDescriptions } = require('../../utils/descriptions') const { triggerTestResultCompleted } = require('../../utils/pushHook') function buildSceneFallback(baseResult) { const mbti = baseResult.mbti || '' const d = mbtiDescriptions[mbti] || {} const jobs = (d.careers || []).slice(0, 2).join('、') || '专业岗位' const name = d.name || baseResult.title || '' return { careerDevelopment: `结合 ${mbti}${name ? '(' + name + ')' : ''} 特质,${jobs} 等与系统性、长期主义更契合的路径往往更容易做出成绩;建议前 1~3 年夯实基本功与协作习惯,再向骨干或专家角色过渡。`, familyParenting: '家庭互动中可减少「对错评判」、增加情感确认;给孩子清晰边界的同时也留出讨论与试错空间,更利于信任感与自驱力。', partnerCofounder: '寻找合伙人时建议重点考察责任感与信息透明度,角色分工、决策机制与退出规则尽量书面化;互补型搭档通常比同特质堆叠更有效。' } } /** 仅在后端已下发完整面相等字段时合并;预览脱敏接口不下发,避免未付费用户看到正文 */ function mergeSceneBlocks(apiData, baseResult) { const trim = (s) => (s && String(s).trim()) || '' const apiC = trim(apiData.careerDevelopment) const apiF = trim(apiData.familyParenting) const apiP = trim(apiData.partnerCofounder) const fa = apiData.faceAnalysis const bone = apiData.boneAnalysis const rel = typeof apiData.relationship === 'string' ? apiData.relationship.trim() : '' const hasUnlockedReport = rel.length > 8 || (typeof fa === 'string' && fa.length > 40) || (fa && typeof fa === 'object' && !Array.isArray(fa)) || (typeof apiData.faceAnalysisText === 'string' && apiData.faceAnalysisText.length > 40) || (typeof bone === 'string' && bone.length > 40) || (bone && typeof bone === 'object' && !Array.isArray(bone)) || (typeof apiData.boneAnalysisText === 'string' && apiData.boneAnalysisText.length > 40) if (!hasUnlockedReport) { return { careerDevelopment: '', familyParenting: '', partnerCofounder: '' } } const fb = buildSceneFallback(baseResult) return { careerDevelopment: apiC || fb.careerDevelopment, familyParenting: apiF || fb.familyParenting, partnerCofounder: apiP || fb.partnerCofounder } } const { getEnterpriseIdForApiPayload } = require('../../utils/enterpriseContext.js') Page({ data: { isAnalyzing: true, showResult: false, hasError: false, errorMessage: '', noFaceError: false, noFaceMessage: '', progress: 0, analyzingTip: '正在识别面部特征...', activeTab: 'face', // 'face' | 'bone' // 报告付费信息 payInfo: { requiresPayment: false, // 是否需要付费才解锁完整报告 isPaid: false, // 当前这次是否已解锁 amountYuan: 0 // 人脸报告价格(元) }, result: { mbti: '', title: '', summary: '', pdp: '', pdpAux: '', pdpEmoji: '', disc: '', discAux: '', sbtiCode: '', sbtiCn: '', sbtiMainTypeDesc: '', traits: [], faceAnalysisText: '', boneAnalysisText: '', careers: [], relationship: '', gallupTop3: [], // 完整面相/骨相(object 才用,字符串走 *Text 字段) faceAnalysis: null, boneAnalysis: null, // 企业版:职业画像、HR视角、老板视角、简历亮点 portrait: null, hrView: null, bossView: null, resumeHighlights: '', careerDevelopment: '', familyParenting: '', partnerCofounder: '' }, // 当前这次AI分析对应的测试记录ID(mbti_test_results.id) testResultId: null, // 支付后是否已经触发过一次“刷新完整报告”,避免重复刷新 hasReloadedAfterPay: false, // 是否已在本地拥有手机号(决定是否还需要弹出微信手机号授权) hasPhone: false, isProfileComplete: false, /** fs=1 等分享落地:不挡手机登录门禁 */ fromShare: false, /** 非分享且本会话未 getPhoneNumber 成功:遮挡完整报告 */ phoneLoginGate: false, /** 企业后台关闭 SBTI 时不展示人脸报告中的 SBTI(与 enterprisePermissions.sbti 一致) */ showSbtiFace: true, analyzingTitle: '正在分析中', reportTitle: '分析报告', aiAnalysisText: '智能分析', showInviteCodeDialog: false, hideInviteCodeEntry: false }, onLoad(options) { this._payInfoSetByDetail = false try { wx.showShareMenu({ withShareTicket: true, menus: ['shareAppMessage', 'shareTimeline'] }) } catch (e) {} // 加载文案配置(分析中提示、报告标题等) const tc = app.globalData.textConfig if (tc) { this.setData({ analyzingTitle: tc.analyzingTitle || '正在分析中', reportTitle: tc.reportTitle || '分析报告', aiAnalysisText: tc.aiAnalysisText || '智能分析' }) if (tc.reportTitle) wx.setNavigationBarTitle({ title: tc.reportTitle }) } else { app.getRuntimeConfig().then((cfg) => { if (cfg && cfg.textConfig) { app.globalData.textConfig = cfg.textConfig const t = cfg.textConfig this.setData({ analyzingTitle: t.analyzingTitle || '正在分析中', reportTitle: t.reportTitle || '分析报告', aiAnalysisText: t.aiAnalysisText || '智能分析' }) if (t.reportTitle) wx.setNavigationBarTitle({ title: t.reportTitle }) } }).catch(() => {}) } const idStr = options && options.id != null && options.id !== '' ? String(options.id) : '' const st = options && options.st ? String(options.st).trim() : '' const rawType = options && options.type ? String(options.type).toLowerCase() : '' // 人脸记录在库中可能是 face 或 ai;仅 id 时默认识别为人脸报告(兼容旧分享) const faceType = rawType || (idStr ? 'ai' : '') // 带记录 id:只读库展示,禁止落入 startAnalysis 造成「二次分析」 if (idStr && (faceType === 'ai' || faceType === 'face')) { const fromShareFs = options && (String(options.fs) === '1' || options.from === 'share') this.setData({ testResultId: idStr, fromShare: !!fromShareFs }) this.loadFaceRecordById(idStr, st, faceType) return } if (idStr) { wx.showToast({ title: '链接参数无效', icon: 'none' }) setTimeout(() => wx.navigateBack(), 1500) return } // 无 id:正常从拍照流程进入,调用 /api/analyze this.startAnalysis() }, /** * 加载人脸报告:优先免登录 share-detail(好友分享),失败且已登录再 detail */ loadFaceRecordById(id, st, typeParam) { const apiBase = app.globalData?.apiBase || '' if (!apiBase) { wx.showToast({ title: '配置异常', icon: 'none' }) return } const token = app.globalData.token || wx.getStorageSync('token') || '' const applyPayload = (payload) => { wx.hideLoading() const apiData = payload.data || payload this.initPayInfoFromRuntime(!!payload.requiresPayment, !!payload.isPaid, payload) this.processResult(apiData) } const loadDetailAuthed = () => { if (!token) { wx.hideLoading() wx.showToast({ title: '未登录,无法查看该记录', icon: 'none' }) setTimeout(() => wx.navigateBack(), 1500) return } wx.showLoading({ title: '加载中...' }) wx.request({ url: `${apiBase}/api/test/detail`, method: 'GET', header: { Authorization: `Bearer ${token}` }, data: { id }, success: (res) => { if (res.statusCode === 200 && res.data && res.data.code === 200 && res.data.data) { applyPayload(res.data.data) } else { wx.hideLoading() wx.showToast({ title: res.data?.message || '加载失败', icon: 'none' }) setTimeout(() => wx.navigateBack(), 1500) } }, fail: () => { wx.hideLoading() wx.showToast({ title: '网络错误', icon: 'none' }) setTimeout(() => wx.navigateBack(), 1500) } }) } wx.showLoading({ title: '加载中...' }) const data = { id: String(id), type: typeParam === 'face' ? 'face' : 'ai' } if (st) data.st = st wx.request({ url: `${apiBase}/api/test/share-detail`, method: 'GET', data, success: (res) => { if (res.statusCode === 200 && res.data && res.data.code === 200 && res.data.data) { applyPayload(res.data.data) return } wx.hideLoading() loadDetailAuthed() }, fail: () => { wx.hideLoading() loadDetailAuthed() } }) }, _syncPhoneLoginGate() { if (this.data.hasError) { this.setData({ phoneLoginGate: false }) return } const gate = needsResultProfileGate(!!this.data.fromShare) this.setData({ phoneLoginGate: gate }) }, onShow() { const gd = app.globalData || {} const ep = gd.enterprisePermissions const showSbtiFace = !ep || ep.sbti !== false this.setData({ hasPhone: hasPhone(), isProfileComplete: isProfileComplete(), showSbtiFace, hideInviteCodeEntry: shouldHideInviteCodeEntry(gd) }) if (this.data.showResult) this._syncPhoneLoginGate() const tc = app.globalData.textConfig if (tc) { this.setData({ analyzingTitle: tc.analyzingTitle || '正在分析中', reportTitle: tc.reportTitle || '分析报告', aiAnalysisText: tc.aiAnalysisText || '智能分析' }) } }, // 面相/骨相 Tab 切换 switchAnalysisTab(e) { this.setData({ activeTab: e.currentTarget.dataset.tab }) }, // 调用后端AI分析API(aiPhotos 应为上传后的 URL 数组,由拍照页上传后写入) startAnalysis() { let photos = wx.getStorageSync('aiPhotos') || [] if (!Array.isArray(photos)) photos = [] const isUrls = photos.length > 0 && photos.every(p => typeof p === 'string' && (p.startsWith('http://') || p.startsWith('https://'))) if (!isUrls || photos.length === 0) { this.setData({ progress: 100 }) setTimeout(() => { wx.showToast({ title: '请先完成拍照并上传', icon: 'none' }) wx.navigateBack({ delta: 1 }) }, 300) return } const tips = [ '正在识别面部特征...', '分析眉眼特征...', '结合《冰鉴》分析骨形...', '匹配MBTI/PDP/DISC/SBTI...', '生成综合报告...' ] let progress = 0 let tipIndex = 0 // 进度动画 const timer = setInterval(() => { progress += 3 if (progress > 95) progress = 95 if (progress > (tipIndex + 1) * 18 && tipIndex < tips.length - 1) tipIndex++ this.setData({ progress: Math.floor(progress), analyzingTip: tips[tipIndex] }) }, 200) // 个人版入口不带企业参数;企业版才回落绑定/默认企业 const enterpriseId = getEnterpriseIdForApiPayload() wx.request({ url: `${app.globalData.apiBase}/api/analyze`, method: 'POST', timeout: 120000, header: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${wx.getStorageSync('token') || ''}` }, data: { photoUrls: photos, userId: app.globalData.openId || '', ...(enterpriseId != null ? { enterpriseId: Number(enterpriseId) } : {}) }, success: (res) => { clearInterval(timer) if (res.statusCode === 200 && res.data) { const bodyCode = res.data.code // 后端 error() 始终返回 HTTP 200,业务错误码放在 data.code 中 if (bodyCode === 422) { // AI 未检测到人脸 const msg = res.data.message || '图片中未检测到人脸,请确保拍摄时面部清晰可见' this.setData({ progress: 100 }) setTimeout(() => this.showNoFaceError(msg), 300) } else if (bodyCode === 200) { const apiData = res.data.data || res.data try { require('../../utils/analytics').track('ai_analysis_complete', { mbti: (apiData.mbti && apiData.mbti.type) || '' }) } catch (e) {} this.setData({ progress: 100, analyzingTip: '分析完成!' }) setTimeout(() => { this.processResult(apiData) }, 500) } else { console.error('API返回错误:', res) this.setData({ progress: 100 }) const msg = (res.data && (res.data.message || res.data.msg)) || '分析失败,请稍后重试' setTimeout(() => this.showAnalyzeError(msg), 300) } } else { console.error('API返回错误:', res) this.setData({ progress: 100 }) setTimeout(() => this.showAnalyzeError('分析失败,请稍后重试'), 300) } }, fail: (err) => { clearInterval(timer) console.error('API调用失败:', err) this.setData({ progress: 100 }) setTimeout(() => this.showAnalyzeError('网络异常,请检查网络后重试'), 300) } }) }, // 处理API返回结果 processResult(apiData) { const ep = app.globalData.enterprisePermissions const showSbtiFace = !ep || ep.sbti !== false const sbtiCode = showSbtiFace ? (apiData.sbti?.code || apiData.sbtiType || '') : '' const sbtiCn = showSbtiFace ? (apiData.sbti?.cn || apiData.sbtiCn || '') : '' const sbtiMainTypeDesc = (showSbtiFace && (sbtiCode || sbtiCn)) ? (apiData.sbti?.mainTypeDesc || apiData.sbtiMainTypeDesc || '维度命中度较高,当前结果可视为你的第一人格画像。') : '' const base = { mbti: apiData.mbti?.type || '', title: apiData.mbti?.title || '', summary: apiData.personalitySummary || apiData.overview || '', pdp: apiData.pdp?.primary || '', pdpAux: apiData.pdp?.secondary || '', pdpEmoji: this.getPDPEmoji(apiData.pdp?.primary), disc: apiData.disc?.primary || '', discAux: apiData.disc?.secondary || '', sbtiCode, sbtiCn, sbtiMainTypeDesc, traits: Array.isArray(apiData.advantages) ? apiData.advantages : [], faceAnalysisText: typeof apiData.faceAnalysis === 'string' ? apiData.faceAnalysis : '', boneAnalysisText: typeof apiData.boneAnalysis === 'string' ? apiData.boneAnalysis : '', careers: Array.isArray(apiData.careers) ? apiData.careers : [], relationship: apiData.relationship || '', gallupTop3: Array.isArray(apiData.gallupTop3) ? apiData.gallupTop3 : [] } const scene = mergeSceneBlocks(apiData, base) const result = { ...base, ...scene, faceAnalysis: null, boneAnalysis: null, portrait: apiData.portrait || null, hrView: apiData.hrView || null, bossView: apiData.bossView || null, resumeHighlights: apiData.resumeHighlights || '', timestamp: Date.now() } wx.setStorageSync('aiResult', result) if (app.globalData) app.globalData.aiResult = result // 测试记录已由 /api/analyze 顺带写入,无需再调 /api/test/submit const updates = { isAnalyzing: false, showResult: true, hasError: false, result, showSbtiFace } // 记录本次测试记录ID(由 /api/analyze 返回) if (apiData && apiData._testResultId) { updates.testResultId = apiData._testResultId triggerTestResultCompleted(apiData._testResultId) } this.setData(updates) this._syncPhoneLoginGate() // 优先使用后端 /api/analyze 返回的价格信息,避免二次请求 if (apiData._payment) { const p = apiData._payment || {} let amountYuan = typeof p.amountYuan === 'number' ? p.amountYuan : (p.amountFen ? (p.amountFen / 100) : 0) if (p.requiresPayment && amountYuan <= 0) amountYuan = 1 this.setData({ payInfo: { requiresPayment: !!p.requiresPayment, isPaid: false, amountYuan } }) } else if (!this._payInfoSetByDetail) { // 拍照直连分析未带 _payment 时,拉 runtime 定价 // 历史详情入口已由 initPayInfoFromRuntime(detailPayload) 处理过,不再覆盖 this.initPayInfoFromRuntime() } }, // PDP类型对应emoji getPDPEmoji(type) { const map = { '老虎': '🐅', '孔雀': '🦚', '无尾熊': '🐨', '考拉': '🐨', '猫头鹰': '🦉', '变色龙': '🦎' } return map[type] || '🐅' }, /** * 初始化付费信息:结合运行配置 + 可选的数据库记录状态 * @param {boolean|null} recordRequires 是否从记录中读到需要付费(可为空) * @param {boolean} recordIsPaid 记录是否已付费 */ initPayInfoFromRuntime(recordRequires = null, recordIsPaid = false, detailPayload = null) { // 从历史/详情进入:优先用 test_results 的 paidAmount,需付款但金额为0 则直接可查看 if (detailPayload && (detailPayload.paidAmount != null || detailPayload.amountYuan != null || detailPayload.needPaymentToUnlock != null)) { const paidAmount = Number(detailPayload.paidAmount ?? 0) const amountYuan = detailPayload.amountYuan != null ? Number(detailPayload.amountYuan) : (paidAmount > 0 ? paidAmount / 100 : 0) const needPay = detailPayload.needPaymentToUnlock === true || (!!detailPayload.requiresPayment && !detailPayload.isPaid && paidAmount > 0) // 标记:历史详情已确定付费状态,processResult 中不再用全局配置覆盖 this._payInfoSetByDetail = true this.setData({ payInfo: { requiresPayment: needPay, isPaid: !!detailPayload.isPaid, amountYuan: needPay ? amountYuan : 0 }, hasPhone: hasPhone(), isProfileComplete: isProfileComplete() }) return } app.getRuntimeConfig() .then((cfg) => { const pricing = cfg.pricing || {} const reportRequires = cfg.reportRequiresPayment || {} const facePriceRaw = pricing.face const facePrice = typeof facePriceRaw === 'number' ? facePriceRaw : Number(facePriceRaw || 0) const requiresByConfig = !!(reportRequires && reportRequires.face) let requiresPayment = typeof recordRequires === 'boolean' ? recordRequires : requiresByConfig let amountYuan = facePrice > 0 ? facePrice : 0 let needPay = requiresPayment && amountYuan > 0 // 后台开启人脸报告付费但未配有效单价时,按 ¥1 展示并走支付 if (requiresByConfig && !needPay) { amountYuan = 1 needPay = true requiresPayment = true } this.setData({ payInfo: { requiresPayment: needPay, isPaid: !!recordIsPaid, amountYuan: needPay ? amountYuan : 0 }, hasPhone: hasPhone(), isProfileComplete: isProfileComplete() }) }) .catch(() => { this.setData({ payInfo: { requiresPayment: false, isPaid: !!recordIsPaid, amountYuan: 0 }, hasPhone: hasPhone(), isProfileComplete: isProfileComplete() }) }) }, goToCompleteProfile() { wx.navigateTo({ url: '/pages/user-profile/index' }) }, /** 付费墙主按钮:先支付,支付后再引导手机号与资料 */ onTapUnlockPay() { try { require('../../utils/analytics').track('tap_unlock_pay', { amount: this.data.payInfo.amountYuan, testResultId: this.data.testResultId }) } catch (e) {} this.unlockFullReport() }, // 解锁完整报告:先留资门禁,再发起人脸测试付费 unlockFullReport() { const { payInfo, testResultId, hasReloadedAfterPay } = this.data if (!payInfo.requiresPayment || payInfo.isPaid) return app.ensureLogin().then((logged) => { if (!logged) { wx.showToast({ title: '请先登录后再解锁', icon: 'none' }) return } unlockGate.ensureUnlockPrerequisitesBeforePay(this).then((ok) => { if (!ok) return inviteCodeGate.ensureInviteCodeGate(this).then((go) => { if (!go) return payment.purchaseFaceTest({ testResultId, success: () => { wx.showToast({ title: '已解锁完整报告', icon: 'success' }) this.setData({ 'payInfo.isPaid': true, hasPhone: hasPhone(), isProfileComplete: isProfileComplete() }) if (testResultId && !hasReloadedAfterPay) { this.setData({ hasReloadedAfterPay: true }) setTimeout(() => { this.reloadFullDetail(testResultId) }, 500) } }, fail: () => {} }) }) }) }) }, openInviteCodeFill() { app.ensureLogin().then((ok) => { if (!ok) { wx.showToast({ title: '请先登录', icon: 'none' }) return } inviteCodeGate.openInviteCodeDialog(this) }) }, onInviteCodeSkip() { inviteCodeGate.finishInviteCodeGate(this, true) }, onInviteCodeSuccess() { inviteCodeGate.finishInviteCodeGate(this, true) }, /** 支付成功后:仅绑定手机号,不重复发起支付 */ onPostPayBindPhone(e) { const { code, errMsg } = e.detail || {} if (errMsg && errMsg.indexOf('getPhoneNumber:fail') === 0) { wx.showToast({ title: '需要手机号以便保存报告', icon: 'none' }) return } if (!code) { wx.showToast({ title: '获取手机号失败', icon: 'none' }) return } bindPhoneByCode(code) .then(() => { this.setData({ hasPhone: true, isProfileComplete: isProfileComplete() }) this._syncPhoneLoginGate() wx.showToast({ title: '已绑定手机号', icon: 'success' }) navigateToCompleteProfileAfterPhoneIfNeeded() }) .catch(() => {}) }, /** 结果页主流程:微信手机号快捷登录后解锁完整报告区 */ onPhoneLoginForFaceResult(e) { const { code, errMsg } = e.detail || {} if (errMsg && errMsg.indexOf('getPhoneNumber:fail') === 0) { wx.showToast({ title: '需要授权手机号才能查看完整报告', icon: 'none' }) return } if (!code) { wx.showToast({ title: '获取手机号失败', icon: 'none' }) return } bindPhoneByCode(code) .then(() => { this.setData({ hasPhone: true, isProfileComplete: isProfileComplete() }) this._syncPhoneLoginGate() navigateToCompleteProfileAfterPhoneIfNeeded() }) .catch(() => {}) }, // 兼容旧版:付费前绑手机(现流程已改为先付费,此方法可不再使用) onGetPhoneNumberForFacePay(e) { const { code, errMsg } = e.detail || {} if (errMsg && errMsg.indexOf('getPhoneNumber:fail') === 0) { if (hasPhone()) { this.unlockFullReport() } else { wx.showToast({ title: '需要授权手机号才能继续', icon: 'none' }) } return } if (!code) { if (hasPhone()) { this.unlockFullReport() } else { wx.showToast({ title: '获取手机号失败', icon: 'none' }) } return } bindPhoneByCode(code) .then(() => { this.setData({ hasPhone: true }) this._syncPhoneLoginGate() this.unlockFullReport() }) .catch(() => { // 保持在当前页,等待用户重新点击 }) }, // 解锁成功后,根据测试记录ID重新拉取完整详情 reloadFullDetail(id) { if (!id) return const app = getApp() const apiBase = app.globalData?.apiBase || '' wx.showLoading({ title: '加载完整报告...' }) wx.request({ url: `${apiBase}/api/test/detail`, method: 'GET', header: { 'Authorization': app.globalData?.token ? `Bearer ${app.globalData.token}` : '' }, data: { id }, success: (res) => { if (res.statusCode === 200 && res.data && res.data.data) { const payload = res.data.data const apiData = payload.data || payload // 先确定付费状态,再渲染结果(避免 processResult 异步覆盖) const recordRequires = typeof payload.requiresPayment === 'boolean' || typeof payload.requiresPayment === 'number' ? !!payload.requiresPayment : null const recordIsPaid = !!payload.isPaid this.initPayInfoFromRuntime(recordRequires, recordIsPaid, payload) this.processResult(apiData) } else { console.error('刷新完整报告失败', res) } }, fail: (err) => { console.error('请求完整报告失败', err) }, complete: () => { wx.hideLoading() } }) }, // 无人脸错误:显示提示并提供重新拍摄入口 showNoFaceError(message) { this.setData({ isAnalyzing: false, showResult: false, noFaceError: true, noFaceMessage: message || '图片中未检测到人脸,请重新拍摄清晰的正面照片' }) }, // 分析失败:不使用任何本地模拟数据 showAnalyzeError(message) { this.setData({ isAnalyzing: false, showResult: true, hasError: true, errorMessage: message || '分析失败,请稍后重试', phoneLoginGate: false }) }, shareResult() { wx.showShareMenu({ withShareTicket: true, menus: ['shareAppMessage', 'shareTimeline'] }) }, /** 跳转 MBTI / PDP / DISC 题目测试选择页 */ goToQuestionnaireTest() { wx.navigateTo({ url: '/pages/test-select/index' }) }, retake() { // camera 是 tabBar 页面,必须用 switchTab wx.switchTab({ url: '/pages/index/camera' }) }, goHome() { // 根据当前 scope 跳对应首页 const scope = (getApp().globalData && getApp().globalData.appScope) || 'personal' if (scope === 'enterprise') { wx.navigateTo({ url: '/pages/enterprise/index' }) } else { wx.switchTab({ url: '/pages/index/index' }) } }, goToDeepServiceFromFace() { try { require('../../utils/analytics').track('tap_deep_service_face_result', {}) } catch (e) {} wx.navigateTo({ url: '/pages/purchase/index' }) }, goToPromoFromFace() { try { require('../../utils/analytics').track('tap_promo_face_result', {}) } catch (e) {} wx.navigateTo({ url: '/pages/promo/index' }) }, goToQuestionnaireFromFace() { try { require('../../utils/analytics').track('tap_questionnaire_face_result', {}) } catch (e) {} wx.navigateTo({ url: '/pages/test-select/index' }) }, onShareAppMessage() { const r = this.data.result const t = this.data.aiAnalysisText || '智能分析' const { getResultSharePath, getSharePathByScope } = require('../../utils/share') const tid = this.data.testResultId if (tid) { return { title: `${t}我是${r?.mbti} ${r?.pdpEmoji}${r?.pdp}型,来测测你的!`, path: getResultSharePath('/pages/index/result', { id: tid, type: 'ai' }) } } return { title: `${t}我是${r?.mbti} ${r?.pdpEmoji}${r?.pdp}型,来测测你的!`, path: getSharePathByScope('/pages/index/index') } }, onShareTimeline() { const r = this.data.result const t = this.data.aiAnalysisText || '智能分析' const { getResultShareTimelineQuery, buildShareQuery } = require('../../utils/share') const tid = this.data.testResultId if (tid) { return { title: `${t}我是${r?.mbti} ${r?.pdpEmoji}${r?.pdp}型,来测测你的!`, query: getResultShareTimelineQuery({ id: tid, type: 'ai' }) } } return { title: `${t}我是${r?.mbti} ${r?.pdpEmoji}${r?.pdp}型,来测测你的!`, query: buildShareQuery() } } })