feat: 更新订单面板样式,优化订单列表和空状态展示;添加用户界面菜单按钮

This commit is contained in:
2025-12-29 17:46:51 +07:00
parent 7f10d4f4e4
commit ae0e73a4e8
4 changed files with 34 additions and 157 deletions

View File

@@ -189,5 +189,5 @@ html.ion-palette-dark {
--ui-input-background: #1e1e1e;
--ui-input-color: #ffffff;
--ion-color-faint: #626262;
--ion-color-faint: #1b1b1b;
}

View File

@@ -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 {

View File

@@ -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>

View File

@@ -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" />