Files
JiaZhiQianYan/pages/geGuCenter/detail.vue
2026-02-04 11:07:16 +08:00

314 lines
9.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view>
<navBar leftText="详情" hideNavBg></navBar>
<image class="topBg absolute" src="/static/image/index/conceptTopBg.png" mode="widthFix"></image>
<view class="searchC fixed flex" :style="'top:'+navH+'px;'">
<image class="icon" src="/static/icon/home/conceptCenter/search.png" mode="widthFix"></image>
<input class="flex1" type="text" v-model="keywords" placeholder="输入股票代码或名称"
placeholder-style="color:#eeeeee" confirm-type="search" @input="clickSearch()" />
</view>
<view v-if="searchShow" class="searchResultList fixed" :style="'top:'+searchResultTop+'px;'" @click="clickSearchResultBg()">
<view class="list">
<view class="item" v-for="(item,index) in searchResultList" :key="index" @click.stop="clickSearchResultListItem(item)">
{{item.stock_code}} {{item.stock_name}}
</view>
</view>
</view>
<scroll-view scroll-y class="stockDetailsC fixed" :style="'top:'+contentTop+'px;'">
<view>
<view style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 16rpx; margin: 0 20rpx;">
<view @click="handleTypeClick(index)" v-for="(item,index) in topLists" :key="index"
style="padding: 12rpx;"
:style="{'border-bottom': (list2Index == index ? '1rpx solid #F2C369' : 'none')}">
<view style="font-size: 24rpx; color: #070707; font-weight: bold; text-align: center;"
:style="{color: (list2Index == index ? '#BB8520' : '#070707')}">
{{item.title}}
</view>
<view style="font-size: 20rpx; font-weight: 400; text-align: center;"
:style="{color: (list2Index == index ? '#BB8520' : '#070707')}">{{item.value}}</view>
</view>
</view>
<view style="height: 1rpx; margin: 0 20rpx; background-color: #E7E7E7;"></view>
<!-- '股票名称', '涨跌幅', '市值', '成交额', '行业' -->
<view
style="display: grid; grid-template-columns: repeat(5, 1fr); gap: 10rpx; background-color: #FAFAFC; line-height: 60rpx; margin: 0 20rpx; margin-top: 20rpx;">
<view v-for="(item,index) in ['股票名称', '涨跌幅', '市值', '成交额', '行业']" :key="index"
style="color: #666666; font-size: 20rpx; font-weight: 500; text-align: center;">
{{item}}
</view>
</view>
<!-- '股票名称', '涨跌幅', '市值', '成交额', '行业' 内容 -->
<view v-for="(obj, j) in filteredData" @click="itemDetails(obj)"
style="display: grid; grid-template-columns: repeat(5, 1fr); gap: 10rpx; min-height: 60rpx; margin: 0 20rpx;"
:style="{'background-color': (j % 2 == 0 ? '#fff' : '#FAFAFC')}">
<!-- 外层循环每一行数据 -->
<view v-for="(item,index) in getTableItem(obj)" :key="index"
style="padding: 10rpx 0; color: #666666; font-size: 20rpx; font-weight: 500; text-align: center; display: flex; justify-content: center; align-items: center; flex-direction: column;"
:style="{
color: (index == 0 ? '#222222' :
index == 1 ? (item[2] === 'positive' ? '#EC3440' : '#01AB5D') : '#666666')
}">
<view>{{item[0]}}</view>
<view v-if="index == 0" style="color: #666666; font-size: 20rpx; font-weight: 500;">{{item[1]}}</view>
</view>
</view>
<view style="height: 25rpx;"></view>
</view>
</scroll-view>
</view>
</template>
<script>
import {
inject
} from 'vue'
import {
marketHeatmap,
searchStockInfo,
stockBasicInfo
} from '@/request/api'
export default {
data() {
return {
navH: inject('navHeight'),
contentTop: '',
allStockData: [],
filteredData: [],
currentDate: '', // 最终要赋值的日期
searchResultTop:'', //搜索结果
contentTop: '',
keywords: '', //搜索关键字
searchShow:false, //是否展示搜索结果
searchResultList:[], //搜索结果
selectSearchStockInfo:null, //选中的搜索股票信息
topLists: [{
title: '超大盘股',
value: '>1000亿',
},
{
title: '大盘股',
value: '500-1000亿',
},
{
title: '中盘股',
value: '100-500亿',
}
],
list2Index: 0
}
},
onLoad(e) {
this.currentDate = e.currentDate
this.searchResultTop = this.navH + (20 + 70) / 750 * inject('windowWidth')
this.contentTop = this.navH + (20 + 70 + 25) / 750 * inject('windowWidth')
this.marketHeatmap()
},
methods: {
/**
* 点击搜索
*/
clickSearch() {
if(this.keywords) {
this.getSearchStockInfoListData()
}else
this.selectSearchStockInfo = null
},
/**
* 点击搜索结果背景
*/
clickSearchResultBg()
{
this.searchShow = false
},
/**
* 点击搜索结果列表项
*/
clickSearchResultListItem(item) {
this.selectSearchStockInfo = item
this.searchShow = false
this.getStockBasicInfoData()
//this.getQuoteDetailsData()
},
/**
* 根据输入内容获取搜索列表项
*/
getSearchStockInfoListData() {
let param = {q:this.keywords,limit:10}
searchStockInfo(param).then(res=>{
this.searchResultList = res.data
this.searchShow = this.searchResultList.length>0
}).catch(error=>{
})
},
/**
* 获取股票基本信息
*/
getStockBasicInfoData() {
let code = this.stockCode
if (this.selectSearchStockInfo) {
code = this.selectSearchStockInfo.stock_code
}
// stockBasicInfo(code).then(res=>{
// this.stockBasicInfo = res.data
// this.navTitle = res.data.SECNAME+'('+res.data.SECCODE+')'
// }).catch(error=>{
// })
uni.navigateTo({
url: '/pagesStock/stockCenterDetails/stockCenterDetails?code=' + code
})
},
handleTypeClick(index) {
this.list2Index = index;
// 先请求数据,再筛选
this.marketHeatmap();
},
getTableItem(obj) {
// 1. 处理空值,避免 toFixed 调用时报错
const marketCap = obj.market_cap ? obj.market_cap.toFixed(2) : '0.00';
const amount = obj.amount ? obj.amount.toFixed(2) : '0.00';
// 统一处理涨跌幅空值默认0转数字避免字符串干扰判断
const changePercent = obj.change_percent ? Number(obj.change_percent) : 0;
// 2. 处理涨跌幅的符号和类型标记
let changePercentStr = '';
let changeType = ''; // 标记正负positive/negative/zero
if (changePercent > 0) {
changePercentStr = `+${changePercent}%`; // 正数拼接+号
changeType = 'positive';
} else if (changePercent < 0) {
changePercentStr = `${changePercent}%`; // 负数直接显示
changeType = 'negative';
} else {
changePercentStr = '0%'; // 0值统一显示
changeType = 'zero';
}
// 3. 返回数组:涨跌幅位置新增 changeType 用于模板判断颜色
return [
[obj.stock_name, obj.stock_code],
[changePercentStr, '', changeType], // 第三个元素存类型标记
[`${marketCap}亿元`],
[`${amount}亿元`],
[obj.industry || '暂无'] // 处理行业为空的情况
];
},
marketHeatmap() {
let param = {
limit: 500
}
if (this.currentDate && this.currentDate !== 'undefined' && this.currentDate.trim() !== '') {
param.date = this.currentDate;
}
marketHeatmap(param).then(res => {
// 存储原始数据
this.allStockData = res.data || [];
// 调用筛选方法
this.filterStockByMarketCap();
}).catch(error => {
})
},
// 根据市值区间筛选数据
filterStockByMarketCap() {
const {
list2Index,
allStockData
} = this;
let filtered = [];
switch (list2Index) {
case 0: // 超大盘股(>1000亿
filtered = allStockData.filter(item => item.market_cap > 1000);
break;
case 1: // 大盘股500-1000亿
filtered = allStockData.filter(item => item.market_cap >= 500 && item.market_cap <= 1000);
break;
case 2: // 中盘股100-500亿
filtered = allStockData.filter(item => item.market_cap >= 100 && item.market_cap <= 500);
break;
default:
filtered = allStockData;
}
this.filteredData = filtered;
},
itemDetails(item) {
uni.navigateTo({
url: '/pagesStock/stockCenterDetails/stockCenterDetails?code=' + item.stock_code
})
},
}
}
</script>
<style lang="less">
page {
background-color: #070707;
}
.topBg {
top: 0;
left: 0;
width: 100%;
height: auto;
}
.searchC {
background-color: #292929B3;
left: 0;
right: 0;
margin: 20rpx 25rpx 0;
padding: 0 25rpx;
height: 70rpx;
border-radius: 35rpx;
font-size: 22rpx;
font-weight: 500;
.icon {
margin-right: 12rpx;
width: 25rpx;
height: auto;
}
input {
height: 100%;
color: white;
}
}
.stockDetailsC {
left: 25rpx;
width: calc(100vw - 50rpx);
bottom: env(safe-area-inset-bottom);
background-color: white;
border-radius: 10rpx;
}
.searchResultList {
background-color: #00000080;
left: 0;
right: 0;
bottom: 0;
padding: 0 25rpx;
.list
{
background-color: white;
border-radius: 10rpx;
.item
{
padding: 0 42rpx;
line-height: 60rpx;
font-size: 22rpx;
font-weight: 500;
color: #333;
}
}
z-index: 20;
}
</style>