diff --git a/api/app/common/service/MpTabbarService.php b/api/app/common/service/MpTabbarService.php index 6f4473c..61619c6 100644 --- a/api/app/common/service/MpTabbarService.php +++ b/api/app/common/service/MpTabbarService.php @@ -57,9 +57,11 @@ class MpTabbarService } if (empty($list)) { - // 无库内配置时:仅首页 + 我;拍摄 / 神仙 AI 需在超管 TabBar 中配置 visible 后才会下发 + // 顺序:首页 · 第2项凸起拍摄 · 神仙AI · 我(与小程序 app.json tabBar.list 一致) $list = [ ['id' => 0, 'pagePath' => 'pages/index/index', 'text' => '首页', 'iconKey' => 'home', 'iconUrl' => null, 'highlight' => false, 'badgeKey' => null], + ['id' => 0, 'pagePath' => 'pages/index/camera', 'text' => '拍摄', 'iconKey' => 'camera', 'iconUrl' => null, 'highlight' => true, 'badgeKey' => null], + ['id' => 0, 'pagePath' => 'pages/ai-chat/index', 'text' => '神仙AI', 'iconKey' => 'ai', 'iconUrl' => null, 'highlight' => false, 'badgeKey' => null], ['id' => 0, 'pagePath' => 'pages/profile/index', 'text' => '我', 'iconKey' => 'profile', 'iconUrl' => null, 'highlight' => false, 'badgeKey' => null], ]; } diff --git a/miniprogram/app.js b/miniprogram/app.js index 77e1cb4..67c3e23 100644 --- a/miniprogram/app.js +++ b/miniprogram/app.js @@ -58,8 +58,8 @@ App({ defaultEnterpriseId: null, // API 基础地址:默认走线上;本机/内网调试可在开发者工具执行 // wx.setStorageSync('apiBaseOverride', 'https://你的调试域名') 后重启小程序 - apiBase: 'https://mbtiapi.quwanzhi.com', - //apiBase: 'http://mbti.com', + //apiBase: 'https://mbtiapi.quwanzhi.com', + apiBase: 'http://mbti.com', // VIP信息 vipInfo: null, // 测试次数 diff --git a/miniprogram/app.json b/miniprogram/app.json index 538dad8..6b668de 100644 --- a/miniprogram/app.json +++ b/miniprogram/app.json @@ -55,12 +55,6 @@ "iconPath": "images/camera.png", "selectedIconPath": "images/camera-active.png" }, - { - "pagePath": "pages/ai-chat/index", - "text": "神仙AI", - "iconPath": "images/home.png", - "selectedIconPath": "images/home-active.png" - }, { "pagePath": "pages/profile/index", "text": "我的", diff --git a/miniprogram/custom-tab-bar/index.js b/miniprogram/custom-tab-bar/index.js index 6b1b16e..ae3697a 100644 --- a/miniprogram/custom-tab-bar/index.js +++ b/miniprogram/custom-tab-bar/index.js @@ -1,14 +1,76 @@ // 自定义 TabBar:完全由后台配置驱动 // 数据来源:app.globalData.tabBar.items(GET /api/mp/tabbar) -// 兜底(无后台配置或不足 2 项时):仅首页 + 我;拍摄 / 神仙 AI 默认不展示,由超管 TabBar 配置显式开启 +// 兜底:首页 · 拍摄(第2项凸起) · 神仙AI · 我 const { isAuditHideAiMode, shouldHideTabBarHighlightFab } = require('../utils/miniprogramAuditGate.js') const DEFAULT_ITEMS = [ { pagePath: 'pages/index/index', text: '首页', iconKey: 'home', iconUrl: '', highlight: false }, + { pagePath: 'pages/index/camera', text: '拍摄', iconKey: 'camera', iconUrl: '', highlight: true }, + { pagePath: 'pages/ai-chat/index', text: '神仙AI', iconKey: 'ai', iconUrl: '', iconUrlActive: '', highlight: false }, { pagePath: 'pages/profile/index', text: '我', iconKey: 'profile', iconUrl: '', highlight: false } ] +const AI_PATH = 'pages/ai-chat/index' + +/** 与 iconKey 为 ai 时的图标 URL 归一(与 refreshFromConfig 内一致) */ +function mapTabIconUrls(rawItems) { + return rawItems.map((it) => { + if (it.iconKey === 'ai') { + const u = (it.iconUrl && String(it.iconUrl).trim()) || '' + const raster = /\.(png|jpg|jpeg|webp)$/i.test(u) + if (raster) { + return { + ...it, + iconUrl: u, + iconUrlActive: (it.iconUrlActive && String(it.iconUrlActive).trim()) || '/images/tab-ai-active.png' + } + } + return { ...it, iconUrl: '', iconUrlActive: '' } + } + return { ...it, iconUrl: it.iconUrl || '' } + }) +} + +/** + * 提审/面相审核:去掉神仙 AI;非审核且列表无神仙 AI 时补回(与 app.json 仅 3 Tab 时 navigateTo 兜底配合) + */ +function applyAuditFilterAndMaybeInjectAi(items, gd) { + const hideAiTab = isAuditHideAiMode(gd) + const hideMiddleFab = shouldHideTabBarHighlightFab(gd) + + let effectiveItems = items.filter((it) => { + const path = (it.pagePath || '').replace(/^\//, '') + if (hideAiTab && (it.iconKey === 'ai' || /ai-chat/.test(path))) return false + if (hideMiddleFab && it.highlight) return false + return true + }) + + const hasAiItem = effectiveItems.some((it) => { + const p = (it.pagePath || '').replace(/^\//, '') + return p === AI_PATH || it.iconKey === 'ai' || /ai-chat/.test(p) + }) + if (!hideAiTab && !hasAiItem) { + const next = effectiveItems.slice() + const insertAt = Math.max(0, next.length - 1) + next.splice(insertAt, 0, { + pagePath: AI_PATH, + text: '神仙AI', + iconKey: 'ai', + iconUrl: '', + iconUrlActive: '', + highlight: false, + }) + effectiveItems = next + } + + return { + effectiveItems, + reviewMode: !!(gd.reviewMode || gd.maintenanceMode), + hideMiddleFab, + } +} + Component({ data: { selected: 0, @@ -31,39 +93,14 @@ Component({ methods: { refreshFromConfig() { + const app = getApp() || {} + const gd = app.globalData || {} + try { - const app = getApp() || {} - const gd = app.globalData || {} const cfg = gd.tabBar && Array.isArray(gd.tabBar.items) ? gd.tabBar.items : null const rawItems = (cfg && cfg.length >= 2) ? cfg.slice() : DEFAULT_ITEMS.slice() - const items = rawItems.map((it) => { - if (it.iconKey === 'ai') { - const u = (it.iconUrl && String(it.iconUrl).trim()) || '' - const raster = /\.(png|jpg|jpeg|webp)$/i.test(u) - if (raster) { - return { - ...it, - iconUrl: u, - iconUrlActive: (it.iconUrlActive && String(it.iconUrlActive).trim()) || '/images/tab-ai-active.png' - } - } - return { ...it, iconUrl: '', iconUrlActive: '' } - } - return { ...it, iconUrl: it.iconUrl || '' } - }) - - const reviewMode = !!(gd.reviewMode || gd.maintenanceMode) - const hideAiTab = isAuditHideAiMode(gd) - const hideMiddleFab = shouldHideTabBarHighlightFab(gd) - - // 提审或面相审核:去掉神仙 AI Tab(与 miniprogramAuditGate 一致) - // 审核模式 / face 关闭时:隐藏所有 highlight=true 的 Tab - const effectiveItems = items.filter((it) => { - const path = (it.pagePath || '').replace(/^\//, '') - if (hideAiTab && (it.iconKey === 'ai' || /ai-chat/.test(path))) return false - if (hideMiddleFab && it.highlight) return false - return true - }) + const items = mapTabIconUrls(rawItems) + const { effectiveItems, reviewMode, hideMiddleFab } = applyAuditFilterAndMaybeInjectAi(items, gd) this.setData({ items: effectiveItems, @@ -71,7 +108,17 @@ Component({ hideMiddleFab, }, () => this.updateSelected()) } catch (e) { - this.setData({ items: DEFAULT_ITEMS, reviewMode: false, hideMiddleFab: false }, () => this.updateSelected()) + try { + const items = mapTabIconUrls(DEFAULT_ITEMS.slice()) + const { effectiveItems, reviewMode, hideMiddleFab } = applyAuditFilterAndMaybeInjectAi(items, gd) + this.setData({ + items: effectiveItems, + reviewMode, + hideMiddleFab, + }, () => this.updateSelected()) + } catch (e2) { + this.setData({ items: [], reviewMode: false, hideMiddleFab: false }, () => this.updateSelected()) + } } }, diff --git a/miniprogram/pages/ai-chat/index.js b/miniprogram/pages/ai-chat/index.js index 56ff1ef..1a571a1 100644 --- a/miniprogram/pages/ai-chat/index.js +++ b/miniprogram/pages/ai-chat/index.js @@ -146,8 +146,16 @@ Page({ onShow() { const { redirectIfMiniprogramAudit } = require('../../utils/miniprogramAuditGate.js') if (redirectIfMiniprogramAudit()) return - const tb = typeof this.getTabBar === 'function' ? this.getTabBar() : null - if (tb && typeof tb.updateSelected === 'function') tb.updateSelected() + try { + const tb = typeof this.getTabBar === 'function' ? this.getTabBar() : null + if (tb && typeof tb.updateSelected === 'function') { + tb.updateSelected() + } else { + const c = typeof this.selectComponent === 'function' ? this.selectComponent('#custom-tab-bar') : null + if (c && typeof c.refreshFromConfig === 'function') c.refreshFromConfig() + else if (c && typeof c.updateSelected === 'function') c.updateSelected() + } + } catch (e) {} const app = getApp() try { const st = wx.getStorageSync('token') diff --git a/miniprogram/pages/ai-chat/index.json b/miniprogram/pages/ai-chat/index.json index da55d1a..d038cf9 100644 --- a/miniprogram/pages/ai-chat/index.json +++ b/miniprogram/pages/ai-chat/index.json @@ -3,5 +3,7 @@ "navigationBarBackgroundColor": "#faf9ff", "navigationBarTextStyle": "black", "backgroundColor": "#f4f3f9", - "usingComponents": {} + "usingComponents": { + "custom-tab-bar": "/custom-tab-bar/index" + } } diff --git a/miniprogram/pages/ai-chat/index.wxml b/miniprogram/pages/ai-chat/index.wxml index d0fc1f2..39726b9 100644 --- a/miniprogram/pages/ai-chat/index.wxml +++ b/miniprogram/pages/ai-chat/index.wxml @@ -132,4 +132,7 @@ + + +