Browse Source

Merge branch 'master' into eta1.0.2

Karsa 1 year ago
parent
commit
87cc5d613a
83 changed files with 2111 additions and 1017 deletions
  1. 4 0
      build/webpack.base.conf.js
  2. 2 1
      config/dev.env.js
  3. 2 1
      config/prod.env.js
  4. 2 1
      config/prod.test.env.js
  5. 11 0
      index.html
  6. 1 0
      package.json
  7. 15 1
      src/api/modules/chartApi.js
  8. 9 0
      src/api/modules/futuresBaseApi.js
  9. 6 2
      src/api/modules/oldApi.js
  10. 11 1
      src/api/modules/predictEdbApi.js
  11. 14 0
      src/api/modules/toolBoxApi.js
  12. BIN
      src/assets/img/icons/tooltip.png
  13. 2 1
      src/mixins/theme.js
  14. 39 1
      src/routes/modules/chartRoutes.js
  15. 4 2
      src/utils/buttonConfig.js
  16. 184 0
      src/utils/common.js
  17. 6 2
      src/utils/commonOptions.js
  18. 1 1
      src/utils/svgToblob.js
  19. 1 0
      src/views/Home.vue
  20. 73 0
      src/views/chartRelevance_manage/components/explainDialog.vue
  21. 38 0
      src/views/chartRelevance_manage/components/explainText.js
  22. 4 3
      src/views/chartRelevance_manage/components/saveEdbToBaseDia.vue
  23. 20 4
      src/views/chartRelevance_manage/fittingEquationChartEditor.vue
  24. 2 2
      src/views/chartRelevance_manage/fittingEquationList.vue
  25. 21 6
      src/views/chartRelevance_manage/relevanceChartEditor.vue
  26. 24 8
      src/views/chartRelevance_manage/statisticFeatureChartEditor.vue
  27. 106 88
      src/views/classify_manage/classifyEnlist.vue
  28. 23 3
      src/views/dataEntry_manage/addChart.vue
  29. 4 3
      src/views/dataEntry_manage/adjustdata/adjustData.vue
  30. 5 4
      src/views/dataEntry_manage/codecount/index.vue
  31. 51 5
      src/views/dataEntry_manage/components/satterSeriesDia.vue
  32. 11 0
      src/views/dataEntry_manage/components/sectionalScatterOption.vue
  33. 6 1
      src/views/dataEntry_manage/databaseComponents/batchComptedDialog.vue
  34. 6 2
      src/views/dataEntry_manage/databaseComponents/chartTrendRender.vue
  35. 3 2
      src/views/dataEntry_manage/databaseComponents/completeTargetDia.vue
  36. 3 2
      src/views/dataEntry_manage/databaseComponents/computedDialog.vue
  37. 3 7
      src/views/dataEntry_manage/databaseComponents/diffusionIndexDia.vue
  38. 15 14
      src/views/dataEntry_manage/databaseComponents/fittingResidueDia.vue
  39. 6 5
      src/views/dataEntry_manage/databaseComponents/jointTargetDia.vue
  40. 49 72
      src/views/dataEntry_manage/databaseComponents/openDialog.vue
  41. 3 2
      src/views/dataEntry_manage/databaseComponents/operationDialog.vue
  42. 18 1
      src/views/dataEntry_manage/databaseComponents/smoothEdbDialog.vue
  43. 156 247
      src/views/dataEntry_manage/databaseList.vue
  44. 28 3
      src/views/dataEntry_manage/editChart.vue
  45. 3 1
      src/views/dataEntry_manage/mixins/addOreditMixin.js
  46. 1 1
      src/views/dataEntry_manage/mixins/chartPublic.js
  47. 13 1
      src/views/datasheet_manage/sheetList.vue
  48. 5 2
      src/views/mychart_manage/components/chartDetailDia.vue
  49. 19 0
      src/views/positionAnalysis_manage/components/chartDetail.vue
  50. 19 17
      src/views/positionAnalysis_manage/components/indexContent.vue
  51. 141 23
      src/views/positionAnalysis_manage/detail.vue
  52. 15 0
      src/views/positionAnalysis_manage/list.vue
  53. 3 2
      src/views/ppt_manage/mixins/mixins.js
  54. 4 1
      src/views/ppt_manage/newVersion/pptCatalog.vue
  55. 6 3
      src/views/ppt_manage/newVersion/pptEnCatalog.vue
  56. 38 3
      src/views/ppt_manage/newVersion/pptEnPublish.vue
  57. 36 3
      src/views/ppt_manage/newVersion/pptPublish.vue
  58. 1 0
      src/views/ppt_manage/newVersion/utils/untils.js
  59. 20 7
      src/views/predictEdb_manage/addPredicEdb.vue
  60. 22 12
      src/views/predictEdb_manage/components/classifyDia.vue
  61. 13 0
      src/views/predictEdb_manage/components/computedDialog.vue
  62. 1 1
      src/views/predictEdb_manage/components/edbDetail.vue
  63. 17 4
      src/views/predictEdb_manage/components/operationDialog.vue
  64. 91 133
      src/views/predictEdb_manage/mixins/mixin.js
  65. 69 89
      src/views/predictEdb_manage/predictEdb.vue
  66. 19 16
      src/views/report_manage/addreportNew.vue
  67. 28 10
      src/views/report_manage/editChapterReport.vue
  68. 19 15
      src/views/report_manage/editreportNew.vue
  69. 16 3
      src/views/report_manage/mixins/reportMixin.js
  70. 96 75
      src/views/report_manage/reportEn/reportEditor.vue
  71. 180 84
      src/views/report_manage/reportEn/reportlist.vue
  72. 1 1
      src/views/sandbox_manage/index.vue
  73. 1 1
      src/views/sandbox_manage/sandFlow/index.vue
  74. 1 1
      src/views/semantics_manage/semanticsPage.vue
  75. 3 2
      src/views/supply_manage/components/createTargetDia.vue
  76. 1 5
      src/views/system_manage/dataAuthManage.vue
  77. 5 2
      src/views/system_manage/etaBaseConfig.vue
  78. 12 0
      src/views/system_manage/operateAuthManage.vue
  79. 13 1
      src/views/system_manage/outlinkList.vue
  80. 143 0
      src/views/toolBox_manage/FederalReserveWatch.vue
  81. 44 0
      src/views/toolBox_manage/components/Sheet.vue
  82. BIN
      static/css/fonts/SourceHanSansSC-Regular.ttf
  83. BIN
      static/css/fonts/SourceHanSerifCN-Regular.ttf

+ 4 - 0
build/webpack.base.conf.js

@@ -17,6 +17,10 @@ module.exports = {
     // app: './src/main.js',
     app: ['babel-polyfill', './src/main.js']
   },
+  // 防止有依赖关联到fs而报错,浏览器不让用 fs
+  node: {
+    fs: "empty"
+  },
   output: {
     path:process.env.NODE_ENV === 'production'? config.build.assetsRoot:config.test.assetsRoot,
     filename: '[name].js',

+ 2 - 1
config/dev.env.js

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

+ 2 - 1
config/prod.env.js

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

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

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

+ 11 - 0
index.html

@@ -36,6 +36,17 @@
         input[type="password"]::-o-reveal{
             display: none;
         }
+    </style>
+    <!-- 字蛛压缩字体 -->
+    <style>
+        @font-face {
+            font-family: '思源黑体';
+            src: url(./static/css/fonts/SourceHanSansSC-Regular.ttf);
+        }
+        @font-face {
+            font-family: '思源宋体';
+            src: url(./static/css/fonts/SourceHanSerifCN-Regular.ttf);
+        }
     </style>
 	<script>
 		var _hmt = _hmt || [];

+ 1 - 0
package.json

@@ -38,6 +38,7 @@
     "js-md5": "^0.7.3",
     "less-loader": "^4.1.0",
     "lodash": "^4.17.21",
+    "minio": "^7.0.18",
     "pptxgenjs": "^3.10.0",
     "qrcode": "^1.4.4",
     "sortablejs": "^1.15.0",

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

@@ -2,6 +2,19 @@ import http from "@/api/http.js"
 
 /* 数据库管理模块  */
 const dataBaseInterface = {
+	/**
+	 * 指标库目录
+	 */
+	targetCatalog:params=>{
+		return http.get('/datamanage/classify/simple',params)
+	},
+	/**
+	 * 指标和目录拖动排序
+	 */
+	classifyMoveSort:params=>{
+		return http.post('/datamanage/edb_classify/move',params)
+	},
+
 	/**
 	 * 新增分类
 	 * @param {ClassifyName} params 
@@ -58,7 +71,8 @@ const dataBaseInterface = {
 		return http.get('/datamanage/classify/items/v2',params)
 	},
 	menuListV3: params => {
-		return http.get('/datamanage/classify/items/v3',params)
+		// return http.get('/datamanage/classify/items/v3',params)
+		return http.get('/datamanage/classify/tree',params)
 	},
 	/**
 	 * 通过分类查找指标列表数据

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

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

+ 6 - 2
src/api/modules/oldApi.js

@@ -164,8 +164,12 @@ const chapterQRCodeImg=params=>{
 	return http.post('/report/getSunCode',params)
 }
 //上传阿里云 oss获取临时票据
-const getOSSSign=()=>{
-	return http.get('/resource/oss/get_sts_token',{})
+/**
+ * @param {*} params.StorageSource number 1:oss 2:minio
+ * @returns 
+ */
+const getOSSSign=params=>{
+	return http.get('/resource/oss/get_sts_token',params)
 }
 
 /* 推送客户群设置 */

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

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

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

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

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


+ 2 - 1
src/mixins/theme.js

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

+ 39 - 1
src/routes/modules/chartRoutes.js

@@ -227,7 +227,7 @@ export default [
 	},
 
 	/* 持仓分析 */
-	{
+	/* {
 		path:'/',
 		component: home,
 		name: '持仓分析',
@@ -244,5 +244,43 @@ export default [
 				component:()=>import('@/views/positionAnalysis_manage/detail.vue'),
 			}
 		]
+	}, */
+	/* 工具箱 */
+	//ETA1.1.3:将持仓分析,商品价格曲线合并至工具箱
+	{
+		path:'/',
+		component:home,
+		name:'工具箱',
+		hidden:false,
+		children:[
+			{
+				path: 'positionAnalysisList',
+				name: '持仓列表',
+				component:()=>import('@/views/positionAnalysis_manage/list.vue')
+			},
+			{
+				path: 'positionAnalysisDetail',
+				name: '持仓详情',
+				component:()=>import('@/views/positionAnalysis_manage/detail.vue'),
+			},
+			{
+				path:'federalReserveWatch',
+				name:'联储观察',
+				component:()=>import('@/views/toolBox_manage/FederalReserveWatch.vue')
+			},{
+				path: "commordityChartBase",
+				name: "商品价格曲线",
+				component: () => import('@/views/futures_manage/commodityChartBase.vue')
+			},
+			{
+				path: "addCommodityChart",
+				name: "编辑图表",
+				component: () => import('@/views/futures_manage/chartEditor.vue'),
+				meta: { 
+					pathFrom: "commordityChartBase",
+					pathName: "商品价格曲线",
+				}
+			},
+		]
 	}
 ]

+ 4 - 2
src/utils/buttonConfig.js

@@ -72,11 +72,11 @@ export const classifyBtn={
     classifyList_cnClassify_childMenu:'classifyList:cnClassify:childMenu',//表单项:子目录
 }
 /*
-*--------英文分类----------- 
+*--------英文分类-----------   ETA_1.1.7 不区分英文研报和线上路演 统一使用英文研报的标识
 */
 export const enClassifyBtn = {
     classifyList_enClassify:'classifyList:enClassify',//英文分类这个选项卡是否展示
-    /* -------------线上路演------------- */
+    /* -------------线上路演------------- */ 
     classifyList_enClassify_roadshow:'classifyList:enClassify:roadshow',//线上路演这个选项卡是否展示
     classifyList_enClassify_rsDel:'classifyList:enClassify:rsDel',//线上路演一二级分类删除
     classifyList_enClassify_rsAuthSetting:'classifyList:enClassify:rsAuthSetting',//线上路演二级分类权限设置
@@ -245,6 +245,7 @@ export const edbDataPermission = {
     edbData_switchEn:'edbData:switchEn',//切换英文版
     edbData_classifyOpt_add:'edbData:classifyOpt:add',//添加/编辑分类
     edbData_classifyOpt_delete:'edbData:classifyOpt:delete',//删除分类
+    edbData_classifyOpt_move:'edbData:classifyOpt:move',//移动分类
     edbData_checkRelatedChart:'edbData:checkRelatedChart',//查看关联图表
     edbData_checkRelatedEdb:'edbData:checkRelatedEdb',//查看关联指标
     edbData_checkCalcChart:'edbData:checkCalcChart',//查看计算指标
@@ -272,6 +273,7 @@ export const predictEdbPermission = {
     edbPreData_isOnlyMine:'edbPreData:isOnlyMine',//只看我的
     edbPreData_classifyOpt_add:'edbPreData:classifyOpt:add',//添加/编辑分类
     edbPreData_classifyOpt_delete:'edbPreData:classifyOpt:delete',//删除分类
+    edbPreData_classifyOpt_move:'edbPreData:classifyOpt:move',//移动分类
     edbPreData_checkRelatedChart:'edbPreData:checkRelatedChart',//查看关联图表
     edbPreData_checkRelatedEdb:'edbPreData:checkRelatedEdb',//查看关联指标
     edbPreData_checkPreRule:'edbPreData:checkPreRule',//查看预测规则

+ 184 - 0
src/utils/common.js

@@ -2,6 +2,11 @@
 // import  getNetworkType from './getNetworkType';
 // import  getSystemInfo from './getSystemInfo';
 
+import {Message} from "element-ui"
+import{getOSSSign} from "@/api/api.js"
+const Minio = require('minio')
+const stream = require('stream')
+
 // 根据字节流下载文件
 /**
  * @param {Blob} data 流数据
@@ -45,4 +50,183 @@ export function getUrlParams(str=window.location.href,key) {
 	str.split('?')[1].split('&').map(i => obj[(i.split('=')[0])] = i.split('=')[1]);
 
   return obj[key]
+}
+
+/**
+ * 
+ * @param {*} objectStorageClient oss-走oss 2-走minio string
+ * @param {*} file 上传文件
+ * @param {*} temName 文件路径/文件名字
+ * @param {*} options 文件路径/文件名字
+ * @param {*} options.OSS 上传至阿里云的配置
+ * @param {*} options.MINIO 上传至MINIO的配置
+ */
+
+// 上传文件 直接走对象存取服务器
+export function uploadFileDirect(objectStorageClient,file,temName,options={}){
+  const objectStorageType= (objectStorageClient || JSON.parse(localStorage.getItem('dynamicOutLinks')).ObjectStorageClient || 'oss')
+  // console.log(objectStorageType,'objectStorageType');
+  // return 
+  if(!objectStorageType){
+    Message.error("ObjectStorageClient参数丢失")
+    return new Promise((resolve,reject) => reject("ObjectStorageClient参数丢失"))
+  }
+  if(!file){
+    Message.error("file参数错误")
+    return new Promise((resolve,reject) => reject("file参数错误"))
+  }
+  if(!temName){
+    Message.error("temName参数错误")
+    return new Promise((resolve,reject) => reject("temName参数错误"))
+  }
+  // console.log(objectStorageType,file,temName,options,'objectStorageType,file,temName,options');
+  switch (objectStorageType) {
+    case "oss":
+      let ossOptions = {}
+      if(options.OSS){
+        ossOptions=options.OSS
+      }
+
+      return handleUploadToOSS(file,temName,ossOptions)
+      // break;
+    case "minio":
+      let minioOptions = {}
+      if(options.MINIO){
+        minioOptions=options.MINIO
+      }
+      return handleUploadToMinIO(file,temName,minioOptions)
+      // break;
+    default:
+      break;
+  }
+}
+
+const handleUploadToOSS= (file,fileName,options={})=>{
+  return new Promise(async (resolve,reject)=>{
+    // 获取oss临时签名
+    const res=await getOSSSign({StorageSource:1})
+    // console.log(res);
+    if(res.Ret!==200) reject("获取阿里云oss临时签名错误,res.Ret="+res.Ret)
+    try {
+
+      let oss_params = {
+        // yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
+        region: res.Data.RegionId,
+        // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
+        accessKeyId: res.Data.AccessKeyId,
+        accessKeySecret: res.Data.AccessKeySecret,
+        // 从STS服务获取的安全令牌(SecurityToken)。
+        stsToken: res.Data.SecurityToken,
+        // 填写Bucket名称,例如examplebucket。
+        bucket: res.Data.Bucketname,
+        endpoint: res.Data.Endpoint,
+        cname:true,
+        timeout:6000000
+      }
+  
+      let imgHost = res.Data.Imghost;
+  
+      const ALOSSINS=new OSS(oss_params);
+
+      const resp=await ALOSSINS.multipartUpload(fileName,file,{...options})
+      console.log('上传结果',resp);
+      if(resp.res.status===200){
+        let url=imgHost+resp.name
+        resolve(url)
+        console.log('oss文件地址',url);
+      }else{
+        throw new Error('上传到阿里云失败:res.status'+resp.res.status)
+      }
+    } catch (error) {
+      console.error(error);
+      if (error.name !== "cancel") {
+        Message.warning('上传失败,请刷新重试')
+      }
+      reject(error)
+    }
+  })
+}
+
+// minio sdk 文档 https://min.io/docs/minio/linux/developers/javascript/API.html
+const handleUploadToMinIO=(file,fileName,options={})=>{
+  return new Promise(async (resolve,reject)=>{
+
+    const res=await getOSSSign({StorageSource:2})
+    // console.log(res);
+    if(res.Ret!==200) reject("获取minio临时签名错误,res.Ret="+res.Ret)
+    // return
+    const minioClient = new Minio.Client({
+      endPoint: res.Data.Endpoint.split(':')[0],
+      port: Number(res.Data.Port)||undefined,
+      useSSL: res.Data.UseSSL.toLocaleLowerCase()=="false"?false:true,
+      accessKey: res.Data.AccessKeyId,
+      secretKey: res.Data.SecretKeyId,
+    })
+    console.log(minioClient);
+    try {
+      var metaData = {...{
+        'Content-Type': file.type||'application/octet-stream',
+        "Content-Length": file.size,
+      },...options}
+    
+      minioClient.bucketExists(res.Data.Bucketname, function (err, exists) {
+          if (err) {
+              throw "minio 查看桶是否存在失败"+err
+              // return console.log(err);
+          }
+          if (!exists) {
+            // 不存在桶,创建桶
+            console.log("桶不存在,先创建桶",res.Data.Bucketname);
+            minioClient.makeBucket(res.Data.Bucketname, res.Data.RegionId,function (err) {
+              if (err) {
+                throw "minio 创建桶失败"+err
+              }
+            
+              let reader = new FileReader();
+              // console.log(reader);
+              reader.readAsArrayBuffer(file);
+              reader.onloadend = function (e) {
+                const dataurl = e.target.result;
+                let bufferStream = new stream.PassThrough();
+                // 转化成数据流  minio接受数据流格式
+                bufferStream.end(Buffer.from(dataurl))
+                // console.log(bufferStream);
+                minioClient.putObject(res.Data.Bucketname, fileName, bufferStream,file.size, metaData, function (err, etag) {
+                  if (err){
+                    throw "上传到minio失败:"+err
+                  }
+            
+                })
+              }
+            })
+          }
+          if (exists) {
+            // console.log("桶存在",res.Data.Bucketname);
+            let reader = new FileReader();
+            console.log(reader);
+            reader.readAsArrayBuffer(file);
+            reader.onloadend = function (e) {
+              const dataurl = e.target.result;
+              let bufferStream = new stream.PassThrough();
+    
+              bufferStream.end(Buffer.from(dataurl))
+              minioClient.putObject(res.Data.Bucketname, fileName, bufferStream, metaData, function (err, etag) {
+                if (err){
+                  throw "上传到minio失败:"+err
+                }
+                let fileUrl = fileName.startsWith('/')?res.Data.ImgHost+fileName:res.Data.ImgHost+"/"+fileName
+                resolve(fileUrl)
+              })
+            }
+          }
+      })
+    } catch (error) {
+      console.error(error);
+      if (error.name !== "cancel") {
+        //不是取消上传的则给错误提示
+        this.$message.warning("上传失败,请刷新重试");
+      }
+      reject(error)
+    }
+  })
 }

+ 6 - 2
src/utils/commonOptions.js

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

+ 1 - 1
src/utils/svgToblob.js

@@ -30,7 +30,7 @@
           );
         })
       }else {
-        bus.$message.warning('浏览器暂不支持')
+        bus.$message.warning('当前协议暂不支持,仅支持https协议')
       }
     }	
  

+ 1 - 0
src/views/Home.vue

@@ -497,6 +497,7 @@ export default {
       getBusinessCode().then(res=>{
         if(res.Ret!==200) return 
         this.bus_code = res.Data||''
+        this.$setting.bus_code = this.bus_code
       })
     },
     //判断是否为初始密码

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

+ 6 - 1
src/views/dataEntry_manage/databaseComponents/batchComptedDialog.vue

@@ -249,6 +249,7 @@ export default {
 				label: 'ClassifyName',
 				value: 'ClassifyId',
 				children: 'Children',
+				checkStrictly: true
 			},
 			frequencyArr: ['日度', '周度','旬度', '月度', '季度', '年度'],
 			fre_options: ['天','周','月','季','年'],
@@ -374,14 +375,18 @@ export default {
 				: await dataBaseInterface.menuListV3()
 				if (res.Ret !== 200) return
 				//this.edbSource !== 'predict' && this.filterNodes(res.Data.AllNodes);
+				// this.options = res.Data.AllNodes || [];
+				
+				this.filterNodes(res.Data.AllNodes||[]);
 				this.options = res.Data.AllNodes || [];
+				
 		},
 		// 递归改变第三级目录结构
 		filterNodes(arr) {
 			arr.length &&
 				arr.forEach((item) => {
 					item.Children.length && this.filterNodes(item.Children);
-					if (item.Level === 2) {
+					if (!item.Children.length) {
 						delete item.Children;
 					}
 				});

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

+ 156 - 247
src/views/dataEntry_manage/databaseList.vue

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

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

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

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

@@ -224,6 +224,7 @@ export default {
 			this.$set(edb,'EdbAliasName',edb.EdbName)
 			if(have_bol) return this.$message.warning('录入指标已存在');
 			this.search_txt = '';
+			this.chartInfo.Unit = this.chartInfo.Unit||edb.Unit
 			this.tableData.push(edb)
 
 		},
@@ -617,7 +618,8 @@ export default {
 									YDate: edb.y_date,
 									YDateValue: edb.y_date_value,
 									IsShow: edb.is_show
-								}))
+								})),
+								IsNameDefault:this.IsNameDefault
 							}))
 						})
 					}	

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

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

+ 13 - 1
src/views/datasheet_manage/sheetList.vue

@@ -346,9 +346,21 @@ export default {
         ExcelClassifyId: _.ExcelClassifyId,
         ExcelClassifyName: _.ExcelClassifyName,
       }));
-
       return options;
     },
+
+     //数据表格是否展示
+    isShowDataSheet(){
+        const cell = {Source:2}
+        return this.isSheetBtnShow(cell,'edit')||this.isSheetBtnShow(cell,'refresh')||this.isSheetBtnShow(cell,'otherSave')
+            || this.isSheetBtnShow(cell,'download')||this.isSheetBtnShow(cell,'del')
+    },
+    //混合表格是否展示
+    isShowMixSheet(){
+        const cell = {Source:3}
+        return this.isSheetBtnShow(cell,'edit')||this.isSheetBtnShow(cell,'refresh')||this.isSheetBtnShow(cell,'otherSave')
+            || this.isSheetBtnShow(cell,'download')||this.isSheetBtnShow(cell,'del')
+    }
   },
   data() {
     return {

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

@@ -571,6 +571,8 @@ export default {
       bind(el, binding) {
         const clickHandle = (e)=>{
           //console.log(e.target.className)
+          //如果弹窗没打开就没必要执行了
+          if(!(this&&this.isOpenDetail)) return
           const isCurrentTarget = el.contains(e.target)||e.target.className==='el-popover el-popper'||['shareLink','copy'].some(str => e.target.className.includes(str))
           if(isCurrentTarget){
             return false
@@ -1063,9 +1065,10 @@ export default {
     saveChartMapHandle() {
       const sourceMap = {
         1: this.saveChartHandle,
-        2: this.saveCommodityChart
+        2: this.saveCommodityChart,
+        5: this.saveCommodityChart,//利润曲线
       }
-      sourceMap[this.chartInfo.Source]();
+      sourceMap[this.chartInfo.Source]&&sourceMap[this.chartInfo.Source]();
     },
 
     /* 商品价格图保存 */

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

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

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

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

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

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

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

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

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

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

+ 4 - 1
src/views/ppt_manage/newVersion/pptCatalog.vue

@@ -249,7 +249,10 @@
         <div class="tool-side ppt-page-wrap">
           <div class="ppt-info">
             <div>作者:{{pptItem.AdminRealName}}</div>
-            <div>{{pptItem.PptxUrl?'发布':'保存'}}时间:{{$moment(pptTime).format('YYYY-MM-DD')}}</div>
+            <div>
+              {{pptItem.PptxUrl?'发布':'保存'}}
+              时间:{{$moment(pptItem.PptxUrl?pptItem.PublishTime || undefined:pptItem.PptModifyTime || undefined).format('YYYY-MM-DD')}}
+            </div>
           </div>
           <div class="tool-list-operation">
             <span>操作</span>

+ 6 - 3
src/views/ppt_manage/newVersion/pptEnCatalog.vue

@@ -239,7 +239,10 @@
         <div class="tool-side ppt-page-wrap">
           <div class="ppt-info">
             <div>作者:{{pptItem.AdminRealName}}</div>
-            <div>{{pptItem.PptxUrl?'发布':'保存'}}时间:{{$moment(pptTime).format('YYYY-MM-DD')}}</div>
+            <div>
+              {{pptItem.PptxUrl?'发布':'保存'}}
+              时间:{{$moment(pptItem.PptxUrl?pptItem.PublishTime || undefined:pptItem.PptModifyTime || undefined).format('YYYY-MM-DD')}}
+            </div>
           </div>
           <div class="tool-list-operation">
             <span>操作</span>
@@ -1022,8 +1025,8 @@ export default {
     getTransSet(data){
       pptEnInterface.transPPTtoReport({
         PptId:this.pptItem.PptId,
-        ClassifyIdFirst:data.type[0],
-        ClassifyIdSecond:data.type[1]?data.type[1]:0,
+        ClassifyIdFirst:data.type[1]?data.type[1]:0,
+        ClassifyIdSecond:data.type[2]?data.type[2]:0,
         Title:data.title,
         Abstract:data.abstract
       }).then(res=>{

+ 38 - 3
src/views/ppt_manage/newVersion/pptEnPublish.vue

@@ -60,6 +60,8 @@ import {pptEnInterface} from '@/api/modules/pptEnApi.js';
 import Highcharts from "highcharts/highstock";
 import HighchartszhCN  from '@/utils/highcahrts-zh_CN'
 import HightchartsExport from 'highcharts/modules/exporting';
+import {uploadFileDirect} from "@/utils/common.js"
+
 HightchartsExport(Highcharts)
 HighchartszhCN(Highcharts)
 export default {
@@ -430,10 +432,43 @@ export default {
         text:"发布中..."
       })
       //console.log('pptx',pptx)
+      // pptx2.write('blob').then((data)=>{
+      //   // 上传到阿里云oss
+      //   // this.handleUploadToOSS(data)
+      // })
+      // 生成文件名
+      let t=new Date()
+      let month=moment(t).format('YYYYMM')
+      let day=moment(t).format('YYYYMMDD')
+      const temName=`ppt/${month}/${day}/${createRandomCode(32)}.pptx`
+
+      const options = {
+        OSS:{
+          // 获取分片上传进度、断点和返回值。
+          progress: (p, cpt, res) => {
+            console.log(p);
+              // this.percentage=parseInt(p*100)
+          },
+          // 设置并发上传的分片数量。
+          parallel: 10,
+          // 设置分片大小。默认值为1 MB,最小值为100 KB。
+          partSize: 1024 * 1024 * 10, // 10MB
+        }
+      };
+
       pptx2.write('blob').then((data)=>{
-        // 上传到阿里云oss
-        this.handleUploadToOSS(data)
+        let clientType = this.$setting.dynamicOutLinks.ObjectStorageClient ||
+                        this.$store.state.dynamicOutLinks.ObjectStorageClient ||
+                        JSON.parse(localStorage.getItem('dynamicOutLinks')).ObjectStorageClient
+        // 上传到 对象存储器 阿里云、mino
+        uploadFileDirect(clientType,data,temName,options).then(url=>{
+          console.log('文件地址',url);
+          this.publishPPT(url)
+        }).catch(err=>{
+          console.error(err);
+        })
       })
+
     },
     //计算各版式下,对应position在ppt中的位置
     getPosition(modelId, position) {
@@ -487,7 +522,7 @@ export default {
     async handleUploadToOSS(file){
       console.log(file);
       // 获取oss临时签名
-      const res=await getOSSSign()
+      const res=await getOSSSign({StorageSource:1})
       if(res.Ret!==200) return
 
       let oss_params = {

+ 36 - 3
src/views/ppt_manage/newVersion/pptPublish.vue

@@ -120,6 +120,8 @@ import{pptInterface,dataBaseInterface,getOSSSign} from "@/api/api.js"
 import Highcharts from "highcharts/highstock";
 import HighchartszhCN  from '@/utils/highcahrts-zh_CN'
 import HightchartsExport from 'highcharts/modules/exporting';
+import {uploadFileDirect} from "@/utils/common.js"
+
 HightchartsExport(Highcharts)
 HighchartszhCN(Highcharts)
 export default {
@@ -508,6 +510,28 @@ export default {
         fullscreen:true,
         text:"发布中..."
       })
+
+      // 生成文件名
+      let t=new Date()
+      let month=moment(t).format('YYYYMM')
+      let day=moment(t).format('YYYYMMDD')
+      /* const temName=`ppt/${month}/${day}/${this.coverInfo.page.Title}.pptx` */
+      const temName=`ppt/${month}/${day}/${createRandomCode(32)}.pptx`
+
+      const options = {
+        OSS:{
+          // 获取分片上传进度、断点和返回值。
+          progress: (p, cpt, res) => {
+            console.log(p);
+              // this.percentage=parseInt(p*100)
+          },
+          // 设置并发上传的分片数量。
+          parallel: 10,
+          // 设置分片大小。默认值为1 MB,最小值为100 KB。
+          partSize: 1024 * 1024 * 10, // 10MB
+        }
+      };
+
       //console.log('pptx',pptx)
       pptx2.write('blob').then((data)=>{
         // let form = new FormData()
@@ -519,7 +543,17 @@ export default {
         //   }
         // })
         // 上传到阿里云oss
-        this.handleUploadToOSS(data)
+        // this.handleUploadToOSS(data)
+        let clientType = this.$setting.dynamicOutLinks.ObjectStorageClient ||
+                        this.$store.state.dynamicOutLinks.ObjectStorageClient ||
+                        JSON.parse(localStorage.getItem('dynamicOutLinks')).ObjectStorageClient
+        // 上传到 对象存储器
+        uploadFileDirect(clientType,data,temName,options).then(url=>{
+          console.log('文件地址',url);
+          this.publishPPT(url)
+        }).catch(err=>{
+          console.error(err);
+        })
       })
     },
     //计算各版式下,对应position在ppt中的位置
@@ -592,7 +626,7 @@ export default {
     async handleUploadToOSS(file){
       console.log(file);
       // 获取oss临时签名
-      const res=await getOSSSign()
+      const res=await getOSSSign({StorageSource:1})
       if(res.Ret!==200) return
       
       let oss_params = {
@@ -617,7 +651,6 @@ export default {
       let t=new Date()
       let month=moment(t).format('YYYYMM')
       let day=moment(t).format('YYYYMMDD')
-      /* const temName=`ppt/${month}/${day}/${this.coverInfo.page.Title}.pptx` */
       const temName=`ppt/${month}/${day}/${createRandomCode(32)}.pptx`
       console.log('文件名',temName);
 

+ 1 - 0
src/views/ppt_manage/newVersion/utils/untils.js

@@ -500,6 +500,7 @@ export const caclShapeRealSize = (layer,shape)=>{
 //将rgba转为hex+透明度的格式
 //rgba(91,155,213,0.44) -> {color: "#5b9bd5",transparency: 56}
 const parseRgbaColor = (color) => {
+  if(!color) color='rgba(51, 51, 51, 1)'
   const arr = color.match(/(\d(\.\d+)?)+/g) || [];
   const res = arr.map((s) => parseInt(s, 10));
   return {

+ 20 - 7
src/views/predictEdb_manage/addPredicEdb.vue

@@ -36,6 +36,7 @@
                         label: 'ClassifyName',
                         value: 'ClassifyId',
                         children: 'Children',
+                        checkStrictly: true
                     }"
                     style="width: 90%"
                     placeholder="请选择所属分类"
@@ -379,6 +380,7 @@
         <div class="top-title">{{ formData.edbName }}</div>
         <chartInfo
           :edbData="edbData"
+          :isAllowEditLimit="true"
           @refreshData="refreshData"
           ref="chartInfo"
         />
@@ -590,6 +592,7 @@ export default {
           if (res.Ret !== 200) return;
           const {
             ClassifyId,
+            ClassifyList,
             EdbName,
             Frequency,
             LatestValue,
@@ -598,9 +601,10 @@ export default {
             LatestDate,
             DataDateType
           } = res.Data;
+          const classifyArr = ClassifyList.length&&ClassifyList.map(item=>item.ClassifyId).reverse()
           this.formData = {
             edb_id: EdbInfoId,
-            classify: ClassifyId,
+            classify: classifyArr||[],
             oldEdb: res.Data.CalculateList[0].FromEdbInfoId,
             oldEdbName: res.Data.CalculateList[0].FromEdbName,
             edbName: EdbName,
@@ -652,17 +656,26 @@ export default {
           };
         });
     },
-
+    // 递归改变目录结构
+		filterNodes(arr) {
+			arr.length &&
+				arr.forEach((item) => {
+					item.Children.length && this.filterNodes(item.Children);
+					if (!item.Children.length) {
+						delete item.Children;
+					}
+				});
+		},
     getClassifyOne() {
       preDictEdbInterface.classifyListV2().then((res) => {
         if (res.Ret !== 200) return;
-
+        this.filterNodes(res.Data.AllNodes || [])
         this.classifyArr = res.Data.AllNodes || [];
 
-        if (this.$route.path == "/editpredictEdb") {
-          //将formData.classify转为数组的格式
-          this.formData.classify = this.findParentNodeHandle(this.classifyArr,this.formData.classify).reverse()
-        } 
+        // if (this.$route.path == "/editpredictEdb") {
+        //   //将formData.classify转为数组的格式
+        //   this.formData.classify = this.findParentNodeHandle(this.classifyArr,this.formData.classify).reverse()
+        // } 
 
       });
     },

+ 22 - 12
src/views/predictEdb_manage/components/classifyDia.vue

@@ -19,18 +19,11 @@
 				:model="formData"
 				:rules="formRules">
 				
-				<!-- 添加一级目录的子分类/编辑二级目录时显示 -->
-				<template v-if="(title=='添加'&&formData.Level >= 1)||(title=='编辑'&&formData.Level >= 2)">
-					<el-form-item label="一级目录" prop="level_1_Name">
-						<span>{{formData.level_1_Name}}</span>
-					</el-form-item>
-				</template>
-				<!-- 添加二级目录的子分类/编辑三级目录时显示 -->
-				<template v-if="(title=='添加'&&formData.Level === 2)||(title=='编辑'&&formData.Level === 3)">
-					<el-form-item label="二级目录" prop="level_2_Name">
-						<span>{{formData.level_2_Name}}</span>
-					</el-form-item>
-				</template>
+				<el-form-item label="上级目录" v-if="formData.Level>0">
+					<el-tooltip class="item" effect="dark" :content="getParentName" placement="top">
+      					<span class="parentStr">{{getParentName}}</span>
+    				</el-tooltip>
+				</el-form-item>
 
 				<el-form-item label="目录名称" prop="classify_name">
 					<el-input
@@ -73,6 +66,16 @@ export default {
 			}
 		}
 	},
+	computed:{
+		getParentName(){
+			const arr=this.formData.parentArr||[]
+			let strArr=arr.reverse().map(item=>{
+				return item.classifyName
+			})
+			
+			return strArr.join('/')
+		}
+	},
 	data () {
 		return {			
 			formData: {},
@@ -113,6 +116,13 @@ export default {
 </script>
 <style lang='scss'>
 .predict-classify-dialog {
+	.parentStr{
+		display: block;
+		width: 304px;
+		overflow: hidden;
+		white-space: nowrap;
+		text-overflow: ellipsis;
+	}
 	.dialog-main {
 		padding-left: 50px;
 	}

+ 13 - 0
src/views/predictEdb_manage/components/computedDialog.vue

@@ -121,6 +121,7 @@
 							label: 'ClassifyName',
 							value: 'ClassifyId',
 							children: 'Children',
+							checkStrictly: true
 						}"
 						style="width: 90%"
 						placeholder="请选择所属分类"
@@ -266,11 +267,23 @@ export default {
 		};
 	},
 	methods: {
+		// 递归改变目录结构
+		filterNodes(arr) {
+			arr.length &&
+				arr.forEach((item) => {
+					item.Children.length && this.filterNodes(item.Children);
+					if (!item.Children.length) {
+						delete item.Children;
+					}
+				});
+		},
+
 		/* 获取目录结构 */
 		getMenu() {
 			preDictEdbInterface.classifyListV2().then(res => {
 				if(res.Ret !== 200) return
 
+				this.filterNodes(res.Data.AllNodes||[]);
 				this.options = res.Data.AllNodes || [];
 			}) 
 		},

+ 1 - 1
src/views/predictEdb_manage/components/edbDetail.vue

@@ -139,7 +139,7 @@ export default {
                 })
                 this.$emit('setOpera',res.Data.Button)
 
-                this.$emit('setCurrentClassify',res.Data.EdbInfo.ClassifyId)
+                this.$emit('setCurrentClassify',res.Data.ClassifyList||[])
                 //更新图片
                 if(type==='updateImg' || !res.Data.EdbInfo.ChartImage) {
                     console.log(type);

+ 17 - 4
src/views/predictEdb_manage/components/operationDialog.vue

@@ -191,6 +191,7 @@
 									label: 'ClassifyName',
 									value: 'ClassifyId',
 									children: 'Children',
+									checkStrictly: true
 								}"
 								style="width: 90%"
 								placeholder="请选择所属分类"
@@ -490,13 +491,25 @@ export default {
 			this.searchApi(this.current_search,++this.search_page)
 		},
 
+		// 递归改变目录结构
+		filterNodes(arr) {
+			arr.length &&
+				arr.forEach((item) => {
+					item.Children.length && this.filterNodes(item.Children);
+					if (!item.Children.length) {
+						delete item.Children;
+					}
+				});
+		},
+
 		/* 获取目录结构 */
 		getMenu() {
-      preDictEdbInterface.classifyListV2().then(res => {
-        if(res.Ret !== 200) return
+			preDictEdbInterface.classifyListV2().then(res => {
+				if(res.Ret !== 200) return
 
-        this.options = res.Data.AllNodes || [];
-      }) 
+				this.filterNodes(res.Data.AllNodes||[]);
+				this.options = res.Data.AllNodes || [];
+			}) 
 		},
 
 		/* 获取指标数据 */

+ 91 - 133
src/views/predictEdb_manage/mixins/mixin.js

@@ -75,7 +75,7 @@ export default {
 					? 'auto'
 					: width <= 260
 					? 80
-					: 0.5 * width;
+					: 0.35 * width;
 			this.$set(node, 'Nodewidth', label_wid + 'px');
 		},200),
 
@@ -108,121 +108,91 @@ export default {
 
     /* 拖拽完成 */
     dropOverHandle(b, a, i, e) {
-      // console.log(i, a);
+      console.log(b,a,i);
       // 被拖拽节点对应的 Node、结束拖拽时最后进入的节点、被拖拽节点的放置位置
-      // 一/二/三级目录
-      if ([1,2,3].includes(b.level)) this.handleMoveCatalogue(b, a, i, e);
-
-      // 指标层
-      if (b.level === 4) this.handleMoveSheet(b, a, i, e);
-    },
-
-    // 移动的为一/二/三级目录
-    handleMoveCatalogue(b, a, i, e) {
-      let list = a.parent.childNodes,
-        targetIndex = 0,
-        PrevClassifyId = 0,
-        NextClassifyId = 0,
-        ParentClassifyId = 0;
-
-      list.forEach((item, index) => {
-        if (item.data.ClassifyId === b.data.ClassifyId) {
-          targetIndex = index;
-          return;
-        }
-      });
-
-      if (targetIndex === 0) {
-        PrevClassifyId = 0;
-        NextClassifyId = list.length>1?list[targetIndex + 1].data.ClassifyId:0;
-      } else if (targetIndex === list.length - 1) {
-        PrevClassifyId = list[targetIndex - 1].data.ClassifyId;
-        NextClassifyId = 0;
-      } else {
-        PrevClassifyId = list[targetIndex - 1].data.ClassifyId;
-        NextClassifyId = list[targetIndex + 1].data.ClassifyId;
-      }
-      
-      if(b.level===2||b.level===3){
-        if(i==='inner'){
-            ParentClassifyId=a.data.ClassifyId
-            PrevClassifyId=0
-            NextClassifyId=a.data.Children.length>1?a.data.Children[1].ClassifyId:0
-        }else{
-            ParentClassifyId=a.data.ParentId
-        }
+      const isEDB=b.data.EdbCode?true:false
+			let list=a.parent.childNodes;
+			let targetIndex=0,PrevClassifyId=0,NextClassifyId=0,ParentClassifyId=0;
+			let ClassifyId=0,EdbInfoId=0,PrevEdbInfoId=0,NextEdbInfoId=0;
+
+			ClassifyId=isEDB?0:b.data.ClassifyId
+			EdbInfoId=isEDB?b.data.EdbInfoId:0
+
+			if(i!=='inner'){
+        ParentClassifyId=a.parent.data.ClassifyId||0
+				list.forEach((item,index)=>{
+					if(isEDB){
+						if(item.data.EdbInfoId===b.data.EdbInfoId){
+							targetIndex=index
+						}
+					}else{
+						if(item.data.ClassifyId===b.data.ClassifyId){
+							targetIndex=index
+						}
+					}
+					
+				})
+
+				console.log(targetIndex);
+				
+				
+				if(targetIndex===0){
+					const data=list[targetIndex+1].data
+					NextClassifyId=data.EdbCode?0:data.ClassifyId
+					NextEdbInfoId=data.EdbCode?data.EdbInfoId:0
+				}else if(targetIndex===list.length-1){
+					const data=list[targetIndex-1].data
+					PrevClassifyId=data.EdbCode?0:data.ClassifyId
+					PrevEdbInfoId=data.EdbCode?data.EdbInfoId:0
+				}else{
+					const pData=list[targetIndex-1].data
+					PrevClassifyId=pData.EdbCode?0:pData.ClassifyId
+
+					PrevEdbInfoId=pData.EdbCode?pData.EdbInfoId:0
+
+					const nData=list[targetIndex+1].data
+					NextClassifyId=nData.EdbCode?0:nData.ClassifyId
+					NextEdbInfoId=nData.EdbCode?nData.EdbInfoId:0
+				}
+			}else{
+        ParentClassifyId=a.data.ClassifyId||0
       }
 
-      preDictEdbInterface
-        .classifyMove({
-          ClassifyId: b.data.ClassifyId,
-          ParentClassifyId: ParentClassifyId,
-          PrevClassifyId: PrevClassifyId,
-          NextClassifyId: NextClassifyId,
-        })
-        .then((res) => {
-          if (res.Ret !== 200) return;
-          this.$message.success("移动成功!");
-          this.getTreeData();
-        });
-    },
-
-    // 移动的为指标
-    handleMoveSheet(b, a, i, e) {
-      let PrevEdbInfoId = 0,
-        NextEdbInfoId = 0,
-        targetIndex = 0,
-        list = a.parent.data.Children;
-      if (i === "inner") {
-        PrevEdbInfoId = 0;
-        NextEdbInfoId =
-          a.data.Children.length > 1 ? a.data.Children[1].EdbInfoId : 0;
-      } else {
-        list.forEach((item, index) => {
-          if (item.EdbInfoId === b.data.EdbInfoId) {
-            targetIndex = index;
-            return;
-          }
-        });
-
-        if (targetIndex === 0) {
-          PrevEdbInfoId = 0;
-          NextEdbInfoId = list[targetIndex + 1].EdbInfoId;
-        } else if (targetIndex === list.length - 1) {
-          PrevEdbInfoId = list[targetIndex - 1].EdbInfoId;
-          NextEdbInfoId = 0;
-        } else {
-          PrevEdbInfoId = list[targetIndex - 1].EdbInfoId;
-          NextEdbInfoId = list[targetIndex + 1].EdbInfoId;
-        }
-      }
-
-      preDictEdbInterface
-        .ebdMove({
-          ClassifyId: a.data.ClassifyId,
-          EdbInfoId: b.data.EdbInfoId,
-          PrevEdbInfoId,
-          NextEdbInfoId,
-        })
-        .then((res) => {
-          if (res.Ret !== 200) return;
-          this.$message.success("移动成功!");
-          this.getTreeData();
-        });
-
+			const params={
+				ClassifyId,
+				ParentClassifyId,
+				EdbInfoId,
+				PrevClassifyId,
+				NextClassifyId,
+				PrevEdbInfoId,
+				NextEdbInfoId
+			}
+			console.log(params);
+			preDictEdbInterface.classifyMoveSort(params).then(res=>{
+				if(res.Ret===200){
+					this.$message.success('移动成功!')
+				}
+				this.getTreeData()
+        this.$refs.detailComponentRef.getDetail()
+			})
     },
 
     /* 拖拽覆盖添加背景色 */
     dropMouseOver(node1, node2, e) {
-      if (
-        (node1.level === 2 && node2.level === 1) &&
-        (e.target.childNodes[0].className.includes("el-tree-node__content") ||
-          e.target.className.includes("el-tree-node__content"))
-      ) {
-        e.target.childNodes[0].className.includes("el-tree-node__content")
-          ? (e.target.childNodes[0].style.backgroundColor = "#409eff")
-          : (e.target.style.backgroundColor = "#409eff");
-      }
+      // 被拖拽节点对应的 Node、所进入节点对应的 Node、event
+			if((node1.level>node2.level||(node1.data.EdbInfoId>0&&!node2.data.EdbInfoId)) && (e.target.childNodes[0].className.includes('el-tree-node__content') 
+			|| e.target.className.includes('el-tree-node__content'))) {
+				// console.log(e.target.childNodes[0])
+				e.target.childNodes[0].className.includes('el-tree-node__content') 
+				? e.target.childNodes[0].style.backgroundColor = '#409eff' 
+				: e.target.style.backgroundColor = '#409eff';
+			}
+      const dropLine=$('.el-tree__drop-indicator')[0]
+			if(dropLine){
+				setTimeout(() => {
+					dropLine.style.top=e.layerY+'px'
+				}, 10);
+			}
     },
 
     /* 拖拽离开/拖拽完成重置背景色 */
@@ -263,30 +233,18 @@ export default {
     /* 判断节点是否能被拖入 */
     canDropHandle(draggingNode, dropNode, type) {
       let canDrop = false;
-      // 移动的是一级目录
-      if (draggingNode.level === 1 && dropNode.level === 1 &&type!=='inner') {
-        canDrop = true;
-      }
-
-      // 二级目录
-        if(draggingNode.level===2){
-            if((dropNode.level===1&&type==='inner')||(dropNode.level===2&&type!=='inner')){
-                canDrop=true
-            }
-        }
-
-        //三级目录
-        if(draggingNode.level===3){
-            if((dropNode.level===2&&type==='inner')||(dropNode.level===3&&type!=='inner')){
-                canDrop=true
-            }
-        }
-        //四级指标层
-        if(draggingNode.level===4){
-            if((dropNode.level===3&&type==='inner')||(dropNode.level===4&&type!=='inner')){
-                canDrop=true
-            }
-        }
+      // 如果拖动的是指标
+			if(draggingNode.data.EdbCode){
+				if(!(dropNode.level===1&&type!=='inner')){
+					canDrop=true
+				}
+			}else{//拖动的是目录
+				// console.log(dropNode.level,draggingNode.level);
+				//目录只能拖动到层级比他大的里面去
+				if(dropNode.level<draggingNode.level||(dropNode.level===draggingNode.level&&type!=='inner')){
+					canDrop=true
+				}
+			}
 
       return canDrop;
     },

+ 69 - 89
src/views/predictEdb_manage/predictEdb.vue

@@ -56,7 +56,7 @@
 						:allow-drop="canDropHandle"
 						:current-node-key="select_node"
 						:default-expanded-keys="defaultShowNodes"
-						draggable
+						:draggable="isEdbBtnShow('edbPreData_classifyOpt_move')"
 						:expand-on-click-node="false"
 						check-strictly
 						empty-text="暂无分类"
@@ -69,6 +69,7 @@
 						@node-drag-end="dropMouseLeave"
 						@node-drag-leave="dropMouseLeave"
 						@node-drag-enter="dropMouseOver"
+						@node-drag-over="dropMouseOver"
 					>
 						<span class="custom-tree-node" slot-scope="{ node, data }">
 							<el-input
@@ -87,6 +88,7 @@
 								:style="`width:${
 									(select_node === data.UniqueCode && node.Nodewidth) || ''
 								}`"
+								:id="`node${data.UniqueCode}`"
 							>
 								<span>{{ currentLang==='en' ? (data.ClassifyNameEn||data.ClassifyName) : data.ClassifyName }}</span>
 							</span>
@@ -106,7 +108,7 @@
 									alt=""
 									style="width: 14px; height: 14px; margin-right: 8px"
 									@click.stop="addNode(node, data)"
-									v-if="data.Button.AddButton&&!data.EdbInfoId&&isEdbBtnShow('edbPreData_classifyOpt_add')"
+									v-if="data.Button.AddButton&&!data.EdbInfoId&&isEdbBtnShow('edbPreData_classifyOpt_add')&&node.level<6"
 								/>
 								<!-- 编辑目录 -->
 								<img
@@ -704,44 +706,43 @@ export default {
 			const {predictEdbPermission,checkPermissionBtn}=this.permissionBtn
 			return checkPermissionBtn(predictEdbPermission[type])||false
 		},
-		setCurrentClassify(classifyId){
+		setCurrentClassify(ClassifyList){
 			//获取指标详情后才能拿到准确的classifyId
 			//根据准备的id查找指标的父级目录并展开
-			let deep_arr = _.cloneDeep(this.treeData);
-			let arr = this.findParentNodeHandle(deep_arr, classifyId).reverse();
-
-			this.defaultShowNodes = arr;
-			this.$refs.treeRef.setCurrentKey(this.select_node);
+			console.log(ClassifyList);
+			
+			// 展开目录
+			this.defaultShowNodes=ClassifyList.reverse().map(item=>item.UniqueCode)
+			
 
 			//滚动到高亮节点位置
-			this.$nextTick(()=>{
+			// this.$nextTick(()=>{
 				setTimeout(() => {
-				const dom = document.querySelector(".el-tree-node.is-current");
-				const parentDom = document.querySelector(".target_tree");
-				if (!dom || !parentDom) {
+					const dom = document.getElementById(`node${this.select_node}`)||{}
+					const parentDom = document.getElementsByClassName('target_tree')[0];
+					/* if (dom.offsetTop > parentDom.offsetHeight) {
+						parentDom.scrollTo({
+							top: dom.offsetTop - parentDom.offsetHeight / 2,
+							left: 0,
+							behavior: "smooth",
+						});
+					} */
+					//parent可视区间:[scrollTop,scrollTop+offsetHeight]
+					//node位置:node.offsetTop
+					const overTop = dom.offsetTop+dom.clientHeight<parentDom.scrollTop
+					const overBottom = dom.offsetTop+dom.clientHeight+30>parentDom.scrollTop+parentDom.offsetHeight
+					if(overTop){
+						parentDom.scrollTop = dom.offsetTop-30
+					}
+					if(overBottom){
+						parentDom.scrollTop =  dom.offsetTop - parentDom.offsetHeight/2
+					}
 					this.searchLoading = false;
-					return;
-				}
-				/* if (dom.offsetTop > parentDom.offsetHeight) {
-					parentDom.scrollTo({
-						top: dom.offsetTop - parentDom.offsetHeight / 2,
-						left: 0,
-						behavior: "smooth",
-					});
-				} */
-				//parent可视区间:[scrollTop,scrollTop+offsetHeight]
-				//node位置:node.offsetTop
-				const overTop = dom.offsetTop+dom.clientHeight<parentDom.scrollTop
-				const overBottom = dom.offsetTop+dom.clientHeight+30>parentDom.scrollTop+parentDom.offsetHeight
-				if(overTop){
-					parentDom.scrollTop = dom.offsetTop-30
-				}
-				if(overBottom){
-					parentDom.scrollTop =  dom.offsetTop - parentDom.offsetHeight/2
-				}
-				this.searchLoading = false;
-			}, 300);
-			})
+				}, 1500);
+				setTimeout(() => {
+					this.$refs.treeRef.setCurrentKey(this.select_node);//设置高亮
+				}, 1500);
+			// })
 		},
 		setNameBack({edb_name,edb_nameEn,userid}) {
 			this.edbName=edb_name;
@@ -759,7 +760,7 @@ export default {
 
 		/* 获取分类 */
 		getTreeData(params=null) {
-			preDictEdbInterface.classifyListV2({IsOnlyMe:this.isOnlyMe||false}).then(res => {
+			preDictEdbInterface.predictEdbCatalog({IsOnlyMe:this.isOnlyMe||false,ParentId:0}).then(res => {
 				const { Ret,Data } = res;
 				
 				if(Ret !== 200) return
@@ -851,23 +852,23 @@ export default {
 			}
 			this.classifyDia = true;
 		},
+		// 递归节点
+		getNodeParentData(data,arr){
+			if(data.level===0) return
+			arr.push({classifyName:data.data.ClassifyName,classifyId:data.data.ClassifyId})
+			this.getNodeParentData(data.parent,arr)
+			return arr
+		},
 		addNode(node,{ClassifyName,ClassifyId}){
 			this.dialog_title = '添加'
+			let arr=[]
+			arr=this.getNodeParentData(node,arr)
 			/* 添加目录 */
 			this.classifyForm = {
 				classify_name:'',
 				Level:node.level,
 				ParentId:ClassifyId,
-				level_1_Name:node.level === 1
-				? ClassifyName
-				: node.level === 2
-				? node.parent.data.ClassifyName
-				: node.parent.parent.data.ClassifyName,
-				level_2_Name:node.level === 1
-				? ''
-				: node.level === 2
-				? ClassifyName
-				: node.parent.data.ClassifyName,
+				parentArr:arr,
 			}
 			this.classifyDia = true;
 		},
@@ -875,22 +876,15 @@ export default {
     editNode(node, { ClassifyName,ClassifyId,Level,ParentId}) {
 
       this.dialog_title = '编辑';
+	  let arr=[]
+	  arr=this.getNodeParentData(node.parent,arr)
       /* 编辑目录 */
       this.classifyForm = {
         classify_name: ClassifyName,
         classify_id: ClassifyId,
-        Level:node.level,
+        Level:node.level-1,
         ParentId:ParentId,
-        level_1_Name:node.level === 1
-            ? ClassifyName
-            : node.level === 2
-            ? node.parent.data.ClassifyName
-            : node.parent.parent.data.ClassifyName,
-        level_2_Name:node.level === 1
-            ? ''
-            : node.level === 2
-            ? ClassifyName
-            : node.parent.data.ClassifyName,
+        parentArr:arr,
       };
       this.classifyDia = true;
     },
@@ -1112,10 +1106,9 @@ export default {
 		},
 
 		/* 计算指标回显 */
-		setComputedDialogForm({Source,CalculateList,CalculateFormula,EdbInfoId,EdbName,Unit,Frequency,ClassifyId,MoveType,MoveFrequency,Calendar},type='') {
+		setComputedDialogForm({Source,CalculateList,CalculateFormula,EdbInfoId,EdbName,Unit,Frequency,ClassifyId,ClassifyList,MoveType,MoveFrequency,Calendar,CorrelationStr},type='') {
 			//找到指标的父级
-			let deep_arr = _.cloneDeep(this.treeData);
-			const parentNodes = this.findParentNodeHandle(deep_arr,ClassifyId,'ClassifyId')
+			const parentNodes = ClassifyList.length&&ClassifyList.map(item=>item.ClassifyId)
 			//指标运算 or 其他计算类型指标
 			if( Source === 31 ) {
 				/* 回显指标和表单 */
@@ -1132,7 +1125,7 @@ export default {
 				this.calulateForm =  {
 					edb_id:EdbInfoId,
 					formula: CalculateFormula,
-					menu: parentNodes.reverse(),
+					menu: parentNodes,
 					targetName: EdbName,
 					unit: Unit,
 					frequency: Frequency,
@@ -1145,7 +1138,7 @@ export default {
 						targetName: EdbName,
 						frequency: Frequency,
 						unit: Unit,
-						menu: parentNodes.reverse(),
+						menu: parentNodes,
 						view: type === 'view',
 						source: Source,
 						date: CalculateFormula,
@@ -1154,6 +1147,7 @@ export default {
 						old_stay_edb: Source === 48 ? CalculateList.find(item => item.FromTag === 'A').FromEdbInfoId : '',
 						concat_edb: Source === 48 ? CalculateList.find(item => item.FromTag === 'B').FromEdbInfoId : '',
 						from_arr: CalculateList,
+						correlationStr: CorrelationStr
 					}
 					return
 				}
@@ -1367,38 +1361,24 @@ export default {
       this.getPublicList();
     },
 		//懒加载el-tree
-		getLazyTreeData(node,resolve,maxLevel=3){
+		async getLazyTreeData(node,resolve,maxLevel=3){
 			if(node.level===0){
-					resolve(this.treeData)
-				}
-				if(node.level>0&&node.level<=maxLevel){
-					//获取对应层级的Child
-					resolve(node.data.Children||[])
-				}
-				if(node.level===maxLevel){
-					//调接口获取该分类下图表的数据
-					preDictEdbInterface.classifyChartList({
-						ClassifyId:node.data.ClassifyId,
-						IsShowMe:this.isOnlyMe
-					}).then(res=>{
-						if(res.Ret===200){
-							let arr=res.Data.EdbInfoList||[]
-							arr=arr.map(item=>{
-								return {
-									...item,
-									isLeaf:true
-								}
-							})
-							resolve(arr)
-						}else{
-							resolve([])
+				resolve(this.treeData)
+			}else{
+				let arr=[]
+				const res=await preDictEdbInterface.predictEdbCatalog({IsOnlyMe:this.isOnlyMe||false,ParentId:node.data.ClassifyId})
+				if (res.Ret === 200) {
+					const temarr = res.Data.AllNodes || [];
+					arr=temarr.map(item=>{
+						return {
+							...item,
+							isLeaf:item.EdbInfoId?true:false
 						}
-						this.changeTreeNode()
 					})
 				}
-				if(node.level>maxLevel){
-					resolve([])
-				}
+				resolve(arr)
+			}
+				
 		},
 		changeTreeNode(){
 			this.$refs.treeRef.setCurrentKey(this.select_node);

+ 19 - 16
src/views/report_manage/addreportNew.vue

@@ -11,7 +11,7 @@
 				id="froala-editor"
 				ref="froalaEditor"
 				:tag="'textarea'"
-				:config="froalaConfig"
+				:config="CNEditorConfig"
 				v-model="aeForm.content"
 			></froala>
 		</div>
@@ -726,31 +726,34 @@ export default {
 				return
 			}
 			console.log('定时去发布了');
-			this.$confirm('是否发布定时报告,并推送模板消息?', '发布提示', {
-				confirmButtonText: '推送',
-				cancelButtonText: '不推送',
+			const isPost = this.permissionBtn.checkPermissionBtn(this.permissionBtn.reportManageBtn.reportManage_sendMsg)
+			this.$confirm(isPost?'是否发布定时报告,并推送模板消息?':'是否发布定时报告?', '发布提示', {
+				confirmButtonText: isPost?'推送':'发布',
+				cancelButtonText: isPost?'不推送':'取消',
 				type: 'warning',
 				distinguishCancelAndClose:true,
 				beforeClose:(action, instance,done)=>{
 					console.log(action, instance);
 					if(action==='close'||action==='cancel') {
-						//右上角或者不推送
-						reportSetPrepublish({
-							ReportId:Number(this.report_draft_id),
-							PrePublishTime:this.taskTime,
-							PreMsgSend:0,
-						}).then(res=>{
-							if(res.Ret===200){
-								this.$message.success('定时发布成功!')
-								this.$router.push({ path: '/reportlist' });
-							}
-						})
+						if(isPost) {
+							//右上角或者不推送
+							reportSetPrepublish({
+								ReportId:Number(this.report_draft_id),
+								PrePublishTime:this.taskTime,
+								PreMsgSend:0,
+							}).then(res=>{
+								if(res.Ret===200){
+									this.$message.success('定时发布成功!')
+									this.$router.push({ path: '/reportlist' });
+								}
+							})
+						}
 					} else {
 						//confirmButton
 						reportSetPrepublish({
 							ReportId:Number(this.report_draft_id),
 							PrePublishTime:this.taskTime,
-							PreMsgSend:1,
+							PreMsgSend:isPost?1:0,
 						}).then(res=>{
 							if(res.Ret===200){
 								this.$message.success('定时发布成功!')

+ 28 - 10
src/views/report_manage/editChapterReport.vue

@@ -11,7 +11,7 @@
         id="froala-editor"
         ref="froalaEditor"
         :tag="'textarea'"
-        :config="froalaConfig"
+        :config="CNEditorConfig"
         v-model="aeForm.content"
       ></froala>
     </div>
@@ -319,7 +319,8 @@ import reportMixin from './mixins/reportMixin';
 import moment from "moment";
 import importMyChart from "./components/importMyChart.vue";
 import importSemantics from './components/importSemantics.vue';
-let ALOSSINS = null; //阿里云上传实例
+import {uploadFileDirect} from "@/utils/common.js"
+
 export default {
   beforeRouteEnter(to, from, next) {
     // 设置面包屑
@@ -428,7 +429,7 @@ export default {
   },
   methods: {
     handelBeforeUploadAudio(e) {
-      console.log(e);
+      // console.log(e);
       if (
         e.name.indexOf(".mp3") == -1 &&
         e.name.indexOf(".wav") == -1 &&
@@ -440,7 +441,6 @@ export default {
       }
     },
     async handleUpload(e) {
-      console.log(e.file.size);
       const duration = await this.handleGetDuration(e.file);
       if (duration > 60 * 15) {
         this.$message.warning("音频时长不得超过15分钟");
@@ -448,15 +448,33 @@ export default {
       }
       this.aeForm.audioDuration = duration;
       this.aeForm.audioSize = e.file.size / 1024 / 1024; //单位MB
-      const res = await getOSSSign();
-      if (res.Ret === 200) {
-        
-        this.handleUploadToOSS(e.file, res.Data);
-      }
+      this.startUploadAudio = true;
+
+      const t = new Date().getTime().toString();
+      const temName = `static/yb/audio/${process.env.NODE_ENV}/${MD5(t)}.${
+        e.file.type.split("/")[1]
+      }`;
+      // const temName = `testOne.${
+      //   e.file.type.split("/")[1]
+      // }`;
+
+      let clientType = this.$setting.dynamicOutLinks.ObjectStorageClient ||
+                        this.$store.state.dynamicOutLinks.ObjectStorageClient ||
+                        JSON.parse(localStorage.getItem('dynamicOutLinks')).ObjectStorageClient
+      uploadFileDirect(clientType,e.file,temName).then(res=>{
+        console.log(res);
+        this.aeForm.audioUrl = res;
+      })
+      .finally(()=>{
+        this.startUploadAudio = false;
+      })
+      // const res = await getOSSSign({StorageSource:1});
+      // if (res.Ret === 200) {
+        // this.handleUploadToOSS(e.file, res.Data);
+      // }
     },
     //上传到阿里云
     async handleUploadToOSS(file, ossRes) {
-      this.startUploadAudio = true;
 
        let oss_params = {
         // yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。

+ 19 - 15
src/views/report_manage/editreportNew.vue

@@ -11,7 +11,7 @@
 				id="froala-editor"
 				ref="froalaEditor"
 				:tag="'textarea'"
-				:config="froalaConfig"
+				:config="CNEditorConfig"
 				v-model="aeForm.content"
 			></froala>
 		</div>
@@ -733,31 +733,35 @@ export default {
 				})
 				return
 			}
-			this.$confirm('是否发布定时报告,并推送模板消息?', '发布提示', {
-				confirmButtonText: '推送',
-				cancelButtonText: '不推送',
+			const isPost = this.permissionBtn.checkPermissionBtn(this.permissionBtn.reportManageBtn.reportManage_sendMsg)
+
+			this.$confirm(isPost?'是否发布定时报告,并推送模板消息?':'是否发布定时报告?', '发布提示', {
+				confirmButtonText: isPost?'推送':'发布',
+				cancelButtonText: isPost?'不推送':'取消',
 				type: 'warning',
 				distinguishCancelAndClose:true,
 				beforeClose:(action, instance,done)=>{
 					console.log(action, instance);
 					if(action==='close'||action==='cancel') {
 						//右上角或者不推送
-						reportSetPrepublish({
-							ReportId:Number(this.report_id),
-							PrePublishTime:this.taskTime,
-							PreMsgSend:0,
-						}).then(res=>{
-							if(res.Ret===200){
-								this.$message.success('定时发布成功!')
-								this.$router.push({ path: '/reportlist' });
-							}
-						})
+						if(isPost){
+							reportSetPrepublish({
+								ReportId:Number(this.report_id),
+								PrePublishTime:this.taskTime,
+								PreMsgSend:0,
+							}).then(res=>{
+								if(res.Ret===200){
+									this.$message.success('定时发布成功!')
+									this.$router.push({ path: '/reportlist' });
+								}
+							})
+						}
 					} else {
 						//confirmButton
 						reportSetPrepublish({
 							ReportId:Number(this.report_id),
 							PrePublishTime:this.taskTime,
-							PreMsgSend:1,
+							PreMsgSend:isPost?1:0,
 						}).then(res=>{
 							if(res.Ret===200){
 								this.$message.success('定时发布成功!')

+ 16 - 3
src/views/report_manage/mixins/reportMixin.js

@@ -24,6 +24,19 @@ export default {
 	        }
 		},
   },
+  computed:{
+      CNEditorConfig(){
+          return {...this.froalaConfig,...{fontFamily:{'Arial,Helvetica,sans-serif': 'Arial',
+          'Georgia,serif': 'Georgia',
+          'Impact,Charcoal,sans-serif': 'Impact',
+          'Tahoma,Geneva,sans-serif': 'Tahoma',
+          "'Times New Roman',Times,serif": 'Times New Roman',
+          'Verdana,Geneva,sans-serif': 'Verdana',
+          '思源宋体':'思源宋体',
+          '思源黑体':'思源黑体',}}
+        }
+      }
+  },
   data() {
     let that = this;
     return {
@@ -285,9 +298,9 @@ export default {
     async setEnHandle({ UniqueCode }) {
       this.formItemArray = { chartInfo: [], chartsList: [] };
 
-      const { Ret, Data } = await dataBaseInterface.getChartByCode({
-        UniqueCode,
-      });
+      const { Ret, Data } = this.chart_source === 2
+        ? await futuresInterface.getChartBasicInfo({ UniqueCode })
+        : await dataBaseInterface.getChartByCode({ UniqueCode })
 
       if (Ret !== 200) return;
       let chartInfo = Data.ChartInfo;

+ 96 - 75
src/views/report_manage/reportEn/reportEditor.vue

@@ -114,6 +114,9 @@
 							<el-cascader
 								@change="userclassidreportdetail"
 								:options="optionsArr"
+								:props="{
+									children:'Child'
+								}"
 								v-model="aeForm.classifynameArr"
 								placeholder="类型筛选"
 								size="medium"
@@ -563,9 +566,10 @@ export default {
 		},
 
 		userclassidreportdetail() {
+			// console.log(this.aeForm.classifynameArr,'this.aeForm.classifynameArr');
 			if (this.aeForm.add_type == 1) {
-				if (this.aeForm.classifynameArr.length == 2) {
-					this.aeForm.title = JSON.parse(this.aeForm.classifynameArr[1]).l;
+				if (this.aeForm.classifynameArr.length == 3) {
+					this.aeForm.title = JSON.parse(this.aeForm.classifynameArr[2]).l;
 				}else{
           this.aeForm.title = ''
         }
@@ -575,11 +579,11 @@ export default {
 				return false;
 			} 
 			let params = {
-				ClassifyIdFirst: JSON.parse(this.aeForm.classifynameArr[0]).v,
+				ClassifyIdFirst: JSON.parse(this.aeForm.classifynameArr[1]).v,
 			};
-			if (this.aeForm.classifynameArr.length === 2) {
+			if (this.aeForm.classifynameArr.length === 3) {
 				params.ClassifyIdSecond = JSON.parse(
-					this.aeForm.classifynameArr[1]
+					this.aeForm.classifynameArr[2]
 				).v;
 			} else {
 				params.ClassifyIdSecond = 0;
@@ -594,24 +598,19 @@ export default {
 					this.aeForm = {
 						add_type: 2,
 						classify_name: 1,
-						classifynameArr:
-							res.Data.ClassifyIdSecond && res.Data.ClassifyNameSecond
-								? [
-										JSON.stringify({
-											l: res.Data.ClassifyNameFirst,
-											v: res.Data.ClassifyIdFirst,
-										}),
-										JSON.stringify({
-											l: res.Data.ClassifyNameSecond,
-											v: res.Data.ClassifyIdSecond,
-										}),
-								  ]
-								: [
-										JSON.stringify({
-											l: res.Data.ClassifyNameFirst,
-											v: res.Data.ClassifyIdFirst,
-										}),
-								  ],
+						classifynameArr:[
+							JSON.stringify({
+								l: res.Data.ClassifyNameRoot,
+								v: parseInt(res.Data.ClassifyIdRoot),
+							}),
+							JSON.stringify({
+								l: res.Data.ClassifyNameFirst,
+								v: parseInt(res.Data.ClassifyIdFirst),
+							}),
+							JSON.stringify({
+								l: res.Data.ClassifyNameSecond,
+								v: parseInt(res.Data.ClassifyIdSecond),
+						})],
 						title: res.Data.Title,
 						abstract: res.Data.Abstract,
 						author: res.Data.Author ? res.Data.Author.split(',') : '',
@@ -635,29 +634,24 @@ export default {
 		//报告详情
 		getreportdetail() {
 			reportEnInterface.reportDetail({ ReportId: parseInt(this.report_id) }).then((res) => {
-				if (res.Ret === 200) {
+				if (res.Ret === 200 && res.Data) {
 					let data = res.Data;
 					this.aeForm = {
 						add_type: parseInt(data.AddType),
 						classify_name: 1,
-						classifynameArr:
-							data.ClassifyIdSecond && data.ClassifyNameSecond
-								? [
-										JSON.stringify({
-											l: data.ClassifyNameFirst,
-											v: parseInt(data.ClassifyIdFirst),
-										}),
-										JSON.stringify({
-											l: data.ClassifyNameSecond,
-											v: parseInt(data.ClassifyIdSecond),
-										}),
-								  ]
-								: [
-										JSON.stringify({
-											l: data.ClassifyNameFirst,
-											v: parseInt(data.ClassifyIdFirst),
-										}),
-								  ],
+						classifynameArr:[
+							JSON.stringify({
+								l: data.ClassifyNameRoot,
+								v: parseInt(data.ClassifyIdRoot),
+							}),
+							JSON.stringify({
+								l: data.ClassifyNameFirst,
+								v: parseInt(data.ClassifyIdFirst),
+							}),
+							JSON.stringify({
+								l: data.ClassifyNameSecond,
+								v: parseInt(data.ClassifyIdSecond),
+						})],
 						title: data.Title,
 						abstract: data.Abstract,
 						author: data.Author ? data.Author.split(',') : '',
@@ -706,8 +700,8 @@ export default {
 			$('#leftfroala .fr-element').find('img.fr-uploading').length&&$('#leftfroala .fr-element').find('img.fr-uploading').remove()
 			let params = {
 				AddType: this.aeForm.add_type,
-				ClassifyIdFirst: JSON.parse(this.aeForm.classifynameArr[0]).v,
-				ClassifyNameFirst: JSON.parse(this.aeForm.classifynameArr[0]).l,
+				ClassifyIdFirst: JSON.parse(this.aeForm.classifynameArr[1]).v,
+				ClassifyNameFirst: JSON.parse(this.aeForm.classifynameArr[1]).l,
 				Title: this.aeForm.title,
 				Abstract: this.aeForm.abstract,
 				Author:
@@ -721,12 +715,12 @@ export default {
 				ReportVersion: 2,
         Overview:this.aeForm.overview.replace(/<p data-f-id=\"pbf\".*?<\/p>/g,'')
 			};
-			if (this.aeForm.classifynameArr.length == 2) {
+			if (this.aeForm.classifynameArr.length == 3) {
 				params.ClassifyIdSecond = JSON.parse(
-					this.aeForm.classifynameArr[1]
+					this.aeForm.classifynameArr[2]
 				).v;
 				params.ClassifyNameSecond = JSON.parse(
-					this.aeForm.classifynameArr[1]
+					this.aeForm.classifynameArr[2]
 				).l;
 			}
 
@@ -885,35 +879,62 @@ export default {
 			let params = { CurrentIndex: 1, PageSize: 1000, KeyWord: '' };
 			reportEnInterface.classifyList(params).then((res) => {
 				if (res.Ret == 200 && Array.isArray(res.Data.List)) {
-					this.optionsArr = [];
-					res.Data.List.forEach(item => {
-						let newitem = {
-							label: item.ClassifyName,
-							value: JSON.stringify({
-								l: item.ClassifyName,
-								v: parseInt(item.Id),
-							}),
-							HasTeleconference:item.HasTeleconference
-						};
-						if (item.Child&&item.Child.length > 0) {
-							let childnode = [];
-							item.Child.forEach((itemchild, i) => {
-								childnode.push({
-									label: itemchild.ClassifyName,
-									value: JSON.stringify({
-										l: itemchild.ClassifyName,
-										v: parseInt(itemchild.Id),
-									}),
-									HasTeleconference:itemchild.HasTeleconference
-								});
-							});
-							newitem.children = childnode;
-						} else {
-							newitem.children = undefined;
-							newitem.disabled=true
+					this.optionsArr = res.Data.List|| []
+					// res.Data.List.forEach(item => {
+					// 	let newitem = {
+					// 		label: item.ClassifyName,
+					// 		value: JSON.stringify({
+					// 			l: item.ClassifyName,
+					// 			v: parseInt(item.Id),
+					// 		}),
+					// 		HasTeleconference:item.HasTeleconference
+					// 	};
+					// 	if (item.Child&&item.Child.length > 0) {
+					// 		let childnode = [];
+					// 		item.Child.forEach((itemchild, i) => {
+					// 			childnode.push({
+					// 				label: itemchild.ClassifyName,
+					// 				value: JSON.stringify({
+					// 					l: itemchild.ClassifyName,
+					// 					v: parseInt(itemchild.Id),
+					// 				}),
+					// 				HasTeleconference:itemchild.HasTeleconference
+					// 			});
+					// 		});
+					// 		newitem.children = childnode;
+					// 	} else {
+					// 		newitem.children = undefined;
+					// 		newitem.disabled=true
+					// 	}
+					// 	this.optionsArr.push(newitem);
+					// });
+					this.optionsArr.map(itemOne =>{
+						itemOne.label = itemOne.ClassifyName
+						itemOne.value = JSON.stringify({
+							l: itemOne.ClassifyName,
+							v: parseInt(itemOne.Id),
+						})
+						itemOne.disabled = !(itemOne.Child && itemOne.Child.length>0)
+						if(itemOne.Child){
+							itemOne.Child.map(itemTwo =>{
+								itemTwo.label = itemTwo.ClassifyName
+								itemTwo.value = JSON.stringify({
+									l: itemTwo.ClassifyName,
+									v: parseInt(itemTwo.Id),
+								})
+								itemTwo.disabled = !(itemTwo.Child && itemTwo.Child.length>0)
+								if(itemTwo.Child){
+									itemTwo.Child.map(itemThree =>{
+										itemThree.label = itemThree.ClassifyName
+										itemThree.value = JSON.stringify({
+											l: itemThree.ClassifyName,
+											v: parseInt(itemThree.Id),
+										})
+									})
+								}
+							})
 						}
-						this.optionsArr.push(newitem);
-					});
+					})
 				}
 			});
 		},

+ 180 - 84
src/views/report_manage/reportEn/reportlist.vue

@@ -59,6 +59,11 @@
           <el-form-item label="">
             <el-cascader
               :options="optionsArr"
+              :props="{
+                value:'Id',
+                label:'ClassifyName',
+                children:'Child'
+              }"
               v-model="searchform.classifynameArr"
               clearable
               placeholder="类型筛选"
@@ -135,9 +140,9 @@
 								<span style="cursor:pointer; color:#4099ef;">{{row.Title}}</span>
 							  <span style="cursor:pointer; color:#4099ef;" v-if="row.CreateTime">({{row.CreateTime.substring(5,7)}}{{row.CreateTime.substring(8,10)}})</span>
 							</span>
-              <span v-else-if="item.key==='ClassifyNameFirst'">
-                {{row.ClassifyNameFirst}} 
-                <span v-if="row.ClassifyNameSecond">/ {{row.ClassifyNameSecond}}</span>
+              <span v-else-if="item.key==='FullClassifyName'">
+                {{row.FullClassifyName}} 
+                <!-- <span v-if="row.ClassifyNameSecond">/ {{row.ClassifyNameSecond}}</span> -->
               </span>
               <span v-else-if="item.key==='State'" :style="row.State===2 && 'color:#46C371;'">
                 {{row.State===2 ? '已发布' : '未发布'}}
@@ -213,61 +218,6 @@
     >
       <div class="send-email-wrap">
         <el-form ref="form" :model="popData" label-width="100px">
-          <el-form-item label="收件人:">
-            <div>
-              <!-- <el-radio v-model="popData.radio" label="1">默认全部</el-radio> -->
-              <el-cascader
-                v-if="popData.show"
-                v-model="popData.varietyVal"
-                :options="popData.varietyOpt"
-                collapse-tags
-                clearable
-                :props="{
-                  multiple:true,
-                  value:'EnPermissionId',
-                  label:'EnPermissionName',
-                  children:'Child'
-                }"
-                placeholder="请选择品种权限"
-              />
-              <el-checkbox v-model="popData.checkUser" style="margin-left:20px">指定人员</el-checkbox>
-            </div>
-            <div v-if="popData.checkUser" class="user-box">
-              <el-select
-                v-model="popData.value"
-                multiple
-                filterable
-                collapse-tags
-                placeholder="请选择客户"
-                value-key="Id"
-              >
-                <el-option
-                  v-for="item in popData.options"
-                  :key="item.Id"
-                  :label="item.Name"
-                  :value="item"
-                  :disabled="item.Enabled===0">
-                  <span>{{item.Name}} &lt;{{item.Email}}&gt;</span>
-                </el-option>
-              </el-select>
-              <div style="margin-top:10px" class="box">
-                <el-tooltip 
-                  effect="dark" 
-                  :content="item.Email" 
-                  placement="top"
-                  v-for="(item,index) in popData.value"
-                  :key="item.Id"
-                  >
-                <el-tag
-                  closable
-                  style="margin:0 10px 10px 0"
-                  @close="handleDelSelectCustom(item,index)">
-                  {{item.Name}}
-                </el-tag>
-                </el-tooltip>
-              </div>
-            </div>
-          </el-form-item>
           <el-form-item label="邮件主题:">
             <div>
               <el-input 
@@ -280,6 +230,101 @@
               ></el-input>
             </div>
           </el-form-item>
+          <el-form-item label="收件人:">
+            <div class="addressee-box">
+              <div class="addressee-cancel-box">
+                <el-cascader
+                  v-if="popData.show"
+                  v-model="popData.varietyVal"
+                  :options="popData.varietyOpt"
+                  collapse-tags
+                  clearable
+                  :props="{
+                    multiple:true,
+                    value:'EnPermissionId',
+                    label:'EnPermissionName',
+                    children:'Child'
+                  }"
+                  placeholder="请选择品种权限"
+                  style="margin-bottom: 10px;"
+                />
+                <div class="user-box-hint">取消发送客户信息:</div>
+                <el-select
+                  v-model="popData.customValue"
+                  multiple
+                  filterable
+                  collapse-tags
+                  placeholder="请选择客户"
+                  value-key="CompanyId">
+                  <el-option
+                    v-for="item in popData.customOptions"
+                    :key="item.CompanyId"
+                    :label="item.CompanyName"
+                    :value="item">
+                  </el-option>
+                </el-select>
+                <div class="user-box">
+                  <div style="margin-top:10px" class="box">
+                    <!-- <el-tooltip 
+                      effect="dark" 
+                      :content="item.Email" 
+                      placement="top"
+                      v-for="(item,index) in popData.customValue"
+                      :key="item.Id"
+                      > -->
+                      <el-tag
+                      closable
+                      v-for="(item,index) in popData.customValue"
+                      :key="item.CompanyId"
+                      style="margin:0 10px 10px 0"
+                      @close="handleDelSelectCompany(item,index)">
+                      {{item.CompanyName}}
+                    </el-tag>
+                    <!-- </el-tooltip> -->
+                  </div>
+                </div>
+              </div>
+              <div class="addressee-append-box">
+                <el-checkbox v-model="popData.checkUser" style="margin:0 0 10px 20px;width: 100px;">指定人员</el-checkbox>
+                <div class="user-box-hint" v-show="popData.checkUser">指定发送人员信息:</div>
+                <el-select
+                  v-show="popData.checkUser"
+                  v-model="popData.value"
+                  multiple
+                  filterable
+                  collapse-tags
+                  placeholder="请选择人员"
+                  value-key="Id">
+                  <el-option
+                    v-for="item in popData.options"
+                    :key="item.Id"
+                    :label="item.Name"
+                    :value="item"
+                    :disabled="item.Enabled===0">
+                    <span>{{item.Name}} &lt;{{item.Email}}&gt;</span>
+                  </el-option>
+                </el-select>
+                <div class="user-box" v-show="popData.checkUser">
+                  <div style="margin-top:10px" class="box">
+                    <el-tooltip 
+                      effect="dark" 
+                      :content="item.Email" 
+                      placement="top"
+                      v-for="(item,index) in popData.value"
+                      :key="item.Id"
+                      >
+                    <el-tag
+                      closable
+                      style="margin:0 10px 10px 0"
+                      @close="handleDelSelectCustom(item,index)">
+                      {{item.Name}}
+                    </el-tag>
+                    </el-tooltip>
+                  </div>
+                </div>
+              </div>
+          </div>
+          </el-form-item>
           <div style="text-align:center;margin-bottom:30px;margin-top:40px">
             <el-button type="primary" plain style="margin-right:10px" @click="popData.show=false">取消</el-button>
             <el-button type="primary" @click="handleConfirmSendEmail">确定</el-button>
@@ -330,7 +375,7 @@
 
 <script>
 import * as reportEnInterface from '@/api/modules/reportEnApi';
-import {strategyReportInterence,reportVarietyENInterence} from '@/api/api.js'
+import {strategyReportInterence,reportVarietyENInterence,customInterence} from '@/api/api.js'
 import mPage from '@/components/mPage.vue';
 import strategyReportEdit from '../components/strategyReportEdit.vue'
 export default {
@@ -347,6 +392,8 @@ export default {
         this.popData.checkUser=false
         this.popData.options=[]
         this.popData.value=[]
+        this.popData.customOptions=[]
+        this.popData.customValue=[]
         this.popData.varietyOpt=[]
         this.popData.varietyVal=[]
       }
@@ -385,7 +432,7 @@ export default {
 				},
         {
 					label: '报告类型',
-					key: 'ClassifyNameFirst',
+					key: 'FullClassifyName',
           minwidthsty: 120
 				},
         {
@@ -429,10 +476,11 @@ export default {
 
       popData:{
         show:false,
-        radio:'1',
         checkUser:false,//是否选择指定人员
         options: [],
         value: [],
+        customOptions:[],
+        customValue:[],
         theme:'',
         reportId:0,
         varietyOpt:[],
@@ -465,17 +513,18 @@ export default {
 			let params={CurrentIndex:0,PageSize:1000,KeyWord:''};
 			reportEnInterface.classifyList(params).then((res) => {
 				if( res.Ret==200&&Array.isArray(res.Data.List) ){
-					res.Data.List.forEach((item,index)=>{
-						let newitem={label:item.ClassifyName,value:item.ClassifyName};
-						if( item.Child ){
-							let childnode=[];
-							item.Child.forEach((itemchild,i)=>{
-								childnode.push({label:itemchild.ClassifyName,value:itemchild.ClassifyName});
-							});
-							newitem.children=childnode;
-						}
-						this.optionsArr.push(newitem);
-					});
+					// res.Data.List.forEach((item,index)=>{
+					// 	let newitem={label:item.ClassifyName,value:item.ClassifyName};
+					// 	if( item.Child ){
+					// 		let childnode=[];
+					// 		item.Child.forEach((itemchild,i)=>{
+					// 			childnode.push({label:itemchild.ClassifyName,value:itemchild.ClassifyName});
+					// 		});
+					// 		newitem.children=childnode;
+					// 	}
+					// 	this.optionsArr.push(newitem);
+					// });
+          this.optionsArr= res.Data.List || []
 				}
 			});
 		},
@@ -486,8 +535,9 @@ export default {
 				CurrentIndex:this.page_no,
         PageSize:15,
         Frequency:this.searchform.frequency,
-        ClassifyNameFirst:this.searchform.classifynameArr?this.searchform.classifynameArr[0]:'',
-        ClassifyNameSecond:this.searchform.classifynameArr&&this.searchform.classifynameArr.length>1?this.searchform.classifynameArr[1]:'',
+        ClassifyIdRoot:this.searchform.classifynameArr[0],
+        ClassifyIdFirst:this.searchform.classifynameArr&&this.searchform.classifynameArr.length>1?this.searchform.classifynameArr[1]:'',
+        ClassifyIdSecond:this.searchform.classifynameArr&&this.searchform.classifynameArr.length>1?this.searchform.classifynameArr[2]:'',
         State:this.searchform.state?this.searchform.state:null,
         KeyWord:this.searchform.key_word,
         StartDate: this.searchform.dateValue ? this.searchform.dateValue[0] : '',
@@ -658,6 +708,7 @@ export default {
             })
           })
         }
+        this.getCustomListEnFun()
       })
     },
 
@@ -683,11 +734,33 @@ export default {
         this.popData.options=arr
       }
     },
+    // 获取英文客户列表
+    getCustomListEnFun(){
+        let arr=[]
+        this.popData.varietyVal&&this.popData.varietyVal.forEach(_e => {
+            arr.push(_e[1])
+        });
+        if(!(arr.length>0)){
+            this.popData.customOptions=[]
+            return 
+        }
 
+        customInterence.getCustomListEn({
+            PageSize:100000,
+            CurrentIndex:1,
+            EnPermissionIds:arr.join(',')
+        }).then(res=>{
+            if(res.Ret!==200) return 
+            this.popData.customOptions = res.Data.List || []
+        })
+    },
     handleDelSelectCustom(item,index){
       this.popData.value.splice(index,1)
     },
-
+    //删除选中的商家
+    handleDelSelectCompany(item,index){
+        this.popData.customValue.splice(index,1)
+    },
     showPVDetail(item){
       this.PVData.reportId=item.Id
       this.getPVDetail()
@@ -715,6 +788,12 @@ export default {
       this.popData.value.forEach(item=>{
         ids.push(item.Id)
       })
+
+      let customIds=[]
+      this.popData.customValue.forEach(item=>{
+        customIds.push(item.CompanyId)
+      })
+
       if(this.popData.checkUser&&ids.length===0){//指定人员
         this.$message.warning('请选择需要发送邮件的人员')
         return
@@ -735,11 +814,13 @@ export default {
       this.popData.varietyVal&&this.popData.varietyVal.forEach(_e => {
         arr.push(_e[1])
       });
+
       reportEnInterface.sendCustomEmail({
         ReportId:this.popData.reportId,
         EmailIds:ids.join(','),
         Theme:this.popData.theme,
-        EnPermissions:arr
+        EnPermissions:arr,
+        NoCompanyIds:customIds,
       }).then(res=>{
         if(res.Ret===200){
           this.$message.success('发送成功')
@@ -802,15 +883,30 @@ export default {
   }
 }
 .send-email-wrap{
-  .user-box{
-    border: 1px dashed #DCDFE6;
-    border-radius: 4px;
-    padding: 20px;
-    margin-top: 20px;
-    .box{
-      max-height: 200px;
-      overflow-y: auto;
+  .addressee-box{
+    display: flex;
+    align-items: flex-start;
+    justify-content: space-between;
+    .addressee-cancel-box,.addressee-append-box{
+      display: flex;
+      flex-direction: column;
+      justify-content: flex-start;
+      width: calc(50% - 12px);
+    }
+    .user-box-hint{
+      color: #999999;
+    }
+    .user-box{
+      border: 1px dashed #DCDFE6;
+      border-radius: 4px;
+      padding: 20px;
+      margin-top: 20px;
+      .box{
+        max-height: 200px;
+        overflow-y: auto;
+      }
     }
   }
+
 }
 </style>

+ 1 - 1
src/views/sandbox_manage/index.vue

@@ -549,7 +549,7 @@ export default {
           });
         }else {
           this.lockLoding && this.lockLoding.close();
-          this.$message.warning('浏览器暂不支持')
+          this.$message.warning('当前协议暂不支持,仅支持https协议')
         }
       }
     }, 500),

+ 1 - 1
src/views/sandbox_manage/sandFlow/index.vue

@@ -303,7 +303,7 @@ export default {
 										});
 									}else {
 										this.lockLoding && this.lockLoding.close();
-										this.$message.warning('浏览器暂不支持')
+										this.$message.warning('当前协议暂不支持,仅支持https协议')
 									}	
                 }
 			},{

+ 1 - 1
src/views/semantics_manage/semanticsPage.vue

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

+ 3 - 2
src/views/supply_manage/components/createTargetDia.vue

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

+ 1 - 5
src/views/system_manage/dataAuthManage.vue

@@ -178,11 +178,7 @@ export default {
 		/* 选择人员 */
 		chooseUser(val) {
 			if(!val) return
-			if(val.length) {
-				// console.log(val)
-				let id = val[2];
-				this.filterClassify(this.classifyArr,Number(id));
-			}
+			this.filterClassify(this.classifyArr,Number(val));
 		},
 		// 遍历取值 push数组
 		filterClassify(arr,id) {

+ 5 - 2
src/views/system_manage/etaBaseConfig.vue

@@ -449,11 +449,13 @@ export default {
             let form = new FormData();
             form.append('file',file.file);
             bannerupload(form).then(res=>{
+                console.log(res);
                 if(res.Ret!==200) return 
                 if(['CnPptCoverImgs','EnPptCoverImgs'].includes(key)){
                     this.formData[key].push(res.Data.ResourceUrl)
                 }else{
-                    this.formData[key] = res.Data.ResourceUrl
+                    this.$set(this.formData,key,res.Data.ResourceUrl)
+                    // this.formData[key] = res.Data.ResourceUrl
                 }
                 console.log(this.formData);
             })
@@ -495,7 +497,8 @@ export default {
                 this.checkList = WatermarkChart==='true'?['研报图表']:[]
                 this.Iflytek = UseXf==='true'?true:false
                 if(res.Data){
-                    this.formData = res.Data
+                    // this.$set(this,'formData',res.Data)
+                    this.formData = {...this.formData,...res.Data}
                     this.formData.CnPptCoverImgs = CnPptCoverImgs.length?CnPptCoverImgs.split(','):[]
                     this.formData.EnPptCoverImgs = EnPptCoverImgs.length?EnPptCoverImgs.split(','):[]
                 }

+ 12 - 0
src/views/system_manage/operateAuthManage.vue

@@ -298,9 +298,21 @@ export default {
       operateAuthInterface.getClassificationBySource({Source: this.default_tab}).then(res => {
         if(res.Ret == 200){
           this.classificationList = res.Data.List || []
+          //如果是三级分类,去掉最后一级分类的child
+          if([3,4,5].includes(this.default_tab)){
+            this.filterNodes(this.classificationList)
+          }
         }
       })
     },
+    filterNodes(arr) {
+        arr.length && arr.forEach(item => {
+            item.Child && item.Child.length && this.filterNodes(item.Child)
+            if(item.Child && !item.Child.length) {
+                delete item.Child
+            }
+        })
+    },
     
     changeTab({key}) {
       this.default_tab = key;

+ 13 - 1
src/views/system_manage/outlinkList.vue

@@ -35,11 +35,23 @@ import {outlinkConfigInterence} from "@/api/modules/etaBaseConfigApi.js"
           if(res.Ret == 200){
             this.outlinkData = res.Data.List || []
             // console.log(this.outlinkData);
+            //ETA1.0.8 在数组开头增加一项培训视频链接
+            this.outlinkData.unshift({
+                Id:9999,
+                Title:'培训视频课堂',
+                Url:`${process.env.VUE_APP_ETA_VIDEO}?bus_code=${this.$setting.bus_code}`
+            })
           }
         })
       },
       gotoOutlink(item){
-        window.open(item.Url, '_blank')
+        let Url = item.Url
+        if(!(item.Url.startsWith("http://") || item.Url.startsWith("https://") || item.Url.startsWith("ftp://") || 
+        item.Url.startsWith("ftps://") || item.Url.startsWith("file://") || item.Url.startsWith("\/"))){
+          Url = "http://"+item.Url
+        }
+        // console.log(Url);
+        window.open(Url, '_blank')
       }
     },
   }

+ 143 - 0
src/views/toolBox_manage/FederalReserveWatch.vue

@@ -0,0 +1,143 @@
+<template>
+    <!-- 联储观察 -->
+    <div class="federal-reserve-wrap">
+        <div class="tool-box">
+            <el-date-picker
+                v-model="selectDate"
+                value-format="yyyy-MM-dd"
+                type="date"
+                placeholder="选择日期" @change="getSheetDetail">
+            </el-date-picker>
+            <el-button type="text" @click="downloadSheet" :loading="isDownload">下载</el-button>
+        </div>
+        <div class="table-box">
+            <div class="sheet-wrap">
+                <div id="sheet-container" v-if="this.sheetDetailInfo.MeetingInfoId">
+                </div>
+                <tableNoData text="该日期暂无数据" v-else/>
+                
+            </div>
+            
+        </div>
+    </div>
+</template>
+
+<script>
+import {ToolBoxInterface} from "@/api/modules/toolBoxApi.js";
+export default {
+    data() {
+        return {
+            sheetDetailInfo:{},
+            selectDate:'',
+            exportBase: process.env.VUE_APP_API_ROOT + "/meeting_probabilities/detail", //数据导出接口
+        };
+    },
+    methods: {
+        getSheetDetail(){
+            let type
+            if(!this.selectDate){
+                type='init'
+            }
+            ToolBoxInterface.getSheetDetail({
+                DateTime: this.selectDate||'',
+            }).then(res=>{
+                if(res.Ret!==200) return
+                this.sheetDetailInfo = res.Data||{};
+                type==='init'&&(this.selectDate = this.sheetDetailInfo.DateTime||'')
+                this.$nextTick(()=>{
+                    this.sheetDetailInfo.MeetingInfoId&&this.initSheet()
+                })
+            })
+        },
+        downloadSheet(){
+            if(!this.sheetDetailInfo.MeetingInfoId){
+                this.$message.warning("暂无下载文件")
+                return 
+            }
+            const exportApi = this.exportBase
+                +`?${localStorage.getItem("auth") || ""}`
+                +`&DateTime=${this.selectDate}`
+                +`&IsExport=1`
+
+            this.isDownload = true;
+            const link = document.createElement("a");
+            link.href = this.escapeStr(exportApi);
+            link.download = "";
+            link.click();
+            setTimeout(() => {
+                this.isDownload = false;
+            }, 5000);
+        },
+        // 对[#,;]转义
+        escapeStr(str) {
+            return str.replace(/#/g, escape("#")).replace(/;/g, escape(";"));
+        },
+        initSheet(){
+            const baseOption = this.sheetDetailInfo.Content ? JSON.parse(this.sheetDetailInfo.Content) : {}
+            //luckysheet配置,能隐藏的都隐藏了,并且禁止编辑
+            const options = {
+                container:'sheet-container',
+                lang: 'zh',
+                showinfobar: false,
+                showtoolbar:false,
+                showsheetbar:false,
+                showstatisticBar:false,
+                showstatisticBarConfig: {
+                    count: false, // 计数栏
+                    view: false, // 打印视图
+                    zoom: true, // 缩放
+                },
+                allowCopy:false,
+                allowEdit:false,//不允许编辑
+                allowUpdate:false,
+                enableAddRow:false,
+                sheetFormulaBar:false,
+                showConfigWindowResize:true,
+                data: [{
+                    ...baseOption,
+                    scrollTop: 0,
+                    scrollLeft: 0,
+                }],
+            }
+            luckysheet.create(options)
+            document.querySelector("#luckysheet-cols-h-c").style.pointerEvents = 'none'
+        }
+    },
+    mounted(){
+        this.getSheetDetail()
+    }
+};
+</script>
+
+<style scoped lang="scss">
+.federal-reserve-wrap{
+    height:calc(100vh - 120px);
+    background-color: #fff;
+    display: flex;
+    flex-direction: column;
+    box-sizing: border-box;
+    padding:30px;
+    .tool-box{
+        display: flex;
+        justify-content: space-between;
+    }
+    .table-box{
+        width:100%;
+        box-sizing: border-box;
+        flex: 1;
+        margin-top: 30px;
+        .sheet-wrap{
+            width:100%;
+            height: 100%;
+            position: relative;
+            /* cursor:not-allowed;
+            pointer-events: none; */
+            #sheet-container {
+                margin:0;padding:0;
+                position:absolute;
+                width:100%;left: 0px;top: 0;bottom:0px;
+            }
+        }
+    }
+}
+</style>

+ 44 - 0
src/views/toolBox_manage/components/Sheet.vue

@@ -0,0 +1,44 @@
+<template>
+    <div class="table-wrapper">
+        <table cellpadding="0" cellspacing="0">
+            <tbody>
+                <tr v-for="(item, index) in props.data" :key="index">
+                    <td :class="['data-cell', {
+                        'one-bg': (index + 1) % 2 && index > 0,
+                        'tow-bg': (index + 1) % 2 !== 0 && index > 0,
+                        'head-column': index === 0
+                    }]" v-for="(cell, cell_index) in item" :key="cell_index" :colspan="cell.mc.cs || 1"
+                        :rowspan="cell.mc.rs || 1" :style="`
+            color: ${cell.fc};
+                                    font-weight: ${cell.bl ? 'bold' : 'normal'};
+                                    font-style: ${cell.it ? 'italic' : 'normal'};
+                                    background: ${cell.bg};
+          `">
+                        <!-- 单元格拆分 -->
+                        <div class="split-word" v-if="cell.ct.s">
+                            <span v-for="(word, word_index) in cell.ct.s" :key="`${index}_${cell_index}_${word_index}`"
+                                :style="`color: ${word.fc};font-weight: ${word.bl ? 'bold' : 'normal'};font-style: ${word.it ? 'italic' : 'normal'};
+                            `">{{ word.v }}</span>
+                        </div>
+                        <div v-else>{{ cell.m }}</div>
+                    </td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+</template>
+
+<script>
+    export default {
+        data() {
+            return {
+
+            };
+        },
+        methods: {
+
+        },
+    };
+</script>
+
+<style scoped lang="scss"></style>

BIN
static/css/fonts/SourceHanSansSC-Regular.ttf


BIN
static/css/fonts/SourceHanSerifCN-Regular.ttf