This commit is contained in:
Ghost
2026-04-27 14:36:52 +08:00
parent 6d5572108d
commit 59419c4ce9
7 changed files with 100 additions and 44 deletions

View File

@@ -1,14 +1,76 @@
// 自定义 TabBar完全由后台配置驱动
// 数据来源app.globalData.tabBar.itemsGET /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())
}
}
},