|
|
<template> <view class="main"> <!-- 顶部状态栏占位 --> <view class="top" :style="{ height: iSMT + 'px' }"></view> <!-- 标题图标部分 --> <deepExploration_header></deepExploration_header> <view class="search"> <input v-model="stockName" class="searchInput" type="text" placeholder="请输入股票名称、股票代码" placeholder-style="color: #A6A6A6; font-size: 22rpx;" /> <image @click="searchStock" class="seachIcon" src="/static/deepExploration-images/search.png" mode="aspectFill" ></image> </view>
<!-- 四大功能模块 --> <view class="select"> <view class="selectItem" @click="toMain('主力追踪')"> <image class="img" src="/static/deepExploration-images/icon3.png" mode="aspectFill" ></image> <view class="txt">主力追踪</view> </view> <view class="selectItem" @click="toMain('主力雷达')"> <image class="img" src="/static/deepExploration-images/icon2.png" mode="aspectFill" ></image> <view class="txt">主力雷达</view> </view> <view class="selectItem" @click="toMain('主力解码')"> <image class="img" src="/static/deepExploration-images/icon1.png" mode="aspectFill" ></image> <view class="txt">主力解码</view> </view> <view class="selectItem" @click="toMain('主力资金流')"> <image class="img" src="/static/deepExploration-images/icon4.png" mode="aspectFill" ></image> <view class="txt">主力资金流</view> </view> </view>
<!-- 灰色间隔 --> <view class="gap"></view> <!-- 选股策略 --> <view class="stockSelection"> <view class="stockSelection_top"> <view class="txt"> <text>选股策略</text> </view> <view class="viewAll" @click="viewAll"> <text>查看全部</text> </view> </view>
<view class="stockSelection_content"> <view class="selectionItem"> <view class="header"> <view class="left"> <image src="/static/deepExploration-images/plus.png" mode="aspectFill" ></image> <text>抄底卖顶</text> </view> <view class="right"> <image src="/static/deepExploration-images/Americle.png" mode="aspectFill" ></image> <text>美股</text> </view> </view> <view class="content"> <view class="contentTitle"> <view class="contentTitle_name">股票名称</view> <view class="contentTitle_close">最新收盘价</view> <view class="contentTitle_price">选股价格</view> </view> <view class="contentItem"> <view class="row" v-for="(item, index) in stockData" :key="index"> <view class="nameItem">{{ item.tscode }}</view> <view class="closeItem">{{ item.close }}</view> <view class="priceItem">{{ item.preClose }}</view> </view> </view> </view> </view> </view>
<view class="stockSelection_content"> <view class="selectionItem"> <view class="header"> <view class="left"> <image src="/static/deepExploration-images/plus.png" mode="aspectFill" ></image> <text>波段行情</text> </view> <view class="right"> <image src="/static/deepExploration-images/Americle.png" mode="aspectFill" ></image> <text>美股</text> </view> </view> <view class="content"> <view class="contentTitle"> <view class="contentTitle_name">股票名称</view> <view class="contentTitle_close">最新收盘价</view> <view class="contentTitle_price">选股价格</view> </view> <view class="contentItem"> <view class="row" v-for="(item, index) in stockDataByName" :key="index"> <view class="nameItem">{{ item.tscode }}</view> <view class="closeItem">{{ item.close }}</view> <view class="priceItem">{{ item.preClose }}</view> </view> </view> </view> </view> </view> </view> <footerBar class="static-footer" :type="type"></footerBar> <LoginPrompt ref="loginPrompt"></LoginPrompt> </view></template>
<script setup> import { ref, onMounted } from 'vue' import footerBar from '@/components/footerBar.vue' import deepExploration_header from '@/components/deepExploration_header.vue' import { stocSelectApi, stocSelectByNameApi } from '@/api/deepExploration/deepExploration.js'
const type = ref("deepExploration");const iSMT = ref(0);
//查看全部选股策略
const toMain = (val) => { if (val == "主力追踪") { uni.navigateTo({ url: "/pages/deepExploration/MainForceActions?index=1", }); } else if (val == "主力雷达") { uni.navigateTo({ url: "/pages/deepExploration/MainForceActions?index=2", }); } else if (val == "主力解码") { uni.navigateTo({ url: "/pages/deepExploration/MainForceActions?index=3", }); } else if (val == "主力资金流") { uni.navigateTo({ url: "/pages/deepExploration/MainForceActions?index=4", }); }};
const stockName = ref("");//搜索股票
const searchStock = () => { console.log("搜索参数:", stockName.value); uni.navigateTo({ url: `/pages/deepExploration/MainForceActions?stockName=${stockName.value}`, });};
//查看全部选股策略
const viewAll = () => { uni.navigateTo({ url: '/pages/deepExploration/stockSelectDetail' }) } //选股策略数据(接口填充)
const stockData = ref([]); const stockDataByName = ref([]); // 安徽板块数据(只显示前三条)
// 加载选股策略(接口)
const loadStockSelection = async () => { try { const res = await stocSelectApi({ language: 'cn', size: 3 }) // console.log('选股策略接口响应原始:', typeof res === 'object' ? JSON.stringify(res) : res)
const raw = res?.data const listCandidates = [ raw?.list, raw?.data?.list, raw?.data?.rows, raw?.rows, Array.isArray(raw) ? raw : null ].filter(Array.isArray) let list = listCandidates.length ? listCandidates[0] : []
// 若是对象包含多个数组(如不同市场),进行扁平化
if ((!Array.isArray(list) || !list.length) && raw && typeof raw === 'object' && !Array.isArray(raw)) { const arrays = Object.values(raw).filter(Array.isArray) if (arrays.length) { list = arrays.flat() } }
if (Array.isArray(list) && list.length) { const mapped = list.map(item => ({ tscode: item.tsCode ?? item.tscode ?? item.code ?? '', close: item.close ?? item.lastClose ?? '', preClose: item.preClose ?? item.preclose ?? item.prevClose ?? '' })) stockData.value = mapped.slice(0, 3) console.log('选股策略列表长度:', stockData.value.length, '首项:', stockData.value[0]) } else { console.warn('选股策略接口返回空列表或结构不匹配', raw) } } catch (e) { console.error('选股策略接口调用失败', e) uni.showToast({ title: '选股策略加载失败', icon: 'none' }) } }
// 安徽板块:按名称查询,仅前三条,字段映射不变
const loadStockSelectionByName = async () => { try { const res = await stocSelectByNameApi({ name: '安徽' }) const raw = res?.data const dataObj = raw?.data || raw let list = [] if (Array.isArray(dataObj)) { list = dataObj } else if (dataObj && typeof dataObj === 'object') { const target = dataObj['安徽'] if (Array.isArray(target)) { list = target } else { const firstArr = Object.values(dataObj).find(v => Array.isArray(v)) if (Array.isArray(firstArr)) list = firstArr } }
if (Array.isArray(list) && list.length) { const mapped = list.map(item => ({ tscode: item.tsCode ?? item.tscode ?? item.code ?? '', close: item.close ?? item.lastClose ?? '', preClose: item.preClose ?? item.preclose ?? item.prevClose ?? '' })) stockDataByName.value = mapped.slice(0, 3) console.log('安徽板块列表长度:', stockDataByName.value.length, '首项:', stockDataByName.value[0]) } else { console.warn('按名称(安徽)接口返回空列表或结构不匹配', raw) } } catch (e) { console.error('按名称(安徽)接口调用失败', e) uni.showToast({ title: '安徽板块加载失败', icon: 'none' }) } }
onMounted(() => { // 状态栏高度
iSMT.value = uni.getSystemInfoSync().statusBarHeight; // 调用接口填充数据
loadStockSelection() loadStockSelectionByName() // 安徽板块填充
})</script>
<style scoped lang="scss">.main { width: 100%; min-height: 100vh; // 保持至少一屏高度
height: auto; // 允许内容超出时自动增高
overflow-y: auto; // 开启纵向滚动
background-color: #fff; padding-bottom: 120rpx; // 为固定底栏预留空间,避免遮挡
.search { position: relative; display: flex; align-items: center; background-color: #f3f3f3; width: calc(100% - 60rpx); height: 80rpx; border-radius: 50rpx; box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1); padding: 0 40rpx; margin: 15rpx 30rpx 0 30rpx;
.seachIcon { position: absolute; right: 50rpx; width: 32rpx; height: 32rpx; }
.searchInput { color: #111; } }
.select { display: flex; padding: 60rpx 10rpx 30rpx 30rpx; gap: 70rpx; align-items: center; justify-content: center;
.selectItem { .img { width: 80rpx; height: 80rpx; display: block; margin: 0 auto; }
.txt { color: #6a6a6a; font-family: "PingFang SC"; font-size: 11px; font-style: normal; font-weight: 400; line-height: 14.5px; margin-top: 13rpx; white-space: nowrap; } } }
.gap { width: 100%; height: 15rpx; background-color: #f3f3f3; }
.stockSelection { width: 100%; padding: 32rpx 15rpx;
.stockSelection_top { display: flex; justify-content: space-between;
.txt { color: #000000; font-family: "PingFang SC"; font-size: 38rpx; font-style: normal; font-weight: 400; line-height: 50rpx; }
.viewAll { background-color: #000000; border-radius: 10rpx; padding: 6rpx 20rpx; color: #ffffff; font-family: "PingFang SC"; font-size: 10rpx; font-style: normal; font-weight: 100; line-height: 29rpx; height: 40rpx; } }
.stockSelection_content { .selectionItem { background-color: #f3f3f3; padding: 30rpx 15rpx 17rpx 30rpx; border-radius: 30rpx; margin-top: 30rpx;
.header { display: flex; justify-content: space-between; align-items: center;
.left { display: flex; justify-content: space-between; align-items: center;
image { display: flex; justify-content: center; align-items: center; width: 15rpx; height: 15rpx; }
text { margin-left: 15rpx; color: #000000; font-family: "PingFang SC"; font-size: 28rpx; font-style: normal; font-weight: 400; line-height: 18.5px; } }
.right { display: flex; justify-content: space-between; align-items: center; border-radius: 15rpx; background-color: #ffffff; padding: 6rpx 20rpx;
image { display: flex; justify-content: center; align-items: center; width: 40rpx; height: 26.5rpx; }
text { margin-left: 10rpx; color: #6a6a6a; font-family: "PingFang SC"; font-size: 18rpx; font-style: normal; font-weight: 400; line-height: 24rpx; } } }
.content { .contentTitle { display: flex; color: #6a6a6a; font-family: "PingFang SC"; font-size: 11px; font-style: normal; font-weight: 400; line-height: 14.5px; margin-top: 24rpx; margin-bottom: 20rpx;
.contentTitle_name { width: 100rpx; }
.contentTitle_close { width: 130rpx; margin-left: 260rpx; }
.contentTitle_price { width: 120rpx; margin-left: 60rpx; } }
.contentItem { .row { display: flex; box-shadow: 0 -2rpx 5rpx rgba(0, 0, 0, 0.05); padding: 10rpx 0; margin-bottom: 10rpx;
.nameItem { width: 260rpx; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: #000000; font-family: "PingFang SC"; font-size: 13px; font-style: normal; font-weight: 400; line-height: 17.5px; }
.closeItem { width: 120rpx; margin-left: 100rpx; color: #25ba5d; font-family: "PingFang SC"; font-size: 13px; font-style: normal; font-weight: 400; line-height: 17.5px; }
.priceItem { width: 120rpx; margin-left: 73rpx; color: #25ba5d; font-family: "PingFang SC"; font-size: 13px; font-style: normal; font-weight: 400; line-height: 17.5px; } } } } } } }
.static-footer { position: fixed; bottom: 0; left: 0; right: 0; }}
* { box-sizing: border-box;}</style>
|