15 changed files with 961 additions and 5 deletions
@ -0,0 +1,583 @@ |
|||
<template> |
|||
<div class="ea-trading-container"> |
|||
<!-- ================= 顶部黑色区域 ================= --> |
|||
<div class="header-section"> |
|||
<div class="header-content"> |
|||
<!-- 左侧标题与切换按钮 --> |
|||
<div class="header-left"> |
|||
<h1 class="title">{{$t('automation.a1')}}</h1> |
|||
<p class="subtitle">{{$t('automation.a2')}}</p> |
|||
<div class="toggle-btns"> |
|||
<button |
|||
:class="['btn-toggle', mainTab === 'stock' ? 'active' : '']" |
|||
@click="switchMainTab('stock')" |
|||
>{{$t('automation.a3')}}</button> |
|||
<button |
|||
:class="['btn-toggle', mainTab === 'crypto' ? 'active' : '']" |
|||
@click="switchMainTab('crypto')" |
|||
>{{$t('automation.a4')}}</button> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- 右侧资产信息 --> |
|||
<div class="header-right"> |
|||
<div> |
|||
<div style="display: flex;justify-content: space-between;margin-bottom: 20px;"> |
|||
<div class="asset-item"> |
|||
<span class="label">{{$t('automation.a5')}}</span> |
|||
<span class="value">{{ currentAccount.total }} {{ currencyUnit }}</span> |
|||
</div> |
|||
<div class="asset-item text-right"> |
|||
<span class="link-text">{{$t('automation.a6')}} ></span> |
|||
</div> |
|||
</div> |
|||
<div class="asset-grid"> |
|||
<div class="asset-item"> |
|||
<span class="label">{{$t('automation.a7')}}</span> |
|||
<span class="value">{{ currentAccount.usable }} {{ currencyUnit }}</span> |
|||
</div> |
|||
<div class="asset-item"> |
|||
<span class="label">{{$t('automation.a8')}}</span> |
|||
<span class="value">{{ currentAccount.todayProfit }} {{ currencyUnit }}</span> |
|||
</div> |
|||
<div class="asset-item"> |
|||
<span class="label">{{$t('automation.a9')}}</span> |
|||
<span class="value">{{ currentAccount.totalProfit }} {{ currencyUnit }}</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="action-links"> |
|||
<span class="link-text" @click="showModal('deposit')">{{$t('automation.a10')}} ></span> |
|||
<span class="link-text" @click="showModal('withdraw')">{{$t('automation.a11')}} ></span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- ================= 底部白色区域 ================= --> |
|||
<div class="body-section"> |
|||
<!-- 内部 Tab 切换 --> |
|||
<div class="tabs"> |
|||
<div |
|||
:class="['tab-item', subTab === 'list' ? 'active' : '']" |
|||
@click="subTab = 'list'" |
|||
> |
|||
{{ mainTab === 'stock' ? $t('automation.a3') : $t('automation.a4') }} |
|||
</div> |
|||
<div |
|||
:class="['tab-item', subTab === 'history' ? 'active' : '']" |
|||
@click="subTab = 'history'" |
|||
> |
|||
{{$t('automation.a12')}} |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- 内容区: 列表 (股票或加密货币双列布局) --> |
|||
<div v-if="subTab === 'list'" class="list-view"> |
|||
<div class="list-header-container"> |
|||
<!-- 左边标题 --> |
|||
<div class="header-half"> |
|||
<span class="w-name">{{ mainTab === 'stock' ? $t('automation.a3') : $t('automation.a13') }}</span> |
|||
<span class="w-price">{{$t('automation.a14')}}</span> |
|||
<span class="w-change">{{$t('automation.a15')}}</span> |
|||
</div> |
|||
<!-- 右边标题 --> |
|||
<div class="header-half"> |
|||
<span class="w-name">{{ mainTab === 'stock' ? $t('automation.a3') : $t('automation.a13') }}</span> |
|||
<span class="w-price">{{$t('automation.a14')}}</span> |
|||
<span class="w-change">{{$t('automation.a15')}}</span> |
|||
</div> |
|||
</div> |
|||
<div class="grid-container"> |
|||
<div class="grid-card" v-for="(item, index) in currentList" :key="index"> |
|||
<div class="coin-info"> |
|||
<!-- 占位图标 --> |
|||
<div class="icon-placeholder">{{ item.symbol.charAt(0) }}</div> |
|||
<div class="name-box"> |
|||
<div class="name">{{ item.name }}</div> |
|||
<div class="symbol">{{ item.symbol }}</div> |
|||
</div> |
|||
</div> |
|||
<div class="price">{{ item.price }}</div> |
|||
<div :class="['change', item.change > 0 ? 'text-green' : 'text-red']"> |
|||
{{ item.change > 0 ? '+' : '' }}{{ item.change }}% |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- 内容区: 历史订单 --> |
|||
<div v-if="subTab === 'history'" class="history-view"> |
|||
<table class="history-table"> |
|||
<thead> |
|||
<tr> |
|||
<th>{{$t('automation.a16')}}</th> |
|||
<th>{{$t('automation.a17')}}</th> |
|||
<th>{{$t('automation.a18')}}</th> |
|||
<th>{{$t('automation.a19')}}</th> |
|||
<th>{{$t('automation.a20')}}</th> |
|||
<th>{{$t('automation.a21')}}</th> |
|||
<th>{{$t('automation.a22')}}</th> |
|||
<th>{{$t('automation.a23')}}</th> |
|||
<th>{{$t('automation.a24')}}</th> |
|||
<th class="text-right">{{$t('automation.a25')}}</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody> |
|||
<tr v-if="currentHistory.length === 0"> |
|||
<td colspan="10" class="empty-text">{{$t('automation.a26')}}</td> |
|||
</tr> |
|||
<!-- 这里可以写 v-for 渲染历史数据 --> |
|||
</tbody> |
|||
</table> |
|||
<!-- 分页占位 --> |
|||
<div class="pagination"> |
|||
<span class="arrow"><</span> |
|||
<span class="page-num">1</span> |
|||
<span class="arrow">></span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- ================= 弹窗 (存入资金) ================= --> |
|||
<div class="modal-overlay" v-if="modalType === 'deposit'"> |
|||
<div class="modal-box"> |
|||
<div class="modal-header"> |
|||
<h3>{{$t('automation.a10')}}</h3> |
|||
<span class="close-btn" @click="closeModal">×</span> |
|||
</div> |
|||
<div class="modal-body"> |
|||
<label>{{$t('automation.a27')}}</label> |
|||
<input type="number" :placeholder="$t('automation.a31')" v-model="formAmount"> |
|||
<div class="modal-tips"> |
|||
<p>{{$t('automation.a5')}}: {{ currentAccount.total }} {{ currencyUnit }}</p> |
|||
<p>{{$t('automation.a28')}}: 0.00 {{ currencyUnit }}</p> |
|||
</div> |
|||
</div> |
|||
<div class="modal-footer"> |
|||
<button class="btn-cancel" @click="closeModal">{{$t('automation.a29')}}</button> |
|||
<button class="btn-confirm" @click="confirmAction">{{$t('automation.a30')}}</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- ================= 弹窗 (提取资金) ================= --> |
|||
<div class="modal-overlay" v-if="modalType === 'withdraw'"> |
|||
<div class="modal-box"> |
|||
<div class="modal-header"> |
|||
<h3>{{$t('automation.a11')}}</h3> |
|||
<span class="close-btn" @click="closeModal">×</span> |
|||
</div> |
|||
<div class="modal-body"> |
|||
<label>{{$t('automation.a21')}}</label> |
|||
<input type="number" :placeholder="$t('automation.a31')" v-model="formAmount"> |
|||
<div class="modal-tips"> |
|||
<p>{{$t('automation.a7')}}: {{ currentAccount.usable }} {{ currencyUnit }}</p> |
|||
</div> |
|||
</div> |
|||
<div class="modal-footer"> |
|||
<button class="btn-cancel" @click="closeModal">{{$t('automation.a29')}}</button> |
|||
<button class="btn-confirm" @click="confirmAction">{{$t('automation.a30')}}</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'EaTrading', |
|||
data() { |
|||
return { |
|||
mainTab: 'stock', // 'stock' | 'crypto' |
|||
subTab: 'list', // 'list' | 'history' |
|||
modalType: '', // '' | 'deposit' | 'withdraw' |
|||
formAmount: '', |
|||
|
|||
// 账户数据 mock |
|||
accountData: { |
|||
stock: { |
|||
total: '0.00', |
|||
usable: '0.00', |
|||
todayProfit: '0.00', |
|||
totalProfit: '0.00' |
|||
}, |
|||
crypto: { |
|||
total: '209,000.00', |
|||
usable: '90,000.00', |
|||
todayProfit: '0.00', |
|||
totalProfit: '0.00' |
|||
} |
|||
}, |
|||
|
|||
// 列表数据 mock |
|||
stockList: [ |
|||
{ name: 'Micron Technology,...', symbol: 'MU', price: '996.00000', change: -7.74 }, |
|||
{ name: 'MINISO Group Hold...', symbol: 'MNSO', price: '13.31000', change: 0.30 }, |
|||
{ name: 'Nvidia Corp', symbol: 'NVDA', price: '218.66000', change: 1.82 }, |
|||
{ name: 'Invesco LTD', symbol: 'IVZ', price: '28.17000', change: 4.57 }, |
|||
{ name: 'Broadcom Inc. Com...', symbol: 'AVGO', price: '418.91000', change: -12.59 }, |
|||
{ name: 'Robert Half Inc.', symbol: 'RHI', price: '31.60000', change: 6.90 }, |
|||
], |
|||
cryptoList: [ |
|||
{ name: 'SOL/USDC', symbol: 'SOL', price: '65.89', change: -5.04 }, |
|||
{ name: 'BTC/USDC', symbol: 'BTC', price: '62,872.47', change: -1.55 }, |
|||
{ name: 'GALA/USDC', symbol: 'GALA', price: '0.00256', change: -5.17 }, |
|||
{ name: 'FIL/USDC', symbol: 'FIL', price: '0.802', change: -6.64 }, |
|||
{ name: 'GRT/USDC', symbol: 'GRT', price: '0.0205', change: -5.94 }, |
|||
{ name: 'HBAR/USDC', symbol: 'HBAR', price: '0.0815', change: -5.08 }, |
|||
], |
|||
|
|||
// 历史订单 mock (默认空数组体现截图效果) |
|||
stockHistory: [], |
|||
cryptoHistory: [] |
|||
} |
|||
}, |
|||
computed: { |
|||
currencyUnit() { |
|||
return this.mainTab === 'stock' ? 'USDT' : 'USDC'; |
|||
}, |
|||
currentAccount() { |
|||
return this.accountData[this.mainTab]; |
|||
}, |
|||
currentList() { |
|||
return this.mainTab === 'stock' ? this.stockList : this.cryptoList; |
|||
}, |
|||
currentHistory() { |
|||
return this.mainTab === 'stock' ? this.stockHistory : this.cryptoHistory; |
|||
} |
|||
}, |
|||
methods: { |
|||
switchMainTab(tab) { |
|||
this.mainTab = tab; |
|||
// 切换主分类时,可以根据需求决定是否重置子菜单,这里默认保持原样 |
|||
}, |
|||
showModal(type) { |
|||
this.modalType = type; |
|||
this.formAmount = ''; |
|||
}, |
|||
closeModal() { |
|||
this.modalType = ''; |
|||
}, |
|||
confirmAction() { |
|||
if (!this.formAmount) { |
|||
// alert('請輸入金額'); |
|||
return; |
|||
} |
|||
console.log(`${this.modalType} amount:`, this.formAmount); |
|||
// 调用你的后端接口逻辑... |
|||
this.closeModal(); |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
/* 基础重置与变量 */ |
|||
.ea-trading-container { |
|||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; |
|||
color: #333; |
|||
/* background-color: #f5f5f5; */ |
|||
min-height: 100vh; |
|||
} |
|||
|
|||
/* ================= 顶部黑色区域 ================= */ |
|||
.header-section { |
|||
background-color: #000; |
|||
color: #fff; |
|||
padding: 100px 0; |
|||
} |
|||
.header-content { |
|||
max-width: 1200px; |
|||
margin: 0 auto; |
|||
display: flex; |
|||
justify-content: space-between; |
|||
padding: 0 20px; |
|||
} |
|||
.title { |
|||
font-size: 28px; |
|||
margin: 0 0 10px 0; |
|||
} |
|||
.subtitle { |
|||
font-size: 14px; |
|||
color: #aaa; |
|||
margin: 0 0 30px 0; |
|||
} |
|||
.toggle-btns { |
|||
display: flex; |
|||
gap: 10px; |
|||
} |
|||
.btn-toggle { |
|||
background-color: #2c2d31; |
|||
color: #aaa; |
|||
border: none; |
|||
padding: 10px 24px; |
|||
border-radius: 6px; |
|||
cursor: pointer; |
|||
font-size: 14px; |
|||
transition: all 0.3s; |
|||
} |
|||
.btn-toggle.active { |
|||
background-color: #fff; |
|||
color: #000; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.header-right { |
|||
width: 500px; |
|||
} |
|||
.asset-grid { |
|||
display: grid; |
|||
grid-template-columns: 1fr 1fr 1fr; |
|||
row-gap: 20px; |
|||
margin-bottom: 20px; |
|||
} |
|||
.asset-item { |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
.asset-item.text-right { |
|||
align-items: flex-end; |
|||
} |
|||
.asset-item .label { |
|||
font-size: 12px; |
|||
color: #aaa; |
|||
margin-bottom: 5px; |
|||
} |
|||
.asset-item .value { |
|||
font-size: 16px; |
|||
font-weight: 500; |
|||
} |
|||
.link-text { |
|||
font-size: 13px; |
|||
color: #aaa; |
|||
cursor: pointer; |
|||
transition: color 0.3s; |
|||
} |
|||
.link-text:hover { |
|||
color: #fff; |
|||
} |
|||
.action-links { |
|||
display: flex; |
|||
gap: 40px; |
|||
} |
|||
|
|||
/* ================= 底部白色区域 ================= */ |
|||
.body-section { |
|||
max-width: 1200px; |
|||
margin: 0 auto; |
|||
padding: 30px 20px; |
|||
background-color: #fff; |
|||
min-height: 500px; |
|||
} |
|||
.tabs { |
|||
display: flex; |
|||
border-bottom: 1px solid #eee; |
|||
margin-bottom: 20px; |
|||
} |
|||
.tab-item { |
|||
padding: 10px 20px; |
|||
cursor: pointer; |
|||
font-size: 16px; |
|||
color: #888; |
|||
border-bottom: 2px solid transparent; |
|||
} |
|||
.tab-item.active { |
|||
color: #000; |
|||
font-weight: bold; |
|||
border-bottom: 2px solid #000; |
|||
} |
|||
|
|||
/* 列表视图布局 */ |
|||
.list-header-container { |
|||
display: grid; |
|||
grid-template-columns: 1fr 1fr; /* 和数据列表一样的双列 */ |
|||
gap: 20px; /* 保持中间有间距 */ |
|||
margin-bottom: 10px; |
|||
} |
|||
.header-half { |
|||
display: flex; |
|||
padding: 10px; |
|||
color: #999; |
|||
font-size: 13px; |
|||
background: #f9f9f9; |
|||
} |
|||
.w-name { flex: 2; } |
|||
.w-price { flex: 1; text-align: right; } |
|||
.w-change { flex: 1; text-align: right; } |
|||
|
|||
.grid-container { |
|||
display: grid; |
|||
grid-template-columns: 1fr 1fr; /* 双列布局 */ |
|||
gap: 20px; |
|||
} |
|||
.grid-card { |
|||
display: flex; |
|||
align-items: center; |
|||
padding: 15px 10px; |
|||
border-bottom: 1px solid #f0f0f0; |
|||
} |
|||
.coin-info { |
|||
flex: 2; |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 10px; |
|||
} |
|||
.icon-placeholder { |
|||
width: 30px; |
|||
height: 30px; |
|||
background-color: #2962ff; |
|||
color: #fff; |
|||
border-radius: 50%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
font-size: 14px; |
|||
font-weight: bold; |
|||
} |
|||
.name-box .name { |
|||
font-size: 14px; |
|||
font-weight: 500; |
|||
color: #333; |
|||
} |
|||
.name-box .symbol { |
|||
font-size: 12px; |
|||
color: #999; |
|||
} |
|||
.price { |
|||
flex: 1; |
|||
text-align: right; |
|||
font-size: 14px; |
|||
} |
|||
.change { |
|||
flex: 1; |
|||
text-align: right; |
|||
font-size: 14px; |
|||
} |
|||
.text-green { color: #0ecb81; } |
|||
.text-red { color: #f6465d; } |
|||
|
|||
/* 历史记录表格 */ |
|||
.history-table { |
|||
width: 100%; |
|||
border-collapse: collapse; |
|||
font-size: 13px; |
|||
} |
|||
.history-table th { |
|||
background: #f9f9f9; |
|||
color: #999; |
|||
font-weight: normal; |
|||
padding: 12px; |
|||
text-align: left; |
|||
} |
|||
.history-table td { |
|||
padding: 15px 12px; |
|||
border-bottom: 1px solid #eee; |
|||
} |
|||
.text-right { |
|||
text-align: right !important; |
|||
} |
|||
.empty-text { |
|||
text-align: center !important; |
|||
color: #999; |
|||
padding: 40px !important; |
|||
} |
|||
|
|||
/* 分页 */ |
|||
.pagination { |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
margin-top: 30px; |
|||
gap: 15px; |
|||
} |
|||
.pagination .page-num { |
|||
padding: 5px 12px; |
|||
border: 1px solid #ddd; |
|||
border-radius: 4px; |
|||
} |
|||
.pagination .arrow { |
|||
cursor: pointer; |
|||
color: #666; |
|||
} |
|||
|
|||
/* ================= 弹窗样式 ================= */ |
|||
.modal-overlay { |
|||
position: fixed; |
|||
top: 0; left: 0; width: 100%; height: 100%; |
|||
background: rgba(0, 0, 0, 0.6); |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
z-index: 999; |
|||
} |
|||
.modal-box { |
|||
background: #fff; |
|||
width: 400px; |
|||
border-radius: 8px; |
|||
overflow: hidden; |
|||
box-shadow: 0 4px 12px rgba(0,0,0,0.15); |
|||
} |
|||
.modal-header { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
padding: 20px; |
|||
} |
|||
.modal-header h3 { |
|||
margin: 0; |
|||
font-size: 16px; |
|||
} |
|||
.close-btn { |
|||
font-size: 24px; |
|||
color: #999; |
|||
cursor: pointer; |
|||
} |
|||
.modal-body { |
|||
padding: 0 20px; |
|||
} |
|||
.modal-body label { |
|||
display: block; |
|||
font-size: 13px; |
|||
color: #666; |
|||
margin-bottom: 8px; |
|||
} |
|||
.modal-body input { |
|||
width: 100%; |
|||
padding: 10px; |
|||
border: 1px solid #ddd; |
|||
border-radius: 4px; |
|||
box-sizing: border-box; |
|||
font-size: 14px; |
|||
} |
|||
.modal-tips { |
|||
margin-top: 15px; |
|||
font-size: 12px; |
|||
color: #999; |
|||
line-height: 1.8; |
|||
} |
|||
.modal-tips p { margin: 0; } |
|||
.modal-footer { |
|||
display: flex; |
|||
gap: 10px; |
|||
padding: 20px; |
|||
margin-top: 10px; |
|||
} |
|||
.btn-cancel, .btn-confirm { |
|||
flex: 1; |
|||
padding: 12px; |
|||
border: none; |
|||
border-radius: 4px; |
|||
cursor: pointer; |
|||
font-size: 14px; |
|||
} |
|||
.btn-cancel { |
|||
background: #f5f5f5; |
|||
color: #333; |
|||
} |
|||
.btn-confirm { |
|||
background: #000; |
|||
color: #fff; |
|||
} |
|||
</style> |
|||
Loading…
Reference in new issue