8.28 修改事件详情相关概念模块样式,增加股票详情信息来源展示

This commit is contained in:
尚政杰
2025-08-28 17:42:22 +08:00
parent 58b3414bdd
commit bf2388c3ec
403 changed files with 19843 additions and 1602 deletions

View File

@@ -1,12 +1,6 @@
<template>
<view>
<navBar leftText="相关概念详情"></navBar>
<image class="topBg absolute" src="/static/image/mine/myTopBg.png" mode="widthFix"></image>
<view class="conceptDetailsC fixed" :style="'top:'+navH+'px;'">
<view class="title">外骨骼机器人(250501)</view>
<view class="time">2025-05-08 08:43</view>
<view class="content">四部门联合启动的人力资源服务业与制造业融合发展试点主要目的是推动人力资源服务向高端制造渗透促进产业升级而外骨骼机器人属于高端制造领域的重要创新产品之一其发展需要人力资源服务业的支持例如技术人才的输送产业工人培训等同时外骨骼机器人在消费级市场的推广和应用也符合制造业与服务业融合发展的方向因此该政策试点对外骨骼机器人行业具有潜在利好影响</view>
</view>
<web-view :src="url"></web-view>
</view>
</template>
@@ -16,7 +10,14 @@
export default {
data() {
return {
navH:inject('navHeight')
navH:inject('navHeight'),
url:''
}
},
onLoad(e) {
if(e.name)
{
this.url = 'https://valuefrontier.cn/htmls/'+e.name+'.html'
}
},
methods: {

View File

@@ -28,22 +28,44 @@
<view class="code">{{item.stock_code}}</view>
</view>
<view class="flex1">
<view style="width:140rpx; height:100rpx">
<l-echart :ref="'chartRef'+index"></l-echart>
</view>
</view>
<view class="price flex1">{{item.trade_data.open_price}}</view>
<view class="price flex1">{{item.trade_data.latest_price}}</view>
<view :class="'chg flex1 '+(getRateUpOrDown(item.trade_data.change_pct)?'down':'up')">{{item.trade_data.change_pct}}%</view>
<view class="price flex1">{{item.trade_data?item.trade_data.open_price:''}}</view>
<view class="price flex1">{{item.trade_data?item.trade_data.latest_price:''}}</view>
<view :class="'chg flex1 '+(getRateUpOrDown(item.trade_data?item.trade_data.change_pct:'')?'down':'up')">{{item.trade_data?item.trade_data.change_pct:''}}%</view>
</view>
<view class="content">{{item.relation_desc}}</view>
</view>
</view>
<view v-if="selectCategory==1" class="conceptList">
<view class="item relative" v-for="(item,index) in conceptList" :key="index" @click="clickConceptItem()">
<image class="cover" :src="item.first_image" mode="aspectFill"></image>
<view class="infoC absolute">
<view v-if="selectCategory==1" class="conceptList flexWrap">
<view class="conceptItem" v-for="(item,index) in conceptList" :key="index" @click="clickConceptItem(item.concept)">
<view class="coverC relative">
<image class="cover" src="" mode="aspectFill"></image>
<view :class="'rateC absolute '+(getRateUpOrDown(item.price_info.avg_change_pct)?'down':'up')">
<image v-if="getRateUpOrDown(item.price_info.avg_change_pct)" class="icon" src="/static/icon/home/conceptDownArrow.png" mode="widthFix"></image>
<image v-else class="icon" src="/static/icon/home/conceptUpArrow.png" mode="widthFix"></image>
<text>{{getRateStr(item.price_info.avg_change_pct)}}%</text>
</view>
<view class="totalC absolute">{{item.stock_count}}只股票</view>
</view>
<view class="infoC">
<view class="title">{{item.concept}}</view>
<view class="content relative">{{item.reason}}
<text class="lookDetails absolute">查看详情</text>
<view class="content">{{item.description}}</view>
<view class="transactionDate">交易日期: {{item.price_info.trade_date}}</view>
<view class="hotStockC">
<view class="titleC flex">
<text class="flex1">热门个股</text>
<image class="arrow" src="/static/icon/home/stockArrow.png" mode="widthFix"></image>
</view>
<view class="stockList flexWrap">
<view class="item" v-for="(item,index) in item.stocks" :key="index">{{item.stock_name}}</view>
</view>
</view>
<view class="dateHistoryTimeC flex">
<view class="date flex1">{{item.happened_times[0]+(item.happened_times.length>1?('(共'+item.happened_times.length+'次)'):'')}}</view>
<view class="historyTimeC">历史时间轴</view>
</view>
</view>
</view>
@@ -65,7 +87,7 @@
<view class="eventInfoC flex1">
<view class="titleCorrelationC flex">
<view class="title flex1">{{item.title}}</view>
<view class="correlation">相关度: 98%</view>
<view class="correlation">相关度: {{item.relevance*10}}%</view>
</view>
<view class="content">{{item.content}}</view>
<scroll-view scroll-x class="increaseRateList">
@@ -122,30 +144,30 @@
</view>
</view>
<view class="list">
<view class="item">
<view class="item" v-for="(item,index) in commentList" :key="index">
<view class="originComment">
<image class="avatar" src="" mode="aspectFill"></image>
<image class="avatar" :src="item.user.avatar_url" mode="aspectFill"></image>
<view class="flex1">
<view class="nickname">逸尘破晓</view>
<view class="content">四部门联合启动的人力资源服务业与制造业融合发展点主要目的是推动人力资源服务向高端制造渗透</view>
<view class="nickname">{{item.user.username}}</view>
<view class="content">{{item.content}}</view>
<view class="timeReplyLikeC flex between">
<view class="timeReplyC flex">
<view class="time">15:37</view>
<view class="reply">回复</view>
<view class="time">{{getLocaleHourMinute(item.created_at)}}</view>
<view class="reply" @click.stop="clickReplyComment(item.post_id)">回复</view>
</view>
<view class="likeC flex">
<view class="likeC flex" @click.stop="clickLikeComment(item.post_id,index,-1)">
<image class="icon" src="/static/icon/home/like.png" mode="widthFix"></image>
<view class="num">85</view>
<view class="num">{{item.likes_count}}</view>
</view>
</view>
<view class="totalCommentNumC flex">
<!-- <view class="totalCommentNumC flex">
<view class="line"></view>
全部34条评论
<image class="arrow" src="/static/icon/home/commentArrow.png" mode="widthFix"></image>
</view>
</view> -->
</view>
</view>
<view class="replyList">
<!-- <view class="replyList">
<view class="replyItem">
<image class="avatar" src="" mode="aspectFill"></image>
<view class="flex1">
@@ -156,19 +178,19 @@
<view class="time">15:37</view>
<view class="reply">回复</view>
</view>
<view class="likeC flex">
<view class="likeC flex" @click.stop="clickLikeComment(item.post_id)">
<image class="icon" src="/static/icon/home/like.png" mode="widthFix"></image>
<view class="num">85</view>
</view>
</view>
</view>
</view>
</view>
</view> -->
</view>
</view>
<view class="popBottomC">
<view class="inputC">
<input type="text" placeholder="我来说两句..." placeholder-style="color:#666"/>
<input type="text" v-model="replyComment" :focus="isFocus" placeholder="我来说两句..." placeholder-style="color:#666" confirm-type="send" @confirm="sendReplyComment()"/>
</view>
</view>
</view>
@@ -197,7 +219,7 @@
</view>
<view class="sectorRateC">
<view class="sector">{{item.sector}}</view>
<view class="rateC">
<view :class="'rateC '+(getRateUpOrDown(item.daily_change)?'down':'up')">
当日涨幅:
<image v-if="getRateUpOrDown(item.daily_change)" class="arrow" src="/static/icon/home/downArrow.png" mode="widthFix"></image>
<image v-else class="arrow" src="/static/icon/home/upArrow.png" mode="widthFix"></image>
@@ -214,8 +236,9 @@
<script>
import { inject } from 'vue';
import { eventRelatedConcept, eventHistoryEvent, eventRelatedStock, eventCommentList, commentEvent } from '@/request/api';
import { getLocaleTime, getRateStr, getRateUpOrDown } from '@/utils/util';
import { eventRelatedConcept, eventHistoryEvent, eventRelatedStock, eventCommentList, commentEvent, likeEventComment, replyComment, followEvent } from '@/request/api';
import { getLocaleHourMinute, getLocaleTime, getRateStr, getRateUpOrDown } from '@/utils/util';
const echarts = require('../../../uni_modules/lime-echart/static/echarts.min.js');
export default {
data() {
@@ -224,19 +247,81 @@
windowWidth:inject('windowWidth'),
eventId:'', //事件id
eventDetails:null, //事件详情
categoryList:['相关标的','相关概念','历史事件','时间传导链分析','关联数据'],
categoryList:['相关标的','相关概念','历史事件'],
targetList:[], //相关标的
conceptList:[], //相关概念
historyEventList:[], //历史事件
historyEventRelatedStockList:[], //历史事件相关股票
selectCategory:0,
headingList:['名称代码','分时图','开盘价','最新价','涨跌幅'],
getLocaleHourMinute:getLocaleHourMinute,
getLocaleTime:getLocaleTime,
getRateUpOrDown:getRateUpOrDown,
getRateStr:getRateStr,
scoreTop:'',
eventComment:'', //事件评论
expectScore:0, //预期得分
commentList:[], //评价列表
eventComment:'', //事件评论内容
replyId:'', //回复评论id
replyPid:'', //回复评论父级id
isFocus:false, //是否获取焦点
replyComment:'', //评论回复内容
option:{
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
confine: true
},
grid:{
left: '0%',
right: '0%',
top: '0%',
bottom: '20%',
},
xAxis: [
{
type: 'category',
data: [],
axisTick:{
show:false
},
axisLine:{
show:false
},
}
],
yAxis: [
{
type: 'value',
show:false,
axisTick: { show: false },
scale:true
}
],
series: {
name: '分时图',
type: 'line',
label: {
show:true,
position:'top',
fontSize:12,
},
data: [],
itemStyle:{
color:''
},
markLine:{
symbol:['none','none'],
lineStyle:{
color:'#AAAAAA',
type:'dashed'
},
data:[]
}
}
},
}
},
onLoad(e)
@@ -249,6 +334,33 @@
}
},
methods: {
async init() {
// chart 图表实例不能存在data里
let that = this
setTimeout(function() {
that.targetList.map(function(item,index) {
const chartDom = that.$refs['chartRef'+index][0]
chartDom.init(echarts).then(res=>{
let option = {...that.option}
let valueData = []
for (let item1 of item.minute_chart_data) {
valueData.push(item1.close)
}
option.series.data = valueData
let firstOpen = item.minute_chart_data[0].open
option.series.markLine.data = [{yAxis:firstOpen}]
// console.log(option.series.markLine.data)
let lastClose = item.minute_chart_data.slice(-1)[0].close
if(lastClose>=firstOpen)
{
option.series.itemStyle.color = '#EF5350'
}else
option.series.itemStyle.color = '#26A69A'
res.setOption(option)
})
})
}, 300);
},
/**
* 点击切换分类
*/
@@ -278,16 +390,16 @@
clickStockItem(code)
{
uni.navigateTo({
url:'/pages/index/stockDetails/stockDetails?code='+code
url:'/pages/index/stockDetails/stockDetails?type=1&code='+code+'&id='+this.eventId
})
},
/**
* 点击查看相关概念
*/
clickConceptItem()
clickConceptItem(name)
{
uni.navigateTo({
url:'/pages/index/conceptDetails/conceptDetails'
url:'/pages/index/conceptDetails/conceptDetails?name='+name
})
},
/**
@@ -330,7 +442,14 @@
let eventId = this.eventId
let param = {content:this.eventComment}
commentEvent(eventId,param).then(res=>{
uni.showToast({
title:res.message,
icon:'none'
})
let that = this
setTimeout(function() {
that.getEventCommentListData()
}, 1000);
}).catch(error=>{
})
@@ -364,6 +483,61 @@
})
},
/**
* 点击回复评论
*/
clickReplyComment(id,pid)
{
this.replyId = id
if(pid)
{
this.replyPid = pid
}
this.isFocus = true
},
sendReplyComment()
{
if(!this.replyComment)
{
uni.showToast({
title:'请输入评论内容',
icon:'none'
})
return
}
let param = {content:this.replyComment}
if(this.replyPid)
{
param.parent_id = this.replyPid
}
replyComment(this.replyId,param).then(res=>{
}).catch(error=>{
})
},
/**
* 点赞评论
*/
clickLikeComment(id,index,cindex)
{
likeEventComment(id).then(res=>{
uni.showToast({
title:res.message,
icon:'none'
})
if(cindex==-1)
{
//一级评论回复
this.commentList[index].likes_count = res.likes_count
}else
{
}
}).catch(error=>{
})
},
/**
* 获取事件相关标的数据
*/
@@ -375,6 +549,7 @@
{
this.eventDetails = res.data
this.targetList = res.data.related_stocks
this.init()
}else
uni.showToast({
title:res.message,
@@ -389,16 +564,17 @@
*/
getEventRelatedConceptData()
{
let eventId = this.eventId
eventRelatedConcept(eventId).then(res=>{
if(res.code==200)
{
this.conceptList = res.data.related_concepts
}else
uni.showToast({
title:res.message,
icon:'none'
})
let eventDetails = this.eventDetails
let param = {query:eventDetails.event_title,size:4,page:1,sort_by:"_score",isJson:1}
eventRelatedConcept(param).then(res=>{
// if(res.code==200)
// {
this.conceptList = res.results
// }else
// uni.showToast({
// title:res.message,
// icon:'none'
// })
}).catch(error=>{
})
@@ -430,7 +606,7 @@
{
let eventId = this.eventId
eventCommentList(eventId).then(res=>{
this.commentList = res.data.comments
this.commentList = res.data.posts
}).catch(error=>{
})
@@ -581,29 +757,64 @@
.conceptList
{
padding: 30rpx 25rpx;
.item
.conceptItem
{
margin-bottom: 20rpx;
.cover
box-shadow: 0px 3px 6px 0px rgba(0,0,0,0.05);
margin: 0 30rpx 30rpx 0;
width: calc((100% - 30rpx)/2);
border-radius: 10rpx;
.coverC
{
display: block;
width: 100%;
height: 350rpx;
border-radius: 10rpx;
.cover
{
display: block;
width: 100%;
height: 220rpx;
}
.rateC
{
top: 12rpx;
left: 12rpx;
padding: 0 10rpx;
line-height: 40rpx;
border-radius: 20rpx;
font-size: 18rpx;
font-weight: 500;
color: white;
.icon
{
width: 11rpx;
height: auto;
}
}
.rateC.up
{
background-color: #E53E3E;
}
.rateC.down
{
background-color: #38A169;
}
.totalC
{
background: linear-gradient(-90deg, #FAC915 0%, #F18D10 100%);
top: 12rpx;
right: 12rpx;
padding: 0 9rpx;
line-height: 40rpx;
border-radius: 20rpx;
font-size: 20rpx;
color: white;
}
}
.infoC
{
background: linear-gradient(to bottom,#00000080,#000);
padding: 20rpx 23rpx;
left:0;
width: 100%;
bottom: 0;
border-radius: ;
color: white;
.title
{
font-size: 26rpx;
font-weight: bold;
color: #222;
}
.content
{
@@ -612,17 +823,76 @@
-webkit-box-orient: vertical;
overflow: hidden;
margin-top: 10rpx;
line-height: 1.2rem;
font-size: 20rpx;
font-weight: 500;
line-height: 1.2rem;
.lookDetails
color: #666;
}
.transactionDate
{
margin-top: 12rpx;
font-size: 22rpx;
font-weight: 500;
color: #AAA;
}
.hotStockC
{
background-color: #F7FAFC;
margin-top: 16rpx;
padding: 10rpx 13rpx;
border-radius: 5rpx;
.titleC
{
right: 0;
color: #F97316;
font-size: 20rpx;
font-weight: 500;
color: #666;
.arrow
{
width: 6rpx;
height: auto;
}
}
.stockList
{
margin-top: 10rpx;
height: 35rpx;
overflow: hidden;
.item
{
background-color: #FFEADC;
margin: 0 5rpx 5rpx 0;
padding: 0 9rpx;
line-height: 30rpx;
border-radius: 5rpx;
font-size: 18rpx;
font-weight: 500;
color: #F97316;
}
}
}
.dateHistoryTimeC
{
margin-top: 10rpx;
font-size: 20rpx;
.date
{
color: #666;
}
.historyTimeC
{
background-color: #F97316;
padding: 0 6rpx;
line-height: 38rpx;
border-radius: 5rpx;
color: white;
}
}
}
}
.conceptItem:nth-child(2n)
{
margin-right: 0;
}
}
.historyEventList
{
@@ -1104,7 +1374,6 @@
}
.rateC
{
background-color: #C00000;
display: inline-block;
padding: 0 10rpx;
height: 30rpx;
@@ -1118,6 +1387,14 @@
height: auto;
}
}
.rateC.up
{
background-color: #C00000;
}
.rateC.down
{
background-color: #355422;
}
}
.content
{

View File

@@ -38,9 +38,9 @@
</scroll-view>
</view>
<scroll-view scroll-y class="eventListC fixed" :style="'top:'+listTop+'px'" @scrolltolower="loadMoreData()">
<!-- <view style="width:750rpx; height:400rpx">
<view style="width:750rpx; height:400rpx">
<l-echart ref="chartRef"></l-echart>
</view> -->
</view>
<view class="list">
<view class="item" @click="clickEventItem(item.id)" v-for="(item,index) in eventList" :key="index">
<view class="flex">
@@ -69,7 +69,7 @@
</view>
</scroll-view>
<scroll-view scroll-x class="stockList">
<view class="stockItem" v-for="(sitem,sindex) in item.related_stocks" :key="sindex" @click.stop="clickLookRelatedStockItem(sitem.stock_code)">{{sitem.stock_name}} <text class="change">{{(getRateUpOrDown(sitem.daily_change)?'':'+')+sitem.daily_change}}%</text></view>
<view class="stockItem" v-for="(sitem,sindex) in item.related_stocks" :key="sindex" @click.stop="clickLookRelatedStockItem(item.id,sitem.stock_code)">{{sitem.stock_name}} <text class="change">{{(getRateUpOrDown(sitem.daily_change)?'':'+')+sitem.daily_change}}%</text></view>
</scroll-view>
<view class="timeToolBarC flex">
<view class="time flex1">{{getLocaleTime(item.created_at)}}</view>
@@ -159,27 +159,78 @@
<block v-if="selectScreenCategory==1">
<view class="section">选择体系</view>
<view class="industryCategoryC flexWrap">
<view :class="'item '+(selectIndustryTopCategory==index?'select':'')" v-for="(item,index) in industryTopCategoryList" :key="index" @click="clickSelectIndustryTopCategoryItem(index)">
<view :class="'item '+(selectIndustryTopCategory==index?'select':'')" v-for="(item,index) in industryCategoryList" :key="index" @click="clickIndustryTopCategoryItem(index)">
{{item.classification_name}}
</view>
</view>
<view class="industrySearchC flex">
<image class="icon" src="/static/icon/home/search.png" mode="widthFix"></image>
<input class="flex1" type="text" placeholder="搜索行业" placeholder-style="color:#94989A"/>
<input class="flex1" type="text" v-model="industryKeywords" placeholder="搜索行业" placeholder-style="color:#94989A" @input="industrySearch"/>
</view>
<view class="industryList">
<view class="selectCategoryList flexWrap">
<view v-if="industryKeywords.length>0" class="searchResultList">
<block v-for="(item,index) in searchResultList" :key="index">
<block v-for="(sitem,sindex) in item.hierarchy" :key="sindex">
<block v-for="(titem,tindex) in sitem.level2_sectors" :key="tindex">
<block v-for="(fitem,findex) in titem.level3_sectors" :key="findex">
<view class="item" @click="clickIndustrySearchItem(fitem)">
<text :class="industryKeywords.indexOf(citem)>-1?'key':''" v-for="(citem,cindex) in (fitem.level3_sector+'/'+titem.level2_sector+'/'+sitem.level1_sector)" :key="cindex">{{citem}}</text>
</view>
</block>
</block>
</block>
</block>
</view>
<view v-else class="industryList">
<view v-if="selectIndustrySecondCategory>-1" class="selectCategoryList flexWrap">
<view v-if="selectIndustrySecondCategory>-1" class="item flex" @click="deleteIndustrySecondCategoryItem()">
{{industryCategoryList[selectIndustryTopCategory].hierarchy[selectIndustrySecondCategory].level1_sector}}
<view class="deleteC">
<image class="icon" src="/static/icon/home/delete.png"></image>
</view>
</view>
<view v-if="selectIndustryThirdCategory>-1" class="item flex" @click="deleteIndustryThirdCategoryItem()">
{{industryCategoryList[selectIndustryTopCategory].hierarchy[selectIndustrySecondCategory].level2_sectors[selectIndustryThirdCategory].level2_sector}}
<view class="deleteC">
<image class="icon" src="/static/icon/home/delete.png"></image>
</view>
</view>
<view v-if="selectIndustryForthCategory>-1" class="item flex" @click="deleteIndustryForthCategoryItem()">
{{industryCategoryList[selectIndustryTopCategory].hierarchy[selectIndustrySecondCategory].level2_sectors[selectIndustryThirdCategory].level3_sectors[selectIndustryForthCategory].level3_sector}}
<view class="deleteC">
<image class="icon" src="/static/icon/home/delete.png"></image>
</view>
</view>
</view>
<view class="list">
<view class="topCategory">{{industryTopCategoryList[selectIndustryTopCategory].classification_name}}</view>
<view class="topCategory">{{industryCategoryList[selectIndustryTopCategory].classification_name}}</view>
<view class="secondList">
<view class="secondItem">
<view class="thirdList">
<view class="thirdItem">
</view>
<view class="secondItem" v-for="(sitem,sindex) in industryCategoryList[selectIndustryTopCategory].hierarchy" :key="sindex">
<view :class="'categoryC flex '+(selectIndustrySecondCategory==sindex?'select':'')" @click.stop="clickIndustrySecondCategoryItem(sindex)">
<view class="spread">{{(selectIndustrySecondCategory==sindex&&sitem.isSpread)?'-':'+'}}</view>
<view class="category">{{sitem.level1_sector}}</view>
</view>
<block v-if="sitem.isSpread">
<view class="thirdList" v-for="(titem,tindex) in industryCategoryList[selectIndustryTopCategory].hierarchy[sindex].level2_sectors" :key="tindex">
<view class="thirdItem">
<view :class="'categoryC flex '+(selectIndustrySecondCategory==sindex&&selectIndustryThirdCategory==tindex?'select':'')" @click.stop="clickIndustryThirdCategoryItem(sindex,tindex)">
<view class="spread">{{(selectIndustrySecondCategory==sindex&&selectIndustryThirdCategory==tindex&&titem.isSpread)?'-':'+'}}</view>
<view class="category">{{titem.level2_sector}}</view>
</view>
<block v-if="titem.isSpread">
<view class="forthList" v-for="(fitem,findex) in industryCategoryList[selectIndustryTopCategory].hierarchy[sindex].level2_sectors[tindex].level3_sectors" :key="findex">
<view class="forthItem" @click.stop="clickIndustryForthCategoryItem(sindex,tindex,findex)">
<view :class="'categoryC flex '+(selectIndustrySecondCategory==sindex&&selectIndustryThirdCategory==tindex&&selectIndustryForthCategory==findex?'select':'')">
<view class="category flex1">{{fitem.level3_sector}}</view>
<view v-if="selectIndustrySecondCategory==sindex&&selectIndustryThirdCategory==tindex&&selectIndustryForthCategory==findex" class="selectC">
<image class="icon" src="/static/icon/home/industry_s.png" mode="widthFix"></image>
</view>
</view>
</view>
</view>
</block>
</view>
</view>
</block>
</view>
</view>
</view>
@@ -217,7 +268,6 @@
menuH: inject('menuHeight'),
navH:inject('navHeight'),
windowWidth:inject('windowWidth'),
contentTop:'',
listTop:'',
sortListTop:'',
@@ -243,8 +293,13 @@
monthDateList:[],
selectMonthIndex:0, //选中月份下标
selectMonth:'', //选中年月
industryTopCategoryList:[], //行业一级分类
selectIndustryTopCategory:0, //
industryCategoryList:[], //行业分类数组
industryKeywords:'', //行业分类搜索关键词
searchResultList:[], //行业分类搜索结果数组
selectIndustryTopCategory:0, //选中行业一级分类
selectIndustrySecondCategory:-1, //选中行业二级分类
selectIndustryThirdCategory:-1, //选中行业三级分类
selectIndustryForthCategory:-1, //选中行业四级分类
selectScreenCategory:0,
importanceList:[], //重要性数组
selectImportanceIndex:0, //选择重要性下标
@@ -259,7 +314,7 @@
grid:{
left: '0%',
right: '0%',
top: '0%',
top: '10%',
bottom: '20%',
},
xAxis: [
@@ -299,71 +354,10 @@
position:'top',
fontSize:12,
},
data: [
{
value:0,
itemStyle: {color:'#355422'},
label:{
textStyle: {color:'#355422'},
},
},
{
value:44,
itemStyle: {color:'#35542299'},
label:{
textStyle: {color:'#355422'},
},
},
{
value:315,
itemStyle: {color:'#355422CC'},
label:{
textStyle: {color:'#355422'},
},
},
{
value:1264,
itemStyle: {color:'#355422'},
label:{
textStyle: {color:'#355422'},
},
},
{
value:1064,
itemStyle: {color:'#ACB0C0'},
label:{
textStyle: {color:'#666'},
},
},
{
value:1809,
itemStyle: {color:'#C00000'},
label:{
textStyle: {color:'#C00000'},
},
},
{
value:602,
itemStyle: {color:'#C00000CC'},
label:{
textStyle: {color:'#C00000'},
},
},
{
value:44,
itemStyle: {color:'#C0000099'},
label:{
textStyle: {color:'#C00000'},
},
},
{
value:0,
itemStyle: {color:'#C00000'},
label:{
textStyle: {color:'#C00000'},
},
},
],
itemStyle:{
borderRadius:[5,5,0,0]
},
data: [],
}
]
},
@@ -376,14 +370,14 @@
}
},
onLoad() {
this.contentTop = this.navH + (75+20)/750*this.windowWidth
this.contentTop = this.navH + (74+20)/750*this.windowWidth
this.listTop = this.contentTop + (22+80+72)/750*this.windowWidth
this.sortListTop = this.navH + (22+80+80)/750*this.windowWidth
this.getEventFilterListData()
this.getEventListData()
this.getIndustryCategoryListData()
this.getStockCategoryListData()
// this.init()
Promise.all([this.getEventFilterListData(),this.getIndustryCategoryListData(),this.getStockCategoryListData()]).then(res=>{
this.getEventListData()
}).catch(error=>{
})
let currentDate = new Date();
// 获取当前年份
let currentYear = currentDate.getFullYear();
@@ -572,13 +566,20 @@
if(this.selectTopCategory!=index)
{
this.selectTopCategory = index
this.selectSecondCategory = 0
let offsetLeft = event.currentTarget.offsetLeft
this.topScrollLeft = offsetLeft - this.topScrollWidth/2
if(index==0)
{
this.listTop = this.contentTop + (22+80+72)/750*this.windowWidth
}else
this.listTop = this.contentTop + (22+80+72+44+44)/750*this.windowWidth
this.listTop = this.contentTop + (22+80+72+42+42)/750*this.windowWidth
if(this.selectTimeCategory==0)
{
//最新
this.getEventListData()
}else
this.getHotEventListData()
}
},
/**
@@ -592,6 +593,12 @@
this.selectSecondCategory = index
let offsetLeft = event.currentTarget.offsetLeft
this.secondScrollLeft = offsetLeft - this.secondScrollWidth/2
if(this.selectTimeCategory==0)
{
//最新
this.getEventListData()
}else
this.getHotEventListData()
}
},
/**
@@ -664,13 +671,140 @@
/**
* 选择行业分类一级分类
*/
clickSelectIndustryTopCategoryItem(index)
clickIndustryTopCategoryItem(index)
{
if(this.selectIndustryTopCategory!=index)
{
this.selectIndustryTopCategory = index
}
},
/**
* 行业分类搜索
*/
industrySearch(e)
{
let keywords = e.detail.value
this.industryKeywords = keywords
let arr = []
for (let item of this.industryCategoryList) {
let index = this.industryCategoryList.indexOf(item)
for (let item1 of item.hierarchy) {
let index1 = item.hierarchy.indexOf(item1)
let arr1 = []
if(item1.level1_sector.indexOf(keywords)>-1)
{
arr1.push(item1)
arr.push({classification_name:item.classification_name,hierarchy: arr1})
}
for (let item2 of item1.level2_sectors) {
let index2 = item1.level2_sectors.indexOf(item2)
let arr2 = []
if(item2.level2_sector.indexOf(keywords)>-1)
{
arr2.push(item2)
arr1.push({level1_sector:item1.level1_sector,level2_sectors: arr2})
arr.push({classification_name:item.classification_name,hierarchy: arr1})
}
for (let item3 of item2.level3_sectors) {
let index3 = item2.level3_sectors.indexOf(item3)
let arr3 = []
if(item3.level3_sector.indexOf(keywords)>-1)
{
item3.index = index
item3.index1 = index1
item3.index2 = index2
item3.index3 = index3
arr3.push(item3)
arr2.push({level2_sector:item2.level2_sector,level3_sectors: arr3})
arr1.push({level1_sector:item1.level1_sector,level2_sectors: arr2})
arr.push({classification_name:item.classification_name,hierarchy: arr1})
}
}
}
}
}
this.searchResultList = arr
},
/**
* 点击选择搜索结果
* @param {Object} item
*/
clickIndustrySearchItem(item)
{
this.industryKeywords = ''
this.selectIndustryTopCategory = item.index
this.selectIndustrySecondCategory = item.index1
this.selectIndustryThirdCategory = item.index2
this.selectIndustryForthCategory = item.index3
},
/**
* 选择行业分类二级分类
*/
clickIndustrySecondCategoryItem(index)
{
if(this.selectIndustrySecondCategory!=index)
{
this.selectIndustrySecondCategory = index
}
this.industryCategoryList[this.selectIndustryTopCategory].hierarchy[index].isSpread = !this.industryCategoryList[this.selectIndustryTopCategory].hierarchy[index].isSpread
},
/**
* 选择行业分类三级分类
*/
clickIndustryThirdCategoryItem(sindex,index)
{
if(this.selectIndustrySecondCategory!=sindex)
{
this.selectIndustrySecondCategory = sindex
}
if(this.selectIndustryThirdCategory!=index)
{
this.selectIndustryThirdCategory = index
}
this.industryCategoryList[this.selectIndustryTopCategory].hierarchy[sindex].level2_sectors[index].isSpread = !this.industryCategoryList[this.selectIndustryTopCategory].hierarchy[sindex].level2_sectors[index].isSpread
},
/**
* 选择行业分类四级分类
*/
clickIndustryForthCategoryItem(sindex,tindex,index)
{
if(this.selectIndustrySecondCategory!=sindex)
{
this.selectIndustrySecondCategory = sindex
}
if(this.selectIndustryThirdCategory!=tindex)
{
this.selectIndustryThirdCategory = tindex
}
if(this.selectIndustryForthCategory!=index)
{
this.selectIndustryForthCategory = index
}
},
/**
* 删除选中的行业二级分类
*/
deleteIndustrySecondCategoryItem()
{
this.selectIndustrySecondCategory = -1
this.selectIndustryThirdCategory = -1
this.selectIndustryForthCategory = -1
},
/**
* 删除选中的行业三级分类
*/
deleteIndustryThirdCategoryItem()
{
this.selectIndustryThirdCategory = -1
this.selectIndustryForthCategory = -1
},
/**
* 删除选中的行业四级分类
*/
deleteIndustryForthCategoryItem()
{
this.selectIndustryForthCategory = -1
},
/**
* 点击选择重要性
*/
@@ -691,12 +825,13 @@
},
/**
* 点击相关股票
* @param {Object} code
* @param {Object} id 事件id
* @param {Object} code 股票代码
*/
clickLookRelatedStockItem(code)
clickLookRelatedStockItem(id,code)
{
uni.navigateTo({
url:'/pages/index/stockDetails/stockDetails?code='+code
url:'/pages/index/stockDetails/stockDetails?type=1&code='+code+'&id='+id
})
},
/**
@@ -717,7 +852,7 @@
/**
* 查看事件详情
*/
clickEventItem(id)
clickEventItem(id)
{
uni.navigateTo({
url:'/pages/index/eventDetails/eventDetails?id='+id
@@ -728,48 +863,57 @@
*/
getEventFilterListData()
{
filterOptions().then(res=>{
if(res.code==200)
{
let timeList = [...res.data.sort_options]
this.timeCategoryList = timeList.splice(0,2)
let sortList = [...res.data.sort_options]
for (let item of sortList) {
if(item.name=='最新')
{
item.icon = '/static/icon/home/new.png'
}
if(item.name=='热门')
{
item.icon = '/static/icon/home/hot.png'
}
if(item.name=='收益率')
{
item.icon = '/static/icon/home/yield.png'
return new Promise((resolve,reject)=>{
filterOptions().then(res=>{
if(res.code==200)
{
resolve(1)
let timeList = [...res.data.sort_options]
this.timeCategoryList = timeList.splice(0,2)
let sortList = [...res.data.sort_options]
for (let item of sortList) {
if(item.name=='最新')
{
item.icon = '/static/icon/home/new.png'
}
if(item.name=='热门')
{
item.icon = '/static/icon/home/hot.png'
}
if(item.name=='收益率')
{
item.icon = '/static/icon/home/yield.png'
}
}
this.sortList = res.data.sort_options.splice(0,3)
this.importanceList = res.data.importance_options
this.importanceList.unshift({desc: "全部",key: "all",name: "全部"})
}else
{
reject(1)
uni.showToast({
title:res.message,
icon:'none'
})
}
this.sortList = res.data.sort_options.splice(0,3)
this.importanceList = res.data.importance_options
this.importanceList.unshift({desc: "全部",key: "all",name: "全部"})
}else
uni.showToast({
title:res.message,
icon:'none'
})
}).catch(error=>{
}).catch(error=>{
reject(1)
})
})
},
/**
* 获取行业分类
*/
getIndustryCategoryListData()
{
industryCategoryList().then(res=>{
this.industryTopCategoryList = res.data
}).catch(error=>{
return new Promise((resolve,reject)=>{
industryCategoryList().then(res=>{
this.industryCategoryList = res.data
resolve(1)
}).catch(error=>{
reject(1)
})
})
},
/**
@@ -777,21 +921,27 @@
*/
getStockCategoryListData()
{
stockCategoryList().then(res=>{
if(res.code==200)
{
for (let item of res.data) {
item.sub_sectors.unshift('全部')
return new Promise((resolve,reject)=>{
stockCategoryList().then(res=>{
if(res.code==200)
{
for (let item of res.data) {
item.sub_sectors.unshift('全部')
}
res.data.unshift({primary_sector:'全部',sub_sectors:[]})
this.stockCategoryList = res.data
resolve(1)
}else
{
uni.showToast({
title:res.message,
icon:'none'
})
reject(1)
}
res.data.unshift({primary_sector:'全部',sub_sectors:[]})
this.stockCategoryList = res.data
}else
uni.showToast({
title:res.message,
icon:'none'
})
}).catch(error=>{
}).catch(error=>{
reject(1)
})
})
},
/**
@@ -799,7 +949,15 @@
*/
getEventListData()
{
let param = {page:this.page,keywords:this.keywords}
let param = {page:this.page,q:this.keywords}
if(this.selectTopCategory>0)
{
param.stock_sector = this.stockCategoryList[this.selectTopCategory].primary_sector
}
if(this.selectSecondCategory>0)
{
param.secondary_sector = this.stockCategoryList[this.selectTopCategory].sub_sectors[this.selectSecondCategory]
}
if(this.startDate)
{
param.start_date = this.startDate
@@ -816,42 +974,143 @@
{
param.sort = this.selectSortKey
}
if(this.selectIndustryForthCategory>-1)
{
param.industry_level = 4
param.industry_classification = this.industryCategoryList[this.selectIndustryTopCategory].hierarchy[this.selectIndustrySecondCategory].level2_sectors[this.selectIndustryThirdCategory].level3_sectors[this.selectIndustryForthCategory].level3_sector
}else
{
if(this.selectIndustryThirdCategory>-1)
{
param.industry_level = 3
param.industry_classification = this.industryCategoryList[this.selectIndustryTopCategory].hierarchy[this.selectIndustrySecondCategory].level2_sectors[this.selectIndustryThirdCategory].level2_sector
}else
{
if(this.selectIndustrySecondCategory>-1)
{
param.industry_level = 2
param.industry_classification = this.industryCategoryList[this.selectIndustryTopCategory].hierarchy[this.selectIndustrySecondCategory].level1_sector
}else
{
param.industry_level = 1
param.industry_classification = this.industryCategoryList[this.selectIndustryTopCategory].classification_name
}
}
}
eventList(param).then(res=>{
if(res.success)
{
let valueData = []
let data = res.data.overall_stats.change_distribution
valueData.push({
value:data.limit_down,
itemStyle: {color:'#35542266'},
label:{
textStyle: {color:'#35542266'},
},
})
valueData.push({
value:data.down_over_5,
itemStyle: {color:'#35542299'},
label:{
textStyle: {color:'#355422'},
},
},)
valueData.push({
value:data.down_5_to_1,
itemStyle: {color:'#355422CC'},
label:{
textStyle: {color:'#355422'},
},
})
valueData.push({
value:data.down_within_1,
itemStyle: {color:'#355422'},
label:{
textStyle: {color:'#355422'},
},
})
valueData.push({
value:data.flat,
itemStyle: {color:'#ACB0C0'},
label:{
textStyle: {color:'#666'},
},
},)
valueData.push({
value:data.up_within_1,
itemStyle: {color:'#C00000'},
label:{
textStyle: {color:'#C00000'},
},
})
valueData.push({
value:data.up_1_to_5,
itemStyle: {color:'#C00000CC'},
label:{
textStyle: {color:'#C00000'},
}
})
valueData.push({
value:data.up_over_5,
itemStyle: {color:'#C0000099'},
label:{
textStyle: {color:'#C00000'},
}
})
valueData.push({
value:data.limit_up,
itemStyle: {color:'#C0000066'},
label:{
textStyle: {color:'#C0000066'},
}
})
this.option.series[0].data = valueData
this.init()
if(this.page==1)
{
this.eventList = res.data.events
}else
this.eventList = this.eventList.concat(res.data.events)
this.loadAll = !res.data.pagination.has_next
}
}).catch(error=>{
})
let token = uni.getStorageSync('token')
if(!token)
{
let param1 = {email:'1198731706@qq.com',password:'Aa123456',isJson:1}
loginByEmail(param1).then(res=>{
if (res.code==200) {
uni.setStorageSync('token',res.data.token)
} else
uni.showToast({
title:res.message,
icon:'none'
})
}).catch(error=>{
})
}
},
/**
* 获取热门事件数据
*/
getHotEventListData()
{
homeData().then(res=>{
let param = {page:this.page,q:this.keywords}
if(this.selectTopCategory>0)
{
param.stock_sector = this.stockCategoryList[this.selectTopCategory].primary_sector
}
if(this.selectSecondCategory>0)
{
param.secondary_sector = this.stockCategoryList[this.selectTopCategory].sub_sectors[this.selectSecondCategory]
}
if(this.startDate)
{
param.start_date = this.startDate
}
if(this.endDate)
{
param.end_date = this.endDate
}
if(this.selectImportanceIndex>0)
{
param.importance = this.importanceList[this.selectImportanceIndex].key
}
if(this.selectSortKey)
{
param.sort = this.selectSortKey
}
homeData(param).then(res=>{
if(res.code==200)
{
if(this.page==1)
@@ -1405,18 +1664,119 @@
height: auto;
}
}
.searchResultList
{
.item
{
padding: 10rpx 44rpx;
font-size: 26rpx;
font-weight: 500;
color: #444;
.key
{
color: #F97316;
}
}
}
.industryList
{
margin-top: 24rpx;
.selectCategoryList
{
padding: 0 22rpx;
.item
{
background-color: #FFF1E7;
margin-right: 15rpx;
padding-left: 16rpx;
line-height: 38rpx;
border-radius: 10rpx;
border: solid .5px #F97316;
font-size: 22rpx;
font-weight: 500;
color: #F97316;
.deleteC
{
padding: 0 11rpx;
.icon
{
width: 15rpx;
height: 15rpx;
}
}
}
}
.list
{
margin-top: 20rpx;
.topCategory
{
padding: 0 30rpx;
padding: 0 22rpx;
font-size: 28rpx;
font-weight: bold;
color: #F97316;
}
.secondItem
{
padding: 0 22rpx;
}
.thirdItem
{
padding-left: 36rpx;
}
.forthItem
{
padding-left: 36rpx;
.categoryC.select
{
border-bottom: solid .5px #F97316;
}
}
.categoryC
{
height: 50rpx;
.spread
{
margin-right: 12rpx;
width: 24rpx;
line-height: 22rpx;
border: solid .5px #8C8C8C;
font-size: 22rpx;
color: #8C8C8C;
text-align: center;
}
.category
{
font-size: 24rpx;
font-weight: 500;
color: #444;
}
}
.categoryC.select
{
.spread
{
color: #F97316;
border: solid .5px #F97316;
}
.category
{
color: #F97316;
}
.selectC
{
width: 24rpx;
height: 24rpx;
border: solid .5px #F97316;
.icon
{
display: block;
width: 20rpx;
height: auto;
}
}
}
}
}
.importanceList

View File

@@ -2,18 +2,29 @@
<view>
<navBar :leftText="navTitle"></navBar>
<image class="topBg absolute" src="/static/image/mine/myTopBg.png" mode="widthFix"></image>
<view class="tabC fixed" :style="'top:'+navH+'px;'">
<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" :style="'top:'+contentTop+'px;'">
<view style="width:750rpx; height:400rpx">
<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">全球原油运输巨头VLCC运力规模全球第一直接受益于霍尔木兹海峡地缘风险带来的运价上涨及风险溢价</view>
<view class="des">{{relatedDesc}}</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>
@@ -21,6 +32,7 @@
<script>
import { inject } from 'vue';
import { stockCandlestickChartData, stockDetails } from '@/request/api';
import { getLocalDate } from '@/utils/util.js';
const echarts = require('../../../uni_modules/lime-echart/static/echarts.min.js');
export default {
@@ -29,18 +41,33 @@
navH:inject('navHeight'),
contentTop:'',
navTitle:'',
type:'', //1事件详情2投资详情
eventId:'', //事件id
stockCode:'', //股票code
categoryList:['分钟线','分时图','日K线'],
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]
console.log(res)
return res; // 经过这么一加工,最终返回出去并渲染,最终就出现了我们所看的效果
},
},
legend: {
show:false
@@ -81,117 +108,90 @@
],
series: [
{
name: '日K',
type: 'candlestick',
data: [],
itemStyle: {
color: '#ec0000',
color0: '#8A0000',
borderColor: '#00da3c',
borderColor0: '#008F28'
},
markPoint: {
label: {
formatter: function (param) {
return param != null ? Math.round(param.value) + '' : '';
}
},
data: [
{
name: 'Mark',
coord: ['2013/5/31', 2300],
value: 2300,
itemStyle: {
color: 'rgb(41,60,85)'
}
},
{
name: 'highest value',
type: 'max',
valueDim: 'highest'
},
{
name: 'lowest value',
type: 'min',
valueDim: 'lowest'
},
{
name: 'average value on close',
type: 'average',
valueDim: 'close'
}
],
tooltip: {
formatter: function (param) {
return param.name + '<br>' + (param.data.coord || '');
}
}
},
markLine: {
symbol: ['none', 'none'],
data: [
[
{
name: 'from lowest to highest',
type: 'min',
valueDim: 'lowest',
symbol: 'circle',
symbolSize: 10,
label: {
show: false
},
emphasis: {
label: {
show: false
}
}
},
{
type: 'max',
valueDim: 'highest',
symbol: 'circle',
symbolSize: 10,
label: {
show: false
},
emphasis: {
label: {
show: false
}
}
}
],
{
name: 'min line on close',
type: 'min',
valueDim: 'close'
},
{
name: 'max line on close',
type: 'max',
valueDim: 'close'
}
]
}
name: '日K',
type: 'candlestick',
data: [],
itemStyle: {
color: '#ec0000',
color0: '#8A0000',
borderColor: '#00da3c',
borderColor0: '#008F28'
},
}
]
},
option1:{
title: {
show:false
},
tooltip: {
trigger: 'axis'
},
grid: {
left: '10%',
right: '12%',
bottom: '10%'
},
xAxis: {
type:'category'
},
yAxis: {
scale:true
},
dataZoom: [
{
type: 'inside'
}
],
series: {
name: '分时图',
type: 'line',
markLine: {
silent: true,
symbol:['none','none'],
lineStyle: {
width: 2,
color: '#AAA'
},
data: []
},
}
},
relatedDesc:'', //关联描述
sourceList:[], //来源列表
getLocalDate:getLocalDate
}
},
onLoad(e) {
this.contentTop = this.navH+(60+10)/750*inject('windowWidth')
if(e.code)
{
this.stockCode = e.code
this.getStockDetailsData()
this.getStockCandlestickChartData()
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);
chart.setOption(this.option)
if(this.selectCategory==0)
{
//分时图
chart.setOption(this.option1)
}else
chart.setOption(this.option)
},
/**
* 点击切换分类
@@ -202,10 +202,12 @@
if(this.selectCategory!=index)
{
this.selectCategory = index
if(index==0||index==2)
if(index==1)
{
//日k
this.getStockCandlestickChartData()
}
}else
this.init()
}
},
/**
@@ -214,10 +216,48 @@
getStockDetailsData()
{
let stockCode = this.stockCode
stockDetails(stockCode).then(res=>{
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 = []
for (let item of data) {
categoryData.push(item.time)
valueData.push(item.close)
}
this.option1.xAxis.data = categoryData
this.option1.series.data = valueData
this.option1.series.markLine.data = [{
yAxis:data[0].open,
label:{
show:true,
position:'start',
// formatter:'111',
color:'#333'
},
},
{
yAxis:data[0].open,
label:{
show:true,
position:'end',
formatter:'0.00%',
color:'#333'
},
}]
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,
@@ -234,17 +274,20 @@
{
let stockCode = this.stockCode
let param = {chart_type:'minute'}
if(this.selectCategory==2)
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=>{
@@ -298,6 +341,7 @@
left: 0;
right: 0;
bottom: 0;
overflow-y: scroll;
.section
{
padding: 0 28rpx;
@@ -308,11 +352,54 @@
}
.des
{
padding: 0 30rpx;
padding: 0 0 30rpx;
margin: 0 25rpx;
border-bottom: solid 1rpx #E4E4E4;
line-height: 1.4rem;
font-size: 24rpx;
font-weight: 500;
color: #666;
}
.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>

View File

@@ -4,14 +4,14 @@
<view class="navTitle fixed" :style="'top:'+menuTop+'px;line-height:'+menuH+'px;'">投资</view>
<view class="searchC fixed flex" :style="'top:'+navH+'px;'">
<image class="icon" src="/static/icon/home/search.png" mode="widthFix"></image>
<input class="flex1" type="text" placeholder="搜索话题/股票名称" placeholder-style="color:#94989A"/>
<input class="flex1" type="text" v-model="keywords" placeholder="搜索话题/股票名称" placeholder-style="color:#94989A"/>
<view class="line"></view>
<view class="search">搜索</view>
<view class="search" @click="clickSearch()">搜索</view>
</view>
<view class="contentC fixed" :style="'top:'+contentTop+'px;'">
<scroll-view scroll-y class="contentC fixed" :style="'top:'+contentTop+'px;'" @scrolltolower="loadMoreData()">
<view class="">
<view class="todayC flex" >
<view class="todayDateC flex" @click="clickExpandOrRetract()">
<view class="todayDateC flex" @click="clickSelectMonth()">
<view class="date">{{selectDate}}</view>
<image class="icon" src="/static/icon/invest/calendar.png" mode="widthFix"></image>
</view>
@@ -64,7 +64,8 @@
<view class="expandBgC flexCenter">
<view class="expandC flex" @click="clickExpandOrRetract()">
<text>{{isExpand?'收起':'展开'}}</text>
<image class="arrow" src="/static/icon/invest/downArrow.png" mode="widthFix"></image>
<image v-if="isExpand" class="arrow" src="/static/icon/invest/upArrow.png" mode="widthFix"></image>
<image v-else class="arrow" src="/static/icon/invest/downArrow.png" mode="widthFix"></image>
</view>
</view>
</view>
@@ -81,9 +82,9 @@
<view class="item" v-for="(item,index) in eventList" :key="index" @click="clickEventItem(item.id)">
<view class="flex">
<view class="time flex1">{{getLocaleHourMinute(item.start_time)}}</view>
<view class="starC relative">
<view class="starC">
<view class="starList flex" >
<image class="icon" :src="(sindex<(item.star)?'/static/icon/invest/star_s.png':'/static/icon/invest/star.png')" mode="widthFix" v-for="(sitem,sindex) in 5" :key="index"></image>
<image class="icon" :src="(sindex<(item.category.star_rating)?'/static/icon/invest/star_s.png':'/static/icon/invest/star.png')" mode="widthFix" v-for="(sitem,sindex) in 5" :key="index"></image>
</view>
</view>
</view>
@@ -91,19 +92,19 @@
<view class="category">{{item.category.event_type}}</view>
<view class="title flex1">{{item.title}}</view>
</view>
<view class="labelC">
<view class="label">
<scroll-view scroll-x class="labelC">
<view class="label" v-for="(titem,tindex) in item.tags" :key="tindex">
{{titem}}
</view>
</view>
</scroll-view>
<view class="content">
<text>{{item.description}}</text>
<ua-markdown :source="replaceAnswerLabel(item.description)" />
</view>
<scroll-view v-if="item.concepts" scroll-x class="percentList">
<view class="percentItem" v-for="(citem,cindex) in JSON.parse(item.concepts)" :key="cindex">
{{citem[0]}}
<zui-progress-circle :position="citem[2]" :range="[270,630]" :size="26" :ring-width="2" :texture="['#F97316','#E3E3E3']">
<view class="num">{{citem[2]*100}}%</view>
<scroll-view v-if="item.related_concepts" scroll-x class="percentList">
<view class="percentItem" v-for="(citem,cindex) in item.related_concepts" :key="cindex">
{{citem.name}}
<zui-progress-circle :position="citem.score" :range="[270,630]" :size="26" :ring-width="2" :texture="['#F97316','#E3E3E3']">
<view class="num">{{citem.score*100}}%</view>
</zui-progress-circle>
</view>
</scroll-view>
@@ -114,30 +115,58 @@
<view class="flex">
<view class="time flex1">{{getLocaleHourMinute(item.created_at)}}</view>
<view class="starC relative">
<view class="starBgList flex">
<image class="icon" src="/static/icon/invest/star.png" mode="widthFix" v-for="(item,index) in 5" :key="index"></image>
</view>
<view class="starList absolute flex">
<image class="icon" src="/static/icon/invest/star_s.png" mode="widthFix" v-for="(item,index) in 5" :key="index"></image>
<view class="starList flex" >
<image class="icon" :src="(sindex<(item.star)?'/static/icon/invest/star_s.png':'/static/icon/invest/star.png')" mode="widthFix" v-for="(sitem,sindex) in 5" :key="index"></image>
</view>
</view>
</view>
<view class="title">{{item.title}}</view>
<view class="valueList flex between">
<view class="pre">前值 -7.1</view>
<view class="prediction">预测 93</view>
<view class="actual">实际 </view>
<view class="pre">前值 {{item.former}}</view>
<view class="prediction">预测 {{item.forecast?item.forecast:'--'}}</view>
<view class="actual">实际 {{item.fact?item.fact:'--'}}</view>
</view>
</view>
</view>
</view>
</scroll-view>
<uni-popup ref="popup" type="top">
<view class="popup" :style="'margin-top:'+navH+'px;'">
<view class="yearMonthC flex">
<view class="preC btn flexCenter" @click="clickPreMonth()">
<image class="icon" src="/static/icon/home/monthLeftArrow.png" mode="widthFix"></image>
</view>
<view class="yearMonth flex1">{{selectMonth}}</view>
<view class="nextC btn flexCenter" @click="clickNextMonth()">
<image class="icon" src="/static/icon/home/monthRightArrow.png" mode="widthFix"></image>
</view>
</view>
<view class="weekList flex">
<view class="item flex1" v-for="(item,index) in weekList" :key="index">{{item}}</view>
</view>
<view class="monthDateList flexWrap">
<view class="item flexColumnCenter" v-for="(item,index) in calendarDateList[selectMonthIndex]" :key="index" @click="clickSelectDate(item)">
<block v-if="item.isToday||item.date==selectDate">
<view class="date today">{{item.day}}</view>
</block>
<block v-else>
<block v-if="!item.isCurrentMonth">
<view class="date notCurrentMonth">{{item.day}}</view>
</block>
<block v-else>
<view class="date">{{item.day}}</view>
</block>
</block>
</view>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import { inject } from 'vue'
import { stockCategoryList, calendarEventList, calendarDataList, calendarEventCount, } from '@/request/api'
import { getLocaleHourMinute } from '@/utils/util'
import { getLocaleHourMinute, replaceAnswerLabel } from '@/utils/util'
export default {
data() {
@@ -147,7 +176,11 @@
navH:inject('navHeight'),
windowWidth:inject('windowWidth'),
contentTop:'',
todayDate:'', //今日日期
keywords:'', //搜索关键字
todayDate:'', //今日日期
calendarDateList:[], //日历日期
selectMonth:'', //选中月份
selectMonthIndex:0, //选中月份下标
weekList:['一','二','三','四','五','六','日'],
weekDateList:[], //当前周日期
monthDateList:[], //当前月日期
@@ -162,73 +195,104 @@
progress: 75,
eventList:[], //事件列表
dataList:[], //数据列表
getLocaleHourMinute:getLocaleHourMinute
page:1,
loadAll:false,
getLocaleHourMinute:getLocaleHourMinute,
replaceAnswerLabel:replaceAnswerLabel
}
},
onLoad() {
let date = new Date()
this.contentTop = this.navH + (75+20)/750*inject('windowWidth')
let year = date.getFullYear()
let month = date.getMonth()+1
let day = date.getDate()
this.todayDate = this.selectDate = date.getFullYear()+'-'+(month>9?month:('0'+month))+'-'+(day>9?day:('0'+day))
let currentYear = date.getFullYear()
let currentMonth = date.getMonth()+1
let currentDay = date.getDate()
this.todayDate = this.selectDate = currentYear+'-'+(currentMonth>9?currentMonth:('0'+currentMonth))+'-'+(currentDay>9?currentDay:('0'+currentDay))
let week = date.getDay() || 7
let diff = week - 1
let daysOfWeek = [];
for (var i = 0; i < 7; i++) {
let newDate = new Date()
newDate.setDate(day - diff + i); // 设置日期为当前周的相应日期
newDate.setDate(currentDay - diff + i); // 设置日期为当前周的相应日期
let newDay = newDate.getDate()
let date = year+'-'+(month>9?month:('0'+month))+'-'+(newDay>9?newDay:('0'+newDay))
daysOfWeek.push({date:date,day:newDay,isToday:newDay==day?true:false});
let date = currentYear+'-'+(currentMonth>9?currentMonth:('0'+currentMonth))+'-'+(newDay>9?newDay:('0'+newDay))
daysOfWeek.push({date:date,day:newDay,isToday:newDay==currentDay?true:false});
}
this.weekDateList = daysOfWeek
let firstDayOfMonth = new Date();
firstDayOfMonth.setDate(1);
//获取当前月天数
let currentMonthDay = new Date(year, month, 0).getDate()
let firstDayWeek = firstDayOfMonth.getDay() || 7
let daysOfMonth = []
for (var i = 1; i <= currentMonthDay; i++) {
let newDate = new Date()
newDate.setDate(i); // 设置日期为当前月的相应日期
let newDay = newDate.getDate()
let date = year+'-'+(month>9?month:('0'+month))+'-'+(newDay>9?newDay:('0'+newDay))
daysOfMonth.push({date:date,day:newDay,isToday:newDay==day?true:false,isCurrentMonth:true});
}
for (var i = 0; i < firstDayWeek-1; i++) {
//获取上月天数
let lastMonthDay = new Date(year, month-1, 0).getDate()
//获取上月日期
let newDate = new Date(year,month-2,lastMonthDay-i)
let newMonth = newDate.getMonth()+1
let newDay = newDate.getDate()
let date = year+'-'+(newMonth>9?newMonth:('0'+newMonth))+'-'+(newDay>9?newDay:('0'+newDay))
daysOfMonth.unshift({date:date,day:newDay,isToday:false,isCurrentMonth:false});
}
// 下一个月的第一天
let nextMonthFirstDay = new Date(year, month, 1);
// 然后减去一天就是当前月的最后一天
let lastDayOfMonth = new Date(nextMonthFirstDay - (24 * 60 * 60 * 1000)); // 减去一天的毫秒数
let lastDayWeek = lastDayOfMonth.getDay() || 7; // 返回0星期天到6星期六
for (var i = 1; i < 8-lastDayWeek; i++) {
if(month>11)
{
month = -1
year ++
let calendarDateList = []
this.selectMonthIndex = 20*12+currentMonth-1
this.selectMonth = currentYear + '-' + (currentMonth>9?currentMonth:('0'+currentMonth))
for (var i = currentYear-20; i < currentYear+20; i++) {
for (var j = 0; j < 12; j++) {
let date = new Date(i,j+1,0)
let firstDayOfMonth = new Date(i,j+1,0);
firstDayOfMonth.setDate(1);
//获取当前月天数
let currentMonthDay = date.getDate()
let firstDayWeek = firstDayOfMonth.getDay() || 7
let daysOfMonth = []
for (var k = 1; k <= currentMonthDay; k++) {
let newDate = new Date(i,j+1,0)
newDate.setDate(k); // 设置日期为当前月的相应日期
let newMonth = newDate.getMonth()+1
let newDay = newDate.getDate()
let time = newDate.getTime()
let date = i+'-'+(newMonth>9?newMonth:('0'+newMonth))+'-'+(newDay>9?newDay:('0'+newDay))
daysOfMonth.push({date:date,year:i,month:newMonth,day:newDay,isToday:(i==currentYear&&newMonth==currentMonth&&newDay==currentDay)?true:false,isCurrentMonth:true,timestamp:time});
}
for (var k = 0; k < firstDayWeek-1; k++) {
//获取上月天数
let year = i
let month = j
if(j<1)
{
year = i - 1
month = 12
}
let lastMonthDay = new Date(year, month, 0).getDate()
//获取上月日期
let newDate = new Date(year,month-1,lastMonthDay-k)
let newMonth = newDate.getMonth()+1
let newDay = newDate.getDate()
let time = newDate.getTime()
let date = year+'-'+(newMonth>9?newMonth:('0'+newMonth))+'-'+(newDay>9?newDay:('0'+newDay))
daysOfMonth.unshift({date:date,year:year,month:newMonth,day:newDay,isToday:false,isCurrentMonth:false,timestamp:time});
}
// 下一个月的第一天
let nextMonthFirstDay = new Date(i, j+1, 1);
// 然后减去一天就是当前月的最后一天
let lastDayOfMonth = new Date(nextMonthFirstDay - (24 * 60 * 60 * 1000)); // 减去一天的毫秒数
let lastDayWeek = lastDayOfMonth.getDay() || 7; // 返回0星期天到6星期六
for (var k = 1; k < 8-lastDayWeek; k++) {
let year = i
let month = j
if(month>11)
{
month = 0
year ++
}
//获取下月日期
let newDate = new Date(year,month + 1,k)
let newMonth = newDate.getMonth()+1
let newDay = newDate.getDate()
let time = newDate.getTime()
let date = year+'-'+(newMonth>9?newMonth:('0'+newMonth))+'-'+(newDay>9?newDay:('0'+newDay))
daysOfMonth.push({date:date,year:year,month:newMonth,day:newDay,isToday:false,isCurrentMonth:false,timestamp:time});
}
calendarDateList.push(daysOfMonth)
}
//获取下月日期
let newDate = new Date(year,month + 1,i)
let newMonth = newDate.getMonth()+1
let newDay = newDate.getDate()
let date = year+'-'+(newMonth>9?newMonth:('0'+newMonth))+'-'+(newDay>9?newDay:('0'+newDay))
daysOfMonth.push({date:date,day:newDay,isToday:false,isCurrentMonth:false});
}
this.monthDateList = daysOfMonth
this.calendarDateList = calendarDateList
this.monthDateList = calendarDateList[this.selectMonthIndex]
this.listTop = this.contentTop + (68+40+96+74+70+74+22)/750*inject('windowWidth')
this.getStockCategoryListData()
this.getEventListData()
this.getCurrentMonthEventCountData()
Promise.all([this.getStockCategoryListData(),this.getCurrentMonthEventCountData()]).then(res=>{
this.getEventListData()
}).catch(error=>{
})
},
onPullDownRefresh() {
this.reloadData()
},
computed: {
circumference() {
@@ -236,6 +300,42 @@
}
},
methods: {
reloadData()
{
this.page = 1
this.loadAll = false
if(this.selectTab==0)
{
this.getEventListData()
}else
this.getDataListData()
},
loadMoreData()
{
if(!this.loadAll)
{
this.page ++
if(this.selectTab==0)
{
this.getEventListData()
}else
this.getDataListData()
}
},
/**
* 点击搜索
*/
clickSearch()
{
this.reloadData()
},
/**
* 点击选择月份
*/
clickSelectMonth()
{
this.$refs['popup'].open()
},
/**
* 点击今日日期
*/
@@ -244,11 +344,10 @@
if(this.selectDate!=this.todayDate)
{
this.selectDate = this.todayDate
if(this.selectTab==0)
{
this.getEventListData()
}else
this.getDataListData()
let date = new Date()
let currentMonth = date.getMonth()+1
this.selectMonthIndex = 20*12+currentMonth-1
this.reloadData()
}
},
/**
@@ -263,6 +362,46 @@
}else
this.listTop = this.contentTop + (68+40+96+74+70+74+22)/750*this.windowWidth
},
/**
* 点击上个月
*/
clickPreMonth()
{
if(this.selectMonthIndex>0)
{
this.selectMonthIndex --
let monthList = this.calendarDateList[this.selectMonthIndex]
let month = ''
for (let item of monthList) {
if(item.isCurrentMonth)
{
month = item.month
break
}
}
this.selectMonth = this.calendarDateList[this.selectMonthIndex][0].year+'-'+(month>9?month:('0'+month))
}
},
/**
* 点击下个月
*/
clickNextMonth()
{
if(this.selectMonthIndex<this.calendarDateList.length-1)
{
this.selectMonthIndex ++
let monthList = this.calendarDateList[this.selectMonthIndex]
let month = ''
for (let item of monthList) {
if(item.isCurrentMonth)
{
month = item.month
break
}
}
this.selectMonth = this.calendarDateList[this.selectMonthIndex][0].year+'-'+(month>9?month:('0'+month))
}
},
/**
* 选中日期
* @param {Object} item
@@ -272,11 +411,7 @@
if(this.selectDate!=item.date)
{
this.selectDate = item.date
if(this.selectTab==0)
{
this.getEventListData()
}else
this.getDataListData()
this.reloadData()
}
},
/**
@@ -287,11 +422,7 @@
if(this.selectTab!=index)
{
this.selectTab = index
if(this.selectTab==0)
{
this.getEventListData()
}else
this.getDataListData()
this.reloadData()
}
},
/**
@@ -302,11 +433,7 @@
if(this.selectTopCategory!=index)
{
this.selectTopCategory = index
if(this.selectTab==0)
{
this.getEventListData()
}else
this.getDataListData()
this.reloadData()
}
},
/**
@@ -323,41 +450,58 @@
*/
getStockCategoryListData()
{
stockCategoryList().then(res=>{
if(res.code==200)
{
res.data.unshift({primary_sector:'全部',sub_sectors:[]})
this.stockCategoryList = res.data
}else
uni.showToast({
title:res.message,
icon:'none'
})
}).catch(error=>{
return new Promise((resolve,reject)=>{
stockCategoryList().then(res=>{
if(res.code==200)
{
res.data.unshift({primary_sector:'全部',sub_sectors:[]})
this.stockCategoryList = res.data
resolve(1)
}else
{
uni.showToast({
title:res.message,
icon:'none'
})
reject(1)
}
}).catch(error=>{
reject(1)
})
})
},
/**
* 获取事件列表数据
*/
getEventListData()
{
let param = {start:this.selectDate}
let param = {start:this.selectDate,q:this.keywords,page:this.page}
if(this.selectTopCategory>0)
{
param.category = this.stockCategoryList[this.selectTopCategory].primary_sector
}
calendarEventList(param).then(res=>{
uni.stopPullDownRefresh()
if(res.code==200)
{
this.eventList = res.data.events
if(res.data.page==1)
{
this.eventList = res.data.events
}else
this.eventList = this.eventList.concat(res.data.events)
if(res.data.page==res.data.total_pages)
{
this.loadAll = true
}
}else
uni.showToast({
title:res.message,
icon:'none'
})
}).catch(error=>{
uni.stopPullDownRefresh()
})
},
/**
@@ -365,7 +509,11 @@
*/
getDataListData()
{
let param = {start:this.selectDate}
let param = {start:this.selectDate,q:this.keywords,page:this.page}
if(this.selectTopCategory>0)
{
param.category = this.stockCategoryList[this.selectTopCategory].primary_sector
}
calendarDataList(param).then(res=>{
if(res.code==200)
{
@@ -376,7 +524,7 @@
icon:'none'
})
}).catch(error=>{
uni.stopPullDownRefresh()
})
},
/**
@@ -384,26 +532,29 @@
*/
getCurrentMonthEventCountData()
{
calendarEventCount().then(res=>{
for (let item of res) {
let date = item.start
for (let s of this.weekDateList) {
if(s.date == date)
{
s.eventCount = item.title
s.className = item.className
return new Promise((resolve,reject)=>{
calendarEventCount().then(res=>{
for (let item of res) {
let date = item.start
for (let s of this.weekDateList) {
if(s.date == date)
{
s.eventCount = item.title
s.className = item.className
}
}
for (let s of this.monthDateList) {
if(s.date == date)
{
s.eventCount = item.title
s.className = item.className
}
}
}
for (let s of this.monthDateList) {
if(s.date == date)
{
s.eventCount = item.title
s.className = item.className
}
}
}
}).catch(error=>{
resolve(1)
}).catch(error=>{
reject(1)
})
})
}
}
@@ -723,14 +874,22 @@
}
.labelC
{
display: inline-block;
margin-top: 12rpx;
.label
{
display: inline-block;
margin-right: 10rpx;
padding: 0 10rpx;
line-height: 30rpx;
font-size: 20rpx;
font-weight: 500;
border-radius: 5rpx;
border: solid 1rpx #333;
}
}
.content
{
margin-top: 20rpx;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
@@ -824,4 +983,89 @@
}
}
}
.popup
{
background-color: white;
padding: 30rpx 0;
.yearMonthC
{
padding: 0 30rpx;
.yearMonth
{
text-align: center;
font-size: 24rpx;
}
.btn
{
background-color: #f8f8f8;
width: 40rpx;
height: 40rpx;
border-radius: 50%;
.icon
{
display: block;
width: 24rpx;
height: auto;
}
}
}
.weekList
{
margin-top: 20rpx;
padding: 0 30rpx;
.item
{
line-height: 40rpx;
font-size: 24rpx;
color: #a1a1a1;
text-align: center;
}
}
.monthDateList
{
padding: 0 30rpx;
.item
{
margin-bottom: 10rpx;
width: calc(100%/7);
.date
{
background-color: #f8f8f8;
width: calc(100% - 10rpx);
line-height: 64rpx;
border-radius: 15rpx;
font-size: 24rpx;
font-weight: bold;
color: #333;
text-align: center;
}
.date.today
{
background-color: #FF7E1A;
color: white;
}
.date.inRange
{
background-color: #FFF2EB;
}
.date.notCurrentMonth
{
background-color: #fdfdfd;
color: #c3c3c3;
}
.eventNum
{
margin-top: 12rpx;
width: 80rpx;
height: 30rpx;
line-height: 30rpx;
border-radius: 5rpx;
font-size: 16rpx;
font-weight: 500;
color: white;
text-align: center;
}
}
}
}
</style>

View File

@@ -8,23 +8,43 @@
<view v-if="selectCategory==index" class="line absolute"></view>
</view>
</view>
<view class="contentC fixed" :style="'top:'+contentTop+'px;'">
<view v-if="selectCategory==3" class="stockC">
<view v-if="investDetails" class="contentC fixed" :style="'top:'+contentTop+'px;'">
<view v-if="selectCategory==0" class="former">
<ua-markdown :source="former" />
</view>
<view v-if="selectCategory==1" class="former">
<ua-markdown :source="investDetails.forecast" />
</view>
<!-- <view v-if="selectCategory==2" class="former">
<ua-markdown :source="investDetails.fact" />
</view> -->
<view v-if="selectCategory==2" class="stockC">
<view class="stockCategoryList flexWrap">
<view class="item flexColumnCenter" :style="'background-color:'+item.bgColor+';color:'+item.color+';'" v-for="(item,index) in stockCategoryList" :key="index">
<view class="num">23</view>
<view class="num">{{item.num}}</view>
<view class="title">{{item.title}}</view>
</view>
</view>
<view class="stockList">
<view class="item">
<view class="item" v-for="(item,index) in investDetails.related_stocks" :key="index" @click="clickLookRelatedStockItem(item)">
<view class="titleCorrelationC flex">
<view class="title flex1">000065.SZ 北方国际</view>
<view class="correlation">相关度: 98%</view>
<view class="title flex1">{{item.code+' '+item.name}} </view>
<view class="correlation">相关度: {{accMul(item.score,100)}}%</view>
</view>
<view class="category">石油石化</view>
<view class="content">
海外订单占比70%-80%在俄语区矿产资源开发蒙古矿山电力运营经验丰富是乌克兰重建核心受益标的公司在俄语区的深厚积累使其直接获益于区域经济复苏和能源合作深化
<view v-if="item.sw_primary_sector" class="category">{{item.sw_primary_sector}}</view>
<view class="content">{{item.description}}</view>
</view>
</view>
</view>
<view v-if="selectCategory==4" class="">
<view class="conceptList">
<view class="item relative" v-for="(item,index) in investDetails.extracted_concepts" :key="index" @click="clickConceptItem()">
<image class="cover" :src="item.first_image" mode="aspectFill"></image>
<view class="infoC absolute">
<view class="title">{{item.name}}</view>
<view class="content relative">{{item.reason}}
<text class="lookDetails absolute">查看详情</text>
</view>
</view>
</view>
</view>
@@ -35,48 +55,58 @@
<script>
import { inject } from 'vue';
import { investEventDetails } from '@/request/api';
import { investEventDetails, stockCategoryList } from '@/request/api';
import { accMul } from '@/utils/util';
export default {
data() {
return {
navH:inject('navHeight'),
eventId:'', //事件id
contentTop:'',
categoryList:['背景','推演','实际','相关股票','相关概念'],
investDetails:null,
former:'', //背景
categoryList:['背景','推演','相关股票'],
selectCategory:0,
stockCategoryList:[
{
title:'全部股票',
num:0,
bgColor:'#C00000',
color:'white'
},
{
title:'大周期',
num:0,
bgColor:'#305496',
color:'white'
},
{
title:'TMT板块',
num:0,
bgColor:'#FFBF00',
color:'white',
},
{
title:'大金融地产',
num:0,
bgColor:'#FFF4D3',
},
{
title:'大消费',
num:0,
bgColor:'#CDEEEE',
},
{
title:'公共产业板块',
num:0,
bgColor:'#DEEBF7'
}]
}],
accMul:accMul
}
},
onLoad(e) {
this.contentTop = this.navH+(30+74)/750*inject('windowWidth')
this.contentTop = this.navH+(30+72)/750*inject('windowWidth')
if(e.id)
{
this.eventId = e.id
@@ -94,13 +124,35 @@
this.selectCategory = index
}
},
/**
* 点击相关股票
* @param {Object} item 股票数据
*/
clickLookRelatedStockItem(item)
{
uni.navigateTo({
url:'/pages/index/stockDetails/stockDetails?type=2&code='+item.code+'&des='+item.description+'&name='+item.name
})
},
/**
* 获取事件详情数据
*/
getEventDetailsData()
{
investEventDetails(this.eventId).then(res=>{
if(res.code==200)
{
let detail = res.data.detail
for (let item of this.stockCategoryList) {
item.num = detail.sector_stats[item.title]
}
this.investDetails = detail
this.former = detail.former.replace('<answer>','').replace('</answer>','')
}else
uni.showToast({
title:res.message,
icon:'none'
})
}).catch(error=>{
})
@@ -155,6 +207,10 @@
right: 0;
bottom: 0;
overflow-y: scroll;
.former
{
padding: 40rpx 25rpx;
}
.stockCategoryList
{
margin-top: 18rpx;
@@ -184,9 +240,10 @@
.stockList
{
padding: 22rpx 25rpx 30rpx;
border-bottom: solid 1rpx #E4E4E4;
.item
{
padding: 22rpx 0 30rpx;
border-bottom: solid 1rpx #E4E4E4;
.title
{
font-size: 30rpx;
@@ -224,5 +281,51 @@
}
}
}
.conceptList
{
padding: 30rpx 25rpx;
.item
{
margin-bottom: 20rpx;
.cover
{
display: block;
width: 100%;
height: 350rpx;
border-radius: 10rpx;
}
.infoC
{
background: linear-gradient(to bottom,#00000080,#000);
padding: 20rpx 23rpx;
left:0;
width: 100%;
bottom: 0;
border-radius: ;
color: white;
.title
{
font-size: 26rpx;
font-weight: bold;
}
.content
{
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
margin-top: 10rpx;
font-size: 20rpx;
font-weight: 500;
line-height: 1.2rem;
.lookDetails
{
right: 0;
color: #F97316;
}
}
}
}
}
}
</style>

View File

@@ -5,18 +5,19 @@
<view class="loginTitle">欢迎登录价值前沿平台</view>
<view class="inputC mobile flex">
<image class="icon" src="/static/icon/login/mobile.png" mode="widthFix"></image>
<input class="flex1" type="number" v-model="mobile" placeholder="请输入手机号" placeholder-style="color: #aaa"/>
<input class="flex1" type="number" v-model="mobile" placeholder="请输入手机号" placeholder-style="color: #aaa" maxlength="11"/>
</view>
<view class="inputC code flex">
<image class="icon" src="/static/icon/login/code.png" mode="widthFix"></image>
<input class="flex1" type="number" v-model="code" placeholder="请输入验证码" placeholder-style="color: #aaa"/>
<view class="getCode" @click="clickGetCode()">获取验证码</view>
<view class="getCode" @click="clickGetCode()">{{getCode?(countdown>0?countdown+'s':'重新获取验证码'):'获取验证码'}}</view>
</view>
<view class="btn loginAtOnce" @click="clickLoginAtOnce()">立即登录</view>
<view class="btn oneClickLogin" @click="clickOneClickLogin()">授权手机号一键登录</view>
<view class="agreeProtocolC fixed flexCenter">
<view class="agreeC">
<image class="icon" src="" mode="widthFix"></image>
<view class="agreeC" @click="clickAgree()">
<image v-if="isAgree" class="icon" src="/static/icon/login/select_s.png" mode="widthFix"></image>
<image v-else class="icon" src="/static/icon/login/select.png" mode="widthFix"></image>
</view>
阅读并同意我们的<text class="protocol">用户服务协议</text><text class="protocol">隐私政策</text>
</view>
@@ -25,7 +26,8 @@
<script>
import { inject } from 'vue';
import { loginByPhone } from '@/request/api';
import { loginByPhone, sendSMS } from '@/request/api';
const app = getApp()
export default {
data() {
@@ -33,6 +35,10 @@
contentTop:'',
mobile:'', //手机号
code:'', //验证码
isAgree:false,
countdown:0, //验证码倒计时
getCode:false, //是否已经获取过验证码
timer:null //定时器
}
},
onLoad() {
@@ -44,7 +50,61 @@
*/
clickGetCode()
{
let mobile = this.mobile
if(!mobile)
{
uni.showToast({
title:'请输入手机号',
icon:'none'
})
return
}
if (!app.globalData.mobileReg.test(mobile)) {
uni.showToast({
title:'请输入正确格式的手机号',
icon:'none'
})
return
}
if (this.isSubmiting) {
return
}
if (this.countdown>0) {
return
}
this.isSubmiting = true
let param = {phone:this.mobile,isJson:1}
let that = this
sendSMS(param).then(res=>{
// if(res.code==200)
// {
uni.showToast({
title:res.message,
icon:'none'
})
let time = 60
this.timer = setInterval(() => {
that.isSubmiting = false
time --
if (time==0) {
clearInterval(that.timer)
}
// that.code = res.debug_code
that.getCode = true
that.countdown = time
}, 1000);
// }else
// {
// this.isSubmiting = false
// uni.showToast({
// title:res.message,
// icon:'none'
// })
// }
}).catch(error=>{
this.isSubmiting = false
})
},
/**
* 点击立即登录
@@ -67,11 +127,27 @@
})
return
}
if(!this.isAgree)
{
uni.showToast({
title:'请阅读并同意我们的《用户服务协议》和《隐私政策》',
icon:'none'
})
return
}
let param = {phone:this.mobile,code:this.code,isJson:1}
loginByPhone(param).then(res=>{
if(res.code==200)
if(res.code==0)
{
uni.showToast({
title:res.message,
})
uni.setStorageSync('token',res.token)
setTimeout(function() {
uni.switchTab({
url:'/pages/index/index'
})
}, 1000);
}else
uni.showToast({
title:res.message,
@@ -87,6 +163,22 @@
clickOneClickLogin()
{
uni.navigateBack()
},
/**
* 点击同意
*/
clickAgree()
{
this.isAgree = !this.isAgree
},
/**
* 点击查看协议
*/
clickProtocol(type)
{
uni.navigateTo({
url:'/pages/mine/web/web?type='+type
})
}
}
}
@@ -180,6 +272,7 @@
padding: 14rpx;
.icon
{
display: block;
width: 28rpx;
height: auto;
}

View File

@@ -7,9 +7,10 @@
<view class="btn codeLogin" @click="clickCodeLogin()">使用短信验证登录</view>
<view class="agreeProtocolC fixed flexCenter">
<view class="agreeC" @click="clickAgree()">
<image class="icon" src="" mode="widthFix"></image>
<image v-if="isAgree" class="icon" src="/static/icon/login/select_s.png" mode="widthFix"></image>
<image v-else class="icon" src="/static/icon/login/select.png" mode="widthFix"></image>
</view>
阅读并同意我们的<text class="protocol" @click="clickProtocol()">用户服务协议</text><text class="protocol"@click="clickProtocol()">隐私政策</text>
阅读并同意我们的<text class="protocol" @click="clickProtocol(2)">用户服务协议</text><text class="protocol"@click="clickProtocol(3)">隐私政策</text>
</view>
</view>
</template>
@@ -21,7 +22,8 @@
export default {
data() {
return {
contentTop:''
contentTop:'',
isAgree:false
}
},
onLoad() {
@@ -33,12 +35,36 @@
*/
clickOneClickLogin()
{
if(!this.isAgree)
{
uni.showToast({
title:'请阅读并同意我们的《用户服务协议》和《隐私政策》',
icon:'none'
})
return
}
uni.login({
provider:'weixin',
success(res) {
console.log(res.code)
let param = {code:res.code,isJson:1}
loginByWx(param).then(res=>{
if(res.code==200)
{
uni.showToast({
title:res.message,
})
uni.setStorageSync('token',res.data.token)
setTimeout(function() {
uni.switchTab({
url:'/pages/index/index'
})
}, 1000);
}else
uni.showToast({
title:res.message,
icon:"none"
})
}).catch(error=>{
})
@@ -63,14 +89,16 @@
*/
clickAgree()
{
this.isAgree = !this.isAgree
},
/**
* 点击查看协议
*/
clickProtocol()
clickProtocol(type)
{
uni.navigateTo({
url:'/pages/mine/web/web?type='+type
})
}
}
}
@@ -123,6 +151,7 @@
padding: 14rpx;
.icon
{
display: block;
width: 28rpx;
height: auto;
}

View File

@@ -14,7 +14,7 @@
<input type="nickname" v-model="nickname" />
</view>
<view class="section">手机号</view>
<view class="inputC">{{mobile}}</view>
<view class="selectC flex">{{mobile}}</view>
<view class="section">性别</view>
<picker mode="selector" :range="sexList" @change="sexChange">
<view class="selectC flex">
@@ -115,7 +115,7 @@
if(this.avatar)
{
//如果选择了新头像
let param = {avatar:this.avatar,nickname:this.nickname,gender:this.sex=='男'?'male':'female',
let param = {avatar:this.avatar,nickname:this.nickname,gender:this.sex=='男'?'male':'female',phone:this.mobile,
bio:this.profile,isFile:1}
updateBasicInfo(param).then(res=>{
uni.navigateTo({
@@ -127,7 +127,7 @@
}else
{
//没有选择新头像
let param = {nickname:this.nickname,gender:this.sex=='男'?'male':'female',
let param = {nickname:this.nickname,gender:this.sex=='男'?'male':'female',phone:this.mobile,
bio:this.profile}
updateBasicInfo(param).then(res=>{
uni.navigateTo({

View File

@@ -32,8 +32,8 @@
</view>
<view class="originEventC">
<view class="levelTitleC flex">
<view class="level">C</view>
<view class="title">四部门联合启动人力资源服务业与制造业...</view>
<view class="level">{{item.event.importance}}</view>
<view class="title">{{item.event.title}}</view>
</view>
<view class="eventContent">人社部工信部等四部门印发通知明确在30个城市开展3年期试点培育人力资源服务与制造业协同机构...</view>
</view>
@@ -44,20 +44,20 @@
<view class="myCommentItem" v-for="(item,index) in commentList" :key="index">
<view class="replyContentC">
<view class="flex">
<image class="avatar" src="" mode="aspectFill"></image>
<image class="avatar" :src="item.commenter.avatar_url" mode="aspectFill"></image>
<view class="flex1">
<view class="nickname">逸尘破晓</view>
<view class="time">{{getLocaleDate(item.created_at)}}</view>
<view class="nickname">{{item.commenter.nickname}}</view>
<view class="time">{{getLocaleMonthDayHourMinte(item.created_at)}}</view>
</view>
</view>
<view class="content">{{item.content}}</view>
</view>
<view class="originEventC">
<view class="originEventC" @click.stop="clickEventItem(item.event.id)">
<view class="levelTitleC flex">
<view class="level">C</view>
<view class="title">{{item.event_title}}</view>
<view class="level">{{item.event.importance}}</view>
<view class="title">{{item.event.title}}</view>
</view>
<view class="eventContent">人社部工信部等四部门印发通知明确在30个城市开展3年期试点培育人力资源服务与制造业协同机构...</view>
<view class="eventContent">{{item.event.description}}</view>
</view>
</view>
</block>
@@ -68,7 +68,7 @@
<script>
import { inject } from 'vue';
import { userActivityList } from '@/request/api';
import { getLocaleDate } from '@/utils/util';
import { getLocaleMonthDayHourMinte } from '@/utils/util';
export default {
data() {
@@ -80,7 +80,7 @@
commentList:[],
page:1,
loadAll:false,
getLocaleDate:getLocaleDate
getLocaleMonthDayHourMinte:getLocaleMonthDayHourMinte
}
},
onLoad() {
@@ -111,6 +111,16 @@
this.getCommentListData()
}
},
/**
* 点击查看事件详情
* @param {Object} id
*/
clickEventItem(id)
{
uni.navigateTo({
url:'/pages/index/eventDetails/eventDetails?id='+id
})
},
/**
* 获取评论列表数据
*/

View File

@@ -30,7 +30,7 @@
</view>
</scroll-view>
<scroll-view scroll-x class="stockList">
<view class="stockItem" v-for="(sitem,sindex) in item.related_stocks" :key="sindex" @click.stop="clickLookRelatedStockItem(sitem.stock_code)">{{sitem.stock_name}} <text class="change">{{(getRateUpOrDown(sitem.daily_change)?'':'+')+sitem.daily_change}}%</text></view>
<view class="stockItem" v-for="(sitem,sindex) in item.related_stocks" :key="sindex" @click.stop="clickLookRelatedStockItem(item.event_id,sitem.stock_code)">{{sitem.stock_name}} <text class="change">{{(getRateUpOrDown(sitem.daily_change)?'':'+')+sitem.daily_change}}%</text></view>
</scroll-view>
<view class="timeToolBarC flex">
<view class="time flex1">{{getLocaleTime(item.created_at)}}</view>
@@ -56,7 +56,7 @@
<script>
import { inject } from 'vue';
import { userActivityList,followEvent } from '@/request/api';
import { userActivityList, followEvent } from '@/request/api';
import { getRateStr, getRateUpOrDown, getLocaleTime } from '@/utils/util.js'
export default {
@@ -90,10 +90,10 @@
* 点击相关股票
* @param {Object} code
*/
clickLookRelatedStockItem(code)
clickLookRelatedStockItem(id,code)
{
uni.navigateTo({
url:'/pages/index/stockDetails/stockDetails?code='+code
url:'/pages/index/stockDetails/stockDetails?type=1&code='+code+'&id='+id
})
},
/**

View File

@@ -211,6 +211,13 @@
*/
uploadInvestPreferenceData()
{
let arr = []
for (let item of this.preferredMarketList) {
if(item.select)
{
arr.push(item.title)
}
}
let param = {trading_experience: this.selectYearIndex,investment_style: this.investPreferenceList[this.selectInvestIndex],
risk_preference: this.riskPreferenceList[this.selectRiskIndex],
investment_amount: this.investmentScaleList[this.selectScaleIndex],
@@ -231,6 +238,7 @@
userInfo().then(res=>{
if(res.code==200)
{
this.avatarUrl = res.data.basic_info.avatar_url
let data = res.data.investment_preferences
//投资偏好
for (var i = 0; i < this.investPreferenceList.length; i++) {

View File

@@ -10,17 +10,17 @@
</view>
<image class="arrow" src="/static/icon/mine/infoArrow.png" mode="widthFix"></image>
</view>
<view class="numList relative flex">
<view v-if="userInfo" class="numList relative flex">
<view class="item flex1 flexColumnCenter" @click="clickNumItem(0)">
<view class="num">1</view>
<view class="num">{{userInfo.statistics.total_comments}}</view>
<view class="title">评论回复</view>
</view>
<view class="item flex1 flexColumnCenter" @click="clickNumItem(1)">
<view class="num">1</view>
<view class="num">{{userInfo.statistics.follows_count}}</view>
<view class="title">关注收藏</view>
</view>
<view class="item flex1 flexColumnCenter" @click="clickNumItem(2)">
<view class="num">1</view>
<view class="num">{{userInfo.statistics.likes_count}}</view>
<view class="title">我的点赞</view>
</view>
</view>
@@ -29,11 +29,11 @@
</view>
<view class="menuList relative">
<view class="list">
<view class="item relative flex" v-for="(item,index) in menuList" :key="index" @click="clickMenuItem(item.url)" >
<view class="item relative flex" v-for="(item,index) in menuList" :key="index" @click="clickMenuItem(item.url,index)" >
<image class="icon" :src="item.icon" mode="aspectFit"></image>
<view class="title flex1">{{item.title}}</view>
<image class="arrow" src="/static/icon/mine/menuArrow.png" mode="widthFix"></image>
<button class="absolute" v-if="index==menuList.length-1" open-type="contact"></button>
<button class="absolute" v-if="index==menuList.length-2" open-type="contact"></button>
</view>
</view>
</view>
@@ -54,27 +54,30 @@
menuList:[{
icon:'/static/icon/mine/aboutUs.png',
title:'关于我们',
url:'/pages/mine/web/web?type=1'
},
{
icon:'/static/icon/mine/serviceTerm.png',
title:'服务条款',
url:'/pages/mine/web/web?type=2'
},
{
icon:'/static/icon/mine/privacyProtocol.png',
title:'隐私协议',
url:'/pages/mine/web/web?type=3'
},
{
icon:'/static/icon/mine/feedback.png',
title:'意见反馈',
url:'/pages/mine/feedback/feedback'
},
{
icon:'/static/icon/mine/accountSetting.png',
title:'账户设置',
},
{
icon:'/static/icon/mine/customerService.png',
title:'联系客服',
},
{
icon:'/static/icon/mine/logout.png',
title:'退出登录',
}]
}
},
@@ -100,7 +103,7 @@
clickVip()
{
uni.navigateTo({
url:'/pages/mine/vip/vip'
url:'/pagesMine/vip/vip'
})
},
/**
@@ -127,13 +130,27 @@
url:'/pages/mine/myLike/myLike'
})
},
clickMenuItem(url)
clickMenuItem(url,index)
{
if(url)
{
uni.navigateTo({
url
})
}else if(index==this.menuList.length-1)
{
uni.showModal({
title:'您确定要退出登录么',
success(res) {
if(res.confirm)
{
uni.removeStorageSync('token')
uni.switchTab({
url:'/pages/index/index'
})
}
}
})
}
},
/**

View File

@@ -4,7 +4,7 @@
<image class="topBg absolute" src="/static/image/mine/myTopBg.png" mode="widthFix"></image>
<view class="list fixed" :style="'top:'+navH+'px;'">
<view class="item" v-for="(item,index) in myLikeList" :key="index">
<image class="avatar" :src="item.author.avatarurl" mode="aspectFill"></image>
<image class="avatar" :src="item.author.avatar_url" mode="aspectFill"></image>
<view class="flex1">
<view class="nickname">{{item.author.nickname}}</view>
<rich-text class="content" :nodes="item.post_content"></rich-text>
@@ -13,7 +13,7 @@
<view class="time">{{getLocaleHourMinute(item.like_time)}}</view>
<!-- <view class="reply">回复</view> -->
</view>
<view class="likeC flex">
<view class="likeC flex" @click="clickLikeComment(item.like_id,index)">
<image class="icon" src="/static/icon/home/like_s.png" mode="widthFix"></image>
<!-- <view class="num">85</view> -->
</view>
@@ -26,7 +26,7 @@
<script>
import { inject } from 'vue';
import { userActivityList } from '@/request/api';
import { userActivityList, likeEventComment } from '@/request/api';
import { getLocaleHourMinute } from '@/utils/util';
export default {
@@ -54,6 +54,20 @@
}
},
methods: {
/**
* 点赞评论
*/
clickLikeComment(id,index)
{
likeEventComment(id).then(res=>{
uni.showToast({
title:res.message,
})
this.myLikeList.splice(index,1)
}).catch(error=>{
})
},
/**
* 获取我的点赞列表数据
*/

View File

@@ -1,480 +0,0 @@
<template>
<view>
<navBar leftText="会员中心"></navBar>
<image class="topBg absolute" src="/static/image/mine/myTopBg.png" mode="widthFix"></image>
<view v-if="memberInfo" class="vipC relative" :style="'margin-top:'+navH+'px;'">
<view class="vipInfoC relative">
<image v-if="memberInfo.is_member" class="bg" src="/static/image/mine/vip/vipTopBg.png" mode="widthFix"></image>
<image v-else class="bg" src="/static/image/mine/vip/noVipTopBg.png" mode="widthFix"></image>
<view v-if="memberInfo.is_member" class="infoC vip absolute">
<view class="title">尊贵的VIP会员</view>
<view class="tips">会员有效期至{{memberInfo.member_expire_date}}</view>
</view>
<view v-else class="infoC absolute">
<view class="title">价值前沿</view>
<view class="tips">您还不是会员 加入尊享N项服务</view>
</view>
</view>
<view class="vipProfitIntroC relative">
<view class="titleC flexCenter">
<image v-if="memberInfo.is_member" class="icon" src="/static/icon/mine/vip/titleLeft_v.png" mode="widthFix"></image>
<image v-else class="icon" src="/static/icon/mine/vip/titleLeft.png" mode="widthFix"></image>
<view class="title">即刻开启</view>
<image v-if="memberInfo.is_member" class="icon" src="/static/icon/mine/vip/titleRight_v.png" mode="widthFix"></image>
<image v-else class="icon" src="/static/icon/mine/vip/titleRight.png" mode="widthFix"></image>
</view>
<view class="subtitle">HOW TO SUBSCRIBE</view>
<view class="stepC flex">
<view class="num">01</view>
<view class="step">点击微信顶部搜索框并指定搜索内容为 <text :class="'impormant '+(memberInfo.is_member?'vip':'')">公众号</text></view>
</view>
<view class="picList flex">
<view class="pic flex1">
<image v-if="memberInfo.is_member" class="icon" src="/static/icon/mine/vip/step1_v.png" mode="widthFix"></image>
<image v-else class="icon" src="/static/icon/mine/vip/step1.png" mode="widthFix"></image>
</view>
<view class="pic flex1">
<image v-if="memberInfo.is_member" class="icon" src="/static/icon/mine/vip/step2_v.png" mode="widthFix"></image>
<image v-else class="icon" src="/static/icon/mine/vip/step2.png" mode="widthFix"></image>
</view>
</view>
<view class="stepC flex">
<view class="num">02</view>
<view class="step">搜索
<text :class="'impormant '+(memberInfo.is_member?'vip':'')">价值前沿</text>并点击搜索结果中的
<text :class="'impormant '+(memberInfo.is_member?'vip':'')">关注</text></view>
</view>
<view class="picList flex">
<view class="pic flex1">
<image v-if="memberInfo.is_member" class="icon" src="/static/icon/mine/vip/step3_v.png" mode="widthFix"></image>
<image v-else class="icon" src="/static/icon/mine/vip/step3.png" mode="widthFix"></image>
</view>
<view class="pic flex1">
<image v-if="memberInfo.is_member" class="icon" src="/static/icon/mine/vip/step4_v.png" mode="widthFix"></image>
<image v-else class="icon" src="/static/icon/mine/vip/step4.png" mode="widthFix"></image>
</view>
</view>
<view class="questionC">
<view class="title">投资的你是否遇到过这些问题</view>
<view class="iconListC flex">
<image class="icon" src="/static/icon/mine/vip/investQuestion.png" mode="widthFix"></image>
<view class="list flex1">
<view :class="'item '+(memberInfo.is_member?'vip':'')" v-for="(item,index) in questionList" :key="index">
{{item}}
</view>
</view>
</view>
</view>
<view class="titleC research flexCenter">
<image v-if="memberInfo.is_member" class="icon" src="/static/icon/mine/vip/titleLeft_v.png" mode="widthFix"></image>
<image v-else class="icon" src="/static/icon/mine/vip/titleLeft.png" mode="widthFix"></image>
<view class="title">行业研究中心</view>
<image v-if="memberInfo.is_member" class="icon" src="/static/icon/mine/vip/titleRight_v.png" mode="widthFix"></image>
<image v-else class="icon" src="/static/icon/mine/vip/titleRight.png" mode="widthFix"></image>
</view>
<view class="subtitle">20余年专业投研赋能每一位投资者</view>
<view class="introC">
<text class="flex1">依托价值前沿研究所深耕20余年的专业积淀我们为您构建一站式行业研究平台内容覆盖宏观趋势产业结构核心公司动态帮助投资者看懂行业识别机会建立自己的知识体系</text>
<image class="icon" src="/static/icon/mine/vip/industrialResearch.png" mode="widthFix"></image>
</view>
<view class="titleC decision flexCenter">
<image v-if="memberInfo.is_member" class="icon" src="/static/icon/mine/vip/titleLeft_v.png" mode="widthFix"></image>
<image v-else class="icon" src="/static/icon/mine/vip/titleLeft.png" mode="widthFix"></image>
<view class="title">经营决策中心</view>
<image v-if="memberInfo.is_member" class="icon" src="/static/icon/mine/vip/titleRight_v.png" mode="widthFix"></image>
<image class="icon" src="/static/icon/mine/vip/titleRight.png" mode="widthFix"></image>
</view>
<view class="subtitle">数据洞察辅助每一个关键判断</view>
<view class="introC operatingDecision">
<text class="flex1">我们整合来自一线调研专题报告行业闭门会的专业数据提供宏观到微观的全链条分析无论是捕捉赛道拐点还是识别公司价值经营决策中心都是您可靠的智囊伙伴</text>
<image class="icon" src="/static/icon/mine/vip/operatingDecision.png" mode="widthFix"></image>
</view>
<view class="titleC privilege flexCenter">
<image v-if="memberInfo.is_member" class="icon" src="/static/icon/mine/vip/titleLeft_v.png" mode="widthFix"></image>
<image v-else class="icon" src="/static/icon/mine/vip/titleLeft.png" mode="widthFix"></image>
<view class="title">会员尊享特权</view>
<image v-if="memberInfo.is_member" class="icon" src="/static/icon/mine/vip/titleRight_v.png" mode="widthFix"></image>
<image v-else class="icon" src="/static/icon/mine/vip/titleRight.png" mode="widthFix"></image>
</view>
<view class="subtitle">数据洞察辅助每一个关键判断</view>
<view :class="'privilegeList flexWrap '+(memberInfo.is_member?'vip':'')">
<view class="item flexColumnCenter" v-for="(item,index) in privilegeList" :key="index">
<image class="icon" :src="(memberInfo.is_member?item.icon_v:item.icon)" mode="widthFix"></image>
<view class="title">{{item.title}}</view>
<view class="tips">{{item.tips}}</view>
</view>
</view>
<view class="bottomTitle">准备好提升您的投资策略了吗</view>
<view class="bottomTips"> 解锁全部高级功能让AI成为您的专属投资顾问</view>
</view>
</view>
<view class="lookMealC fixed" @click="clickVipMeal()">查看VIP套餐</view>
</view>
</template>
<script>
import { inject } from 'vue';
import { membershipStatus } from '@/request/api';
export default {
data() {
return {
navH:inject('navHeight'),
memberInfo:null, //会员信息
questionList:['信息纷杂难辨真伪?','信息纷杂难辨真伪?','无法把握宏观趋势与行业动向?'],
privilegeList:[{
icon:'/static/icon/mine/vip/depthReport.png',
icon_v:'/static/icon/mine/vip/depthReport_v.png',
title:'深度研报',
tips:'行业/公司独家分析'
},
{
icon:'/static/icon/mine/vip/strategicInsight.png',
icon_v:'/static/icon/mine/vip/strategicInsight_v.png',
title:'策略洞察',
tips:'赛道趋势+拐点信号'
},
{
icon:'/static/icon/mine/vip/dataTool.png',
icon_v:'/static/icon/mine/vip/dataTool_v.png',
title:'数据工具',
tips:'行业/公司独家分析'
},
{
icon:'/static/icon/mine/vip/dataTool.png',
icon_v:'/static/icon/mine/vip/intelligentScreening_v.png',
title:'智能筛选',
tips:'按需定制标的列表'
},
{
icon:'/static/icon/mine/vip/decisionSupport.png',
icon_v:'/static/icon/mine/vip/decisionSupport_v.png',
title:'决策辅助',
tips:'关键因子评分系统'
},
{
icon:'/static/icon/mine/vip/expertMeeting.png',
icon_v:'/static/icon/mine/vip/expertMeeting_v.png',
title:'专家闭门会',
tips:'深度交流机会'
},
{
icon:'/static/icon/mine/vip/dailyReport.png',
icon_v:'/static/icon/mine/vip/dailyReport_v.png',
title:'日报周报',
tips:'研判速递、节奏掌控'
},
{
icon:'/static/icon/mine/vip/specialColumn.png',
icon_v:'/static/icon/mine/vip/specialColumn_v.png',
title:'专题专栏',
tips:'核心团队观点集结'
},
{
icon:'/static/icon/mine/vip/continuouslyUnlock.png',
icon_v:'/static/icon/mine/vip/continuouslyUnlock_v.png',
title:'持续解锁',
tips:'不定期上线新功能'
}]
}
},
onLoad() {
this.getMemberStatus()
},
methods: {
/**
* 点击查看vip套餐
*/
clickVipMeal()
{
uni.navigateTo({
url:'/pages/mine/vipMeal/vipMeal'
})
},
/**
* 获取会员状态
*/
getMemberStatus()
{
membershipStatus().then(res=>{
if (res.code==200) {
this.memberInfo = res.data
} else
uni.showToast({
title:res.message,
icon:'none'
})
}).catch(error=>{
})
}
}
}
</script>
<style lang="less">
.topBg
{
top: 0;
left: 0;
width: 100%;
height: auto;
}
.vipC
{
padding-bottom: calc(180rpx + env(safe-area-inset-bottom));
.vipInfoC
{
margin: 0 25rpx;
.bg
{
width: 100%;
height: auto;
}
.infoC
{
top: 130rpx;
left: 38rpx;
.title
{
font-size: 40rpx;
font-weight: bold;
color: #556B87;
}
.tips
{
font-size: 28rpx;
font-weight: 500;
color: #65758A;
}
}
.infoC.vip
{
.title
{
color: #AB3D1A;
}
.tips
{
color: #AB3D1A;
}
}
}
.vipProfitIntroC
{
background-color: white;
margin-top: -70rpx;
padding-top: 40rpx;
border-radius: 20rpx 20rpx 0 0;
.titleC
{
.icon
{
width: 54rpx;
height: auto;
}
.title
{
margin: 0 20rpx;
font-size: 50rpx;
font-weight: bold;
color: #222;
}
}
.titleC.research
{
margin-top: 50rpx;
}
.titleC.decision
{
margin-top: 30rpx;
}
.titleC.privilege
{
margin-top: 40rpx;
}
.subtitle
{
font-size: 24rpx;
color: #888;
text-align: center;
}
.stepC
{
margin: 16rpx 25rpx 0;
.num
{
background-color: #EDEEF1;
margin-right: 25rpx;
width: 50rpx;
line-height: 50rpx;
border-radius: 50%;
font-size: 24rpx;
font-weight: bold;
color: #5C6473;
text-align: center;
}
.step
{
font-size: 24rpx;
color: #5C6473;
.impormant
{
font-weight: bold;
}
.impormant.vip
{
color: #F97316;
}
}
}
.picList
{
padding: 0 25rpx;
margin-top: 34rpx;
.pic
{
margin-right: 20rpx;
.icon
{
width: 100%;
height: auto;
}
}
.pic:last-child
{
margin-right: 0;
}
}
.questionC
{
margin-top: 40rpx;
.title
{
font-size: 45rpx;
font-weight: bold;
color: #222;
text-align: center;
}
.iconListC
{
margin-top: 46rpx;
padding: 0 23rpx 0 59rpx;
.icon
{
margin-right: 56rpx;
width: 235rpx;
height: auto;
}
.list
{
.item
{
background-color: #EDEDED;
margin-bottom: 15rpx;
line-height: 70rpx;
border-radius: 35rpx;
font-size: 24rpx;
color: #555;
text-align: center;
}
.item.vip
{
background-color: #FFEBDB;
color: #F97316;
}
}
}
}
.introC
{
display: flex;
box-shadow: 0px 0px 9rpx 0px rgba(0,0,0,0.1);
margin: 24rpx 25rpx 0;
padding: 40rpx 20rpx 20rpx 33rpx;
line-height: 1.5rem;
border-radius: 10rpx;
font-size: 24rpx;
color: #555;
.icon
{
margin-top: 92rpx;
width: 251rpx;
height: auto;
}
}
.introC.operatingDecision
{
padding-bottom: 11rpx;
.icon
{
margin-top: 116rpx;
width: 249rpx;
height: auto;
}
}
.privilegeList
{
margin: 24rpx 25rpx 0;
padding: 20rpx 0;
box-shadow: 0px 0px 9rpx 0px rgba(0,0,0,0.1);
border-radius: 10rpx;
.item
{
padding: 20rpx 0;
width: calc((100%)/3);
.icon
{
margin-bottom: 10rpx;
width: 91rpx;
height: auto;
}
.title
{
font-size: 26rpx;
font-weight: bold;
color: #242323;
}
.tips
{
margin-top: 6rpx;
font-size: 22rpx;
color: #555;
}
}
}
.privilegeList.vip
{
box-shadow: 0px 0px 9px 0px rgba(249,115,22,0.4);
}
.bottomTitle
{
margin-top: 80rpx;
font-size: 45rpx;
font-weight: bold;
color: #222;
text-align: center;
}
.bottomTips
{
font-size: 24rpx;
color: #888;
text-align: center;
}
}
}
.lookMealC
{
background-color: #F97316;
margin: 0 25rpx;
left: 0;
right: 0;
bottom: calc(20rpx + env(safe-area-inset-bottom));
line-height: 80rpx;
border-radius: 20rpx;
font-size: 26rpx;
font-weight: 500;
color: white;
text-align: center;
}
</style>

View File

@@ -1,267 +0,0 @@
<template>
<view>
<navBar leftText="会员中心"></navBar>
<image class="topBg absolute" src="/static/image/mine/myTopBg.png" mode="widthFix"></image>
<view v-if="memberInfo" class="vipC" :style="'margin-top:'+navH+'px;'">
<view class="vipInfoC relative">
<image v-if="memberInfo.is_member" class="bg" src="/static/image/mine/vip/vipTopBg.png" mode="widthFix"></image>
<image v-else class="bg" src="/static/image/mine/vip/noVipTopBg.png" mode="widthFix"></image>
<view v-if="memberInfo.is_member" class="infoC vip absolute">
<view class="title">尊贵的VIP会员</view>
<view class="tips">会员有效期至{{memberInfo.member_expire_date}}</view>
</view>
<view v-else class="infoC absolute">
<view class="title">价值前沿</view>
<view class="tips">您还不是会员 加入尊享N项服务</view>
</view>
</view>
<view class="privilegeCompareC relative">
<view class="titleC flexCenter">
<image v-if="memberInfo.is_member" class="icon" src="/static/icon/mine/vip/titleLeft_v.png" mode="widthFix"></image>
<image v-else class="icon" src="/static/icon/mine/vip/titleLeft.png" mode="widthFix"></image>
<view class="title">特权对比</view>
<image v-if="memberInfo.is_member" class="icon" src="/static/icon/mine/vip/titleRight_v.png" mode="widthFix"></image>
<image v-else class="icon" src="/static/icon/mine/vip/titleRight.png" mode="widthFix"></image>
</view>
<view :class="'privilegeList '+(memberInfo.is_member?'vip':'')">
<view class="header flex">
<view class="privilege item">专属特权</view>
<view class="item free">普通免费</view>
<view class="item vip">VIP会员</view>
</view>
<view class="list">
<view class="item flex" v-for="(item,index) in privilegeList" :key="index">
<view class="optionItem privilege flex">{{item}}</view>
<view class="optionItem free flexCenter">
<block v-if="index==0||index==1||index==2">
<image class="notContain" src="/static/icon/mine/vip/notContain.png" mode="widthFix"></image>
</block>
<block v-if="index==3||index==4">
<block v-if="index==3">限制查看数量</block>
<block v-if="index==4">每日查看2只</block>
</block>
<block v-if="index==5||index==6">
<image class="contain" src="/static/icon/mine/vip/contain.png" mode="widthFix"></image>
</block>
</view>
<view class="optionItem vip flexCenter">
<image class="contain" src="/static/icon/mine/vip/contain.png" mode="widthFix"></image>
</view>
</view>
</view>
</view>
</view>
</view>
<view v-if="memberInfo" class="joinVipC fixed" @click="clickJoinVip()">{{memberInfo.is_member?'您已是年度VIP':'立即加入年度VIP'}}</view>
</view>
</template>
<script>
import { inject } from 'vue';
import { membershipStatus } from '@/request/api';
export default {
data() {
return {
navH:inject('navHeight'),
memberInfo:null, //会员信息
privilegeList:['高效选股工具','股票基金明星榜单','定期专属晨报、股票动态','独家产业研报','个股产业分析','股票、基金基础指标','7x24 财经直播']
}
},
onLoad() {
this.getMemberStatus()
},
methods: {
/**
* 点击加入vip
*/
clickJoinVip()
{
},
/**
* 获取会员状态
*/
getMemberStatus()
{
membershipStatus().then(res=>{
if (res.code==200) {
this.memberInfo = res.data
} else
uni.showToast({
title:res.message,
icon:'none'
})
}).catch(error=>{
})
}
}
}
</script>
<style lang="less">
.topBg
{
top: 0;
left: 0;
width: 100%;
height: auto;
}
.vipC
{
padding-bottom: calc(180rpx + env(safe-area-inset-bottom));
.vipInfoC
{
margin: 0 25rpx;
.bg
{
width: 100%;
height: auto;
}
.infoC
{
top: 130rpx;
left: 38rpx;
.title
{
font-size: 40rpx;
font-weight: bold;
color: #556B87;
}
.tips
{
font-size: 28rpx;
font-weight: 500;
color: #65758A;
}
}
.infoC.vip
{
.title
{
color: #AB3D1A;
}
.tips
{
color: #AB3D1A;
}
}
}
.privilegeCompareC
{
background-color: white;
margin-top: -70rpx;
padding-top: 40rpx;
border-radius: 20rpx 20rpx 0 0;
.titleC
{
.icon
{
width: 54rpx;
height: auto;
}
.title
{
margin: 0 20rpx;
font-size: 50rpx;
font-weight: bold;
color: #222;
}
}
.privilegeList
{
margin: 0 25rpx;
padding: 0 30rpx;
box-shadow: 0px 0px 9px 0px rgba(0,0,0,0.1);
border-radius: 10rpx;
.header
{
margin-top: 50rpx;
padding-top: 14rpx;
border-bottom: solid 1rpx #F3F4F6;
.item
{
line-height: 90rpx;
font-size: 30rpx;
font-weight: bold;
color: #555;
}
.item.privilege
{
padding-left: 24rpx;
width: 300rpx;
}
.item.free
{
width: 174rpx;
text-align: center;
}
.item.vip
{
width: 160rpx;
text-align: center;
}
}
.list
{
.item
{
.optionItem
{
height: 90rpx;
border-bottom: solid 1rpx #F3F4F6;
.contain
{
width: 21rpx;
height: auto;
}
.notContain
{
width: 17rpx;
height: auto;
}
}
}
.optionItem.privilege
{
width: 300rpx;
font-size: 24rpx;
font-weight: 500;
color: #222;
}
.optionItem.free
{
width: 174rpx;
font-size: 20rpx;
color: #555;
text-align: center;
}
.optionItem.vip
{
width: 160rpx;
}
}
}
.privilegeList.vip
{
box-shadow: 0px 0px 9px 0px rgba(249,115,22,0.4);
}
}
}
.joinVipC
{
background-color: #F97316;
margin: 0 25rpx;
left: 0;
right: 0;
bottom: calc(20rpx + env(safe-area-inset-bottom));
line-height: 80rpx;
border-radius: 20rpx;
font-size: 26rpx;
font-weight: 500;
color: white;
text-align: center;
}
</style>

93
pages/mine/web/web.vue Normal file
View File

@@ -0,0 +1,93 @@
<template>
<view>
<navBar :leftText="navTitle"></navBar>
<image class="topBg absolute" src="/static/image/mine/myTopBg.png" mode="widthFix"></image>
<view class="contentC fixed" :style="'top:'+navH+'px;'">
<text>{{webContent}}</text>
</view>
</view>
</template>
<script>
import { inject } from 'vue'
import { agreements } from '@/request/api'
export default {
data() {
return {
navH:inject('navHeight'),
navTitle:'',
type:'', //1.关于我们2.服务条款3.隐私协议
webContent:'',
}
},
onLoad(e) {
if(e.type)
{
this.type = e.type
this.getUserInfoData()
if(e.type==1)
{
this.navTitle = '关于我们'
}else if(e.type==2)
{
this.navTitle = '服务条款'
}else if(e.type==3)
{
this.navTitle = '隐私协议'
}
}
},
methods: {
/**
* 获取用户信息数据
*/
getUserInfoData()
{
agreements().then(res=>{
if(res.code==200)
{
if(this.type==1)
{
//关于我们
this.webContent = res.data.agreements.about_us.content
}else if(this.type==2)
{
//服务条款
this.webContent = res.data.agreements.service_terms.content
}else if(this.type==3)
{
//隐私协议
this.webContent = res.data.agreements.privacy_policy.content
}
}else
wx.showToast({
title:res.message,
})
}).catch(error=>{
})
}
}
}
</script>
<style lang="less">
.topBg
{
top: 0;
left: 0;
width: 100%;
height: auto;
}
.contentC
{
background-color: white;
left: 0;
right: 0;
bottom: 0;
margin-top: 10rpx;
padding: 50rpx 25rpx;
overflow-y: scroll;
}
</style>