feat: 更新 '@capp/eden' 依赖至 0.0.9,添加资产中心页面,优化钱包相关逻辑
This commit is contained in:
4
components.d.ts
vendored
4
components.d.ts
vendored
@@ -34,6 +34,8 @@ declare module 'vue' {
|
||||
IonRouterOutlet: typeof import('@ionic/vue')['IonRouterOutlet']
|
||||
IonSegment: typeof import('@ionic/vue')['IonSegment']
|
||||
IonSegmentButton: typeof import('@ionic/vue')['IonSegmentButton']
|
||||
IonSelect: typeof import('@ionic/vue')['IonSelect']
|
||||
IonSelectOption: typeof import('@ionic/vue')['IonSelectOption']
|
||||
IonSpinner: typeof import('@ionic/vue')['IonSpinner']
|
||||
IonTabBar: typeof import('@ionic/vue')['IonTabBar']
|
||||
IonTabButton: typeof import('@ionic/vue')['IonTabButton']
|
||||
@@ -72,6 +74,8 @@ declare global {
|
||||
const IonRouterOutlet: typeof import('@ionic/vue')['IonRouterOutlet']
|
||||
const IonSegment: typeof import('@ionic/vue')['IonSegment']
|
||||
const IonSegmentButton: typeof import('@ionic/vue')['IonSegmentButton']
|
||||
const IonSelect: typeof import('@ionic/vue')['IonSelect']
|
||||
const IonSelectOption: typeof import('@ionic/vue')['IonSelectOption']
|
||||
const IonSpinner: typeof import('@ionic/vue')['IonSpinner']
|
||||
const IonTabBar: typeof import('@ionic/vue')['IonTabBar']
|
||||
const IonTabButton: typeof import('@ionic/vue')['IonTabButton']
|
||||
|
||||
14
pnpm-lock.yaml
generated
14
pnpm-lock.yaml
generated
@@ -52,8 +52,8 @@ catalogs:
|
||||
specifier: 8.0.0
|
||||
version: 8.0.0
|
||||
'@capp/eden':
|
||||
specifier: http://192.168.1.2:9538/api/capp-eden-0.0.8.tgz
|
||||
version: 0.0.8
|
||||
specifier: http://192.168.1.2:9538/api/capp-eden-0.0.9.tgz
|
||||
version: 0.0.9
|
||||
'@cloudflare/workers-types':
|
||||
specifier: ^4.20260113.0
|
||||
version: 4.20260116.0
|
||||
@@ -298,7 +298,7 @@ importers:
|
||||
version: 8.0.0(@capacitor/core@8.0.0)
|
||||
'@capp/eden':
|
||||
specifier: 'catalog:'
|
||||
version: http://192.168.1.2:9538/api/capp-eden-0.0.8.tgz(@elysiajs/eden@1.4.6(elysia@1.4.22(@sinclair/typebox@0.34.47)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3)))
|
||||
version: http://192.168.1.2:9538/api/capp-eden-0.0.9.tgz(@elysiajs/eden@1.4.6(elysia@1.4.22(@sinclair/typebox@0.34.47)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3)))
|
||||
'@elysiajs/eden':
|
||||
specifier: 'catalog:'
|
||||
version: 1.4.6(elysia@1.4.22(@sinclair/typebox@0.34.47)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3))
|
||||
@@ -1182,9 +1182,9 @@ packages:
|
||||
'@capacitor/synapse@1.0.4':
|
||||
resolution: {integrity: sha512-/C1FUo8/OkKuAT4nCIu/34ny9siNHr9qtFezu4kxm6GY1wNFxrCFWjfYx5C1tUhVGz3fxBABegupkpjXvjCHrw==}
|
||||
|
||||
'@capp/eden@http://192.168.1.2:9538/api/capp-eden-0.0.8.tgz':
|
||||
resolution: {tarball: http://192.168.1.2:9538/api/capp-eden-0.0.8.tgz}
|
||||
version: 0.0.8
|
||||
'@capp/eden@http://192.168.1.2:9538/api/capp-eden-0.0.9.tgz':
|
||||
resolution: {tarball: http://192.168.1.2:9538/api/capp-eden-0.0.9.tgz}
|
||||
version: 0.0.9
|
||||
peerDependencies:
|
||||
'@elysiajs/eden': ^1.4.6
|
||||
|
||||
@@ -6903,7 +6903,7 @@ snapshots:
|
||||
|
||||
'@capacitor/synapse@1.0.4': {}
|
||||
|
||||
'@capp/eden@http://192.168.1.2:9538/api/capp-eden-0.0.8.tgz(@elysiajs/eden@1.4.6(elysia@1.4.22(@sinclair/typebox@0.34.47)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3)))':
|
||||
'@capp/eden@http://192.168.1.2:9538/api/capp-eden-0.0.9.tgz(@elysiajs/eden@1.4.6(elysia@1.4.22(@sinclair/typebox@0.34.47)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3)))':
|
||||
dependencies:
|
||||
'@elysiajs/eden': 1.4.6(elysia@1.4.22(@sinclair/typebox@0.34.47)(exact-mirror@0.2.6(@sinclair/typebox@0.34.47))(file-type@21.3.0)(openapi-types@12.1.3)(typescript@5.9.3))
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ catalog:
|
||||
'@capacitor/keyboard': 8.0.0
|
||||
'@capacitor/share': ^8.0.0
|
||||
'@capacitor/status-bar': 8.0.0
|
||||
'@capp/eden': http://192.168.1.2:9538/api/capp-eden-0.0.8.tgz
|
||||
'@capp/eden': http://192.168.1.2:9538/api/capp-eden-0.0.9.tgz
|
||||
'@cloudflare/workers-types': ^4.20260113.0
|
||||
'@elysiajs/eden': ^1.4.6
|
||||
'@faker-js/faker': ^10.2.0
|
||||
|
||||
@@ -61,8 +61,8 @@ export function safeClient<T, E>(
|
||||
isPending.value = false;
|
||||
});
|
||||
|
||||
if (res.error && res.status === 418) {
|
||||
if (!options.silent) {
|
||||
if (res.error) {
|
||||
if (!options.silent && res.status === 418) {
|
||||
const toast = await toastController.create({
|
||||
message: i18n.global.t((res.error as any).value.code, {
|
||||
...(res.error as any).value.context,
|
||||
@@ -73,6 +73,10 @@ export function safeClient<T, E>(
|
||||
});
|
||||
await toast.present();
|
||||
}
|
||||
else if (res.status === 401) {
|
||||
localStorage.removeItem("user-token");
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
throw res.error;
|
||||
}
|
||||
|
||||
@@ -119,6 +119,11 @@ const routes: Array<RouteRecordRaw> = [
|
||||
component: () => import("@/views/team/index.vue"),
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
{
|
||||
path: "/asset_center",
|
||||
component: () => import("@/views/asset_center/index.vue"),
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
|
||||
@@ -5,21 +5,20 @@ export type Wallet = Treaty.Data<typeof client.api.wallet.wallets.get>[number];
|
||||
|
||||
export const useWalletStore = defineStore("wallet", () => {
|
||||
const wallets = ref<Wallet[]>([]);
|
||||
const balanceWallet = ref<Wallet | null>(null);
|
||||
|
||||
async function syncWallets() {
|
||||
const { data } = await safeClient(client.api.wallet.wallets.get(), { silent: true });
|
||||
wallets.value = data.value || [];
|
||||
}
|
||||
async function syncBalanceWallet() {
|
||||
const { data } = await safeClient(client.api.wallet.wallet_by_code({ walletTypeCode: "balance" }).get(), { silent: true });
|
||||
balanceWallet.value = data.value || null;
|
||||
async function getWalletByType(type: Wallet["walletType"]["code"]) {
|
||||
const { data } = await safeClient(client.api.wallet.wallet_by_code({ walletTypeCode: type }).get(), { silent: true });
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
return {
|
||||
wallets,
|
||||
balanceWallet,
|
||||
syncWallets,
|
||||
syncBalanceWallet,
|
||||
getWalletByType,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -63,75 +63,9 @@
|
||||
--ion-color-dark-tint: #444444;
|
||||
|
||||
}
|
||||
/*
|
||||
:root {
|
||||
--ion-color-primary: #2065c3;
|
||||
--ion-color-primary-rgb: 32,101,195;
|
||||
--ion-color-primary-contrast: #ffffff;
|
||||
--ion-color-primary-contrast-rgb: 255,255,255;
|
||||
--ion-color-primary-shade: #1c59ac;
|
||||
--ion-color-primary-tint: #3674c9;
|
||||
|
||||
--ion-color-secondary: #0163aa;
|
||||
--ion-color-secondary-rgb: 1,99,170;
|
||||
--ion-color-secondary-contrast: #ffffff;
|
||||
--ion-color-secondary-contrast-rgb: 255,255,255;
|
||||
--ion-color-secondary-shade: #015796;
|
||||
--ion-color-secondary-tint: #1a73b3;
|
||||
|
||||
--ion-color-tertiary: #6030ff;
|
||||
--ion-color-tertiary-rgb: 96,48,255;
|
||||
--ion-color-tertiary-contrast: #ffffff;
|
||||
--ion-color-tertiary-contrast-rgb: 255,255,255;
|
||||
--ion-color-tertiary-shade: #542ae0;
|
||||
--ion-color-tertiary-tint: #7045ff;
|
||||
|
||||
--ion-color-success: #2dd55b;
|
||||
--ion-color-success-rgb: 45,213,91;
|
||||
--ion-color-success-contrast: #000000;
|
||||
--ion-color-success-contrast-rgb: 0,0,0;
|
||||
--ion-color-success-shade: #28bb50;
|
||||
--ion-color-success-tint: #42d96b;
|
||||
|
||||
--ion-color-warning: #ffc409;
|
||||
--ion-color-warning-rgb: 255,196,9;
|
||||
--ion-color-warning-contrast: #000000;
|
||||
--ion-color-warning-contrast-rgb: 0,0,0;
|
||||
--ion-color-warning-shade: #e0ac08;
|
||||
--ion-color-warning-tint: #ffca22;
|
||||
|
||||
--ion-color-danger: #c5000f;
|
||||
--ion-color-danger-rgb: 197,0,15;
|
||||
--ion-color-danger-contrast: #ffffff;
|
||||
--ion-color-danger-contrast-rgb: 255,255,255;
|
||||
--ion-color-danger-shade: #ad000d;
|
||||
--ion-color-danger-tint: #cb1a27;
|
||||
|
||||
--ion-color-light: #f6f8fc;
|
||||
--ion-color-light-rgb: 246,248,252;
|
||||
--ion-color-light-contrast: #000000;
|
||||
--ion-color-light-contrast-rgb: 0,0,0;
|
||||
--ion-color-light-shade: #d8dade;
|
||||
--ion-color-light-tint: #f7f9fc;
|
||||
|
||||
--ion-color-medium: #5f5f5f;
|
||||
--ion-color-medium-rgb: 95,95,95;
|
||||
--ion-color-medium-contrast: #ffffff;
|
||||
--ion-color-medium-contrast-rgb: 255,255,255;
|
||||
--ion-color-medium-shade: #545454;
|
||||
--ion-color-medium-tint: #6f6f6f;
|
||||
|
||||
--ion-color-dark: #2f2f2f;
|
||||
--ion-color-dark-rgb: 47,47,47;
|
||||
--ion-color-dark-contrast: #ffffff;
|
||||
--ion-color-dark-contrast-rgb: 255,255,255;
|
||||
--ion-color-dark-shade: #292929;
|
||||
--ion-color-dark-tint: #444444;
|
||||
|
||||
} */
|
||||
|
||||
.ion-toolbar {
|
||||
--background: var(--ion-color-primary);
|
||||
--background: #c32120;
|
||||
--min-height: 58px;
|
||||
--color: white;
|
||||
}
|
||||
107
src/views/asset_center/index.vue
Normal file
107
src/views/asset_center/index.vue
Normal file
@@ -0,0 +1,107 @@
|
||||
<script lang='ts' setup>
|
||||
import { arrowDownOutline, arrowUpOutline, cardOutline, swapHorizontalOutline, syncOutline } from "ionicons/icons";
|
||||
|
||||
const router = useRouter();
|
||||
const walletStore = useWalletStore();
|
||||
const { wallets } = storeToRefs(walletStore);
|
||||
|
||||
onMounted(async () => {
|
||||
await walletStore.syncWallets();
|
||||
});
|
||||
|
||||
function formatAmount(amount: number | string) {
|
||||
const num = Number(amount);
|
||||
return num.toLocaleString("zh-CN", {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
}
|
||||
|
||||
// 操作按钮配置
|
||||
const actions = [
|
||||
{ id: "recharge", name: "充值", icon: arrowDownOutline, color: "#c32120" },
|
||||
{ id: "withdraw", name: "提现", icon: arrowUpOutline, color: "#c32120" },
|
||||
{ id: "transfer", name: "转账", icon: swapHorizontalOutline, color: "#c32120" },
|
||||
{ id: "exchange", name: "兑换", icon: syncOutline, color: "#c32120" },
|
||||
];
|
||||
|
||||
function handleAction(actionId: string) {
|
||||
router.push(`/${actionId}`);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ion-page>
|
||||
<ion-header class="ion-no-border">
|
||||
<ion-toolbar class="ion-toolbar">
|
||||
<ion-buttons slot="start">
|
||||
<back-button />
|
||||
</ion-buttons>
|
||||
<ion-title>资产中心</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content :fullscreen="true">
|
||||
<div class="ion-padding">
|
||||
<!-- 操作按钮 -->
|
||||
<section class="my-5 grid grid-cols-4 gap-4">
|
||||
<div
|
||||
v-for="action in actions"
|
||||
:key="action.id"
|
||||
class="flex flex-col items-center gap-2 cursor-pointer transition-transform active:scale-95"
|
||||
@click="handleAction(action.id)"
|
||||
>
|
||||
<div
|
||||
class="w-12 h-12 rounded-xl flex-center shadow-lg"
|
||||
:style="{ background: action.color }"
|
||||
>
|
||||
<ion-icon :icon="action.icon" class="text-xl text-white" />
|
||||
</div>
|
||||
<span class="text-xs text-[#333] font-medium text-center">{{ action.name }}</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 钱包列表 -->
|
||||
<section class="mt-8 mb-5">
|
||||
<div class="flex items-center gap-2 mb-4">
|
||||
<img src="@/assets/images/icon.png" class="size-7">
|
||||
<div class="text-xl font-bold text-[#1a1a1a]">
|
||||
我的钱包
|
||||
</div>
|
||||
</div>
|
||||
<empty v-if="wallets.length === 0" class="my-10" />
|
||||
<div v-else class="flex flex-col gap-4">
|
||||
<div
|
||||
v-for="wallet in wallets"
|
||||
:key="wallet.id"
|
||||
class="card rounded-2xl overflow-hidden shadow-sm p-5"
|
||||
>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex-1">
|
||||
<div class="text-sm text-[#666] mb-1 flex items-center gap-2 font-bold">
|
||||
<ion-icon :icon="cardOutline" class="text-xl text-primary" />
|
||||
{{ wallet.walletType.name }}
|
||||
</div>
|
||||
<div class="text-2xl font-bold text-[#1a1a1a]">
|
||||
¥ {{ formatAmount(wallet.available) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</ion-content>
|
||||
</ion-page>
|
||||
</template>
|
||||
|
||||
<style lang='css' scoped>
|
||||
.flex-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.card {
|
||||
/* background: linear-gradient(45deg, #ffffff, #ffdbdb 100%); */
|
||||
}
|
||||
</style>
|
||||
@@ -2,7 +2,7 @@
|
||||
import { arrowDownCircleOutline, arrowUpCircleOutline, listOutline, walletOutline } from "ionicons/icons";
|
||||
|
||||
const walletStore = useWalletStore();
|
||||
const { balanceWallet } = storeToRefs(walletStore);
|
||||
const balanceWallet = await walletStore.getWalletByType("balance");
|
||||
|
||||
// 当前选中的标签
|
||||
const selectedTab = ref<"all" | "income" | "investment">("all");
|
||||
@@ -137,8 +137,6 @@ function getTypeName(type: string) {
|
||||
function formatAmount(amount: number) {
|
||||
return amount >= 0 ? `+${amount.toFixed(2)}` : amount.toFixed(2);
|
||||
}
|
||||
|
||||
walletStore.syncBalanceWallet();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -39,6 +39,15 @@ async function handleSignup() {
|
||||
|
||||
<template>
|
||||
<ion-page>
|
||||
<ion-header class="ion-no-border">
|
||||
<ion-toolbar class="ion-toolbar">
|
||||
<ion-buttons slot="start">
|
||||
<back-button />
|
||||
</ion-buttons>
|
||||
<!-- <ion-title>签到</ion-title> -->
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<!-- 顶部横幅 -->
|
||||
<img src="@/assets/images/signup-banner.jpg" class="h-50 w-full object-cover" alt="服务页横幅">
|
||||
|
||||
@@ -70,6 +70,15 @@ function handleDownloadQR() {
|
||||
|
||||
<template>
|
||||
<ion-page>
|
||||
<ion-header class="ion-no-border">
|
||||
<ion-toolbar class="ion-toolbar">
|
||||
<ion-buttons slot="start">
|
||||
<back-button />
|
||||
</ion-buttons>
|
||||
<ion-title>邀请</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content :fullscreen="true">
|
||||
<!-- 顶部横幅 -->
|
||||
<img src="@/assets/images/invite-banner.jpg" class="w-full object-cover" alt="邀请横幅">
|
||||
|
||||
@@ -9,9 +9,9 @@ const router = useRouter();
|
||||
const userStore = useUserStore();
|
||||
const walletStore = useWalletStore();
|
||||
const { userProfile } = storeToRefs(userStore);
|
||||
const { balanceWallet } = storeToRefs(walletStore);
|
||||
|
||||
walletStore.syncBalanceWallet();
|
||||
const balanceWallet = await walletStore.getWalletByType("balance");
|
||||
const profitWallet = await walletStore.getWalletByType("profit");
|
||||
|
||||
function handleRecharge() {
|
||||
router.push("/recharge");
|
||||
@@ -72,7 +72,7 @@ async function handleLogout() {
|
||||
手机号:{{ userProfile?.user.username }}
|
||||
</div>
|
||||
<div class="text-primary text-sm font-semibold opacity-90">
|
||||
邀请码:{{ userProfile?.inviteCode }}
|
||||
邀请码:{{ userProfile?.referralCode }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -96,7 +96,7 @@ async function handleLogout() {
|
||||
收益钱包
|
||||
</div>
|
||||
<div class="text-2xl font-bold text-[#c41e3a] mb-1">
|
||||
¥{{ balanceWallet?.available }}
|
||||
¥{{ Number(profitWallet?.available).toString() }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-linear-to-br from-[#fff7f0] to-[#ffe8e8] rounded-xl p-4">
|
||||
@@ -104,11 +104,20 @@ async function handleLogout() {
|
||||
账户余额
|
||||
</div>
|
||||
<div class="text-2xl font-bold text-[#c41e3a] mb-1">
|
||||
¥{{ balanceWallet?.available }}
|
||||
¥{{ Number(balanceWallet?.available).toString() }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ion-button
|
||||
expand="block"
|
||||
class="flex-1 recharge-btn mb-5"
|
||||
@click="router.push('/asset_center')"
|
||||
>
|
||||
<ion-icon slot="start" :icon="walletOutline" class="mr-2" />
|
||||
资产中心
|
||||
</ion-button>
|
||||
|
||||
<!-- 快捷操作按钮 -->
|
||||
<div class="flex gap-3">
|
||||
<ion-button
|
||||
|
||||
@@ -3,7 +3,7 @@ import { alertController, toastController } from "@ionic/vue";
|
||||
import { cardOutline, checkmarkCircleOutline, documentTextOutline, logoAlipay, logoWechat, walletOutline } from "ionicons/icons";
|
||||
|
||||
const walletStore = useWalletStore();
|
||||
const { balanceWallet } = storeToRefs(walletStore);
|
||||
const balanceWallet = await walletStore.getWalletByType("balance");
|
||||
|
||||
interface PaymentMethod {
|
||||
id: number;
|
||||
@@ -144,12 +144,11 @@ async function handleSubmit() {
|
||||
handler: async () => {
|
||||
// TODO: 调用充值 API
|
||||
await showToast("充值成功");
|
||||
// 重置表单
|
||||
rechargeAmount.value = "";
|
||||
selectedPaymentType.value = null;
|
||||
selectedPaymentId.value = null;
|
||||
// 刷新余额
|
||||
walletStore.syncBalanceWallet();
|
||||
const data = await walletStore.getWalletByType("balance");
|
||||
balanceWallet.value = data.value;
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -157,8 +156,6 @@ async function handleSubmit() {
|
||||
|
||||
await alert.present();
|
||||
}
|
||||
|
||||
walletStore.syncBalanceWallet();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -185,7 +182,7 @@ walletStore.syncBalanceWallet();
|
||||
<span>当前账户余额</span>
|
||||
</div>
|
||||
<div class="balance-amount">
|
||||
¥{{ balanceWallet?.balance?.toFixed(2) || '0.00' }}
|
||||
¥{{ Number(balanceWallet?.available)?.toFixed(2) || '0.00' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ const [depth3Query] = useResetRef({
|
||||
pageSize: 10,
|
||||
});
|
||||
// 统计数据
|
||||
const { data: statistics } = safeClient(client.api.team.stats.get({ query: { currentTime: new Date().toISOString() } }));
|
||||
const { data: statistics } = safeClient(client.api.team.stats.get());
|
||||
const { data: depth1, execute: executeDepth1 } = safeClient(() => client.api.team.members.get({ query: { ...depth1Query.value } }));
|
||||
const { data: depth2, execute: executeDepth2 } = safeClient(() => client.api.team.members.get({ query: { ...depth2Query.value } }));
|
||||
const { data: depth3, execute: executeDepth3 } = safeClient(() => client.api.team.members.get({ query: { ...depth3Query.value } }));
|
||||
|
||||
Reference in New Issue
Block a user