import type { EntryTone, PortalEntryCard, PortalEntryGroup, PortalEntryVo } from '@/types/business/home' const TONE_CYCLE: EntryTone[] = ['purple', 'green', 'blue', 'amber', 'red'] const NAME_ICON_MAP: Record = { 项目中心: '🗂️', 需求中心: '🧾', 需求池: '🧾', 工单需求池: '📋', 快捷提报: '➕', 在线客服: '🎧', 客服工作台: '💬', 合同管理: '📑', 合同台账: '📄', 合同列表: '📁', 合同档案: '📁', 财务管理: '💰', 财务台账: '💰', 财务档案: '💰', 案例库管理: '📁', 案例库: '📁', 个人中心: '👤', 消息中心: '💬', 账号安全: '🔒', 意见反馈: '✉️', 交易列表: '📊', 交易明细: '📊', 部署管理: '🚀', 设备工作台: '🖥️', 设备管理: '🖥️', 资质列表: '📋', 帮助中心: '❓', 关于我们: 'ℹ️', } const DEFAULT_ICON = '📦' function isImageUrl(value: string): boolean { return /^(https?:)?\/\//i.test(value) || value.startsWith('/') } function isGlyph(value: string): boolean { return !/^[a-zA-Z0-9_-]+$/.test(value) } function resolveIcon(icon: string | null, name: string): { icon: string; isImage: boolean } { const raw = (icon ?? '').trim() if (raw) { if (isImageUrl(raw)) return { icon: raw, isImage: true } if (isGlyph(raw)) return { icon: raw, isImage: false } } return { icon: NAME_ICON_MAP[name] ?? DEFAULT_ICON, isImage: false } } export function toPortalEntryCard(vo: PortalEntryVo, index: number): PortalEntryCard | null { if (vo.id == null) return null const label = (vo.name ?? '').trim() || '未命名入口' const { icon, isImage } = resolveIcon(vo.icon, label) return { id: vo.id, label, route: (vo.route ?? '').trim(), groupType: (vo.groupType === '1' ? '1' : '0') as PortalEntryGroup, icon, isImage, tone: TONE_CYCLE[index % TONE_CYCLE.length], } } export function toPortalEntryCards(list: PortalEntryVo[]): PortalEntryCard[] { return list .map((vo, index) => toPortalEntryCard(vo, index)) .filter((item): item is PortalEntryCard => item !== null) }