import { defineStore } from 'pinia' import { apiClient } from '@/shared/api/client' import type { ApiResponse } from '@/shared/types/types' export interface DistributionBanner { image_url: string link_url?: string title?: string } export interface DistributionFooterInfo { icp?: string copyright?: string contact?: string disclaimer?: string } export interface DistributionSiteInfo { site_code: string site_name: string domain: string status: string display_account_enabled: boolean default_support_group_id?: number | null logo_url?: string favicon_url?: string banners_json?: string announcements_json?: string footer_info_json?: string receive_ratio_delta?: number receive_cost_delta?: number } /** * 获取当前上下文生效的分销站点编码 * 优先级: * 1. 环境变量 VITE_DISTRIBUTION_SITE_CODE(针对独立分销前台开发端口,如 5191) * 2. 当前标签页 sessionStorage 中的 hfb_site_code(避免跨 Tab 污染主站) * 3. 本地二级域名(如 test_1.localhost:5189) * * 注意:独立域名下的站点编码只来自 sessionStorage,由 initSite() 通过 * /distribution/site-info?domain= 探测后写入。历史上曾读取 localStorage 缓存, * 会让同一浏览器访问主站时串到分站站点码(把主站发布记到分站/反之),因此已移除。 */ export function getEffectiveSiteCode(): string { if (typeof window === 'undefined') return '' const envCode = ((import.meta.env.VITE_DISTRIBUTION_SITE_CODE as string) || '').trim() if (envCode) return envCode const sessionCode = sessionStorage.getItem('hfb_site_code') || '' if (sessionCode) return sessionCode const hostname = window.location.hostname if (hostname && hostname.endsWith('.localhost')) { return hostname.replace(/\.localhost$/, '') } return '' } export const useDistributionSiteStore = defineStore('distributionSite', { state: () => { const code = getEffectiveSiteCode() return { siteCode: code, siteName: sessionStorage.getItem('hfb_site_name') || '大锤商行', domain: '', isDistribution: Boolean(code), displayAccountEnabled: true, defaultSupportGroupId: null as number | null, logoUrl: '', faviconUrl: '', banners: [] as DistributionBanner[], announcements: [] as string[], footerInfo: null as DistributionFooterInfo | null, receiveRatioDelta: 0, receiveCostDelta: 0, initialized: false, } }, actions: { async initSite() { const envCode = ((import.meta.env.VITE_DISTRIBUTION_SITE_CODE as string) || '').trim() const hostname = window.location.hostname const urlParams = new URLSearchParams(window.location.search) const querySite = ( urlParams.get('site') || urlParams.get('site_code') || urlParams.get('distribution_site_code') || '' ).trim() // 1. 显式清除或重置为主站 if (querySite === 'main' || querySite === 'clear' || querySite === '0') { this.resetToMainSite() this.initialized = true return } // 2. 识别目标分销站点编码 let targetCode: string if (querySite) { targetCode = querySite sessionStorage.setItem('hfb_site_code', querySite) } else if (envCode) { targetCode = envCode sessionStorage.setItem('hfb_site_code', envCode) } else if (hostname && hostname.endsWith('.localhost')) { targetCode = hostname.replace(/\.localhost$/, '') sessionStorage.setItem('hfb_site_code', targetCode) } else { targetCode = sessionStorage.getItem('hfb_site_code') || '' // 若在普通 localhost 且无 envCode、无 query、无 sessionStorage,则视为纯主站,清理旧的 localStorage 串扰 if (!targetCode && (hostname === 'localhost' || hostname === '127.0.0.1')) { this.resetToMainSite() this.initialized = true return } } let queryUrl = '' if (targetCode) { queryUrl = `/distribution/site-info?code=${encodeURIComponent(targetCode)}` } else if (hostname && hostname !== 'localhost' && hostname !== '127.0.0.1') { queryUrl = `/distribution/site-info?domain=${encodeURIComponent(hostname)}` } if (!queryUrl) { this.resetToMainSite() this.initialized = true return } try { const { data } = await apiClient.get>(queryUrl, { silent: true, skipErrorHandler: true, }) const info = data.data if (info && info.site_code && info.status === 'active') { this.siteCode = info.site_code this.siteName = info.site_name || info.site_code this.domain = info.domain || '' this.isDistribution = true this.displayAccountEnabled = info.display_account_enabled ?? true this.defaultSupportGroupId = info.default_support_group_id ?? null this.logoUrl = info.logo_url || '' this.faviconUrl = info.favicon_url || '' if (info.banners_json) { try { this.banners = JSON.parse(info.banners_json) } catch { this.banners = [] } } else { this.banners = [] } if (info.announcements_json) { try { this.announcements = JSON.parse(info.announcements_json) } catch { this.announcements = [] } } else { this.announcements = [] } if (info.footer_info_json) { try { this.footerInfo = JSON.parse(info.footer_info_json) } catch { this.footerInfo = null } } else { this.footerInfo = null } this.receiveRatioDelta = Math.max(0, Number(info.receive_ratio_delta || 0)) this.receiveCostDelta = Math.max(0, Number(info.receive_cost_delta || 0)) sessionStorage.setItem('hfb_site_code', this.siteCode) sessionStorage.setItem('hfb_site_name', this.siteName) // 更新页面标题和 Favicon document.title = `【${this.siteName}】租号商城 - 精选游戏账号平台` if (this.faviconUrl && typeof document !== 'undefined') { let link = document.querySelector("link[rel*='icon']") as HTMLLinkElement | null if (!link) { link = document.createElement('link') link.rel = 'icon' document.head.appendChild(link) } link.href = this.faviconUrl } } else { this.resetToMainSite() } } catch { // 若站点编码无效或未找到,自动回退为主站 this.resetToMainSite() } finally { this.initialized = true } }, resetToMainSite() { this.siteCode = '' this.siteName = '大锤商行' this.domain = '' this.isDistribution = false this.displayAccountEnabled = true this.defaultSupportGroupId = null this.logoUrl = '' this.faviconUrl = '' this.banners = [] this.announcements = [] this.footerInfo = null this.receiveRatioDelta = 0 this.receiveCostDelta = 0 sessionStorage.removeItem('hfb_site_code') sessionStorage.removeItem('hfb_site_name') localStorage.removeItem('hfb_site_code') localStorage.removeItem('hfb_site_name') document.title = '大锤商行 - 官方租号平台' }, }, })