|
@@ -0,0 +1,404 @@
|
|
|
|
+<script setup>
|
|
|
|
+import {reactive, ref,watch,nextTick} from 'vue'
|
|
|
|
+import { useRoute, useRouter } from 'vue-router'
|
|
|
|
+import ChartBox from './components/ChartBox.vue'
|
|
|
|
+import moment from 'moment'
|
|
|
|
+import { Popup, Toast,DatetimePicker,PullRefresh } from 'vant';
|
|
|
|
+import {apiPositionAnalysisInfo,apiPositionAnalysisList} from '@/api/hzyb/positionAnalysis'
|
|
|
|
+
|
|
|
|
+const route=useRoute()
|
|
|
|
+const router=useRouter()
|
|
|
|
+localStorage.setItem('hzyb-token',route.query.token)
|
|
|
|
+
|
|
|
|
+// 是否为pc端展示
|
|
|
|
+const isPcShow=ref(route.query.showType||'')
|
|
|
|
+
|
|
|
|
+// 选择时间
|
|
|
|
+let showDate=ref(false)
|
|
|
|
+const minDate=ref(new Date('2000/01/01'))
|
|
|
|
+let currentDate=ref('')//这是绑定在时间选择器的时间防止用户滑动了时间但是没点确定 这时候又把这个时间改成selectDate
|
|
|
|
+let selectDate=ref('')
|
|
|
|
+function confirmSelectDate(e){
|
|
|
|
+ // 如果选择的是 周六日 提示
|
|
|
|
+ if([0,6].includes(moment(currentDate.value).weekday())){
|
|
|
|
+ Toast('今日无数据,请选择其他日期!')
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ selectDate.value=e
|
|
|
|
+ currentDate.value=e
|
|
|
|
+ showDate.value=false
|
|
|
|
+ getInfo()
|
|
|
|
+}
|
|
|
|
+//选择时间弹窗关闭时更新 currentDate为selectDate
|
|
|
|
+function handleCloseSelectDate(){
|
|
|
|
+ // console.log('更新currentDate');
|
|
|
|
+ currentDate.value=selectDate.value
|
|
|
|
+}
|
|
|
|
+//切换 前一天\后一天 如果遇到周六日则跳过
|
|
|
|
+function handleDateChange(type){
|
|
|
|
+ let num=1
|
|
|
|
+ if(type==='before'){
|
|
|
|
+ if(moment(selectDate.value).weekday()===1){//向前一天时 当前为周一则 跳到 上周五
|
|
|
|
+ num=3
|
|
|
|
+ }
|
|
|
|
+ currentDate.value=moment(currentDate.value).add(-num,'days')
|
|
|
|
+ selectDate.value=moment(selectDate.value).add(-num,'days')
|
|
|
|
+ }else{
|
|
|
|
+ if(moment(selectDate.value).weekday()===5){//向前一天时 当前为周五则 跳到 下周一
|
|
|
|
+ num=3
|
|
|
|
+ }
|
|
|
|
+ currentDate.value=moment(currentDate.value).add(num,'days')
|
|
|
|
+ selectDate.value=moment(selectDate.value).add(num,'days')
|
|
|
|
+ }
|
|
|
|
+ getInfo()
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+// 切换合约
|
|
|
|
+const allClassifyTypeList=[] //所有合约的数据
|
|
|
|
+function getAllClassifyType(){
|
|
|
|
+ apiPositionAnalysisList().then(res=>{
|
|
|
|
+ if(res.code===200){
|
|
|
|
+ const arr=res.data||[]
|
|
|
|
+ // 将数据展开
|
|
|
|
+ arr.forEach(item => {
|
|
|
|
+ item.items&&item.items.forEach(itemC1=>{
|
|
|
|
+ itemC1.items&&itemC1.items.forEach(itemC2=>{
|
|
|
|
+ allClassifyTypeList.push({
|
|
|
|
+ exchange:item.exchange,
|
|
|
|
+ classify_name:itemC1.classify_name,
|
|
|
|
+ classify_type:itemC2.classify_type
|
|
|
|
+ })
|
|
|
|
+ })
|
|
|
|
+ })
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
+getAllClassifyType()
|
|
|
|
+function handleClassifyTypeChange(type){
|
|
|
|
+ const currentExchange=route.query.exchange
|
|
|
|
+ const currentClassifyName=route.query.classify_name
|
|
|
|
+ const currentClassifyType=route.query.classify_type
|
|
|
|
+ // 找index
|
|
|
|
+ let indexNum=0
|
|
|
|
+ allClassifyTypeList.forEach((item,index)=>{
|
|
|
|
+ if(item.exchange===currentExchange&&item.classify_name===currentClassifyName&&item.classify_type===currentClassifyType) indexNum=index
|
|
|
|
+ })
|
|
|
|
+ // console.log(indexNum);
|
|
|
|
+ let obj={}
|
|
|
|
+ if(type==='before'){
|
|
|
|
+ obj=allClassifyTypeList[indexNum===0?allClassifyTypeList.length-1:indexNum-1]
|
|
|
|
+ }else{
|
|
|
|
+ obj=allClassifyTypeList[indexNum===allClassifyTypeList.length-1?0:indexNum+1]
|
|
|
|
+ }
|
|
|
|
+ // console.log(obj);
|
|
|
|
+
|
|
|
|
+ router.replace({
|
|
|
|
+ query:{
|
|
|
|
+ ...route.query,
|
|
|
|
+ exchange:obj.exchange,
|
|
|
|
+ classify_name:obj.classify_name,
|
|
|
|
+ classify_type:obj.classify_type
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+watch(
|
|
|
|
+ ()=>route.query,
|
|
|
|
+ (n)=>{
|
|
|
|
+ selectDate.value=''
|
|
|
|
+ currentDate.value=''
|
|
|
|
+ getInfo()
|
|
|
|
+ }
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+// 获取详情
|
|
|
|
+let pageLoading=ref(false)
|
|
|
|
+const chartListState = reactive({
|
|
|
|
+ buy_list:{
|
|
|
|
+ name:'多单',
|
|
|
|
+ labelName:'持多单量',
|
|
|
|
+ },
|
|
|
|
+ sold_list:{
|
|
|
|
+ name:'空单',
|
|
|
|
+ labelName:'持空单量',
|
|
|
|
+ },
|
|
|
|
+ clean_buy_list:{
|
|
|
|
+ name:'净多单',
|
|
|
|
+ labelName:'净多单量',
|
|
|
|
+ },
|
|
|
|
+ clean_sold_list:{
|
|
|
|
+ name:'净空单',
|
|
|
|
+ labelName:'净空单量',
|
|
|
|
+ }
|
|
|
|
+})
|
|
|
|
+async function getInfo(){
|
|
|
|
+ pageLoading.value=true
|
|
|
|
+ const res=await apiPositionAnalysisInfo({
|
|
|
|
+ data_time:selectDate.value?moment(selectDate.value).format('YYYY-MM-DD'):'',
|
|
|
|
+ classify_name:route.query.classify_name,
|
|
|
|
+ classify_type:route.query.classify_type,
|
|
|
|
+ exchange:route.query.exchange
|
|
|
|
+ })
|
|
|
|
+ pageLoading.value=false
|
|
|
|
+ if(res.code===200){
|
|
|
|
+ const obj=res.data||{}
|
|
|
|
+ for (let key in chartListState) {
|
|
|
|
+ chartListState[key]={...chartListState[key],...obj[key]}
|
|
|
|
+ }
|
|
|
|
+ if(res.data.data_time){
|
|
|
|
+ selectDate.value=moment(res.data.data_time).toDate()
|
|
|
|
+ currentDate.value=moment(res.data.data_time).toDate()
|
|
|
|
+ }
|
|
|
|
+ document.title=`${route.query.classify_type} ${moment(selectDate.value).format('YYYYMMDD')}持仓`
|
|
|
|
+ }else{
|
|
|
|
+ // 清空数据
|
|
|
|
+ for (let key in chartListState) {
|
|
|
|
+ chartListState[key].list=null
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ const postData={
|
|
|
|
+ path:'/pages/positionAnalysis/detail',
|
|
|
|
+ params:{
|
|
|
|
+ classify_name:route.query.classify_name,
|
|
|
|
+ classify_type:route.query.classify_type,
|
|
|
|
+ exchange:route.query.exchange,
|
|
|
|
+ },
|
|
|
|
+ title:`${route.query.classify_type} ${selectDate.value?moment(selectDate.value).format('YYYY-MM-DD'):''}持仓`||'持仓分析',
|
|
|
|
+ shareImg:''
|
|
|
|
+ }
|
|
|
|
+ wx.miniProgram.postMessage({ data: postData })
|
|
|
|
+
|
|
|
|
+ nextTick(()=>{
|
|
|
|
+ // 获取页面实际高度 传给pc端
|
|
|
|
+ const pageEl=document.getElementsByClassName('chart-position-analysis-page')
|
|
|
|
+ window.parent.postMessage({
|
|
|
|
+ opt:'updateIframeHeight',
|
|
|
|
+ height:pageEl[0].offsetHeight
|
|
|
|
+ },"*")
|
|
|
|
+
|
|
|
|
+ // 传给pc当前的数据
|
|
|
|
+ window.parent.postMessage({
|
|
|
|
+ opt:'updateInfo',
|
|
|
|
+ data_time:selectDate.value?moment(selectDate.value).format('YYYY-MM-DD'):'',
|
|
|
|
+ classify_name:route.query.classify_name,
|
|
|
|
+ classify_type:route.query.classify_type,
|
|
|
|
+ exchange:route.query.exchange,
|
|
|
|
+ title:`${route.query.classify_type} ${moment(selectDate.value).format('YYYYMMDD')}持仓`
|
|
|
|
+ },"*")
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
+getInfo()
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+// 下拉刷新
|
|
|
|
+let isRefresh=ref(false)
|
|
|
|
+function onRefresh(){
|
|
|
|
+ getInfo()
|
|
|
|
+ setTimeout(()=>{
|
|
|
|
+ isRefresh.value=false
|
|
|
|
+ },1500)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+// 返回列表
|
|
|
|
+function handleBackList(){
|
|
|
|
+ wx.miniProgram.navigateBack()
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+// 监听pc端传来的消息
|
|
|
|
+window.addEventListener('message',e=>{
|
|
|
|
+ // 监听选择的日期改变
|
|
|
|
+ if(e.data.opt=="date"){
|
|
|
|
+ selectDate.value=e.data.val
|
|
|
|
+ getInfo()
|
|
|
|
+ }else if(e.data.opt==='beforeDate'){
|
|
|
|
+ handleDateChange('before')
|
|
|
|
+ }else if(e.data.opt==='nextDate'){
|
|
|
|
+ handleDateChange('next')
|
|
|
|
+ }else if(e.data.opt==='beforeClassifyType'){
|
|
|
|
+ handleClassifyTypeChange('before')
|
|
|
|
+ }else if(e.data.opt==='nextClassifyType'){
|
|
|
|
+ handleClassifyTypeChange('next')
|
|
|
|
+ }
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<template>
|
|
|
|
+ <PullRefresh v-model="isRefresh" @refresh="onRefresh">
|
|
|
|
+ <div :class="['chart-position-analysis-page',isPcShow?'chart-position-analysis-page-pc':'']" v-if="!pageLoading">
|
|
|
|
+ <div class="top-sticky-wrap">
|
|
|
|
+ <div class="notice-box">如无法滑动,请在左侧空白处尝试</div>
|
|
|
|
+ <div class="action-box">
|
|
|
|
+ <div
|
|
|
|
+ class="select-time-box"
|
|
|
|
+ :style="{color:selectDate?'#333':'#999'}"
|
|
|
|
+ @click="showDate=true"
|
|
|
|
+ >{{selectDate?moment(selectDate).format('YYYY-MM-DD'):'选择日期'}}</div>
|
|
|
|
+ <span style="color:#E3B377" @click="handleDateChange('before')">前一天</span>
|
|
|
|
+ <span style="color:#E3B377" @click="handleDateChange('next')">后一天</span>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="empty-wrap" v-if="!chartListState.buy_list.list">
|
|
|
|
+ <span>该日期无数据!</span>
|
|
|
|
+ </div>
|
|
|
|
+ <template v-else>
|
|
|
|
+ <div class="chart-wrap" v-for="(val,key) of chartListState" :key="key">
|
|
|
|
+ <div class="top-info-box">
|
|
|
|
+ <span>{{chartListState[key].name}}</span>
|
|
|
|
+ <span><span style="color:#999;margin-right:2px">总计 </span>{{chartListState[key].total_deal_value}}</span>
|
|
|
|
+ <span><span style="color:#999;margin-right:2px">较昨日 </span>{{chartListState[key].total_deal_change}}</span>
|
|
|
|
+ </div>
|
|
|
|
+ <chart-box :keyVal="key" :data="chartListState[key]"/>
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+
|
|
|
|
+ <div class="bot-fixed-wrap">
|
|
|
|
+ <div class="btn black-btn" @click="handleClassifyTypeChange('before')">上个合约</div>
|
|
|
|
+ <div class="btn black-btn" @click="handleClassifyTypeChange('next')">下个合约</div>
|
|
|
|
+ <div class="btn grey-btn" @click="handleBackList">返回列表</div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ </div>
|
|
|
|
+ </PullRefresh>
|
|
|
|
+ <!-- 选择时间弹窗 -->
|
|
|
|
+ <Popup
|
|
|
|
+ v-model:show="showDate"
|
|
|
|
+ position="bottom"
|
|
|
|
+ round
|
|
|
|
+ @close="handleCloseSelectDate"
|
|
|
|
+ >
|
|
|
|
+ <DatetimePicker
|
|
|
|
+ v-model="currentDate"
|
|
|
|
+ type="date"
|
|
|
|
+ title=""
|
|
|
|
+ :min-date="minDate"
|
|
|
|
+ @confirm="confirmSelectDate"
|
|
|
|
+ @cancel="showDate=false"
|
|
|
|
+ />
|
|
|
|
+ </Popup>
|
|
|
|
+
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
+.chart-position-analysis-page{
|
|
|
|
+ padding-bottom: calc(160px + constant(safe-area-inset-bottom));
|
|
|
|
+ padding-bottom: calc(160px + env(safe-area-inset-bottom));
|
|
|
|
+}
|
|
|
|
+.top-sticky-wrap{
|
|
|
|
+ position: sticky;
|
|
|
|
+ top: 0;
|
|
|
|
+ z-index: 99;
|
|
|
|
+ background-color: #fff;
|
|
|
|
+ .notice-box{
|
|
|
|
+ font-size: 24px;
|
|
|
|
+ background: rgba(207, 192, 159, 0.1);
|
|
|
|
+ padding: 15px 34px;
|
|
|
|
+ }
|
|
|
|
+ .action-box{
|
|
|
|
+ padding: 40px 60px 40px 34px;
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+ .select-time-box{
|
|
|
|
+ width: 360px;
|
|
|
|
+ height: 70px;
|
|
|
|
+ background: #F6F6F6;
|
|
|
|
+ border: 1px solid #E5E5E5;
|
|
|
|
+ border-radius: 35px;
|
|
|
|
+ position: relative;
|
|
|
|
+ padding-left: 80px;
|
|
|
|
+ line-height: 70px;
|
|
|
|
+ &::before{
|
|
|
|
+ content: '';
|
|
|
|
+ display: block;
|
|
|
|
+ width: 28px;
|
|
|
|
+ height: 28px;
|
|
|
|
+ background-image: url('@/assets/hzyb/chart/calendar.png');
|
|
|
|
+ background-size: cover;
|
|
|
|
+ position: absolute;
|
|
|
|
+ top: 20px;
|
|
|
|
+ left: 25px;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+.bot-fixed-wrap{
|
|
|
|
+ position: fixed;
|
|
|
|
+ left: 0;
|
|
|
|
+ right: 0;
|
|
|
|
+ bottom: 0;
|
|
|
|
+ z-index: 99;
|
|
|
|
+ filter: drop-shadow(0px -2px 12px rgba(0, 0, 0, 0.08));
|
|
|
|
+ background-color: #fff;
|
|
|
|
+ padding-bottom: constant(safe-area-inset-bottom);
|
|
|
|
+ padding-bottom: env(safe-area-inset-bottom);
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+ padding: 20px 34px;
|
|
|
|
+ .btn{
|
|
|
|
+ width: 30%;
|
|
|
|
+ height: 80px;
|
|
|
|
+ line-height: 80px;
|
|
|
|
+ text-align: center;
|
|
|
|
+ font-size: 28px;
|
|
|
|
+ border-radius: 40px;
|
|
|
|
+ }
|
|
|
|
+ .black-btn{
|
|
|
|
+ color: #E3B377;
|
|
|
|
+ background-color: #333333;
|
|
|
|
+ }
|
|
|
|
+ .grey-btn{
|
|
|
|
+ color: #666666;
|
|
|
|
+ background-color: #F5F5F5;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+.chart-wrap{
|
|
|
|
+ width: 100%;
|
|
|
|
+ margin-bottom: 60px;
|
|
|
|
+ .top-info-box{
|
|
|
|
+ padding: 0 34px 30px 34px;
|
|
|
|
+ text-align: center;
|
|
|
|
+ span{
|
|
|
|
+ display: inline-block;
|
|
|
|
+ margin-right: 50px;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+.empty-wrap{
|
|
|
|
+ text-align: center;
|
|
|
|
+ padding-top: 300px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// @media (min-width: 600px){
|
|
|
|
+ .chart-position-analysis-page-pc{
|
|
|
|
+ padding: 0;
|
|
|
|
+ .top-sticky-wrap{
|
|
|
|
+ display: none;
|
|
|
|
+ }
|
|
|
|
+ .bot-fixed-wrap{
|
|
|
|
+ display: none;
|
|
|
|
+ }
|
|
|
|
+ .empty-wrap{
|
|
|
|
+ font-size: 16PX;
|
|
|
|
+ }
|
|
|
|
+ .chart-wrap{
|
|
|
|
+ margin-bottom: 60PX;
|
|
|
|
+ .top-info-box{
|
|
|
|
+ padding: 0 20PX 20PX;
|
|
|
|
+ text-align: center;
|
|
|
|
+ font-size: 20PX;
|
|
|
|
+ span{
|
|
|
|
+ display: inline-block;
|
|
|
|
+ margin-right: 30PX;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+// }
|
|
|
|
+</style>
|