feat: 小程序与管理端迭代(神仙AI、了解自己CRM、AI测试入口、报表与分润等)

Made-with: Cursor
This commit is contained in:
卡若
2026-04-17 19:46:48 +08:00
parent cf835ea585
commit 7108f28280
239 changed files with 21061 additions and 2175 deletions

View File

@@ -9,20 +9,25 @@ Page({
personalCategories: [],
enterpriseCategories: [],
loading: true,
loadError: false,
loadErrorMsg: '',
purchasing: false,
hasPhone: false,
successModal: {
visible: false,
title: '',
content: '',
wechat: ''
content: ''
}
},
retryLoad() {
this.loadDeepPricing()
},
onLoad(options) {
const tab = (options && options.tab === 'enterprise') ? 'enterprise' : 'personal'
this.setData({ activeTab: tab })
wx.setNavigationBarTitle({ title: '深度服务' })
wx.setNavigationBarTitle({ title: '了解自己' })
this.loadDeepPricing()
},
@@ -34,21 +39,44 @@ Page({
loadDeepPricing() {
const apiBase = app.globalData.apiBase || ''
if (!apiBase) {
this.setData({ loading: false })
this.setData({ loading: false, loadError: true, loadErrorMsg: '服务地址未配置' })
return
}
this.setData({ loading: true })
this.setData({ loading: true, loadError: false, loadErrorMsg: '' })
Promise.all([
this.requestDeepPricing('personal'),
this.requestDeepPricing('enterprise')
]).then(([personal, enterprise]) => {
const pErr = personal && personal.__error
const eErr = enterprise && enterprise.__error
const pList = Array.isArray(personal) ? personal : []
const eList = Array.isArray(enterprise) ? enterprise : []
const bothFailed = pErr && eErr
const bothEmpty = !pList.length && !eList.length
if (bothFailed || bothEmpty) {
const msg = pErr ? (personal.__errorMsg || '网络异常') : (eErr ? (enterprise.__errorMsg || '网络异常') : '暂无可购买方案')
this.setData({
personalCategories: [],
enterpriseCategories: [],
loading: false,
loadError: true,
loadErrorMsg: msg
})
return
}
this.setData({
personalCategories: personal || [],
enterpriseCategories: enterprise || [],
loading: false
personalCategories: pList,
enterpriseCategories: eList,
loading: false,
loadError: false,
loadErrorMsg: ''
})
}).catch((err) => {
this.setData({
loading: false,
loadError: true,
loadErrorMsg: (err && err.message) || '加载失败,请检查网络后重试'
})
}).catch(() => {
this.setData({ loading: false })
})
},
@@ -58,14 +86,15 @@ Page({
url: `${app.globalData.apiBase.replace(/\/$/, '')}/api/config/deep-pricing`,
method: 'GET',
data: { scope },
timeout: 15000,
success: (res) => {
if (res.statusCode === 200 && res.data && res.data.code === 200 && Array.isArray(res.data.data && res.data.data.categories)) {
resolve(res.data.data.categories)
} else {
resolve([])
resolve({ __error: true, __errorMsg: (res && res.data && res.data.message) || '响应异常' })
}
},
fail: () => resolve([])
fail: (err) => resolve({ __error: true, __errorMsg: (err && err.errMsg) || '网络异常' })
})
})
},
@@ -74,7 +103,7 @@ Page({
const tab = e.currentTarget.dataset.tab
if (tab !== 'personal' && tab !== 'enterprise') return
this.setData({ activeTab: tab })
wx.setNavigationBarTitle({ title: '深度服务' })
wx.setNavigationBarTitle({ title: '了解自己' })
},
// 无需再次授权时,直接点击按钮执行购买/咨询
@@ -147,8 +176,7 @@ Page({
this.setData({ purchasing: false })
this._reportCrmLead(category, 'buy')
const successMsg = (category.successMessage || '购买成功!我们的顾问会尽快与您联系,为您提供专属深度解读服务。').trim()
const wechat = (category.serviceWechat || '').trim()
this._showSuccessModal('购买成功', successMsg, wechat)
this._showSuccessModal('购买成功', successMsg)
},
fail: () => {
wx.hideLoading()
@@ -158,27 +186,21 @@ Page({
},
applyConsult(category) {
// serviceWechat 展示给用户consultWechat 是存客宝 API key
const wechat = (category.serviceWechat || '').trim()
const apiKey = (category.consultWechat || '').trim()
const successMsg = (category.successMessage || '感谢您的申请,我们的顾问会尽快与您联系!').trim()
wx.showLoading({ title: '提交中...', mask: true })
if (apiKey) {
this._reportCrmLead(category, 'consult')
}
setTimeout(() => {
const done = () => {
wx.hideLoading()
this._showSuccessModal('申请成功', successMsg, wechat)
}, 600)
this._showSuccessModal('申请成功', successMsg)
}
this._reportCrmLead(category, 'consult', done)
},
_showSuccessModal(title, content, wechat) {
_showSuccessModal(title, content) {
this.setData({
successModal: {
visible: true,
title: title || '成功',
content: content || '',
wechat: wechat || ''
content: content || ''
}
})
},
@@ -189,25 +211,23 @@ Page({
this.setData({ 'successModal.visible': false })
},
copyWechat() {
const wechat = this.data.successModal.wechat
if (!wechat) return
wx.setClipboardData({
data: wechat,
success: () => wx.showToast({ title: '已复制微信号', icon: 'success' })
})
},
/**
* 向后端上报存客宝线索,后端负责签名和调用存客宝 API
* @param {Object} category 深度服务类目对象(需含 consultWechat / title
* @param {Object} category 深度服务类目对象consultWechat 为存客宝 KEY可空由后端按企业配置回落
* @param {string} actionType 'buy'(付款完成)| 'consult'(申请咨询)
* @param {Function} [onDone] 请求结束回调(含失败)
*/
_reportCrmLead(category, actionType) {
const apiKey = category.consultWechat || ''
if (!apiKey) return
_reportCrmLead(category, actionType, onDone) {
const apiKey = (category.consultWechat || '').trim()
const apiBase = app.globalData.apiBase || ''
if (!apiBase) return
if (actionType === 'buy' && !apiKey) {
if (typeof onDone === 'function') onDone()
return
}
if (!apiBase) {
if (typeof onDone === 'function') onDone()
return
}
const isEnterprise = this.data.activeTab === 'enterprise'
const source = (isEnterprise ? '企业深度服务' : '个人深度服务') + (category.title ? `-${category.title}` : '')
@@ -225,6 +245,7 @@ Page({
source,
remark,
siteTags: category.title || '',
deepConsult: actionType === 'consult',
},
success(res) {
console.log('[CRM] 线索上报结果', res.data)
@@ -232,6 +253,9 @@ Page({
fail(err) {
console.warn('[CRM] 线索上报请求失败', err)
},
complete() {
if (typeof onDone === 'function') onDone()
},
})
},

View File

@@ -10,12 +10,7 @@
</view>
<text class="success-dialog-title">{{successModal.title}}</text>
<text class="success-dialog-content">{{successModal.content}}</text>
<view wx:if="{{successModal.wechat}}" class="success-wechat-wrap">
<text class="success-wechat-label">客服微信</text>
<text class="success-wechat-val">{{successModal.wechat}}</text>
</view>
<view class="success-dialog-btns">
<button wx:if="{{successModal.wechat}}" class="success-btn-copy" bindtap="copyWechat">复制微信号</button>
<button class="success-btn-close" bindtap="closeSuccessModal">我知道了</button>
</view>
</view>
@@ -27,9 +22,19 @@
<text class="loading-text">加载中...</text>
</view>
<view wx:elif="{{loadError}}" class="purchase-error-state">
<view class="purchase-error-ic">⚠️</view>
<text class="purchase-error-title">加载失败</text>
<text class="purchase-error-msg">{{loadErrorMsg || '网络异常,请检查后重试'}}</text>
<view class="purchase-error-btn" bindtap="retryLoad">重新加载</view>
<text class="purchase-error-hint">若持续失败,请在微信中关闭小程序后再次打开</text>
</view>
<block wx:else>
<view class="deep-intro">
<text class="deep-intro-text">先选服务类型,查看说明与权益;具体安排可在下一步与顾问沟通确认。</text>
<view class="deep-hero">
<text class="deep-hero__eyebrow">UNDERSTAND YOURSELF · 了解自己</text>
<text class="deep-hero__title">更深入地看见你自己</text>
<text class="deep-hero__desc">结合 MBTI / DISC / PDP / SBTI / 面相的综合解读;个人 1v1、团队工作坊、VIP 职业发展三档方案。提交后顾问会主动与你联系。</text>
</view>
<view class="tabs-container deep-tabs">
@@ -136,12 +141,12 @@
<text class="safety-text">流程在微信内完成</text>
</view>
<view class="safety-item">
<text class="safety-icon"></text>
<text class="safety-text">顾问跟进确认</text>
<text class="safety-icon">💼</text>
<text class="safety-text">顾问主动联系</text>
</view>
<view class="safety-item">
<text class="safety-icon">📞</text>
<text class="safety-text">支持咨询与售后</text>
<text class="safety-icon">🧑‍💼</text>
<text class="safety-text">团队成本节约 40%+</text>
</view>
</view>
</block>

View File

@@ -134,6 +134,39 @@
line-height: 1.65;
}
/* 新:了解自己 · Hero 卡 */
.deep-hero {
margin: 24rpx 24rpx 0;
padding: 40rpx 32rpx 36rpx;
border-radius: 28rpx;
background: linear-gradient(140deg, #6366f1 0%, #8b5cf6 60%, #ec4899 100%);
color: #fff;
box-shadow: 0 20rpx 48rpx rgba(99, 102, 241, 0.25);
}
.deep-hero__eyebrow {
display: block;
font-size: 22rpx;
letter-spacing: 0.2em;
opacity: 0.82;
margin-bottom: 12rpx;
}
.deep-hero__title {
display: block;
font-size: 44rpx;
font-weight: 800;
letter-spacing: -0.01em;
margin-bottom: 12rpx;
}
.deep-hero__desc {
display: block;
font-size: 24rpx;
line-height: 1.7;
opacity: 0.92;
}
.deep-tabs.tabs-container {
margin-top: 20rpx;
}
@@ -806,3 +839,49 @@
font-weight: 600;
color: #fff;
}
/* ===== 错误态:深度服务加载失败 + 重试 ===== */
.purchase-error-state {
padding: 120rpx 60rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
}
.purchase-error-ic {
font-size: 84rpx;
line-height: 1;
margin-bottom: 20rpx;
}
.purchase-error-title {
font-size: 36rpx;
font-weight: 700;
color: #111827;
margin-bottom: 12rpx;
}
.purchase-error-msg {
font-size: 26rpx;
color: #6b7280;
line-height: 1.6;
margin-bottom: 40rpx;
max-width: 520rpx;
}
.purchase-error-btn {
padding: 20rpx 56rpx;
background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
color: #fff;
font-size: 30rpx;
font-weight: 600;
border-radius: 48rpx;
box-shadow: 0 10rpx 24rpx rgba(99, 102, 241, 0.3);
margin-bottom: 28rpx;
}
.purchase-error-btn:active {
transform: scale(0.97);
opacity: 0.9;
}
.purchase-error-hint {
font-size: 22rpx;
color: #9ca3af;
}