484 lines
11 KiB
Vue
484 lines
11 KiB
Vue
<template>
|
||
<view>
|
||
<navBar :leftText="navTitle"></navBar>
|
||
<image class="topBg absolute" src="/static/image/mine/myTopBg.png" mode="widthFix"></image>
|
||
<view v-if="type==1" class="tabC fixed" :style="'top:'+navH+'px;'">
|
||
<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 :class="'contentC fixed '+(type==2?'radius':'')" :style="'top:'+contentTop+'px;'">
|
||
<view v-if="type==1" style="width:750rpx; height:400rpx">
|
||
<l-echart ref="chartRef"></l-echart>
|
||
</view>
|
||
<view class="section">关联描述</view>
|
||
<view class="des">{{relatedDesc}}<text class="ai">(AI合成)【风险提示:解析内容由价值前沿人工采集整理自新闻、公告、研报等公开信息,团队辛苦编写,未经许可严禁转载。本产品内容内容均不构成投资建议,请投资者注意风险,独立审慎决策。】</text></view>
|
||
<view v-if="type==1&&sourceList.length>0" 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,
|
||
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: 'dataMax'
|
||
},
|
||
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: '#ec0000',
|
||
color0: '#00da3c',
|
||
borderColor: '#ec0000',
|
||
borderColor0: '#00da3c'
|
||
}
|
||
}],
|
||
|
||
},
|
||
option1:{
|
||
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',
|
||
formatter: function (params) {
|
||
console.log(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]+'%'
|
||
return res;
|
||
},
|
||
},
|
||
grid: {
|
||
top: '10%',
|
||
left: '12%',
|
||
right: '14%',
|
||
bottom: '10%'
|
||
},
|
||
xAxis: {
|
||
type:'category',
|
||
scale:true
|
||
},
|
||
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+(60+8)/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);
|
||
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
|
||
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)
|
||
valueData.push([item.time,item.close,item.high,item.open,item.low,rate])
|
||
}
|
||
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
|
||
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">
|
||
.topBg
|
||
{
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: auto;
|
||
}
|
||
.tabC
|
||
{
|
||
background-color: white;
|
||
margin-top: 10rpx;
|
||
left: 0;
|
||
right: 0;
|
||
border-radius: 20rpx 20rpx 0 0;
|
||
.item
|
||
{
|
||
display: inline-block;
|
||
padding: 0 30rpx;
|
||
line-height: 60rpx;
|
||
font-size: 28rpx;
|
||
font-weight: 500;
|
||
color: #42485B;
|
||
}
|
||
.item.select
|
||
{
|
||
font-weight: bold;
|
||
color: #F97316;
|
||
.line
|
||
{
|
||
background-color: #F97316;
|
||
left: calc((100% - 50rpx)/2);
|
||
bottom: 0;
|
||
width: 50rpx;
|
||
height: 2rpx;
|
||
}
|
||
}
|
||
}
|
||
.contentC
|
||
{
|
||
background-color: white;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
overflow-y: scroll;
|
||
.section
|
||
{
|
||
padding: 0 28rpx;
|
||
line-height: 80rpx;
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #222;
|
||
}
|
||
.des
|
||
{
|
||
padding: 0 0 30rpx;
|
||
margin: 0 25rpx;
|
||
border-bottom: solid 1rpx #E4E4E4;
|
||
line-height: 1.4rem;
|
||
font-size: 24rpx;
|
||
font-weight: 500;
|
||
color: #666;
|
||
.ai
|
||
{
|
||
color: #C00000;
|
||
}
|
||
}
|
||
.list
|
||
{
|
||
padding: 0 25rpx;
|
||
.item
|
||
{
|
||
background-color: #F8F8F8;
|
||
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>
|