| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519 |
- <template>
- <view class="page-container">
- <!-- 自定义导航栏 -->
- <view class="nav-bar">
- <view class="nav-back" @click="goBack">
- <text class="back-icon">←</text>
- </view>
- <text class="nav-title">历史股票池回顾</text>
- <view class="nav-placeholder"></view>
- </view>
-
- <scroll-view class="scroll-view" scroll-y @scrolltolower="loadMore">
- <view class="content-wrapper">
- <!-- 查询条件显示 -->
- <view class="query-info">
- <text class="query-label">查询区间:</text>
- <text class="query-value">{{ formatDate(startDate) }} 至 {{ formatDate(endDate) }}</text>
- </view>
-
- <!-- 统计信息 (仅超短池显示) -->
- <view v-if="poolType === 1" class="stats-card">
- <view class="stat-item">
- <text class="stat-value">{{ total }}</text>
- <text class="stat-label">总记录</text>
- </view>
- <view class="stat-divider"></view>
- <view class="stat-item">
- <text class="stat-value success-text">{{ successCount }}</text>
- <text class="stat-label">成功</text>
- </view>
- <view class="stat-divider"></view>
- <view class="stat-item">
- <text class="stat-value fail-text">{{ failCount }}</text>
- <text class="stat-label">失败</text>
- </view>
- </view>
- <!-- 表头 -->
- <view v-if="poolType === 1" class="table-header">
- <text class="th-name">名称/代码</text>
- <text class="th-close">收盘价</text>
- <text class="th-high">隔日最高</text>
- <text class="th-trend">隔日涨幅</text>
- </view>
- <view v-else class="table-header-simple">
- <text class="th-name-simple">名称/代码</text>
- <text class="th-trend-simple">最高涨幅</text>
- </view>
- <!-- 数据列表 -->
- <view class="stock-list">
- <view v-if="poolType === 1" class="stock-item" v-for="(item, index) in historyList" :key="index">
- <view class="td-name">
- <text class="stock-name">{{ item.stockName }}</text>
- <text class="stock-code">{{ item.stockCode }}</text>
- <text class="stock-date">入池: {{ formatRecordDate(item.recordDate) }}</text>
- </view>
- <text class="td-close">{{ item.closePrice ? item.closePrice.toFixed(2) : '-' }}</text>
- <text class="td-high">{{ item.nextDayHighPrice ? item.nextDayHighPrice.toFixed(2) : '-' }}</text>
- <view class="td-trend">
- <text :class="['trend-value', getTrendClass(item.nextDayHighTrend)]">
- {{ formatTrend(item.nextDayHighTrend) }}
- </text>
- <text v-if="item.status === 'success'" class="status-tag success">成功</text>
- <text v-else-if="item.status === 'fail'" class="status-tag fail">失败</text>
- </view>
- </view>
- <view v-else class="stock-item-simple" v-for="(item, index) in historyList" :key="index">
- <view class="td-name-simple">
- <text class="stock-name">{{ item.stockName }}</text>
- <text class="stock-code">{{ item.stockCode }}</text>
- <text class="stock-date">入池: {{ formatRecordDate(item.recordDate) }}</text>
- </view>
- <view class="td-trend-simple">
- <text :class="['trend-value', getTrendClass(item.nextDayHighTrend)]">
- {{ formatTrend(item.nextDayHighTrend) }}
- </text>
- </view>
- </view>
- </view>
-
- <!-- 加载状态 -->
- <view class="load-status">
- <text v-if="loading" class="load-text">加载中...</text>
- <text v-else-if="!hasMore && historyList.length > 0" class="load-text">已加载全部</text>
- <text v-else-if="historyList.length === 0 && !loading" class="load-text">暂无数据</text>
- </view>
-
- <!-- 底部安全区 -->
- <view class="bottom-safe-area"></view>
- </view>
- </scroll-view>
- </view>
- </template>
- <script setup>
- import { ref, computed } from 'vue'
- import { onLoad } from '@dcloudio/uni-app'
- import { getStockHistory } from '../../utils/api.js'
- const startDate = ref('')
- const endDate = ref('')
- const poolType = ref(1)
- const historyList = ref([])
- const total = ref(0)
- const hasMore = ref(false)
- const loading = ref(false)
- const pageNum = ref(1)
- const pageSize = ref(20)
- // 统计成功和失败数量
- const successCount = computed(() => historyList.value.filter(item => item.status === 'success').length)
- const failCount = computed(() => historyList.value.filter(item => item.status === 'fail').length)
- // 格式化日期显示
- const formatDate = (dateStr) => {
- if (!dateStr) return ''
- const [year, month, day] = dateStr.split('-')
- return `${year}年${month}月${day}日`
- }
- // 格式化入池日期(简短格式)
- const formatRecordDate = (dateStr) => {
- if (!dateStr) return '-'
- // 处理可能的日期格式:2025-01-10 或 数组格式 [2025, 1, 10]
- if (Array.isArray(dateStr)) {
- const [year, month, day] = dateStr
- return `${month}/${day}`
- }
- const parts = dateStr.split('-')
- if (parts.length >= 3) {
- return `${parseInt(parts[1])}/${parseInt(parts[2])}`
- }
- return dateStr
- }
- // 获取涨幅样式
- const getTrendClass = (trend) => {
- if (trend === null || trend === undefined) return ''
- return trend >= 0 ? 'text-red' : 'text-green'
- }
- // 格式化涨幅
- const formatTrend = (trend) => {
- if (trend === null || trend === undefined) return '-'
- const prefix = trend >= 0 ? '+' : ''
- return `${prefix}${trend.toFixed(2)}%`
- }
- // 返回上一页
- const goBack = () => {
- const pages = getCurrentPages()
- pages.length > 1 ? uni.navigateBack() : uni.switchTab({ url: '/pages/index/index' })
- }
- // 加载历史数据
- const loadHistoryData = async () => {
- if (loading.value) return
-
- loading.value = true
- try {
- const res = await getStockHistory({
- startDate: startDate.value,
- endDate: endDate.value,
- poolType: poolType.value,
- pageNum: pageNum.value,
- pageSize: pageSize.value
- })
-
- if (res.code === 200 && res.data) {
- if (pageNum.value === 1) {
- historyList.value = res.data.list || []
- } else {
- historyList.value = [...historyList.value, ...(res.data.list || [])]
- }
- total.value = res.data.total || 0
- hasMore.value = res.data.hasMore || false
- }
- } catch (e) {
- console.error('加载历史数据失败:', e)
- uni.showToast({ title: '加载失败', icon: 'none' })
- } finally {
- loading.value = false
- }
- }
- // 加载更多
- const loadMore = () => {
- if (loading.value || !hasMore.value) return
- pageNum.value++
- loadHistoryData()
- }
- onLoad((options) => {
- startDate.value = options.startDate || ''
- endDate.value = options.endDate || ''
- poolType.value = parseInt(options.poolType) || 1
-
- // 设置导航栏标题
- const poolName = poolType.value === 1 ? '超短池' : '强势池'
- uni.setNavigationBarTitle({ title: `${poolName}历史回顾` })
-
- loadHistoryData()
- })
- </script>
- <style scoped>
- .page-container {
- height: 100vh;
- display: flex;
- flex-direction: column;
- background: #f5f6fb;
- }
- /* 自定义导航栏 */
- .nav-bar {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 44px 32rpx 20rpx;
- background: #ffffff;
- box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
- }
- .nav-back {
- width: 60rpx;
- height: 60rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .back-icon {
- font-size: 36rpx;
- color: #333;
- }
- .nav-title {
- font-size: 32rpx;
- font-weight: 600;
- color: #222222;
- }
- .nav-placeholder {
- width: 60rpx;
- }
- .scroll-view {
- flex: 1;
- height: 0;
- }
- .content-wrapper {
- padding: 24rpx 32rpx;
- }
- /* 查询条件 */
- .query-info {
- display: flex;
- align-items: center;
- padding: 20rpx 24rpx;
- background: #ffffff;
- border-radius: 16rpx;
- margin-bottom: 24rpx;
- }
- .query-label {
- font-size: 26rpx;
- color: #666a7f;
- }
- .query-value {
- font-size: 26rpx;
- color: #222222;
- font-weight: 500;
- }
- /* 统计卡片 */
- .stats-card {
- display: flex;
- align-items: center;
- justify-content: space-around;
- padding: 32rpx 24rpx;
- background: #ffffff;
- border-radius: 20rpx;
- margin-bottom: 24rpx;
- box-shadow: 0 8rpx 24rpx rgba(37, 52, 94, 0.06);
- }
- .stat-item {
- display: flex;
- flex-direction: column;
- align-items: center;
- flex: 1;
- }
- .stat-value {
- font-size: 40rpx;
- font-weight: 700;
- color: #1a1a2e;
- margin-bottom: 8rpx;
- }
- .stat-value.success-text {
- color: #22c55e;
- }
- .stat-value.fail-text {
- color: #ef4444;
- }
- .stat-label {
- font-size: 24rpx;
- color: #9ca3af;
- }
- .stat-divider {
- width: 1rpx;
- height: 60rpx;
- background: #eef0f5;
- }
- /* 表头 */
- .table-header {
- display: flex;
- align-items: center;
- padding: 20rpx 24rpx;
- background: #eef0f5;
- border-radius: 12rpx;
- margin-bottom: 16rpx;
- }
- .table-header-simple {
- display: flex;
- align-items: center;
- padding: 20rpx 24rpx;
- background: #eef0f5;
- border-radius: 12rpx;
- margin-bottom: 16rpx;
- }
- .th-name {
- width: 180rpx;
- font-size: 24rpx;
- font-weight: 600;
- color: #666a7f;
- }
- .th-close {
- width: 120rpx;
- font-size: 24rpx;
- font-weight: 600;
- color: #666a7f;
- text-align: center;
- }
- .th-high {
- width: 120rpx;
- font-size: 24rpx;
- font-weight: 600;
- color: #666a7f;
- text-align: center;
- }
- .th-trend {
- flex: 1;
- font-size: 24rpx;
- font-weight: 600;
- color: #666a7f;
- text-align: right;
- }
- .th-name-simple {
- flex: 1;
- font-size: 24rpx;
- font-weight: 600;
- color: #666a7f;
- }
- .th-trend-simple {
- width: 200rpx;
- font-size: 24rpx;
- font-weight: 600;
- color: #666a7f;
- text-align: right;
- }
- /* 数据列表 */
- .stock-list {
- display: flex;
- flex-direction: column;
- gap: 16rpx;
- }
- .stock-item {
- display: flex;
- align-items: center;
- padding: 24rpx;
- background: #ffffff;
- border-radius: 16rpx;
- box-shadow: 0 4rpx 12rpx rgba(37, 52, 94, 0.04);
- }
- .stock-item-simple {
- display: flex;
- align-items: center;
- padding: 24rpx;
- background: #ffffff;
- border-radius: 16rpx;
- box-shadow: 0 4rpx 12rpx rgba(37, 52, 94, 0.04);
- }
- .td-name {
- width: 180rpx;
- display: flex;
- flex-direction: column;
- }
- .stock-name {
- font-size: 28rpx;
- font-weight: 700;
- color: #1a1a2e;
- margin-bottom: 4rpx;
- }
- .stock-code {
- font-size: 22rpx;
- color: #9ca3af;
- }
- .stock-date {
- font-size: 20rpx;
- color: #5d55e8;
- margin-top: 4rpx;
- }
- .td-close {
- width: 120rpx;
- font-size: 28rpx;
- font-weight: 600;
- color: #1a1a2e;
- text-align: center;
- }
- .td-high {
- width: 120rpx;
- font-size: 28rpx;
- font-weight: 600;
- color: #1a1a2e;
- text-align: center;
- }
- .td-trend {
- flex: 1;
- display: flex;
- flex-direction: column;
- align-items: flex-end;
- gap: 6rpx;
- }
- .td-name-simple {
- flex: 1;
- display: flex;
- flex-direction: column;
- }
- .td-trend-simple {
- width: 200rpx;
- display: flex;
- flex-direction: column;
- align-items: flex-end;
- gap: 6rpx;
- }
- .trend-value {
- font-size: 28rpx;
- font-weight: 700;
- }
- .text-red {
- color: #ef4444;
- }
- .text-green {
- color: #22c55e;
- }
- .status-tag {
- font-size: 20rpx;
- padding: 6rpx 16rpx;
- border-radius: 8rpx;
- font-weight: 600;
- }
- .status-tag.success {
- background: rgba(34, 197, 94, 0.15);
- color: #22c55e;
- }
- .status-tag.fail {
- background: rgba(239, 68, 68, 0.15);
- color: #ef4444;
- }
- /* 加载状态 */
- .load-status {
- padding: 40rpx 0;
- text-align: center;
- }
- .load-text {
- font-size: 26rpx;
- color: #9ca3af;
- }
- .bottom-safe-area {
- height: 40rpx;
- }
- </style>
|