Initial commit: Monisuo - 虚拟货币模拟交易平台
功能模块: - 用户注册/登录/KYC - 资金账户/交易账户 - 实时行情/币种管理 - 即时交易/充提审核 - 管理后台 技术栈: - 后端: SpringBoot 2.2.4 + MyBatis Plus - 前端: uni-app x (Vue3 + UTS) - 数据库: MySQL Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
305
app/pages/index/index.uvue
Normal file
305
app/pages/index/index.uvue
Normal file
@@ -0,0 +1,305 @@
|
||||
<template>
|
||||
<view class="index-container">
|
||||
<!-- 资产概览卡片 -->
|
||||
<view class="asset-card">
|
||||
<text class="asset-label">总资产(USDT)</text>
|
||||
<text class="asset-value">{{ totalAsset }}</text>
|
||||
<view class="asset-row">
|
||||
<view class="asset-item">
|
||||
<text class="asset-item-label">资金账户</text>
|
||||
<text class="asset-item-value">{{ fundBalance }}</text>
|
||||
</view>
|
||||
<view class="asset-item">
|
||||
<text class="asset-item-label">交易账户</text>
|
||||
<text class="asset-item-value">{{ tradeBalance }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 快捷操作 -->
|
||||
<view class="quick-actions">
|
||||
<view class="action-item" @click="goToRecharge">
|
||||
<text class="action-icon">充</text>
|
||||
<text class="action-text">充值</text>
|
||||
</view>
|
||||
<view class="action-item" @click="goToWithdraw">
|
||||
<text class="action-icon">提</text>
|
||||
<text class="action-text">提现</text>
|
||||
</view>
|
||||
<view class="action-item" @click="goToTransfer">
|
||||
<text class="action-icon">转</text>
|
||||
<text class="action-text">划转</text>
|
||||
</view>
|
||||
<view class="action-item" @click="goToTrade">
|
||||
<text class="action-icon">币</text>
|
||||
<text class="action-text">交易</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 持仓列表 -->
|
||||
<view class="holding-section">
|
||||
<text class="section-title">我的持仓</text>
|
||||
<view class="holding-list">
|
||||
<view class="holding-item" v-for="(item, index) in holdings" :key="index">
|
||||
<view class="holding-info">
|
||||
<text class="coin-code">{{ item.coinCode }}</text>
|
||||
<text class="coin-quantity">{{ item.quantity }}</text>
|
||||
</view>
|
||||
<view class="holding-value">
|
||||
<text class="value-text">{{ item.value }} USDT</text>
|
||||
<text :class="['profit-text', item.profit >= 0 ? 'up' : 'down']">
|
||||
{{ item.profit >= 0 ? '+' : '' }}{{ item.profit }}%
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="empty-hint" v-if="holdings.length === 0">
|
||||
<text class="empty-text">暂无持仓</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="uts">
|
||||
import { getAssetOverview, getTradeAccounts } from '@/api/asset.uts'
|
||||
|
||||
type HoldingItem = {
|
||||
coinCode: string
|
||||
quantity: string
|
||||
value: string
|
||||
profit: number
|
||||
}
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
totalAsset: '0.00' as string,
|
||||
fundBalance: '0.00' as string,
|
||||
tradeBalance: '0.00' as string,
|
||||
holdings: [] as HoldingItem[]
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.loadAssetData()
|
||||
},
|
||||
methods: {
|
||||
async loadAssetData() {
|
||||
try {
|
||||
const res = await getAssetOverview()
|
||||
const data = res.data
|
||||
this.totalAsset = this.formatAmount(data['totalAsset'] as number)
|
||||
this.fundBalance = this.formatAmount(data['fundBalance'] as number)
|
||||
this.tradeBalance = this.formatAmount(data['tradeBalance'] as number)
|
||||
|
||||
// 加载持仓
|
||||
const tradeRes = await getTradeAccounts()
|
||||
const list = tradeRes.data['list'] as any[]
|
||||
this.holdings = []
|
||||
if (list !== null && list.length > 0) {
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
const item = list[i]
|
||||
const qty = item['quantity'] as number
|
||||
if (qty > 0) {
|
||||
this.holdings.push({
|
||||
coinCode: item['coinCode'] as string,
|
||||
quantity: qty.toFixed(6),
|
||||
value: (item['totalValue'] as number).toFixed(2),
|
||||
profit: item['profitRate'] as number
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('加载资产数据失败', e)
|
||||
}
|
||||
},
|
||||
formatAmount(value: number): string {
|
||||
if (value === null || value === undefined) {
|
||||
return '0.00'
|
||||
}
|
||||
return value.toFixed(2)
|
||||
},
|
||||
goToRecharge() {
|
||||
uni.navigateTo({ url: '/pages/asset/asset?action=deposit' })
|
||||
},
|
||||
goToWithdraw() {
|
||||
uni.navigateTo({ url: '/pages/asset/asset?action=withdraw' })
|
||||
},
|
||||
goToTransfer() {
|
||||
uni.navigateTo({ url: '/pages/asset/asset?action=transfer' })
|
||||
},
|
||||
goToTrade() {
|
||||
uni.switchTab({ url: '/pages/trade/trade' })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.index-container {
|
||||
min-height: 100vh;
|
||||
background: $bg-color-dark;
|
||||
padding: $spacing-base;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.asset-card {
|
||||
background: linear-gradient(135deg, $primary-color 0%, $primary-color-dark 100%);
|
||||
border-radius: $border-radius-lg;
|
||||
padding: $spacing-lg;
|
||||
margin-bottom: $spacing-lg;
|
||||
}
|
||||
|
||||
.asset-label {
|
||||
font-size: $font-size-base;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
display: block;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.asset-value {
|
||||
font-size: 56rpx;
|
||||
font-weight: bold;
|
||||
color: #FFFFFF;
|
||||
display: block;
|
||||
margin-bottom: $spacing-base;
|
||||
}
|
||||
|
||||
.asset-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.asset-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.asset-item-label {
|
||||
font-size: $font-size-sm;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.asset-item-value {
|
||||
font-size: $font-size-lg;
|
||||
color: #FFFFFF;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.quick-actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
background: $bg-color-card;
|
||||
border-radius: $border-radius-lg;
|
||||
padding: $spacing-base;
|
||||
margin-bottom: $spacing-lg;
|
||||
}
|
||||
|
||||
.action-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.action-icon {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
background: rgba(0, 212, 170, 0.2);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: $font-size-lg;
|
||||
color: $primary-color;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.action-text {
|
||||
font-size: $font-size-sm;
|
||||
color: $text-color;
|
||||
}
|
||||
|
||||
.holding-section {
|
||||
background: $bg-color-card;
|
||||
border-radius: $border-radius-lg;
|
||||
padding: $spacing-base;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: $font-size-lg;
|
||||
color: $text-color;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
margin-bottom: $spacing-base;
|
||||
}
|
||||
|
||||
.holding-list {
|
||||
min-height: 100rpx;
|
||||
}
|
||||
|
||||
.holding-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: $spacing-base 0;
|
||||
border-bottom: 1rpx solid $border-color;
|
||||
}
|
||||
|
||||
.holding-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.holding-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.coin-code {
|
||||
font-size: $font-size-lg;
|
||||
color: $text-color;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.coin-quantity {
|
||||
font-size: $font-size-sm;
|
||||
color: $text-color-secondary;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.holding-value {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.value-text {
|
||||
font-size: $font-size-base;
|
||||
color: $text-color;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.profit-text {
|
||||
font-size: $font-size-sm;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.profit-text.up {
|
||||
color: $up-color;
|
||||
}
|
||||
|
||||
.profit-text.down {
|
||||
color: $down-color;
|
||||
}
|
||||
|
||||
.empty-hint {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100rpx;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: $font-size-base;
|
||||
color: $text-color-secondary;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user