Files
MBTI_wang/miniprogram/app.js
Ghost a411bf7b21 高考版优化
审核模式优化
2026-04-29 18:01:26 +08:00

740 lines
28 KiB
JavaScript
Raw Permalink 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.

// app.js - MBTI小程序主入口
const { request } = require('./utils/request.js')
const { isAuditHideAiMode } = require('./utils/miniprogramAuditGate.js')
function normalizeAvailableVersions(input, pricingType) {
const list = Array.isArray(input) ? input : []
const allowed = ['personal', 'enterprise', 'gaokao']
const normalized = list
.map((item) => String(item || '').toLowerCase())
.filter((item, idx, arr) => allowed.includes(item) && arr.indexOf(item) === idx)
if (normalized.length > 0) return normalized
if (pricingType && allowed.includes(String(pricingType))) return [String(pricingType)]
return ['personal']
}
// 全局注入:所有页面 onShow 自动上报 page_viewonShareAppMessage 自动上报 share
const _OrigPage = Page
Page = function (pageConfig) {
const origOnShow = pageConfig.onShow
pageConfig.onShow = function () {
try {
const { reportPageView } = require('./utils/analytics.js')
reportPageView()
} catch (e) {}
if (typeof origOnShow === 'function') {
origOnShow.call(this)
}
}
if (typeof pageConfig.onShareAppMessage === 'function') {
const origShare = pageConfig.onShareAppMessage
pageConfig.onShareAppMessage = function (res) {
try { require('./utils/analytics.js').reportShare('friend') } catch (e) {}
return origShare.call(this, res)
}
}
if (typeof pageConfig.onShareTimeline === 'function') {
const origTimeline = pageConfig.onShareTimeline
pageConfig.onShareTimeline = function () {
try { require('./utils/analytics.js').reportShare('timeline') } catch (e) {}
return origTimeline.call(this)
}
}
return _OrigPage(pageConfig)
}
App({
globalData: {
userInfo: null,
openId: null,
token: null,
siteTitle: '神仙团队AI性格测试',
textConfig: null, // 从 /api/config/runtime 动态加载analyzingTitle, startButtonText, reportTitle, aiAnalysisText 等
maintenanceMode: undefined, // 审核模式undefined=未加载,等 getRuntimeConfig 后再决定,避免 tabBar 闪烁
/** 小程序提审:隐藏神仙 AI Tab/入口,由 runtime.miniprogramAuditMode 写入 */
miniprogramAuditMode: false,
reviewMode: undefined, // 面相审核开关,与 camera/index 一致,由 runtime.reviewMode 写入
// GET /api/config/runtime 内嵌的快捷问句(网关拦截独立接口时兜底)
runtimeAiQuickQuestions: null,
/** 仅当 /api/config/runtime 返回 data.aiChat 时写入用于区分「runtime 已发版 / 对话接口未发版」 */
aiChatRuntime: null,
// GET /api/config/runtime 内嵌的深度服务类目(与 /api/config/deep-pricing 同源)
deepPricingPersonal: null,
deepPricingEnterprise: null,
availableVersions: ['personal'],
// 当前使用范围personal 个人版 / enterprise 企业版(影响定价与 enterpriseId 写入)
appScope: 'personal',
// 扫码进入企业页时 scene 解析出的企业IDe_123提交测试/分析时优先使用
enterpriseIdFromScene: null,
// 超管配置的默认企业 ID无 scene/eid 等入口参数时回落)
defaultEnterpriseId: null,
// API 基础地址:默认走线上;本机/内网调试可在开发者工具执行
// wx.setStorageSync('apiBaseOverride', 'https://你的调试域名') 后重启小程序
apiBase: 'https://mbtiapi.quwanzhi.com',
//apiBase: 'http://mbti.com',
// VIP信息
vipInfo: null,
// 测试次数
testCount: 0,
// 已解锁的测试
unlockedTests: [],
// 测试结果缓存
mbtiResult: null,
sbtiResult: null,
discResult: null,
pdpResult: null,
aiResult: null,
// 企业功能权限超管在企业管理中配置null=无限制(个人版),对象时按 key 控制
enterprisePermissions: null
},
onLaunch(launchOptions) {
// 记录场景值供埋点使用
this.globalData.scene = launchOptions && launchOptions.scene ? launchOptions.scene : ''
try {
const ov = wx.getStorageSync('apiBaseOverride')
if (ov && typeof ov === 'string' && ov.trim()) {
this.globalData.apiBase = ov.trim().replace(/\/$/, '')
}
} catch (e) {}
try {
const { mergeThirdPartyFromQuery } = require('./utils/thirdPartyContext.js')
mergeThirdPartyFromQuery((launchOptions && launchOptions.query) || {})
} catch (e) {}
// 加载本地存储的数据
this.loadStoredData()
// 上报应用启动事件
try {
const analytics = require('./utils/analytics.js')
analytics.reportAppLaunch(launchOptions)
} catch (e) {}
// 先读取缓存的 TabBar 配置,避免首屏 flash后续拉接口再刷新
try {
const cachedTabBar = wx.getStorageSync('tabBarConfig')
if (cachedTabBar && Array.isArray(cachedTabBar.items) && cachedTabBar.items.length >= 2) {
this.globalData.tabBar = cachedTabBar
}
} catch (e) {}
// 必须先完成静默登录再拉 runtime否则无 token 时 enterprisePermissions 永远 null清除缓存后必现「要二次刷新」
this.silentLogin()
.catch(() => {})
.then(() => this.getRuntimeConfig())
.then(() => {
this._afterRuntimeSynced()
})
.catch(() => {})
// 并行拉取 TabBar 动态配置(不阻塞主流程)
this.loadTabBarConfig().catch(() => {})
},
/**
* 拉取小程序 TabBar 动态配置(后台可调整顺序/显示)
* 写入 globalData.tabBar 并缓存到本地
*/
loadTabBarConfig() {
return new Promise((resolve) => {
const base = (this.globalData.apiBase || '').replace(/\/$/, '')
if (!base) { resolve(null); return }
const apply = (res) => {
if (res && res.statusCode === 200 && res.data && res.data.code === 200 && res.data.data) {
const cfg = res.data.data
if (Array.isArray(cfg.items) && cfg.items.length >= 2) {
this.globalData.tabBar = cfg
try { wx.setStorageSync('tabBarConfig', cfg) } catch (e) {}
this.refreshCustomTabBar()
return true
}
}
return false
}
// 线上部分网关对 /api/mp/tabbar 返回 404与 runtime 相同前缀的 config 常已放行
const urls = [base + '/api/config/mp-tabbar', base + '/api/mp/tabbar']
const tryNext = (i) => {
if (i >= urls.length) {
resolve(null)
return
}
wx.request({
url: urls[i],
method: 'GET',
timeout: 6000,
success: (res) => {
if (apply(res)) resolve(null)
else tryNext(i + 1)
},
fail: () => tryNext(i + 1)
})
}
tryNext(0)
})
},
/** 审核开关或 Tab 配置变化后刷新自定义 tabBar与 getRuntimeConfig / loadTabBarConfig 共用) */
refreshCustomTabBar() {
try {
const pages = getCurrentPages()
if (!pages || pages.length === 0) return
const top = pages[pages.length - 1]
if (top && typeof top.getTabBar === 'function') {
const tb = top.getTabBar()
if (tb && typeof tb.refreshFromConfig === 'function') tb.refreshFromConfig()
}
} catch (e) {}
},
/**
* runtime 写入 globalData 后,同步当前栈顶页面与 tabBar避免首屏用旧 null 权限)
*/
_afterRuntimeSynced() {
try {
const pages = getCurrentPages()
if (!pages || pages.length === 0) return
const top = pages[pages.length - 1]
if (!top) return
const gd = this.globalData
const ep = gd.enterprisePermissions
const audit = !!(gd.reviewMode || gd.maintenanceMode)
const permFace = !ep || ep.face !== false
if (typeof top.getTabBar === 'function') {
const tb = top.getTabBar()
if (tb && typeof tb.refreshFromConfig === 'function') tb.refreshFromConfig()
else if (tb && typeof tb.updateSelected === 'function') tb.updateSelected()
}
const route = top.route || ''
if (isAuditHideAiMode(gd) && route.indexOf('pages/ai-chat/') === 0) {
wx.switchTab({ url: '/pages/index/index' })
return
}
if (route === 'pages/index/index' && typeof top.setData === 'function') {
top.setData({
reviewMode: audit,
permFace,
siteTitle: audit ? String(gd.siteTitle || '神仙团队性格测试').replace(/AI/gi, '') : (gd.siteTitle || '神仙团队性格测试'),
startButtonText: (audit || (ep && ep.face === false)) ? '开始性格测试' : ((gd.textConfig && gd.textConfig.startButtonText) || '30秒测出你的性格'),
aiAnalysisText: audit ? '分析' : ((gd.textConfig && gd.textConfig.aiAnalysisText) || '分析')
})
} else if (route === 'pages/profile/index' && typeof top.setData === 'function') {
if (typeof top._syncPerms === 'function') top._syncPerms.call(top)
top.setData({ reviewMode: audit })
if (typeof top.getTabBar === 'function') {
const tb = top.getTabBar()
if (tb && typeof tb.updateSelected === 'function') tb.updateSelected()
}
} else if (route === 'pages/enterprise/index' && typeof top.setData === 'function') {
const maintenanceMode = audit
const pf = permFace
top.setData({
maintenanceMode,
reviewMode: maintenanceMode,
permFace: pf,
siteTitle: gd.siteTitle || '神仙团队AI性格测试',
startButtonEnterprise: (maintenanceMode || !pf) ? '开始性格测试' : ((gd.textConfig && gd.textConfig.startButtonEnterprise) || '开始面部测试'),
aiAnalysisText: (gd.textConfig && gd.textConfig.aiAnalysisText) || '智能分析'
})
if (typeof top.getTabBar === 'function') {
const tb = top.getTabBar()
if (tb && typeof tb.updateSelected === 'function') tb.updateSelected()
}
} else if (route === 'pages/index/camera' && typeof top.setData === 'function') {
top.setData({ reviewMode: audit })
if (ep && ep.face === false) {
wx.navigateTo({ url: '/pages/test-select/index' })
}
if (typeof top.getTabBar === 'function') {
const tb = top.getTabBar()
if (tb && typeof tb.updateSelected === 'function') tb.updateSelected()
}
}
} catch (e) {
console.error('_afterRuntimeSynced', e)
}
},
onShow() {
try {
const { reportPageView } = require('./utils/analytics.js')
reportPageView()
} catch (e) {}
},
onHide() {
try {
const { flush } = require('./utils/analytics.js')
flush()
} catch (e) {}
},
// 加载本地存储数据
loadStoredData() {
const token = wx.getStorageSync('token')
if (token) {
this.globalData.token = token
}
const userInfo = wx.getStorageSync('userInfo')
if (userInfo) {
this.globalData.userInfo = userInfo
// 优先使用后端返回的 openid 字段,而不是内部自增 id
this.globalData.openId = userInfo.openid || userInfo.openId || null
}
// VIP信息
const vipInfo = wx.getStorageSync('vipInfo')
if (vipInfo) {
this.globalData.vipInfo = vipInfo
}
// 测试次数
const testCount = wx.getStorageSync('testCount')
if (testCount) {
this.globalData.testCount = testCount
}
// 已解锁测试
const unlockedTests = wx.getStorageSync('unlockedTests')
if (unlockedTests) {
this.globalData.unlockedTests = unlockedTests
}
// 测试结果
this.globalData.mbtiResult = wx.getStorageSync('mbtiResult') || null
this.globalData.sbtiResult = wx.getStorageSync('sbtiResult') || null
this.globalData.discResult = wx.getStorageSync('discResult') || null
this.globalData.pdpResult = wx.getStorageSync('pdpResult') || null
this.globalData.aiResult = wx.getStorageSync('aiResult') || null
},
/**
* 静默登录wx.login 取 code请求后端换 token 与用户信息
* @returns {Promise<boolean>} 是否登录成功(拿到 token
*/
silentLogin() {
return new Promise((resolve) => {
wx.login({
success: (res) => {
if (!res.code) {
resolve(false)
return
}
const url = `${this.globalData.apiBase}/api/auth/wechat`
const loginData = { code: res.code }
try {
const { getEffectiveEnterpriseId } = require('./utils/enterpriseContext.js')
const eid = getEffectiveEnterpriseId()
if (eid) loginData.enterpriseId = eid
} catch (e) {}
try {
const { getThirdPartyForLoginBody } = require('./utils/thirdPartyContext.js')
Object.assign(loginData, getThirdPartyForLoginBody())
} catch (e) {}
wx.request({
url,
method: 'POST',
timeout: 25000,
header: { 'Content-Type': 'application/json' },
data: loginData,
success: (response) => {
if (response.statusCode === 200 && response.data && response.data.code === 409 && response.data.message) {
try {
wx.showToast({ title: String(response.data.message), icon: 'none', duration: 3000 })
} catch (e) {}
}
if (response.statusCode === 200 && response.data && response.data.code === 200) {
const data = response.data.data || {}
const { token, user } = data
if (token) {
this.globalData.token = token
wx.setStorageSync('token', token)
}
if (user) {
try {
const { syncPhoneLoginStorageWithUser } = require('./utils/phoneAuth.js')
syncPhoneLoginStorageWithUser(user)
} catch (e) {}
this.globalData.userInfo = user
this.globalData.openId = user.openid || user.openId || null
wx.setStorageSync('userInfo', user)
}
if (token) {
this._tryDistributionBind()
try {
require('./utils/analytics.js').track('login_silent_success', {
userId: user && user.id,
hasEnterprise: !!(user && user.enterpriseId),
invited: !!(this.globalData._pendingInviterId)
})
} catch (e) {}
}
resolve(!!token)
return
}
try { require('./utils/analytics.js').track('login_silent_fail', { reason: 'non_200' }) } catch (e) {}
resolve(false)
},
fail: (err) => {
console.error('登录请求失败:', err)
try { require('./utils/analytics.js').track('login_silent_fail', { reason: 'network' }) } catch (e) {}
const storedToken = wx.getStorageSync('token')
const storedUser = wx.getStorageSync('userInfo')
if (storedToken) {
this.globalData.token = storedToken
this.globalData.userInfo = storedUser || null
this.globalData.openId = storedUser
? (storedUser.openid || storedUser.openId || null)
: null
resolve(true)
} else {
resolve(false)
}
}
})
},
fail: () => {
try { require('./utils/analytics.js').track('login_silent_fail', { reason: 'wx_login' }) } catch (e) {}
resolve(false)
}
})
})
},
/**
* 确保已登录:有 token 直接 resolve否则先执行静默登录
* 加 15s 超时兜底:若 wx.login / wx.request 卡住,强制 resolve(false),避免调用方 promise 悬挂
* @returns {Promise<boolean>} 当前是否有有效登录态
*/
ensureLogin() {
if (this.globalData.token) return Promise.resolve(true)
try {
const st = wx.getStorageSync('token')
if (st) {
this.globalData.token = st
const su = wx.getStorageSync('userInfo')
if (su) {
this.globalData.userInfo = su
this.globalData.openId = su.openid || su.openId || this.globalData.openId
}
return Promise.resolve(true)
}
} catch (e) {}
return new Promise((resolve) => {
let settled = false
const timer = setTimeout(() => {
if (settled) return
settled = true
try { require('./utils/analytics.js').track('login_silent_fail', { reason: 'timeout' }) } catch (e) {}
resolve(false)
}, 15000)
this.silentLogin()
.then((ok) => {
if (settled) return
settled = true
clearTimeout(timer)
if (!ok) {
try {
const st = wx.getStorageSync('token')
if (st) {
this.globalData.token = st
const su = wx.getStorageSync('userInfo')
if (su) {
this.globalData.userInfo = su
this.globalData.openId = su.openid || su.openId || this.globalData.openId
}
resolve(true)
return
}
} catch (e) {}
}
resolve(!!ok)
})
.catch(() => {
if (settled) return
settled = true
clearTimeout(timer)
try {
const st = wx.getStorageSync('token')
if (st) {
this.globalData.token = st
resolve(true)
return
}
} catch (e) {}
resolve(false)
})
})
},
/**
* 登录成功后尝试分销绑定(处理进入时携带的 uid 参数)
*/
_tryDistributionBind() {
const inviterId = this.globalData._pendingInviterId
const scope = this.globalData._pendingInviterScope || 'personal'
const eid = this.globalData._pendingInviterEid || null
if (!inviterId || inviterId <= 0) return
// 清除 pending 状态,避免重复绑定
this.globalData._pendingInviterId = null
this.globalData._pendingInviterScope = null
this.globalData._pendingInviterEid = null
const token = this.globalData.token
if (!token) return
const data = { inviterId, scope }
if (eid) data.eid = eid
request({
url: '/api/distribution/bind',
method: 'POST',
data,
success: () => {},
fail: () => {}
})
},
/** 清除登录态(退出登录时调用) */
logout() {
try {
const { clearPhoneLoginSession } = require('./utils/phoneAuth.js')
clearPhoneLoginSession()
} catch (e) {}
this.globalData.token = null
this.globalData.userInfo = null
this.globalData.openId = null
wx.removeStorageSync('token')
wx.removeStorageSync('userInfo')
},
// 获取用户信息(弹窗授权),并同步昵称/头像到后端
getUserInfo(callback) {
wx.getUserProfile({
desc: '用于展示用户头像和昵称',
success: (res) => {
const u = res.userInfo
this.globalData.userInfo = { ...this.globalData.userInfo, ...u, avatarUrl: u.avatarUrl || u.avatar }
wx.setStorageSync('userInfo', this.globalData.userInfo)
callback && callback(this.globalData.userInfo)
this.syncProfileToServer({ nickname: u.nickName, avatar: u.avatarUrl || u.avatar })
},
fail: () => {
callback && callback(this.globalData.userInfo || null)
}
})
},
// 同步昵称、头像到后端(需已登录)
syncProfileToServer(profile, callback) {
if (!this.globalData.token || !profile) {
callback && callback(false)
return
}
// 记录同步请求(调试用)
console.log('同步用户资料到服务器:', profile)
request({
url: '/api/auth/wechat/profile',
method: 'PUT',
data: profile,
success: (res) => {
console.log('同步用户资料响应:', res)
if (res.statusCode === 200 && res.data && res.data.code === 200) {
// 如果服务器返回了更新后的数据,使用服务器数据
if (res.data.data) {
const updatedUserInfo = { ...this.globalData.userInfo, ...res.data.data }
// 确保 nickname 和 nickName 字段都更新
if (profile.nickname) {
updatedUserInfo.nickname = profile.nickname
updatedUserInfo.nickName = profile.nickname
}
if (profile.avatar) {
updatedUserInfo.avatar = profile.avatar
updatedUserInfo.avatarUrl = profile.avatar
}
if (profile.birthday !== undefined) {
updatedUserInfo.birthday = profile.birthday
}
this.globalData.userInfo = updatedUserInfo
wx.setStorageSync('userInfo', updatedUserInfo)
console.log('用户资料已同步:', updatedUserInfo)
} else {
// 服务器没有返回数据,使用本地更新的数据
const updatedUserInfo = { ...this.globalData.userInfo, ...profile }
if (profile.nickname) {
updatedUserInfo.nickname = profile.nickname
updatedUserInfo.nickName = profile.nickname
}
if (profile.avatar) {
updatedUserInfo.avatar = profile.avatar
updatedUserInfo.avatarUrl = profile.avatar
}
if (profile.birthday !== undefined) {
updatedUserInfo.birthday = profile.birthday
}
this.globalData.userInfo = updatedUserInfo
wx.setStorageSync('userInfo', updatedUserInfo)
console.log('用户资料已更新(本地):', updatedUserInfo)
}
callback && callback(true)
} else {
console.error('更新用户资料失败:', res.data)
callback && callback(false)
}
},
fail: (err) => {
console.error('请求失败:', err)
callback && callback(false)
}
})
},
// 保存测试结果(同步服务端后 resolve { id, testType },用于结果页 URL 与分享)
saveTestResult(type, result) {
const { getEnterpriseIdForApiPayload } = require('./utils/enterpriseContext.js')
const { triggerTestResultCompleted } = require('./utils/pushHook.js')
const key = `${type}Result`
wx.setStorageSync(key, result)
this.globalData[key] = result
if (!this.globalData.token) {
return Promise.resolve({})
}
const enterpriseId = getEnterpriseIdForApiPayload()
return new Promise((resolve) => {
wx.request({
url: `${this.globalData.apiBase}/api/test/submit`,
method: 'POST',
header: {
'Authorization': `Bearer ${this.globalData.token}`,
'Content-Type': 'application/json'
},
data: {
testType: type,
answers: result.answers || [],
result: result,
userId: this.globalData.userInfo?.id ?? this.globalData.openId,
enterpriseId: enterpriseId != null ? enterpriseId : undefined,
testDuration: result.testDuration || 0,
timestamp: new Date().toISOString(),
...(this.globalData.appScope === 'gaokao' ? { pricingScope: 'gaokao' } : {})
},
success: (res) => {
if (res.statusCode === 200 && res.data && res.data.code === 200 && res.data.data && typeof res.data.data === 'object') {
const extra = res.data.data
if (extra && extra.id) {
triggerTestResultCompleted(extra.id)
}
resolve(extra)
} else {
resolve({})
}
},
fail: () => resolve({})
})
})
},
// 获取测试结果
getTestResult(type) {
return this.globalData[`${type}Result`] || wx.getStorageSync(`${type}Result`) || null
},
/**
* 获取运行配置:个人/企业定价 + 当前 AI 服务商(超管配置,默认第一个启用的)
* 有 token 且用户属于企业则返回企业定价,否则个人定价
* @returns {Promise<{pricingType, pricing, aiProviderId, aiProviderName}>}
*/
getRuntimeConfig() {
const reqId = (this._runtimeReqSeq = (this._runtimeReqSeq || 0) + 1)
return new Promise((resolve, reject) => {
const scope = this.globalData.appScope || 'personal'
const base = this.globalData.apiBase.replace(/\/$/, '')
const url = `${base}/api/config/runtime?scope=${encodeURIComponent(scope)}`
const token = this.globalData.token || wx.getStorageSync('token') || ''
wx.request({
url,
method: 'GET',
header: token ? { Authorization: 'Bearer ' + token } : {},
success: (res) => {
if (reqId !== this._runtimeReqSeq) {
resolve(null)
return
}
if (res.statusCode === 200 && res.data && res.data.code === 200) {
const data = res.data.data || {}
if (data.siteTitle) this.globalData.siteTitle = data.siteTitle
if (data.textConfig) this.globalData.textConfig = data.textConfig
if (data.maintenanceMode !== undefined) this.globalData.maintenanceMode = !!data.maintenanceMode
if (data.miniprogramAuditMode !== undefined) {
this.globalData.miniprogramAuditMode = !!data.miniprogramAuditMode
} else {
this.globalData.miniprogramAuditMode = false
}
if (data.reviewMode !== undefined) {
this.globalData.reviewMode = !!data.reviewMode
} else if (data.maintenanceMode !== undefined) {
this.globalData.reviewMode = !!data.maintenanceMode
}
if (data.defaultEnterpriseId != null && Number(data.defaultEnterpriseId) > 0) {
this.globalData.defaultEnterpriseId = Number(data.defaultEnterpriseId)
} else {
this.globalData.defaultEnterpriseId = null
}
if (data.enterprisePermissions && typeof data.enterprisePermissions === 'object') {
this.globalData.enterprisePermissions = data.enterprisePermissions
} else {
this.globalData.enterprisePermissions = null
}
if (data.tabBar && Array.isArray(data.tabBar.items) && data.tabBar.items.length >= 2) {
this.globalData.tabBar = data.tabBar
try {
wx.setStorageSync('tabBarConfig', data.tabBar)
} catch (e) {}
}
try {
const { applyAuditUiOverride } = require('./utils/miniprogramAuditGate.js')
applyAuditUiOverride(this)
} catch (e) {}
this.refreshCustomTabBar()
if (data.aiQuickQuestions && typeof data.aiQuickQuestions === 'object') {
this.globalData.runtimeAiQuickQuestions = data.aiQuickQuestions
} else {
this.globalData.runtimeAiQuickQuestions = null
}
if (data.aiChat && typeof data.aiChat === 'object') {
this.globalData.aiChatRuntime = data.aiChat
} else {
this.globalData.aiChatRuntime = null
}
if (data.deepPricingPersonal && Array.isArray(data.deepPricingPersonal.categories)) {
this.globalData.deepPricingPersonal = data.deepPricingPersonal.categories
} else {
this.globalData.deepPricingPersonal = null
}
if (data.deepPricingEnterprise && Array.isArray(data.deepPricingEnterprise.categories)) {
this.globalData.deepPricingEnterprise = data.deepPricingEnterprise.categories
} else {
this.globalData.deepPricingEnterprise = null
}
this.globalData.availableVersions = normalizeAvailableVersions(data.availableVersions, data.pricingType)
resolve(data)
} else {
reject(new Error(res.data && res.data.message ? res.data.message : '获取配置失败'))
}
},
fail: reject
})
})
}
})