From e104c5ce435a5fe8fd4d7a75553a0986385c9545 Mon Sep 17 00:00:00 2001 From: Seven Date: Sun, 8 Mar 2026 01:42:44 +0700 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=BA=94=E7=94=A8=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E5=BA=94=E7=94=A8=E5=88=97=E8=A1=A8=E5=92=8C=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E9=A1=B5=E9=9D=A2=E7=9A=84=E5=8A=A0=E8=BD=BD=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/data/apps.json => apps.json | 6 +-- src/data/apps.ts | 72 +++++++++++++++++++++++++++++++-- src/views/AppDetail.vue | 25 ++++++++++-- src/views/StoreHome.vue | 28 ++++++++++--- 4 files changed, 115 insertions(+), 16 deletions(-) rename src/data/apps.json => apps.json (99%) diff --git a/src/data/apps.json b/apps.json similarity index 99% rename from src/data/apps.json rename to apps.json index 13285ea..cb3c139 100644 --- a/src/data/apps.json +++ b/apps.json @@ -12,9 +12,9 @@ "en-US": "YixinDa is China's leading instant messaging app, providing secure and convenient chat and social services." }, "category": "tools", - "version": "1.0.0", + "version": "1.1.8", "buildNumber": "1000", - "releaseDate": "2026-03-06", + "releaseDate": "2026-03-08", "releaseNotes": { "zh-CN": [ "初始版本发布", @@ -30,7 +30,7 @@ ] }, "downloads": { - "android": "https://s3.yxdim.com/__UNI__44929DB__20260306175925.apk", + "android": "https://download.yxdim.com/yxd_1.1.8.apk", "h5": "https://www.yxdim.com" }, "size": { diff --git a/src/data/apps.ts b/src/data/apps.ts index cdbd725..c6d8abd 100644 --- a/src/data/apps.ts +++ b/src/data/apps.ts @@ -1,7 +1,73 @@ -import type { AppItem, Locale } from '../types/app' -import appsJson from './apps.json' +import { readonly, ref } from 'vue' -export const apps: AppItem[] = appsJson as AppItem[] +import type { AppItem, Locale } from '../types/app' + +const APPS_URL = 'https://s3.yxdim.com/apps.json' + +const appsState = ref([]) +const loadingState = ref(false) +const errorState = ref('') + +let hasLoaded = false +let pendingRequest: Promise | null = null + +function getErrorMessage(error: unknown) { + if (error instanceof Error) { + return error.message + } + + return 'Unknown error' +} + +export async function fetchApps(force = false) { + if (pendingRequest) { + return pendingRequest + } + + if (hasLoaded && !force) { + return + } + + loadingState.value = true + errorState.value = '' + + pendingRequest = (async () => { + const response = await fetch(APPS_URL, { + method: 'GET', + }) + + if (!response.ok) { + throw new Error(`Failed to fetch apps: ${response.status}`) + } + + const data: unknown = await response.json() + + if (!Array.isArray(data)) { + throw new Error('Invalid apps data format') + } + + appsState.value = data as AppItem[] + hasLoaded = true + })() + .catch((error: unknown) => { + errorState.value = getErrorMessage(error) + }) + .finally(() => { + loadingState.value = false + pendingRequest = null + }) + + return pendingRequest +} + +export function useAppsStore() { + return { + apps: readonly(appsState), + isLoading: readonly(loadingState), + error: readonly(errorState), + fetchApps, + } +} export const categoryLabel: Record> = { all: { diff --git a/src/views/AppDetail.vue b/src/views/AppDetail.vue index ae66675..37064b1 100644 --- a/src/views/AppDetail.vue +++ b/src/views/AppDetail.vue @@ -1,19 +1,36 @@