feat: 更新钱包管理功能,添加银行账户和余额的初始化逻辑,优化API请求和响应处理
This commit is contained in:
12
auto-imports.d.ts
vendored
12
auto-imports.d.ts
vendored
@@ -364,6 +364,7 @@ declare module 'vue' {
|
||||
interface GlobalComponents {}
|
||||
interface ComponentCustomProperties {
|
||||
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
|
||||
readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
|
||||
readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']>
|
||||
readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']>
|
||||
readonly computed: UnwrapRef<typeof import('vue')['computed']>
|
||||
@@ -377,6 +378,7 @@ declare module 'vue' {
|
||||
readonly createEventHook: UnwrapRef<typeof import('@vueuse/core')['createEventHook']>
|
||||
readonly createGlobalState: UnwrapRef<typeof import('@vueuse/core')['createGlobalState']>
|
||||
readonly createInjectionState: UnwrapRef<typeof import('@vueuse/core')['createInjectionState']>
|
||||
readonly createPinia: UnwrapRef<typeof import('pinia')['createPinia']>
|
||||
readonly createReactiveFn: UnwrapRef<typeof import('@vueuse/core')['createReactiveFn']>
|
||||
readonly createRef: UnwrapRef<typeof import('@vueuse/core')['createRef']>
|
||||
readonly createReusableTemplate: UnwrapRef<typeof import('@vueuse/core')['createReusableTemplate']>
|
||||
@@ -388,11 +390,13 @@ declare module 'vue' {
|
||||
readonly debouncedWatch: UnwrapRef<typeof import('@vueuse/core')['debouncedWatch']>
|
||||
readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']>
|
||||
readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']>
|
||||
readonly defineStore: UnwrapRef<typeof import('pinia')['defineStore']>
|
||||
readonly eagerComputed: UnwrapRef<typeof import('@vueuse/core')['eagerComputed']>
|
||||
readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
|
||||
readonly emailPattern: UnwrapRef<typeof import('./src/utils/pattern')['emailPattern']>
|
||||
readonly extendRef: UnwrapRef<typeof import('@vueuse/core')['extendRef']>
|
||||
readonly formatBalance: UnwrapRef<typeof import('./src/utils/helper')['formatBalance']>
|
||||
readonly getActivePinia: UnwrapRef<typeof import('pinia')['getActivePinia']>
|
||||
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
|
||||
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
|
||||
readonly getCurrentWatcher: UnwrapRef<typeof import('vue')['getCurrentWatcher']>
|
||||
@@ -407,6 +411,11 @@ declare module 'vue' {
|
||||
readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
|
||||
readonly isShallow: UnwrapRef<typeof import('vue')['isShallow']>
|
||||
readonly makeDestructurable: UnwrapRef<typeof import('@vueuse/core')['makeDestructurable']>
|
||||
readonly mapActions: UnwrapRef<typeof import('pinia')['mapActions']>
|
||||
readonly mapGetters: UnwrapRef<typeof import('pinia')['mapGetters']>
|
||||
readonly mapState: UnwrapRef<typeof import('pinia')['mapState']>
|
||||
readonly mapStores: UnwrapRef<typeof import('pinia')['mapStores']>
|
||||
readonly mapWritableState: UnwrapRef<typeof import('pinia')['mapWritableState']>
|
||||
readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
|
||||
readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
|
||||
readonly numberPattern: UnwrapRef<typeof import('./src/utils/pattern')['numberPattern']>
|
||||
@@ -450,9 +459,12 @@ declare module 'vue' {
|
||||
readonly refWithControl: UnwrapRef<typeof import('@vueuse/core')['refWithControl']>
|
||||
readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
|
||||
readonly resolveRef: UnwrapRef<typeof import('@vueuse/core')['resolveRef']>
|
||||
readonly setActivePinia: UnwrapRef<typeof import('pinia')['setActivePinia']>
|
||||
readonly setMapStoreSuffix: UnwrapRef<typeof import('pinia')['setMapStoreSuffix']>
|
||||
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
|
||||
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
|
||||
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
|
||||
readonly storeToRefs: UnwrapRef<typeof import('pinia')['storeToRefs']>
|
||||
readonly syncRef: UnwrapRef<typeof import('@vueuse/core')['syncRef']>
|
||||
readonly syncRefs: UnwrapRef<typeof import('@vueuse/core')['syncRefs']>
|
||||
readonly templateRef: UnwrapRef<typeof import('@vueuse/core')['templateRef']>
|
||||
|
||||
10
src/App.vue
10
src/App.vue
@@ -1,12 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { client, safeClient } from "./api";
|
||||
const { initializeWallet } = useWalletStore();
|
||||
|
||||
const walletStore = useWalletStore();
|
||||
|
||||
onMounted(async () => {
|
||||
const { data } = await safeClient(() => client.api.asset.balances.get(), { silent: true });
|
||||
walletStore.state.balances = data.value;
|
||||
client.api.rwa.issuance.products.get();
|
||||
onMounted(() => {
|
||||
initializeWallet();
|
||||
console.log("App mounted successfully");
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -8,15 +8,21 @@ const client = treaty<App>(window.location.origin, {
|
||||
},
|
||||
});
|
||||
|
||||
export interface SafeClientOptions {
|
||||
silent?: boolean;
|
||||
immediate?: boolean;
|
||||
}
|
||||
|
||||
export async function safeClient<T, E>(
|
||||
requestPromise: () => Promise<{ data: T; error: E }>,
|
||||
options: { silent?: boolean; immediate?: boolean } = {},
|
||||
options: SafeClientOptions = {},
|
||||
) {
|
||||
const { immediate = true } = options;
|
||||
const data = ref<T | null>(null);
|
||||
const error = ref<E | null>(null);
|
||||
let responseCallback: ((data: T, error: E) => void) | null = null;
|
||||
|
||||
const executeRequest = async () => {
|
||||
const execute = async () => {
|
||||
const res = await requestPromise();
|
||||
|
||||
if (res.error) {
|
||||
@@ -34,13 +40,22 @@ export async function safeClient<T, E>(
|
||||
}
|
||||
data.value = res.data;
|
||||
error.value = res.error;
|
||||
|
||||
// 调用注册的回调函数
|
||||
if (responseCallback) {
|
||||
responseCallback(res.data, res.error);
|
||||
}
|
||||
};
|
||||
|
||||
if (immediate) {
|
||||
await executeRequest();
|
||||
function onFetchResponse(callback: (data: T, error: E) => void) {
|
||||
responseCallback = callback;
|
||||
}
|
||||
|
||||
return { data, error, refresh: executeRequest };
|
||||
if (immediate) {
|
||||
await execute();
|
||||
}
|
||||
|
||||
return { data, error, refresh: execute, onFetchResponse };
|
||||
}
|
||||
|
||||
export { client };
|
||||
|
||||
@@ -1,16 +1,50 @@
|
||||
import type { BalancesData } from "@/api/types";
|
||||
import type { BalancesData, BankAccountsData } from "@/api/types";
|
||||
import { defineStore } from "pinia";
|
||||
import { client, safeClient } from "@/api";
|
||||
|
||||
interface State {
|
||||
balances: BalancesData | null;
|
||||
balances: BalancesData;
|
||||
bankAccounts: BankAccountsData["data"];
|
||||
}
|
||||
|
||||
export const useWalletStore = defineStore("wallet", () => {
|
||||
const state = reactive<State>({
|
||||
balances: null,
|
||||
balances: [],
|
||||
bankAccounts: [],
|
||||
});
|
||||
|
||||
const balances = computed(() => state.balances);
|
||||
const bankAccounts = computed(() => state.bankAccounts);
|
||||
|
||||
async function initializeWallet() {
|
||||
updateBalances();
|
||||
updateBankAccounts();
|
||||
}
|
||||
|
||||
async function updateBalances(data?: BalancesData) {
|
||||
if (data) {
|
||||
state.balances = data;
|
||||
return;
|
||||
}
|
||||
const { data: balances } = await safeClient(() => client.api.asset.balances.get(), { silent: true });
|
||||
state.balances = balances.value || [];
|
||||
}
|
||||
|
||||
async function updateBankAccounts(data?: BankAccountsData["data"]) {
|
||||
if (data) {
|
||||
state.bankAccounts = data;
|
||||
return;
|
||||
}
|
||||
const { data: bankAccounts } = await safeClient(() => client.api.bank_account.get(), { silent: true });
|
||||
state.bankAccounts = bankAccounts.value?.data || [];
|
||||
}
|
||||
|
||||
return {
|
||||
state,
|
||||
balances,
|
||||
bankAccounts,
|
||||
initializeWallet,
|
||||
updateBalances,
|
||||
updateBankAccounts,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -11,10 +11,15 @@ import { client, safeClient } from "@/api";
|
||||
|
||||
const { t } = useI18n();
|
||||
const router = useRouter();
|
||||
const { updateBankAccounts } = useWalletStore();
|
||||
|
||||
const { data, refresh } = await safeClient(() => client.api.bank_account.get());
|
||||
const { data, refresh, onFetchResponse } = await safeClient(() => client.api.bank_account.get());
|
||||
const bankCards = computed(() => data.value?.data || []);
|
||||
|
||||
onFetchResponse((data) => {
|
||||
data?.data && updateBankAccounts(data.data);
|
||||
});
|
||||
|
||||
function handleAddCard() {
|
||||
router.push("/trade-settings/bank-management/add");
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@ import RechargeChannel from "./recharge-channel.vue";
|
||||
|
||||
const { t } = useI18n();
|
||||
const router = useRouter();
|
||||
const { state } = useWalletStore();
|
||||
const walletStore = useWalletStore();
|
||||
const { balances } = storeToRefs(walletStore);
|
||||
const rechargeInstance = ref<ModalInstance>();
|
||||
|
||||
function onCloseModal() {
|
||||
@@ -12,12 +13,16 @@ function onCloseModal() {
|
||||
function handleWithdraw() {
|
||||
router.push("/withdraw/index");
|
||||
}
|
||||
|
||||
onUpdated(() => {
|
||||
walletStore.updateBalances();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="mt-5 shadow-md rounded-lg overflow-hidden">
|
||||
<div class="grid grid-cols-1 gap-5 p-5 bg-(--ion-card-background)">
|
||||
<div v-for="item in state.balances" :key="item.assetCode" class="flex flex-col gap-1">
|
||||
<div v-for="item in balances" :key="item.assetCode" class="flex flex-col gap-1">
|
||||
<div class="uppercase text-xs text-text-400 font-medium tracking-[0.4px]">
|
||||
{{ item.assetCode }}
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script lang='ts' setup>
|
||||
import type { WithdrawBody } from "@/api/types";
|
||||
import { toastController } from "@ionic/vue";
|
||||
import { client, safeClient } from "@/api";
|
||||
import { AssetCodeEnum, ChainEnum, WithdrawMethodEnum } from "@/api/enum";
|
||||
|
||||
@@ -15,9 +14,10 @@ const [form, resetForm] = useResetRef<WithdrawBody>({
|
||||
bankAccountId: "",
|
||||
chain: "BEP20",
|
||||
});
|
||||
const { state } = useWalletStore();
|
||||
const walletStore = useWalletStore();
|
||||
const { balances } = storeToRefs(walletStore);
|
||||
const maxAmount = computed(() => {
|
||||
const balance = state.balances?.find(item => item.assetCode === form.value.assetCode);
|
||||
const balance = balances.value?.find(item => item.assetCode === form.value.assetCode);
|
||||
return balance ? balance.available : "0";
|
||||
});
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ export default defineConfig({
|
||||
tailwindcss(),
|
||||
autoImport({
|
||||
dirs: ["src/composables", "src/utils", "src/store"],
|
||||
imports: ["vue", "vue-router", "@vueuse/core", "vue-i18n"],
|
||||
imports: ["vue", "vue-router", "@vueuse/core", "vue-i18n", "pinia"],
|
||||
resolvers: [IonicResolver()],
|
||||
vueTemplate: true,
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user