From 532b229299de2636fd433341264850a05a1f91e0 Mon Sep 17 00:00:00 2001 From: Seven Date: Tue, 20 Jan 2026 05:27:54 +0700 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E7=94=B3=E8=B4=AD=E5=8A=9F=E8=83=BD=EF=BC=8C=E9=9B=86=E6=88=90?= =?UTF-8?q?=E9=92=B1=E5=8C=85=E9=80=89=E6=8B=A9=E5=92=8C=E4=BA=A4=E6=98=93?= =?UTF-8?q?=E5=AF=86=E7=A0=81=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- auto-imports.d.ts | 3 + components.d.ts | 6 + src/utils/ionic-helper.ts | 4 + src/views/product/components/subscribe.vue | 322 +++++++++++++++++++++ src/views/product/index.vue | 26 +- 5 files changed, 359 insertions(+), 2 deletions(-) create mode 100644 src/utils/ionic-helper.ts create mode 100644 src/views/product/components/subscribe.vue diff --git a/auto-imports.d.ts b/auto-imports.d.ts index 07d3e21..f5718a5 100644 --- a/auto-imports.d.ts +++ b/auto-imports.d.ts @@ -334,6 +334,9 @@ declare global { export type { UploadFetchOptions } from './src/utils/aws/s3' import('./src/utils/aws/s3') // @ts-ignore + export type { PageInstance, InputInstance, ModalInstance, ContentInstance } from './src/utils/ionic-helper' + import('./src/utils/ionic-helper') + // @ts-ignore export type { Wallet } from './src/store/wallet' import('./src/store/wallet') } diff --git a/components.d.ts b/components.d.ts index 22b8917..1720e9c 100644 --- a/components.d.ts +++ b/components.d.ts @@ -30,7 +30,10 @@ declare module 'vue' { IonItem: typeof import('@ionic/vue')['IonItem'] IonLabel: typeof import('@ionic/vue')['IonLabel'] IonList: typeof import('@ionic/vue')['IonList'] + IonModal: typeof import('@ionic/vue')['IonModal'] IonPage: typeof import('@ionic/vue')['IonPage'] + IonRadio: typeof import('@ionic/vue')['IonRadio'] + IonRadioGroup: typeof import('@ionic/vue')['IonRadioGroup'] IonRefresher: typeof import('@ionic/vue')['IonRefresher'] IonRefresherContent: typeof import('@ionic/vue')['IonRefresherContent'] IonRouterOutlet: typeof import('@ionic/vue')['IonRouterOutlet'] @@ -72,7 +75,10 @@ declare global { const IonItem: typeof import('@ionic/vue')['IonItem'] const IonLabel: typeof import('@ionic/vue')['IonLabel'] const IonList: typeof import('@ionic/vue')['IonList'] + const IonModal: typeof import('@ionic/vue')['IonModal'] const IonPage: typeof import('@ionic/vue')['IonPage'] + const IonRadio: typeof import('@ionic/vue')['IonRadio'] + const IonRadioGroup: typeof import('@ionic/vue')['IonRadioGroup'] const IonRefresher: typeof import('@ionic/vue')['IonRefresher'] const IonRefresherContent: typeof import('@ionic/vue')['IonRefresherContent'] const IonRouterOutlet: typeof import('@ionic/vue')['IonRouterOutlet'] diff --git a/src/utils/ionic-helper.ts b/src/utils/ionic-helper.ts new file mode 100644 index 0000000..dd103d6 --- /dev/null +++ b/src/utils/ionic-helper.ts @@ -0,0 +1,4 @@ +export type PageInstance = InstanceType; +export type InputInstance = InstanceType; +export type ModalInstance = InstanceType; +export type ContentInstance = InstanceType; diff --git a/src/views/product/components/subscribe.vue b/src/views/product/components/subscribe.vue new file mode 100644 index 0000000..2e1309f --- /dev/null +++ b/src/views/product/components/subscribe.vue @@ -0,0 +1,322 @@ + + + + + diff --git a/src/views/product/index.vue b/src/views/product/index.vue index a0f4145..a59d1e2 100644 --- a/src/views/product/index.vue +++ b/src/views/product/index.vue @@ -2,18 +2,22 @@ import type { Treaty } from "@elysiajs/eden"; import type { InfiniteScrollCustomEvent } from "@ionic/vue"; import type { TreatyQuery } from "@/api/types"; +import { modalController } from "@ionic/vue"; import { calendarOutline, cardOutline, timeOutline, trendingUpOutline } from "ionicons/icons"; import { client, safeClient } from "@/api"; +import Subscribe from "./components/subscribe.vue"; type Product = Treaty.Data["data"][number]; type ProductQuery = TreatyQuery; +const modalInst = useTemplateRef("modalInst"); const [query] = useResetRef({ offset: 0, limit: 10, }); const data = ref([]); const isFinished = ref(false); +const walletStore = useWalletStore(); async function fetchData() { const { data: responseData } = await safeClient(client.api.subscription.products.get({ query: { ...query.value } })); @@ -38,9 +42,25 @@ function handleProductClick(product: Product) { // TODO: 跳转到产品详情 } -function handleSubscribe(product: Product) { +async function handleSubscribe(product: Product) { console.log("申购产品:", product.name); - // TODO: 实现申购功能 + await walletStore.syncWallets(); + const wallets = walletStore.wallets.filter(w => w.walletType.allowTransaction === true); + const modal = await modalController.create({ + component: Subscribe, + componentProps: { + productId: product.id, + wallets, + onClose: () => { + modal.dismiss(); + }, + onSuccess: () => { + modal.dismiss(); + console.log("申购成功"); + }, + }, + }); + await modal.present(); } onMounted(() => { @@ -128,6 +148,8 @@ onMounted(() => { 我要申购 + +