Răsfoiți Sursa

日历详情

cxmo 11 luni în urmă
părinte
comite
a9a2a5f48f

+ 13 - 5
src/views/hzyb/chart/component/noAuth.vue

@@ -15,6 +15,14 @@ getUserInfo()
 
 const props = defineProps({
   data: Object,
+  source:{
+    type:Number,
+    default:3,
+  },
+  from_page:{
+    type:String,
+    default:'图库详情'
+  }
 });
 
 const authType = computed(() => {
@@ -40,8 +48,8 @@ const handleAutoApply=()=>{
         apiApplyPermission({
             company_name:props.data.customer_info.company_name,
             real_name:props.data.customer_info.name,
-            source:3,
-            from_page:'图库详情'
+            source:props.source,
+            from_page:props.from_page
         }).then(res=>{
             if(res.code===200){
                 console.log('主动申请成功');
@@ -71,14 +79,14 @@ const handleApply=()=>{
         apiApplyPermission({
             company_name:props.data.customer_info.company_name,
             real_name:props.data.customer_info.name,
-            source:3,
-            from_page:'图库详情'
+            source:props.source,
+            from_page:props.from_page
         }).then(res=>{
             wx.miniProgram.navigateTo({url:'/pages-applyPermission/applyResult'})
         })
         return
     }
-    wx.miniProgram.navigateTo({ url: '/pages-applyPermission/applyPermission?source=3&from_page=图库详情' })
+    wx.miniProgram.navigateTo({ url: `/pages-applyPermission/applyPermission?source=${props.source}&from_page=${props.from_page}`})
 }
 
 const goBack=()=>{

+ 101 - 2
src/views/hzyb/forexCalendar/Detail.vue

@@ -1,13 +1,112 @@
 <script setup>
 import { ref, reactive } from 'vue'
+import {useRoute, useRouter,onBeforeRouteUpdate} from 'vue-router'
+import chartBox from '../chart/component/chartBox.vue'
+import {
+    apiMyChartDetail,
+} from '@/api/hzyb/chart.js'
+import {setSplineOpt} from '../hooks/chartBase'
+/**
+ * 外汇日历详情
+        传入参数:
+            选中的指标
+            月份的起始日期,结束日期
+        获取所有事项
+        找到带指标的事项,设置初始索引为选中的指标在所有指标事项中的位置
+        切换上下张切换索引,当到达第一张/最后一张时,循环这个列表
+ */
+const route=useRoute()
+let chartData=ref({
+    series:[],
+    xAxis:[],
+    yAxis:[],
+
+})// 图表配置数据
+let resData=ref(null)//接口详情数据
+let pageBoxPosition=reactive({
+    top:window.innerHeight-165,
+    left:window.innerWidth-50,
+    temTop:0,
+    temLeft:0,
+})
+localStorage.setItem('hzyb-token',route.query.token)
+async function testChart(){
+    const res=await apiMyChartDetail({
+        ChartInfoId:'178',
+    })
+    resData.value=res.data
+    chartData.value = setSplineOpt(res.data.EdbInfoList,resData)
+}
+testChart()
+function pageChange(){}
+const pageTouchmove=(e)=>{
+    const touchObj=e.touches[0]
+    let top=touchObj.clientY-82
+    let left=touchObj.clientX-25
+    if(left<=0){
+        left=0
+    }
+    if(left>window.innerWidth-50){
+        left=window.innerWidth-50
+    }
+    if(top<=0){
+        top=0
+    }
+    if(top>window.innerHeight-115){
+        top=window.innerHeight-115
+    }
+
+    pageBoxPosition.top=top
+    pageBoxPosition.left=left
+
+    event.preventDefault();//阻止页面移动
+}
+
 </script>
 
 <template>
-    <div>
-        外汇日历详情
+    <div class="edb-detail-wrap">
+        <div class="edb-title">{{resData.ChartInfo.ChartName}}</div>
+        <chartBox :options='chartData' :chartInfo="{}" v-if="!loading"></chartBox>
+        <!-- 上一张下一张图切换 -->
+        <div 
+            class="change-page-wrap" 
+            :style="{left:pageBoxPosition.left+'px',top:pageBoxPosition.top+'px'}"
+            @touchmove.stop="pageTouchmove"
+            @touchstart.stop=""
+        >
+            <div class="top" @click.stop="pageChange('before')"></div>
+            <div class="bot" @click.stop="pageChange('next')"></div>
+        </div>
     </div>
 </template>
 
 <style scoped lang="scss">
+.edb-detail-wrap{
+    .edb-title{
+        padding: 40px 34px 20px 34px;
+        font-size: 32px;
+        font-weight: bold;
+        color: #1F243A;
+        letter-spacing: 2px;
+        @media (min-width: 768px){
+            padding: 0px 0 20px 0;
+            font-size: 18px;
+        }
+    }
+    .change-page-wrap{
+        position: fixed;
+        right: 0;
+        bottom: 50px;
+        width: 50PX;
+        height: 115PX;
+        background-image: url('../../../assets/hzyb/chart/before-next.png');
+        background-size: cover;
+        z-index: 10;
+        .top,.bot{
+            height: 50%;
+        }
 
+    }
+}
 </style>

+ 337 - 0
src/views/hzyb/hooks/chartBase.js

@@ -0,0 +1,337 @@
+//图表数据处理 公共函数
+/**
+ * 为了应对之后其他页面需要渲染Highcharts图表的情况
+ * 基于 hzyb/chart/Detail.vue 内的函数进一步封装
+ * 非/---/括起来的部分表示对原函数有调整,/---/括起来的部分是直接复制的
+ */
+import moment from 'moment'
+import Highcharts from 'highcharts';
+import {basicYAxis,basicXAxis} from '../utils/chartBaseConfig'
+
+//--------------------------------------
+/* 指标顺序调整  IsAxis: 0右轴 1左轴 2右2*/
+export const changeEdbOrder = (data) => {
+    // 左轴指标
+    let left_edbs = data.filter(_ => _.IsAxis===1);
+    //右轴指标
+    let right_edbs = data.filter(_ => !_.IsAxis);
+    // 右2轴指标
+    let right_two_edbs = data.filter(_ => _.IsAxis === 2);
+    // 按 左 右 右2顺序排列
+    return [left_edbs,right_edbs,right_two_edbs].flat(Infinity);
+}
+/* 拼接数据列动态name */
+export const setDyncmicSerieName = (item,dynamic_arr) => {
+    const { IsAxis,IsOrder,EdbInfoType,LeadValue,LeadUnit }  = item;
+    // IsAxis左轴1 右轴0 2右2轴 
+      //IsOrder正序false 逆序true 
+      //EdbInfoType是否是领先指标
+    const axisLabelMap = {
+        0: '右轴',
+        2: '右2轴'
+    }
+    const orderLabelMap = {
+        1: '逆序'
+    }
+    const edbInfoMap = {
+        0: '领先'
+    }
+
+    let axis_tag = axisLabelMap[IsAxis] || '';
+      //逆序拼接
+    let order_tag = orderLabelMap[Number(IsOrder)] ? `${axis_tag ? ',': ''}${orderLabelMap[Number(IsOrder)]}` : ''
+      //领先拼接
+    let edb_tag = edbInfoMap[EdbInfoType] ? `${(axis_tag||order_tag) ? ',' : '' }${edbInfoMap[EdbInfoType]}${LeadValue}${LeadUnit}` : '';
+
+    let dynamic_tag = (axis_tag || order_tag || edb_tag) ? `(${axis_tag}${order_tag}${edb_tag})` : '';
+
+    let temName = dynamic_arr.length > 1
+                ? `${item.EdbName}(${item.SourceName})${dynamic_tag}`
+                : `${item.EdbName}${dynamic_tag}`
+    if(temName.length>20){
+        let temArr=[]
+        for(let i=0;i<temName.length/20;i++){
+            temArr.push(temName.slice(i*20,i*20+20))
+        }
+        // console.log(temArr);
+        temName=temArr.join('<br>')
+    }
+
+    return temName
+}
+/* 预测配置 分区 */
+export const getPredictParams = ({LatestDate,MoveLatestDate,PredictChartColor,ChartStyle},chartStyle) => {
+    return {
+    zoneAxis: 'x',
+    zones: [{
+        value: new Date(MoveLatestDate||LatestDate).getTime()+1
+    }, {
+        dashStyle: 'ShortDot',
+        color: (ChartStyle==='column' || chartStyle==='column') ? 'transparent' : PredictChartColor
+    }]
+    }
+}
+// 查询范围为1年内 x轴显示为月/日 否则默认年/月
+export const xTimeDiffer=(minTime,maxTime)=>{
+    //年限差
+    let year_differ=moment(maxTime).diff(moment(minTime),'years',true)
+    console.log('年限差',year_differ)
+    if (year_differ<=1) {
+        console.log('true');
+        return true;
+    } else {
+        console.log('false');
+        return false;
+    }
+}
+//-------------------------------------
+ /* 处理轴的标识线结构 在指定轴位置上拼接标识线 
+    0:右轴 1:左轴 2:右2轴 x轴固定3
+    axisType表示x轴类型 处理时间轴的值 datetime/null 
+*/
+export const setAxisPlotLines = (axis,axisType,resData) => {
+    const { MarkersLines,ChartType } = resData.value.ChartInfo;
+    const { EdbInfoList } = resData.value;
+    if(!MarkersLines) return []
+
+    let markerLines = JSON.parse(MarkersLines);
+
+    let arr = markerLines.filter(_ => _.isShow&&_.axis===axis)
+    let plotLines = arr.map(_ => {
+        //是否是x时间轴
+        let isXDateAxis = axis===3&&axisType==='datetime';
+        let markerValue;
+        if(isXDateAxis) {
+            //季节图x轴额外拼个年份
+            let nowYear = ChartType===2 ? new Date(EdbInfoList[0].DataList[1].DataList
+                [0].DataTimestamp).getFullYear() : '';
+            markerValue = ChartType===2 
+                ? new Date(`${nowYear}-${_.value}`).getTime()
+                : new Date(_.value).getTime()
+        }else {
+            markerValue = Number(_.value)
+        }
+
+        return { 
+        value: markerValue,
+        dashStyle: _.dashStyle,
+        width: Number(_.lineWidth),
+        color: _.color,
+        label: {
+            text: _.text||'',
+            verticalAlign: _.textPosition,
+            style: {
+            color: _.textColor,
+            fontSize: _.textFontSize
+            }
+        }
+        }
+    })
+    return plotLines
+}
+/* 处理标识区拼接 axisType表示x轴类型处理时间轴的值 datetime/null */
+export const setAxisPlotAreas = (axis,axisType,resData) => {
+    const { MarkersAreas,ChartType } = resData.value.ChartInfo;
+    const { EdbInfoList } = resData.value;
+    if(!MarkersAreas) return []
+
+    let markerAreas = JSON.parse(MarkersAreas);
+
+    let arr = markerAreas.filter(_ => _.isShow&&_.axis===axis)
+    let plotBands = arr.map(_ => {
+        //是否是x时间轴
+        let isXDateAxis = axis===3&&axisType==='datetime';
+        let fromMarkerValue,toMarkerValue;
+        if(isXDateAxis) {
+            //季节图x轴额外拼个年份
+            let nowYear = ChartType===2 ? new Date(EdbInfoList[0].DataList[1].DataList
+                [0].DataTimestamp).getFullYear() : '';
+                console.log(nowYear)
+            fromMarkerValue = ChartType===2 
+                ? new Date(`${nowYear}-${_.fromValue}`).getTime()
+                : new Date(_.fromValue).getTime()
+
+            toMarkerValue = ChartType===2 
+                ? new Date(`${nowYear}-${_.toValue}`).getTime()
+                : new Date(_.toValue).getTime()
+        }else {
+            fromMarkerValue = Number(_.fromValue);
+            toMarkerValue = Number(_.toValue);
+        }
+
+        //默认label有些偏移 重新归正下
+        let positionMapValue = {
+            'top': 12,
+            'middle': 0,
+            'bottom': -10
+        }
+
+        return { 
+            from: fromMarkerValue,
+            to: toMarkerValue,
+            color: _.color,
+            label: {
+                text: _.text||'',
+                verticalAlign: _.textPosition,
+                y: positionMapValue[_.textPosition],
+                style: {
+                    color: _.textColor,
+                    fontSize: _.textFontSize
+                }
+            }
+        }
+    })
+
+    return plotBands
+}
+// 设置常规图配置 曲线
+export const setSplineOpt=(data,resData)=>{
+    let series=[]
+    let yAxis=[]
+    let xAxis = {}
+
+    let temYLeftArr=[]
+    let temYRightArr=[]
+    let temYRightTwoArr = []
+    let temYLeftIndex=data.findIndex((item) => item.IsAxis===1)
+    let temYRightIndex=data.findIndex((item) => !item.IsAxis)
+    let temYRightTwoIndex = data.findIndex((item) => item.IsAxis===2)
+
+     /* 主题样式*/
+    const chartTheme =  resData.value.ChartInfo.ChartThemeStyle ? JSON.parse(resData.value.ChartInfo.ChartThemeStyle) : null;
+
+    let minAndMaxTimeTemArr=[]//存放所有指标的最大最小时间
+
+    //有右二轴时排个序 按照左 右 右2的顺序
+    let newData = data.some(_ =>_.IsAxis===2) ? changeEdbOrder(data) : data;
+    
+
+    newData.forEach((item,index)=>{
+
+         //轴位置值相同的下标
+        let sameSideIndex = newData.findIndex(i => i.IsAxis === item.IsAxis);
+
+        let dynamic_title = item.EdbName;
+        let dynamic_arr = newData.filter(
+          (item) => dynamic_title === item.EdbName
+        );
+        //处理数据列name
+        let temName= setDyncmicSerieName(item,dynamic_arr)  
+
+        //预测指标配置
+        let predict_params = item.EdbInfoCategoryType === 1 ? getPredictParams(item) : {};
+
+        let seriesItemObj={
+            data:[],
+            dataGrouping:{
+                enabled:false
+            },
+            type: (chartTheme&&chartTheme.lineOptions.lineType) || 'spline',
+            dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+            yAxis:index,
+            name:temName,
+            color: item.ChartColor,
+            lineWidth: Number(item.ChartWidth),
+            visible:true,
+            LatestDate:item.LatestDate,
+            LatestValue:item.LatestValue,
+            ...predict_params
+        }
+        item.DataList = item.DataList || [];
+        for (let i of item.DataList) {
+          seriesItemObj.data.push([i.DataTimestamp, i.Value]);
+        }
+        series.push(seriesItemObj)
+        
+
+        // 设置y轴
+        if(item.IsAxis){
+            temYLeftArr.push(item)
+        }else{
+            temYRightArr.push(item)
+        }
+
+        let yItem={
+            ...basicYAxis,
+            IsAxis:item.IsAxis,
+            labels: {
+                formatter: function (ctx) {
+                    return sameSideIndex !== index ? '' : ctx.value;
+                },
+                align: 'center',
+                x: [0,2].includes(item.IsAxis) ? 5 : -5,
+                style:{
+                    ...chartTheme&&chartTheme.yAxisOptions.style
+                },
+            },
+            tickWidth: sameSideIndex !== index ? 0 : 1,
+            title: {
+                text:  sameSideIndex !== index ? '' : `${item.Unit||''}`,
+                align: 'high',
+                rotation: 0,
+                y: -15,
+                x: (item.IsAxis===0 && temYRightTwoIndex>-1) ? -newData[temYRightTwoIndex].Unit.length*12 : 0,
+                textAlign: item.IsAxis===1 ? 'left' : 'right',
+                reserveSpace: false,
+                style:{
+                    ...chartTheme&&chartTheme.yAxisOptions.style
+                },
+            },
+            opposite: [0,2].includes(item.IsAxis),
+            reversed: item.IsOrder,
+            min: item.MinData,
+            max: item.MaxData,
+            visible: sameSideIndex === index,
+            plotBands: setAxisPlotAreas(item.IsAxis,'',resData),
+            plotLines: setAxisPlotLines(item.IsAxis,'',resData),
+            chartEdbInfo:item//指标数据用于在保存时读取指标数据
+        }
+        yAxis.push(yItem)
+        
+        if(item.DataList.length>0){
+            minAndMaxTimeTemArr.push(item.DataList[0].DataTimestamp)
+            minAndMaxTimeTemArr.push(item.DataList[item.DataList.length-1].DataTimestamp)
+        }
+        
+    })
+
+    // 设置x轴
+    // 找出所有指标的最大和最小时间 分成6段
+    let minTime=Math.min.apply(null,minAndMaxTimeTemArr)
+    let maxTime=Math.max.apply(null,minAndMaxTimeTemArr)
+    const isLessThanOneYear = xTimeDiffer(minTime,maxTime)
+    xAxis={
+        ...basicXAxis,
+        tickInterval:((maxTime-minTime)/6)/(24*3600*1000)>30?(maxTime-minTime)/6:24*3600*1000*30,
+        labels: {
+            formatter:  (ctx)=> {
+                return isLessThanOneYear
+                ? Highcharts.dateFormat('%m/%d', ctx.value)
+                : Highcharts.dateFormat('%y/%m', ctx.value);
+            },
+            style: {
+                ...chartTheme&&chartTheme.xAxisOptions.style
+            }
+        },
+        plotBands: setAxisPlotAreas(3,'datetime',resData),
+        plotLines: setAxisPlotLines(3,'datetime',resData)
+    }
+    yAxis.forEach(item=>{
+        if(item.IsAxis===1){//左轴
+            item.min=data[temYLeftIndex].MinData
+            item.max=data[temYLeftIndex].MaxData
+        }else if (item.IsAxis===2){ // 右2轴
+            item.min=data[temYRightTwoIndex].MinData
+            item.max=data[temYRightTwoIndex].MaxData
+        }else{
+            item.min=data[temYRightIndex].MinData
+            item.max=data[temYRightIndex].MaxData
+        }
+    })
+    return {
+        series,
+        xAxis:[xAxis],
+        yAxis,
+        rangeSelector:{ enabled: false}
+    }
+}

+ 44 - 0
src/views/hzyb/utils/chartBaseConfig.js

@@ -0,0 +1,44 @@
+//图表基础配置
+// 散点x轴
+export const scatterXAxis = {
+    tickPosition: 'inside',
+    lineColor: '#bfbfbf',
+    tickColor: '#bfbfbf',
+    tickLength:5,
+    ordinal: false,
+    type: 'linear',
+}
+
+// 基础y轴配置
+export const basicYAxis = {
+    tickWidth: 1,
+    tickLength: 5,
+    lineWidth: 1,
+    lineColor: '#bfbfbf',
+    tickColor: '#bfbfbf',
+    // offset: 0,
+    visible: true,
+    gridLineWidth: 0,
+    tickPosition: 'inside',
+    endOnTick: false,
+    startOnTick: false,
+    showLastLabel: true,
+    tickPixelInterval: 50,
+}
+
+//基础x轴配置
+export const basicXAxis={
+    tickPosition: 'inside',
+    lineColor: '#bfbfbf',
+    tickColor: '#bfbfbf',
+    tickLength:5,
+    type: 'datetime',
+    ordinal: false,
+    dateTimeLabelFormats: {
+        day: '%y/%m',
+        week: '%y/%m',
+        month: '%y/%m',
+        year: '%y/%m',
+    },
+    xDateFormat:'%Y-%m-%d'
+}