Files
JiaZhiQianYan/pages/index/stockDetails/stockDetails.vue

549 lines
13 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="navTitle" :hideNavBg="true"></navBar>
<image class="topBg absolute" src="/static/image/index/conceptTopBg.png" mode="widthFix"></image>
<view class="chartDesC relative" :style="'margin-top:'+contentTop+'px;'">
<view v-if="type==1" class="tabC" >
<view :class="'item relative '+(selectCategory==index?'select':'')" v-for="(item,index) in categoryList" :key="index" @click="clickCategoryItem(index)">
{{item}}
<view v-if="selectCategory==index" class="line absolute"></view>
</view>
</view>
<view v-if="type==1&&tradeData" class="volumeAmountC flex">
<block v-if="tradeData.volume>100000000">
<text class="volume">成交量{{(tradeData.volume/100000000).toFixed(2)}}亿</text>
</block>
<block v-else>
<text v-if="tradeData.volume>10000" class="volume">成交量{{(tradeData.volume/10000).toFixed(2)}}</text>
<text v-else class="volume">成交量{{tradeData.volume}}</text>
</block>
<block v-if="tradeData.amount>100000000">
<text class="amount">成交金额{{(tradeData.amount/100000000).toFixed(2)}}亿元</text>
</block>
<block v-else>
<text v-if="tradeData.amount>10000" class="amount">成交金额{{(tradeData.amount/10000).toFixed(2)}}万元</text>
<text v-else class="amount">成交金额{{tradeData.amount}}</text>
</block>
</view>
<view v-if="type==1" style="width:700rpx; height:400rpx">
<l-echart ref="chartRef"></l-echart>
</view>
<view class="section">关联描述</view>
<view class="des">{{relatedDesc}}<text class="ai">AI合成</text></view>
<view class="riskTips">
风险提示解析内容由价值前沿人工采集整理自新闻公告研报等公开信息团队辛苦编写未经许可严禁转载本产品内容内容均不构成投资建议请投资者注意风险独立审慎决策
</view>
</view>
<view v-if="type==1&&sourceList.length>0" class="infoSourceC">
<view class="section">信息来源</view>
<view class="list">
<view class="item" v-for="(item,index) in sourceList" :key="index">
<view class="content">{{item.sentences}}</view>
<view class="article">{{item.report_title}}</view>
<view class="authorDateC flex">
<view class="author flex1">{{item.author}}</view>
<view class="date">{{getLocalDate(item.declare_date)}}</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { inject } from 'vue';
import { stockCandlestickChartData, stockDetails } from '@/request/api';
import { accDiv, accMul, accSub, getLocalDate } from '@/utils/util.js';
const echarts = require('../../../uni_modules/lime-echart/static/echarts.min.js');
export default {
data() {
return {
navH:inject('navHeight'),
contentTop:'',
navTitle:'',
type:'', //1事件详情2投资详情
eventId:'', //事件id
stockCode:'', //股票code
categoryList:['分时图','日K线'],
selectCategory:0,
tradeData:null, //成交数据
option:{
title: {
show:false
},
tooltip: {
position:function (pos, params, dom, rect, size) {
// 鼠标在左侧时 tooltip 显示到右侧,鼠标在右侧时 tooltip 显示到左侧。
var obj = {top: '10%'};
obj[['left', 'right'][+(pos[0] < size.viewSize[0] / 2)]] = 5;
return obj;
},
trigger: 'axis',
axisPointer: {
type: 'cross'
},
formatter: function (params) {
console.log(params)
let res = '日期:'+params[0].name+'\n'+'开盘价:'+params[0].data[1]+'\n'+'收盘价:'+params[0].data[2]+'\n'+'最低价:'+params[0].data[3]+'\n'+'最高价:'+params[0].data[4]
return res; // 经过这么一加工,最终返回出去并渲染,最终就出现了我们所看的效果
},
},
legend: {
show:false
},
grid: {
top: '10%',
left: '10%',
right: '10%',
bottom:"15%"
},
xAxis: {
type: 'category',
data: [],
boundaryGap: false,
axisLine: { onZero: false },
splitLine: { show: false },
min: 'dataMin',
max: ''
},
yAxis: {
scale: true,
splitArea: {
show: true
}
},
dataZoom: [
{
type: 'inside',
start: 50,
end: 100
},
{
show: true,
type: 'slider',
top: '90%',
start: 50,
end: 100
}
],
series: [
{
name: '日K',
type: 'candlestick',
data: [],
itemStyle: {
color: '#ffffff',
color0: '#355422',
borderColor: '#c00000',
borderColor0: '#355422'
}
}],
},
option1:{
title: {
show:false
},
tooltip: {
position:function (pos, params, dom, rect, size) {
// 鼠标在左侧时 tooltip 显示到右侧,鼠标在右侧时 tooltip 显示到左侧。
var obj = {top: '3%'};
obj[['left', 'right'][+(pos[0] < size.viewSize[0] / 2)]] = 5;
return obj;
},
trigger: 'axis',
formatter: function (params) {
let res = '时间:'+params[0].name+'\n'+'高:'+params[0].data[2]+'\n'+'开:'+params[0].data[3]
+'\n'+'低:'+params[0].data[4]+'\n'+'收:'+params[0].data[1]+'\n'+'涨幅:'+params[0].data[5]+'%'
// +'\n'+'量:'+params[0].data[6]+'\n'+'金额:'+params[0].data[7]
return res;
},
},
grid: {
top: '10%',
left: '12%',
right: '14%',
bottom: '10%'
},
xAxis: {
type:'category',
scale:true,
axisLabel: {
customValues:['09:30','10:00','10:30','11:00','11:30','13:00','13:30','14:00','14:30','15:00',]
},
},
yAxis: {
show:false,
scale:true,
},
dataZoom: [
{
type: 'inside'
}
],
series:{
name: '分时图',
type: 'line',
symbol:'none',
markLine: {
silent: true,
symbol:['none','none'],
lineStyle: {
type:'solid',
width: 1,
color: '#dedede'
},
z:1
},
data: [],
},
animation:false
},
relatedDesc:'', //关联描述
sourceList:[], //来源列表
getLocalDate:getLocalDate
}
},
onLoad(e) {
if(e.code)
{
this.type = e.type
if(e.type==1)
{
//事件详情
this.contentTop = this.navH+20/750*inject('windowWidth')
this.eventId = e.id
this.stockCode = e.code
this.getStockDetailsData()
}else
{
//投资详情
this.contentTop = this.navH
this.navTitle = e.name+'('+e.code+')'
this.relatedDesc = e.des
}
}
},
methods: {
async init() {
// chart 图表实例不能存在data里
const chart = await this.$refs.chartRef.init(echarts);
// chart.on('click',function (params) {
// console.log(params)
// })
if(this.selectCategory==0)
{
//分时图
chart.setOption(this.option1)
}else
chart.setOption(this.option)
},
/**
* 点击切换分类
* @param {Object} index
*/
clickCategoryItem(index)
{
if(this.selectCategory!=index)
{
this.selectCategory = index
if(index==1)
{
//日k
this.getStockCandlestickChartData()
}else
this.init()
}
},
/**
* 获取股票详情数据
*/
getStockDetailsData()
{
let stockCode = this.stockCode
let eventId = this.eventId
stockDetails(eventId,stockCode).then(res=>{
if(res.code==200)
{
this.navTitle = res.data.basic_info.stock_name+'('+res.data.basic_info.stock_code+')'
let data = res.data.minute_chart_data
this.tradeData = res.data.latest_trade
let categoryData = []
let valueData = []
let open = data[0].open
for (let item of data) {
categoryData.push(item.time)
let rate = accMul(accDiv(accSub(item.close,open),open).toFixed(4),100)
let volume = item.volume
if (volume>10000) {
volume = (volume/10000).toFixed(0)+'万'
}
let amount = item.amount
if (amount>10000)
{
amount = (amount/10000).toFixed(0)+'万'
}
valueData.push([item.time,item.close,item.high,item.open,item.low,rate,volume,amount])
}
let min = open
let max = 0
for (let item of valueData) {
let value = item[1]
if(parseFloat(value)<min)
{
min = parseFloat(value)
}
if(parseFloat(value)>max)
{
max = parseFloat(value)
}
}
let minInterval = (open - min)/3
let maxInterval = (max - open)/3
let intervalList = []
if(minInterval>maxInterval)
{
for (var i = 3; i > 0; i--) {
intervalList.push(open-i*minInterval)
}
for (var i = 0; i < 4; i++) {
intervalList.push(open+i*minInterval)
}
}else
{
for (var i = 3; i > 0; i--) {
intervalList.push(open-i*maxInterval)
}
for (var i = 0; i < 4; i++) {
intervalList.push(open+i*maxInterval)
}
}
this.option1.xAxis.data = categoryData
this.option1.yAxis.min = intervalList[0].toFixed(2)
this.option1.yAxis.max = intervalList[intervalList.length-1].toFixed(2)
this.option1.series.data = valueData
let markData = []
let time = res.data.event_info.event_start_time.split('T')[1]
time = time.substring(0,5)
for (let item of intervalList) {
markData.push({
xAxis:time,
lineStyle:{
type:'solid',
width: 1,
color: '#ffd700'
},
label:{
position:'middle',
formatter:'事件发生',
color: '#ffd700'
}
},
{
yAxis:item,
label:{
show:true,
position:'start',
color:'#333'
},
},
{
yAxis:item,
label:{
show:true,
position:'end',
formatter:accMul(accDiv(accSub(item,open),open).toFixed(4),100)+'%',
color:'#333'
},
})
}
this.option1.series.markLine.data = markData
let relatedDesc = res.data.related_desc
if(relatedDesc)
{
this.relatedDesc = relatedDesc.relation_desc
if(relatedDesc.retrieved_sources)
{
this.sourceList = relatedDesc.retrieved_sources
}
}
this.init()
}else
uni.showToast({
title:res.message,
icon:'none'
})
}).catch(error=>{
})
},
/**
* 获取股票K线数据
*/
getStockCandlestickChartData()
{
let stockCode = this.stockCode
let param = {chart_type:'minute'}
if(this.selectCategory==1)
{
param.chart_type = 'daily'
}
stockCandlestickChartData(stockCode,param).then(res=>{
let data = res.data
let categoryData = []
let valueData = []
for (let item of data) {
categoryData.push(item.time)
valueData.push([item.open,item.close,item.low,item.high])
}
this.option.xAxis.data = categoryData
this.option.series[0].data = valueData
this.init()
}).catch(error=>{
})
}
}
}
</script>
<style lang="less">
page
{
background-color: #070707;
}
.topBg
{
top: 0;
left: 0;
width: 100%;
height: auto;
}
.chartDesC
{
background: linear-gradient(-30deg, #FFF6F0 0%, #FEFEFE 100%);
margin: 0 25rpx;
padding-top: 10rpx;
border-radius: 10rpx;
.tabC
{
.item
{
display: inline-block;
padding: 0 25rpx;
line-height: 60rpx;
font-size: 28rpx;
font-weight: 500;
color: #42485B;
}
.item.select
{
font-weight: bold;
color: #F3C368;
.line
{
background-color: #F3C368;
left: calc((100% - 50rpx)/2);
bottom: 0;
width: 50rpx;
height: 2rpx;
}
}
}
.volumeAmountC {
padding: 25rpx;
font-size: 28rpx;
font-weight: bold;
color: #666;
.volume {
margin-right: 30rpx;
}
}
.section
{
padding: 0 25rpx;
line-height: 80rpx;
font-size: 32rpx;
font-weight: bold;
color: #222;
}
.des
{
margin: 0 25rpx;
line-height: 1.4rem;
font-size: 24rpx;
font-weight: 500;
color: #666;
.ai
{
color: #EC3440;
}
}
.riskTips
{
margin: 20rpx 25rpx 0;
padding-bottom: 30rpx;
line-height: 1.2rem;
font-size: 22rpx;
color: #A2A2A1;
}
}
.infoSourceC
{
.section
{
padding: 0 25rpx;
line-height: 80rpx;
font-size: 27rpx;
font-weight: bold;
color: #F3C368;
}
.list
{
padding: 0 25rpx;
.item
{
background: linear-gradient(-30deg, #FFF6F0 0%, #FEFEFE 100%);
margin-bottom: 20rpx;
padding: 30rpx 26rpx;
border-radius: 10rpx;
.content
{
font-size: 24rpx;
font-weight: 500;
color: #222;
}
.article
{
margin-top: 10rpx;
font-size: 22rpx;
font-weight: 500;
color: #666;
text-align: right;
}
.authorDateC
{
margin-top: 30rpx;
font-size: 22rpx;
font-weight: 500;
color: #AAA;
.author
{
margin-right: 10rpx;
}
}
}
}
}
.contentC.radius
{
margin-top: 10rpx;
border-radius: 20rpx 20rpx 0 0;
}
</style>