/** * VIP 权限判断工具(前端口子) * 当前从登录态 userInfo.vip 读取;后续可扩展为按 storeId 请求接口 */ import { useUserStore } from '@vben/stores'; export interface StoreVipInfo { level_code?: string; level_name?: string; level_weight?: number; badge_url?: string; duration_type?: string; duration_label?: string; duration_badge_url?: string; permissions?: string[]; expire_at?: number; is_lifetime?: boolean; } /** 读取当前登录用户 VIP 信息 */ export function getCurrentVip(): StoreVipInfo | null { const userStore = useUserStore(); return ((userStore.userInfo as any)?.vip as StoreVipInfo) || null; } /** 是否拥有指定权限码 */ export function hasVipPermission(code: string): boolean { if (!code) return false; const vip = getCurrentVip(); const list = vip?.permissions; return Array.isArray(list) && list.includes(code); } /** * 等级是否不低于目标(按 level_weight;若无 weight 则仅精确匹配编码时返回 true) * 简化:仅当当前 level_code 与 minCode 相同,或 weight 足够时通过 */ export function levelAtLeast(minCode: string): boolean { const vip = getCurrentVip(); if (!vip?.level_code) return false; if (vip.level_code === minCode) return true; // 无完整等级表时,仅做字符串相等判断;业务侧应以后端 Gate 为准 const weight = Number(vip.level_weight ?? 0); const minWeight = parseLevelWeight(minCode); if (minWeight >= 0) { return weight >= minWeight; } return false; } /** 粗略解析 V0-V11 / BLACK_GOLD / CUSTOM 权重 */ function parseLevelWeight(code: string): number { if (/^V\d+$/i.test(code)) { return Number(code.slice(1)); } if (code === 'BLACK_GOLD') return 12; if (code === 'CUSTOM') return 13; return -1; } /** 组合式:供组件调用 */ export function useVipGate() { return { vip: getCurrentVip(), hasVipPermission, levelAtLeast, }; }