Explorar o código

Merge branch 'eta-auth'

cxmo hai 1 ano
pai
achega
8e2004cd82

+ 29 - 1
src/api/chart.js

@@ -237,5 +237,33 @@ export default{
      */
     chartLocate(params){
         return get('/my_chart/chart/locate',params)
-    }
+    },
+    /*
+     * 保存图表
+     * @param 
+     *    ChartClassifyId: number,
+          ChartInfoId: number,
+          ChartEdbInfoList: [],
+          不同图表类型有不同参数
+     * @returns 
+     */
+    chartSave(params){
+        return post('/datamanage/chart_info/save',params)
+    },
+    /*
+     * 上传图表缩略图
+     * @param FormData
+     * @returns 
+     */
+    uploadChartImg(params){
+        return post('/datamanage/chart_info/base64Upload',params)
+    },
+    /*
+     * 设置图表缩略图
+     * @param ChartInfoId ImageUrl
+     * @returns 
+     */
+    setChartImg(params){
+        return post('/datamanage/chart_info/image/set',params)
+    },
 } 

+ 7 - 0
src/api/common.js

@@ -50,4 +50,11 @@ export function apiCommonSetSysConfig(params){
  */
 export function apiGetLanguageConfig(params){
     return get('/system/config/language',params)
+}
+
+/**
+ * 获取系统按钮权限
+ */
+export function apiGetAuthBtnList(){
+    return get('/system/role/menu/buttons',{})
 }

+ 7 - 0
src/api/myETA.js

@@ -235,5 +235,12 @@ export default{
      */
     myETAClassifySort(params){
         return post('/my_chart/classify/move',params)
+    },
+    /**
+     * myETA中保存商品价格曲线图
+     * @param {*} params ChartInfoId LeftMin LeftMax
+     */
+    myETASaveChart(params){
+        return post('/future_good/chart_info/save',params)
     }
 }

+ 51 - 0
src/directives/AuthBtn.js

@@ -0,0 +1,51 @@
+//按钮权限指令
+//eg: v-permission="buttonCode"
+//元素必须在组件内存在父元素,否则el.parentNode.removeChild不起作用
+import {useAuthBtnStore} from '@/store/modules/authBtn'
+export default {
+    mounted(el, binding) {
+        let {
+            value
+        } = binding
+        // 拿出所有按钮的code
+        const authBtnStore = useAuthBtnStore()
+        let buttonCodes = authBtnStore.authBtnList.map(item => item.ButtonCode)
+        if (value && typeof (value) == 'string') {
+            // 字符类型
+            if (!buttonCodes.includes(value)) {
+                // 没有权限,删除dom
+                el.parentNode && el.parentNode.removeChild(el)
+            }
+        } else if (Array.isArray(value)) {
+            // 数组类型
+            /**
+             * 权限类型 type
+             * or-只要一个满足 and-全部都满足
+             */
+            let type;
+            let hasType = ['or', 'and'].includes(value[value.length - 1].toLocaleLowerCase())
+            if (hasType) {
+                //参数中有标明type
+                type = value[value.length - 1].toLocaleLowerCase()
+                // 去掉最后一个权限类型参数
+                value.pop()
+                // console.log(value,true);
+                let operation = type == 'or' ? 'some' : 'every'
+                if (!value[operation](item => buttonCodes.includes(item))) {
+                    // 没有权限,删除dom
+                    el.parentNode && el.parentNode.removeChild(el)
+                }
+            } else {
+                type = 'or'
+                // console.log(value,false);
+                if (!value.some(item => buttonCodes.includes(item))) {
+                    // 没有权限,删除dom
+                    el.parentNode && el.parentNode.removeChild(el)
+                }
+            }
+        } else {
+            throw new Error('permission指令参数类型错误')
+        }
+
+    },
+}

+ 2 - 1
src/directives/Index.js

@@ -1,8 +1,9 @@
 // 注册自定义指令
 import ScreenshotDirective from './Screenshot'
 import LongPress from './LongPress';
-
+import Permission from './AuthBtn';
 export function RegisterDirective(app){
     app.directive('screenshot', ScreenshotDirective);
     app.directive('longpress', LongPress);
+    app.directive('permission',Permission)
 }

+ 145 - 0
src/hooks/useAuthBtn.js

@@ -0,0 +1,145 @@
+//权限按钮相关
+import {useAuthBtnStore} from '@/store/modules/authBtn'
+const authBtnStore = useAuthBtnStore()
+/*
+---------------------------研报管理----------------- 
+*/
+export const reportManageBtn = {
+    reportManage_sendMsg:'reportManage:sendMsg',//推送消息/已推送消息
+    reportManage_reportView:'reportManage:reportView',//研报预览:即是否能点击研报名称跳转预览页面
+    reportManage_reportDel:'reportManage:reportDel',//删除研报
+    reportManage_reportEdit:'reportManage:reportEdit',//编辑研报
+    reportManage_cancelPublish:'reportManage:cancelPublish',//取消发布
+    reportManage_publish:'reportManage:publish',//发布研报
+    reportManage_reportList:'reportManage:reportList',//研报列表的选项
+    reportManage_reportList_uv:'reportManage:reportList:uv',//研报列表-PV/UV
+    reportManage_reportList_sendTime:'reportManage:reportList:sendTime',//研报列表-报告推送时间
+    reportManage_dayWeekReportAdd:'reportManage:dayWeekReportAdd',//添加晨报周报
+    reportManage_reportAdd:'reportManage:reportAdd',//添加研报
+}
+export const enReportManageBtn = {
+    enReport_reportView:'enReport:reportView',//研报预览:即是否能点击研报名称跳转预览页面
+    enReport_sendEmail:'enReport:sendEmail',//群发邮件/群发日志
+    enReport_reportDel:'enReport:reportDel',//删除研报
+    enReport_reportEdit:'enReport:reportEdit',//编辑研报
+    enReport_cancelPublish:'enReport:cancelPublish',//取消发布
+    enReport_publish:'enReport:publish',//发布研报
+    enReport_reportAdd:'enReport:reportAdd',//添加研报
+}
+
+/*
+--------------------------智能PPT-----------------
+PS:由于移动端中英文PPT是一个页面,特地把按钮名称设置为一致的方便处理
+与ETA后台不同,修改时请注意
+*/
+export const pptBtn={
+    ppt_del:'ppt:del',
+    ppt_copy:'ppt:copy',
+    ppt_download:'ppt:download',
+    ppt_show:'ppt:show',//演示
+    ppt_publish:'ppt:publish',
+    ppt_visible:'ppt:visible',//可见权限
+    ppt_save:'ppt:save',//添加PPT按钮,同时也控制目录重命名权限
+}
+export const enPPTBtn={
+    ppt_del:'pptEn:del',
+    ppt_copy:'pptEn:copy',
+    ppt_download:'pptEn:download',
+    ppt_show:'pptEn:show',
+    ppt_publish:'pptEn:publish',
+    ppt_visible:'pptEn:visible',
+    ppt_save:'pptEn:save',//添加PPT按钮,同时也控制目录重命名权限
+}
+
+/*
+--------------------------ETA指标库---------------
+*/
+export const edbDataBtn={
+        /*-----------指标详情按钮--------- */
+        edbData_refreshAll:'edbData:refreshAll',//全部刷新
+        edbData_newestValue:'edbData:newestValue',//添加最新值
+        edbData_enNameSetting:'edbData:enNameSetting',//设置英文名称
+        edbData_edbSource:'edbData:edbSource',//指标溯源
+        edbData_copyData:'edbData:copyData',//复制数据
+        edbData_edit:'edbData:edit',//指标编辑,也包括列表项的编辑按钮
+        edbData_update:'edbData:update',//更新指标
+        edbData_saveEdb:'edbData:saveEdb',//保存
+        edbData_deleteEdb:'edbData:deleteEdb',//删除
+        edbData_showChartBasis:'edbData:showChartBasis',//展示/隐藏同比图
+        edbData_switchSeason:'edbData:switchSeason',//切换季节性图
+        edbData_editLimit:'edbData:editLimit',//编辑上下限
+        edbData_calculateAgain:'edbData:calculateAgain',//重新计算
+        /*------------页面按钮---------- */
+        edbData_replaceEdb:'edbData:replaceEdb',//替换指标
+        edbData_calcuEdb:'edbData:calcuEdb',//计算指标
+        edbData_addEdb:'edbData:addEdb',//添加指标
+        edbData_switchEn:'edbData:switchEn',//切换英文版
+        edbData_classifyOpt_add:'edbData:classifyOpt:add',//添加/编辑分类
+        edbData_classifyOpt_delete:'edbData:classifyOpt:delete',//删除分类
+        edbData_classifyOpt_move:'edbData:classifyOpt:move',//移动分类
+        edbData_checkRelatedChart:'edbData:checkRelatedChart',//查看关联图表
+        edbData_checkRelatedEdb:'edbData:checkRelatedEdb',//查看关联指标
+        edbData_checkCalcChart:'edbData:checkCalcChart',//查看计算指标
+}
+
+/*
+-------------------------ETA图库------------------
+*/
+export const chartLibBtn={
+    /*-----------图表详情按钮--------- */
+    chartLib_del:'chartLib:del',//删除
+    chartLib_enNameSetting:'chartLib:enNameSetting',//设置英文名称
+    chartLib_copyWechat:'chartLib:copyWechat',//保存图片(两个按钮控制)
+    chartLib_copyOffice:'chartLib:copyOffice',//保存图片(两个按钮控制)
+    chartLib_otherSave:'chartLib:otherSave',//另存为
+    chartLib_save:'chartLib:save',//保存
+    chartLib_refresh:'chartLib:refresh',//刷新
+    chartLib_addMy:'chartLib:addMy',//加入我的图库
+    chartLib_share:'chartLib:share',//分享
+    chartLib_editLimit:'chartLib:editLimit',//编辑上下限
+    /*------------页面按钮---------- */
+    chartLib_switchEn:'chartLib:switchEn',//切换中英文
+    chartLib_isOnlyMine:'chartLib:isOnlyMine',//只看我的
+    chartLib_classifyOpt_add:'chartLib:classifyOpt:add',//新增/编辑分类
+	chartLib_classifyOpt_delete:'chartLib:classifyOpt:delete',//删除分类
+}
+
+/*
+------------------------MyETA--------------------
+*/
+export const myETABtn={
+    /*-----------图表详情弹窗按钮--------- */
+    myChart_del:'myChart:del',
+    myChart_enNameSetting:'myChart:enNameSetting',
+    myChart_copyWechat:'myChart:copyWechat',
+    myChart_copyOffice:'myChart:copyOffice',
+    myChart_otherSave:'myChart:otherSave',
+    myChart_save:'myChart:save',
+    myChart_refresh:'myChart:refresh',
+    myChart_copyTo:'myChart:copyTo',
+    myChart_share:'myChart:share',
+    myChart_move:'myChart:move',//移出,同时也控制列表项的移出
+    myChart_copyData:'myChart:copyData',//复制数据
+    myChart_checkData:'myChart:checkData',//查看数据
+    myChart_editLimit:'myChart:editLimit',//编辑上下限
+    /*-----------页面按钮--------- */
+    myChart_selectChart:'myChart:selectChart',//选择图表
+    myChart_classifyOpt_copy:'myChart:classifyOpt:copy',//复制
+    myChart_classifyOpt_show:'myChart:classifyOpt:show',//可见权限
+    myChart_classifyOpt_edit:'myChart:classifyOpt:edit',//添加我的分类
+    myChart_classifyOpt_rename:'myChart:classifyOpt:rename',//重命名
+    myChart_classifyOpt_delete:'myChart:classifyOpt:delete',//删除
+}
+
+
+export function useAuthBtn(){
+    const isShowBtn = ()=>{}
+    const checkAuthBtn = (buttonCode)=>{
+        const list = authBtnStore.authBtnList||[]
+        return list.map(item=>item.ButtonCode).includes(buttonCode)
+    }
+    return {
+        isShowBtn,
+        checkAuthBtn
+    }
+}

+ 5 - 2
src/router/index.js

@@ -10,6 +10,7 @@
  */
 import { createRouter, createWebHistory } from "vue-router";
 import {useCachedViewsStore} from '@/store/modules/cachedViews'
+import {useAuthBtnStore} from '@/store/modules/authBtn'
 
 import { pptRoutes } from "./ppt";
 import {pptENRoutes} from './pptEn'
@@ -18,6 +19,7 @@ import {reportRoutes} from './report'
 import {reportEnRoutes} from './reportEn'
 import {chartETARoutes} from './chartETA'
 import {dataEDBRoutes} from './dataEDB'
+import { storeToRefs } from "pinia";
 
 const routes = [
   	{
@@ -113,9 +115,10 @@ function setKeeplive(to){
 	}
 }
 
-router.beforeEach((to, from, next) => {
+router.beforeEach(async(to, from, next) => {
 	setKeeplive(to)
-
+    const authBtnStore = useAuthBtnStore()
+    to.path!='/login'&&await authBtnStore.getAuthList()
 	document.title = to.meta.title;
   	next();
 });

+ 27 - 0
src/store/modules/authBtn.js

@@ -0,0 +1,27 @@
+/**
+ * 权限按钮
+ */
+import {apiGetAuthBtnList} from '@/api/common';
+import { defineStore } from "pinia";
+export const useAuthBtnStore = defineStore('authBtn',{
+    state:()=>{
+        return {
+            authBtnList:[]
+        }
+    },
+    actions:{
+        getAuthList(){
+            return new Promise((resolve)=>{
+                apiGetAuthBtnList().then(res=>{
+                    this.authBtnList = res.Data||[]
+                })
+                /* 
+                //mock
+                this.authBtnList = [
+                    {ButtonCode:'reportManage:reportAdd'},
+                ] */
+                resolve('权限获取成功')
+            })
+        }
+    }
+})

+ 151 - 15
src/views/chartETA/ChartDetail.vue

@@ -14,7 +14,8 @@ import AddChartToMyETA from './components/AddChartToMyETA.vue'
 import SetChartEnName from './components/SetChartEnName.vue'
 import {useCachedViewsStore} from '@/store/modules/cachedViews'
 import { setExtremumDate } from '@/hooks/chart/commonFun.js'
-
+import {chartLibBtn,useAuthBtn} from '@/hooks/useAuthBtn'
+const {checkAuthBtn} = useAuthBtn()
 import _ from 'lodash';
 
 
@@ -260,43 +261,68 @@ function handleShowSourceDetail(){
 let showMoreAction = ref(false)
 let chartActions = ref([])
 function getChartActions(chartInfo){
-    return [
+    //加上权限判断
+    const actionsArr = [
         {
             type:'refresh',
             label:'刷新',
-            show:true
+            show:true,
+            btnCode:chartLibBtn.chartLib_refresh
         },
         {
             type:'share',
             label:'分享',
-            show:!Boolean(chartInfo.Disabled)
+            show:!Boolean(chartInfo.Disabled),
+            btnCode:chartLibBtn.chartLib_share
+        },
+        {
+            type:'save',
+            label:'保存',
+            show:true,
+            btnCode:chartLibBtn.chartLib_save
         },
         {
             type:'saveOther',
             label:'另存为',
-            show:true
+            show:true,
+            btnCode:chartLibBtn.chartLib_otherSave
         },
         {
             type:'savePic',
             label:'保存图片',
-            show:true
+            show:true,
         },
         {
             type:'setEnName',
             label:'设置英文名称',
-            show:true
+            show:true,
+            btnCode:chartLibBtn.chartLib_enNameSetting
         },
         {
             type:'addToMyETA',
             label:'加入我的图库',
-            show:true
+            show:true,
+            btnCode:chartLibBtn.chartLib_addMy
         },
         {
             type:'delete',
             label:'删除',
-            show:chartInfo.IsEdit
+            show:chartInfo.IsEdit,
+            btnCode:chartLibBtn.chartLib_del
         }
     ]
+    let currentArr=[]
+    actionsArr.forEach(item=>{
+        if(item.btnCode&&checkAuthBtn(item.btnCode)){
+            currentArr.push(item)
+        }
+        if(item.type==='savePic'){
+            if(checkAuthBtn(chartLibBtn.chartLib_copyWechat)&&checkAuthBtn(chartLibBtn.chartLib_copyOffice)){
+                currentArr.push(item)
+            }
+        }
+    })
+    return currentArr
 }
 
 function handleActionClick(action){
@@ -307,7 +333,8 @@ function handleActionClick(action){
         'savePic':saveChartPic,
         'setEnName':openSetChartEnNameDialog,
         'addToMyETA':openAddToMyETADialog,
-        'delete':deleteChart
+        'delete':deleteChart,
+        'save':saveChart,
     }
     eventMap[action.type]()
     //showMoreAction.value = false
@@ -372,7 +399,116 @@ function checkChartEnOption(){
     }
     return true
 }
-
+//保存图表
+function saveChart(){
+    //获取每条线的指标配置
+    let arr = edbList.value.map((item)=>{
+        return {
+            ChartColor: item.ChartColor,
+            PredictChartColor: item.PredictChartColor,
+            ChartStyle: item.ChartStyle,
+            ChartWidth: Number(item.ChartWidth),
+            EdbInfoId: item.EdbInfoId,
+            EdbInfoType: item.EdbInfoType,
+            IsAxis: item.IsAxis,
+            IsOrder: item.IsOrder,
+            LeadUnit: item.EdbInfoType ? '' : item.LeadUnit,
+            LeadValue: item.EdbInfoType ? 0 : Number(item.LeadValue),
+            MaxData: Number(item.MaxData),
+            MinData: Number(item.MinData),
+        }
+    })
+    //所有图表的公共参数
+    let public_param = {
+        ChartClassifyId: chartInfo.value.ChartClassifyId,
+        ChartInfoId: chartInfo.value.ChartInfoId,
+        ChartEdbInfoList: arr,
+    }
+    //根据ChartType决定剩余参数
+    let type_param = {}
+    switch(chartInfo.value.ChartType){
+        case 2:
+            type_param = {
+              DateType: chartState.yearVal,
+              StartYear:chartState.startYear || 0,
+              Calendar: chartState.calendarType,
+              StartDate: chartState.startTime||'',
+              EndDate: chartState.endTime||'',
+            }
+            break
+        case 7:
+            type_param = {
+              DateType: 6,
+              LeftMin: String(axisLimitState.leftMin),
+              LeftMax: String(axisLimitState.leftMax),
+            }
+            break
+        case 10:
+            type_param = {
+              DateType: 6,
+              Calendar: "公历",
+              ExtraConfig: JSON.stringify({
+                ...JSON.parse(chartInfo.value.ExtraConfig),
+                XMinValue: String(axisLimitState.xMin),
+                XMaxValue: String(axisLimitState.xMax),
+                YMinValue: String(axisLimitState.leftMin),
+                YMaxValue: String(axisLimitState.leftMax),
+              })
+            }
+            break
+    }
+    if(sameOptionType.includes(chartInfo.value.ChartType)){
+        type_param = {
+            DateType: chartState.yearVal,
+            StartYear:chartState.startYear || 0,
+            StartDate:chartState.yearVal === 5 || chartState.yearVal === 6
+                ? chartState.startTime
+                : '',
+            EndDate: chartState.yearVal === 5 ? chartState.endTime : '',
+        }
+    }
+    let params = {...public_param,...type_param}
+    //保存
+    apiChart.chartSave(params).then(async res=>{
+        if(res.Ret!==200) return
+        showToast("保存成功")
+        //更新缩略图
+        setChartImage()
+        //保存成功后修改route.query防止刷新后请求旧参数
+        router.replace({
+            path:'/chartETA/chartdetail',
+            query:{
+                id:route.query.id,
+                chartType:route.query.chartType,
+                chartClassifyId:route.query.chartClassifyId,
+                DateType:params.DateType,
+                StartDate:chartState.startTime,
+                EndDate:chartState.endTime,
+                Calendar:chartState.calendarType,
+                SeasonStartDate:chartState.startTime,
+                SeasonEndDate:chartState.endTime,
+                StartYear:chartState.startYear
+            }
+        })
+    })
+    
+}
+async function setChartImage(){
+    const svgData = highChart.value.getSVG({
+        chart: {
+            width: 340,
+            height: 230,
+        }
+    })
+    let form = new FormData();
+    form.append('Img', svgData);
+    let {Data,Ret} = await apiChart.uploadChartImg(form)
+    if(Ret!==200||!Data) return
+    await apiChart.setChartImg({
+        ChartInfoId:Number(route.query.id),
+        ImageUrl:Data.ResourceUrl
+    })
+}
 let isShowSaveOtherDialog = ref(false)
 let catalogNodes = ref([])
 //另存为
@@ -571,7 +707,7 @@ function openDateSelect(){
                 </span>
             </div>
             <div class="right-action-box">
-                <div class="item" @click="showMoreAction=true" >
+                <div class="item" @click="showMoreAction=true" v-if="chartActions.length">
                     <img src="@/assets/imgs/chartETA/more-icon.png" alt="">
                     <span>更多设置</span>
                 </div>
@@ -611,7 +747,7 @@ function openDateSelect(){
         <!-- 指标模块 -->
         <div class="edb-list-box">
             <!-- pad 设置上下限按钮 -->
-            <div class="pad-limit-set-btn" @click="handleShowAxisLimitOpt" v-if="![3,4,6,7,8,9].includes(chartInfo.Source)">设置上下限</div>
+            <div class="pad-limit-set-btn" @click="handleShowAxisLimitOpt" v-if="![3,4,6,7,8,9].includes(chartInfo.Source)&&checkAuthBtn(chartLibBtn.chartLib_editLimit)">设置上下限</div>
             <!-- <div class="list-lable">指标信息</div> -->
             <div class="list-box">
                 <div class="list-item" v-for="item in edbList" :key="item.EdbInfoId" @click="handleShowEDBInfo(item)">
@@ -631,11 +767,11 @@ function openDateSelect(){
                 <img class="icon" style="transform: rotate(180deg);" src="@/assets/imgs/icon_arrow.png" alt="">
                 <div>下一张</div>
             </div>
-            <div class="item" @click="handleShowAxisLimitOpt" v-if="![3,4,6,7,8,9].includes(chartInfo.Source)">
+            <div class="item" @click="handleShowAxisLimitOpt" v-if="![3,4,6,7,8,9].includes(chartInfo.Source)&&checkAuthBtn(chartLibBtn.chartLib_editLimit)">
                 <img class="icon" src="@/assets/imgs/myETA/icon_limit.png" alt="">
                 <div>上下限</div>
             </div>
-            <div class="item" @click="showMoreAction=true">
+            <div class="item" @click="showMoreAction=true" v-if="chartActions.length">
                 <img class="icon" src="@/assets/imgs/myETA/icon_menu.png" alt="">
                 <div>更多</div>
             </div>

+ 6 - 5
src/views/chartETA/List.vue

@@ -9,8 +9,9 @@ import CatalogItem from './components/CatalogItem.vue';
 import OptionPopup from './components/OptionPopup.vue';
 import AddChartToMyETA from './components/AddChartToMyETA.vue';
 import TreeSelectPop from './components/TreeSelectPop.vue';
-import apiChart from '@/api/chart'
-
+import apiChart from '@/api/chart';
+import {chartLibBtn,useAuthBtn} from '@/hooks/useAuthBtn'
+const {checkAuthBtn} = useAuthBtn()
 import {useCatalogList} from './hooks/useCatalogList';
 
 const { width } = useWindowSize()
@@ -407,7 +408,7 @@ getChartList()
                     style="flex:1;padding-left:0"
                     @click-input="$router.push('/chartETA/search')"
                 />
-                <div class="lang-icon icon" @click="changeLang">
+                <div class="lang-icon icon" @click="changeLang" v-permission="chartLibBtn.chartLib_switchEn">
                     <img v-if="currentLang==='CN'" src="@/assets/imgs/chartETA/lang-icon.png" alt="">
                     <img v-if="currentLang==='EN'" src="@/assets/imgs/chartETA/langEn-icon.png" alt="">
                 </div>
@@ -418,7 +419,7 @@ getChartList()
             <p style="font-weight: bold;word-break: break-all;margin-bottom: 5px;">{{ catalogMenu }}</p>
             <div class="select-box">
                 <span>共{{listState.total}}张图表</span>
-                <span> <van-checkbox v-model="listState.IsShowMe">只看我的</van-checkbox></span>
+                <span v-permission="chartLibBtn.chartLib_isOnlyMine"> <van-checkbox v-model="listState.IsShowMe">只看我的</van-checkbox></span>
             </div>
         </div>
         <div class="chart-list-wrap">
@@ -478,7 +479,7 @@ getChartList()
                         </van-collapse-item>
                     </van-collapse>
                 </div>
-                <div class="bottom sticky-part" v-if="['rai_admin', 'ficc_admin','admin'].includes(UserInfo.RoleTypeCode)">
+                <div class="bottom sticky-part" v-if="['rai_admin', 'ficc_admin','admin'].includes(UserInfo.RoleTypeCode)&&checkAuthBtn(chartLibBtn.chartLib_classifyOpt_add)">
                     <span @click.stop="openEditNameDialog({Level:0},{id:'addNew',label:'添加图表分类'})">添加图表分类</span>
                 </div>
             </div>

+ 1 - 0
src/views/chartETA/Search.vue

@@ -66,6 +66,7 @@ function goDetail(item){
             Calendar:item.Calendar?item.Calendar:'公历',
             SeasonStartDate:item.SeasonStartDate,
             SeasonEndDate:item.SeasonEndDate,
+            StartYear:item.StartYear
         }
     })
 }

+ 12 - 2
src/views/chartETA/hooks/useCatalogList.js

@@ -1,6 +1,9 @@
 import {getStaticImg,useUserInfo} from '@/hooks/common'
 import {ref} from 'vue'
 import apiChart from '@/api/chart'
+import {chartLibBtn,useAuthBtn} from '@/hooks/useAuthBtn'
+
+const {checkAuthBtn} = useAuthBtn()
 export function useCatalogList(){
     //操作栏图标的地址
     const iconSrc = {
@@ -112,13 +115,20 @@ export function useCatalogList(){
         const {authRole} = opt
         const {AdminId,RoleTypeCode} = UserInfo.value
         const roleType = ['rai_admin', 'ficc_admin','admin'].includes(RoleTypeCode)?'admin':RoleTypeCode
+        //在原先的基础上加上权限设置
+        const authMap = {
+            'addNext':chartLibBtn.chartLib_classifyOpt_add,
+            'reName':chartLibBtn.chartLib_classifyOpt_add,
+            'delete':chartLibBtn.chartLib_del,
+            'addChart':chartLibBtn.chartLib_addMy
+        }
         if(opt.id==='moveTo'||opt.id==='moveChart'){
             return node.SysUserId===AdminId||roleType==='admin'
         }
         if(authRole){
-            return authRole===roleType
+            return (authRole===roleType)&&checkAuthBtn(authMap[opt.id])
         }
-        return true
+        return checkAuthBtn(authMap[opt.id])
     }
 
 

+ 27 - 12
src/views/dataEDB/Detail.vue

@@ -14,6 +14,8 @@ import {useCopyEdbData} from '@/hooks/edb/useCopyEdbData'
 import {useEDBDelete} from './hooks/useEDBDelete'
 import {useCachedViewsStore} from '@/store/modules/cachedViews'
 import { useWindowSize } from '@vueuse/core'
+import {edbDataBtn,useAuthBtn} from '@/hooks/useAuthBtn'
+const {checkAuthBtn} = useAuthBtn()
 
 const { width } = useWindowSize()
 const cachedViewsStore=useCachedViewsStore()
@@ -178,6 +180,15 @@ async function handleCalculateReset(){
 function handleSave(){
     chartDetailIns?.value.handleSaveChartLimit()
 }
+function isMoreOptShow(){
+    return checkAuthBtn(edbDataBtn.edbData_enNameSetting)
+        || (edbInfo.value.Button.InsertNewDataButton&&checkAuthBtn(edbDataBtn.edbData_newestValue))
+        || (edbInfo.value.EdbType===1&&checkAuthBtn(edbDataBtn.edbData_refreshAll))
+        || (edbInfo.value.EdbType===2&&checkAuthBtn(edbDataBtn.edbData_edbSource))
+        || (edbInfo.value.EdbType===2&&checkAuthBtn(edbDataBtn.edbData_calculateAgain))
+        || (activeType.value==='chart'&&checkAuthBtn(edbDataBtn.edbData_saveEdb))
+        || checkAuthBtn(edbDataBtn.edbData_deleteEdb)
+}
 
 </script>
 
@@ -203,23 +214,23 @@ function handleSave(){
             </van-tab>
         </van-tabs>
         <div class="fix-bottom-box">
-            <div class="item" @click="handleRefreshEDBInfo">
+            <div class="item" @click="handleRefreshEDBInfo" v-permission="edbDataBtn.edbData_update">
                 <img class="icon" src="@/assets/imgs/report/icon_refresh.png" alt="">
                 <span>刷新</span>
             </div>
-            <div class="item" v-if="edbInfo.Button.OpButton" @click="handleEdit">
+            <div class="item" v-if="edbInfo.Button.OpButton&&checkAuthBtn(edbDataBtn.edbData_edit)" @click="handleEdit">
                 <img class="icon" src="@/assets/imgs/dataEDB/icon_edit.png" alt="">
                 <span>编辑</span>
             </div>
-            <div class="item" v-if="activeType==='chart'" @click="handleShowLimit">
+            <div class="item" v-if="activeType==='chart'&&checkAuthBtn(edbDataBtn.edbData_editLimit)" @click="handleShowLimit">
                 <img class="icon" src="@/assets/imgs/myETA/icon_limit.png" alt="">
                 <div>上下限</div>
             </div>
-            <div class="item" v-if="activeType==='data'" @click="handleCopyData">
+            <div class="item" v-if="activeType==='data'&&checkAuthBtn(edbDataBtn.edbData_copyData)" @click="handleCopyData">
                 <img class="icon" src="@/assets/imgs/myETA/icon_copy.png" alt="">
                 <div>复制</div>
             </div>
-            <div class="item" @click="showMoreOpt=true">
+            <div class="item" @click="showMoreOpt=true" v-if="isMoreOptShow()">
                 <img class="icon" src="@/assets/imgs/myETA/icon_menu.png" alt="">
                 <div>更多</div>
             </div>
@@ -244,16 +255,20 @@ function handleSave(){
             <ul class="edb-opt-list">
                 <li class="van-ellipsis item name">{{edbInfo.EdbName}}</li>
 
-                <li class="item" @click="showSetEn=true">设置英文名称</li>
                 <li class="item" 
-                    v-if="edbInfo.Button.InsertNewDataButton"
+                    v-if="checkAuthBtn(edbDataBtn.edbData_enNameSetting)"
+                    @click="showSetEn=true">设置英文名称</li>
+                <li class="item" 
+                    v-if="edbInfo.Button.InsertNewDataButton&&checkAuthBtn(edbDataBtn.edbData_newestValue)"
                     @click="showSetNewData=true"
                 >{{edbInfo.DataInsertConfig.Date?'编辑最新值':'添加最新值'}}</li>
-                <li class="item" v-if="edbInfo.EdbType===1" @click="handleRefreshBaseEDBData">全部刷新</li>
-                <li class="item" v-if="edbInfo.EdbType===2" @click="showEDBHistory=true">指标溯源</li>
-                <li class="item" v-if="edbInfo.EdbType===2" @click="handleCalculateReset">重新计算</li>  
-                <li class="item" v-if="activeType==='chart'" @click="handleSave">保存</li>
-                <li class="item color-red" @click="handleEDBDelete">删除</li>
+                <li class="item" v-if="edbInfo.EdbType===1&&checkAuthBtn(edbDataBtn.edbData_refreshAll)" @click="handleRefreshBaseEDBData">全部刷新</li>
+                <li class="item" v-if="edbInfo.EdbType===2&&checkAuthBtn(edbDataBtn.edbData_edbSource)" @click="showEDBHistory=true">指标溯源</li>
+                <li class="item" v-if="edbInfo.EdbType===2&&checkAuthBtn(edbDataBtn.edbData_calculateAgain)" @click="handleCalculateReset">重新计算</li>  
+                <li class="item" v-if="activeType==='chart'&&checkAuthBtn(edbDataBtn.edbData_saveEdb)" @click="handleSave">保存</li>
+                <li class="item color-red" 
+                    v-if="checkAuthBtn(edbDataBtn.edbData_deleteEdb)"
+                    @click="handleEDBDelete">删除</li>
             </ul>
         </template>
     </van-action-sheet>

+ 50 - 20
src/views/dataEDB/Index.vue

@@ -1,5 +1,5 @@
 <script setup name="DataEDBIndex">
-import {reactive,ref, watch} from 'vue'
+import {computed, reactive,ref, watch} from 'vue'
 import apiDataEDB from '@/api/dataEDB'
 import {apiCommonSetSysConfig,apiGetLanguageConfig} from '@/api/common'
 import EDBClassify from './components/EDBClassify.vue'
@@ -8,6 +8,8 @@ import {useRouter} from 'vue-router'
 import {useCachedViewsStore} from '@/store/modules/cachedViews'
 import langIconZH from '@/assets/imgs/chartETA/lang-icon.png'
 import langIconEN from '@/assets/imgs/chartETA/langEn-icon.png'
+import {edbDataBtn,useAuthBtn} from '@/hooks/useAuthBtn'
+const {checkAuthBtn} = useAuthBtn()
 
 const cachedViewsStore=useCachedViewsStore()
 const router=useRouter()
@@ -36,6 +38,29 @@ async function langTypeChange(){
     }
 }
 
+//根据权限决定actions
+const actions = computed(()=>{
+    let actionArr = []
+    if(checkAuthBtn(edbDataBtn.edbData_addEdb)){
+        actionArr.push({
+            name:'添加指标',
+            path:'/dataEDB/addbaseEDB'
+        })
+    }
+    if(checkAuthBtn(edbDataBtn.edbData_calcuEdb)){
+        actionArr.push({
+            name:'计算指标',
+            path:'/dataEDB/calculate/index'
+        })
+    }
+    if(checkAuthBtn(edbDataBtn.edbData_replaceEdb)){
+        actionArr.push({
+                name:'替换指标',
+                path:'/dataEDB/replaceEDB'
+            })
+    }
+    return actionArr
+})
 
 const listState = reactive({
     list:[],
@@ -129,6 +154,23 @@ watch(
         }
     }
 )
+//图表option check
+function checkOption(item){
+    let optionArr = []
+    if(seeComputeEDBInfo(item)&&checkAuthBtn(edbDataBtn.edbData_checkCalcChart)){
+        optionArr.push('查看')
+    }
+    if(item.Button.ShowEdbRelation&&checkAuthBtn(edbDataBtn.edbData_checkRelatedEdb)){
+        optionArr.push('关联指标')
+    }
+    if(item.Button.ShowChartRelation&&checkAuthBtn(edbDataBtn.edbData_checkRelatedChart)){
+        optionArr.push('关联图表')
+    }
+    if(item.Button.MoveButton){
+        optionArr.push('移动至')
+    }
+    return optionArr.length
+}
 function handleShowEdbOpt(item){
     edbOptState.data=item
 
@@ -251,7 +293,7 @@ async function goSearch(){
                     style="flex:1;padding-left:0"
                     @click-input="goSearch"
                 />
-                <div class="lang-icon icon">
+                <div class="lang-icon icon" v-permission="edbDataBtn.edbData_switchEn">
                     <img :src="langType==='zh'?langIconZH:langIconEN" alt="" @click="langTypeChange">
                 </div>
             </div>
@@ -288,6 +330,7 @@ async function goSearch(){
                                 height="28" 
                                 viewBox="0 0 28 28" 
                                 fill="none"
+                                v-if="checkOption(item)"
                                 @click.stop="handleShowEdbOpt(item)"
                             >
                                 <rect width="28" height="28" rx="4" :fill="item.EdbInfoId===edbOptState.data?.EdbInfoId?'#0052D9':'none'"/>
@@ -302,7 +345,7 @@ async function goSearch(){
     </div>
 
     <!-- 悬浮操作按钮 -->
-    <div class="fixed-opt-btn" @click="showActionPop=true">
+    <div class="fixed-opt-btn" @click="showActionPop=true" v-if="actions.length">
         <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48" fill="none">
             <path fill-rule="evenodd" clip-rule="evenodd" d="M43.4855 12.7505L25.4062 2.31235C24.536 1.80995 23.4639 1.80995 22.5937 2.31235L4.5144 12.7505V33.6267C4.5144 34.6315 5.05046 35.5599 5.92065 36.0623L24 46.5005L42.0793 36.0623C42.9495 35.5599 43.4855 34.6315 43.4855 33.6267V12.7505ZM23.997 22.2665L9.01233 13.6153L24 4.96245L38.9859 13.6158L23.997 22.2665ZM25.5 24.8665L40.485 16.2149V33.5165L25.5 42.1666V24.8665ZM22.5 24.8665V42.1667L7.51198 33.5165V16.2132L22.5 24.8665Z" fill="white"/>
         </svg>
@@ -314,20 +357,7 @@ async function goSearch(){
         v-model:show="showActionPop"
         cancel-text="取消"
         close-on-click-action
-        :actions="[
-            {
-                name:'添加指标',
-                path:'/dataEDB/addbaseEDB'
-            },
-            {
-                name:'计算指标',
-                path:'/dataEDB/calculate/index'
-            },
-            {
-                name:'替换指标',
-                path:'/dataEDB/replaceEDB'
-            }
-        ]"
+        :actions="actions"
         @select="handleSelectActionOpt"
     >
     </van-action-sheet>
@@ -345,9 +375,9 @@ async function goSearch(){
         <template #default>
             <ul class="edb-opt-list">
                 <!-- 计算指标查看 -->
-                <li class="item" v-if="seeComputeEDBInfo(edbOptState.data)" @click="handleEDBOpt('see',edbOptState.data)">查看</li>
-                <li class="item" v-if="edbOptState.data?.Button.ShowEdbRelation" @click="handleEDBOpt('relationEDB',edbOptState.data)">关联指标</li>
-                <li class="item" v-if="edbOptState.data?.Button.ShowChartRelation" @click="handleEDBOpt('relationChart',edbOptState.data)">关联图表</li>
+                <li class="item" v-if="seeComputeEDBInfo(edbOptState.data)&&checkAuthBtn(edbDataBtn.edbData_checkCalcChart)" @click="handleEDBOpt('see',edbOptState.data)">查看</li>
+                <li class="item" v-if="edbOptState.data?.Button.ShowEdbRelation&&checkAuthBtn(edbDataBtn.edbData_checkRelatedEdb)" @click="handleEDBOpt('relationEDB',edbOptState.data)">关联指标</li>
+                <li class="item" v-if="edbOptState.data?.Button.ShowChartRelation&&checkAuthBtn(edbDataBtn.edbData_checkRelatedChart)" @click="handleEDBOpt('relationChart',edbOptState.data)">关联图表</li>
                 <li class="item" v-if="edbOptState.data?.Button.MoveButton" @click="handleEDBOpt('move',edbOptState.data)">移动至</li>
             </ul>
         </template>

+ 12 - 10
src/views/dataEDB/components/EDBChartDetail.vue

@@ -15,6 +15,9 @@ Boost(Highcharts)
 import { useRoute } from 'vue-router'
 import { showToast } from 'vant'
 
+import {edbDataBtn,useAuthBtn} from '@/hooks/useAuthBtn'
+const {checkAuthBtn} = useAuthBtn()
+
 const { width } = useWindowSize()
 const route=useRoute()
 
@@ -466,17 +469,16 @@ onMounted(() => {
 
 
 // 图表类型
-const chartTypeOpts=[
-    {
-        name:'曲线图'
-    },
-    {
-        name:'同比图'
-    },
-    {
-        name:'季节性图'
+const chartTypeOpts = computed(()=>{
+    let optionArr=[{name:'曲线图'}]
+    if(checkAuthBtn(edbDataBtn.edbData_showChartBasis)){
+        optionArr.push({name:'同比图'})
     }
-]
+    if(checkAuthBtn(edbDataBtn.edbData_switchSeason)){
+        optionArr.push({name:'季节性图'})
+    }
+    return optionArr
+})
 let beforeChartType='曲线图'
 const chartType=ref('曲线图')
 const showChartType=ref(false)

+ 31 - 7
src/views/dataEDB/components/EDBClassify.vue

@@ -5,6 +5,8 @@ import apiDataEDB from '@/api/dataEDB'
 import { showDialog , showToast } from 'vant';
 import {useEDBDelete} from '../hooks/useEDBDelete'
 import {deleteClassifyItemEmpty} from '../util/util'
+import {edbDataBtn,useAuthBtn} from '@/hooks/useAuthBtn'
+const {checkAuthBtn} = useAuthBtn()
 
 const {edbClassifyDelete}=useEDBDelete()
 const { width } = useWindowSize()
@@ -108,7 +110,7 @@ function getClassifyItemName(item){
     return langType.value==='zh'?item.ClassifyName:item.ClassifyNameEn||item.ClassifyName
 }
 
-// 获取分类数据
+// 获取分类数据classifyState
 let classifyList=ref([])
 async function getEDBClassifyList(){
     const res=await apiDataEDB.edbClassifyList()
@@ -185,6 +187,23 @@ watch(
         }
     }
 )
+//判断每一项的optArr并返回长度
+function checkOpt(item){
+    let optArr = []
+    if(item.Button.AddButton&&checkAuthBtn(edbDataBtn.edbData_classifyOpt_add)&&item.Level<6){
+        optArr.push({name:'添加下级目录',type:'add'})
+    }
+    if(checkAuthBtn(edbDataBtn.edbData_classifyOpt_add)){
+        optArr.push({name:'重命名',type:'edit'})
+    }
+    if(item.Button.DeleteButton&&checkAuthBtn(edbDataBtn.edbData_classifyOpt_delete)){
+        optArr.push({name:'删除',type:'delete',color:"#C54322"})
+    }
+    if(item.Level!==1&&item.Button.MoveButton&&checkAuthBtn(edbDataBtn.edbData_classifyOpt_move)){
+        optArr.push({name:'移动至',type:'move'})
+    }
+    return optArr.length
+}
 // 显示分类的具体操作选项
 function handleShowClassifyOpt(item){
     let optArr=[
@@ -192,12 +211,15 @@ function handleShowClassifyOpt(item){
         {name:'删除',type:'delete',color:"#C54322"},
     ]
     if(item.Button.AddButton&&showParentClassifyData.value.length<5){//添加权限
-        optArr.unshift({name:'添加下级目录',type:'add'})
+        checkAuthBtn(edbDataBtn.edbData_classifyOpt_add)&&optArr.unshift({name:'添加下级目录',type:'add'})
+    }
+    if(!checkAuthBtn(edbDataBtn.edbData_classifyOpt_add)){//重命名
+        optArr=optArr.filter(item=>item.type!='edit')
     }
-    if(!item.Button.DeleteButton){//删除
+    if(!item.Button.DeleteButton||!checkAuthBtn(edbDataBtn.edbData_classifyOpt_delete)){//删除
         optArr=optArr.filter(item=>item.type!='delete')
     }
-    if(item.Button.MoveButton){//移动权限
+    if(item.Button.MoveButton&&checkAuthBtn(edbDataBtn.edbData_classifyOpt_move)){//移动权限
         // 一级目录不能移动至
         if(selectClassifyArr.value.length){
             optArr.push({name:'移动至',type:'move'})
@@ -205,7 +227,7 @@ function handleShowClassifyOpt(item){
     }
     classifyOptState.actions=optArr
     classifyOptState.data=item
-    classifyOptState.show=true
+    optArr.length&&(classifyOptState.show=true)
 }
 function handleSelectOpt(e){
     if(e.type==='add'){
@@ -317,10 +339,12 @@ defineExpose({classifyList,langTypeChange})
                         :style="{color:selectClassifyArr[selectClassifyArr.length-1]?.ClassifyId===item.ClassifyId?'#0052D9':''}"
                         @click.stop="handleSelectClassify(item)"
                     >{{getClassifyItemName(item)}}</span>
-                    <img style="width:22px;height:22px;cursor: pointer;" src="@/assets/imgs/dataEDB/icon_opt.png" alt="" @click.stop="handleShowClassifyOpt(item)">
+                    <img style="width:22px;height:22px;cursor: pointer;" src="@/assets/imgs/dataEDB/icon_opt.png" alt="" 
+                        v-if="checkOpt(item)"
+                        @click.stop="handleShowClassifyOpt(item)">
                 </li>
             </ul>
-            <div class="bot-btn-box">
+            <div class="bot-btn-box" v-permission="edbDataBtn.edbData_classifyOpt_add">
                 <van-button type="primary" block @click="handleAddLevel1">添加一级目录</van-button>
             </div>
         </div>

+ 143 - 14
src/views/myETA/ChartDetail.vue

@@ -1,5 +1,5 @@
 <script setup>
-import {ref,nextTick, reactive} from 'vue'
+import {ref,nextTick, reactive,computed} from 'vue'
 import apiETAChart from '@/api/chart'
 import apiFutureChart from '@/api/futureChart'
 import apiCorrelationChart from '@/api/correlationChart'
@@ -21,7 +21,19 @@ import SetChartEnName from '@/components/SetChartEnName.vue'
 import {useCachedViewsStore} from '@/store/modules/cachedViews'
 import AddChartToMyETA from '@/views/chartETA/components/AddChartToMyETA.vue'
 import { setExtremumDate } from '@/hooks/chart/commonFun.js'
-
+import {myETABtn,useAuthBtn} from '@/hooks/useAuthBtn'
+const {checkAuthBtn} = useAuthBtn()
+
+const isMoreActionShow = computed(()=>{
+    return checkAuthBtn(myETABtn.myChart_refresh)
+        || checkAuthBtn(myETABtn.myChart_share)
+        || checkAuthBtn(myETABtn.myChart_move)
+        || checkAuthBtn(myETABtn.myChart_copyTo)
+        || checkAuthBtn(myETABtn.myChart_otherSave)
+        || (checkAuthBtn(myETABtn.myChart_copyWechat)&&checkAuthBtn(myETABtn.myChart_copyOffice))
+        || checkAuthBtn(myETABtn.myChart_enNameSetting)
+        || checkAuthBtn(myETABtn.myChart_del)
+}) 
 const { width, height } = useWindowSize()
 const cachedViewsStore=useCachedViewsStore()
 const {options,axisLimitState,chartRender}=useChartRender()
@@ -524,6 +536,120 @@ function handleChartShare(){
     const url=import.meta.env.VITE_CHART_LINK+`?code=${chartInfo.value.UniqueCode}&fromType=share&lang=ch`
     setClipboardData(url)
 }
+//保存图表:目前myETA里能保存的只有ETA图库的图和商品价格曲线图
+function handleChartSave(){
+    const sourceMap = {
+        1: saveChartHandle,
+        2: saveCommodityChart,//商品价格曲线
+        5: saveCommodityChart,//利润曲线
+      }
+      sourceMap[chartInfo.value.Source]&&sourceMap[chartInfo.value.Source]();
+}
+function saveChartHandle(){
+    //获取每条线的指标配置
+    let arr = edbList.value.map((item)=>{
+        return {
+            ChartColor: item.ChartColor,
+            PredictChartColor: item.PredictChartColor,
+            ChartStyle: item.ChartStyle,
+            ChartWidth: Number(item.ChartWidth),
+            EdbInfoId: item.EdbInfoId,
+            EdbInfoType: item.EdbInfoType,
+            IsAxis: item.IsAxis,
+            IsOrder: item.IsOrder,
+            LeadUnit: item.EdbInfoType ? '' : item.LeadUnit,
+            LeadValue: item.EdbInfoType ? 0 : Number(item.LeadValue),
+            MaxData: Number(item.MaxData),
+            MinData: Number(item.MinData),
+        }
+    })
+    //所有图表的公共参数
+    let public_param = {
+        ChartClassifyId: chartInfo.value.ChartClassifyId,
+        ChartInfoId: chartInfo.value.ChartInfoId,
+        ChartEdbInfoList: arr,
+    }
+    //根据ChartType决定剩余参数
+    let type_param = {}
+    switch(chartInfo.value.ChartType){
+        case 2:
+            type_param = {
+              DateType: chartState.yearVal,
+              StartYear:chartState.startYear || 0,
+              Calendar: chartState.calendarType,
+              StartDate: chartState.startTime||'',
+              EndDate: chartState.endTime||'',
+            }
+            break
+        case 7:
+            type_param = {
+              DateType: 6,
+              LeftMin: String(axisLimitState.leftMin),
+              LeftMax: String(axisLimitState.leftMax),
+            }
+            break
+        case 10:
+            type_param = {
+              DateType: 6,
+              Calendar: "公历",
+              ExtraConfig: JSON.stringify({
+                ...JSON.parse(chartInfo.value.ExtraConfig),
+                XMinValue: String(axisLimitState.xMin),
+                XMaxValue: String(axisLimitState.xMax),
+                YMinValue: String(axisLimitState.leftMin),
+                YMaxValue: String(axisLimitState.leftMax),
+              })
+            }
+            break
+    }
+    if(sameOptionType.includes(chartInfo.value.ChartType)){
+        type_param = {
+            DateType: chartState.yearVal,
+            StartYear:chartState.startYear || 0,
+            StartDate:chartState.yearVal === 5 || chartState.yearVal === 6
+                ? chartState.startTime
+                : '',
+            EndDate: chartState.yearVal === 5 ? chartState.endTime : '',
+        }
+    }
+    let params = {...public_param,...type_param}
+    //保存
+    apiChart.chartSave(params).then(async res=>{
+        if(res.Ret!==200) return
+        showToast("保存成功")
+        setChartImage()
+    })
+}
+function saveCommodityChart(){
+    apiMyETAChart.myETASaveChart({
+        ChartInfoId:chartInfo.value.ChartInfoId,
+        LeftMin:String(axisLimitState.leftMin),
+        LeftMax:String(axisLimitState.leftMax),
+    }).then(res=>{
+        if(res.Ret!==200) return 
+        showToast("保存成功")
+        setChartImage()
+    })
+}
+
+//更新缩略图
+async function setChartImage(){
+    //打开保存图片弹窗
+    const svgData = CHARTINS.getSVG({
+        chart: {
+            width: 340,
+            height: 230,
+        }
+    })
+    let form = new FormData();
+    form.append('Img', svgData);
+    let {Data,Ret} = await apiETAChart.uploadChartImg(form)
+    if(Ret!==200||!Data) return
+    await apiETAChart.setChartImg({
+        ChartInfoId:Number(chartInfo.value.ChartInfoId),
+        ImageUrl:Data.ResourceUrl
+    })
+}
 
 //保存图片
 let savePicDialogShow = ref(false)
@@ -597,11 +723,11 @@ const isShowAddToMyETADialog=ref(false)
                 >{{chartState.startTime?chartState.startTime+'~'+(chartState.endTime?chartState.endTime:'至今'):'请选择时间段'}}</span>
             </div>
             <div class="right-action-box">
-                <div class="item" @click="handleShowAxisLimitOpt" v-if="![3,4,6,7,8,9].includes(chartInfo.Source)">
+                <div class="item" @click="handleShowAxisLimitOpt" v-if="![3,4,6,7,8,9].includes(chartInfo.Source)&&checkAuthBtn(myETABtn.myChart_editLimit)">
                     <img src="@/assets/imgs/myETA/icon_limit2.png" alt="">
                     <span>上下限设置</span>
                 </div>
-                <div class="item" @click="showMoreAction=true">
+                <div class="item" @click="showMoreAction=true" v-if="isMoreActionShow||$route.query.from==='edbRelationChart'">
                     <img src="@/assets/imgs/chartETA/more-icon.png" alt="">
                     <span>更多设置</span>
                 </div>
@@ -659,11 +785,11 @@ const isShowAddToMyETADialog=ref(false)
                 <img class="icon" style="transform: rotate(180deg);" src="@/assets/imgs/icon_arrow.png" alt="">
                 <div>下一张</div>
             </div>
-            <div class="item" @click="handleShowAxisLimitOpt" v-if="![3,4,6,7,8,9].includes(chartInfo.Source)">
+            <div class="item" @click="handleShowAxisLimitOpt" v-if="![3,4,6,7,8,9].includes(chartInfo.Source)&&checkAuthBtn(myETABtn.myChart_editLimit)">
                 <img class="icon" src="@/assets/imgs/myETA/icon_limit.png" alt="">
                 <div>上下限</div>
             </div>
-            <div class="item" @click="showMoreAction=true">
+            <div class="item" @click="showMoreAction=true" v-if="isMoreActionShow||$route.query.from==='edbRelationChart'">
                 <img class="icon" src="@/assets/imgs/myETA/icon_menu.png" alt="">
                 <div>更多</div>
             </div>
@@ -815,31 +941,34 @@ const isShowAddToMyETADialog=ref(false)
     >
         <div class="more-action-wrap">
             <div class="van-ellipsis title-box">{{chartInfo.ChartName}}</div>
-            <div class="item" @click.stop="handleChartRefresh">
+            <div class="item" @click.stop="handleChartRefresh" v-permission="myETABtn.myChart_refresh">
                 刷新
             </div>
-            <div class="item" @click.stop="handleChartShare" v-if="!chartInfo.Disabled">
+            <div class="item" @click.stop="handleChartShare" v-if="!chartInfo.Disabled&&checkAuthBtn(myETABtn.myChart_share)">
                 分享
             </div>
-            <div class="item" @click.stop="handleRemoveChart" v-if="$route.query.iscommon!='true'">
+            <div class="item" @click.stop="handleChartSave" v-if="![3,4,6,7,8,9].includes(chartInfo.Source)&&checkAuthBtn(myETABtn.myChart_save)">
+                保存
+            </div>
+            <div class="item" @click.stop="handleRemoveChart" v-if="$route.query.iscommon!='true'&&checkAuthBtn(myETABtn.myChart_move)">
                 移出
             </div>
-            <div class="item" @click.stop="handleShowCopyTo" v-if="$route.query.iscommon!='true'">
+            <div class="item" @click.stop="handleShowCopyTo" v-if="$route.query.iscommon!='true'&&checkAuthBtn(myETABtn.myChart_copyTo)">
                 复制到
             </div>
             <div class="item" @click.stop="isShowAddToMyETADialog=true" v-if="$route.query.from==='edbRelationChart'">
                 加入我的图库
             </div>
-            <div class="item" @click.stop="showSaveChartOther=true" v-if="chartInfo.Button.IsCopy">
+            <div class="item" @click.stop="showSaveChartOther=true" v-if="chartInfo.Button.IsCopy&&checkAuthBtn(myETABtn.myChart_otherSave)">
                 另存为
             </div>
-            <div class="item" @click.stop="handleChartSavePicture" v-if="!chartInfo.Disabled">
+            <div class="item" @click.stop="handleChartSavePicture" v-if="!chartInfo.Disabled&&checkAuthBtn(myETABtn.myChart_copyWechat)&&checkAuthBtn(myETABtn.myChart_copyOffice)">
                 保存图片
             </div>
-            <div class="item" @click.stop="handleShowEditEnName">
+            <div class="item" @click.stop="handleShowEditEnName" v-permission="myETABtn.myChart_enNameSetting">
                 设置英文名称
             </div>
-            <div class="item" @click.stop="handleDeleteChart" v-if="chartInfo.IsEdit">
+            <div class="item" @click.stop="handleDeleteChart" v-if="chartInfo.IsEdit&&checkAuthBtn(myETABtn.myChart_del)">
                 删除
             </div>
         </div>

+ 22 - 8
src/views/myETA/Index.vue

@@ -7,6 +7,8 @@ import { showConfirmDialog, showToast } from 'vant';
 import { useWindowSize } from '@vueuse/core'
 import draggable from 'vuedraggable'
 import {useCachedViewsStore} from '@/store/modules/cachedViews'
+import {myETABtn,useAuthBtn} from '@/hooks/useAuthBtn'
+const {checkAuthBtn} = useAuthBtn()
 
 const cachedViewsStore=useCachedViewsStore()
 const { width, height } = useWindowSize()
@@ -32,6 +34,18 @@ const {
 const curChartClassifyList=computed(()=>{
     return classifyState.classifyTypeAct==1?classifyState.myClassifyList:classifyState.pubClassifyList
 })
+//我的图库/公共图库opt:重命名、可见、复制、删除
+const isOptShow = computed(()=>{
+    if(classifyState.classifyTypeAct===1){
+        return checkAuthBtn(myETABtn.myChart_classifyOpt_rename)
+            || checkAuthBtn(myETABtn.myChart_classifyOpt_show)
+            || checkAuthBtn(myETABtn.myChart_classifyOpt_copy)
+            || checkAuthBtn(myETABtn.myChart_classifyOpt_delete)
+    }
+    if(classifyState.classifyTypeAct===2){
+        return checkAuthBtn(myETABtn.myChart_classifyOpt_copy)
+    }
+})
 // 拖动排序结束
 function onClassifySortEnd(e){
     console.log(e);
@@ -172,7 +186,7 @@ async function goSearch(){
                     placeholder="请输入图表名称"
                     @click="goSearch"
                 />
-                <img @click="goChooseChart" class="icon" src="@/assets/imgs/myETA/icon_select.png" alt="icon">
+                <img @click="goChooseChart" class="icon" src="@/assets/imgs/myETA/icon_select.png" alt="icon" v-permission="myETABtn.myChart_selectChart">
                 <img @click="showClassifyPop=true" class="icon" src="@/assets/imgs/myETA/icon_menu2.png" alt="icon">
             </div>
             <p style="margin-top:10px;font-weight:bold">{{listState.ctype}}{{listState.cname?'/'+listState.cname:''}}</p>
@@ -197,7 +211,7 @@ async function goSearch(){
                     <img class="img" :src="item.ChartImage" alt="">   
                     <div class="time">
                         <span>{{item.CreateTime.slice(0,10)}}</span>
-                        <img v-if="listState.ctype==='我的图库'" class="remove-box" @click.stop="handleRemoveChart(item,index)" src="@/assets/imgs/myETA/icon_remove2.png" alt="">
+                        <img v-if="listState.ctype==='我的图库'&&checkAuthBtn(myETABtn.myChart_move)" class="remove-box" @click.stop="handleRemoveChart(item,index)" src="@/assets/imgs/myETA/icon_remove2.png" alt="">
                     </div>
                 </li>
             </ul>
@@ -240,7 +254,7 @@ async function goSearch(){
                                 <path d="M40.4087 23.8334L33.7785 18.3083V22.7283H24.9384V13.8882H29.3585L23.8334 7.25806L18.3083 13.8882H22.7283V22.7283H13.8882V18.3083L7.25806 23.8334L13.8882 29.3585V24.9384H22.7283V33.7785H18.3083L23.8334 40.4087L29.3585 33.7785H24.9384V24.9384H33.7785V29.3585L40.4087 23.8334Z" fill="#666666"/>
                             </svg>
                         </div>
-                        <div class="icon-menu-box" @click.stop="handleShowOpt(element)">
+                        <div class="icon-menu-box" @click.stop="handleShowOpt(element)" v-if="isOptShow">
                             <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48" fill="none">
                                 <path d="M24 33C25.65 33 27 34.35 27 36C27 37.65 25.65 39 24 39C22.35 39 21 37.65 21 36C21 34.35 22.35 33 24 33ZM21 24C21 25.65 22.35 27 24 27C25.65 27 27 25.65 27 24C27 22.35 25.65 21 24 21C22.35 21 21 22.35 21 24ZM21 12C21 13.65 22.35 15 24 15C25.65 15 27 13.65 27 12C27 10.35 25.65 9 24 9C22.35 9 21 10.35 21 12Z" fill="#666666"/>
                             </svg>
@@ -248,7 +262,7 @@ async function goSearch(){
                     </li>
                 </template>
             </draggable>
-            <div class="bot-btns">
+            <div class="bot-btns" v-permission="myETABtn.myChart_classifyOpt_edit">
                 <van-button type="primary" block @click="handleAddClassify('')">添加我的分类</van-button>
             </div>
         </div>
@@ -281,11 +295,11 @@ async function goSearch(){
             </div> -->
             <!-- 我的图库分类操作 -->
             <template v-if="classifyState.classifyTypeAct==1">
-            <div class="item border" @click="handleAddClassify(classifyState.activeClassifyVal)">
+            <div class="item border" @click="handleAddClassify(classifyState.activeClassifyVal)" v-permission="myETABtn.myChart_classifyOpt_edit">
                 <!-- <img src="@/assets/imgs/ppt/ppt_icon_write.png" alt=""> -->
                 <span>重命名</span>
             </div>
-            <div class="item border">
+            <div class="item border" v-permission="myETABtn.myChart_classifyOpt_show">
                 <!-- <img src="@/assets/imgs/icon_user.png" alt=""> -->
                 <span style="display:inline-block;margin-right:10px">所有人可见</span>
                 <van-switch
@@ -295,14 +309,14 @@ async function goSearch(){
                     @update:model-value="handleClassifyShare"
                 />
             </div>
-            <div class="item border red" @click="handleClassifyDel(classifyState.activeClassifyVal)">
+            <div class="item border red" @click="handleClassifyDel(classifyState.activeClassifyVal)" v-permission="myETABtn.myChart_classifyOpt_delete">
                 <!-- <img src="@/assets/imgs/icon_del.png" alt=""> -->
                 <span>删除</span>
             </div>
             </template>
             <!-- 公共图库分类操作 -->
             <template v-if="classifyState.classifyTypeAct==2">
-            <div class="item border" @click="handleCopyClassify(classifyState.activeClassifyVal)">
+            <div class="item border" @click="handleCopyClassify(classifyState.activeClassifyVal)" v-permission="myETABtn.myChart_classifyOpt_copy">
                 <!-- <img src="@/assets/imgs/ppt/ppt_icon_copy.png" alt=""> -->
                 <span>复制</span>
             </div>

+ 5 - 4
src/views/myETA/components/EDBInfo.vue

@@ -6,7 +6,8 @@ import _ from 'lodash'
 // import apiChart from '@/api/chart'
 import SourceDetail from '@/views/chartETA/components/SourceDetail.vue'
 import {useCopyEdbData} from '@/hooks/edb/useCopyEdbData'
-
+import {myETABtn,useAuthBtn} from '@/hooks/useAuthBtn'
+const {checkAuthBtn} = useAuthBtn()
 const {copyData} =useCopyEdbData()
 
 const leadUnitOpt=[{text:'年'}, {text:'季'}, {text:'月'}, {text:'周'}, {text:'天'}]//领先指标频度配置
@@ -238,9 +239,9 @@ function handleCopyEDBData(){
                         </div>
                     </div>
                     </template>
-                    <div class="item-box">
-                        <van-button color="#F2F3FF" size="small" style="color:#0052D9;margin-right:10px" @click="handleCopyEDBData">复制数据</van-button>
-                        <van-button color="#0052D9" size="small">查看数据</van-button>
+                    <div class="item-box" v-if="checkAuthBtn(myETABtn.myChart_checkData)||checkAuthBtn(myETABtn.myChart_copyData)">
+                        <van-button color="#F2F3FF" size="small" style="color:#0052D9;margin-right:10px" @click="handleCopyEDBData" v-permission="myETABtn.myChart_copyData">复制数据</van-button>
+                        <van-button color="#0052D9" size="small" v-permission="myETABtn.myChart_checkData">查看数据</van-button>
                     </div>
                 </div>
             </div>

+ 16 - 13
src/views/ppt/Detail.vue

@@ -61,7 +61,10 @@ const {
     handleShowPPTCopy,
     handlePPTDel,
     handlePPTCopy,
-    handlePPTCopyBeforeClose
+    handlePPTCopyBeforeClose,
+
+    permissionBtn,
+    checkAuthBtn
 
 }=useClassify()
 
@@ -143,27 +146,27 @@ const showPopover=ref(false)
     <div class="ppt-detail-page" :style="{height:pptContentHeight+'px'}">
         <!-- pad端顶部操作栏 -->
         <div class="pad-top-action-wrap">
-            <div class="item-box" @click="handllePublishPPT">
+            <div class="item-box" @click="handllePublishPPT" v-permission="permissionBtn.ppt_publish">
                 <img src="@/assets/imgs/ppt/icon_action_publish.png" alt="">
                 <span>发布</span>
             </div>
-            <div class="item-box" @click="showPlayOpt=true">
+            <div class="item-box" @click="showPlayOpt=true" v-permission="permissionBtn.ppt_show">
                 <img src="@/assets/imgs/ppt/icon_action_play.png" alt="">
                 <span>播放</span>
             </div>
-            <div class="item-box" @click="handleShowPPTCopy({pptid:$route.query.id})">
+            <div class="item-box" @click="handleShowPPTCopy({pptid:$route.query.id})" v-permission="permissionBtn.ppt_copy">
                 <img src="@/assets/imgs/ppt/icon_action_copy.png" alt="">
                 <span>复制</span>
             </div>
-            <div class="item-box" @click="handleDownLoadFile">
+            <div class="item-box" @click="handleDownLoadFile" v-permission="permissionBtn.ppt_download">
                 <img src="@/assets/imgs/ppt/icon_action_download2.png" alt="">
                 <span>下载</span>
             </div>
-            <div class="item-box red" @click="handlePPTDel({back:true})" v-if="!PPTOptState.isCommon">
+            <div class="item-box red" @click="handlePPTDel({back:true})" v-if="!PPTOptState.isCommon&&checkAuthBtn(permissionBtn.ppt_del)">
                 <img src="@/assets/imgs/icon_del.png" alt="">
                 <span>删除</span>
             </div>
-            <div class="item-box" style="flex-direction:row">
+            <div class="item-box" style="flex-direction:row" v-if="!PPTOptState.isCommon&&checkAuthBtn(permissionBtn.ppt_visible)">
                 <span style="margin-right:4px">公开</span>
                 <van-switch 
                     size="22px" 
@@ -181,15 +184,15 @@ const showPopover=ref(false)
             </template>
         </div>
         <div class="mobile-fix-bot-warp">
-            <div class="item-box" @click="handllePublishPPT">
+            <div class="item-box" @click="handllePublishPPT" v-permission="permissionBtn.ppt_publish">
                 <img src="@/assets/imgs/ppt/icon_action_publish.png" alt="">
                 <span>发布</span>
             </div>
-            <div class="item-box" @click="showPlayOpt=true">
+            <div class="item-box" @click="showPlayOpt=true" v-permission="permissionBtn.ppt_show">
                 <img src="@/assets/imgs/ppt/icon_action_play.png" alt="">
                 <span>播放</span>
             </div>
-            <div class="item-box" @click="handleShowPPTCopy({pptid:$route.query.id})">
+            <div class="item-box" @click="handleShowPPTCopy({pptid:$route.query.id})" v-permission="permissionBtn.ppt_copy">
                 <img src="@/assets/imgs/ppt/icon_action_copy.png" alt="">
                 <span>复制</span>
             </div>
@@ -218,7 +221,7 @@ const showPopover=ref(false)
                         </div>
                     </div>
                 </div>
-                <div class="flex" v-if="!PPTOptState.isCommon">
+                <div class="flex" v-if="!PPTOptState.isCommon&&checkAuthBtn(permissionBtn.ppt_visible)">
                     <span style="margin-right:4px">公开</span>
                     <van-switch 
                         size="22px" 
@@ -228,11 +231,11 @@ const showPopover=ref(false)
                 </div>
                 
             </div>
-            <div class="item border blue" @click="handleDownLoadFile">
+            <div class="item border blue" @click="handleDownLoadFile" v-permission="permissionBtn.ppt_download">
                 <img src="@/assets/imgs/ppt/icon_action_download.png" alt="">
                 <span>下载</span>
             </div>
-            <div class="item border red" @click="handlePPTDel({back:true})" v-if="!PPTOptState.isCommon">
+            <div class="item border red" @click="handlePPTDel({back:true})" v-if="!PPTOptState.isCommon&&checkAuthBtn(permissionBtn.ppt_del)">
                 <img src="@/assets/imgs/icon_del.png" alt="">
                 <span>删除</span>
             </div>

+ 10 - 7
src/views/ppt/components/MobileClassifyWrap.vue

@@ -24,7 +24,10 @@ const {
     handlePPTCopy,
     handlePPTCopyBeforeClose,
 
-    goPPTDetail
+    goPPTDetail,
+
+    permissionBtn,
+    checkAuthBtn
 }=useClassify()
 
 getPPTClassifyData()
@@ -134,15 +137,15 @@ const showPopover=ref(false)
                 <img src="@/assets/imgs/ppt/ppt_icon_file.png" alt="">
                 <span>{{fileOptState.data.GroupName}}</span>
             </div>
-            <div class="item border blue" @click="handlePPTCatalogueCopy">
+            <div class="item border blue" @click="handlePPTCatalogueCopy" v-permission="permissionBtn.ppt_copy">
                 <img src="@/assets/imgs/ppt/ppt_icon_copy.png" alt="">
                 <span>复制</span>
             </div>
-            <div class="item border blue" @click="fileOptState.showReName=true">
+            <div class="item border blue" @click="fileOptState.showReName=true" v-permission="permissionBtn.ppt_save">
                 <img src="@/assets/imgs/ppt/ppt_icon_write.png" alt="">
                 <span>重命名</span>
             </div>
-            <div class="item border red" @click="handlePPTCatalogueDel">
+            <div class="item border red" @click="handlePPTCatalogueDel" v-permission="permissionBtn.ppt_del">
                 <img src="@/assets/imgs/icon_del.png" alt="">
                 <span>删除</span>
             </div>
@@ -180,7 +183,7 @@ const showPopover=ref(false)
                         </div>
                     </div>
                 </div>
-                <div class="flex" v-if="!PPTOptState.isCommon">
+                <div class="flex" v-if="!PPTOptState.isCommon&&checkAuthBtn(permissionBtn.ppt_visible)">
                     <span style="margin-right:4px">公开</span>
                     <van-switch 
                         size="22px" 
@@ -190,11 +193,11 @@ const showPopover=ref(false)
                 </div>
                 
             </div>
-            <div class="item border blue" @click="handleShowPPTCopy">
+            <div class="item border blue" @click="handleShowPPTCopy" v-permission="permissionBtn.ppt_copy">
                 <img src="@/assets/imgs/ppt/ppt_icon_copy.png" alt="">
                 <span>复制</span>
             </div>
-            <div class="item border red" @click="handlePPTDel" v-if="!PPTOptState.isCommon">
+            <div class="item border red" @click="handlePPTDel" v-if="!PPTOptState.isCommon&&checkAuthBtn(permissionBtn.ppt_del)">
                 <img src="@/assets/imgs/icon_del.png" alt="">
                 <span>删除</span>
             </div>

+ 21 - 12
src/views/ppt/components/PadPPTIndexWrap.vue

@@ -1,5 +1,5 @@
 <script setup>
-import {ref} from 'vue'
+import {computed, ref} from 'vue'
 import {useClassify} from '../hooks/useClassify'
 import openShareIcon from '@/assets/imgs/ppt/ppt_icon_user1.png'
 import closeShareIcon from '@/assets/imgs/ppt/ppt_icon_user2.png'
@@ -30,10 +30,19 @@ const {
     handlePPTCopy,
     handlePPTCopyBeforeClose,
 
-    goPPTDetail
+    goPPTDetail,
+
+    permissionBtn,
+    checkAuthBtn
 }=useClassify()
 getPPTClassifyData()
 
+const isOptBoxShow = computed(()=>{
+    return checkAuthBtn(permissionBtn.ppt_copy)||checkAuthBtn(permissionBtn.ppt_save)||checkAuthBtn(permissionBtn.ppt_del)
+})
+const isOptPPTShow = computed(()=>{
+    return checkAuthBtn(permissionBtn.ppt_copy)||checkAuthBtn(permissionBtn.ppt_del)
+})
 const activeType=ref('myPPT')
 
 // 获取ppt列表
@@ -109,20 +118,20 @@ const showPopover=ref(false)
                                 <div @click.stop="handleShowFileOpt(item)">
                                     <van-popover position="bottom-start">
                                         <template #reference>
-                                            <div class="menu-icon">
+                                            <div class="menu-icon" v-if="isOptBoxShow">
                                                 <img class="icon" src="@/assets/imgs/ppt/ppt_icon_menu.png" alt="">
                                             </div>
                                         </template>
                                         <div class="pad-classify-file-opt-box">
-                                            <div class="item" @click="handlePPTCatalogueCopy">
+                                            <div class="item" @click="handlePPTCatalogueCopy" v-permission="permissionBtn.ppt_copy">
                                                 <img src="@/assets/imgs/ppt/icon_action_copy.png" alt="">
                                                 <span>复制</span>
                                             </div>
-                                            <div class="item" @click="fileOptState.showReName=true">
+                                            <div class="item" @click="fileOptState.showReName=true" v-permission="permissionBtn.ppt_save">
                                                 <img src="@/assets/imgs/ppt/ppt_icon_write02.png" alt="">
                                                 <span>重命名</span>
                                             </div>
-                                            <div class="item del" @click="handlePPTCatalogueDel">
+                                            <div class="item del" @click="handlePPTCatalogueDel" v-permission="permissionBtn.ppt_del">
                                                 <img src="@/assets/imgs/icon_del.png" alt="">
                                                 <span>删除</span>
                                             </div>
@@ -141,14 +150,14 @@ const showPopover=ref(false)
                             <div @click.stop="handleShowPPTOpt(_item)">
                                 <van-popover position="bottom-start">
                                     <template #reference>
-                                        <img class="share-icon" :src="_item.IsSingleShareBoolean?openShareIcon:closeShareIcon" alt="">
+                                        <img class="share-icon" :src="_item.IsSingleShareBoolean?openShareIcon:closeShareIcon" alt="" v-if="checkAuthBtn(permissionBtn.ppt_visible)">
                                     </template>
                                     <div class="pad-classify-file-opt-box">
-                                        <div class="item" @click="handleChangePPTShare(1,_item)">
+                                        <div class="item" @click="handleChangePPTShare(1,_item)" v-permission="permissionBtn.ppt_visible">
                                             <img :src="closeShareIcon" alt="">
                                             <span>仅自己可见</span>
                                         </div>
-                                        <div class="item" @click="handleChangePPTShare(2,_item)">
+                                        <div class="item" @click="handleChangePPTShare(2,_item)" v-permission="permissionBtn.ppt_visible">
                                             <img :src="openShareIcon" alt="">
                                             <span>所有人可见</span>
                                         </div>
@@ -158,16 +167,16 @@ const showPopover=ref(false)
                             <div @click.stop="handleShowPPTOpt(_item)">
                                 <van-popover position="bottom-start">
                                     <template #reference>
-                                        <div class="menu-icon">
+                                        <div class="menu-icon" v-if="isOptPPTShow">
                                             <img class="icon" src="@/assets/imgs/ppt/ppt_icon_menu.png" alt="">
                                         </div>
                                     </template>
                                     <div class="pad-classify-file-opt-box">
-                                        <div class="item" @click="handleShowPPTCopy">
+                                        <div class="item" @click="handleShowPPTCopy" v-permission="permissionBtn.ppt_copy">
                                             <img src="@/assets/imgs/ppt/icon_action_copy.png" alt="">
                                             <span>复制</span>
                                         </div>
-                                        <div class="item del" @click="handlePPTDel">
+                                        <div class="item del" @click="handlePPTDel" v-permission="permissionBtn.ppt_del">
                                             <img src="@/assets/imgs/icon_del.png" alt="">
                                             <span>删除</span>
                                         </div>

+ 7 - 1
src/views/ppt/hooks/useClassify.js

@@ -4,6 +4,9 @@ import {ref,reactive} from 'vue'
 import { useRouter } from 'vue-router';
 import { showToast,showDialog,Dialog  } from 'vant';
 import {useUserInfo} from '@/hooks/common'
+import {pptBtn,enPPTBtn,useAuthBtn} from '@/hooks/useAuthBtn'
+const  {checkAuthBtn} = useAuthBtn()
+const permissionBtn = window.location.pathname.startsWith('/ppten')?enPPTBtn:pptBtn
 import {
     apiPPTClassify,
     apiPPTCatalogueCopy,
@@ -242,6 +245,9 @@ export function useClassify(){
         handlePPTCopy,
         handlePPTCopyBeforeClose,
 
-        goPPTDetail
+        goPPTDetail,
+
+        permissionBtn,
+        checkAuthBtn
     }
 }

+ 4 - 3
src/views/report/AddReport.vue

@@ -10,6 +10,7 @@ import moment from 'moment'
 import { showToast,showDialog  } from 'vant'
 import { useRouter } from 'vue-router'
 import {useCachedViewsStore} from '@/store/modules/cachedViews'
+import {reportManageBtn} from '@/hooks/useAuthBtn'
 const cachedViewsStore=useCachedViewsStore()
 
 const router=useRouter()
@@ -311,7 +312,7 @@ function onConfirmDSFBTime(time){
                     <img src="@/assets/imgs/report/icon_refresh.png" alt="">
                     <span>刷新</span>
                 </div>
-                <div class="item" @click="handleReportOpt('yl')">
+                <div class="item" @click="handleReportOpt('yl')" v-permission="reportManageBtn.reportManage_reportView">
                     <img src="@/assets/imgs/report/icon_preview.png" alt="">
                     <span>预览</span>
                 </div>
@@ -319,11 +320,11 @@ function onConfirmDSFBTime(time){
                     <img src="@/assets/imgs/report/icon_save2.png" alt="">
                     <span>保存</span>
                 </div>
-                <div class="item" @click="handleReportOpt('dsfb')">
+                <div class="item" @click="handleReportOpt('dsfb')" v-permission="reportManageBtn.reportManage_publish">
                     <img src="@/assets/imgs/report/icon_time.png" alt="">
                     <span>定时发布</span>
                 </div>
-                <div class="item" @click="handleReportOpt('fb')">
+                <div class="item" @click="handleReportOpt('fb')" v-permission="reportManageBtn.reportManage_publish">
                     <img src="@/assets/imgs/report/icon_publish3.png" alt="">
                     <span>发布</span>
                 </div>

+ 4 - 3
src/views/report/EditReport.vue

@@ -10,6 +10,7 @@ import moment from 'moment'
 import { showToast,showDialog } from 'vant'
 import { useRoute, useRouter } from 'vue-router'
 import {useCachedViewsStore} from '@/store/modules/cachedViews'
+import {reportManageBtn} from '@/hooks/useAuthBtn'
 const cachedViewsStore=useCachedViewsStore()
 
 const router=useRouter()
@@ -394,7 +395,7 @@ function onConfirmDSFBTime(time){
                     <img src="@/assets/imgs/report/icon_refresh.png" alt="">
                     <span>刷新</span>
                 </div>
-                <div class="item" @click="handleReportOpt('yl')">
+                <div class="item" @click="handleReportOpt('yl')" v-permission="reportManageBtn.reportManage_reportView">
                     <img src="@/assets/imgs/report/icon_preview.png" alt="">
                     <span>预览</span>
                 </div>
@@ -402,11 +403,11 @@ function onConfirmDSFBTime(time){
                     <img src="@/assets/imgs/report/icon_save2.png" alt="">
                     <span>保存</span>
                 </div>
-                <div class="item" @click="handleReportOpt('dsfb')">
+                <div class="item" @click="handleReportOpt('dsfb')" v-permission="reportManageBtn.reportManage_publish">
                     <img src="@/assets/imgs/report/icon_time.png" alt="">
                     <span>定时发布</span>
                 </div>
-                <div class="item" @click="handleReportOpt('fb')">
+                <div class="item" @click="handleReportOpt('fb')" v-permission="reportManageBtn.reportManage_publish">
                     <img src="@/assets/imgs/report/icon_publish3.png" alt="">
                     <span>发布</span>
                 </div>

+ 42 - 16
src/views/report/List.vue

@@ -9,8 +9,27 @@ import { useRouter } from 'vue-router';
 import { useWindowSize } from '@vueuse/core'
 import {useCachedViewsStore} from '@/store/modules/cachedViews'
 import {reportFrequencyOpts} from './utils/config'
+import {reportManageBtn,useAuthBtn} from '@/hooks/useAuthBtn'
 const cachedViewsStore=useCachedViewsStore()
 
+const {checkAuthBtn} = useAuthBtn()
+
+//添加按钮和添加选项
+const isAddReportBtnShow = computed(()=>{
+    return checkAuthBtn(reportManageBtn.reportManage_reportAdd)||checkAuthBtn(reportManageBtn.reportManage_dayWeekReportAdd)
+})
+
+const addReportActions = computed(()=>{
+    let arr = []
+    if(checkAuthBtn(reportManageBtn.reportManage_reportAdd)){
+        arr.push({name:'研报'})
+    }
+    if(checkAuthBtn(reportManageBtn.reportManage_dayWeekReportAdd)){
+        arr.push({name:'晨报/周报'})
+    }
+    return arr.reverse()
+})
+
 const { width, height } = useWindowSize()
 
 const router=useRouter()
@@ -210,6 +229,8 @@ function handleConfirmClassify({firstClassify,secondClassify}){
 // 跳转详情
 function goDetail(item){
     console.log(item);
+    //若没有预览权限,则不跳转
+    if(!checkAuthBtn(reportManageBtn.reportManage_reportView)) return 
     router.push({
         path:"/report/preview",
         query:{
@@ -227,6 +248,18 @@ async function onLongPressItem(e){
         showToast(`${e.Editor}正在编辑中,不可操作!`)
         return
     }
+    //检验权限,如果该状态下无可操作项,则长按不弹出
+    let checkState = false
+    if(e.State===1){ //编辑、发布、删除
+        checkState = checkAuthBtn(reportManageBtn.reportManage_reportEdit)
+            ||checkAuthBtn(reportManageBtn.reportManage_publish)
+            ||checkAuthBtn(reportManageBtn.reportManage_reportDel)
+    }
+    if(e.State===2){ //推送消息、取消发布
+        checkState = checkAuthBtn(reportManageBtn.reportManage_sendMsg)
+            ||checkAuthBtn(reportManageBtn.reportManage_cancelPublish)
+    }
+    if(!checkState) return
     activeItem.value=e
     showReportItemOpt.value=true
 }
@@ -438,7 +471,7 @@ async function handleReportEdit(e){
                         </div>
                     </div>
                 </van-dropdown-item>
-                <van-dropdown-item title="推送状态" ref="statusDropMenuIns">
+                <van-dropdown-item title="推送状态" ref="statusDropMenuIns" v-if="checkAuthBtn(reportManageBtn.reportManage_sendMsg)">
                     <div class="report-status-box">
                         <ul>
                             <li 
@@ -507,7 +540,7 @@ async function handleReportEdit(e){
                         </div>
                         <div class="read-count">
                             <span>PV:{{item.Pv}}</span>
-                            <span>UV:{{item.Uv}}</span>
+                            <span v-permission="reportManageBtn.reportManage_reportList_uv">UV:{{item.Uv}}</span>
                         </div>
                         <div class="status">
                             <span v-if="item.State===1">未发布</span>
@@ -520,7 +553,7 @@ async function handleReportEdit(e){
     </div>
 
     <!-- 添加报告按钮 -->
-    <div class="add-report-btn" @click="showAddReportPop=true">
+    <div class="add-report-btn" @click="showAddReportPop=true" v-if="isAddReportBtnShow">
         <svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
             <path d="M12.0499 15.9499V27.5H15.9499V15.9499H27.5V12.0499H15.9499V0.5H12.0499V12.0499H0.5V15.9499H12.0499Z" fill="white"/>
         </svg>
@@ -532,14 +565,7 @@ async function handleReportEdit(e){
         v-model:show="showAddReportPop"
         cancel-text="取消"
         close-on-click-action
-        :actions="[
-            {
-                name:'研报'
-            },
-            {
-                name:'晨报/周报'
-            }
-        ]"
+        :actions="addReportActions"
         @select="handleSelectAddReportType"
     >
     </van-action-sheet>
@@ -554,13 +580,13 @@ async function handleReportEdit(e){
         <div class="report-item-action-box" v-if="activeItem">
             <!-- <div class="title">{{activeItem.Title}}</div> -->
             <template v-if="activeItem.State==1">
-                <div class="item" @click="handleReportEdit(activeItem)">编辑</div>
-                <div class="item" @click="handleReportPublish(activeItem)">发布</div>
-                <div class="item" @click="handleReportDel(activeItem)">删除</div>
+                <div class="item" @click="handleReportEdit(activeItem)" v-permission="reportManageBtn.reportManage_reportEdit">编辑</div>
+                <div class="item" @click="handleReportPublish(activeItem)" v-permission="reportManageBtn.reportManage_publish">发布</div>
+                <div class="item" @click="handleReportDel(activeItem)" v-permission="reportManageBtn.reportManage_reportDel">删除</div>
             </template>
             <template v-if="activeItem.State==2">
-                <div class="item" @click="handldReportMsgSend(activeItem)" v-if="activeItem.MsgIsSend==0">推送消息</div>
-                <div class="item" @click="handleReportPublishCancle(activeItem)">取消发布</div>
+                <div class="item" @click="handldReportMsgSend(activeItem)" v-if="activeItem.MsgIsSend==0&&checkAuthBtn(reportManageBtn.reportManage_sendMsg)">推送消息</div>
+                <div class="item" @click="handleReportPublishCancle(activeItem)" v-permission="reportManageBtn.reportManage_cancelPublish">取消发布</div>
             </template>
         </div>
     </van-action-sheet>

+ 3 - 1
src/views/report/PreviewDetail.vue

@@ -4,6 +4,8 @@ import { useRoute, useRouter } from "vue-router";
 import apiReport from '@/api/report'
 import AudioBox from './components/AudioBox.vue'
 import {showToast} from 'vant'
+import {reportManageBtn,useAuthBtn} from '@/hooks/useAuthBtn'
+const {checkAuthBtn} = useAuthBtn()
 
 const route=useRoute()
 const router=useRouter()
@@ -69,7 +71,7 @@ async function goEdit(){
     <div class="report-detail-page" v-if="reportInfo">
         <div class="top-stage-box" v-if="$route.query.id!=-1">
             <span class="stage">第{{reportInfo.Stage}}期 / {{reportInfo.Frequency}}</span>
-            <img v-if="reportInfo.State==1" class="edit-icon" src="@/assets/imgs/report/icon_edit2.png" alt="" @click="goEdit">
+            <img v-if="reportInfo.State==1&&checkAuthBtn(reportManageBtn.reportManage_reportEdit)" class="edit-icon" src="@/assets/imgs/report/icon_edit2.png" alt="" @click="goEdit">
         </div>
         <h1 class="report-title">{{reportInfo.Title}}</h1>
         <div class="auth-box">

+ 3 - 2
src/views/report/chapter/Detail.vue

@@ -12,6 +12,7 @@ import {useUserInfo,isWeiXin} from '@/hooks/common'
 import { showToast,showDialog } from 'vant'
 import {useUploadFileToOSS} from '@/hooks/useUploadFileToOSS'
 import MD5 from 'js-md5'
+import {reportManageBtn} from '@/hooks/useAuthBtn'
 
 const route=useRoute()
 const router=useRouter()
@@ -444,7 +445,7 @@ async function handleReportOpt(type){
                     <img src="@/assets/imgs/report/icon_refresh.png" alt="">
                     <span>刷新</span>
                 </div>
-                <div class="item" @click="handleReportOpt('yl')">
+                <div class="item" @click="handleReportOpt('yl')" v-permission="reportManageBtn.reportManage_reportView">
                     <img src="@/assets/imgs/report/icon_preview.png" alt="">
                     <span>预览</span>
                 </div>
@@ -452,7 +453,7 @@ async function handleReportOpt(type){
                     <img src="@/assets/imgs/report/icon_save2.png" alt="">
                     <span>保存</span>
                 </div>
-                <div class="item" @click="handleReportOpt('fb')">
+                <div class="item" @click="handleReportOpt('fb')" v-permission="reportManageBtn.reportManage_publish">
                     <img src="@/assets/imgs/report/icon_publish3.png" alt="">
                     <span>发布</span>
                 </div>

+ 4 - 3
src/views/reportEn/AddReport.vue

@@ -10,6 +10,7 @@ import { showToast,showDialog } from 'vant'
 import { useRoute, useRouter } from 'vue-router'
 import {useInitFroalaEditor} from '@/hooks/useFroalaEditor'
 import {useCachedViewsStore} from '@/store/modules/cachedViews'
+import {enReportManageBtn} from '@/hooks/useAuthBtn'
 
 const cachedViewsStore=useCachedViewsStore()
 const router=useRouter()
@@ -352,7 +353,7 @@ function onConfirmDSFBTime(time){
                     <img src="@/assets/imgs/report/icon_refresh.png" alt="">
                     <span>刷新</span>
                 </div>
-                <div class="item" @click="handleReportOpt('yl')">
+                <div class="item" @click="handleReportOpt('yl')" v-permission="enReportManageBtn.enReport_reportView">
                     <img src="@/assets/imgs/report/icon_preview.png" alt="">
                     <span>预览</span>
                 </div>
@@ -360,11 +361,11 @@ function onConfirmDSFBTime(time){
                     <img src="@/assets/imgs/report/icon_save2.png" alt="">
                     <span>保存</span>
                 </div>
-                <div class="item" @click="handleReportOpt('dsfb')">
+                <div class="item" @click="handleReportOpt('dsfb')" v-permission="enReportManageBtn.enReport_publish">
                     <img src="@/assets/imgs/report/icon_time.png" alt="">
                     <span>定时发布</span>
                 </div>
-                <div class="item" @click="handleReportOpt('fb')">
+                <div class="item" @click="handleReportOpt('fb')" v-permission="enReportManageBtn.enReport_publish">
                     <img src="@/assets/imgs/report/icon_publish3.png" alt="">
                     <span>发布</span>
                 </div>

+ 3 - 1
src/views/reportEn/Detail.vue

@@ -3,6 +3,8 @@ import {ref} from 'vue'
 import { useRoute, useRouter } from "vue-router";
 import apiReportEn from '@/api/reportEn'
 import { showToast,showDialog } from 'vant';
+import {enReportManageBtn,useAuthBtn} from '@/hooks/useAuthBtn'
+const {checkAuthBtn} = useAuthBtn()
 
 const route=useRoute()
 const router=useRouter()
@@ -62,7 +64,7 @@ async function goEdit(){
     <div class="report-detail-page" v-if="reportInfo">
         <div class="top-stage-box" v-if="route.query.id>0">
             <span class="stage">第{{reportInfo.Stage}}期 / {{reportInfo.Frequency}}</span>
-            <img v-if="reportInfo.State==1" class="edit-icon" src="@/assets/imgs/report/icon_edit2.png" alt="" @click="goEdit">
+            <img v-if="reportInfo.State==1&&checkAuthBtn(enReportManageBtn.enReport_reportEdit)" class="edit-icon" src="@/assets/imgs/report/icon_edit2.png" alt="" @click="goEdit">
         </div>
         <h1 class="report-title">{{reportInfo.Title}}</h1>
         <div class="auth-box">

+ 24 - 9
src/views/reportEn/List.vue

@@ -9,8 +9,9 @@ import { showToast,showDialog,Dialog } from 'vant';
 import { useRouter } from 'vue-router';
 import { useWindowSize } from '@vueuse/core'
 import {useCachedViewsStore} from '@/store/modules/cachedViews'
-
+import {enReportManageBtn,useAuthBtn} from '@/hooks/useAuthBtn'
 const cachedViewsStore=useCachedViewsStore()
+const {checkAuthBtn} = useAuthBtn()
 
 const { width, height } = useWindowSize()
 
@@ -188,6 +189,8 @@ function handleConfirmClassify({rootClassify,firstClassify,secondClassify}){
 
 // 跳转详情
 function goDetail(item){
+    //若没有预览权限,则不跳转
+    if(!checkAuthBtn(enReportManageBtn.enReport_reportView)) return 
     router.push({
         path:"/reportEn/detail",
         query:{
@@ -205,6 +208,18 @@ function onLongPressItem(e){
         showToast(`${e.Editor}正在编辑中,不可操作!`)
         return
     }
+    //检验权限,如果该状态下无可操作项,则长按不弹出
+    let checkState = false
+    if(e.State===1){ //编辑、发布、删除
+        checkState = checkAuthBtn(enReportManageBtn.enReport_reportEdit)
+            ||checkAuthBtn(enReportManageBtn.enReport_publish)
+            ||checkAuthBtn(enReportManageBtn.enReport_reportDel)
+    }
+    if(e.State===2){ //群发邮件/群发日志、取消发布
+        checkState = checkAuthBtn(enReportManageBtn.enReport_sendEmail)
+            ||checkAuthBtn(enReportManageBtn.enReport_cancelPublish)
+    }
+    if(!checkState) return
     activeItem.value=e
     showReportItemOpt.value=true
 }
@@ -455,7 +470,7 @@ function handleGoEmailLog(e){
                         </div>
                     </div>
                 </van-dropdown-item>
-                <van-dropdown-item title="群发状态" ref="statusDropMenuIns">
+                <van-dropdown-item title="群发状态" ref="statusDropMenuIns" v-if="checkAuthBtn(enReportManageBtn.enReport_sendEmail)">
                     <div class="report-status-box">
                         <ul>
                             <li 
@@ -535,7 +550,7 @@ function handleGoEmailLog(e){
     </div>
 
     <!-- 添加报告按钮 -->
-    <div class="add-report-btn" @click="$router.push('/reportEn/add')">
+    <div class="add-report-btn" @click="$router.push('/reportEn/add')" v-if="checkAuthBtn(enReportManageBtn.enReport_reportAdd)">
         <svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
             <path d="M12.0499 15.9499V27.5H15.9499V15.9499H27.5V12.0499H15.9499V0.5H12.0499V12.0499H0.5V15.9499H12.0499Z" fill="white"/>
         </svg>
@@ -551,14 +566,14 @@ function handleGoEmailLog(e){
         <div class="report-item-action-box" v-if="activeItem">
             <!-- <div class="title">{{activeItem.Title}}</div> -->
             <template v-if="activeItem.State==1">
-                <div class="item" @click="handleReportEdit(activeItem)" v-if="activeItem.CanEdit">编辑</div>
-                <div class="item" @click="handleReportPublish(activeItem)">发布</div>
-                <div class="item" @click="handleReportDel(activeItem)">删除</div>
+                <div class="item" @click="handleReportEdit(activeItem)" v-if="activeItem.CanEdit&&checkAuthBtn(enReportManageBtn.enReport_reportEdit)">编辑</div>
+                <div class="item" @click="handleReportPublish(activeItem)" v-permission="enReportManageBtn.enReport_publish">发布</div>
+                <div class="item" @click="handleReportDel(activeItem)" v-permission="enReportManageBtn.enReport_reportDel">删除</div>
             </template>
             <template v-if="activeItem.State==2">
-                <div class="item" @click="showSendEmail=true;showReportItemOpt=false" v-if="activeItem.EmailState===0&&activeItem.EmailAuth">群发邮件</div>
-                <div class="item" @click="handleGoEmailLog(activeItem)" v-if="activeItem.EmailState===1&&activeItem.EmailAuth">群发日志</div>
-                <div class="item" @click="handleReportPublishCancle(activeItem)">取消发布</div>
+                <div class="item" @click="showSendEmail=true;showReportItemOpt=false" v-if="activeItem.EmailState===0&&activeItem.EmailAuth&&checkAuthBtn(enReportManageBtn.enReport_sendEmail)">群发邮件</div>
+                <div class="item" @click="handleGoEmailLog(activeItem)" v-if="activeItem.EmailState===1&&activeItem.EmailAuth&&checkAuthBtn(enReportManageBtn.enReport_sendEmail)">群发日志</div>
+                <div class="item" @click="handleReportPublishCancle(activeItem)" v-permission="enReportManageBtn.enReport_cancelPublish">取消发布</div>
             </template>
         </div>
     </van-action-sheet>