jwyu 1 年之前
父節點
當前提交
b0e0d9985f

+ 16 - 0
src/api/myETA.js

@@ -39,6 +39,22 @@ export function apiDeleteClassify(params){
     return post('/my_chart/classify/delete',params)
 }
 
+/**
+ * 将分类设置共享
+ * @param IsPublic 1共享 0不共享
+ * @param MyChartClassifyId
+ */
+export function apiShareClassify(params){
+    return post('/my_chart/classify/modify_public',params)
+}
+
+/**
+ * 复制公共图库分类
+ * @param MyChartClassifyId 
+ */
+export function apiClassifyCopy(params){
+    return post('/my_chart/classify/copy',params)
+}
 
 /**
  * 获取图库分类下的图列表

二進制
src/assets/imgs/icon_file.png


二進制
src/assets/imgs/icon_select.png


二進制
src/assets/imgs/icon_user.png


二進制
src/assets/imgs/myETA/icon_myETA_logo.png


+ 1 - 1
src/assets/styles/common.scss

@@ -4,7 +4,7 @@
 }
 
 html,body{
-    font-size: 28px;
+    font-size: 30px;
     color: #333;
 }
 

+ 31 - 0
src/hooks/chart/config.js

@@ -168,3 +168,34 @@ export const relevanceUnitEnMap={
     '天': 'Day',
 }
 
+//图表年份筛选项
+export const yearSelectOpt = [
+	{
+		name: '15年至今',
+		value: 3,
+	},
+	// {
+	// 	name: '18年至今',
+	// 	value: 7,
+	// },
+	// {
+	// 	name: '19年至今',
+	// 	value: 8,
+	// },
+	{
+		name: '20年至今',
+		value: 9,
+	},
+	{
+		name: '21年至今',
+		value: 4,
+	},
+	{
+		name: '22年至今',
+		value: 11
+	},
+]
+
+// 拥有相同配置的图表类型集合
+export const sameOptionType=[1,3,4,5,6]
+

+ 80 - 2
src/views/myETA/ChartDetail.vue

@@ -1,18 +1,25 @@
 <script setup>
-import {ref,nextTick} from 'vue'
+import {ref,nextTick, reactive} from 'vue'
 import {apiChartInfoByCode} from '@/api/chart'
 import { useRoute } from 'vue-router'
 import {chartRender} from '@/hooks/chart/render'
+import {yearSelectOpt,sameOptionType} from '@/hooks/chart/config'
 
 const route=useRoute()
 const chartCode=route.query.code
 
 // 获取图详情
 let chartInfo=ref(null)
+let edbList=ref([])//指标数据
 async function getChartInfo(){
     const res=await apiChartInfoByCode({UniqueCode:chartCode})
     if(res.Ret!==200) return
     chartInfo.value=res.Data.ChartInfo
+    if(res.Data.ChartInfo.Source===2){
+        edbList.value=[res.Data.EdbInfoList[0]]
+    }else{
+        edbList.value=res.Data.EdbInfoList
+    }
     nextTick(()=>{
         chartRender({
             data:res.Data,
@@ -25,18 +32,83 @@ async function getChartInfo(){
 }
 getChartInfo()
 
+
+let timeState=reactive({
+    showTimePop:false,
+    startTime:['2022', '06', '01'],
+    endTime:['2023', '06', '01'],
+    minDate: new Date(1970, 0, 1),
+    maxDate: new Date(2050, 11, 31),
+})
+
 </script>
 
 <template>
     <div class="chart-detail-page" v-if="chartInfo">
         <div class="chart-title">{{chartInfo.ChartName}}</div>
-        <div class="select-time-box">
+        <!-- 一般曲线图选择时间区间或者季节图选择日期 -->
+        <div 
+            class="select-time-box" 
+            v-if="sameOptionType.includes(chartInfo.ChartType)||chartInfo.ChartType===2" 
+            @click="timeState.showTimePop=true"
+        >
             <span>开始日期</span>
             <span>至</span>
             <span>结束日期</span>
         </div>
+
         <div class="chart-box" id="chart-box"></div>
+
+        <!-- 一般曲线图选择时间区间 -->
+        <div class="select-year-box" v-if="sameOptionType.includes(chartInfo.ChartType)">
+            <span 
+                :class="['item']"
+                v-for="item in yearSelectOpt" 
+                :key="item.value"
+            >{{item.name}}</span>
+            <span class="item">全部</span>
+        </div>
+        <!-- 季节图切换公/农历 -->
+        <div class="calendar-type-box" v-if="chartInfo.ChartType === 2">
+            <span>公历</span>
+            <span>农历</span>
+        </div>
+
+        <!-- 指标模块 -->
+        <div class="edb-list-box">
+            <div class="list-lable">指标信息</div>
+            <van-cell :title="item.EdbName" is-link v-for="item in edbList" :key="item.EdbInfoId"/>
+        </div>
     </div>
+
+    <!-- 选择日期弹窗 -->
+    <van-popup 
+        v-model:show="timeState.showTimePop"
+        position="bottom"
+    >
+        <div class="time-picker-wrap">
+            <van-picker-group
+                title="选择起始时间"
+                :tabs="['开始时间', '结束时间']"
+                @cancel="timeState.showTimePop=false"
+            >
+                <van-date-picker
+                    v-model="timeState.startTime"
+                    :min-date="timeState.minDate"
+                    :max-date="timeState.maxDate"
+                    :columns-type="chartInfo.ChartType==2?['year']:['year','month']"
+                />
+                <van-date-picker 
+                    v-model="timeState.endTime" 
+                    :min-date="timeState.minDate" 
+                    :max-date="timeState.maxDate"
+                    :columns-type="chartInfo.ChartType==2?['year']:['year','month']"
+                />
+            </van-picker-group>
+        </div>
+    </van-popup>
+
+    <!--  -->
 </template>
 
 <style lang="scss" scoped>
@@ -46,5 +118,11 @@ getChartInfo()
         width: 100%;
         height: 700px;
     }
+    .select-year-box{
+        .item{
+            display: inline-block;
+            margin-right: 20px;
+        }
+    }
 }
 </style>

+ 42 - 9
src/views/myETA/ChartList.vue

@@ -2,7 +2,7 @@
 import {ref,reactive} from 'vue'
 import {apiMyChartList,apiMyChartRemove} from '@/api/myETA'
 import { useRoute, useRouter } from "vue-router";
-import { showConfirmDialog } from 'vant';
+import { showConfirmDialog, showToast } from 'vant';
 
 
 const router=useRouter()
@@ -43,12 +43,22 @@ function onLoad(){
 }
 
 // 移除图表
-function handleRemove(item){
+function handleRemove(item,index){
     showConfirmDialog({
         title: '提示',
         message:'是否确认移出?',
     }).then(()=>{
-
+        apiMyChartRemove({
+            MyChartClassifyId:Number(cid.value),
+            MyChartId:item.MyChartId
+        }).then(res=>{
+            if(res.Ret===200){
+                setTimeout(() => {
+                    showToast('移出成功')
+                }, 100);
+                listState.list.splice(index,1)
+            }
+        })
     }).catch(()=>{})
 }
 
@@ -76,20 +86,21 @@ function goChartDetail(item){
         <van-list
             v-model:loading="listState.loading"
             :finished="listState.finished"
-            finished-text="没有更多了"
+            :finished-text="listState.list.length>0?'没有更多了':'暂无图表'"
             @load="onLoad"
         >
-            <template v-for="item in listState.list" :key="item.ChartInfoId">
+            <img v-if="listState.list.length==0&&listState.finished" class="empty-img" src="https://hzstatic.hzinsights.com/static/ETA_mobile/empty_img.png" alt="">
+            <template v-for="item,index in listState.list" :key="item.ChartInfoId">
                 <van-swipe-cell :disabled="isCommon">
                     <div class="list-item" @click="goChartDetail(item)">
                         <img class="img" :src="item.ChartImage" alt="">
                         <div class="con-box">
-                            <div class="name">{{item.ChartName}}</div>
+                            <div class="van-multi-ellipsis--l2 name">{{item.ChartName}}</div>
                             <div class="time">创建时间:{{item.CreateTime.slice(0,10)}}</div>
                         </div>
                     </div>
                     <template #right>
-                        <van-button square text="移除" type="danger" @click="handleRemove(item)"/>
+                        <div class="del-btn" @click="handleRemove(item,index)">移除</div>
                     </template>
                 </van-swipe-cell>
             </template>
@@ -104,15 +115,37 @@ function goChartDetail(item){
     background-color: #fff;
     z-index: 99;
 }
+.empty-img{
+    width: 400px;
+    display: block;
+    margin: 0 auto;
+}
 .list-item{
     display: flex;
+    padding: 20px $page-padding;
     .img{
-        width: 100px;
-        height: 100px;
+        width: 137px;
+        height: 137px;
         object-fit: contain;
+        margin-right: 20px;
     }
     .con-box{
         flex: 1;
+        display: flex;
+        flex-direction: column;
+        justify-content: space-between;
+        .time{
+            color: $font-grey_999;
+        }
     }
 }
+.del-btn{
+        width: 137px;
+        height: 100%;
+        background-color: $theme-red;
+        color: #fff;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+}
 </style>

+ 148 - 12
src/views/myETA/components/MobileClassifyWrap.vue

@@ -11,7 +11,12 @@ const {
     getPubClassify,
     classifyTypeChange,
     handleAddClassify,
-    handleConfirmEditClassify
+    handleConfirmEditClassify,
+
+    handleShowOpt,
+    handleClassifyShare,
+    handleCopyClassify,
+    handleClassifyDel
 }=useClassify()
 
 getMyClassify()
@@ -44,6 +49,7 @@ function goChooseChart(){
 
 <template>
     <div class="myETA-mobile-classify-wrap">
+        <div class="sticky-top">
         <div class="search-box">
             <van-search 
                 shape="round" 
@@ -54,12 +60,13 @@ function goChooseChart(){
         </div>
         <div class="classify-type-box">
             <span
-                class="item"
+                :class="['item',item.type===classifyState.classifyTypeAct?'active':'']"
                 v-for="item in classifyTypeOpt" 
                 :key="item.id"
                 @click="classifyTypeChange(item)"
             >{{item.name}}</span>
         </div>
+        </div>
         <ul class="list-box">
             <li 
                 class="item"
@@ -67,47 +74,131 @@ function goChooseChart(){
                 :key="item.MyChartClassifyId"
                 @click="goChartList(item)"
             >
-                <span class="van-ellipsis name">{{item.MyChartClassifyName}}</span>
+                <img class="left-icon" src="@/assets/imgs/ppt/ppt_icon_file.png" alt="">
+                <div style="flex:1">
+                    <div class="van-ellipsis name">{{item.MyChartClassifyName}}</div>
+                    <div class="share-user" v-if="classifyState.classifyTypeAct==2">分享人: {{item.RealName}}</div>
+                </div>
+                <img class="right-icon" src="@/assets/imgs/ppt/ppt_icon_menu.png" alt="" @click.stop="handleShowOpt(item)">
             </li>
         </ul>
         <!-- 底部操作栏 -->
         <div class="fix-bot-box">
-            <span @click="handleAddClassify">添加我的分类</span>
-            <span @click="goChooseChart">选择图表</span>
+            <div class="item" @click="handleAddClassify">
+                <img class="icon" src="@/assets/imgs/icon_file.png" alt="">
+                <span>添加分类</span>
+            </div>
+            <div class="item" @click="goChooseChart">
+                <img class="icon" src="@/assets/imgs/icon_select.png" alt="">
+                <span>选择图表</span>
+            </div>
         </div>
     </div>
     <!-- 添加我的分类弹窗 -->
     <van-dialog 
         v-model:show="classifyState.showEidtClassifyName" 
-        :title="classifyState.isAddClassifyName?'添加我的分类':'重命名'" 
+        :title="classifyState.isAddClassifyName?'添加分类':'重命名'" 
         show-cancel-button
         confirmButtonText="确定"
         @confirm="handleConfirmEditClassify"
     >
         <div class="rename-wrap">
-            <span>分类名称</span>
             <input type="text" placeholder="请输入分类名称!" v-model="classifyState.classifyNameVal">
         </div>
     </van-dialog>
+
+    <!-- 分类操作弹窗 -->
+    <van-popup 
+        v-model:show="classifyState.showClassifyOpt" 
+        round
+        position="bottom"
+    >
+        <div class="classify-opt-wrap">
+            <div class="item border">
+                <img src="@/assets/imgs/ppt/ppt_icon_file.png" alt="">
+                <span>{{classifyState.activeClassifyVal.MyChartClassifyName}}</span>
+            </div>
+            <!-- 我的图库分类操作 -->
+            <template v-if="classifyState.classifyTypeAct==1">
+            <div class="item border blue" @click="handleAddClassify(classifyState.activeClassifyVal)">
+                <img src="@/assets/imgs/ppt/ppt_icon_write.png" alt="">
+                <span>重命名</span>
+            </div>
+            <div class="item border blue">
+                <img src="@/assets/imgs/icon_user.png" alt="">
+                <span>所有人可见</span>
+                <van-switch
+                    class="switch-box"
+                    size="22px" 
+                    :model-value="classifyState.activeClassifyVal.IsPublic?true:false"
+                    @update:model-value="handleClassifyShare"
+                />
+            </div>
+            <div class="item border red" @click="handleClassifyDel(classifyState.activeClassifyVal)">
+                <img src="@/assets/imgs/icon_del.png" alt="">
+                <span>删除</span>
+            </div>
+            </template>
+            <!-- 公共图库分类操作 -->
+            <template v-if="classifyState.classifyTypeAct==2">
+            <div class="item border blue" @click="handleCopyClassify(classifyState.activeClassifyVal)">
+                <img src="@/assets/imgs/ppt/ppt_icon_copy.png" alt="">
+                <span>复制</span>
+            </div>
+            </template>
+        </div>
+
+    </van-popup>
 </template>
 
 <style lang="scss" scoped>
+.sticky-top{
+    position: sticky;
+    top: 0;
+    z-index: 99;
+    background-color: #fff;
+}
 .classify-type-box{
     padding: $page-padding;
     .item{
         display: inline-block;
-        margin-right: 20px;
+        width: 172px;
+        height: 64px;
+        line-height: 64px;
+        text-align: center;
+        border: 1px solid $theme-color;
+        color: $theme-color;
+    }
+    .active{
+        background-color: $theme-color;
+        color: #fff;
     }
 }
 .list-box{
     padding: $page-padding;
+    padding-bottom: 110px;
     .item{
-        border-bottom: 1px solid $border-color;
         padding: 20px 0;
         display: flex;
+        .left-icon{
+            width: 32px;
+            height: 32px;
+            margin-right: 20px;
+            flex-shrink: 0;
+        }
+        .right-icon{
+            flex-shrink: 0;
+            width: 4px;
+            height: 20px;
+            margin-left: 20px;
+        }
         .name{
             flex: 1;
         }
+        .share-user{
+            color: $font-grey_999;
+            margin-top: 15px;
+        }
     }
 }
 .fix-bot-box{
@@ -115,11 +206,28 @@ function goChooseChart(){
     left: 0;
     right: 0;
     bottom: 0;
-    height: 80px;
+    height: 100px;
     background-color: #fff;
-    border-top: 1px solid $border-color;
     display: flex;
-
+    justify-content: space-around;
+    align-items: center;
+    z-index: 99;
+    .item{
+        width: 300px;
+        height: 76px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        color: $theme-color;
+        font-size: 32px;
+        border: 1px solid $theme-color;
+        border-radius: 80px;
+        .icon{
+            width: 32px;
+            height: 32px;
+            margin-right: 20px;
+        }
+    }
 }
 .rename-wrap{
     display: flex;
@@ -138,4 +246,32 @@ function goChooseChart(){
         width: 150px;
     }
 }
+.classify-opt-wrap{
+    .item{
+        padding: 42px;
+        display: flex;
+        align-items: center;
+        position: relative;
+        img{
+            width: 36px;
+            height: 36px;
+            margin-right: 20px;
+        }
+        .switch-box{
+            position: absolute;
+            right: 42px;
+            top: 50%;
+            transform: translateY(-50%);
+        }
+    }
+    .border{
+        border-bottom: 1px solid $border-color;
+    }
+    .blue{
+        color: $theme-color;
+    }
+    .red{
+        color: $theme-red;
+    }
+}
 </style>

+ 68 - 8
src/views/myETA/hooks/useClassify.js

@@ -3,7 +3,9 @@ import {
     apiPublicClassifyList,
     apiAddClassify,
     apiEidtClassify,
-    apiDeleteClassify
+    apiDeleteClassify,
+    apiShareClassify,
+    apiClassifyCopy
 } from '@/api/myETA.js'
 import {reactive} from 'vue'
 import { showToast,showDialog,Dialog } from 'vant';
@@ -29,8 +31,9 @@ export function useClassify(){
 
         showEidtClassifyName:false,//显示新增/编辑分类弹窗
         isAddClassifyName:false,//是否为新增分类 false为编辑分类
-        classifyNameVal:'',
-        editClassifyId:0,//编辑分类的id
+        classifyNameVal:'',//当前分类名称
+        showClassifyOpt:false,//显示分类操作弹窗
+        activeClassifyVal:null,//当前选中的分类数据
     })
 
     // 获取我的图库分类
@@ -55,9 +58,9 @@ export function useClassify(){
     }
 
     // 显示新增分类弹窗
-    const handleAddClassify=()=>{
-        classifyState.isAddClassifyName=true
-        classifyState.classifyNameVal=''
+    const handleAddClassify=(item)=>{
+        classifyState.isAddClassifyName=item?false:true
+        classifyState.classifyNameVal=item.MyChartClassifyName||''
         classifyState.showEidtClassifyName=true
     }
     // 确认编辑分类
@@ -72,12 +75,65 @@ export function useClassify(){
         }else{
             const res=await apiEidtClassify({
                 MyChartClassifyName:classifyState.classifyNameVal,
-                MyChartClassifyId:classifyState.editClassifyId
+                MyChartClassifyId:classifyState.activeClassifyVal.MyChartClassifyId
             })
         }
         getMyClassify()
     }
 
+    // 显示分类操作弹窗
+    const handleShowOpt=(item)=>{
+        classifyState.activeClassifyVal=item
+        classifyState.showClassifyOpt=true
+    }
+
+    // 设置分类是否为公共
+    const handleClassifyShare=async ()=>{
+        const params={
+            IsPublic:classifyState.activeClassifyVal.IsPublic?0:1,
+            MyChartClassifyId:classifyState.activeClassifyVal.MyChartClassifyId
+        }
+        const res=await apiShareClassify(params)
+        if(res.Ret===200){
+            classifyState.activeClassifyVal.IsPublic=params.IsPublic
+            getMyClassify()
+        }
+    }
+
+    // 复制公共图表分类到我的分类中
+    const handleCopyClassify=async (item)=>{
+        const res=await apiClassifyCopy({
+            MyChartClassifyId:item.MyChartClassifyId
+        })
+        if(res.Ret===200){
+            setTimeout(() => {
+                showToast('复制成功')
+            }, 100);
+
+            getMyClassify()
+        }
+    }
+
+    // 删除分类
+    const handleClassifyDel=(item)=>{
+        showDialog({
+            title: '提示',
+            message: '若删除分类,则分类下关联的所有图表将被全部删除,是否确认删除?',
+            showCancelButton:true
+        }).then(() => {
+            // on close
+            apiDeleteClassify({MyChartClassifyId:item.MyChartClassifyId}).then(res=>{
+                if(res.Ret===200){
+                    getMyClassify()
+                    classifyState.showClassifyOpt=false
+                    setTimeout(() => {
+                        showToast('删除成功')
+                    }, 100);
+                }
+            })
+        }).catch(()=>{})
+    }
+
     return {
         classifyTypeOpt,
         classifyState,
@@ -85,6 +141,10 @@ export function useClassify(){
         getPubClassify,
         classifyTypeChange,
         handleAddClassify,
-        handleConfirmEditClassify
+        handleConfirmEditClassify,
+        handleShowOpt,
+        handleClassifyShare,
+        handleCopyClassify,
+        handleClassifyDel
     }
 }

+ 1 - 1
src/views/tabbar/Home.vue

@@ -25,7 +25,7 @@ if(!localStorage.getItem('token')){
                 <div>英文PPT</div>
             </div>
             <div class="item-box" @click="goNext('/myETA/index')">
-                <img src="@/assets/imgs/ppt/ppt_icon_en.png" alt="">
+                <img src="@/assets/imgs/myETA/icon_myETA_logo.png" alt="">
                 <div>My ETA</div>
             </div>
         </div>