feat: 更新 API 地址,添加分类组件,优化市场页面布局和功能

This commit is contained in:
2025-12-17 20:27:58 +07:00
parent f3b7931d78
commit 5b5fcf9d44
12 changed files with 198 additions and 56 deletions

View File

@@ -2,13 +2,13 @@
import type { GenericObject } from "vee-validate";
import type { RwaIssuanceCategoriesData, RwaIssuanceProductBody } from "@/api/types";
import { toTypedSchema } from "@vee-validate/yup";
import { ErrorMessage, Field, FieldArray, Form } from "vee-validate";
import { ErrorMessage, Field, Form } from "vee-validate";
import { useI18n } from "vue-i18n";
import * as yup from "yup";
const props = defineProps<{
initialData: RwaIssuanceProductBody["product"];
categories: RwaIssuanceCategoriesData;
categories: RwaIssuanceCategoriesData | null;
}>();
const emit = defineEmits<{
(e: "next", values: GenericObject): void;
@@ -64,7 +64,7 @@ function handleSubmit(values: GenericObject) {
<Field name="categoryId" type="text">
<template #default="{ field }">
<ion-select class="ui-select" interface="action-sheet" toggle-icon="" v-bind="field" :label="t('asset.issue.apply.productType')" :placeholder="t('asset.issue.apply.chooseProductType')">
<ion-select-option v-for="item in categories" :key="item.id" :value="item.id">
<ion-select-option v-for="item in categories?.data" :key="item.id" :value="item.id">
{{ item.name }}
</ion-select-option>
</ion-select>

View File

@@ -17,7 +17,7 @@ const initialData: RwaIssuanceProductBody = {
product: {
name: "",
code: "",
categoryId: categories.value!.length > 0 ? categories.value![0].id : "",
categoryId: categories.value?.data && categories.value?.data!.length > 0 ? categories.value?.data![0].id : "",
},
editions: [
{
@@ -55,7 +55,7 @@ async function handleSubmit(editions: RwaIssuanceProductBody["editions"]) {
</ion-toolbar>
</ion-header>
<IonContent :fullscreen="true" class="ion-padding">
<Base v-if="step === 1" :initial-data="form.product" :categories="categories || []" @next="handleNext" />
<Base v-if="step === 1" :initial-data="form.product" :categories="categories" @next="handleNext" />
<IssuePeriod v-else-if="step === 2" :initial-data="form.editions" @submit="handleSubmit" />
<Done v-else />
</IonContent>

View File

@@ -0,0 +1,46 @@
<script lang='ts' setup>
import { client, safeClient } from "@/api";
const model = defineModel({ type: String, default: "" });
const { data: categories } = await safeClient(() => client.api.rwa.issuance.categories.get());
</script>
<template>
<ion-content :scroll-x="true" :scroll-y="false" class="w-full h-10">
<div class="flex items-center whitespace-nowrap space-x-4">
<div class="item" :class="{ active: model === '' }" @click="model = ''">
全部
</div>
<div
v-for="item in categories?.data"
:key="item.id"
class="item"
:class="{ active: model === item.id }"
@click="model = item.id"
>
{{ item.name }}
</div>
</div>
</ion-content>
</template>
<style scoped>
@reference "tailwindcss";
ion-content::part(scroll) {
scrollbar-width: none;
}
.item {
@apply px-3 py-1 rounded-full text-xs transition-all;
}
@media (prefers-color-scheme: dark) {
.item {
@apply bg-(--ion-color-step-800);
}
}
.item.active {
@apply bg-(--ion-color-success) text-white;
}
</style>

View File

@@ -1,21 +1,43 @@
<script setup lang="ts">
import type { AvailableSubscriptionBody } from "@/api/types";
import { client, safeClient } from "@/api";
import Category from "./components/category.vue";
const [query] = useResetRef<AvailableSubscriptionBody>({
status: "open",
pageIndex: 1,
pageSize: 20,
categoryId: "",
});
const { data, refresh } = safeClient(() => client.api.rwa.subscription.available_editions.get({
query: query.value,
}));
watch(query, () => {
refresh();
}, { deep: true });
</script>
<template>
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>Trade</IonTitle>
<IonToolbar class="ui-toolbar">
<ion-title>Market</ion-title>
</IonToolbar>
<ion-toolbar class="ui-toolbar">
<ion-searchbar />
</ion-toolbar>
</IonHeader>
<IonContent :fullscreen="true">
<IonHeader collapse="condense">
<IonToolbar>
<IonTitle size="large">
Trade
</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent :fullscreen="true" class="ion-padding">
<ui-tabs sticky>
<ui-tab-pane name="spot" title="Digital Products" class="py-5">
<Category v-model="query!.categoryId" />
<ion-content :scroll-y="true" />
</ui-tab-pane>
<ui-tab-pane name="futures" title="Tokenized Products" class="py-5">
<div>Futures Market Content</div>
</ui-tab-pane>
</ui-tabs>
</IonContent>
</IonPage>
</template>