فهرست منبع

Merge branch 'master' of http://8.136.199.33:3000/eta_front/eta_front into ETA_1.1.5

hbchen 1 سال پیش
والد
کامیت
b1c85b6a4f
100فایلهای تغییر یافته به همراه6181 افزوده شده و 925 حذف شده
  1. 2 1
      config/dev.env.js
  2. 2 1
      config/prod.env.js
  3. 2 1
      config/prod.test.env.js
  4. 12 0
      index.html
  5. 2 1
      src/api/api.js
  6. 1 0
      src/api/http.js
  7. 112 1
      src/api/modules/chartApi.js
  8. 9 0
      src/api/modules/futuresBaseApi.js
  9. 11 1
      src/api/modules/predictEdbApi.js
  10. 97 0
      src/api/modules/sheetApi.js
  11. 14 0
      src/api/modules/toolBoxApi.js
  12. 3 0
      src/assets/icons/chartFrame/arrow-left.svg
  13. 3 0
      src/assets/icons/chartFrame/arrow-right.svg
  14. 11 0
      src/assets/icons/chartFrame/fillColor.svg
  15. 17 0
      src/assets/icons/chartFrame/fontColor.svg
  16. 12 0
      src/assets/icons/chartFrame/fontStyle.svg
  17. 11 0
      src/assets/icons/chartFrame/fontText.svg
  18. 12 0
      src/assets/icons/chartFrame/fontWeight.svg
  19. 8 0
      src/assets/icons/chartFrame/redo.svg
  20. 5 0
      src/assets/icons/chartFrame/stokeColor.svg
  21. 5 0
      src/assets/icons/chartFrame/stokeStyle.svg
  22. 5 0
      src/assets/icons/chartFrame/textAlign.svg
  23. 8 0
      src/assets/icons/chartFrame/undo.svg
  24. BIN
      src/assets/img/chart_m/check.png
  25. BIN
      src/assets/img/home/loading.gif
  26. BIN
      src/assets/img/icons/jump_ico.png
  27. BIN
      src/assets/img/icons/tooltip.png
  28. 1 0
      src/components/pwdDlg.vue
  29. 2 1
      src/mixins/theme.js
  30. 94 7
      src/routes/modules/chartRoutes.js
  31. 38 49
      src/utils/TimeOnPage.js
  32. 45 11
      src/utils/buttonConfig.js
  33. 6 2
      src/utils/commonOptions.js
  34. 2 0
      src/utils/icon.js
  35. 3 3
      src/utils/svgToblob.js
  36. 3 1
      src/views/Home.vue
  37. 5 0
      src/views/Login.vue
  38. 140 0
      src/views/chartFrame_manage/common/config.js
  39. 115 0
      src/views/chartFrame_manage/common/event.js
  40. 135 0
      src/views/chartFrame_manage/common/graph.js
  41. 267 0
      src/views/chartFrame_manage/components/frameContainer.vue
  42. 402 0
      src/views/chartFrame_manage/components/frameToolBar.vue
  43. 36 0
      src/views/chartFrame_manage/components/toolItem.vue
  44. 149 0
      src/views/chartFrame_manage/css/basePage.scss
  45. 69 0
      src/views/chartFrame_manage/css/customTree.scss
  46. 221 0
      src/views/chartFrame_manage/frameEditor.vue
  47. 601 0
      src/views/chartFrame_manage/index.vue
  48. 73 0
      src/views/chartRelevance_manage/components/explainDialog.vue
  49. 38 0
      src/views/chartRelevance_manage/components/explainText.js
  50. 4 3
      src/views/chartRelevance_manage/components/saveEdbToBaseDia.vue
  51. 20 4
      src/views/chartRelevance_manage/fittingEquationChartEditor.vue
  52. 2 2
      src/views/chartRelevance_manage/fittingEquationList.vue
  53. 21 6
      src/views/chartRelevance_manage/relevanceChartEditor.vue
  54. 24 8
      src/views/chartRelevance_manage/statisticFeatureChartEditor.vue
  55. 106 88
      src/views/classify_manage/classifyEnlist.vue
  56. 23 3
      src/views/dataEntry_manage/addChart.vue
  57. 4 3
      src/views/dataEntry_manage/adjustdata/adjustData.vue
  58. 5 92
      src/views/dataEntry_manage/chartSetting.vue
  59. 5 4
      src/views/dataEntry_manage/codecount/index.vue
  60. 51 5
      src/views/dataEntry_manage/components/satterSeriesDia.vue
  61. 11 0
      src/views/dataEntry_manage/components/sectionalScatterOption.vue
  62. 23 8
      src/views/dataEntry_manage/databaseComponents/batchComptedDialog.vue
  63. 6 2
      src/views/dataEntry_manage/databaseComponents/chartTrendRender.vue
  64. 3 2
      src/views/dataEntry_manage/databaseComponents/completeTargetDia.vue
  65. 3 2
      src/views/dataEntry_manage/databaseComponents/computedDialog.vue
  66. 3 7
      src/views/dataEntry_manage/databaseComponents/diffusionIndexDia.vue
  67. 15 14
      src/views/dataEntry_manage/databaseComponents/fittingResidueDia.vue
  68. 6 5
      src/views/dataEntry_manage/databaseComponents/jointTargetDia.vue
  69. 49 72
      src/views/dataEntry_manage/databaseComponents/openDialog.vue
  70. 22 12
      src/views/dataEntry_manage/databaseComponents/operationDialog.vue
  71. 18 1
      src/views/dataEntry_manage/databaseComponents/smoothEdbDialog.vue
  72. 16 1
      src/views/dataEntry_manage/databaseComponents/util.js
  73. 164 258
      src/views/dataEntry_manage/databaseList.vue
  74. 28 3
      src/views/dataEntry_manage/editChart.vue
  75. 7 1
      src/views/dataEntry_manage/mixins/addOreditMixin.js
  76. 1 1
      src/views/dataEntry_manage/mixins/chartPublic.js
  77. 2 1
      src/views/datasheet_manage/addSheet.vue
  78. 33 23
      src/views/datasheet_manage/common/option.js
  79. 3 13
      src/views/datasheet_manage/components/SheetExcel.vue
  80. 1 1
      src/views/datasheet_manage/components/selectTargetValueDia.vue
  81. 6 2
      src/views/datasheet_manage/components/sheetClassifyDia.vue
  82. 119 0
      src/views/datasheet_manage/components/sheetListWrap.vue
  83. 505 0
      src/views/datasheet_manage/customAnalysis/addAnalysisSheet.vue
  84. 130 0
      src/views/datasheet_manage/customAnalysis/components/bottomSection.vue
  85. 261 0
      src/views/datasheet_manage/customAnalysis/components/createTargetForm.vue
  86. 118 0
      src/views/datasheet_manage/customAnalysis/components/rightSection.vue
  87. 1092 0
      src/views/datasheet_manage/customAnalysis/list.vue
  88. 1 1
      src/views/datasheet_manage/customSheetEdit.vue
  89. 1 1
      src/views/datasheet_manage/mixedSheetEdit.vue
  90. 38 2
      src/views/datasheet_manage/mixins/classifyMixin.js
  91. 76 139
      src/views/datasheet_manage/sheetList.vue
  92. 9 2
      src/views/mychart_manage/components/chartDetailDia.vue
  93. 80 0
      src/views/mychart_manage/components/classifyDeleteCheck.vue
  94. 57 9
      src/views/mychart_manage/index.vue
  95. 20 0
      src/views/positionAnalysis_manage/components/chartDetail.vue
  96. 19 17
      src/views/positionAnalysis_manage/components/indexContent.vue
  97. 141 23
      src/views/positionAnalysis_manage/detail.vue
  98. 15 0
      src/views/positionAnalysis_manage/list.vue
  99. 3 2
      src/views/ppt_manage/mixins/mixins.js
  100. 2 2
      src/views/ppt_manage/newVersion/pptEnCatalog.vue

+ 2 - 1
config/dev.env.js

@@ -13,5 +13,6 @@ module.exports = merge(prodEnv, {
   VUE_APP_FINANCIAL_MANAGEMENT_SYSTEM:'"http://8.136.199.33:8618/login"',
   VUE_APP_FINANCIAL_MANAGEMENT_SYSTEM:'"http://8.136.199.33:8618/login"',
   VUE_APP_CRM_SYSTEM:'"http://8.136.199.33:7777/temppage"',
   VUE_APP_CRM_SYSTEM:'"http://8.136.199.33:7777/temppage"',
   VUE_APP_ETA_DOCS:'"http://8.136.199.33:8622/update/index"',
   VUE_APP_ETA_DOCS:'"http://8.136.199.33:8622/update/index"',
-	VUE_APP_ETA_HELP_DOCS:'"http://8.136.199.33:8622/help/index"'
+	VUE_APP_ETA_HELP_DOCS:'"http://8.136.199.33:8622/help/index"',
+    VUE_APP_ETA_VIDEO:'"http://8.136.199.33:8622/video/list"',
 });
 });

+ 2 - 1
config/prod.env.js

@@ -10,6 +10,7 @@ module.exports = {
 	VUE_APP_FINANCIAL_MANAGEMENT_SYSTEM:'"https://fms.hzinsights.com/login"',
 	VUE_APP_FINANCIAL_MANAGEMENT_SYSTEM:'"https://fms.hzinsights.com/login"',
 	VUE_APP_CRM_SYSTEM:'"https://admin.hzinsights.com/temppage"',
 	VUE_APP_CRM_SYSTEM:'"https://admin.hzinsights.com/temppage"',
 	VUE_APP_ETA_DOCS:'"https://etadocs.hzinsights.com/update/index"',
 	VUE_APP_ETA_DOCS:'"https://etadocs.hzinsights.com/update/index"',
-	VUE_APP_ETA_HELP_DOCS:'"https://etadocs.hzinsights.com/help/index"'
+	VUE_APP_ETA_HELP_DOCS:'"https://etadocs.hzinsights.com/help/index"',
+	VUE_APP_ETA_VIDEO:'"https://etadocs.hzinsights.com/video/list"',
 		
 		
 }
 }

+ 2 - 1
config/prod.test.env.js

@@ -10,5 +10,6 @@ module.exports = {
   VUE_APP_FINANCIAL_MANAGEMENT_SYSTEM:'"http://8.136.199.33:8618/login"',
   VUE_APP_FINANCIAL_MANAGEMENT_SYSTEM:'"http://8.136.199.33:8618/login"',
 	VUE_APP_CRM_SYSTEM:'"http://8.136.199.33:7777/temppage"',
 	VUE_APP_CRM_SYSTEM:'"http://8.136.199.33:7777/temppage"',
 	VUE_APP_ETA_DOCS:'"http://8.136.199.33:8622/update/index"',
 	VUE_APP_ETA_DOCS:'"http://8.136.199.33:8622/update/index"',
-	VUE_APP_ETA_HELP_DOCS:'"http://8.136.199.33:8622/help/index"'
+	VUE_APP_ETA_HELP_DOCS:'"http://8.136.199.33:8622/help/index"',
+	VUE_APP_ETA_VIDEO:'"http://8.136.199.33:8622/video/list"',
 }
 }

+ 12 - 0
index.html

@@ -36,6 +36,17 @@
         input[type="password"]::-o-reveal{
         input[type="password"]::-o-reveal{
             display: none;
             display: none;
         }
         }
+    </style>
+    <!-- 字蛛压缩字体 -->
+    <style>
+        @font-face {
+            font-family: '思源黑体';
+            src: url(./static/css/fonts/SourceHanSansSC-Regular.ttf);
+        }
+        @font-face {
+            font-family: '思源宋体';
+            src: url(./static/css/fonts/SourceHanSerifCN-Regular.ttf);
+        }
     </style>
     </style>
 	<script>
 	<script>
 		var _hmt = _hmt || [];
 		var _hmt = _hmt || [];
@@ -64,6 +75,7 @@
 	<script type="text/javascript" src="./static/js/jquery.min.js"></script>
 	<script type="text/javascript" src="./static/js/jquery.min.js"></script>
 	<script src="https://hzstatic.hzinsights.com/static/cdn/Luckysheet@2.1.13/dist/plugins/js/plugin.js"></script>
 	<script src="https://hzstatic.hzinsights.com/static/cdn/Luckysheet@2.1.13/dist/plugins/js/plugin.js"></script>
 	<script src="https://hzstatic.hzinsights.com/static/cdn/Luckysheet@2.1.13/dist/luckysheet.umd.js"></script>
 	<script src="https://hzstatic.hzinsights.com/static/cdn/Luckysheet@2.1.13/dist/luckysheet.umd.js"></script>
+	<script src="https://hzstatic.hzinsights.com/static/cdn/luckyexcel.umd.js"></script>
 	<script type="text/javascript" src="./static/js/jquery.dataTables.js"></script>
 	<script type="text/javascript" src="./static/js/jquery.dataTables.js"></script>
 </body>
 </body>
 </html>
 </html>

+ 2 - 1
src/api/api.js

@@ -1,5 +1,5 @@
 // eta图表 我的图库 数据指标库
 // eta图表 我的图库 数据指标库
-import { dataBaseInterface, mychartInterface } from './modules/chartApi';
+import { dataBaseInterface, mychartInterface,chartFrameInterface } from './modules/chartApi';
 
 
 //接入的第三方的数据库
 //接入的第三方的数据库
 import {
 import {
@@ -75,6 +75,7 @@ import {reportVarietyENInterence} from './modules/reportVariety'
 export {
 export {
   dataBaseInterface,
   dataBaseInterface,
   mychartInterface,
   mychartInterface,
+  chartFrameInterface,
   lzDataInterface,
   lzDataInterface,
   glDataInterface,
   glDataInterface,
   smmDataInterface,
   smmDataInterface,

+ 1 - 0
src/api/http.js

@@ -52,6 +52,7 @@ function checkStatus(response) {
       bus.$message.error(res.Msg);
       bus.$message.error(res.Msg);
     } else if (res.Ret === 408) {
     } else if (res.Ret === 408) {
       localStorage.setItem("auth", "")
       localStorage.setItem("auth", "")
+      localStorage.setItem("loginTime", "")
       bus
       bus
         .$alert(res.Msg, "提示", {
         .$alert(res.Msg, "提示", {
           showClose: false,
           showClose: false,

+ 112 - 1
src/api/modules/chartApi.js

@@ -2,6 +2,19 @@ import http from "@/api/http.js"
 
 
 /* 数据库管理模块  */
 /* 数据库管理模块  */
 const dataBaseInterface = {
 const dataBaseInterface = {
+	/**
+	 * 指标库目录
+	 */
+	targetCatalog:params=>{
+		return http.get('/datamanage/classify/simple',params)
+	},
+	/**
+	 * 指标和目录拖动排序
+	 */
+	classifyMoveSort:params=>{
+		return http.post('/datamanage/edb_classify/move',params)
+	},
+
 	/**
 	/**
 	 * 新增分类
 	 * 新增分类
 	 * @param {ClassifyName} params 
 	 * @param {ClassifyName} params 
@@ -58,7 +71,8 @@ const dataBaseInterface = {
 		return http.get('/datamanage/classify/items/v2',params)
 		return http.get('/datamanage/classify/items/v2',params)
 	},
 	},
 	menuListV3: params => {
 	menuListV3: params => {
-		return http.get('/datamanage/classify/items/v3',params)
+		// return http.get('/datamanage/classify/items/v3',params)
+		return http.get('/datamanage/classify/tree',params)
 	},
 	},
 	/**
 	/**
 	 * 通过分类查找指标列表数据
 	 * 通过分类查找指标列表数据
@@ -929,6 +943,13 @@ const mychartInterface = {
 	addClassify: params => {
 	addClassify: params => {
 		return http.post('/my_chart/classify/add',params)
 		return http.post('/my_chart/classify/add',params)
 	},
 	},
+	/**
+	 * 获取图表关联的节点列表
+	 * @param {MyChartClassifyId} params 
+	 */
+	getFrameNode:params =>{
+		return http.get('/my_chart/classify/framework_node_list',params)
+	},
 	/**
 	/**
 	 * 删除分类
 	 * 删除分类
 	 * @param {MyChartClassifyId} params 
 	 * @param {MyChartClassifyId} params 
@@ -1092,8 +1113,98 @@ const mychartInterface = {
 		return http.get('/my_chart/search_by_es',params)
 		return http.get('/my_chart/search_by_es',params)
 	}
 	}
 }
 }
+/* 图库框架 */
+const chartFrameInterface = {
+    /**
+     * 添加框架
+     * @param {Object} params 
+     * @param {String} params.FrameworkName 框架名称
+     * @param {String} params.FrameworkImg 框架图片地址
+     * @param {String} params.FrameworkContent 框架内容
+     * @param {Array} params.Nodes 框架所包含的节点数组
+     * @param {String} Nodes.NodeName 节点名称
+     * @param {Number} Nodes.MyChartClassifyId 节点对应图库分类id
+     * @returns 
+     */
+    addFrame: params => {
+        return http.post('/chart_framework/add',params)
+    },
+    /**
+     * 编辑框架
+     * @param {Object} params 
+     * @param {Number} params.ChartFrameworkId 框架id
+     * 其他参数同上
+     * @returns 
+     */
+    editFrame: params => {
+        return http.post('/chart_framework/edit',params)
+    },
+    getFrameDetail:params=>{
+        return http.get('/chart_framework/detail',params)
+    },
+    /**
+     * 重命名框架
+     * @param {Object} params 
+     * @param {Number} params.ChartFrameworkId
+     * @param {String} params.FrameworkName
+     * @returns 
+     */
+    reNameFrame: params => {
+        return http.post('/chart_framework/rename',params)
+    },
+    /**
+     * 删除框架
+     * @param {Object} params 
+     * @param {Number} params.ChartFrameworkId
+     * @returns 
+     */
+    deleteFrame: params => {
+        return http.post('/chart_framework/remove',params)
+    },
+    /**
+     * 公开/隐藏框架
+     * @param {Object} params 
+     * @param {Number} params.ChartFrameworkId
+     * @param {Number} params.IsPublic 0隐藏 1公开
+     * @returns 
+     */
+    changePublicFrame: params => {
+        return http.post('/chart_framework/edit_public',params)
+    },
+    /**
+     * 框架移动排序
+     * @param {Object} params 
+     * @param {Number} params.ChartFrameworkId
+     * @param {Number} params.PrevChartFrameworkId
+     * @param {Number} params.NextChartFrameworkId
+     * @returns 
+     */
+    moveFrame: params => {
+        return http.post('/chart_framework/move',params)
+    },
+    /**
+     * 获取公开框架目录
+     * @returns 
+     */
+    getPublicFrameList:params=>{
+        return http.get('/chart_framework/public_menu',params)
+    },
+    /**
+     * 获取我的框架列表
+     * @param {Object} params 
+     * @param {Number} params.AdminId
+     * @param {String} params.Keyword 筛选关键词
+     * @param {Number} params.Visibility 0所有用户 1自己用户
+     * @returns 
+     */
+    getMyFrameList:params=>{
+        return http.get('/chart_framework/list',params)
+    },
+
+}
 
 
 export {
 export {
 	dataBaseInterface,
 	dataBaseInterface,
 	mychartInterface,
 	mychartInterface,
+	chartFrameInterface
 }
 }

+ 9 - 0
src/api/modules/futuresBaseApi.js

@@ -306,5 +306,14 @@ export default {
   profitChartEdit: params => {
   profitChartEdit: params => {
     return http.post('/future_good/chart_info/profit/edit',params)
     return http.post('/future_good/chart_info/profit/edit',params)
   },
   },
+
+  /**
+   * 获取图表基本信息 价格曲线遍历指标找数据太慢 这个用来获取基本信息不包含数据
+   * @param {*} params 
+   * @returns 
+  */
+  getChartBasicInfo: params => {
+    return http.get('/future_good/chart_info/base_detail/from_unique_code',params)
+  }
   
   
 }
 }

+ 11 - 1
src/api/modules/predictEdbApi.js

@@ -12,8 +12,18 @@ export const classifyList = params => {
  * @returns 
  * @returns 
  */
  */
 export const classifyListV2 = params => {
 export const classifyListV2 = params => {
-    return http.get('/datamanage/predict_classify/list/v2',params)
+    return http.get('/datamanage/predict_classify/tree',params)
 }
 }
+//分类数据
+export const predictEdbCatalog=params=>{
+	return http.get('/datamanage/predict_classify/simple',params)
+}
+//目录指标移动
+export const classifyMoveSort=params=>{
+	return http.post('/datamanage/predict_classify/move',params)
+}
+
+
 /**
 /**
  * 分类的图表列表 IsOnlyMe ClassifyId
  * 分类的图表列表 IsOnlyMe ClassifyId
  * @param {*} params 
  * @param {*} params 

+ 97 - 0
src/api/modules/sheetApi.js

@@ -254,4 +254,101 @@ export const insertData = params => {
  */
  */
 export const getDateLatelyData = params => {
 export const getDateLatelyData = params => {
 	return http.get('/datamanage/edb_info/date_data/before_after',params)
 	return http.get('/datamanage/edb_info/date_data/before_after',params)
+}
+
+
+/* =====自定义分析==== */
+
+export const sheetAnalysisInterface = {
+
+	/**
+	 * 移动表格
+	 * @param {*} params ExcelClassifyId ExcelInfoId PrevExcelInfoId NextExcelInfoId
+	 * @returns 
+	 */
+	sheetMove: params => {
+		return http.post('/datamanage/excel_info/move',params)
+	},
+	
+	/**
+	 * 新增表格
+	 * @param {*} params ExcelName ExcelClassifyId ExcelImage Content
+	 * @returns 
+	 */
+	excelSheetAdd: params => {
+		return http.post('/custom_analysis/add',params)
+	},
+
+	/**
+	 * 获取详情
+	 * @param {*} params UniqueCode
+	 * @returns 
+	 */
+	getExcelDetail: params => {
+		return http.get('/custom_analysis/excel/base',params)
+	},
+
+	/**
+	 * 分页加载celldata
+	 * @param {*} params  UniqueCode Page
+	 * @returns 
+	 */
+	getExcelDataByPage: params => {
+		return http.get('/custom_analysis/excel/data',params)
+	},
+
+	/**
+	 * 表格保存
+	 * @param {*} params ExcelName ExcelInfoId ExcelClassifyId ExcelImage Content
+	 */
+	sheetEdit: params => {
+		return http.post('/custom_analysis/save',params)
+	},
+
+	/**
+	 * 生成指标
+	 * @param {*} params  
+	 * EdbName ExcelInfoId ClassifyId Frequency Unit DateSequenceVal DataSequenceVal DateSequenceStr DataSequenceStr
+	 * @returns 
+	 */
+	edbAddBysheet: params => {
+		return http.post('/custom_analysis/edb/add',params)
+	},
+
+	/**
+	 * 指标编辑
+	 * @param {*} params 
+	 * EdbName ExcelInfoId EdbInfoId ClassifyId Frequency Unit DateSequenceVal DataSequenceVal
+	 * @returns 
+	 */
+	edbEditBysheet: params => {
+		return http.post('/custom_analysis/edb/edit',params)
+	},
+
+	/**
+	 * 获取表格生成的指标列表
+	 * @param {*} params ExcelInfoId
+	 * @returns 
+	 */
+	edbListBySheet: params => {
+		return http.get('/custom_analysis/edb/list',params)
+	},
+
+	/**
+	 * 刷新
+	 * @param {*} params ExcelInfoId
+	 * @returns 
+	 */
+	sheetRefresh: params => {
+		return http.get('/custom_analysis/edb/refresh',params)
+	},
+
+	/**
+	 * 检查是否有同名表格
+	 * @param {*} params  ExcelName
+	 * @returns 
+	 */
+	checkSheetRepeat: params => {
+		return http.get('/custom_analysis/excel_by_name',params)
+	}
 }
 }

+ 14 - 0
src/api/modules/toolBoxApi.js

@@ -0,0 +1,14 @@
+import http from "@/api/http.js"
+
+//工具箱
+export const ToolBoxInterface = {
+    /**
+     * 获取联储观察的数据
+     * @param {Object} params 
+     * @param {String} DateTime //时间 yyyy-MM-dd
+     * @returns 
+     */
+    getSheetDetail:(params)=>{
+        return http.get('/meeting_probabilities/detail',params)
+    }
+}

+ 3 - 0
src/assets/icons/chartFrame/arrow-left.svg

@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M3.91423 8.49963L7.56053 12.1459L6.85342 12.853L2.21213 8.21174C2.09497 8.09458 2.09497 7.90463 2.21213 7.78748L6.85342 3.14619L7.56053 3.8533L3.91419 7.49963L13.9999 7.4998L13.9999 8.4998L3.91423 8.49963Z" fill="#C8CDD9" stroke="#C8CDD9" stroke-width="0.5"/>
+</svg>

+ 3 - 0
src/assets/icons/chartFrame/arrow-right.svg

@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M12.0857 7.50013L8.43938 3.85384L9.14649 3.14673L13.7878 7.78802C13.9049 7.90517 13.9049 8.09512 13.7878 8.21228L9.14649 12.8536L8.43938 12.1465L12.0857 8.50013L2 8.49996L2.00002 7.49996L12.0857 7.50013Z" fill="#C8CDD9" stroke="#C8CDD9" stroke-width="0.5"/>
+</svg>

+ 11 - 0
src/assets/icons/chartFrame/fillColor.svg

@@ -0,0 +1,11 @@
+<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_1428_2103)">
+<path d="M6.30152 0.666687L5.35886 1.60935L6.77286 3.02335L1.58752 8.20935C1.46254 8.33437 1.39233 8.50391 1.39233 8.68069C1.39233 8.85746 1.46254 9.027 1.58752 9.15202L7.24419 14.8087C7.36921 14.9337 7.53875 15.0039 7.71552 15.0039C7.8923 15.0039 8.06184 14.9337 8.18686 14.8087L13.8442 9.15202C13.9692 9.027 14.0394 8.85746 14.0394 8.68069C14.0394 8.50391 13.9692 8.33437 13.8442 8.20935L6.30152 0.666687ZM3.00152 8.68002L7.71552 3.96669L12.4295 8.68002L7.71619 13.3947L3.00152 8.68069V8.68002Z" fill="#C8CDD9"/>
+<path d="M14.392 10.6667L15.5707 11.8454C15.8037 12.0785 15.9624 12.3754 16.0267 12.6987C16.091 13.022 16.0579 13.3571 15.9318 13.6616C15.8056 13.9661 15.592 14.2264 15.3179 14.4095C15.0438 14.5926 14.7216 14.6904 14.392 14.6904C14.0624 14.6904 13.7402 14.5926 13.4661 14.4095C13.192 14.2264 12.9784 13.9661 12.8523 13.6616C12.7261 13.3571 12.6931 13.022 12.7573 12.6987C12.8216 12.3754 12.9803 12.0785 13.2133 11.8454L14.392 10.6667Z" fill="#C8CDD9"/>
+</g>
+<defs>
+<clipPath id="clip0_1428_2103">
+<rect width="16" height="16" fill="white" transform="translate(0.39209)"/>
+</clipPath>
+</defs>
+</svg>

+ 17 - 0
src/assets/icons/chartFrame/fontColor.svg

@@ -0,0 +1,17 @@
+<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_1428_2042)">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M3.39209 14.9999H13.3921V13.2599H3.39209V14.9999Z" fill="#C8CDD9"/>
+<g clip-path="url(#clip1_1428_2042)">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M9.44209 2H7.29209L3.39209 11H5.29209L6.29209 8.45H10.3821L11.3721 11H13.3421L9.44209 2Z" fill="#C8CDD9"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M9.93218 7.31999L9.47218 6.12C9.09218 5.14 8.73218 4.14 8.37218 3.12H8.30218C7.95218 4.15 7.58218 5.14 7.20218 6.12L6.73218 7.31999H9.93218Z" fill="white"/>
+</g>
+</g>
+<defs>
+<clipPath id="clip0_1428_2042">
+<rect width="10" height="13" fill="white" transform="translate(3.39209 2)"/>
+</clipPath>
+<clipPath id="clip1_1428_2042">
+<rect width="9.952" height="9" fill="white" transform="translate(3.39209 2)"/>
+</clipPath>
+</defs>
+</svg>

+ 12 - 0
src/assets/icons/chartFrame/fontStyle.svg

@@ -0,0 +1,12 @@
+<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_1428_2031)">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M3.39209 3C3.39209 2.44772 3.83981 2 4.39209 2H10.3921C10.9444 2 11.3921 2.44772 11.3921 3C11.3921 3.55228 10.9444 4 10.3921 4H4.39209C3.83981 4 3.39209 3.55228 3.39209 3Z" fill="#C8CDD9"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7.89209 12.5L8.89209 3H6.89209L5.89209 12.5H7.89209Z" fill="#C8CDD9"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M3.39209 13C3.39209 12.4477 3.83981 12 4.39209 12H10.3921C10.9444 12 11.3921 12.4477 11.3921 13C11.3921 13.5523 10.9444 14 10.3921 14H4.39209C3.83981 14 3.39209 13.5523 3.39209 13Z" fill="#C8CDD9"/>
+</g>
+<defs>
+<clipPath id="clip0_1428_2031">
+<rect width="8" height="12" fill="white" transform="translate(3.39209 2)"/>
+</clipPath>
+</defs>
+</svg>

+ 11 - 0
src/assets/icons/chartFrame/fontText.svg

@@ -0,0 +1,11 @@
+<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_1428_2000)">
+<path d="M4.39209 1V6C4.39209 7.06 4.81209 8.08 5.56209 8.83C6.31209 9.58 7.33209 10 8.39209 10C9.45209 10 10.4721 9.58 11.2221 8.83C11.9721 8.08 12.3921 7.06 12.3921 6V1" stroke="#C8CDD9" stroke-width="2" stroke-linejoin="round"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M3.39209 14C3.39209 13.4477 3.83981 13 4.39209 13H12.3921C12.9444 13 13.3921 13.4477 13.3921 14C13.3921 14.5523 12.9444 15 12.3921 15H4.39209C3.83981 15 3.39209 14.5523 3.39209 14Z" fill="#C8CDD9"/>
+</g>
+<defs>
+<clipPath id="clip0_1428_2000">
+<rect width="10" height="14" fill="white" transform="translate(3.39209 1)"/>
+</clipPath>
+</defs>
+</svg>

+ 12 - 0
src/assets/icons/chartFrame/fontWeight.svg

@@ -0,0 +1,12 @@
+<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_1428_2021)">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M4.39209 13.79H8.33209C10.9521 13.79 12.8421 12.67 12.8421 10.34C12.8421 8.74 11.8621 7.81 10.5221 7.54V7.46C11.5921 7.1 12.2021 6.03 12.2021 4.9C12.2021 2.78 10.4521 2 8.05209 2H4.39209V13.79Z" fill="#C8CDD9"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7.8822 3.46002H6.2522V6.93002H7.8322C9.6222 6.93002 10.3722 6.26002 10.3722 5.15002C10.3722 3.94002 9.5422 3.46002 7.8822 3.46002Z" fill="white"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M6.2522 8.34003V12.34H8.1222C9.9622 12.34 11.0122 11.68 11.0122 10.24C11.0122 8.93003 9.9922 8.34003 8.1222 8.34003H6.2522Z" fill="white"/>
+</g>
+<defs>
+<clipPath id="clip0_1428_2021">
+<rect width="8.448" height="11.792" fill="white" transform="translate(4.39209 2)"/>
+</clipPath>
+</defs>
+</svg>

+ 8 - 0
src/assets/icons/chartFrame/redo.svg

@@ -0,0 +1,8 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<mask id="mask0_1428_2007" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="16" height="16">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M0 0H16V16H0V0Z" fill="white"/>
+</mask>
+<g mask="url(#mask0_1428_2007)">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M14.841 7.96784C15.051 7.74784 15.031 7.40784 14.801 7.20784L9.37097 2.54784C9.27097 2.45784 9.13097 2.40784 8.99097 2.40784C8.68097 2.40784 8.42097 2.64784 8.42097 2.94784V6.04784C6.08097 6.13784 4.13097 6.35784 2.82097 7.59784C0.880971 9.44784 1.01097 11.7778 1.01097 12.3678C1.01097 12.6778 1.01097 13.2378 1.01097 13.5878H1.17097C1.41097 13.5878 1.63097 13.4478 1.71097 13.2378C2.46097 11.2878 3.53097 10.1078 4.92097 9.69784C5.88097 9.40784 6.94097 9.31784 8.42097 9.27784V12.3578C8.42097 12.4878 8.47097 12.6278 8.57097 12.7278C8.79097 12.9378 9.15097 12.9578 9.38097 12.7578L14.811 7.99784C14.821 7.98784 14.831 7.97784 14.841 7.96784Z" fill="#C8CDD9"/>
+</g>
+</svg>

+ 5 - 0
src/assets/icons/chartFrame/stokeColor.svg

@@ -0,0 +1,5 @@
+<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M9.21239 3.66195L9.7372 2.79734L12.0681 5.10705L11.5442 5.97156L9.21239 3.66195Z" fill="#C8CDD9"/>
+<path d="M10.9596 2.5202L4.98385 8.49595L4.47785 10.5227L6.50405 10.0162L12.4798 4.0404L10.9596 2.5202ZM14 4.0404L7.0535 10.9869L3 12L4.01365 7.9465L10.9596 1L14 4.0404Z" fill="#C8CDD9"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M3 15H14V13H3V15Z" fill="#C8CDD9"/>
+</svg>

+ 5 - 0
src/assets/icons/chartFrame/stokeStyle.svg

@@ -0,0 +1,5 @@
+<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<line x1="2.39209" y1="3" x2="14.3921" y2="3" stroke="#C8CDD9" stroke-width="2"/>
+<line x1="2.39209" y1="8" x2="14.3921" y2="8" stroke="#C8CDD9" stroke-width="2" stroke-dasharray="2 2"/>
+<line x1="2.39209" y1="13" x2="14.3921" y2="13" stroke="#C8CDD9" stroke-width="2" stroke-dasharray="1 1"/>
+</svg>

+ 5 - 0
src/assets/icons/chartFrame/textAlign.svg

@@ -0,0 +1,5 @@
+<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M14.3921 2H2.39209V4H14.3921V2Z" fill="#C8CDD9"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M9.39209 7H2.39209V9H9.39209V7Z" fill="#C8CDD9"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M14.3921 12H2.39209V14H14.3921V12Z" fill="#C8CDD9"/>
+</svg>

+ 8 - 0
src/assets/icons/chartFrame/undo.svg

@@ -0,0 +1,8 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<mask id="mask0_1428_2013" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="16" height="16">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M0 0H16V16H0V0Z" fill="white"/>
+</mask>
+<g mask="url(#mask0_1428_2013)">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M6.62965 2.54784L1.19965 7.20784C0.959647 7.40784 0.949647 7.74784 1.15965 7.96784C1.16965 7.97784 1.17965 7.98784 1.18965 7.99784L6.61965 12.7578C6.84965 12.9578 7.20965 12.9378 7.42965 12.7278C7.52965 12.6278 7.57965 12.4878 7.57965 12.3578V9.27784C9.05965 9.31784 10.1196 9.40784 11.0796 9.69784C12.4696 10.1078 13.5296 11.2878 14.2896 13.2378C14.3696 13.4478 14.5796 13.5878 14.8296 13.5878H14.9896C14.9896 13.2378 14.9896 12.6778 14.9896 12.3678C14.9896 11.7778 15.1196 9.44784 13.1796 7.59784C11.8696 6.35784 9.91965 6.13784 7.57965 6.04784V2.94784C7.57965 2.64784 7.31965 2.40784 7.00965 2.40784C6.86965 2.40784 6.72965 2.45784 6.62965 2.54784Z" fill="#C8CDD9"/>
+</g>
+</svg>

BIN
src/assets/img/chart_m/check.png


BIN
src/assets/img/home/loading.gif


BIN
src/assets/img/icons/jump_ico.png


BIN
src/assets/img/icons/tooltip.png


+ 1 - 0
src/components/pwdDlg.vue

@@ -117,6 +117,7 @@ export default {
                 localStorage.setItem('AdminName',"");
                 localStorage.setItem('AdminName',"");
                 localStorage.setItem("RoleIdentity", "");
                 localStorage.setItem("RoleIdentity", "");
                 localStorage.setItem("ManageType", "");
                 localStorage.setItem("ManageType", "");
+                localStorage.setItem("loginTime", "");
                 this.$router.push({ path: "/login" });
                 this.$router.push({ path: "/login" });
               }, 1000);
               }, 1000);
             }
             }

+ 2 - 1
src/mixins/theme.js

@@ -30,5 +30,6 @@ export default {
   login_logo: require('@/assets/img/login_logo.png'),
   login_logo: require('@/assets/img/login_logo.png'),
   g_logo: require('@/assets/img/home/logo.png'),
   g_logo: require('@/assets/img/home/logo.png'),
   g_mini_logo: require('@/assets/img/home/eta_mini.png'),
   g_mini_logo: require('@/assets/img/home/eta_mini.png'),
-  dynamicOutLinks:{}//动态的外部link链接
+  dynamicOutLinks:{},//动态的外部link链接
+  bus_code:'',
 }
 }

+ 94 - 7
src/routes/modules/chartRoutes.js

@@ -65,12 +65,31 @@ export default [
 		name: 'My ETA',
 		name: 'My ETA',
 		hidden: false,
 		hidden: false,
 		icon_path: require('@/assets/img/home/data_ic.png'),
 		icon_path: require('@/assets/img/home/data_ic.png'),
-		children: [{
+		children: [
+			{
 				path: 'mychart',
 				path: 'mychart',
 				name: 'My ETA',
 				name: 'My ETA',
 				component: () => import('@/views/mychart_manage/index.vue'),
 				component: () => import('@/views/mychart_manage/index.vue'),
 				hidden: false,
 				hidden: false,
-			}
+			},
+			{
+				path: 'chartframe',
+				name: '图库框架',
+				component: () => import('@/views/chartFrame_manage/index.vue'),
+				hidden: false,
+			},
+			{
+				path: 'addframe',
+				name: '添加框架',
+				component: () => import('@/views/chartFrame_manage/frameEditor.vue'),
+				hidden: false,
+			},
+			{
+				path: 'editframe',
+				name: '编辑框架',
+				component: () => import('@/views/chartFrame_manage/frameEditor.vue'),
+				hidden: false,
+			},
 		]
 		]
 	},
 	},
 
 
@@ -83,7 +102,17 @@ export default [
 		children:[
 		children:[
 			{
 			{
 				path:"sheetList",
 				path:"sheetList",
-				name:"ETA表格",
+				name:"在线Excel",
+				component:()=>import('@/views/datasheet_manage/sheetList.vue')
+			},
+			{
+				path:"sheetTimeList",
+				name:"时间序列表格",
+				component:()=>import('@/views/datasheet_manage/sheetList.vue')
+			},
+			{
+				path:"sheetMixedList",
+				name:"混合表格",
 				component:()=>import('@/views/datasheet_manage/sheetList.vue')
 				component:()=>import('@/views/datasheet_manage/sheetList.vue')
 			},
 			},
 			{
 			{
@@ -93,14 +122,29 @@ export default [
 			},
 			},
 			{
 			{
 				path:"addCustomSheet",
 				path:"addCustomSheet",
-				name:"添加表格",
+				name:"添加数据表格",
 				component:()=>import('@/views/datasheet_manage/customSheetEdit.vue')
 				component:()=>import('@/views/datasheet_manage/customSheetEdit.vue')
 			},
 			},
 			{
 			{
 				path:"addMixedSheet",
 				path:"addMixedSheet",
-				name:"添加表格",
+				name:"添加混合表格",
 				component:()=>import('@/views/datasheet_manage/mixedSheetEdit.vue')
 				component:()=>import('@/views/datasheet_manage/mixedSheetEdit.vue')
-			}
+			},
+			{
+				path:"sheetAnalysisList",
+				name:"自定义分析",
+				component:()=>import('@/views/datasheet_manage/customAnalysis/list.vue')
+			},
+			{
+				path:"addAnalysisSheet",
+				name:"上传文件",
+				component:()=>import('@/views/datasheet_manage/customAnalysis/addAnalysisSheet.vue')
+			},
+			{
+				path:"createTaregtBySheet",
+				name:"生成指标",
+				component:()=>import('@/views/datasheet_manage/customAnalysis/addAnalysisSheet.vue')
+			},
 		]
 		]
 	},
 	},
 
 
@@ -215,7 +259,7 @@ export default [
 	},
 	},
 
 
 	/* 持仓分析 */
 	/* 持仓分析 */
-	{
+	/* {
 		path:'/',
 		path:'/',
 		component: home,
 		component: home,
 		name: '持仓分析',
 		name: '持仓分析',
@@ -232,5 +276,48 @@ export default [
 				component:()=>import('@/views/positionAnalysis_manage/detail.vue'),
 				component:()=>import('@/views/positionAnalysis_manage/detail.vue'),
 			}
 			}
 		]
 		]
+	}, */
+	/* 工具箱 */
+	//ETA1.1.3:将持仓分析,商品价格曲线合并至工具箱
+	{
+		path:'/',
+		component:home,
+		name:'工具箱',
+		hidden:false,
+		children:[
+			/* {
+				path: 'positionAnalysisList',
+				name: '持仓列表',
+				component:()=>import('@/views/positionAnalysis_manage/list.vue')
+			}, */
+			{//不要列表页了,但是改path需要动ETA菜单很麻烦,先这样
+				path: 'positionAnalysisList',
+				name: '持仓详情',
+				component:()=>import('@/views/positionAnalysis_manage/detail.vue')
+			},
+			{
+				path: 'positionAnalysisDetail',
+				name: '持仓详情',
+				component:()=>import('@/views/positionAnalysis_manage/detail.vue'),
+			},
+			{
+				path:'federalReserveWatch',
+				name:'联储观察',
+				component:()=>import('@/views/toolBox_manage/FederalReserveWatch.vue')
+			},{
+				path: "commordityChartBase",
+				name: "商品价格曲线",
+				component: () => import('@/views/futures_manage/commodityChartBase.vue')
+			},
+			{
+				path: "addCommodityChart",
+				name: "编辑图表",
+				component: () => import('@/views/futures_manage/chartEditor.vue'),
+				meta: { 
+					pathFrom: "commordityChartBase",
+					pathName: "商品价格曲线",
+				}
+			},
+		]
 	}
 	}
 ]
 ]

+ 38 - 49
src/utils/TimeOnPage.js

@@ -11,16 +11,13 @@ let stayTime = 0
 let intervalTimer=null
 let intervalTimer=null
 
 
 export const openLoginTimer=()=>{
 export const openLoginTimer=()=>{
-  // 登录时间
-  localStorage.setItem("loginTime",new Date())
 
 
   clearInterval(intervalTimer)
   clearInterval(intervalTimer)
   intervalTimer = setInterval(()=>{
   intervalTimer = setInterval(()=>{
-    // let inactiveTime = time || new Date()
     let ActiveTime=0
     let ActiveTime=0
     if(localStorage.getItem('loginTime')){
     if(localStorage.getItem('loginTime')){
       ActiveTime = (new Date()-new Date(localStorage.getItem('loginTime')))/1000
       ActiveTime = (new Date()-new Date(localStorage.getItem('loginTime')))/1000
-      console.log("1分钟间隔记录时长",ActiveTime+'s');
+      console.log("间隔记录时长",ActiveTime+'s');
       recordActiveLogin({ActiveTime:Math.round(ActiveTime)}).then(res=>{
       recordActiveLogin({ActiveTime:Math.round(ActiveTime)}).then(res=>{
         if(res.Ret!==200) return
         if(res.Ret!==200) return
       })
       })
@@ -39,7 +36,7 @@ export const recordActiveLoginFun=(time)=>{
     }).finally(()=>{
     }).finally(()=>{
       // 清除工作
       // 清除工作
       clearInterval(intervalTimer)
       clearInterval(intervalTimer)
-      localStorage.removeItem('loginTime')
+      // localStorage.removeItem('loginTime')
     })
     })
   }
   }
 }
 }
@@ -49,6 +46,7 @@ let timer = null
 //打开计时器
 //打开计时器
 export const optionTimeCalc = ()=>{
 export const optionTimeCalc = ()=>{
   const IsActive = sessionStorage.getItem('IsActive')
   const IsActive = sessionStorage.getItem('IsActive')
+  // console.log(IsActive,'IsActive');
   if(Number(IsActive)===0){
   if(Number(IsActive)===0){
     //console.log('打开计时器')
     //console.log('打开计时器')
     sessionStorage.setItem('IsActive',1)
     sessionStorage.setItem('IsActive',1)
@@ -62,7 +60,6 @@ export const startCalc = ()=>{
   sessionStorage.setItem('preTitle',document.title)
   sessionStorage.setItem('preTitle',document.title)
   timer = setInterval(()=>{
   timer = setInterval(()=>{
     stayTime++
     stayTime++
-    
     if(stayTime>=TimeInterval){
     if(stayTime>=TimeInterval){
       endCalc('timeup',0)
       endCalc('timeup',0)
     }
     }
@@ -137,24 +134,25 @@ let rewriteHis = function(type){
 }
 }
 
 
 export function init(){
 export function init(){
-  const unloadT = sessionStorage.getItem('unloadT')
-  const IsActive = sessionStorage.getItem('IsActive')
-  if(unloadT){
-    //console.log('刷新该页呆了时长',unloadT)
-    sessionStorage.removeItem('unloadT')
-    sessionStorage.setItem('preTitle',document.title)
-    if(Number(IsActive)){
-      endCalc('unload',unloadT)
-    }
-  }
-  timeStr = new Date().getTime()
+  // const unloadT = sessionStorage.getItem('unloadT')
+  // console.log("init",unloadT,IsActive);
+  // if(unloadT){
+  //   //console.log('刷新该页呆了时长',unloadT)
+  //   sessionStorage.removeItem('unloadT')
+  //   sessionStorage.setItem('preTitle',document.title)
+  //   if(Number(IsActive)){
+  //     endCalc('unload',unloadT)
+  //   }
+  // }
+  // timeStr = new Date().getTime()
+  sessionStorage.setItem('IsActive',0)
   optionTimeCalc()
   optionTimeCalc()
+  // const IsActive = sessionStorage.getItem('IsActive')
 
 
-  if((!localStorage.getItem("loginTime")) && localStorage.getItem('auth')){
-    // 初始化的时候 先重置最近登录时长
-    recordActiveLogin({ActiveTime:0}).then(res=>{
-      if(res.Ret!==200) return
-    })
+  // if(Number(IsActive)){
+  //   sessionStorage.setItem('unloadT',t)
+  // }
+  if(localStorage.getItem("loginTime") && localStorage.getItem('auth')){
     openLoginTimer()
     openLoginTimer()
   }
   }
 }
 }
@@ -195,10 +193,23 @@ export const doPageEventListener=function(){
   window.addEventListener('beforeunload',(e)=>{
   window.addEventListener('beforeunload',(e)=>{
     console.log('beforeunload')
     console.log('beforeunload')
     let t = new Date().getTime() - timeStr
     let t = new Date().getTime() - timeStr
+    // const unloadT = sessionStorage.getItem('unloadT')
     const IsActive = sessionStorage.getItem('IsActive')
     const IsActive = sessionStorage.getItem('IsActive')
-    if(Number(IsActive)){
-      sessionStorage.setItem('unloadT',t)
-    }
+    console.log("init",IsActive);
+    // if(unloadT){
+      //console.log('刷新该页呆了时长',unloadT)
+      // sessionStorage.removeItem('unloadT')
+      // sessionStorage.setItem('preTitle',document.title)
+      if(Number(IsActive)){
+        endCalc('unload',t)
+      }
+    // }
+    // timeStr = new Date().getTime()
+    // optionTimeCalc()
+    // const IsActive = sessionStorage.getItem('IsActive')
+    // if(Number(IsActive)){
+      // sessionStorage.setItem('unloadT',t)
+    // }
   })
   })
 
 
   //刷新离开页面
   //刷新离开页面
@@ -207,7 +218,7 @@ export const doPageEventListener=function(){
     recordActiveLoginFun()
     recordActiveLoginFun()
     // 猜测在unload这里 浏览器不会等待异步返回 清除工作在这进行
     // 猜测在unload这里 浏览器不会等待异步返回 清除工作在这进行
     clearInterval(intervalTimer)
     clearInterval(intervalTimer)
-    localStorage.removeItem('loginTime')
+    // localStorage.removeItem('loginTime')
   })
   })
 
 
   //popstate会在router.before/afterEach 之前触发,所以这里不对计时操作,操作放到before/afterEach
   //popstate会在router.before/afterEach 之前触发,所以这里不对计时操作,操作放到before/afterEach
@@ -242,29 +253,6 @@ export const doPageEventListener=function(){
     optionTimeCalc()
     optionTimeCalc()
   })
   })
   
   
-  //页面监听
-  /* document.addEventListener('visibilitychange', function () {
-    // 用户离开了当前页面
-    if (document.visibilityState === 'hidden') {
-      console.log('hidden')
-      const IsActive = sessionStorage.getItem('IsActive')
-      if(Number(IsActive)){
-        let t = new Date().getTime() - timeStr
-        timeStr = new Date().getTime()
-        endCalc('hidden',t)
-      }
-    }
-  
-    // 用户打开或回到页面
-    if (document.visibilityState === 'visible') {
-      console.log('visible')
-      const IsActive = sessionStorage.getItem('IsActive')
-      if(IsActive==='0'){
-        timeStr = new Date().getTime()
-        optionTimeCalc()
-      }
-    }
-  }); */
   document.addEventListener('click',(e)=>{
   document.addEventListener('click',(e)=>{
 
 
     //console.log('click',e,e.composedPath())
     //console.log('click',e,e.composedPath())
@@ -274,6 +262,7 @@ export const doPageEventListener=function(){
     if(contentIndex===-1) return 
     if(contentIndex===-1) return 
     //console.log('合法的click')
     //console.log('合法的click')
     const IsActive = sessionStorage.getItem('IsActive')
     const IsActive = sessionStorage.getItem('IsActive')
+    console.log(IsActive,'IsActive');
     if(Number(IsActive)===0){
     if(Number(IsActive)===0){
       optionTimeCalc()
       optionTimeCalc()
     }else{
     }else{

+ 45 - 11
src/utils/buttonConfig.js

@@ -72,11 +72,11 @@ export const classifyBtn={
     classifyList_cnClassify_childMenu:'classifyList:cnClassify:childMenu',//表单项:子目录
     classifyList_cnClassify_childMenu:'classifyList:cnClassify:childMenu',//表单项:子目录
 }
 }
 /*
 /*
-*--------英文分类----------- 
+*--------英文分类-----------   ETA_1.1.7 不区分英文研报和线上路演 统一使用英文研报的标识
 */
 */
 export const enClassifyBtn = {
 export const enClassifyBtn = {
     classifyList_enClassify:'classifyList:enClassify',//英文分类这个选项卡是否展示
     classifyList_enClassify:'classifyList:enClassify',//英文分类这个选项卡是否展示
-    /* -------------线上路演------------- */
+    /* -------------线上路演------------- */ 
     classifyList_enClassify_roadshow:'classifyList:enClassify:roadshow',//线上路演这个选项卡是否展示
     classifyList_enClassify_roadshow:'classifyList:enClassify:roadshow',//线上路演这个选项卡是否展示
     classifyList_enClassify_rsDel:'classifyList:enClassify:rsDel',//线上路演一二级分类删除
     classifyList_enClassify_rsDel:'classifyList:enClassify:rsDel',//线上路演一二级分类删除
     classifyList_enClassify_rsAuthSetting:'classifyList:enClassify:rsAuthSetting',//线上路演二级分类权限设置
     classifyList_enClassify_rsAuthSetting:'classifyList:enClassify:rsAuthSetting',//线上路演二级分类权限设置
@@ -245,6 +245,7 @@ export const edbDataPermission = {
     edbData_switchEn:'edbData:switchEn',//切换英文版
     edbData_switchEn:'edbData:switchEn',//切换英文版
     edbData_classifyOpt_add:'edbData:classifyOpt:add',//添加/编辑分类
     edbData_classifyOpt_add:'edbData:classifyOpt:add',//添加/编辑分类
     edbData_classifyOpt_delete:'edbData:classifyOpt:delete',//删除分类
     edbData_classifyOpt_delete:'edbData:classifyOpt:delete',//删除分类
+    edbData_classifyOpt_move:'edbData:classifyOpt:move',//移动分类
     edbData_checkRelatedChart:'edbData:checkRelatedChart',//查看关联图表
     edbData_checkRelatedChart:'edbData:checkRelatedChart',//查看关联图表
     edbData_checkRelatedEdb:'edbData:checkRelatedEdb',//查看关联指标
     edbData_checkRelatedEdb:'edbData:checkRelatedEdb',//查看关联指标
     edbData_checkCalcChart:'edbData:checkCalcChart',//查看计算指标
     edbData_checkCalcChart:'edbData:checkCalcChart',//查看计算指标
@@ -272,6 +273,7 @@ export const predictEdbPermission = {
     edbPreData_isOnlyMine:'edbPreData:isOnlyMine',//只看我的
     edbPreData_isOnlyMine:'edbPreData:isOnlyMine',//只看我的
     edbPreData_classifyOpt_add:'edbPreData:classifyOpt:add',//添加/编辑分类
     edbPreData_classifyOpt_add:'edbPreData:classifyOpt:add',//添加/编辑分类
     edbPreData_classifyOpt_delete:'edbPreData:classifyOpt:delete',//删除分类
     edbPreData_classifyOpt_delete:'edbPreData:classifyOpt:delete',//删除分类
+    edbPreData_classifyOpt_move:'edbPreData:classifyOpt:move',//移动分类
     edbPreData_checkRelatedChart:'edbPreData:checkRelatedChart',//查看关联图表
     edbPreData_checkRelatedChart:'edbPreData:checkRelatedChart',//查看关联图表
     edbPreData_checkRelatedEdb:'edbPreData:checkRelatedEdb',//查看关联指标
     edbPreData_checkRelatedEdb:'edbPreData:checkRelatedEdb',//查看关联指标
     edbPreData_checkPreRule:'edbPreData:checkPreRule',//查看预测规则
     edbPreData_checkPreRule:'edbPreData:checkPreRule',//查看预测规则
@@ -330,15 +332,23 @@ export const myETAPermission = {
     myChart_classifyOpt_rename:'myChart:classifyOpt:rename',//重命名
     myChart_classifyOpt_rename:'myChart:classifyOpt:rename',//重命名
     myChart_classifyOpt_delete:'myChart:classifyOpt:delete',//删除
     myChart_classifyOpt_delete:'myChart:classifyOpt:delete',//删除
 }
 }
+//图库框架
+export const chartFramePermission={
+    chartframe_public_copyImg:'chartframe:public:copyImg',//公共框架-复制图片
+    chartframe_my_editNode:'chartframe:my:editNode',//我的框架-添加/编辑节点
+    chartframe_my_saveFrame:'chartframe:my:saveFrame',//我的框架-保存框架
+    chartframe_my_editFrame:'chartframe:my:editFrame',//我的框架-添加/编辑框架
+    chartframe_my_delFrame:'chartframe:my:delFrame',//我的框架-删除框架
+    chartframe_my_show:'chartframe:my:show',//我的框架-设置可见权限
+    chartframe_my_rename:'chartframe:my:rename',//我的框架-重命名
+    chartframe_my_copyImg:'chartframe:my:copyImg',//我的框架-复制图片
+    chartframe_my_move:'chartframe:my:move',//我的框架-移动排序
+}
 /*
 /*
  * --------------------------------------------------------------------------ETA表格------------------------------------------------
  * --------------------------------------------------------------------------ETA表格------------------------------------------------
 */
 */
 export const etaTablePermission = {
 export const etaTablePermission = {
     /*-----------页面按钮--------- */
     /*-----------页面按钮--------- */
-    etaTable_customize:'etaTable:customize',//自定义表格这个按钮显示不显示
-    etaTable_excel:'etaTable:excel',//添加Excel表格这个按钮显示不显示
-    etaTable_classifyOpt_edit:'etaTable:classifyOpt:edit',//添加编辑表格
-    etaTable_classifyOpt_delete:'etaTable:classifyOpt:delete',//删除表格
 
 
     /*-----------自定义表格--------- */
     /*-----------自定义表格--------- */
     /* etaTable_customize_del:'etaTable:customize:del',
     /* etaTable_customize_del:'etaTable:customize:del',
@@ -346,22 +356,46 @@ export const etaTablePermission = {
     etaTable_customize_otherSave:'etaTable:customize:otherSave',
     etaTable_customize_otherSave:'etaTable:customize:otherSave',
     etaTable_customize_refresh:'etaTable:customize:refresh',
     etaTable_customize_refresh:'etaTable:customize:refresh',
     etaTable_customize_edit:'etaTable:customize:edit', */
     etaTable_customize_edit:'etaTable:customize:edit', */
-    //混合表格
+
+    //混合表格页面
+    etaTable_customize_mix_sheetAdd: 'etaTable:customize:mix:sheetAdd',//添加混合表格按钮
+    etaTable_customize_mix_classifyOpt_edit: 'etaTable:customize:mix:classifyOpt:edit',//混合表格分类操作
+    etaTable_customize_mix_classifyOpt_delete: 'etaTable:customize:mix:classifyOpt:delete',//混合表格分类删除
     etaTable_customize_mix_edit:'etaTable:customize:mix:edit',//编辑
     etaTable_customize_mix_edit:'etaTable:customize:mix:edit',//编辑
     etaTable_customize_mix_refresh:'etaTable:customize:mix:refresh',//刷新
     etaTable_customize_mix_refresh:'etaTable:customize:mix:refresh',//刷新
     etaTable_customize_mix_otherSave:'etaTable:customize:mix:otherSave',//另存为
     etaTable_customize_mix_otherSave:'etaTable:customize:mix:otherSave',//另存为
     etaTable_customize_mix_download:'etaTable:customize:mix:download',//下载
     etaTable_customize_mix_download:'etaTable:customize:mix:download',//下载
     etaTable_customize_mix_del:'etaTable:customize:mix:del',//删除
     etaTable_customize_mix_del:'etaTable:customize:mix:del',//删除
-    //数据表格
+
+    //数据表格页面
+    etaTable_customize_data_sheetAdd: 'etaTable:customize:data:sheetAdd',//添加数据表格按钮
+    etaTable_customize_data_classifyOpt_edit: 'etaTable:customize:data:classifyOpt:edit',//数据表格分类操作
+    etaTable_customize_data_classifyOpt_delete: 'etaTable:customize:data:classifyOpt:delete',//数据表格分类删除
     etaTable_customize_data_edit:'etaTable:customize:data:edit',//编辑
     etaTable_customize_data_edit:'etaTable:customize:data:edit',//编辑
     etaTable_customize_data_refresh:'etaTable:customize:data:refresh',//刷新
     etaTable_customize_data_refresh:'etaTable:customize:data:refresh',//刷新
     etaTable_customize_data_otherSave:'etaTable:customize:data:otherSave',//另存为
     etaTable_customize_data_otherSave:'etaTable:customize:data:otherSave',//另存为
     etaTable_customize_data_download:'etaTable:customize:data:download',//下载
     etaTable_customize_data_download:'etaTable:customize:data:download',//下载
     etaTable_customize_data_del:'etaTable:customize:data:del',//删除
     etaTable_customize_data_del:'etaTable:customize:data:del',//删除
-    /*-----------常规表格--------- */
+
+    /*-----------excel表格页面--------- */
+    etaTable_excel:'etaTable:excel',//添加Excel表格这个按钮显示不显示
+    etaTable_excel_classifyOpt_edit:'etaTable:excel:classifyOpt:edit',//添加编辑表格
+    etaTable_excel_classifyOpt_delete:'etaTable:excel:classifyOpt:delete',//删除表格
     etaTable_excel_del:'etaTable:excel:del',
     etaTable_excel_del:'etaTable:excel:del',
     etaTable_excel_download:'etaTable:excel:download',
     etaTable_excel_download:'etaTable:excel:download',
-    etaTable_excel_save:'etaTable:excel:save'
+    etaTable_excel_save:'etaTable:excel:save',
+
+    //自定义分析表格页面
+    // etaTable_analysis_sheetAdd: 'etaTable:analysis:sheetAdd',//添加数据表格按钮
+    etaTable_analysis_classifyOpt_edit: 'etaTable:analysis:classifyOpt:edit',//数据表格分类操作
+    etaTable_analysis_classifyOpt_delete: 'etaTable:analysis:classifyOpt:delete',//数据表格分类删除
+    etaTable_analysis_upload:'etaTable:analysis:upload',//上传文件
+    etaTable_analysis_createedb:'etaTable:analysis:createedb',//生成指标
+    etaTable_analysis_refresh:'etaTable:analysis:refresh',//刷新
+    etaTable_analysis_otherSave:'etaTable:analysis:otherSave',//另存为
+    etaTable_analysis_download:'etaTable:analysis:download',//下载
+    etaTable_analysis_del:'etaTable:analysis:del',//删除
+    etaTable_analysis_save:'etaTable:analysis:save',//保存
 }
 }
 /*
 /*
  * --------------------------------------------------------------------------ETA逻辑------------------------------------------------
  * --------------------------------------------------------------------------ETA逻辑------------------------------------------------
@@ -565,7 +599,7 @@ const btnMap  = {
     pptPermission,enPPTPermission,
     pptPermission,enPPTPermission,
     dataSourcePermission,
     dataSourcePermission,
     edbDataPermission,predictEdbPermission,chartLibPermission,
     edbDataPermission,predictEdbPermission,chartLibPermission,
-    myETAPermission,etaTablePermission,
+    myETAPermission,chartFramePermission,etaTablePermission,
     sandboxPermission,semanticPermission,
     sandboxPermission,semanticPermission,
     statisticPermission,stockPlantPermission,
     statisticPermission,stockPlantPermission,
     productPricePermission,sysDepartPermission,
     productPricePermission,sysDepartPermission,

+ 6 - 2
src/utils/commonOptions.js

@@ -22,7 +22,7 @@ export function checkPassWord(pwd){
 //验证手机号的正则 仅支持国内大陆的
 //验证手机号的正则 仅支持国内大陆的
 export const patternPhone = /0?(13|14|15|18|17)[0-9]{9}/
 export const patternPhone = /0?(13|14|15|18|17)[0-9]{9}/
 export function isMobileNo(account) {
 export function isMobileNo(account) {
-    // 手机号正则
+    /* // 手机号正则
     var isChinaMobile = new RegExp(
     var isChinaMobile = new RegExp(
       "(^1(3[4-9]|4[78]|5[0-27-9]|7[28]|8[2-478]|98)\\d{8}$)"
       "(^1(3[4-9]|4[78]|5[0-27-9]|7[28]|8[2-478]|98)\\d{8}$)"
     ); // 中国移动
     ); // 中国移动
@@ -41,7 +41,11 @@ export function isMobileNo(account) {
       return true;
       return true;
     } else if (isChinaTelcom.test(account)) {
     } else if (isChinaTelcom.test(account)) {
       return true;
       return true;
-    } else return isOtherTelphone.test(account);
+    } else return isOtherTelphone.test(account); */
+    
+    //改成和后端一样的正则
+    const phonePatter = new RegExp("(^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0-9])|(17[0-9])|(16[0-9])|(19[0-9]))\\d{8}$)")
+    return phonePatter.test(account)
   }
   }
 //验证邮箱的正则
 //验证邮箱的正则
 export const patternEmail = /\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}/
 export const patternEmail = /\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}/

+ 2 - 0
src/utils/icon.js

@@ -65,4 +65,6 @@ export default {
 	no_view: require('@/assets/img/icons/no_view.png'),
 	no_view: require('@/assets/img/icons/no_view.png'),
 	/* 中英文切换 */
 	/* 中英文切换 */
 	to_en: require('@/assets/img/icons/toEn.png'),
 	to_en: require('@/assets/img/icons/toEn.png'),
+	/* 跳转icon */
+	jupm_icon: require('@/assets/img/icons/jump_ico.png')
 }
 }

+ 3 - 3
src/utils/svgToblob.js

@@ -1,10 +1,10 @@
 /* 针对系统中众多svg的图表/沙盘想要复制粘到微信中 */		
 /* 针对系统中众多svg的图表/沙盘想要复制粘到微信中 */		
   import bus from '@/api/bus.js';
   import bus from '@/api/bus.js';
 
 
-  export const copyBlob = (url,callback=null,ratio=1) => {
+  export const copyBlob = (url,callback=null,ratio=1,urlType='svg') => {
     const copyImg = new Image()
     const copyImg = new Image()
     copyImg.crossOrigin = 'anonymous';
     copyImg.crossOrigin = 'anonymous';
-    copyImg.src = svgToBase64(url);
+    copyImg.src = urlType==='svg'?svgToBase64(url):url;
 
 
     copyImg.onload = ()=> {
     copyImg.onload = ()=> {
       const canvas = document.createElement('canvas');
       const canvas = document.createElement('canvas');
@@ -30,7 +30,7 @@
           );
           );
         })
         })
       }else {
       }else {
-        bus.$message.warning('浏览器暂不支持')
+        bus.$message.warning('当前协议暂不支持,仅支持https协议')
       }
       }
     }	
     }	
  
  

+ 3 - 1
src/views/Home.vue

@@ -286,7 +286,7 @@
               :style="!isHaveAside ? 'padding: 0 30px 0 0;' : ''"
               :style="!isHaveAside ? 'padding: 0 30px 0 0;' : ''"
             >
             >
               <transition name="fade" mode="out-in">
               <transition name="fade" mode="out-in">
-                <router-view></router-view>
+                <router-view :key="$route.fullPath"></router-view>
               </transition>
               </transition>
             </el-col>
             </el-col>
           </el-row>
           </el-row>
@@ -497,6 +497,7 @@ export default {
       getBusinessCode().then(res=>{
       getBusinessCode().then(res=>{
         if(res.Ret!==200) return 
         if(res.Ret!==200) return 
         this.bus_code = res.Data||''
         this.bus_code = res.Data||''
+        this.$setting.bus_code = this.bus_code
       })
       })
     },
     },
     //判断是否为初始密码
     //判断是否为初始密码
@@ -798,6 +799,7 @@ export default {
             localStorage.setItem("AdminName", "");
             localStorage.setItem("AdminName", "");
             localStorage.setItem("ManageType", "");
             localStorage.setItem("ManageType", "");
             localStorage.setItem("RoleIdentity", "");
             localStorage.setItem("RoleIdentity", "");
+            localStorage.setItem("loginTime", "");
 
 
             that.$router.push("/login");
             that.$router.push("/login");
           }, 10);
           }, 10);

+ 5 - 0
src/views/Login.vue

@@ -443,6 +443,11 @@ export default {
             localStorage.setItem("ManageType", res.Data.Authority);
             localStorage.setItem("ManageType", res.Data.Authority);
             localStorage.setItem("AdminId", res.Data.AdminId);
             localStorage.setItem("AdminId", res.Data.AdminId);
             localStorage.setItem("AdminName", res.Data.AdminName);
             localStorage.setItem("AdminName", res.Data.AdminName);
+            localStorage.setItem("loginTime",new Date())
+            // 清除最近登录时长
+            recordActiveLogin({ActiveTime:0}).then(res=>{
+                if(res.Ret!==200) return
+            })
         },
         },
         //根据角色判断应该进入系统的哪个页面,进入系统
         //根据角色判断应该进入系统的哪个页面,进入系统
         async loginSys(res){
         async loginSys(res){

+ 140 - 0
src/views/chartFrame_manage/common/config.js

@@ -0,0 +1,140 @@
+/* ports 样式 */
+const portStyle = {
+    attrs: {
+        circle: {
+            r: 5,
+            magnet: true,
+            stroke: '#333',
+            strokeWidth: 1,
+            fill: '#fff'
+        }
+    }
+    }
+//基础节点
+export const baseNode = {
+    shape:'rect',
+    width: 120,
+    height: 50,
+    attrs:{
+        text:{ //文字换行
+            textWrap: {
+                width: -10,
+                ellipsis: true,
+            }
+        },
+        body:{
+            fill:'#ECF2FE',//背景色
+            stroke:'#0052D9',//边框色
+            strokeWidth:1,//边框宽度
+            strokeDasharray:'',//虚线,如果赋值为0保存缩略图时会省略掉边框
+        },
+        label:{ //与svg text属性相同
+            fill:'#0052D9',//文字颜色
+            fontSize:14,//文字大小
+            fontWeight:'normal',//文字粗细
+            fontStyle:'normal',//斜体
+            textDecoration:'normal',//下划线
+        }
+    },
+    ports: { //基础连接桩
+        items: [
+            { group: 'port-top', id: 'p_top' },
+            { group: 'port-bottom', id: 'p_bottom' },
+            { group: 'port-left', id: 'p_left' },
+            { group: 'port-right', id: 'p_right' },
+        ],
+        groups: {
+            "port-top": {
+                    position: 'top',
+                    zIndex: 20,
+                    ...portStyle
+            },
+            "port-bottom": {
+                    position: 'bottom',
+                    zIndex: 20,
+                    ...portStyle
+            },
+            "port-left": {
+                    position: 'left',
+                    zIndex: 20,
+                    ...portStyle
+            },
+            "port-right": {
+                    position: 'right',
+                    zIndex: 20,
+                    ...portStyle
+            },
+        }
+    },
+}
+//基础线条
+export const baseEdge = {
+    attrs:{
+        line:{
+            stroke:'#333',//线条颜色
+            strokeWidth:2,//线条宽
+            strokeDasharray:0,//虚线
+        }
+    }
+}
+
+//字号
+export const sizeOptions = [
+    30,
+    28,
+    26,
+    24,
+    22,
+    20,
+    18,
+    16,
+    14,
+    12,
+    10,
+]
+//线框宽度
+export const stokeWidthOptions = [1,2,3,4,5]
+//行高
+export const lineHeightOptions = [ //倍数 设置的值为 value*fontSize
+    {
+        label:'默认',
+        value:''
+    },
+    {
+        label:'1',
+        value:1,
+    },
+    {
+        label:'1.5',
+        value:1.5
+    },
+    {
+        label:'2',
+        value:2
+    }]
+//对齐方式
+export const textAnchorOptions = [
+    {
+        label:'居左',
+        options:{
+            refX:0,
+            refY:0.5,
+            textAnchor:'start',
+        }
+    },
+    {
+        label:'居中',
+        options:{
+            refX:0.5,
+            refY:0.5,
+            textAnchor:'middle',
+        }
+    },
+    {
+        label:'居右',
+        options:{
+            refX:0.99,
+            refY:0.5,
+            textAnchor:'end',
+        }
+    }]

+ 115 - 0
src/views/chartFrame_manage/common/event.js

@@ -0,0 +1,115 @@
+import { baseNode } from './config';
+//监听画布事件 tempThis是一个vue实例
+export const myEvents = (graph,tempThis=null)=>{
+    //右键节点/边
+    graph.on('cell:contextmenu',({cell,e})=>{
+        if(window.location.pathname.startsWith('/chartframe')) return 
+        graph.select(cell)
+        const dom = $('#context-menu-wrapper')[0];
+        dom.style.left = e.clientX-3 + 'px';
+        dom.style.top = e.clientY-3 + 'px';
+    })
+
+    graph.on('node:click',({node,e})=>{
+        if(!window.location.pathname.startsWith('/chartframe')) return 
+        console.log('node.data',node.data)
+        if(node.data&&node.data.id){
+            tempThis&&tempThis.$emit('showDialog',node.data)
+        }
+    })
+
+    /* 鼠标移入移出控制连接桩 */
+    graph.on('node:mouseenter', ({ node, e }) => {
+        if(window.location.pathname.startsWith('/chartframe')) return 
+        for(let i of document.querySelectorAll(`g[data-cell-id="${node.id}"] .x6-port-body`)) {
+            i.style.display = 'block'
+        }
+    })
+
+    graph.on('node:mouseleave', ({ node, e }) => {
+        if(window.location.pathname.startsWith('/chartframe')) return 
+        for(let i of document.querySelectorAll(`g[data-cell-id="${node.id}"] .x6-port-body`)) {
+            i.style.display = 'none'
+        }
+    })
+
+    /* 鼠标移入移出边 */
+    graph.on('edge:mouseenter', ({ edge }) => {
+        edge.addTools([
+          'source-arrowhead',
+          'target-arrowhead',
+          {
+            name: 'button-remove',
+            args: {
+              distance: -30,
+            },
+          },
+        ])
+      })
+      
+    graph.on('edge:mouseleave', ({ edge }) => {
+        edge.removeTools()
+    })
+
+    /* 元素选中事件 */
+    graph.on('cell:selected',({cell})=>{
+        const selects = graph.getSelectedCells()
+        if(cell.isNode()){
+            tempThis.isSelectEdge = false
+            tempThis.isSelectNode = true
+        }else if(cell.isEdge()){
+            tempThis.isSelectNode = false
+            tempThis.isSelectEdge = true
+        }
+        tempThis.cleanSelect = false
+        selects&&selects.length&&(tempThis.currentCell = selects[0])
+    })
+    /* 点击空白区域清空选区 屏蔽工具栏 */
+    graph.on('blank:click',() => {
+        graph.cleanSelection();
+        tempThis.isSelectEdge = false
+        tempThis.isSelectNode = false
+        tempThis.cleanSelect = true
+        tempThis.currentCell = baseNode
+    })
+
+    /* 历史记录改变 */
+    graph.history.on('change',()=>{
+        tempThis.canRedo = graph.history.canRedo()
+        tempThis.canUndo = graph.history.canUndo()
+    })
+
+}
+//监听键盘绑定事件
+export const bindKey = (graph,tempThis=null)=>{
+    //delete 删除选中元素
+    graph.bindKey(['delete'],()=>{
+        const selectCells = graph.getSelectedCells()
+        if(selectCells.length){
+            // 移除工具
+            selectCells.forEach(item => item.removeTools());
+            graph.removeCells(selectCells)
+            //重置工具栏
+            tempThis.isSelectEdge = false
+            tempThis.isSelectNode = false
+            tempThis.cleanSelect = true
+            tempThis.currentCell = baseNode
+        }
+    },'keydown')
+    //ctrl+c复制选择元素
+    graph.bindKey('ctrl+c',()=>{
+        const selectCells = graph.getSelectedCells()
+        if(selectCells.length){
+            graph.copy(selectCells)
+        }
+    })
+    //ctrl+v粘贴元素
+    graph.bindKey('ctrl+v', () => {
+        if (!graph.isClipboardEmpty()) {
+            const selectCell = graph.paste({ offset: 30 })
+            graph.cleanSelection()
+            graph.select(selectCell)
+        }
+        return false
+    });
+}

+ 135 - 0
src/views/chartFrame_manage/common/graph.js

@@ -0,0 +1,135 @@
+import {
+    Graph,Shape
+} from '@antv/x6';
+import { myEvents,bindKey } from './event';
+//非编辑页的配置
+const viewConfig = {
+    resizing:false,//不允许节点缩放
+    translating:{
+        restrict:true,//节点移动时无法超出画布
+    },
+    interacting:function (cellView){ //禁止节点移动
+        /* if(cellView.cell.getData().disableMove){
+            return false
+        } */
+        return false
+    },
+    highlighting:{},
+    /* connecting:{}, */
+    history:false,//关闭画布撤销/重做能力。
+    keyboard:false,
+    clipboard: false,
+}
+export function myGraph(wrapper,tempThis) {
+    const otherConfig = window.location.pathname.startsWith('/chartframe')?viewConfig:{}
+    const graph = new Graph({...{
+        container: document.getElementById(wrapper),
+        background: {
+            color: '#fff',
+        },
+        history:true,
+        keyboard:{
+            enabled:true,
+            global:true
+        },
+        clipboard: true,
+        selecting:{
+            enabled: true,
+            showNodeSelectionBox: false,
+            multiple: false
+        },
+        snapline: true,
+        scroller: {
+            enabled: true,
+            pannable: true,
+            minVisibleWidth: 50,
+            minVisibleHeight: 50,
+        },
+        //节点是否允许缩放
+        resizing: {
+            enabled: true,
+            orthogonal: false,
+        },
+        scaling: {
+            min: 0.5,
+            max: 2
+        },
+        mousewheel:{
+            enabled: true,
+            modifiers:['ctrl','meta']
+        },
+        highlighting: {
+            //当链接桩可以被链接时,在链接桩外围渲染一个 2px 宽的红色矩形框
+            magnetAvailable: {
+                name: "stroke",
+                args: {
+                    padding: 0.8,
+                    attrs: {
+                            "stroke-width": 2,
+                            stroke: "skyblue",
+                    },
+                },
+            },
+            //连线过程中,自动吸附到链接桩时被使用
+            magnetAdsorbed: {
+                name: "stroke",
+                args: {
+                    padding: 0.8,
+                    attrs: {
+                            "stroke-width": 4,
+                            stroke: "skyblue",
+                    },
+                },
+            },
+        },
+        connecting: {
+            snap: true,
+            highlight: true,
+            allowLoop:false,
+            allowNode:false,
+            connector: {
+                name: 'normal',
+                args: {
+                    padding:1
+                }
+            },
+            connectionPoint: 'anchor',
+            router:{
+                name:'manhattan',
+                args:{
+                }
+            },
+            /*
+            router: {
+                name: 'er',
+                args: {
+                    direction: 'V',
+                },
+            },
+             */
+            // 定义边样式
+            createEdge() {
+                return new Shape.Edge({
+                    attrs: {
+                        line: {
+                            stroke: '#0052D9',
+                            strokeWidth: 1,
+                            strokeDasharray: "",//虚线间隔
+                            sourceMarker: false,//起始箭头 
+                            targetMarker: 'classic',//终止箭头
+                        },
+                    },
+                    zIndex: 0,
+                })
+            },
+        },//连线
+        minimap: {
+            enabled: true,
+            container: document.getElementById("frameMinimap"),
+        }
+    },...otherConfig})
+    myEvents(graph,tempThis)
+
+    bindKey(graph,tempThis)
+    return graph
+}

+ 267 - 0
src/views/chartFrame_manage/components/frameContainer.vue

@@ -0,0 +1,267 @@
+<template>
+    <!-- 沙盘图区域 -->
+    <div class="frame-container-wrap">
+        <!-- 工具栏 -->
+        <FrameToolBar v-if="$route.path!=='/chartframe'&&graph"
+            :is-select-edge="isSelectEdge"
+            :is-select-node="isSelectNode"
+            :canUndo="canUndo"
+            :canRedo="canRedo"
+            :graph="graph"
+            :current-cell="currentCell||baseNode"
+        ></FrameToolBar>
+        <div class="frame-container" id="frameContainer"></div>
+        <!-- 缩略图 -->
+        <div class="minimap" id="frameMinimap"></div>
+        <!-- 右键菜单 -->
+        <div id="context-menu-wrapper" @mouseleave="hideContextMenu">
+            <el-dropdown-menu size="medium">
+                <el-dropdown-item v-for="menu in contextMenu" :key="menu.key" @click.native="handleContext(menu.key)">
+                    <i :class="menu.icon" v-if="menu.icon"/> 
+                    {{menu.label}}
+                </el-dropdown-item>
+            </el-dropdown-menu>
+        </div>
+        <!-- 内容空提示 -->
+        <div class="empty" v-if="!FrameworkContent.length&&$route.path==='/chartframe'">
+            <tableNoData text="框架内无节点"/>
+        </div>
+    </div>
+</template>
+
+<script>
+import { ElDropdownMenu } from 'element-ui';
+import { myGraph } from '../common/graph';
+import { baseNode } from '../common/config';
+import FrameToolBar from './frameToolBar.vue';
+export default {
+    components:{ElDropdownMenu,FrameToolBar},
+    props:{
+        FrameworkContent:{ //框架内容
+            type:String,
+            default:''
+        }
+    },
+    data() {
+        this.baseNode = baseNode //默认节点样式
+        return {
+            graph:null,//画布对象
+            /* contextMenu:[{
+                label: '编辑',
+                key: 'edit',
+                icon: 'el-icon-edit'
+            },
+            {
+                label: '删除',
+                key: 'del',
+                icon: 'el-icon-delete'
+            }], *///右键菜单
+            isSelectEdge:false,//是否选择了边
+            isSelectNode:false,//是否选择了节点
+            currentCell:null,//当前选中的元素
+            canRedo:false,//是否能前进
+            canUndo:false,//是否能后退
+            cleanSelect:false,//是否清除选区
+        };
+    },
+    watch:{
+        cleanSelect(newVal){
+            if(newVal){
+                this.currentCell = null
+            }
+        },
+        FrameworkContent(newVal){//当框架内容发生改变时,画布内容也发生改变
+            newVal.length&&this.gragh&&this.graph.fromJSON(JSON.parse(newVal))
+        }
+    },
+    computed:{
+        contextMenu(){//右键菜单,根据权限配置
+            const editOption = {label: '编辑',key: 'edit',icon: 'el-icon-edit'}
+            const deleteOption = {label: '删除',key: 'del',icon: 'el-icon-delete'}
+            let MenuArr = []
+            if(this.permissionBtn.isShowBtn('chartFramePermission','chartframe_my_editNode')){
+                MenuArr.push(editOption)
+            }
+            MenuArr.push(deleteOption)
+            return MenuArr
+        }
+    },
+    methods: {
+        //初始化画布
+        init(){
+            //如果需要在内部调用vue实例,则初始化时就将this传入
+            this.graph = new myGraph('frameContainer',this)
+            //如果有内容,初始化画布内容
+            this.FrameworkContent.length&&this.graph.fromJSON(JSON.parse(this.FrameworkContent))
+            //如果有内容,将画布内容居中
+            this.FrameworkContent.length&&this.graph.scrollToContent({ animation: { duration: 600 }})
+            //如果是非编辑页,加载完成画布内容后冻结画布
+            window.location.pathname.startsWith('/chartframe')&&this.graph.freeze()
+            //如果是编辑页,加载完成后清除历史数据
+            !window.location.pathname.startsWith('/chartframe')&&this.graph.cleanHistory()
+        },
+        //销毁画布
+        dispose(){
+            this.graph&&this.graph.dispose()
+        },
+        //添加/编辑节点
+        editNode(node){
+            //获取视口范围
+            const position = this.graph.getContentArea()
+            const nodes = this.graph.getNodes()
+            const currentNode = nodes.find(item=>item.id===node.nodeId)
+            if(currentNode){
+                currentNode.data.id=node.nodeLink.MyChartClassifyId
+                currentNode.label=node.nodeName
+                currentNode.data.nodeLink = node.nodeLink
+            }else{
+                //在视口范围内添加节点
+                this.graph.addNode({
+                    ...baseNode,
+                    ...{
+                    x:position.x+position.width/2+20,
+                    y:position.y+position.height/2+20,
+                    width:120,
+                    height:50,
+                    data:{
+                        id:node.nodeLink.MyChartClassifyId,//存储节点对应的myETA分类id
+                        nodeLink:node.nodeLink
+                    },
+                    label:node.nodeName||''
+                }})
+            }
+        },
+        //点击右键菜单事件
+        handleContext(key){
+            const select_cell = this.graph.getSelectedCells()
+            if(!select_cell.length) return 
+
+            if(key==='edit'){
+                const {id} = select_cell[0]
+                const node = this.graph.getNodes().find(item=>item.id===id)
+                this.$emit('editNode',{
+                    nodeId:node.id,
+                    nodeName:node.label,
+                    nodeLink:node.data.nodeLink
+                })
+            }
+            if(key==='del'){
+                this.graph.removeCells(select_cell)
+                this.hideContextMenu()
+            }
+            //清除选区
+            this.graph.cleanSelection()
+        },
+        hideContextMenu(){
+            const dom = $('#context-menu-wrapper')[0];
+            dom.style.left = '-9999px';
+            dom.style.top = '-9999px';
+        },
+        //获取画布内容的svg数据
+        getContentPic(){
+            const { cells } = this.graph.toJSON();
+            let svgData = ''
+            this.graph.toSVG((dataUri) => {
+                svgData = dataUri 
+                
+            },{
+                preserveDimensions:true,//让svg为实际图片大小
+                beforeSerialize:(svg)=>{
+                    const {x,y,width,height} = this.graph.getContentBBox(cells)
+                    let {tx,ty} = this.graph.translate() // 画布偏移量
+                    //给导出的svg增加一点宽高
+                    svg.setAttribute('width',width+50)
+                    svg.setAttribute('height',height+50) 
+                    //设置viewBox使图像居中
+                    svg.setAttribute('viewBox',`${x-25} ${y-25} ${width+50} ${height+50}`)
+                },
+                copyStyles:false,
+                stylesheet: `
+                    svg{
+                        background-color:white;
+                    }
+                    .x6-port {
+                        visibility: hidden;
+                    }
+                    ` 
+            })
+            return svgData
+        },
+        //获取画布节点并转换成对应格式
+        getContentNodes(){
+            return this.graph.getNodes().map(node=>{
+                return {
+                    NodeName:node.label,
+                    MyChartClassifyId:Number(node.data.id)
+                }
+            })
+        }
+    },
+    mounted(){
+        //this.init()
+    }
+};
+</script>
+
+<style lang="scss">
+.frame-container-wrap {
+    width:100%;
+    height:100%;
+    display: flex;
+    overflow: hidden;
+    position: relative;
+    padding-top: 26px;
+    .minimap {
+        position: absolute;
+        right: 16px;
+        bottom: 16px;
+        box-sizing: border-box;
+
+        .x6-widget-minimap-viewport {
+            border-color: #0052D9;
+
+            .x6-widget-minimap-viewport-zoom {
+                border-color: #0052D9;
+            }
+        }
+
+        .x6-widget-minimap {
+            width: auto !important;
+            height: auto !important;
+            overflow: visible !important;
+            padding:0 !important;
+        }
+    }
+    #context-menu-wrapper{
+        position: fixed;
+        z-index: 99;
+        top: -9999px;
+        left: -9999px;
+        background: #fff;
+        padding: 10px 0;
+        box-shadow: 0 1px 4px #999;
+
+    }
+    #frameContainer{
+        flex: 1;
+    }
+    .x6-graph-scroller {
+        flex: 1;
+        width:auto !important;
+        height:auto !important;
+    }
+
+    .x6-port-body {
+        display: none;
+    }
+    .empty{
+        position:absolute;
+        left:50%;
+        top:0;
+        transform: translateX(-50%);
+    }
+}
+</style>
+<style scoped lang="scss">
+
+</style>

+ 402 - 0
src/views/chartFrame_manage/components/frameToolBar.vue

@@ -0,0 +1,402 @@
+<template>
+    <!-- 框架工具栏 -->
+    <div class="frame-tool-bar-wrap">
+        <div class="cell-style">
+            <!-- 撤销 -->
+            <ToolItem tooltip="撤销" toolkey="undo">
+                <div class="tool-item" @click="handleGraphHistory('undo')">
+                    <img :src="require(`@/assets/icons/chartFrame/undo.svg`)"
+                        :class="{'img-disabled':!canUndo,'actived':canUndo}">
+                    <span class="disabled" v-if="!canUndo"></span>
+                </div>
+                
+            </ToolItem>
+            <!-- 恢复 -->
+            <ToolItem tooltip="恢复" toolkey="undo">
+                <div class="tool-item" @click="handleGraphHistory('redo')">
+                    <img :src="require(`@/assets/icons/chartFrame/redo.svg`)"
+                        :class="{'img-disabled':!canRedo,'actived':canRedo}">
+                    <span class="disabled" v-if="!canRedo"></span>
+                </div>
+            </ToolItem>
+            <!-- 字体 暂定-->
+            <!-- 字号 -->
+            <ToolItem tooltip="字号" toolkey="fontSize">
+                <el-dropdown @command="changeStyle" trigger="click" class="tool-item">
+                    <span class="el-dropdown-link tool-item"> 
+                        <span>{{nodeStyle.fontSize}}px</span>
+                        <i class="el-icon-caret-bottom"></i>
+                    </span>
+                    <el-dropdown-menu slot="dropdown">
+                        <el-dropdown-item v-for="item in sizeOptions" 
+                            :key="item" :command="{attr:'label/fontSize',value:item}">{{item}}</el-dropdown-item>
+                    </el-dropdown-menu>
+                    <span class="disabled" v-if="!isSelectNode"></span>
+                </el-dropdown>
+            </ToolItem>
+            <!-- 加粗 -->
+            <ToolItem tooltip="加粗" toolkey="fontWeight">
+                <span class="tool-item">
+                    <span class="item-text" :class="{'text-disabled':!isSelectNode,'text-actived':isSelectNode}"
+                        :style="'font-size: 16px;font-weight: bold;'"
+                        @click="changeStyleToggle('label/fontWeight')">B</span>
+                    <span class="disabled" v-if="!isSelectNode"></span>
+                </span>
+            </ToolItem>
+            <!-- 斜体 -->
+            <ToolItem tooltip="斜体" toolkey="fontstyle">
+                <span class="tool-item">
+                    <span style="font-style: italic;" class="item-text"
+                        @click="changeStyleToggle('label/fontStyle')">
+                        <img :src="require(`@/assets/icons/chartFrame/fontStyle.svg`)"
+                            :class="{'img-disabled':!isSelectNode,'actived':isSelectNode}">
+                    </span>
+                    <span class="disabled" v-if="!isSelectNode"></span>
+                </span>
+            </ToolItem>
+            <!-- 下划线 -->
+            <ToolItem tooltip="下划线" toolkey="textDecoration">
+                <span class="tool-item">
+                    <span style="text-decoration: underline;" class="item-text"
+                        @click="changeStyleToggle('label/textDecoration')">
+                        <img :src="require(`@/assets/icons/chartFrame/fontText.svg`)"
+                            :class="{'img-disabled':!isSelectNode,'actived':isSelectNode}">
+                    </span>
+                    <span class="disabled" v-if="!isSelectNode"></span>
+                </span>
+            </ToolItem>
+            <!-- 字体颜色 -->
+            <ToolItem tooltip="字体颜色" toolkey="textDecoration">
+                <span class="tool-item">
+                    <label for="label/fill" :style="`color:${color}`">
+                        <img :src="require(`@/assets/icons/chartFrame/fontColor.svg`)"
+                            :class="{'img-disabled':!isSelectNode,'actived':isSelectNode}">
+                    </label>
+                    <input type="color" id="label/fill" style="width: 0;height: 0;visibility: hidden;" 
+                        :value="nodeStyle.color"
+                        @input="valueChange"/>
+                    <span class="disabled" v-if="!isSelectNode"></span>
+                </span>
+            </ToolItem>
+            <!-- 文本行高 暂定-->
+            <!-- 文本对齐 -->
+            <ToolItem tooltip="文本对齐" toolkey="textAligh">
+                <el-dropdown @command="changeTextStyle" trigger="click" class="tool-item">
+                    <span class="el-dropdown-link tool-item"> 
+                        <img :src="require(`@/assets/icons/chartFrame/textAlign.svg`)"
+                            :class="{'img-disabled':!isSelectNode,'actived':isSelectNode}">
+                        <i class="el-icon-caret-bottom"></i>
+                    </span>
+                    <el-dropdown-menu slot="dropdown">
+                        <el-dropdown-item v-for="item in textAnchorOptions" 
+                            :key="item.label" :command="{attr:'label/textAligh',value:item.options}">{{item.label}}</el-dropdown-item>
+                    </el-dropdown-menu>
+                    <span class="disabled" v-if="!isSelectNode"></span>
+                </el-dropdown>
+            </ToolItem>
+            <!-- 节点颜色填充 -->
+            <ToolItem tooltip="填充颜色" toolkey="fillColor">
+                <span class="tool-item">
+                    <label for="body/fill" :style="`color:${fillColor}`">
+                        <img :src="require(`@/assets/icons/chartFrame/fillColor.svg`)"
+                            :class="{'img-disabled':!isSelectNode,'actived':isSelectNode}">
+                    </label>
+                    <input type="color" id="body/fill" style="width: 0;height: 0;visibility: hidden;"
+                        :value="nodeStyle.fill"
+                        @input="valueChange"/>
+                    <span class="disabled" v-if="!isSelectNode"></span>
+                </span>
+            </ToolItem>
+            <!-- 节点/线条边框颜色 -->
+            <ToolItem tooltip="边框颜色" toolkey="borderColor">
+                <span class="tool-item">
+                    <label for="storke" :style="`color:${borderColor}`">
+                        <img :src="require(`@/assets/icons/chartFrame/stokeColor.svg`)"
+                            :class="{'img-disabled':!isSelectNode&&!isSelectEdge,'actived':isSelectNode||isSelectEdge}">
+                    </label>
+                    <input type="color" id="storke" style="width: 0;height: 0;visibility: hidden;" 
+                        :value="cellStyle.stroke"
+                        @input="valueChange"/>
+                    <span class="disabled" v-if="!isSelectNode&&!isSelectEdge"></span>
+                </span>
+            </ToolItem>
+            <!-- 节点/线条边框宽度 -->
+            <ToolItem tooltip="线框宽度" toolkey="stokeWidth">
+                <el-dropdown @command="changeCellStyle" trigger="click" class="tool-item">
+                    <span class="el-dropdown-link tool-item"> 
+                        <i class="el-icon-minus"></i>
+                        <i class="el-icon-caret-bottom"></i>
+                    </span>
+                    <el-dropdown-menu slot="dropdown">
+                        <el-dropdown-item v-for="item in stokeWidthOptions" 
+                            :key="item" :command="{attr:'width',value:item}">{{item}}</el-dropdown-item>
+                    </el-dropdown-menu>
+                    <span class="disabled" v-if="!isSelectNode&&!isSelectEdge"></span>
+                </el-dropdown>
+            </ToolItem>
+            <!-- 节点/线条边框样式 -->
+            <ToolItem tooltip="边框样式" toolkey="stokeWidth">
+                <el-dropdown @command="changeCellStyle" trigger="click" class="tool-item">
+                    <span class="el-dropdown-link tool-item"> 
+                        <img :src="require(`@/assets/icons/chartFrame/stokeStyle.svg`)"
+                            :class="{'img-disabled':!isSelectNode&&!isSelectEdge,'actived':isSelectNode||isSelectEdge}">
+                        <i class="el-icon-caret-bottom"></i>
+                    </span>
+                    <el-dropdown-menu slot="dropdown">
+                        <el-dropdown-item :command="{attr:'dash',value:5}">
+                            <i class="iconfont icon--xuxian" style="color:'#000';fontSize:30px"></i>
+                        </el-dropdown-item>
+                        <el-dropdown-item :command="{attr:'dash',value:0}">
+                            <i class="iconfont icon--shixian" style="color:'#000';fontSize:30px"></i>
+                        </el-dropdown-item>
+                    </el-dropdown-menu>
+                    <span class="disabled" v-if="!isSelectNode&&!isSelectEdge"></span>
+                </el-dropdown>
+            </ToolItem>
+            <!-- 开始箭头 -->
+            <ToolItem tooltip="开始箭头" toolkey="stokeWidth">
+                <el-dropdown trigger="click" @command="changeStyle" class="tool-item">
+                    <div class="el-dropdown-link">
+                        <img :src="require(`@/assets/icons/chartFrame/arrow-left.svg`)"
+                            :class="{'img-disabled':!isSelectEdge,'actived':isSelectEdge}">
+                            <i class="el-icon-caret-bottom"></i>
+                    </div>
+                    <el-dropdown-menu slot="dropdown">
+                        <el-dropdown-item :command="{attr:'line/sourceMarker',value: 'classic'}">
+                            <i class="iconfont icon-arrow-left" style="color:'#000';fontSize:24px"></i>
+                        </el-dropdown-item>
+                        <el-dropdown-item :command="{attr:'line/sourceMarker',value: ''}">
+                            <i class="iconfont icon--shixian" style="color:'#000';fontSize:32px"></i>
+                        </el-dropdown-item>
+                    </el-dropdown-menu>
+                    <span class="disabled" v-if="!isSelectEdge"></span>
+                </el-dropdown>
+            </ToolItem>
+            <!-- 结束箭头 -->
+            <ToolItem tooltip="结束箭头" toolkey="stokeWidth">
+                <el-dropdown trigger="click" @command="changeStyle" class="tool-item">
+                    <div class="el-dropdown-link">
+                        <img :src="require(`@/assets/icons/chartFrame/arrow-right.svg`)"
+                            :class="{'img-disabled':!isSelectEdge,'actived':isSelectEdge}">
+                            <i class="el-icon-caret-bottom"></i>
+                    </div>
+                    <el-dropdown-menu slot="dropdown">
+                        <el-dropdown-item :command="{attr:'line/targetMarker',value: 'classic'}">
+                            <i class="iconfont icon-arrow-right" style="color:'#000';fontSize:24px"></i>
+                        </el-dropdown-item>
+                        <el-dropdown-item :command="{attr:'line/targetMarker',value: ''}">
+                            <i class="iconfont icon--shixian" style="color:'#000';fontSize:32px"></i>
+                        </el-dropdown-item>
+                    </el-dropdown-menu>
+                    <span class="disabled" v-if="!isSelectNode&&!isSelectEdge"></span>
+                </el-dropdown>
+            </ToolItem>
+        </div>
+        
+    </div>
+</template>
+
+<script>
+import '@/assets/icons/iconfont.css';
+import ToolItem from './toolItem.vue';
+import {sizeOptions,stokeWidthOptions,lineHeightOptions,textAnchorOptions} from '../common/config';
+export default {
+    components: { ToolItem },
+    props:{
+        isSelectNode:{//当前选中的元素是否是节点
+            type:Boolean,
+            default:false
+        },
+        isSelectEdge:{//当前选中的元素是否是边
+            type:Boolean,
+            default:false
+        },
+        currentCell:{//当前传入的元素,Node/Edge
+            type:Object,
+        },
+        graph:{ //当前画布
+            type:Object,
+        },
+        canRedo:{
+            type:Boolean
+        },
+        canUndo:{
+            type:Boolean
+        }
+    },
+    data() {
+        this.sizeOptions=sizeOptions
+        this.stokeWidthOptions=stokeWidthOptions
+        this.textAnchorOptions=textAnchorOptions
+        return {
+            nodeStyle:{ //回显用的
+                fontSize:14,
+                fill:'#333',
+                color:'#333',
+            },
+            cellStyle:{
+                stroke:'#333',
+            },
+            color:'#333',
+            fillColor:'#333',
+            borderColor:'#333',
+        };
+    },
+    watch:{
+        isSelectNode(newVal){
+            if(!newVal){
+                //重置 node相关样式
+                this.nodeStyle = {
+                    fontSize:14,
+                    fill:'#333',
+                    color:'#333',
+                    stroke:'#333'
+                }
+            }
+        },
+        currentCell(newVal){
+            if(newVal){
+                if(newVal.isNode&&newVal.isNode()){
+                    this.nodeStyle = {
+                        fontSize:newVal.attrs.label.fontSize,
+                        fill:newVal.attrs.body.fill,
+                        color:newVal.attrs.label.fill,
+                        stroke:newVal.attrs.body.stroke,
+                    }
+                    this.cellStyle = {
+                        store:newVal.attrs.body.stroke,
+                    }
+                }
+                if(newVal.isEdge&&newVal.isEdge()){
+                    this.cellStyle = {
+                        store:newVal.attrs.line.stroke
+                    }
+                }
+
+            }
+        },
+    },
+    methods: {
+        //加粗,斜体,下划线样式
+        changeStyleToggle(attr){
+            const value = this.currentCell.attr(attr)
+            const valueMap = {
+                'label/fontWeight':['normal','bold'],
+                'label/fontStyle':['normal','italic'],
+                'label/textDecoration':['normal','underline'],
+            }
+            this.changeStyle({attr,
+                value:value===valueMap[attr][0]
+                ?valueMap[attr][1]
+                :valueMap[attr][0]})
+        },
+        changeStyle({attr,value}){
+            this.currentCell.attr(attr,value)
+            if(attr==='label/fontSize'){
+                this.nodeStyle.fontSize = value
+            }
+            
+        },
+        //边框和线条通用样式:线条颜色,宽度,虚线
+        valueChange(e){
+            //t.target.value: "#9c3535"
+            if(e.target){
+                const styleMap = {
+                    'storke':['body/stroke','line/stroke'],
+                    'width':['body/strokeWidth','line/strokeWidth'],
+                    'dash':['body/strokeDasharray','line/strokeDasharray']
+                }
+                const {id,value} = e.target
+                let attr = id
+                if(styleMap[id]){
+                    attr = this.isSelectNode?styleMap[id][0]:styleMap[id][1]
+                } 
+                this.currentCell.attr(attr,value)
+            }
+        },
+        changeCellStyle({attr,value}){
+            this.valueChange({target:{id:attr,value}})
+        },
+        changeTextStyle({attr,value}){
+            for(const key in value){
+                this.currentCell.attr('label/'+key,value[key])
+            }
+        },
+        //撤销/恢复
+        handleGraphHistory(type){
+            this.graph.history[type]()
+        }
+    },
+    mounted(){
+    },
+    
+};
+</script>
+
+<style lang="scss">
+.frame-tool-bar-wrap{
+    .tool-item{
+        .el-input{
+            .el-input__inner {
+                padding:0;
+                height:100%;
+            }
+        }
+    }
+    .el-button{
+        padding:0;
+    }
+}
+</style>
+<style scoped lang="scss">
+.frame-tool-bar-wrap{
+    background-color:#F6F7F8;
+    padding: 5px;
+    position: absolute;
+    height: 26px;
+    left: 0;
+    right:0;
+    top:0;
+    z-index: 100;
+    box-sizing: border-box;
+    .cell-style{
+        display: flex;
+        gap:0 20px;
+        overflow:hidden;
+        align-items:center;
+        .tool-item{
+            cursor: pointer;
+            position: relative;
+            .img-disabled{
+                transform:translateY(50px);
+                filter:drop-shadow(#C8CDD9 0px -50px 0px);
+            }
+            .actived{
+                transform:translateY(50px);
+                filter:drop-shadow(#333 0px -50px 0px);
+            }
+            .item-text{
+                padding:0 2px;
+                &.text-disabled{
+                    color:#C8CDD9;
+                }
+                &.text-actived{
+                    color:#333;
+                }
+            }
+            .disabled {
+                color: #bbb;
+                /* background: rgba(0, 0, 0, 0.08); */
+                background-color: transparent;
+                cursor: not-allowed;
+                position: absolute;
+                top: 0;
+                right: 0;
+                left: 0;
+                bottom: 0;
+                z-index: 1;
+            }
+        }
+    }
+}
+</style>

+ 36 - 0
src/views/chartFrame_manage/components/toolItem.vue

@@ -0,0 +1,36 @@
+<template>
+    <div class="tool-item-wrap">
+        <el-tooltip class="item" effect="dark" :content="tooltip" placement="top">
+            <slot></slot>
+        </el-tooltip>
+    </div>
+</template>
+
+<script>
+export default {
+    props:{
+        tooltip:{
+            type:String,
+            default:''
+        },
+        toolkey:{
+            type:String,
+            default:''
+        },
+        disabled:{
+            type:Boolean,
+            default:false,
+        }
+    },
+    data() {
+        return {};
+    },
+    methods: {
+
+    },
+};
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 149 - 0
src/views/chartFrame_manage/css/basePage.scss

@@ -0,0 +1,149 @@
+.chart-frame-wrap{
+    display: flex;
+    width:100%;
+    position:relative;
+    *{box-sizing: border-box;}
+    .slide-icon {
+        padding: 20px 0;
+        box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.3);
+        border-radius: 5px;
+        cursor: pointer;
+        position: absolute;
+        top: 50%;
+        transform: translateY(-50%);
+        z-index: 99;
+        &:hover {
+          background-color: rgba(0, 0, 0, 0.05);
+        }
+        &.slide-left {
+          right: 0;
+        }
+        &.slide-right {
+          left: 0;
+        }
+    }
+    .page-block-wrap{
+        padding:20px;
+        background-color: #fff;
+        border-radius: 4px;
+        height: calc(100vh - 120px);
+    }
+    .catalog-wrap{
+        width:300px;
+        min-width: 300px;
+        margin-right: 30px;
+        padding:20px;
+        position: relative;
+        display: flex;
+        flex-direction: column;
+        gap:20px 0;
+        .move-btn {
+            height: 100%;
+            width: 4px;
+            position: absolute;
+            right: 0px;
+            top: 0;
+            &:hover {
+              cursor: col-resize;
+            }
+          }
+        .catalog-list{
+            display: flex;
+            flex-direction: column;
+            flex: 1;
+            overflow-y: auto;
+            /* .public-catalog,.my-list{
+                height: 50%;
+                overflow-y: auto;
+            } */
+            .public-catalog{
+                .catalog-tree{
+                    margin: 20px 0;
+                    min-height: 100px;
+                }
+            }
+            .my-list{
+                .classify-item{
+                    display: flex;
+                    align-items: center;
+                    padding:10px;
+                    cursor: pointer;
+                    &.active{
+                        background: #e0eefd;
+                        color: #409eff;
+                    }
+                    .item-label{
+                        flex: 1;
+                        margin: 0 5px;
+                    }
+                    .icon{
+                        width: 18px;
+                    }
+                }
+            }
+        }
+    }
+    .detail-wrap{
+        padding:0;
+        flex:1;
+        background-color: transparent;
+        overflow-y: auto;
+        .list{
+            display: flex;
+            flex-wrap: wrap;
+            gap:20px;
+            .item-title{
+                padding-bottom: 10px;
+            }
+            .list-item{
+                width: 22%;
+                min-width:270px;
+               /*  max-width:300px; */
+                padding:10px;
+                background-color: #fff;
+                cursor: pointer;
+                .item-image{
+                    margin-top:10px;
+                    width:100%;
+                    height: 0;
+                    padding-bottom: 70%;
+                    background-color: pink;
+                    background: no-repeat center/contain url('~@/assets/img/document_m/default-img.png');
+                }
+            }
+        }
+        .detail{
+            background-color: #fff;
+            width:100%;
+            height:100%;
+            display: flex;
+            flex-direction: column;
+            .top-info{
+                width:100%;
+                padding:20px;
+                display: flex;
+                .title{
+                    flex: 1;
+                    text-align: center;
+                    margin: 0 20px;
+                }
+                .tool{
+                    .el-button{
+                        padding: 0;
+                    }
+                }
+                border-bottom: 1px solid #ECECEC;
+            }
+            .frame-wrap{
+                flex:1;
+                overflow: hidden;
+            }
+        }
+    }
+    .dialog-container,.dialog-footer{
+        text-align: center;
+    }
+    .dialog-footer{
+        padding:25px 0;
+    }
+}

+ 69 - 0
src/views/chartFrame_manage/css/customTree.scss

@@ -0,0 +1,69 @@
+.chart-frame-wrap{
+    .catalog-tree{
+        .custom-tree-node {
+            display: flex !important;
+            justify-content: space-between;
+            align-items: center;
+            display: block;
+            flex: 1;
+            width: calc(100% - 28px);
+            .node_label {
+                margin-right: 2px;
+            }
+            .tree-label {
+                flex: 1;
+                overflow: hidden;
+                white-space: nowrap;
+                text-overflow: ellipsis;
+            }
+        }
+        .el-tree-node__content {
+            margin-bottom: 7px !important;
+            &:hover {
+                background-color: #f0f4ff !important;
+              }
+        }
+        .el-tree-node__children {
+            .el-tree-node {
+              margin-bottom: 0px !important;
+              padding-left: 18px;
+            }
+        
+            .el-tree-node__content {
+              margin-bottom: 5px !important;
+              padding-left: 0 !important;
+        
+              &:hover {
+                background-color: #f0f4ff !important;
+              }
+            }
+        }
+        .el-tree-node.is-current>.el-tree-node__content {
+            background-color: #f0f4ff !important;
+            color: #409eff;
+        }
+        .expanded.el-icon-caret-right:before {
+            content: url('~@/assets/img/set_m/down.png') !important;
+        }
+        .el-icon-caret-right:before {
+            content: url('~@/assets/img/set_m/slide.png') !important;
+        }
+        .el-tree-node__expand-icon.is-leaf.el-icon-caret-right:before {
+            content: '' !important;
+        }
+        .el-tree-node__expand-icon.expanded {
+            -webkit-transform: rotate(0deg);
+            transform: rotate(0deg);
+        }
+    }
+    .el-dropdown-menu-item{
+        &:hover {
+            background-color: #F5F7FA  !important;
+            color: #606266 !important;
+        }
+    }
+    .el-dropdown-menu .el-dropdown-menu-item-chat {
+        background-color: #ecf5ff !important;
+        color: #66b1ff !important;
+    }
+}

+ 221 - 0
src/views/chartFrame_manage/frameEditor.vue

@@ -0,0 +1,221 @@
+<template>
+    <!-- 添加编辑框架 -->
+    <div class="frame-editor-wrap">
+        <div class="option-wrap">
+            <el-input style="width:240px;" placeholder="请输入框架名称" v-model.trim="frameDetail.FrameworkName"></el-input>
+            <el-button type="primary" style="margin-left:auto;" @click="handleEditNode({})"
+                v-if="permissionBtn.isShowBtn('chartFramePermission','chartframe_my_editNode')">添加节点</el-button>
+            <el-button type="primary" style="margin-left:20px;" @click="saveFrame"
+                v-if="permissionBtn.isShowBtn('chartFramePermission','chartframe_my_saveFrame')">保存</el-button>
+        </div>
+        <div class="editor-wrap">
+            <!-- 沙盘图组件 -->
+            <FrameContainer ref="container"
+                :FrameworkContent="frameDetail.FrameworkContent"
+                @editNode="handleEditNode"
+                @framePic="getFramePic"
+            />
+        </div>
+        <!-- 添加/编辑节点弹窗 -->
+        <el-dialog
+            :title="modifyNode.nodeId?'编辑节点':'添加节点'"
+            :visible.sync="isModifyNodeDialogShow"
+            :close-on-click-modal="false"
+            :modal-append-to-body="false"
+            @close="isModifyNodeDialogShow=false"
+            width="589px"
+            v-dialogDrag
+            center
+        >
+            <div class="dialog-container">
+                <el-form
+                    ref="refForm"
+                    :model="modifyNode"
+                    :rules="rules"
+                >
+                    <el-form-item label="节点名称" prop="nodeName">
+                        <el-input v-model.trim="modifyNode.nodeName" placeholder="请输入节点名称" style="width:217px;"></el-input>
+                    </el-form-item>
+                    <el-form-item label="节点链接" prop="nodeLink">
+                        <el-select v-model="modifyNode.nodeLink" value-key="MyChartClassifyId" placeholder="请选择节点链接" style="width:217px;">
+                            <el-option v-for="item in myList" 
+                                :key="item.MyChartClassifyId"
+                                :label="item.MyChartClassifyName"
+                                :value="item">
+                                <span style="float:left;">{{item.MyChartClassifyName}}</span>
+                                <span style="float:right;color: #8492a6; font-size: 13px"
+                                @click="goToList(item)"><img src="~@/assets/img/chart_m/check.png"></span>
+                            </el-option>
+                        </el-select>
+                    </el-form-item>
+                </el-form>
+            </div>
+            <div class="dialog-footer">
+                <el-button @click="isModifyNodeDialogShow=false">取消</el-button>
+                <el-button type="primary" @click="editNode">确定</el-button>
+            </div>
+
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import FrameContainer from './components/frameContainer.vue';
+import { mychartInterface,chartFrameInterface,dataBaseInterface } from '@/api/api.js';
+export default {
+    components: { FrameContainer },
+    data() {
+        return {
+            frameId:this.$route.query.frameId||0,
+            frameDetail:{
+                FrameworkName:'',
+                FrameworkContent:'',
+            },
+            lockLoding:null,
+            modifyNode: {},//正在编辑的节点
+            isModifyNodeDialogShow: false,//编辑节点弹窗
+            rules: {
+                nodeName: [{ required: true, message: "请输入节点名称", trigger: "blur" }],
+                nodeLink: [{ required: true, message: "请选择节点链接", trigger: "blur" }]
+            },
+            myList:[],//我的图库列表
+        };
+    },
+    methods: {
+        //获取正在编辑的节点,弹出弹窗
+        handleEditNode(node = {}) {
+            this.$refs.refForm && this.$refs.refForm.resetFields();
+            this.modifyNode = _.cloneDeep(node);
+            this.isModifyNodeDialogShow = true;
+        },
+        //编辑节点,更改子组件节点信息,隐藏弹窗
+        async editNode() {
+            await this.$refs.refForm.validate();
+            if(!this.$refs.container) return
+            this.$refs.container.editNode(this.modifyNode)
+            this.$message.success(`${this.modifyNode.nodeId ? '编辑' : '添加'}节点成功`);
+            this.isModifyNodeDialogShow = false;
+        },
+        //跳转至my eta
+        goToList(item) {
+            window.open(`/mychart?frameId=${item.MyChartClassifyId}`);
+        },
+        //保存框架:内容验证->生成缩略图->获取节点信息,内容信息->编辑/添加框架
+        async saveFrame(){
+            if(!this.frameDetail.FrameworkName.length){
+                return this.$message.warning("请输入框架名称")
+            }
+            if(!this.$refs.container.graph.toJSON().cells.length){
+                return this.$message.warning('请绘制画布内容');
+            }
+
+            this.lockLoding = this.$loading({
+                lock: true,
+                text: '保存中...',
+                target: '.frame-editor-wrap',
+                spinner: 'el-icon-loading',
+                background: 'rgba(255, 255, 255, 0.8)'
+            });
+
+            //获取框架内容图片
+            const svgData = this.$refs.container.getContentPic()
+            if(svgData){
+                const params = new FormData();
+                params.append('Img',svgData)
+                const { Data,Ret } = await dataBaseInterface.uploadImgSvg(params);
+                if(Ret !== 200) return;
+                if(!Data){
+                    return this.$message.warning("上传图片失败")
+                }
+                this.frameDetail.FrameworkImg = Data.ResourceUrl||''
+            }
+            //获取框架节点和内容
+            this.frameDetail.Nodes = this.$refs.container.getContentNodes()
+            this.frameDetail.FrameworkContent = JSON.stringify(this.$refs.container.graph.toJSON())
+            if(this.frameId){
+                //edit
+                chartFrameInterface.editFrame({...this.frameDetail,...{ChartFrameworkId:Number(this.frameId)}}).then(res=>{
+                    this.lockLoding.close();
+                    if(res.Ret!==200) return 
+                    this.$message.success("编辑成功")
+                })
+            }else{
+                //add 
+                chartFrameInterface.addFrame(this.frameDetail).then(res=>{
+                    this.lockLoding.close();
+                    if(res.Ret!==200) return 
+                    this.frameId = res.Data?res.Data.ChartFrameworkId:0
+                    this.frameDetail = res.Data||{FrameworkName:'',FrameworkContent:''}
+                    this.$message.success("新增成功")
+                    //切换至编辑页
+                    this.$router.replace({path:'/editframe',query:{frameId:this.frameId}})
+                })
+            }
+        },
+        getMyList(){
+            mychartInterface.classifyList().then((res)=>{
+                if(res.Ret!==200) return
+                if(!res.Data) return 
+                this.myList = res.Data.List||[]
+            })
+        },
+        async getFrameDetail(){
+            if(this.frameId){
+                const res = await chartFrameInterface.getFrameDetail({ChartFrameworkId:Number(this.frameId)})
+                if(res.Ret!==200) return 
+                this.frameDetail = res.Data||{FrameworkName:'',FrameworkContent:''}
+            }
+            //获取到框架内容后再加载graph
+            this.$nextTick(()=>{
+                this.$refs.container.init()
+            })
+            
+        },
+    },
+    mounted(){
+        this.getMyList()
+        this.getFrameDetail()
+    }
+};
+</script>
+
+<style scoped lang="scss">
+.frame-editor-wrap{
+    display: flex;
+    flex-direction: column;
+    height: calc(100vh - 120px);
+    *{box-sizing: border-box;}
+    .option-wrap{
+        background-color:#fff;
+        padding:20px;
+        display: flex;
+        justify-content: space-between;
+    }
+    .editor-wrap{
+        margin-top: 15px;
+        flex: 1;
+        display: flex;
+        flex-direction: column;
+        background-color: #fff;
+        overflow: hidden;
+        .frame-wrap{
+            flex:1;
+            background-color: #F2F6FA;
+        }
+    }
+    .el-dialog{
+        .dialog-container{
+           .el-form{
+               .el-form-item{
+                   display: flex;
+                   justify-content: center;
+               }
+           }
+        }
+        .dialog-footer{
+            text-align: center;
+            padding-bottom:25px;
+        }
+    }
+}
+</style>

+ 601 - 0
src/views/chartFrame_manage/index.vue

@@ -0,0 +1,601 @@
+<template>
+    <!-- 图库框架 列表页 -->
+    <div class="chart-frame-wrap">
+        <!-- 控制目录栏展开收起-->
+        <span class="slide-icon slide-right" @click="slideHandle" v-show="isSlideLeft">
+            <i class="el-icon-d-arrow-right"></i>
+        </span>
+        <div class="catalog-wrap page-block-wrap" id="catalog-left" v-show="!isSlideLeft">
+            <span class="slide-icon slide-left" @click="slideHandle">
+                <i class="el-icon-d-arrow-left"></i>
+            </span>
+            <span class="move-btn resize" v-drag id="resize"></span>
+            <div class="btn-wrap">
+                <el-button type="primary" @click="$router.push('/addframe')" 
+                v-permission="permissionBtn.chartFramePermission.chartframe_my_editFrame">添加框架</el-button>
+            </div>
+            <div class="search-wrap">
+                <el-select style="width:100%"
+                    filterable remote
+                    placeholder="请输入框架名称"
+                    v-model.trim="searchText"
+                    :remote-method="searchHandle"
+                    value-key="ChartFrameworkId"
+                    clearable
+                    >
+                    <i slot="prefix" class="el-input__icon el-icon-search"></i>
+                    <el-option
+                        v-for="item in searchOptions"
+                        :key="item.ChartFrameworkId"
+                        :label="item.FrameworkName"
+                        :value="item"
+                    />
+                </el-select>
+            </div>
+            <div class="catalog-list">
+                <div class="public-catalog">
+                    <p>公共框架</p>
+                    <div class="catalog-tree">
+                        <el-tree
+                            ref="catalogTree"
+                            class="catalog-tree other-tree"
+                            empty-text="暂无分类"
+                            :data="publicFrameList"
+                            node-key="nodeKeyId"
+                            :expand-on-click-node="false"
+                            @current-change="(data,node)=>{nodeChange(data,node)}"
+                            >
+                            <span class="custom-tree-node" slot-scope="{ data,node }"
+                            >
+                                <span class="tree-label">{{ data.name }}</span>
+                            </span>
+                        </el-tree>
+                    </div>
+                </div>
+                <div class="my-list">
+                    <p>我的框架</p>
+                    <draggable
+                        v-model="myFrameList"
+                        class="classify-ul"
+                        animation="300"
+                        tag="ul"
+                        :disabled="!permissionBtn.isShowBtn('chartFramePermission','chartframe_my_move')"
+                        @start="menuDragStart"
+                        @update="menuDragenter"
+                        @end="menuDragOver"
+                    >
+                        <li class="classify-item" :class="{'active':currentFrame.ChartFrameworkId===item.ChartFrameworkId&&frameType==='my'}"
+                            v-for="item in myFrameList" :key="item.ChartFrameworkId"
+                            @click="chooseFrame(item)"
+                            >
+                            <span v-if="permissionBtn.isShowBtn('chartFramePermission','chartframe_my_move')">
+                                <img src="~@/assets/img/data_m/move_ico.png"
+                                    alt="" class="move"
+                                    style="width: 14px; height: 14px;"
+                                />
+                            </span>
+                            <span class="item-label text_oneLine">{{ item.FrameworkName }}</span>
+                            <el-dropdown style="margin-right: 10px" @command="handleCommand" trigger="click"
+                                v-if="permissionBtn.isShowBtn('chartFramePermission','chartframe_my_show')">
+                                <span class="el-dropdown-link  el-dropdown-link-img">
+                                    <img class="icon" src="~@/assets/img/chart_m/Group.png" v-if="item.IsPublic === 0">
+                                    <img class="icon" src="~@/assets/img/chart_m/User.png" v-else>
+                                </span>
+                                <el-dropdown-menu slot="dropdown">
+                                    <el-dropdown-item 
+                                        :command="{key:'own',value:item}" 
+                                        class="el-dropdown-menu-item-chat"
+                                        >
+                                        <div style="display: flex;align-items: center;">
+                                            <img src="~@/assets/img/chart_m/Group.png">
+                                            <span style="margin-left:5px">仅自己可见</span>
+                                        </div>
+                                    </el-dropdown-item>
+                                    <el-dropdown-item 
+                                        :command="{key:'public',value:item}" 
+                                        class="el-dropdown-menu-item-chat"
+                                        >
+                                        <div style="display: flex;align-items: center;">
+                                            <img src="~@/assets/img/chart_m/User.png">
+                                            <span style="margin-left:5px">所有人可见</span>
+                                        </div>
+                                        
+                                    </el-dropdown-item>
+                                </el-dropdown-menu>
+                            </el-dropdown>
+                            <el-dropdown @command="handleCommand" trigger="click"
+                                v-if="isDropDownShow"
+                            >
+                                <span class="el-dropdown-link"> 
+                                    <i class="el-icon-more" style="font-size: 16px;transform: rotate(90deg);cursor: pointer"/>
+                                </span>
+                                <el-dropdown-menu slot="dropdown">
+                                    <el-dropdown-item v-if="permissionBtn.isShowBtn('chartFramePermission','chartframe_my_rename')"
+                                        :command="{key:'edit'}">重命名</el-dropdown-item>
+                                    <el-dropdown-item v-if="permissionBtn.isShowBtn('chartFramePermission','chartframe_my_delFrame')"
+                                        :command="{key:'del'}">删除</el-dropdown-item>
+                                </el-dropdown-menu>
+                            </el-dropdown>
+                           
+                        </li>
+                    </draggable>
+                </div>
+            </div>
+        </div>
+        <div class="detail-wrap page-block-wrap" id="detail-right">
+            <div class="empty" v-if="!currentFrame.ChartFrameworkId&&currentList.length===0">
+                <tableNoData text="暂无数据"/>
+            </div>
+            <template v-else>
+                <div class="list" v-if="model==='list'">
+                    <div class="list-item" 
+                        v-for="item in currentList" :key="item.nodeKeyId"
+                        @click="nodeChange(item,{level:2})"
+                        >
+                        <div class="item-title text_oneLine">
+                            <span>{{item.name}}</span>
+                        </div>
+                        <div style="height:1px;background:#ECECEC;margin:0 -10px;"></div>
+                        <div class="item-image" 
+                            :style="`background-image:url(${item.FrameworkImg?item.FrameworkImg:require('@/assets/img/document_m/default-img.png')})`"></div>
+                        <div style="height:1px;background:#ECECEC;margin:10px -10px;"></div>
+                        <div class="item-time">
+                            创建时间:{{item.CreateTime}}
+                        </div>
+                    </div>
+                    <div class="empty" v-if="currentList.length===0">
+                        <tableNoData text="暂无数据"/>
+                    </div>
+                </div>
+                <div class="detail" v-else>
+                    <div class="top-info">
+                        <span>更新时间:{{currentFrame.ModifyTime}}</span>
+                        <span class="title text_oneLine">{{currentFrame.FrameworkName}}</span>
+                        <div class="tool">
+                            <el-button type="text" @click="handleOption('edit',currentFrame)" 
+                                v-if="frameType==='my'&&permissionBtn.isShowBtn('chartFramePermission','chartframe_my_editFrame')">编辑</el-button>
+
+                            <el-button type="text" @click="handleOption('copy',currentFrame)" :disabled="!currentFrame.FrameworkContent"
+                                v-if="frameType==='my'&&permissionBtn.isShowBtn('chartFramePermission','chartframe_my_copyImg')">复制图片</el-button>
+                            <el-button type="text" @click="handleOption('copy',currentFrame)" :disabled="!currentFrame.FrameworkContent"
+                                v-if="frameType==='public'&&permissionBtn.isShowBtn('chartFramePermission','chartframe_public_copyImg')">复制图片</el-button>
+
+                            <el-button type="text" @click="handleOption('del',currentFrame)" style="color:red;"
+                                v-if="frameType==='my'&&permissionBtn.isShowBtn('chartFramePermission','chartframe_my_delFrame')">删除</el-button>
+                        </div>
+                    </div>
+                    <div class="frame-wrap">
+                        <!--沙盘图组件-->
+                        <FrameContainer ref="container"
+                            :FrameworkContent="currentFrame.FrameworkContent"
+                            @showDialog="handleShowDialog"/>
+                    </div>
+                </div>
+            </template>
+        </div>
+        <!-- 重命名弹窗 -->
+        <el-dialog
+            title="重命名框架"
+            :visible.sync="isRenameDialogShow"
+            :close-on-click-modal="false"
+            :modal-append-to-body="false"
+            @close="isRenameDialogShow=false"
+            width="589px"
+            v-dialogDrag
+            center
+        >
+            <div class="dialog-container">
+                <div>
+                    <span style="margin-right:5px;">框架名称</span>
+                    <el-input v-model.trim="modifyFrame.FrameworkName" placeholder="请输入框架名称"></el-input>
+                </div>
+            </div>
+            <div class="dialog-footer">
+                <el-button @click="isRenameDialogShow=false">取消</el-button>
+                <el-button type="primary" @click="renameFrame">确定</el-button>
+            </div>
+        </el-dialog>
+        <!-- my eta图表详情弹窗 -->
+        <chartDetail 
+            :isOpenDetail="myETADetailDialogShow"
+            :select_classify="chartClassify"
+            :chart_code="chartCode"
+            :allChart="chartArr"
+            :classifyUserId="classifyUserId"
+            @close="myETADetailDialogShow=false"
+            @remove="removeChart"
+        />
+        <!-- my eta图表复制到弹窗 -->
+        <el-dialog
+            title="复制到我的图库"
+            :visible.sync="isCopyDialogShow"
+            :close-on-click-modal="false"
+            :modal-append-to-body="false"
+            @close="isCopyDialogShow=false"
+            width="589px"
+            v-dialogDrag
+            center
+        >
+            <div class="dialog-container" v-loading="copyDialogLoading">
+                <div>
+                    <span style="margin-right:5px;">复制到</span>
+                    <el-select
+                        v-model="copyToClassify"
+                        placeholder="请选择目录"
+                        style="width: 80%;"
+                        multiple clearable
+                    >
+                        <el-option v-for="item in myETAClassArr"
+                            :key="item.value"
+                            :label="item.name"
+                            :value="item.value"
+                        />
+                    </el-select>
+                </div>
+            </div>
+            <div class="dialog-footer">
+                <el-button @click="isCopyDialogShow=false">取消</el-button>
+                <el-button type="primary" @click="copyToClass">确定</el-button>
+            </div>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import draggable from 'vuedraggable';
+import FrameContainer from './components/frameContainer.vue';
+import chartDetail from '@/views/mychart_manage/components/chartDetailDia.vue';
+import { mychartInterface,chartFrameInterface } from '@/api/api.js';
+import {copyBlob} from '@/utils/svgToblob.js';
+export default {
+    components:{ draggable, FrameContainer,chartDetail},
+    directives: {//自定义指令调整目录栏宽度
+        drag(el, bindings) {
+            el.onmousedown = function (e) {
+                let init = e.clientX;
+                let left = $('#catalog-left')[0];
+                let initWidth = left.offsetWidth;
+                document.onmousemove = function (e) {
+                let end = e.clientX;
+                let newWidth = end - init + initWidth;
+                left.style.width = newWidth+'px';
+                //reloadFrame()
+                };
+                document.onmouseup = function () {
+                document.onmousemove = document.onmouseup = null;
+                e.releaseCapture && e.releaseCapture();
+                };
+                e.setCapture && e.setCapture();
+                return false;
+            };
+        },
+    },
+    data() {
+        return {
+            isSlideLeft:false,//控制左侧目录栏是否显示
+
+            /* drag 我的框架相关 */
+            dragStartIndex:0,
+            dragFrame:null,
+            prevFrame:null,
+            nextFrame:null,
+
+            /* search */
+            searchText:'',
+            searchOptions:[],
+            
+            /* select frame*/
+            model:'frame',
+            frameType:'my',
+            publicFrameList:[],//公共框架列表
+            currentList:[],//选择公共框架时,框架列表
+            myFrameList:[],//我的框架列表
+            currentFrame:{},//选择的框架
+            /* frame node */
+            myETADetailDialogShow:false,//点击节点时,弹出myeta图表详情弹框
+            modifyFrame:{},//正在修改的框架
+            isRenameDialogShow:false,//重命名弹窗
+            /*my eta 图表详情操作相关 */
+            chartClassify:0,
+            classifyUserId:0,
+            chartCode:'',
+            chartArr:[],
+            isCopyDialogShow:false,
+            myETAClassArr:[],
+            copyToClassify:[],
+            modeId:0,
+            /* 页面loading */
+            lockLoding:null,
+        };
+    },
+    watch:{
+        searchText(newVal){
+            newVal&&this.chooseFrame(newVal)
+        }
+    },
+    computed:{
+        adminId(){
+            return Number(localStorage.getItem('AdminId'))
+        },
+        isDropDownShow(){
+            return this.permissionBtn.isShowBtn('chartFramePermission','chartframe_my_rename')
+                || this.permissionBtn.isShowBtn('chartFramePermission','chartframe_my_delFrame')
+        }
+    },
+    methods: {
+        slideHandle(){
+            this.isSlideLeft = !this.isSlideLeft;
+        },
+        getPublicList(){
+            chartFrameInterface.getPublicFrameList().then(res=>{
+                if(res.Ret!==200) return 
+                this.publicFrameList = res.Data||[]
+                this.publicFrameList = this.publicFrameList.map(list=>{
+                    list.name = list.MenuName
+                    list.nodeKeyId = 'list'+list.AdminId
+                    if(list.Frameworks){
+                        list.children = list.Frameworks.map(item=>{
+                            return {
+                                ...item,
+                                ...{
+                                    nodeKeyId:'item'+item.ChartFrameworkId,
+                                    name:item.FrameworkName
+                                }
+                            }
+                        })
+                    }
+                    return list
+                })
+            })
+        },
+        async getMyList(type){
+            const res = await chartFrameInterface.getMyFrameList({AdminId:this.adminId})
+            if(res.Ret!==200) return 
+            this.myFrameList = res.Data||[]
+            if(type!=='init') return 
+            //如果是其他页面跳转来的
+            if(this.$route.query.frameId){
+                this.currentFrame = this.myFrameList.find(i=>i.ChartFrameworkId===Number(this.$route.query.frameId))||{}
+            }else{
+                //否则选择myFrameList的第一个
+                this.currentFrame = this.myFrameList[0]||{}
+            }
+            this.handleInitGraph()
+        },
+        searchHandle(keyword){
+            chartFrameInterface.getMyFrameList({
+                AdminId:this.adminId,
+                Keyword:keyword,
+            }).then(res=>{
+                if(res.Ret!==200) return
+                this.searchOptions = res.Data||[]
+            })
+        },
+        nodeChange(data,node){
+            this.frameType = 'public'
+            this.changeModel(node.level===2?'frame':'list',data)
+            this.$nextTick(()=>{
+                this.$refs.catalogTree.setCurrentKey(data.nodeKeyId)
+            })
+        },
+        changeModel(type,data){
+            if(type==='frame'&&data.ChartFrameworkId===this.currentFrame.ChartFrameworkId) return 
+            this.model = type
+            //销毁画布
+            this.$refs.container&&this.$refs.container.dispose()
+            if(type==='frame'){
+                this.currentFrame = data
+                this.handleInitGraph()
+            }else{
+                this.currentList = data.children||[]
+                this.currentFrame={}
+            }
+        },
+        handleInitGraph(){
+            //判断一下框架内容是否是合法的JSON,否则置为空
+            try{
+                JSON.parse(this.currentFrame.FrameworkContent)
+            }catch(e){
+                this.currentFrame.FrameworkContent = ''
+            }
+            this.$nextTick(()=>{
+                //若框架有内容,才加载画布
+                this.currentFrame.FrameworkContent&&this.$refs.container.init()
+            })
+        },
+        /* 拖动相关 */
+        menuDragStart({oldIndex}){
+            this.dragStartIndex = oldIndex
+            this.dragFrame = this.myFrameList[oldIndex]
+        },
+        menuDragenter({newIndex}){
+            //置顶
+            if(newIndex===0){
+                this.prevFrame=null
+                this.nextFrame=this.myFrameList[newIndex+1]
+            }
+            //置底
+            if(newIndex===this.myFrameList.length-1){
+                this.prevFrame = this.myFrameList[newIndex-1]
+                this.nextFrame = null
+            }
+            if(newIndex!==0&&newIndex!==this.myFrameList.length-1){
+                this.prevFrame = this.myFrameList[newIndex-1]
+                this.nextFrame = this.myFrameList[newIndex+1]
+            }
+        },
+        menuDragOver({newIndex}){
+            if(newIndex===this.drageStartIndex) return
+            if(!this.dragFrame) return
+            chartFrameInterface.moveFrame({
+                ChartFrameworkId:this.dragFrame.ChartFrameworkId,
+                PrevChartFrameworkId:this.prevFrame?this.prevFrame.ChartFrameworkId:0,
+                NextChartFrameworkId:this.nextFrame?this.nextFrame.ChartFrameworkId:0,
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.$message.success("移动成功")
+                this.getMyList()
+            })
+        },
+        /*下拉框 */
+        handleCommand(command){
+            if(command.key==='edit'){
+                this.modifyFrame = _.cloneDeep(this.currentFrame)
+                this.isRenameDialogShow = true
+            }
+            if(command.key==='del'){
+                this.deleteFrame(this.currentFrame)
+            }
+            if(['own','public'].includes(command.key)){
+                chartFrameInterface.changePublicFrame({
+                    ChartFrameworkId:command.value.ChartFrameworkId,
+                    IsPublic:command.key==='own'?0:1
+                }).then(res=>{
+                    if(res.Ret!==200) return
+                    this.getPublicList()
+                    this.getMyList()
+                    this.$message.success(`操作成功`)
+                })
+            }
+        },
+        //选择我的框架
+        chooseFrame(item){
+            this.frameType = 'my'
+            this.changeModel('frame',item)
+            this.$nextTick(()=>{
+                this.$refs.catalogTree.setCurrentKey(null)
+            })
+        },
+        /* 框架操作相关 */
+        handleOption(type,data){
+            const optionMap = {
+                'edit':this.handleEditFrame,
+                'copy':this.copyFrameImg,
+                'del':this.deleteFrame,
+            }
+            optionMap[type](data)
+        },
+        handleEditFrame(data){
+            this.$router.push({path:'/editframe',query:{frameId:data.ChartFrameworkId}})
+        },
+        copyFrameImg(data){
+            this.lockLoding = this.$loading({
+                lock: true,
+                text: '复制图片中...',
+                target: '.frame-container-wrap',
+                spinner: 'el-icon-loading',
+                background: 'rgba(255, 255, 255, 0.8)'
+            });
+            const svgData = this.$refs.container.getContentPic()
+            copyBlob(svgData,()=>{
+                this.lockLoding && this.lockLoding.close();
+            },1,'svg')
+        },
+        deleteFrame(data){
+            this.$confirm("删除后不可恢复,确认删除吗?","提示",{
+                confirmButtonText:"确定",
+                cancelButtonText:"取消",
+                type:"warning"
+            }).then(()=>{
+                chartFrameInterface.deleteFrame({
+                    ChartFrameworkId:data.ChartFrameworkId
+                }).then(res=>{
+                    if(res.Ret!==200) return
+                    this.$message.success("删除成功")
+                    this.getPublicList()
+                    this.getMyList()
+                    this.currentFrame = {}
+                })
+            }).catch(()=>{})
+        },
+        renameFrame(){
+            if(!this.modifyFrame.FrameworkName.length){
+                this.$message.warning("请输入框架名称")
+                return
+            }
+            chartFrameInterface.reNameFrame({
+                ChartFrameworkId:this.modifyFrame.ChartFrameworkId,
+                FrameworkName:this.modifyFrame.FrameworkName
+            }).then(async res=>{
+                if(res.Ret!==200) return
+                this.getPublicList()
+                await this.getMyList()
+                this.currentFrame = this.myFrameList.find(item=>item.ChartFrameworkId===this.modifyFrame.ChartFrameworkId)||{}
+                this.$message.success("编辑成功")
+                this.isRenameDialogShow = false
+            })
+            
+        },
+        //点击框架内节点
+        handleShowDialog({id,nodeLink}){
+            //请求接口看有没有数据
+            mychartInterface.myList({
+                PageSize:1200,
+                CurrentIndex:1,
+                MyChartClassifyId: Number(id),
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                if(res.Data&&res.Data.List){
+                    if(res.Data.List.length){
+                        this.chartClassify = id
+                        this.classifyUserId = nodeLink.AdminId||0
+                        this.chartCode = res.Data.List[0].UniqueCode
+                        this.chartArr = res.Data.List.map(item => item.UniqueCode)
+                        this.myETADetailDialogShow = true
+                    }
+                }else{
+                    this.$message.warning('该节点链接的图库没有图表')
+                }
+            })
+        },
+        //打开复制到弹窗
+        async moveMychart(id) {
+            this.isCopyDialogShow = true
+            this.copyDialogLoading = true
+            this.modeId = id
+            //获取当前图表所属分类
+            const { Data : chartClassifyList=[]} = await mychartInterface.getChartInClassify({ChartInfoId: id })
+            //获取myETA全部分类
+            const {Data} = await mychartInterface.classifyList()
+            const classifyListData = Data?Data.List.map(item=>{
+                return {...item,fromPublic: 0}
+            }):[]
+            //过滤掉所属分类
+            this.myETAClassArr = classifyListData
+                .map((item) => ({
+                name: item.MyChartClassifyName,
+                value: item.MyChartClassifyId,
+                }))
+                .filter((x) => !chartClassifyList.includes(x.value))
+            this.copyDialogLoading = false
+        },
+        //将图表复制到其他目录
+        copyToClass(){
+            mychartInterface.copyMyChart({
+                ChartInfoId: this.modeId,
+                MyChartClassifyId: this.copyToClassify,
+            })
+            .then((res) => {
+                if (res.Ret !== 200) return;
+                this.$message.success('复制成功');
+                this.isCopyDialogShow = false;
+            });
+        },
+        //弹窗中移除了图表,对chartArr做对应改动
+        removeChart(UniqueCode){
+            this.chartArr.splice(this.chartArr.findIndex(item => item === UniqueCode), 1)
+        }
+    },
+    mounted(){
+        this.getPublicList()
+        this.getMyList('init')
+    }
+};
+</script>
+
+<style lang="scss">
+@import "./css/customTree.scss";
+</style>
+<style scoped lang="scss">
+@import "./css/basePage.scss";
+</style>

+ 73 - 0
src/views/chartRelevance_manage/components/explainDialog.vue

@@ -0,0 +1,73 @@
+<template>
+    <el-dialog custom-class="explain-dialog-wrap"
+        :visible.sync="showExplain"
+        :close-on-click-modal="false"
+        :append-to-body="true"
+        center
+        width="976px"
+        v-dialogDrag
+        top="8vh"
+        title="操作说明"
+        @close="$emit('close')"
+    >
+        <div class="dialog-container">
+            <div class="explain-text" v-for="text,index in textArray" :key="index" v-html="text">
+            </div>
+        </div>
+        <div class="dialog-btn">
+            <el-button type="primary" @click="$emit('close')">知道了</el-button>
+        </div>
+        
+    </el-dialog>
+</template>
+
+<script>
+import * as explainText from './explainText'
+export default {
+    props:{
+        showExplain:{
+            type:Boolean,
+            default:false
+        },
+        textArrName:{
+            type:String,
+            default:'chartrelevanceTextArr'
+        }
+    },
+    computed:{
+        textArray(){
+            return explainText[this.textArrName]
+        }
+    },
+    data() {
+        return {
+
+        };
+    },
+    methods: {
+
+    },
+};
+</script>
+
+<style scoped lang="scss">
+.explain-dialog-wrap{
+    .dialog-container{
+        .explain-text{
+            font-size: 16px;
+            padding-bottom: 20px;
+            &:not(:last-child){
+                border-bottom:1px solid #D9D9D9;
+            }
+            &:not(:first-child){
+                padding-top: 20px;
+            }
+        }
+    }
+    .dialog-btn{
+        margin-top: 25px;
+        padding-bottom: 25px;
+        text-align: center;
+    }
+}
+</style>

+ 38 - 0
src/views/chartRelevance_manage/components/explainText.js

@@ -0,0 +1,38 @@
+//相关性分析
+export const chartrelevanceTextArr = [
+    `<p style='font-weight:bold;'>相关性计算处理逻辑:</p>
+    <p>1、取数:取计算窗口的时间长度,从当前时间往前推移对应的时间长度,取该日期区间,指标A序列值和指标B序列值;</p>
+    <p>2、变频:根据指标A和指标B的频度对取出的数据序列做如下处理</p>
+    <p>①指标A高频,对指标B升频(线性方程插值法补全数据);</p>
+    <p>②指标B高频,对指标A升频(线性方程插值法补全数据);</p>
+    <p>③指标A,指标B同频,不作处理;</p>
+    <p>3、计算:按照分析周期,以指标A为基准,对指标B作对应期数的位移,根据公式相关系数R = SUM[(Xi-Mx)*(Yi-My)]/[(N-1)(SDx*SDy)],计算每个期数对应的相关性;</p>
+    <p style='height:20px;'></p>
+    <p>注:指标B作位移时,若以指标A的日期序列未找到指标B的值,则往前找最近值进行计算(往前找的范围为当前日期往前推移计算窗口的时间范围)</p>`,
+    `<p style='font-weight:bold;'>相关性配置:</p>
+    <p>1、计算窗口:参与计算的历史数据时间段;</p>
+    <p>2、分析周期:指标B领先A的期数,如配置参数10个月,表示B领先A -10月、B领先A -9月,...,B领先A 9月、B领先A 10月,每期分别计算相关性值;</p>`,
+    `<p style='font-weight:bold;'>滚动相关性配置:</p>
+    <p>1、计算窗口:参与计算的时间段长度,从两个指标都有值的日期开始滚动的取计算窗口长度的值进行计算,如配置计算窗口1个月,则2023.7.28的值取2023.6.28~2023.7.28时间段,2023.7.27的值取2023.6.27~2023.7.27时间段;</p>
+    <p>2、B领先A:B指标领先A指标的参数,为0时不领先;</p>`
+]
+
+//拟合方程曲线
+export const fittingEquationListTextArr = [
+    `<p style='font-weight:bold;'>拟合方程曲线处理逻辑:</p>
+    <p>1、选择两组有相关性的指标</p>
+    <p>2、对两组在选定时间范围内的每一个时间节点,生成拟合方程Y=aX+b以及相关系数R²</p>
+    <p>3、分别画出弹性系数a,截距b,相关系数R²,在选定时间范围内的曲线图</p>`,
+]
+
+export const statisticFeatureListTextArr = [
+    `<p style='font-weight:bold;'>标准差处理逻辑:</p>
+    <p>计算所选时间范围内数据的样本标准差s,s=sqrt(((x1-x)^2 (x2-x)^2 ......(xn-x)^2)/(n-1)),n表示数据个数</p>`,
+    `<p style='font-weight:bold;'>百分位处理逻辑:</p>
+    <p>对所选时间范围内的数据,取最大值Max,最小值Min,计算Max-Min,百分位=(现值-Min)/(Max-Min),Max=Min时不计算</p>`,
+    `<p style='font-weight:bold;'>频率分布处理逻辑:</p>
+    <p>1、在所选时间范围内,取最大值和最小值;</p>
+    <p>2、根据频段数划分多个间距相同的区间(左闭右开,最后一个区间为左闭右闭),统计数据值落在每个区间的数据个数;</p>
+    <p>3、频率=落在某区间数据个数/所选时间段内数据总个数;</p>
+    <p>4、累计频率为从最小值所在区间对应的频率开始累加;</p>`
+]

+ 4 - 3
src/views/chartRelevance_manage/components/saveEdbToBaseDia.vue

@@ -125,7 +125,8 @@ export default {
 				label: 'ClassifyName',
 				label: 'ClassifyName',
 				value: 'ClassifyId',
 				value: 'ClassifyId',
 				children: 'Children',
 				children: 'Children',
-				emitPath: false
+				emitPath: false,
+				checkStrictly: true
 			},
 			},
 			frequencyArr:['日度','周度','旬度','月度','季度','年度'],
 			frequencyArr:['日度','周度','旬度','月度','季度','年度'],
 		};
 		};
@@ -144,13 +145,13 @@ export default {
 				if(res.Ret !== 200) return
 				if(res.Ret !== 200) return
 				//this.filterNodes(res.Data.AllNodes,2);
 				//this.filterNodes(res.Data.AllNodes,2);
 			}
 			}
-
+			this.filterNodes(res.Data.AllNodes||[]);
 			this.options = res.Data.AllNodes || [];
 			this.options = res.Data.AllNodes || [];
 		},
 		},
 		filterNodes(arr,n) {
 		filterNodes(arr,n) {
 			arr.length && arr.forEach(item => {
 			arr.length && arr.forEach(item => {
 				item.Children && item.Children.length && this.filterNodes(item.Children,n)
 				item.Children && item.Children.length && this.filterNodes(item.Children,n)
-				if(item.Level === n) {
+				if(!item.Children.length) {
 					delete item.Children
 					delete item.Children
 				}
 				}
 			})
 			})

+ 20 - 4
src/views/chartRelevance_manage/fittingEquationChartEditor.vue

@@ -14,7 +14,7 @@
 					path: '/fittingEquationList',
 					path: '/fittingEquationList',
 					query: $route.query
 					query: $route.query
 				})">取消</el-button>
 				})">取消</el-button>
-				<span style="color: #666;">
+				<!-- <span style="color: #666;">
 						使用说明
 						使用说明
 					<el-tooltip
 					<el-tooltip
 						effect="dark"
 						effect="dark"
@@ -26,7 +26,11 @@
 						></div>
 						></div>
 						<i class="el-icon-question" />
 						<i class="el-icon-question" />
 					</el-tooltip>
 					</el-tooltip>
-				</span>
+				</span> -->
+				<div style="color:#409EFF;font-size: 16px;cursor: pointer;" @click="showExplain = true">
+					<i class="el-icon-document" style="font-size:22px;"></i>
+					操作说明
+				</div>
       </div>
       </div>
 			<div class="left-min">
 			<div class="left-min">
 				<div class="section-item">
 				<div class="section-item">
@@ -155,6 +159,12 @@
       :isShow.sync="isSaveDialog"
       :isShow.sync="isSaveDialog"
 			:initData="leftOption.ChartMappingList"
 			:initData="leftOption.ChartMappingList"
 			@saveBack="editChartBackHandle"
 			@saveBack="editChartBackHandle"
+    />
+	<!-- 操作说明 -->
+    <ExplainDialog 
+        textArrName="fittingEquationListTextArr"
+        :show-explain="showExplain"
+        @close="showExplain = false"
     />
     />
 
 
   </div>
   </div>
@@ -167,8 +177,9 @@ import Chart from '@/views/dataEntry_manage/components/chart';
 import selectTarget from './components/selectTarget.vue';
 import selectTarget from './components/selectTarget.vue';
 import fittingEquationSaveDia from './components/fittingEquationSaveDia.vue';
 import fittingEquationSaveDia from './components/fittingEquationSaveDia.vue';
 import chartCard from './components/chartCard.vue';
 import chartCard from './components/chartCard.vue';
+import ExplainDialog from './components/explainDialog.vue';
 export default {
 export default {
-  components: { Chart,selectTarget,fittingEquationSaveDia,chartCard },
+  components: { Chart,selectTarget,fittingEquationSaveDia,chartCard,ExplainDialog },
 	directives: {
 	directives: {
     drag(el, bindings) {
     drag(el, bindings) {
       el.onmousedown = function (e) {
       el.onmousedown = function (e) {
@@ -236,7 +247,9 @@ export default {
 
 
 			useTip:`1、选择两组有相关性的指标<br>
 			useTip:`1、选择两组有相关性的指标<br>
 					2、对两组在选定时间范围内的每一个时间节点,生成拟合方程Y=aX+b以及相关系数R²<br>
 					2、对两组在选定时间范围内的每一个时间节点,生成拟合方程Y=aX+b以及相关系数R²<br>
-					3、分别画出弹性系数a,截距b,相关系数R²,在选定时间范围内的曲线图`
+					3、分别画出弹性系数a,截距b,相关系数R²,在选定时间范围内的曲线图`,
+			//操作说明弹窗
+			showExplain:false
 
 
     };
     };
   },
   },
@@ -417,6 +430,9 @@ export default {
       padding: 15px 20px;
       padding: 15px 20px;
       border: 1px solid #ececec;
       border: 1px solid #ececec;
       box-shadow: 0px 3px 6px rgba(167, 167, 167, 0.09);
       box-shadow: 0px 3px 6px rgba(167, 167, 167, 0.09);
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
     }
     }
 		.left-min {
 		.left-min {
 			padding: 30px 20px;
 			padding: 30px 20px;

+ 2 - 2
src/views/chartRelevance_manage/fittingEquationList.vue

@@ -13,7 +13,7 @@
 				<div class="datasheet_top">
 				<div class="datasheet_top">
 						<el-button v-permission="permissionBtn.statisticPermission.fittingEq_addChart"
 						<el-button v-permission="permissionBtn.statisticPermission.fittingEq_addChart"
 							type="primary" @click="goAddChart">添加图表</el-button>
 							type="primary" @click="goAddChart">添加图表</el-button>
-						<div style="color: #666">
+						<!-- <div style="color: #666">
 							 使用说明
 							 使用说明
 							<el-tooltip
 							<el-tooltip
 								effect="dark"
 								effect="dark"
@@ -25,7 +25,7 @@
 								></div>
 								></div>
 								<i class="el-icon-question" />
 								<i class="el-icon-question" />
 							</el-tooltip>
 							</el-tooltip>
-						</div>
+						</div> -->
 				</div>
 				</div>
 
 
 				<div class="search-cont">
 				<div class="search-cont">

+ 21 - 6
src/views/chartRelevance_manage/relevanceChartEditor.vue

@@ -10,6 +10,10 @@
     <div class="left-cont" v-show="!isSlideLeft" id="left">
     <div class="left-cont" v-show="!isSlideLeft" id="left">
       <div class="left-top">
       <div class="left-top">
         <el-button type="primary" plain @click="$router.back()">取消</el-button>
         <el-button type="primary" plain @click="$router.back()">取消</el-button>
+        <div style="color:#409EFF;font-size: 16px;cursor: pointer;" @click="showExplain = true">
+            <i class="el-icon-document" style="font-size:22px;"></i>
+            操作说明
+        </div>
       </div>
       </div>
       <div class="left-min">
       <div class="left-min">
         <el-form
         <el-form
@@ -148,7 +152,7 @@
 
 
         <div class="section">
         <div class="section">
           <div>相关性
           <div>相关性
-            <el-tooltip
+            <!-- <el-tooltip
               effect="dark"
               effect="dark"
             >
             >
               <div
               <div
@@ -157,7 +161,7 @@
                 style="line-height: 20px;width:350px"
                 style="line-height: 20px;width:350px"
               ></div>
               ></div>
               <i class="el-icon-question" style="color:#666"/>
               <i class="el-icon-question" style="color:#666"/>
-            </el-tooltip>
+            </el-tooltip> -->
           </div>
           </div>
           <div class="section-item">
           <div class="section-item">
             <div style="flex-shrink:0;min-width:70px"><span style="color:red;font-size:18px;">*</span>计算窗口</div>
             <div style="flex-shrink:0;min-width:70px"><span style="color:red;font-size:18px;">*</span>计算窗口</div>
@@ -208,7 +212,7 @@
 
 
       <div class="section" v-for="(item,index) in chartInfo.RollingCorrelation" :key="index">
       <div class="section" v-for="(item,index) in chartInfo.RollingCorrelation" :key="index">
         <div>滚动相关性{{index+1}}
         <div>滚动相关性{{index+1}}
-          <el-tooltip
+          <!-- <el-tooltip
             effect="dark"
             effect="dark"
           >
           >
             <div
             <div
@@ -217,7 +221,7 @@
               style="line-height: 20px;width:350px"
               style="line-height: 20px;width:350px"
             ></div>
             ></div>
             <i class="el-icon-question" style="color:#666"/>
             <i class="el-icon-question" style="color:#666"/>
-          </el-tooltip>
+          </el-tooltip> -->
         </div>
         </div>
         <div class="section-item">
         <div class="section-item">
           <span style="flex-shrink:0;min-width:70px">计算窗口</span>
           <span style="flex-shrink:0;min-width:70px">计算窗口</span>
@@ -357,6 +361,11 @@
       :chartData="chartData"
       :chartData="chartData"
       @saveBack="saveEdbBack"
       @saveBack="saveEdbBack"
     />
     />
+    <!-- 操作说明 -->
+    <ExplainDialog 
+        :show-explain="showExplain"
+        @close="showExplain = false"
+    />
   </div>
   </div>
 </template>
 </template>
 
 
@@ -370,8 +379,9 @@ import chartCard from './components/chartCard.vue';
 import SaveChartOther from '@/views/dataEntry_manage/components/SaveChartOther';
 import SaveChartOther from '@/views/dataEntry_manage/components/SaveChartOther';
 import saveChartToBase from './components/saveChartTobaseDia.vue';
 import saveChartToBase from './components/saveChartTobaseDia.vue';
 import saveEdbToBase from './components/saveEdbToBaseDia.vue'
 import saveEdbToBase from './components/saveEdbToBaseDia.vue'
+import ExplainDialog from './components/explainDialog.vue';
 export default {
 export default {
-  components: { selectTarget,chartCard,SaveChartOther,saveChartToBase,saveEdbToBase },
+  components: { selectTarget, chartCard, SaveChartOther, saveChartToBase, saveEdbToBase, ExplainDialog },
   directives: {
   directives: {
     drag(el, bindings) {
     drag(el, bindings) {
       el.onmousedown = function (e) {
       el.onmousedown = function (e) {
@@ -506,7 +516,9 @@ export default {
           分析周期:指标B领先A的期数,如配置参数10个月,表示B领先A -10月、B领先A -9月,...,B领先A 9月、B领先A 10月,每期分别计算相关性值;`,
           分析周期:指标B领先A的期数,如配置参数10个月,表示B领先A -10月、B领先A -9月,...,B领先A 9月、B领先A 10月,每期分别计算相关性值;`,
         rollingCorrelation:`计算窗口:参与计算的时间段长度,从两个指标都有值的日期开始滚动的取计算窗口长度的值进行计算,如配置计算窗口1个月,则2023.7.28的值取2023.6.28~2023.7.28时间段,2023.7.27的值取2023.6.27~2023.7.27时间段;<br>
         rollingCorrelation:`计算窗口:参与计算的时间段长度,从两个指标都有值的日期开始滚动的取计算窗口长度的值进行计算,如配置计算窗口1个月,则2023.7.28的值取2023.6.28~2023.7.28时间段,2023.7.27的值取2023.6.27~2023.7.27时间段;<br>
         B领先A:B指标领先A指标的参数,为0时不领先;`
         B领先A:B指标领先A指标的参数,为0时不领先;`
-      }
+      },
+      /* 操作说明弹窗 */
+      showExplain:false
 
 
     };
     };
   },
   },
@@ -813,6 +825,9 @@ export default {
       padding: 15px 20px;
       padding: 15px 20px;
       border-bottom: 1px solid #ececec;
       border-bottom: 1px solid #ececec;
       box-shadow: 0px 3px 6px rgba(167, 167, 167, 0.09);
       box-shadow: 0px 3px 6px rgba(167, 167, 167, 0.09);
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
     }
     }
     .left-min {
     .left-min {
       padding: 20px;
       padding: 20px;

+ 24 - 8
src/views/chartRelevance_manage/statisticFeatureChartEditor.vue

@@ -10,6 +10,10 @@
     <div class="left-cont" v-show="!isSlideLeft" id="left">
     <div class="left-cont" v-show="!isSlideLeft" id="left">
       <div class="left-top">
       <div class="left-top">
         <el-button type="primary" plain @click="$router.back()">取消</el-button>
         <el-button type="primary" plain @click="$router.back()">取消</el-button>
+        <div style="color:#409EFF;font-size: 16px;cursor: pointer;" @click="showExplain = true">
+            <i class="el-icon-document" style="font-size:22px;"></i>
+            操作说明
+        </div>
       </div>
       </div>
       <div class="left-min">
       <div class="left-min">
         <div class="search-cont">
         <div class="search-cont">
@@ -72,14 +76,14 @@
 
 
         <div class="section">
         <div class="section">
           <div>标准差
           <div>标准差
-            <el-tooltip effect="dark" placement="right">
+            <!-- <el-tooltip effect="dark" placement="right">
               <div
               <div
                 slot="content"
                 slot="content"
                 v-html="ruleTips.StandardDeviation"
                 v-html="ruleTips.StandardDeviation"
                 style="line-height: 20px;width:300px"
                 style="line-height: 20px;width:300px"
               ></div>
               ></div>
               <i class="el-icon-question" style="color: #666" />
               <i class="el-icon-question" style="color: #666" />
-            </el-tooltip>
+            </el-tooltip> -->
           </div>
           </div>
           <div class="section-item">
           <div class="section-item">
             <div>滚动期数:</div>
             <div>滚动期数:</div>
@@ -95,14 +99,14 @@
 
 
         <div class="section">
         <div class="section">
           <div>百分位
           <div>百分位
-            <el-tooltip effect="dark" placement="right">
+            <!-- <el-tooltip effect="dark" placement="right">
               <div
               <div
                 slot="content"
                 slot="content"
                 v-html="ruleTips.Percentile"
                 v-html="ruleTips.Percentile"
                 style="line-height: 20px;width:300px"
                 style="line-height: 20px;width:300px"
               ></div>
               ></div>
               <i class="el-icon-question" style="color: #666" />
               <i class="el-icon-question" style="color: #666" />
-            </el-tooltip>
+            </el-tooltip> -->
           </div>
           </div>
           <div class="section-item">
           <div class="section-item">
             <span style="flex-shrink:0;min-width:70px">时间长度:</span>
             <span style="flex-shrink:0;min-width:70px">时间长度:</span>
@@ -130,14 +134,14 @@
 
 
         <div class="section">
         <div class="section">
           <div>频率分布
           <div>频率分布
-            <el-tooltip effect="dark" placement="right">
+            <!-- <el-tooltip effect="dark" placement="right">
               <div
               <div
                 slot="content"
                 slot="content"
                 v-html="ruleTips.FrequencyDistribution"
                 v-html="ruleTips.FrequencyDistribution"
                 style="line-height: 20px;width:300px"
                 style="line-height: 20px;width:300px"
               ></div>
               ></div>
               <i class="el-icon-question" style="color: #666" />
               <i class="el-icon-question" style="color: #666" />
-            </el-tooltip>
+            </el-tooltip> -->
           </div>
           </div>
           <div class="section-item">
           <div class="section-item">
             <span style="flex-shrink:0;min-width:70px">时间段:</span>
             <span style="flex-shrink:0;min-width:70px">时间段:</span>
@@ -271,6 +275,12 @@
       :chartData="chartData"
       :chartData="chartData"
       @saveBack="saveEdbBack"
       @saveBack="saveEdbBack"
     />
     />
+    <!-- 操作说明 -->
+    <ExplainDialog 
+        textArrName="statisticFeatureListTextArr"
+        :show-explain="showExplain"
+        @close="showExplain = false"
+    />
   </div>
   </div>
 </template>
 </template>
 
 
@@ -283,9 +293,10 @@ import selectTarget from './components/selectTarget.vue'
 import chartCard from './components/chartCard.vue';
 import chartCard from './components/chartCard.vue';
 import SaveChartOther from '@/views/dataEntry_manage/components/SaveChartOther';
 import SaveChartOther from '@/views/dataEntry_manage/components/SaveChartOther';
 import saveChartToBase from './components/saveChartTobaseDia.vue';
 import saveChartToBase from './components/saveChartTobaseDia.vue';
-import saveEdbToBase from './components/saveEdbToBaseDia.vue'
+import saveEdbToBase from './components/saveEdbToBaseDia.vue';
+import ExplainDialog from './components/explainDialog.vue';
 export default {
 export default {
-  components: { selectTarget,chartCard,SaveChartOther,saveChartToBase,saveEdbToBase },
+  components: { selectTarget,chartCard,SaveChartOther,saveChartToBase,saveEdbToBase,ExplainDialog },
   directives: {
   directives: {
     drag(el, bindings) {
     drag(el, bindings) {
       el.onmousedown = function (e) {
       el.onmousedown = function (e) {
@@ -393,6 +404,8 @@ export default {
       isSaveEdbToBase: false,
       isSaveEdbToBase: false,
 
 
       oldEdbInfoType: 0,//原指标来源
       oldEdbInfoType: 0,//原指标来源
+      //操作说明弹窗
+      showExplain:false
     };
     };
   },
   },
   methods: {
   methods: {
@@ -672,6 +685,9 @@ export default {
       padding: 15px 20px;
       padding: 15px 20px;
       border-bottom: 1px solid #ececec;
       border-bottom: 1px solid #ececec;
       box-shadow: 0px 3px 6px rgba(167, 167, 167, 0.09);
       box-shadow: 0px 3px 6px rgba(167, 167, 167, 0.09);
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
     }
     }
     .left-min {
     .left-min {
       padding: 20px;
       padding: 20px;

+ 106 - 88
src/views/classify_manage/classifyEnlist.vue

@@ -23,7 +23,7 @@
         </el-input>
         </el-input>
         </div>
         </div>
       </div>
       </div>
-      <div class="tabs-box" :style="authTabsOpt.length>1?'':'border:none'"
+      <!-- <div class="tabs-box" :style="authTabsOpt.length>1?'':'border:none'"
         v-if="authTabsOpt.length">
         v-if="authTabsOpt.length">
         <span 
         <span 
           v-for="item in authTabsOpt" 
           v-for="item in authTabsOpt" 
@@ -31,10 +31,10 @@
           :class="item.val==aTab?'active':''"
           :class="item.val==aTab?'active':''"
           @click="handleTabChange(item)"
           @click="handleTabChange(item)"
         >{{item.name}}</span>
         >{{item.name}}</span>
-      </div>
+      </div> -->
 
 
+      <!-- v-if="authTabsOpt.length" -->
       <el-table
       <el-table
-        v-if="authTabsOpt.length"
         :data="tableData"
         :data="tableData"
         v-loading="dataLoading"
         v-loading="dataLoading"
         row-class-name="tableRowClassName"
         row-class-name="tableRowClassName"
@@ -42,7 +42,7 @@
         :default-expand-all="isexpand"
         :default-expand-all="isexpand"
         row-key="Id"
         row-key="Id"
         style="border: 1px solid #dcdfe6"
         style="border: 1px solid #dcdfe6"
-        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
+        :tree-props="{ children: 'Child', hasChildren: 'hasChildren' }"
       >
       >
         <el-table-column
         <el-table-column
           v-for="item in tableColums"
           v-for="item in tableColums"
@@ -54,21 +54,24 @@
           :align="item.align || 'left'"
           :align="item.align || 'left'"
           :default-expand-all="isexpand"
           :default-expand-all="isexpand"
           row-key="Id"
           row-key="Id"
-          :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
+          :tree-props="{ children: 'Child', hasChildren: 'hasChildren' }"
         >
         >
           <template slot-scope="{ row }">
           <template slot-scope="{ row }">
             <span v-if="item.prop === 'ClassifyOne'">{{
             <span v-if="item.prop === 'ClassifyOne'">{{
-              row.ischild ? "" : row.ClassifyName
+              row.level==1 ? row.ClassifyName : "" 
             }}</span>
             }}</span>
             <span v-else-if="item.prop === 'ClassifyTwo'">{{
             <span v-else-if="item.prop === 'ClassifyTwo'">{{
-              row.ischild ? row.ClassifyName : ""
+              row.level==2 ? row.ClassifyName : ""
+            }}</span>
+           <span v-else-if="item.prop === 'ClassifyThree'">{{
+              row.level==3 ? row.ClassifyName : ""
             }}</span>
             }}</span>
 
 
             <div v-else-if="item.prop === 'handle'">
             <div v-else-if="item.prop === 'handle'">
               <span 
               <span 
                 
                 
                 class="editsty"
                 class="editsty"
-                v-if="row.ischild&&isAuthSetBtnShow" 
+                v-if="row.level==3&&isAuthSetBtnShow" 
                 @click="handleShowSetVariety(row)"
                 @click="handleShowSetVariety(row)"
               >权限配置</span>
               >权限配置</span>
               <span class="editsty" v-if="isEditBtnShow"
               <span class="editsty" v-if="isEditBtnShow"
@@ -107,7 +110,7 @@
           label-position="left"
           label-position="left"
           hide-required-asterisk
           hide-required-asterisk
           label-width="80px">
           label-width="80px">
-          <el-form-item prop="type" label="所属模块">
+          <!-- <el-form-item prop="type" label="所属模块">
             <el-select 
             <el-select 
               v-model="classifyForm.type"
               v-model="classifyForm.type"
               placeholder="请选择所属模块"
               placeholder="请选择所属模块"
@@ -119,7 +122,7 @@
             <el-option v-for="item in authTabsOpt" :key="item.val" :label="item.name" :value="item.val"/>
             <el-option v-for="item in authTabsOpt" :key="item.val" :label="item.name" :value="item.val"/>
             </el-select>
             </el-select>
 
 
-          </el-form-item>
+          </el-form-item> -->
           <el-form-item prop="classify_name" label="分类名称">
           <el-form-item prop="classify_name" label="分类名称">
             <el-input 
             <el-input 
               type="text" 
               type="text" 
@@ -130,7 +133,7 @@
             />
             />
           </el-form-item>
           </el-form-item>
           <el-form-item prop="parent_id" label="上级分类">
           <el-form-item prop="parent_id" label="上级分类">
-            <el-select 
+            <!-- <el-select 
               v-model="classifyForm.parent_id"
               v-model="classifyForm.parent_id"
               placeholder="请选择"
               placeholder="请选择"
               size="small"
               size="small"
@@ -138,7 +141,9 @@
             >
             >
               <el-option label="无" :value="0"/>
               <el-option label="无" :value="0"/>
               <el-option v-for="item in classifyparentArr" :key="item.ClassifyName" :label="item.ClassifyName" :value="item.Id"/>
               <el-option v-for="item in classifyparentArr" :key="item.ClassifyName" :label="item.ClassifyName" :value="item.Id"/>
-            </el-select>
+            </el-select> -->
+            <el-cascader :options="classifyparentArr" v-model="classifyForm.parent_id" placeholder="请选择"
+            :props="{value:'Id',label:'ClassifyName',children:'Child',checkStrictly:true,emitPath:false}" style="min-width:400px;"></el-cascader>
           </el-form-item>
           </el-form-item>
           <el-form-item label="后台排序" prop="sort">
           <el-form-item label="后台排序" prop="sort">
             <el-input 
             <el-input 
@@ -200,72 +205,71 @@ export default {
   computed:{
   computed:{
       //添加分类是否展示
       //添加分类是否展示
       isAddClassifyBtnShow(){
       isAddClassifyBtnShow(){
-          if(this.aTab===0&&this.authTabsOpt.length){
+          // if(this.aTab===0&&this.authTabsOpt.length){
               return this.permissionBtn.checkPermissionBtn(
               return this.permissionBtn.checkPermissionBtn(
                   this.permissionBtn.enClassifyBtn.classifyList_enClassify_rpAddClassify
                   this.permissionBtn.enClassifyBtn.classifyList_enClassify_rpAddClassify
                 )
                 )
-          }
-          if(this.aTab===1&&this.authTabsOpt.length){
-            return this.permissionBtn.checkPermissionBtn(
-                  this.permissionBtn.enClassifyBtn.classifyList_enClassify_rsAddClassify
-                )
-          }
-        return false
+          // }
+          // if(this.aTab===1&&this.authTabsOpt.length){
+          //   return this.permissionBtn.checkPermissionBtn(
+          //         this.permissionBtn.enClassifyBtn.classifyList_enClassify_rsAddClassify
+          //       )
+          // }
       },
       },
       //编辑是否展示
       //编辑是否展示
       isEditBtnShow(){
       isEditBtnShow(){
-        if(this.aTab===0){
+        // if(this.aTab===0){
                 return this.permissionBtn.checkPermissionBtn(
                 return this.permissionBtn.checkPermissionBtn(
                     this.permissionBtn.enClassifyBtn.classifyList_enClassify_rpEdit
                     this.permissionBtn.enClassifyBtn.classifyList_enClassify_rpEdit
                 )
                 )
-            }else{
-            return this.permissionBtn.checkPermissionBtn(
-                    this.permissionBtn.enClassifyBtn.classifyList_enClassify_rsEdit
-                )
-            }
+            // }else{
+            // return this.permissionBtn.checkPermissionBtn(
+            //         this.permissionBtn.enClassifyBtn.classifyList_enClassify_rsEdit
+            //     )
+            // }
       },
       },
       //删除是否展示
       //删除是否展示
       isDeleteBtnShow(){
       isDeleteBtnShow(){
-        if(this.aTab===0){
+        // if(this.aTab===0){
                 return this.permissionBtn.checkPermissionBtn(
                 return this.permissionBtn.checkPermissionBtn(
                     this.permissionBtn.enClassifyBtn.classifyList_enClassify_rpDel
                     this.permissionBtn.enClassifyBtn.classifyList_enClassify_rpDel
                 )
                 )
-            }else{
-            return this.permissionBtn.checkPermissionBtn(
-                    this.permissionBtn.enClassifyBtn.classifyList_enClassify_rsDel
-                )
-            }
+            // }else{
+            // return this.permissionBtn.checkPermissionBtn(
+            //         this.permissionBtn.enClassifyBtn.classifyList_enClassify_rsDel
+            //     )
+            // }
       },
       },
       //权限设置是否展示
       //权限设置是否展示
       isAuthSetBtnShow(){
       isAuthSetBtnShow(){
-        if(this.aTab===0){
+        // if(this.aTab===0){
                 return this.permissionBtn.checkPermissionBtn(
                 return this.permissionBtn.checkPermissionBtn(
                     this.permissionBtn.enClassifyBtn.classifyList_enClassify_rpAuthSetting
                     this.permissionBtn.enClassifyBtn.classifyList_enClassify_rpAuthSetting
                 )
                 )
-            }else{
-            return this.permissionBtn.checkPermissionBtn(
-                    this.permissionBtn.enClassifyBtn.classifyList_enClassify_rsAuthSetting
-                )
-            }
-      },
-      //英文研报、线上路演选项卡
-      authTabsOpt(){
-        const isShowTabRoadshow = this.permissionBtn.checkPermissionBtn(
-            this.permissionBtn.enClassifyBtn.classifyList_enClassify_roadshow
-        )
-        const isShowTabReport = this.permissionBtn.checkPermissionBtn(
-            this.permissionBtn.enClassifyBtn.classifyList_enClassify_report
-        )
-        //没时间写更好的写法了,有空再优化
-        let authTabs = []
-        if(isShowTabReport){
-            authTabs.push(this.tabsOpt[0])
-        }
-        if(isShowTabRoadshow){
-            authTabs.push(this.tabsOpt[1])
-        }
-        return authTabs
+            // }else{
+            // return this.permissionBtn.checkPermissionBtn(
+            //         this.permissionBtn.enClassifyBtn.classifyList_enClassify_rsAuthSetting
+            //     )
+            // }
       },
       },
+      //英文研报、线上路演选项卡 - ETA1.1.7 不区分英文研报和线上路演,统一用英文研报的 按钮标识
+      // authTabsOpt(){
+      //   const isShowTabRoadshow = this.permissionBtn.checkPermissionBtn(
+      //       this.permissionBtn.enClassifyBtn.classifyList_enClassify_roadshow
+      //   )
+      //   const isShowTabReport = this.permissionBtn.checkPermissionBtn(
+      //       this.permissionBtn.enClassifyBtn.classifyList_enClassify_report
+      //   )
+      //   //没时间写更好的写法了,有空再优化
+      //   let authTabs = []
+      //   if(isShowTabReport){
+      //       authTabs.push(this.tabsOpt[0])
+      //   }
+      //   if(isShowTabRoadshow){
+      //       authTabs.push(this.tabsOpt[1])
+      //   }
+      //   return authTabs
+      // },
       //添加分类时的选项框
       //添加分类时的选项框
   },
   },
   data() {
   data() {
@@ -287,6 +291,10 @@ export default {
           label: "二级分类",
           label: "二级分类",
           prop: "ClassifyTwo",
           prop: "ClassifyTwo",
         },
         },
+        {
+          label: "三级分类",
+          prop: "ClassifyThree",
+        },
         {
         {
           label: "操作",
           label: "操作",
           prop: "handle",
           prop: "handle",
@@ -299,7 +307,7 @@ export default {
         title: '',
         title: '',
         show: false,
         show: false,
         classify_name: '',
         classify_name: '',
-        parent_id: 0,
+        parent_id: "0", // 数字的0,级联选择器不回显
         sort: 1,
         sort: 1,
         classify_id: '',
         classify_id: '',
 
 
@@ -309,7 +317,7 @@ export default {
         classify_name: [{ required:true,message:'请输入分类名称',trigger:'blur'}],
         classify_name: [{ required:true,message:'请输入分类名称',trigger:'blur'}],
         parent_id: [{ required:true,message:'请输入',trigger:'blur'}],
         parent_id: [{ required:true,message:'请输入',trigger:'blur'}],
         sort: [{ required:true,message:'请输入数字',trigger:'blur'}],
         sort: [{ required:true,message:'请输入数字',trigger:'blur'}],
-        type: [{ required:true,message:'请选择',trigger:'change'}]
+        // type: [{ required:true,message:'请选择',trigger:'change'}]
       },
       },
 
 
       tabsOpt:[
       tabsOpt:[
@@ -362,7 +370,7 @@ export default {
         CurrentIndex: this.page_no,
         CurrentIndex: this.page_no,
         PageSize: 15,
         PageSize: 15,
         KeyWord: this.searchform.key_word,
         KeyWord: this.searchform.key_word,
-        ClassifyType:this.aTab
+        // ClassifyType:this.aTab
       };
       };
       classifyEnInterface.classifyList(params).then(res => {
       classifyEnInterface.classifyList(params).then(res => {
         this.dataLoading = false;
         this.dataLoading = false;
@@ -370,25 +378,30 @@ export default {
           this.tableData = res.Data.List || [];
           this.tableData = res.Data.List || [];
           this.total = parseInt(res.Data.Paging.Totals);
           this.total = parseInt(res.Data.Paging.Totals);
           this.tableData.forEach((item, index) => {
           this.tableData.forEach((item, index) => {
+            item.level = 1
             if (item.Child) {
             if (item.Child) {
               // item.hasChildren=true;
               // item.hasChildren=true;
-              let childnode = JSON.parse(JSON.stringify(item.Child));
-              childnode.forEach((itemchild, i) => {
-                itemchild.ischild = true;
+              // let childnode = JSON.parse(JSON.stringify(item.Child));
+              item.Child.forEach((itemchild, i) => {
+                itemchild.level = 2;
+                itemchild.Child && itemchild.Child.forEach((itemChildTwo,i)=>{
+                  itemChildTwo.level=3
+                })
               });
               });
-              item.children = childnode;
+              // item.children = childnode;
             }
             }
           });
           });
+          console.log(this.tableData,'this.tableData');
         }
         }
       });
       });
     },
     },
 
 
-    addClassify() {
+    addClassify() {      
       this.classifyForm = {
       this.classifyForm = {
         title: '新增英文分类',
         title: '新增英文分类',
         show: true,
         show: true,
         classify_name: '',
         classify_name: '',
-        parent_id: 0,
+        parent_id: "0",
         sort: 1,
         sort: 1,
         type:0
         type:0
       }
       }
@@ -396,16 +409,13 @@ export default {
 
 
     /* 获取一级分类 */
     /* 获取一级分类 */
     getClassifyOne() {
     getClassifyOne() {
-      classifyEnInterface.classifyOne({ CurrentIndex: 1, PageSize: 9999,ClassifyType:this.classifyForm.type })
+      classifyEnInterface.classifyOne({ CurrentIndex: 1, PageSize: 9999 /**,ClassifyType:this.classifyForm.type */ })
         .then(res => {
         .then(res => {
           if(res.Ret !== 200) return
           if(res.Ret !== 200) return
 
 
-          this.classifyparentArr=[];
-					res.Data.List && res.Data.List.forEach((item,i)=>{
-							item.Id=parseInt(item.Id);
+          this.classifyparentArr=res.Data.List || [];
 
 
-							if(!item.Child) this.classifyparentArr.push(item);
-					});
+          this.classifyparentArr.unshift({Id:"0",ClassifyName:'无',Child:null})
         })
         })
     },
     },
 
 
@@ -424,7 +434,7 @@ export default {
         title: '编辑分类',
         title: '编辑分类',
         show: true,
         show: true,
         classify_name: ClassifyName,
         classify_name: ClassifyName,
-        parent_id: ParentId,
+        parent_id: ParentId==0?0+'':ParentId,//数字的0,'无'不回显
         sort: Sort,
         sort: Sort,
         classify_id: Id,
         classify_id: Id,
         type:ClassifyType
         type:ClassifyType
@@ -453,17 +463,19 @@ export default {
     /* 保存分类 */
     /* 保存分类 */
     async setClassifyHandle() {
     async setClassifyHandle() {
       await this.$refs.formRef.validate();
       await this.$refs.formRef.validate();
-
+      console.log(this.classifyForm);
+      // return 
       const { classify_name,parent_id,sort,classify_id } = this.classifyForm;
       const { classify_name,parent_id,sort,classify_id } = this.classifyForm;
       let params = {
       let params = {
         ClassifyName: classify_name,
         ClassifyName: classify_name,
-        ParentId: parent_id,
+        ParentId: parseInt(parent_id),
         Sort: sort
         Sort: sort
       }
       }
 
 
       const { Ret,Msg } = classify_id 
       const { Ret,Msg } = classify_id 
         ? await classifyEnInterface.classifyEdit({...params,ClassifyId: classify_id}) 
         ? await classifyEnInterface.classifyEdit({...params,ClassifyId: classify_id}) 
-        : await classifyEnInterface.classifyAdd({...params,ClassifyType:this.classifyForm.type})
+        : await classifyEnInterface.classifyAdd(params)
+        // : await classifyEnInterface.classifyAdd({...params,ClassifyType:this.classifyForm.type})
 
 
       if(Ret !== 200) return
       if(Ret !== 200) return
       this.$message.success(Msg)
       this.$message.success(Msg)
@@ -478,25 +490,25 @@ export default {
     },
     },
 
 
     //切换分类
     //切换分类
-    handleTabChange(item){
-      this.aTab=item.val
-      this.page_no=1
-      this.searchform.key_word=''
-      this.getList()
-    },
+    // handleTabChange(item){
+    //   this.aTab=item.val
+    //   this.page_no=1
+    //   this.searchform.key_word=''
+    //   this.getList()
+    // },
 
 
     //新增分类时切换分类
     //新增分类时切换分类
-    FormClassifyChange(){
-      this.classifyForm.parent_id=0
-      this.getClassifyOne()
-    }
+    // FormClassifyChange(){
+    //   this.classifyForm.parent_id=0
+    //   this.getClassifyOne()
+    // }
   },
   },
 
 
   mounted() {
   mounted() {
-      if(this.authTabsOpt.length){
-        this.aTab = this.authTabsOpt[0].val
+      // if(this.authTabsOpt.length){
+      //   this.aTab = this.authTabsOpt[0].val
         this.getList();
         this.getList();
-      }
+      // }
   },
   },
 };
 };
 </script>
 </script>
@@ -542,3 +554,9 @@ export default {
   }
   }
 }
 }
 </style>
 </style>
+<style lang="scss">
+.el-cascader .el-input{
+  width: 100%;
+}
+
+</style>

+ 23 - 3
src/views/dataEntry_manage/addChart.vue

@@ -57,13 +57,28 @@
 						/>
 						/>
 					</el-form-item>
 					</el-form-item>
 					<el-form-item label="图表单位" prop="Unit" v-if="chartInfo.ChartType===7">
 					<el-form-item label="图表单位" prop="Unit" v-if="chartInfo.ChartType===7">
-						<el-input
+						<!-- <el-input
 							v-model="chartInfo.Unit"
 							v-model="chartInfo.Unit"
 							style="width: 90%"
 							style="width: 90%"
 							placeholder="请输入图表单位"
 							placeholder="请输入图表单位"
 							clearable
 							clearable
 							@change="changeUnit"
 							@change="changeUnit"
-						/>
+						/> -->
+						<el-select
+							v-model="chartInfo.Unit"
+							filterable
+							allow-create
+							default-first-option
+							clearable
+							@change="changeUnit"
+							placeholder="请输入图表单位">
+							<el-option
+								v-for="item in UnitOptions"
+								:key="item"
+								:label="item"
+								:value="item">
+							</el-option>
+						</el-select>
 					</el-form-item>
 					</el-form-item>
 				</el-form>
 				</el-form>
 
 
@@ -315,6 +330,7 @@
 						v-if="chartInfo.ChartType===10"
 						v-if="chartInfo.ChartType===10"
 						ref="SectionScatterOptRef"
 						ref="SectionScatterOptRef"
 						@getData="getSectionScatterData"
 						@getData="getSectionScatterData"
+						@modifySeriesName="IsNameDefault = false"
 					/>
 					/>
         </div>
         </div>
 			</div>
 			</div>
@@ -551,6 +567,7 @@
 <script>
 <script>
 import { dataBaseInterface } from '@/api/api.js';
 import { dataBaseInterface } from '@/api/api.js';
 import { chartSetMixin } from './mixins/chartPublic';
 import { chartSetMixin } from './mixins/chartPublic';
+import {unitArr} from '@/utils/defaultOptions.js';
 import addOrEditMixn from './mixins/addOreditMixin';
 import addOrEditMixn from './mixins/addOreditMixin';
 import Chart from './components/chart';
 import Chart from './components/chart';
 import DateChooseDia from './components/DateChooseDia';
 import DateChooseDia from './components/DateChooseDia';
@@ -626,7 +643,10 @@ export default {
 			season_year:'',//季节图时间段
 			season_year:'',//季节图时间段
 			activeNames:'',
 			activeNames:'',
 
 
-			needWatch: true
+			needWatch: true,
+			IsNameDefault:true,
+
+			UnitOptions:unitArr
 
 
     };
     };
   },
   },

+ 4 - 3
src/views/dataEntry_manage/adjustdata/adjustData.vue

@@ -68,7 +68,8 @@
                 label: 'ClassifyName',
                 label: 'ClassifyName',
                 value: 'ClassifyId',
                 value: 'ClassifyId',
                 children: 'Children',
                 children: 'Children',
-                emitPath: false
+                emitPath: false,
+                checkStrictly: true
               }"
               }"
               clearable
               clearable
               placeholder="请选择指标目录"
               placeholder="请选择指标目录"
@@ -351,7 +352,7 @@ export default {
 		getMenu() {
 		getMenu() {
 			dataBaseInterface.menuListV3().then((res) => {
 			dataBaseInterface.menuListV3().then((res) => {
 				if (res.Ret === 200) {
 				if (res.Ret === 200) {
-					//this.filterNodes(res.Data.AllNodes)
+					this.filterNodes(res.Data.AllNodes||[])
 					this.classifyOptions = res.Data.AllNodes || [];
 					this.classifyOptions = res.Data.AllNodes || [];
 				}
 				}
 			});
 			});
@@ -361,7 +362,7 @@ export default {
 			arr.length &&
 			arr.length &&
 				arr.forEach((item) => {
 				arr.forEach((item) => {
 					item.Children.length && this.filterNodes(item.Children);
 					item.Children.length && this.filterNodes(item.Children);
-					if (item.Level === 2) {
+					if (!item.Children.length) {
 						delete item.Children;
 						delete item.Children;
 					}
 					}
 				});
 				});

+ 5 - 92
src/views/dataEntry_manage/chartSetting.vue

@@ -1671,90 +1671,12 @@ export default {
       this.tableData.forEach((item) => {
       this.tableData.forEach((item) => {
         let edbData = EdbInfoList.find(_ => _.EdbInfoId===item.EdbInfoId);
         let edbData = EdbInfoList.find(_ => _.EdbInfoId===item.EdbInfoId);
         item.DataList = edbData.DataList;
         item.DataList = edbData.DataList;
+        //更新起始时间和最近更新时间
+        item.StartDate = edbData.StartDate;
+        item.ModifyTime = edbData.ModifyTime;
+
         if(edbData.EdbInfoCategoryType===1) item.MoveLatestDate = edbData.MoveLatestDate;
         if(edbData.EdbInfoCategoryType===1) item.MoveLatestDate = edbData.MoveLatestDate;
       });
       });
-
-
-
-      // // 判断图标类型 设置参数
-      // let params =
-      //   this.sameOptionType.includes(this.selected_chartType)
-      //     ? {
-      //         ChartInfoId: this.selected_chartid,
-      //         DateType: this.year_select,
-      //         StartDate:
-      //           this.year_select === 5 || this.year_select === 6
-      //             ? this.select_date[0]
-      //             : '',
-      //         EndDate: this.year_select === 5 ? this.select_date[1] : '',
-      //       }
-      //     : {
-      //         ChartInfoId: this.selected_chartid,
-      //         Calendar: this.calendar_type,
-      //         SeasonStartDate: this.season_year ? this.season_year[0] : '',
-      //         SeasonEndDate: this.season_year ? this.season_year[1] : '',
-      //       };
-      // dataBaseInterface.chartInfo(params).then((res) => {
-      //   if (res.Ret === 200) {
-      //     this.chartInfo = res.Data.ChartInfo;
-      //     let beforeOptions = sessionStorage.getItem('beforeOptions')
-      //       ? JSON.parse(sessionStorage.getItem('beforeOptions'))
-      //       : '';
-      //     //合并缓存配置和新的数据
-      //     let newarr = res.Data.EdbInfoList.map((item, index) => {
-      //       if (beforeOptions && type === 'refresh') {
-      //         const DataList = item.DataList;
-      //         return {
-      //           ...beforeOptions[index],
-      //           DataList,
-      //         };
-      //       } else {
-      //         return item;
-      //       }
-      //     });
-      //     this.tableData = newarr;
-      //     //  刷新最新的指标数据 防止领先配置已保存 指标数据确实原数据的情况 针对正常图
-      //     if (
-      //       type === 'refresh' &&
-      //       beforeOptions &&
-      //       (this.sameOptionType.includes(this.chartInfo.ChartType) && this.chartInfo.ChartType!==5)
-      //     )
-      //       this.refreshTarget();
-      //     sessionStorage.setItem(
-      //       'defaultArr',
-      //       JSON.stringify(res.Data.EdbInfoList)
-      //     );
-      //     if (!type) {
-      //       this.year_select = this.chartInfo.DateType;
-      //       this.select_date = [
-      //         this.chartInfo.StartDate,
-      //         this.chartInfo.EndDate,
-      //       ];
-      //       this.calendar_type = this.chartInfo.Calendar; //日历类型
-      //       // this.season_year = [ this.chartInfo.SeasonStartDate, this.chartInfo.SeasonEndDate ];
-      //       this.dateTip =
-      //         this.chartInfo.DateType === 5
-      //           ? `${this.chartInfo.StartDate}~${this.chartInfo.EndDate}`
-      //           : this.chartInfo.DateType === 6
-      //           ? `${this.chartInfo.StartDate}~至今`
-      //           : '请选择时间段';
-
-      //       //新图表类型 依赖数据不同单独init 数据
-      //       const typeInitMap = {
-      //         7: this.initBarData,
-      //         10: this.initSectionScatterData
-      //       }
-      //       typeInitMap[this.chartInfo.ChartType] && typeInitMap[this.chartInfo.ChartType](res.Data);
-            
-      //     }
-      //     //将指标添加进标签列表中
-      //       const {ChartNameEn,ChartName,ChartInfoId,UniqueCode,ChartClassifyId}=res.Data.ChartInfo
-      //       this.addLabel({code:UniqueCode,id:ChartInfoId,classifyId:ChartClassifyId,EdbName:ChartName,EdbNameEn:ChartNameEn,chartData:res.Data.ChartInfo})
-      //       this.defaultShowNodes=this.findParentNodeHandle(this.treeData,ChartClassifyId)
-      //       this.changeTreeNode()
-      //   }
-        
-      // });
     },
     },
 
 
     /* 搜索 */
     /* 搜索 */
@@ -2243,16 +2165,7 @@ export default {
     slideHandle() {
     slideHandle() {
       this.isSlideLeft = !this.isSlideLeft;
       this.isSlideLeft = !this.isSlideLeft;
     },
     },
-    /* 保存图表当前配置项 上下限 */
-    saveNowOptions() {
-      // const dataArr = _.cloneDeep(this.tableData);
-      // dataArr.forEach((item) => {
-      //   item.MaxData = Number(item.MaxData);
-      //   item.MinData = Number(item.MinData);
-      //   delete item.DataList;
-      // });
-      // sessionStorage.setItem('beforeOptions', JSON.stringify(dataArr));
-    },
+
     /* 季节图切换年份  保持当前配置 */
     /* 季节图切换年份  保持当前配置 */
     seasonYearChange() {
     seasonYearChange() {
       // this.saveNowOptions();
       // this.saveNowOptions();

+ 5 - 4
src/views/dataEntry_manage/codecount/index.vue

@@ -67,6 +67,7 @@
 									label: 'ClassifyName',
 									label: 'ClassifyName',
 									value: 'ClassifyId',
 									value: 'ClassifyId',
 									children: 'Children',
 									children: 'Children',
+									checkStrictly: true
 								}"
 								}"
 								@change="menuChange"
 								@change="menuChange"
 								clearable
 								clearable
@@ -341,7 +342,7 @@ export default {
 				EdbName: edb_name,
 				EdbName: edb_name,
 				Frequency: frequency,
 				Frequency: frequency,
 				Unit: unit,
 				Unit: unit,
-				ClassifyId: menu
+				ClassifyId: menu&&menu[menu.length-1]
 			}
 			}
 			
 			
 			const { Ret,Data } = this.$route.query.edbid ? await dataBaseInterface.editCountCode({ ...params,EdbInfoId: Number(this.$route.query.edbid) }) : await dataBaseInterface.addCountCode(params);
 			const { Ret,Data } = this.$route.query.edbid ? await dataBaseInterface.editCountCode({ ...params,EdbInfoId: Number(this.$route.query.edbid) }) : await dataBaseInterface.addCountCode(params);
@@ -362,7 +363,7 @@ export default {
 		getMenu() {
 		getMenu() {
 			dataBaseInterface.menuListV3().then((res) => {
 			dataBaseInterface.menuListV3().then((res) => {
 				if (res.Ret !== 200) return
 				if (res.Ret !== 200) return
-					//this.filterNodes(res.Data.AllNodes);
+					this.filterNodes(res.Data.AllNodes||[]);
 					this.menuOptions = res.Data.AllNodes || [];
 					this.menuOptions = res.Data.AllNodes || [];
 			});
 			});
 		},
 		},
@@ -371,7 +372,7 @@ export default {
 			arr.length &&
 			arr.length &&
 				arr.forEach((item) => {
 				arr.forEach((item) => {
 					item.Children.length && this.filterNodes(item.Children);
 					item.Children.length && this.filterNodes(item.Children);
-					if (item.Level === 2) {
+					if (!item.Children.length) {
 						delete item.Children;
 						delete item.Children;
 					}
 					}
 				});
 				});
@@ -379,7 +380,7 @@ export default {
 
 
 		/* 选择目录 */
 		/* 选择目录 */
 		menuChange(val) {
 		menuChange(val) {
-			this.formData.menu = val.length ? val[val.length - 1] : '';
+			// this.formData.menu = val.length ? val[val.length - 1] : '';
 		},
 		},
 
 
 		/* 搜索 */
 		/* 搜索 */

+ 51 - 5
src/views/dataEntry_manage/components/satterSeriesDia.vue

@@ -351,6 +351,13 @@ export default {
     },
     },
     serieInfo: {
     serieInfo: {
       type: Object
       type: Object
+    },
+    edbInfoData:{
+        type:Array,
+        default:[]
+    },
+    IsNameDefault:{
+        type:Boolean
     }
     }
   },
   },
   components: { mDialog },
   components: { mDialog },
@@ -392,8 +399,10 @@ export default {
             date: '',
             date: '',
             value: '',
             value: '',
           })).filter(_ =>_.target_id)
           })).filter(_ =>_.target_id)
-        }     
-
+        }
+        //遍历请求xEdbs yEdbs的指标详情,获取最新日期和值
+        this.getEdbData()
+        this.getEdbNewInfo()
       }
       }
     }
     }
   },
   },
@@ -414,6 +423,7 @@ export default {
         xEdbs: [],
         xEdbs: [],
         yEdbs: []
         yEdbs: []
       },
       },
+      edbData:{},
 
 
       form: {
       form: {
         x_title:'',
         x_title:'',
@@ -515,7 +525,7 @@ export default {
             name: item.EdbName,
             name: item.EdbName,
           })
           })
 
 
-          this.form.series_name = this.form.series_name || this.targetInfo.xEdbs[0].date;
+          this.form.series_name = this.IsNameDefault?this.targetInfo.xEdbs[0].date:this.form.series_name;
           this.form.x_unit = this.form.x_unit || item.Unit;
           this.form.x_unit = this.form.x_unit || item.Unit;
         }else {
         }else {
           this.targetInfo.yEdbs.push({
           this.targetInfo.yEdbs.push({
@@ -534,6 +544,9 @@ export default {
     /* 删除指标 */
     /* 删除指标 */
     removeTarget(type,index) {
     removeTarget(type,index) {
       type === 'x' ? this.targetInfo.xEdbs.splice(index,1) : this.targetInfo.yEdbs.splice(index,1);
       type === 'x' ? this.targetInfo.xEdbs.splice(index,1) : this.targetInfo.yEdbs.splice(index,1);
+      if(type === 'x'&&this.IsNameDefault){
+        this.form.series_name = this.targetInfo.xEdbs.length?this.targetInfo.xEdbs[0].date:''
+      }
     },
     },
 
 
     /* 保存 */
     /* 保存 */
@@ -595,6 +608,10 @@ export default {
         edbs: arr
         edbs: arr
       }
       }
       this.$emit('saveCallback',params)
       this.$emit('saveCallback',params)
+      //如果没修改过,且保存时值不相等,则此次保存视为修改
+      if(params.series_name!==xEdbs[0].date&&this.IsNameDefault){
+        this.$emit('modifySeriesName')
+      }
       this.cancelHandle()
       this.cancelHandle()
     },
     },
 
 
@@ -640,13 +657,13 @@ export default {
           target_id: item.EdbInfoId,
           target_id: item.EdbInfoId,
           target_name: item.EdbName,
           target_name: item.EdbName,
           date: item.LatestDate,
           date: item.LatestDate,
-          value: '',
+          value: item.LatestValue,
           name: item.EdbName,
           name: item.EdbName,
         } : {
         } : {
           target_id: item.EdbInfoId,
           target_id: item.EdbInfoId,
           target_name: item.EdbName,
           target_name: item.EdbName,
           date: item.LatestDate,
           date: item.LatestDate,
-          value: '',
+          value: item.LatestValue,
         }
         }
       }else {
       }else {
         this.replaceForm.item = { date: '' }
         this.replaceForm.item = { date: '' }
@@ -659,6 +676,9 @@ export default {
       const { index,type,item } = this.replaceForm;
       const { index,type,item } = this.replaceForm;
 
 
       type==='x' ? this.targetInfo.xEdbs.splice(index,1,item) : this.targetInfo.yEdbs.splice(index,1,item);
       type==='x' ? this.targetInfo.xEdbs.splice(index,1,item) : this.targetInfo.yEdbs.splice(index,1,item);
+      if(type==='x'&&index===0&&this.IsNameDefault){
+        this.form.series_name = this.targetInfo.xEdbs[0].date;
+      }
       this.cancelReplace()
       this.cancelReplace()
     },
     },
 
 
@@ -678,6 +698,32 @@ export default {
       
       
       this.$emit("update:show", false);
       this.$emit("update:show", false);
     },
     },
+    getEdbData(){
+        this.edbInfoData.forEach(e=>{
+            if(!this.edbData[e.EdbInfoId]){
+                this.edbData[e.EdbInfoId] = {
+                    date:e.LatestDate,
+                    value:e.LatestValue
+                }
+            }
+        })
+    },
+    //获取指标的最新日期和值
+    getEdbNewInfo(){
+        const {xEdbs,yEdbs} = this.targetInfo
+        xEdbs.forEach(x=>{
+            if(this.edbData[x.target_id]){
+                x.date = this.edbData[x.target_id].date
+                x.value = this.edbData[x.target_id].value
+            }
+        })
+        yEdbs.forEach(y=>{
+            if(this.edbData[y.target_id]){
+                y.date = this.edbData[y.target_id].date
+                y.value = this.edbData[y.target_id].value
+            }
+        })
+    }
   }
   }
 }
 }
 </script>
 </script>

+ 11 - 0
src/views/dataEntry_manage/components/sectionalScatterOption.vue

@@ -54,7 +54,10 @@
     <satterSeriesDia
     <satterSeriesDia
       :show.sync="isOpenSeriesDialog"
       :show.sync="isOpenSeriesDialog"
       :serieInfo="seriesArr[0]"
       :serieInfo="seriesArr[0]"
+      :edbInfoData="edbInfoData"
+      :IsNameDefault="IsNameDefault"
       @saveCallback="saveSeriesOpt"
       @saveCallback="saveSeriesOpt"
+      @modifySeriesName="$emit('modifySeriesName')"
     />
     />
 
 
     <!-- 添加其他系列 -->
     <!-- 添加其他系列 -->
@@ -166,6 +169,14 @@ export default {
   props: {
   props: {
     initData: {
     initData: {
       default: null
       default: null
+    },
+    edbInfoData:{
+        type:Array,
+        default:[]
+    },
+    IsNameDefault:{
+        type:Boolean,
+        default:true
     }
     }
   },
   },
   data() {
   data() {

+ 23 - 8
src/views/dataEntry_manage/databaseComponents/batchComptedDialog.vue

@@ -15,7 +15,7 @@
 				:src="$icons.computed"
 				:src="$icons.computed"
 				style="color: #fff; width: 16px; height: 16px; margin-right: 5px"
 				style="color: #fff; width: 16px; height: 16px; margin-right: 5px"
 			/>
 			/>
-			<span style="font-size: 16px">{{ switchType.get(type) }}</span>
+			<span style="font-size: 16px">{{ titleMap.get(type) }}</span>
 		</div>
 		</div>
 
 
     <div class="cont">
     <div class="cont">
@@ -84,7 +84,7 @@
 					<selectUnit 
 					<selectUnit 
 						v-model="list.unit" 
 						v-model="list.unit" 
 						style="width: 15%;margin: 0 10px" 
 						style="width: 15%;margin: 0 10px" 
-						:disabled="[6,7,32,33].includes(type)"
+						:disabled="[6,7,32,33,75].includes(type)"
 					/>
 					/>
           <el-input
           <el-input
             v-if="[8,12,13,39,43,44].includes(type)"
             v-if="[8,12,13,39,43,44].includes(type)"
@@ -99,7 +99,7 @@
 						placeholder="请选择频率"
 						placeholder="请选择频率"
 						style="width: 20%"
 						style="width: 20%"
 						clearable
 						clearable
-            :disabled="[6,7,32,33,5,42,61,64,63,66].includes(type)"
+            :disabled="[6,7,32,33,5,42,61,64,63,66,75].includes(type)"
 					>
 					>
 						<el-option
 						<el-option
 							v-for="item in frequencyArr"
 							v-for="item in frequencyArr"
@@ -119,7 +119,7 @@
 				style="margin-right: 20px"
 				style="margin-right: 20px"
 				@click="saveHandle"
 				@click="saveHandle"
 				:loading="loading"
 				:loading="loading"
-				>{{loading ? '计算中...' : save_txts.get(type)}}</el-button
+				>{{loading ? '计算中...' : saveBtnMap.get(type)}}</el-button
 			>
 			>
 			<el-button type="primary" plain @click="cancelHandle('cancel')">取消</el-button>
 			<el-button type="primary" plain @click="cancelHandle('cancel')">取消</el-button>
 		</div>
 		</div>
@@ -199,7 +199,7 @@ export default {
 				},
 				},
       ],
       ],
 
 
-			switchType: new Map([
+			titleMap: new Map([
 				[6,'同比值'],
 				[6,'同比值'],
 				[7,'同差值'],
 				[7,'同差值'],
 				[8,'N数值移动平均计算'],
 				[8,'N数值移动平均计算'],
@@ -220,8 +220,9 @@ export default {
 				[64,'累计值转月/季值'],
 				[64,'累计值转月/季值'],
 				[65,'累计值'],
 				[65,'累计值'],
 				[66,'累计值'],
 				[66,'累计值'],
+				[75,'日均值']
 			]),//标题
 			]),//标题
-			save_txts: new Map([
+			saveBtnMap: new Map([
 				[6,'同比值计算'],
 				[6,'同比值计算'],
 				[7,'同差值计算'],
 				[7,'同差值计算'],
 				[8,'移动平均计算'],
 				[8,'移动平均计算'],
@@ -242,6 +243,7 @@ export default {
 				[64,'转季值计算'],
 				[64,'转季值计算'],
 				[65,'累计值计算'],
 				[65,'累计值计算'],
 				[66,'年初至今计算'],
 				[66,'年初至今计算'],
+				[75,'日均值计算']
 			]),//保存文案
 			]),//保存文案
 			unitArr,
 			unitArr,
 			options: [],
 			options: [],
@@ -249,6 +251,7 @@ export default {
 				label: 'ClassifyName',
 				label: 'ClassifyName',
 				value: 'ClassifyId',
 				value: 'ClassifyId',
 				children: 'Children',
 				children: 'Children',
+				checkStrictly: true
 			},
 			},
 			frequencyArr: ['日度', '周度','旬度', '月度', '季度', '年度'],
 			frequencyArr: ['日度', '周度','旬度', '月度', '季度', '年度'],
 			fre_options: ['天','周','月','季','年'],
 			fre_options: ['天','周','月','季','年'],
@@ -326,6 +329,7 @@ export default {
             list.targetName = default_opt.targetName;
             list.targetName = default_opt.targetName;
             list.unit = default_opt.unit;
             list.unit = default_opt.unit;
             list.frequency = default_opt.frequency;
             list.frequency = default_opt.frequency;
+						list.menu = default_opt.menu||0
 					}
 					}
 				});
 				});
 
 
@@ -374,14 +378,18 @@ export default {
 				: await dataBaseInterface.menuListV3()
 				: await dataBaseInterface.menuListV3()
 				if (res.Ret !== 200) return
 				if (res.Ret !== 200) return
 				//this.edbSource !== 'predict' && this.filterNodes(res.Data.AllNodes);
 				//this.edbSource !== 'predict' && this.filterNodes(res.Data.AllNodes);
+				// this.options = res.Data.AllNodes || [];
+				
+				this.filterNodes(res.Data.AllNodes||[]);
 				this.options = res.Data.AllNodes || [];
 				this.options = res.Data.AllNodes || [];
+				
 		},
 		},
 		// 递归改变第三级目录结构
 		// 递归改变第三级目录结构
 		filterNodes(arr) {
 		filterNodes(arr) {
 			arr.length &&
 			arr.length &&
 				arr.forEach((item) => {
 				arr.forEach((item) => {
 					item.Children.length && this.filterNodes(item.Children);
 					item.Children.length && this.filterNodes(item.Children);
-					if (item.Level === 2) {
+					if (!item.Children.length) {
 						delete item.Children;
 						delete item.Children;
 					}
 					}
 				});
 				});
@@ -431,7 +439,7 @@ export default {
       let params = filterArr.map(item => ({
       let params = filterArr.map(item => ({
         CalculateId: item.tag,
         CalculateId: item.tag,
         CalculateInfo: {
         CalculateInfo: {
-          ClassifyId: item.menu[item.menu.length - 1],
+          ClassifyId: Array.isArray(item.menu)?item.menu[item.menu.length - 1]:item.menu,
           EdbName: item.targetName,
           EdbName: item.targetName,
           Formula: String(item.n_num),
           Formula: String(item.n_num),
           Frequency:item.frequency,
           Frequency:item.frequency,
@@ -578,6 +586,13 @@ export default {
 						unit: '无',
 						unit: '无',
 						frequency: obj.Frequency
 						frequency: obj.Frequency
 					}
 					}
+				case 75: 
+					return {
+						targetName: `${obj.EdbName}日均值`,
+						unit: obj.Unit,
+						frequency: obj.Frequency,
+						menu: obj.ClassifyId,
+					}
 			}
 			}
     }  
     }  
 	},
 	},

+ 6 - 2
src/views/dataEntry_manage/databaseComponents/chartTrendRender.vue

@@ -144,8 +144,10 @@ export default {
 	computed: {
 	computed: {
 
 
 		// 同比,环比,环差,超季节性、 残差展示基础图
 		// 同比,环比,环差,超季节性、 残差展示基础图
+		//ETA1.1.1 所有的计算指标都能展示季节性图
 		isOnlyShowBaseChart() {
 		isOnlyShowBaseChart() {
-			return [6,12,13,35,37].includes(this.chartInfo.Source)
+			/* return [6,12,13,35,37].includes(this.chartInfo.Source) */
+			return false
 		}
 		}
 	},
 	},
 	watch: {
 	watch: {
@@ -269,7 +271,9 @@ export default {
 			});
 			});
 			let form = new FormData();
 			let form = new FormData();
 			form.append("Img", svg);
 			form.append("Img", svg);
-			let { Data } = await dataBaseInterface.uploadImgSvg(form);
+			let { Data,Ret } = await dataBaseInterface.uploadImgSvg(form);
+
+			if(Ret!==200 || !Data) return 
 			await dataBaseInterface.saveEdbChartImg({
 			await dataBaseInterface.saveEdbChartImg({
 				EdbInfoId: EdbInfo.EdbInfoId,
 				EdbInfoId: EdbInfo.EdbInfoId,
 				ImageUrl: Data.ResourceUrl,
 				ImageUrl: Data.ResourceUrl,

+ 3 - 2
src/views/dataEntry_manage/databaseComponents/completeTargetDia.vue

@@ -117,6 +117,7 @@ export default {
 				label: 'ClassifyName',
 				label: 'ClassifyName',
 				value: 'ClassifyId',
 				value: 'ClassifyId',
 				children: 'Children',
 				children: 'Children',
+				checkStrictly: true
 			},
 			},
 			frequencyArr:['日度','周度','旬度','月度','季度','年度']
 			frequencyArr:['日度','周度','旬度','月度','季度','年度']
 		};
 		};
@@ -126,7 +127,7 @@ export default {
 		getMenu() {
 		getMenu() {
 			dataBaseInterface.menuListV3().then(res => {
 			dataBaseInterface.menuListV3().then(res => {
 				if(res.Ret === 200) {
 				if(res.Ret === 200) {
-					//this.filterNodes(res.Data.AllNodes);
+					this.filterNodes(res.Data.AllNodes||[]);
 					this.options = res.Data.AllNodes || [];
 					this.options = res.Data.AllNodes || [];
 				}
 				}
 			})
 			})
@@ -135,7 +136,7 @@ export default {
 		filterNodes(arr) {
 		filterNodes(arr) {
 			arr.length && arr.forEach(item => {
 			arr.length && arr.forEach(item => {
 				item.Children.length && this.filterNodes(item.Children)
 				item.Children.length && this.filterNodes(item.Children)
-				if(item.Level === 2) {
+				if(!item.Children.length) {
 					delete item.Children
 					delete item.Children
 				}
 				}
 			})
 			})

+ 3 - 2
src/views/dataEntry_manage/databaseComponents/computedDialog.vue

@@ -209,6 +209,7 @@ export default {
 				label: 'ClassifyName',
 				label: 'ClassifyName',
 				value: 'ClassifyId',
 				value: 'ClassifyId',
 				children: 'Children',
 				children: 'Children',
+				checkStrictly: true
 			},
 			},
 			frequencyArr: ['日度', '周度','旬度','月度', '季度', '年度'],
 			frequencyArr: ['日度', '周度','旬度','月度', '季度', '年度'],
 			formRules,
 			formRules,
@@ -260,7 +261,7 @@ export default {
 		getMenu() {
 		getMenu() {
 			dataBaseInterface.menuListV3().then((res) => {
 			dataBaseInterface.menuListV3().then((res) => {
 				if (res.Ret === 200) {
 				if (res.Ret === 200) {
-					//this.filterNodes(res.Data.AllNodes);
+					this.filterNodes(res.Data.AllNodes||[]);
 					this.options = res.Data.AllNodes || [];
 					this.options = res.Data.AllNodes || [];
 				}
 				}
 			});
 			});
@@ -270,7 +271,7 @@ export default {
 			arr.length &&
 			arr.length &&
 				arr.forEach((item) => {
 				arr.forEach((item) => {
 					item.Children.length && this.filterNodes(item.Children);
 					item.Children.length && this.filterNodes(item.Children);
-					if (item.Level === 2) {
+					if (!item.Children.length) {
 						delete item.Children;
 						delete item.Children;
 					}
 					}
 				});
 				});

+ 3 - 7
src/views/dataEntry_manage/databaseComponents/diffusionIndexDia.vue

@@ -225,6 +225,7 @@ export default {
 				label: 'ClassifyName',
 				label: 'ClassifyName',
 				value: 'ClassifyId',
 				value: 'ClassifyId',
 				children: 'Children',
 				children: 'Children',
+				checkStrictly: true
 			},
 			},
 			frequencyArr: ['日度', '周度','旬度', '月度', '季度', '年度'],
 			frequencyArr: ['日度', '周度','旬度', '月度', '季度', '年度'],
 			fre_options: ['天','周','月','季','年'],
 			fre_options: ['天','周','月','季','年'],
@@ -328,12 +329,7 @@ export default {
       ? await preDictEdbInterface.classifyListV2()
       ? await preDictEdbInterface.classifyListV2()
       : await dataBaseInterface.menuListV3()
       : await dataBaseInterface.menuListV3()
 				if (res.Ret === 200) {
 				if (res.Ret === 200) {
-					/* if(!this.isPredict){
-						this.filterNodes(res.Data.AllNodes);
-						this.options = res.Data.AllNodes || [];
-					}else{
-						this.options = res.Data.AllNodes || [];
-					} */
+					this.filterNodes(res.Data.AllNodes||[]);
 					this.options = res.Data.AllNodes || [];
 					this.options = res.Data.AllNodes || [];
 				}
 				}
 		},
 		},
@@ -342,7 +338,7 @@ export default {
 			arr.length &&
 			arr.length &&
 				arr.forEach((item) => {
 				arr.forEach((item) => {
 					item.Children.length && this.filterNodes(item.Children);
 					item.Children.length && this.filterNodes(item.Children);
-					if (item.Level === 2) {
+					if (!item.Children.length) {
 						delete item.Children;
 						delete item.Children;
 					}
 					}
 				});
 				});

+ 15 - 14
src/views/dataEntry_manage/databaseComponents/fittingResidueDia.vue

@@ -28,7 +28,7 @@
         :disabled="operationForm.view"
         :disabled="operationForm.view"
       >
       >
 			
 			
-        <el-form-item label="自变量" prop="self_variate">
+        <el-form-item label="自变量(x)" prop="self_variate">
           <el-select
           <el-select
             v-model="formData.self_variate"
             v-model="formData.self_variate"
             v-loadMore="searchLoad"
             v-loadMore="searchLoad"
@@ -72,7 +72,7 @@
           </template>  
           </template>  
         </el-form-item>
         </el-form-item>
 
 
-        <el-form-item label="因变量" prop="depend_variate">
+        <el-form-item label="因变量(y)" prop="depend_variate">
           <el-select
           <el-select
             v-model="formData.depend_variate"
             v-model="formData.depend_variate"
             v-loadMore="searchLoad"
             v-loadMore="searchLoad"
@@ -117,7 +117,7 @@
             @change="changeDate"
             @change="changeDate"
             :picker-options="endDateOptions"
             :picker-options="endDateOptions"
           />
           />
-					<span v-if="correlationIndex" class="editsty" style="margin-left: 20px">相关系数:{{correlationIndex}}</span>
+					<span v-if="correlationStr" class="editsty" style="margin-left: 20px">{{correlationStr}}</span>
         </el-form-item>
         </el-form-item>
         <el-form-item label="指标名称" prop="edb_name" class="target-form-cont">
         <el-form-item label="指标名称" prop="edb_name" class="target-form-cont">
           <el-input
           <el-input
@@ -225,6 +225,8 @@ export default {
 					StartDate: item.StartDate,
 					StartDate: item.StartDate,
 					EndDate: item.EndDate,
 					EndDate: item.EndDate,
 				}))
 				}))
+
+				this.correlationStr = backData.correlationStr;
 				
 				
 			}
 			}
 		}
 		}
@@ -276,6 +278,7 @@ export default {
 				label: 'ClassifyName',
 				label: 'ClassifyName',
 				value: 'ClassifyId',
 				value: 'ClassifyId',
 				children: 'Children',
 				children: 'Children',
+				checkStrictly: true
 			},
 			},
 			frequencyArr: ['日度', '周度','旬度', '月度', '季度', '年度'],
 			frequencyArr: ['日度', '周度','旬度', '月度', '季度', '年度'],
 			fre_options: ['天','周','月','季','年'],
 			fre_options: ['天','周','月','季','年'],
@@ -298,7 +301,7 @@ export default {
 			depend_edb_name: '',
 			depend_edb_name: '',
 			self_edb_name: '',
 			self_edb_name: '',
 
 
-			correlationIndex: '',//相关系数
+			correlationStr: '',//相关系数
 
 
 		};
 		};
 	},
 	},
@@ -350,13 +353,10 @@ export default {
 			const res=this.isPredict?await preDictEdbInterface.classifyListV2():await dataBaseInterface.menuListV3()
 			const res=this.isPredict?await preDictEdbInterface.classifyListV2():await dataBaseInterface.menuListV3()
 			// dataBaseInterface.menuList().then((res) => {
 			// dataBaseInterface.menuList().then((res) => {
 				if (res.Ret === 200) {
 				if (res.Ret === 200) {
-					/* if(!this.isPredict){
-						this.filterNodes(res.Data.AllNodes);
-						this.options = res.Data.AllNodes || [];
-					}else{
-						this.options = res.Data.AllNodes || [];
-					} */
+					
+					this.filterNodes(res.Data.AllNodes);
 					this.options = res.Data.AllNodes || [];
 					this.options = res.Data.AllNodes || [];
+					
 				}
 				}
 			// });
 			// });
 		},
 		},
@@ -365,7 +365,7 @@ export default {
 			arr.length &&
 			arr.length &&
 				arr.forEach((item) => {
 				arr.forEach((item) => {
 					item.Children.length && this.filterNodes(item.Children);
 					item.Children.length && this.filterNodes(item.Children);
-					if (item.Level === 2) {
+					if (!item.Children.length) {
 						delete item.Children;
 						delete item.Children;
 					}
 					}
 				});
 				});
@@ -397,9 +397,9 @@ export default {
 		/* 获取相关系数 */
 		/* 获取相关系数 */
 		async getCorrelationIndex() {
 		async getCorrelationIndex() {
 
 
-			if(!this.formData.self_variate || !this.formData.depend_variate || !this.formData.date[0] || !this.formData.date[1]) return this.correlationIndex = '';
+			if(!this.formData.self_variate || !this.formData.depend_variate || !this.formData.date[0] || !this.formData.date[1]) return this.correlationStr = '';
 			
 			
-			if(this.formData.self_move_type===1 && !this.formData.self_move_val) return this.correlationIndex = '';
+			if(this.formData.self_move_type===1 && !this.formData.self_move_val) return this.correlationStr = '';
 
 
 			const { date,self_variate,self_move_type,self_move_val,depend_variate } = this.formData;
 			const { date,self_variate,self_move_type,self_move_val,depend_variate } = this.formData;
 			let params = {
 			let params = {
@@ -423,7 +423,7 @@ export default {
 
 
 			if(res.Ret !==200) return
 			if(res.Ret !==200) return
 			
 			
-			this.correlationIndex = res.Data;
+			this.correlationStr = res.Data;
 		},
 		},
 
 
     /* 选择日期 */
     /* 选择日期 */
@@ -445,6 +445,7 @@ export default {
 
 
 		init() {
 		init() {
 			this.searchOptions = [];
 			this.searchOptions = [];
+			this.correlationStr = '';
 			this.formData = {
 			this.formData = {
 				self_variate: '',
 				self_variate: '',
         self_move_type: 0,
         self_move_type: 0,

+ 6 - 5
src/views/dataEntry_manage/databaseComponents/jointTargetDia.vue

@@ -157,6 +157,7 @@
 					label: 'ClassifyName',
 					label: 'ClassifyName',
 					value: 'ClassifyId',
 					value: 'ClassifyId',
 					children: 'Children',
 					children: 'Children',
+					checkStrictly: true
 				}"
 				}"
 				style="width: 70%"
 				style="width: 70%"
 				clearable
 				clearable
@@ -424,13 +425,13 @@ export default {
 			const res=this.isPredict?await preDictEdbInterface.classifyListV2():await dataBaseInterface.menuListV3()
 			const res=this.isPredict?await preDictEdbInterface.classifyListV2():await dataBaseInterface.menuListV3()
 			// dataBaseInterface.menuList().then(res => {
 			// dataBaseInterface.menuList().then(res => {
 				if(res.Ret === 200) {
 				if(res.Ret === 200) {
-					/* if(!this.isPredict){
-						this.filterNodes(res.Data.AllNodes);
+					if(!this.isPredict){
+						this.filterNodes(res.Data.AllNodes||[]);
 						this.menuOptions = res.Data.AllNodes || [];
 						this.menuOptions = res.Data.AllNodes || [];
 					}else{
 					}else{
 						this.menuOptions = res.Data.AllNodes || [];
 						this.menuOptions = res.Data.AllNodes || [];
-					} */
-					this.menuOptions = res.Data.AllNodes || [];
+					} 
+					// this.menuOptions = res.Data.AllNodes || [];
 				}
 				}
 			// })
 			// })
 		},
 		},
@@ -438,7 +439,7 @@ export default {
 		filterNodes(arr) {
 		filterNodes(arr) {
 			arr.length && arr.forEach(item => {
 			arr.length && arr.forEach(item => {
 				item.Children.length && this.filterNodes(item.Children)
 				item.Children.length && this.filterNodes(item.Children)
-				if(item.Level === 2) {
+				if(!item.Children.length) {
 					delete item.Children
 					delete item.Children
 				}
 				}
 			})
 			})

+ 49 - 72
src/views/dataEntry_manage/databaseComponents/openDialog.vue

@@ -1,4 +1,4 @@
-<template>
+ <template>
 	<div class="Dialog-box">
 	<div class="Dialog-box">
 		<el-dialog
 		<el-dialog
 		:visible.sync="isOpenDialog"
 		:visible.sync="isOpenDialog"
@@ -21,53 +21,24 @@
 				label-width="80px"
 				label-width="80px"
 				:model="formData"
 				:model="formData"
 				:rules="formRules">
 				:rules="formRules">
-					<!-- 添加/编辑1级目录 -->
-					<template 
-					v-if="(title=='添加'&&formData.level === 0)
-					|| (title=='编辑'&&formData.level === 1)">
-						<el-form-item label="目录名称" prop="level_1">
-							<el-input
-							v-model="formData.level_1"
-							style="width: 80%"
-							placeholder="必填项"></el-input>
+					<template v-if="!formData.isEDB">
+						<el-form-item label="上级目录" v-if="formData.level>0">
+							<el-tooltip class="item" effect="dark" :content="getParentName" placement="top">
+      							<span class="parentStr">{{getParentName}}</span>
+    						</el-tooltip>
 						</el-form-item>
 						</el-form-item>
-					</template>
-					<!-- 添加/编辑2级目录 -->
-					<template 
-					v-else-if="(title=='添加'&&formData.level === 1)
-					|| (title=='编辑'&&formData.level === 2)">
-						<el-form-item label="一级目录" prop="level_1">
-							<span>{{formData.level_1}}</span>
-						</el-form-item>
-						<el-form-item label="目录名称" prop="level_2">
+						<el-form-item label="目录名称" prop="levelVal">
 							<el-input
 							<el-input
-							v-model="formData.level_2"
-							style="width: 80%"
-							placeholder="必填项"></el-input>
-						</el-form-item>
-					</template>
-					<!-- 添加/编辑3级目录 -->
-					<template 
-					v-else-if="(title=='添加'&&formData.level === 2)
-					|| (title=='编辑'&&formData.level === 3)">
-						<el-form-item label="一级目录" prop="level_1">
-							<span>{{formData.level_1}}</span>
-						</el-form-item>
-						<el-form-item label="二级目录" prop="level_2">
-							<span>{{formData.level_2}}</span>
-						</el-form-item>
-						<el-form-item label="目录名称" prop="level_3">
-							<el-input
-							v-model="formData.level_3"
+							v-model="formData.levelVal"
 							style="width: 80%"
 							style="width: 80%"
 							placeholder="必填项"></el-input>
 							placeholder="必填项"></el-input>
 						</el-form-item>
 						</el-form-item>
 					</template>
 					</template>
 					<!-- 编辑具体指标 -->
 					<!-- 编辑具体指标 -->
-					<template v-else-if="title=='编辑' && formData.level === 4">
-						<el-form-item label="指标名称" prop="level_4">
+					<template v-if="title=='编辑' && formData.isEDB">
+						<el-form-item label="指标名称" prop="levelVal">
 							<el-input
 							<el-input
-							v-model="formData.level_4"
+							v-model="formData.levelVal"
 							style="width: 80%"
 							style="width: 80%"
 							placeholder="指标名称"></el-input>
 							placeholder="指标名称"></el-input>
 						</el-form-item>
 						</el-form-item>
@@ -124,34 +95,44 @@ export default {
 			default: '添加'
 			default: '添加'
 		},
 		},
 		formData: {
 		formData: {
-			type: Object,
+			type: Object,//{parentArr父级数据,isEDB:true 是否为指标}
 		}
 		}
 	},
 	},
 	watch: {
 	watch: {
 		'isOpenDialog': {
 		'isOpenDialog': {
 			handler(newval) {
 			handler(newval) {
-				if(newval && this.formData.level === 4) {
+				if(newval && this.formData.isEDB) {
 					this.getMenu();
 					this.getMenu();
 				}
 				}
 				// console.log(this.formData);
 				// console.log(this.formData);
 			}
 			}
 		}
 		}
 	},
 	},
+	computed:{
+		getParentName(){
+			const arr=this.formData.parentArr||[]
+			let strArr=arr.reverse().map(item=>{
+				return item.classifyName
+			})
+			
+			return strArr.join('/')
+		}
+	},
 	data () {
 	data () {
 		return {
 		return {
 			formRules: {
 			formRules: {
-				level_1:[
-					{ required: true, message: '目录名称不能为空', trigger: 'blur' },
-				],
-				level_2:[
-					{ required: true, message: '目录名称不能为空', trigger: 'blur' },
-				],
-				level_3:[
+				levelVal:[
 					{ required: true, message: '目录名称不能为空', trigger: 'blur' },
 					{ required: true, message: '目录名称不能为空', trigger: 'blur' },
 				],
 				],
-				level_4:[
-					{ required: true, message: '指标名称不能为空', trigger: 'blur' },
-				],
+				// level_2:[
+				// 	{ required: true, message: '目录名称不能为空', trigger: 'blur' },
+				// ],
+				// level_3:[
+				// 	{ required: true, message: '目录名称不能为空', trigger: 'blur' },
+				// ],
+				// level_4:[
+				// 	{ required: true, message: '指标名称不能为空', trigger: 'blur' },
+				// ],
 				level_menu:[
 				level_menu:[
 					{ required: true, message: '所属目录不能为空', trigger: 'blur' },
 					{ required: true, message: '所属目录不能为空', trigger: 'blur' },
 				],
 				],
@@ -168,6 +149,7 @@ export default {
 				label: 'ClassifyName',
 				label: 'ClassifyName',
 				value: 'ClassifyId',
 				value: 'ClassifyId',
 				children: 'Children',
 				children: 'Children',
+				checkStrictly: true
 			},
 			},
 			frequencyArr:['日度','周度','旬度','月度','季度','年度'],
 			frequencyArr:['日度','周度','旬度','月度','季度','年度'],
 
 
@@ -180,33 +162,21 @@ export default {
 
 
 			if(this.title==='添加') {
 			if(this.title==='添加') {
 				res = await dataBaseInterface.nodeAdd({
 				res = await dataBaseInterface.nodeAdd({
-						ClassifyName: this.formData.level === 0 
-							? this.formData.level_1
-							: this.formData.level === 1
-							? this.formData.level_2
-							: this.formData.level === 2
-							? this.formData.level_3
-							:'',
+						ClassifyName: this.formData.levelVal||'',
 						ParentId:this.formData.parent_id || 0,
 						ParentId:this.formData.parent_id || 0,
 						Level: this.formData.level
 						Level: this.formData.level
 					})
 					})
 			}else if(this.title==='编辑') {
 			}else if(this.title==='编辑') {
-				res = this.formData.level===4
+				res = this.formData.isEDB
 					? await dataBaseInterface.targetEdit({
 					? await dataBaseInterface.targetEdit({
 							ClassifyId: this.formData.level_menu[this.formData.level_menu.length - 1],
 							ClassifyId: this.formData.level_menu[this.formData.level_menu.length - 1],
 							EdbInfoId: this.formData.edbinfo_id,
 							EdbInfoId: this.formData.edbinfo_id,
-							EdbName: this.formData.level_4,
+							EdbName: this.formData.levelVal,
 							Frequency: this.formData.frequency,
 							Frequency: this.formData.frequency,
 							Unit: this.formData.unit
 							Unit: this.formData.unit
 						})
 						})
 					: await dataBaseInterface.nodeEdit({
 					: await dataBaseInterface.nodeEdit({
-							ClassifyName: this.formData.level === 1
-								? this.formData.level_1
-								: this.formData.level === 2
-								? this.formData.level_2
-								: this.formData.level === 3
-								?this.formData.level_3
-								:'',
+							ClassifyName: this.formData.levelVal||'',
 							ClassifyId:this.formData.classify_id || 0
 							ClassifyId:this.formData.classify_id || 0
 						})
 						})
 			}
 			}
@@ -214,8 +184,8 @@ export default {
 			this.$message.success(res.Msg);
 			this.$message.success(res.Msg);
 
 
 		 if(this.title==='添加') this.callbackHandle('add');
 		 if(this.title==='添加') this.callbackHandle('add');
-		 else if(this.title==='编辑' && this.formData.level===4) this.callbackHandle('update');
-		 else if(this.title==='编辑' && this.formData.level!==4) this.callbackHandle();
+		 else if(this.title==='编辑' && this.formData.isEDB) this.callbackHandle('update');
+		 else if(this.title==='编辑' && !this.formData.isEDB) this.callbackHandle();
 
 
 				
 				
 		},
 		},
@@ -234,7 +204,7 @@ export default {
 		getMenu() {
 		getMenu() {
 			dataBaseInterface.menuListV3().then(res => {
 			dataBaseInterface.menuListV3().then(res => {
 				if(res.Ret === 200) {
 				if(res.Ret === 200) {
-					//this.filterNodes(res.Data.AllNodes);
+					this.filterNodes(res.Data.AllNodes||[]);
 					this.options = res.Data.AllNodes || [];
 					this.options = res.Data.AllNodes || [];
 				}
 				}
 			})
 			})
@@ -243,7 +213,7 @@ export default {
 		filterNodes(arr) {
 		filterNodes(arr) {
 			arr.length && arr.forEach(item => {
 			arr.length && arr.forEach(item => {
 				item.Children.length && this.filterNodes(item.Children)
 				item.Children.length && this.filterNodes(item.Children)
-				if(item.Level === 2) {
+				if(!item.Children.length) {
 					delete item.Children
 					delete item.Children
 				}
 				}
 			})
 			})
@@ -255,6 +225,13 @@ export default {
 </script>
 </script>
 <style lang='scss'>
 <style lang='scss'>
 .Dialog-box {
 .Dialog-box {
+	.parentStr{
+		display: block;
+		width: 304px;
+		overflow: hidden;
+		white-space: nowrap;
+		text-overflow: ellipsis;
+	}
 	.dialog-main {
 	.dialog-main {
 		padding-left: 50px;
 		padding-left: 50px;
 	}
 	}

+ 22 - 12
src/views/dataEntry_manage/databaseComponents/operationDialog.vue

@@ -15,7 +15,7 @@
 				:src="$icons.computed"
 				:src="$icons.computed"
 				style="color: #fff; width: 16px; height: 16px; margin-right: 5px"
 				style="color: #fff; width: 16px; height: 16px; margin-right: 5px"
 			/>
 			/>
-			<span style="font-size: 16px">{{ (operationForm.edb_id ? (operationForm.view ? '查看' : '编辑') : '') + switchType.get(type) }}</span>
+			<span style="font-size: 16px">{{ (operationForm.edb_id ? (operationForm.view ? '查看' : '编辑') : '') + titleMap.get(type) }}</span>
 		</div>
 		</div>
 		<div class="dialog-main">
 		<div class="dialog-main">
 
 
@@ -163,7 +163,7 @@
 							<selectUnit 
 							<selectUnit 
 								v-model="formData.unit" 
 								v-model="formData.unit" 
 								style="width: 340px" 
 								style="width: 340px" 
-								:disabled="!operationForm.edb_id&&[6,7].includes(type)"
+								:disabled="!operationForm.edb_id&&[6,7,75].includes(type)"
 							/>
 							/>
 						</el-form-item>
 						</el-form-item>
 						<el-form-item label="指标目录" prop="menu">
 						<el-form-item label="指标目录" prop="menu">
@@ -181,7 +181,7 @@
 								placeholder="请选择频度"
 								placeholder="请选择频度"
 								style="width: 340px"
 								style="width: 340px"
 								clearable
 								clearable
-								:disabled="[5,14,61,63].includes(type)||(!operationForm.edb_id&&[6,7].includes(type))"
+								:disabled="[5,14,61,63].includes(type)||(!operationForm.edb_id&&[6,7,75].includes(type))"
 							>
 							>
 								<el-option
 								<el-option
 									v-for="item in frequencyArr"
 									v-for="item in frequencyArr"
@@ -237,7 +237,7 @@
 				style="margin-right: 20px"
 				style="margin-right: 20px"
 				@click="saveHandle"
 				@click="saveHandle"
 				:loading="loading"
 				:loading="loading"
-				>{{loading ? '计算中...' : operationForm.edb_id ? '保存' : save_txts.get(type)}}</el-button
+				>{{loading ? '计算中...' : operationForm.edb_id ? '保存' : saveBtnMap.get(type)}}</el-button
 			>
 			>
 			<el-button type="primary" plain @click="cancelHandle('cancel')">取消</el-button>
 			<el-button type="primary" plain @click="cancelHandle('cancel')">取消</el-button>
 		</div>
 		</div>
@@ -359,7 +359,7 @@ export default {
 					key: 'SourceName',
 					key: 'SourceName',
 				},
 				},
 			],
 			],
-			switchType: new Map([
+			titleMap: new Map([
 				[5,'累计值转月/季值'],
 				[5,'累计值转月/季值'],
 				[6,'同比值'],
 				[6,'同比值'],
 				[7,'同差值'],
 				[7,'同差值'],
@@ -375,8 +375,9 @@ export default {
 				[61,'累计值转月/季值'],
 				[61,'累计值转月/季值'],
 				[62,'累计值'],
 				[62,'累计值'],
 				[63,'累计值'],
 				[63,'累计值'],
+				[75,'日均值']
 			]),//标题
 			]),//标题
-			save_txts: new Map([
+			saveBtnMap: new Map([
 				[5,'转月值计算'],
 				[5,'转月值计算'],
 				[6,'同比值计算'],
 				[6,'同比值计算'],
 				[7,'同差值计算'],
 				[7,'同差值计算'],
@@ -391,6 +392,7 @@ export default {
 				[61,'转季值计算'],
 				[61,'转季值计算'],
 				[62,'累计值计算'],
 				[62,'累计值计算'],
 				[63,'年初至今计算'],
 				[63,'年初至今计算'],
+				[75,'日均值计算'],
 			]),//保存文案
 			]),//保存文案
 			formData: {
 			formData: {
 				targetName:'',
 				targetName:'',
@@ -411,6 +413,7 @@ export default {
 				label: 'ClassifyName',
 				label: 'ClassifyName',
 				value: 'ClassifyId',
 				value: 'ClassifyId',
 				children: 'Children',
 				children: 'Children',
+				checkStrictly: true
 			},
 			},
 			frequencyArr: ['日度', '周度','旬度', '月度', '季度', '年度'],
 			frequencyArr: ['日度', '周度','旬度', '月度', '季度', '年度'],
 			fre_options: ['天','周','月','季','年'],
 			fre_options: ['天','周','月','季','年'],
@@ -488,7 +491,7 @@ export default {
 		getMenu() {
 		getMenu() {
 			dataBaseInterface.menuListV3().then((res) => {
 			dataBaseInterface.menuListV3().then((res) => {
 				if (res.Ret === 200) {
 				if (res.Ret === 200) {
-					//this.filterNodes(res.Data.AllNodes);
+					this.filterNodes(res.Data.AllNodes||[]);
 					this.options = res.Data.AllNodes || [];
 					this.options = res.Data.AllNodes || [];
 				}
 				}
 			});
 			});
@@ -498,7 +501,7 @@ export default {
 			arr.length &&
 			arr.length &&
 				arr.forEach((item) => {
 				arr.forEach((item) => {
 					item.Children.length && this.filterNodes(item.Children);
 					item.Children.length && this.filterNodes(item.Children);
-					if (item.Level === 2) {
+					if (!item.Children.length) {
 						delete item.Children;
 						delete item.Children;
 					}
 					}
 				});
 				});
@@ -604,7 +607,7 @@ export default {
 					Source: this.type,
 					Source: this.type,
 					EdbName: this.formData.targetName,
 					EdbName: this.formData.targetName,
 					Unit: this.formData.unit,
 					Unit: this.formData.unit,
-					ClassifyId: this.formData.menu[this.formData.menu.length - 1],
+					ClassifyId: Array.isArray(this.formData.menu)?this.formData.menu[this.formData.menu.length - 1]:this.formData.menu,
 					Frequency: this.formData.frequency,
 					Frequency: this.formData.frequency,
 					Formula: valueMap[this.type] ? String(this.formData[valueMap[this.type]]) : String(this.formData.n_num),
 					Formula: valueMap[this.type] ? String(this.formData[valueMap[this.type]]) : String(this.formData.n_num),
 					FromEdbInfoId: this.select_target,
 					FromEdbInfoId: this.select_target,
@@ -687,13 +690,20 @@ export default {
 				61:  obj.EdbName,
 				61:  obj.EdbName,
 				62:  obj.EdbName,
 				62:  obj.EdbName,
 				63:  obj.EdbName,
 				63:  obj.EdbName,
+				75: `${obj.EdbName}日均值`
+			}
+			
+			let frequerncyMap = {
+				14: '日度',
+				61: '季度',
+				62: ''
 			}
 			}
 
 
 			this.formData = {
 			this.formData = {
 				targetName: name_map[this.type] || '',
 				targetName: name_map[this.type] || '',
-				frequency: this.type === 14 ? '日度' : this.type === 61 ? '季度' : this.type === 62 ? '' : obj.Frequency,
-				unit: [5,8,14,7,35].includes(this.type) ? obj.Unit : '无',
-				menu:'',
+				frequency: frequerncyMap[this.type] || obj.Frequency,
+				unit: [5,8,14,7,35,75].includes(this.type) ? obj.Unit : '无',
+				menu: this.type===75 ? obj.ClassifyId : '',
 				n_num: 1,
 				n_num: 1,
 				moveType: 1,
 				moveType: 1,
 				moveUnit: '天',
 				moveUnit: '天',

+ 18 - 1
src/views/dataEntry_manage/databaseComponents/smoothEdbDialog.vue

@@ -312,6 +312,7 @@ export default {
                 value: 'ClassifyId',
                 value: 'ClassifyId',
                 children: 'Children',
                 children: 'Children',
                 emitPath: false,
                 emitPath: false,
+                checkStrictly: true
             },
             },
 
 
             select_target:'',
             select_target:'',
@@ -432,8 +433,24 @@ export default {
                 ? await preDictEdbInterface.classifyListV2()
                 ? await preDictEdbInterface.classifyListV2()
                 : await dataBaseInterface.menuListV3()
                 : await dataBaseInterface.menuListV3()
             if(res.Ret!==200) return 
             if(res.Ret!==200) return 
-            this.catalogArr = res.Data.AllNodes || [];
+            // this.catalogArr = res.Data.AllNodes || [];
+            if(!this.isPredict){
+				this.filterNodes(res.Data.AllNodes||[]);
+				this.catalogArr = res.Data.AllNodes || [];
+			}else{
+				this.catalogArr = res.Data.AllNodes || [];
+			} 
         },
         },
+        // 递归改变第三级目录结构
+		filterNodes(arr) {
+			arr.length &&
+				arr.forEach((item) => {
+					item.Children.length && this.filterNodes(item.Children);
+					if (!item.Children.length) {
+						delete item.Children;
+					}
+				});
+		},
         /* 选择指标 */
         /* 选择指标 */
         chooseTarget(val) {
         chooseTarget(val) {
             if(val) {
             if(val) {

+ 16 - 1
src/views/dataEntry_manage/databaseComponents/util.js

@@ -102,6 +102,10 @@ export const computedTypes = [
 	{
 	{
 		name:'指数修匀',
 		name:'指数修匀',
 		type:'alpha'
 		type:'alpha'
+	},
+	{
+		name:'日均值',
+		type: 75
 	}
 	}
 ]
 ]
 
 
@@ -142,6 +146,10 @@ export const computedBatchTypes = [
 	{
 	{
 		name:'指数修匀',
 		name:'指数修匀',
 		type:'alpha'
 		type:'alpha'
+	},
+	{
+		name:'日均值',
+		type: 75
 	}
 	}
 ]
 ]
 
 
@@ -418,5 +426,12 @@ export const formulaTip = new Map([
 	['alpha',`指数修匀计算公式:<br>
 	['alpha',`指数修匀计算公式:<br>
 	1、设定指数修匀值序列的初始值=原来时间序列的初始值 <br>
 	1、设定指数修匀值序列的初始值=原来时间序列的初始值 <br>
 	2、选择平滑系数alpha值:在0-1之间,开区间 <br>
 	2、选择平滑系数alpha值:在0-1之间,开区间 <br>
-	3、本期指数修匀值=alpha*本期实际值+(1-alpha)*上期指数修匀值`]
+	3、本期指数修匀值=alpha*本期实际值+(1-alpha)*上期指数修匀值`],
+	[75,`日均值计算公式:<br>
+	1、年度值转日均值=年度值/对应年份天数 <br>
+	2、半年度值转日均值=半年度值/对应半年度天数 <br>
+	3、季度值转日均值=季度值/对应季度天数 <br>
+	4、月度值转日均值=月度值/对应月度天数 <br>
+	5、旬度值转日均值=旬度值/对应旬度天数 <br>
+	6、周度值转日均值=周度值/7`]
 ])
 ])

+ 164 - 258
src/views/dataEntry_manage/databaseList.vue

@@ -12,8 +12,8 @@
 					type="primary" @click="$router.push({path: '/codecount'})">代码运算</el-button>
 					type="primary" @click="$router.push({path: '/codecount'})">代码运算</el-button>
 				<el-button v-permission="permissionBtn.edbDataPermission.edbData_dataAdjust"
 				<el-button v-permission="permissionBtn.edbDataPermission.edbData_dataAdjust"
 					type="primary" @click="$router.push({path: '/adjustdata'})">数据调整</el-button>
 					type="primary" @click="$router.push({path: '/adjustdata'})">数据调整</el-button>
-				<el-button v-permission="permissionBtn.edbDataPermission.edbData_batchUpdate"
-					type="primary" plain @click="updateHandler">一键刷新</el-button>
+				<!-- <el-button v-permission="permissionBtn.edbDataPermission.edbData_batchUpdate"
+					type="primary" plain @click="updateHandler">一键刷新</el-button> -->
 			</div>
 			</div>
 			<div class="top-right">
 			<div class="top-right">
 
 
@@ -54,6 +54,7 @@
 				/>
 				/>
 		</div>
 		</div>
 		<div class="database_main box" id="box" v-if="showData">
 		<div class="database_main box" id="box" v-if="showData">
+			<!-- <target-tree /> -->
 			<div class="main-left left" id="left">
 			<div class="main-left left" id="left">
 				<div class="tree-cont">
 				<div class="tree-cont">
 					<el-tree
 					<el-tree
@@ -66,7 +67,7 @@
 						:allow-drop="canDropHandle"
 						:allow-drop="canDropHandle"
 						:current-node-key="select_node"
 						:current-node-key="select_node"
 						:default-expanded-keys="defaultShowNodes"
 						:default-expanded-keys="defaultShowNodes"
-						draggable
+						:draggable="isEdbBtnShow('moveCatalog')"
 						:expand-on-click-node="false"
 						:expand-on-click-node="false"
 						check-strictly
 						check-strictly
 						empty-text="暂无目录"
 						empty-text="暂无目录"
@@ -79,6 +80,7 @@
 						@node-drag-end="dropMouseLeave"
 						@node-drag-end="dropMouseLeave"
 						@node-drag-leave="dropMouseLeave"
 						@node-drag-leave="dropMouseLeave"
 						@node-drag-enter="dropMouseOver"
 						@node-drag-enter="dropMouseOver"
+						@node-drag-over="dropMouseOver"
 					>
 					>
 						<span
 						<span
 							class="custom-tree-node"
 							class="custom-tree-node"
@@ -110,7 +112,7 @@
 									src="~@/assets/img/data_m/move_ico.png"
 									src="~@/assets/img/data_m/move_ico.png"
 									alt=""
 									alt=""
 									style="width: 14px; height: 14px; margin-right: 8px"
 									style="width: 14px; height: 14px; margin-right: 8px"
-									v-if="data.Button.MoveButton"
+									v-if="data.Button.MoveButton&&isEdbBtnShow('moveCatalog')"
 								/>
 								/>
 								<!-- 添加子项 -->
 								<!-- 添加子项 -->
 								<img
 								<img
@@ -118,9 +120,9 @@
 									alt=""
 									alt=""
 									style="width: 14px; height: 14px; margin-right: 8px"
 									style="width: 14px; height: 14px; margin-right: 8px"
 									@click.stop="addNode(node,data)"
 									@click.stop="addNode(node,data)"
-									v-if="data.Button.AddButton&&isEdbBtnShow('editCatalog')"
+									v-if="data.Button.AddButton&&isEdbBtnShow('editCatalog')&&node.level<6"
 								/>
 								/>
-								<!--编辑节点 如果是分类,判断data.Button.OpButton不变;如果是指标,不显示(ETA1.0.3)-->
+								<!-- 编辑节点 如果是分类,判断data.Button.OpButton不变;如果是指标,不显示(ETA1.0.3) -->
 								<img
 								<img
 									src="~@/assets/img/set_m/edit.png"
 									src="~@/assets/img/set_m/edit.png"
 									alt=""
 									alt=""
@@ -128,7 +130,7 @@
 									@click.stop="editNode(node,data)"
 									@click.stop="editNode(node,data)"
 									v-if="!data.EdbCode&&(data.Button.OpButton)&&isEdbBtnShow('editCatalog')"
 									v-if="!data.EdbCode&&(data.Button.OpButton)&&isEdbBtnShow('editCatalog')"
 								/>
 								/>
-								<!-- 删除节点 如果是分类,判断data.Button.DeleteButton不变;如果是指标,不显示(ETA1.0.3)-->
+								<!-- 删除节点 如果是分类,判断data.Button.DeleteButton不变;如果是指标,不显示(ETA1.0.3) -->
 								<img
 								<img
 									slot="reference"
 									slot="reference"
 									src="~@/assets/img/set_m/del.png"
 									src="~@/assets/img/set_m/del.png"
@@ -139,7 +141,7 @@
 								/>
 								/>
 								<!-- 查看计算指标 -->
 								<!-- 查看计算指标 -->
 								<i class="el-icon-view" 
 								<i class="el-icon-view" 
-									v-if="data.EdbType===2&&![58,59,67,68].includes(data.Source)&&isEdbBtnShow('checkCalcChart')" 
+									v-if="data.EdbType===2&&![58,59,67,68,74].includes(data.Source)&&isEdbBtnShow('checkCalcChart')" 
 									@click.stop="viewNode(node,data)"></i>
 									@click.stop="viewNode(node,data)"></i>
 								<!-- 查看关联图表 -->
 								<!-- 查看关联图表 -->
 								<img 
 								<img 
@@ -215,18 +217,7 @@
 							type="text" @click="refreshTargetHandle" >刷新</el-button>
 							type="text" @click="refreshTargetHandle" >刷新</el-button>
 						<el-button v-if="isEdbBtnShow('edit')"
 						<el-button v-if="isEdbBtnShow('edit')"
 								type="text" :disabled="!(EdbData.Button.OpButton)"
 								type="text" :disabled="!(EdbData.Button.OpButton)"
-								@click="editNode({
-									level: 4,
-									parent: {
-										data: { ClassifyId:edb_levels[2].ClassifyId },
-										parent:{
-											data: { ClassifyId:edb_levels[1].ClassifyId },
-											parent:{
-												data: { ClassifyId:edb_levels[0].ClassifyId },
-											}
-										},
-									}
-								},EdbData)"
+								@click="editNode({},EdbData)"
 							>编辑</el-button>
 							>编辑</el-button>
 						<!-- 指保存指标的上下限,在走势图才显示 -->
 						<!-- 指保存指标的上下限,在走势图才显示 -->
 						<el-button v-if="activeTab==='Chart'&&isEdbBtnShow('saveEdb')"
 						<el-button v-if="activeTab==='Chart'&&isEdbBtnShow('saveEdb')"
@@ -373,7 +364,7 @@
 		</el-dialog>
 		</el-dialog>
 		<!-- 转月值 同比 同差 平均值弹窗 -->
 		<!-- 转月值 同比 同差 平均值弹窗 -->
 		<operationDialog
 		<operationDialog
-			:isOperation="([5,6,7,8,12,13,14,22,35,51,52,61,62,63].includes(computed_type) || (computed_type===40&&operationForm.view)) && computed_source===1"
+			:isOperation="([5,6,7,8,12,13,14,22,35,51,52,61,62,63,75].includes(computed_type) || (computed_type===40&&operationForm.view)) && computed_source===1"
 			:type="computed_type"
 			:type="computed_type"
 			:operationForm="operationForm"
 			:operationForm="operationForm"
 			@cancel="computed_type=0"
 			@cancel="computed_type=0"
@@ -425,7 +416,7 @@
 
 
 		<!-- 批量计算弹窗 -->
 		<!-- 批量计算弹窗 -->
 		<batchComputedDialog
 		<batchComputedDialog
-			:isBatchComputed="[6,7,8,12,13,14,5,61,62,63].includes(computed_type) && computed_source===2"
+			:isBatchComputed="[6,7,8,12,13,14,5,61,62,63,75].includes(computed_type) && computed_source===2"
 			:type="computed_type"
 			:type="computed_type"
 			@cancel="computed_type=0"
 			@cancel="computed_type=0"
 			@addCallBack="addComputedCallBack"
 			@addCallBack="addComputedCallBack"
@@ -518,7 +509,7 @@ export default {
 		EdbLabelList,
 		EdbLabelList,
 		chartTrendRender,
 		chartTrendRender,
 		edbDetailData,
 		edbDetailData,
-		SmoothEdbDialog
+		SmoothEdbDialog,
 	},
 	},
 	directives: {
 	directives: {
     drag(el, bindings) {
     drag(el, bindings) {
@@ -799,6 +790,7 @@ export default {
 
 
 				'editCatalog':edbDataPermission.edbData_classifyOpt_add,//添加编辑目录
 				'editCatalog':edbDataPermission.edbData_classifyOpt_add,//添加编辑目录
 				'deleteCatalog':edbDataPermission.edbData_classifyOpt_delete,//删除目录
 				'deleteCatalog':edbDataPermission.edbData_classifyOpt_delete,//删除目录
+				'moveCatalog':edbDataPermission.edbData_classifyOpt_move,//删除目录
 				'checkRelatedChart':edbDataPermission.edbData_checkRelatedChart,//查看关联图表
 				'checkRelatedChart':edbDataPermission.edbData_checkRelatedChart,//查看关联图表
 				'checkRelatedEdb':edbDataPermission.edbData_checkRelatedEdb,//查看关联指标
 				'checkRelatedEdb':edbDataPermission.edbData_checkRelatedEdb,//查看关联指标
 				'checkCalcChart':edbDataPermission.edbData_checkCalcChart,//查看计算指标
 				'checkCalcChart':edbDataPermission.edbData_checkCalcChart,//查看计算指标
@@ -808,13 +800,13 @@ export default {
 		/* 获取树分类数据 */
 		/* 获取树分类数据 */
 		getTreeData(params) {
 		getTreeData(params) {
 			
 			
-			dataBaseInterface.menuListV3().then(res=>{
+			dataBaseInterface.targetCatalog({ParentId:0}).then(res=>{
 				if(res.Ret===200){
 				if(res.Ret===200){
 					const arr=res.Data.AllNodes || []
 					const arr=res.Data.AllNodes || []
 					this.treeData=arr.map(item=>{
 					this.treeData=arr.map(item=>{
 						return {
 						return {
 							...item,
 							...item,
-							isLeaf:item.Children.length?false:true
+							// isLeaf:item.Children.length?false:true
 						}
 						}
 					})
 					})
 					this.CanOpClassify = res.Data.CanOpClassify;
 					this.CanOpClassify = res.Data.CanOpClassify;
@@ -863,10 +855,15 @@ export default {
 						//将指标添加进标签列表中
 						//将指标添加进标签列表中
 						const {EdbNameEn,EdbName,EdbInfoId,UniqueCode,ClassifyId}=res.Data.Item
 						const {EdbNameEn,EdbName,EdbInfoId,UniqueCode,ClassifyId}=res.Data.Item
 						this.addLabel({code:UniqueCode,id:EdbInfoId,classifyId:ClassifyId,EdbName,EdbNameEn})
 						this.addLabel({code:UniqueCode,id:EdbInfoId,classifyId:ClassifyId,EdbName,EdbNameEn})
-						let deep_arr = _.cloneDeep(this.treeData);
-						this.defaultShowNodes=this.findParentNodeHandle(deep_arr,ClassifyId).reverse()||[]
+						// 展开目录
+						this.defaultShowNodes=classify_arr.map(item=>item.UniqueCode)
 						//设置tree高亮
 						//设置tree高亮
-						this.$refs.menuTree.setCurrentKey(UniqueCode);
+						this.$nextTick(()=>{
+							setTimeout(() => {
+								this.$refs.menuTree.setCurrentKey(UniqueCode);
+							}, 1000);
+						})
+						
 
 
 					}else {
 					}else {
 						this.tableData = [];
 						this.tableData = [];
@@ -902,7 +899,7 @@ export default {
 							if(overBottom){
 							if(overBottom){
 								parent.scrollTop =  node.offsetTop - parent.offsetHeight/2
 								parent.scrollTop =  node.offsetTop - parent.offsetHeight/2
 							}
 							}
-						},400)
+						},1500)
 					})
 					})
 					
 					
 				}
 				}
@@ -1111,7 +1108,7 @@ export default {
 					? 'auto'
 					? 'auto'
 					: width <= 260
 					: width <= 260
 					? 80
 					? 80
-					: 0.5 * width;
+					: 0.4 * width;
 			this.$set(node, 'Nodewidth', label_wid + 'px');
 			this.$set(node, 'Nodewidth', label_wid + 'px');
 		},200),
 		},200),
 		/* 双击label出现input修改框 */
 		/* 双击label出现input修改框 */
@@ -1151,27 +1148,28 @@ export default {
 			}
 			}
 			this.isOpenDialog = true;
 			this.isOpenDialog = true;
 		},
 		},
+		// 递归节点
+		getNodeParentData(data,arr){
+			if(data.level===0) return
+			arr.push({classifyName:data.data.ClassifyName,classifyId:data.data.ClassifyId})
+			this.getNodeParentData(data.parent,arr)
+			return arr
+		},
 		/* 添加节点 */
 		/* 添加节点 */
 		addNode(node,data) {
 		addNode(node,data) {
-			// console.log(node,data);
+			console.log(node);
 			this.dialog_title = '添加';
 			this.dialog_title = '添加';
+			let arr=[]
+			arr=this.getNodeParentData(node,arr)
+			// console.log(arr);
+			
 				/* 添加目录 */
 				/* 添加目录 */
 			this.dialogForm = {
 			this.dialogForm = {
-				level_1: node.level === 1 
-				? data.ClassifyName
-				:node.level === 2
-				? node.parent.data.ClassifyName
-				: node.parent.parent.data.ClassifyName,
-				level_2: node.level === 1 
-				? ''
-				:node.level === 2
-				? data.ClassifyName
-				: node.parent.data.ClassifyName,
-				// level_3: node.level === 3
-				// ? data.ClassifyName
-				// : '',
+				parentArr:arr,
 				parent_id: data.ClassifyId,
 				parent_id: data.ClassifyId,
-				level: node.level
+				level: node.level,
+				levelVal:'',
+				isEDB:false
 			}
 			}
 			//存储当前要新增子级的目录code
 			//存储当前要新增子级的目录code
 			sessionStorage.setItem('expandCode', data.UniqueCode);
 			sessionStorage.setItem('expandCode', data.UniqueCode);
@@ -1179,25 +1177,28 @@ export default {
 		},
 		},
 		/* 编辑节点 */
 		/* 编辑节点 */
 		editNode(node,data) {
 		editNode(node,data) {
+			// console.log(node);
 			this.dialog_title = '编辑';
 			this.dialog_title = '编辑';
 			if(data.EdbCode) {
 			if(data.EdbCode) {
-				/* 编辑指标 */
+				/* 编辑指标 基础弹窗 */
 				
 				
-				(data.EdbType===1 || [58,59,67,68].includes(data.Source)) && dataBaseInterface.targetDetail({
+				(data.EdbType===1 || [58,59,67,68,74].includes(data.Source)) && dataBaseInterface.targetDetail({
 					EdbInfoId: data.EdbInfoId
 					EdbInfoId: data.EdbInfoId
 				}).then(res => {
 				}).then(res => {
 					if(res.Ret === 200) {
 					if(res.Ret === 200) {
+						// 处理所在目录
+						let menuArrId=res.Data.ClassifyList&&res.Data.ClassifyList.map(item=>{
+							return item.ClassifyId
+						}).reverse()
 						this.dialogForm = {
 						this.dialogForm = {
-							level: node.level,
-							level_4: res.Data.EdbName,
-							level_menu:[
-								node.parent.parent.parent.data.ClassifyId,
-								node.parent.parent.data.ClassifyId,
-								node.parent.data.ClassifyId
-							],
+							parentArr:[],
+							level: 0,
+							levelVal: res.Data.EdbName,
+							level_menu:menuArrId||[],
 							edbinfo_id: res.Data.EdbInfoId,
 							edbinfo_id: res.Data.EdbInfoId,
 							frequency:res.Data.Frequency,
 							frequency:res.Data.Frequency,
-							unit:res.Data.Unit
+							unit:res.Data.Unit,
+							isEDB:true
 						}
 						}
 						this.isOpenDialog = true;
 						this.isOpenDialog = true;
 					}
 					}
@@ -1232,23 +1233,15 @@ export default {
 
 
 
 
 			}else {
 			}else {
+				let arr=[]
+				arr=this.getNodeParentData(node.parent,arr)
 				/* 编辑目录 */
 				/* 编辑目录 */
 				this.dialogForm = {
 				this.dialogForm = {
-					level_1: node.level === 1 
-					? data.ClassifyName
-					:node.level === 2
-					? node.parent.data.ClassifyName
-					: node.parent.parent.data.ClassifyName,
-					level_2: node.level === 1 
-					? ''
-					:node.level === 2
-					? data.ClassifyName
-					: node.parent.data.ClassifyName,
-					level_3: node.level === 3
-					? data.ClassifyName
-					: '',
+					isEDB:false,
+					parentArr:arr,
+					levelVal: data.ClassifyName||'',
 					classify_id: data.ClassifyId,
 					classify_id: data.ClassifyId,
-					level: node.level
+					level: node.level-1
 				}
 				}
 				this.isOpenDialog = true;
 				this.isOpenDialog = true;
 			}
 			}
@@ -1355,155 +1348,122 @@ export default {
 		},
 		},
 		/* 判断节点是否能被拖拽 */
 		/* 判断节点是否能被拖拽 */
 		canDragHandle({data}) {
 		canDragHandle({data}) {
-      return data.Button.MoveButton;
+      		return data.Button.MoveButton;
 		},
 		},
 		/* 判断节点是否能被拖入 */
 		/* 判断节点是否能被拖入 */
 		canDropHandle(draggingNode, dropNode, type) {
 		canDropHandle(draggingNode, dropNode, type) {
 			let canDrop=false
 			let canDrop=false
-			// 移动的是一级目录
-			if(draggingNode.level===1&&dropNode.level===1&&type!=='inner') {
-				canDrop=true
-			} 
-
-			// 二级目录
-			if(draggingNode.level===2){
-				if((dropNode.level===1&&type==='inner')||(dropNode.level===2&&type!=='inner')){
-					canDrop=true
-				}
-			}
-
-			//三级目录
-			if(draggingNode.level===3){
-				if((dropNode.level===2&&type==='inner')||(dropNode.level===3&&type!=='inner')){
+			
+			// 如果拖动的是指标
+			if(draggingNode.data.EdbCode){
+				if(!(dropNode.level===1&&type!=='inner')){
 					canDrop=true
 					canDrop=true
 				}
 				}
-			}
-			//四级指标
-			if(draggingNode.level===4){
-				if((dropNode.level===3&&type==='inner')||(dropNode.level===4&&type!=='inner')){
+			}else{//拖动的是目录
+				// console.log(dropNode.level,draggingNode.level);
+				//目录只能拖动到层级比他大的里面去
+				if(dropNode.level<draggingNode.level||(dropNode.level===draggingNode.level&&type!=='inner')){
 					canDrop=true
 					canDrop=true
 				}
 				}
 			}
 			}
-			
 			return canDrop
 			return canDrop
 		},
 		},
 		/* 拖拽完成 */
 		/* 拖拽完成 */
 		dropOverHandle(b,a,i,e) {
 		dropOverHandle(b,a,i,e) {
 			// 被拖拽节点对应的 Node、结束拖拽时最后进入的节点、被拖拽节点的放置位置
 			// 被拖拽节点对应的 Node、结束拖拽时最后进入的节点、被拖拽节点的放置位置
-			if(b.level===1||b.level===2||b.level===3){
-				this.handleMoveCatalogue(b,a,i,e)
-			}
-
-			// 指标层
-			if(b.level===4){
-				this.handleMoveEdb(b,a,i,e)
-			}
-		},
+			console.log(b,a,i);
+			const isEDB=b.data.EdbCode?true:false
+			let list=a.parent.childNodes;
+			let targetIndex=0,PrevClassifyId=0,NextClassifyId=0,ParentClassifyId=0;
+			let ClassifyId=0,EdbInfoId=0,PrevEdbInfoId=0,NextEdbInfoId=0;
+
+			ClassifyId=isEDB?0:b.data.ClassifyId
+			EdbInfoId=isEDB?b.data.EdbInfoId:0
+			
 
 
-		// 移动的为一、二、三级目录
-		handleMoveCatalogue(b,a,i,e){
-			let list=a.parent.childNodes,targetIndex=0,PrevClassifyId=0,NextClassifyId=0,ParentClassifyId=0;
+			if(i!=='inner'){
+				ParentClassifyId=a.parent.data.ClassifyId||0
+				list.forEach((item,index)=>{
+					if(isEDB){
+						if(item.data.EdbInfoId===b.data.EdbInfoId){
+							targetIndex=index
+						}
+					}else{
+						if(item.data.ClassifyId===b.data.ClassifyId){
+							targetIndex=index
+						}
+					}
+					
+				})
 
 
-			list.forEach((item,index)=>{
-				if(item.data.ClassifyId===b.data.ClassifyId){
-					targetIndex=index
-					return
-				}
-			})
+				console.log(targetIndex);
+				
+				
+				if(targetIndex===0){
+					const data=list[targetIndex+1].data
+					NextClassifyId=data.EdbCode?0:data.ClassifyId
+					NextEdbInfoId=data.EdbCode?data.EdbInfoId:0
+				}else if(targetIndex===list.length-1){
+					const data=list[targetIndex-1].data
+					PrevClassifyId=data.EdbCode?0:data.ClassifyId
+					PrevEdbInfoId=data.EdbCode?data.EdbInfoId:0
+				}else{
+					const pData=list[targetIndex-1].data
+					PrevClassifyId=pData.EdbCode?0:pData.ClassifyId
 
 
-			if(targetIndex===0){
-				PrevClassifyId=0
-				NextClassifyId=list[targetIndex+1].data.ClassifyId
-			}else if(targetIndex===list.length-1){
-				PrevClassifyId=list[targetIndex-1].data.ClassifyId
-				NextClassifyId=0
-			}else{
-				PrevClassifyId=list[targetIndex-1].data.ClassifyId
-				NextClassifyId=list[targetIndex+1].data.ClassifyId
-			}
+					PrevEdbInfoId=pData.EdbCode?pData.EdbInfoId:0
 
 
-			if(b.level===2){
-				if(i==='inner'){
-					ParentClassifyId=a.data.ClassifyId
-					PrevClassifyId=0
-					NextClassifyId=a.data.Children.length>1?a.data.Children[1].ClassifyId:0
-				}else{
-					ParentClassifyId=a.data.ParentId
+					const nData=list[targetIndex+1].data
+					NextClassifyId=nData.EdbCode?0:nData.ClassifyId
+					NextEdbInfoId=nData.EdbCode?nData.EdbInfoId:0
 				}
 				}
+			}else{
+				ParentClassifyId=a.data.ClassifyId||0
 			}
 			}
 
 
-			if(b.level===3){
-				if(i==='inner'){
-					ParentClassifyId=a.data.ClassifyId
-					PrevClassifyId=0
-					NextClassifyId=a.data.Children.length>1?a.data.Children[1].ClassifyId:0
-				}else{
-					ParentClassifyId=a.data.ParentId
-				}
+			const params={
+				ClassifyId,
+				ParentClassifyId,
+				EdbInfoId,
+				PrevClassifyId,
+				NextClassifyId,
+				PrevEdbInfoId,
+				NextEdbInfoId
 			}
 			}
-
-			dataBaseInterface.classifyMove({
-				ClassifyId:b.data.ClassifyId,
-				ParentClassifyId:ParentClassifyId,
-				PrevClassifyId:PrevClassifyId,
-				NextClassifyId:NextClassifyId
-			}).then(res=>{
+			console.log(params);
+			dataBaseInterface.classifyMoveSort(params).then(res=>{
 				if(res.Ret===200){
 				if(res.Ret===200){
 					this.$message.success('移动成功!')
 					this.$message.success('移动成功!')
 				}
 				}
-				this.getTreeData();
-			})
-		},
-
-		// 移动的为指标层 四级
-		handleMoveEdb(b,a,i,e){
-			let PrevEdbInfoId=0,NextEdbInfoId=0,targetIndex=0,list=a.parent.childNodes.map(_ => _.data)
-			if(i==='inner'){
-				PrevEdbInfoId=0
-				NextEdbInfoId=a.data.Children.length>1?a.data.Children[1].EdbInfoId:0
-			}else{
-				list.forEach((item,index)=>{
-					if(item.EdbInfoId===b.data.EdbInfoId){
-						targetIndex=index
-						return
-					}
-				})
-
-				if(targetIndex===0){
-					PrevEdbInfoId=0
-					NextEdbInfoId=list[targetIndex+1].EdbInfoId
-				}else if(targetIndex===list.length-1){
-					PrevEdbInfoId=list[targetIndex-1].EdbInfoId
-					NextEdbInfoId=0
-				}else{
-					PrevEdbInfoId=list[targetIndex-1].EdbInfoId
-					NextEdbInfoId=list[targetIndex+1].EdbInfoId
+				this.getTreeData()
+				if(this.selected_edbid){
+					this.getDataList();
 				}
 				}
-			}	
-			
-			dataBaseInterface.targetMove({
-				ClassifyId: a.data.ClassifyId,
-				EdbInfoId: b.data.EdbInfoId,
-				PrevEdbInfoId:PrevEdbInfoId,
-				NextEdbInfoId:NextEdbInfoId
-			}).then(res => {
-				if(res.Ret === 200) {
-					this.$message.success('移动成功!')
-				}
-				this.getTreeData();
+				
 			})
 			})
 		},
 		},
 
 
 		/* 拖拽覆盖添加背景色 */
 		/* 拖拽覆盖添加背景色 */
 		dropMouseOver(node1,node2,e) {
 		dropMouseOver(node1,node2,e) {
+			// console.log(e.layerY);
+			
 			// 被拖拽节点对应的 Node、所进入节点对应的 Node、event
 			// 被拖拽节点对应的 Node、所进入节点对应的 Node、event
-			if(((node1.level===2&&node2.level === 1)||(node1.level===3&&node2.level === 2)) && (e.target.childNodes[0].className.includes('el-tree-node__content') 
+			if((node1.level>node2.level||(node1.data.EdbInfoId>0&&!node2.data.EdbInfoId)) && (e.target.childNodes[0].className.includes('el-tree-node__content') 
 			|| e.target.className.includes('el-tree-node__content'))) {
 			|| e.target.className.includes('el-tree-node__content'))) {
 				// console.log(e.target.childNodes[0])
 				// console.log(e.target.childNodes[0])
 				e.target.childNodes[0].className.includes('el-tree-node__content') 
 				e.target.childNodes[0].className.includes('el-tree-node__content') 
 				? e.target.childNodes[0].style.backgroundColor = '#409eff' 
 				? e.target.childNodes[0].style.backgroundColor = '#409eff' 
 				: e.target.style.backgroundColor = '#409eff';
 				: e.target.style.backgroundColor = '#409eff';
 			}
 			}
+			const dropLine=$('.el-tree__drop-indicator')[0]
+			if(dropLine){
+				// console.log(dropLine);
+				setTimeout(() => {
+					dropLine.style.top=e.layerY+'px'
+					// console.log(e.layerY,dropLine);
+				}, 100);
+			}
+			
 		},
 		},
 		/* 拖拽离开/拖拽完成重置背景色 */
 		/* 拖拽离开/拖拽完成重置背景色 */
 		dropMouseLeave(node1,node2,e) {
 		dropMouseLeave(node1,node2,e) {
@@ -1515,13 +1475,7 @@ export default {
 		// 树节点展开
 		// 树节点展开
 		handleNodeExpand (data) {
 		handleNodeExpand (data) {
 			// 保存当前展开的节点
 			// 保存当前展开的节点
-			let flag = false
-			this.defaultShowNodes.some(item => {
-				if (item === data.UniqueCode) { // 判断当前节点是否存在, 存在不做处理
-					flag = true
-					return true
-				}
-			})
+			let flag = this.defaultShowNodes.some((item) => item === data.UniqueCode);
 			if (!flag) { // 不存在则存到数组里
 			if (!flag) { // 不存在则存到数组里
 				this.defaultShowNodes.push(data.UniqueCode)
 				this.defaultShowNodes.push(data.UniqueCode)
 			}
 			}
@@ -1586,41 +1540,6 @@ export default {
 			})
 			})
 			return [...arr,code]
 			return [...arr,code]
 		},
 		},
-		// 懒加载tree
-		handleTreeLoad(node,resolve){
-			if(node.level===0){
-				resolve(this.treeData)
-			}
-			if(node.level===1){
-				let arr=[]
-				this.treeData.forEach(item=>{
-					if(item.UniqueCode===node.data.UniqueCode){
-						arr=item.Children
-					}
-				})
-				resolve(arr)
-			}
-			if(node.level===2){
-				dataBaseInterface.getEdbListForClassify({ClassifyId:node.data.ClassifyId}).then(res=>{
-					if(res.Ret===200){
-						let arr=res.Data.EdbInfoList||[]
-						arr=arr.map(item=>{
-							return {
-								...item,
-								isLeaf:true
-							}
-						})
-						resolve(arr)
-					}else{
-						resolve([])
-					}
-					this.changeTreeNode()
-				})
-			}
-			if(node.level>2){
-				resolve([])
-			}
-		},
 		/* 添加计算指标 */
 		/* 添加计算指标 */
 		addComputedHandler() {
 		addComputedHandler() {
 			this.computedTit = '计算指标';
 			this.computedTit = '计算指标';
@@ -1699,6 +1618,12 @@ export default {
 		/* 设置回显计算指标的表单 */
 		/* 设置回显计算指标的表单 */
 		setComputedDialogForm(type,node,data,res,view=false) {
 		setComputedDialogForm(type,node,data,res,view=false) {
 			//指标运算 or 其他计算类型指标
 			//指标运算 or 其他计算类型指标
+
+			// 处理所在目录
+			let menuArrId=res.EdbInfoDetail.ClassifyList&&res.EdbInfoDetail.ClassifyList.map(item=>{
+				return item.ClassifyId
+			}).reverse()
+
 			if( type === 4 ) {
 			if( type === 4 ) {
 				/* 回显指标和表单 */
 				/* 回显指标和表单 */
 				const list = res.CalculateList;
 				const list = res.CalculateList;
@@ -1717,11 +1642,7 @@ export default {
 				this.calulateForm =  {
 				this.calulateForm =  {
 					edb_id:res.EdbInfoDetail.EdbInfoId,
 					edb_id:res.EdbInfoDetail.EdbInfoId,
 					formula: res.EdbInfoDetail.CalculateFormula,
 					formula: res.EdbInfoDetail.CalculateFormula,
-					menu: [
-						node.parent.parent.parent.data.ClassifyId,
-						node.parent.parent.data.ClassifyId,
-						data.ClassifyId
-					],
+					menu: menuArrId||[],
 					targetName: res.EdbInfoDetail.EdbName,
 					targetName: res.EdbInfoDetail.EdbName,
 					unit: res.EdbInfoDetail.Unit,
 					unit: res.EdbInfoDetail.Unit,
 					frequency: res.EdbInfoDetail.Frequency,
 					frequency: res.EdbInfoDetail.Frequency,
@@ -1736,11 +1657,7 @@ export default {
 					targetName: dataInfo.EdbName,
 					targetName: dataInfo.EdbName,
 					frequency: dataInfo.Frequency,
 					frequency: dataInfo.Frequency,
 					unit: dataInfo.Unit,
 					unit: dataInfo.Unit,
-					menu: [
-						node.parent.parent.parent.data.ClassifyId,
-						node.parent.parent.data.ClassifyId,
-						data.ClassifyId
-					],
+					menu: menuArrId||[],
 					view
 					view
 				}
 				}
 
 
@@ -1754,6 +1671,7 @@ export default {
 							old_stay_edb: type === 24 ? old_edb.find(item => item.FromTag === 'A').FromEdbInfoId : '',
 							old_stay_edb: type === 24 ? old_edb.find(item => item.FromTag === 'A').FromEdbInfoId : '',
 							concat_edb: type === 24 ? old_edb.find(item => item.FromTag === 'B').FromEdbInfoId : '',
 							concat_edb: type === 24 ? old_edb.find(item => item.FromTag === 'B').FromEdbInfoId : '',
 							from_arr: old_edb,
 							from_arr: old_edb,
+							correlationStr: dataInfo.CorrelationStr
 						} 
 						} 
 					: {
 					: {
 							...public_params,
 							...public_params,
@@ -1916,34 +1834,22 @@ export default {
 			})
 			})
 		},
 		},
 		//绑定el-tree的load属性
 		//绑定el-tree的load属性
-		getLazyTreeData (node,resolve,maxLevel=3){
+		async getLazyTreeData (node,resolve){
 			if(node.level===0){
 			if(node.level===0){
 				resolve(this.treeData)
 				resolve(this.treeData)
-			}
-			if(node.level>0&&node.level<=maxLevel){
-				//获取对应层级的Child
-				resolve(node.data.Children||[])
-			}
-			if(node.level===maxLevel){
-				//调接口获取该分类下指标的数据
-				dataBaseInterface.getEdbListForClassify({ClassifyId:node.data.ClassifyId}).then(res=>{
-					if(res.Ret===200){
-						let arr=res.Data.EdbInfoList||[]
-						arr=arr.map(item=>{
-							return {
-								...item,
-								isLeaf:true
-							}
-						})
-						resolve(arr)
-					}else{
-						resolve([])
-					}
-					this.changeTreeNode()
-				})
-			}
-			if(node.level>maxLevel){
-				resolve([])
+			}else{
+				let arr=[]
+				const res=await dataBaseInterface.targetCatalog({ParentId:node.data.ClassifyId})
+				if (res.Ret === 200) {
+					const temarr = res.Data.AllNodes || [];
+					arr=temarr.map(item=>{
+						return {
+							...item,
+							isLeaf:item.EdbInfoId?true:false
+						}
+					})
+				}
+				resolve(arr)
 			}
 			}
 		},
 		},
 		//保存指标上下限
 		//保存指标上下限

+ 28 - 3
src/views/dataEntry_manage/editChart.vue

@@ -66,13 +66,28 @@
 						/>
 						/>
 					</el-form-item>
 					</el-form-item>
 					<el-form-item label="图表单位" prop="Unit" v-if="chartInfo.ChartType===7">
 					<el-form-item label="图表单位" prop="Unit" v-if="chartInfo.ChartType===7">
-						<el-input
+						<!-- <el-input
 							v-model="chartInfo.Unit"
 							v-model="chartInfo.Unit"
 							style="width: 90%"
 							style="width: 90%"
 							placeholder="请输入图表单位"
 							placeholder="请输入图表单位"
 							clearable
 							clearable
 							@change="changeUnit"
 							@change="changeUnit"
-						/>
+						/> -->
+						<el-select
+							v-model="chartInfo.Unit"
+							filterable
+							allow-create
+							default-first-option
+							clearable
+							@change="changeUnit"
+							placeholder="请输入图表单位">
+							<el-option
+								v-for="item in UnitOptions"
+								:key="item"
+								:label="item"
+								:value="item">
+							</el-option>
+						</el-select>
 					</el-form-item>
 					</el-form-item>
 				</el-form>
 				</el-form>
 
 
@@ -313,7 +328,10 @@
 						v-if="chartInfo.ChartType===10"
 						v-if="chartInfo.ChartType===10"
 						ref="SectionScatterOptRef"
 						ref="SectionScatterOptRef"
 						:initData="chartInfo.ExtraConfig?JSON.parse(chartInfo.ExtraConfig):null"
 						:initData="chartInfo.ExtraConfig?JSON.parse(chartInfo.ExtraConfig):null"
+						:edbInfoData="tableData"
+						:IsNameDefault="IsNameDefault"
 						@getData="getSectionScatterData"
 						@getData="getSectionScatterData"
+						@modifySeriesName="IsNameDefault = false"
 					/>
 					/>
         </div>
         </div>
 			</div>
 			</div>
@@ -561,6 +579,7 @@
 <script>
 <script>
 import { dataBaseInterface } from '@/api/api.js';
 import { dataBaseInterface } from '@/api/api.js';
 import { chartSetMixin } from './mixins/chartPublic';
 import { chartSetMixin } from './mixins/chartPublic';
+import {unitArr} from '@/utils/defaultOptions.js'
 import addOrEditMixn from './mixins/addOreditMixin';
 import addOrEditMixn from './mixins/addOreditMixin';
 
 
 import Chart from './components/chart';
 import Chart from './components/chart';
@@ -629,6 +648,9 @@ export default {
 
 
 			initBarOptions: null,//编辑时回显的barOptions数据
 			initBarOptions: null,//编辑时回显的barOptions数据
 			needWatch: false,
 			needWatch: false,
+			IsNameDefault:true,
+
+			UnitOptions:unitArr
     };
     };
   },
   },
   methods: {
   methods: {
@@ -641,7 +663,10 @@ export default {
         })
         })
         .then((res) => {
         .then((res) => {
           if (res.Ret !== 200) return;
           if (res.Ret !== 200) return;
-					const { ChartInfo,EdbInfoList,BarChartInfo } = res.Data;
+					const { ChartInfo,EdbInfoList,BarChartInfo} = res.Data;
+					const {SeriesList=[]} = ChartInfo.ExtraConfig?JSON.parse(ChartInfo.ExtraConfig):{} 
+					const {IsNameDefault=true} = SeriesList.length?SeriesList[0]:[]
+					this.IsNameDefault = IsNameDefault
 
 
            this.chartInfo = {
            this.chartInfo = {
 						...ChartInfo,
 						...ChartInfo,

+ 7 - 1
src/views/dataEntry_manage/mixins/addOreditMixin.js

@@ -224,6 +224,7 @@ export default {
 			this.$set(edb,'EdbAliasName',edb.EdbName)
 			this.$set(edb,'EdbAliasName',edb.EdbName)
 			if(have_bol) return this.$message.warning('录入指标已存在');
 			if(have_bol) return this.$message.warning('录入指标已存在');
 			this.search_txt = '';
 			this.search_txt = '';
+			this.chartInfo.Unit = this.chartInfo.Unit||edb.Unit
 			this.tableData.push(edb)
 			this.tableData.push(edb)
 
 
 		},
 		},
@@ -312,6 +313,10 @@ export default {
       this.tableData.forEach((item) => {
       this.tableData.forEach((item) => {
         let edbData = EdbInfoList.find(_ => _.EdbInfoId===item.EdbInfoId);
         let edbData = EdbInfoList.find(_ => _.EdbInfoId===item.EdbInfoId);
         item.DataList = edbData.DataList;
         item.DataList = edbData.DataList;
+				//更新起始时间和最近更新时间
+        item.StartDate = edbData.StartDate;
+        item.ModifyTime = edbData.ModifyTime;
+				
         if(edbData.EdbInfoCategoryType===1) item.MoveLatestDate = edbData.MoveLatestDate;
         if(edbData.EdbInfoCategoryType===1) item.MoveLatestDate = edbData.MoveLatestDate;
       });
       });
 		},
 		},
@@ -617,7 +622,8 @@ export default {
 									YDate: edb.y_date,
 									YDate: edb.y_date,
 									YDateValue: edb.y_date_value,
 									YDateValue: edb.y_date_value,
 									IsShow: edb.is_show
 									IsShow: edb.is_show
-								}))
+								})),
+								IsNameDefault:this.IsNameDefault
 							}))
 							}))
 						})
 						})
 					}	
 					}	

+ 1 - 1
src/views/dataEntry_manage/mixins/chartPublic.js

@@ -1934,7 +1934,7 @@ export const chartSetMixin = {
             );
             );
           });
           });
         }else {
         }else {
-          this.$message.warning('浏览器暂不支持')
+          this.$message.warning('当前协议暂不支持,仅支持https协议')
         }
         }
       };
       };
     },
     },

+ 2 - 1
src/views/datasheet_manage/addSheet.vue

@@ -72,7 +72,8 @@ export default {
     saveSheetHandle: _.debounce(async function() {
     saveSheetHandle: _.debounce(async function() {
       const { name,classify } = this.sheetForm;
       const { name,classify } = this.sheetForm;
       luckysheet.exitEditMode()
       luckysheet.exitEditMode()
-      let data = luckysheet.getAllSheets()[0]
+      //结构类型乱飘 强制定义下
+      let data = {...luckysheet.getAllSheets()[0],status:Number(luckysheet.getAllSheets()[0].status)}
       if(!name || !classify) return this.$message.warning(name ? '请选择表格分类' : '请输入表格名称')
       if(!name || !classify) return this.$message.warning(name ? '请选择表格分类' : '请输入表格名称')
       if(!data.celldata.length) return this.$message.warning('请输入表格内容');
       if(!data.celldata.length) return this.$message.warning('请输入表格内容');
 
 

+ 33 - 23
src/views/datasheet_manage/common/option.js

@@ -1,11 +1,10 @@
 
 
 /*  初始化  
 /*  初始化  
-  options 用来初始化数据用 
-  data 初始化数据 [{celldata}]
+  options 其他配置 包括初始化数据 data:[{ celldata:[] }]
   sheetInfo 表格id相关信息 用来内容hooks变化时保存草稿
   sheetInfo 表格id相关信息 用来内容hooks变化时保存草稿
 */
 */
 import * as sheetInterface from '@/api/modules/sheetApi.js';
 import * as sheetInterface from '@/api/modules/sheetApi.js';
-export const initSheet = (container,options={},sheetInfo={}) =>  {
+export function initSheet(container,options={},sheetInfo={}) {
   const configOpt = {
   const configOpt = {
     container,
     container,
     lang: 'zh', // 设定表格语言
     lang: 'zh', // 设定表格语言
@@ -22,24 +21,23 @@ export const initSheet = (container,options={},sheetInfo={}) =>  {
       image: false, // 插入图片
       image: false, // 插入图片
       link: false, // 插入链接
       link: false, // 插入链接
     },
     },
-    data: [{
-      ...options,
-      scrollTop: 0,
-      scrollLeft: 0
-    }],
     hook: {
     hook: {
       updated: (a,b,c,d,e)=> {
       updated: (a,b,c,d,e)=> {
-        let data = luckysheet.getAllSheets()[0];
-        data.luckysheet_select_save = [];
-        const { ExcelInfoId,ExcelName,ExcelClassifyId } = sheetInfo;
-        ExcelInfoId && sheetInterface.sheetDrafSave({
-          ExcelInfoId,
-          ExcelName,
-          ExcelClassifyId,
-          Content: JSON.stringify(data)
-        })
+
+        if(sheetInfo.Source&&sheetInfo.Source===1) {
+          let data = luckysheet.getAllSheets()[0];
+          data.luckysheet_select_save = [];
+          const { ExcelInfoId,ExcelName,ExcelClassifyId } = sheetInfo;
+          ExcelInfoId && sheetInterface.sheetDrafSave({
+            ExcelInfoId,
+            ExcelName,
+            ExcelClassifyId,
+            Content: JSON.stringify(data)
+          })
+        }
       }
       }
-    }
+    },
+    ...options
   }
   }
 
 
   luckysheet.create(configOpt)
   luckysheet.create(configOpt)
@@ -49,12 +47,24 @@ export const initSheet = (container,options={},sheetInfo={}) =>  {
 /* 保存表格关联截图 手动选区截图再清空选区 */
 /* 保存表格关联截图 手动选区截图再清空选区 */
 export const getSheetImage = (data) => {
 export const getSheetImage = (data) => {
   const { celldata } = data;
   const { celldata } = data;
-  
-  const r_arr = celldata.map(_ => _.c);
-  let r_start = celldata[0].r,
-    r_end = celldata[celldata.length-1].r,
-    c_start = Math.min(...r_arr),
+
+  //超过1000个就不遍历了
+  let r_start,r_end,c_start,c_end;
+  if(celldata.length > 1000) {
+    const splitData = celldata.slice(0,1000);
+    const r_arr = splitData.map(_ => _.c);
+    r_start = splitData[0].r;
+    r_end = splitData[splitData.length-1].r;
+    c_start = Math.min(...r_arr);
     c_end = Math.max(...r_arr);
     c_end = Math.max(...r_arr);
+
+  }else {
+    const r_arr = celldata.map(_ => _.c);
+    r_start = celldata[0].r;
+    r_end = celldata[celldata.length-1].r;
+    c_start = Math.min(...r_arr);
+    c_end = Math.max(...r_arr);
+  }
   
   
   luckysheet.setRangeShow({row:[r_start,r_end],column:[c_start,c_end]},{show: false})
   luckysheet.setRangeShow({row:[r_start,r_end],column:[c_start,c_end]},{show: false})
   let img = luckysheet.getScreenshot()
   let img = luckysheet.getScreenshot()

+ 3 - 13
src/views/datasheet_manage/components/SheetExcel.vue

@@ -8,7 +8,7 @@ import { initSheet } from '../common/option';
 export default {
 export default {
   props: {
   props: {
     option: {
     option: {
-      type: String,
+      type: Object,
       default: ''
       default: ''
     },
     },
     sheetInfo: {
     sheetInfo: {
@@ -16,25 +16,15 @@ export default {
       default: ()=>{}
       default: ()=>{}
     }
     }
   },
   },
-  // watch: {
-  //   option: {
-  //     handler(newval) {
-  //       console.log(newval)
-  //       this.optionData = newval ? JSON.parse(newval) : {}
-  //       this.init();
-  //     },
-  //     deep:true
-  //   }
-  // },
   data() {
   data() {
     return {
     return {
-      // optionData: {},
       sheetObj: {}
       sheetObj: {}
     }
     }
   },
   },
   methods: {
   methods: {
     init() {
     init() {
-      let optionData = this.option ? JSON.parse(this.option) : {};
+      let optionData = this.option ? this.option : {};
+
       initSheet('sheet-container',optionData,this.sheetInfo)
       initSheet('sheet-container',optionData,this.sheetInfo)
     }
     }
   },
   },

+ 1 - 1
src/views/datasheet_manage/components/selectTargetValueDia.vue

@@ -107,7 +107,7 @@ export default {
 }
 }
 </script>
 </script>
 <style scoped lang='scss'>
 <style scoped lang='scss'>
-@import "../../../styles/theme-vars.scss";
+@import "~@/styles/theme-vars.scss";
 .select-target-value-dia {
 .select-target-value-dia {
   background: #fff;
   background: #fff;
   position: fixed;
   position: fixed;

+ 6 - 2
src/views/datasheet_manage/components/sheetClassifyDia.vue

@@ -1,3 +1,4 @@
+<!-- 通用二级分类的弹窗 -->
 <template>
 <template>
 	<div class="sheet-classify-dialog">
 	<div class="sheet-classify-dialog">
 		<el-dialog
 		<el-dialog
@@ -81,6 +82,9 @@ export default {
       
       
 			const handleMap = {
 			const handleMap = {
 				'/sheetList': this.sheetClassifyApi,
 				'/sheetList': this.sheetClassifyApi,
+				'/sheetTimeList': this.sheetClassifyApi,
+				'/sheetMixedList': this.sheetClassifyApi,
+				'/sheetAnalysisList': this.sheetClassifyApi,
 				'/commordityChartBase': this.commodityClassifyApi,
 				'/commordityChartBase': this.commodityClassifyApi,
 				'/chartrelevance':this.relevanceClassifyApi,
 				'/chartrelevance':this.relevanceClassifyApi,
 				'/fittingEquationList': this.fittingEquationClassifyApi,
 				'/fittingEquationList': this.fittingEquationClassifyApi,
@@ -92,8 +96,8 @@ export default {
 		/* 表格分类接口 */
 		/* 表格分类接口 */
 		async sheetClassifyApi(classify_name,classify_id) {
 		async sheetClassifyApi(classify_name,classify_id) {
 			const { Ret,Msg } = !classify_id
 			const { Ret,Msg } = !classify_id
-        ? await sheetInterface.classifyAdd({ ExcelClassifyName:classify_name })
-        : await sheetInterface.classifyEdit({ ExcelClassifyName:classify_name, ExcelClassifyId:classify_id  })
+        ? await sheetInterface.classifyAdd({ ExcelClassifyName:classify_name,Source: this.$parent.sourceMap[this.$route.path] })
+        : await sheetInterface.classifyEdit({ ExcelClassifyName:classify_name, ExcelClassifyId:classify_id,Source: this.$parent.sourceMap[this.$route.path] })
         
         
       if( Ret !== 200) return
       if( Ret !== 200) return
       this.$message.success(Msg);
       this.$message.success(Msg);

+ 119 - 0
src/views/datasheet_manage/components/sheetListWrap.vue

@@ -0,0 +1,119 @@
+<template>
+  <div class="sheet-list-cont">
+    <span>共{{ total }}张表格</span>
+    <div class="sheetlist-wrapper" ref="listRef" @scroll="$emit('loadMoreHandle')">
+      <el-col
+        :span="6"
+        style="margin-bottom: 20px; padding-right: 20px"
+        v-for="cell in list"
+        :key="cell.ExcelInfoId"
+      >
+        <el-card class="sheet-item">
+          <div slot="header" class="item-top">
+            <span class="text_oneLine">{{ cell.ExcelName }}</span>
+          </div>
+          <img
+            :src="cell.ExcelImage"
+            alt=""
+            class="chart-img"
+            :height="imgHeight"
+            @click="$emit('detailShowHandle',cell)"
+          />
+          <div class="item-bottom">
+            <span>创建时间: {{ cell.CreateTime.slice(0, 10) }}</span>
+            <div>
+              <span
+                v-if="$parent.isSheetBtnShow('download')"
+                class="editsty"
+                style="margin-right: 10px"
+                @click="$emit('downloadExcel',cell)"
+                >下载</span
+              >
+              <span
+                v-if="$parent.isSheetBtnShow('del')"
+                class="deletesty"
+                @click="$emit('delSheetHandle',{cell, type:'del-list'})"
+                >删除</span
+              >
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </div>
+    <div v-if="!total" class="nodata">
+      <tableNoData text="暂无表格"/>
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  props: ['total','list'],
+  data() {
+    return {
+    }
+  },
+  mounted(){
+
+  },
+}
+</script>
+<style scoped lang='scss'>
+  .sheet-list-cont {
+    color: #333;
+    .el-card .el-card__header,
+    .el-card__body {
+      padding: 10px;
+    }
+
+    .sheetlist-wrapper {
+      margin-top: 10px;
+      display: flex;
+      flex-wrap: wrap;
+      max-height: calc(100vh - 143px);
+      overflow: hidden;
+      overflow-y: auto;
+      .drag-cont {
+        width: 100%;
+        display: flex;
+        flex-wrap: wrap;
+      }
+      .dragShdow {
+        box-shadow: 0 1px 8px rgba(64, 158, 255, 0.8);
+        opacity: 0.5;
+      }
+      .sheet-item {
+        .item-top {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          font-size: 16px;
+          font-weight: 600;
+        }
+        .chart-img {
+          width: 100%;
+          height: 196px;
+          object-fit: contain !important;
+          cursor: pointer;
+        }
+        .item-bottom {
+          margin-top: 10px;
+          display: flex;
+          justify-content: space-between;
+          font-size: 12px;
+          color: #666;
+          .collected {
+            color: #f00;
+            cursor: pointer;
+          }
+          .join_txt {
+            color: #409eff;
+            cursor: pointer;
+          }
+        }
+      }
+    }
+    .nodata {
+      text-align: center;
+    }
+  }
+</style>

+ 505 - 0
src/views/datasheet_manage/customAnalysis/addAnalysisSheet.vue

@@ -0,0 +1,505 @@
+<template>
+  <div class="addSheet-wrap">
+    
+    <createTargetForm 
+      v-if="$route.path==='/createTaregtBySheet'"
+      ref="createTargetRef" 
+      @save="handleCreateTarget" 
+    />
+
+
+    <div class="main">
+      <div class="left-section">
+        <el-tabs 
+          v-model="selectIndex" 
+          type="card"
+        >
+          <el-tab-pane
+            :key="item.name"
+            v-for="(item,index) in uploadSheetsList"
+            :label="item.name"
+            :name="String(index)"
+          />
+        </el-tabs>
+        <div class="sheet-wrapper">
+          <Sheet ref="sheetRef" :option="sheetConfig" v-if="sheetConfig.data"/>
+
+          <dataLoading :loading="isLoading"/>
+        </div>
+
+      </div>
+
+      <!-- 指标列表 -->
+      <rightSection 
+        ref="edbWrapRef"
+        v-if="$route.path==='/createTaregtBySheet'"
+        :list="edbList"
+        @choose="chooseEdbHandle"
+      />
+    </div>
+
+
+    <!-- 上传文件 -->
+    <bottomSection
+      ref="bottomSecRef"
+      v-if="$route.path==='/addAnalysisSheet'" 
+      :sheetList="sheetConfig.data||[]"
+      :classifyArr="classifyArr"
+      @save="handleAddSheet"
+    />
+
+  </div>
+</template>
+
+<script>
+import * as sheetInterface from '@/api/modules/sheetApi.js';
+import Sheet from '../components/SheetExcel.vue';
+import { getSheetImage } from '../common/option';
+import bottomSection from './components/bottomSection.vue'
+import rightSection from './components/rightSection.vue';
+import createTargetForm from './components/createTargetForm.vue';
+export default {
+  components: { Sheet,bottomSection,rightSection,createTargetForm },
+  computed: {
+    files() {
+      return this.$store.state.sheet.files;
+    },
+    sheetConfig() {
+      return this.$route.path==='/createTaregtBySheet' 
+        ? {
+            showsheetbar: true,
+            // allowCopy:false,
+            // allowEdit:false,
+            // allowUpdate:false,
+            // enableAddRow:false,
+            data: null,
+            hook: {
+              //选区时
+              rangeSelect: (sheet,range) => {
+                if(this.$refs.createTargetRef && this.$refs.createTargetRef.selectArea && !this.$refs.createTargetRef.isLockUpdate) this.getRangeCell()
+              },
+            }
+          } 
+        : {
+            showsheetbar: true,
+            data: null
+          }
+    },
+  },
+  data() {
+    return {
+      isLoading: false,
+      uploadSheetsList: [],
+      pageSize: 2000,
+      currentPage: 0,
+      maxPage:0,
+
+      selectIndex: '0',
+      classifyArr: [],
+
+      sheetDetailInfo: {},
+      sheetDataPage: 2,
+      sheetAllcellData:[],//全部单元格数据 分页push
+      dataToalPage: 0,
+
+      edbList: [],//生成的指标列表
+    }
+  },
+  methods: {
+
+    backHandle(scence=null) {
+      if(scence === 'into-detail') {
+        const { ExcelInfoId, UniqueCode } = this.sheetDetailInfo;
+        
+        this.$router.replace({
+          path: '/sheetAnalysisList',
+          query: {
+            code: UniqueCode,
+            id: ExcelInfoId
+          }
+        })
+      }else {
+        this.$router.go(-1);
+      }
+
+    },
+
+    /* 切换表格 */
+    handleSwitchSheet() {
+      this.sheetConfig.data = null;
+      this.handelTranslateData(); 
+    },
+
+    /* 获取分类 */
+    getClassify() {
+      sheetInterface.excelClassifyOne({Source: 4}).then(res => {
+        if(res.Ret !==200) return
+        
+        this.classifyArr = res.Data.AllNodes || [];
+      })
+    },
+
+    loadDataSync() {
+      let len = this.sheetConfig.data.length;
+      for(let i =0;i<len;i++) {
+        if(this.allSheetData[i].celldata[this.currentPage*this.pageSize]) {
+          let concatData = this.allSheetData[i].celldata.slice(this.currentPage*this.pageSize, (this.currentPage+1)*this.pageSize);
+
+          // this.sheetConfig.data[i].celldata = this.sheetConfig.data[i].celldata.concat(concatData) 
+          // this.$refs.sheetRef.init()
+        }
+        continue
+
+      }
+
+      if (this.currentPage<this.maxPage) {
+        this.currentPage++
+        requestAnimationFrame(this.loadDataSync());
+      }
+    },
+
+    /* 分割数据 */
+    splitSheetData(sheets) {
+      // this.allSheetData = sheets.map(_ => ({
+      //   index: _.index, //工作表索引
+      //   order: _.order, //工作表的下标
+      //   name: _.name,
+      //   calcChain: _.calcChain,
+      //   celldata: _.celldata,
+      //   config: _.config
+      // }));
+      // this.maxPage = Math.max(...sheets.map(_ =>  Math.ceil(_.celldata.length / this.pageSize)))
+      console.log(sheets)
+
+      this.sheetConfig.data = sheets.map(_ => ({
+        index: _.index, //工作表索引
+        order: Number(_.order), //工作表的下标
+        name: _.name,
+        calcChain: _.calcChain,
+        config: _.config,
+        celldata: _.celldata,
+      }));
+      
+      //辣鸡插件连更新数据的api都没有
+       //  this.loadDataSync();
+      
+      this.isLoading = false;
+    },
+
+    handelTranslateData() {
+        this.isLoading = true;
+        LuckyExcel.transformExcelToLucky(this.uploadSheetsList[Number(this.selectIndex)], (exportJson, luckysheetfile) =>{
+                                  
+          if(exportJson.sheets==null || exportJson.sheets.length==0){
+              this.$message.warning('解析文件失败')
+              return;
+          }
+
+            this.splitSheetData(exportJson.sheets);
+
+        });
+
+    },
+
+    /* 移除表格 */
+    handleRemoveSheet(index) {
+      if(this.uploadSheetsList.length === 1) {
+        this.backHandle()
+        return
+      }
+
+      this.uploadSheetsList.splice(Number(index),1)
+      if(this.selectIndex === index) {
+        this.selectIndex = '0';
+        this.handleSwitchSheet()
+      }
+
+    },
+
+
+    /* 保存表格 */
+    handleAddSheet: _.debounce(async function() {
+      luckysheet.exitEditMode()
+      let data = luckysheet.getAllSheets().filter(_ => this.$refs.bottomSecRef.sheetChecked.includes(_.name));
+      console.log(data)
+
+      this.loading = this.$loading({
+				target:'.addSheet-wrap',
+				lock: true,
+				text: '保存中...',
+				spinner: 'el-icon-loading',
+				background: 'rgba(255, 255, 255, 0.6)'
+			});
+      let img = getSheetImage(data[0]);
+			const form  = new FormData();
+			form.append('Image', img);
+			const { Data } = await sheetInterface.uploadImg(form)
+
+      data.luckysheet_select_save = [];
+      const res = await sheetInterface.sheetAnalysisInterface.excelSheetAdd({
+        ExcelName: this.uploadSheetsList[0].name,
+        ExcelClassifyId: this.$refs.bottomSecRef.select_classify,
+        ExcelImage: Data.ResourceUrl,
+        Content: JSON.stringify(data)
+      })
+      this.loading.close()
+      if(res.Ret !== 200) return
+
+      this.$message.success(res.Msg);
+
+      // const { ExcelInfoId, UniqueCode } = res.Data;
+      
+      this.$router.replace({
+        path: '/sheetAnalysisList',
+        // query: {
+        //   code: UniqueCode,
+        //   id: ExcelInfoId
+        // }
+      })
+    },300),
+
+     /* 获取表格详情 */
+    getDetailHandle() {
+      this.isLoading = true;
+      sheetInterface.sheetAnalysisInterface.getExcelDetail({
+        UniqueCode: this.$route.query.code,
+      }).then((res) => {
+        if (res.Ret !== 200) return;
+
+        this.sheetDetailInfo = res.Data.ExcelInfo;
+        this.dataToalPage =  Math.max(...res.Data.SheetList.map(_ => _.PageNum));
+        this.sheetAllcellData = res.Data.SheetList.map(_ => _.Data ? JSON.parse(_.Data.Data): []);
+
+        this.getCellData(res.Data.SheetList)
+      });
+    },
+
+    //分页获取表格数据
+    async getCellData(sheets) {
+
+      let res = await sheetInterface.sheetAnalysisInterface.getExcelDataByPage({
+        UniqueCode: this.$route.query.code,
+        Page: this.sheetDataPage
+      })
+
+      if(res.Ret !== 200) return
+
+      for(let i = 0;i<this.sheetAllcellData.length;i++) {
+        if(res.Data[i].Data) {
+          this.sheetAllcellData[i] = [...this.sheetAllcellData[i],...JSON.parse(res.Data[i].Data.Data)]
+        }
+        continue
+      }
+      
+      //数据继续加载或渲染表格
+      if(this.sheetDataPage < this.dataToalPage) {
+        this.sheetDataPage++;
+        this.getCellData(sheets)
+      }else {
+        this.sheetConfig.data = sheets.map((_,index) => ({
+          index: _.Index, //工作表id
+          order: _.Sort, //工作表的下标
+          name: _.SheetName,
+          calcChain: JSON.parse(_.CalcChain),
+          config: JSON.parse(_.Config),
+          celldata: this.sheetAllcellData[index],
+        }))
+
+        this.isLoading = false;
+        this.getTargetList()
+      }
+    },
+
+
+    /* 获取选取对应单元格数组和拼接选取的公式 
+      Sheet1!$A$1:$A$25
+      Sheet1!$E:$E
+    */
+    getRangeCell: _.debounce(function() {
+      let sheet = luckysheet.getSheet();
+      let rangeArr = luckysheet.getRangeAxis();
+
+      if(rangeArr.length > 1) return this.$message.warning('同时只允许选择一块区域');
+      //检查选取是否满足同行/同列
+      if(!this.checkRangeVaild(rangeArr[0])) return this.$message.warning('序列只允许选择同行或同列');
+
+      let rangeCells = luckysheet.getRangeValue().flat().map(_=>_?_.m:'');
+
+      let format = `${sheet.name}!${this.formatStr(rangeArr[0])}`;
+
+      console.log(format)
+      this.$refs.createTargetRef.setFormula(format,rangeCells)
+    },300),
+
+    //检验同行同列
+    checkRangeVaild(range) {
+      let reg = /^([A-Z]+)(\d+)$/;
+      let arr = range.split(':').map(_ => [_.match(reg)[1],_.match(reg)[2]]);
+      
+      if(arr.length ===1) return true;
+
+      if(arr[0][0] === arr[1][0] || arr[0][1] === arr[1][1]) {
+        return true
+      }else {
+        return false
+      }
+    },
+
+    formatStr(inputRange) {
+      // 将字母和数字前面都拼接"$"
+      const parts = inputRange.split(':');
+      if (parts.length === 2) {
+          const start = parts[0].replace(/(^[A-Z]+)(\d+)$/, '$$$1$$$2');
+          const end = parts[1].replace(/(^[A-Z]+)(\d+)$/, '$$$1$$$2');
+          return start + ':' + end;
+      }
+      return inputRange;
+      
+    },
+    
+    /* 生成指标 */
+    async handleCreateTarget() {
+      console.log(this.$refs.createTargetRef.formData)
+      this.loading = this.$loading({
+				target:'.addSheet-wrap',
+				lock: true,
+				text: '保存中...',
+				spinner: 'el-icon-loading',
+				background: 'rgba(255, 255, 255, 0.6)'
+			});
+
+      let data = luckysheet.getAllSheets();
+      data.luckysheet_select_save = [];
+      const { ExcelInfoId, ExcelName, ExcelClassifyId } = this.sheetDetailInfo;
+      await sheetInterface.sheetAnalysisInterface.sheetEdit({
+        ExcelInfoId,
+        ExcelName,
+        ExcelClassifyId,
+        // ExcelImage: Data.ResourceUrl,
+        Content: JSON.stringify(data)
+      });
+      
+      const { edbInfoId,
+        dateSeries,
+        valueSeries,
+        dateArr,
+        valueArr,
+				edbName,
+				classify,
+				frequency,
+				unit } = this.$refs.createTargetRef.formData;
+      let params = {
+        EdbName: edbName,
+        ExcelInfoId: ExcelInfoId,
+        ClassifyId: classify,
+        Frequency: frequency,
+        Unit: unit,
+        DateSequenceVal: dateArr,
+        DataSequenceVal: valueArr,
+        DateSequenceStr: dateSeries,
+        DataSequenceStr: valueSeries
+      }
+      const res = edbInfoId 
+        ? await sheetInterface.sheetAnalysisInterface.edbEditBysheet({...params,EdbInfoId: edbInfoId})
+        : await sheetInterface.sheetAnalysisInterface.edbAddBysheet(params)
+
+      this.loading.close();
+      if(res.Ret !== 200) return
+
+      this.$message.success(res.Msg)
+
+      if(!edbInfoId) this.$refs.createTargetRef.initData();
+
+      this.getTargetList()
+    },
+
+    /* 获取生成指标列表 */
+    async getTargetList() {
+      const res = await sheetInterface.sheetAnalysisInterface.edbListBySheet({
+        ExcelInfoId: this.sheetDetailInfo.ExcelInfoId
+      })
+
+      if(res.Ret !== 200) return
+      
+      this.edbList = res.Data || [];
+    },
+
+    /* 选择指标列表更新表单信息和区域选中 */
+    chooseEdbHandle() {
+
+      if(this.$refs.edbWrapRef.selectEdb.EdbInfoId) {
+        this.$refs.createTargetRef.initData(this.$refs.edbWrapRef.selectEdb)
+      } else {
+        this.$refs.createTargetRef.initData()
+      }
+    }
+    
+  },
+  mounted() {
+    this.getClassify();
+    //上传文件的解析渲染
+    if(this.files) {
+      this.uploadSheetsList =  Object.values(this.files);
+      this.handelTranslateData()
+      this.$store.commit('sheet/SET_UPLOADFIlES',null)
+    }
+
+    //详情的渲染
+    if(this.$route.query.code) this.getDetailHandle();
+  }
+}
+</script>
+<style scoped lang="scss">
+*{ box-sizing: border-box; }
+.addSheet-wrap {
+  min-height: calc(100vh - 120px);
+  .wrap-top {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 20px;
+    padding: 20px;
+    background: #fff;
+    border: 1px solid #ececec;
+    border-radius: 4px;
+    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
+    display: flex;
+    z-index: 1;
+    .form-ul {
+      flex: 1;
+      display: flex;
+      li {
+        margin-right: 30px;
+      }
+    }
+  }
+  .main {
+    display: flex;
+    position: relative;
+    min-height: 700px;
+    .left-section {
+      flex:1;
+      .sheet-wrapper {
+        position: relative;
+        background: #fff;
+        min-height: 700px;
+      }
+    
+    }
+    &.full-height {
+      min-height: calc(100vh - 120px);
+    }
+  }
+}
+</style>
+<style lang="scss">
+.addSheet-wrap {
+  .el-tabs__nav {
+    background: #fff;
+  }
+  .el-tabs__header {
+    margin-bottom: 0;
+    // border-bottom: none;
+  }
+}
+</style>

+ 130 - 0
src/views/datasheet_manage/customAnalysis/components/bottomSection.vue

@@ -0,0 +1,130 @@
+<template>
+  <div class="bottom-section">
+
+    <!-- 无同名 -->
+    <div>
+      <div class="page-list" v-if="sheetPages.length">
+        <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange" style="margin-right:30px">全部</el-checkbox>
+        <el-checkbox-group v-model="sheetChecked" @change="handleCheckedChange">
+          <el-checkbox v-for="item in sheetPages" :label="item" :key="item">{{item}}</el-checkbox>
+        </el-checkbox-group>
+      </div>
+
+      <div>
+        <el-select 
+          v-model="select_classify"
+          placeholder="请选择表格目录"
+          clearable
+          style="width:350px;"
+        >
+          <el-option
+            v-for="item in classifyArr"
+            :key="item.ExcelClassifyId"
+            :label="item.ExcelClassifyName"
+            :value="item.ExcelClassifyId"
+          />
+        </el-select>
+        <el-button type="primary" style="margin-left:30px" @click="saveSheetHandle">保存</el-button>
+          <el-tooltip class="item" effect="dark" content="根据用户选择的sheet页上传文件" placement="top-start">
+          <i class="el-icon-warning"/>
+        </el-tooltip>
+      </div>
+    </div>
+
+    <!-- 有同名文件 -->
+    <!-- <div>
+      <div class="same-page-item">
+        <label>
+          <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
+            <path d="M14.7136 12.8013L9.22087 2.90725C8.54904 1.69758 7.45106 1.69758 6.77941 2.90725L1.28669 12.8013C0.615035 14.0122 1.16452 15 2.5069 15H13.4933C14.8357 15 15.3846 14.0121 14.7136 12.8013ZM7.2457 5.71459C7.44308 5.49263 7.69402 5.38164 8.00006 5.38164C8.30627 5.38164 8.55698 5.49146 8.75456 5.71015C8.95086 5.92933 9.04898 6.20343 9.04898 6.53305C9.04898 6.81664 8.63924 8.902 8.50257 10.4191H7.51565C7.39579 8.90199 6.95119 6.81664 6.95119 6.53305C6.95122 6.20844 7.0495 5.93546 7.2457 5.71459ZM8.74074 12.9285C8.53313 13.1387 8.28608 13.2435 8.00013 13.2435C7.71426 13.2435 7.46714 13.1387 7.25956 12.9285C7.05256 12.7186 6.94967 12.4645 6.94967 12.166C6.94967 11.8691 7.05256 11.6123 7.25956 11.397C7.46714 11.1816 7.71426 11.0739 8.00013 11.0739C8.28608 11.0739 8.53313 11.1816 8.74074 11.397C8.94761 11.6123 9.05074 11.8691 9.05074 12.166C9.05074 12.4645 8.94761 12.7186 8.74074 12.9285Z" fill="#E37318"/>
+          </svg>
+          下列sheet页同名,勾选可替换页面内容
+          <span style="color:#999">(不勾选则拼接原内容+上传内容,不去重)</span>
+        </label>
+        <div class="page-list">
+          <el-radio v-model="item.checked" v-for="item in sheetPages" :key="item">{{item}}</el-radio>
+        </div>
+      </div>
+      <div class="same-page-item">
+        <label>
+          <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
+            <path d="M14.7136 12.8013L9.22087 2.90725C8.54904 1.69758 7.45106 1.69758 6.77941 2.90725L1.28669 12.8013C0.615035 14.0122 1.16452 15 2.5069 15H13.4933C14.8357 15 15.3846 14.0121 14.7136 12.8013ZM7.2457 5.71459C7.44308 5.49263 7.69402 5.38164 8.00006 5.38164C8.30627 5.38164 8.55698 5.49146 8.75456 5.71015C8.95086 5.92933 9.04898 6.20343 9.04898 6.53305C9.04898 6.81664 8.63924 8.902 8.50257 10.4191H7.51565C7.39579 8.90199 6.95119 6.81664 6.95119 6.53305C6.95122 6.20844 7.0495 5.93546 7.2457 5.71459ZM8.74074 12.9285C8.53313 13.1387 8.28608 13.2435 8.00013 13.2435C7.71426 13.2435 7.46714 13.1387 7.25956 12.9285C7.05256 12.7186 6.94967 12.4645 6.94967 12.166C6.94967 11.8691 7.05256 11.6123 7.25956 11.397C7.46714 11.1816 7.71426 11.0739 8.00013 11.0739C8.28608 11.0739 8.53313 11.1816 8.74074 11.397C8.94761 11.6123 9.05074 11.8691 9.05074 12.166C9.05074 12.4645 8.94761 12.7186 8.74074 12.9285Z" fill="#E37318"/>
+          </svg>
+          下列sheet页不同名,勾选可新增sheet页
+          <span style="color:#999">(不勾选则不新增)</span>
+        </label>
+        <div class="page-list">
+          <el-radio v-model="item.checked" v-for="item in sheetPages" :key="item">{{item}}</el-radio>
+          
+        </div>
+      </div>
+
+      <el-button type="primary">保存</el-button>
+    </div> -->
+
+  </div>
+</template>
+<script>
+export default {
+  props: {
+    sheetList: {
+      type: Array
+    },
+    classifyArr: {
+      type: Array
+    }
+  },
+  watch: {
+    sheetList(nval) {
+      this.sheetPages = nval.map(_ => _.name)
+      this.sheetChecked = this.sheetPages;
+    }
+  },
+  data() {
+    return {
+      isIndeterminate: false,
+      checkAll: true,
+      sheetPages: [],
+      sheetChecked: [],
+
+      select_classify: '',
+      classifyArr: this.classifyArr,
+    }
+  },
+  methods:{
+    saveSheetHandle() {
+      if(!this.sheetChecked.length) return this.$message.warning('请选择要保存的sheet页')
+      if(!this.select_classify) return this.$message.warning('请选择分类')
+
+      this.$emit('save')
+    },
+
+    handleCheckedChange(val){
+      this.checkAll = val.length === this.sheetPages.length;
+      this.isIndeterminate = val.length > 0 && val.length < this.sheetPages.length;
+      console.log(this.sheetChecked)
+    },
+    handleCheckAllChange(val){
+      this.sheetChecked = val ? this.sheetPages : [];
+      this.isIndeterminate = false;
+    },
+  },
+}
+</script>
+<style scoped lang='scss'>
+.bottom-section {
+  background: #fff;
+  padding: 20px 20px 50px;
+  border-radius: 4px;
+  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
+  .page-list  {
+    display: flex;
+    align-items: center;
+    margin: 10px 0;
+    margin-bottom: 30px;
+  }
+  .btn-bottom {
+    margin-top: 20px;
+  }
+}
+</style>

+ 261 - 0
src/views/datasheet_manage/customAnalysis/components/createTargetForm.vue

@@ -0,0 +1,261 @@
+<template>
+  <div class="create-form-cont">
+    <el-form
+      ref="formRef"
+      label-position="left"
+      hide-required-asterisk
+      inline
+      label-width="0"
+      :model="formData"
+      :rules="formRules"
+    >
+      <el-form-item prop="dateSeries">
+        <el-input v-model="formData.dateSeries" placeholder="请选择日期序列" @focus="selectArea='date'" @change="changeFormat('date')" @keyup.native="e => { e.keyCode===13 && initSelect()}" :class="{'select': selectArea==='date'}"></el-input>
+      </el-form-item>
+      <el-form-item prop="valueSeries">
+        <el-input v-model="formData.valueSeries" placeholder="请选择数值序列" @focus="selectArea='value'" @change="changeFormat('value')" @keyup.native="e => { e.keyCode===13 && initSelect()}" :class="{'select': selectArea==='value'}"></el-input>
+      </el-form-item>
+
+      <el-form-item prop="edbName">
+        <el-input v-model="formData.edbName" placeholder="指标名称" @focus="initSelect"></el-input>
+      </el-form-item>
+      <el-form-item prop="classify">
+        <el-cascader
+          v-model="formData.classify"
+          :options="classifyOption"
+          style="width: 100%"
+          @focus="initSelect"
+          :props="{
+            label: 'ClassifyName',
+            value: 'ClassifyId',
+            children: 'Children',
+            emitPath: false,
+            checkStrictly: true
+          }"
+          clearable
+          placeholder="请选择所属目录"
+        />
+      </el-form-item>
+      <el-form-item prop="frequency">
+        <el-select
+          v-model="formData.frequency"
+          placeholder="请选择频率"
+          style="width: 100%"
+          @focus="initSelect"
+          clearable
+        >
+          <el-option
+            v-for="item in frequencyArr"
+            :key="item"
+            :label="item"
+            :value="item"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item prop="unit">
+        <selectUnit v-model="formData.unit" @click.native="initSelect"/>
+      </el-form-item>
+      
+      <el-form-item>
+        <el-button type="primary" @click="handleSaveTarget">保存</el-button>
+        <el-button type="primary" plain @click="$parent.backHandle('into-detail')">返回</el-button>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+<script>
+import {dataBaseInterface} from '@/api/api.js'
+export default {
+  data() {
+    return {
+      selectArea: '',
+      formData: {
+        edbInfoId: 0,
+        dateSeries: '',
+        valueSeries: '',
+        dateArr:[],
+        valueArr: [],
+				edbName:'',
+				classify:'',
+				frequency: '',
+				unit:'',
+      },
+      formRules: {
+        // dateSeries: [{ required: true, message: '日期序列不能为空', trigger: 'blur' }],
+        // valueSeries: [{ required: true, message: '数值序列不能为空', trigger: 'blur' }],
+        edbName: [{ required: true, message: '指标名称不能为空', trigger: 'blur' }],
+        classify: [{ required: true, message: '目录不能为空', trigger: 'blur' }],
+        frequency: [{ required: true, message: '频率不能为空', trigger: 'blur' }],
+        unit: [{ required: true, message: '单位不能为空', trigger: 'blur' }],
+      },
+      frequencyArr:['日度','周度','旬度','月度','季度','年度'],
+      classifyOption: [],
+
+      isLockUpdate: false,//防止手动改变公式设置选区出发hook事件又更新公式和值 手动设置值即可
+    };
+  },
+  methods: {
+
+    /* 选区时更新公式 */
+    setFormula(formula,arr) {
+      if(!this.selectArea) return
+      //更新日期序列公式
+      if(this.selectArea === 'date') {
+        this.formData.dateArr = arr;
+        this.formData.dateSeries = formula
+      }else if(this.selectArea === 'value') {
+        //更新数值序列公式
+        this.formData.valueArr = arr;
+         this.formData.valueSeries = formula
+      }
+
+      console.log(this.formData)
+    },
+
+    /* 获取分类 */
+		getMenu() {
+			dataBaseInterface.menuListV3().then((res) => {
+				if (res.Ret !== 200) return
+        this.filterNodes(res.Data.AllNodes||[]);
+				this.classifyOption = res.Data.AllNodes || [];
+			});
+		},
+    
+    filterNodes(arr) {
+			arr.length &&
+				arr.forEach((item) => {
+					item.Children.length && this.filterNodes(item.Children);
+					if (!item.Children.length) {
+						delete item.Children;
+					}
+				});
+		},
+
+    /* 改变公式 */
+    changeFormat(type) {
+      this.isLockUpdate = true;
+      this.setRangeShow(type==='date'?this.formData.dateSeries:this.formData.valueSeries)
+      
+      let rangeArr = luckysheet.getRangeAxis();
+
+      //检查选取是否满足同行/同列
+      if(!this.$parent.checkRangeVaild(rangeArr[0])){
+        type==='date'?this.formData.dateSeries = '':this.formData.valueSeries ='';
+        return this.$message.warning('序列只允许选择同行或同列');
+      } 
+
+      let rangeCells = luckysheet.getRangeValue().flat().map(_=>_?_.m:'');
+      //更新公式关联的数据数组
+      type==='date' ? this.formData.dateArr = rangeCells : this.formData.valueArr = rangeCells;
+      console.log(this.formData)
+      this.isLockUpdate = false;
+    },
+
+    initSelect() {
+      this.selectArea = ''
+    },
+
+    initData(data=null) {
+      this.initSelect()
+      if(data) {
+        this.formData = {
+          edbInfoId: data.EdbInfoId,
+          dateSeries: data.DateSequenceStr,
+          valueSeries: data.DataSequenceStr,
+          dateArr:[],
+          valueArr: [],
+          edbName: data.EdbName,
+          classify: data.ClassifyId,
+          frequency: data.Frequency,
+          unit: data.Unit,
+        }
+
+        this.setRangeShow([data.DateSequenceStr,data.DataSequenceStr]);
+      }else {
+        this.formData = {
+          edbInfoId: 0,
+          dateSeries: '',
+          valueSeries: '',
+          dateArr:[],
+          valueArr: [],
+          edbName:'',
+          classify:'',
+          frequency: '',
+          unit:'',
+        }
+        
+        this.setRangeShow(['A1','A1'])
+      }
+    },
+
+    /* 解析公式显示选区 */
+    setRangeShow(range) {
+      
+      //初始化多选区
+      let rangeArr = [];
+      if(Array.isArray(range)) {
+        range.forEach(_ => {
+          rangeArr.push(this.splitFormula(_))
+        })
+      }else {
+        rangeArr = [this.splitFormula(range)]
+      }
+      luckysheet.setRangeShow(rangeArr)
+    },
+
+    /* 解析公式 */
+    splitFormula(formula) {
+      let str = formula.substr(formula.indexOf('!')+1).replace(/\$/g,'')
+      return str
+    },
+
+    /* 保存 */
+    handleSaveTarget: _.debounce(async function() {
+      if(!this.formData.dateSeries) return this.$message.warning('日期序列不能为空')
+      if(!this.formData.valueSeries) return this.$message.warning('数值序列不能为空')
+
+      await this.$refs.formRef.validate();
+      this.initSelect();
+      this.$emit('save')
+    },300),
+  },
+  
+  mounted() {
+    this.getMenu()
+  },
+};
+</script>
+<style scoped lang="scss">
+.create-form-cont {
+  background: #fff;
+  margin-bottom: 20px;
+  display: flex;
+  flex-wrap: wrap;
+  padding: 20px;
+  .el-form-item {
+    margin-bottom: 20px;
+    /* .select {
+      &::before {
+        content: '';
+        position: absolute;
+        left: 0;
+        right: 0;
+        top: 0;
+        bottom: 0;
+        border: 2px dashed #18ad18;
+        border-radius: 4px;
+      }
+    } */
+  }
+}
+</style>
+
+<style lang="scss">
+  .create-form-cont {
+    .select .el-input__inner {
+       border: 2px dashed #18ad18;
+      border-radius: 4px;
+    }
+  }
+</style>

+ 118 - 0
src/views/datasheet_manage/customAnalysis/components/rightSection.vue

@@ -0,0 +1,118 @@
+<template>
+  <div class="right-section-wrapper">
+    <div class="create-cont">
+      <ul class="edb-list" v-if="edbList.length">
+        <li :class="['edb-item',{'selected':selectEdb.EdbInfoId===item.EdbInfoId}]" v-for="(item,index) in edbList" :key="index" @click="chooseEdb(item)">
+          <span>{{item.EdbName}}</span>
+          <div class="item-right">
+            <!-- <i class="el-icon-edit" style="margin-right:10px" @click.stop="editEdbSettingHandle"/> -->
+            <img :src="$icons.jupm_icon" class="jump-icon" @click.stop="linkToEdbBase(item)">
+          </div>
+        </li>
+      </ul>
+      <div style="padding-top: 50px;" v-else>
+        <tableNoData text="暂无指标"/>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  props: {
+    list: {
+      type: Array
+    }
+  },
+  watch: {
+    list(nval) {
+      this.edbList = nval;
+    }
+  },
+  data() {
+    return {
+      edbList:[],
+      selectEdb: {},
+    }
+  },
+  mounted(){
+
+  },
+  methods:{
+
+    chooseEdb(item) {
+      if(item.EdbInfoId === this.selectEdb.EdbInfoId) {
+        this.selectEdb = {};
+      }else {
+        this.selectEdb = item;
+      }
+
+      this.$emit('choose')
+    },
+
+    //跳转指标库
+    linkToEdbBase({UniqueCode,EdbInfoId,ClassifyId}) {
+      let {href} = this.$router.resolve({path:'/database', query: {
+        code: UniqueCode,
+        id: EdbInfoId,
+        classifyId:ClassifyId
+      }});
+			window.open(href,'_blank');
+    }
+  },
+}
+</script>
+<style scoped lang='scss'>
+@import"~@/styles/theme-vars.scss";
+.right-section-wrapper {
+  width: 360px;
+  flex-shrink: 0;
+  border-radius: 4px;
+  border: 1px solid #C8CDD9;
+  background: #FFF;
+  margin-left: 20px;
+  .create-cont {
+    .edb-list {
+      padding: 30px;
+      overflow-y: auto;
+      .edb-item {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        padding: 14px 20px;
+        margin: 10px 0;
+        border-radius: 4px;
+        border: 1px solid #C8CDD9;
+        background: #FFF;
+        &.selected { 
+          border-color: $theme-color; background: #ECF2FE;
+        }
+        .item-right {
+          display: flex;
+          align-items: center;
+          .jump-icon {
+            cursor: pointer;
+            &:hover {
+              opacity: 0.8;
+            }
+          }
+        }
+        .el-icon-edit {
+          font-size: 16px;
+          &:hover {
+            color: $theme-color;
+            cursor: pointer;
+          }
+        }
+      }
+    }
+  }
+}
+</style>
+<style lang="scss">
+.right-section-wrapper {
+  .el-form--label-top .el-form-item__label {
+    height: 20px;
+    line-height: 20px;
+  }
+} 
+</style>

+ 1092 - 0
src/views/datasheet_manage/customAnalysis/list.vue

@@ -0,0 +1,1092 @@
+<template>
+  <div class="dataSheet-container" v-if="showData">
+    <span
+      class="slide-icon slide-right"
+      @click="isSlideLeft = !isSlideLeft"
+      v-show="isSlideLeft"
+    >
+      <i class="el-icon-d-arrow-right"></i>
+    </span>
+    <div class="data-sheet-main" id="box">
+      <div class="main-left left" id="left" v-show="!isSlideLeft">
+        <div class="datasheet_top">
+          
+          <el-button
+            type="primary" 
+            style="margin-right:20px"
+            :loading="isUploadLoading"
+            @click="clickUpload"
+            v-if="permissionBtn.checkPermissionBtn(permissionBtn.etaTablePermission.etaTable_analysis_upload)"
+          >上传文件</el-button>
+          <input type="file" @change="fileSelected" id="file"  style="display: none;">
+          
+          <el-checkbox v-model="isShowMe"  @change="() => { getTreeData();getPublicList() }">只看我的</el-checkbox>
+        </div>
+        <div class="search-cont">
+          <el-select
+            v-model="search_txt"
+            ref="searchRef"
+            :filterable="!search_txt"
+            remote
+            clearable
+            placeholder="表格名称"
+            style="width: 100%"
+            :remote-method="searchHandle"
+            @focus="searchHandle('')"
+          >
+            <i slot="prefix" class="el-input__icon el-icon-search"></i>
+            <el-option
+              v-for="item in searchOptions"
+              :key="item.ExcelInfoId"
+              :label="item.ExcelName"
+              :value="item.ExcelInfoId"
+            >
+            </el-option>
+          </el-select>
+        </div>
+        <div class="tree-cont">
+          <el-tree
+            ref="treeRef"
+            class="target_tree"
+            :data="treeData"
+            node-key="UniqueCode"
+            :props="defaultProp"
+            :allow-drag="canDragHandle"
+            :allow-drop="canDropHandle"
+            :current-node-key="select_node"
+            :default-expanded-keys="defaultShowNodes"
+            draggable
+            :expand-on-click-node="false"
+            check-strictly
+            empty-text="暂无分类"
+            @node-expand="handleNodeExpand"
+            @node-collapse="handleNodeCollapse"
+            @current-change="nodeChange"
+            @node-drop="dropOverHandle"
+            @node-drag-end="dropMouseLeave"
+            @node-drag-leave="dropMouseLeave"
+            @node-drag-enter="dropMouseOver"
+          >
+            <span class="custom-tree-node" slot-scope="{ node, data }">
+              <el-input
+                ref="editVal"
+                style="width: 90px"
+                placeholder="请输入值"
+                class="label-input"
+                v-model="new_label"
+                v-if="data.isEdit&&isSheetBtnShow('classifyOpt_edit')"
+                @blur="changeValue(data)"
+              />
+              <span
+                @dblclick.stop="editNodeLabel(data)"
+                v-else
+                class="text_oneLine node_label"
+                :style="`width:${
+                  (select_node === data.UniqueCode && node.Nodewidth) || ''
+                }`"
+              >
+                <span>{{ data.ExcelClassifyName }}</span>
+              </span>
+              <span
+                style="display: flex; align-items: center"
+                v-if="select_node === data.UniqueCode"
+              >
+                <img
+                  src="~@/assets/img/data_m/move_ico.png"
+                  alt=""
+                  style="width: 14px; height: 14px; margin-right: 8px"
+                />
+                <img
+                  src="~@/assets/img/set_m/edit.png"
+                  alt=""
+                  style="width: 15px; height: 14px; margin-right: 8px"
+                  @click.stop="editNode(node, data)"
+                  v-if="!data.ExcelInfoId&&isSheetBtnShow('classifyOpt_edit')"
+                />
+                <img
+                  slot="reference"
+                  src="~@/assets/img/set_m/del.png"
+                  alt=""
+                  style="width: 14px; height: 14px"
+                  @click.stop="removeNode(node, data)"
+                  v-if="!data.ExcelInfoId&&isSheetBtnShow('classifyOpt_delete')"
+                />
+              </span>
+            </span>
+          </el-tree>
+          <div class="noDepart" @click="addLevelOneHandle" v-if="isSheetBtnShow('classifyOpt_edit')">
+            <img
+              src="~@/assets/img/set_m/add_ico.png"
+              alt=""
+              style="width: 16px; height: 16px; margin-right: 10px"
+            />
+            <span>添加表格分类</span>
+          </div>
+        </div>
+        <span
+          class="move-btn resize"
+          v-drag
+          id="resize"
+          @mousemove="dynamicNode && resetNodeStyle(dynamicNode)"
+        ></span>
+        <span class="slide-icon slide-left" @click="isSlideLeft = !isSlideLeft">
+          <i class="el-icon-d-arrow-left"></i>
+        </span>
+      </div>
+
+      <div
+        class="main-right"
+        id="right"
+        :style="isSlideLeft ? 'width:100%' : 'width:80%'"
+      >
+        <!-- 表格详情 -->
+        <div class="sheet-detail-wrapper" v-if="select_id" >
+          <div class="detail-top">
+            <span class="author"
+              >作者:{{ sheetDetailInfo.SysUserRealName }}</span
+            >
+            <el-input
+              ref="sheetEditTitRef"
+              style="width: 400px"
+              placeholder="请输入表格名称"
+              class="label-input"
+              v-model="sheet_title"
+              v-if="sheetDetailInfo.isEditTit"
+              @blur="changeValue(sheetDetailInfo, 'edit-tit')"
+            />
+            <span
+              class="sheet-name"
+              @click="editNodeLabel(sheetDetailInfo, 'edit-tit')"
+              v-else
+            >
+              {{ sheetDetailInfo.ExcelName }}
+              <i class="el-icon-edit"/>
+            </span>
+            <ul class="action-ul" v-if="sheetDetailInfo.Button">
+
+              <el-tooltip effect="dark" content="在当前表格选择日期列和数据列生成指标" placement="top-start">
+                  <li class="editsty" @click="HandleToPath" v-if="isSheetBtnShow('createedb')&&sheetDetailInfo.Button.OpEdbButton">生成指标</li>
+              </el-tooltip>
+
+              <el-tooltip effect="dark" content="根据表格保存的最新内容,更新当前表格生成的所有指标" placement="top-start">
+                  <li class="editsty" @click="refreshSheet" v-if="isSheetBtnShow('refresh')&&sheetDetailInfo.Button.RefreshEdbButton">刷新指标</li>
+              </el-tooltip>
+              <li class="editsty" @click="saveHandle" v-if="isSheetBtnShow('save')&&sheetDetailInfo.Button.OpButton">保存</li>
+              <li
+                class="editsty"
+                @click="saveOtherHandle"
+                v-if="isSheetBtnShow('otherSave')&&sheetDetailInfo.Button.CopyButton"
+              >
+                另存为
+              </li>
+              <li class="editsty" @click="downloadExcel
+              (sheetDetailInfo)" v-if="isSheetBtnShow('download')&&sheetDetailInfo.Button.DownloadButton">
+                下载
+              </li>
+              <li
+                class="deletesty"
+                v-if="isSheetBtnShow('del')&&sheetDetailInfo.Button.DeleteButton"
+                @click="delSheetHandle({cell:sheetDetailInfo, type:'del'})"
+              >
+                删除
+              </li>
+            </ul>
+          </div>
+
+          <!-- <dataLoading :loading="isSheetLoading"/> -->
+
+          <!-- 表格 -->
+          <div class="sheet-wrap">
+            <Sheet
+              ref="sheetRef"
+              v-if="sheetConfigOpt.data"
+              :option="sheetConfigOpt"
+              :sheetInfo="{
+                ExcelInfoId: sheetDetailInfo.ExcelInfoId,
+                ExcelName: sheetDetailInfo.ExcelName,
+                ExcelClassifyId: sheetDetailInfo.ExcelClassifyId,
+                Source: sheetDetailInfo.Source
+              }"
+            />
+          </div>
+        </div>
+
+         <!-- 列表 -->
+        <sheetListWrap
+          v-else
+          :total="sheet_total" 
+          :list="sheetList" 
+          @loadMoreHandle="loadMoreHandle"
+          @detailShowHandle="detailShowHandle"
+          @delSheetHandle="delSheetHandle"
+          @downloadExcel="downloadExcel"
+          ref="sheetListWrap"
+        />
+      </div>
+
+      <dataLoading :loading="isSheetLoading"/>
+    </div>
+
+    <!-- 分类弹窗 -->
+    <classify-dia
+      :isOpenDialog.sync="classifyDia"
+      :title="dialog_title"
+      :form="classifyForm"
+      @successCallback="getTreeData"
+    />
+
+    <!-- 表格另存 -->
+    <m-dialog
+      :show.sync="isSaveOther"
+      width="650px"
+      title="另存为"
+      @close="cancelSaveOther"
+    >
+      <div style="padding-left: 80px">
+        <el-form
+          ref="formRef"
+          label-position="left"
+          hide-required-asterisk
+          label-width="80px"
+          :model="saveOtherForm"
+          :rules="saveOtherFormRule"
+        >
+          <el-form-item label="表格名称" prop="name">
+            <el-input
+              v-model="saveOtherForm.name"
+              style="width: 80%"
+              placeholder="请输入表格名称"
+            />
+          </el-form-item>
+          <el-form-item label="表格分类" prop="classify">
+            <el-cascader
+              v-model="saveOtherForm.classify"
+              :options="classifyOptions"
+              :props="{
+                label: 'ExcelClassifyName',
+                value: 'ExcelClassifyId',
+                children: 'Children',
+                emitPath: false,
+              }"
+              style="width: 80%"
+              placeholder="请选择所属分类"
+              class="sheet-classify-cascader"
+            />
+          </el-form-item>
+        </el-form>
+      </div>
+      <div style="display: flex; justify-content: center; margin-top: 30px">
+        <el-button
+          type="primary"
+          style="margin-right: 60px"
+          @click="saveCopyOther"
+          >保存</el-button
+        >
+        <el-button type="primary" plain @click="cancelSaveOther"
+          >取消</el-button
+        >
+      </div>
+    </m-dialog>
+  </div>
+</template>
+
+<script>
+import * as sheetInterface from "@/api/modules/sheetApi.js";
+import leftMixin from "../mixins/classifyMixin";
+import mDialog from "@/components/mDialog.vue";
+import classifyDia from "../components/sheetClassifyDia.vue";
+import Sheet from "../components/SheetExcel.vue";
+import { getSheetImage } from "../common/option";
+import sheetListWrap from "../components/sheetListWrap.vue"
+export default {
+  name: "",
+  components: { mDialog, classifyDia, Sheet, sheetListWrap },
+  mixins: [leftMixin],
+  computed: {
+    downExcelFileUrl() {
+      let url = `${
+        process.env.VUE_APP_API_ROOT
+      }/datamanage/excel_info/table/download?${localStorage.getItem("auth")}`;
+      return url;
+    },
+    classifyOptions() {
+      let options = this.treeData.map((_) => ({
+        ExcelClassifyId: _.ExcelClassifyId,
+        ExcelClassifyName: _.ExcelClassifyName,
+      }));
+
+      return options;
+    },
+  },
+  data() {
+    return {
+      showData: false,
+      search_txt: "",
+      searchOptions: [],
+      isSlideLeft: false, //左侧分类收起
+
+      select_node: "", //节点唯一标识code
+      select_classify: "",
+      new_label: "", //双击修改的value
+      treeData: [], //分类数据
+      defaultShowNodes: [], //展开节点
+      defaultProp: {
+        label: "ExcelClassifyName",
+        children: "Children",
+      }, //树结构配置项
+      dynamicNode: null,
+
+      /* 分类弹窗 */
+      dialog_title: "",
+      classifyDia: false, //
+      classifyForm: {},
+
+      select_id: "", //选中的表格id
+      sheetDetailInfo: {},
+      sheet_title: "", //表格标题 双击标题修改时来存储最新值
+      sheetConfigOpt: {
+        showsheetbar: true,
+        data: null
+      },
+      sheetDataPage: 2,
+      sheetAllcellData:[],//全部单元格数据 分页push
+      dataToalPage: 0,
+      isSheetLoading: false,
+
+      /* 表格列表 */
+      publicHaveMove: true, //是否还有列表数据
+      sheetList: [],
+      sheet_total: 0,
+      sheet_page: 1,
+      sheet_pages_size: 16,
+
+      /* 另存为 */
+      isSaveOther: false,
+      saveOtherForm: {
+        name: '',
+				classify: ''
+      },
+      saveOtherFormRule: {
+        name: [
+          { required: true, message: "表格名称不能为空", trigger: "blur" },
+        ],
+        classify: [
+          { required: true, message: "表格分类不能为空", trigger: "blur" },
+        ],
+      },
+
+      isShowMe: false,
+
+      sourceMap: {
+        '/sheetAnalysisList': 4,
+      },
+    };
+  },
+  watch: {
+    /* 设置动态右侧区域宽度 */
+    isSlideLeft(newval) {
+      this.select_id && this.$refs.sheetRef && this.$refs.sheetRef.init();
+      this.$nextTick(() => {
+        this.reloadRightWid();
+      });
+    },
+    /* 表格id */
+    select_id(newval) {
+      this.sheetDataPage = 2,
+      this.sheetAllcellData = [],//全部单元格数据 分页push
+      this.dataToalPage = 0;
+      this.sheetConfigOpt.data = null;
+      newval && this.getDetailHandle();
+    },
+
+    select_classify(newval) {
+      if (this.$refs.sheetListWrap) this.$refs.sheetListWrap.$refs.listRef.scrollTop = 0;
+      if (newval) {
+        this.sheet_page = 1;
+        this.getPublicList();
+      }
+    },
+
+    /* 搜索关键词 */
+    search_txt(newval) {
+      if (newval) {
+        let search_obj = this.searchOptions.find(
+          (_) => _.ExcelInfoId === newval
+        );
+        let deep_arr = _.cloneDeep(this.treeData);
+        // 查找图表的分类父级id
+        let arr = this.findParentNodeHandle(deep_arr, search_obj.UniqueCode)
+          .slice(1)
+          .reverse(); // 父的父的父-父的父-父
+        this.defaultShowNodes = arr;
+        this.select_node = search_obj.UniqueCode;
+        this.$refs.treeRef.setCurrentKey(this.select_node);
+        // 重置筛选状态
+        this.select_id = newval;
+      }
+    },
+  },
+  methods: {
+
+    /* 获取表格分类 */
+    getTreeData(params = null) {
+      sheetInterface.classifyList({Source: this.sourceMap[this.$route.path],IsShowMe: this.isShowMe}).then((res) => {
+        const { Ret, Data } = res;
+        if (Ret !== 200) return;
+
+        this.showData = true;
+        this.treeData = Data.AllNodes || [];
+        this.$nextTick(() => {
+          /* 新增完成后 处理树展开和选中 */
+          params && this.selectCurrentNode(params);
+        });
+      });
+    },
+
+    /* 搜索表格 */
+    searchHandle(query) {
+      if (query) {
+        /* 查找列表 */
+        sheetInterface
+          .sheetList({
+            Keyword: query,
+            CurrentIndex: 1,
+            PageSize: 10000,
+            Source: this.sourceMap[this.$route.path]
+          })
+          .then((res) => {
+            if (res.Ret !== 200) return;
+            this.searchOptions = res.Data.List || [];
+          });
+      } else {
+        this.searchOptions = [];
+      }
+    },
+
+    /* 选中分类变化时 */
+    nodeChange({ UniqueCode, ExcelInfoId, ExcelClassifyId }, node) {
+      this.search_txt = "";
+      this.select_node = UniqueCode;
+      this.select_classify = !ExcelInfoId ? ExcelClassifyId : 0;
+      if (this.select_id !== ExcelInfoId) {
+        this.select_id = ExcelInfoId || 0;
+        this.sheetDetailInfo = {};
+      }
+      this.resetNodeStyle(node);
+      this.dynamicNode = node;
+    },
+
+    /* 添加一级目录 */
+    addLevelOneHandle() {
+      this.dialog_title = "添加";
+      this.classifyForm = {
+        classify_name: "",
+      };
+      this.classifyDia = true;
+    },
+
+    /* 编辑节点 */
+    editNode(node, { ExcelClassifyName, ExcelClassifyId }) {
+      this.dialog_title = "编辑";
+      /* 编辑目录 */
+      this.classifyForm = {
+        classify_name: ExcelClassifyName,
+        classify_id: ExcelClassifyId,
+      };
+      this.classifyDia = true;
+    },
+
+    /* 删除节点校验 */
+    async removeNode(node, { ExcelClassifyId, ExcelInfoId }) {
+      const { Data } = await sheetInterface.classifyDelCheck({
+        ExcelClassifyId,
+        ExcelInfoId,
+      });
+
+      const { DeleteStatus } = Data;
+
+      DeleteStatus === 1
+        ? this.$confirm("该分类下关联表格不可删除", "删除失败", {
+            confirmButtonText: "知道了",
+            showCancelButton: false,
+            type: "error",
+          })
+        : DeleteStatus === 0 && !ExcelInfoId
+        ? this.$confirm("确定删除当前分类吗?", "提示", {
+            confirmButtonText: "确定",
+            cancelButtonText: "取消",
+            type: "warning",
+          }).then(() => {
+            this.delApi(ExcelClassifyId, ExcelInfoId);
+          })
+        : null;
+    },
+
+    /* 删除方法 */
+    delApi(ExcelClassifyId, ExcelInfoId, type = "") {
+      sheetInterface
+        .classifyDel({
+          ExcelClassifyId,
+          ExcelInfoId,
+          Source: this.sourceMap[this.$route.path]
+        })
+        .then((res) => {
+          if (res.Ret !== 200) return;
+          this.$message.success(res.Msg);
+
+          if (!res.Data.ExcelInfoId) this.select_id = "";
+
+          //删除表格后自动显示下一张表格
+          type == "del" && res.Data.ExcelInfoId
+            ? this.getTreeData({
+                code: res.Data.UniqueCode,
+                id: res.Data.ExcelInfoId,
+              })
+            : this.getTreeData();
+
+          //删除封面
+          if (type === "del-list") {
+            let index = this.sheetList.findIndex(
+              (_) => _.ExcelInfoId === ExcelInfoId
+            );
+            this.sheetList.splice(index, 1);
+          }
+        });
+    },
+
+    /* 分类成功回调 */
+    classifyCallback(type) {
+      this.getTreeData();
+
+      if (type === "add") {
+        //新增分类完成之后,展开父节点显示刚新增的分类,若已展开节点则不做处理
+        let code = this.add_parent_id;
+        let flag = this.defaultShowNodes.some((item) => item === code);
+        // console.log(flag)
+        !flag && this.defaultShowNodes.push(code);
+        this.add_parent_id = "";
+      }
+    },
+
+    /* 展开对应菜单 显示详情 */
+    detailShowHandle({ UniqueCode, ExcelInfoId }) {
+      let params = {
+        code: UniqueCode,
+        id: ExcelInfoId,
+      };
+      this.selectCurrentNode(params);
+      this.select_classify = 0;
+    },
+
+    /* 下载数据 */
+    downloadExcel(cell) {
+      const { FileUrl, ExcelName } = cell;
+      this.downLoad(FileUrl, ExcelName);
+    },
+
+    downLoad(url, filename) {
+      const request = new window.XMLHttpRequest();
+      request.open("GET", url, true);
+      request.responseType = "blob";
+      request.onload = () => {
+        const url = window.URL.createObjectURL(request.response);
+        const a = document.createElement("a");
+        a.href = url;
+        a.target = "_blank";
+        a.download = filename;
+        a.style.display = "none";
+        document.body.append(a);
+        a.click();
+      };
+      request.send();
+    },
+
+    /* 保存表格 */
+    saveHandle: _.debounce(async function () {
+      luckysheet.exitEditMode();
+      let data = luckysheet.getAllSheets();
+
+      this.loading = this.$loading({
+        target: ".dataSheet-container",
+        lock: true,
+        text: "保存中...",
+        spinner: "el-icon-loading",
+        background: "rgba(255, 255, 255, 0.6)",
+      });
+
+      let img = getSheetImage(data[0]);
+      const form = new FormData();
+      form.append("Image", img);
+      const { Data } = await sheetInterface.uploadImg(form);
+
+      data.luckysheet_select_save = [];
+      const { ExcelInfoId, ExcelName, ExcelClassifyId } = this.sheetDetailInfo;
+      const res = await sheetInterface.sheetAnalysisInterface.sheetEdit({
+        ExcelInfoId,
+        ExcelName,
+        ExcelClassifyId,
+        ExcelImage: Data.ResourceUrl,
+        Content: JSON.stringify(data),
+      });
+      this.loading.close();
+      if (res.Ret !== 200) return;
+      this.$message.success("保存成功");
+      this.getTreeData();
+    }, 300),
+
+    /* 获取表格列表 */
+    getPublicList() {
+      sheetInterface
+        .sheetList({
+          CurrentIndex: this.sheet_page,
+          PageSize: this.sheet_pages_size,
+          ExcelClassifyId: this.select_classify || 0,
+          Source: this.sourceMap[this.$route.path],
+          IsShowMe: this.isShowMe 
+        })
+        .then((res) => {
+          if (res.Ret !== 200) return;
+
+          this.publicHaveMove = res.Data
+            ? this.sheet_page < res.Data.Paging.Pages
+            : false;
+          this.sheetList = res.Data
+            ? this.sheet_page === 1
+              ? res.Data.List
+              : [...this.sheetList, ...res.Data.List]
+            : [];
+          this.sheet_total = res.Data ? res.Data.Paging.Totals : 0;
+        });
+    },
+
+    /* 加载更多 */
+    loadMoreHandle: _.throttle(function () {
+      let scrollTop = this.$refs.sheetListWrap.$refs.listRef.scrollTop;
+      let clientHeight = this.$refs.sheetListWrap.$refs.listRef.clientHeight;
+      let scrollHeight = this.$refs.sheetListWrap.$refs.listRef.scrollHeight;
+      if (
+        scrollTop + clientHeight >= scrollHeight - 10 &&
+        this.publicHaveMove
+      ) {
+        this.sheet_page++;
+        this.getPublicList();
+      }
+    }, 300),
+
+    /* 获取表格详情 */
+    getDetailHandle() {
+      this.isSheetLoading = true;
+      sheetInterface.sheetAnalysisInterface.getExcelDetail({
+        UniqueCode: this.select_node,
+      }).then((res) => {
+        if (res.Ret !== 200) return;
+
+        this.sheetDetailInfo = res.Data.ExcelInfo;
+        this.dataToalPage =  Math.max(...res.Data.SheetList.map(_ => _.PageNum));
+        this.sheetAllcellData = res.Data.SheetList.map(_ => _.Data ? JSON.parse(_.Data.Data) : []);
+
+        this.getCellData(res.Data.SheetList)
+      });
+    },
+
+    //分页获取表格数据
+    async getCellData(sheets) {
+
+      let res = await sheetInterface.sheetAnalysisInterface.getExcelDataByPage({
+        UniqueCode: this.select_node,
+        Page: this.sheetDataPage
+      })
+
+      if(res.Ret !== 200) return
+      console.log(this.sheetAllcellData)
+
+      for(let i = 0;i<this.sheetAllcellData.length;i++) {
+        if(res.Data[i].Data) {
+          this.sheetAllcellData[i] = [...this.sheetAllcellData[i],...JSON.parse(res.Data[i].Data.Data)]
+        }
+
+        continue
+      }
+      
+      //数据继续加载或渲染表格.
+      if(this.sheetDataPage < this.dataToalPage) {
+        this.sheetDataPage++;
+        this.getCellData(sheets)
+      }else {
+        this.sheetConfigOpt.data = sheets.map((_,index) => ({
+          index: _.Index, //工作表id
+          order: _.Sort, //工作表的下标
+          name: _.SheetName,
+          calcChain: _.CalcChain?JSON.parse(_.CalcChain):[],
+          config: JSON.parse(_.Config),
+          celldata: this.sheetAllcellData[index],
+        }))
+
+        console.log(this.sheetConfigOpt)
+
+        this.isSheetLoading = false;
+      }
+    },
+
+    /* 删除表格 */
+    delSheetHandle({cell, type = ""}) {
+      const { ExcelClassifyId, ExcelInfoId  } = cell;
+      this.$confirm("删除后该表格将不能再引用,确认删除吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          this.delApi(ExcelClassifyId, ExcelInfoId, type);
+        })
+        .catch(() => {});
+    },
+
+    /* 表格另存为 */
+    saveOtherHandle() {
+      this.saveOtherForm.name = this.sheetDetailInfo.ExcelName + "(1)";
+      this.isSaveOther = true;
+    },
+
+    cancelSaveOther() {
+      this.$refs.formRef.resetFields();
+      this.saveOtherForm = {
+        name: '',
+				classify: ''
+      };
+      this.isSaveOther = false;
+    },
+
+    /* 另存为 */
+    async saveCopyOther() {
+      await this.$refs.formRef.validate();
+      let { classify, name } = this.saveOtherForm;
+
+      const res = await sheetInterface.copyExcel({
+        ExcelInfoId: this.sheetDetailInfo.ExcelInfoId,
+        ExcelName: name,
+        ExcelClassifyId: classify
+      });
+
+      if (res.Ret !== 200) return;
+
+      this.$message.success("保存成功");
+      this.cancelSaveOther();
+      this.getTreeData();
+    },
+
+    /* 刷新表格 */
+    refreshSheet: _.debounce(async function() {
+      let res = await sheetInterface.sheetAnalysisInterface.sheetRefresh({ExcelInfoId: this.sheetDetailInfo.ExcelInfoId})
+
+      if(res.Ret !== 200) return 
+      this.$message.success(res.Msg)
+    },300),
+
+    /* 重绘右侧区域宽度 */
+    reloadRightWid() {
+      let total_wid = $(".data-sheet-main")[0].offsetWidth;
+      let left = $("#left")[0].offsetWidth;
+      let rigtWid = total_wid - left - 20 + "px";
+      $("#right")[0].style.width = rigtWid;
+    },
+
+    clickUpload() {
+      $(`#file`).click()
+    },
+
+    //选择文件上传
+    async fileSelected(){ 
+      let file = document.getElementById('file').files[0];
+      if(file){
+        if(!file.name.includes('.xlsx')) return this.$message.warning("上传失败,格式不符合xlsx");
+        if(file.size > 5.1*1024*1024) return this.$message.warning("上传文件最大不能超过5M");
+
+
+        const res = await sheetInterface.sheetAnalysisInterface.checkSheetRepeat({ExcelName: file.name})
+        if(res.Data.IsFind) return this.$message.warning('已有同名文件,请上传新文件')
+
+        this.$store.commit('sheet/SET_UPLOADFIlES',[file])
+        this.$router.push({ path: '/addAnalysisSheet' });
+      } 
+		},
+
+    //跳转生成指标
+    HandleToPath() {
+      this.$router.push({ path: '/createTaregtBySheet',query: {
+        code: this.sheetDetailInfo.UniqueCode 
+      }});
+    }
+
+  },
+  mounted() {
+    if (this.$route.query.code) {
+      this.getTreeData({
+        code: this.$route.query.code,
+        id: Number(this.$route.query.id),
+      });
+    } else {
+      this.getTreeData();
+      this.getPublicList();
+    }
+
+    window.addEventListener("resize", this.reloadRightWid);
+  },
+  destroyed() {
+    window.removeEventListener("resize", this.reloadRightWid);
+  },
+};
+</script>
+<style lang="scss" scoped>
+* {
+  box-sizing: border-box;
+}
+$mini-font: 12px;
+$normal-font: 14px;
+.dataSheet-container {
+  .slide-icon {
+    padding: 20px 0;
+    /* display: block; */
+    box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.3);
+    border-radius: 5px;
+    cursor: pointer;
+    position: absolute;
+    top: 50%;
+    transform: translateY(-50%);
+    z-index: 99;
+    &:hover {
+      background-color: rgba(0, 0, 0, 0.05);
+    }
+    &.slide-left {
+      right: 0;
+    }
+    &.slide-right {
+      left: 0;
+    }
+  }
+  .data-sheet-main {
+    display: flex;
+    position: relative;
+
+    .main-left {
+      width: 400px;
+      min-width: 350px;
+      background: #fff;
+      margin-right: 20px;
+      border: 1px solid #ececec;
+      border-radius: 4px;
+      box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+      height: calc(100vh - 120px);
+      overflow: hidden;
+      position: relative;
+      box-sizing: border-box;
+
+      .datasheet_top {
+        padding: 20px;
+        background: #fff;
+        border: 1px solid #ececec;
+        box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
+        margin-bottom: 20px;
+      }
+      .search-cont {
+        padding: 0 20px;
+      }
+
+      .tree-cont {
+        padding: 30px 20px;
+        max-height: calc(100vh - 280px);
+        overflow: auto;
+      }
+      .target_tree {
+        color: #333;
+        .custom-tree-node {
+          display: flex !important;
+          justify-content: space-between;
+          align-items: center;
+          display: block;
+          flex: 1;
+          .node_label {
+            margin-right: 2px;
+          }
+          .el-icon-view {
+            color: #409eff;
+            font-size: 18px;
+            margin-left: 5px;
+          }
+        }
+      }
+      .noDepart {
+        margin: 60px 0;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        color: #409eff;
+        font-size: 16px;
+        cursor: pointer;
+      }
+      .move-btn {
+        height: 100%;
+        width: 4px;
+        /* opacity: 0; */
+        position: absolute;
+        right: 0px;
+        top: 0;
+        &:hover {
+          cursor: col-resize;
+          /* background-color: orange */
+        }
+      }
+    }
+
+    .main-right {
+      width: 80%;
+      position: relative;
+      .sheet-detail-wrapper {
+        height: 100%;
+        border: 1px solid #ececec;
+        border-radius: 4px;
+        box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+        overflow: auto;
+        background: #fff;
+        .detail-top {
+          padding: 20px;
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          border-bottom: 1px solid #ececec;
+          .sheet-name {
+            font-size: 17px;
+            cursor: pointer;
+            max-width: 450px;
+            &:hover {
+              text-decoration: underline;
+            }
+          }
+          .action-ul {
+            display: flex;
+            li {
+              margin: 0 10px;
+            }
+          }
+        }
+        .sheet-wrap {
+          position: relative;
+          height: calc(100vh - 190px);
+          padding: 15px;
+          /* min-height: 500px; */
+        }
+      }
+
+      .sheet-list-cont {
+        color: #333;
+        .el-card .el-card__header,
+        .el-card__body {
+          padding: 10px;
+        }
+
+        .sheetlist-wrapper {
+          margin-top: 10px;
+          display: flex;
+          flex-wrap: wrap;
+          max-height: calc(100vh - 143px);
+          overflow: hidden;
+          overflow-y: auto;
+          .drag-cont {
+            width: 100%;
+            display: flex;
+            flex-wrap: wrap;
+          }
+          .dragShdow {
+            box-shadow: 0 1px 8px rgba(64, 158, 255, 0.8);
+            opacity: 0.5;
+          }
+          .sheet-item {
+            .item-top {
+              display: flex;
+              justify-content: space-between;
+              align-items: center;
+              font-size: 16px;
+              font-weight: 600;
+            }
+            .chart-img {
+              width: 100%;
+              /* height: 230px; */
+              object-fit: contain !important;
+              cursor: pointer;
+            }
+            .item-bottom {
+              margin-top: 10px;
+              display: flex;
+              justify-content: space-between;
+              font-size: 12px;
+              color: #666;
+              .collected {
+                color: #f00;
+                cursor: pointer;
+              }
+              .join_txt {
+                color: #409eff;
+                cursor: pointer;
+              }
+            }
+          }
+        }
+        .nodata {
+          text-align: center;
+        }
+      }
+    }
+  }
+}
+</style>
+
+<style lang="scss">
+.dataSheet-container {
+  .label-input .el-input__inner {
+    height: 25px;
+    line-height: 25px;
+    padding: 0 10px;
+  }
+
+  .el-tree__drop-indicator {
+    height: 3px;
+    background-color: #409eff;
+  }
+  .el-tree-node__content {
+    margin-bottom: 14px !important;
+  }
+  .el-tree-node__children {
+    .el-tree-node {
+      /* margin-bottom: 8px !important; */
+      margin-bottom: 0px !important;
+      padding-left: 18px;
+    }
+    .el-tree-node__content {
+      margin-bottom: 5px !important;
+      padding-left: 0 !important;
+    }
+  }
+  .expanded.el-icon-caret-right:before {
+    content: url("~@/assets/img/set_m/down.png") !important;
+  }
+  .el-icon-caret-right:before {
+    content: url("~@/assets/img/set_m/slide.png") !important;
+  }
+  .el-tree-node__expand-icon.is-leaf.el-icon-caret-right:before {
+    content: "" !important;
+  }
+  .el-tree-node__expand-icon.expanded {
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  .el-tree-node.is-current > .el-tree-node__content {
+    background-color: #f0f4ff !important;
+  }
+  .el-tree-node__content {
+    padding-right: 10px !important;
+  }
+}
+.sheet-classify-cascader .el-input {
+	width: 100%;
+}
+</style>

+ 1 - 1
src/views/datasheet_manage/customSheetEdit.vue

@@ -165,7 +165,7 @@ export default {
 
 
     /* 获取分类 */
     /* 获取分类 */
     getClassify() {
     getClassify() {
-      sheetInterface.excelClassifyOne().then(res => {
+      sheetInterface.excelClassifyOne({Source: 2}).then(res => {
         if(res.Ret !==200) return
         if(res.Ret !==200) return
         
         
         this.classifyArr = res.Data.AllNodes || [];
         this.classifyArr = res.Data.AllNodes || [];

+ 1 - 1
src/views/datasheet_manage/mixedSheetEdit.vue

@@ -117,7 +117,7 @@ export default {
 
 
     /* 获取分类 */
     /* 获取分类 */
     getClassify() {
     getClassify() {
-      sheetInterface.excelClassifyOne().then(res => {
+      sheetInterface.excelClassifyOne({Source: 3}).then(res => {
         if(res.Ret !==200) return
         if(res.Ret !==200) return
         
         
         this.classifyArr = res.Data.AllNodes || [];
         this.classifyArr = res.Data.AllNodes || [];

+ 38 - 2
src/views/datasheet_manage/mixins/classifyMixin.js

@@ -85,7 +85,9 @@ export default {
 		editNodeLabel(data,type='') {
 		editNodeLabel(data,type='') {
       if(type === 'edit-tit') {
       if(type === 'edit-tit') {
         if([2,3].includes(this.sheetDetailInfo.Source)) return
         if([2,3].includes(this.sheetDetailInfo.Source)) return
-        if(!this.permissionBtn.isShowBtn('etaTablePermission','etaTable_classifyOpt_edit')) return
+        // if(!this.permissionBtn.isShowBtn('etaTablePermission','etaTable_classifyOpt_edit')) return
+
+        if(!this.isSheetBtnShow('classifyOpt_edit')) return
         this.$set(data,'isEditTit',true)
         this.$set(data,'isEditTit',true)
         this.sheet_title = data.ExcelName;
         this.sheet_title = data.ExcelName;
         this.$nextTick(() => {
         this.$nextTick(() => {
@@ -114,7 +116,8 @@ export default {
   
   
         this.new_label !== data.ClassifyName && sheetInterface.classifyEdit({
         this.new_label !== data.ClassifyName && sheetInterface.classifyEdit({
           ExcelClassifyId: data.ExcelClassifyId,
           ExcelClassifyId: data.ExcelClassifyId,
-          ExcelClassifyName: this.new_label
+          ExcelClassifyName: this.new_label,
+          Source: this.sourceMap[this.$route.path]
         }).then(res => {
         }).then(res => {
           if(res.Ret !== 200) return
           if(res.Ret !== 200) return
   
   
@@ -286,5 +289,38 @@ export default {
 
 
       return canDrop;
       return canDrop;
     },
     },
+
+    //判断右侧列表的下载按钮是否显示
+    isDownLoadShow(cell){
+        const {checkPermissionBtn,etaTablePermission} = this.permissionBtn
+        const checkMap = {
+            1:etaTablePermission.etaTable_excel_download,
+            2:etaTablePermission.etaTable_customize_data_download,
+            3:etaTablePermission.etaTable_customize_mix_download,
+            4:etaTablePermission.etaTable_analysis_download
+        }
+        return checkPermissionBtn(checkMap[cell.Source])
+    },
+    //判断右侧列表的删除按钮是否显示
+    isDeleteShow(cell){
+        const {checkPermissionBtn,etaTablePermission} = this.permissionBtn
+        const checkMap = {
+            1:etaTablePermission.etaTable_excel_del,
+            2:etaTablePermission.etaTable_customize_data_del,
+            3:etaTablePermission.etaTable_customize_mix_del,
+            4:etaTablePermission.etaTable_analysis_del,
+        }
+        return checkPermissionBtn(checkMap[cell.Source])
+    },
+    //判断自定义表格-编辑,另存为,刷新按钮是否显示
+    isSheetBtnShow(type){
+      const sheetType = {
+        '/sheetList': 'etaTable_excel',
+        '/sheetTimeList': 'etaTable_customize_data',
+        '/sheetMixedList': 'etaTable_customize_mix',
+        '/sheetAnalysisList': 'etaTable_analysis'
+      }
+      return this.permissionBtn.isShowBtn('etaTablePermission',`${sheetType[this.$route.path]}_${type}`)
+    }
   },
   },
 };
 };

+ 76 - 139
src/views/datasheet_manage/sheetList.vue

@@ -10,20 +10,11 @@
     <div class="data-sheet-main" id="box">
     <div class="data-sheet-main" id="box">
       <div class="main-left left" id="left" v-show="!isSlideLeft">
       <div class="main-left left" id="left" v-show="!isSlideLeft">
         <div class="datasheet_top">
         <div class="datasheet_top">
-          <el-button v-permission="permissionBtn.etaTablePermission.etaTable_excel"
-            type="primary" style="margin-right:20px" @click="goAddSheetHandle(1)"
+          <el-button v-if="permissionBtn.checkPermissionBtn(permissionBtn.etaTablePermission.etaTable_excel)&&sourceMap[$route.path]===1" type="primary" style="margin-right:20px" @click="goAddSheetHandle"
           >添加Excel表格</el-button >
           >添加Excel表格</el-button >
+          <el-button v-if="permissionBtn.checkPermissionBtn(permissionBtn.etaTablePermission.etaTable_customize_data_sheetAdd)&&sourceMap[$route.path]===2" type="primary" style="margin-right:20px" @click="goAddSheetHandle">添加时间序列表格</el-button >
+          <el-button v-if="permissionBtn.checkPermissionBtn(permissionBtn.etaTablePermission.etaTable_customize_mix_sheetAdd)&&sourceMap[$route.path]===3" type="primary" @click="goAddSheetHandle">添加混合表格</el-button >
 
 
-          <el-dropdown v-if="isShowDataSheet||isShowMixSheet"
-            @command="goAddSheetHandle">
-            <el-button type="primary">
-              自定义表格<i class="el-icon-arrow-down el-icon--right"></i>
-            </el-button>
-            <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item :command="2" v-if="isShowDataSheet">数据表格</el-dropdown-item>
-              <el-dropdown-item :command="3" v-if="isShowMixSheet">混合表格</el-dropdown-item>
-            </el-dropdown-menu>
-          </el-dropdown>
         </div>
         </div>
         <div class="search-cont">
         <div class="search-cont">
           <el-select
           <el-select
@@ -77,7 +68,7 @@
                 placeholder="请输入值"
                 placeholder="请输入值"
                 class="label-input"
                 class="label-input"
                 v-model="new_label"
                 v-model="new_label"
-                v-if="data.isEdit&&permissionBtn.isShowBtn('etaTablePermission','etaTable_classifyOpt_edit')"
+                v-if="data.isEdit&&isSheetBtnShow('classifyOpt_edit')"
                 @blur="changeValue(data)"
                 @blur="changeValue(data)"
               />
               />
               <span
               <span
@@ -104,7 +95,7 @@
                   alt=""
                   alt=""
                   style="width: 15px; height: 14px; margin-right: 8px"
                   style="width: 15px; height: 14px; margin-right: 8px"
                   @click.stop="editNode(node, data)"
                   @click.stop="editNode(node, data)"
-                  v-if="!data.ExcelInfoId&&permissionBtn.isShowBtn('etaTablePermission','etaTable_classifyOpt_edit')"
+                  v-if="!data.ExcelInfoId&&isSheetBtnShow('classifyOpt_edit')"
                 />
                 />
                 <img
                 <img
                   slot="reference"
                   slot="reference"
@@ -112,12 +103,12 @@
                   alt=""
                   alt=""
                   style="width: 14px; height: 14px"
                   style="width: 14px; height: 14px"
                   @click.stop="removeNode(node, data)"
                   @click.stop="removeNode(node, data)"
-                  v-if="!data.ExcelInfoId&&permissionBtn.isShowBtn('etaTablePermission','etaTable_classifyOpt_delete')"
+                  v-if="!data.ExcelInfoId&&isSheetBtnShow('classifyOpt_delete')"
                 />
                 />
               </span>
               </span>
             </span>
             </span>
           </el-tree>
           </el-tree>
-          <div class="noDepart" @click="addLevelOneHandle" v-if="permissionBtn.isShowBtn('etaTablePermission','etaTable_classifyOpt_edit')">
+          <div class="noDepart" @click="addLevelOneHandle" v-if="isSheetBtnShow('classifyOpt_edit')">
             <img
             <img
               src="~@/assets/img/set_m/add_ico.png"
               src="~@/assets/img/set_m/add_ico.png"
               alt=""
               alt=""
@@ -171,7 +162,7 @@
                 @click="saveHandle"
                 @click="saveHandle"
                 v-if="
                 v-if="
                   sheetDetailInfo.Source === 1 &&
                   sheetDetailInfo.Source === 1 &&
-                  sheetDetailInfo.Button.OpButton&&permissionBtn.isShowBtn('etaTablePermission','etaTable_excel_save')
+                  sheetDetailInfo.Button.OpButton&&isSheetBtnShow('save')
                 "
                 "
               >
               >
                 保存
                 保存
@@ -180,21 +171,21 @@
                 <li
                 <li
                   class="editsty"
                   class="editsty"
                   @click="goEditHandle"
                   @click="goEditHandle"
-                  v-if="sheetDetailInfo.Button.OpButton&&isSheetBtnShow(sheetDetailInfo,'edit')"
+                  v-if="sheetDetailInfo.Button.OpButton&&isSheetBtnShow('edit')"
                 >
                 >
                   编辑
                   编辑
                 </li>
                 </li>
                 <li
                 <li
                   class="editsty"
                   class="editsty"
-                  @click="refreshSheet"
-                  v-if="sheetDetailInfo.Button.RefreshButton&&isSheetBtnShow(sheetDetailInfo,'refresh')"
+                  @click="refreshSheetEdb"
+                  v-if="sheetDetailInfo.Button.RefreshButton&&isSheetBtnShow('refresh')"
                 >
                 >
                   刷新
                   刷新
                 </li>
                 </li>
                 <li
                 <li
                   class="editsty"
                   class="editsty"
                   @click="saveOtherHandle"
                   @click="saveOtherHandle"
-                  v-if="sheetDetailInfo.Button.CopyButton&&isSheetBtnShow(sheetDetailInfo,'otherSave')"
+                  v-if="sheetDetailInfo.Button.CopyButton&&isSheetBtnShow('otherSave')"
                 >
                 >
                   另存为
                   另存为
                 </li>
                 </li>
@@ -209,7 +200,7 @@
                   sheetDetailInfo.Button && sheetDetailInfo.Button.DeleteButton
                   sheetDetailInfo.Button && sheetDetailInfo.Button.DeleteButton
                   &&isDeleteShow(sheetDetailInfo)
                   &&isDeleteShow(sheetDetailInfo)
                 "
                 "
-                @click="delSheetHandle(sheetDetailInfo, 'del')"
+                @click="delSheetHandle({cell:sheetDetailInfo, type:'del'})"
               >
               >
                 删除
                 删除
               </li>
               </li>
@@ -221,11 +212,18 @@
             <Sheet
             <Sheet
               ref="sheetRef"
               ref="sheetRef"
               v-if="sheetDetailInfo.Source === 1"
               v-if="sheetDetailInfo.Source === 1"
-              :option="sheetDetailInfo.Content"
+              :option="{
+                data: [{
+                  ...JSON.parse(sheetDetailInfo.Content),
+                  scrollTop: 0,
+                  scrollLeft: 0
+                }]
+              }"
               :sheetInfo="{
               :sheetInfo="{
                 ExcelInfoId: sheetDetailInfo.ExcelInfoId,
                 ExcelInfoId: sheetDetailInfo.ExcelInfoId,
                 ExcelName: sheetDetailInfo.ExcelName,
                 ExcelName: sheetDetailInfo.ExcelName,
                 ExcelClassifyId: sheetDetailInfo.ExcelClassifyId,
                 ExcelClassifyId: sheetDetailInfo.ExcelClassifyId,
+                Source: sheetDetailInfo.Source
               }"
               }"
             />
             />
 
 
@@ -245,52 +243,17 @@
           </div>
           </div>
         </div>
         </div>
 
 
-        <!-- 列表 -->
-        <div class="sheet-list-cont" v-else>
-          <span>共{{ sheet_total }}张表格</span>
-          <div class="sheetlist-wrapper" ref="listRef" @scroll="loadMoreHandle">
-            <el-col
-              :span="6"
-              style="margin-bottom: 20px; padding-right: 20px"
-              v-for="cell in sheetList"
-              :key="cell.ExcelInfoId"
-            >
-              <el-card class="sheet-item">
-                <div slot="header" class="item-top">
-                  <span class="text_oneLine">{{ cell.ExcelName }}</span>
-                </div>
-                <img
-                  :src="cell.ExcelImage"
-                  alt=""
-                  class="chart-img"
-                  :height="imgHeight"
-                  @click="detailShowHandle(cell)"
-                />
-                <div class="item-bottom">
-                  <span>创建时间: {{ cell.CreateTime.slice(0, 10) }}</span>
-                  <div>
-                    <span
-                      v-if="isDownLoadShow(cell)"
-                      class="editsty"
-                      style="margin-right: 10px"
-                      @click="downloadExcel(cell)"
-                      >下载</span
-                    >
-                    <span
-                      v-if="isDeleteShow(cell)"
-                      class="deletesty"
-                      @click="delSheetHandle(cell, 'del-list')"
-                      >删除</span
-                    >
-                  </div>
-                </div>
-              </el-card>
-            </el-col>
-          </div>
-          <div v-if="!sheet_total" class="nodata">
-            <tableNoData text="暂无表格"/>
-          </div>
-        </div>
+         <!-- 列表 -->
+        <sheetListWrap
+          v-else
+          :total="sheet_total" 
+          :list="sheetList" 
+          @loadMoreHandle="loadMoreHandle"
+          @detailShowHandle="detailShowHandle"
+          @delSheetHandle="delSheetHandle"
+          @downloadExcel="downloadExcel"
+          ref="sheetListWrap"
+        />
       </div>
       </div>
     </div>
     </div>
 
 
@@ -366,9 +329,10 @@ import Sheet from "./components/SheetExcel.vue";
 import { getSheetImage } from "./common/option";
 import { getSheetImage } from "./common/option";
 import CustomTable from "./components/CustomTable.vue";
 import CustomTable from "./components/CustomTable.vue";
 import MixedTable from "./components/MixedTable.vue";
 import MixedTable from "./components/MixedTable.vue";
+import sheetListWrap from "./components/sheetListWrap.vue"
 export default {
 export default {
   name: "",
   name: "",
-  components: { mDialog, classifyDia, Sheet, CustomTable, MixedTable },
+  components: { mDialog, classifyDia, Sheet, CustomTable, MixedTable,sheetListWrap },
   mixins: [leftMixin],
   mixins: [leftMixin],
   computed: {
   computed: {
     downExcelFileUrl() {
     downExcelFileUrl() {
@@ -431,7 +395,6 @@ export default {
       sheet_total: 0,
       sheet_total: 0,
       sheet_page: 1,
       sheet_page: 1,
       sheet_pages_size: 16,
       sheet_pages_size: 16,
-      imgHeight: 196,
 
 
       /* 另存为 */
       /* 另存为 */
       isSaveOther: false,
       isSaveOther: false,
@@ -447,6 +410,12 @@ export default {
           { required: true, message: "表格分类不能为空", trigger: "blur" },
           { required: true, message: "表格分类不能为空", trigger: "blur" },
         ],
         ],
       },
       },
+
+      sourceMap: {
+        '/sheetList': 1,
+        '/sheetTimeList': 2,
+        '/sheetMixedList': 3,
+      }
     };
     };
   },
   },
   watch: {
   watch: {
@@ -463,7 +432,7 @@ export default {
     },
     },
 
 
     select_classify(newval) {
     select_classify(newval) {
-      if (this.$refs.listRef) this.$refs.listRef.scrollTop = 0;
+      if (this.$refs.sheetListWrap) this.$refs.sheetListWrap.$refs.listRef.scrollTop = 0;
       if (newval) {
       if (newval) {
         this.sheet_page = 1;
         this.sheet_page = 1;
         this.getPublicList();
         this.getPublicList();
@@ -491,9 +460,10 @@ export default {
   },
   },
   methods: {
   methods: {
     /* 添加表格 */
     /* 添加表格 */
-    goAddSheetHandle(type) {
-      if (!this.treeData.length)
-        return this.$message.warning("请先添加表格分类");
+    goAddSheetHandle() {
+      if (!this.treeData.length) return this.$message.warning("请先添加表格分类");
+      let type = this.sourceMap[this.$route.path];
+
       let path = {
       let path = {
         1: "/addsheet",
         1: "/addsheet",
         2: "/addCustomSheet",
         2: "/addCustomSheet",
@@ -510,7 +480,7 @@ export default {
 
 
     /* 获取表格分类 */
     /* 获取表格分类 */
     getTreeData(params = null) {
     getTreeData(params = null) {
-      sheetInterface.classifyList().then((res) => {
+      sheetInterface.classifyList({Source: this.sourceMap[this.$route.path]}).then((res) => {
         const { Ret, Data } = res;
         const { Ret, Data } = res;
         if (Ret !== 200) return;
         if (Ret !== 200) return;
 
 
@@ -527,13 +497,12 @@ export default {
     searchHandle(query) {
     searchHandle(query) {
       if (query) {
       if (query) {
         /* 查找列表 */
         /* 查找列表 */
-        sheetInterface
-          .sheetList({
+        sheetInterface.sheetList({
             Keyword: query,
             Keyword: query,
             CurrentIndex: 1,
             CurrentIndex: 1,
             PageSize: 10000,
             PageSize: 10000,
-          })
-          .then((res) => {
+            Source: this.sourceMap[this.$route.path]
+          }).then((res) => {
             if (res.Ret !== 200) return;
             if (res.Ret !== 200) return;
             this.searchOptions = res.Data.List || [];
             this.searchOptions = res.Data.List || [];
           });
           });
@@ -607,6 +576,7 @@ export default {
         .classifyDel({
         .classifyDel({
           ExcelClassifyId,
           ExcelClassifyId,
           ExcelInfoId,
           ExcelInfoId,
+          Source: this.sourceMap[this.$route.path]
         })
         })
         .then((res) => {
         .then((res) => {
           if (res.Ret !== 200) return;
           if (res.Ret !== 200) return;
@@ -696,7 +666,8 @@ export default {
     /* 保存表格 */
     /* 保存表格 */
     saveHandle: _.debounce(async function () {
     saveHandle: _.debounce(async function () {
       luckysheet.exitEditMode();
       luckysheet.exitEditMode();
-      let data = luckysheet.getAllSheets()[0];
+      //结构类型乱飘 强制定义下
+      let data = {...luckysheet.getAllSheets()[0],status:Number(luckysheet.getAllSheets()[0].status)}
       if (!data.celldata.length) return this.$message.warning("请输入表格内容");
       if (!data.celldata.length) return this.$message.warning("请输入表格内容");
 
 
       this.loading = this.$loading({
       this.loading = this.$loading({
@@ -731,32 +702,31 @@ export default {
 
 
     /* 获取表格列表 */
     /* 获取表格列表 */
     getPublicList() {
     getPublicList() {
-      sheetInterface
-        .sheetList({
-          CurrentIndex: this.sheet_page,
-          PageSize: this.sheet_pages_size,
-          ExcelClassifyId: this.select_classify || 0,
-        })
-        .then((res) => {
-          if (res.Ret !== 200) return;
-
-          this.publicHaveMove = res.Data
-            ? this.sheet_page < res.Data.Paging.Pages
-            : false;
-          this.sheetList = res.Data
-            ? this.sheet_page === 1
-              ? res.Data.List
-              : [...this.sheetList, ...res.Data.List]
-            : [];
-          this.sheet_total = res.Data ? res.Data.Paging.Totals : 0;
-        });
+      sheetInterface.sheetList({
+        CurrentIndex: this.sheet_page,
+        PageSize: this.sheet_pages_size,
+        ExcelClassifyId: this.select_classify || 0,
+        Source: this.sourceMap[this.$route.path]
+      }).then((res) => {
+        if (res.Ret !== 200) return;
+
+        this.publicHaveMove = res.Data
+          ? this.sheet_page < res.Data.Paging.Pages
+          : false;
+        this.sheetList = res.Data
+          ? this.sheet_page === 1
+            ? res.Data.List
+            : [...this.sheetList, ...res.Data.List]
+          : [];
+        this.sheet_total = res.Data ? res.Data.Paging.Totals : 0;
+      });
     },
     },
 
 
     /* 加载更多 */
     /* 加载更多 */
     loadMoreHandle: _.throttle(function () {
     loadMoreHandle: _.throttle(function () {
-      let scrollTop = this.$refs.listRef.scrollTop;
-      let clientHeight = this.$refs.listRef.clientHeight;
-      let scrollHeight = this.$refs.listRef.scrollHeight;
+      let scrollTop = this.$refs.sheetListWrap.$refs.listRef.scrollTop;
+      let clientHeight = this.$refs.sheetListWrap.$refs.listRef.clientHeight;
+      let scrollHeight = this.$refs.sheetListWrap.$refs.listRef.scrollHeight;
       if (
       if (
         scrollTop + clientHeight >= scrollHeight - 10 &&
         scrollTop + clientHeight >= scrollHeight - 10 &&
         this.publicHaveMove
         this.publicHaveMove
@@ -790,7 +760,8 @@ export default {
     },
     },
 
 
     /* 删除表格 */
     /* 删除表格 */
-    delSheetHandle({ ExcelClassifyId, ExcelInfoId }, type = "") {
+    delSheetHandle({cell, type = ""}) {
+      const { ExcelClassifyId, ExcelInfoId  } = cell;
       this.$confirm("删除后该表格将不能再引用,确认删除吗?", "提示", {
       this.$confirm("删除后该表格将不能再引用,确认删除吗?", "提示", {
         confirmButtonText: "确定",
         confirmButtonText: "确定",
         cancelButtonText: "取消",
         cancelButtonText: "取消",
@@ -815,7 +786,7 @@ export default {
     },
     },
 
 
     /* 刷新表格 */
     /* 刷新表格 */
-    refreshSheet: _.debounce(async function () {
+    refreshSheetEdb: _.debounce(async function () {
       const res = await sheetInterface.refreshCustomSheet({
       const res = await sheetInterface.refreshCustomSheet({
         ExcelInfoId: this.sheetDetailInfo.ExcelInfoId,
         ExcelInfoId: this.sheetDetailInfo.ExcelInfoId,
       });
       });
@@ -864,40 +835,6 @@ export default {
       let left = $("#left")[0].offsetWidth;
       let left = $("#left")[0].offsetWidth;
       let rigtWid = total_wid - left - 20 + "px";
       let rigtWid = total_wid - left - 20 + "px";
       $("#right")[0].style.width = rigtWid;
       $("#right")[0].style.width = rigtWid;
-
-      !this.select_id &&
-        this.$nextTick(() => {
-          this.imgHeight =
-            $(".chart-img")[0].offsetWidth / 1.64 > 150
-              ? $(".chart-img")[0].offsetWidth / 1.64
-              : 150;
-        });
-    },
-    //判断右侧列表的下载按钮是否显示
-    isDownLoadShow(cell){
-        const {checkPermissionBtn,etaTablePermission} = this.permissionBtn
-        const checkMap = {
-            1:etaTablePermission.etaTable_excel_download,
-            2:etaTablePermission.etaTable_customize_data_download,
-            3:etaTablePermission.etaTable_customize_mix_download
-        }
-        return checkPermissionBtn(checkMap[cell.Source])
-    },
-    //判断右侧列表的删除按钮是否显示
-    isDeleteShow(cell){
-        const {checkPermissionBtn,etaTablePermission} = this.permissionBtn
-        const checkMap = {
-            1:etaTablePermission.etaTable_excel_del,
-            2:etaTablePermission.etaTable_customize_data_del,
-            3:etaTablePermission.etaTable_customize_mix_del
-        }
-        return checkPermissionBtn(checkMap[cell.Source])
-    },
-    //判断自定义表格-编辑,另存为,刷新按钮是否显示
-    isSheetBtnShow(cell,type){
-        console.log('cell',cell.Source)
-        const sheetType = cell.Source===2?'data':'mix'
-        return this.permissionBtn.isShowBtn('etaTablePermission',`etaTable_customize_${sheetType}_${type}`)
     }
     }
   },
   },
   mounted() {
   mounted() {

+ 9 - 2
src/views/mychart_manage/components/chartDetailDia.vue

@@ -571,6 +571,8 @@ export default {
       bind(el, binding) {
       bind(el, binding) {
         const clickHandle = (e)=>{
         const clickHandle = (e)=>{
           //console.log(e.target.className)
           //console.log(e.target.className)
+          //如果弹窗没打开就没必要执行了
+          if(!(this&&this.isOpenDetail)) return
           const isCurrentTarget = el.contains(e.target)||e.target.className==='el-popover el-popper'||['shareLink','copy'].some(str => e.target.className.includes(str))
           const isCurrentTarget = el.contains(e.target)||e.target.className==='el-popover el-popper'||['shareLink','copy'].some(str => e.target.className.includes(str))
           if(isCurrentTarget){
           if(isCurrentTarget){
             return false
             return false
@@ -814,6 +816,10 @@ export default {
       this.tableData.forEach((item) => {
       this.tableData.forEach((item) => {
         let edbData = EdbInfoList.find(_ => _.EdbInfoId===item.EdbInfoId);
         let edbData = EdbInfoList.find(_ => _.EdbInfoId===item.EdbInfoId);
         item.DataList = edbData.DataList;
         item.DataList = edbData.DataList;
+        //更新起始时间和最近更新时间
+        item.StartDate = edbData.StartDate;
+        item.ModifyTime = edbData.ModifyTime;
+        
         if(edbData.EdbInfoCategoryType===1) item.MoveLatestDate = edbData.MoveLatestDate;
         if(edbData.EdbInfoCategoryType===1) item.MoveLatestDate = edbData.MoveLatestDate;
       });
       });
     },
     },
@@ -1063,9 +1069,10 @@ export default {
     saveChartMapHandle() {
     saveChartMapHandle() {
       const sourceMap = {
       const sourceMap = {
         1: this.saveChartHandle,
         1: this.saveChartHandle,
-        2: this.saveCommodityChart
+        2: this.saveCommodityChart,
+        5: this.saveCommodityChart,//利润曲线
       }
       }
-      sourceMap[this.chartInfo.Source]();
+      sourceMap[this.chartInfo.Source]&&sourceMap[this.chartInfo.Source]();
     },
     },
 
 
     /* 商品价格图保存 */
     /* 商品价格图保存 */

+ 80 - 0
src/views/mychart_manage/components/classifyDeleteCheck.vue

@@ -0,0 +1,80 @@
+<template>
+    <el-dialog custom-class="classify-delete-wrap"
+        :visible.sync="hintDialogShow"
+        :close-on-click-modal="false"
+        :modal-append-to-body="false"
+        :append-to-body="false"
+        @close="$emit('close')"
+        center
+        width="400px"
+        v-dialogDrag
+    >
+        <div slot="title" style="display: flex; align-items: center;">
+            <i style="color:#FF8A00;font-size: 16px;" class="el-icon-warning"></i>
+            <span style="font-size: 16px;color:#333;margin-left: 5px;">提示</span>
+        </div>
+        <div class="dialog-container">
+            <p>该图分类已添加节点链接,不允许删除!</p>
+            <div class="frame-list">
+                <p class="frame-item" v-for="(item,index) in detailArr" :key="index" @click="goToFrameList(item)">
+                    {{index+1}}、{{item.FrameworkName}}({{item.NodeName}})
+                </p>
+            </div>
+        </div>
+        <div class="dialog-footer">
+            <el-button @click="$emit('close')">取消</el-button>
+            <el-button type="primary" @click="$emit('close')">确定</el-button>
+        </div>
+    </el-dialog>
+</template>
+
+<script>
+export default {
+    props:{
+        hintDialogShow:{
+            type:Boolean,
+            default:false
+        },
+        detailArr:{
+            type:Array,
+            default:[]
+        }
+    },
+    data() {
+        return {
+
+        };
+    },
+    methods: {
+        goToFrameList(item){
+            window.open(`/chartframe?frameId=${item.ChartFrameworkId}`);
+        }
+    },
+};
+</script>
+
+<style lang="scss">
+.classify-delete-wrap{
+    .el-dialog__header{
+        background-color: transparent;
+        border-bottom:1px solid #ECECEC;
+        .el-dialog__headerbtn>i{
+            color: #C0C4CC;
+        }
+
+    }
+    .dialog-container{
+        .frame-item{
+            cursor: pointer;
+            text-decoration: underline;
+            &:hover{
+                color:#0052D9;
+            }
+        }
+    }
+    .dialog-footer{
+        padding:25px 0;
+        text-align: right;
+    }
+}
+</style>

+ 57 - 9
src/views/mychart_manage/index.vue

@@ -261,6 +261,13 @@
       @close="chartCallBack"
       @close="chartCallBack"
       @remove="removeCallBack"
       @remove="removeCallBack"
     />
     />
+
+    <!-- 删除确认弹窗 -->
+    <ClassifyDeleteCheck 
+        :hintDialogShow="hintDialogShow"
+        :detailArr="detailArr"
+        @close="hintDialogShow=false"
+    />
   </div>
   </div>
 </template>
 </template>
 
 
@@ -270,14 +277,16 @@ import { mychartInterface } from '@/api/api.js';
 import pubDialog from '@/components/pubDialog.vue';
 import pubDialog from '@/components/pubDialog.vue';
 import chooseChart from './components/chooseChart.vue';
 import chooseChart from './components/chooseChart.vue';
 import chartDetail from './components/chartDetailDia.vue';
 import chartDetail from './components/chartDetailDia.vue';
+import ClassifyDeleteCheck from './components/classifyDeleteCheck.vue';
 export default {
 export default {
   name: '',
   name: '',
   components: {
   components: {
     chooseChart,
     chooseChart,
     pubDialog,
     pubDialog,
     draggable,
     draggable,
-    chartDetail
-  },
+    chartDetail,
+    ClassifyDeleteCheck
+},
   directives: {
   directives: {
     drag(el, bindings) {
     drag(el, bindings) {
       el.onmousedown = function (e) {
       el.onmousedown = function (e) {
@@ -374,6 +383,9 @@ export default {
       haveMove: false,
       haveMove: false,
 
 
       chart_lang: 'ch',
       chart_lang: 'ch',
+
+      hintDialogShow:false,
+      detailArr:[]
     };
     };
   },
   },
   computed: {
   computed: {
@@ -434,7 +446,7 @@ export default {
     getClassify() {
     getClassify() {
       mychartInterface.classifyList().then((res) => {
       mychartInterface.classifyList().then((res) => {
         if (res.Ret !== 200) return;
         if (res.Ret !== 200) return;
-        this.chart_lang = res.Data.Language === 'EN' ? 'en' : 'ch';
+        this.chart_lang = res.Data&&res.Data.Language === 'EN' ? 'en' : 'ch';
 
 
         this.classifyList = res.Data ? res.Data.List.map(item => ({
         this.classifyList = res.Data ? res.Data.List.map(item => ({
           ...item,
           ...item,
@@ -690,8 +702,8 @@ export default {
     /* 编辑 删除*/
     /* 编辑 删除*/
     dealAction(key) {
     dealAction(key) {
       // this.isRightClick = false;
       // this.isRightClick = false;
-      key === 'del' &&
-        this.$confirm(
+      key === 'del' && this.handleDeleteClassify()
+        /* this.$confirm(
           '若删除该分类,则分类下关联的所有图表将被全部删除, 是否继续?',
           '若删除该分类,则分类下关联的所有图表将被全部删除, 是否继续?',
           '提示',
           '提示',
           {
           {
@@ -710,17 +722,48 @@ export default {
                 this.$message.success('删除成功');
                 this.$message.success('删除成功');
                 this.getClassify();
                 this.getClassify();
                 this.getPublicClassify();
                 this.getPublicClassify();
-                // if (this.rightClick_classify === this.select_classify)
-                //   this.select_classify = '';
               });
               });
           })
           })
-          .catch(() => {});
-
+          .catch(() => {}); */
       const obj = this.classifyList.find(
       const obj = this.classifyList.find(
         (x) => x.MyChartClassifyId === this.select_classify
         (x) => x.MyChartClassifyId === this.select_classify
       );
       );
       key === 'edit' && this.editClassify(obj);
       key === 'edit' && this.editClassify(obj);
     },
     },
+    async handleDeleteClassify(){
+        const res = await mychartInterface.getFrameNode({
+            MyChartClassifyId:this.select_classify
+        })
+        if(res.Ret!==200) return
+        this.detailArr = res.Data||[]
+        if(this.detailArr.length){
+            this.hintDialogShow = true
+            return
+        }
+        this.$confirm(
+          '若删除该分类,则分类下关联的所有图表将被全部删除, 是否继续?',
+          '提示',
+          {
+            confirmButtonText: '确定',
+            cancelButtonText: '取消',
+            type: 'warning',
+          }
+        )
+          .then(() => {
+            mychartInterface
+              .delClassify({
+                MyChartClassifyId: this.select_classify,
+              })
+              .then((res) => {
+                if (res.Ret !== 200) return;
+                this.$message.success('删除成功');
+                this.getClassify();
+                this.getPublicClassify();
+              });
+          })
+          .catch(() => {});
+      
+    },
 
 
     /* 右键菜单打开 */
     /* 右键菜单打开 */
     // rightClickHandle({ MyChartClassifyId }, e) {
     // rightClickHandle({ MyChartClassifyId }, e) {
@@ -882,6 +925,11 @@ export default {
       : 0;
       : 0;
     this.ispublic=sessionStorage.getItem('myChartIspublic')? Number(sessionStorage.getItem('myChartIspublic')): '';
     this.ispublic=sessionStorage.getItem('myChartIspublic')? Number(sessionStorage.getItem('myChartIspublic')): '';
     }
     }
+    //从图库框架跳转来的
+    if(this.$route.query.frameId){
+        this.select_classify = Number(this.$route.query.frameId)
+        this.ispublic = ''
+    }
     this.getClassify();
     this.getClassify();
     this.getPublicClassify();
     this.getPublicClassify();
   },
   },

+ 20 - 0
src/views/positionAnalysis_manage/components/chartDetail.vue

@@ -23,12 +23,26 @@
             >
             >
           </el-radio-group>
           </el-radio-group>
         </div>
         </div>
+        <div>
+            <el-date-picker
+                v-model="selectDate"
+                type="date"
+                placeholder="请选择日期"
+                value-format="yyyy-MM-dd"
+                :picker-options="pickerOption"
+                @change="$emit('handleOpt','date')"
+                style="margin-right: 10px"
+            />
+            <el-button type="primary" plain @click="$emit('handleOpt','beforeDate')">查看前一天</el-button>
+            <el-button type="primary" plain @click="$emit('handleOpt','nextDate')" :disabled="disabledNextBtn">查看后一天</el-button>
+        </div>
       </div>
       </div>
       <div
       <div
         class="chart-wrap"
         class="chart-wrap"
         v-if="chartItemInfo&&chartItemInfo.List && chartListState.BuyList.List"
         v-if="chartItemInfo&&chartItemInfo.List && chartListState.BuyList.List"
       >
       >
         <div class="top-info-box">
         <div class="top-info-box">
+          <span>{{$route.query.classify_type}}</span>
           <span>{{ chartItemInfo.name }}</span>
           <span>{{ chartItemInfo.name }}</span>
           <span
           <span
             ><span style="color: #999; margin-right: 2px">总计 </span
             ><span style="color: #999; margin-right: 2px">总计 </span
@@ -66,6 +80,11 @@ export default {
       },
       },
     },
     },
   },
   },
+  props:{
+    disabledNextBtn:Boolean,
+    selectDate:String,
+    pickerOption:Object
+  },
   data() {
   data() {
     return {
     return {
       isPcShow: true,
       isPcShow: true,
@@ -198,6 +217,7 @@ export default {
     },
     },
 
 
     async getInfo() {
     async getInfo() {
+      if(!this.$route.query.classify_name||!this.$route.query.classify_type) return
       this.pageLoading = true;
       this.pageLoading = true;
       const res = await apiPositionAnalysisInfo({
       const res = await apiPositionAnalysisInfo({
         DataTime: this.selectDate || "",
         DataTime: this.selectDate || "",

+ 19 - 17
src/views/positionAnalysis_manage/components/indexContent.vue

@@ -4,19 +4,12 @@
             <span style="margin-right:20px">{{num}}品种</span>
             <span style="margin-right:20px">{{num}}品种</span>
             <span>{{time}}</span>
             <span>{{time}}</span>
         </div>
         </div>
-        <div style="margin:30px 0">
-            <el-switch
-                v-model="isHistory"
-                size="large"
-                active-text="历史合约"
-            />
-        </div>
         <div class="list-wrap">
         <div class="list-wrap">
             <div class="item" v-for="item in clist" :key="item.ClassifyName">
             <div class="item" v-for="item in clist" :key="item.ClassifyName">
                 <div class="label">{{item.ClassifyName}}</div>
                 <div class="label">{{item.ClassifyName}}</div>
-                <div style="flex:1">
+                <div style="margin-top:20px;">
                     <div 
                     <div 
-                        class="opt" 
+                        class="opt" :class="{'active':$route.query.classify_type===_item.ClassifyType}"
                         v-for="_item in item.Items" 
                         v-for="_item in item.Items" 
                         :key="_item.ClassifyType"
                         :key="_item.ClassifyType"
                         @click="goDetail(_item,item)"
                         @click="goDetail(_item,item)"
@@ -34,12 +27,13 @@ export default {
     time:String,
     time:String,
     exchange:String,
     exchange:String,
     now:String,
     now:String,
-    list:null
+    list:null,
+    isHistory:Boolean
   },
   },
   computed: {
   computed: {
     clist() {
     clist() {
       if(this.isHistory){
       if(this.isHistory){
-          console.log('看历史');
+          /* console.log('看历史'); */
           return this.list
           return this.list
       }
       }
 
 
@@ -74,8 +68,6 @@ export default {
   },
   },
   data() {
   data() {
     return {
     return {
-      isHistory: false,
-
     }
     }
   },
   },
 
 
@@ -86,7 +78,8 @@ export default {
           query:{
           query:{
               classify_name:item.ClassifyName,
               classify_name:item.ClassifyName,
               classify_type:_item.ClassifyType,
               classify_type:_item.ClassifyType,
-              exchange:this.exchange
+              exchange:this.exchange,
+              isHistory:this.isHistory
           }
           }
       })      
       })      
     }
     }
@@ -102,6 +95,8 @@ export default {
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 @import '~@/styles/theme-vars.scss';
 @import '~@/styles/theme-vars.scss';
 .index-content-wrap{
 .index-content-wrap{
+    display: flex;
+    flex-direction: column;
     .top-box{
     .top-box{
         background: #e6eefb;
         background: #e6eefb;
         padding: 15px 30px;
         padding: 15px 30px;
@@ -110,10 +105,13 @@ export default {
         }
         }
     }
     }
     .list-wrap{
     .list-wrap{
-        padding: 30px 0;
+        padding: 30px;
+        height: 958px;
+        box-sizing: border-box;
+        overflow-y: auto;
         .item{
         .item{
-            margin-bottom: 40px;
-            display: flex;
+            margin-bottom: 30px;
+            /* display: flex; */
 
 
             .label{
             .label{
                 color: #666;
                 color: #666;
@@ -132,6 +130,10 @@ export default {
                 border: 1px solid $theme-color;
                 border: 1px solid $theme-color;
                 border-radius: 4px;
                 border-radius: 4px;
                 cursor: pointer;
                 cursor: pointer;
+                &:hover,&.active{
+                    background-color: #0052D9;
+                    color: #FFFFFF;
+                }
             }
             }
         }
         }
     }
     }

+ 141 - 23
src/views/positionAnalysis_manage/detail.vue

@@ -1,39 +1,76 @@
 <template>
 <template>
   <div class="hasrightaside-box position-analysis-detail-page">
   <div class="hasrightaside-box position-analysis-detail-page">
-    <div class="detail-top">
-      <div>
-          <el-date-picker
-            v-model="selectDate"
-            type="date"
-            placeholder="请选择日期"
-            value-format="yyyy-MM-dd"
-            :picker-options="pickerOption"
-            @change="handleOpt('date')"
-            style="margin-right: 10px"
-          />
-          <el-button type="primary" plain @click="handleOpt('beforeDate')">查看前一天</el-button>
-          <el-button type="primary" plain @click="handleOpt('nextDate')" :disabled="disabledNextBtn">查看后一天</el-button>
+    <div class="detail">
+        <div class="detail-top">
+            <div>
+                <!-- <el-button type="primary" @click="refreshData" plain>一键刷新</el-button> -->
+                <el-button type="primary" @click="handleOpt('beforeClassifyType')">上一个合约</el-button>
+                <el-button type="primary" @click="handleOpt('nextClassifyType')">下一个合约</el-button>
+            </div>
+        </div>
+        <div class="content-box detail-content">
+            <chartDetail ref="chartDetailRef" 
+                :disabledNextBtn="disabledNextBtn"
+                :selectDate="selectDate"
+                :pickerOption="pickerOption"
+                @setInfo="e => { selectDate=e.date;}"
+                @handleOpt="handleOpt"
+            />
         </div>
         </div>
-      <div>
-        <!-- <el-button type="primary" @click="refreshData" plain>一键刷新</el-button> -->
-        <el-button type="primary" @click="handleOpt('beforeClassifyType')">上一个合约</el-button>
-        <el-button type="primary" @click="handleOpt('nextClassifyType')">下一个合约</el-button>
-      </div>
     </div>
     </div>
-    <div class="content-box detail-content">
-        <chartDetail ref="chartDetailRef" @setInfo="e => { selectDate=e.date; }"/>
+    <div class="list" :class="{'expand-list':isSlide}">
+        <div class="header">
+            <span>持仓列表</span>
+            <div>历史合约
+                <el-switch
+                    v-model="isHistory"
+                    size="large"
+                />
+            </div>
+        </div>
+        <el-tabs 
+            class="tabs-wrap"
+            v-model="activeType"
+        >
+            <el-tab-pane 
+                v-for="item in list"
+                :key="item.Exchange"
+                :label="item.Exchange" 
+                :name="item.Exchange"
+            >
+                <indexContent 
+                  :list="item.Items" 
+                  :num="item.Num" 
+                  :time="item.DataTime" 
+                  :exchange="item.Exchange"
+                  :now="item.CurrDate"
+                  :isHistory="isHistory"
+                />
+            </el-tab-pane>
+        </el-tabs>
+        <span class="slide-icon" @click="isSlide = !isSlide">
+            <i :class="{'el-icon-d-arrow-left':!isSlide,'el-icon-d-arrow-right':isSlide}"></i>
+        </span>
     </div>
     </div>
-   
   </div>
   </div>
 </template>
 </template>
 
 
 <script>
 <script>
 import chartDetail from './components/chartDetail.vue'
 import chartDetail from './components/chartDetail.vue'
+import indexContent from './components/indexContent.vue'
+import {apiPositionAnalysisList} from '@/api/modules/positionAnalysis'
 export default {
 export default {
-  components: { chartDetail },
+  components: { chartDetail , indexContent },
   data() {
   data() {
     return {
     return {
-      selectDate: ''
+      selectDate: '',
+
+      /* list */
+      activeType: '',
+      list: [],
+      loading: false,
+      isHistory:false,
+      isSlide:false,
     }
     }
   },
   },
   computed: {
   computed: {
@@ -65,6 +102,7 @@ export default {
     handleOpt(type){
     handleOpt(type){
         let obj={}
         let obj={}
         if(type==='date'){
         if(type==='date'){
+            this.selectDate = this.$refs.chartDetailRef.selectDate
             obj={
             obj={
                 opt:type,
                 opt:type,
                 val:this.selectDate
                 val:this.selectDate
@@ -94,10 +132,22 @@ export default {
         this.$refs.chartDetailRef.selectDate=''
         this.$refs.chartDetailRef.selectDate=''
         this.$refs.chartDetailRef.getInfo()  
         this.$refs.chartDetailRef.getInfo()  
       }
       }
+    },
+
+    getList(){
+      this.loading=true
+      apiPositionAnalysisList().then(res=>{
+          this.loading=false
+          if(res.Ret!==200) return
+          this.list=res.Data||[]
+          this.activeType= this.$route.query.exchange||res.Data[0]&&res.Data[0].Exchange
+          this.isHistory = Boolean(this.$route.query.isHistory)
+      })
     }
     }
   },
   },
 
 
   mounted() {
   mounted() {
+    this.getList()
   }
   }
 }
 }
 
 
@@ -121,12 +171,79 @@ export default {
         }
         }
 
 
     }
     }
+    .position-analysis-detail-page{
+        .list{
+            .tabs-wrap{
+                .el-tabs__nav{
+                    display: flex;
+                    width: 100%;
+                }
+                .el-tabs__item{
+                    text-align: center;
+                    flex: 1;
+                    padding:0;
+                }
+                .el-tabs__header{
+                    margin-bottom: 0;
+                }
+            }
+            
+        }
+    }
 </style>
 </style>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 @import '~@/styles/theme-vars.scss';
 @import '~@/styles/theme-vars.scss';
 .position-analysis-detail-page{
 .position-analysis-detail-page{
   min-height: calc(100vh - 410px);
   min-height: calc(100vh - 410px);
+  display: flex;
+  position: relative;
+  .list{
+      width:379px;
+      margin-left:20px;
+      position: relative;
+      background: #fff;
+      border: 1px solid #F2F2F2;
+      border-radius: 4px;
+      /* box-shadow: 0 3px 6px rgba(0,0,0,.05); */
+      .header{
+          padding:30px;
+          display: flex;
+          justify-content: space-between;
+          box-sizing: border-box;
+          span{
+              font-size: 16px;
+              font-weight: 500;
+          }
+      }
+      .tabs-wrap{
+          flex: 1;
+          border-top: 1px solid #DCDFE6;
+      }
+      .slide-icon{
+        position:absolute;
+        left: -10px;
+        padding: 20px 0;
+        box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.3);
+        border-radius: 5px;
+        cursor: pointer;
+        top: 50%;
+        transform: translateY(-50%);
+        z-index: 99;
+        background-color: #fff;
+      }
+  }
+  .expand-list{
+      position:absolute;
+      right:0;
+      width:50%;
+  }
+  .detail{
+      flex:1;
+      display: flex;
+      flex-direction: column;
+      max-width: calc(100% - 379px - 20px);
+  }
   .detail-top {
   .detail-top {
     padding: 20px;
     padding: 20px;
     margin-bottom: 20px;
     margin-bottom: 20px;
@@ -138,6 +255,7 @@ export default {
     justify-content: space-between;
     justify-content: space-between;
   }
   }
   .detail-content {
   .detail-content {
+      flex: 1;
     padding: 20px;
     padding: 20px;
     background: #fff;
     background: #fff;
     border-right: 2px solid #F2F2F2;
     border-right: 2px solid #F2F2F2;

+ 15 - 0
src/views/positionAnalysis_manage/list.vue

@@ -16,9 +16,17 @@
                   :time="item.DataTime" 
                   :time="item.DataTime" 
                   :exchange="item.Exchange"
                   :exchange="item.Exchange"
                   :now="item.CurrDate"
                   :now="item.CurrDate"
+                  :isHistory="isHistory"
                 />
                 />
             </el-tab-pane>
             </el-tab-pane>
         </el-tabs>
         </el-tabs>
+        <div class="switch-wrap">
+            <el-switch
+                v-model="isHistory"
+                size="large"
+                active-text="历史合约"
+            />
+        </div>
     </div>
     </div>
 </template>
 </template>
 
 
@@ -32,6 +40,7 @@ export default {
       activeType: '',
       activeType: '',
       list: [],
       list: [],
       loading: false,
       loading: false,
+      isHistory:false
 
 
     }
     }
   },
   },
@@ -59,6 +68,7 @@ export default {
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
 .position-analysis-index-page{
 .position-analysis-index-page{
+    position: relative;
     min-height: 60vh;
     min-height: 60vh;
     padding: 20px;
     padding: 20px;
     background: #fff;
     background: #fff;
@@ -73,6 +83,11 @@ export default {
             font-size: 16px;
             font-size: 16px;
         }
         }
     }
     }
+    .switch-wrap{
+        position:absolute;
+        right:20px;
+        top:20px;
+    }
 }
 }
 </style>
 </style>
 <style lang="scss">
 <style lang="scss">

+ 3 - 2
src/views/ppt_manage/mixins/mixins.js

@@ -337,9 +337,10 @@ export default {
 
 
 
 
       // 农历数据需要去除第一项 在ETA1.0.5之后,除了这里 农历和公历处理逻辑一样
       // 农历数据需要去除第一项 在ETA1.0.5之后,除了这里 农历和公历处理逻辑一样
+      const temChartDataList=chartData.DataList||[]
       const chartDataHandle=this.calendar_type === '农历'?
       const chartDataHandle=this.calendar_type === '农历'?
-      chartData.DataList.filter((item, index) => index > 0):
-      chartData.DataList
+      temChartDataList.filter((item, index) => index > 0):
+      temChartDataList
       let seasonYdata = [],
       let seasonYdata = [],
         seasonData = [],
         seasonData = [],
         chart = {
         chart = {

+ 2 - 2
src/views/ppt_manage/newVersion/pptEnCatalog.vue

@@ -1025,8 +1025,8 @@ export default {
     getTransSet(data){
     getTransSet(data){
       pptEnInterface.transPPTtoReport({
       pptEnInterface.transPPTtoReport({
         PptId:this.pptItem.PptId,
         PptId:this.pptItem.PptId,
-        ClassifyIdFirst:data.type[0],
-        ClassifyIdSecond:data.type[1]?data.type[1]:0,
+        ClassifyIdFirst:data.type[1]?data.type[1]:0,
+        ClassifyIdSecond:data.type[2]?data.type[2]:0,
         Title:data.title,
         Title:data.title,
         Abstract:data.abstract
         Abstract:data.abstract
       }).then(res=>{
       }).then(res=>{

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است