feat: 更新订单面板样式,优化订单列表和空状态展示;添加用户界面菜单按钮
This commit is contained in:
@@ -189,5 +189,5 @@ html.ion-palette-dark {
|
||||
--ui-input-background: #1e1e1e;
|
||||
--ui-input-color: #ffffff;
|
||||
|
||||
--ion-color-faint: #626262;
|
||||
--ion-color-faint: #1b1b1b;
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ const qrcode = useQRCode(url, {
|
||||
@apply flex flex-col items-center gap-2 text-[text-500] font-medium;
|
||||
}
|
||||
.icon {
|
||||
@apply p-2.5 bg-(--ion-text-color-step-700) rounded-full;
|
||||
@apply p-2.5 bg-(--ion-color-faint) rounded-full;
|
||||
}
|
||||
|
||||
.text {
|
||||
|
||||
@@ -118,7 +118,7 @@ async function cancelOrder(orderId: string) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="orders-panel">
|
||||
<div class="flex flex-col h-full bg-(--ion-background-color)">
|
||||
<!-- Tab切换 -->
|
||||
<ui-tabs v-model="activeTab" size="small">
|
||||
<ui-tab-pane
|
||||
@@ -132,194 +132,67 @@ async function cancelOrder(orderId: string) {
|
||||
</ui-tabs>
|
||||
|
||||
<!-- 订单列表 -->
|
||||
<div class="orders-list">
|
||||
<div v-if="displayOrders.length === 0" class="empty-state">
|
||||
<div class="text-text-500 text-sm">
|
||||
<div class="flex-1 overflow-y-auto">
|
||||
<div v-if="displayOrders.length === 0" class="flex items-center justify-center py-10 px-5">
|
||||
<div class="text-(--ion-text-color-step-500) text-sm">
|
||||
{{ activeTab === 'current' ? '暂无当前委托' : '暂无历史记录' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="orders-content">
|
||||
<div v-else class="space-y-3">
|
||||
<div
|
||||
v-for="order in displayOrders"
|
||||
:key="order.id"
|
||||
class="order-item"
|
||||
class="bg-faint rounded-xl p-3"
|
||||
>
|
||||
<div class="order-header">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
<div class="flex items-center gap-2">
|
||||
<span
|
||||
class="side-badge"
|
||||
:class="order.side === 'buy' ? 'buy' : 'sell'"
|
||||
class="px-2 py-0.5 rounded text-[11px] font-semibold"
|
||||
:class="order.side === 'buy'
|
||||
? 'bg-success/10 text-(--ion-color-success)'
|
||||
: 'bg-danger/10 text-(--ion-color-danger)'"
|
||||
>
|
||||
{{ order.side === 'buy' ? '买入' : '卖出' }}
|
||||
</span>
|
||||
<span class="text-sm font-medium">{{ order.symbol }}</span>
|
||||
<ion-badge :color="getStatusColor(order.status)" class="status-badge">
|
||||
<ion-badge :color="getStatusColor(order.status)" class="text-[10px] px-1.5 py-0.5">
|
||||
{{ getStatusText(order.status) }}
|
||||
</ion-badge>
|
||||
</div>
|
||||
<button
|
||||
v-if="activeTab === 'current' && order.status !== 'filled'"
|
||||
class="cancel-btn"
|
||||
class="px-3 py-1 bg-transparent border border-(--ion-color-danger) text-(--ion-color-danger) rounded-md text-xs transition-all active:bg-(--ion-color-danger) active:text-white"
|
||||
@click="cancelOrder(order.id)"
|
||||
>
|
||||
撤单
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="order-details">
|
||||
<div class="detail-row">
|
||||
<span class="label">{{ order.type === 'limit' ? '价格' : '市价' }}</span>
|
||||
<span class="value">{{ order.type === 'limit' ? order.price : '-' }}</span>
|
||||
<div class="grid grid-cols-2 gap-2 mb-2">
|
||||
<div class="flex justify-between text-xs">
|
||||
<span class="text-(--ion-text-color-step-400)">{{ order.type === 'limit' ? '价格' : '市价' }}</span>
|
||||
<span class="text-(--ion-text-color) font-medium">{{ order.type === 'limit' ? order.price : '-' }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="label">数量</span>
|
||||
<span class="value">{{ order.amount }}</span>
|
||||
<div class="flex justify-between text-xs">
|
||||
<span class="text-(--ion-text-color-step-400)">数量</span>
|
||||
<span class="text-(--ion-text-color) font-medium">{{ order.amount }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="label">成交</span>
|
||||
<span class="value">{{ order.filled }}</span>
|
||||
<div class="flex justify-between text-xs">
|
||||
<span class="text-(--ion-text-color-step-400)">成交</span>
|
||||
<span class="text-(--ion-text-color) font-medium">{{ order.filled }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="label">总额</span>
|
||||
<span class="value">{{ order.total }} USDT</span>
|
||||
<div class="flex justify-between text-xs">
|
||||
<span class="text-(--ion-text-color-step-400)">总额</span>
|
||||
<span class="text-(--ion-text-color) font-medium">{{ order.total }} USDT</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="order-footer">
|
||||
<span class="time">{{ order.time }}</span>
|
||||
<div class="pt-2">
|
||||
<span class="text-[11px] text-(--ion-text-color-step-500)">{{ order.time }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.orders-panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
background: var(--ion-background-color);
|
||||
}
|
||||
|
||||
.tabs-header {
|
||||
display: flex;
|
||||
border-bottom: 1px solid var(--ion-border-color);
|
||||
background: var(--ion-background-color);
|
||||
}
|
||||
|
||||
.tabs-header button {
|
||||
flex: 1;
|
||||
padding: 12px 0;
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--ion-text-color-step-400);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
border-bottom: 2px solid transparent;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.tabs-header button.active {
|
||||
color: var(--ion-color-primary);
|
||||
border-bottom-color: var(--ion-color-primary);
|
||||
}
|
||||
|
||||
.orders-list {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 40px 20px;
|
||||
}
|
||||
|
||||
.order-item {
|
||||
background: var(--ion-color-light);
|
||||
border-radius: 12px;
|
||||
padding: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.order-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.side-badge {
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.side-badge.buy {
|
||||
background: rgba(34, 197, 94, 0.1);
|
||||
color: var(--ion-color-success);
|
||||
}
|
||||
|
||||
.side-badge.sell {
|
||||
background: rgba(239, 68, 68, 0.1);
|
||||
color: var(--ion-color-danger);
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
font-size: 10px;
|
||||
padding: 2px 6px;
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
padding: 4px 12px;
|
||||
background: transparent;
|
||||
border: 1px solid var(--ion-color-danger);
|
||||
color: var(--ion-color-danger);
|
||||
border-radius: 6px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.cancel-btn:active {
|
||||
background: var(--ion-color-danger);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.order-details {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.detail-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.detail-row .label {
|
||||
color: var(--ion-text-color-step-400);
|
||||
}
|
||||
|
||||
.detail-row .value {
|
||||
color: var(--ion-text-color);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.order-footer {
|
||||
padding-top: 8px;
|
||||
border-top: 1px solid var(--ion-border-color);
|
||||
}
|
||||
|
||||
.order-footer .time {
|
||||
font-size: 11px;
|
||||
color: var(--ion-text-color-step-500);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { RefresherCustomEvent } from "@ionic/vue";
|
||||
import { notificationsOutline, scanOutline, settingsOutline } from "ionicons/icons";
|
||||
import IconParkOutlineApplicationMenu from "~icons/icon-park-outline/application-menu";
|
||||
import IconParkOutlineScanCode from "~icons/icon-park-outline/scan-code";
|
||||
import IconParkOutlineSettingOne from "~icons/icon-park-outline/setting-one";
|
||||
import MaterialSymbolsNotificationsOutline from "~icons/material-symbols/notifications-outline";
|
||||
@@ -42,6 +43,9 @@ async function handleScan() {
|
||||
<ion-page>
|
||||
<ion-header class="ion-no-border">
|
||||
<ion-toolbar class="ui-toolbar">
|
||||
<ion-button slot="start" fill="clear" class="z-1" @click="$router.push('/global-menu')">
|
||||
<IconParkOutlineApplicationMenu slot="icon-only" />
|
||||
</ion-button>
|
||||
<div slot="end">
|
||||
<ion-button fill="clear" @click="handleScan">
|
||||
<IconParkOutlineScanCode slot="icon-only" />
|
||||
|
||||
Reference in New Issue
Block a user