feat: 小程序统一走 Go 后台,咨询与登录切到 /api/v1
去掉协会 WebView 和魔方账密页,微信登录与咨询接口共用同一 token 和拦截器。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
export const ICON_NAMES = [
|
||||
'mbti', 'star', 'portrait', 'rhythm', 'synastry', 'astro',
|
||||
'companion', 'ask', 'cards', 'reports', 'growth', 'relation',
|
||||
'nine', 'eq', 'stress', 'sleep',
|
||||
]
|
||||
|
||||
export function resolveIcon(raw, fallback = 'mbti') {
|
||||
return ICON_NAMES.includes(raw) ? raw : fallback
|
||||
}
|
||||
|
||||
export function toolIconFor(pathOrKey) {
|
||||
const s = String(pathOrKey || '').toLowerCase()
|
||||
if (s.includes('mbti') || s.includes('人格类型') || s.includes('tests')) return 'mbti'
|
||||
if (s.includes('synastry') || s.includes('合盘')) return 'synastry'
|
||||
if (s.includes('portrait') || s.includes('decode') || s.includes('解码')) return 'portrait'
|
||||
if (s.includes('star') || s.includes('星座') || s.includes('星盘')) return 'star'
|
||||
if (s.includes('rhythm') || s.includes('节律')) return 'rhythm'
|
||||
if (s.includes('companion') || s.includes('节气') || s.includes('mood')) return 'companion'
|
||||
if (s.includes('ask') || s.includes('问答')) return 'ask'
|
||||
if (s.includes('card') || s.includes('意象')) return 'cards'
|
||||
if (s.includes('report') || s.includes('报告')) return 'reports'
|
||||
if (s.includes('growth') || s.includes('计划') || s.includes('会员') || s.includes('member')) return 'growth'
|
||||
if (s.includes('relation') || s.includes('匹配') || s.includes('love')) return 'relation'
|
||||
if (s.includes('astro') || s.includes('星象')) return 'astro'
|
||||
if (s.includes('explore') || s.includes('探索') || s.includes('分类')) return 'mbti'
|
||||
return 'portrait'
|
||||
}
|
||||
|
||||
export function typeLabel(type) {
|
||||
const map = {
|
||||
portrait: '愈心解码',
|
||||
star: '星座排盘',
|
||||
rhythm: '身心节律',
|
||||
synastry: '合盘',
|
||||
relation: '人格匹配',
|
||||
scale: '测评',
|
||||
}
|
||||
return map[type] || '成长报告'
|
||||
}
|
||||
|
||||
export function formatDate(iso) {
|
||||
if (!iso) return ''
|
||||
const d = new Date(iso)
|
||||
if (Number.isNaN(d.getTime())) return String(iso).slice(0, 10)
|
||||
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
|
||||
}
|
||||
|
||||
export function headlineOf(report) {
|
||||
const s = report?.summary || {}
|
||||
return s.headline || s.one_liner || s.label || s.title || typeLabel(report?.type)
|
||||
}
|
||||
|
||||
export const homeGridRow1 = [
|
||||
{ to: '/scales/mbti-lite', icon: 'mbti', label: 'MBTI测试' },
|
||||
{ to: '/star', icon: 'star', label: '星座' },
|
||||
{ to: '/portrait', icon: 'portrait', label: '愈心解码', badge: '热', badgeTone: 'hot' },
|
||||
{ to: '/rhythm', icon: 'rhythm', label: '身心节律' },
|
||||
{ to: '/synastry', icon: 'synastry', label: '合盘', badge: '新', badgeTone: 'new' },
|
||||
{ to: '/star', icon: 'astro', label: '星象性格' },
|
||||
]
|
||||
|
||||
export const homeGridRow2 = [
|
||||
{ to: '/companion', icon: 'companion', label: '节气陪伴' },
|
||||
{ to: '/ask', icon: 'ask', label: 'AI问答' },
|
||||
{ to: '/cards', icon: 'cards', label: '意象卡片' },
|
||||
{ to: '/reports', icon: 'reports', label: '成长报告', badge: '新', badgeTone: 'new' },
|
||||
{ to: '/growth-plan', icon: 'growth', label: '成长计划' },
|
||||
{ to: '/relation', icon: 'relation', label: '人格匹配' },
|
||||
]
|
||||
|
||||
export const homeFeeds = [
|
||||
{ to: '/portrait', icon: 'portrait', title: '愈心解码', meta: '一个生日,读懂性格与身心节奏', stat: '核心入口', tone: 'fc-e', tag: '热' },
|
||||
{ to: '/ask', icon: 'ask', title: 'AI 成长助手', meta: '结合档案聊聊卡住的事', stat: '随时可问', tone: 'fc-a', tag: 'AI' },
|
||||
{ to: '/star', icon: 'star', title: '星座排盘', meta: '本命盘 · 相位 · 日周月运势', stat: '本周热门', tone: 'fc-b', tag: '新' },
|
||||
{ to: '/synastry', icon: 'synastry', title: '合盘', meta: '恋爱 / 友情 / 婚姻指数', stat: '了解彼此', tone: 'fc-c' },
|
||||
{ to: '/scales/mbti-lite', icon: 'mbti', title: 'MBTI测试', meta: '四维偏好探索,看见自己的能量与决策节奏', stat: '热门测评', tone: 'fc-a' },
|
||||
{ to: '/membership', icon: 'growth', title: '成长会员', meta: '深度报告与全年节气陪伴', stat: '解锁更多', tone: 'fc-e' },
|
||||
]
|
||||
|
||||
export const mineGroupArchive = [
|
||||
{ to: '/profile', label: '个人档案', icon: 'portrait' },
|
||||
{ to: '/reports', label: '我的成长报告', icon: 'reports' },
|
||||
{ to: '/portrait', label: '愈心解码', icon: 'portrait' },
|
||||
{ to: '/star', label: '星象性格', icon: 'star' },
|
||||
{ to: '/rhythm', label: '身心节律', icon: 'rhythm' },
|
||||
{ to: '/cards', label: '意象卡片', icon: 'cards' },
|
||||
]
|
||||
|
||||
export const mineGroupGrowth = [
|
||||
{ to: '/relation', label: '人格匹配', icon: 'relation' },
|
||||
{ to: '/ask', label: 'AI 成长助手', icon: 'ask' },
|
||||
{ to: '/explore', label: '探索测试', icon: 'mbti' },
|
||||
{ to: '/growth-plan', label: '成长计划', icon: 'growth' },
|
||||
{ to: '/membership', label: '成长会员', icon: 'growth' },
|
||||
]
|
||||
|
||||
const FEED_TONES = ['fc-e', 'fc-a', 'fc-b', 'fc-c', 'fc-a', 'fc-e']
|
||||
|
||||
export function mapHomeBannersToFeeds(items) {
|
||||
const sorted = [...(items || [])].sort((a, b) => (a.sort_order ?? 0) - (b.sort_order ?? 0))
|
||||
const out = []
|
||||
for (let i = 0; i < sorted.length; i++) {
|
||||
const it = sorted[i]
|
||||
const to = String(it.link_path || '').trim()
|
||||
if (!to.startsWith('/') || to.includes('://')) continue
|
||||
out.push({
|
||||
to,
|
||||
icon: 'portrait',
|
||||
title: it.title,
|
||||
meta: '运营推荐',
|
||||
stat: '推荐',
|
||||
tone: FEED_TONES[i % FEED_TONES.length],
|
||||
tag: '荐',
|
||||
})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
export function mapHomeTools(items) {
|
||||
const toTool = (it) => {
|
||||
if (!ICON_NAMES.includes(it.icon)) return null
|
||||
const t = { to: it.path, icon: it.icon, label: it.label }
|
||||
if (it.badge) t.badge = it.badge
|
||||
if (it.badge_tone === 'hot' || it.badge_tone === 'new') t.badgeTone = it.badge_tone
|
||||
return t
|
||||
}
|
||||
const sorted = [...(items || [])].sort(
|
||||
(a, b) => a.row_index - b.row_index || a.sort_order - b.sort_order,
|
||||
)
|
||||
const row1 = []
|
||||
const row2 = []
|
||||
for (const it of sorted) {
|
||||
const t = toTool(it)
|
||||
if (!t) continue
|
||||
if (it.row_index === 1) row1.push(t)
|
||||
else if (it.row_index === 2) row2.push(t)
|
||||
}
|
||||
return { row1, row2 }
|
||||
}
|
||||
Reference in New Issue
Block a user