You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

529 lines
13 KiB

<template>
<LoginPrompt ref="loginPrompt"></LoginPrompt>
<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: 28rpx; " />
<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>
</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'
import {
useUserStore
} from '@/stores/modules/userInfo.js'
import {
getUserInfo
} from "@/api/member"
const userInfo = ref({})
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);
console.log(userInfo.value.isVisitor);
if (userInfo.value.isVisitor) {
uni.showToast({
title: '请登录',
icon: 'none'
})
return
}
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;
// 调用接口填充数据
getUserInfo()
loadStockSelection()
loadStockSelectionByName() // 安徽板块填充
userInfo.value = useUserStore().userInfo
console.log('用户信息', userInfo.value);
})
</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;
width: 100%;
}
}
.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>