feat: 添加产品记录页面,支持我的业务功能和数据加载
This commit is contained in:
@@ -39,6 +39,11 @@ const routes: Array<RouteRecordRaw> = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "/product/records",
|
||||
component: () => import("@/views/product/records.vue"),
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
{
|
||||
path: "/news/:id",
|
||||
props: true,
|
||||
|
||||
@@ -3,7 +3,7 @@ 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 { bagHandleOutline, calendarOutline, cardOutline, timeOutline, trendingUpOutline } from "ionicons/icons";
|
||||
import { client, safeClient } from "@/api";
|
||||
import Subscribe from "./components/subscribe.vue";
|
||||
|
||||
@@ -82,13 +82,17 @@ onMounted(() => {
|
||||
<!-- 基金产品列表 -->
|
||||
<section class="mb-5 -mt-5 ion-padding-horizontal">
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<div class="flex justify-between items-center mb-4 w-full">
|
||||
<div class="flex items-center gap-2">
|
||||
<img src="@/assets/images/icon.png" class="size-7">
|
||||
<div class="text-xl font-bold text-[#1a1a1a]">
|
||||
基金产品
|
||||
</div>
|
||||
</div>
|
||||
<ion-button fill="clear" size="small" @click="$router.push('/product/records')">
|
||||
<ion-icon slot="start" :icon="bagHandleOutline" />
|
||||
我的业务
|
||||
</ion-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -137,6 +141,12 @@ onMounted(() => {
|
||||
{{ Number(product.cycleDays) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span class="text-xs text-[#999] mb-1">改革先锋扶持金</span>
|
||||
<span class="text-lg font-bold text-[#52c41a] flex items-center gap-0.5">
|
||||
¥{{ Number(product.reformPioneerAllowance) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 申购按钮 -->
|
||||
|
||||
128
src/views/product/records.vue
Normal file
128
src/views/product/records.vue
Normal file
@@ -0,0 +1,128 @@
|
||||
<script lang='ts' setup>
|
||||
import type { Treaty } from "@elysiajs/eden";
|
||||
import type { InfiniteScrollCustomEvent } from "@ionic/vue";
|
||||
import type { TreatyQuery } from "@/api/types";
|
||||
import { client, safeClient } from "@/api";
|
||||
|
||||
type Subscribe = Treaty.Data<typeof client.api.subscription.orders.get>["data"][number];
|
||||
type SubscribeQuery = TreatyQuery<typeof client.api.subscription.orders.get>;
|
||||
|
||||
const [query] = useResetRef<SubscribeQuery>({
|
||||
offset: 0,
|
||||
limit: 10,
|
||||
});
|
||||
const data = ref<Subscribe[]>([]);
|
||||
const isFinished = ref(false);
|
||||
|
||||
async function fetchData() {
|
||||
const { data: responseData } = await safeClient(client.api.subscription.orders.get({ query: { ...query.value } }));
|
||||
data.value.push(...(responseData.value?.data || []));
|
||||
isFinished.value = responseData.value?.pagination.hasNextPage === false;
|
||||
}
|
||||
async function handleInfinite(event: InfiniteScrollCustomEvent) {
|
||||
if (isFinished.value) {
|
||||
event.target.complete();
|
||||
event.target.disabled = true;
|
||||
return;
|
||||
}
|
||||
query.value.offset! += query.value.limit!;
|
||||
await fetchData();
|
||||
setTimeout(() => {
|
||||
event.target.complete();
|
||||
}, 500);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchData();
|
||||
});
|
||||
</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="p-4">
|
||||
<empty v-if="data.length === 0 && !isFinished" class="my-20" />
|
||||
|
||||
<div v-else class="flex flex-col gap-3">
|
||||
<div
|
||||
v-for="item in data"
|
||||
:key="item.id"
|
||||
class="bg-white rounded-2xl p-4 shadow-sm"
|
||||
>
|
||||
<!-- 顶部状态栏 -->
|
||||
<div class="flex items-center justify-between mb-3 pb-3 border-b border-gray-100">
|
||||
<div class="text-xs text-gray-500">
|
||||
{{ useDateFormat(item.createdAt, 'YYYY-MM-DD HH:mm') }}
|
||||
</div>
|
||||
<div
|
||||
class="px-3 py-1 rounded-full text-xs font-semibold"
|
||||
:class="{
|
||||
'bg-green-50 text-green-600': item.status === 'unlocked',
|
||||
'bg-blue-50 text-blue-600': item.status === 'locked',
|
||||
'bg-yellow-50 text-yellow-600': item.status === 'pending',
|
||||
'bg-red-50 text-red-600': item.status === 'cancelled',
|
||||
'bg-gray-50 text-gray-600': !['unlocked', 'locked', 'pending', 'cancelled'].includes(item.status),
|
||||
}"
|
||||
>
|
||||
{{ item.status === 'unlocked' ? '已解锁' : item.status === 'locked' ? '锁定中' : item.status === 'pending' ? '待处理' : item.status === 'cancelled' ? '已取消' : item.status }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 金额信息 -->
|
||||
<div class="grid grid-cols-2 gap-4 mb-3">
|
||||
<div>
|
||||
<div class="text-xs text-gray-500 mb-1">
|
||||
申购金额
|
||||
</div>
|
||||
<div class="text-lg font-bold text-[#c41e3a]">
|
||||
¥{{ Number(item.price).toFixed(2) }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-xs text-gray-500 mb-1">
|
||||
改革先锋津贴
|
||||
</div>
|
||||
<div class="text-lg font-bold text-green-600">
|
||||
¥{{ Number(item.reformPioneerAllowance).toFixed(2) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 周期信息 -->
|
||||
<div class="flex items-center justify-between pt-3 border-t border-gray-100">
|
||||
<div class="text-sm text-gray-600">
|
||||
投资周期
|
||||
</div>
|
||||
<div class="text-sm font-semibold text-gray-900">
|
||||
{{ item.cycleDays }} 天
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ion-infinite-scroll threshold="100px" :disabled="isFinished" @ion-infinite="handleInfinite">
|
||||
<ion-infinite-scroll-content
|
||||
loading-spinner="bubbles"
|
||||
loading-text="加载更多..."
|
||||
/>
|
||||
</ion-infinite-scroll>
|
||||
</ion-content>
|
||||
</ion-page>
|
||||
</template>
|
||||
|
||||
<style lang='css' scoped>
|
||||
.shadow-sm {
|
||||
box-shadow:
|
||||
0 1px 3px 0 rgba(0, 0, 0, 0.1),
|
||||
0 1px 2px -1px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user