Files
MBTI_wang/miniprogram/pages/ai-chat/report.js

195 lines
6.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 神仙 AI · 深度画像报告页
const { request } = require('../../utils/request.js')
const analytics = require('../../utils/analytics.js')
Page({
data: {
cid: 0, // 来源对话 id
reportId: 0, // 当前报告 id
report: {}, // 报告对象
paying: false,
pollTimer: null
},
onLoad(options) {
const cid = parseInt(options && options.cid, 10) || 0
const rid = parseInt(options && options.rid, 10) || 0
this.setData({ cid, reportId: rid })
analytics.track('page_view', { pagePath: 'pages/ai-chat/report' })
this.initReport()
},
onUnload() {
if (this.data.pollTimer) clearTimeout(this.data.pollTimer)
},
/** 初始化:有 rid 直接拉;否则先 createOrGetPending */
initReport() {
if (this.data.reportId > 0) {
this.loadReport(this.data.reportId)
return
}
request({
url: '/api/ai/report/create',
method: 'POST',
data: { conversationId: this.data.cid },
success: (res) => {
const body = (res && res.data) || {}
if (body.code !== 200) {
wx.showToast({ title: body.message || '创建失败', icon: 'none' })
return
}
const r = body.data || {}
this.setData({ reportId: r.id, report: r }, () => {
if (r.status === 'generating' || r.status === 'paid') this._schedulePoll()
})
}
})
},
loadReport(id) {
request({
url: `/api/ai/report/${id}`,
method: 'GET',
success: (res) => {
const body = (res && res.data) || {}
if (body.code !== 200) {
wx.showToast({ title: body.message || '加载失败', icon: 'none' })
return
}
this.setData({ report: body.data || {} }, () => {
const s = this.data.report.status
if (s === 'generating' || s === 'paid') this._schedulePoll()
})
}
})
},
_schedulePoll() {
if (this.data.pollTimer) clearTimeout(this.data.pollTimer)
const t = setTimeout(() => {
this.loadReport(this.data.reportId)
}, 3500)
this.setData({ pollTimer: t })
},
reload() {
this.loadReport(this.data.reportId)
},
/** 付费解锁:先尝试 dev 模式,生产环境走 payment/create 下单 */
onTapPay() {
if (this.data.paying) return
this.setData({ paying: true })
analytics.track('ai_report_pay_tap', { reportId: this.data.reportId })
const report = this.data.report || {}
const orderSn = report.orderSn || ''
// 1) 尝试调用现有 /api/payment/create 下单
request({
url: '/api/payment/create',
method: 'POST',
data: {
productType: 'ai_deep_report',
productId: this.data.reportId,
amount: report.priceFen || 990,
orderSn
},
success: (res) => {
const body = (res && res.data) || {}
if (body.code === 200 && body.data && body.data.timeStamp) {
const p = body.data
wx.requestPayment({
timeStamp: p.timeStamp,
nonceStr: p.nonceStr,
package: p.package,
signType: p.signType || 'RSA',
paySign: p.paySign,
success: () => {
wx.showToast({ title: '支付成功', icon: 'success' })
analytics.track('ai_report_pay_success', { reportId: this.data.reportId })
setTimeout(() => this.loadReport(this.data.reportId), 1500)
this.setData({ paying: false })
},
fail: () => {
wx.showToast({ title: '已取消支付', icon: 'none' })
this.setData({ paying: false })
}
})
} else {
// 2) 下单失败(比如接口不支持该 productType→ 兜底 dev markPaid仅超管可用
this._fallbackDevMarkPaid()
}
},
fail: () => this._fallbackDevMarkPaid()
})
},
_fallbackDevMarkPaid() {
// 仅在配置了 dev 模式或超管账号时生效
request({
url: `/api/ai/report/${this.data.reportId}/mark-paid-dev`,
method: 'POST',
success: (res) => {
const body = (res && res.data) || {}
if (body.code === 200) {
wx.showToast({ title: '解锁成功', icon: 'success' })
this.setData({ paying: false })
setTimeout(() => this.loadReport(this.data.reportId), 800)
} else {
wx.showToast({ title: body.message || '支付接口未开通', icon: 'none' })
this.setData({ paying: false })
}
},
fail: () => {
wx.showToast({ title: '支付通道异常,稍后再试', icon: 'none' })
this.setData({ paying: false })
}
})
},
onRetry() {
if (!this.data.reportId) return
request({
url: `/api/ai/report/${this.data.reportId}/regenerate`,
method: 'POST',
success: (res) => {
const body = (res && res.data) || {}
if (body.code === 200) {
this.setData({ report: body.data || {} })
const s = body.data && body.data.status
if (s === 'generating' || s === 'paid') this._schedulePoll()
} else {
wx.showToast({ title: body.message || '重试失败', icon: 'none' })
}
}
})
},
onCopy() {
const c = (this.data.report && this.data.report.content) || ''
if (!c) return
wx.setClipboardData({ data: c })
},
onShareAppMessage() {
const app = getApp() || {}
const gd = app.globalData || {}
const inviterId = (gd.userInfo && (gd.userInfo.id || gd.userInfo.user_id)) || 0
const mbti = (this.data.report && this.data.report.mbtiType) || ''
const title = mbti
? `神仙 AI 帮我看懂了 ${mbti},推荐你也来做一份专属报告`
: '神仙 AI · 深度画像报告'
analytics.track('ai_report_share', { reportId: this.data.reportId, mbti })
return {
title,
path: `/pages/ai-chat/index?inviterId=${inviterId}&src=ai_report_share`,
}
},
onShareTimeline() {
return { title: '神仙 AI 帮我看懂了自己的 MBTI', query: 'src=ai_report_timeline' }
}
})