diff --git a/.env b/.env index c5d1ca7..9ae1e59 100644 --- a/.env +++ b/.env @@ -1 +1 @@ -VITE_API_URL=http://192.168.1.36:9527 \ No newline at end of file +VITE_API_URL=http://192.168.1.54:9528 \ No newline at end of file diff --git a/components.d.ts b/components.d.ts index 1030ebd..7a92964 100644 --- a/components.d.ts +++ b/components.d.ts @@ -24,17 +24,27 @@ declare module 'vue' { InputLabel: typeof import('./src/components/ui/input-label/index.vue')['default'] IonApp: typeof import('@ionic/vue')['IonApp'] IonAvatar: typeof import('@ionic/vue')['IonAvatar'] + IonBackButton: typeof import('@ionic/vue')['IonBackButton'] IonButton: typeof import('@ionic/vue')['IonButton'] + IonButtons: typeof import('@ionic/vue')['IonButtons'] IonContent: typeof import('@ionic/vue')['IonContent'] + IonDatetime: typeof import('@ionic/vue')['IonDatetime'] + IonDatetimeButton: typeof import('@ionic/vue')['IonDatetimeButton'] IonHeader: typeof import('@ionic/vue')['IonHeader'] IonIcon: typeof import('@ionic/vue')['IonIcon'] + IonInputOtp: typeof import('@ionic/vue')['IonInputOtp'] IonItem: typeof import('@ionic/vue')['IonItem'] IonLabel: typeof import('@ionic/vue')['IonLabel'] IonList: typeof import('@ionic/vue')['IonList'] IonModal: typeof import('@ionic/vue')['IonModal'] + IonNote: typeof import('@ionic/vue')['IonNote'] IonPage: typeof import('@ionic/vue')['IonPage'] + IonRadio: typeof import('@ionic/vue')['IonRadio'] + IonRadioGroup: typeof import('@ionic/vue')['IonRadioGroup'] IonRouterOutlet: typeof import('@ionic/vue')['IonRouterOutlet'] IonSearchbar: typeof import('@ionic/vue')['IonSearchbar'] + IonSelect: typeof import('@ionic/vue')['IonSelect'] + IonSelectOption: typeof import('@ionic/vue')['IonSelectOption'] IonTabBar: typeof import('@ionic/vue')['IonTabBar'] IonTabButton: typeof import('@ionic/vue')['IonTabButton'] IonTabs: typeof import('@ionic/vue')['IonTabs'] @@ -73,17 +83,27 @@ declare global { const InputLabel: typeof import('./src/components/ui/input-label/index.vue')['default'] const IonApp: typeof import('@ionic/vue')['IonApp'] const IonAvatar: typeof import('@ionic/vue')['IonAvatar'] + const IonBackButton: typeof import('@ionic/vue')['IonBackButton'] const IonButton: typeof import('@ionic/vue')['IonButton'] + const IonButtons: typeof import('@ionic/vue')['IonButtons'] const IonContent: typeof import('@ionic/vue')['IonContent'] + const IonDatetime: typeof import('@ionic/vue')['IonDatetime'] + const IonDatetimeButton: typeof import('@ionic/vue')['IonDatetimeButton'] const IonHeader: typeof import('@ionic/vue')['IonHeader'] const IonIcon: typeof import('@ionic/vue')['IonIcon'] + const IonInputOtp: typeof import('@ionic/vue')['IonInputOtp'] 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 IonNote: typeof import('@ionic/vue')['IonNote'] const IonPage: typeof import('@ionic/vue')['IonPage'] + const IonRadio: typeof import('@ionic/vue')['IonRadio'] + const IonRadioGroup: typeof import('@ionic/vue')['IonRadioGroup'] const IonRouterOutlet: typeof import('@ionic/vue')['IonRouterOutlet'] const IonSearchbar: typeof import('@ionic/vue')['IonSearchbar'] + const IonSelect: typeof import('@ionic/vue')['IonSelect'] + const IonSelectOption: typeof import('@ionic/vue')['IonSelectOption'] const IonTabBar: typeof import('@ionic/vue')['IonTabBar'] const IonTabButton: typeof import('@ionic/vue')['IonTabButton'] const IonTabs: typeof import('@ionic/vue')['IonTabs'] diff --git a/package.json b/package.json index 6e98304..12c67a5 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "@elysiajs/eden": "^1.4.5", "@ionic/vue": "^8.7.11", "@ionic/vue-router": "^8.7.11", - "@riwa/api-types": "http://192.168.1.36:9527/api/riwa-api-types-0.0.22.tgz", + "@riwa/api-types": "http://192.168.1.36:9527/api/riwa-api-types-0.0.24.tgz", "@tailwindcss/vite": "^4.1.18", "@vee-validate/yup": "^4.15.1", "@vueuse/core": "^14.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 643d06e..f0ed89b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,8 +36,8 @@ importers: specifier: ^8.7.11 version: 8.7.11(@stencil/core@4.39.0)(vue-router@4.6.3(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3)) '@riwa/api-types': - specifier: http://192.168.1.36:9527/api/riwa-api-types-0.0.22.tgz - version: http://192.168.1.36:9527/api/riwa-api-types-0.0.22.tgz(@elysiajs/eden@1.4.5(elysia@1.4.18(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3))) + specifier: http://192.168.1.36:9527/api/riwa-api-types-0.0.24.tgz + version: http://192.168.1.36:9527/api/riwa-api-types-0.0.24.tgz(@elysiajs/eden@1.4.5(elysia@1.4.18(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3))) '@tailwindcss/vite': specifier: ^4.1.18 version: 4.1.18(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.2)) @@ -1248,9 +1248,9 @@ packages: resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@riwa/api-types@http://192.168.1.36:9527/api/riwa-api-types-0.0.22.tgz': - resolution: {tarball: http://192.168.1.36:9527/api/riwa-api-types-0.0.22.tgz} - version: 0.0.22 + '@riwa/api-types@http://192.168.1.36:9527/api/riwa-api-types-0.0.24.tgz': + resolution: {tarball: http://192.168.1.36:9527/api/riwa-api-types-0.0.24.tgz} + version: 0.0.24 peerDependencies: '@elysiajs/eden': ^1.4.5 @@ -5908,7 +5908,7 @@ snapshots: '@pkgr/core@0.2.9': {} - '@riwa/api-types@http://192.168.1.36:9527/api/riwa-api-types-0.0.22.tgz(@elysiajs/eden@1.4.5(elysia@1.4.18(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3)))': + '@riwa/api-types@http://192.168.1.36:9527/api/riwa-api-types-0.0.24.tgz(@elysiajs/eden@1.4.5(elysia@1.4.18(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3)))': dependencies: '@elysiajs/eden': 1.4.5(elysia@1.4.18(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3)) diff --git a/src/api/index.ts b/src/api/index.ts index 4dba714..d5b3e8a 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,4 +1,5 @@ import type { App } from "@riwa/api-types"; +import type { Awaitable } from "@vueuse/core"; import { treaty } from "@elysiajs/eden"; import { toastController } from "@ionic/vue"; @@ -13,10 +14,17 @@ export interface SafeClientOptions { immediate?: boolean; } -export async function safeClient( +export interface SafeClientReturn { + data: Ref; + error: Ref; + refresh: () => Promise; + onFetchResponse: (callback: (data: T, error: E) => void) => void; +} + +export function safeClient( requestPromise: () => Promise<{ data: T; error: E }>, options: SafeClientOptions = {}, -) { +): SafeClientReturn & Promise> { const { immediate = true } = options; const data = ref(null); const error = ref(null); @@ -61,11 +69,20 @@ export async function safeClient( responseCallback = callback; } - if (immediate) { - await execute(); - } + const result: SafeClientReturn = { + data: data as Ref, + error: error as Ref, + refresh: execute, + onFetchResponse, + }; - return { data, error, refresh: execute, onFetchResponse }; + // 创建一个 Promise 并在其上添加属性 + const promise = immediate ? execute().then(() => result) : Promise.resolve(result); + + // 将 result 的属性添加到 promise 上 + Object.assign(promise, result); + + return promise as SafeClientReturn & Promise>; } export { client }; diff --git a/src/api/types.ts b/src/api/types.ts index 2fc002d..b4d8cde 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -7,6 +7,10 @@ export type DepositFiatBody = Parameters[0] assetCode: AssetCodeEnum; }; +export type TreatyQuery = T extends (...args: any[]) => any + ? NonNullable[0]>["query"]> + : never; + export type DepositFiatData = Treaty.Data; export type BalancesData = Treaty.Data; @@ -18,18 +22,22 @@ export type WithdrawBody = Omit[0], export type UserProfileData = Treaty.Data["userProfile"]; -export type UpdateUserProfileBody = NonNullable[0]>; +export type UpdateUserProfileBody = TreatyQuery; export type RwaIssuanceProductsData = Treaty.Data; -export type RwaIssuanceProductBody = NonNullable[0]>; +export type RwaIssuanceProductBody = TreatyQuery; export type RwaIssuanceCategoriesData = Treaty.Data; export type BankAccountsData = Treaty.Data; -export type BankAccountBody = Parameters[0]; +export type BankAccountBody = TreatyQuery; export type BankAccountData = Treaty.Data; export type SupportBanksData = Treaty.Data; + +export type AvailableSubscriptionData = Treaty.Data; + +export type AvailableSubscriptionBody = TreatyQuery; diff --git a/src/components/ui/tabs/index.vue b/src/components/ui/tabs/index.vue index 3cebe79..d0c1cef 100644 --- a/src/components/ui/tabs/index.vue +++ b/src/components/ui/tabs/index.vue @@ -7,6 +7,8 @@ interface TabsProps { closable?: boolean; addable?: boolean; placement?: "top" | "bottom" | "left" | "right"; + sticky?: boolean; + stickyTop?: string | number; tabStyle?: string | Record; tabClass?: string; paneStyle?: string | Record; @@ -27,6 +29,8 @@ const props = withDefaults(defineProps(), { closable: false, addable: false, placement: "top", + sticky: false, + stickyTop: 0, }); const emit = defineEmits(); @@ -229,14 +233,34 @@ const tabsClasses = computed(() => [ `ui-tabs--${props.placement}`, { "ui-tabs--animated": props.animated, + "ui-tabs--sticky": props.sticky, }, ]); + +// 计算sticky样式 +const stickyStyle = computed(() => { + if (!props.sticky) + return {}; + + const topValue = typeof props.stickyTop === "number" + ? `${props.stickyTop}px` + : props.stickyTop; + + return { + position: "sticky" as const, + top: topValue, + zIndex: 100, + }; +});