372 lines
8.8 KiB
Vue
372 lines
8.8 KiB
Vue
<template>
|
|
<view class="stock-home-container">
|
|
<!-- 顶部用户信息栏 -->
|
|
<view class="user-header">
|
|
<view class="user-info">
|
|
<image class="avatar" src="/static/images/avatar.png" mode="aspectFill"></image>
|
|
<view class="user-details">
|
|
<text class="username">Welcome, {{userName}}</text>
|
|
<text class="account-id">Account ID: {{accountId}}</text>
|
|
</view>
|
|
</view>
|
|
<view class="account-summary">
|
|
<text class="total-assets">${{formatNumber(totalAssets)}}</text>
|
|
<text class="asset-change" :class="{'positive': dailyChange >= 0, 'negative': dailyChange < 0}">
|
|
{{dailyChange >= 0 ? '+' : ''}}{{formatNumber(dailyChange)}} ({{dailyChangePercent >= 0 ? '+' : ''}}{{dailyChangePercent}}%)
|
|
</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 主要功能入口 -->
|
|
<view class="quick-actions">
|
|
<view class="action-item" @click="navigateTo('trade')">
|
|
<image src="/static/icons/trade.png"></image>
|
|
<text>Trade</text>
|
|
</view>
|
|
<view class="action-item" @click="navigateTo('deposit')">
|
|
<image src="/static/icons/deposit.png"></image>
|
|
<text>Deposit</text>
|
|
</view>
|
|
<view class="action-item" @click="navigateTo('withdraw')">
|
|
<image src="/static/icons/withdraw.png"></image>
|
|
<text>Withdraw</text>
|
|
</view>
|
|
<view class="action-item" @click="navigateTo('transfer')">
|
|
<image src="/static/icons/transfer.png"></image>
|
|
<text>Transfer</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 自选股票列表 -->
|
|
<view class="watchlist-section">
|
|
<view class="section-header">
|
|
<text class="section-title">Watchlist</text>
|
|
<text class="section-more" @click="navigateTo('watchlist')">More ></text>
|
|
</view>
|
|
<scroll-view scroll-x class="stock-scroll">
|
|
<view class="stock-card" v-for="(stock, index) in watchlist" :key="index" @click="viewStockDetail(stock)">
|
|
<text class="stock-symbol">{{stock.symbol}}</text>
|
|
<text class="stock-name">{{stock.name}}</text>
|
|
<text class="stock-price">${{stock.price}}</text>
|
|
<text class="stock-change" :class="{'positive': stock.change >= 0, 'negative': stock.change < 0}">
|
|
{{stock.change >= 0 ? '+' : ''}}{{stock.change}}%
|
|
</text>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
|
|
<!-- 市场指数 -->
|
|
<view class="market-indices">
|
|
<view class="section-header">
|
|
<text class="section-title">Market Indices</text>
|
|
<text class="section-more" @click="navigateTo('markets')">More ></text>
|
|
</view>
|
|
<view class="indices-container">
|
|
<view class="index-item" v-for="(index, i) in marketIndices" :key="i">
|
|
<text class="index-name">{{index.name}}</text>
|
|
<text class="index-value">{{index.value}}</text>
|
|
<text class="index-change" :class="{'positive': index.change >= 0, 'negative': index.change < 0}">
|
|
{{index.change >= 0 ? '+' : ''}}{{index.change}}%
|
|
</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 新闻资讯 -->
|
|
<view class="news-section">
|
|
<view class="section-header">
|
|
<text class="section-title">Market News</text>
|
|
<text class="section-more" @click="navigateTo('news')">More ></text>
|
|
</view>
|
|
<view class="news-list">
|
|
<view class="news-item" v-for="(news, idx) in marketNews" :key="idx" @click="viewNewsDetail(news)">
|
|
<image class="news-image" :src="news.imageUrl" mode="aspectFill"></image>
|
|
<view class="news-content">
|
|
<text class="news-title">{{news.title}}</text>
|
|
<text class="news-time">{{formatTime(news.time)}}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
data() {
|
|
return {
|
|
userName: "John Doe",
|
|
accountId: "EU20230001",
|
|
totalAssets: 125430.56,
|
|
dailyChange: 1254.32,
|
|
dailyChangePercent: 1.01,
|
|
watchlist: [
|
|
{ symbol: "AAPL", name: "Apple Inc.", price: 175.34, change: 1.23 },
|
|
{ symbol: "MSFT", name: "Microsoft", price: 328.39, change: 0.56 },
|
|
{ symbol: "TSLA", name: "Tesla", price: 260.54, change: -2.34 },
|
|
{ symbol: "AMZN", name: "Amazon", price: 134.56, change: 0.89 },
|
|
{ symbol: "GOOGL", name: "Alphabet", price: 125.67, change: -0.45 }
|
|
],
|
|
marketIndices: [
|
|
{ name: "S&P 500", value: 4524.09, change: 0.42 },
|
|
{ name: "NASDAQ", value: 14019.31, change: 0.85 },
|
|
{ name: "Dow 30", value: 34721.12, change: -0.12 },
|
|
{ name: "FTSE 100", value: 7527.53, change: 0.23 }
|
|
],
|
|
marketNews: [
|
|
{
|
|
title: "Fed signals more rate hikes to combat inflation",
|
|
imageUrl: "/static/images/news1.jpg",
|
|
time: "2023-06-15T09:30:00Z"
|
|
},
|
|
{
|
|
title: "Tech stocks rally as AI boom continues",
|
|
imageUrl: "/static/images/news2.jpg",
|
|
time: "2023-06-15T08:45:00Z"
|
|
},
|
|
{
|
|
title: "European markets open higher amid positive earnings",
|
|
imageUrl: "/static/images/news3.jpg",
|
|
time: "2023-06-15T07:15:00Z"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
methods: {
|
|
// formatNumber(num) {
|
|
// return num.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
|
// },
|
|
// formatTime(timeString) {
|
|
// const date = new Date(timeString);
|
|
// return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
|
// },
|
|
// navigateTo(page) {
|
|
// uni.navigateTo({
|
|
// url: `/pages/${page}/${page}`
|
|
// });
|
|
// },
|
|
// viewStockDetail(stock) {
|
|
// uni.navigateTo({
|
|
// url: `/pages/stock/detail?symbol=${stock.symbol}`
|
|
// });
|
|
// },
|
|
// viewNewsDetail(news) {
|
|
// uni.navigateTo({
|
|
// url: `/pages/news/detail?title=${encodeURIComponent(news.title)}`
|
|
// });
|
|
// }
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.stock-home-container {
|
|
padding: 20rpx;
|
|
background-color: #f5f5f5;
|
|
min-height: 100vh;
|
|
padding-bottom: 120rpx; /* 给底部导航留空间 */
|
|
}
|
|
|
|
.user-header {
|
|
background: linear-gradient(135deg, #1976D2, #2196F3);
|
|
border-radius: 16rpx;
|
|
padding: 30rpx;
|
|
color: white;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.user-info {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.avatar {
|
|
width: 100rpx;
|
|
height: 100rpx;
|
|
border-radius: 50%;
|
|
margin-right: 20rpx;
|
|
}
|
|
|
|
.user-details {
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.username {
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.account-id {
|
|
font-size: 24rpx;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.account-summary {
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.total-assets {
|
|
font-size: 48rpx;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.asset-change {
|
|
font-size: 28rpx;
|
|
}
|
|
|
|
.positive {
|
|
color: #4CAF50;
|
|
}
|
|
|
|
.negative {
|
|
color: #F44336;
|
|
}
|
|
|
|
.quick-actions {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
background-color: white;
|
|
border-radius: 16rpx;
|
|
padding: 20rpx;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.action-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
|
|
.action-item image {
|
|
width: 60rpx;
|
|
height: 60rpx;
|
|
margin-bottom: 10rpx;
|
|
}
|
|
|
|
.action-item text {
|
|
font-size: 24rpx;
|
|
}
|
|
|
|
.section-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin: 30rpx 0 20rpx;
|
|
}
|
|
|
|
.section-title {
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.section-more {
|
|
font-size: 26rpx;
|
|
color: #1976D2;
|
|
}
|
|
|
|
.stock-scroll {
|
|
white-space: nowrap;
|
|
width: 100%;
|
|
}
|
|
|
|
.stock-card {
|
|
display: inline-block;
|
|
background-color: white;
|
|
border-radius: 12rpx;
|
|
padding: 20rpx;
|
|
margin-right: 20rpx;
|
|
width: 200rpx;
|
|
}
|
|
|
|
.stock-symbol {
|
|
font-size: 28rpx;
|
|
font-weight: bold;
|
|
display: block;
|
|
}
|
|
|
|
.stock-name {
|
|
font-size: 24rpx;
|
|
color: #666;
|
|
display: block;
|
|
margin: 10rpx 0;
|
|
}
|
|
|
|
.stock-price {
|
|
font-size: 28rpx;
|
|
font-weight: bold;
|
|
display: block;
|
|
}
|
|
|
|
.stock-change {
|
|
font-size: 24rpx;
|
|
display: block;
|
|
}
|
|
|
|
.indices-container {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.index-item {
|
|
background-color: white;
|
|
border-radius: 12rpx;
|
|
padding: 20rpx;
|
|
width: 48%;
|
|
margin-bottom: 15rpx;
|
|
}
|
|
|
|
.index-name {
|
|
font-size: 26rpx;
|
|
color: #666;
|
|
}
|
|
|
|
.index-value {
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
margin: 10rpx 0;
|
|
display: block;
|
|
}
|
|
|
|
.news-list {
|
|
background-color: white;
|
|
border-radius: 16rpx;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.news-item {
|
|
display: flex;
|
|
padding: 20rpx;
|
|
border-bottom: 1rpx solid #eee;
|
|
}
|
|
|
|
.news-image {
|
|
width: 160rpx;
|
|
height: 120rpx;
|
|
border-radius: 8rpx;
|
|
margin-right: 20rpx;
|
|
}
|
|
|
|
.news-content {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.news-title {
|
|
font-size: 28rpx;
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 2;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.news-time {
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
}
|
|
</style> |