返回 AiToEarn
appDownloadConfig.ts
根目录 / project / aitoearn-web / src / app / config / appDownloadConfig.ts
1 /**
2 * 应用下载配置文件
3 * 管理不同平台的下载链接、二维码等信息
4 */
5
6 // 根据语言获取主应用下载地址
7 // zh-* 使用中文地址,其余使用英文地址
8 // 优先使用API返回的direct下载地址,如果获取失败则使用默认地址
9 import { useUserStore } from '@/store/user'
10
11 export interface AppDownloadConfig {
12 platform: string
13 appName: string
14 downloadUrl: string
15 qrCodeUrl?: string
16 description: string
17 tips: string[]
18 }
19
20 // API响应类型定义
21 interface AppReleaseResponse {
22 data: {
23 _id: string
24 platform: string
25 version: string
26 buildNumber: number
27 forceUpdate: boolean
28 notes: string
29 links: {
30 direct?: string
31 _id: string
32 id: string
33 }
34 publishedAt: string
35 id: string
36 }
37 code: number
38 message: string
39 }
40
41 // 主应用下载配置(默认英文)
42 export const MAIN_APP_DOWNLOAD_URL = 'https://docs.aitoearn.ai/en/downloads'
43
44 // API端点
45 const APP_RELEASE_API = 'https://aitoearn.ai/api/app-release/latest'
46
47 // 缓存最新下载地址
48 let cachedDownloadUrl: string | null = null
49 let lastFetchTime: number = 0
50 const CACHE_DURATION = 5 * 60 * 1000 // 5分钟缓存
51 let inflightRequest: Promise<string | null> | null = null
52
53 /**
54 * 从API获取最新的Android应用下载地址
55 * @returns 最新的下载地址,如果获取失败则返回null
56 */
57 export async function fetchLatestDownloadUrl(): Promise<string | null> {
58 try {
59 // 检查缓存
60 const now = Date.now()
61 if (cachedDownloadUrl && now - lastFetchTime < CACHE_DURATION) {
62 return cachedDownloadUrl
63 }
64
65 // 如果存在进行中的请求,直接复用
66 if (inflightRequest) {
67 return inflightRequest
68 }
69
70 inflightRequest = (async () => {
71 const response = await fetch(`${APP_RELEASE_API}?platform=android`)
72
73 if (!response.ok) {
74 console.error('Failed to fetch app release info:', response.statusText)
75 return null
76 }
77
78 const result: AppReleaseResponse = await response.json()
79
80 if (result.code === 0 && result.data?.links?.direct) {
81 // 缓存下载地址
82 cachedDownloadUrl = result.data.links.direct
83 lastFetchTime = now
84 return cachedDownloadUrl
85 }
86
87 return null
88 })()
89
90 const data = await inflightRequest
91 inflightRequest = null
92 return data
93 }
94 catch (error) {
95 console.error('Error fetching latest download url:', error)
96 inflightRequest = null
97 return null
98 }
99 }
100 export async function getMainAppDownloadUrl(lng?: string): Promise<string> {
101 // 尝试从API获取最新下载地址
102 const latestUrl = await fetchLatestDownloadUrl()
103 if (latestUrl) {
104 return latestUrl
105 }
106
107 // 如果API获取失败,使用默认地址
108 const lang = (lng || useUserStore.getState().lang || 'en').toLowerCase()
109 const isZh = lang.startsWith('zh')
110 return isZh ? 'https://docs.aitoearn.ai/zh/downloads' : 'https://docs.aitoearn.ai/en/downloads'
111 }
112
113 /**
114 * 同步获取主应用下载地址(用于不支持async的场景)
115 * 会先返回缓存的URL,如果没有缓存则返回默认URL
116 * 同时在后台触发API请求更新缓存
117 */
118 export function getMainAppDownloadUrlSync(lng?: string): string {
119 // 后台更新缓存
120 fetchLatestDownloadUrl().catch(console.error)
121
122 // 如果有缓存,返回缓存的URL
123 if (cachedDownloadUrl) {
124 return cachedDownloadUrl
125 }
126
127 // 否则返回默认URL
128 const lang = (lng || useUserStore.getState().lang || 'en').toLowerCase()
129 const isZh = lang.startsWith('zh')
130 return isZh ? 'https://docs.aitoearn.ai/zh/downloads' : 'https://docs.aitoearn.ai/en/downloads'
131 }
132
133 export const APP_DOWNLOAD_CONFIGS: Record<string, AppDownloadConfig> = {
134 xhs: {
135 platform: 'Xiaohongshu',
136 appName: 'Xiaohongshu App',
137 downloadUrl: 'https://apps.apple.com/cn/app/id123456789', // Configure actual download link here
138 qrCodeUrl: '', // Configure actual QR code image URL here
139 description:
140 'Xiaohongshu operations need to be performed in the mobile app. Please download and install the Xiaohongshu App to continue.',
141 tips: [
142 'After installation, please log in to your account in the App',
143 'Ensure your account has completed identity verification',
144 'Complete related task operations in the App',
145 ],
146 },
147 douyin: {
148 platform: 'Douyin',
149 appName: 'Douyin App',
150 downloadUrl: 'https://apps.apple.com/cn/app/douyin/id123456789',
151 qrCodeUrl: '',
152 description:
153 'Douyin operations need to be performed in the mobile app. Please download and install the Douyin App to continue.',
154 tips: [
155 'After installation, please log in to your account in the App',
156 'Ensure your account has completed identity verification',
157 'Complete related task operations in the App',
158 ],
159 },
160 // Additional platform configurations can be added here
161 }
162
163 /**
164 * 获取平台下载配置
165 * @param platformKey 平台标识符,如 'xhs', 'douyin'
166 * @returns 下载配置信息
167 */
168 export function getAppDownloadConfig(platformKey: string): AppDownloadConfig | null {
169 return APP_DOWNLOAD_CONFIGS[platformKey] || null
170 }
171
172 /**
173 * 检查任务是否需要App操作
174 * @param accountTypes 账号类型数组
175 * @returns 需要App操作的平台列表
176 */
177 export function getTasksRequiringApp(accountTypes: string[]): string[] {
178 return accountTypes.filter(type => APP_DOWNLOAD_CONFIGS[type])
179 }
180
180 lines TYPESCRIPT