Browse Source

Merge branch 'master' into eta1.4.1

Karsa 1 year ago
parent
commit
e8e06efc8a
66 changed files with 4825 additions and 1419 deletions
  1. 338 1
      src/api/modules/chartRelevanceApi.js
  2. 10 0
      src/api/modules/pptApi.js
  3. 10 0
      src/api/modules/pptEnApi.js
  4. BIN
      src/assets/img/icons/ai_Company.png
  5. BIN
      src/assets/img/icons/ai_avatar.png
  6. BIN
      src/assets/img/icons/gpt-4-turbo.png
  7. BIN
      src/assets/img/icons/gpt-4.png
  8. 22 10
      src/components/chart/chartDetailHandlesWrap.vue
  9. 7 3
      src/components/chart/chartListWrap.vue
  10. 21 7
      src/routes/modules/chartRoutes.js
  11. 18 0
      src/utils/buttonConfig.js
  12. 11 1
      src/views/Home.vue
  13. 24 0
      src/views/chartRelevance_manage/components/explainText.js
  14. 670 0
      src/views/chartRelevance_manage/crossVarietyAnalysis/chartEditor.vue
  15. 208 0
      src/views/chartRelevance_manage/crossVarietyAnalysis/components/chartFormSection.vue
  16. 140 0
      src/views/chartRelevance_manage/crossVarietyAnalysis/components/edbTableSection.vue
  17. 182 0
      src/views/chartRelevance_manage/crossVarietyAnalysis/components/tagRelationDialog.vue
  18. 203 0
      src/views/chartRelevance_manage/crossVarietyAnalysis/components/tagSetDialog.vue
  19. 570 0
      src/views/chartRelevance_manage/crossVarietyAnalysis/list.vue
  20. 1 1
      src/views/chartRelevance_manage/css/index.scss
  21. 4 4
      src/views/chartRelevance_manage/fittingEquation/fittingEquationChartEditor.vue
  22. 3 3
      src/views/chartRelevance_manage/fittingEquation/fittingEquationList.vue
  23. 35 21
      src/views/chartRelevance_manage/mixins/classifyMixin.js
  24. 4 4
      src/views/chartRelevance_manage/relevance/list.vue
  25. 5 5
      src/views/chartRelevance_manage/relevance/relevanceChartEditor.vue
  26. 5 5
      src/views/chartRelevance_manage/statistic/statisticFeatureChartEditor.vue
  27. 3 3
      src/views/chartRelevance_manage/statistic/statisticFeatureList.vue
  28. 2 1
      src/views/dataEntry_manage/addChart.vue
  29. 8 2
      src/views/dataEntry_manage/components/LegendEditDia.vue
  30. 8 2
      src/views/dataEntry_manage/components/SaveChartOther.vue
  31. 46 12
      src/views/dataEntry_manage/components/setEnNameDia.vue
  32. 97 104
      src/views/dataEntry_manage/databaseComponents/addTargetDiaBase.vue
  33. 46 0
      src/views/dataEntry_manage/databaseComponents/util.js
  34. 2 1
      src/views/dataEntry_manage/editChart.vue
  35. 209 14
      src/views/dataEntry_manage/mixins/chartPublic.js
  36. 15 2
      src/views/datasheet_manage/components/sheetClassifyDia.vue
  37. 1 0
      src/views/datasheet_manage/components/sheetListWrap.vue
  38. 15 1
      src/views/mychart_manage/components/chartDetailDia.vue
  39. 21 20
      src/views/mychart_manage/components/chooseChart.vue
  40. 54 21
      src/views/operation_manage/AIQA/AIQA.vue
  41. 6 4
      src/views/operation_manage/AIQA/components/messageItem.vue
  42. 2 3
      src/views/operation_manage/AIQA/components/newWindowHint.vue
  43. 1 1
      src/views/operation_manage/AIQA/components/windowListItem.vue
  44. 116 1
      src/views/ppt_manage/mixins/mixins.js
  45. 107 18
      src/views/ppt_manage/mixins/pptMixins.js
  46. 1 0
      src/views/ppt_manage/newVersion/components/catalog/pptContent.vue
  47. 1 0
      src/views/ppt_manage/newVersion/components/catalog/pptContentEn.vue
  48. 22 2
      src/views/ppt_manage/newVersion/pptCatalog.vue
  49. 10 12
      src/views/ppt_manage/newVersion/pptEditor.vue
  50. 22 2
      src/views/ppt_manage/newVersion/pptEnCatalog.vue
  51. 23 12
      src/views/ppt_manage/newVersion/pptEnEditor.vue
  52. 1 0
      src/views/report_manage/addreportNew.vue
  53. 3 0
      src/views/report_manage/editChapterReport.vue
  54. 1 0
      src/views/report_manage/editreportNew.vue
  55. 71 13
      src/views/report_manage/mixins/reportMixin.js
  56. 1 0
      src/views/report_manage/reportEn/reportEditor.vue
  57. 1 6
      src/views/sandbox_manage/common/edge.js
  58. 36 78
      src/views/sandbox_manage/common/events.js
  59. 3 5
      src/views/sandbox_manage/common/gragh.js
  60. 223 108
      src/views/sandbox_manage/common/mindmap.js
  61. 1 12
      src/views/sandbox_manage/common/node.js
  62. 158 274
      src/views/sandbox_manage/index_new_version.vue
  63. 649 0
      src/views/sandbox_manage/sandFlowNew/components/addLInkDia.vue
  64. 339 617
      src/views/sandbox_manage/sandFlowNew/index.vue
  65. 7 0
      src/views/smartReport/components/StatisticAnalysis.vue
  66. 2 3
      src/vuex/modules/sand.js

+ 338 - 1
src/api/modules/chartRelevanceApi.js

@@ -635,7 +635,19 @@ export const statisticFeatureInterface = {
 
 
   /**
   /**
    * 设置英文
    * 设置英文
-   * @param {*} params  ChartInfoId ChartNameEn
+   * @param {*} params  ChartInfoId ChartNameEn 
+   * "TagList": [
+      {
+        "ChartTagId": 1,
+        "TagNameEn": "宏观en"
+      }
+    ],
+    "VarietyList": [
+      {
+        "ChartVarietyId": 2,
+        "VarietyNameEn": "甲醇en"
+      }
+    ]
    * @returns 
    * @returns 
    */
    */
   editChartEn: params => {
   editChartEn: params => {
@@ -682,4 +694,329 @@ export const statisticFeatureInterface = {
     previewSpline: params => {
     previewSpline: params => {
       return http.post('/line_feature/preview_cure',params)
       return http.post('/line_feature/preview_cure',params)
     }
     }
+}
+
+/* 跨品种分析 */
+export const crossVarietyInterface = {
+  /**
+   * 分类列表
+   * @param {*} params 
+   * @returns 
+   */
+  classifyList: params => {
+    return http.get('/cross_variety/classify/list',params)
+  },
+
+  /**
+   * 分类添加
+   * @param {*} params ChartClassifyName
+   * @returns 
+   */
+  classifyAdd: params => {
+    return http.post('/cross_variety/classify/add',params)
+  },
+
+  /**
+   * 分类编辑
+   * @param {*} params ChartClassifyName ChartClassifyId
+   * @returns 
+   */
+  classifyEdit: params => {
+    return http.post('/cross_variety/classify/edit',params)
+  },
+
+  /**
+   * 分类移动
+   * @param {*} params 
+   * "ClassifyId": 269,
+    "PrevClassifyId": 0,
+    "NextClassifyId": 227,
+   * @returns 
+   */
+  classifyMove: params => {
+    return http.post('/cross_variety/classify/move',params)
+  },
+
+   /**
+   * 图表拖动
+   * @param {*} params 
+   * "ChartInfoId": 844,
+    "PrevChartInfoId": 0,
+    "NextChartInfoId": 839,
+    "ChartClassifyId": 270
+   * @returns 
+   */
+    chartMove: params => {
+      return http.post('/cross_variety/chart_info/move',params)
+    },
+  
+    /**
+     * 获取图表列表
+     * @param {*} params 
+     * CurrentIndex PageSize ChartClassifyId Keyword IsShowMe
+     * @returns 
+     */
+    getChartList: params => {
+      return http.get('/cross_variety/chart_info/list',params)
+    },
+  
+    /**
+     * 图表详情
+     * @param {*} params  ChartInfoId
+     * @returns 
+     */
+    chartDetail: params => {
+      return http.get('/cross_variety/chart_info/detail',params)
+    },
+
+    /**
+     * 添加图表
+     * @param {*} params 
+     * "ChartName": "跨品种分析图标名称",
+      "TagX": 1,
+      "TagY": 2,
+      "CalculateValue": 6,
+      "CalculateUnit": "月",
+      "DateConfigList": [
+        {
+          "DateType": 2,
+          "Num": 60
+        }
+      ],
+      "VarietyList": [2,5]
+     * @returns 
+     */
+    chartAdd: params => {
+      return http.post('/cross_variety/chart_info/add',params)
+    },
+
+    /**
+     * 编辑图表
+     * @param {*} params 
+     * ChartInfoId
+     * "ChartName": "跨品种分析图标名称",
+      "TagX": 1,
+      "TagY": 2,
+      "CalculateValue": 6,
+      "CalculateUnit": "月",
+      "DateConfigList": [
+        {
+          "DateType": 2,
+          "Num": 60
+        }
+      ],
+      "VarietyList": [2,5]
+     * @returns 
+     */
+    chartEdit: params => {
+      return http.post('/cross_variety/chart_info/edit',params)
+    },
+
+    /**
+     * 删除图表
+     * @param {*} params ChartInfoId
+     * @returns 
+     */
+    chartDel: params => {
+      return http.post('/cross_variety/chart_info/delete',params)
+    },
+
+    /**
+     * 预览图表
+     * @param {*} params 
+     *  "TagX": 1,
+        "TagY": 2,
+        "CalculateValue": 6,
+        "CalculateUnit": "月",
+        "DateConfigList": [
+          {
+            "DateType": 1,
+            "Num": 0
+          }
+        ],
+        "VarietyList": [2,5]
+     * @returns 
+     */
+    chartPreview: params => {
+      return http.post('/cross_variety/chart_info/preview',params)
+    },
+
+    /**
+     * 设置英文
+     * @param {*} params  ChartInfoId ChartNameEn
+     * "TagList": [
+        {
+          "ChartTagId": 1,
+          "TagNameEn": "宏观en"
+        }
+      ],
+      "VarietyList": [
+        {
+          "ChartVarietyId": 2,
+          "VarietyNameEn": "甲醇en"
+        }
+      ]
+     */
+    editChartEn: params => {
+      return http.post('/cross_variety/chart_info/en/edit',params)
+    },
+
+    /**
+     * 图表搜索
+     * @param {*} params Keyword
+     * @returns 
+     */
+    searchChart: params => {
+      return http.get('/cross_variety/chart_info/search_by_es',params)
+    },
+
+    /**
+     * 刷新图表
+     * @param {*} params ChartInfoId
+     * @returns 
+     */
+    refreshChart: params => {
+      return http.get('/cross_variety/chart_info/refresh',params)
+    },
+
+    /**
+     * 图表另存为
+     * @param {*} params ChartInfoId ChartName
+     * @returns 
+     */
+    saveOtherChart: params => {
+      return http.post('/cross_variety/chart_info/copy',params)
+    },
+    
+    /**
+     * 编辑英文名称
+     * @param {*} params 
+     * @returns 
+     */
+    editChartEn: params => {
+      return http.post('/cross_variety/chart_info/en/edit',params)
+    },
+
+    /**
+     * 图表设置语言配置信息
+     * @param {*} params  ChartInfoId
+     * @returns 
+     */
+    chartLangOption: params => {
+      return http.get('/cross_variety/chart_info/relation',params)
+    },
+    
+    /**
+     * 品种列表
+     * @param {*} params 
+     */
+    getVarietyList: params => {
+      return http.get('/cross_variety/variety/list',params)
+    },
+
+    /**
+     * 添加品种
+     * @param {VarietyName} params 
+     * @returns 
+     */
+    varietyAdd: params => {
+      return http.post('/cross_variety/variety/add',params)
+    },
+    
+    /**
+     * 编辑品种
+     * @param {VarietyName ChartVarietyId} params 
+     * @returns 
+     */
+    varietyEdit: params => {
+      return http.post('/cross_variety/variety/edit',params)
+    },
+    
+    /**
+     * 删除品种检测
+     * @param {ChartVarietyId} params 
+     * @returns 
+     */
+    varietyDelCheck: params => {
+      return http.post('/cross_variety/variety/delete/check',params)
+    },
+    
+    /**
+     * 删除品种
+     * @param {ChartVarietyId} params 
+     * @returns 
+     */
+    varietyDel: params => {
+      return http.post('/cross_variety/variety/delete',params)
+    },
+
+    /**
+     * 标签列表
+     * @param {*} params 
+     */
+    getTagList: params => {
+      return http.get('/cross_variety/tag/list',params)
+    },
+
+    /**
+     * 添加标签
+     * @param {TagName} params 
+     * @returns 
+     */
+    tagAdd: params => {
+      return http.post('/cross_variety/tag/add',params)
+    },
+
+    /**
+     * 编辑标签
+     * @param {TagName ChartTagId} params 
+     * @returns 
+     */
+    tagEdit: params => {
+      return http.post('/cross_variety/tag/edit',params)
+    },
+
+    /**
+     * 删除标签检测
+     * @param {ChartTagId} params 
+     * @returns 
+     */
+    tagDelCheck: params => {
+      return http.post('/cross_variety/tag/delete/check',params)
+    },
+
+    /**
+     * 添加标签
+     * @param {ChartTagId} params 
+     * @returns 
+     */
+    tagDel: params => {
+      return http.post('/cross_variety/tag/delete',params)
+    },
+
+    /**
+     * 设置标签关联品种对应信息
+     * @param {
+        "ChartTagId": 1,
+        "VarietyEdb": [
+            {
+                "ChartVarietyId": 2,
+                "EdbInfoId": 103407
+            },
+        ]
+     * } params 
+     * @returns 
+     */
+    setTagRelationVariety: params => {
+      return http.post('/cross_variety/tag/variety_edb/save',params)
+    },
+
+
+    /**
+     * 获取标签关联的品种信息
+     * @param {ChartTagId} params 
+     */
+    getTagRelation: params => {
+      return http.get('/cross_variety/tag/variety_edb/list',params)
+    }
 }
 }

+ 10 - 0
src/api/modules/pptApi.js

@@ -256,6 +256,16 @@ export default{
      */
      */
     transCatalogtoEn:params=>{
     transCatalogtoEn:params=>{
       return http.post('pptv2/batchToEn',params)
       return http.post('pptv2/batchToEn',params)
+    },
+    /**
+     * PPT编辑加锁
+     * @param {*} params 
+     * @param {Number} params.PptId 
+     * @param {Number} params.Status :0仅查看,1编辑中,2编辑完成
+     * @returns 
+     */
+    pptEditLock:params=>{
+        return http.post('pptv2/editing',params)
     }
     }
 
 
 }
 }

+ 10 - 0
src/api/modules/pptEnApi.js

@@ -217,6 +217,16 @@ export const pptEnInterface = {
      */
      */
     transPPTtoReport:params => {
     transPPTtoReport:params => {
       return http.post('/ppt_english/toReport',params)
       return http.post('/ppt_english/toReport',params)
+    },
+    /**
+     * PPT编辑加锁
+     * @param {*} params 
+     * @param {Number} params.PptId 
+     * @param {Number} params.Status :0仅查看,1编辑中,2编辑完成
+     * @returns 
+     */
+    pptEditLock:params=>{
+        return http.post('ppt_english/editing',params)
     }
     }
 
 
 }
 }

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


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


BIN
src/assets/img/icons/gpt-4-turbo.png


BIN
src/assets/img/icons/gpt-4.png


+ 22 - 10
src/components/chart/chartDetailHandlesWrap.vue

@@ -162,20 +162,32 @@ export default {
             enNameSetting:checkPermissionBtn(productPricePermission.goodsPrice_incomeLine_enNameSetting),
             enNameSetting:checkPermissionBtn(productPricePermission.goodsPrice_incomeLine_enNameSetting),
             del:checkPermissionBtn(productPricePermission.goodsPrice_incomeLine_del),
             del:checkPermissionBtn(productPricePermission.goodsPrice_incomeLine_del),
         }
         }
-        //相关性分析
-        if(path==='/chartrelevance'){
-            return chartrelevanceMap[btn]
+
+         const crossVarietyBtnMap = {
+            share:checkPermissionBtn(statisticPermission.crossVariety_share),
+            addMyChart:checkPermissionBtn(statisticPermission.crossVariety_addMyChart),
+            refresh:checkPermissionBtn(statisticPermission.crossVariety_refresh),
+            otherSave:checkPermissionBtn(statisticPermission.crossVariety_otherSave),
+            edit:checkPermissionBtn(statisticPermission.crossVariety_edit),
+            copyOffice:checkPermissionBtn(statisticPermission.crossVariety_copyOffice),
+            copyWechat:checkPermissionBtn(statisticPermission.crossVariety_copyWechat),
+            enNameSetting:checkPermissionBtn(statisticPermission.crossVariety_enNameSetting),
+            del:checkPermissionBtn(statisticPermission.crossVariety_del),
         }
         }
+        //相关性分析
+        if(path==='/chartrelevance') return chartrelevanceMap[btn]
+
         //拟合方程曲线
         //拟合方程曲线
-        if(path==='/fittingEquationList'){
-            return fittingEquationMap[btn]
-        }
+        else if(path==='/fittingEquationList') return fittingEquationMap[btn]
+        
         //统计特性
         //统计特性
-        if(path==='/statisticFeatureList'){
-            return statisticFeatureMap[btn]
-        }
+        else if(path==='/statisticFeatureList') return statisticFeatureMap[btn]
+
+        //跨品种分析
+        else if(path==='/crossVarietyChartList') return crossVarietyBtnMap[btn]
+
         //商品价格曲线
         //商品价格曲线
-        if(path==='/commordityChartBase'){
+        else if(path==='/commordityChartBase'){
             const {Source,ChartType} = this.chartInfo
             const {Source,ChartType} = this.chartInfo
             if(Source===2&&ChartType===8){//是商品价格曲线
             if(Source===2&&ChartType===8){//是商品价格曲线
                 return priceLineMap[btn]
                 return priceLineMap[btn]

+ 7 - 3
src/components/chart/chartListWrap.vue

@@ -67,15 +67,19 @@ export default {
             return checkPermissionBtn(statisticPermission.corrAnalysis_addMyChart)
             return checkPermissionBtn(statisticPermission.corrAnalysis_addMyChart)
         }
         }
         //拟合方程曲线
         //拟合方程曲线
-        if(path==='/fittingEquationList'){
+        else if(path==='/fittingEquationList'){
             return checkPermissionBtn(statisticPermission.fittingEq_addMyChart)
             return checkPermissionBtn(statisticPermission.fittingEq_addMyChart)
         }
         }
         //统计特性
         //统计特性
-        if(path==='/statisticFeatureList'){
+        else if(path==='/statisticFeatureList'){
             return checkPermissionBtn(statisticPermission.statisticFeature_addMyChart)
             return checkPermissionBtn(statisticPermission.statisticFeature_addMyChart)
         }
         }
+        //跨品种分析
+        else if(path==='/crossVarietyChartList') {
+          return checkPermissionBtn(statisticPermission.crossVariety_addMyChart)
+        }
         //商品价格曲线
         //商品价格曲线
-        if(path==='/commordityChartBase'){
+        else if(path==='/commordityChartBase'){
             const {Source,ChartType} = item
             const {Source,ChartType} = item
             if(Source===2&&ChartType===8){//是商品价格曲线
             if(Source===2&&ChartType===8){//是商品价格曲线
                 return checkPermissionBtn(productPricePermission.goodsPrice_priceLine_addMyChart)
                 return checkPermissionBtn(productPricePermission.goodsPrice_priceLine_addMyChart)

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

@@ -229,17 +229,17 @@ export default [
 			{
 			{
 				path: 'chartrelevance',
 				path: 'chartrelevance',
 				name: '相关性分析',
 				name: '相关性分析',
-				component:()=>import('@/views/chartRelevance_manage/list.vue')
+				component:()=>import('@/views/chartRelevance_manage/relevance/list.vue')
 			},
 			},
 			{
 			{
 				path: 'fittingEquationList',
 				path: 'fittingEquationList',
 				name: '拟合方程曲线',
 				name: '拟合方程曲线',
-				component:()=>import('@/views/chartRelevance_manage/fittingEquationList.vue')
+				component:()=>import('@/views/chartRelevance_manage/fittingEquation/fittingEquationList.vue')
 			},
 			},
 			{
 			{
 				path: 'fittingEquationChartEditor',
 				path: 'fittingEquationChartEditor',
 				name: '添加图表',
 				name: '添加图表',
-				component: () => import('@/views/chartRelevance_manage/fittingEquationChartEditor.vue'),
+				component: () => import('@/views/chartRelevance_manage/fittingEquation/fittingEquationChartEditor.vue'),
 				meta: { 
 				meta: { 
 					pathFrom: "fittingEquationList",
 					pathFrom: "fittingEquationList",
           			pathName: "拟合方程曲线",
           			pathName: "拟合方程曲线",
@@ -248,7 +248,7 @@ export default [
 			{
 			{
 				path: 'relevancechartEditor',
 				path: 'relevancechartEditor',
 				name: '编辑图表',
 				name: '编辑图表',
-				component:()=>import('@/views/chartRelevance_manage/relevanceChartEditor.vue'),
+				component:()=>import('@/views/chartRelevance_manage/relevance/relevanceChartEditor.vue'),
 				meta: { 
 				meta: { 
 					pathFrom: "chartrelevance",
 					pathFrom: "chartrelevance",
           			pathName: "相关性图表",
           			pathName: "相关性图表",
@@ -257,17 +257,31 @@ export default [
 			{
 			{
 				path: 'statisticFeatureList',
 				path: 'statisticFeatureList',
 				name: '统计特征',
 				name: '统计特征',
-				component: () => import('@/views/chartRelevance_manage/statisticFeatureList.vue')
+				component: () => import('@/views/chartRelevance_manage/statistic/statisticFeatureList.vue')
 			},
 			},
 			{
 			{
 				path: 'statisticFeatureChartEditor',
 				path: 'statisticFeatureChartEditor',
 				name: '编辑图表',
 				name: '编辑图表',
-				component:()=>import('@/views/chartRelevance_manage/statisticFeatureChartEditor.vue'),
+				component:()=>import('@/views/chartRelevance_manage/statistic/statisticFeatureChartEditor.vue'),
 				meta: { 
 				meta: { 
 					pathFrom: "statisticFeatureList",
 					pathFrom: "statisticFeatureList",
           			pathName: "统计特征",
           			pathName: "统计特征",
 				}
 				}
-			}
+			},
+			{
+				path: 'crossVarietyChartList',
+				name: '跨品种分析',
+				component: () => import('@/views/chartRelevance_manage/crossVarietyAnalysis/list.vue')
+			},
+			{
+				path: 'crossVarietyChartEditor',
+				name: '编辑图表',
+				component:()=>import('@/views/chartRelevance_manage/crossVarietyAnalysis/chartEditor.vue'),
+				meta: { 
+					pathFrom: "crossVarietyChartList",
+          pathName: "跨品种分析",
+				}
+			},
 		]
 		]
 	},
 	},
 
 

+ 18 - 0
src/utils/buttonConfig.js

@@ -513,6 +513,24 @@ export const statisticPermission = {
     fittingEq_refresh:'fittingEq:refresh',
     fittingEq_refresh:'fittingEq:refresh',
     fittingEq_addMyChart:'fittingEq:addMyChart',
     fittingEq_addMyChart:'fittingEq:addMyChart',
     fittingEq_share:'fittingEq:share',
     fittingEq_share:'fittingEq:share',
+
+    /* 跨品种分析 */
+    crossVariety_addChart:'crossVariety:addChart',//添加图表按钮
+    crossVariety_onlyMine:'crossVariety:onlyMine',//只看我的
+    crossVariety_classifyOpt_edit:'crossVariety:classifyOpt:edit',//添加编辑分类
+    crossVariety_classifyOpt_delete:'crossVariety:classifyOpt:delete',//删除分类
+    crossVariety_variety_edit: 'crossVariety:variety:edit',//品种管理
+    crossVariety_tag_edit: 'crossVariety:tag:edit',//标签管理
+        /*---图表操作栏--- */
+    crossVariety_del:'crossVariety:del',
+    crossVariety_enNameSetting:'crossVariety:enNameSetting',
+    crossVariety_copyWechat:'crossVariety:copyWechat',
+    crossVariety_copyOffice:'crossVariety:copyOffice',
+    crossVariety_edit:'crossVariety:edit',
+    crossVariety_otherSave:'crossVariety:otherSave',
+    crossVariety_refresh:'crossVariety:refresh',
+    crossVariety_addMyChart:'crossVariety:addMyChart',
+    crossVariety_share:'crossVariety:share',
 }
 }
 /*
 /*
  * --------------------------------------------------------------------------供应分析------------------------------------------------
  * --------------------------------------------------------------------------供应分析------------------------------------------------

+ 11 - 1
src/views/Home.vue

@@ -105,7 +105,7 @@
                       :style="`display: flex;align-items:center;color:${
                       :style="`display: flex;align-items:center;color:${
                         child.path === activePath ? $setting.theme_color : '#666'
                         child.path === activePath ? $setting.theme_color : '#666'
                       }`"
                       }`"
-                      @click="(e) => e.preventDefault()"
+                      @click="handleClickSubMenuItem(child,$event)"
                     >
                     >
                       <svg t="1689672247666" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7676" width="30" height="30"><path d="M640 499.2v25.6a21.333333 21.333333 0 0 1-21.333333 21.333333h-213.333334a21.333333 21.333333 0 0 1-21.333333-21.333333v-25.6a21.333333 21.333333 0 0 1 21.333333-21.333333h213.333334a21.333333 21.333333 0 0 1 21.333333 21.333333z"  p-id="7677" :fill="child.path === activePath ? $setting.theme_color : '#666'"></path></svg>
                       <svg t="1689672247666" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7676" width="30" height="30"><path d="M640 499.2v25.6a21.333333 21.333333 0 0 1-21.333333 21.333333h-213.333334a21.333333 21.333333 0 0 1-21.333333-21.333333v-25.6a21.333333 21.333333 0 0 1 21.333333-21.333333h213.333334a21.333333 21.333333 0 0 1 21.333333 21.333333z"  p-id="7677" :fill="child.path === activePath ? $setting.theme_color : '#666'"></path></svg>
                       <span style="margin-left:15px;">{{ child.name }}</span>
                       <span style="margin-left:15px;">{{ child.name }}</span>
@@ -490,6 +490,16 @@ export default {
     this.getPublicSettings();
     this.getPublicSettings();
   },
   },
   methods: {
   methods: {
+    handleClickSubMenuItem(item,e){
+      e.preventDefault();
+      if(item.path==='AIQA'){
+        e.stopPropagation();
+        let { href } = this.$router.resolve({
+          path:'/'+item.path
+        });
+        window.open(href, '_blank')
+      }
+    },
     // 获取商家Code
     // 获取商家Code
     getBusinessCodeFun(){
     getBusinessCodeFun(){
       getBusinessCode().then(res=>{
       getBusinessCode().then(res=>{

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

@@ -35,4 +35,28 @@ export const statisticFeatureListTextArr = [
     <p>2、根据频段数划分多个间距相同的区间(左闭右开,最后一个区间为左闭右闭),统计数据值落在每个区间的数据个数;</p>
     <p>2、根据频段数划分多个间距相同的区间(左闭右开,最后一个区间为左闭右闭),统计数据值落在每个区间的数据个数;</p>
     <p>3、频率=落在某区间数据个数/所选时间段内数据总个数;</p>
     <p>3、频率=落在某区间数据个数/所选时间段内数据总个数;</p>
     <p>4、累计频率为从最小值所在区间对应的频率开始累加;</p>`
     <p>4、累计频率为从最小值所在区间对应的频率开始累加;</p>`
+]
+
+//跨品种分析
+export const crossVarietyAnalisisTextArr = [
+    `<p style="font-weight:bold;">一、处理逻辑</p>
+    <p>1、百分位计算公式:对所选时间范围内的数据,取最大值Max,最小值Min,计算Max-Min,百分位=(现值-Min)/(Max-Min),Max=Min时不计算</p>
+    <p>2、取值方式:</p>
+    <p>(1)通过“选择日期”和“时间长度”,时间范围为“选择日期”至选择的日期往过去推“时间长度”,在这个时间段找出指标最大值和最小值,进行百分位计算。</p>
+    <p>(2)若在(1)的时间范围下找不到值,则继续往过去找,直到找到值。</p>
+    <p>3、图表说明:</p>
+    <p> (1)某个品种会有多个坐标点(坐标点的数量取决于设置的日期数量);</p>
+    <p> (2)坐标点的X、Y值取实际日期与值。</p>`,
+
+    `<p style="font-weight:bold;">二、相关配置</p>
+    <p>1、基本配置</p>
+    <p>(1)管理员进行品种管理、标签管理;</p>
+    <p>(2)使用者对标签的品种关联指标。</p>
+    <p>2、计算配置</p>
+    <p>(1)时间长度:默认显示6个月;</p>
+    <p>(2)选择日期:最多支持选择5个日期;</p>
+    <p>(3)X轴坐标:选择标签;</p>
+    <p>(4)Y轴坐标:选择标签;</p>
+    <p>(5)图表名称:X轴坐标和Y轴坐标的拼接。</p>`
+
 ]
 ]

+ 670 - 0
src/views/chartRelevance_manage/crossVarietyAnalysis/chartEditor.vue

@@ -0,0 +1,670 @@
+<template>
+  <div class="crossVariety-edit-page" id="box">
+    <span
+      class="slide-icon slide-right"
+      @click="isSlideLeft = !isSlideLeft"
+      v-show="isSlideLeft"
+    >
+      <i class="el-icon-d-arrow-right"></i>
+    </span>
+    <div class="left-cont" v-show="!isSlideLeft" id="left">
+      <div class="left-top">
+        <div>
+          <el-button type="primary" @click="saveChartHandle">保存</el-button>
+          <el-button type="primary" plain @click="$router.back()">取消</el-button>
+
+        </div>
+        <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 class="left-min">
+        <section class="section-item">
+          <div class="top">
+            <label>选择品种</label>
+            <el-button
+              v-permission="permissionBtn.statisticPermission.crossVariety_variety_edit"
+              type="text" 
+              @click="setDialogOpen('variety')"
+            >品种管理</el-button>
+          </div>
+          <div class="list" v-if="varietyOptions.length">
+            <el-tag 
+              size="small" 
+              :class="['tag',{'act':checkedVarietys.includes(item.ChartVarietyId)}]"
+              v-for="item in varietyOptions"
+              :key="item.ChartVarietyId"
+              @click="checkVarietyHandle(item)"
+            >{{item.ChartVarietyName}}</el-tag>
+          </div>
+
+          <tableNoData v-else text="暂无品种" size="mini"/>
+        </section>
+
+        <el-divider/>
+
+        <section class="section-item">
+          <div class="top">
+            <label>标签配置</label>
+            <el-button
+              v-permission="permissionBtn.statisticPermission.crossVariety_tag_edit"
+              type="text" 
+              @click="setDialogOpen('tag')"
+            >标签管理</el-button>
+          </div>
+          <div class="list" v-if="tagOptions.length">
+            <el-tag 
+              size="small" 
+              :class="item.VarietyTotal?'act tag':'tag'"
+              v-for="item in tagOptions"
+              :key="item.ChartTagId"
+              @click="setTagRelationOpen(item)"
+            >{{item.ChartTagName}}</el-tag>
+          </div>
+
+          <tableNoData text="暂无标签" size="mini" v-else/>
+        </section>
+
+      </div>
+      
+      <span
+        class="move-btn resize"
+        v-drag
+        id="resize"
+      ></span>
+      <span class="slide-icon slide-left" @click="isSlideLeft = !isSlideLeft">
+        <i class="el-icon-d-arrow-left"></i>
+      </span>
+    </div>
+    <div
+      class="right-cont"
+      id="right"
+      :style="isSlideLeft ? 'width:100%' : `width:80%`"
+    >
+      <div
+        class="chart-min-cont"
+      >
+        <div class="chart-wrapper" v-if="options.series&&options.series.length">
+          <div class="chart-show-cont"  v-if="!chartInfo.WarnMsg">
+            <div style="position:relative;">
+              <h2 class="chart-title">{{ chartInfo.ChartName }}</h2>
+              <Chart 
+                :options="options"
+                minHeight="400px" 
+                height="450px"
+                ref="chartRef"
+              />
+              <span class="chart-author">作者:{{ chartInfo.SysUserRealName || accountName}}</span>
+
+              <!-- 上下限 -->
+              <template>	
+                <div class="range-cont left">
+                  <el-input
+                    style="width: 60px; display: block"
+                    size="mini"
+                    type="number"
+                    :min="0"
+                    :max="100"
+                    placeholder="上限"
+                    v-model="chartLimit.max"
+                    @change="changeLimit"
+                  />
+                  <el-input
+                    class="min-data-input"
+                    size="mini"
+                    type="number"
+                    :min="0"
+                    :max="100"
+                    placeholder="下限"
+                    v-model="chartLimit.min"
+                    @change="changeLimit"
+                  />
+                </div>
+                <!-- x轴上下限 -->
+                <div class="range-cont bottom" > 
+                  <el-input
+                    class="left"
+                    size="mini"
+                    type="number"
+                    :min="0"
+                    :max="100"
+                    placeholder="下限"
+                    v-model="chartLimit.x_min"
+                    @change="changeLimit"
+                  />
+                  <el-input
+                    class="left"
+                    size="mini"
+                    type="number"
+                    :min="0"
+                    :max="100"
+                    placeholder="上限"
+                    v-model="chartLimit.x_max"
+                    @change="changeLimit"
+                  />
+                </div>
+              </template>
+              
+            </div>
+          </div>
+
+          <!-- 异常显示 -->
+          <p class="error-tip" style="min-height: 400px;" v-if="chartInfo.WarnMsg">{{chartInfo.WarnMsg}}</p>
+        </div>
+
+        <div class="nodata" v-else>
+          <tableNoData text="暂无信息"/>
+        </div>
+
+        <div class="bottom-wrapper">
+          <!-- 图表相关配置 -->
+          <chartFormSection
+            :tagList="tagOptions"
+            :chartInfo="chartInfo"
+            ref="chartFormRef"
+            @getData="getChartPreviewData"
+          />
+
+          <!-- 指标列表 -->
+          <edbTableSection :tableData="tableData"/>
+        </div>
+
+      </div> 
+
+    </div>
+
+    <!-- 管理弹窗 -->
+    <tagSetDialog
+      :isShow.sync="isShowSetDia"
+      :type="dialogType"
+      :dataList="dialogType==='variety'?varietyOptions:tagOptions"
+      @refresh="dialogType==='tag'?getTagList():getVarietyList();"
+    />
+
+    <!-- 标签指标配置 -->
+    <tagRelationDialog
+      :isShow.sync="isShowTagRelationDia"
+      :varietyList="varietyOptions"
+      :info="tagRelationInfo"
+      @refresh="getTagList"
+    />
+
+    <!-- 操作说明 -->
+    <ExplainDialog 
+        textArrName="crossVarietyAnalisisTextArr"
+        :show-explain="showExplain"
+        @close="showExplain = false"
+    />
+  </div>
+</template>
+
+<script>
+import { crossVarietyInterface } from '@/api/modules/chartRelevanceApi';
+import { dataBaseInterface } from '@/api/api';
+import { chartSetMixin } from '@/views/dataEntry_manage/mixins/chartPublic';
+import Chart from '@/views/dataEntry_manage/components/chart';
+import ExplainDialog from '../components/explainDialog.vue';
+import chartFormSection from './components/chartFormSection.vue';
+import tagSetDialog from './components/tagSetDialog.vue';
+import tagRelationDialog from './components/tagRelationDialog.vue';
+import edbTableSection from './components/edbTableSection.vue'
+export default {
+  components: {
+    ExplainDialog,
+    Chart,
+    chartFormSection,
+    tagSetDialog,
+    tagRelationDialog,
+    edbTableSection
+  },
+  directives: {
+    drag(el, bindings) {
+      el.onmousedown = function (e) {
+        var init = e.clientX;
+        // console.log(init);
+        var box = $('#box')[0];
+        // console.log(box.clientWidth)
+        let total_wid = box.offsetWidth;
+        var left = $('#left')[0];
+        var right = $('#right')[0];
+        var initWidth = left.offsetWidth;
+        document.onmousemove = function (e) {
+          var end = e.clientX;
+          var newWidth = end - init + initWidth;
+          left.style.width = newWidth + 'px';
+          right.style.width = newWidth > 300 ? total_wid - newWidth + 'px' : total_wid - 320 + 'px';
+        };
+        document.onmouseup = function () {
+          document.onmousemove = document.onmouseup = null;
+          e.releaseCapture && e.releaseCapture();
+        };
+        e.setCapture && e.setCapture();
+        return false;
+      };
+    },
+  },
+  mixins: [ chartSetMixin ],
+  computed: {
+    accountName() {
+      return localStorage.getItem('userName')
+    }
+  },
+  data() {
+    return {
+      chart_code: this.$route.query.code || '',
+      isSlideLeft: false,
+      chartInfo: {
+        Source: 10,
+        ChartName: '',
+        SysUserRealName: ''
+      },
+
+      showExplain: false,
+
+      checkedVarietys: [], //选中的品种
+      varietyOptions: [],
+      tagOptions: [],
+
+      isShowSetDia: false,//管理弹窗
+      dialogType: '',
+
+      isShowTagRelationDia: false,//标签指标管理弹窗
+      tagRelationInfo: {
+        tagName:'',
+        id: 0
+      }
+    };
+  },
+  methods: {
+
+    /* 获取图表详情 */
+    async getChartDetail() {
+      if(!this.chart_code) return 
+
+      let res = await dataBaseInterface.getChartByCode({
+				UniqueCode: this.chart_code
+			})
+
+      if(res.Ret !== 200) return
+
+      const { ChartInfo,DataResp,EdbInfoList } = res.Data;
+      let configSet = JSON.parse(ChartInfo.ExtraConfig);
+      this.checkedVarietys = configSet.VarietyList;
+      this.$refs.chartFormRef.initData(configSet);
+
+      this.chartInfo = ChartInfo;
+      this.tableData = EdbInfoList;
+      this.crossVarietyChartData = DataResp;
+      this.chartLimit = {
+        min: DataResp.YMinValue,
+        max: DataResp.YMaxValue ,
+        x_min: DataResp.XMinValue,
+        x_max: DataResp.XMaxValue,
+      }
+
+      this.setCrossVarietyChart()
+    },
+
+    checkParmas(type='') {
+      if(!this.checkedVarietys.length || !this.$refs.chartFormRef.form.CalculateValue || !this.$refs.chartFormRef.form.TagX ||!this.$refs.chartFormRef.form.TagY){
+        
+        type && this.dealWarnings()
+        return false
+      }
+      return true
+    },
+
+    dealWarnings() {
+      const {CalculateValue,TagX,TagY } = this.$refs.chartFormRef.form;
+      let message = '';
+      
+      if(!this.checkedVarietys.length) message = '请选择品种'
+      else if(!CalculateValue) message = '请输入时间长度'
+      else if(!TagX) message = '请选择X轴坐标'
+      else if(!TagY) message = '请选择Y轴坐标'
+
+      this.$message.warning(message)
+    },
+
+    /* 获取标签列表 */
+    async getTagList() {
+      let res = await crossVarietyInterface.getTagList()
+
+      if(res.Ret !== 200) return
+      this.tagOptions = res.Data.List || []
+    },
+
+    async getVarietyList() {
+      let res = await crossVarietyInterface.getVarietyList()
+
+      if(res.Ret !== 200) return
+      this.varietyOptions = res.Data.List || []
+    },
+
+    /* 预览数据 */
+    async getChartPreviewData() {
+      if(!this.checkParmas()) return;
+
+      let params = {
+        VarietyList: this.checkedVarietys,
+        ...this.$refs.chartFormRef.form
+      }
+      let res = await crossVarietyInterface.chartPreview(params)
+
+      if(res.Ret !== 200) return
+
+      const { DataResp,EdbInfoList } = res.Data;
+      this.tableData = EdbInfoList;
+      
+      this.chartLimit = {
+        min: Number(DataResp.YMinValue),
+        max: Number(DataResp.YMaxValue),
+        x_min: Number(DataResp.XMinValue),
+        x_max: Number(DataResp.XMaxValue)
+      }
+      this.crossVarietyChartData = DataResp;
+      this.setCrossVarietyChart()
+    },
+    
+    /* 选择品种 */
+    checkVarietyHandle(item) {
+      this.checkedVarietys.includes(item.ChartVarietyId) 
+        ? this.checkedVarietys.splice(this.checkedVarietys.indexOf(item.ChartVarietyId),1) 
+        : this.checkedVarietys.push(item.ChartVarietyId)
+
+      this.getChartPreviewData();
+    },
+
+    /* 打开标签关联弹窗 */
+    setTagRelationOpen(item) {
+      this.tagRelationInfo = {
+        tagName: item.ChartTagName,
+        id: item.ChartTagId
+      }
+      this.isShowTagRelationDia = true;
+    },
+
+    /* 标签管理 */
+    setDialogOpen(type) {
+      this.dialogType = type;
+      this.isShowSetDia = true;
+    },
+
+    /* 保存图表 */
+    async saveChartHandle() {
+      if(!this.checkParmas('warning')) return;
+
+      let { min,max,x_min,x_max } = this.chartLimit;
+      let params = {
+        VarietyList: this.checkedVarietys,
+        ...this.$refs.chartFormRef.form,
+        XMinValue: String(x_min),
+				XMaxValue: String(x_max),
+				YMinValue: String(min),
+				YMaxValue: String(max),
+      }
+      let res = this.chart_code 
+        ? await crossVarietyInterface.chartEdit({...params,ChartInfoId: this.chartInfo.ChartInfoId})
+        : await crossVarietyInterface.chartAdd(params)
+
+      if(res.Ret !== 200) return
+      this.setChartImage(res.Data);
+    },
+
+     /* 设置图表封面图片 */
+    setChartImage(data) {
+      let svg = this.$refs.chartRef.chart.getSVG({
+        chart: {
+          width: 340,
+          height: 230,
+        }
+      });
+      let form = new FormData();
+      form.append('Img', svg);
+      this.setImageHandle(form,data);
+    },
+    async setImageHandle(form,{ UniqueCode,ChartInfoId }) {
+      let { Data } = await dataBaseInterface.uploadImgSvg(form);
+      await dataBaseInterface.setChartImage({
+        ChartInfoId: ChartInfoId,
+        ImageUrl: Data.ResourceUrl,
+      });
+
+			this.$message.success('保存成功');
+			this.$router.replace({
+				path: '/crossVarietyChartList',
+				query: {
+					code: UniqueCode,
+					id: ChartInfoId
+				}
+			})
+
+    },
+   
+    reloadRightWid() {
+      let total_wid = $('#box')[0].offsetWidth;
+      let left = $('#left')[0].offsetWidth;
+      let rigtWid = total_wid - left - 20 + 'px';
+      $('#right')[0].style.width = rigtWid;
+    },
+
+  },
+  mounted() {
+    this.getVarietyList();
+    this.getTagList();
+    this.getChartDetail();
+    window.addEventListener('resize', this.reloadRightWid);
+  },
+  destroyed() {
+    window.removeEventListener('resize', this.reloadRightWid);
+  },
+  beforeRouteEnter(to, from, next) {
+    if(to.query.code){
+      to.matched[1].name='编辑图表'
+    }else{
+      to.matched[1].name='添加图表'
+    }
+    next()
+  }
+};
+</script>
+<style lang="scss" scoped>
+.crossVariety-edit-page {
+  $font-small: 12px;
+  $font-normal: 14px;
+  display: flex;
+  * {
+    box-sizing: border-box;
+  }
+
+  .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;
+    }
+  }
+  .left-cont {
+    width: 380px;
+    min-width: 380px;
+    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 - 113px);
+    overflow: hidden;
+    position: relative;
+    box-sizing: border-box;
+    .left-top {
+      padding: 15px 20px;
+      border-bottom: 1px solid #ececec;
+      box-shadow: 0px 3px 6px rgba(167, 167, 167, 0.09);
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+    }
+    .left-min {
+      padding: 0 20px;
+      max-height: calc(100vh - 190px);
+      overflow-y: auto;
+      
+      .section-item{
+        padding: 20px 0;
+        .top {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          margin-bottom: 15px;
+
+        }
+        .list {
+          display: flex;
+          flex-wrap: wrap;
+          gap: 10px;
+          .tag {
+            color: #333;
+            background: #fff;
+            border-color: transparent;
+            cursor: pointer;
+            &.act {
+              color: #0052D9;
+              background-color: #e6eefb;
+              border-color: #ccdcf7;
+            }
+          }
+        }
+      }
+
+      .left-bottom {
+        margin-top: 20px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+      }
+     
+    }
+    .move-btn {
+      height: 100%;
+      width: 4px;
+      position: absolute;
+      right: 0px;
+      top: 0;
+      &:hover {
+        cursor: col-resize;
+      }
+    }
+  }
+  .right-cont {
+    width: 80%;
+    overflow-x: auto;
+    .chart-min-cont {
+      background: #fff;
+      min-width: 880px;
+      height: calc(100vh - 118px);
+      overflow-y: auto;
+      display: flex;
+      flex-wrap: wrap;
+      .chart-wrapper {
+				padding: 30px 0;
+        width: 100%;
+				/* =================== */
+				.chart-show-cont {
+					min-height: 400px;
+					padding: 0 100px 50px;
+					position: relative;
+					.chart-title {
+						font-size: 16px;
+						font-weight: normal;
+						text-align: center;
+						margin-bottom: 10px;
+					}
+					.chart-author {
+						font-size: 14px;
+						color: #333;
+						position: absolute;
+						bottom: -50px;
+						right: -70px;
+					}
+          .range-cont {
+            position: absolute;
+            top: 15%;
+            .min-data-input {
+              width: 60px;
+              display: block;
+            }
+            &.left {
+              left: -70px;
+            }
+            &.bottom {
+              width: 100%;
+              display: flex;
+              justify-content: space-between;
+              top: auto;
+              right: 0;
+              bottom: -4%;
+              .left {
+                width: 60px;
+                display: block;
+                flex-shrink: 0;
+              }
+            }
+          }
+				}
+				.options-cont {
+					display: flex;
+					flex-wrap: wrap;
+					justify-content: space-between;
+				}
+			}
+
+      @media screen and (min-width: 1711px) {
+        .min-data-input {
+          margin-top: 290px;
+        }
+      }
+      @media screen and (max-width: 1710px) {
+        .min-data-input {
+          margin-top: 250px;
+        }
+      }
+
+    }
+    .nodata {
+      background-color: #fff;
+      text-align: center;
+      font-size: 16px;
+      color: #666;
+      width: 100%;
+      padding: 100px 0;
+    }
+    .bottom-wrapper {
+      width: 100%;
+      padding: 20px;
+      border-top: 1px solid #ebeff6;
+    }
+  }
+}
+</style>
+<style lang="scss">
+.crossVariety-edit-page {
+  .el-input--mini .el-input__inner {
+		padding: 0 0 0 4px;
+	}
+}
+</style>

+ 208 - 0
src/views/chartRelevance_manage/crossVarietyAnalysis/components/chartFormSection.vue

@@ -0,0 +1,208 @@
+<template>
+  <div class="form-cont">
+    <el-form
+      ref="diaForm"
+      label-position="left"
+      label-width="80px"
+      :model="form"
+      :rules="formRules"
+    >
+      <el-form-item label="时间长度" prop="CalculateValue">
+        <el-input
+          v-model="form.CalculateValue"
+          style="width: 140px"
+          :step="1"
+          type="number"
+          @change="(val) => {form.CalculateValue = Number(val);changeParams()}"
+        />
+        <el-select
+          v-model="form.CalculateUnit"
+          placeholder="请选择"
+          style="width: 100px"
+          @change="changeParams"
+        >
+          <el-option
+            v-for="item in unitOpt"
+            :key="item.val"
+            :label="item.label"
+            :value="item.val"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="X轴坐标" prop="TagX">
+        <el-select
+          v-model="form.TagX"
+          style="width: 240px"
+          placeholder="请选择"
+          @change="changeSeries"
+        >
+          <el-option
+            v-for="item in tagList"
+            :key="item.ChartTagId"
+            :label="item.ChartTagName"
+            :value="item.ChartTagId"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="Y轴坐标" prop="TagY">
+        <el-select
+          v-model="form.TagY"
+          placeholder="请选择"
+          style="width: 240px"
+          @change="changeSeries"
+        >
+          <el-option
+            v-for="item in tagList"
+            :key="item.ChartTagId"
+            :label="item.ChartTagName"
+            :value="item.ChartTagId"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="图表名称" prop="ChartName">
+        <el-input
+          v-model="form.ChartName"
+          style="width: 240px"
+          placeholder="请输入图表名称"
+          @change="changeParams"
+        />
+      </el-form-item>
+    </el-form>
+
+    <div class="date-section">
+      <label class="el-form-item__label">选择日期</label>
+      <ul>
+        <li class="date-li" v-for="(item,index) in form.DateConfigList" :key="index">
+          <el-select
+            v-model="item.DateType"
+            style="width: 150px"
+            placeholder="请选择"
+            @change="changeParams"
+          >
+            <el-option
+              v-for="item in dateOptions"
+              :key="item.val"
+              :label="item.label"
+              :value="item.val"
+            />
+          </el-select>
+
+          <el-input
+            v-model="item.Num"
+            v-if="item.DateType===2"
+            style="width: 140px"
+            :step="1"
+            type="number"
+            @change="(val) => {item.Num = Number(val);changeParams()}"
+          />
+
+          <el-button type="text" v-if="index===0" @click="addDateHandle">
+            <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 -2 16 16" fill="none">
+              <path d="M5.23966 8.48046H7.51966V10.7605C7.51966 10.8265 7.57366 10.8805 7.63966 10.8805H8.35966C8.42566 10.8805 8.47966 10.8265 8.47966 10.7605V8.48046H10.7597C10.8257 8.48046 10.8797 8.42646 10.8797 8.36046V7.64046C10.8797 7.57446 10.8257 7.52046 10.7597 7.52046H8.47966V5.24046C8.47966 5.17446 8.42566 5.12046 8.35966 5.12046H7.63966C7.57366 5.12046 7.51966 5.17446 7.51966 5.24046V7.52046H5.23966C5.17366 7.52046 5.11966 7.57446 5.11966 7.64046V8.36046C5.11966 8.42646 5.17366 8.48046 5.23966 8.48046Z" fill="#0052D9"/>
+              <path d="M13.52 2H2.48C2.2145 2 2 2.2145 2 2.48V13.52C2 13.7855 2.2145 14 2.48 14H13.52C13.7855 14 14 13.7855 14 13.52V2.48C14 2.2145 13.7855 2 13.52 2ZM12.92 12.92H3.08V3.08H12.92V12.92Z" fill="#0052D9"/>
+            </svg>添加日期
+          </el-button>
+
+          <i 
+            v-else 
+            class="el-icon-delete" 
+            style="cursor:pointer;color:#f00;"
+            @click="() => {form.DateConfigList.splice(index,1);changeParams()}"
+          />
+
+        </li>
+      </ul>
+    </div>
+  </div>
+</template>
+<script>
+export default {
+  props: {
+    tagList: {
+      type: Array,
+    },
+    chartInfo: {
+      type: Object
+    }
+  },
+  data() {
+    return {
+      form: {
+        ChartName:'',
+        Source: 10,
+        CalculateValue: 6,
+        CalculateUnit: '月',
+        TagX: '',
+        TagY: '',
+        DateConfigList: [
+          { DateType: 1,Num: 0 },
+        ],
+      },
+      unitOpt: [
+        { label: "年", val: "年" },
+        { label: "季", val: "季" },
+        { label: "月", val: "月" },
+        { label: "周", val: "周" },
+        { label: "天", val: "天" },
+      ],
+
+      dateOptions: [
+        { label: '最新日期',val: 1 },
+        { label: 'N天前',val: 2 },
+      ]
+    };
+  },
+  methods: {
+    addDateHandle() {
+      if(this.form.DateConfigList.length === 5) return this.$message.warning('日期数量已达上限')
+
+      this.form.DateConfigList.push({
+        DateType: 1,Num: 1
+      })
+      
+      this.changeParams()
+    },
+
+    initData(data) {
+      const { ChartName,CalculateValue,CalculateUnit,TagX,TagY,DateConfigList } = data;
+      this.form = {
+        ChartName,
+        CalculateValue,
+        CalculateUnit,
+        TagX,
+        TagY,
+        DateConfigList
+      }
+    },
+
+    changeSeries() {
+      let xName = this.tagList.find(_ => _.ChartTagId===Number(this.form.TagX))?this.tagList.find(_ => _.ChartTagId===Number(this.form.TagX)).ChartTagName:'';
+      let yName = this.tagList.find(_ => _.ChartTagId===Number(this.form.TagY))?this.tagList.find(_ => _.ChartTagId===Number(this.form.TagY)).ChartTagName:'';
+
+      this.form.ChartName = (xName&&yName) ? `${xName}百分位和${yName}百分位` : '';
+      this.changeParams()
+    },
+
+    changeParams() {
+      this.$emit('getData')
+    },
+  },
+};
+</script>
+<style scoped lang="scss">
+.form-cont {
+  width: 100%;
+  display: flex;
+  gap: 50px;
+
+  .date-section {
+    display: flex;
+    .date-li {
+      display: flex;
+      align-items: center;
+      gap: 10px;
+      margin-bottom: 20px;
+    }
+  }
+}
+</style>

+ 140 - 0
src/views/chartRelevance_manage/crossVarietyAnalysis/components/edbTableSection.vue

@@ -0,0 +1,140 @@
+<template>
+  <el-table
+    :data="tableData"
+    ref="tableRef"
+    highlight-current-row
+    border
+    >
+      <el-table-column
+        v-for="item in tableColums"
+        :key="item.label"
+        :label="item.label"
+        :width="item.widthsty"
+        :min-width="item.minwidthsty"
+        align="center"
+      >
+        <template slot-scope="scope">
+          <span>{{ scope.row[item.key] }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" key="Copy" align="center" width="140">
+        <template slot-scope="scope">
+          <span class="editsty" @click="copyCode(scope.row)">
+          <i class="el-icon-document-copy" />&nbsp;复制数据</span
+        ><br />
+        <span class="editsty" @click="viewTarget(scope.row)">查看数据</span>
+      </template>
+    </el-table-column>
+    <div slot="empty">
+      <tableNoData text="暂无指标" size="mini"/>
+    </div>
+  </el-table>
+</template>
+<script>
+import { dataBaseInterface } from '@/api/api';
+import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
+export default {
+  props: {
+    tableData: {
+      type: Array,
+      default: () => []
+    }
+  },
+  data() {
+    return {
+      tableColums: [
+        {
+          label: '指标名称',
+          key: 'EdbName',
+          enKey:'EdbNameEn',
+					inputTip:'点击输入英文指标名称',
+          minwidthsty: '150px',
+        },
+        {
+          label: '指标ID',
+          key: 'EdbCode',
+          widthsty: '120px',
+        },
+        {
+          label: '更新频度',
+          key: 'Frequency',
+          enKey:'FrequencyEn',
+          minwidthsty: '60px',
+        },
+        {
+          label: '单位',
+          key: 'Unit',
+          enKey:'UnitEn',
+					inputTip:'英文单位',
+          minwidthsty: '50px',
+        },
+        {
+          label: '起始时间',
+          key: 'StartDate',
+          minwidthsty: '100px',
+        },
+        {
+          label: '最新日期',
+          key: 'LatestDate',
+          minwidthsty: '90px',
+        },
+        {
+          label: '最新值',
+          key: 'LatestValue',
+          minwidthsty: '90px',
+        },
+        {
+          label: '最近更新',
+          key: 'ModifyTime',
+          minwidthsty: '100px',
+        },
+        {
+          label: '数据来源',
+          key: 'SourceName',
+        },
+      ],//表格列
+    }
+  },
+  methods:{
+    /* 用于复制指标 */
+    async copyCode({EdbInfoId, EdbInfoCategoryType}) {
+      let params = {
+        PageSize: 100000,
+        CurrentIndex: 1,
+        EdbInfoId: EdbInfoId,
+      }
+      const res = EdbInfoCategoryType === 1 
+        ? await preDictEdbInterface.edbDataInfo(params)
+        : await dataBaseInterface.targetList(params);
+      if (res.Ret !== 200) return
+
+      let arr = res.Data.Item.DataList || [];
+
+      let str = '日期\t 值\n';
+      arr.forEach((item) => (str += `${item.DataTime}\t${item.Value}\n`));
+      this.$copyText(str).then(
+        (res) => {
+          this.$message.success('已成功复制!');
+        },
+        (err) => {
+          this.$message.error('复制失败!');
+        }
+      );
+    },
+
+    /* 查看数据 跳转指标库展开具体指标 */
+    viewTarget({ UniqueCode,EdbInfoId,EdbInfoCategoryType,ClassifyId }) {
+      let path = EdbInfoCategoryType ? '/predictEdb' : '/database';
+      let {href} = this.$router.resolve({path, query: {
+        code: UniqueCode,
+        id: EdbInfoId,
+        classifyId:ClassifyId
+      }});
+			window.open(href,'_blank');
+    },
+  },
+}
+</script>
+<style scoped lang='scss'>
+
+</style>

+ 182 - 0
src/views/chartRelevance_manage/crossVarietyAnalysis/components/tagRelationDialog.vue

@@ -0,0 +1,182 @@
+<template>
+  <el-dialog
+    :visible.sync="isShow"
+    :close-on-click-modal="false"
+    :modal-append-to-body="false"
+    :title="`${info.tagName}指标配置`"
+    @close="cancelHandle"
+    custom-class="tag-relation-dialog"
+    center
+    width="650px"
+    v-dialogDrag
+  >
+    <div class="dialog-min">
+      <ul class="list-ul">
+        <li class="list-li" v-for="(item,index) in list" :key="index">
+          <label class="variety-name">{{item.varietyName}}</label>
+
+          <selectTarget
+            :defaultId="item.edbInfoId"
+            :defaultOpt="searchOptions"
+            @select="e => selectTargetHandle(e,item)"  
+            :filter="false"
+            style="max-width: 200px;"
+          />
+          <el-date-picker
+            v-model="item.endDate"
+            type="date"
+            value-format="yyyy-MM-dd"
+            disabled
+            style="width:140px;"
+            placeholder="最新日期"
+          />
+
+          <el-input
+            v-model="item.endValue"
+            style="width: 100px;"
+            disabled
+            placeholder="最新值"
+          />
+
+        </li>
+      </ul>
+
+      <div class="dialog-bot">
+        <el-button type="primary" style="margin-right: 20px" @click="saveHandle"
+          >保存</el-button
+        >
+        <el-button type="primary" plain @click="cancelHandle">取消</el-button>
+      </div>
+    </div>
+  </el-dialog>
+</template>
+<script>
+import { crossVarietyInterface } from '@/api/modules/chartRelevanceApi';
+import selectTarget from '@/views/chartRelevance_manage/components/selectTarget.vue';
+export default {
+  components: { selectTarget },
+  props: {
+    isShow: {
+      type: Boolean
+    },
+    info: {
+      type:  Object
+    },
+    varietyList: {
+      type: Array
+    }
+  },
+  watch: {
+    isShow(nval) {
+      if(!nval) return
+
+      this.getRelationList() 
+    }
+  },
+  data() {
+    return {
+      list: [],
+      searchOptions: []
+    }
+  },
+  methods:{
+    selectTargetHandle(e,item) {
+      if(!e){
+        item.edbName = '';
+        item.edbInfoId = '';
+        item.endDate = '';
+        item.endValue = '';
+        return
+      } 
+      const { EndDate,EndValue,EdbName,EdbInfoId } = e;
+      
+      item.edbName = EdbName;
+      item.edbInfoId = EdbInfoId;
+      item.endDate = EndDate;
+      item.endValue = EndValue;
+    },
+
+    /* 获取标签关联品种列表 */
+    async getRelationList() {
+      let res = await crossVarietyInterface.getTagRelation({ ChartTagId: this.info.id })
+      if(res.Ret!==200) return
+
+      let relationArr = res.Data.List || [];
+
+      this.list = this.varietyList.map(_ => {
+        let relationItem = relationArr.length ? relationArr.find(item => item.ChartVarietyId===_.ChartVarietyId) : undefined
+
+        return {
+          varietyName: _.ChartVarietyName,
+          varietyId: _.ChartVarietyId,
+          edbName: relationItem?relationItem.EdbName:'',
+          edbInfoId: relationItem?relationItem.EdbInfoId:0,
+          endDate: relationItem?relationItem.EndDate:'',
+          endValue: relationItem?relationItem.EndValue:''
+        }
+      })
+
+      this.searchOptions = this.list.map(_ => ({
+        EdbName: _.edbName,
+        EdbInfoId: _.edbInfoId
+      }))
+    },
+
+    /* 保存`` */
+    saveHandle: _.debounce(async function() {
+      let params = {
+        ChartTagId: this.info.id,
+        VarietyEdb: this.list.map(_ => ({
+          ChartVarietyId: _.varietyId,
+          EdbInfoId: _.edbInfoId
+        })).filter(_ => _.EdbInfoId)
+      }
+      let res = await crossVarietyInterface.setTagRelationVariety(params)
+
+      if(res.Ret!==200) return
+      this.$message.success('配置保存成功')
+      this.$emit('refresh')
+      this.cancelHandle()
+    },300),
+
+    cancelHandle() {
+      this.list = [];
+      this.searchOptions=[];
+      this.$emit('update:isShow',false)
+    }
+  },
+}
+</script>
+<style scoped lang='scss'>
+.dialog-min {
+  padding: 30px 0 50px;
+  .list-ul{
+    padding: 0 15px;
+    max-height: calc(100vh - 500px);
+    min-height: 300px;
+    overflow-y: auto;
+    .list-li {
+      display: flex;
+      align-items: center;
+      gap: 20px;
+      margin-bottom: 20px;
+      .variety-name {
+        /* margin-right: 20px; */
+        width: 100px;
+      }
+    }
+  }
+  .dialog-bot {
+    display: flex;
+    margin-top: 30px;
+    justify-content: center;
+  }
+}
+</style>
+<style lang="scss">
+  /* .tag-relation-dialog .el-dialog__body {
+    max-height: calc(100vh - 350px);
+    min-height: 300px;
+    overflow-y: auto;
+  } */
+</style>

+ 203 - 0
src/views/chartRelevance_manage/crossVarietyAnalysis/components/tagSetDialog.vue

@@ -0,0 +1,203 @@
+<template>
+  <el-dialog
+    :visible.sync="isShow"
+    :close-on-click-modal="false"
+    :modal-append-to-body="false"
+    :title="type==='tag'?'标签管理':'品种管理'"
+    @close="cancelHandle"
+    custom-class="dialog"
+    center
+    width="560px"
+    v-dialogDrag
+  >
+    <div class="dialog-min">
+      <el-input
+        v-model="searchTxt"
+        placeholder="请输入名称"
+        prefix-icon="el-icon-search"
+        size="medium"
+        clearable 
+        @change="filterList"
+      />
+      <div class="tag-list">
+        <div
+          v-for="(item,index) in showList"
+          :key="item.id"
+          class="el-tag"
+          :style="item.isEdit&&'padding:0;border:none;'"
+          @dblclick="editTagOpen(item,index)"
+        >
+
+          <el-input
+            v-model="item.label"
+            v-if="item.isEdit"
+            class="input-edit"
+            :ref="`inputRef${index}`"
+            size="small"
+            @change="editItemHandle(item)"
+          />
+          <span v-else>
+            {{ item.label }}
+            <el-popconfirm
+              :title="`是否确认删除该${type==='tag'?'标签':'品种'}`"
+              @onConfirm="closeItemHandle(item)"
+            >
+              <i
+                slot="reference"
+                class="el-tag__close el-icon-close" 
+              />
+                <!-- @click.stop="closeItemHandle(item)" -->
+            </el-popconfirm>
+          </span>
+        </div>
+
+        <el-input
+          class="input-edit"
+          v-if="inputVisible"
+          v-model="inputValue"
+          ref="saveTagInput"
+          size="small"
+          @change="addNewTagHandle"
+        >
+        </el-input>
+        <el-button v-else size="small" @click="addNewItem">+ 标签</el-button>
+
+      </div>
+    </div>
+
+  </el-dialog>
+</template>
+<script>
+import { crossVarietyInterface } from '@/api/modules/chartRelevanceApi';
+export default {
+  props: {
+    isShow: {
+      type: Boolean
+    },
+    type: { //tag  variety
+      type: String
+    },
+    dataList: {
+      type: Array,
+      default: () => []
+    }
+  },
+  watch: {
+    isShow(nval) {
+      if(!nval) return
+      this.initData()
+    },
+
+    dataList(nval) {
+      this.initData();
+    }
+  },
+  computed: {
+    showList() {
+      return this.list.length ? this.list.filter(_ => _.label.includes(this.searchTxt)) : []
+    }
+  },
+  data() {
+    return {
+      searchTxt: '',
+      inputVisible: false,
+      inputValue: '',
+      list: []
+    }
+  },
+  mounted(){
+
+  },
+  methods:{
+    /* 关闭标签 */
+    closeItemHandle(item) {
+      this.delItem(item)
+    },
+
+    async delItem(item) {
+      let res = this.type==='tag' 
+        ? await crossVarietyInterface.tagDel({ChartTagId:item.id})
+        : await crossVarietyInterface.varietyDel({ChartVarietyId:item.id})
+
+      if(res.Ret !== 200) return
+      this.$message.success('删除成功')
+      // let index = this.list.findIndex(_ => _.id === item.id);
+      // this.list.splice(index,1)
+      
+      this.refreshData()
+    },
+
+    addNewItem() {
+      this.inputValue = '';
+      this.inputVisible = true;
+      this.$nextTick(_ => {
+        this.$refs.saveTagInput.$refs.input.focus();
+      });
+    },
+
+    /* 新增标签 */
+    async addNewTagHandle() {
+      this.inputVisible = false;
+      if(!this.inputValue) return
+
+      let res = this.type==='tag' 
+        ? await crossVarietyInterface.tagAdd({ TagName: this.inputValue})
+        : await crossVarietyInterface.varietyAdd({ VarietyName: this.inputValue})
+        
+      if(res.Ret!==200) return
+      this.refreshData()
+      
+    },
+
+    editTagOpen(item,index) {
+      this.$set(item,'isEdit',true)
+      this.$nextTick(_ => {
+        this.$refs[`inputRef${index}`][0].$refs.input.focus();
+      });
+    },
+
+    /* 编辑标签 */
+    async editItemHandle(item) {
+      let res = this.type==='tag' 
+        ? await crossVarietyInterface.tagEdit({ TagName: item.label,ChartTagId:item.id})
+        : await crossVarietyInterface.varietyEdit({ VarietyName: item.label,ChartVarietyId:item.id})
+      if(res.Ret !== 200) return
+
+      item.isEdit = false;
+      this.refreshData()
+    },
+
+    refreshData() {
+      this.searchTxt = ''
+      this.$emit('refresh')
+    },
+
+    initData() {
+      this.list = this.dataList.map(_ => ({
+        label: _.ChartTagName || _.ChartVarietyName,
+        id:  _.ChartTagId || _.ChartVarietyId,
+        ..._
+      }))
+    },
+
+    cancelHandle() {
+      this.searchTxt = ''
+      this.$emit('update:isShow',false)
+    }
+  },
+}
+</script>
+<style scoped lang='scss'>
+.dialog-min {
+  padding: 0 0 60px;
+  .tag-list { 
+    margin-top: 30px;
+    display: flex;
+    flex-wrap: wrap;
+    gap: 15px;
+  }
+  .input-edit {
+    width: 100px;
+  }
+}
+</style>

+ 570 - 0
src/views/chartRelevance_manage/crossVarietyAnalysis/list.vue

@@ -0,0 +1,570 @@
+<template>
+	<div class=" pub-chart-box" 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 v-permission="permissionBtn.statisticPermission.crossVariety_addChart"
+							 type="primary" @click="goAddChart">添加图表</el-button>
+				</div>
+
+				<div class="search-cont">
+					<el-checkbox v-model="isShowMe"  
+						v-permission="permissionBtn.statisticPermission.crossVariety_onlyMine"
+						@change="() => { getTreeData();getPublicList() }">只看我的</el-checkbox>
+					<el-select
+						v-model="search_txt"
+						v-loadMore="searchLoad"
+						:filterable="!search_txt"
+						remote
+						clearable
+						placeholder="请输入图表名称"
+						style="width: 100%; margin-top: 20px"
+						:remote-method="searchHandle"
+						@click.native="inputFocusHandle"
+					>
+						<i slot="prefix" class="el-input__icon el-icon-search"></i>
+						<el-option
+							v-for="item in searchOptions"
+							:key="item.ChartInfoId"
+							:label="item.ChartName"
+							:value="item.ChartInfoId"
+						>
+						</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&&permissionBtn.isShowBtn('statisticPermission','crossVariety_classifyOpt_edit')"
+								@blur="changeValue(data)"
+							/>
+							<span
+								@dblclick.stop="handleDblClick(data)"
+								v-else
+								class="text_oneLine node_label"
+								:style="`width:${
+									(select_node === data.UniqueCode && node.Nodewidth) || ''
+								}`"
+							>
+								<span>{{ data.ChartClassifyName }}</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.ChartInfoId&&permissionBtn.isShowBtn('statisticPermission','crossVariety_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.ChartInfoId&&permissionBtn.isShowBtn('statisticPermission','crossVariety_classifyOpt_delete')"
+								/> -->
+							</span>
+						</span>
+					</el-tree>
+
+				</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="chart-detail-wrapper" v-if="chartInfo.ChartInfoId">
+					<el-row class="bottom-min">
+              <el-col
+                :span="21"
+                style="padding: 20px 0;"
+              >
+                <div class="chartEn-mark" v-show="chartInfo.IsEnChart" style="top: 0;left: 0;">En</div>
+                <div class="chart-show-cont"  v-if="!chartInfo.WarnMsg">
+                  <div class="chartWrapper" id="chartWrapper">
+                    <h2 class="chart-title">{{ chartInfo.ChartName }}</h2>
+                    <Chart 
+											:options="options"
+											minHeight="440px" 
+											height="500px"
+											ref="chartRef"
+										/>
+                  </div>
+                  <span class="chart-author">作者:{{ chartInfo.SysUserRealName}}</span>
+                </div>
+
+                <!-- 异常显示 -->
+                <p class="error-tip" style="min-height: 400px;" v-if="chartInfo.WarnMsg">{{chartInfo.WarnMsg}}</p>
+              </el-col>
+              <el-col :span="3" style="position: absolute;height: 100%;right: 0;">
+								<!-- 操作 -->
+								<chartHandlesWrap
+									:chartInfo="chartInfo"
+									:linkUrl="linkUrl"
+									@copyChartConfirm="copyChartConfirm"
+									@addMychartHandle="addMychartHandle"
+									@refreshHandle="refreshHandle"
+									@saveChartOtherHandle="saveChartOtherHandle"
+									@editChartHandle="editChartHandle"
+									@openEnNameDia="openEnNameDia"
+									@delChartHandle="delChartHandle"
+								/>
+              </el-col>
+          </el-row>
+
+					<!-- 指标列表 -->
+					<edbTableSection :tableData="tableData"/>
+
+				</div>
+				<!-- 列表 -->
+				<chartListWrap
+          v-else 
+          :total="chart_total"
+          :list="chartList" 
+          @loadMoreHandle="loadMoreHandle"
+          @detailShowHandle="detailShowHandle"
+          @addMychartHandle="addMychartHandle"
+          ref="chartListWrap"
+        />
+			</div>
+		</div>
+
+
+		<!-- 分类弹窗 -->
+		<classify-dia
+			:isOpenDialog.sync="classifyDia"
+			:title="dialog_title"
+			:form="classifyForm"
+			@successCallback="getTreeData"
+		/>
+
+		 <!-- 加入我的图库弹窗 -->
+    <addMyClassifyDia
+      :isAddMyDialog="isAddMyChart"
+      :add_id="add_chart_id"
+      :add_ids="add_ids"
+      @cancel="isAddMyChart = false"
+      @addSuccess="addMySuccess"
+    />
+
+		 <!-- 图表另存 -->
+    <SaveChartOther 
+      :show.sync="isShowSaveOther" 
+      fromType="chartsetting"
+			source="cross_variety"
+      :data="chartInfo"
+      @ensure="getTreeData"
+    />
+
+		<!-- 输入英文指标弹窗 -->
+		<set-en-name-dia 
+			:isOpenDialog="setEnName" 
+		  :formData="formItemArray"
+			@cancel="setEnName=false"
+   	  @updateEnName="updateEnName"
+		/>
+
+	</div>
+</template>
+
+<script>
+import { crossVarietyInterface } from '@/api/modules/chartRelevanceApi';
+import leftMixin from '../mixins/classifyMixin';
+import Chart from '@/views/dataEntry_manage/components/chart';
+import classifyDia from '@/views/datasheet_manage/components/sheetClassifyDia.vue';
+import addMyClassifyDia from '@/views/dataEntry_manage/components/addMyClassifyDia';
+import SaveChartOther from '@/views/dataEntry_manage/components/SaveChartOther';
+import setEnNameDia from '@/views/dataEntry_manage/components/setEnNameDia.vue'
+import { chartSetMixin } from '@/views/dataEntry_manage/mixins/chartPublic';
+import { copyOtherOptions } from '@/utils/defaultOptions';
+import edbTableSection from './components/edbTableSection.vue';
+export default {
+	components: {
+		classifyDia,
+		Chart,
+		addMyClassifyDia,
+		SaveChartOther,
+		setEnNameDia,
+		edbTableSection
+	},
+	mixins:[ leftMixin,chartSetMixin ],
+	computed: {
+		/* 分享地址 */
+    linkUrl() {
+      const LINK_CHART_URL = this.$setting.dynamicOutLinks.ChartViewUrl+'/chartshow';
+      return `${LINK_CHART_URL}?code=${this.chartInfo.UniqueCode}&fromType=share?&lang=${this.currentLang}`
+    }
+	},
+	data () {
+		return {
+			showData: false,
+			refreshLoading: false,
+			isShowMe: false,
+			search_txt: '',
+			searchOptions:[],
+			isSlideLeft: false,//左侧分类收起
+
+			select_node: '',//节点唯一标识code
+			select_classify: '',
+			new_label:'',//双击修改的value
+			treeData: [], //分类数据
+      defaultShowNodes: [], //展开节点
+      defaultProp: {
+        label: 'ChartClassifyName',
+        children: 'Children',
+      }, //树结构配置项
+			dynamicNode: null,
+
+			/* 分类弹窗 */
+			dialog_title:'',
+			classifyDia: false, //
+			classifyForm: {},
+
+			select_id: '',//选中的图表id
+			chartInfo: {},
+			chart_title:'',//图表标题 双击标题修改时来存储最新值
+
+			isAddMyChart: false, //加入图库弹窗
+      add_chart_id: 0, //要加入的图表
+			add_ids:[],//加入时已有的分类
+
+			/* 图表列表 */
+			publicHaveMove: true,//是否还有列表数据
+			chartList: [],
+			chart_total: 0,
+			chart_page: 1,
+			chart_pages_size: 16,
+
+			search_page: 1,
+			search_have_more: false,
+			current_search:'',
+		};
+	},
+	methods: {
+
+		/* 添加图表 */
+		goAddChart() {
+			this.$router.push({ path: '/crossVarietyChartEditor' });
+		},
+
+		/* 获取分类 */
+		getTreeData(params=null) {
+			crossVarietyInterface.classifyList({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) {
+			this.search_page = 1;
+			this.current_search = query;
+			this.searchApi(this.current_search)
+		},
+
+		searchApi(query,page=1) {
+      /* 查找列表 */
+      crossVarietyInterface
+        .searchChart({
+          Keyword: query,
+          IsShowMe:this.isShowMe,
+          CurrentIndex: page
+        })
+        .then((res) => {
+          if (res.Ret !== 200) return
+          const { List,Paging } = res.Data;
+          this.search_have_more = page < Paging.Pages;
+          this.searchOptions = page === 1 ? List : [...this.searchOptions,...List];
+        });
+		},
+
+		/* 聚焦获取当前检索 */
+		inputFocusHandle(e) {
+			this.search_page = 1;
+			this.current_search = e.target.value;
+      if(this.current_search) {
+        this.searchApi(this.current_search)
+      }else {
+        this.searchOptions = [];
+      }
+		},
+
+		searchLoad() {
+			if(!this.search_have_more) return;
+			this.searchApi(this.current_search,++this.search_page);
+		},
+
+		/* 选中分类变化时 */
+		nodeChange({ UniqueCode,ChartInfoId,ChartClassifyId },node) {
+			this.search_txt = '';
+			this.select_node = UniqueCode;
+			this.select_classify = !ChartInfoId ? ChartClassifyId : 0;
+			this.select_id = ChartInfoId || 0;
+			this.resetNodeStyle(node);
+			this.dynamicNode = node;
+		},
+
+
+    /* 编辑节点 */
+    editNode(node, { ChartClassifyName,ChartClassifyId }) {
+
+      this.dialog_title = '编辑图表分类';
+      /* 编辑目录 */
+      this.classifyForm = {
+        classify_name: ChartClassifyName,
+        classify_id: ChartClassifyId,
+      };
+      this.classifyDia = true;
+    },
+
+		 /* 删除方法 */
+    delApi(ChartInfoId) {
+      crossVarietyInterface.chartDel({
+				ChartInfoId
+			})
+      .then((res) => {
+				if (res.Ret !== 200) return
+				this.$message.success(res.Msg);
+
+				if (!res.Data.ChartInfoId) this.select_id = '';
+
+				//删除自动显示下一张
+				res.Data.ChartInfoId
+					? this.getTreeData({
+							code: res.Data.UniqueCode,
+							id: res.Data.ChartInfoId
+						})
+					: this.getTreeData();
+			});
+    },
+
+		/* 分类成功回调 */
+		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 = '';
+
+      }
+		},
+
+		/* 获取图表列表 */
+		getPublicList() {
+			crossVarietyInterface.getChartList({
+				CurrentIndex: this.chart_page,
+				PageSize: this.chart_pages_size,
+        ChartClassifyId: this.select_classify || 0,
+				IsShowMe: this.isShowMe
+			}).then(res => {
+				if(res.Ret !== 200) return
+
+				this.publicHaveMove = res.Data
+            ? this.chart_page < res.Data.Paging.Pages
+            : false;
+          this.chartList = res.Data
+            ? this.chart_page === 1
+              ? res.Data.List
+              : [...this.chartList, ...res.Data.List]
+            : [];
+        this.chart_total = res.Data ? res.Data.Paging.Totals : 0;
+			})
+		},
+
+		getChartInfo() {
+			this.getDetailHandle();
+		},
+
+		/* 获取图表详情 */
+		getDetailHandle() {
+			crossVarietyInterface.chartDetail({
+				ChartInfoId: this.select_id
+			}).then(res => {
+				if(res.Ret !== 200) return
+
+				const { ChartInfo,DataResp,EdbInfoList } = res.Data;
+
+				this.chartInfo = ChartInfo;
+				this.tableData = EdbInfoList;
+				this.crossVarietyChartData = DataResp;
+				this.chartLimit = {
+					min: DataResp.YMinValue,
+					max: DataResp.YMaxValue ,
+					x_min: DataResp.XMinValue,
+					x_max: DataResp.XMaxValue,
+				}
+
+				this.setCrossVarietyChart()
+			})
+		},
+
+		/* 删除图表 */
+		delChartHandle() {
+			const { ChartClassifyId,ChartInfoId } = this.chartInfo;
+			this.$confirm('删除后该图表将不能再引用,确认删除吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+      })
+        .then(() => {
+          this.delApi(ChartInfoId)
+        })
+        .catch(() => {});
+		},
+
+		/* 刷新图表 */
+		refreshHandle() {
+			this.refreshLoading = this.$loading({
+        lock: true,
+        target: '.main-right',
+        text: '刷新图表中...',
+        spinner: 'el-icon-loading',
+        background: 'rgba(255, 255, 255, 0.8)',
+      });
+      crossVarietyInterface.refreshChart({
+          ChartInfoId: this.chartInfo.ChartInfoId,
+      }).then((res) => {
+				this.refreshLoading.close();
+				if (res.Ret === 200) {
+					this.getDetailHandle();
+					this.$message.success(res.Msg);
+				}
+			});
+		},
+
+		/* 编辑图表 */
+		editChartHandle() {
+			this.$router.push({
+        path: '/crossVarietyChartEditor',
+        query: {
+          code: this.chartInfo.UniqueCode,
+					id: this.chartInfo.ChartInfoId
+        }
+      })
+		},
+
+		copyChartHandle:_.debounce(function(type){
+      let chartsName = this.currentLang=='ch'?this.chartInfo.ChartName:this.chartInfo.ChartNameEn
+      let { heightNum, widthNum , newTitle , dynamic_copyOptions} = this.dynamicWidthAndHeight(type,this.chartInfo.ChartType,chartsName,1)
+      const chartType = 'seasonLegend';
+      // 英文转SVG设置变动
+      if(this.currentLang == 'en'){
+        // 如果竖轴坐标单位为'英文单位',表示客户没填,转成svg时置为空
+        this.$refs.chartRef.chart.options.yAxis.forEach(it => {
+          if(it.title.text == '英文单位') it.title.text='' 
+        });
+      }
+      let svg = this.$refs.chartRef.chart.getSVG({
+        chart:{
+          width:widthNum,
+          height:heightNum,
+          backgroundColor:"rgba(255, 255, 255, 0)",
+        },
+        title: {
+          text: newTitle,
+          margin: 10,
+          style: {
+            fontSize: '18px'
+          }
+        },
+        legend:{
+          ...copyOtherOptions[chartType],
+          ...dynamic_copyOptions[chartType]
+          }
+      });
+      this.copyBlobItem(widthNum,heightNum,svg,type);
+    },500),
+    
+		handleDblClick(data){
+			if(!this.permissionBtn.isShowBtn('statisticPermission','crossVariety_classifyOpt_edit')) return 
+			this.editNodeLabel(data)
+		}
+	},
+	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>
+@import '../css/index.scss';
+</style>
+
+<style lang="scss">
+@import '../css/pub.scss';
+</style>

+ 1 - 1
src/views/chartRelevance_manage/css/index.scss

@@ -136,7 +136,7 @@ $normal-font: 14px;
           margin-bottom: 20px;
           margin-bottom: 20px;
 
 
           .chart-show-cont {
           .chart-show-cont {
-            padding: 0 160px 0 120px;
+            padding: 0 160px 0 100px;
             position: relative;
             position: relative;
             min-height: 400px;
             min-height: 400px;
             .chart-title {
             .chart-title {

+ 4 - 4
src/views/chartRelevance_manage/fittingEquationChartEditor.vue → src/views/chartRelevance_manage/fittingEquation/fittingEquationChartEditor.vue

@@ -174,10 +174,10 @@
 import { fittingEquationInterface } from '@/api/modules/chartRelevanceApi';
 import { fittingEquationInterface } from '@/api/modules/chartRelevanceApi';
 import { yearSelector } from '@/utils/defaultOptions';
 import { yearSelector } from '@/utils/defaultOptions';
 import Chart from '@/views/dataEntry_manage/components/chart';
 import Chart from '@/views/dataEntry_manage/components/chart';
-import selectTarget from './components/selectTarget.vue';
-import fittingEquationSaveDia from './components/fittingEquationSaveDia.vue';
-import chartCard from './components/chartCard.vue';
-import ExplainDialog from './components/explainDialog.vue';
+import selectTarget from '../components/selectTarget.vue';
+import fittingEquationSaveDia from '../components/fittingEquationSaveDia.vue';
+import chartCard from '../components/chartCard.vue';
+import ExplainDialog from '../components/explainDialog.vue';
 export default {
 export default {
   components: { Chart,selectTarget,fittingEquationSaveDia,chartCard,ExplainDialog },
   components: { Chart,selectTarget,fittingEquationSaveDia,chartCard,ExplainDialog },
 	directives: {
 	directives: {

+ 3 - 3
src/views/chartRelevance_manage/fittingEquationList.vue → src/views/chartRelevance_manage/fittingEquation/fittingEquationList.vue

@@ -243,7 +243,7 @@
 
 
 <script>
 <script>
 import { fittingEquationInterface } from '@/api/modules/chartRelevanceApi';
 import { fittingEquationInterface } from '@/api/modules/chartRelevanceApi';
-import leftMixin from './mixins/classifyMixin';
+import leftMixin from '../mixins/classifyMixin';
 import Chart from '@/views/dataEntry_manage/components/chart';
 import Chart from '@/views/dataEntry_manage/components/chart';
 import changeLang from "@/views/dataEntry_manage/components/changeLang.vue"
 import changeLang from "@/views/dataEntry_manage/components/changeLang.vue"
 import classifyDia from '@/views/datasheet_manage/components/sheetClassifyDia.vue';
 import classifyDia from '@/views/datasheet_manage/components/sheetClassifyDia.vue';
@@ -634,9 +634,9 @@ export default {
 }
 }
 </script>
 </script>
 <style lang='scss' scoped>
 <style lang='scss' scoped>
-@import './css/index.scss';
+@import '../css/index.scss';
 </style>
 </style>
 
 
 <style lang="scss">
 <style lang="scss">
-@import './css/pub.scss';
+@import '../css/pub.scss';
 </style>
 </style>

+ 35 - 21
src/views/chartRelevance_manage/mixins/classifyMixin.js

@@ -1,5 +1,5 @@
 import chartRelevanceApi from '@/api/modules/chartRelevanceApi.js';
 import chartRelevanceApi from '@/api/modules/chartRelevanceApi.js';
-import { fittingEquationInterface,statisticFeatureInterface } from '@/api/modules/chartRelevanceApi';
+import { fittingEquationInterface,statisticFeatureInterface,crossVarietyInterface } from '@/api/modules/chartRelevanceApi';
 import { dataBaseInterface } from '@/api/api.js';
 import { dataBaseInterface } from '@/api/api.js';
 
 
 export default {
 export default {
@@ -117,7 +117,6 @@ export default {
     resetNodeStyle: _.debounce(function(node) {
     resetNodeStyle: _.debounce(function(node) {
 			const tree = $('.target_tree')[0];
 			const tree = $('.target_tree')[0];
 			let width = tree.offsetWidth;
 			let width = tree.offsetWidth;
-			// let label_wid = width > 500 ? 'auto' : (width <= 300 && width < 360) ?  100 : 0.7*width;
 			let label_wid =
 			let label_wid =
 				width > 500
 				width > 500
 					? 'auto'
 					? 'auto'
@@ -143,26 +142,34 @@ export default {
       if(!this.new_label) return this.$message.warning('名称不能为空');
       if(!this.new_label) return this.$message.warning('名称不能为空');
       this.$set(data,'isEdit',false)
       this.$set(data,'isEdit',false)
 
 
-      if(this.new_label !== data.ClassifyName) {
-        let res = this.$route.path === '/fittingEquationList'
-          ? await fittingEquationInterface.classifyEdit({
-              ChartClassifyId: data.ChartClassifyId,
-              ChartClassifyName: this.new_label
-            })
-          : this.$route.path === '/statisticFeatureList'
-          ? await statisticFeatureInterface.classifyEdit({
-              ChartClassifyId: data.ChartClassifyId,
-              ChartClassifyName: this.new_label
-            })
-          :await chartRelevanceApi.classifyEdit({
-              ChartClassifyId: data.ChartClassifyId,
-              ChartClassifyName: this.new_label
-            })
-
-        if(res.Ret !== 200) return
-  
-        this.getTreeData();
+      if(this.new_label === data.ClassifyName) return 
+      
+      let res;
+      if(this.$route.path === '/fittingEquationList') {
+        res = await fittingEquationInterface.classifyEdit({
+                ChartClassifyId: data.ChartClassifyId,
+                ChartClassifyName: this.new_label
+              })
+      }else if(this.$route.path === '/statisticFeatureList') {
+        res = await statisticFeatureInterface.classifyEdit({
+                ChartClassifyId: data.ChartClassifyId,
+                ChartClassifyName: this.new_label
+              })
+      }else if(this.$route.path === '/chartrelevance') {
+        res = await chartRelevanceApi.classifyEdit({
+                ChartClassifyId: data.ChartClassifyId,
+                ChartClassifyName: this.new_label
+              })
+      }else if(this.$route.path === '/crossVarietyChartList') {
+        res = await crossVarietyInterface.classifyEdit({
+          ChartClassifyId: data.ChartClassifyId,
+          ChartClassifyName: this.new_label
+        })
       }
       }
+
+      if(res.Ret !== 200) return
+
+      this.getTreeData();
     },
     },
 
 
     /* 拖拽完成 */
     /* 拖拽完成 */
@@ -214,6 +221,8 @@ export default {
         res=await fittingEquationInterface.classifyMove(params)
         res=await fittingEquationInterface.classifyMove(params)
       }else if(this.$route.path === '/statisticFeatureList') {
       }else if(this.$route.path === '/statisticFeatureList') {
         res=await statisticFeatureInterface.classifyMove(params)
         res=await statisticFeatureInterface.classifyMove(params)
+      }else if(this.$route.path === '/crossVarietyChartList') {
+        res=await crossVarietyInterface.classifyMove(params)
       }
       }
 
 
       if (res.Ret !== 200) return;
       if (res.Ret !== 200) return;
@@ -264,6 +273,8 @@ export default {
         res=await fittingEquationInterface.chartMove(params)
         res=await fittingEquationInterface.chartMove(params)
       }else if(this.$route.path === '/statisticFeatureList') {
       }else if(this.$route.path === '/statisticFeatureList') {
         res=await statisticFeatureInterface.chartMove(params)
         res=await statisticFeatureInterface.chartMove(params)
+      }else if(this.$route.path === '/crossVarietyChartList') {
+        res=await crossVarietyInterface.chartMove(params)
       }
       }
       
       
       if (res.Ret !== 200) return;
       if (res.Ret !== 200) return;
@@ -335,6 +346,9 @@ export default {
           (dropNode.level === 2 && type !== "inner")
           (dropNode.level === 2 && type !== "inner")
         ) {
         ) {
           canDrop = true;
           canDrop = true;
+          
+          //跨品种分析不允许跨分类拖
+          if(draggingNode.data.ChartClassifyId !== dropNode.data.ChartClassifyId)  canDrop = false;
         }
         }
       }
       }
 
 

+ 4 - 4
src/views/chartRelevance_manage/list.vue → src/views/chartRelevance_manage/relevance/list.vue

@@ -302,7 +302,7 @@
 
 
 <script>
 <script>
 import chartRelevanceApi from "@/api/modules/chartRelevanceApi.js";
 import chartRelevanceApi from "@/api/modules/chartRelevanceApi.js";
-import leftMixin from "./mixins/classifyMixin";
+import leftMixin from "../mixins/classifyMixin";
 import Chart from "@/views/dataEntry_manage/components/chart";
 import Chart from "@/views/dataEntry_manage/components/chart";
 import changeLang from "@/views/dataEntry_manage/components/changeLang.vue";
 import changeLang from "@/views/dataEntry_manage/components/changeLang.vue";
 import classifyDia from "@/views/datasheet_manage/components/sheetClassifyDia.vue";
 import classifyDia from "@/views/datasheet_manage/components/sheetClassifyDia.vue";
@@ -745,10 +745,10 @@ export default {
   },
   },
 };
 };
 </script>
 </script>
-<style lang='scss' scoped>
-@import './css/index.scss';
+<style lang="scss" scoped>
+@import '../css/index.scss';
 </style>
 </style>
 
 
 <style lang="scss">
 <style lang="scss">
-@import './css/pub.scss';
+@import '../css/pub.scss';
 </style>
 </style>

+ 5 - 5
src/views/chartRelevance_manage/relevanceChartEditor.vue → src/views/chartRelevance_manage/relevance/relevanceChartEditor.vue

@@ -373,12 +373,12 @@ import { dataBaseInterface } from '@/api/api.js';
 import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
 import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
 import {yearSelector} from '@/utils/defaultOptions';
 import {yearSelector} from '@/utils/defaultOptions';
 import chartRelevanceApi from '@/api/modules/chartRelevanceApi';
 import chartRelevanceApi from '@/api/modules/chartRelevanceApi';
-import selectTarget from './components/selectTarget.vue'
-import chartCard from './components/chartCard.vue';
+import selectTarget from '../components/selectTarget.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 saveEdbToBase from './components/saveEdbToBaseDia.vue'
-import ExplainDialog from './components/explainDialog.vue';
+import saveChartToBase from '../components/saveChartTobaseDia.vue';
+import saveEdbToBase from '../components/saveEdbToBaseDia.vue'
+import ExplainDialog from '../components/explainDialog.vue';
 export default {
 export default {
   components: { selectTarget, chartCard, SaveChartOther, saveChartToBase, saveEdbToBase, ExplainDialog },
   components: { selectTarget, chartCard, SaveChartOther, saveChartToBase, saveEdbToBase, ExplainDialog },
   directives: {
   directives: {

+ 5 - 5
src/views/chartRelevance_manage/statisticFeatureChartEditor.vue → src/views/chartRelevance_manage/statistic/statisticFeatureChartEditor.vue

@@ -289,12 +289,12 @@ import { dataBaseInterface } from '@/api/api.js';
 import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
 import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
 import {yearSelector} from '@/utils/defaultOptions';
 import {yearSelector} from '@/utils/defaultOptions';
 import {statisticFeatureInterface} from '@/api/modules/chartRelevanceApi';
 import {statisticFeatureInterface} from '@/api/modules/chartRelevanceApi';
-import selectTarget from './components/selectTarget.vue'
-import chartCard from './components/chartCard.vue';
+import selectTarget from '../components/selectTarget.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 saveEdbToBase from './components/saveEdbToBaseDia.vue';
-import ExplainDialog from './components/explainDialog.vue';
+import saveChartToBase from '../components/saveChartTobaseDia.vue';
+import saveEdbToBase from '../components/saveEdbToBaseDia.vue';
+import ExplainDialog from '../components/explainDialog.vue';
 export default {
 export default {
   components: { selectTarget,chartCard,SaveChartOther,saveChartToBase,saveEdbToBase,ExplainDialog },
   components: { selectTarget,chartCard,SaveChartOther,saveChartToBase,saveEdbToBase,ExplainDialog },
   directives: {
   directives: {

+ 3 - 3
src/views/chartRelevance_manage/statisticFeatureList.vue → src/views/chartRelevance_manage/statistic/statisticFeatureList.vue

@@ -229,7 +229,7 @@
 <script>
 <script>
 
 
 import { statisticFeatureInterface } from '@/api/modules/chartRelevanceApi';
 import { statisticFeatureInterface } from '@/api/modules/chartRelevanceApi';
-import leftMixin from './mixins/classifyMixin';
+import leftMixin from '../mixins/classifyMixin';
 import Chart from '@/views/dataEntry_manage/components/chart';
 import Chart from '@/views/dataEntry_manage/components/chart';
 import classifyDia from '@/views/datasheet_manage/components/sheetClassifyDia.vue';
 import classifyDia from '@/views/datasheet_manage/components/sheetClassifyDia.vue';
 import addMyClassifyDia from '@/views/dataEntry_manage/components/addMyClassifyDia';
 import addMyClassifyDia from '@/views/dataEntry_manage/components/addMyClassifyDia';
@@ -602,9 +602,9 @@ export default {
 }
 }
 </script>
 </script>
 <style lang='scss' scoped>
 <style lang='scss' scoped>
-@import './css/index.scss';
+@import '../css/index.scss';
 </style>
 </style>
 
 
 <style lang="scss">
 <style lang="scss">
-@import './css/pub.scss';
+@import '../css/pub.scss';
 </style>
 </style>

+ 2 - 1
src/views/dataEntry_manage/addChart.vue

@@ -172,6 +172,7 @@
 					></el-date-picker>
 					></el-date-picker>
 					<el-checkbox label="跨年" v-model="isSpanYear" :disabled="isSpanYearDisable"
 					<el-checkbox label="跨年" v-model="isSpanYear" :disabled="isSpanYearDisable"
 					style="margin-top: 12px;" @change="changeIsSpanYear"></el-checkbox>
 					style="margin-top: 12px;" @change="changeIsSpanYear"></el-checkbox>
+					<br />
 					<div class="legend-set-text" @click="openLegendEditDia">
 					<div class="legend-set-text" @click="openLegendEditDia">
 						<span>图例名称设置</span>
 						<span>图例名称设置</span>
 						<img src="~@/assets/img/icons/edit-blue.png" />
 						<img src="~@/assets/img/icons/edit-blue.png" />
@@ -881,7 +882,7 @@ export default {
 				.legend-set-text{
 				.legend-set-text{
 					font-size: 15px;
 					font-size: 15px;
 					color: #1B7BDE;
 					color: #1B7BDE;
-					display: flex;
+					display: inline-flex;
 					align-items: center;
 					align-items: center;
 					justify-content: flex-start;
 					justify-content: flex-start;
 					margin-top: 20px;
 					margin-top: 20px;

+ 8 - 2
src/views/dataEntry_manage/components/LegendEditDia.vue

@@ -48,8 +48,14 @@ data () {
   };
   };
 },
 },
 watch: {
 watch: {
-  isEditLegend(val) {
-    if(val) {
+  // isEditLegend(val) {
+  //   if(val) {
+  //     // 数据没加载出来时 打开弹窗 legendListCopy 会为空
+  //     this.legendListCopy = _.cloneDeep(this.legendList)
+  //   }
+  // },
+  legendList(val){
+    if(val){
       this.legendListCopy = _.cloneDeep(this.legendList)
       this.legendListCopy = _.cloneDeep(this.legendList)
     }
     }
   }
   }

+ 8 - 2
src/views/dataEntry_manage/components/SaveChartOther.vue

@@ -25,7 +25,7 @@
           clearable
           clearable
         />
         />
       </el-form-item>
       </el-form-item>
-      <el-form-item label="图表分类" prop="classify">
+      <el-form-item label="图表分类" prop="classify" v-if="![10,'cross_variety'].includes(this.source)">
         <el-cascader
         <el-cascader
           v-model="form.classify"
           v-model="form.classify"
           :options="classifyOptions"
           :options="classifyOptions"
@@ -53,7 +53,7 @@
 import { dataBaseInterface } from '@/api/api.js';
 import { dataBaseInterface } from '@/api/api.js';
 import futuresInterface from '@/api/modules/futuresBaseApi';
 import futuresInterface from '@/api/modules/futuresBaseApi';
 import chartRelevanceApi from '@/api/modules/chartRelevanceApi.js';
 import chartRelevanceApi from '@/api/modules/chartRelevanceApi.js';
-import { fittingEquationInterface,statisticFeatureInterface } from '@/api/modules/chartRelevanceApi';
+import { fittingEquationInterface,statisticFeatureInterface,crossVarietyInterface } from '@/api/modules/chartRelevanceApi';
 export default {
 export default {
   props: {
   props: {
     show: Boolean,
     show: Boolean,
@@ -114,6 +114,8 @@ export default {
         res=await fittingEquationInterface.classifyList()
         res=await fittingEquationInterface.classifyList()
       }else if([7,8,9,'statistic_feature'].includes(this.source)) { //标准差 百分位 频率图
       }else if([7,8,9,'statistic_feature'].includes(this.source)) { //标准差 百分位 频率图
         res=await statisticFeatureInterface.classifyList()
         res=await statisticFeatureInterface.classifyList()
+      }else if([10,'cross_variety'].includes(this.source)) { //跨品种分析
+        res = await crossVarietyInterface.classifyList();
       }else{
       }else{
         res=await dataBaseInterface.chartClassify();
         res=await dataBaseInterface.chartClassify();
       }
       }
@@ -128,6 +130,8 @@ export default {
         this.filterNodes(res.Data.AllNodes,1)
         this.filterNodes(res.Data.AllNodes,1)
       }else if([7,8,9,'statistic_feature'].includes(this.source)) { //标准差 百分位 频率图
       }else if([7,8,9,'statistic_feature'].includes(this.source)) { //标准差 百分位 频率图
         this.filterNodes(res.Data.AllNodes,1)
         this.filterNodes(res.Data.AllNodes,1)
+      }else if([10,'cross_variety'].includes(this.source)) { //
+        this.filterNodes(res.Data.AllNodes,1)
       }else{
       }else{
         this.filterNodes(res.Data.AllNodes,3)
         this.filterNodes(res.Data.AllNodes,3)
       }
       }
@@ -163,6 +167,8 @@ export default {
         res=await fittingEquationInterface.saveOtherChart(params)
         res=await fittingEquationInterface.saveOtherChart(params)
       }else if([7,8,9,'statistic_feature'].includes(this.source)) { //标准差 百分位 频率图
       }else if([7,8,9,'statistic_feature'].includes(this.source)) { //标准差 百分位 频率图
         res=await statisticFeatureInterface.saveOtherChart(params)
         res=await statisticFeatureInterface.saveOtherChart(params)
+      }else if([10,'cross_variety'].includes(this.source)) { //跨品种分析
+        res = await crossVarietyInterface.saveOtherChart(params);
       }else{
       }else{
         res=await dataBaseInterface.saveChartOther(params)
         res=await dataBaseInterface.saveChartOther(params)
       }
       }

+ 46 - 12
src/views/dataEntry_manage/components/setEnNameDia.vue

@@ -1,6 +1,14 @@
 <template>
 <template>
-  <el-dialog title="英文名称" :visible.sync="isOpenDialog" :close-on-click-modal="false" :modal-append-to-body='false'
-       @close="cancel" custom-class="dialog" width="800px" v-dialogDrag>
+  <el-dialog 
+    title="英文名称" 
+    :visible.sync="isOpenDialog" 
+    :close-on-click-modal="false" 
+    :modal-append-to-body='false'
+    @close="cancel" 
+    custom-class="set-en-dialog" 
+    width="800px" 
+    v-dialogDrag
+  >
       <el-form v-if="cType=='chart'" style="padding:0 40px" label-width="140px">
       <el-form v-if="cType=='chart'" style="padding:0 40px" label-width="140px">
         <!-- 截面散点图 -->
         <!-- 截面散点图 -->
         <div class="set-en-name-box" v-if="chartType===10">
         <div class="set-en-name-box" v-if="chartType===10">
@@ -74,21 +82,17 @@
             </el-collapse-item>
             </el-collapse-item>
           </el-collapse>
           </el-collapse>
         </div>
         </div>
-				<el-form-item style="text-align: center;margin-top: 30px;">
-					<el-button type="primary" @click="saveEnName">保存</el-button>
-					<el-button @click="cancel">取消</el-button>
-				</el-form-item>
 			</el-form>
 			</el-form>
 			<el-form v-else label-width="110px" >
 			<el-form v-else label-width="110px" >
 				<el-form-item :label="item.label+':'" :prop="item.key" v-for="item in copyFormData" :key="item.key">
 				<el-form-item :label="item.label+':'" :prop="item.key" v-for="item in copyFormData" :key="item.key">
 					<span v-show="item.notEdit">{{item.value}}</span>
 					<span v-show="item.notEdit">{{item.value}}</span>
           <el-input v-show="!item.notEdit" v-model="item.value" :placeholder="item.placeholder" style="width: 100%;"></el-input>
           <el-input v-show="!item.notEdit" v-model="item.value" :placeholder="item.placeholder" style="width: 100%;"></el-input>
 				</el-form-item>
 				</el-form-item>
-				<el-form-item style="text-align: center;margin-left:-110px">
-					<el-button @click="cancel">取消</el-button>
-					<el-button type="primary" @click="saveEnName">确定</el-button>
-				</el-form-item>
 			</el-form>
 			</el-form>
+      <div class="btn-bottom">
+        <el-button type="primary" @click="saveEnName" style="margin-right:20px">确定</el-button>
+        <el-button @click="cancel">取消</el-button>
+      </div>
 		</el-dialog>
 		</el-dialog>
 </template>
 </template>
 <script>
 <script>
@@ -185,8 +189,29 @@ export default {
       this.$emit('updateEnName',params)
       this.$emit('updateEnName',params)
     },
     },
 
 
+    /* 跨品种分析参数设置 */
+    setCrossVarietyEn() {
+      console.log(this.copyFormData)
+      const { chartInfo,chartsList }  = this.copyFormData;
+      let params = {
+        ChartInfoId: chartInfo[1].id,
+        ChartNameEn: chartInfo[1].value.trim(),
+        TagList: [
+          { ChartTagId: chartInfo[3].id,TagNameEn: chartInfo[3].value },
+          { ChartTagId: chartInfo[5].id,TagNameEn: chartInfo[5].value }
+        ],
+        VarietyList: chartsList.map(_ => ({
+          ChartVarietyId: _[1].id,
+          VarietyNameEn: _[1].value
+        }))
+      }
+      this.$emit('updateEnName',params)
+    },
+
     saveEnName(){
     saveEnName(){
       if(this.cType === 'chart'&&this.chartType === 10) return this.setSectionScatterEn();
       if(this.cType === 'chart'&&this.chartType === 10) return this.setSectionScatterEn();
+      else if(this.cType === 'chart'&&this.copyFormData.chartInfo[0].source === 10) return this.setCrossVarietyEn();
+
       if(JSON.stringify(this.copyFormData) === JSON.stringify(this.formData)){
       if(JSON.stringify(this.copyFormData) === JSON.stringify(this.formData)){
         // 没有修改过
         // 没有修改过
         this.$emit('cancel')
         this.$emit('cancel')
@@ -230,9 +255,13 @@ export default {
 }
 }
 </script>
 </script>
 <style lang="scss">
 <style lang="scss">
+.set-en-dialog {
+  .el-dialog__body {
+    max-height:600px;
+    overflow-y:auto;
+  }
+}
 .set-en-name-box{
 .set-en-name-box{
-  max-height:600px;
-  overflow-y:auto;
   .el-collapse-item__header{
   .el-collapse-item__header{
     background-color:#DCDFE6;
     background-color:#DCDFE6;
     padding-left:8px;
     padding-left:8px;
@@ -275,4 +304,9 @@ export default {
       .el-input {  min-width: 240px;}
       .el-input {  min-width: 240px;}
     }
     }
   }
   }
+  .btn-bottom {
+    display: flex;
+    margin: 40px 0;
+    justify-content: center;
+  }
 </style>
 </style>

+ 97 - 104
src/views/dataEntry_manage/databaseComponents/addTargetDiaBase.vue

@@ -15,8 +15,8 @@
 							<el-option v-for="item in fromArr" :key="item" :label="item" :value="item">
 							<el-option v-for="item in fromArr" :key="item" :label="item" :value="item">
 							</el-option>
 							</el-option>
 						</el-select>
 						</el-select>
-						<el-select v-model="fromDatabase" placeholder="请选择数据库" style="width:240px;margin-left:10px" @change="changeDatabase"
-							:disabled="haveResult" v-if="fromType=='wind'">
+						<el-select v-model="fromDatabase" placeholder="请选择数据库" style="width:240px;margin-left:10px"
+							:disabled="haveResult" v-if="hasDateSequence">
 							<el-option v-for="item in databaseType" :key="item.value" :label="item.label" :value="item.value">
 							<el-option v-for="item in databaseType" :key="item.value" :label="item.label" :value="item.value">
 							</el-option>
 							</el-option>
 						</el-select>
 						</el-select>
@@ -26,32 +26,34 @@
 						<i slot="prefix" class="el-input__icon el-icon-search"></i>
 						<i slot="prefix" class="el-input__icon el-icon-search"></i>
 					</el-input>
 					</el-input>
 
 
-					<el-input placeholder="指标ID" v-model="search_txt" style="maxWidth:300px" v-if="!(this.fromType=='wind' && this.fromDatabase=='1')"
+					<el-input placeholder="指标ID" v-model="search_txt" style="maxWidth:300px" v-if="!(hasDateSequence && fromDatabase=='1')"
 						@keyup.enter.native="searchHandle" :disabled="haveResult" clearable>
 						@keyup.enter.native="searchHandle" :disabled="haveResult" clearable>
 						<i slot="prefix" class="el-input__icon el-icon-search"></i>
 						<i slot="prefix" class="el-input__icon el-icon-search"></i>
 					</el-input>
 					</el-input>
 				</div>
 				</div>
-				<div v-if="this.fromType=='wind' && this.fromDatabase=='1'">
+				<div v-if="hasDateSequence && fromDatabase=='1'">
 					<div class="wsd-index-box">
 					<div class="wsd-index-box">
 						<el-input placeholder="请输入证券代码,每次只查询一个证券代码" v-model.trim="securityCodeText" class="wsd-index-input" 
 						<el-input placeholder="请输入证券代码,每次只查询一个证券代码" v-model.trim="securityCodeText" class="wsd-index-input" 
 						@blur="codeInputBlur('security')" style="margin-bottom: 20px;"></el-input>
 						@blur="codeInputBlur('security')" style="margin-bottom: 20px;"></el-input>
-						<!-- <div class="wsd-code-row">
-							<div class="wsd-code-item" v-for="item in securityCode" :key="item">
-								<div class="wsd-code-item-text">{{ item }}</div>
-								<img src="~@/assets/img/icons/close_icon_black.png" @click="deleteCode('security',item)" />
-							</div>
-						</div> -->
 						<div class="wsd-index-code">
 						<div class="wsd-index-code">
-							<el-input placeholder="请输入指标代码,多个指标代码用英文逗号分隔" v-model.trim="indexCodeText" class="wsd-index-input" @blur="codeInputBlur('index')"></el-input>
-							<div class="index-code-hint">Wind金融终端输入“CG”会弹出代码生成器,可在代码生成器上获取其他指标的代码</div>
+							<el-input placeholder="请输入指标代码,多个指标代码用英文逗号分隔" v-model.trim="indexCodeText" 
+							class="wsd-index-input" @blur="codeInputBlur('index')"></el-input>
+							<div class="index-code-hint">
+								{{ indexCodeHintText }}
+							</div>
 						</div>
 						</div>
+						<el-select v-model="THSIndexCodeType" placeholder="请选择常用指标类型" v-if="fromType=='同花顺'"
+						@change="THSIndexCodeTypeChange" style="margin-bottom: 15px;" class="wsd-index-input">
+							<el-option :label="item.label" :value="item.value" 
+							v-for="item in THSIndexCodeTypeArr" :key="item.value"></el-option>
+						</el-select>
 						<el-checkbox-group v-model="indexCodeSelected">
 						<el-checkbox-group v-model="indexCodeSelected">
 							<el-checkbox :label="item.value" v-for="item in indexCodeArr" :key="item.value">{{ item.label }}</el-checkbox>
 							<el-checkbox :label="item.value" v-for="item in indexCodeArr" :key="item.value">{{ item.label }}</el-checkbox>
 						</el-checkbox-group>
 						</el-checkbox-group>
 						<div class="wsd-code-row" style="margin-top: -10px;">
 						<div class="wsd-code-row" style="margin-top: -10px;">
 							<div class="wsd-code-item" v-for="item in indexCode" :key="item">
 							<div class="wsd-code-item" v-for="item in indexCode" :key="item">
 								<div class="wsd-code-item-text">{{ item }}</div>
 								<div class="wsd-code-item-text">{{ item }}</div>
-								<img src="~@/assets/img/icons/close_icon_black.png" @click="deleteCode('index',item)" />
+								<img src="~@/assets/img/icons/close_icon_black.png" @click="deleteCode(item)" />
 							</div>
 							</div>
 						</div>
 						</div>
 					</div>
 					</div>
@@ -110,7 +112,8 @@
                 <td class="sticky" style="left: 0;text-align: center;">
                 <td class="sticky" style="left: 0;text-align: center;">
                   {{ edbTableHeadData.get(item) }}
                   {{ edbTableHeadData.get(item) }}
                 </td>
                 </td>
-                <td v-for="(data, sub_index) in edbIndexDatas" :key="sub_index" :colspan="2">
+                <td v-for="(data, sub_index) in edbIndexDatas" :key="sub_index" :colspan="2" 
+								:class="highLightIndex.includes(data.EdbName) && item=='EdbName' ?'exist-highlight':''">
 									<template v-if="item === 'ClassifyId'">
 									<template v-if="item === 'ClassifyId'">
 										<el-cascader :options="options" v-model="data[item]" placeholder="请选择所属目录"
 										<el-cascader :options="options" v-model="data[item]" placeholder="请选择所属目录"
 										size="mini" :disabled="!data.Source"
 										size="mini" :disabled="!data.Source"
@@ -172,8 +175,8 @@
 			<div class="check-fail-box">
 			<div class="check-fail-box">
 				<div>
 				<div>
 					<div style="margin-bottom: 20px;">指标库中已存在以下指标,请勿重新输入!</div>
 					<div style="margin-bottom: 20px;">指标库中已存在以下指标,请勿重新输入!</div>
-					<div v-for="(item,index) in existIndexList">
-						{{ index+1+'、'+item }}
+					<div v-for="(item,index) in existIndexList" class="exist-index-item" @click="existIndexClick(item)">
+						{{ index+1+'、'+item.text }}
 					</div>
 					</div>
 				</div>
 				</div>
 				<div class="check-fail-button">
 				<div class="check-fail-button">
@@ -186,7 +189,7 @@
 
 
 <script>
 <script>
 import { dataBaseInterface,dataInterence } from '@/api/api.js'
 import { dataBaseInterface,dataInterence } from '@/api/api.js'
-import { fromArr, fromCode ,frequencyArr} from './util';
+import { fromArr, fromCode ,frequencyArr,windCommonIndexCodeArr,THSCommonIndexStockCodeArr,THSCommonIndexFuturesCodeArr} from './util';
 export default {
 export default {
 	name: '',
 	name: '',
 	props: {
 	props: {
@@ -196,33 +199,44 @@ export default {
 	},
 	},
 	computed:{
 	computed:{
 		isCodeComplete(){
 		isCodeComplete(){
-			// return this.securityCode.length>0 && (this.indexCode.length>0 || this.indexCodeSelected.length>0)
 			return this.securityCodeText && (this.indexCode.length>0 || this.indexCodeSelected.length>0)
 			return this.securityCodeText && (this.indexCode.length>0 || this.indexCodeSelected.length>0)
-			
+		},
+		hasDateSequence(){
+			return ["wind","同花顺"].includes(this.fromType)
+		},
+		// 常用的指标代码
+		indexCodeArr(){
+			if(this.fromType=='wind'){
+				return windCommonIndexCodeArr
+			}else if(this.fromType=='同花顺'){
+				if(this.THSIndexCodeType==1){
+					//期货常用
+					return THSCommonIndexFuturesCodeArr
+				}else{
+					//股票常用
+					return THSCommonIndexStockCodeArr
+				}
+			}
+		},
+		indexCodeHintText(){
+			if(this.fromType=='wind'){
+				return 'Wind金融终端输入“CG”会弹出代码生成器,可在代码生成器上获取其他指标的代码'
+			}else if(this.fromType=='同花顺'){
+				return '可用Excel同花顺插件/日期序列功能,根据所选指标获取指标代码,期货和股票常用代码可在下方勾选'
+			}
 		}
 		}
 	},
 	},
 	data() {
 	data() {
+		this.prefixMap=new Map([
+			["wind","wsd"],
+			["同花顺","thsds"]
+		])
 		return {
 		return {
 			search_txt: '',//搜素关键词 M001625518 M0001427
 			search_txt: '',//搜素关键词 M001625518 M0001427
 			fromType: 'wind',
 			fromType: 'wind',
 			fromDatabase:'0',
 			fromDatabase:'0',
 			fromArr,
 			fromArr,
 			indexCodeSelected:[],
 			indexCodeSelected:[],
-			indexCodeArr:[
-				{value:'pre_close',label:"前收盘价"},
-				{value:'open',label:"开盘价"},
-				{value:'high',label:"最高价"},
-				{value:'low',label:"最低价"},
-				{value:'close',label:"收盘价"},
-				{value:'settle',label:"结算价"},
-				{value:'volume',label:"成交量"},
-				{value:'amt',label:"成交额"},
-				{value:'pct_chg',label:"涨跌幅"},
-				{value:'swing',label:"振幅"},
-				{value:'turn',label:"换手率"},
-				{value:'oi',label:"持仓量"},
-				{value:'oiamount',label:"持仓额"},
-			], // 常用的指标代码
 			databaseType:[
 			databaseType:[
 				{value:'0',label:'经济数据库'},
 				{value:'0',label:'经济数据库'},
 				{value:'1',label:'日期序列'}
 				{value:'1',label:'日期序列'}
@@ -255,35 +269,9 @@ export default {
 			isCompanyCode: false,
 			isCompanyCode: false,
 			search_company_txt: '',
 			search_company_txt: '',
 			securityCodeText:"",
 			securityCodeText:"",
-			// securityCode:[],
 			indexCodeText:'',
 			indexCodeText:'',
 			indexCode:[],
 			indexCode:[],
-			edbIndexDatas:[
-				// {Source:1,Catalogue:'',Unit:"",Frequency:'日度',SecName:'CU2403收盘价',SecurityCode:'CU2403.SHF',IndexCode:'close',
-				// DataList:[{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},
-				// {Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},
-				// {Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"}]},
-				// {Catalogue:'',Unit:"",Frequency:'日度',SecName:'CU2403收盘价',SecurityCode:'CU2403.SHF',IndexCode:'close',
-				// DataList:[{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},
-				// {Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},
-				// {Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"}]},
-				// {Catalogue:'',Unit:"",Frequency:'日度',SecName:'CU2403收盘价',SecurityCode:'CU2403.SHF',IndexCode:'close',
-				// DataList:[{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},
-				// {Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},
-				// {Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"}]},
-				// {Catalogue:'',Unit:"",Frequency:'日度',SecName:'CU2403收盘价',SecurityCode:'CU2403.SHF',IndexCode:'close',
-				// DataList:[{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},
-				// {Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},
-				// {Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"}]},
-				// {Catalogue:'',Unit:"",Frequency:'日度',SecName:'CU2403收盘价',SecurityCode:'CU2403.SHF',IndexCode:'close',
-				// DataList:[{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},
-				// {Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},
-				// {Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"}]},
-				// {Catalogue:'',Unit:"",Frequency:'日度',SecName:'CU2403收盘价',SecurityCode:'CU2403.SHF',IndexCode:'close',
-				// DataList:[{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},
-				// {Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},
-				// {Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"},{Close: "632107.0000",Dt: "2023-09-07"}]}
-			],
+			edbIndexDatas:[],
 			edbTableHeadKey: [
 			edbTableHeadKey: [
         "ClassifyId",
         "ClassifyId",
         "Unit",
         "Unit",
@@ -306,7 +294,14 @@ export default {
 			frequencyArr,
 			frequencyArr,
 			checkFailShow:false,
 			checkFailShow:false,
 			existIndexList:[],
 			existIndexList:[],
-			isLoadingData:false
+			isLoadingData:false,
+			highLightIndex:[],
+			// 同花顺常用指标类型
+			THSIndexCodeType:1,
+			THSIndexCodeTypeArr:[
+				{value:1,label:"期货常用指标"},
+				{value:2,label:"股票常用指标"}
+			]
 		};
 		};
 	},
 	},
 	watch:{
 	watch:{
@@ -322,7 +317,6 @@ export default {
 		init() {
 		init() {
 			this.fromType = 'wind'
 			this.fromType = 'wind'
 			this.fromDatabase='0'
 			this.fromDatabase='0'
-			this.wsdAddStep=1
 			this.status = ''
 			this.status = ''
 			this.tableData = []
 			this.tableData = []
 			this.dataList = []
 			this.dataList = []
@@ -330,6 +324,12 @@ export default {
 			this.search_txt = '';
 			this.search_txt = '';
 			this.haveResult = false;
 			this.haveResult = false;
 			this.search_company_txt = '';
 			this.search_company_txt = '';
+			this.wsdAddStep=1
+			this.securityCodeText=""
+			this.indexCodeText=''
+			this.indexCode=[]
+			this.indexCodeSelected=[]
+			this.THSIndexCodeType=1
 			this.isCompanyCode = false;
 			this.isCompanyCode = false;
 		},
 		},
 		cancelHandle() {
 		cancelHandle() {
@@ -434,18 +434,18 @@ export default {
 				this.isCompanyCode = false;
 				this.isCompanyCode = false;
 			}
 			}
 			if(this.fromDatabase=='1'){
 			if(this.fromDatabase=='1'){
-				this.changeDatabase('0')
+				this.fromDatabase='0'
+				this.securityCodeText=""
+				this.indexCodeText=''
+				this.indexCode=[]
+				this.indexCodeSelected=[]
+				this.THSIndexCodeType=1
 			}
 			}
 			this.search_txt = '';
 			this.search_txt = '';
 			this.search_company_txt = '';
 			this.search_company_txt = '';
 			this.loading && this.loading.close();
 			this.loading && this.loading.close();
 		},
 		},
-		changeDatabase(e){
-			this.fromDatabase=e
-			this.securityCodeText=""
-			// this.securityCode=[]
-			this.indexCodeText=''
-			this.indexCode=[]
+		THSIndexCodeTypeChange(){
 			this.indexCodeSelected=[]
 			this.indexCodeSelected=[]
 		},
 		},
 		getTargetSource(){
 		getTargetSource(){
@@ -466,18 +466,6 @@ export default {
 		codeInputBlur(type){
 		codeInputBlur(type){
 			if(type == 'security'){
 			if(type == 'security'){
 				this.securityCodeText=this.securityCodeText.replaceAll(' ','')
 				this.securityCodeText=this.securityCodeText.replaceAll(' ','')
-				// if(!this.securityCodeText) return  
-				// if(!(this.securityCode.length<5)){
-				// 	this.$message.warning('证券代码一次最多输入5个')
-				// 	this.securityCodeText=''
-				// 	return
-				// }
-				// this.securityCode=Array.from(new Set([...this.securityCode,...this.securityCodeText.split(',')])).filter(Boolean)
-				// if(this.securityCode.length>5){
-				// 	this.securityCode = this.securityCode.slice(0,5)
-				// 	this.$message.warning('证券代码一次最多输入5个')
-				// }
-				// this.securityCodeText=''
 			}else if(type == 'index'){
 			}else if(type == 'index'){
 				if(!this.indexCodeText) return  
 				if(!this.indexCodeText) return  
 				this.indexCodeText=this.indexCodeText.replaceAll(' ','')
 				this.indexCodeText=this.indexCodeText.replaceAll(' ','')
@@ -487,12 +475,8 @@ export default {
 			}
 			}
 
 
 		},
 		},
-		deleteCode(type,code){
-			if(type == 'security'){
-				// this.securityCode = this.securityCode.filter(it => it!=code)
-			}else if(type == 'index'){
-				this.indexCode = this.indexCode.filter(it => it!=code)
-			}
+		deleteCode(code){
+			this.indexCode = this.indexCode.filter(it => it!=code)
 		},
 		},
 		/* 获取目录结构 */
 		/* 获取目录结构 */
 		getMenu() {
 		getMenu() {
@@ -535,28 +519,21 @@ export default {
 						Source:Number(this.fromCode.get(this.fromType)),
 						Source:Number(this.fromCode.get(this.fromType)),
 						SubSource:this.fromDatabase,
 						SubSource:this.fromDatabase,
 						EdbCode:Array.from(new Set([...this.indexCode,...this.indexCodeSelected])).join(','),
 						EdbCode:Array.from(new Set([...this.indexCode,...this.indexCodeSelected])).join(','),
-						// StockCode:this.securityCode.join(',')
 						StockCode:this.securityCodeText
 						StockCode:this.securityCodeText
 					}
 					}
 					dataBaseInterface.edbExistCheck(params).then(res=>{
 					dataBaseInterface.edbExistCheck(params).then(res=>{
 						if(res.Ret == 200){
 						if(res.Ret == 200){
+							// console.log(res,'res');
+							// return 
 							if(res.Data.IndexExist){
 							if(res.Data.IndexExist){
 								// 有重复
 								// 有重复
 								this.existIndexList=[]
 								this.existIndexList=[]
-								let ExistEdbCodeArr=res.Data.ExistEdbCodeArr
-								// let ExistStockCodeArr=res.Data.ExistStockCodeArr
+								let existEdbInfo=res.Data.ExistEdbInfo || []
 								let text=''
 								let text=''
-								// ExistStockCodeArr.map(item =>{
-									Array.from(new Set(ExistEdbCodeArr)).map(item1 =>{
-										let isCommon = this.indexCodeArr.find(it => it.value == item1)
-										if(isCommon){
-											text=`${this.securityCodeText}${isCommon.label}(wsd${this.securityCodeText}${isCommon.value})`
-										}else{
-											text=`${this.securityCodeText}${item1}(wsd${this.securityCodeText}${item1})`
-										}
-										this.existIndexList.push(text)
-									})
-								// })
+								existEdbInfo.map(item =>{
+									text=`${item.EdbName}(${item.EdbCode})`
+									this.existIndexList.push({text,code:item.UniqueCode,id:item.EdbInfoId,classifyId:item.ClassifyId})
+								})
 								this.checkFailShow=true
 								this.checkFailShow=true
 							}else{
 							}else{
 								// 没有重复
 								// 没有重复
@@ -614,6 +591,10 @@ export default {
 				}
 				}
 			},50)
 			},50)
 		},
 		},
+		existIndexClick({code,id,classifyId}){
+			const { href } = this.$router.resolve({ path: '/database',query:{code,id,classifyId}});
+			window.open(href, '_blank');
+		},
 		wsdPrevHandle(){
 		wsdPrevHandle(){
 			this.wsdAddStep=1
 			this.wsdAddStep=1
 		},
 		},
@@ -638,6 +619,8 @@ export default {
 					this.$message.success("添加指标成功")
 					this.$message.success("添加指标成功")
 					this.$emit('addSuccessHandle',{ code:res.Data.UniqueCode,id:res.Data.EdbInfoId,classifyId:res.Data.ClassifyId })	
 					this.$emit('addSuccessHandle',{ code:res.Data.UniqueCode,id:res.Data.EdbInfoId,classifyId:res.Data.ClassifyId })	
 					this.cancelHandle()	
 					this.cancelHandle()	
+				}else if(res.Ret == 403){
+					this.highLightIndex=res.Data?res.Data.ExistEdbName || []:[]
 				}
 				}
 			})
 			})
 		}
 		}
@@ -695,7 +678,7 @@ export default {
 		.wsd-index-code{
 		.wsd-index-code{
 			display: flex;
 			display: flex;
 			align-items: center;
 			align-items: center;
-			margin-bottom: 15px;
+			margin-bottom: 20px;
 			.index-code-hint{
 			.index-code-hint{
 				color: #C0C4CC;
 				color: #C0C4CC;
 				font-size: 15px;
 				font-size: 15px;
@@ -728,7 +711,8 @@ export default {
 			}
 			}
 		}
 		}
 		.wsd-index-input{
 		.wsd-index-input{
-			width: 400px;
+			min-width: 400px;
+			width:400px;
 			margin-right: 10px;
 			margin-right: 10px;
 		}
 		}
 	}
 	}
@@ -806,10 +790,19 @@ export default {
       border-top: 1px solid #dcdfe6;
       border-top: 1px solid #dcdfe6;
       border-left: 1px solid #dcdfe6;
       border-left: 1px solid #dcdfe6;
     }
     }
+		.exist-highlight{
+			border: red solid 1px;
+		}
 	}
 	}
 	.check-fail-box{
 	.check-fail-box{
 		padding: 0 0 15px 40px;	
 		padding: 0 0 15px 40px;	
 		color: #333333;
 		color: #333333;
+		.exist-index-item{
+			cursor: pointer;
+			&:hover{
+				text-decoration: underline;
+			}
+		}
 		.check-fail-button{
 		.check-fail-button{
 			margin-top: 80px;
 			margin-top: 80px;
 			display: flex;
 			display: flex;

+ 46 - 0
src/views/dataEntry_manage/databaseComponents/util.js

@@ -437,3 +437,49 @@ export const formulaTip = new Map([
 	5、旬度值转日均值=旬度值/对应旬度天数 <br>
 	5、旬度值转日均值=旬度值/对应旬度天数 <br>
 	6、周度值转日均值=周度值/7`]
 	6、周度值转日均值=周度值/7`]
 ])
 ])
+
+// wind 日期序列常见指标代码
+export const windCommonIndexCodeArr=[
+	{value:'pre_close',label:"前收盘价"},
+	{value:'open',label:"开盘价"},
+	{value:'high',label:"最高价"},
+	{value:'low',label:"最低价"},
+	{value:'close',label:"收盘价"},
+	{value:'settle',label:"结算价"},
+	{value:'volume',label:"成交量"},
+	{value:'amt',label:"成交额"},
+	{value:'pct_chg',label:"涨跌幅"},
+	{value:'swing',label:"振幅"},
+	{value:'turn',label:"换手率"},
+	{value:'oi',label:"持仓量"},
+	{value:'oiamount',label:"持仓额"}
+]
+
+// 同花顺 日期序列常见 股票指标代码
+export const THSCommonIndexStockCodeArr=[
+	{value:'ths_pre_close_stock',label:"前收盘价"},
+	{value:'ths_open_price_stock',label:"开盘价"},
+	{value:'ths_high_price_stock',label:"最高价"},
+	{value:'ths_low_stock',label:"最低价"},
+	{value:'ths_close_price_stock',label:"收盘价"},
+	{value:'ths_vol_stock',label:"成交量"},
+	{value:'ths_amt_stock',label:"成交额"},
+	{value:'ths_chg_ratio_stock',label:"涨跌幅"},
+	{value:'ths_swing_stock',label:"振幅"},
+	{value:'ths_turnover_ratio_stock',label:"换手率"},
+]
+
+// 同花顺 日期序列常见 指标代码
+export const THSCommonIndexFuturesCodeArr=[
+	{value:'ths_pre_close_future',label:"前收盘价"},
+	{value:'ths_open_price_future',label:"开盘价"},
+	{value:'ths_high_price_future',label:"最高价"},
+	{value:'ths_low_future',label:"最低价"},
+	{value:'ths_close_price_future',label:"收盘价"},
+	{value:'ths_settle_future',label:"结算价"},
+	{value:'ths_vol_future',label:"成交量"},
+	{value:'ths_amt_future',label:"成交额"},
+	{value:'ths_chg_ratio_future',label:"涨跌幅"},
+	{value:'ths_swing_d_future',label:"日振幅"},
+	{value:'ths_open_interest_future',label:"持仓量"},
+]

+ 2 - 1
src/views/dataEntry_manage/editChart.vue

@@ -173,6 +173,7 @@
 					></el-date-picker>
 					></el-date-picker>
 					<el-checkbox label="跨年" v-model="isSpanYear" :disabled="isSpanYearDisable"
 					<el-checkbox label="跨年" v-model="isSpanYear" :disabled="isSpanYearDisable"
 					style="margin-top: 12px;" @change="changeIsSpanYear"></el-checkbox>
 					style="margin-top: 12px;" @change="changeIsSpanYear"></el-checkbox>
+					<br />
 					<div class="legend-set-text" @click="openLegendEditDia">
 					<div class="legend-set-text" @click="openLegendEditDia">
 						<span>图例名称设置</span>
 						<span>图例名称设置</span>
 						<img src="~@/assets/img/icons/edit-blue.png" />
 						<img src="~@/assets/img/icons/edit-blue.png" />
@@ -951,7 +952,7 @@ export default {
 				.legend-set-text{
 				.legend-set-text{
 					font-size: 15px;
 					font-size: 15px;
 					color: #1B7BDE;
 					color: #1B7BDE;
-					display: flex;
+					display: inline-flex;
 					align-items: center;
 					align-items: center;
 					justify-content: flex-start;
 					justify-content: flex-start;
 					margin-top: 20px;
 					margin-top: 20px;

+ 209 - 14
src/views/dataEntry_manage/mixins/chartPublic.js

@@ -8,7 +8,7 @@ import { dataBaseInterface } from '@/api/api';
 import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
 import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
 import futuresInterface from '@/api/modules/futuresBaseApi';
 import futuresInterface from '@/api/modules/futuresBaseApi';
 import chartRelevanceApi from '@/api/modules/chartRelevanceApi';
 import chartRelevanceApi from '@/api/modules/chartRelevanceApi';
-import { fittingEquationInterface,statisticFeatureInterface } from '@/api/modules/chartRelevanceApi';
+import { fittingEquationInterface,statisticFeatureInterface,crossVarietyInterface } from '@/api/modules/chartRelevanceApi';
 
 
 /* 散点x轴 */
 /* 散点x轴 */
 const scatterXAxis = {
 const scatterXAxis = {
@@ -36,7 +36,19 @@ const basicYAxis = {
   showLastLabel: true,
   showLastLabel: true,
   tickPixelInterval: 50,
   tickPixelInterval: 50,
 }
 }
-
+/**备注一下 越多越乱
+ * @params
+ * Source 1 ; chartType 1曲线 2季节 3面积 4堆积柱 5散点 6组合 7柱形 8截面散点
+ * 2 商品价格
+ * 3 相关性
+ * 4 滚动相关性
+ * 5 商品利润
+ * 6 拟合方程
+ * 7 统计特征/标准差
+ * 8 统计特征/百分位
+ * 9 统计特征/频率
+ * 10 跨品种分析
+ */
 export const chartSetMixin = {
 export const chartSetMixin = {
 	data() {
 	data() {
 		return {
 		return {
@@ -174,6 +186,9 @@ export const chartSetMixin = {
 				XEndDate:"12-31", // 横坐标显示范围-结束
 				XEndDate:"12-31", // 横坐标显示范围-结束
 				JumpYear:0, //是否跨年
 				JumpYear:0, //是否跨年
 			},
 			},
+
+      /* 跨品种分析图 */
+      crossVarietyChartData: {}
 		}
 		}
 	},
 	},
   watch: {
   watch: {
@@ -212,16 +227,17 @@ export const chartSetMixin = {
       //不同图表来源 1eta图 2商品价格图 3相关性图表
       //不同图表来源 1eta图 2商品价格图 3相关性图表
       const sourceMap = {
       const sourceMap = {
         1: this.changeOptions,
         1: this.changeOptions,
-        2: this.changeCommodityOptions,
-        3: this.changeRelevanceOptions,
-        4: this.changeRelevanceOptions,
-        5: this.changeCommodityOptions,
+        2: this.changeCommodityLang,
+        3: this.changeRelevanceLang,
+        4: this.changeRelevanceLang,
+        5: this.changeCommodityLang,
+        // 10: wydgw 
       }
       }
 
 
       sourceMap[this.chartInfo.Source]()
       sourceMap[this.chartInfo.Source]()
 		},
 		},
     // 打开设置英文信息弹窗
     // 打开设置英文信息弹窗
-    openEnNameDia(){
+    async openEnNameDia(){
       this.formItemArray={}
       this.formItemArray={}
       this.formItemArray.chartInfo=[]
       this.formItemArray.chartInfo=[]
       this.formItemArray.chartsList=[]
       this.formItemArray.chartsList=[]
@@ -230,6 +246,7 @@ export const chartSetMixin = {
         value:this.chartInfo.ChartName,
         value:this.chartInfo.ChartName,
         key:'ChartName',
         key:'ChartName',
         id:this.chartInfo.ChartInfoId,
         id:this.chartInfo.ChartInfoId,
+        source: this.chartInfo.Source,
         notEdit:true
         notEdit:true
       },
       },
       {
       {
@@ -239,7 +256,8 @@ export const chartSetMixin = {
         id:this.chartInfo.ChartInfoId,
         id:this.chartInfo.ChartInfoId,
         placeholder:'请输入英文图表名称'
         placeholder:'请输入英文图表名称'
       })
       })
-      if(![3,6,7,8,9].includes(this.chartInfo.Source)){//相关性图表
+
+      if([1,2,5].includes(this.chartInfo.Source)){ //需要设置指标的
         this.tableData.map(item =>{
         this.tableData.map(item =>{
           if(item.Unit){
           if(item.Unit){
             this.formItemArray.chartsList.push([
             this.formItemArray.chartsList.push([
@@ -312,7 +330,7 @@ export const chartSetMixin = {
       }
       }
 
 
       //利润曲线
       //利润曲线
-      if(this.chartInfo.Source===5) {
+      else if(this.chartInfo.Source===5) {
         this.formItemArray.chartInfo.push({
         this.formItemArray.chartInfo.push({
           label:'盘面利润名称',
           label:'盘面利润名称',
           value:this.chartInfo.ProfitName,
           value:this.chartInfo.ProfitName,
@@ -328,6 +346,62 @@ export const chartSetMixin = {
           placeholder:'请输入英文盘面利润名称'
           placeholder:'请输入英文盘面利润名称'
         })
         })
       }
       }
+
+      //跨品种分析
+      else if(this.chartInfo.Source===10) {
+        let { Data } = await crossVarietyInterface.chartLangOption({ChartInfoId: this.chartInfo.ChartInfoId})
+
+        const { TagList,VarietyList } = Data;
+
+        this.formItemArray.chartInfo.push({
+          label:'X轴名称',
+          value:this.crossVarietyChartData.XName,
+          key:'XName',
+          id:TagList[0].ChartTagId,
+          notEdit:true
+        },
+        {
+          label:'英文X轴名称',
+          value:this.crossVarietyChartData.XNameEn,
+          key:'XNameEn',
+          id:TagList[0].ChartTagId,
+          placeholder:'请输入英文X轴名称'
+        },{
+          label:'Y轴名称',
+          value:this.crossVarietyChartData.YName,
+          key:'YName',
+          id:TagList[1].ChartTagId,
+          notEdit:true
+        },
+        {
+          label:'英文Y轴名称',
+          value:this.crossVarietyChartData.YNameEn,
+          key:'YNameEn',
+          id:TagList[1].ChartTagId,
+          placeholder:'请输入英文Y轴名称'
+        })
+
+        VarietyList.forEach(item => {
+          this.formItemArray.chartsList.push([
+            {
+              label:'品种名称',
+              value:item.ChartVarietyName,
+              key:'ChartVarietyName',
+              id:item.ChartVarietyId,
+              notEdit:true
+            },
+            {
+              label:'英文品种名称',
+              value:item.ChartVarietyNameEn,
+              key:'ChartVarietyNameEn',
+              id:item.ChartVarietyId,
+              placeholder:'请输入英文品种名称'
+            }
+          ])
+        })
+      }
+
+
       this.setEnName = true
       this.setEnName = true
     },
     },
     // 更新英文信息
     // 更新英文信息
@@ -358,6 +432,8 @@ export const chartSetMixin = {
           ChartInfoId: enNameData.ChartInfoId,
           ChartInfoId: enNameData.ChartInfoId,
           ChartNameEn: enNameData.ChartNameEn
           ChartNameEn: enNameData.ChartNameEn
         })
         })
+      }else if(this.chartInfo.Source === 10) {//跨品种分析
+        res=await crossVarietyInterface.editChartEn(enNameData)
       }else{
       }else{
         res = await dataBaseInterface.chartInfoEditEn(enNameData)
         res = await dataBaseInterface.chartInfoEditEn(enNameData)
       }
       }
@@ -431,7 +507,7 @@ export const chartSetMixin = {
     },
     },
 
 
     /* 切换商品价格图中英文 */
     /* 切换商品价格图中英文 */
-    changeCommodityOptions() {
+    changeCommodityLang() {
       console.log(this.options)
       console.log(this.options)
         this.options.yAxis.forEach(item => {
         this.options.yAxis.forEach(item => {
           item.title.text = this.currentLang == 'ch' ? item.title.textCh : item.title.textEn
           item.title.text = this.currentLang == 'ch' ? item.title.textCh : item.title.textEn
@@ -447,8 +523,7 @@ export const chartSetMixin = {
     },
     },
 
 
     /* 切换相关性图中英文 */
     /* 切换相关性图中英文 */
-    changeRelevanceOptions(){
-      console.log(this.options)
+    changeRelevanceLang(){
         this.options.yAxis.forEach(item => {
         this.options.yAxis.forEach(item => {
           item.title.text = this.currentLang == 'ch' ? item.title.textCh : item.title.textEn
           item.title.text = this.currentLang == 'ch' ? item.title.textCh : item.title.textEn
         });
         });
@@ -1259,7 +1334,7 @@ export const chartSetMixin = {
         tooltip
         tooltip
       }
       }
 
 
-      this.currentLang==='en' && this.changeCommodityOptions();
+      this.currentLang==='en' && this.changeCommodityLang();
     },
     },
 
 
     /* 处理无效数据为null */
     /* 处理无效数据为null */
@@ -1437,7 +1512,7 @@ export const chartSetMixin = {
       this.rightIndex = -1;
       this.rightIndex = -1;
       this.rightTwoIndex = -1;
       this.rightTwoIndex = -1;
       
       
-      const { DataList,XName,XNameEn,XUnitName,XUnitNameEn,YName,YNameEn,YUnitName,YUnitNameEn } = this.sectionScatterData;
+      const { DataList,XName,XNameEn,YName,YNameEn } = this.sectionScatterData;
       const { min,max,x_min,x_max }  = this.chartLimit;
       const { min,max,x_min,x_max }  = this.chartLimit;
 
 
       //y轴
       //y轴
@@ -1686,6 +1761,123 @@ export const chartSetMixin = {
       this.currentLang=='en' && this.changeOptions()
       this.currentLang=='en' && this.changeOptions()
     },
     },
 
 
+    /* 跨品种分析 */
+    setCrossVarietyChart() {
+      this.leftIndex = -1;
+      this.rightIndex = -1;
+      this.rightTwoIndex = -1;
+      
+      const { min,max,x_min,x_max }  = this.chartLimit;
+
+      const { DataList,XName,YName,XNameEn,YNameEn } = this.crossVarietyChartData;
+
+      //y轴
+      let yAxis = {
+        ...basicYAxis,
+        title: {
+          text: YName,
+          textCh:YName,// 中文
+          textEn:YNameEn||YName,
+          align: 'middle',
+        },
+        opposite: false,
+        reversed: false,
+        min: Number(min),
+        max: Number(max),
+        tickWidth: 1,
+      }
+
+      // x轴
+      let xAxis = {
+        ...scatterXAxis,
+        title: {
+          text: XName,
+          textCh:XName,// 中文
+          textEn:XNameEn || XName,
+          align: 'middle',
+        },
+        min: Number(x_min),
+        max: Number(x_max),
+      }
+
+       //数据列
+      let series = [];
+      DataList.forEach(item => {
+        //数据列
+        let series_item = {
+          data: [],
+          type: 'scatter',
+          name: item.Name,
+          nameCh: item.Name,
+          nameEn: item.NameEn||item.Name,
+          color: item.Color,
+          lineWidth: 0,
+          chartType: 'linear',
+          zIndex:1
+        }
+        item.CoordinatePointData.forEach(_ => {
+          series_item.data.push({x: _.X,y: _.Y,})
+        })
+        series.push(series_item);
+      })
+
+      let edbInfoList = this.tableData;
+      let tooltip = {
+        formatter: function() {
+          let series_obj = DataList.find(_ => _.Name === this.series.name);
+          let ponit_obj = series_obj.CoordinatePointData.find(_ => _.X ===this.x && _.Y===this.y);
+          
+          let xEdbInfo = edbInfoList.find(_ => _.EdbInfoId===ponit_obj.XEdbInfoId);
+          let yEdbInfo = edbInfoList.find(_ => _.EdbInfoId===ponit_obj.YEdbInfoId);
+
+          let str=`<b>${ this.series.name }</b>`;
+          str += `<br><span style="color:${this.color}">\u25CF</span>${xEdbInfo.EdbName}: ${this.x} ${ponit_obj.XDate}<br>`;
+          str += `<span style="color:${this.color}">\u25CF</span>${yEdbInfo.EdbName}: ${this.y} ${ponit_obj.YDate}`;
+
+          return str
+        },
+        formatterCh: function() {
+          let series_obj = DataList.find(_ => _.Name === this.series.name);
+          let ponit_obj = series_obj.CoordinatePointData.find(_ => _.X ===this.x && _.Y===this.y);
+          
+          let xEdbInfo = edbInfoList.find(_ => _.EdbInfoId===ponit_obj.XEdbInfoId);
+          let yEdbInfo = edbInfoList.find(_ => _.EdbInfoId===ponit_obj.YEdbInfoId);
+
+          let str=`<b>${ this.series.name }</b>`;
+          str += `<br><span style="color:${this.color}">\u25CF</span>${xEdbInfo.EdbName}: ${this.x} ${ponit_obj.XDate}<br>`;
+          str += `<span style="color:${this.color}">\u25CF</span>${yEdbInfo.EdbName}: ${this.y} ${ponit_obj.YDate}`;
+
+          return str
+          
+        },
+        formatterEn: function() {
+          let series_obj = DataList.find(_ => _.NameEn === this.series.name);
+          let ponit_obj = series_obj.CoordinatePointData.find(_ => _.X ===this.x && _.Y===this.y);
+          
+          let xEdbInfo = edbInfoList.find(_ => _.EdbInfoId===ponit_obj.XEdbInfoId);
+          let yEdbInfo = edbInfoList.find(_ => _.EdbInfoId===ponit_obj.YEdbInfoId);
+
+          let str=`<b>${ this.series.name }</b>`;
+          str += `<br><span style="color:${this.color}">\u25CF</span>${xEdbInfo.EdbNameEn}: ${this.x} ${ponit_obj.XDate}<br>`;
+          str += `<span style="color:${this.color}">\u25CF</span>${yEdbInfo.EdbNameEn}: ${this.y} ${ponit_obj.YDate}`;
+
+          return str
+        }
+      }
+
+      this.options = {
+        title: {
+          text:''
+        },
+        series,
+        yAxis: [yAxis],
+        xAxis,
+        tooltip
+      }
+      this.currentLang=='en' && this.changeRelevanceLang()
+
+    },
+
 		/* 查询范围为1年内 x轴显示为月/日 否则默认年/月 */
 		/* 查询范围为1年内 x轴显示为月/日 否则默认年/月 */
 		xLabelDealHandle() {
 		xLabelDealHandle() {
 			const end =
 			const end =
@@ -1979,12 +2171,15 @@ export const chartSetMixin = {
 
 
     /* 改变上下限时重绘图 依赖于chartLimit的柱 商品价格 散点截面 */
     /* 改变上下限时重绘图 依赖于chartLimit的柱 商品价格 散点截面 */
     changeLimit() {
     changeLimit() {
+      //source1 eta图库的类型对应
       const typeMap = {
       const typeMap = {
         7: this.setBarChart,
         7: this.setBarChart,
         10: this.setSectionScatterChart
         10: this.setSectionScatterChart
       }
       }
+      //其他source
       const sourceMap = {
       const sourceMap = {
         2: this.setCommodityChart,
         2: this.setCommodityChart,
+        10: this.setCrossVarietyChart
         // 3:
         // 3:
       }
       }
       if(this.chartInfo.Source === 1) {
       if(this.chartInfo.Source === 1) {

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

@@ -40,7 +40,7 @@
 import * as sheetInterface from '@/api/modules/sheetApi.js';
 import * as sheetInterface from '@/api/modules/sheetApi.js';
 import futuresInterface from '@/api/modules/futuresBaseApi';
 import futuresInterface from '@/api/modules/futuresBaseApi';
 import chartRelevanceApi from '@/api/modules/chartRelevanceApi.js';
 import chartRelevanceApi from '@/api/modules/chartRelevanceApi.js';
-import { fittingEquationInterface,statisticFeatureInterface } from '@/api/modules/chartRelevanceApi';
+import { fittingEquationInterface,statisticFeatureInterface,crossVarietyInterface } from '@/api/modules/chartRelevanceApi';
 export default {
 export default {
 	props: {
 	props: {
 		isOpenDialog: {
 		isOpenDialog: {
@@ -88,7 +88,8 @@ export default {
 				'/commordityChartBase': this.commodityClassifyApi,
 				'/commordityChartBase': this.commodityClassifyApi,
 				'/chartrelevance':this.relevanceClassifyApi,
 				'/chartrelevance':this.relevanceClassifyApi,
 				'/fittingEquationList': this.fittingEquationClassifyApi,
 				'/fittingEquationList': this.fittingEquationClassifyApi,
-				'/statisticFeatureList': this.statisticFeatureClassifyApi
+				'/statisticFeatureList': this.statisticFeatureClassifyApi,
+				'/crossVarietyChartList': this.crossVarietyClassifyApi
 			}
 			}
 			handleMap[this.$route.path] && handleMap[this.$route.path](classify_name,classify_id)
 			handleMap[this.$route.path] && handleMap[this.$route.path](classify_name,classify_id)
 		},
 		},
@@ -153,6 +154,18 @@ export default {
 			this.$emit('successCallback')
 			this.$emit('successCallback')
 		},
 		},
 
 
+		/* 跨品种分析 */
+		async crossVarietyClassifyApi(classify_name,classify_id){
+			const { Ret,Msg } = !classify_id
+				? await crossVarietyInterface.classifyAdd({ ChartClassifyName:classify_name })
+				: await crossVarietyInterface.classifyEdit({ ChartClassifyName:classify_name, ChartClassifyId:classify_id  })
+				
+			if( Ret !== 200) return
+			this.$message.success(Msg);
+			this.cancelHandle();
+			this.$emit('successCallback')
+		},
+
 		/* 取消 */
 		/* 取消 */
 		cancelHandle() {
 		cancelHandle() {
       this.formData = {}
       this.formData = {}

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

@@ -59,6 +59,7 @@ export default {
 </script>
 </script>
 <style scoped lang='scss'>
 <style scoped lang='scss'>
   .sheet-list-cont {
   .sheet-list-cont {
+    width: 100%;
     color: #333;
     color: #333;
     .el-card .el-card__header,
     .el-card .el-card__header,
     .el-card__body {
     .el-card__body {

+ 15 - 1
src/views/mychart_manage/components/chartDetailDia.vue

@@ -122,7 +122,7 @@
               class="span-item"
               class="span-item"
               style="margin-left: 7px"
               style="margin-left: 7px"
               @click="saveChartMapHandle"
               @click="saveChartMapHandle"
-              v-if="![3,4,6,7,8,9].includes(chartInfo.Source)"
+              v-if="[1,2,5].includes(chartInfo.Source)"
             >
             >
               <span> <i class="el-icon-collection" />&nbsp;保存 </span>
               <span> <i class="el-icon-collection" />&nbsp;保存 </span>
             </span>
             </span>
@@ -750,6 +750,16 @@ export default {
             this.tableData = res.Data.EdbInfoList;
             this.tableData = res.Data.EdbInfoList;
             this.statisticFrequencyData = res.Data.DataResp;
             this.statisticFrequencyData = res.Data.DataResp;
             this.setStatisticFrequency();
             this.setStatisticFrequency();
+          }else if(this.chartInfo.Source===10) { //跨品种分析
+            this.tableData = res.Data.EdbInfoList;
+            this.crossVarietyChartData = res.Data.DataResp;
+            this.chartLimit = {
+              min: Number(res.Data.DataResp.YMinValue),
+              max: Number(res.Data.DataResp.YMaxValue),
+              x_min: Number(res.Data.DataResp.XMinValue),
+              x_max: Number(res.Data.DataResp.XMaxValue)
+            }
+            this.setCrossVarietyChart();
           }
           }
         });
         });
     },
     },
@@ -900,6 +910,8 @@ export default {
         res=await fittingEquationInterface.refreshChart({ ChartInfoId })
         res=await fittingEquationInterface.refreshChart({ ChartInfoId })
       }else if([7,8,9].includes(Source)) {
       }else if([7,8,9].includes(Source)) {
         res=await statisticFeatureInterface.refreshChart({ ChartInfoId })
         res=await statisticFeatureInterface.refreshChart({ ChartInfoId })
+      }else if(Source===10) {
+        res=await crossVarietyInterface.refreshChart({ ChartInfoId })
       }
       }
      
      
         this.refreshLoading = false;
         this.refreshLoading = false;
@@ -1309,6 +1321,8 @@ export default {
         path='/fittingEquationChartEditor'
         path='/fittingEquationChartEditor'
       }else if([7,8,9].includes(this.chartInfo.Source)) {
       }else if([7,8,9].includes(this.chartInfo.Source)) {
         path='/statisticFeatureChartEditor'
         path='/statisticFeatureChartEditor'
+      }else if(this.chartInfo.Source===10) {
+        path='/crossVarietyChartEditor'
       }
       }
 
 
 
 

+ 21 - 20
src/views/mychart_manage/components/chooseChart.vue

@@ -36,6 +36,7 @@
 						<el-radio :label="3">相关性图表</el-radio>
 						<el-radio :label="3">相关性图表</el-radio>
 						<el-radio :label="6">拟合方程曲线</el-radio>
 						<el-radio :label="6">拟合方程曲线</el-radio>
 						<el-radio :label="7">统计特征</el-radio>
 						<el-radio :label="7">统计特征</el-radio>
+						<el-radio :label="10">跨品种分析</el-radio>
 					</el-radio-group>
 					</el-radio-group>
           <el-checkbox v-model="isShowMe"  @change="searchHandle">只看我的</el-checkbox>
           <el-checkbox v-model="isShowMe"  @change="searchHandle">只看我的</el-checkbox>
         </div>
         </div>
@@ -96,7 +97,7 @@
 import { mychartInterface } from '@/api/api.js';
 import { mychartInterface } from '@/api/api.js';
 import addMyClassifyDia from '@/views/dataEntry_manage/components/addMyClassifyDia';
 import addMyClassifyDia from '@/views/dataEntry_manage/components/addMyClassifyDia';
 import chartRelevanceApi from '@/api/modules/chartRelevanceApi';
 import chartRelevanceApi from '@/api/modules/chartRelevanceApi';
-import { fittingEquationInterface,statisticFeatureInterface } from '@/api/modules/chartRelevanceApi';
+import { fittingEquationInterface,statisticFeatureInterface,crossVarietyInterface } from '@/api/modules/chartRelevanceApi';
 import futuresInterface from '@/api/modules/futuresBaseApi';
 import futuresInterface from '@/api/modules/futuresBaseApi';
 export default {
 export default {
   components: {
   components: {
@@ -140,26 +141,26 @@ export default {
         KeyWord: this.search_txt,
         KeyWord: this.search_txt,
         IsShowMe: this.isShowMe
         IsShowMe: this.isShowMe
       };
       };
-      let res=null 
-      if(this.chart_source===1){
-        res=await mychartInterface.publicList(params)
-      }else if(this.chart_source===2){
-				res=await futuresInterface.searchChart(params)
-			}else if(this.chart_source===3){
-        res=await chartRelevanceApi.getChartList(params)
-      }else if(this.chart_source===6) {
-        res=await fittingEquationInterface.getChartList(params)
-      }else if(this.chart_source===7) {
-        res=await statisticFeatureInterface.getChartList(params)
+
+      const apiMap = {
+        1: mychartInterface.publicList,
+        2: futuresInterface.searchChart,
+        3: chartRelevanceApi.getChartList,
+        6: fittingEquationInterface.getChartList,
+        7: statisticFeatureInterface.getChartList,
+        10: crossVarietyInterface.searchChart,
       }
       }
-        if (res.Ret !== 200) return;
-        this.haveMove = res.Data ? this.page_no < res.Data.Paging.Pages : false;
-        this.chartPublicList = res.Data
-          ? this.page_no === 1
-            ? res.Data.List
-            : [...this.chartPublicList, ...res.Data.List]
-          : [];
-        this.haveData = this.chartPublicList.length ? true : false;
+      let res = await apiMap[this.chart_source](params)
+
+
+      if (res.Ret !== 200) return;
+      this.haveMove = res.Data ? this.page_no < res.Data.Paging.Pages : false;
+      this.chartPublicList = res.Data
+        ? this.page_no === 1
+          ? res.Data.List
+          : [...this.chartPublicList, ...res.Data.List]
+        : [];
+      this.haveData = this.chartPublicList.length ? true : false;
       
       
     },
     },
 
 

+ 54 - 21
src/views/operation_manage/AIQA/AIQA.vue

@@ -3,10 +3,10 @@
         <div class="window-list-wrap">
         <div class="window-list-wrap">
             <div class="window-title">
             <div class="window-title">
                 <div class="title-wrap">
                 <div class="title-wrap">
-                    <p style="color: #333333;font-size: 20px;font-weight: 600;">HORIZON INSIGHTS</p>
-                    <span style="color: #666666;font-size: 16px;">弘则研究AI问答小助手</span>
+                    <p class="text-ellipsis" style="color: #333333;font-size: 20px;font-weight: 600;">{{companyName}}</p>
+                    <span style="color: #666666;font-size: 16px;">研究AI问答小助手</span>
                 </div>
                 </div>
-                <div class="icon"><img src="~@/assets/img/icons/horizon.png" /></div>
+                <div class="icon"><img src="~@/assets/img/icons/ai_company.png"/></div>
             </div>
             </div>
             <div class="add-btn" @click="handleAddNewWindow"><i class="el-icon-circle-plus-outline"></i>新建对话窗口</div>
             <div class="add-btn" @click="handleAddNewWindow"><i class="el-icon-circle-plus-outline"></i>新建对话窗口</div>
             <div class="list-wrap hidden-scrollbar">
             <div class="list-wrap hidden-scrollbar">
@@ -28,10 +28,10 @@
             <div class="content-header">
             <div class="content-header">
                 <div class="title-wrap">
                 <div class="title-wrap">
                     <p>{{activeWindowId<=0?'新对话窗口':activeWindow.TopicName||''}}</p>
                     <p>{{activeWindowId<=0?'新对话窗口':activeWindow.TopicName||''}}</p>
-                    <span>{{activeWindowId<=0?'弘则AI助手使用说明':`${historyList.length||0} messages`}}</span>
+                    <span>{{activeWindowId<=0?'AI助手使用说明':`${historyList.length||0} messages`}}</span>
                 </div>
                 </div>
                 <div class="select-box">
                 <div class="select-box">
-                    <el-select v-model="model" :class="{'hint':showHint}" :disabled="isTyping||(windowContentLoading&&windowContentLoading.visible)" ref="modelSelect" 
+                    <!-- <el-select v-model="model" :class="{'hint':showHint}" :disabled="isTyping||(windowContentLoading&&windowContentLoading.visible)" ref="modelSelect" 
                         @click.native="selectClick"
                         @click.native="selectClick"
                         @change="changeModel">
                         @change="changeModel">
                         <el-option v-for="item in modelList" :key="item.label"
                         <el-option v-for="item in modelList" :key="item.label"
@@ -40,7 +40,7 @@
                             <span style="float:left">{{item.label}}</span>
                             <span style="float:left">{{item.label}}</span>
                             <span style="float:right"><img :src="item.icon" style="margin-top:5px;width:24px;height:24px;"/></span>
                             <span style="float:right"><img :src="item.icon" style="margin-top:5px;width:24px;height:24px;"/></span>
                         </el-option>
                         </el-option>
-                    </el-select>
+                    </el-select> -->
                 </div>
                 </div>
             </div>
             </div>
             <!-- 仅这一部分滚动 -->
             <!-- 仅这一部分滚动 -->
@@ -74,6 +74,7 @@ import NewWindowHint from './components/newWindowHint.vue';
 import WindowListItem from './components/windowListItem';
 import WindowListItem from './components/windowListItem';
 /* api */
 /* api */
 import {aiQAInterence} from '@/api/modules/aiApi.js'; 
 import {aiQAInterence} from '@/api/modules/aiApi.js'; 
+import {etaBaseConfigInterence} from '@/api/modules/etaBaseConfigApi.js';
 export default {
 export default {
     components: { WindowListItem,NewWindowHint, MessageItem },
     components: { WindowListItem,NewWindowHint, MessageItem },
     data() {
     data() {
@@ -86,17 +87,25 @@ export default {
             /* window-content*/
             /* window-content*/
             historyList:[],//当前窗口历史记录
             historyList:[],//当前窗口历史记录
             inputText:'',
             inputText:'',
-            model:'',//当前选择的模型
+            model:'GPT-4 Turbo',//当前选择的模型
             modelOldValue:'',
             modelOldValue:'',
             modelList:[
             modelList:[
                 {
                 {
-                    label:'gpt-3.5-turbo',
-                    icon:require('@/assets/img/icons/chat-gpt.png'),
+                    label:'GPT-4 Turbo',
+                    icon:require('@/assets/img/icons/gpt-4-turbo.png'),
+                },
+                {
+                    label:'GPT4',
+                    icon:require('@/assets/img/icons/gpt-4.png'),
                 },
                 },
                 {
                 {
                     label:'gpt-3.5-turbo-16k',
                     label:'gpt-3.5-turbo-16k',
                     icon:require('@/assets/img/icons/chat-gpt-16k.png'),
                     icon:require('@/assets/img/icons/chat-gpt-16k.png'),
                 },
                 },
+                {
+                    label:'gpt-3.5-turbo',
+                    icon:require('@/assets/img/icons/chat-gpt.png'),
+                },
                 {
                 {
                     label:'eta',
                     label:'eta',
                     icon:require('@/assets/img/icons/horizon.png'),
                     icon:require('@/assets/img/icons/horizon.png'),
@@ -105,6 +114,8 @@ export default {
             showHint:false,//选择模型提示
             showHint:false,//选择模型提示
             isTyping:false,//是否处于打字动画中
             isTyping:false,//是否处于打字动画中
             windowContentLoading:null,
             windowContentLoading:null,
+            answerLoading:false,//回答中
+            companyName:'',
         };
         };
     },
     },
     watch:{
     watch:{
@@ -153,7 +164,7 @@ export default {
                 this.historyList = List||[]
                 this.historyList = List||[]
                 this.windowContentLoading&&this.windowContentLoading.close()
                 this.windowContentLoading&&this.windowContentLoading.close()
                 //使用模型
                 //使用模型
-                this.model = this.historyList.length?this.historyList[this.historyList.length-1].Model:''
+                this.model = this.historyList.length?this.historyList[this.historyList.length-1].Model:'GPT-4 Turbo'
                 //如果有历史记录,则滚动到底部
                 //如果有历史记录,则滚动到底部
                 this.$nextTick(()=>{
                 this.$nextTick(()=>{
                     const windowContentWrap = document.querySelector('.window-content-wrap')
                     const windowContentWrap = document.querySelector('.window-content-wrap')
@@ -199,7 +210,7 @@ export default {
             this.activeWindowId=0
             this.activeWindowId=0
             this.activeWindow=null
             this.activeWindow=null
             this.historyList=[]
             this.historyList=[]
-            this.model=''
+            this.model='GPT-4 Turbo'
             //this.inputText=''
             //this.inputText=''
             this.isTyping = false
             this.isTyping = false
         },
         },
@@ -285,23 +296,24 @@ export default {
                 this.inputText+='\n'
                 this.inputText+='\n'
                 return
                 return
             }
             }
-            if(this.isTyping){
+            if(this.isTyping||this.answerLoading){
                 this.$message.warning('请等待回答完成')
                 this.$message.warning('请等待回答完成')
                 return
                 return
             }
             }
             //新建窗口,未选择模型
             //新建窗口,未选择模型
-            if(this.activeWindowId===0&&this.model===''){
-                this.showHint = true
-                this.$message.error('请选择模型')
-                this.$nextTick(()=>{
-                    this.$refs.modelSelect.focus()
-                })
-                return
-            }
+            // if(this.activeWindowId===0&&this.model===''){
+            //     this.showHint = true
+            //     this.$message.error('请选择模型')
+            //     this.$nextTick(()=>{
+            //         this.$refs.modelSelect.focus()
+            //     })
+            //     return
+            // }
             if(this.inputText.length===0){
             if(this.inputText.length===0){
                 this.$message.warning('请输入提问')
                 this.$message.warning('请输入提问')
                 return
                 return
             }
             }
+            this.answerLoading=true
             this.activeWindowId===0&&(this.activeWindowId = -1)
             this.activeWindowId===0&&(this.activeWindowId = -1)
             //this.activeWindowId!==0&&this.getWindowDetail()
             //this.activeWindowId!==0&&this.getWindowDetail()
             //mock 加入到historyList中
             //mock 加入到historyList中
@@ -329,8 +341,9 @@ export default {
             aiQAInterence.sendChatMsg({
             aiQAInterence.sendChatMsg({
                 AiChatTopicId:this.activeWindowId<=0?0:this.activeWindowId,
                 AiChatTopicId:this.activeWindowId<=0?0:this.activeWindowId,
                 Ask:inputText,
                 Ask:inputText,
-                Model:this.model
+                // Model:this.model
             }).then(res=>{
             }).then(res=>{
+                this.answerLoading=false
                 //在回答未获取前切换了新窗口
                 //在回答未获取前切换了新窗口
                 if(this.historyList.length===0){
                 if(this.historyList.length===0){
                     this.getWindowList()
                     this.getWindowList()
@@ -365,6 +378,8 @@ export default {
                 msg.Model = Model
                 msg.Model = Model
                 msg.isPlay = true
                 msg.isPlay = true
                 this.historyList.splice(this.historyList.length-1,1,msg)
                 this.historyList.splice(this.historyList.length-1,1,msg)
+            }).catch(()=>{
+                this.answerLoading=false
             })
             })
         },
         },
         //获取窗口列表
         //获取窗口列表
@@ -378,10 +393,19 @@ export default {
                 this.windowList = res.Data.List||[]
                 this.windowList = res.Data.List||[]
                 this.listWrapLoading&&this.listWrapLoading.close()
                 this.listWrapLoading&&this.listWrapLoading.close()
             })
             })
+        },
+
+        getBaseConfig(){
+            etaBaseConfigInterence.getBaseConfig().then(res=>{
+                if(res.Ret===200){
+                    this.companyName=res.Data.CompanyName||''
+                }
+            })
         }
         }
     },
     },
     mounted(){
     mounted(){
         this.getWindowList()
         this.getWindowList()
+        this.getBaseConfig()
     }
     }
 };
 };
 </script>
 </script>
@@ -422,10 +446,19 @@ $border-color:#3D52A1;
             display: flex;
             display: flex;
             justify-content: space-between;
             justify-content: space-between;
             align-items: center;
             align-items: center;
+            // overflow: hidden;
             .icon img{
             .icon img{
                 width:58px;
                 width:58px;
                 height:58px;
                 height:58px;
             }
             }
+            .title-wrap{
+                overflow: hidden;
+            }
+            .text-ellipsis{
+                overflow: hidden;
+                white-space: nowrap;
+                text-overflow: ellipsis;
+            }
         }
         }
         .add-btn{
         .add-btn{
             border:2px dashed $border-color;
             border:2px dashed $border-color;

+ 6 - 4
src/views/operation_manage/AIQA/components/messageItem.vue

@@ -28,10 +28,12 @@ export default {
     data() {
     data() {
         return {
         return {
             iconMap:{
             iconMap:{
-                'user':require('@/assets/img/set_m/user_img.png'),
+                'user':require('@/assets/img/icons/ai_avatar.png'),
                 'gpt-3.5-turbo':require('@/assets/img/icons/chat-gpt.png'),
                 'gpt-3.5-turbo':require('@/assets/img/icons/chat-gpt.png'),
                 'gpt-3.5-turbo-16k':require('@/assets/img/icons/chat-gpt-16k.png'),
                 'gpt-3.5-turbo-16k':require('@/assets/img/icons/chat-gpt-16k.png'),
-                'eta':require('@/assets/img/icons/horizon.png')
+                'eta':require('@/assets/img/icons/horizon.png'),
+                'GPT4':require('@/assets/img/icons/gpt-4.png'),
+                'GPT-4 Turbo':require('@/assets/img/icons/gpt-4-turbo.png'),
             },
             },
             isPlay:false,//是否播放动画
             isPlay:false,//是否播放动画
             typingText:'',
             typingText:'',
@@ -51,13 +53,13 @@ export default {
     computed:{
     computed:{
         IconSrc(){
         IconSrc(){
             const {messageType,modelName} = this.messageInfo
             const {messageType,modelName} = this.messageInfo
-            const iconType = messageType==='question'?'user':modelName
+            const iconType = messageType==='question'?'user':'GPT-4 Turbo'
             return this.iconMap[iconType]||''
             return this.iconMap[iconType]||''
         }
         }
     },
     },
     methods: {
     methods: {
         async playTyping(){
         async playTyping(){
-            const writeText = (text,delay=150)=>{
+            const writeText = (text,delay=20)=>{
                 return new Promise((res,rej)=>{
                 return new Promise((res,rej)=>{
                     setTimeout(()=>{
                     setTimeout(()=>{
                         this.typingText+=text
                         this.typingText+=text

+ 2 - 3
src/views/operation_manage/AIQA/components/newWindowHint.vue

@@ -1,9 +1,8 @@
 <template>
 <template>
     <div class="new-window-hint-wrap">
     <div class="new-window-hint-wrap">
         <p class="title">使用说明:</p>
         <p class="title">使用说明:</p>
-        <p>1、每账号每天最高50次问答。</p>
-        <p>2、在同一个对话窗口内提问,选择同一模型可联系上下文回答,切换模型后不支持。</p>
-        <p>3、历史问答默认用该对话窗口内第一个提问命名,可修改。</p>
+        <p>1、每账号每天最高500次问答。</p>
+        <p>2、历史问答默认用该对话窗口内第一个提问命名,可修改。</p>
     </div>
     </div>
 </template>
 </template>
 
 

+ 1 - 1
src/views/operation_manage/AIQA/components/windowListItem.vue

@@ -1,5 +1,5 @@
 <template>
 <template>
-    <div class="list-item" :class="{'active':activeWindowId===item.AiChatTopicId}">
+    <div class="list-item" :class="[activeWindowId===item.AiChatTopicId?'active':'']">
         <template v-if="!isEdit">
         <template v-if="!isEdit">
             <p>{{item.TopicName}}</p>
             <p>{{item.TopicName}}</p>
             <!-- <span>6 messages </span> -->
             <!-- <span>6 messages </span> -->

+ 116 - 1
src/views/ppt_manage/mixins/mixins.js

@@ -72,7 +72,10 @@ export default {
       },
       },
 
 
       /* 统计频率图 */
       /* 统计频率图 */
-      statisticFrequencyData: {}
+      statisticFrequencyData: {},
+
+      /* 跨品种分析图 */
+      crossVarietyChartData: {}
     }
     }
   },
   },
   methods: {
   methods: {
@@ -1231,6 +1234,118 @@ export default {
       }
       }
     },
     },
 
 
+     /* 跨品种分析 */
+     setCrossVarietyChart() {
+      
+      const { min,max,x_min,x_max }  = this.chartLimit;
+
+      const { DataList,XName,YName,XNameEn,YNameEn } = this.crossVarietyChartData;
+
+      //y轴
+      let yAxis = {
+        ...basicYAxis,
+        title: {
+          text: YName,
+          textCh:YName,// 中文
+          textEn:YNameEn||YName,
+          align: 'middle',
+        },
+        opposite: false,
+        reversed: false,
+        min: Number(min),
+        max: Number(max),
+        tickWidth: 1,
+      }
+
+      // x轴
+      let xAxis = {
+        ...scatterXAxis,
+        title: {
+          text: XName,
+          textCh:XName,// 中文
+          textEn:XNameEn || XName,
+          align: 'middle',
+        },
+        min: Number(x_min),
+        max: Number(x_max),
+      }
+
+       //数据列
+      let series = [];
+      DataList.forEach(item => {
+        //数据列
+        let series_item = {
+          data: [],
+          type: 'scatter',
+          name: item.Name,
+          nameCh: item.Name,
+          nameEn: item.NameEn||item.Name,
+          color: item.Color,
+          lineWidth: 0,
+          chartType: 'linear',
+          zIndex:1
+        }
+        item.CoordinatePointData.forEach(_ => {
+          series_item.data.push({x: _.X,y: _.Y,})
+        })
+        series.push(series_item);
+      })
+
+      let edbInfoList = this.dataList;
+      let tooltip = {
+        formatter: function() {
+          let series_obj = DataList.find(_ => _.Name === this.series.name);
+          let ponit_obj = series_obj.CoordinatePointData.find(_ => _.X ===this.x && _.Y===this.y);
+          
+          let xEdbInfo = edbInfoList.find(_ => _.EdbInfoId===ponit_obj.XEdbInfoId);
+          let yEdbInfo = edbInfoList.find(_ => _.EdbInfoId===ponit_obj.YEdbInfoId);
+
+          let str=`<b>${ this.series.name }</b>`;
+          str += `<br><span style="color:${this.color}">\u25CF</span>${xEdbInfo.EdbName}: ${this.x} ${ponit_obj.XDate}<br>`;
+          str += `<span style="color:${this.color}">\u25CF</span>${yEdbInfo.EdbName}: ${this.y} ${ponit_obj.YDate}`;
+
+          return str
+        },
+        formatterCh: function() {
+          let series_obj = DataList.find(_ => _.Name === this.series.name);
+          let ponit_obj = series_obj.CoordinatePointData.find(_ => _.X ===this.x && _.Y===this.y);
+          
+          let xEdbInfo = edbInfoList.find(_ => _.EdbInfoId===ponit_obj.XEdbInfoId);
+          let yEdbInfo = edbInfoList.find(_ => _.EdbInfoId===ponit_obj.YEdbInfoId);
+
+          let str=`<b>${ this.series.name }</b>`;
+          str += `<br><span style="color:${this.color}">\u25CF</span>${xEdbInfo.EdbName}: ${this.x} ${ponit_obj.XDate}<br>`;
+          str += `<span style="color:${this.color}">\u25CF</span>${yEdbInfo.EdbName}: ${this.y} ${ponit_obj.YDate}`;
+
+          return str
+          
+        },
+        formatterEn: function() {
+          let series_obj = DataList.find(_ => _.NameEn === this.series.name);
+          let ponit_obj = series_obj.CoordinatePointData.find(_ => _.X ===this.x && _.Y===this.y);
+          
+          let xEdbInfo = edbInfoList.find(_ => _.EdbInfoId===ponit_obj.XEdbInfoId);
+          let yEdbInfo = edbInfoList.find(_ => _.EdbInfoId===ponit_obj.YEdbInfoId);
+
+          let str=`<b>${ this.series.name }</b>`;
+          str += `<br><span style="color:${this.color}">\u25CF</span>${xEdbInfo.EdbNameEn}: ${this.x} ${ponit_obj.XDate}<br>`;
+          str += `<span style="color:${this.color}">\u25CF</span>${yEdbInfo.EdbNameEn}: ${this.y} ${ponit_obj.YDate}`;
+
+          return str
+        }
+      }
+
+      this.options = {
+        title: {
+          text:''
+        },
+        series,
+        yAxis: [yAxis],
+        xAxis,
+        tooltip
+      }
+    },
+
     /* 查询范围为1年内 x轴显示为月/日 否则默认年/月 */
     /* 查询范围为1年内 x轴显示为月/日 否则默认年/月 */
     xTimeDiffer() {
     xTimeDiffer() {
       const end_date =
       const end_date =

+ 107 - 18
src/views/ppt_manage/mixins/pptMixins.js

@@ -7,7 +7,7 @@ import {etaBaseConfigInterence} from '@/api/modules/etaBaseConfigApi.js';
 import {pptEnInterface} from '@/api/modules/pptEnApi.js';
 import {pptEnInterface} from '@/api/modules/pptEnApi.js';
 import * as sheetInterface from '@/api/modules/sheetApi.js';
 import * as sheetInterface from '@/api/modules/sheetApi.js';
 import futuresInterface from '@/api/modules/futuresBaseApi';
 import futuresInterface from '@/api/modules/futuresBaseApi';
-import { fittingEquationInterface,statisticFeatureInterface } from '@/api/modules/chartRelevanceApi';
+import { fittingEquationInterface,statisticFeatureInterface,crossVarietyInterface } from '@/api/modules/chartRelevanceApi';
 import chartRelevanceApi from '@/api/modules/chartRelevanceApi.js';
 import chartRelevanceApi from '@/api/modules/chartRelevanceApi.js';
 import { defaultOpts } from '@/utils/defaultOptions';
 import { defaultOpts } from '@/utils/defaultOptions';
 import {formatPPTDate,checkPPTpageElemant,getStrSize,isShowPPTTitle} from '../newVersion/utils/untils.js';
 import {formatPPTDate,checkPPTpageElemant,getStrSize,isShowPPTTitle} from '../newVersion/utils/untils.js';
@@ -98,7 +98,8 @@ export default {
 			TemplateType,
 			TemplateType,
       ReportId,
       ReportId,
       ModifyTime,
       ModifyTime,
-      PublishTime
+      PublishTime,
+      Editor
 		} = res.Data
 		} = res.Data
       const pptDate = formatPPTDate(this.currentLang,PptDate)
       const pptDate = formatPPTDate(this.currentLang,PptDate)
       let legalContent = JSON.parse(Content)
       let legalContent = JSON.parse(Content)
@@ -118,13 +119,24 @@ export default {
 			},
 			},
       ReportId,
       ReportId,
       ModifyTime,
       ModifyTime,
-      PublishTime
+      PublishTime,Editor
 		}
 		}
       }else{
       }else{
         this.result = {status:'',content:'获取ppt数据失败!'}
         this.result = {status:'',content:'获取ppt数据失败!'}
       }
       }
     },
     },
-    //ppt设置相关,引用mixins.js里的setOptions
+    //ppt设置相关,引用mixins.js里的setOptions chartType只有source是1才有用
+    /* Source 1 ; chartType 1曲线 2季节 3面积 4堆积柱 5散点 6组合 7柱形 8截面散点
+    * 2 商品价格
+    * 3 相关性
+    * 4 滚动相关性
+    * 5 商品利润
+    * 6 拟合方程
+    * 7 统计特征/标准差
+    * 8 统计特征/百分位
+    * 9 统计特征/频率
+    * 10 跨品种分析
+    */
     //获取图表数据
     //获取图表数据
     async getchartData(id,lang='ch') {
     async getchartData(id,lang='ch') {
       const currentLang = this.currentLang || lang
       const currentLang = this.currentLang || lang
@@ -187,6 +199,17 @@ export default {
         this.dataList = res.Data.EdbInfoList;
         this.dataList = res.Data.EdbInfoList;
         this.statisticFrequencyData = res.Data.DataResp;
         this.statisticFrequencyData = res.Data.DataResp;
         this.setStatisticFrequency();
         this.setStatisticFrequency();
+      }else if(this.chartInfo.Source===10) {
+        this.dataList = res.Data.EdbInfoList;
+        this.crossVarietyChartData = res.Data.DataResp;
+        this.chartLimit = {
+          min: Number(res.Data.DataResp.YMinValue),
+          max: Number(res.Data.DataResp.YMaxValue),
+          x_min: Number(res.Data.DataResp.XMinValue),
+          x_max: Number(res.Data.DataResp.XMaxValue)
+        }
+        this.setCrossVarietyChart();
+        this.changeRelevanceOptions();//更改英文一样
       }
       }
 
 
       //根据图表数据获取配置项
       //根据图表数据获取配置项
@@ -299,16 +322,25 @@ export default {
       if(!this.chartInfo.ChartNameEn){
       if(!this.chartInfo.ChartNameEn){
         result = false
         result = false
       }
       }
-      //指标名称:this.dataList[].EdbNameEn
-      //指标单位:this.dataList[].UnitEn
-      this.dataList.forEach(item=>{
-        if(!item.EdbNameEn){
-          result = false
-        }
-        if(this.chartInfo.ChartType!==10&&item.Unit&&!item.UnitEn){
-          result = false
-        }
-      })
+
+      if(this.chartInfo.Source === 10) {
+        const { XNameEn,YNameEn,DataList } = this.crossVarietyChartData;
+
+        let haveOneNoEn = DataList.some(_ =>!_.NameEn);
+
+        if(haveOneNoEn || !XNameEn || !YNameEn) result = false
+      }else {
+        //指标名称:this.dataList[].EdbNameEn
+        //指标单位:this.dataList[].UnitEn
+        this.dataList.forEach(item=>{
+          if(!item.EdbNameEn){
+            result = false
+          }
+          if(this.chartInfo.ChartType!==10&&item.Unit&&!item.UnitEn){
+            result = false
+          }
+        })
+      }
       return result
       return result
     },
     },
     //刷新图表数据
     //刷新图表数据
@@ -608,6 +640,7 @@ export default {
         value:chartInfo.ChartName,
         value:chartInfo.ChartName,
         key:'ChartName',
         key:'ChartName',
         id:chartInfo.ChartInfoId,
         id:chartInfo.ChartInfoId,
+        source: chartInfo.Source,
         notEdit:true
         notEdit:true
       },
       },
       {
       {
@@ -617,7 +650,7 @@ export default {
         id:chartInfo.ChartInfoId,
         id:chartInfo.ChartInfoId,
         placeholder:'请输入英文图表名称'
         placeholder:'请输入英文图表名称'
       })
       })
-      if(![3,6,7,8,9].includes(chartInfo.Source)){
+      if([1,2,5].includes(chartInfo.Source)){
         this.formItemArray.chartsList = tableData.map(item => {
         this.formItemArray.chartsList = tableData.map(item => {
           return item.Unit 
           return item.Unit 
             ? [
             ? [
@@ -688,7 +721,7 @@ export default {
       }
       }
 
 
       //利润曲线
       //利润曲线
-      if(chartInfo.Source===5) {
+      else if(chartInfo.Source===5) {
         this.formItemArray.chartInfo.push({
         this.formItemArray.chartInfo.push({
           label:'盘面利润名称',
           label:'盘面利润名称',
           value:Data.DataResp.ProfitName,
           value:Data.DataResp.ProfitName,
@@ -704,6 +737,60 @@ export default {
           placeholder:'请输入英文盘面利润名称'
           placeholder:'请输入英文盘面利润名称'
         })
         })
       }
       }
+
+      //跨品种分析
+      else if(chartInfo.Source===10) {
+        let res = await crossVarietyInterface.chartLangOption({ChartInfoId: chartInfo.ChartInfoId})
+
+        const { TagList,VarietyList } = res.Data;
+
+        this.formItemArray.chartInfo.push({
+          label:'X轴名称',
+          value:Data.DataResp.XName,
+          key:'XName',
+          id:TagList[0].ChartTagId,
+          notEdit:true
+        },
+        {
+          label:'英文X轴名称',
+          value:Data.DataResp.XNameEn,
+          key:'XNameEn',
+          id:TagList[0].ChartTagId,
+          placeholder:'请输入英文X轴名称'
+        },{
+          label:'Y轴名称',
+          value:Data.DataResp.YName,
+          key:'YName',
+          id:TagList[1].ChartTagId,
+          notEdit:true
+        },
+        {
+          label:'英文Y轴名称',
+          value:Data.DataResp.YNameEn,
+          key:'YNameEn',
+          id:TagList[1].ChartTagId,
+          placeholder:'请输入英文Y轴名称'
+        })
+
+        VarietyList.forEach(item => {
+          this.formItemArray.chartsList.push([
+            {
+              label:'品种名称',
+              value:item.ChartVarietyName,
+              key:'ChartVarietyName',
+              id:item.ChartVarietyId,
+              notEdit:true
+            },
+            {
+              label:'英文品种名称',
+              value:item.ChartVarietyNameEn,
+              key:'ChartVarietyNameEn',
+              id:item.ChartVarietyId,
+              placeholder:'请输入英文品种名称'
+            }
+          ])
+        })
+      }
 			
 			
       this.setEnName = true
       this.setEnName = true
 		},
 		},
@@ -727,16 +814,18 @@ export default {
           ChartInfoId: enNameData.ChartInfoId,
           ChartInfoId: enNameData.ChartInfoId,
           ChartNameEn: enNameData.ChartNameEn
           ChartNameEn: enNameData.ChartNameEn
         })
         })
-      }else if(this.chartInfo.Source===6){//拟合方程
+      }else if(this.chart_source===6){//拟合方程
         res=await fittingEquationInterface.editChartEn({
         res=await fittingEquationInterface.editChartEn({
           ChartInfoId: enNameData.ChartInfoId,
           ChartInfoId: enNameData.ChartInfoId,
           ChartNameEn: enNameData.ChartNameEn
           ChartNameEn: enNameData.ChartNameEn
         })
         })
-      }else if(this.chartInfo.Source===7){//统计特征
+      }else if(this.chart_source===7){//统计特征
         res=await statisticFeatureInterface.editChartEn({
         res=await statisticFeatureInterface.editChartEn({
           ChartInfoId: enNameData.ChartInfoId,
           ChartInfoId: enNameData.ChartInfoId,
           ChartNameEn: enNameData.ChartNameEn
           ChartNameEn: enNameData.ChartNameEn
         })
         })
+      }else if(this.chart_source===10) {//跨品种分析
+        res=await crossVarietyInterface.editChartEn(enNameData)
       }
       }
       
       
 			if(res.Ret !==200) return
 			if(res.Ret !==200) return

+ 1 - 0
src/views/ppt_manage/newVersion/components/catalog/pptContent.vue

@@ -173,6 +173,7 @@ export default {
           this.firstPage.BackIndex = FirstPage.TemplateType-1
           this.firstPage.BackIndex = FirstPage.TemplateType-1
           this.firstPage.imgLocalUrl = this.bgList[FirstPage.TemplateType-1]
           this.firstPage.imgLocalUrl = this.bgList[FirstPage.TemplateType-1]
           this.pptTime = this.pptItem.PptxUrl?PublishTime:ModifyTime
           this.pptTime = this.pptItem.PptxUrl?PublishTime:ModifyTime
+          this.$emit('resetToolList',this.result)
         }else{
         }else{
           this.$message.error('获取ppt数据失败!')
           this.$message.error('获取ppt数据失败!')
           this.dataLoading.close();
           this.dataLoading.close();

+ 1 - 0
src/views/ppt_manage/newVersion/components/catalog/pptContentEn.vue

@@ -168,6 +168,7 @@ export default {
           this.firstPage.BackIndex = FirstPage.TemplateType-1
           this.firstPage.BackIndex = FirstPage.TemplateType-1
           this.firstPage.imgLocalUrl = pptCoverEn[FirstPage.TemplateType-1]
           this.firstPage.imgLocalUrl = pptCoverEn[FirstPage.TemplateType-1]
           this.pptTime = this.pptItem.PptxUrl?PublishTime:ModifyTime
           this.pptTime = this.pptItem.PptxUrl?PublishTime:ModifyTime
+          this.$emit('resetToolList',this.result)
         }else{
         }else{
           this.$message.error('获取ppt数据失败!')
           this.$message.error('获取ppt数据失败!')
           this.dataLoading.close();
           this.dataLoading.close();

+ 22 - 2
src/views/ppt_manage/newVersion/pptCatalog.vue

@@ -240,6 +240,7 @@
             :pptItem="pptItem"
             :pptItem="pptItem"
             :key="pptItem.PptId"
             :key="pptItem.PptId"
             @isLegal="handleIsLegal"
             @isLegal="handleIsLegal"
+            @resetToolList="setToolList"
           ></ppt-content>
           ></ppt-content>
           <ppt-content-old 
           <ppt-content-old 
             v-else
             v-else
@@ -545,7 +546,7 @@ export default {
       }
       }
     },
     },
     //设置操作按钮
     //设置操作按钮
-    setToolList(){
+    setToolList(pptDetail={}){
       //公共目录:显示除 删除, 编辑 外的全部按钮
       //公共目录:显示除 删除, 编辑 外的全部按钮
       if(this.treeName==='public'){
       if(this.treeName==='public'){
         this.pptToolList = toolList.filter((i)=>{
         this.pptToolList = toolList.filter((i)=>{
@@ -592,6 +593,16 @@ export default {
       this.pptToolList = this.pptToolList.filter((i)=>{
       this.pptToolList = this.pptToolList.filter((i)=>{
           return authArr.includes(i.key)
           return authArr.includes(i.key)
         })
         })
+      //若有人在编辑,则显示编辑中
+      if(this.pptToolList.find(i=>i.key==='edit')){
+        const {Editor={}} = pptDetail
+        const labelName = Editor.IsEditing?`${Editor.Editor}编辑中...`:'编辑'
+        this.pptToolList.map(i=>{
+            if(i.key==='edit'){
+                i.label = labelName
+            }
+        })
+      }
     },
     },
     //判断公共目录按钮是否显示
     //判断公共目录按钮是否显示
     checkNode(data){
     checkNode(data){
@@ -722,7 +733,7 @@ export default {
       })
       })
     },
     },
     //点击操作栏事件处理
     //点击操作栏事件处理
-    handleToolClick(item){
+    async handleToolClick(item){
       const urlMap = {
       const urlMap = {
         edit:`/ppteditor?id=${this.pptItem.PptId}`,
         edit:`/ppteditor?id=${this.pptItem.PptId}`,
         publish:`/pptpublish?id=${this.pptItem.PptId}`,
         publish:`/pptpublish?id=${this.pptItem.PptId}`,
@@ -732,6 +743,15 @@ export default {
       if(urlMap[item.key]){
       if(urlMap[item.key]){
         if(this.pptItem.PptVersion===2){
         if(this.pptItem.PptVersion===2){
           if(!this.pptItem.overLimit||item.key!=='publish'){
           if(!this.pptItem.overLimit||item.key!=='publish'){
+            if(item.key==='edit'){
+                if(item.label.length>2){
+                    this.$message.warning("他人正在编辑中,不可重复编辑")
+                    return
+                }
+                //调接口加锁然后跳转
+                const res = await pptInterface.pptEditLock({PptId:Number(this.pptItem.PptId),Status:1})
+                if(res.Ret!==200) return
+            }
             window.open(urlMap[item.key],'_blank');
             window.open(urlMap[item.key],'_blank');
           }else if(item.key==='publish'){
           }else if(item.key==='publish'){
             //this.$message.warning('该PPT页数超过60页或图表数量超过100张,无法发布,请修改后重试')
             //this.$message.warning('该PPT页数超过60页或图表数量超过100张,无法发布,请修改后重试')

+ 10 - 12
src/views/ppt_manage/newVersion/pptEditor.vue

@@ -129,6 +129,7 @@
                   <el-radio :label="3" style="margin-bottom:5px">相关性图表</el-radio>
                   <el-radio :label="3" style="margin-bottom:5px">相关性图表</el-radio>
                   <el-radio :label="6" style="margin-bottom:5px">拟合方程曲线</el-radio>
                   <el-radio :label="6" style="margin-bottom:5px">拟合方程曲线</el-radio>
                   <el-radio :label="7" style="margin-bottom:5px">统计特征</el-radio>
                   <el-radio :label="7" style="margin-bottom:5px">统计特征</el-radio>
+                  <el-radio :label="10">跨品种分析</el-radio>
                 </el-radio-group>
                 </el-radio-group>
                 <div style="margin: 10px 0">
                 <div style="margin: 10px 0">
                   <el-checkbox v-model="isShowMe" @change="() => {search_page=1;$refs.chartListRef.scrollTop = 0;getreportlist()}">只看我的</el-checkbox>
                   <el-checkbox v-model="isShowMe" @change="() => {search_page=1;$refs.chartListRef.scrollTop = 0;getreportlist()}">只看我的</el-checkbox>
@@ -270,7 +271,7 @@ import {modelInfo,defaultPosition} from './utils/config'
 import { dataBaseInterface ,sandInterface } from "@/api/api.js";
 import { dataBaseInterface ,sandInterface } from "@/api/api.js";
 import futuresInterface from '@/api/modules/futuresBaseApi';
 import futuresInterface from '@/api/modules/futuresBaseApi';
 import chartRelevanceApi from '@/api/modules/chartRelevanceApi';
 import chartRelevanceApi from '@/api/modules/chartRelevanceApi';
-import { fittingEquationInterface,statisticFeatureInterface } from '@/api/modules/chartRelevanceApi';
+import { fittingEquationInterface,statisticFeatureInterface,crossVarietyInterface } from '@/api/modules/chartRelevanceApi';
 import pptmixin from '../mixins/pptMixins';
 import pptmixin from '../mixins/pptMixins';
 import {uploadFileDirect} from "@/utils/common.js"
 import {uploadFileDirect} from "@/utils/common.js"
 import mixins from '../mixins/mixins';
 import mixins from '../mixins/mixins';
@@ -735,18 +736,15 @@ export default {
         PageSize: this.search_page_sizes,
         PageSize: this.search_page_sizes,
         IsShowMe: this.isShowMe
         IsShowMe: this.isShowMe
       }
       }
-      let res=null
-      if(this.chart_source === 1){
-        res=await dataBaseInterface.chartSearchByEs(params)
-      }else if(this.chart_source === 2){
-        res=await futuresInterface.searchChart(params)
-      }else if(this.chart_source === 3){
-        res=await chartRelevanceApi.searchChart(params)
-      }else if(this.chart_source === 6){
-        res=await fittingEquationInterface.searchChart(params)
-      }else if(this.chart_source === 7){
-        res=await statisticFeatureInterface.searchChart(params)
+      const apiMap = {
+        1: dataBaseInterface.chartSearchByEs,
+        2: futuresInterface.searchChart,
+        3: chartRelevanceApi.searchChart,
+        6: fittingEquationInterface.searchChart,
+        7: statisticFeatureInterface.searchChart,
+        10: crossVarietyInterface.searchChart,
       }
       }
+      let res = await apiMap[this.chart_source](params)
 
 
       if (res.Ret !== 200) return;
       if (res.Ret !== 200) return;
       res.Data.List = res.Data.List || [];
       res.Data.List = res.Data.List || [];

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

@@ -234,6 +234,7 @@
             :pptItem="pptItem"
             :pptItem="pptItem"
             :key="pptItem.PptId"
             :key="pptItem.PptId"
             @isLegal="handleIsLegal"
             @isLegal="handleIsLegal"
+            @resetToolList="setToolList"
           ></ppt-content>
           ></ppt-content>
         </div>
         </div>
         <div class="tool-side ppt-page-wrap">
         <div class="tool-side ppt-page-wrap">
@@ -518,7 +519,7 @@ export default {
       }
       }
     },
     },
     //设置操作按钮
     //设置操作按钮
-    setToolList(){
+    setToolList(pptDetail={}){
       //公共目录:显示除 删除, 编辑 外的全部按钮
       //公共目录:显示除 删除, 编辑 外的全部按钮
       if(this.treeName==='public'){
       if(this.treeName==='public'){
         this.pptToolList = toolList.filter((i)=>{
         this.pptToolList = toolList.filter((i)=>{
@@ -560,6 +561,16 @@ export default {
       this.pptToolList = this.pptToolList.filter((i)=>{
       this.pptToolList = this.pptToolList.filter((i)=>{
           return authArr.includes(i.key)
           return authArr.includes(i.key)
         })
         })
+      //若有人在编辑,则显示编辑中
+      if(this.pptToolList.find(i=>i.key==='edit')){
+        const {Editor={}} = pptDetail
+        const labelName = Editor.IsEditing?`${Editor.Editor}编辑中...`:'编辑'
+        this.pptToolList.map(i=>{
+            if(i.key==='edit'){
+                i.label = labelName
+            }
+        })
+      }  
 
 
     },
     },
     //判断公共目录按钮是否显示
     //判断公共目录按钮是否显示
@@ -688,7 +699,7 @@ export default {
       })
       })
     },
     },
     //点击操作栏事件处理
     //点击操作栏事件处理
-    handleToolClick(item){
+    async handleToolClick(item){
       const urlMap = {
       const urlMap = {
         edit:`/ppteneditor?id=${this.pptItem.PptId}`,
         edit:`/ppteneditor?id=${this.pptItem.PptId}`,
         publish:`/pptenpublish?id=${this.pptItem.PptId}`,
         publish:`/pptenpublish?id=${this.pptItem.PptId}`,
@@ -697,6 +708,15 @@ export default {
       //要跳转页面的:预览发布,编辑,演示
       //要跳转页面的:预览发布,编辑,演示
       if(urlMap[item.key]){
       if(urlMap[item.key]){
         if(!this.pptItem.overLimit||item.key!=='publish'){
         if(!this.pptItem.overLimit||item.key!=='publish'){
+            if(item.key==='edit'){
+                if(item.label.length>2){
+                    this.$message.warning("他人正在编辑中,不可重复编辑")
+                    return
+                }
+                //调接口加锁然后跳转
+                const res = await pptEnInterface.pptEditLock({PptId:Number(this.pptItem.PptId),Status:1})
+                if(res.Ret!==200) return
+            }
           window.open(urlMap[item.key],'_blank');
           window.open(urlMap[item.key],'_blank');
         }else if(item.key==='publish'){
         }else if(item.key==='publish'){
           if(!this.pptItem.overLimitHint.chartNum){
           if(!this.pptItem.overLimitHint.chartNum){

+ 23 - 12
src/views/ppt_manage/newVersion/pptEnEditor.vue

@@ -126,6 +126,7 @@
                   <el-radio :label="3" style="margin-bottom:5px">相关性图表</el-radio> 
                   <el-radio :label="3" style="margin-bottom:5px">相关性图表</el-radio> 
                   <el-radio :label="6" style="margin-bottom:5px">拟合方程曲线</el-radio>
                   <el-radio :label="6" style="margin-bottom:5px">拟合方程曲线</el-radio>
                   <el-radio :label="7" style="margin-bottom:5px">统计特征</el-radio>
                   <el-radio :label="7" style="margin-bottom:5px">统计特征</el-radio>
+                  <el-radio :label="10">跨品种分析</el-radio>
                 </el-radio-group>
                 </el-radio-group>
                 <div style="margin: 10px 0">
                 <div style="margin: 10px 0">
                   <el-checkbox v-model="isShowMe" @change="() => {search_page=1;$refs.chartListRef.scrollTop = 0;getreportlist()}">只看我的</el-checkbox>
                   <el-checkbox v-model="isShowMe" @change="() => {search_page=1;$refs.chartListRef.scrollTop = 0;getreportlist()}">只看我的</el-checkbox>
@@ -281,7 +282,7 @@ import {modelInfo,defaultPosition} from './utils/config'
 import { dataBaseInterface ,sandInterface } from "@/api/api.js";
 import { dataBaseInterface ,sandInterface } from "@/api/api.js";
 import futuresInterface from '@/api/modules/futuresBaseApi';
 import futuresInterface from '@/api/modules/futuresBaseApi';
 import chartRelevanceApi from '@/api/modules/chartRelevanceApi';
 import chartRelevanceApi from '@/api/modules/chartRelevanceApi';
-import { fittingEquationInterface,statisticFeatureInterface } from '@/api/modules/chartRelevanceApi';
+import { fittingEquationInterface,statisticFeatureInterface,crossVarietyInterface } from '@/api/modules/chartRelevanceApi';
 import pptmixin from '../mixins/pptMixins';
 import pptmixin from '../mixins/pptMixins';
 import mixins from '../mixins/mixins';
 import mixins from '../mixins/mixins';
 import layerMixins from '../mixins/layerMixins';
 import layerMixins from '../mixins/layerMixins';
@@ -729,18 +730,28 @@ export default {
           PageSize: this.search_page_sizes,
           PageSize: this.search_page_sizes,
           IsShowMe: this.isShowMe
           IsShowMe: this.isShowMe
         }
         }
-        let res=null
-        if(this.chart_source === 1){
-          res=await dataBaseInterface.chartSearchByEs(params)
-        }else if(this.chart_source === 2){
-          res=await futuresInterface.searchChart(params)
-        }else if(this.chart_source === 3){
-          res=await chartRelevanceApi.searchChart(params)
-        }else if(this.chart_source === 6){
-          res=await fittingEquationInterface.searchChart(params)
-        }else if(this.chart_source === 7){
-          res=await statisticFeatureInterface.searchChart(params)
+        // let res=null
+        // if(this.chart_source === 1){
+        //   res=await dataBaseInterface.chartSearchByEs(params)
+        // }else if(this.chart_source === 2){
+        //   res=await futuresInterface.searchChart(params)
+        // }else if(this.chart_source === 3){
+        //   res=await chartRelevanceApi.searchChart(params)
+        // }else if(this.chart_source === 6){
+        //   res=await fittingEquationInterface.searchChart(params)
+        // }else if(this.chart_source === 7){
+        //   res=await statisticFeatureInterface.searchChart(params)
+        // }
+
+        const apiMap = {
+          1: dataBaseInterface.chartSearchByEs,
+          2: futuresInterface.searchChart,
+          3: chartRelevanceApi.searchChart,
+          6: fittingEquationInterface.searchChart,
+          7: statisticFeatureInterface.searchChart,
+          10: crossVarietyInterface.searchChart,
         }
         }
+        let res = await apiMap[this.chart_source](params)
 
 
         if (res.Ret !== 200) return;
         if (res.Ret !== 200) return;
         res.Data.List = res.Data.List || [];
         res.Data.List = res.Data.List || [];

+ 1 - 0
src/views/report_manage/addreportNew.vue

@@ -197,6 +197,7 @@
 						<el-radio :label="3">相关性图表</el-radio>
 						<el-radio :label="3">相关性图表</el-radio>
 						<el-radio :label="6">拟合方程曲线</el-radio>
 						<el-radio :label="6">拟合方程曲线</el-radio>
 						<el-radio :label="7">统计特征</el-radio>
 						<el-radio :label="7">统计特征</el-radio>
+						<el-radio :label="10">跨品种分析</el-radio>
 					</el-radio-group>
 					</el-radio-group>
 					<div style="margin: 10px 0">
 					<div style="margin: 10px 0">
 						<el-checkbox v-model="isShowMe" @change="() => {search_page=1;$refs.chartListRef.scrollTop = 0;getreportlist(key_word)}">只看我的</el-checkbox>
 						<el-checkbox v-model="isShowMe" @change="() => {search_page=1;$refs.chartListRef.scrollTop = 0;getreportlist(key_word)}">只看我的</el-checkbox>

+ 3 - 0
src/views/report_manage/editChapterReport.vue

@@ -178,6 +178,7 @@
             <el-radio :label="3">相关性图表</el-radio>
             <el-radio :label="3">相关性图表</el-radio>
             <el-radio :label="6">拟合方程曲线</el-radio>
             <el-radio :label="6">拟合方程曲线</el-radio>
             <el-radio :label="7">统计特征</el-radio>
             <el-radio :label="7">统计特征</el-radio>
+            <el-radio :label="10">跨品种分析</el-radio>
           </el-radio-group>
           </el-radio-group>
           <div style="margin: 10px 0">
           <div style="margin: 10px 0">
             <el-checkbox v-model="isShowMe" @change="() => {search_page=1;$refs.chartListRef.scrollTop = 0;getreportlist(key_word)}">只看我的</el-checkbox>
             <el-checkbox v-model="isShowMe" @change="() => {search_page=1;$refs.chartListRef.scrollTop = 0;getreportlist(key_word)}">只看我的</el-checkbox>
@@ -357,6 +358,8 @@ export default {
       tabsactive: "基础信息",
       tabsactive: "基础信息",
       ticketList: [], //指标列表
       ticketList: [], //指标列表
       key_word: "",
       key_word: "",
+      newreportlist: [],
+
       // 沙盘插入 ----------start
       // 沙盘插入 ----------start
       sandTabelQuery: {
       sandTabelQuery: {
         PageSize: 13,
         PageSize: 13,

+ 1 - 0
src/views/report_manage/editreportNew.vue

@@ -197,6 +197,7 @@
 						<el-radio :label="3">相关性图表</el-radio>
 						<el-radio :label="3">相关性图表</el-radio>
 						<el-radio :label="6">拟合方程曲线</el-radio>
 						<el-radio :label="6">拟合方程曲线</el-radio>
 						<el-radio :label="7">统计特征</el-radio>
 						<el-radio :label="7">统计特征</el-radio>
+						<el-radio :label="10">跨品种分析</el-radio>
 					</el-radio-group>
 					</el-radio-group>
 					<div style="margin: 10px 0">
 					<div style="margin: 10px 0">
 						<el-checkbox v-model="isShowMe" @change="() => {search_page=1;$refs.chartListRef.scrollTop = 0;getreportlist(key_word)}">只看我的</el-checkbox>
 						<el-checkbox v-model="isShowMe" @change="() => {search_page=1;$refs.chartListRef.scrollTop = 0;getreportlist(key_word)}">只看我的</el-checkbox>

+ 71 - 13
src/views/report_manage/mixins/reportMixin.js

@@ -5,6 +5,7 @@ import chartRelevanceApi from "@/api/modules/chartRelevanceApi";
 import {
 import {
   fittingEquationInterface,
   fittingEquationInterface,
   statisticFeatureInterface,
   statisticFeatureInterface,
+  crossVarietyInterface
 } from "@/api/modules/chartRelevanceApi";
 } from "@/api/modules/chartRelevanceApi";
 export default {
 export default {
   watch:{
   watch:{
@@ -317,6 +318,7 @@ export default {
           value: chartInfo.ChartName,
           value: chartInfo.ChartName,
           key: "ChartName",
           key: "ChartName",
           id: chartInfo.ChartInfoId,
           id: chartInfo.ChartInfoId,
+          source: chartInfo.Source,
           notEdit: true,
           notEdit: true,
         },
         },
         {
         {
@@ -327,7 +329,7 @@ export default {
           placeholder: "请输入英文图表名称",
           placeholder: "请输入英文图表名称",
         }
         }
       );
       );
-      if (![3, 6, 7, 8, 9].includes(chartInfo.Source)) {
+      if ([1,2,5].includes(chartInfo.Source)) {
         this.formItemArray.chartsList = tableData.map((item) => {
         this.formItemArray.chartsList = tableData.map((item) => {
           return item.Unit
           return item.Unit
             ? [
             ? [
@@ -400,7 +402,7 @@ export default {
       }
       }
 
 
       //利润曲线
       //利润曲线
-      if (chartInfo.Source === 5) {
+      else if (chartInfo.Source === 5) {
         this.formItemArray.chartInfo.push(
         this.formItemArray.chartInfo.push(
           {
           {
             label: "盘面利润名称",
             label: "盘面利润名称",
@@ -418,6 +420,60 @@ export default {
           }
           }
         );
         );
       }
       }
+
+       //跨品种分析
+      else if(chartInfo.Source===10) {
+        let res = await crossVarietyInterface.chartLangOption({ChartInfoId: chartInfo.ChartInfoId})
+
+        const { TagList,VarietyList } = res.Data;
+
+        this.formItemArray.chartInfo.push({
+          label:'X轴名称',
+          value:Data.DataResp.XName,
+          key:'XName',
+          id:TagList[0].ChartTagId,
+          notEdit:true
+        },
+        {
+          label:'英文X轴名称',
+          value:Data.DataResp.XNameEn,
+          key:'XNameEn',
+          id:TagList[0].ChartTagId,
+          placeholder:'请输入英文X轴名称'
+        },{
+          label:'Y轴名称',
+          value:Data.DataResp.YName,
+          key:'YName',
+          id:TagList[1].ChartTagId,
+          notEdit:true
+        },
+        {
+          label:'英文Y轴名称',
+          value:Data.DataResp.YNameEn,
+          key:'YNameEn',
+          id:TagList[1].ChartTagId,
+          placeholder:'请输入英文Y轴名称'
+        })
+
+        VarietyList.forEach(item => {
+          this.formItemArray.chartsList.push([
+            {
+              label:'品种名称',
+              value:item.ChartVarietyName,
+              key:'ChartVarietyName',
+              id:item.ChartVarietyId,
+              notEdit:true
+            },
+            {
+              label:'英文品种名称',
+              value:item.ChartVarietyNameEn,
+              key:'ChartVarietyNameEn',
+              id:item.ChartVarietyId,
+              placeholder:'请输入英文品种名称'
+            }
+          ])
+        })
+      }
       this.setEnName = true;
       this.setEnName = true;
     },
     },
 
 
@@ -452,6 +508,8 @@ export default {
           ChartInfoId: enNameData.ChartInfoId,
           ChartInfoId: enNameData.ChartInfoId,
           ChartNameEn: enNameData.ChartNameEn,
           ChartNameEn: enNameData.ChartNameEn,
         });
         });
+      }else if (this.chart_source === 10) {
+        res=await crossVarietyInterface.editChartEn(enNameData)
       }
       }
 
 
       if (res.Ret !== 200) return;
       if (res.Ret !== 200) return;
@@ -471,18 +529,16 @@ export default {
         PageSize: this.search_page_sizes,
         PageSize: this.search_page_sizes,
         IsShowMe: this.isShowMe,
         IsShowMe: this.isShowMe,
       };
       };
-      let res = null;
-      if (this.chart_source === 1) {
-        res = await dataBaseInterface.chartSearchByEs(params);
-      } else if (this.chart_source === 2) {
-        res = await futuresInterface.searchChart(params);
-      } else if (this.chart_source === 3) {
-        res = await chartRelevanceApi.searchChart(params);
-      } else if (this.chart_source === 6) {
-        res = await fittingEquationInterface.searchChart(params);
-      } else if (this.chart_source === 7) {
-        res = await statisticFeatureInterface.searchChart(params);
+
+      const apiMap = {
+        1: dataBaseInterface.chartSearchByEs,
+        2: futuresInterface.searchChart,
+        3: chartRelevanceApi.searchChart,
+        6: fittingEquationInterface.searchChart,
+        7: statisticFeatureInterface.searchChart,
+        10: crossVarietyInterface.searchChart,
       }
       }
+      let res = await apiMap[this.chart_source](params)
 
 
       if (res.Ret !== 200) return;
       if (res.Ret !== 200) return;
       res.Data.List = res.Data.List || [];
       res.Data.List = res.Data.List || [];
@@ -491,6 +547,8 @@ export default {
           ? res.Data.List
           ? res.Data.List
           : [...this.newreportlist, ...res.Data.List];
           : [...this.newreportlist, ...res.Data.List];
       this.search_have_more = this.search_page < res.Data.Paging.Pages;
       this.search_have_more = this.search_page < res.Data.Paging.Pages;
+
+      console.log(this.chart_source,this.newreportlist)
     },
     },
 
 
     loadReportHandle() {
     loadReportHandle() {

+ 1 - 0
src/views/report_manage/reportEn/reportEditor.vue

@@ -203,6 +203,7 @@
 						<el-radio :label="3">相关性图表</el-radio> 
 						<el-radio :label="3">相关性图表</el-radio> 
 						<el-radio :label="6">拟合方程曲线</el-radio>
 						<el-radio :label="6">拟合方程曲线</el-radio>
 						<el-radio :label="7">统计特征</el-radio>
 						<el-radio :label="7">统计特征</el-radio>
+						<el-radio :label="10">跨品种分析</el-radio>
 					</el-radio-group>
 					</el-radio-group>
 					<div style="margin: 10px 0">
 					<div style="margin: 10px 0">
 						<el-checkbox v-model="isShowMe" @change="() => {search_page=1;$refs.chartListRef.scrollTop = 0;getreportlist(key_word)}">只看我的</el-checkbox>
 						<el-checkbox v-model="isShowMe" @change="() => {search_page=1;$refs.chartListRef.scrollTop = 0;getreportlist(key_word)}">只看我的</el-checkbox>

+ 1 - 6
src/views/sandbox_manage/common/edge.js

@@ -4,12 +4,7 @@ const { line} = configOpt;
 import store from "@/vuex/index"
 import store from "@/vuex/index"
 
 
 const styleConfig=store.state.sand.styleConfig
 const styleConfig=store.state.sand.styleConfig
-// export const myEdges = [
-// 	{
-// 		type: 'noArrowStraight',
-//     ImgUrl:'~@/assets/icons/arrow.svg'
-// 	}
-// ]
+
 /**type--类型  xP--定位点的横坐标 yP--定位点的纵坐标
 /**type--类型  xP--定位点的横坐标 yP--定位点的纵坐标
  * 创建的线条
  * 创建的线条
  * 斜直线无箭头、斜直线单项箭头、斜直线双线箭头
  * 斜直线无箭头、斜直线单项箭头、斜直线双线箭头

+ 36 - 78
src/views/sandbox_manage/common/events.js

@@ -5,13 +5,11 @@ const { line} = configOpt;
 
 
 /* 节点操作监听事件 */
 /* 节点操作监听事件 */
 export const myEvents = (graph,mindmapDataUseFun) => {
 export const myEvents = (graph,mindmapDataUseFun) => {
-		
 		/* 节点双击编辑 */
 		/* 节点双击编辑 */
 		graph.on('node:dblclick', ({ node, e }) => {
 		graph.on('node:dblclick', ({ node, e }) => {
 			// 节点当前设置的样式同步到编辑区
 			// 节点当前设置的样式同步到编辑区
 
 
 			const { text, rect} = node.attrs;
 			const { text, rect} = node.attrs;
-			// console.log(node,'nodenode');
 			const edit_area = document.createElement('div');
 			const edit_area = document.createElement('div');
 			edit_area.contentEditable = "true";
 			edit_area.contentEditable = "true";
 			edit_area.id = "editable-wrapper";
 			edit_area.id = "editable-wrapper";
@@ -23,25 +21,14 @@ export const myEvents = (graph,mindmapDataUseFun) => {
 
 
 			const position = node.position();
 			const position = node.position();
       const size = node.size();
       const size = node.size();
-			// console.log(position,size);
-      // const pos = graph.localToClient(position);
       const pos = graph.localToGraph(position);
       const pos = graph.localToGraph(position);
       const zoom = graph.zoom();
       const zoom = graph.zoom();
       let width = size.width,height = size.height;
       let width = size.width,height = size.height;
 
 
-			// const edit_area =  $('#editable-wrapper')[0];
-			// if(node.shape.indexOf('mindmap')!==-1){
-
-			// 	edit_area.innerText = text.text
-			// 	node.attr('text/text', '');
-			// }else{
-				edit_area.innerText = text.text || text.textWrap.text || ' ';
-				// 开启editText的事务 
-				graph.startBatch('editText')
-				node.attr('text/textWrap/text', '');
-				
-			// }
-
+			edit_area.innerText = text.text || text.textWrap.text || ' ';
+			// 开启editText的事务 
+			graph.startBatch('editText')
+			node.attr('text/textWrap/text', '');
 
 
 			edit_area.style.left = `${pos.x}px`;
 			edit_area.style.left = `${pos.x}px`;
 			edit_area.style.top = `${pos.y}px`;
 			edit_area.style.top = `${pos.y}px`;
@@ -68,15 +55,12 @@ export const myEvents = (graph,mindmapDataUseFun) => {
 			edit_area.oninput = () => {
 			edit_area.oninput = () => {
 				const domH = (edit_area.getBoundingClientRect().height) /zoom;
 				const domH = (edit_area.getBoundingClientRect().height) /zoom;
 				node.size(width,domH > 50 ? domH : 50);
 				node.size(width,domH > 50 ? domH : 50);
-				// node.size(width,domH > height ? domH : height);
-
 			}
 			}
 
 
 			//失焦后设置内容
 			//失焦后设置内容
 			edit_area.onblur = () => {
 			edit_area.onblur = () => {
 				let newval = edit_area.innerText.replace(/(\n[\s\t]*\r*\n)/g,'\n');
 				let newval = edit_area.innerText.replace(/(\n[\s\t]*\r*\n)/g,'\n');
 
 
-				// console.log(node.shape,'edit_area');
 
 
 				node.attr('text/textWrap/text', newval);
 				node.attr('text/textWrap/text', newval);
 				node.attr('text/text', newval);
 				node.attr('text/text', newval);
@@ -84,7 +68,8 @@ export const myEvents = (graph,mindmapDataUseFun) => {
 				graph.stopBatch('editText')
 				graph.stopBatch('editText')
 
 
 				if(node.shape.indexOf('mindmap')!==-1){
 				if(node.shape.indexOf('mindmap')!==-1){
-					const mindmapDataUse=mindmapDataUseFun()
+					if(!mindmapDataUseFun) return 
+					const mindmapDataUse=mindmapDataUseFun().mindmapDataUse
 					let ids = node.id.split('-')
 					let ids = node.id.split('-')
 					let mindmapDataIndex = mindmapDataUse.findIndex(mindmap => mindmap.mindmapData.id == ids[0])
 					let mindmapDataIndex = mindmapDataUse.findIndex(mindmap => mindmap.mindmapData.id == ids[0])
 					let mindMapDataCurrent = mindmapDataUse[mindmapDataIndex]?mindmapDataUse[mindmapDataIndex].mindmapData:{}
 					let mindMapDataCurrent = mindmapDataUse[mindmapDataIndex]?mindmapDataUse[mindmapDataIndex].mindmapData:{}
@@ -97,23 +82,15 @@ export const myEvents = (graph,mindmapDataUseFun) => {
 					}
 					}
 					mindMapDataCurrent.label = newval
 					mindMapDataCurrent.label = newval
 				}
 				}
-				if(node.shape.indexOf('mindmap')==-1){
-					const domH = (edit_area.getBoundingClientRect().height) /zoom;
-					node.size(width,domH > 50 ? domH : 50);
-					// node.size(width,domH);
-				}else{
-					const domH = (edit_area.getBoundingClientRect().height) /zoom;
-					// node.size(width,domH);
-					node.size(width,domH > 50 ? domH : 50);
-					// node.fit({ deep: true })
-				}
+
+				const domH = (edit_area.getBoundingClientRect().height) /zoom;
+				node.size(width,domH > 50 ? domH : 50);
 
 
 				$('#sand-chart-container')[0].removeChild(edit_area);
 				$('#sand-chart-container')[0].removeChild(edit_area);
 			}
 			}
 		})
 		})
 		/* 鼠标移入移出控制连接桩 */
 		/* 鼠标移入移出控制连接桩 */
 		graph.on('node:mouseenter', ({ node, e }) => {
 		graph.on('node:mouseenter', ({ node, e }) => {
-			// console.log(node)
 			for(let i of document.querySelectorAll(`g[data-cell-id="${node.id}"] .x6-port-body`)) {
 			for(let i of document.querySelectorAll(`g[data-cell-id="${node.id}"] .x6-port-body`)) {
 				i.style.display = 'block'
 				i.style.display = 'block'
 			}
 			}
@@ -135,7 +112,6 @@ export const myEvents = (graph,mindmapDataUseFun) => {
 
 
 		/* 选中事件 */
 		/* 选中事件 */
 		// graph.on('cell:selected',({cell,options}) => {
 		// graph.on('cell:selected',({cell,options}) => {
-		// 	// console.log(cell)
 		// 	//节点
 		// 	//节点
 		// 	if(cell.shape === 'rect') {
 		// 	if(cell.shape === 'rect') {
 		// 		const { key } = cell.data;
 		// 		const { key } = cell.data;
@@ -174,21 +150,16 @@ export const myEvents = (graph,mindmapDataUseFun) => {
 		// })
 		// })
 
 
 		const changeSelection=_.debounce((selected)=> {
 		const changeSelection=_.debounce((selected)=> {
-			// console.log(selected,'selected');
 			store.commit('sand/SET_SELECT_CELLS',selected)
 			store.commit('sand/SET_SELECT_CELLS',selected)
 		},50)
 		},50)
 
 
 		/* 监听选中事件 */
 		/* 监听选中事件 */
 		graph.on('selection:changed',({selected}) => {
 		graph.on('selection:changed',({selected}) => {
-			// console.log(selected,'选中修改');
-			// selected.length ? store.commit('sand/SET_SELECT_CELL',selected[0]) : store.commit('sand/SET_SELECT_CELL',null);
 			changeSelection(selected)
 			changeSelection(selected)
 		})
 		})
 
 
 		/* 监听选中事件 */
 		/* 监听选中事件 */
 		graph.on('edge:mouseenter', ({ cell }) => {
 		graph.on('edge:mouseenter', ({ cell }) => {
-			// console.log(cell,'myEdgeOption');
-			// console.log(cell.store.data);
 			if(cell.store.data.shape=="mindmap-edge"){
 			if(cell.store.data.shape=="mindmap-edge"){
 				// 思维导图的边
 				// 思维导图的边
 			}else{
 			}else{
@@ -236,11 +207,10 @@ export const myEvents = (graph,mindmapDataUseFun) => {
 }
 }
 
 
 /* 绑定键盘事件 */
 /* 绑定键盘事件 */
-export const bindKey = (graph,mindmapDataUseFun,mindmapAssistData) => {
+export const bindKey = (graph,mindmapDataUseFun) => {
 	 // 删除
 	 // 删除
 	graph.bindKey(['delete', 'backspace'], () => {
 	graph.bindKey(['delete', 'backspace'], () => {
-		const mindmapDataUse=mindmapDataUseFun()
-		deleteNodes(graph,mindmapDataUse,mindmapAssistData)
+		deleteNodes(graph,mindmapDataUseFun)
 		return false
 		return false
 	}, 'keydown');
 	}, 'keydown');
 
 
@@ -278,27 +248,20 @@ export const bindKey = (graph,mindmapDataUseFun,mindmapAssistData) => {
 }
 }
 
 
 /* 右键事件 */
 /* 右键事件 */
-export const contextEvent = (graph,key,mindmapDataUse,mindmapAssistData) => {
-	// console.log(key)
+export const contextEvent = (graph,key,mindmapDataUseFun) => {
 	switch (key) {
 	switch (key) {
 		case 'copy':
 		case 'copy':
 			nodeCopyAndPaste(graph);
 			nodeCopyAndPaste(graph);
 			break;
 			break;
 		case 'del': 
 		case 'del': 
-			nodeDelete(graph,mindmapDataUse,mindmapAssistData);
+			deleteNodes(graph,mindmapDataUseFun);
 			break;
 			break;
 	}
 	}
 }
 }
 
 
-/* 删除节点 清空选区*/
-const nodeDelete = (graph,mindmapDataUse,mindmapAssistData) => {
-	deleteNodes(graph,mindmapDataUse,mindmapAssistData)
-}
 /* 复制粘贴节点 */
 /* 复制粘贴节点 */
 const nodeCopyAndPaste = (graph) => {
 const nodeCopyAndPaste = (graph) => {
 	const select_cell = graph.getSelectedCells();
 	const select_cell = graph.getSelectedCells();
-	// console.log(select_cell)
-	// return
 	if (select_cell.length) {
 	if (select_cell.length) {
 		graph.copy(select_cell);
 		graph.copy(select_cell);
 		const copy_cell = graph.paste({ offset: 30 });
 		const copy_cell = graph.paste({ offset: 30 });
@@ -309,7 +272,6 @@ const nodeCopyAndPaste = (graph) => {
 
 
 /* 关联三种基础图形选中样式 */
 /* 关联三种基础图形选中样式 */
 // const setSelectedOptions = ({ rect, text }, key) => {
 // const setSelectedOptions = ({ rect, text }, key) => {
-// 	console.log({ rect, text },'{ rect, text }',key);
 // 	return ['rect','date'].includes(key) ? {
 // 	return ['rect','date'].includes(key) ? {
 // 		text: { //文本设置
 // 		text: { //文本设置
 // 			size: text.fontSize,
 // 			size: text.fontSize,
@@ -332,13 +294,19 @@ const nodeCopyAndPaste = (graph) => {
 // 	}: {}
 // 	}: {}
 // }
 // }
 
 
-const deleteNodes=(graph,mindmapDataUse,mindmapAssistData)=>{
-	console.log(mindmapDataUse,mindmapAssistData,'最源数据');
+const deleteNodes=(graph,mindmapDataUseFun)=>{
 	const select_cell = graph.getSelectedCells();
 	const select_cell = graph.getSelectedCells();
 	let delete_cells=[]
 	let delete_cells=[]
+	if(!mindmapDataUseFun){
+		delete_cells = select_cell
+		if (delete_cells.length) {
+			// 移除工具
+			delete_cells.forEach(item => item.removeTools());
+			graph.removeCells(delete_cells)
+		}
+		return 
+	}
 	let mindmapCell=[]
 	let mindmapCell=[]
-	// return 
-	// console.log(select_cell.length,'select_cell.length');
 	for (let i = 0; i < select_cell.length; i++) {
 	for (let i = 0; i < select_cell.length; i++) {
 		const cell = select_cell[i];
 		const cell = select_cell[i];
 		if(cell.shape == "mindmap-edge"){
 		if(cell.shape == "mindmap-edge"){
@@ -347,63 +315,53 @@ const deleteNodes=(graph,mindmapDataUse,mindmapAssistData)=>{
 			mindmapCell.push(cell)
 			mindmapCell.push(cell)
 			// 拿到该节点的所有子节点
 			// 拿到该节点的所有子节点
 			let Successors = graph.getSuccessors(cell) 
 			let Successors = graph.getSuccessors(cell) 
-			// console.log(Successors,'Successors');
 			mindmapCell = [...mindmapCell,...Successors]
 			mindmapCell = [...mindmapCell,...Successors]
 		}
 		}
 		delete_cells.push(cell)
 		delete_cells.push(cell)
 	}
 	}
 	// 去重
 	// 去重
 	const uniqueArr = mindmapCell.filter((item, index) => mindmapCell.findIndex(i => i.id === item.id) === index);
 	const uniqueArr = mindmapCell.filter((item, index) => mindmapCell.findIndex(i => i.id === item.id) === index);
-	// console.log(uniqueArr,'uniqueArr');
 
 
 	delete_cells = [...delete_cells,...uniqueArr]
 	delete_cells = [...delete_cells,...uniqueArr]
-	// return 
 	if (delete_cells.length) {
 	if (delete_cells.length) {
 		// 移除工具
 		// 移除工具
 		delete_cells.forEach(item => item.removeTools());
 		delete_cells.forEach(item => item.removeTools());
 		graph.removeCells(delete_cells)
 		graph.removeCells(delete_cells)
 	}
 	}
+	const mindmapAssistData = mindmapDataUseFun()
+
 	let shouldOperations=[]
 	let shouldOperations=[]
-	mindmapDataUse.map((item,index)=>{
+	mindmapAssistData.mindmapDataUse.map((item,index)=>{
 		let levelIds = uniqueArr.filter(mindMap => mindMap.id.startsWith(item.mindmapData.id)).map(mindMap => mindMap.id)
 		let levelIds = uniqueArr.filter(mindMap => mindMap.id.startsWith(item.mindmapData.id)).map(mindMap => mindMap.id)
-		// console.log(levelIds,'levelIds');
 		if(!(levelIds && levelIds.length>0)) return 
 		if(!(levelIds && levelIds.length>0)) return 
-		// console.log(levelIds,'levelIds');
 		let mindMapIds=[...levelIds]
 		let mindMapIds=[...levelIds]
 		for (let i = 0; i < levelIds.length; i++) {
 		for (let i = 0; i < levelIds.length; i++) {
 			const element = levelIds[i]
 			const element = levelIds[i]
 			mindMapIds=mindMapIds.filter( id => id.indexOf(element) !=0 || id==element)
 			mindMapIds=mindMapIds.filter( id => id.indexOf(element) !=0 || id==element)
 		}
 		}
-		// console.log(mindMapIds,'mindMapIds');
 		shouldOperations.push(mindMapIds)
 		shouldOperations.push(mindMapIds)
 	})
 	})
-	// 删除前备份
-	console.log(mindmapDataUse,'元数据');
-	mindmapAssistData.mindmapDataRecoverUse=[JSON.stringify(mindmapDataUse)]
 
 
-	console.log('删除备份',JSON.parse(mindmapAssistData.mindmapDataRecoverUse[0]),mindmapAssistData.mindmapDataRecoverUse.length,mindmapAssistData.mindmapDataRecoverUse);
-	
-	// console.log(shouldOperations,'shouldOperations');
+	mindmapAssistData.deletedMindmapData.push([])
 	shouldOperations.map(it =>{
 	shouldOperations.map(it =>{
 		it.map(it1 =>{
 		it.map(it1 =>{
-			deleteMindmapData(it1,mindmapDataUse)
+			deleteMindmapData(it1,mindmapAssistData)
 		})
 		})
 	})
 	})
-	// console.log(mindmapDataUse,'mindmapDataUse',mindmapAssistData,'mindmapAssistData');
-
 }
 }
 
 
 const deleteMindmapData=(id,data)=>{
 const deleteMindmapData=(id,data)=>{
-	// console.log(id,data,'id,data');
-	// return 
+
 	let ids = id.split('-')
 	let ids = id.split('-')
-	let mindmapDataIndex = data.findIndex(mindmap => mindmap.mindmapData.id == ids[0])
+	let mindmapDataIndex = data.mindmapDataUse.findIndex(mindmap => mindmap.mindmapData.id == ids[0])
 	if(ids.length==1){
 	if(ids.length==1){
-		data.splice(mindmapDataIndex,1)
+		let spliceData=data.mindmapDataUse.splice(mindmapDataIndex,1)
+		// 备份删除掉的数据
+		data.deletedMindmapData[data.deletedMindmapData.length-1].push(spliceData)
 		return 
 		return 
 	}
 	}
 
 
-	let mindmapData = data[mindmapDataIndex].mindmapData
+	let mindmapData = data.mindmapDataUse[mindmapDataIndex].mindmapData
 	let findId = ids[0]
 	let findId = ids[0]
 	for (let i = 1; i < ids.length-1; i++) {
 	for (let i = 1; i < ids.length-1; i++) {
 		const element = ids[i];
 		const element = ids[i];
@@ -418,6 +376,6 @@ const deleteMindmapData=(id,data)=>{
 		return 
 		return 
 	}
 	}
 	let endIndex = mindmapData.children.findIndex(it => it.id == findId+'-'+endId)
 	let endIndex = mindmapData.children.findIndex(it => it.id == findId+'-'+endId)
-	mindmapData.children.splice(endIndex,1)
-	// console.log(data);
+	let spliceData=mindmapData.children.splice(endIndex,1)
+	data.deletedMindmapData[data.deletedMindmapData.length-1].push(spliceData)
 }
 }

+ 3 - 5
src/views/sandbox_manage/common/gragh.js

@@ -2,12 +2,11 @@ import { Graph,Shape } from '@antv/x6';
 import { bindKey,myEvents } from './events';
 import { bindKey,myEvents } from './events';
 import { configOpt } from './toolConfig';
 import { configOpt } from './toolConfig';
 import store from '@/vuex/index'
 import store from '@/vuex/index'
-console.log(store,'store');
 const styleConfig=store.state.sand.styleConfig
 const styleConfig=store.state.sand.styleConfig
 
 
 const { line } = configOpt;
 const { line } = configOpt;
 // wrapper DOM的Id mindmapDataUseFun 返回思维导图数组函数,传递给事件 type 模式,编辑和查看
 // wrapper DOM的Id mindmapDataUseFun 返回思维导图数组函数,传递给事件 type 模式,编辑和查看
-export function myGraph (wrapper,mindmapDataUseFun,mindmapAssistData,type='edit') {
+export function myGraph (wrapper,mindmapDataUseFun,type='edit') {
 	const graph = new Graph({
 	const graph = new Graph({
 		container: document.getElementById(wrapper),
 		container: document.getElementById(wrapper),
 		// width: $(window).width(),
 		// width: $(window).width(),
@@ -15,7 +14,6 @@ export function myGraph (wrapper,mindmapDataUseFun,mindmapAssistData,type='edit'
 		history:{
 		history:{
 			enabled:true,
 			enabled:true,
 			beforeAddCommand(event, args){
 			beforeAddCommand(event, args){
-				console.log(event, args,'event, args');
 				if(args.key=='tools'){
 				if(args.key=='tools'){
 					// 工具的改变不加入撤销和重做的队列
 					// 工具的改变不加入撤销和重做的队列
 					return false
 					return false
@@ -61,7 +59,7 @@ export function myGraph (wrapper,mindmapDataUseFun,mindmapAssistData,type='edit'
 			visible: false,
 			visible: false,
 		},
 		},
 		highlighting: {
 		highlighting: {
-			// 当链接桩可以被链接时,在链接桩外围渲染一个 2px 宽的色矩形框
+			// 当链接桩可以被链接时,在链接桩外围渲染一个 2px 宽的天蓝色矩形框
 			magnetAvailable: {
 			magnetAvailable: {
 					name: "stroke",
 					name: "stroke",
 					args: {
 					args: {
@@ -150,7 +148,7 @@ export function myGraph (wrapper,mindmapDataUseFun,mindmapAssistData,type='edit'
 	
 	
 
 
 	/* 键盘事件 */
 	/* 键盘事件 */
-	if(type!='view') bindKey(graph,mindmapDataUseFun,mindmapAssistData);
+	if(type!='view') bindKey(graph,mindmapDataUseFun);
 
 
 	return graph;
 	return graph;
 }
 }

+ 223 - 108
src/views/sandbox_manage/common/mindmap.js

@@ -7,7 +7,12 @@ export default {
       mindMapDataCurrent:{},
       mindMapDataCurrent:{},
       positionCurrent:{},
       positionCurrent:{},
       addTypeCurrent:'',
       addTypeCurrent:'',
-      styleConfig:{}
+      styleConfig:{},
+      mindmapAssistData:{
+        mindmapDataUse:[],
+        deletedMindmapData:[],// 用于撤销删除,恢复删除掉的数据
+        mindmapDataRecoverUse:[],//用于 重做时 恢复思维导图数据
+      },
     }
     }
   },
   },
   mounted() {
   mounted() {
@@ -15,7 +20,6 @@ export default {
   },
   },
   created() {
   created() {
     this.styleConfig=this.$store.state.sand.styleConfig
     this.styleConfig=this.$store.state.sand.styleConfig
-    // console.log(this.styleConfig,'this.styleConfig');
     // 中心主题
     // 中心主题
     Graph.registerNode(
     Graph.registerNode(
       'mindmap-topic',          
       'mindmap-topic',          
@@ -43,8 +47,6 @@ export default {
           body: {
           body: {
             rx: 6,
             rx: 6,
             ry: 6,
             ry: 6,
-            // stroke: this.$store.state.sand.styleConfig.borderColor,
-            // fill: this.$store.state.sand.styleConfig.backgroundColor,
             strokeWidth: 1,
             strokeWidth: 1,
             width:100,
             width:100,
             height:50
             height:50
@@ -111,8 +113,6 @@ export default {
           body: {
           body: {
             rx: 6,
             rx: 6,
             ry: 6,
             ry: 6,
-            // stroke: this.$store.state.sand.styleConfig.borderColor,
-            // fill: this.$store.state.sand.styleConfig.backgroundColor,
             strokeWidth: 1,
             strokeWidth: 1,
             width:100,
             width:100,
             height:50
             height:50
@@ -167,8 +167,6 @@ export default {
           body: {
           body: {
             rx: 6,
             rx: 6,
             ry: 6,
             ry: 6,
-            // stroke: this.$store.state.sand.styleConfig.borderColor,
-            // fill: this.$store.state.sand.styleConfig.backgroundColor,
             strokeWidth: 1,
             strokeWidth: 1,
             width:100,
             width:100,
             height:50
             height:50
@@ -196,53 +194,12 @@ export default {
       },
       },
       true,
       true,
     )
     )
-    // 分支主题
-    // Graph.registerNode(
-    //   'mindmap-topic-child',
-    //   {
-    //     inherit: 'rect',
-    //     markup: [
-    //       {
-    //         tagName: 'rect',
-    //         selector: 'body',
-    //       },
-    //       {
-    //         tagName: 'text',
-    //         selector: 'text',
-    //       },
-    //       {
-    //         tagName: 'path',
-    //         selector: 'line',
-    //       },
-    //     ],
-    //     attrs: {
-    //       body: {
-    //         fill: '#ffffff',
-    //         strokeWidth: 0,
-    //         stroke: '#5F95FF',
-    //       },
-    //       text: {
-    //         fontSize: 14,
-    //         fill: '#262626',
-    //         textVerticalAnchor: 'bottom',
-    //       },
-    //       line: {
-    //         stroke: '#5F95FF',
-    //         strokeWidth: 2,
-    //         d: 'M 0 15 L 60 15',
-    //       },
-    //     },
-    //   },
-    //   true,
-    // )
-
     // 连接器
     // 连接器
     Graph.registerConnector(
     Graph.registerConnector(
       'mindmap',
       'mindmap',
       (sourcePoint, targetPoint, routerPoints, options) => {
       (sourcePoint, targetPoint, routerPoints, options) => {
-        // console.log(sourcePoint, targetPoint, routerPoints, options,'sourcePoint, targetPoint, routerPoints, options');
         const midX = sourcePoint.x + 10
         const midX = sourcePoint.x + 10
-        const midY = sourcePoint.y
+        // const midY = sourcePoint.y
         const ctrX = (targetPoint.x - midX) / 5 + midX
         const ctrX = (targetPoint.x - midX) / 5 + midX
         const ctrY = targetPoint.y
         const ctrY = targetPoint.y
         const pathData = `
         const pathData = `
@@ -265,7 +222,6 @@ export default {
         attrs: {
         attrs: {
           line: {
           line: {
             targetMarker: false,
             targetMarker: false,
-            // stroke: this.$store.state.sand.styleConfig.lineColor,
             strokeWidth: 2,
             strokeWidth: 2,
           },
           },
         },
         },
@@ -276,6 +232,7 @@ export default {
   },
   },
   methods: {
   methods: {
     setGraph(){
     setGraph(){
+      // 添加左边节点
       this.graph.on('add:topic:left', ({ node }) => {
       this.graph.on('add:topic:left', ({ node }) => {
         if(this.operationType=='view') return 
         if(this.operationType=='view') return 
         const { id } = node
         const { id } = node
@@ -285,7 +242,7 @@ export default {
           this.mindMapRender()      
           this.mindMapRender()      
         }
         }
       })
       })
-
+      // 添加右边节点
       this.graph.on('add:topic:right', ({ node }) => {
       this.graph.on('add:topic:right', ({ node }) => {
         if(this.operationType=='view') return 
         if(this.operationType=='view') return 
         const { id } = node
         const { id } = node
@@ -295,12 +252,13 @@ export default {
           this.mindMapRender()      
           this.mindMapRender()      
         }
         }
       })
       })
+      // 改变大小 - 更新数据源
       this.graph.on('node:change:size', (args) => { 
       this.graph.on('node:change:size', (args) => { 
         if(this.operationType=='view') return 
         if(this.operationType=='view') return 
         if(args.node.shape.indexOf('mindmap')!==-1){
         if(args.node.shape.indexOf('mindmap')!==-1){
           let ids = args.node.id.split('-')
           let ids = args.node.id.split('-')
-					let mindmapDataIndex = this.mindmapDataUse.findIndex(mindmap => mindmap.mindmapData.id == ids[0])
-					let mindMapDataCurrent = this.mindmapDataUse[mindmapDataIndex]?this.mindmapDataUse[mindmapDataIndex].mindmapData:{}
+					let mindmapDataIndex = this.mindmapAssistData.mindmapDataUse.findIndex(mindmap => mindmap.mindmapData.id == ids[0])
+					let mindMapDataCurrent = this.mindmapAssistData.mindmapDataUse[mindmapDataIndex]?this.mindmapAssistData.mindmapDataUse[mindmapDataIndex].mindmapData:{}
 
 
 					let findId = ids[0]
 					let findId = ids[0]
 
 
@@ -314,39 +272,19 @@ export default {
 					mindMapDataCurrent.height = args.node.size().height
 					mindMapDataCurrent.height = args.node.size().height
         }
         }
       })
       })
+      // 改变位置 - 更新数据源
       this.graph.on('node:change:position', (args) => { 
       this.graph.on('node:change:position', (args) => { 
         if(this.operationType=='view') return 
         if(this.operationType=='view') return 
         if(args.node.shape.indexOf('mindmap')!==-1 && Number(args.node.id)){
         if(args.node.shape.indexOf('mindmap')!==-1 && Number(args.node.id)){
 
 
-          let index = this.mindmapDataUse.findIndex(it =>it.mindmapData.id == args.node.id)
-          // let index = Number(args.node.id)
+          let index = this.mindmapAssistData.mindmapDataUse.findIndex(it =>it.mindmapData.id == args.node.id)
           if(index!=-1){
           if(index!=-1){
-            this.mindmapDataUse[index].position = args.current
-          // this.setCurrent(args.node.id)
+            this.mindmapAssistData.mindmapDataUse[index].position = args.current
           }
           }
         }
         }
       })
       })
-      // this.graph.on('node:added', ({node}) => { 
-      //   if(node.shape.indexOf('mindmap')!=-1){
-      //     // 思维导图需要处理相对应的数据
-      //     console.log('mindmap',node.id);
-      //   }
-      //   console.log(node,'node:added');
-      // })
-      // this.graph.on('node:removed', (args) => { 
-      //   console.log(args,'node:removed');
-      // })
-      // this.graph.bindKey(['backspace', 'delete'], () => {
-      //   const selectedNodes = this.graph.getSelectedCells().filter((item) => item.isNode())
-      //   if (selectedNodes.length) {
-      //     const { id } = selectedNodes[0]
-      //     if (this.removeNode(id)) {
-      //       this.mindMapRender()
-      //     }
-      //   }
-      // })
-      
-      this.graph.bindKey('tab', (e) => {  
+      // tab 键添加节点-右边的 - 更新数据源
+      this.graph.bindKey('tab', (e) => {
         if(this.operationType=='view') return 
         if(this.operationType=='view') return 
         e.preventDefault()
         e.preventDefault()
         const selectedNodes = this.graph.getSelectedCells().filter((item) => {
         const selectedNodes = this.graph.getSelectedCells().filter((item) => {
@@ -362,20 +300,88 @@ export default {
           }
           }
         }
         }
       })
       })
+      // 撤销 - 入栈
+      this.graph.history.on('undo', (args) => { 
+        let mindmapNodes=args.cmds.filter(it => it.data.props && it.data.props.shape.indexOf('mindmap')!=-1 && it.data.node)
+        if(!(mindmapNodes && mindmapNodes.length>0)) return 
+        let mindmapUndoType=mindmapNodes[0].event
+        
+        if(mindmapUndoType=="cell:added"){
+          this.mindmapDeleteRecordPush(mindmapNodes)
+        }else if(mindmapUndoType=="cell:removed"){
+          this.mindmapAddRecordPush()
+        }
+      })
+      // 重做,出栈
+      this.graph.history.on('redo', (args) => { 
+        let mindmapNodes=args.cmds.filter(it => it.data.props && it.data.props.shape.indexOf('mindmap')!=-1 && it.data.node)
+        if(!(mindmapNodes && mindmapNodes.length>0)) return
+        this.mindmapRecover()
+      })
+    },
+    // 生成思维导图初始化数据
+    generateMindmapData(position,addType){
+      let beId=this.mindmapAssistData.mindmapDataUse.length>0?
+      parseInt(this.mindmapAssistData.mindmapDataUse[this.mindmapAssistData.mindmapDataUse.length-1].mindmapData.id)+1+'':'1'
+      let mindmapData={
+        id: beId,
+        type: 'topic',
+        label: '中心主题',
+        width: 160,
+        height: 50,
+        direction:'double',
+        children: [
+          {
+            id: beId+'-1',
+            type: 'topic-branch',
+            label: '分支主题1',
+            width: 100,
+            height: 40,
+            direction:'left',
+            children: [
+              {
+                id: beId+'-1-1',
+                type: 'topic-child',
+                label: '子主题1',
+                width: 60,
+                height: 30,
+                direction:'left',
+              },
+              {
+                id: beId+'-1-2',
+                type: 'topic-child',
+                label: '子主题2',
+                width: 60,
+                height: 30,
+                direction:'left',
+              },
+            ],
+          },
+          {
+            id: beId+'-2',
+            type: 'topic-branch',
+            label: '分支主题2',
+            width: 100,
+            height: 40,
+            direction:'right',
+          },
+        ],
+      }
+      this.mindmapAssistData.mindmapDataUse.push({mindmapData,position,addType})
     },
     },
     // 通过id设置当前操作的思维导图
     // 通过id设置当前操作的思维导图
     setCurrent(id){
     setCurrent(id){
       let rootId = id.split('-')[0]
       let rootId = id.split('-')[0]
-      let index = this.mindmapDataUse.findIndex(it =>it.mindmapData.id == rootId)
-      this.mindMapDataCurrent = this.mindmapDataUse[index]?this.mindmapDataUse[index].mindmapData:{}
-      this.positionCurrent = this.mindmapDataUse[index]?this.mindmapDataUse[index].position:{x:0,y:0}
-      this.addTypeCurrent = this.mindmapDataUse[index]?this.mindmapDataUse[index].addType:'singleMindmap'
+      let index = this.mindmapAssistData.mindmapDataUse.findIndex(it =>it.mindmapData.id == rootId)
+      this.mindMapDataCurrent = this.mindmapAssistData.mindmapDataUse[index]?this.mindmapAssistData.mindmapDataUse[index].mindmapData:{}
+      this.positionCurrent = this.mindmapAssistData.mindmapDataUse[index]?this.mindmapAssistData.mindmapDataUse[index].position:{x:0,y:0}
+      this.addTypeCurrent = this.mindmapAssistData.mindmapDataUse[index]?this.mindmapAssistData.mindmapDataUse[index].addType:'singleMindmap'
     },
     },
     mindMapRender(i){
     mindMapRender(i){
       this.graph.startBatch('renderMindmap')
       this.graph.startBatch('renderMindmap')
-      let mindMapType = i || i==0?this.mindmapDataUse[i].addType:this.addTypeCurrent
-      this.mindMapDataCurrent = i || i==0?this.mindmapDataUse[i].mindmapData:this.mindMapDataCurrent
-      this.positionCurrent = i || i==0?this.mindmapDataUse[i].position:this.positionCurrent
+      let mindMapType = i || i==0?this.mindmapAssistData.mindmapDataUse[i].addType:this.addTypeCurrent
+      this.mindMapDataCurrent = i || i==0?this.mindmapAssistData.mindmapDataUse[i].mindmapData:this.mindMapDataCurrent
+      this.positionCurrent = i || i==0?this.mindmapAssistData.mindmapDataUse[i].position:this.positionCurrent
       const result = Hierarchy.mindmap(this.mindMapDataCurrent, {
       const result = Hierarchy.mindmap(this.mindMapDataCurrent, {
         direction: 'H',
         direction: 'H',
         getHeight(d) {
         getHeight(d) {
@@ -397,14 +403,11 @@ export default {
       const cells = []
       const cells = []
       let xGap = this.positionCurrent?this.positionCurrent.x-result.x:0
       let xGap = this.positionCurrent?this.positionCurrent.x-result.x:0
       let yGap = this.positionCurrent?this.positionCurrent.y-result.y:0
       let yGap = this.positionCurrent?this.positionCurrent.y-result.y:0
-      // console.log(result,'result');
-      // return 
+
       const traverse = (hierarchyItem) => {
       const traverse = (hierarchyItem) => {
         if (hierarchyItem) {
         if (hierarchyItem) {
           const { data, children } = hierarchyItem
           const { data, children } = hierarchyItem
-          // console.log(hierarchyItem,'hierarchyItemhierarchyItemhierarchyItem');
           let mindmapDirection = mindMapType.indexOf('double') != -1?data.direction:'right'
           let mindmapDirection = mindMapType.indexOf('double') != -1?data.direction:'right'
-          // console.log(mindmapDirection,data.label,data.direction);
           let currentCell=this.graph.getCellById(data.id)
           let currentCell=this.graph.getCellById(data.id)
 
 
           if(!currentCell){
           if(!currentCell){
@@ -434,7 +437,6 @@ export default {
             // 有,更新下位置信息
             // 有,更新下位置信息
             currentCell.position(xGap+hierarchyItem.x,yGap+hierarchyItem.y)
             currentCell.position(xGap+hierarchyItem.x,yGap+hierarchyItem.y)
           }
           }
-          // return 
    
    
           if (children) {
           if (children) {
             children.forEach((item) => {
             children.forEach((item) => {
@@ -477,13 +479,10 @@ export default {
       traverse(result)
       traverse(result)
       // 排下序,把边放最后面 不然 边 会找不到 节点
       // 排下序,把边放最后面 不然 边 会找不到 节点
       let sortCells = cells.sort(cell => cell.shape.indexOf('edge'))
       let sortCells = cells.sort(cell => cell.shape.indexOf('edge'))
-      // console.log(sortCells,'result');
-      // return 
-      // this.graph.removeCells(sortCells)
+
       this.graph.addCell(sortCells)
       this.graph.addCell(sortCells)
       this.graph.stopBatch('renderMindmap')
       this.graph.stopBatch('renderMindmap')
-      // this.graph.resetCells(cells)
-      // this.graph.centerContent()
+
     },
     },
     findItem(obj,id){
     findItem(obj,id){
       if (obj.id === id) {
       if (obj.id === id) {
@@ -507,16 +506,13 @@ export default {
       return null
       return null
     },
     },
     addChildNode (id, type,direction='left'){
     addChildNode (id, type,direction='left'){
-      console.log('添加');
       // 重做不了 清空重做栈
       // 重做不了 清空重做栈
       this.mindmapAssistData.mindmapDataRecoverUse = []
       this.mindmapAssistData.mindmapDataRecoverUse = []
-      // console.log(this.mindmapAssistData);
 
 
       const res = this.findItem(this.mindMapDataCurrent, id)
       const res = this.findItem(this.mindMapDataCurrent, id)
       const dataItem = res && res.node
       const dataItem = res && res.node
       if (dataItem) {
       if (dataItem) {
         let item = null
         let item = null
-        // console.log(dataItem.children);
         let addId ='1'
         let addId ='1'
         if(dataItem.children && dataItem.children.length>0){
         if(dataItem.children && dataItem.children.length>0){
           let ids = dataItem.children[dataItem.children.length-1].id.split('-')
           let ids = dataItem.children[dataItem.children.length-1].id.split('-')
@@ -552,15 +548,134 @@ export default {
       }
       }
       return null
       return null
     },
     },
-    removeNode (id) {
-      const res = this.findItem(this.mindMapDataCurrent, id)
-      const dataItem = res && res.parent
-      if (dataItem && dataItem.children) {
-        const { children } = dataItem
-        const index = children.findIndex((item) => item.id === id)
-        return children.splice(index, 1)
+    getMindmapDataUse(){
+      return this.mindmapAssistData
+    },
+    mindmapDeleteRecordPush(mindmapNodes){
+      let shouldOperations=[]
+      this.mindmapAssistData.mindmapDataUse.map((item,index)=>{
+        let levelIds = mindmapNodes.filter(mindMap => mindMap.data.id.startsWith(item.mindmapData.id)).map(mindMap => mindMap.data.id)
+        if(!(levelIds && levelIds.length>0)) return 
+        let mindMapIds=[...levelIds]
+        for (let i = 0; i < levelIds.length; i++) {
+          const element = levelIds[i]
+          mindMapIds=mindMapIds.filter( id => id.indexOf(element) !=0 || id==element)
+        }
+        shouldOperations.push(mindMapIds)
+      })
+      // 入栈
+      if(!this.canRedo){
+        this.mindmapAssistData.mindmapDataRecoverUse=[JSON.stringify(this.mindmapAssistData.mindmapDataUse)]
+      }else{
+        this.mindmapAssistData.mindmapDataRecoverUse.push(JSON.stringify(this.mindmapAssistData.mindmapDataUse))
       }
       }
-      return null
-    }
+      shouldOperations.map(it =>{
+        it.map(it1 =>{
+          this.deleteMindmapData(it1,this.mindmapAssistData.mindmapDataUse)
+        })
+      })
+    },
+    mindmapAddRecordPush(){
+      // 入栈
+      if(!this.canRedo){
+        this.mindmapAssistData.mindmapDataRecoverUse=[JSON.stringify(this.mindmapAssistData.mindmapDataUse)]
+      }else{
+        this.mindmapAssistData.mindmapDataRecoverUse.push(JSON.stringify(this.mindmapAssistData.mindmapDataUse))
+      }
+      let recoverDeletedData=this.mindmapAssistData.deletedMindmapData.pop()
+      if(recoverDeletedData && recoverDeletedData.length>0){
+        // 添加
+        recoverDeletedData.map(it =>{
+          it.map(it1 =>{
+            this.addMindmapData(it1,this.mindmapAssistData.mindmapDataUse)
+          })
+        })
+      }
+    },
+    deleteMindmapData(id,data){
+      let ids = id.split('-')
+      let mindmapDataIndex = data.findIndex(mindmap => mindmap.mindmapData.id == ids[0])
+      if(ids.length==1){
+        data.splice(mindmapDataIndex,1)
+        return 
+      }
+
+      let mindmapData = data[mindmapDataIndex].mindmapData
+      let findId = ids[0]
+      for (let i = 1; i < ids.length-1; i++) {
+        const element = ids[i];
+        findId = findId+'-'+element
+        mindmapData=mindmapData.children.find(it => it.id==findId)
+      }
+      let endId = ids[ids.length-1]
+      let endIndex = mindmapData.children.findIndex(it => it.id == findId+'-'+endId)
+      mindmapData.children.splice(endIndex,1)
+    },
+    addMindmapData(item,data){
+      let isRoot = item.mindmapData?true:false
+      let id = isRoot?item.mindmapData.id:item.id
+      
+      if(isRoot){
+        // 恢复根节点
+        let mindmapDataIndexRoot=data.length
+        for (let i = 0; i < data.length-1; i++) {
+          const element = data[i];
+          if((+id) < (+element.mindmapData.id)){
+            mindmapDataIndexRoot=0
+            break
+          }else if((+id) > (+element.mindmapData.id) && (+id) < (+data[i+1].mindmapData.id)){
+            mindmapDataIndexRoot=i+1
+            break
+          }
+        }
+        data.splice(mindmapDataIndexRoot,0,item)
+        return
+      }
+
+      let ids = id.split('-')
+      let mindmapDataIndex = data.findIndex(mindmap => {
+        return mindmap.mindmapData.id == ids[0]
+      })
+      let mindmapData = data[mindmapDataIndex].mindmapData
+      let findId = ids[0]
+      for (let i = 1; i < ids.length-1; i++) {
+        const element = ids[i];
+        findId = findId+'-'+element
+        mindmapData=mindmapData.children.find(it => it.id==findId)
+      }
+      let endId = ids[ids.length-1]
+      let endIndex = mindmapData.children.length
+      if(mindmapData.children.length==1){
+        // 只有一个
+        let prevIdx = mindmapData.children[0].id.substring(mindmapData.children[0].id.lastIndexOf('-')+1)
+        if((+endId) < (+prevIdx)){
+          endIndex=0
+        }else{
+          endIndex=1
+        }
+      }else{
+        for (let i = 0; i < mindmapData.children.length-1; i++) {
+          // 两个及以上
+          const element = mindmapData.children[i];
+
+          let prevIdx = element.id.substring(element.id.lastIndexOf('-')+1)
+          let nextIdx = mindmapData.children[i+1].id.substring(mindmapData.children[i+1].id.lastIndexOf('-')+1)
+          // 找到对应位置,前提 id是按顺序的
+          if((+endId) < (+prevIdx)){
+            endIndex=0
+            break
+          }else if((+endId) > (+prevIdx) && (+endId) < (+nextIdx)){
+            endIndex=i+1
+            break
+          }
+        }
+      }
+      mindmapData.children.splice(endIndex,0,item)
+    },
+    mindmapRecover(){
+      // 重做添加时 恢复数据指针前进
+      let recoverData = this.mindmapAssistData.mindmapDataRecoverUse.pop()
+      if(recoverData) this.mindmapAssistData.mindmapDataUse=JSON.parse(recoverData) 
+    },
   },
   },
 }
 }

+ 1 - 12
src/views/sandbox_manage/common/node.js

@@ -3,7 +3,6 @@ import store from "@/vuex/index"
 
 
 const { line,border,text } = configOpt;
 const { line,border,text } = configOpt;
 
 
-console.log(store,'storestorestore');
 const styleConfig=store.state.sand.styleConfig
 const styleConfig=store.state.sand.styleConfig
 
 
 //定义图形
 //定义图形
@@ -273,17 +272,7 @@ export const myNodeOption = (key) => {
 							// 		position: 'bottom',
 							// 		position: 'bottom',
 							// 		zIndex: 20,
 							// 		zIndex: 20,
 							// 		...portStyle
 							// 		...portStyle
-							// },
-							// "port-left": {
-							// 		position: 'left',
-							// 		zIndex: 20,
-							// 		...portStyle
-							// },
-							// "port-right": {
-							// 		position: 'right',
-							// 		zIndex: 20,
-							// 		...portStyle
-							// },
+							// }
 					}
 					}
 				},
 				},
 			}
 			}

+ 158 - 274
src/views/sandbox_manage/index_new_version.vue

@@ -110,6 +110,7 @@
     </div>
     </div>
     <!-- 目录自定义按钮区域 -->
     <!-- 目录自定义按钮区域 -->
     <div id="custom-button-zone" class="custom-button-zone">
     <div id="custom-button-zone" class="custom-button-zone">
+      <img src="~@/assets/img/data_m/move_ico.png" style="pointer-events: none;" v-permission="permissionBtn.sandboxPermission.sandbox_classify_move"/>
       <img src="~@/assets/img/sand_new/add_outline.png" class="add-classify-img" v-permission="permissionBtn.sandboxPermission.sandbox_classify_addEdit"/>
       <img src="~@/assets/img/sand_new/add_outline.png" class="add-classify-img" v-permission="permissionBtn.sandboxPermission.sandbox_classify_addEdit"/>
       <img src="~@/assets/img/sand_new/edit_outline.png" class="edit-classify-img" v-permission="permissionBtn.sandboxPermission.sandbox_classify_addEdit"/>
       <img src="~@/assets/img/sand_new/edit_outline.png" class="edit-classify-img" v-permission="permissionBtn.sandboxPermission.sandbox_classify_addEdit"/>
       <img src="~@/assets/img/sand_new/delete_outline.png" class="delete-classify-img" v-permission="permissionBtn.sandboxPermission.sandbox_classify_del"/>
       <img src="~@/assets/img/sand_new/delete_outline.png" class="delete-classify-img" v-permission="permissionBtn.sandboxPermission.sandbox_classify_del"/>
@@ -129,15 +130,18 @@
             {{ lastLevelClassifyName }}
             {{ lastLevelClassifyName }}
           </el-form-item>
           </el-form-item>
           <el-form-item label="目录名称" prop="SandboxClassifyName">
           <el-form-item label="目录名称" prop="SandboxClassifyName">
-            <el-input v-model="classifyForm.SandboxClassifyName" style="width: 317px;" placeholder="请输入目录名称"></el-input>
+            <el-input v-model.trim="classifyForm.SandboxClassifyName" style="width: 317px;" placeholder="请输入目录名称"></el-input>
           </el-form-item>
           </el-form-item>
-          <el-form-item label="关联品种" prop="ChartPermissionId" v-if="hasVariety && (classifyAddTitle.indexOf('添加')!==-1)">
+          <el-form-item label="关联品种" prop="ChartPermissionId" v-if="hasVariety">
             <el-cascader 
             <el-cascader 
+              @change="chartPermissionIdChange"
 							:options="classifyArr"
 							:options="classifyArr"
 							:props="classifyProps"
 							:props="classifyProps"
 							v-model="classifyForm.ChartPermissionId" 
 							v-model="classifyForm.ChartPermissionId" 
 							placeholder="请选择对应品种" 
 							placeholder="请选择对应品种" 
               id="classifyAddCascader"
               id="classifyAddCascader"
+              ref="chartPermissionCascader"
+              :disabled="(classifyForm.SandboxClassifyId && classifyForm.Level!=1) || (!classifyForm.SandboxClassifyId && classifyForm.Level!=0)"
 						/>
 						/>
           </el-form-item>
           </el-form-item>
         </el-form>
         </el-form>
@@ -162,24 +166,15 @@
             <el-input v-model="saveOtherForm.chartName" style="width: 317px;" placeholder="请输入逻辑图名称"></el-input>
             <el-input v-model="saveOtherForm.chartName" style="width: 317px;" placeholder="请输入逻辑图名称"></el-input>
           </el-form-item>
           </el-form-item>
           <el-form-item label="分类" prop="classifyId" :rules="{required:true,message:'请选择分类',trigger:'change'}" >
           <el-form-item label="分类" prop="classifyId" :rules="{required:true,message:'请选择分类',trigger:'change'}" >
-            <el-popover
-              placement="bottom"
-              width="400"
-              popper-class="classify-popper"
-              trigger="click"
-              v-model="selectClassifyShow">
-                <tree :nodes="onlyClassifyTreeData" :setting="selectSetting" key="saveOther" @onCreated="getSelectZTree" @onClick="selectClassify" />
-                <el-cascader 
-                slot="reference"
-                :options="onlyClassifyTreeData"
-                :props="{children: 'Children',
-                  label: 'SandboxClassifyName',
-                   value: 'SandboxClassifyId',emitPath:false,checkStrictly:true}"
-                v-model="saveOtherForm.classifyId" 
-                popper-class="classify-cascader-popper"
-                placeholder="请选择分类">
-                </el-cascader>
-            </el-popover>
+            <el-cascader 
+            :options="onlyClassifyTreeData"
+            @change="classifyTreeChange"
+            :props="{children: 'Children',
+              label: 'SandboxClassifyName',
+                value: 'SandboxClassifyId',checkStrictly:true}"
+            v-model="saveOtherClassifys" 
+            placeholder="请选择分类">
+            </el-cascader>
           </el-form-item>
           </el-form-item>
         </el-form>
         </el-form>
         <div style="text-align: center;padding:40px 0 ;">
         <div style="text-align: center;padding:40px 0 ;">
@@ -210,7 +205,6 @@ import { myGraph } from './common/gragh';
     mixins:[mindmap],
     mixins:[mindmap],
     watch: {
     watch: {
       initData(newval) {
       initData(newval) {
-        console.log(newval);
         if(!this.graph){
         if(!this.graph){
           this.$nextTick(()=>{
           this.$nextTick(()=>{
             this.init()
             this.init()
@@ -261,9 +255,7 @@ import { myGraph } from './common/gragh';
             showLine:false,
             showLine:false,
             showIcon:false,
             showIcon:false,
             selectedMulti:false,
             selectedMulti:false,
-            addDiyDom: this.addDiyDom,
-            // addHoverDom: this.addHoverDom,
-		        // removeHoverDom: this.removeHoverDom
+            addHoverDom: this.addHoverDom,
           },
           },
           edit:{
           edit:{
             enable:true,
             enable:true,
@@ -283,25 +275,11 @@ import { myGraph } from './common/gragh';
           }
           }
         },
         },
         zTreeObj:{},
         zTreeObj:{},
-        selectSetting:{
-          data:{
-            key:{
-              name:"SandboxClassifyName",
-              children:"Children"
-            }
-          },
-          view:{
-            showLine:false,
-            showIcon:false,
-            selectedMulti:false
-          }
-        },
-        selectClassifyShow:false,
-        selectZTreeObj:{},
         lockLoding:null,
         lockLoding:null,
         viewSandbox:{},
         viewSandbox:{},
         activeNode:{},
         activeNode:{},
         addClassifyNodeTid:'',
         addClassifyNodeTid:'',
+        locationNode:'',
         movingRecoveData:{
         movingRecoveData:{
           targetNode:null,
           targetNode:null,
           treeNode:null,
           treeNode:null,
@@ -309,6 +287,7 @@ import { myGraph } from './common/gragh';
         },
         },
         graph:null,
         graph:null,
         initData:{},
         initData:{},
+        customButtonDom:'',
         // ------- 添加分类弹窗
         // ------- 添加分类弹窗
         classifyAddTitle:"添加分类",
         classifyAddTitle:"添加分类",
         classifyAddShow:false,
         classifyAddShow:false,
@@ -316,7 +295,8 @@ import { myGraph } from './common/gragh';
         classifyForm:{
         classifyForm:{
           SandboxClassifyId:0,
           SandboxClassifyId:0,
           SandboxClassifyName:'',
           SandboxClassifyName:'',
-          ChartPermissionId:null,
+          ChartPermissionId:0,
+          ChartPermissionName:'',
           ParentId:0,
           ParentId:0,
           Level:0
           Level:0
         },
         },
@@ -337,8 +317,7 @@ import { myGraph } from './common/gragh';
           chartName:"",
           chartName:"",
           classifyId:""
           classifyId:""
         },
         },
-        saveOtherClassifys:'',
-        locationActiveNode:'',
+        saveOtherClassifys:[],
         operationType:'view',
         operationType:'view',
         popoverVisible:false,
         popoverVisible:false,
         popoverFlod:true,
         popoverFlod:true,
@@ -347,48 +326,27 @@ import { myGraph } from './common/gragh';
         checkedLinkList:[],
         checkedLinkList:[],
         linkNode:null,
         linkNode:null,
         popoverTimeout:null,
         popoverTimeout:null,
-        isSlideLeft:false
+        isSlideLeft:false,
+        locationParentIds:''
       }
       }
     },
     },
     created(){
     created(){
       this.getClassify()
       this.getClassify()
+      if(sessionStorage.getItem("sandboxEditBack")){
+        this.locationParentIds=sessionStorage.getItem("sandboxEditBack").split(',')
+        this.getSandboxDetailFun(this.locationParentIds[this.locationParentIds.length-1])
+      }else{
+        this.getSandboxList()
+      }
       this.getSandboxClassify()
       this.getSandboxClassify()
-      this.getSandboxClassifyOnly()
-      this.getSandboxList()
-      // this.setting.async={
-        // enable:false,
-        // type:'head'
-      //   url:(()=>{
-      //     console.log(process.env);
-      //     // console.log(process.env.VUE_APP_API_ROOT,'process.env.VUE_APP_API_ROOT');
-      //     // if(process.env.NODE_ENV === "development"){
-      //     //   return "http://8.136.199.33:7777/adminapi/sandbox/classify/list"
-      //     // }else{
-      //       return process.env.VUE_APP_API_ROOT+'/sandbox/classify/list'
-      //     // }
-      //   })(),
-      //   type:'get',
-      //   autoParam: ["SandboxClassifyId"],
-      //   otherParam:{ "IsShowMe":this.isOnlyMe},
-      //   dataFilter: (treeId,parentNode,responseData)=>{
-      //     console.log(treeId,parentNode,responseData,'responseData');
-      //     return responseData.Data.AllNodes
-      //   },
-      //   headers:{
-      //     Authorization:localStorage.getItem("auth"),
-      //     Uuid:localStorage.getItem("uuid") || "",
-      //     AccessToken:localStorage.getItem("uuid")+"--zheshiyigename",
-      //   }
-      // }
     },
     },
     mounted(){
     mounted(){
-      // this.init()
       this.popoverDom = $('#link-popover')[0];
       this.popoverDom = $('#link-popover')[0];
       this.popoverTriggerDom = $('#link-reference')[0];
       this.popoverTriggerDom = $('#link-reference')[0];
       
       
       this.popoverDom.addEventListener('mouseenter',this.clearPopoverTimeout)
       this.popoverDom.addEventListener('mouseenter',this.clearPopoverTimeout)
       this.popoverDom.addEventListener('mouseleave',this.closePopover)
       this.popoverDom.addEventListener('mouseleave',this.closePopover)
-
+      this.customButtonDom = $('#custom-button-zone')[0]
     },
     },
     beforeDestroy(){
     beforeDestroy(){
       this.popoverDom.removeEventListener('mouseenter',this.clearPopoverTimeout)
       this.popoverDom.removeEventListener('mouseenter',this.clearPopoverTimeout)
@@ -401,20 +359,20 @@ import { myGraph } from './common/gragh';
         customInterence.getvariety({
         customInterence.getvariety({
           CompanyType: 'ficc'
           CompanyType: 'ficc'
         }).then(res => {
         }).then(res => {
-          console.log(res);
           if(res.Ret !== 200)  return
           if(res.Ret !== 200)  return
             this.classifyArr = res.Data.List||[ ]
             this.classifyArr = res.Data.List||[ ]
         })
         })
       },
       },
       // 获取沙盘图分类
       // 获取沙盘图分类
       getSandboxClassify(parentNode,locationNode) {
       getSandboxClassify(parentNode,locationNode) {
-        console.log(parentNode,locationNode,'parentNode,locationNode');
+        // parentNode--父节点
+        // locationNode--展开父节点后需要定位的子节点,拖拽后
         const sandboxClassifyId = parentNode ? parentNode.SandboxClassifyId:0
         const sandboxClassifyId = parentNode ? parentNode.SandboxClassifyId:0
         sandInterface.getSandboxClassify({SandboxClassifyId:sandboxClassifyId,IsShowMe:this.searchParams.IsShowMe}).then(res=>{
         sandInterface.getSandboxClassify({SandboxClassifyId:sandboxClassifyId,IsShowMe:this.searchParams.IsShowMe}).then(res=>{
-          console.log(res);
           if (res.Ret === 200) {
           if (res.Ret === 200) {
             let nodesData=res.Data.AllNodes || []
             let nodesData=res.Data.AllNodes || []
             nodesData.map(item =>{
             nodesData.map(item =>{
+              // 添加是否是目录的字段
               item.isCatalogue = item.SandboxId?false:true
               item.isCatalogue = item.SandboxId?false:true
             })
             })
             if(parentNode){
             if(parentNode){
@@ -422,46 +380,45 @@ import { myGraph } from './common/gragh';
             }else{
             }else{
               this.treeData = nodesData
               this.treeData = nodesData
             }
             }
-            if(locationNode){
+            let location = locationNode || this.locationNode
+            if(location){
               let searchNode
               let searchNode
-              let locationId = locationNode.isCatalogue?locationNode.SandboxClassifyId:locationNode.SandboxId
+              let locationId = location.isCatalogue?location.SandboxClassifyId:location.SandboxId
               if(parentNode){
               if(parentNode){
-                if(locationNode.isCatalogue){
+                if(location.isCatalogue){
                   searchNode=this.zTreeObj.getNodesByParam('SandboxClassifyId',+locationId,parentNode)
                   searchNode=this.zTreeObj.getNodesByParam('SandboxClassifyId',+locationId,parentNode)
                 }else{
                 }else{
                   searchNode=this.zTreeObj.getNodesByParam('SandboxId',+locationId,parentNode)
                   searchNode=this.zTreeObj.getNodesByParam('SandboxId',+locationId,parentNode)
                 }
                 }
-                console.log(searchNode,'searchNode');
                 if(!(searchNode && searchNode.length>0)) return 
                 if(!(searchNode && searchNode.length>0)) return 
                 this.zTreeClick(null,'',searchNode[0],1)
                 this.zTreeClick(null,'',searchNode[0],1)
                 this.zTreeObj.selectNode(searchNode[0])
                 this.zTreeObj.selectNode(searchNode[0])
               }else{
               }else{
                 requestAnimationFrame(()=>{
                 requestAnimationFrame(()=>{
                   searchNode=this.zTreeObj.getNodesByParam('SandboxClassifyId',+locationId)
                   searchNode=this.zTreeObj.getNodesByParam('SandboxClassifyId',+locationId)
-                  console.log(searchNode,'searchNode');
                   if(!(searchNode && searchNode.length>0)) return 
                   if(!(searchNode && searchNode.length>0)) return 
                   this.zTreeClick(null,'',searchNode[0],1)
                   this.zTreeClick(null,'',searchNode[0],1)
                   this.zTreeObj.selectNode(searchNode[0])
                   this.zTreeObj.selectNode(searchNode[0])
                 })
                 })
               }
               }
+              this.locationNode=''
+            }else if(this.locationParentIds && this.locationParentIds.length>0){
+              // 获取分类列表后需要定位
+              requestAnimationFrame(()=>{
+                this.sandboxLocation(this.locationParentIds)
+                this.locationParentIds=[]
+                sessionStorage.removeItem('sandboxEditBack')
+              })
 
 
             }
             }
           }
           }
         })
         })
       },
       },
-      getSandboxClassifyOnly(){
-        sandInterface.getSandboxClassifyOnly().then(res=>{
-          if (res.Ret === 200) {
-            this.onlyClassifyTreeData=res.Data.AllNodes || []
-          }
-        })
-      },
       getSandboxList(type){
       getSandboxList(type){
         if(type == 'setCurrentIndex'){
         if(type == 'setCurrentIndex'){
           this.searchParams.CurrentIndex=1
           this.searchParams.CurrentIndex=1
         }
         }
         sandInterface.getSandboxListV2(this.searchParams).then(res=>{
         sandInterface.getSandboxListV2(this.searchParams).then(res=>{
-          console.log(res,'res');
           if(res.Ret == 200){
           if(res.Ret == 200){
             if(!res.Data){
             if(!res.Data){
               this.pictureList=[]
               this.pictureList=[]
@@ -477,45 +434,43 @@ import { myGraph } from './common/gragh';
           }
           }
         })
         })
       },
       },
+      getSandboxDetailFun(SandboxId){
+        sandInterface.getSandboxDetail({SandboxId:SandboxId || this.activeNode.SandboxId}).then(res=>{
+          if(res.Ret == 200){
+            this.viewSandbox=res.Data
+            this.rightType='chart'
+            this.initData = JSON.parse(this.viewSandbox.Content)
+          }
+        })
+      },
       getZTree(zTree){
       getZTree(zTree){
         this.zTreeObj=zTree
         this.zTreeObj=zTree
       },
       },
-      getSelectZTree(zTree){
-        this.selectZTreeObj=zTree
-      },
-      selectClassify(event,treeId,treeNode,clickFlag){
-        this.sandSaveParams.SandboxClassifyId = treeNode.SandboxClassifyId
-        this.selectClassifyShow = false
-      },
       zTreeDragBefore(treeId,treeNodes){
       zTreeDragBefore(treeId,treeNodes){
         return this.permissionBtn.isShowBtn('sandboxPermission','sandbox_classify_move')
         return this.permissionBtn.isShowBtn('sandboxPermission','sandbox_classify_move')
       },
       },
       zTreeDropBefore(treeId,treeNodes,targetNode,moveType,isCopy){
       zTreeDropBefore(treeId,treeNodes,targetNode,moveType,isCopy){
-        console.log(treeId,treeNodes,targetNode,moveType,isCopy,'zTreeDropBefore');
         if((!targetNode) && (!moveType)) return false
         if((!targetNode) && (!moveType)) return false
         if(((!treeNodes[0].isCatalogue) && targetNode.Level==1 && moveType!='inner')||
         if(((!treeNodes[0].isCatalogue) && targetNode.Level==1 && moveType!='inner')||
         ((!targetNode.isCatalogue) && moveType=='inner')||
         ((!targetNode.isCatalogue) && moveType=='inner')||
         (treeNodes[0].isCatalogue && targetNode.Level==5 && moveType=='inner')){
         (treeNodes[0].isCatalogue && targetNode.Level==5 && moveType=='inner')){
           return false
           return false
         }
         }
-
-        // 接口失败后的还原
-        // this.movingRecoveData.treeNode=treeNodes[0]
-        // if(treeNodes[0].getPreNode()){
-        //   this.movingRecoveData.targetNode = treeNodes[0].getPreNode()
-        //   this.movingRecoveData.moveType = "next"
-        // }else if(treeNodes[0].getNextNode()){
-        //   this.movingRecoveData.targetNode = treeNodes[0].getNextNode()
-        //   this.movingRecoveData.moveType = "prev"
-        // }else if(treeNodes[0].getParentNode()){
-        //   this.movingRecoveData.targetNode = treeNodes[0].getParentNode()
-        //   this.movingRecoveData.moveType = "inner"
-        // }
+        // 用于接口失败后的还原位置
+        this.movingRecoveData.treeNode=treeNodes[0]
+        if(treeNodes[0].getPreNode()){
+          this.movingRecoveData.targetNode = treeNodes[0].getPreNode()
+          this.movingRecoveData.moveType = "next"
+        }else if(treeNodes[0].getNextNode()){
+          this.movingRecoveData.targetNode = treeNodes[0].getNextNode()
+          this.movingRecoveData.moveType = "prev"
+        }else if(treeNodes[0].getParentNode()){
+          this.movingRecoveData.targetNode = treeNodes[0].getParentNode()
+          this.movingRecoveData.moveType = "inner"
+        }
       },
       },
       zTreeDrop(e,treeId,treeNodes,targetNode,moveType,isCopy){
       zTreeDrop(e,treeId,treeNodes,targetNode,moveType,isCopy){
-        console.log(treeId,treeNodes[0],targetNode,moveType,isCopy,'zTreeDrop');
         if((!targetNode) && (!moveType)) return
         if((!targetNode) && (!moveType)) return
-        console.log(treeNodes[0].getParentNode(),targetNode.getParentNode());
         let parentNode = treeNodes[0].getParentNode()
         let parentNode = treeNodes[0].getParentNode()
         let prevNode = treeNodes[0].getPreNode()
         let prevNode = treeNodes[0].getPreNode()
         let nextNode = treeNodes[0].getNextNode()
         let nextNode = treeNodes[0].getNextNode()
@@ -536,48 +491,26 @@ import { myGraph } from './common/gragh';
               this.zTreeObj.removeChildNodes(parentNode)
               this.zTreeObj.removeChildNodes(parentNode)
             }
             }
             this.getSandboxClassify(parentNode,treeNodes[0])
             this.getSandboxClassify(parentNode,treeNodes[0])
+          }else{
+            // 接口失败后的还原位置
+            let result=this.zTreeObj.moveNode(this.movingRecoveData.targetNode,this.movingRecoveData.treeNode,this.movingRecoveData.moveType)
+            if(!result){
+              this.$message.error('目录位置还原失败,刷新目录')
+              setTimeout(()=>{
+                this.getSandboxClassify()
+              },1000)
+            }
           }
           }
         })
         })
-        // if((!targetNode) && (!moveType)) return
-        // let parentNode = treeNodes[0].getParentNode()
-        // let prevNode = treeNodes[0].getPreNode()
-        // let nextNode = treeNodes[0].getNextNode()
-        // //移动分类
-        // let params={
-        //   ClassifyId:treeNodes[0].SandboxClassifyId,
-        //   SandboxId:treeNodes[0].isCatalogue?0:treeNodes[0].SandboxId,
-        //   ParentClassifyId:parentNode?parentNode.SandboxClassifyId:0,
-        //   PrevId:prevNode? (prevNode.isCatalogue?prevNode.SandboxClassifyId:prevNode.SandboxId) :0,
-        //   NextId:nextNode? (nextNode.isCatalogue?nextNode.SandboxClassifyId:nextNode.SandboxId) :0,
-        //   PrevType:prevNode?(prevNode.isCatalogue?1:2):0,
-        //   NextType:nextNode?(nextNode.isCatalogue?1:2):0
-        // }
-        // console.log(params);
-        // sandInterface.sandboxClassifyMove(params).then(res=>{
-        //   if(res.Ret == 200){
-        //     this.$message.success('移动分类成功')
-        //   }else{
-        //     // let result=this.zTreeObj.moveNode(this.movingRecoveData.targetNode,this.movingRecoveData.treeNode,this.movingRecoveData.moveType)
-        //     // if(!result){
-        //     //   window.location.reload()
-        //     // }
-        //   }
-        // })
       },
       },
       zTreeExpandBefore(treeId, treeNode){
       zTreeExpandBefore(treeId, treeNode){
-        // console.log( treeId, treeNode);
         if(treeNode.Children && treeNode.Children.length>0){
         if(treeNode.Children && treeNode.Children.length>0){
           return true
           return true
         }else{
         }else{
           this.getSandboxClassify(treeNode)
           this.getSandboxClassify(treeNode)
         }
         }
       },
       },
-      zTreeExpand(event, treeId, treeNode){
-        // console.log(event, treeId, treeNode);
-      },
       zTreeClick(event, treeId, treeNode,clickFlag){
       zTreeClick(event, treeId, treeNode,clickFlag){
-        console.log(event, treeId, treeNode,clickFlag);
-
         if(clickFlag==1){
         if(clickFlag==1){
           if(this.activeNode.SandboxClassifyId == treeNode.SandboxClassifyId &&
           if(this.activeNode.SandboxClassifyId == treeNode.SandboxClassifyId &&
           this.activeNode.SandboxId == treeNode.SandboxId){
           this.activeNode.SandboxId == treeNode.SandboxId){
@@ -589,26 +522,18 @@ import { myGraph } from './common/gragh';
             this.searchParams.CurrentIndex=1
             this.searchParams.CurrentIndex=1
             this.searchParams.SandboxClassifyId = treeNode.SandboxClassifyId
             this.searchParams.SandboxClassifyId = treeNode.SandboxClassifyId
             this.getSandboxList('setCurrentIndex')
             this.getSandboxList('setCurrentIndex')
-            // this.rightType='list'
           }else{
           }else{
             // 沙盘图
             // 沙盘图
-            sandInterface.getSandboxDetail({SandboxId:this.activeNode.SandboxId}).then(res=>{
-              console.log(res);
-              if(res.Ret == 200){
-                this.viewSandbox=res.Data
-                this.rightType='chart'
-                this.initData = JSON.parse(this.viewSandbox.Content)
-              }
-            })
+            this.getSandboxDetailFun()
           }
           }
         }
         }
 
 
         if(clickFlag==0 && treeNode.isCatalogue){
         if(clickFlag==0 && treeNode.isCatalogue){
+          // 取消选中
           this.activeNode={}
           this.activeNode={}
           this.searchParams.CurrentIndex=1
           this.searchParams.CurrentIndex=1
           this.searchParams.SandboxClassifyId = ''
           this.searchParams.SandboxClassifyId = ''
           this.getSandboxList('setCurrentIndex')
           this.getSandboxList('setCurrentIndex')
-          // this.rightType='list'
         }
         }
       },
       },
       onlyMeHandler(){
       onlyMeHandler(){
@@ -618,7 +543,6 @@ import { myGraph } from './common/gragh';
         this.getSandboxList('setCurrentIndex')
         this.getSandboxList('setCurrentIndex')
       },
       },
       searchHandle(query) {
       searchHandle(query) {
-        // console.log(query,"搜索");
         this.searchCurrentIndex = 1;
         this.searchCurrentIndex = 1;
         this.KeyWord = query;
         this.KeyWord = query;
         this.searchSandbox()
         this.searchSandbox()
@@ -641,7 +565,6 @@ import { myGraph } from './common/gragh';
       },
       },
       searchLoad() {
       searchLoad() {
         // 加载更多
         // 加载更多
-        console.log("加载更多");
         if(!this.searchHaveMore) return;
         if(!this.searchHaveMore) return;
         this.searchCurrentIndex++
         this.searchCurrentIndex++
         this.searchSandbox()
         this.searchSandbox()
@@ -649,7 +572,6 @@ import { myGraph } from './common/gragh';
       /* 聚焦获取当前检索 */
       /* 聚焦获取当前检索 */
       inputFocusHandle(e) {
       inputFocusHandle(e) {
         // 选取
         // 选取
-        console.log('选取',e.target.value);
         this.searchCurrentIndex = 1;
         this.searchCurrentIndex = 1;
         this.KeyWord = e.target.value;
         this.KeyWord = e.target.value;
         if(this.KeyWord) {
         if(this.KeyWord) {
@@ -678,12 +600,13 @@ import { myGraph } from './common/gragh';
       },
       },
       addClassify(e,node){
       addClassify(e,node){
         e.stopPropagation()
         e.stopPropagation()
-        console.log(node);
         this.addClassifyNodeTid = node.tId
         this.addClassifyNodeTid = node.tId
         this.lastLevelClassifyName = this.getParentNodeName(node)
         this.lastLevelClassifyName = this.getParentNodeName(node)
         this.classifyAddTitle="添加分类"
         this.classifyAddTitle="添加分类"
         this.classifyForm.Level = node.Level
         this.classifyForm.Level = node.Level
         this.classifyForm.ParentId = node.SandboxClassifyId
         this.classifyForm.ParentId = node.SandboxClassifyId
+        this.classifyForm.ChartPermissionId = node.ChartPermissionId
+        this.classifyForm.ChartPermissionName = node.ChartPermissionName
         this.classifyAddShow=true
         this.classifyAddShow=true
       },
       },
       getParentNodeName(node){
       getParentNodeName(node){
@@ -695,13 +618,16 @@ import { myGraph } from './common/gragh';
         }
         }
       },
       },
       editClassify(e,node){
       editClassify(e,node){
-        console.log(node);
         e.stopPropagation()
         e.stopPropagation()
+        this.locationNode = node
         let pNode = node.getParentNode()
         let pNode = node.getParentNode()
         this.lastLevelClassifyName = pNode ? pNode.SandboxClassifyName:''
         this.lastLevelClassifyName = pNode ? pNode.SandboxClassifyName:''
         this.classifyForm.SandboxClassifyId = node.SandboxClassifyId
         this.classifyForm.SandboxClassifyId = node.SandboxClassifyId
+        this.classifyForm.Level = node.Level
         this.classifyForm.SandboxClassifyName = node.SandboxClassifyName
         this.classifyForm.SandboxClassifyName = node.SandboxClassifyName
-        this.classifyAddTitle="重命名"
+        this.classifyForm.ChartPermissionId = node.ChartPermissionId
+        this.classifyForm.ChartPermissionName = node.ChartPermissionName
+        this.classifyAddTitle="编辑分类"
         this.classifyAddShow=true
         this.classifyAddShow=true
       },
       },
       deleteClassify(e,node){
       deleteClassify(e,node){
@@ -740,8 +666,7 @@ import { myGraph } from './common/gragh';
                 res.Data.DeleteStatus === 0 && node.SandboxId 
                 res.Data.DeleteStatus === 0 && node.SandboxId 
                 ? this.delHandle(node.SandboxClassifyId, node.SandboxId, 1)
                 ? this.delHandle(node.SandboxClassifyId, node.SandboxId, 1)
                 : this.delHandle(node.SandboxClassifyId, node.SandboxId);
                 : this.delHandle(node.SandboxClassifyId, node.SandboxId);
-              }).catch(() => {         
-              });
+              }).catch(() => {});
           }
           }
         })
         })
       },
       },
@@ -754,16 +679,15 @@ import { myGraph } from './common/gragh';
           if (res.Ret === 200) {
           if (res.Ret === 200) {
             this.zTreeObj.removeNode(currentNode)
             this.zTreeObj.removeNode(currentNode)
             this.$message.success(res.Msg);
             this.$message.success(res.Msg);
-            // if(type && res.Data.SandboxId){
-              
-            // }else{
-
-            // }
           }
           }
         });
         });
       },
       },
+      chartPermissionIdChange(value){
+        this.classifyForm.ChartPermissionName=
+        this.$refs.chartPermissionCascader.getCheckedNodes()[0] ?
+        this.$refs.chartPermissionCascader.getCheckedNodes()[0].label+'' || '':''
+      },
       classifyAddSubmit(){
       classifyAddSubmit(){
-        console.log(this.classifyForm);
         //提交
         //提交
         this.$refs.classifyFormRef.validate(valid=>{
         this.$refs.classifyFormRef.validate(valid=>{
           if(valid){
           if(valid){
@@ -771,17 +695,23 @@ import { myGraph } from './common/gragh';
               //编辑
               //编辑
               let params={
               let params={
                 SandboxClassifyId:this.classifyForm.SandboxClassifyId,
                 SandboxClassifyId:this.classifyForm.SandboxClassifyId,
-                SandboxClassifyName:this.classifyForm.SandboxClassifyName
+                SandboxClassifyName:this.classifyForm.SandboxClassifyName,
+                ChartPermissionId:this.classifyForm.ChartPermissionId,
+                ChartPermissionName:this.classifyForm.ChartPermissionName,
               }
               }
               sandInterface.editSandboxClassify(params).then(res=>{
               sandInterface.editSandboxClassify(params).then(res=>{
                 if(res.Ret == 200){
                 if(res.Ret == 200){
                   this.classifyAddShow=false
                   this.classifyAddShow=false
                   this.$message.success(this.classifyAddTitle+"成功")
                   this.$message.success(this.classifyAddTitle+"成功")
-                  let currentNode = this.zTreeObj.getSelectedNodes()[0]
+                  let parentNode = this.locationNode.getParentNode()
 
 
-                  currentNode.SandboxClassifyName = this.classifyForm.SandboxClassifyName
-                  this.zTreeObj.updateNode(currentNode)
-                  // this.getSandboxClassify()
+                  if(!parentNode){
+                    this.getSandboxClassify(null,this.locationNode)
+                  }else{
+                    this.zTreeObj.removeChildNodes(parentNode)
+                    this.zTreeObj.expandNode(parentNode,true,false,false,true)
+                    this.zTreeClick(null,'',this.locationNode,1)
+                  }
                 }
                 }
               })
               })
             }else{
             }else{
@@ -790,7 +720,8 @@ import { myGraph } from './common/gragh';
                 SandboxClassifyName:this.classifyForm.SandboxClassifyName,
                 SandboxClassifyName:this.classifyForm.SandboxClassifyName,
                 ParentId:this.classifyForm.ParentId,
                 ParentId:this.classifyForm.ParentId,
                 Level:this.classifyForm.Level,
                 Level:this.classifyForm.Level,
-                ChartPermissionId:this.classifyForm.ChartPermissionId
+                ChartPermissionId:this.classifyForm.ChartPermissionId,
+                ChartPermissionName:this.classifyForm.ChartPermissionName,
               }
               }
               sandInterface.addSandboxClassify(params).then(res=>{
               sandInterface.addSandboxClassify(params).then(res=>{
                 if(res.Ret == 200){
                 if(res.Ret == 200){
@@ -800,11 +731,8 @@ import { myGraph } from './common/gragh';
                     this.getSandboxClassify()
                     this.getSandboxClassify()
                   }else{
                   }else{
                     let curNode = this.zTreeObj.getNodeByTId(this.addClassifyNodeTid)
                     let curNode = this.zTreeObj.getNodeByTId(this.addClassifyNodeTid)
-                    // console.log(curNode,'');
                     this.zTreeObj.removeChildNodes(curNode)
                     this.zTreeObj.removeChildNodes(curNode)
-                    // this.$nextTick(()=>{
-                      this.zTreeObj.expandNode(curNode,true,false,false,true)
-                    // })
+                    this.zTreeObj.expandNode(curNode,true,false,false,true)
                   }
                   }
                 }
                 }
               })
               })
@@ -817,7 +745,8 @@ import { myGraph } from './common/gragh';
         this.classifyForm={
         this.classifyForm={
           SandboxClassifyId:0,
           SandboxClassifyId:0,
           SandboxClassifyName:'',
           SandboxClassifyName:'',
-          ChartPermissionId:null,
+          ChartPermissionId:0,
+          ChartPermissionName:'',
           ParentId:0,
           ParentId:0,
           Level:0
           Level:0
         }
         }
@@ -829,13 +758,9 @@ import { myGraph } from './common/gragh';
         let scrollTop = this.$refs.pictureListRef.scrollTop;
         let scrollTop = this.$refs.pictureListRef.scrollTop;
         let clientHeight = this.$refs.pictureListRef.clientHeight;
         let clientHeight = this.$refs.pictureListRef.clientHeight;
         let scrollHeight = this.$refs.pictureListRef.scrollHeight;
         let scrollHeight = this.$refs.pictureListRef.scrollHeight;
-        // console.log('scrollTop:',scrollTop)
-        // console.log('clientHeight:',clientHeight)
-        // console.log('scrollHeight:',scrollHeight)
         if(scrollTop + clientHeight >= scrollHeight-10 && this.pictureHaveMore){
         if(scrollTop + clientHeight >= scrollHeight-10 && this.pictureHaveMore){
           this.searchParams.CurrentIndex++
           this.searchParams.CurrentIndex++
           this.getSandboxList();
           this.getSandboxList();
-          console.log("加载更多");
         }
         }
       },300),
       },300),
       /* 展示详情 */
       /* 展示详情 */
@@ -849,19 +774,10 @@ import { myGraph } from './common/gragh';
         this.sandboxLocation(ParentClassifys)
         this.sandboxLocation(ParentClassifys)
       },
       },
       async sandboxLocation(ParentClassifys){
       async sandboxLocation(ParentClassifys){
-        console.log(ParentClassifys,'ParentClassifys');
         let beActiveNode=''
         let beActiveNode=''
         for (let i = 0; i < ParentClassifys.length; i++) {
         for (let i = 0; i < ParentClassifys.length; i++) {
           const element = ParentClassifys[i];
           const element = ParentClassifys[i];
-          // if(i == (ParentClassifys.length-1)){
-          //   console.log(+element,beActiveNode,'element');
-          //   let searchNode=this.zTreeObj.getNodesByParam('SandboxId',+element,beActiveNode)
-          //   console.log(searchNode[0]);
-          //   this.zTreeObj.selectNode(searchNode[0],false,false)
-          //   return 
-          // }
           let searchNode=this.zTreeObj.getNodesByParam('SandboxClassifyId',+element,beActiveNode)
           let searchNode=this.zTreeObj.getNodesByParam('SandboxClassifyId',+element,beActiveNode)
-          console.log(searchNode,'searchNode',i);
           if(!(searchNode&&searchNode.length>0)){
           if(!(searchNode&&searchNode.length>0)){
             if(!beActiveNode){
             if(!beActiveNode){
               break
               break
@@ -883,12 +799,11 @@ import { myGraph } from './common/gragh';
             beActiveNode = searchNode[0]
             beActiveNode = searchNode[0]
           }
           }
         }
         }
-        this.locationActiveNode=beActiveNode
         // 选中
         // 选中
-        requestAnimationFrame(()=>{
+        this.activeNode = beActiveNode
+        setTimeout(()=>{
           this.zTreeObj.selectNode(beActiveNode)
           this.zTreeObj.selectNode(beActiveNode)
-          this.activeNode = beActiveNode
-        })
+        },300)
       },
       },
       expandNodeAsync(parentNode,activeId,isLast=false){
       expandNodeAsync(parentNode,activeId,isLast=false){
         return new Promise((resolve,reject)=>{
         return new Promise((resolve,reject)=>{
@@ -898,7 +813,6 @@ import { myGraph } from './common/gragh';
           }else{
           }else{
             resultNode = this.zTreeObj.getNodesByParam('SandboxClassifyId',activeId,parentNode)
             resultNode = this.zTreeObj.getNodesByParam('SandboxClassifyId',activeId,parentNode)
           }
           }
-          console.log(resultNode,'resolve(resultNode)');
           if(resultNode.length>0){
           if(resultNode.length>0){
             resolve(resultNode)
             resolve(resultNode)
             return 
             return 
@@ -924,7 +838,6 @@ import { myGraph } from './common/gragh';
       },
       },
       copyHandle:_.debounce(function ({ PicUrl }){
       copyHandle:_.debounce(function ({ PicUrl }){
         if(!PicUrl) return this.$message('暂无内容可复制')
         if(!PicUrl) return this.$message('暂无内容可复制')
-        console.log("复制");
         this.lockLoding = this.$loading({
         this.lockLoding = this.$loading({
           lock: true,
           lock: true,
           text: '复制图片中...',
           text: '复制图片中...',
@@ -965,7 +878,6 @@ import { myGraph } from './common/gragh';
         }
         }
       },500),
       },500),
       deleteHandle(item,type){
       deleteHandle(item,type){
-        console.log(item,type);
         this.$confirm("确定删除该沙盘图吗?", "提示", {
         this.$confirm("确定删除该沙盘图吗?", "提示", {
           type: "warning",
           type: "warning",
         })
         })
@@ -977,7 +889,6 @@ import { myGraph } from './common/gragh';
             if (res.Ret === 200) {
             if (res.Ret === 200) {
               this.$message.success(res.Msg);
               this.$message.success(res.Msg);
               let result = this.zTreeObj.getNodesByParam('SandboxId',item.SandboxId)[0]
               let result = this.zTreeObj.getNodesByParam('SandboxId',item.SandboxId)[0]
-              console.log(result);
               if(type=='inList'){
               if(type=='inList'){
                 // 在沙盘图列表中删除
                 // 在沙盘图列表中删除
                 if(result){
                 if(result){
@@ -985,8 +896,10 @@ import { myGraph } from './common/gragh';
                 }
                 }
               }else{
               }else{
                 // 在沙盘图详情删除
                 // 在沙盘图详情删除
-                this.sandboxLocation([result.SandboxClassifyId])
                 this.zTreeObj.removeNode(result)
                 this.zTreeObj.removeNode(result)
+                let parentNode = result.getParentNode()
+                this.zTreeObj.selectNode(parentNode)
+                this.zTreeClick(null,'',parentNode,1)
               }
               }
               this.getSandboxList('setCurrentIndex')
               this.getSandboxList('setCurrentIndex')
               
               
@@ -995,16 +908,15 @@ import { myGraph } from './common/gragh';
         })
         })
         .catch(() => {});
         .catch(() => {});
       },
       },
-      addDiyDom(treeId, treeNode) {
-        // console.log(treeNode,'treeId, treeNode');
+      addHoverDom(treeId, treeNode){
         var aObj = $("#" + treeNode.tId + "_a");
         var aObj = $("#" + treeNode.tId + "_a");
-        if ($("#diyBtn_"+treeNode.SandboxClassifyId).length>0) return;
+        if (aObj.find('#custom-button-zone').length>0) return;
+        let dom = this.customButtonDom.cloneNode(true)
+        let addClassifyDom = $(dom).find('.add-classify-img')[0]
+        let editClassifyDom = $(dom).find('.edit-classify-img')[0]
+        let delClassifyDom = $(dom).find('.delete-classify-img')[0]
         if(treeNode.isCatalogue){
         if(treeNode.isCatalogue){
           //目录添加自定义按钮
           //目录添加自定义按钮
-          let dom = $('#custom-button-zone')[0].cloneNode(true)
-          let addClassifyDom = $(dom).find('.add-classify-img')[0]
-          let editClassifyDom = $(dom).find('.edit-classify-img')[0]
-          let delClassifyDom = $(dom).find('.delete-classify-img')[0]
           if(treeNode.Level>4){
           if(treeNode.Level>4){
             addClassifyDom && (addClassifyDom.style.display='none')
             addClassifyDom && (addClassifyDom.style.display='none')
           }else{
           }else{
@@ -1013,15 +925,13 @@ import { myGraph } from './common/gragh';
           editClassifyDom && editClassifyDom.addEventListener("click",(e)=>this.editClassify(e,treeNode))
           editClassifyDom && editClassifyDom.addEventListener("click",(e)=>this.editClassify(e,treeNode))
           delClassifyDom && delClassifyDom.addEventListener("click",(e)=>this.deleteClassify(e,treeNode))
           delClassifyDom && delClassifyDom.addEventListener("click",(e)=>this.deleteClassify(e,treeNode))
 
 
-          aObj.append(dom);
+        }else{
+          addClassifyDom && (addClassifyDom.style.display='none')
+          editClassifyDom && (editClassifyDom.style.display='none')
+          delClassifyDom && (delClassifyDom.style.display='none')
         }
         }
-
+        aObj.append(dom);
       },
       },
-      // removeHoverDom(treeId, treeNode) {
-      //   console.log(treeId, treeNode,'treeId, treeNode');
-      //   $("#diyBtn_"+treeNode.SandboxClassifyId).unbind().remove();
-	    //   $("#diyBtn_space_" +treeNode.SandboxClassifyId).unbind().remove();
-      // }
       addSand(){
       addSand(){
         const { href } = this.$router.resolve({ path: '/sandflow' });
         const { href } = this.$router.resolve({ path: '/sandflow' });
         window.open(href, '_blank');
         window.open(href, '_blank');
@@ -1031,12 +941,21 @@ import { myGraph } from './common/gragh';
         window.open(href, '_blank');
         window.open(href, '_blank');
       },
       },
       saveOther(){
       saveOther(){
+        sandInterface.getSandboxClassifyOnly().then(res=>{
+          if (res.Ret === 200) {
+            this.onlyClassifyTreeData=res.Data.AllNodes || []
+          }
+        })
         this.saveOtherForm.chartName = this.viewSandbox.Name+"(1)"
         this.saveOtherForm.chartName = this.viewSandbox.Name+"(1)"
         this.saveOtherShow=true
         this.saveOtherShow=true
       },
       },
+      classifyTreeChange(value){
+        if(!value){
+          this.saveOtherForm.classifyId=''
+        }
+        this.saveOtherForm.classifyId=value[value.length-1]
+      },
       saveOtherSubmit: _.debounce( function() {
       saveOtherSubmit: _.debounce( function() {
-        // console.log(this.viewSandbox);
-        // return 
         if(!this.graph.toJSON().cells.length) return this.$message.warning('画布无内容');
         if(!this.graph.toJSON().cells.length) return this.$message.warning('画布无内容');
         this.$refs.saveOtherFormRef.validate(valid=>{
         this.$refs.saveOtherFormRef.validate(valid=>{
           if(valid){
           if(valid){
@@ -1068,12 +987,13 @@ import { myGraph } from './common/gragh';
                 this.lockLoding.close();
                 this.lockLoding.close();
                 return;
                 return;
               }
               }
-              console.log(sandData,'sandData');
               this.lockLoding.close();
               this.lockLoding.close();
               this.$message.success("另存为成功")
               this.$message.success("另存为成功")
-              let saveOtherIds = this.saveOtherClassifys.split(',')
-              saveOtherIds.push(sandData.SandboxId)
-              this.sandboxLocation(saveOtherIds)
+              //沙盘图详情
+              this.getSandboxDetailFun(sandData.SandboxId)
+
+              this.saveOtherClassifys.push(sandData.SandboxId)
+              this.sandboxLocation(this.saveOtherClassifys)
               this.saveOtherShow=false
               this.saveOtherShow=false
             },{
             },{
               preserveDimensions:true,//让svg为实际图片大小
               preserveDimensions:true,//让svg为实际图片大小
@@ -1088,19 +1008,6 @@ import { myGraph } from './common/gragh';
                 svg.setAttribute('viewBox',`${x-30} ${y-30} ${width+60} ${height+60}`)
                 svg.setAttribute('viewBox',`${x-30} ${y-30} ${width+60} ${height+60}`)
                 // // 在图表右下方 加上"来源:弘则研究"字样
                 // // 在图表右下方 加上"来源:弘则研究"字样
                 // let gNode = svg.getElementsByClassName('x6-graph-svg-viewport')[0]
                 // let gNode = svg.getElementsByClassName('x6-graph-svg-viewport')[0]
-                // 去掉不该截图的添加图标
-                let leftImg = svg.getElementsByClassName('left-topic-image')
-                for (let i = 0; i < leftImg.length; i++) {
-                  const element = leftImg[i];
-                  element.parentElement.removeChild(element)
-                  i--
-                }
-                let rightImg = svg.getElementsByClassName('right-topic-image')
-                for (let i = 0; i < rightImg.length; i++) {
-                  const element = rightImg[i];
-                  element.parentElement.removeChild(element)
-                  i--
-                }
                 // let textNode = document.createElement('text')
                 // let textNode = document.createElement('text')
                 // textNode.setAttribute('x',(x-tx+width)/zoom-85)
                 // textNode.setAttribute('x',(x-tx+width)/zoom-85)
                 // textNode.setAttribute('y',(y-ty+height)/zoom+27)
                 // textNode.setAttribute('y',(y-ty+height)/zoom+27)
@@ -1117,6 +1024,12 @@ import { myGraph } from './common/gragh';
                 .x6-port {
                 .x6-port {
                     visibility: hidden;
                     visibility: hidden;
                 }
                 }
+                .left-topic-image{
+                  visibility:hidden;
+                }
+                .right-topic-image{
+                  visibility: hidden;
+                }
                 ` 
                 ` 
             })
             })
           }
           }
@@ -1126,10 +1039,11 @@ import { myGraph } from './common/gragh';
       },500),
       },500),
       saveOtherClosed(){
       saveOtherClosed(){
         this.saveOtherForm={
         this.saveOtherForm={
-          chartName:"逻辑图名称",
+          chartName:"",
           classifyId:""
           classifyId:""
         }
         }
-        this.selectZTreeObj.cancelSelectedNode()
+        this.saveOtherClassifys=[]
+        // this.selectZTreeObj.cancelSelectedNode()
         this.$refs.saveOtherFormRef.clearValidate()
         this.$refs.saveOtherFormRef.clearValidate()
       },
       },
       copySandHandle: _.debounce(function() {
       copySandHandle: _.debounce(function() {
@@ -1153,8 +1067,6 @@ import { myGraph } from './common/gragh';
         img.onload = ()=>{
         img.onload = ()=>{
           canvas.width = img.width;
           canvas.width = img.width;
           canvas.height = img.height;
           canvas.height = img.height;
-          // console.log('width',img.width)
-          // console.log('height',img.height)
           ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
           ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
           ctx.fillStyle="#fff";
           ctx.fillStyle="#fff";
           ctx.fillRect(0, 0, img.width, img.height);
           ctx.fillRect(0, 0, img.width, img.height);
@@ -1182,26 +1094,13 @@ import { myGraph } from './common/gragh';
         preserveDimensions:true,//让svg为实际图片大小
         preserveDimensions:true,//让svg为实际图片大小
         beforeSerialize:(svg)=>{
         beforeSerialize:(svg)=>{
           const {x,y,width,height} = this.graph.getContentBBox(cells)
           const {x,y,width,height} = this.graph.getContentBBox(cells)
-          let {tx,ty} = this.graph.translate()
+          // let {tx,ty} = this.graph.translate()
           //给导出的svg增加一点宽高
           //给导出的svg增加一点宽高
           svg.setAttribute('width',width+60)
           svg.setAttribute('width',width+60)
           svg.setAttribute('height',height+60) 
           svg.setAttribute('height',height+60) 
           //设置viewBox使图像居中
           //设置viewBox使图像居中
           svg.setAttribute('viewBox',`${x-30} ${y-30} ${width+60} ${height+60}`)
           svg.setAttribute('viewBox',`${x-30} ${y-30} ${width+60} ${height+60}`)
           // let gNode = svg.getElementsByClassName('x6-graph-svg-viewport')[0]
           // let gNode = svg.getElementsByClassName('x6-graph-svg-viewport')[0]
-          // 去掉不该截图的添加图标
-          let leftImg = svg.getElementsByClassName('left-topic-image')
-          for (let i = 0; i < leftImg.length; i++) {
-            const element = leftImg[i];
-            element.parentElement.removeChild(element)
-            i--
-          }
-          let rightImg = svg.getElementsByClassName('right-topic-image')
-          for (let i = 0; i < rightImg.length; i++) {
-            const element = rightImg[i];
-            element.parentElement.removeChild(element)
-            i--
-          }
           // let textNode = document.createElement('text')
           // let textNode = document.createElement('text')
           // textNode.setAttribute('x',x-tx+width-90)
           // textNode.setAttribute('x',x-tx+width-90)
           // textNode.setAttribute('y',y-ty+height+22)
           // textNode.setAttribute('y',y-ty+height+22)
@@ -1210,38 +1109,28 @@ import { myGraph } from './common/gragh';
           // textNode.innerText = '来源:弘则研究'
           // textNode.innerText = '来源:弘则研究'
           // gNode.appendChild(textNode)
           // gNode.appendChild(textNode)
             },
             },
-        copyStyles:false,
-        stylesheet: `
+          copyStyles:false,
+          stylesheet: `
             svg{
             svg{
                 background-color:white;
                 background-color:white;
             }
             }
           .x6-port {
           .x6-port {
               visibility: hidden;
               visibility: hidden;
+          }
+          .left-topic-image{
+            visibility:hidden;
+          }
+          .right-topic-image{
+            visibility: hidden;
           }` 
           }` 
         })
         })
       },500),
       },500),
-      selectClassify(event,treeId,treeNode,clickFlag){
-        // console.log(treeNode);
-        this.saveOtherForm.classifyId = treeNode.SandboxClassifyId
-        this.saveOtherClassifys=this.getParentClassifyIds(treeNode)
-        this.selectClassifyShow = false
-      },
-      getParentClassifyIds(treeNode){
-        let parentNode = treeNode.getParentNode()
-        if(parentNode){
-          return this.getParentClassifyIds(parentNode)+','+treeNode.SandboxClassifyId
-        }else{
-          return treeNode.SandboxClassifyId+''
-        }
-      },
       //==============================画布
       //==============================画布
       // 初始化画布
       // 初始化画布
       init() {
       init() {
-        const graph = new myGraph('sand-chart-body',null,'','view');
-        console.log(graph,'graph');
+        const graph = new myGraph('sand-chart-body',null,'view');
         this.graph = graph;
         this.graph = graph;
         graph.on('node:mouseenter', ({ node, e }) => {
         graph.on('node:mouseenter', ({ node, e }) => {
-          console.log(node);
           let data = node.data
           let data = node.data
           this.linkNode = node
           this.linkNode = node
           if(data && data.linkData && data.linkData.length>0){
           if(data && data.linkData && data.linkData.length>0){
@@ -1266,10 +1155,6 @@ import { myGraph } from './common/gragh';
                 })
                 })
                 let clinetPositon=graph.localToClient(node.position())
                 let clinetPositon=graph.localToClient(node.position())
                 let size=node.size()
                 let size=node.size()
-                console.log(clinetPositon,'clinetPositon',node.position());
-                // const dom = $('#link-reference')[0];
-                // console.log(this.popoverTriggerDom,'domdomdom');
-                console.log(clinetPositon.x+size.width/2,clinetPositon.y);
                 this.popoverTriggerDom.style.left = clinetPositon.x+size.width/2 + 'px';
                 this.popoverTriggerDom.style.left = clinetPositon.x+size.width/2 + 'px';
                 this.popoverTriggerDom.style.top = clinetPositon.y + 'px';
                 this.popoverTriggerDom.style.top = clinetPositon.y + 'px';
                 this.popoverVisible=true
                 this.popoverVisible=true
@@ -1300,7 +1185,6 @@ import { myGraph } from './common/gragh';
         })
         })
       },
       },
       navigateTo(item){
       navigateTo(item){
-        console.log(item,'item');
         if(item.Type == 1){
         if(item.Type == 1){
           if(item.databaseType==0){
           if(item.databaseType==0){
             // 普通指标
             // 普通指标

+ 649 - 0
src/views/sandbox_manage/sandFlowNew/components/addLInkDia.vue

@@ -0,0 +1,649 @@
+<template>
+    <el-dialog :modal-append-to-body='false' title="添加链接" :visible.sync="show" 
+    :close-on-click-modal="false" width="872px" top="5vh">
+      <div class="add-link-box">
+        <div class="link-box-option">
+          <el-select v-model="addLinkSearchParams.linkType" placeholder="链接类型" style="width: 240px;" @change="changeLinkType">
+            <el-option :label="item.label" :value="item.value" v-for="item in linkTypeList" :key="item.value"></el-option>
+          </el-select>
+          <el-select v-if="addLinkSearchParams.linkType==1"
+            v-model="search_dataBaseId"
+            v-loadMore="dataBaseSearchLoad"
+            ref="searchRef"
+            :filterable="!search_dataBaseId"
+            remote
+            clearable
+            placeholder="指标ID/指标名称"
+            style="width: 240px"
+            :remote-method="dataBaseSearch"
+            @click.native="dataBaseInputFocus"
+          >
+            <i slot="prefix" class="el-input__icon el-icon-search"></i>
+            <el-option
+              v-for="item in dataBaseOptions"
+              :key="item.EdbInfoId"
+              :label="item.EdbName"
+              :value="item.EdbInfoId"
+            >
+            </el-option>
+          </el-select>
+          <el-select v-else-if="addLinkSearchParams.linkType==2"
+            v-model="search_dataBaseId"
+            v-loadMore="dataBaseSearchLoad"
+            ref="searchRef"
+            :filterable="!search_dataBaseId"
+            remote
+            clearable
+            placeholder="图表名称"
+            style="width: 240px"
+            :remote-method="dataBaseSearch"
+            @click.native="dataBaseInputFocus"
+          >
+            <i slot="prefix" class="el-input__icon el-icon-search"></i>
+            <el-option
+              v-for="item in dataBaseOptions"
+              :key="item.ChartInfoId"
+              :label="item.ChartName"
+              :value="item.ChartInfoId"
+            >
+            </el-option>
+          </el-select>
+          <el-input v-else v-model="reportKeyWord" @input="searchReport"
+          placeholder="标题 / 创建人" style="width: 240px;" clearable >
+            <i slot="prefix" class="el-input__icon el-icon-search"></i>
+          </el-input>
+        </div>
+        <div class="link-box-content">
+          <!-- 指标 -->
+          <div class="link-content-dataIndex" v-if="addLinkSearchParams.linkType==1 && databaseTableData && databaseTableData.length>0">
+            <el-table :data="databaseTableData" border style="box-shadow: rgba(155, 170, 219, 0.2) 0px 3px 6px;">
+              <el-table-column label="指标Id" align="center">
+                <template slot-scope="scope">{{ scope.row.EdbCode }}</template>
+              </el-table-column>
+              <el-table-column label="指标名称" align="center" width="200">
+                <template slot-scope="scope">{{ scope.row.EdbName }}</template>
+              </el-table-column>
+              <el-table-column label="频度" align="center" width="50">
+                <template slot-scope="scope">{{ scope.row.Frequency }}</template>
+              </el-table-column>
+              <el-table-column label="单位" align="center">
+                <template slot-scope="scope">{{ scope.row.Unit }}</template>
+              </el-table-column>
+              <el-table-column label="起始时间" align="center" width="100">
+                <template slot-scope="scope">{{ scope.row.StartDate }}</template>
+              </el-table-column>
+              <el-table-column label="更新时间" align="center" width="160">
+                <template slot-scope="scope">{{ scope.row.ModifyTime }}</template>
+              </el-table-column>
+              <el-table-column label="来源" align="center">
+                <template slot-scope="scope">{{ scope.row.SourceName }}</template>
+              </el-table-column>
+              <el-table-column label="操作" align="center" width="50">
+                <template slot-scope="scope">
+                  <span class="delete-button">删除</span>
+                </template>
+              </el-table-column>
+            </el-table>
+            <ul 
+              class="value-ul" 
+              ref="valueUl" 
+              @scroll="databaseScrollHandle" 
+              v-show="databaseList.length">
+              <li
+                class="value-item"
+                v-for="item in databaseList"
+                :key="item.EdbDataId"
+              >
+                <span class="value-label">
+                  <span style="position: relative;">
+                    <i class="new-tag" v-if="databaseTableData[0].LatestDate===item.DataTime"></i>
+                    {{item.DataTime}}
+                  </span>
+                </span>
+                <span :class="['value-label',{'predict-act': databaseTableData[0].DataInsertConfig.Date===item.DataTime}]" style="min-width:200px;text-align:center;">
+                  <span :class="['value-style',{'predict-act': databaseTableData[0].DataInsertConfig.Date===item.DataTime}]">{{item.Value}}</span>
+                </span>
+              </li>
+              <li class="nodata value-item" v-if="!databaseList.length">暂无数据</li>
+            </ul>
+          </div>
+          <div class="link-content-chartIndex" v-else-if="addLinkSearchParams.linkType==2 && this.chartInfo && this.chartInfo.ChartInfoId">
+            <div class="chart-name">{{ this.chartInfo.ChartName }}</div>
+            <Chart :options="options" ref="chartRef" />
+          </div>
+          <div class="link-content-dataIndex" v-else-if="addLinkSearchParams.linkType==3 && this.reportList.length>0">
+            <el-table :data="this.reportList" border style="margin-bottom: 10px;" ref="reportTable"
+            @select="reportSelect" @select-all="reportSelect"> 
+              <el-table-column type="selection" width="40" align="center"></el-table-column>
+              <el-table-column label="报告标题" align="center" show-overflow-tooltip>
+                <template slot-scope="scope">
+                  <span >{{ scope.row.Title }}</span>
+                  <span  v-if="scope.row.MsgSendTime">
+                    ({{ scope.row.MsgSendTime.substring(5, 7)}}{{ scope.row.MsgSendTime.substring(8, 10) }})
+                  </span>
+                  <span v-else-if="scope.row.PublishTime">
+                    ({{ scope.row.PublishTime.substring(5, 7)}}{{ scope.row.PublishTime.substring(8, 10) }})
+                  </span>
+                  <span v-else-if="scope.row.CreateTime">
+                    ({{ scope.row.CreateTime.substring(5, 7)}}{{ scope.row.CreateTime.substring(8, 10) }})
+                  </span>
+                </template>
+              </el-table-column >
+              <el-table-column label="发布时间" align="center">
+                <template slot-scope="scope">
+                  <span>{{scope.row.PrePublishTime?scope.row.PrePublishTime:scope.row.PublishTime}}</span>
+                </template>
+              </el-table-column>
+            </el-table>
+            <m-page :page_no="reportParams.CurrentIndex" :pageSize="5" :total="reportTotal" @handleCurrentChange="pageChange"/>
+          </div>
+          <tableNoData text="暂无数据" v-else/>
+        </div>
+        <div class="link-box-tags">
+          <div class="link-box-tag" v-for="(item,index) in checkedLinkList" :key="item.RId">
+            <span @dblclick.stop="editLinkName(item)" v-if="!item.editing" @click="linkClick(item)">{{ item.Name }}</span>
+            <el-input v-else @blur="editLinkNameFinish(item)" 
+              v-model.trim="editingLabel" class="label-edit-input" ref="labelEditInput"/>
+            <img src="~@/assets/img/sand_new/delete_outline_1.png" @click="linkDelete(item,index)">
+          </div>
+        </div>
+        <div class="link-box-buttons">
+          <el-button type="info" style="width:120px;color:#333333;background-color:#F4F8FE" @click="cancelHandle">取消</el-button>
+          <el-button type="primary" style="width:120px;margin-left: 30px;" @click="saveLink">确定</el-button>
+        </div>
+      </div>
+		</el-dialog>
+</template>
+
+<script>
+import { chartSetMixin } from '../../../dataEntry_manage/mixins/chartPublic'
+import * as sheetInterface from "@/api/modules/sheetApi.js";
+import mPage from "@/components/mPage.vue";
+import Chart from '../../../dataEntry_manage/components/chart.vue'
+import { dataBaseInterface,reportlist} from '@/api/api.js';
+
+  export default {
+    components:{
+      mPage,Chart
+    },
+    props:{
+      show:{
+        reuqired:true,
+        type:Boolean
+      },
+      linkList:{
+        type:Array,
+        default:()=>[]
+      }
+    },
+    mixins:[chartSetMixin],
+    watch:{
+      /* 选中搜索指标 展开目录 选中指标 展示数据 */
+      search_dataBaseId(newval) {
+        if (newval) {
+          if(this.addLinkSearchParams.linkType==1){
+            let search_obj = this.dataBaseOptions.find(
+              (item) => item.EdbInfoId === newval
+            );
+            if(search_obj){
+              this.checkedLinkList.push({
+                RId:this.addLinkSearchParams.linkType+'-'+search_obj.EdbInfoId,
+                Id:search_obj.EdbInfoId,
+                Name:search_obj.EdbName,
+                Type:this.addLinkSearchParams.linkType,
+                editing:false,
+                databaseType:search_obj.EdbInfoType, //0 普通指标 | 1 预测指标
+                detailParams:{
+                  code:search_obj.UniqueCode,
+                  id:search_obj.EdbInfoId,
+                  classifyId:search_obj.ClassifyId
+                }
+              })
+              this.activeItemRId=this.addLinkSearchParams.linkType+'-'+search_obj.EdbInfoId
+              this.initGetData()
+            }
+          }else{
+            let search_obj = this.dataBaseOptions.find(
+              (item) => item.ChartInfoId === newval
+            );
+            if(search_obj){
+              this.checkedLinkList.push({
+                RId:this.addLinkSearchParams.linkType+'-'+search_obj.ChartInfoId,
+                Id:search_obj.ChartInfoId,
+                Name:search_obj.ChartName,
+                Type:this.addLinkSearchParams.linkType,
+                editing:false,
+                detailParams:{
+                  code:search_obj.UniqueCode,
+                  id:search_obj.ChartInfoId
+                }
+              })
+              this.activeItemRId=this.addLinkSearchParams.linkType+'-'+search_obj.ChartInfoId
+              this.getChartDetail(search_obj.ChartInfoId)
+            }
+          }
+        }
+      },
+      edbData: {
+        handler(newval, oldval) {
+          newval.length && !this.chartInfo.WarnMsg && this.setChartOptionHandle(newval);
+        },
+        deep: true,
+      },
+      show(value){
+        if(value){
+          this.addLinkSearchParams.linkType=1
+          this.changeLinkType()
+          this.checkedLinkList = JSON.parse(JSON.stringify(this.linkList))
+        }
+      }
+    },
+    data() {
+      return {
+        linkTypeList:[
+          {value:1,label:"ETA指标/预测指标"},
+          {value:2,label:"ETA图库"},
+          {value:3,label:"ETA研报"}
+        ],
+        addLinkSearchParams:{
+          linkType:1
+        },
+        //添加链接:指标
+        search_dataBaseId:'',
+        dataBaseParams:{
+          pages:1,
+          searchText:'',
+          search_have_more:false
+        },
+        dataBaseOptions:[],
+
+        databaseTableData:[],
+        databaseList:[],
+        databaseHaveMore:false,
+        databasePageNo:1,
+        chartInfo:{},
+        edbData:[],
+        options:{},
+        reportKeyWord:'',
+        reportParams:{
+          CurrentIndex:1,
+          PageSize:5,
+        },
+        reportList:[],
+        selections:[],
+        checkedLinkList:[],
+        reportTotal:0,
+        editingLabel:'',
+        activeItemRId:'',
+      }
+    },
+    methods: {
+      // -------------------------------添加链接
+      changeLinkType(){
+        this.search_dataBaseId=''
+        this.dataBaseOptions=[]
+        this.dataBaseParams={
+          pages:1,
+          searchText:'',
+          search_have_more:false
+        }
+
+        this.databaseTableData=[]
+        this.databaseList=[]
+        this.databaseHaveMore=false
+        this.databasePageNo=1
+        
+        this.chartInfo={}
+        this.edbData=[]
+
+        this.reportKeyWord=''
+        this.reportList=[]
+      },
+      /* 搜索 */
+      dataBaseSearch(query) {
+        this.dataBaseParams.pages = 1;
+        this.dataBaseParams.searchText = query;
+        this.dataBaseSearchApi(this.dataBaseParams.searchText)
+      },
+      // 加载更多
+      dataBaseSearchLoad() {
+        if(!this.dataBaseParams.search_have_more) return;
+        this.dataBaseSearchApi(this.dataBaseParams.searchText,++this.dataBaseParams.pages);
+      },
+      /* 聚焦获取当前检索 */
+      dataBaseInputFocus(e) {
+        this.dataBaseParams.pages = 1;
+        this.dataBaseParams.searchText = e.target.value;
+        if(this.dataBaseParams.searchText) {
+          this.dataBaseSearchApi(this.dataBaseParams.searchText);
+        }else {
+          this.searchOptions = [];
+          this.dataBaseParams.search_have_more=false
+        }
+
+      },
+      dataBaseSearchApi(query,page=1) {
+        if(this.addLinkSearchParams.linkType==1){
+          sheetInterface.searchTarget({
+            KeyWord:query,
+            CurrentIndex: page
+          }).then(res => {
+            if(res.Ret !== 200) return
+            const { List,Paging } = res.Data;
+            this.dataBaseParams.search_have_more = page < Paging.Pages;
+            this.dataBaseOptions = page === 1 ? List : this.dataBaseOptions.concat(List);
+          })
+        }else{
+          dataBaseInterface.chartSearchByEs({
+            Keyword: query,
+            IsShowMe:false,
+            CurrentIndex: page
+          })
+          .then((res) => {
+            if (res.Ret !== 200) return
+            const { List,Paging } = res.Data;
+            this.dataBaseParams.search_have_more = page < Paging.Pages;
+            this.dataBaseOptions = page === 1 ? List : [...this.dataBaseOptions,...List];
+          });
+        }
+
+      },
+      initGetData() {
+        this.databasePageNo = 1;
+        if(this.$refs.edb_detail_data){
+          this.$refs.valueUl.scrollTop=0
+        }
+        this.getDatabaseList();
+      },
+      getDatabaseList(){
+        dataBaseInterface.targetList({
+          PageSize: 20,
+          CurrentIndex: this.databasePageNo,
+          EdbInfoId: this.search_dataBaseId,
+        }).then(res => {
+          if(res.Ret === 200) {
+            if(res.Data) {
+              this.databaseTableData = [res.Data.Item] || [];
+              this.databaseHaveMore =  this.databasePageNo < res.Data.Paging.Pages ? true : false;
+              this.databaseList = this.databasePageNo === 1 ? (res.Data.Item.DataList || []) : this.databaseList.concat(res.Data.Item.DataList);
+            }else {
+              this.databaseTableData = [];
+              this.databaseList = [];  
+            }
+          }
+        })
+      },
+      databaseScrollHandle:_.throttle(function() {
+        let scrollTop = this.$refs.valueUl.scrollTop;
+        let clientHeight = this.$refs.valueUl.clientHeight;
+        let scrollHeight = this.$refs.valueUl.scrollHeight;
+        if(scrollTop===0) return
+        if(scrollTop + clientHeight >= scrollHeight-10 && this.databaseHaveMore){
+          this.databasePageNo++
+          this.getDatabaseList()
+        }
+		  },200),
+      async getChartDetail(ChartInfoId) {
+        const res = await dataBaseInterface.getChartInfoById({ChartInfoId})
+        if (res.Ret !== 200) return;
+        this.chartInfo = res.Data.ChartInfo || {}
+        this.edbData = res.Data.EdbInfoList|| []
+
+        const chartTypeMap = {
+          7: this.initBarData, //柱形图
+          10: this.initSectionScatterData //截面散点
+        }
+
+        chartTypeMap[this.chartInfo.ChartType] && chartTypeMap[this.chartInfo.ChartType](res.Data);
+
+      },
+      editLinkName(item){
+        this.editingLabel = item.Name
+        item.editing=true
+        this.$nextTick(() => {
+          this.$refs.labelEditInput[0].focus();
+        });
+      },
+      linkClick(item){
+        if(this.activeItemRId == item.RId) return
+        this.activeItemRId = item.RId
+        if(item.Type==3){
+          this.$message.info('研报类型的暂无回显')
+        }else if(item.Type==1){
+          this.addLinkSearchParams.linkType=item.Type
+          this.changeLinkType()
+          this.initGetData() 
+        }else if(item.Type==2){
+          this.addLinkSearchParams.linkType=item.Type
+          this.changeLinkType()
+          this.getChartDetail(item.Id)
+        }
+
+      },
+      linkDelete(item,index){
+        if(this.activeItemRId == item.RId){
+          this.activeItemRId=""
+          this.changeLinkType()
+        }
+        if(item.Type==3){
+          let deleteId=this.selections.filter(it=> it.Id==item.Id)
+          if(deleteId[0]){
+            this.$refs.reportTable && this.$refs.reportTable.toggleRowSelection(deleteId[0],false)
+          }
+        }
+        this.checkedLinkList.splice(index,1)
+      },
+      editLinkNameFinish(item){
+        if (this.editingLabel) {
+          item.editing=false
+          item.Name = this.editingLabel
+        } else {
+          this.$message.warning('不能为空');
+        }
+      },
+      searchReport(){
+        this.reportParams.CurrentIndex=1
+        if(!this.reportKeyWord){
+          this.reportList=[]
+          this.reportTotal=0
+        }else{
+          this.getReportList()
+        }
+      },
+      getReportList(){
+        let params={
+          CurrentIndex: this.reportParams.CurrentIndex,
+          PageSize: this.reportParams.PageSize,
+          KeyWord:this.reportKeyWord,
+          State:2
+        }
+        reportlist(params).then((res) => {
+          if (res.Ret === 200) {
+            this.reportList = res.Data.List || [];
+            this.reportTotal = parseInt(res.Data.Paging.Totals);
+          }
+        });    
+      },
+      pageChange(page_no){
+        this.reportParams.CurrentIndex = page_no;
+        this.getReportList();
+      },
+      reportSelect(selection){
+        this.selections=selection
+        let allIds = this.reportList.map(it => {
+          return it.Id
+        })
+        let simpleSelections = selection.map(it => {
+          return {Id:it.Id,Code:it.ReportCode,Name:it.Title}
+        })
+
+        let unselectIds=[]
+
+        if(simpleSelections.length>0){
+          allIds.map(id =>{
+            if(simpleSelections.every(sele => id!=sele.Id )){
+              unselectIds.push(id)
+            }
+          })
+        }else{
+          unselectIds=allIds
+        }
+        //没有就增加
+        simpleSelections.map(item =>{
+          let rId = this.addLinkSearchParams.linkType+'-'+item.Id
+          if(this.checkedLinkList.every(sele => rId!=sele.RId )){
+            this.checkedLinkList.push({
+              RId:rId,
+              Id:item.Id,
+              Name:item.Name,
+              Type:this.addLinkSearchParams.linkType,
+              editing:false,
+              detailParams:{id:item.Id,code:item.Code}
+            })
+          }
+        })
+        //有就去掉
+        unselectIds.map(item =>{
+          let rId = this.addLinkSearchParams.linkType+'-'+item
+          let index = this.checkedLinkList.findIndex(link => rId==link.RId)
+          if(index!=-1){
+            this.checkedLinkList.splice(index,1)
+          }
+        })
+      },
+      saveLink(){
+        this.$emit("saveLink", this.checkedLinkList);
+      },
+      cancelHandle(){
+        this.$emit("update:show", false);
+      }
+    },
+  }
+</script>
+
+<style lang="scss" scoped>
+    .add-link-box{
+      padding: 15px 40px 35px;
+      .link-box-option{
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        margin-bottom: 30px;
+      }
+      .link-box-content{
+        margin-bottom: 30px;
+        .link-content-dataIndex{
+          display: flex;
+          flex-direction: column;
+          .value-ul {
+            flex-grow: 1;
+            overflow-y: auto;
+            margin-top: 10px;
+            height: 200px;
+            border-bottom: 1px solid #EBEFF6;
+            .value-item {
+              /* width: 100%; */
+              padding: 10px 0;
+              border: 1px solid #dcdfe6;
+              border-bottom: none;
+              display: flex;
+              justify-content: space-around;
+              >span{
+                padding:0 16px;
+                box-sizing: border-box;
+              }
+              .value-label {
+                position: relative;
+                color: #666;
+                .value-style{
+                  padding:5px;
+                  border-radius: 4px;
+                  &.predict-act {
+                    color: orange;
+                  }
+                }
+                &.date{
+                  &::after{
+                    content: '';
+                    position:absolute;
+                    right:0;
+                    top:-14px;
+                    height:calc(100% + 28px);
+                    width:1px;
+                    background-color: #dcdfe6;
+                  }
+                }
+              }
+              .predict-act {
+                color: orange;
+              }
+              .new-tag {
+                width: 6px;
+                height: 6px;
+                display: inline-block;
+                position: absolute;
+                left: -12px;
+                top: 50%;
+                transform: translateY(-50%);
+                border-radius: 50%;
+                background: #f00;
+              }
+            }
+            .nodata {
+              text-align: center;
+              padding: 40px 0;
+              color: #999;
+            }
+          }
+          .delete-button{
+            color: #AD352F;
+            font-size: 14px;
+            cursor: pointer;
+          }
+        }
+        .link-content-chartIndex{
+          .chart-name{
+            font-size: 16px;
+            text-align: center;
+            color: #333333;
+          }
+        }
+      }
+      .link-box-tags{
+        display: flex;
+        align-items: center;
+        overflow-x: auto;
+        .link-box-tag{
+          display: flex;
+          align-items: center;
+          padding: 0 8px;
+          height: 30px;
+          max-width: 250px;
+          background-color: #F8F8F8;
+          margin-right: 30px;
+          cursor: pointer;
+          &:last-child{
+            margin-right: 0;
+          }
+          span{
+            color: #666666;
+            white-space: nowrap;
+            overflow: hidden;
+            text-overflow: ellipsis;
+          }
+          img{
+            height: 16px;
+            width: 16px;
+            margin-left: 8px;
+          }
+        }
+      }
+      .link-box-buttons{
+        margin-top: 60px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+
+      }
+    }
+</style>

File diff suppressed because it is too large
+ 339 - 617
src/views/sandbox_manage/sandFlowNew/index.vue


+ 7 - 0
src/views/smartReport/components/StatisticAnalysis.vue

@@ -51,6 +51,7 @@ import chartRelevanceApi from "@/api/modules/chartRelevanceApi";
 import {
 import {
   fittingEquationInterface,
   fittingEquationInterface,
   statisticFeatureInterface,
   statisticFeatureInterface,
+  crossVarietyInterface
 } from "@/api/modules/chartRelevanceApi";
 } from "@/api/modules/chartRelevanceApi";
 export default {
 export default {
     data() {
     data() {
@@ -67,6 +68,10 @@ export default {
                 {
                 {
                     name:'统计特征',
                     name:'统计特征',
                     key:'统计特征'
                     key:'统计特征'
+                },
+                {
+                    name:'跨品种分析',
+                    key:'跨品种分析'
                 }
                 }
             ],
             ],
             keyword:'',
             keyword:'',
@@ -137,6 +142,8 @@ export default {
                 res = await fittingEquationInterface.searchChart(params);
                 res = await fittingEquationInterface.searchChart(params);
             } else if (this.activeType === '统计特征') {
             } else if (this.activeType === '统计特征') {
                 res = await statisticFeatureInterface.searchChart(params);
                 res = await statisticFeatureInterface.searchChart(params);
+            } else if (this.activeType === '跨品种分析') {
+                res = await crossVarietyInterface.searchChart(params);
             }
             }
 
 
             if (res.Ret !== 200) return;
             if (res.Ret !== 200) return;

+ 2 - 3
src/vuex/modules/sand.js

@@ -2,7 +2,6 @@
 import { configOpt,styleSettings } from '@/views/sandbox_manage/common/toolConfig';
 import { configOpt,styleSettings } from '@/views/sandbox_manage/common/toolConfig';
 
 
 const setSandboxToolStatus=(state,payload)=>{
 const setSandboxToolStatus=(state,payload)=>{
-	console.log(payload,'payload',state);
 	if(!(payload&&payload.length>0)){
 	if(!(payload&&payload.length>0)){
 		state.toolStatus.textDisabled=true
 		state.toolStatus.textDisabled=true
 		state.toolStatus.edgeDisabled=true
 		state.toolStatus.edgeDisabled=true
@@ -35,7 +34,7 @@ const setSandboxToolStatus=(state,payload)=>{
 		for (let i = 0; i < payload.length; i++) {
 		for (let i = 0; i < payload.length; i++) {
 			const element = payload[i];
 			const element = payload[i];
 			const attrs = element.getAttrs()
 			const attrs = element.getAttrs()
-			console.log(element.shape);
+			// console.log(element.shape);
 			if(element.shape.indexOf('edge')==-1){
 			if(element.shape.indexOf('edge')==-1){
 				state.toolStatus.textDisabled=false
 				state.toolStatus.textDisabled=false
 				state.toolStatus.edgeDisabled=true
 				state.toolStatus.edgeDisabled=true
@@ -68,7 +67,7 @@ const setSandboxToolStatus=(state,payload)=>{
 				endArrowSet.add(attrs.line.targetMarker)
 				endArrowSet.add(attrs.line.targetMarker)
 				const router = element.getRouter()
 				const router = element.getRouter()
 				const connector = element.getConnector()
 				const connector = element.getConnector()
-				console.log(router,connector,'router,connector');
+				// console.log(router,connector,'router,connector');
 				if(router && router.name=="normal"){
 				if(router && router.name=="normal"){
 					connectStyleSet.add(1)
 					connectStyleSet.add(1)
 				}else{
 				}else{

Some files were not shown because too many files changed in this diff