|
|
@@ -6,49 +6,55 @@
|
|
|
<text class="back-icon">←</text>
|
|
|
</view>
|
|
|
<view class="navbar-title">
|
|
|
- <text class="title-text">交易记录</text>
|
|
|
+ <text class="title-text">订阅记录</text>
|
|
|
</view>
|
|
|
<view class="navbar-placeholder"></view>
|
|
|
</view>
|
|
|
|
|
|
- <!-- 交易记录列表 -->
|
|
|
+ <!-- 订阅记录列表 -->
|
|
|
<scroll-view class="scroll-view" scroll-y>
|
|
|
- <view class="transaction-list">
|
|
|
- <!-- 按日期分组显示 -->
|
|
|
- <view v-for="(group, dateKey) in groupedTransactions" :key="dateKey" class="date-group">
|
|
|
- <view class="date-header">
|
|
|
- <text class="date-text">{{ dateKey }}</text>
|
|
|
+ <view class="subscription-list">
|
|
|
+ <!-- 订阅记录项 -->
|
|
|
+ <view
|
|
|
+ v-for="(item, index) in subscriptions"
|
|
|
+ :key="index"
|
|
|
+ class="subscription-item"
|
|
|
+ >
|
|
|
+ <view class="item-header">
|
|
|
+ <view class="pool-info">
|
|
|
+ <text class="pool-icon">{{ item.poolType === 'pool' ? '⚡' : '📈' }}</text>
|
|
|
+ <text class="pool-name">{{ item.poolName }}</text>
|
|
|
+ </view>
|
|
|
+ <view :class="['status-badge', item.isActive ? 'status-active' : 'status-expired']">
|
|
|
+ <text class="status-text">{{ item.isActive ? '生效中' : '已过期' }}</text>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
|
|
|
- <view
|
|
|
- v-for="(item, index) in group"
|
|
|
- :key="index"
|
|
|
- class="transaction-item"
|
|
|
- >
|
|
|
- <view class="item-left">
|
|
|
- <view class="stock-info">
|
|
|
- <text class="stock-name">{{ item.stockName }}</text>
|
|
|
- <text class="stock-code">{{ item.stockCode }}</text>
|
|
|
- </view>
|
|
|
- <text class="transaction-time">{{ formatTime(item.timestamp) }}</text>
|
|
|
+ <view class="item-body">
|
|
|
+ <view class="info-row">
|
|
|
+ <text class="info-label">订阅方案:</text>
|
|
|
+ <text class="info-value">{{ item.planName }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="info-row">
|
|
|
+ <text class="info-label">订阅金额:</text>
|
|
|
+ <text class="info-value price">¥{{ item.amount }}</text>
|
|
|
</view>
|
|
|
-
|
|
|
- <view class="item-right">
|
|
|
- <text :class="['amount-text', item.type === 'buy' ? 'amount-buy' : 'amount-sell']">
|
|
|
- {{ item.type === 'buy' ? '-' : '+' }}¥{{ formatAmount(item.totalAmount) }}
|
|
|
- </text>
|
|
|
- <view :class="['status-badge', item.type === 'buy' ? 'status-buy' : 'status-sell']">
|
|
|
- <text class="status-text">{{ item.type === 'buy' ? '买入' : '卖出' }}</text>
|
|
|
- </view>
|
|
|
+ <view class="info-row">
|
|
|
+ <text class="info-label">购买时间:</text>
|
|
|
+ <text class="info-value">{{ formatDateTime(item.purchaseTime) }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="info-row">
|
|
|
+ <text class="info-label">到期时间:</text>
|
|
|
+ <text class="info-value">{{ formatDateTime(item.expireTime) }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<!-- 空状态 -->
|
|
|
- <view v-if="transactions.length === 0" class="empty-state">
|
|
|
+ <view v-if="subscriptions.length === 0" class="empty-state">
|
|
|
<text class="empty-icon">📋</text>
|
|
|
- <text class="empty-text">暂无交易记录</text>
|
|
|
- <text class="empty-desc">开始您的模拟交易之旅吧</text>
|
|
|
+ <text class="empty-text">暂无订阅记录</text>
|
|
|
+ <text class="empty-desc">前往超短池或强势池订阅服务</text>
|
|
|
</view>
|
|
|
|
|
|
<!-- 底部安全区域 -->
|
|
|
@@ -60,8 +66,17 @@
|
|
|
|
|
|
<script setup>
|
|
|
import { ref, computed, onMounted } from 'vue'
|
|
|
+import { onLoad, onShow } from '@dcloudio/uni-app'
|
|
|
+import { isLoggedIn as checkLoginStatus } from '../../utils/auth.js'
|
|
|
+
|
|
|
+const subscriptions = ref([])
|
|
|
+const isLoggedIn = ref(false)
|
|
|
|
|
|
-const transactions = ref([])
|
|
|
+// 检查登录状态
|
|
|
+const checkLogin = () => {
|
|
|
+ isLoggedIn.value = checkLoginStatus()
|
|
|
+ console.log('[订阅记录] 登录状态:', isLoggedIn.value)
|
|
|
+}
|
|
|
|
|
|
// 返回上一页
|
|
|
const handleBack = () => {
|
|
|
@@ -77,83 +92,71 @@ const handleBack = () => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// 按日期分组的交易记录
|
|
|
-const groupedTransactions = computed(() => {
|
|
|
- const groups = {}
|
|
|
-
|
|
|
- transactions.value.forEach(item => {
|
|
|
- const dateKey = formatDate(item.timestamp)
|
|
|
- if (!groups[dateKey]) {
|
|
|
- groups[dateKey] = []
|
|
|
- }
|
|
|
- groups[dateKey].push(item)
|
|
|
- })
|
|
|
-
|
|
|
- return groups
|
|
|
-})
|
|
|
-
|
|
|
-// 格式化日期(用于分组)
|
|
|
-const formatDate = (timestamp) => {
|
|
|
- const date = new Date(timestamp)
|
|
|
- const today = new Date()
|
|
|
- const yesterday = new Date(today)
|
|
|
- yesterday.setDate(yesterday.getDate() - 1)
|
|
|
-
|
|
|
- const dateStr = date.toLocaleDateString('zh-CN', {
|
|
|
- year: 'numeric',
|
|
|
- month: '2-digit',
|
|
|
- day: '2-digit'
|
|
|
- })
|
|
|
-
|
|
|
- const todayStr = today.toLocaleDateString('zh-CN', {
|
|
|
- year: 'numeric',
|
|
|
- month: '2-digit',
|
|
|
- day: '2-digit'
|
|
|
- })
|
|
|
-
|
|
|
- const yesterdayStr = yesterday.toLocaleDateString('zh-CN', {
|
|
|
- year: 'numeric',
|
|
|
- month: '2-digit',
|
|
|
- day: '2-digit'
|
|
|
- })
|
|
|
-
|
|
|
- if (dateStr === todayStr) {
|
|
|
- return '今天'
|
|
|
- } else if (dateStr === yesterdayStr) {
|
|
|
- return '昨天'
|
|
|
- } else {
|
|
|
- return dateStr
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 格式化金额
|
|
|
-const formatAmount = (amount) => {
|
|
|
- return amount.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
|
|
|
-}
|
|
|
-
|
|
|
-// 格式化时间(仅显示时分秒)
|
|
|
-const formatTime = (timestamp) => {
|
|
|
+// 格式化日期时间
|
|
|
+const formatDateTime = (timestamp) => {
|
|
|
const date = new Date(timestamp)
|
|
|
+ const year = date.getFullYear()
|
|
|
+ const month = String(date.getMonth() + 1).padStart(2, '0')
|
|
|
+ const day = String(date.getDate()).padStart(2, '0')
|
|
|
const hours = String(date.getHours()).padStart(2, '0')
|
|
|
const minutes = String(date.getMinutes()).padStart(2, '0')
|
|
|
|
|
|
- return `${hours}:${minutes}`
|
|
|
+ return `${year}-${month}-${day} ${hours}:${minutes}`
|
|
|
}
|
|
|
|
|
|
-// 加载交易记录
|
|
|
-const loadTransactions = () => {
|
|
|
+// 加载订阅记录
|
|
|
+const loadSubscriptions = () => {
|
|
|
try {
|
|
|
- const storedTransactions = uni.getStorageSync('simulated_transactions') || []
|
|
|
- // 按时间倒序排列
|
|
|
- transactions.value = storedTransactions.sort((a, b) => b.timestamp - a.timestamp)
|
|
|
+ const now = Date.now()
|
|
|
+ const allSubscriptions = []
|
|
|
+
|
|
|
+ // 加载超短池订阅记录
|
|
|
+ const poolPurchase = uni.getStorageSync('pool_purchase')
|
|
|
+ if (poolPurchase) {
|
|
|
+ allSubscriptions.push({
|
|
|
+ poolType: 'pool',
|
|
|
+ poolName: '超短精选池',
|
|
|
+ planName: poolPurchase.plan === 'daily' ? '日订阅' : '周套餐',
|
|
|
+ amount: poolPurchase.plan === 'daily' ? '18' : '98',
|
|
|
+ purchaseTime: poolPurchase.purchaseTime,
|
|
|
+ expireTime: poolPurchase.expireTime,
|
|
|
+ isActive: now < poolPurchase.expireTime
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 加载强势池订阅记录
|
|
|
+ const strongPurchase = uni.getStorageSync('strong_pool_purchase')
|
|
|
+ if (strongPurchase) {
|
|
|
+ allSubscriptions.push({
|
|
|
+ poolType: 'strong',
|
|
|
+ poolName: '强势趋势池',
|
|
|
+ planName: '年订阅',
|
|
|
+ amount: '98',
|
|
|
+ purchaseTime: strongPurchase.purchaseTime,
|
|
|
+ expireTime: strongPurchase.expireTime,
|
|
|
+ isActive: now < strongPurchase.expireTime
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 按购买时间倒序排列
|
|
|
+ subscriptions.value = allSubscriptions.sort((a, b) => b.purchaseTime - a.purchaseTime)
|
|
|
} catch (e) {
|
|
|
- console.error('加载交易记录失败:', e)
|
|
|
- transactions.value = []
|
|
|
+ console.error('加载订阅记录失败:', e)
|
|
|
+ subscriptions.value = []
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+onLoad(() => {
|
|
|
+ checkLogin()
|
|
|
+})
|
|
|
+
|
|
|
onMounted(() => {
|
|
|
- loadTransactions()
|
|
|
+ loadSubscriptions()
|
|
|
+})
|
|
|
+
|
|
|
+onShow(() => {
|
|
|
+ checkLogin()
|
|
|
+ loadSubscriptions()
|
|
|
})
|
|
|
</script>
|
|
|
|
|
|
@@ -198,132 +201,103 @@ onMounted(() => {
|
|
|
|
|
|
.title-text {
|
|
|
font-size: 36rpx;
|
|
|
- font-weight: 800;
|
|
|
- color: #3F51F7;
|
|
|
- letter-spacing: 2rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #222222;
|
|
|
}
|
|
|
|
|
|
.navbar-placeholder {
|
|
|
width: 80rpx;
|
|
|
}
|
|
|
|
|
|
-/* 交易记录列表 */
|
|
|
+/* 订阅记录列表 */
|
|
|
.scroll-view {
|
|
|
flex: 1;
|
|
|
height: 0;
|
|
|
}
|
|
|
|
|
|
-.transaction-list {
|
|
|
- padding: 0 0 32rpx;
|
|
|
-}
|
|
|
-
|
|
|
-/* 日期分组 */
|
|
|
-.date-group {
|
|
|
- margin-bottom: 32rpx;
|
|
|
-}
|
|
|
-
|
|
|
-.date-header {
|
|
|
- padding: 24rpx 32rpx 16rpx;
|
|
|
-}
|
|
|
-
|
|
|
-.date-text {
|
|
|
- font-size: 26rpx;
|
|
|
- color: #9ca2b5;
|
|
|
- font-weight: 500;
|
|
|
+.subscription-list {
|
|
|
+ padding: 32rpx;
|
|
|
}
|
|
|
|
|
|
-/* 交易项 */
|
|
|
-.transaction-item {
|
|
|
+.subscription-item {
|
|
|
background: #ffffff;
|
|
|
+ border-radius: 24rpx;
|
|
|
padding: 32rpx;
|
|
|
+ margin-bottom: 24rpx;
|
|
|
+ box-shadow: 0 8rpx 24rpx rgba(37, 52, 94, 0.08);
|
|
|
+}
|
|
|
+
|
|
|
+.item-header {
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: center;
|
|
|
- border-bottom: 1rpx solid #f5f6fb;
|
|
|
-}
|
|
|
-
|
|
|
-.transaction-item:first-child {
|
|
|
- border-top-left-radius: 0;
|
|
|
- border-top-right-radius: 0;
|
|
|
-}
|
|
|
-
|
|
|
-.transaction-item:last-child {
|
|
|
- border-bottom: none;
|
|
|
+ margin-bottom: 24rpx;
|
|
|
+ padding-bottom: 24rpx;
|
|
|
+ border-bottom: 1rpx solid #f1f2f6;
|
|
|
}
|
|
|
|
|
|
-.item-left {
|
|
|
- flex: 1;
|
|
|
+.pool-info {
|
|
|
display: flex;
|
|
|
- flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
}
|
|
|
|
|
|
-.stock-info {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- margin-bottom: 8rpx;
|
|
|
+.pool-icon {
|
|
|
+ font-size: 32rpx;
|
|
|
+ margin-right: 12rpx;
|
|
|
}
|
|
|
|
|
|
-.stock-name {
|
|
|
+.pool-name {
|
|
|
font-size: 30rpx;
|
|
|
font-weight: 600;
|
|
|
color: #222222;
|
|
|
- margin-right: 12rpx;
|
|
|
}
|
|
|
|
|
|
-.stock-code {
|
|
|
- font-size: 24rpx;
|
|
|
- color: #9ca2b5;
|
|
|
-}
|
|
|
-
|
|
|
-.transaction-time {
|
|
|
+.status-badge {
|
|
|
+ padding: 8rpx 20rpx;
|
|
|
+ border-radius: 20rpx;
|
|
|
font-size: 24rpx;
|
|
|
- color: #9ca2b5;
|
|
|
-}
|
|
|
-
|
|
|
-.item-right {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- align-items: flex-end;
|
|
|
-}
|
|
|
-
|
|
|
-.amount-text {
|
|
|
- font-size: 32rpx;
|
|
|
- font-weight: 700;
|
|
|
- margin-bottom: 8rpx;
|
|
|
}
|
|
|
|
|
|
-.amount-buy {
|
|
|
+.status-active {
|
|
|
+ background: #e7f7ef;
|
|
|
color: #3abf81;
|
|
|
}
|
|
|
|
|
|
-.amount-sell {
|
|
|
- color: #f16565;
|
|
|
+.status-expired {
|
|
|
+ background: #f5f5f5;
|
|
|
+ color: #999999;
|
|
|
}
|
|
|
|
|
|
-.status-badge {
|
|
|
- padding: 4rpx 16rpx;
|
|
|
- border-radius: 12rpx;
|
|
|
+.status-text {
|
|
|
+ font-weight: 500;
|
|
|
}
|
|
|
|
|
|
-.status-buy {
|
|
|
- background: #e7f7ef;
|
|
|
+.item-body {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 16rpx;
|
|
|
}
|
|
|
|
|
|
-.status-sell {
|
|
|
- background: #ffe7ee;
|
|
|
+.info-row {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ font-size: 26rpx;
|
|
|
}
|
|
|
|
|
|
-.status-text {
|
|
|
- font-size: 22rpx;
|
|
|
- font-weight: 500;
|
|
|
+.info-label {
|
|
|
+ color: #666a7f;
|
|
|
+ min-width: 160rpx;
|
|
|
}
|
|
|
|
|
|
-.status-buy .status-text {
|
|
|
- color: #3abf81;
|
|
|
+.info-value {
|
|
|
+ color: #222222;
|
|
|
+ font-weight: 500;
|
|
|
}
|
|
|
|
|
|
-.status-sell .status-text {
|
|
|
+.info-value.price {
|
|
|
color: #f16565;
|
|
|
+ font-weight: 700;
|
|
|
+ font-size: 28rpx;
|
|
|
}
|
|
|
|
|
|
/* 空状态 */
|
|
|
@@ -331,31 +305,30 @@ onMounted(() => {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
align-items: center;
|
|
|
- padding: 120rpx 0;
|
|
|
- background: #ffffff;
|
|
|
- margin: 0 32rpx;
|
|
|
- border-radius: 24rpx;
|
|
|
+ justify-content: center;
|
|
|
+ padding: 200rpx 60rpx;
|
|
|
}
|
|
|
|
|
|
.empty-icon {
|
|
|
font-size: 120rpx;
|
|
|
margin-bottom: 32rpx;
|
|
|
- opacity: 0.5;
|
|
|
}
|
|
|
|
|
|
.empty-text {
|
|
|
font-size: 32rpx;
|
|
|
- color: #666666;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #333333;
|
|
|
margin-bottom: 16rpx;
|
|
|
- font-weight: 500;
|
|
|
}
|
|
|
|
|
|
.empty-desc {
|
|
|
font-size: 26rpx;
|
|
|
- color: #9ca2b5;
|
|
|
+ color: #999999;
|
|
|
+ text-align: center;
|
|
|
+ line-height: 1.6;
|
|
|
}
|
|
|
|
|
|
.bottom-safe-area {
|
|
|
- height: 40rpx;
|
|
|
+ height: 80rpx;
|
|
|
}
|
|
|
</style>
|