ソースを参照

图详情-更多设置:分享链接、刷新、另存为、加入图库

cxmo 1 年間 前
コミット
c2d0ecf026

+ 2 - 0
.env.development

@@ -4,3 +4,5 @@ VITE_APP_API_URL="https://rddptest.hzinsights.com/adminapi"
 VITE_APP_BASE_URL="/"
 # 打包输入文件名
 VITE_APP_OUTDIR="dist"
+#分享图表地址
+VITE_CHART_LINK="https://charttest.hzinsights.com/chartshow"

+ 3 - 1
.env.production

@@ -3,4 +3,6 @@ VITE_APP_API_URL="https://mveta.hzinsights.com/v1"
 # 路由根地址
 VITE_APP_BASE_URL="/"
 # 打包输入文件名
-VITE_APP_OUTDIR="hongze_ETA_mobile"
+VITE_APP_OUTDIR="hongze_ETA_mobile"
+#分享图表地址
+VITE_CHART_LINK="https://chartlib.hzinsights.com/chartshow"

+ 2 - 0
.env.test

@@ -4,3 +4,5 @@ VITE_APP_API_URL="http://8.136.199.33:8610/v1"
 VITE_APP_BASE_URL="/"
 # 打包输入文件名
 VITE_APP_OUTDIR="hongze_ETA_mobile"
+#分享图表地址
+VITE_CHART_LINK="https://charttest.hzinsights.com/chartshow"

+ 7 - 0
src/api/chart.js

@@ -212,5 +212,12 @@ export default{
     getEdbCreateHistory(params){
         return get('/datamanage/edb_info/trace',params)
     },
+    /**
+     * 刷新图表
+     * @param ChartInfoId 
+     */
+    chartRefresh(params){
+        return get('/datamanage/chart_info/refresh',params)
+    }
 
 } 

+ 403 - 77
src/views/chartETA/ChartDetail.vue

@@ -1,13 +1,16 @@
 <script setup name="ChartETAChartDetail">
 import {nextTick, onMounted,ref,reactive} from 'vue'
+import {showDialog, showToast} from 'vant'
 import apiChart from '@/api/chart'
 import { useRoute } from 'vue-router'
-import { useWindowSize } from '@vueuse/core'
+import { getSSRHandler, useWindowSize } from '@vueuse/core'
 import {yearSelectOpt,sameOptionType} from '@/hooks/chart/config'
 import {useChartRender} from '@/hooks/chart/render'
 import moment from 'moment'
 import EdbInfo from './components/EdbInfo.vue'
 import SourceDetail from './components/SourceDetail.vue'
+import TreeSelectPop from './components/TreeSelectPop.vue'
+import AddChartToMyETA from './components/AddChartToMyETA.vue'
 import _ from 'lodash';
 const {options,axisLimitState,chartRender}=useChartRender()
 const { width } = useWindowSize()
@@ -34,6 +37,7 @@ async function getChartDetail(e){
     if(res.Ret!==200) return
     chartInfoData=res.Data
     chartInfo.value=res.Data.ChartInfo
+    chartActions.value = getChartActions(res.Data.ChartInfo)
     if(res.Data.ChartInfo.Source===2){
         edbList.value=[res.Data.EdbInfoList[0]]
     }else{
@@ -206,6 +210,144 @@ let showSourceDetail = ref(false)
 function handleShowSourceDetail(){
     showSourceDetail.value = true
 }
+//显示更多操作栏
+let showMoreAction = ref(false)
+let chartActions = ref([])
+function getChartActions(chartInfo){
+    return [
+        {
+            type:'refresh',
+            label:'刷新',
+            show:true
+        },
+        {
+            type:'share',
+            label:'分享',
+            show:!Boolean(chartInfo.Disabled)
+        },
+        {
+            type:'saveOther',
+            label:'另存为',
+            show:true
+        },
+        {
+            type:'savePic',
+            label:'保存图片',
+            show:true
+        },
+        {
+            type:'setEnName',
+            label:'设置英文名称',
+            show:true
+        },
+        {
+            type:'addToMyETA',
+            label:'加入我的图库',
+            show:true
+        },
+        {
+            type:'delete',
+            label:'删除',
+            show:chartInfo.IsEdit
+        }
+    ]
+}
+
+function handleActionClick(action){
+    const eventMap = {
+        'refresh':refreshChart,
+        'share':getShareLink,
+        'saveOther':openSaveChartOtherDialog,
+        'savePic':saveChartPic,
+        'setEnName':goSetChartEnName,
+        'addToMyETA':openAddToMyETADialog,
+        'delete':deleteChart
+    }
+    eventMap[action.type]()
+    //showMoreAction.value = false
+}
+//刷新图表
+function refreshChart(){
+    apiChart.chartRefresh({
+        ChartInfoId:chartInfo.value.ChartInfoId
+    }).then(res=>{
+        if(res.Ret!==200) return 
+        getChartDetail()
+        showToast({message:'刷新成功',type:'success'})
+    })
+}
+let confirmFlag = ref(true)
+//获取分享链接
+async function getShareLink(){
+    const currentLang = localStorage.getItem('chartETALange')==='EN'?'en':'ch'
+    //若当前语言设置为英文,则检测图表
+    if(currentLang==='en') {
+        !checkChartEnOption()&&(
+            await showDialog({
+                title: '提示',
+                message: '英文名称未输入完整,分享图表上可能出现空名称的情况,确定继续分享吗?',
+                showCancelButton:true
+            }).then(() => {
+                confirmFlag.value = true
+            }).catch(()=>{
+                confirmFlag.value = false
+            })
+        )
+    }
+    if(!confirmFlag.value) return 
+    const linkUrl = `${import.meta.env.VITE_CHART_LINK}?code=${chartInfo.value.UniqueCode}&fromType=share&lang=${currentLang}`
+    //console.log('url',linkUrl)
+    try{
+        await navigator.clipboard.writeText(linkUrl)
+        showToast({message:'复制链接成功',type:'success'})
+    }catch(err){
+        showToast({message:'复制链接失败',type:'fail'})
+    }
+}
+function checkChartEnOption(){
+    if(!chartInfo.value.ChartNameEn) return false
+    for(const data of edbList){
+        if(data.EdbNameEn==""||(data.UnitEn==""&&data.Unit!="")){
+            return false
+        }
+    }
+    return true
+}
+
+let isShowSaveOtherDialog = ref(false)
+let catalogNodes = ref([])
+//另存为
+async function openSaveChartOtherDialog(){
+    const res = await apiChart.ETAChartClassifyList()
+    if(res.Ret!==200) return 
+    catalogNodes.value = res.Data?res.Data.AllNodes:[]||[]
+    isShowSaveOtherDialog.value = true
+}
+function saveOther(ClassifyId){
+    apiChart.ETAChartSaveOther({
+        ChartInfoId:chartInfo.value.ChartInfoId,
+        ChartName:chartInfo.value.ChartName+'(1)',
+        ChartClassifyId:ClassifyId
+    }).then(res=>{
+        if(res.Ret!==200) return 
+        showToast({message:'另存为成功',type:'success'})
+        isShowSaveOtherDialog.value = false
+    })
+}
+//保存图片
+function saveChartPic(){}
+//跳转设置英文页面
+function goSetChartEnName(){}
+
+let isShowAddToMyETADialog = ref(false)
+//加入我的图库
+function openAddToMyETADialog(){
+    isShowAddToMyETADialog.value = true
+}
+function addToMyETA(){}
+//删除图表
+function deleteChart(){}
+
 
 </script>
 
@@ -242,7 +384,7 @@ function handleShowSourceDetail(){
                 >{{chartState.startTime?chartState.startTime+'~'+chartState.endTime:'请选择时间段'}}</span>
             </div>
             <div class="right-action-box">
-                <div class="item" @click.stop="" >
+                <div class="item" @click="showMoreAction=true" >
                     <img src="@/assets/imgs/chartETA/more-icon.png" alt="">
                     <span>更多设置</span>
                 </div>
@@ -363,101 +505,173 @@ function handleShowSourceDetail(){
                 :show="showSourceDetail"
                 :EdbInfoId="showEDBData.EdbInfoId"
             />
-        </van-popup>
-    </div>
-
-
-    <!-- 上下限调整弹窗 -->
-    <van-popup 
-        v-model:show="showLimitPop"
-        :position="width>650?'center':'bottom'"
-        round
-        closeable
-        :style="width>650?{ width: '400px'}:''"
-    >
-        <div class="global-pop-wrap_mobile chart-set-limit-wrap">
-            <div class="head-box">
-                <div class="title">上下限设置</div>
-            </div>
-            <div class="content">
-                <!-- 左轴 -->
-                <div class="item-box" v-if="axisLimitState.hasLeftAxis">
-                    <span class="lable-text">左轴</span>
-                    <div class="input-box">
-                        <div class="item">
-                            <div class="type-text">上限</div>
-                            <div class="step-box">
-                                <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.leftMax" />
+        </van-popup> 
+        <!-- 上下限调整弹窗 -->
+        <van-popup 
+            v-model:show="showLimitPop"
+            :position="width>650?'center':'bottom'"
+            round
+            closeable
+            :style="width>650?{ width: '400px'}:''"
+        >
+            <div class="global-pop-wrap_mobile chart-set-limit-wrap">
+                <div class="head-box">
+                    <div class="title">上下限设置</div>
+                </div>
+                <div class="content">
+                    <!-- 左轴 -->
+                    <div class="item-box" v-if="axisLimitState.hasLeftAxis">
+                        <span class="lable-text">左轴</span>
+                        <div class="input-box">
+                            <div class="item">
+                                <div class="type-text">上限</div>
+                                <div class="step-box">
+                                    <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.leftMax" />
+                                </div>
                             </div>
-                        </div>
-                        <div class="item">
-                            <div class="type-text">下限</div>
-                            <div class="step-box">
-                                <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.leftMin" />
+                            <div class="item">
+                                <div class="type-text">下限</div>
+                                <div class="step-box">
+                                    <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.leftMin" />
+                                </div>
                             </div>
                         </div>
                     </div>
-                </div>
-                <!-- 右轴 -->
-                <div class="item-box" v-if="axisLimitState.hasRightAxis">
-                    <span class="lable-text">右轴</span>
-                    <div class="input-box">
-                        <div class="item">
-                            <div class="type-text">上限</div>
-                            <div class="step-box">
-                                <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.rightMax" />
+                    <!-- 右轴 -->
+                    <div class="item-box" v-if="axisLimitState.hasRightAxis">
+                        <span class="lable-text">右轴</span>
+                        <div class="input-box">
+                            <div class="item">
+                                <div class="type-text">上限</div>
+                                <div class="step-box">
+                                    <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.rightMax" />
+                                </div>
                             </div>
-                        </div>
-                        <div class="item">
-                            <div class="type-text">下限</div>
-                            <div class="step-box">
-                                <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.rightMin" />
+                            <div class="item">
+                                <div class="type-text">下限</div>
+                                <div class="step-box">
+                                    <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.rightMin" />
+                                </div>
                             </div>
                         </div>
                     </div>
-                </div>
-                <!-- 右二轴 -->
-                <div class="item-box" v-if="axisLimitState.hasRightTwoAxis">
-                    <span class="lable-text">右2轴</span>
-                    <div class="input-box">
-                        <div class="item">
-                            <div class="type-text">上限</div>
-                            <div class="step-box">
-                                <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.rightTwoMax" />
+                    <!-- 右二轴 -->
+                    <div class="item-box" v-if="axisLimitState.hasRightTwoAxis">
+                        <span class="lable-text">右2轴</span>
+                        <div class="input-box">
+                            <div class="item">
+                                <div class="type-text">上限</div>
+                                <div class="step-box">
+                                    <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.rightTwoMax" />
+                                </div>
                             </div>
-                        </div>
-                        <div class="item">
-                            <div class="type-text">下限</div>
-                            <div class="step-box">
-                                <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.rightTwoMin" />
+                            <div class="item">
+                                <div class="type-text">下限</div>
+                                <div class="step-box">
+                                    <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.rightTwoMin" />
+                                </div>
                             </div>
                         </div>
                     </div>
-                </div>
-                <!-- x轴 -->
-                <div class="item-box" v-if="axisLimitState.hasXAxis">
-                    <span class="lable-text">X轴</span>
-                    <div class="input-box">
-                        <div class="item">
-                            <div class="type-text">上限</div>
-                            <div class="step-box">
-                                <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.xMax" />
+                    <!-- x轴 -->
+                    <div class="item-box" v-if="axisLimitState.hasXAxis">
+                        <span class="lable-text">X轴</span>
+                        <div class="input-box">
+                            <div class="item">
+                                <div class="type-text">上限</div>
+                                <div class="step-box">
+                                    <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.xMax" />
+                                </div>
                             </div>
-                        </div>
-                        <div class="item">
-                            <div class="type-text">下限</div>
-                            <div class="step-box">
-                                <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.xMin" />
+                            <div class="item">
+                                <div class="type-text">下限</div>
+                                <div class="step-box">
+                                    <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.xMin" />
+                                </div>
                             </div>
                         </div>
                     </div>
                 </div>
+                <div class="bot-btn-box" @click="handleConfirmLimitChange">确定</div>
             </div>
-            <div class="bot-btn-box" @click="handleConfirmLimitChange">确定</div>
-        </div>
-    </van-popup>
+        </van-popup>
+        <!-- 更多设置弹窗 -->
+        <van-popup
+            v-model:show="showMoreAction"
+            :position="width>650?'center':'bottom'"
+            round
+            closeable
+            :style="width>650?{ width: '400px'}:''"
+        >
+            <div class="global-pop-wrap_mobile chart-more-action-wrap">
+                    <div class="head-box">
+                        <div class="title van-ellipsis">{{chartInfo.ChartName}}</div>
+                    </div>
+                    <div class="action-box">
+                        <template v-for="item in chartActions" :key="item.types">
+                            <div class="action-item" v-if="item.show" @click="handleActionClick(item)">
+                                {{item.label}}
+                            </div>
+                        </template>
+                        
+                    </div>
+            </div>
+        </van-popup>
+        <!-- 另存为弹窗 -->
+        <TreeSelectPop 
+            :isShowDialog="isShowSaveOtherDialog"
+            :dialogPosition="width>650?'center':'bottom'"
+            :catalogNodes="catalogNodes"
+            :chartInfo="chartInfo"
+            popTitle="另存为"
+            @close="isShowSaveOtherDialog=false"
+            @confirmMove="saveOther"
+        />
+        <!-- 加入我的图库弹窗 -->
+        <AddChartToMyETA 
+            :isShowDialog="isShowAddToMyETADialog"
+            :dialogPosition="width>650?'center':'bottom'"
+            :chartInfo="chartInfo"
+            @close="isShowAddToMyETADialog=false"
+        />
+    </div>
+
+
+   
 </template>
 
+<style lang="scss">
+.chart-detail-page{
+    .rename-wrap{
+        padding:48px;
+        input{
+            padding: 24px 32px;
+            border-radius: 12px;
+            background-color: #F6F6F6;
+            width: 100%;
+        }
+        .label{
+            color: #666666;
+            margin-bottom: 32px;
+            text-align: center;
+        }
+    }
+    @media screen and (min-width:$media-width){
+        .rename-wrap{
+            padding:24px;
+            input{
+                padding: 12px 16px;
+                border-radius: 6px;
+                background-color: #F6F6F6;
+                width: 100%;
+            }
+            .label{
+                margin-bottom: 16px;
+            }
+        }
+    }
+}
+</style>
 <style scoped lang="scss">
 .chart-detail-page{
     padding: $page-padding;
@@ -603,6 +817,74 @@ function handleShowSourceDetail(){
             }
         }
     }
+    .chart-set-limit-wrap{
+        .head-box{
+            .title{
+                padding: 0 $page-padding;
+                font-size: 36px;
+                font-weight: 600;
+                line-height: 120px;
+            }
+        }
+        .bot-btn-box{
+            line-height: 112px;
+            text-align: center;
+            color: $theme-color;
+            font-size: 32px;
+        }
+        .content{
+            padding: $page-padding;
+            .item-box{
+                display: flex;
+                align-items: flex-end;
+                margin-bottom: 30px;
+                .lable-text{
+                    width: 100px;
+                }
+                .input-box{
+                    flex: 1;
+                    display: flex;
+                    .item{
+                        flex: 1;
+                        text-align: center;
+                        .type-text{
+                            margin-bottom: 40px;
+                        }
+                        .step-box{
+                            display: inline-block;
+                            :deep(.van-stepper){
+                                display: flex;
+                                justify-content: center;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    
+    }
+    .chart-more-action-wrap{
+        .head-box{
+            .title{
+                width: 100%;
+                padding:34px 100px;
+                box-sizing: border-box;
+                font-size: 36px;
+                font-weight: 600;
+                text-align: center;
+            }
+        }
+        .action-box{
+            .action-item{
+                text-align: center;
+                padding:32px 84px;
+                border-bottom: 1px solid #DCDFE6;
+                &:last-child{
+                    border-bottom: none;
+                }
+            }
+        }
+    }
     @media screen and (min-width:$media-width){
         padding:30px;
         .chart-title{
@@ -703,6 +985,50 @@ function handleShowSourceDetail(){
                 }
             }
         }
+        .chart-set-limit-wrap{
+            .head-box{
+                .title{
+                    font-size: 18px;
+                    line-height: 50px;
+                    padding-left: 16px;
+                }
+            }
+            .bot-btn-box{
+                font-size: 16px;
+                line-height: 56px;
+                border-top-width: 8px;
+            }
+            .content{
+                max-height: 500px;
+                padding: 30px;
+                .item-box{
+                    margin-bottom: 15px;
+                    .lable-text{
+                        width: 50px;
+                    }
+                    .input-box{
+                        .item{
+                            .type-text{
+                                margin-bottom: 20px;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        .chart-more-action-wrap{
+        .head-box{
+            .title{
+                padding:17px 50px;
+                font-size: 18px;
+            }
+        }
+        .action-box{
+            .action-item{
+                padding:16px 42px;
+            }
+        }
+    }
     }
 }
 </style>

+ 1 - 0
src/views/chartETA/components/AddChartToMyETA.vue

@@ -182,6 +182,7 @@ function handleConfirmEditClassify(){
         background-color: #F6F6F6;
         height:16px;
     }
+    
     @media screen and (min-width:$media-width){
         width: 375px;
         .top-box{

+ 1 - 1
src/views/chartETA/components/SourceDetail.vue

@@ -17,7 +17,7 @@ watch(()=>props.show,()=>{
     if(props.show){
         getEdbInfo()
     }
-})
+},{immediate:true})
 
 const edbSourceData = ref([])
 async function getEdbInfo(){

+ 7 - 1
src/views/chartETA/components/TreeSelectPop.vue

@@ -48,7 +48,9 @@ watch(()=>props.isShowDialog,()=>{
     showPop.value = props.isShowDialog
 })
 watch(()=>props.chartInfo,()=>{
-    activeId.value = props.chartInfo.ChartClassifyId
+    if(props.popTitle==='移动至'){
+        activeId.value = props.chartInfo.ChartClassifyId
+    }
 },{immediate:true,deep:true})
 const emits = defineEmits(['close','confirmMove'])
 watch(showPop,()=>{
@@ -59,6 +61,10 @@ watch(showPop,()=>{
 
 
 function handleConfirmMove(){
+    if(!activeId.value){
+        showToast('请选择分类!')
+        return
+    }
     emits('confirmMove',activeId.value)
 }
 </script>