Browse Source

Merge branch 'master' into fix_yjw

jwyu 8 months ago
parent
commit
36031a72d9
100 changed files with 5357 additions and 1156 deletions
  1. 1 1
      config/index.js
  2. 10 6
      src/api/http.js
  3. 66 0
      src/api/modules/BIBoard.js
  4. 159 0
      src/api/modules/approve.js
  5. 98 2
      src/api/modules/chartApi.js
  6. 216 0
      src/api/modules/knowledge.js
  7. BIN
      src/assets/img/icons/home_sjjd.png
  8. BIN
      src/assets/img/knowledge/tem_1.png
  9. BIN
      src/assets/img/knowledge/tem_2.png
  10. BIN
      src/assets/img/knowledge/tem_3.png
  11. BIN
      src/assets/img/knowledge/tem_4.png
  12. 6 5
      src/components/antvVueComponents/tooltipCom.vue
  13. 52 16
      src/components/notificationMsg.vue
  14. 6 0
      src/lang/modules/Aprroval/En.js
  15. 6 0
      src/lang/modules/Aprroval/Zh.js
  16. 2 2
      src/lang/modules/ETATables/Zh.js
  17. 1 1
      src/lang/modules/EtaBase/commonLang.js
  18. 1 1
      src/lang/modules/EtaChart/Zh.js
  19. 3 3
      src/lang/modules/PredictEdb/Zh.js
  20. 1 1
      src/lang/modules/ReportManagement/ReportList.js
  21. 1 1
      src/lang/modules/SandboxManage/SandFlow.js
  22. 2 2
      src/lang/modules/Slides/pptPresent.js
  23. 6 3
      src/lang/modules/systemManage/BaseConfig.js
  24. 1 1
      src/lang/modules/systemManage/OperateAuth.js
  25. 6 5
      src/mixins/reportApproveConfig.js
  26. 11 2
      src/routes/modules/chartRoutes.js
  27. 78 0
      src/routes/modules/knowledgeRoutes.js
  28. 2 2
      src/routes/modules/oldRoutes.js
  29. 1 1
      src/routes/modules/semanticsRoutes.js
  30. 1 1
      src/styles/element-ui.scss
  31. 53 1
      src/utils/buttonConfig.js
  32. 10 4
      src/views/BI_manage/components/BoardContent.vue
  33. 4 3
      src/views/BI_manage/components/ChartBox.vue
  34. 52 7
      src/views/BI_manage/components/CommonClassify.vue
  35. 22 5
      src/views/BI_manage/components/EditCommonClassify.vue
  36. 90 20
      src/views/BI_manage/components/SetCommon.vue
  37. 82 8
      src/views/BI_manage/components/SetShare.vue
  38. 186 14
      src/views/BI_manage/components/TableBox.vue
  39. 3 3
      src/views/BI_manage/editBoard.vue
  40. 177 32
      src/views/BI_manage/index.vue
  41. 10 1
      src/views/Home.vue
  42. 81 32
      src/views/approve_manage/approveDetail.vue
  43. 57 20
      src/views/approve_manage/approveEdit.vue
  44. 145 41
      src/views/approve_manage/approveList.vue
  45. 151 54
      src/views/approve_manage/approveSetting.vue
  46. 3 0
      src/views/approve_manage/components/rejectDialog.vue
  47. 1 0
      src/views/approve_manage/components/timeLineItem.vue
  48. 68 3
      src/views/approve_manage/config/tableConfig.js
  49. 7 0
      src/views/approve_manage/mixins/approveMixins.js
  50. 1 1
      src/views/chartRelevance_manage/components/chartCard.vue
  51. 1 1
      src/views/chartRelevance_manage/components/saveEdbToBaseDia.vue
  52. 2 2
      src/views/chartRelevance_manage/crossVarietyAnalysis/components/edbTableSection.vue
  53. 2 2
      src/views/chartRelevance_manage/relevance/components/multipleIndForm.vue
  54. 12 16
      src/views/classify_manage/chapterSettingV2.vue
  55. 12 14
      src/views/classify_manage/classifylistV2.vue
  56. 1 1
      src/views/dataEntry_manage/adjustdata/adjustData.vue
  57. 1 1
      src/views/dataEntry_manage/codecount/index.vue
  58. 112 0
      src/views/dataEntry_manage/databaseComponents/addCollectClassifyDia.vue
  59. 1 1
      src/views/dataEntry_manage/databaseComponents/batchComptedDialog.vue
  60. 1 1
      src/views/dataEntry_manage/databaseComponents/batchComputedSave.vue
  61. 172 172
      src/views/dataEntry_manage/databaseComponents/batchComputedV2.vue
  62. 1 0
      src/views/dataEntry_manage/databaseComponents/chartTrendRender.vue
  63. 114 0
      src/views/dataEntry_manage/databaseComponents/collectEdbMenu.vue
  64. 1 1
      src/views/dataEntry_manage/databaseComponents/computedDialog.vue
  65. 2 35
      src/views/dataEntry_manage/databaseComponents/dataAssociateChart.vue
  66. 1 1
      src/views/dataEntry_manage/databaseComponents/diffusionIndexDia.vue
  67. 149 0
      src/views/dataEntry_manage/databaseComponents/edbCollectDia.vue
  68. 1 1
      src/views/dataEntry_manage/databaseComponents/fittingResidueDia.vue
  69. 1 1
      src/views/dataEntry_manage/databaseComponents/jointTargetDia.vue
  70. 5 1
      src/views/dataEntry_manage/databaseComponents/openDialog.vue
  71. 5 3
      src/views/dataEntry_manage/databaseComponents/operationDialog.vue
  72. 5 3
      src/views/dataEntry_manage/databaseComponents/smoothEdbDialog.vue
  73. 396 225
      src/views/dataEntry_manage/databaseList.vue
  74. 4 4
      src/views/dataEntry_manage/mixins/chartPublic.js
  75. 2 2
      src/views/datasheet_manage/components/CustomTable.vue
  76. 1 1
      src/views/datasheet_manage/customAnalysis/components/createTargetForm.vue
  77. 6 2
      src/views/edbHistoryPage.vue
  78. 0 66
      src/views/home_manage/components/BIWrap.vue
  79. 0 81
      src/views/home_manage/components/PointViewWrap.vue
  80. 0 81
      src/views/home_manage/components/PolicyWrap.vue
  81. 0 82
      src/views/home_manage/components/ReportWrap.vue
  82. 217 0
      src/views/home_manage/components/SelectBoard.vue
  83. 68 12
      src/views/home_manage/index.vue
  84. 1 1
      src/views/intervalAnalysis/components/batchSelectEdb.vue
  85. 1 1
      src/views/intervalAnalysis/components/saveMultipleEdb.vue
  86. 1 1
      src/views/intervalAnalysis/components/saveSingleEdb.vue
  87. 380 0
      src/views/knowledge_manage/components/classifyDia.vue
  88. 44 0
      src/views/knowledge_manage/components/eventPreview.vue
  89. 240 0
      src/views/knowledge_manage/components/importExcelDia.vue
  90. 248 0
      src/views/knowledge_manage/components/importFileDia.vue
  91. 355 0
      src/views/knowledge_manage/edit.vue
  92. 545 0
      src/views/knowledge_manage/list.vue
  93. 271 0
      src/views/knowledge_manage/tagSetting.vue
  94. 4 4
      src/views/mychart_manage/components/chartDetailDia.vue
  95. 1 1
      src/views/predictEdb_manage/components/edbDia.vue
  96. 1 1
      src/views/predictEdb_manage/predictEdb.vue
  97. 15 15
      src/views/report_manage/reportV2/components/chapterEditWrapper.vue
  98. 11 11
      src/views/report_manage/reportV2/components/reportBaseInfoDia.vue
  99. 2 2
      src/views/report_manage/reportV2/list.vue
  100. 1 1
      src/views/report_manage/reportV2/normalReport/components/ETASandBox.vue

+ 1 - 1
config/index.js

@@ -31,7 +31,7 @@ module.exports = {
 	//	原始配置
     env: require('./dev.env'),
     host: 'newadmin.brilliantstart.cn', // can be overwritten by process.env.HOST
-    port: '3030',
+    port: '3033',
     autoOpenBrowser: false,
     assetsSubDirectory: 'static',
     assetsPublicPath: '/',

+ 10 - 6
src/api/http.js

@@ -67,6 +67,7 @@ function errorMsgShow(closableErrMsg,msg){
   }
 }
 
+let loginOutCount=0
 function checkStatus(response,closableErrMsg) {
   //处理响应数据
   if (response && response.status === 200) {
@@ -78,16 +79,19 @@ function checkStatus(response,closableErrMsg) {
     } else if (res.Ret == 403) {
       errorMsgShow(closableErrMsg,res.Msg)
     } else if (res.Ret === 408) {
-      // localStorage.setItem("auth", "")
-      localStorage.setItem("loginTime", "")
-      bus
-        .$alert(res.Msg, "提示", {
+      if(loginOutCount===0){
+        localStorage.setItem("loginTime", "")
+        bus.$alert(res.Msg, "提示", {
           showClose: false,
-        })
-        .then(() => {
+        }).then(() => {
+          loginOutCount=0
           router.replace('/login')
           // window.location.href = window.location.origin + '/login';
         });
+      }
+      loginOutCount++
+      // localStorage.setItem("auth", "")
+      
     }
     return res;
   } else {

+ 66 - 0
src/api/modules/BIBoard.js

@@ -27,5 +27,71 @@ export default{
   editBoard:params=>{
     return http.post('/bi_dashborad/edit',params)
   },
+  // 看板编辑状态
+  editBoardLock:params=>{
+    return http.post('/bi_dashborad/editing',params)
+  },
+  // 删除看板
+  deleteBoard:params=>{
+    return http.post('/bi_dashborad/delete',params)
+  },
+  // 看板元素拖动
+  moveBoardElement:params=>{
+    return http.post('/bi_dashborad/detail/move',params)
+  },
+
+  // 表格详情
+  tableDetail:params=>{
+    return http.get('/datamanage/excel_info/table_data',params)
+  },
+
+  // 新增看板公共分类
+  addCommonClassify:params=>{
+    return http.post('/bi_dashborad/classify/add',params)
+  },
+  // 公共看板分类数据
+  commonClassifyList:params=>{
+    return http.get('/bi_dashborad/classify/list',{})
+  },
+   // 编辑看板公共分类
+  editCommonClassify:params=>{
+    return http.post('/bi_dashborad/classify/edit',params)
+  },
+  // 删除看板公共分类
+  deleteCommonClassify:params=>{
+    return http.post('/bi_dashborad/classify/del',params)
+  },
+  // 将看板设置为公共看板
+  setBoardCommon:params=>{
+    return http.post('/bi_dashborad/public',params)
+  },
+  // 将看板取消设置为公共看板
+  cancelBoardCommon:params=>{
+    return http.post('/bi_dashborad/public/cancel',params)
+  },
+
+  // 将看板设置为共享看板
+  setBoardShare:params=>{
+    return http.post('/bi_dashborad/grant',params)
+  },
+  // 将看板取消设置为共享看板
+  cancelBoardShare:params=>{
+    return http.post('/bi_dashborad/grant/cancel',params)
+  },
+  //获取看板共享用户
+  getBoardShareUsers:params=>{
+    return http.get('/bi_dashborad/grant/info',params)
+  },
+
+  // 获取首页看板
+  getHomePageBoard:params=>{
+    return http.get('/bi_dashborad/home_page',{})
+  },
+  //设置首页看板
+  setHomePageBoard:params=>{
+    return http.post('/bi_dashborad/home_page/save',params)
+  },
+
+
   
 }

+ 159 - 0
src/api/modules/approve.js

@@ -222,4 +222,163 @@ export const approveInterence = {
         return http.post("/smart_report/approve/cancel",params)
     },
 
+    /*------------bi看板审批接口----------- */
+     /**
+     * 获取审批流列表
+     * @param {Object} params 
+     * @param {Number} params.PageSize
+     * @param {Number} params.CurrentIndex
+     * @param {Number} params.ClassifyId 关联报告二级分类ID
+     * @param {String} params.Keyword
+     * @param {Number} params.SortRule 排序方式: 1-正序; 2-倒序(默认)
+     * @returns 
+     */
+     getBiApproveFlowList(params){
+        return http.get("/bi_approve/flow/list",params)
+    },
+
+    getBiApproveClassifyTree(params){
+        return http.get("/bi_approve/classify/list",params)
+    },
+
+    /**
+     * 删除审批流
+     * @param {Object} params 
+     * @param {Number} params.BiApproveFlowId
+     * @returns 
+     */
+    deleteBiApproveFlow(params){
+        return http.post("/bi_approve/flow/remove",params)
+    },
+
+    /**
+     * 新增审批流
+     * @param {Object} params 
+     * @param {number} params.BiApproveFlowId 0
+     * @param {String} params.FlowName 审批流名称
+     * @param {Number} params.ClassifyId 分类ID
+     * @param {Object[]} params.Nodes 审批节点
+     * @param {Number} params.Nodes[].ApproveType 审批类型:1-依次审批;2-会签;3-或签
+     * @param {Object[]} params.Nodes[].Users 审批人信息
+     * @param {String} params.Nodes[].Users[].UserType 审批人类型: user-用户; role-角色
+     * @param {Number} params.Nodes[].Users[].UserId 用户/角色ID
+     * @param {String} params.Nodes[].Users[].UserName 用户/角色姓名
+     * @returns 
+     */
+    addNewBiApproveFlow(params){
+        return http.post("/bi_approve/flow/add",params)
+    },
+
+    /**
+     * 编辑审批流
+     * @param {Object} params 
+     * @param {number} params.BiApproveFlowId id
+     * @param {String} params.FlowName 审批流名称
+     * @param {Number} params.ClassifyId 分类ID
+     * @param {Object[]} params.Nodes 审批节点
+     * @param {Number} params.Nodes[].ApproveType 审批类型:1-依次审批;2-会签;3-或签
+     * @param {Object[]} params.Nodes[].Users 审批人信息
+     * @param {String} params.Nodes[].Users[].UserType 审批人类型: user-用户; role-角色
+     * @param {Number} params.Nodes[].Users[].UserId 用户/角色ID
+     * @param {String} params.Nodes[].Users[].UserName 用户/角色姓名
+     * @returns 
+     */
+    editBiApproveFlow(params){
+        return http.post("/bi_approve/flow/edit",params)
+    },
+
+    /**
+     * 审批流详情
+     * @param {Object} params 
+     * @param {Number} params.BiApproveFlowId
+     * @returns 
+     */
+    getBiApproveFlowDetail(params){
+        return http.get("/bi_approve/flow/detail",params)
+    },
+
+
+    /**
+     * bi审批消息通知
+     * @param {Object} params 
+     * @param {Number} params.PageSize
+     * @param {Number} params.CurrentIndex
+     * @returns 
+     */
+    getBiApproveMsgList(params){
+        return http.get("/bi_approve/message/list",params)
+    },
+
+    /**
+     * 消息通知已读
+     * @param {Object} params 
+     * @param {Number} params.MessageId
+     * @returns 
+     */
+    readBiApproveMsg(params){
+        return http.post("/bi_approve/message/read",params)
+    },
+    
+
+    /**
+     * 获取bi看板审批列表
+     * @param {Object} params 
+     * @param {Number} params.PageSize
+     * @param {Number} params.CurrentIndex
+     * @param {Number} params.ClassifyId  目录id
+     * @param {String} params.Keyword
+     * @param {Number} params.SortRule 排序方式: 1-正序; 2-倒序(默认)
+     * @param {Number} params.SortField 排序字段:1-提交时间;2-处理时间;3-审批时间
+     * @param {Number} params.ListType 列表类型:1-待处理;2-已处理;3-我发起的
+     * @param {Number} params.ApproveState 审批状态:1-待审批;2-已审批/已通过;3-已驳回;4-已撤回/已撤销
+     * @param {Number} params.TimeType 时间类型:1-提交时间;2-处理时间;3-审批时间
+     * @param {String} params.StartTime 开始时间
+     * @param {String} params.EndTime 结束时间
+     * @returns 
+     */
+    getBiApproveList(params){
+        return http.get("/bi_approve/list",params)
+    },
+
+    /**
+     * bi看板驳回审批
+     * @param {Object} params 
+     * @param {Number} params.BiApproveId
+     * @param {String} params.ApproveRemark
+     * @returns 
+     */
+    rejectBiApprove(params){
+        return http.post("/bi_approve/refuse",params)
+    },
+
+    /**
+     * bi通过审批
+     * @param {Object} params 
+     * @param {Number} params.BiApproveId
+     * @returns 
+     */
+    passBiApprove(params){
+        return http.post("/bi_approve/approve",params)
+    },
+
+    /**
+     * bi撤销审批
+     * @param {Object} params 
+     * @param {Number} params.BiApproveId
+     * @returns 
+     */
+    cancelBiApprove(params){
+        return http.post("/bi_approve/cancel",params)
+    },
+
+    /**
+     * 获取bi审批详情
+     * @param {Object} params
+     * @param {Number} params.BiApproveId
+     * @returns 
+     */
+    getBiApproveDetail(params){
+        return http.get("/bi_approve/detail",params)
+    },
+
 }

+ 98 - 2
src/api/modules/chartApi.js

@@ -458,7 +458,7 @@ const dataBaseInterface = {
 
 
 
-	//========================================chart
+	//=========================================chart==========
 	// /**
 	//  * 
 	//  * @param {Image} params 
@@ -1375,8 +1375,104 @@ const chartFrameInterface = {
 
 }
 
+
+const edbCollectInterface = {
+	/**
+	 * 获取收藏分类
+	 * @param {*} params  ParentId
+	 * @returns 
+	 */
+		getEdbCollectClassify: params => {
+			return http.get('/datamanage/edb_collect/classify/list',params)
+		},
+
+		/**
+		 * 获取一级收藏分类
+		 * @param {*} params  ParentId
+		 * @returns 
+		 */
+		getEdbCollectClassifyOne: params => {
+			return http.get('/datamanage/edb_collect/classify/tree',params)
+		},
+
+		/**
+		 * 新增收藏分类
+		 * @param {*} params  ClassifyName ParentId Level
+		 * @returns 
+		 */
+		addCollectClassify: params => {
+			return http.post('/datamanage/edb_collect/classify/add',params)
+		},
+
+		/**
+		 * 编辑收藏分类
+		 * @param {*} params  ClassifyName ClassifyId
+		 * @returns 
+		 */
+		editCollectClassify: params => {
+			return http.post('/datamanage/edb_collect/classify/edit',params)
+		},
+
+		/**
+		 * 删除收藏分类
+		 * @param {*} params ClassifyId
+		 * @returns 
+		 */
+		delCollectClassify: params => {
+			return http.post('/datamanage/edb_collect/classify/remove',params)
+		},
+
+		/**
+		 * 移动收藏
+		 * @param {*} params ClassifyId
+		 * EdbInfoId NextEdbInfoId  PrevEdbInfoId
+		 * @returns 
+		 */
+		moveCollectEdb: params => {
+			return http.post('/datamanage/edb_collect/move',params)
+		},
+
+		/**
+		 * 移动收藏分类
+		 * @param {*} params ClassifyId
+		 * PrevClassifyId NextClassifyId
+		 * @returns 
+		 */
+		moveCollectClassify: params => {
+			return http.post('/datamanage/edb_collect/classify/move',params)
+		},
+
+		/**
+		 * 收藏指标
+		 * @param {*} params ClassifyId EdbInfoId
+		 * @returns 
+		 */
+		edbCollect: params => {
+			return http.post('/datamanage/edb_collect/collect',params)
+		},
+		
+		/**
+		 * 取消收藏指标
+		 * @param {*} params ClassifyId EdbInfoId
+		 * @returns 
+		 */
+		edbCollectCancel: params => {
+			return http.post('/datamanage/edb_collect/cancel_collect',params)
+		},
+
+		/**
+		 * 收藏列表
+		 * @param {*} params PageSize CurrentIndex ClassifyId Keyword
+		 * @returns 
+		 */
+		getCollectEdb: params => {
+			return http.get('/datamanage/edb_collect/list',params)
+		},
+}
+
 export {
 	dataBaseInterface,
 	mychartInterface,
-	chartFrameInterface
+	chartFrameInterface,
+	edbCollectInterface
 }

+ 216 - 0
src/api/modules/knowledge.js

@@ -0,0 +1,216 @@
+import http from "@/api/http.js";
+
+export const eventInterface = {
+  /**
+   * 获取分类
+   * @param {*} params 
+   * @returns 
+   */
+  getClassify: params => {
+    return http.get("/knowledge/classify/list",params)
+  },
+
+  /**
+   * 添加分类
+   * @param {*} params ClassifyName ParentId ResourceType
+   * @returns 
+   */
+  addClassify: params => {
+    return http.post("/knowledge/classify/add",params)
+  },
+
+  /**
+   * 编辑分类
+   * @param {*} params
+   *  ResourceType 
+   *  "ClassifyName": "分类3",
+      "ParentId": 0,
+      "ClassifyId": 6
+   * @returns 
+   */
+  editClassify: params => {
+    return http.post("/knowledge/classify/edit",params)
+  },
+
+  /**
+   * 移动分类
+   * @param {*} params 
+   * "ClassifyId": 3,
+    "PrevClassifyId": 0,
+    "NextClassifyId": 6
+    ResourceType
+   * @returns 
+   */
+  moveClassify: params => {
+    return http.post("/knowledge/classify/move",params)
+  },
+
+  /**
+   * 删除分类检测
+   * @param {*} params ClassifyId
+   * @returns 
+   */
+  delClassifyCheck: params => {
+    return http.get("/knowledge/classify/checkDelete",params)
+  },
+
+  /**
+   * 删除分类
+   * @param {*} params 
+   * ClassifyId
+   * @returns 
+   */
+  delClassify: params => {
+    return http.post("/knowledge/classify/delete",params)
+  },
+
+  /**
+   * 事件列表
+   * @param {*} params 
+   * PageSize CurrentIndex ClassifyIds SysUserIds TagIds Keyword
+   * @returns 
+   */
+  getEventList: params => {
+    return http.get("/knowledge/resource/list",params)
+  },
+
+  /**
+   * 新建事件
+   * @param {*} params 
+   * "ResourceType": 0,
+    "ClassifyId": 6,
+    "Title": "美联储",
+    "Content": "第二届“一带一路”国际合作高峰论坛",
+    "SourceFrom": "中华网",
+    "TagId": 0,
+    "StartTime": "2024-09-26 10:12:00",
+    "EndTime": "2024-09-30 10:12:00",
+    "FileUrl": ""
+   * @returns 
+   */
+  addEvent: params => {
+    return http.post('/knowledge/resource/add',params)
+  },
+
+  /**
+   * 编辑事件
+   * @param {*} params 
+   * ResourceType
+   * "KnowledgeResourceId": 1,
+    "ClassifyId": 9,
+    "Title": "美联储22",
+    "Content": "00000第届“一带一路”国际合作高峰论坛",
+    "SourceFrom": "中华网11",
+    "TagId": 0,
+    "StartTime": "2024-09-26 10:12:00"
+   * @returns 
+   */
+  editEvent: params => {
+    return http.post('/knowledge/resource/edit',params) 
+  },
+
+  /**
+   * 删除事件
+   * @param {*} params  KnowledgeResourceId ResourceType
+   * @returns 
+   */
+  delEvent: params => {
+    return http.post('/knowledge/resource/delete',params) 
+  },
+
+  /**
+   * 获取事件详情
+   * @param {*} params KnowledgeResourceId ResourceType
+   * @returns 
+   */
+  getEventDetail: params => {
+    return http.get('/knowledge/resource/detail',params)
+  },
+
+  /**
+   * 标签列表
+   * @param {*} params 
+   *  ResourceType
+   * @returns 
+   */
+  getTagList: params => {
+    return http.get('/knowledge/tag/list',params)
+  },
+
+  /**
+   * 新增标签
+   * @param {*} params 
+   * TagName ResourceType
+   * @returns 
+   */
+  addTag: params => {
+    return http.post('/knowledge/tag/add',params)
+  },
+  /**
+   * 编辑标签
+   * @param {*} params 
+   * TagName ResourceType TagId
+   * @returns 
+   */
+  editTag: params => {
+    return http.post('/knowledge/tag/edit',params)
+  },
+  /**
+   * 删除标签
+   * @param {*} params 
+   * TagId ResourceType 
+   * @returns 
+   */
+  delTag: params => {
+    return http.post('/knowledge/tag/delete',params)
+  },
+
+  /**
+   * 删除标签
+   * @param {*} params 
+   * TagId ResourceType  PrevTagId NextTagId
+   * @returns 
+   */
+  moveTag: params => {
+    return http.post('/knowledge/tag/move',params)
+  },
+
+  /**
+   * 来源列表 
+   * @param {*} params Keyword ResourceType
+   * @returns 
+   */
+  getSourcesList: params => {
+    return http.get('/knowledge/resource/source_from',params)
+  },
+
+  /**
+   * 创建人列表
+   * @param {*} params 
+   * Keyword ResourceType=0
+   * @returns 
+   */
+  getUsersList: params => {
+    return http.get('/knowledge/resource/admins',params)
+  },
+
+  /**
+   * excel导入
+   * @param {*} params 
+   * EntryFile ResourceType
+   * @returns 
+   */
+  excelImportUpload: params => {
+    return http.post('/knowledge/resource/import_add',params)
+  },
+
+  /**
+   * 文件导入
+   * @param {*} params 
+   * ResourceType EntryFile
+   * @returns 
+   */
+  fileImportUpload: params => {
+    return http.post('/knowledge/resource/upload',params)
+  }
+}

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


BIN
src/assets/img/knowledge/tem_1.png


BIN
src/assets/img/knowledge/tem_2.png


BIN
src/assets/img/knowledge/tem_3.png


BIN
src/assets/img/knowledge/tem_4.png


+ 6 - 5
src/components/antvVueComponents/tooltipCom.vue

@@ -103,12 +103,13 @@ export default {
       this.show=false
     },
     nodeClick(){
-      if(this.params.stopNodeClick) return 
+      if(this.params.stopNodeClick) return
       //EdbInfoType 1:跳预测指标详情 0:跳指标库详情
-      const { ClassifyId, UniqueCode, EdbInfoId, EdbInfoType } = this.data.routeQuery
-      let { href } =
-      this.$router.resolve({ path: EdbInfoType === 1 ? '/predictEdb' : '/database', query: { code: UniqueCode, id:
-      EdbInfoId, classifyId: ClassifyId } });
+      const { ClassifyId, UniqueCode, EdbInfoId, EdbInfoType,EdbType,HaveOperaAuth } = this.data.routeQuery
+      if(!HaveOperaAuth) return this.$message.warning('暂无指标权限')
+
+      let { href } = this.$router.resolve({ path: EdbInfoType === 1 ? '/predictEdb' : (EdbType===1?'/edbBasicbase':'/database'), 
+        query: { code: UniqueCode, id:EdbInfoId, classifyId: ClassifyId } });
       window.open(href, '_blank');
     }
   },

+ 52 - 16
src/components/notificationMsg.vue

@@ -8,8 +8,12 @@
             <div class="notifation-wrap">
                 <!-- 防止tabs在popover前渲染,会导致tab选中状态不正确 -->
                 <el-tabs v-model="activeName" v-if="visible" @tab-click="getMsgList">
-                    <el-tab-pane :label="`${$t('AprrovalPage.research_approval_btn')}${activeName==='first'?'('+UnreadTotal+')':''}`" name="first"></el-tab-pane>
-                    <el-tab-pane :label="`${$t('SystemManage.OperateAuth.label_notice_title')}${activeName==='second'?'('+UnreadTotal+')':''}`" name="second"></el-tab-pane>
+                    <!-- 研报审批 -->
+                    <el-tab-pane v-if="tabsShow.first" :label="`${$t('AprrovalPage.research_approval_btn')}${activeName==='first'?'('+UnreadTotal+')':''}`" name="first"></el-tab-pane>
+                    <!-- bi看板审批 -->
+                    <el-tab-pane v-if="tabsShow.second" :label="`${$t('SystemManage.BaseConfig.bIDashboard_approval')}${activeName==='second'?'('+UnreadTotal+')':''}`" name="second"></el-tab-pane>
+                    <!-- 资产数据 -->
+                    <el-tab-pane v-if="tabsShow.third" :label="`${$t('SystemManage.OperateAuth.label_notice_title')}${activeName==='third'?'('+UnreadTotal+')':''}`" name="third"></el-tab-pane>
                 </el-tabs>
                 <div class="massage-list" v-if="visible">
                     <div class="message-item" :class="{'IsRead':item.IsRead}" v-for="item in msgList" :key="item.Id" @click="readMsg(item)">
@@ -23,6 +27,8 @@
                             </div>
                             <!-- 审批内容 -->
                             <div class="content" v-if="activeName==='first'">{{item.Remark||''}}&nbsp;</div>
+                            <!-- 看板审批 内容部分-->
+                            <div class="content" v-else-if="activeName==='second'">{{item.Remark||''}}&nbsp;</div>
                             <!-- 权限内容 -->
                             <div class="content" v-else>
                                 {{item.Remark||''}}
@@ -118,13 +124,15 @@
 <script>
 import {approveInterence} from '@/api/modules/approve.js';
 import { operateAuthInterface } from '@/api/modules/setApi';
+import {etaBaseConfigInterence} from '@/api/modules/etaBaseConfigApi.js';
 import mDialog from './mDialog.vue';
+const tabNames = ['first','second','third'];
 export default {
     components: { mDialog },
     data() {
         this.approveState=['','process','passed','reject','return',]
         return {
-            activeName:'first',
+            activeName:'',
             visible:false,
             msgList:[],
             UnreadTotal:0,
@@ -141,7 +149,12 @@ export default {
                 isAuthSet: false,//true权限设置 false资产转移
                 Source: 1,
                 SubSource: 0,
-            }
+            },
+            tabsShow:{
+              first:false, //研报
+              second:false, //BI
+              third:true, //资产
+            },
         };
     },
     computed: {
@@ -184,8 +197,9 @@ export default {
         },
     },
     watch:{
-        visible(val){
+        async visible(val){
             if(val){
+               await this.handleTabs()
                 this.getMsgList()
             }
         },
@@ -202,29 +216,44 @@ export default {
         }
     },
     methods:{
+        async handleTabs(){
+            return new Promise(async resolve=>{
+                const res = await etaBaseConfigInterence.getBaseConfig()
+                if(res.Ret != 200) return;
+                const {IsReportApprove='',ReportApproveType='',IsBIApprove=''} = res.Data
+                let isETAApprove = (IsReportApprove==='true'?true:false) && ReportApproveType==='eta'
+                let IsBIApprove_v = IsBIApprove==='true'?true:false
+                
+                if(isETAApprove) this.tabsShow.first = true;
+                if(IsBIApprove_v) this.tabsShow.second = true;
+                if(!tabNames.includes(this.activeName)){//默认选中第一个显示的tab   
+                    this.activeName = Object.entries(this.tabsShow).filter(_=>_[1])[0][0] || 'third'; 
+                }
+                resolve()
+            })
+        },
         async readMsg(msg){
-            const {ApproveState,ReportApproveId,Id,DataPermissionMessageId} = msg
-            
-            const res = this.activeName === 'first' 
-                ? await approveInterence.readApproveMsg({
-                    MessageId:Id
-                  })
-                : await operateAuthInterface.redMessage({ MessageId: DataPermissionMessageId })
+            const res = this.activeName === 'first'    
+                ? await approveInterence.readApproveMsg({MessageId:msg.Id})
+                : this.activeName === 'second' ? await approveInterence.readBiApproveMsg({MessageId:msg.Id})
+                  : await operateAuthInterface.redMessage({ MessageId: msg.DataPermissionMessageId })
 
             if(res.Ret!==200) return 
             this.getMsgList()
             this.getUnreadNum()
 
-            if(this.activeName === 'first' ) {
-                const type = ApproveState===1?'approve':ApproveState===4?'detail':'myself'
+            if(this.activeName === 'first' || this.activeName === 'second'){
+                const type = msg.ApproveState===1?'approve':msg.ApproveState===4?'detail':'myself' 
                 this.$router.push({
                     path:'/approveDetail',
                     query:{
+                        mainType:this.activeName === 'first' ? 'report' :'bi',
                         type,
-                        approveId:ReportApproveId
+                        approveId:this.activeName === 'first' ? msg.ReportApproveId :msg.BiApproveId, 
                     }
                 })
             }
+            
         },
         async getMsgList(){
             const res = this.activeName === 'first' 
@@ -232,10 +261,17 @@ export default {
                     CurrentIndex:1,
                     PageSize:1000
                 })
+                :  (
+                this.activeName === 'second' ?
+                await approveInterence.getBiApproveMsgList({ 
+                    CurrentIndex:1,
+                    PageSize:1000
+                }) 
                 : await operateAuthInterface.getNoticeList({
                     CurrentIndex:1,
                     PageSize:1000
-                })
+                }) 
+                )
 
             if(res.Ret!==200) return 
             this.msgList = res.Data.List||[]

+ 6 - 0
src/lang/modules/Aprroval/En.js

@@ -34,6 +34,12 @@ export default {
     research_approval_btn: "Research report approval",
     close_btn: "close",
     no_news_yet: "No news yet",
+    kanban_name:'BI Kanban name',
+    associative_classification:'Associative classification',
+    association_kanban:'Association kanban',
+    processing_state:'Processing state',
+    select_associated_Kanban_tip:'Please select associated Kanban',
+    enter_Kanban_name_tip:'Please enter a BI Kanban name',
   },
   AprrovalDetailPage: {
     report_name_info: "Research Report name",

+ 6 - 0
src/lang/modules/Aprroval/Zh.js

@@ -34,6 +34,12 @@ export default {
     research_approval_btn: "研报审批",
     close_btn: "关闭",
     no_news_yet: "暂无消息",
+    kanban_name:'BI看板名称',
+    associative_classification:'关联分类',
+    association_kanban:'关联看板',
+    processing_state:'处理状态',
+    select_associated_Kanban_tip:'请选择关联看板',
+    enter_Kanban_name_tip:'请输入BI看板名称',
   },
   AprrovalDetailPage: {
     report_name_info: "研报名称",

+ 2 - 2
src/lang/modules/ETATables/Zh.js

@@ -50,7 +50,7 @@ export default {
     table_name_empty_msg: "表格名称不能为空",
     name_empty_msg: "名称不能为空",
     TableInstructionsText: `表格说明:<br>
-    1、手动输入:单击每个单元格可直接输入文本、数字、日期(格式示例:2023-05-23),输入内容可匹配指标名称,指标库和预测指标库指标均可搜索,在下拉框中选择指标,则该单元格为已选指标行/列。<br>
+    1、手动输入:单击每个单元格可直接输入文本、数字、日期(格式示例:2023-05-23),输入内容可匹配指标名称,指标库和衍生指标库指标均可搜索,在下拉框中选择指标,则该单元格为已选指标行/列。<br>
     2、插入指标值:右键单元格,点击“插入指标值”,则查询该单元格行、列最近的日期和指标名称,将查找到的指标对应日期的值填入该单元格,指标值总是在右下角。<br>
     3、更新与计算规则:表格中指标值的日期不自动更新,数值不支持单元格计算`,
     date_type_label: "日期类型",
@@ -98,7 +98,7 @@ export default {
     not_allow_edit:'当前不可编辑',
     batch_settings:'批量设置',
     metrics:'指标',
-    forecast_metrics:'预测指标',
+    forecast_metrics:'衍生指标',
     please_select_metric_name:'请选择指标名称',
     move_successful:'移动成功',
     no_found_search:'未搜索到该指标',

+ 1 - 1
src/lang/modules/EtaBase/commonLang.js

@@ -109,7 +109,7 @@ export default {
     en:'index'
   },
   eta_predictor_name:{
-    zh:'预测指标',
+    zh:'衍生指标',
     en:'predictor index'
   },
   formula_instru: {

+ 1 - 1
src/lang/modules/EtaChart/Zh.js

@@ -77,7 +77,7 @@ export default {
     section_pos_bot: '底部',
     right_edb_type_on_year:'左轴指标同比',
     right_edb_type_lib:'指标库',
-    right_edb_type_pred:'预测指标',
+    right_edb_type_pred:'衍生指标',
     right_edb_gen_style:'生成样式',
     right_edb_gen_column:'柱形',
     right_edb_gen_mark:'标记点',

+ 3 - 3
src/lang/modules/PredictEdb/Zh.js

@@ -5,8 +5,8 @@ export default {
   /* 预测指标页面 */
   PredictEdbPage: {
     only_see_mine: '只看我的',
-    total_list_view: '共{limit}个预测指标',
-    del_edb_msg: '预测指标删除后不可恢复,确认删除吗',
+    total_list_view: '共{limit}个衍生指标',
+    del_edb_msg: '衍生指标删除后不可恢复,确认删除吗',
     
     /* 查看基础指标弹窗 */
     view_rules: '查看预测规则',
@@ -22,7 +22,7 @@ export default {
   /* 添加指标页面 */
   PredictEditPage: {
     add_to_classify: '添加到分类',
-    predict_edb_name: '预测指标名称',
+    predict_edb_name: '衍生指标名称',
     predict_date_type: '预测日期类型',
     ph_date_type: '请选择日期类型',
     date_type_trade:'交易日',

+ 1 - 1
src/lang/modules/ReportManagement/ReportList.js

@@ -250,7 +250,7 @@ export const ReportListZh = {
   library_top_type: "版图资源库",
   eta_top_type: "表格",
   statistical_top_type: "统计分析",
-  sandbox_top_type: "沙盘图",
+  sandbox_top_type: "逻辑图",
   semantic_top_type: "语义分析",
   chart_top_type: "图库",
   insert_charts_msg: "请插入图表",

+ 1 - 1
src/lang/modules/SandboxManage/SandFlow.js

@@ -96,7 +96,7 @@ export const SandFlowEn = {
     copy_tag:'复制',
     delete_tag:'删除',
     add_link_search_placeholder:'指标ID/指标名称',
-    link_type_opt1:'指标/预测指标',
+    link_type_opt1:'指标/衍生指标',
     link_type_opt2:'图库',
     link_type_opt3:'研报',
     msg_leave_page_save:'在离开页面之前,是否保存当前内容?',

+ 2 - 2
src/lang/modules/Slides/pptPresent.js

@@ -129,8 +129,8 @@ export const presentZh = {
   statistical_features: "统计特征",
   intercommodity_analysis: "跨品种分析",
   show_only_mine: "只看我的",
-  sandbox_name_category: "沙盘名称/品种",
-  sandbox_name: "沙盘",
+  sandbox_name_category: "逻辑图名称/品种",
+  sandbox_name: "逻辑图",
   table_name: "表格",
   table_analysis_semantic: "语义分析插入",
   table_name_input: "表格名称",

+ 6 - 3
src/lang/modules/systemManage/BaseConfig.js

@@ -102,8 +102,9 @@ export const BaseConfigEn = {
     mobile_website_title_Tip:"Please enter the mobile website name",
     system_logo:"System Logo",
     upload_image_tip:"Click to Upload Image",
-    report_logo:'Report Logo'
-    
+    report_logo:'Report Logo',
+    bIDashboard_approval:'BI Dashboard Approval',
+    board_approval:'Board Approval',
 };
   
 /* 中文 */
@@ -209,7 +210,9 @@ export const BaseConfigZh = {
     system_logo:"系统logo",
     upload_image_tip:"点击上传图片",
 
-    report_logo:'研报Logo'
+    report_logo:'研报Logo',
+    bIDashboard_approval:'BI看板审批',
+    board_approval:'看板审批',
 };
   
 /**

+ 1 - 1
src/lang/modules/systemManage/OperateAuth.js

@@ -78,7 +78,7 @@ export const OperateAuthZh = {
     tab01:'手工数据指标',
     tab02:'钢联化工数据库',
     tab03:'指标库',
-    tab04:'预测指标',
+    tab04:'衍生指标',
     tab05:'图库',
     tab06:'表格',
 

+ 6 - 5
src/mixins/reportApproveConfig.js

@@ -17,6 +17,7 @@ export default{
             pageLoading:false,
             hasApproveFlow:false,
             checkLoading:false,
+            IsBIApprove:false,
         }
     },
     computed:{
@@ -40,11 +41,11 @@ export default{
             const res = await etaBaseConfigInterence.getBaseConfig()
             this.pageLoading = false
             if(res.Ret!==200) return
-            const {IsReportApprove='',ReportApproveType=''} = res.Data
-            this.IsReportApprove = IsReportApprove==='true'?true:false,
+            const {IsReportApprove='',ReportApproveType='',IsBIApprove=''} = res.Data
+            this.IsReportApprove = IsReportApprove==='true'?true:false
             this.ReportApproveType = ReportApproveType
-
-            console.log(this.isApprove)
+            this.IsBIApprove = IsBIApprove==='true'?true:false
+            this.afterGetBaseConfig && this.afterGetBaseConfig();
         },
         //检查是否有审批流
         checkClassifyNameArr(type=1,classify=[]){
@@ -53,7 +54,7 @@ export default{
                 ReportType:type,
                 ClassifyFirstId:classify[0]||0,
                 ClassifySecondId:classify[1]||0,
-                ClassifyThirId:classify[2]||0,
+                ClassifyThirdId:classify[2]||0,
             }
             approveInterence.checkClassifyApprove(params).then(res=>{
                 this.checkLoading=false

+ 11 - 2
src/routes/modules/chartRoutes.js

@@ -45,7 +45,7 @@ export default [
 	{
 		path: '/',
 		component: home,
-		name: '指标库',
+		name: '数据分析',
 		hidden: false,
 		icon_path: require('@/assets/img/home/data_ic.png'),
 		meta:{
@@ -55,7 +55,16 @@ export default [
 			{
 				path: 'database',
 				component: () => import('@/views/dataEntry_manage/databaseList.vue'),
-				name: '指标库',
+				name: '指标加工',
+				hidden: false,
+				meta:{
+					name_en:'Indics'
+				},
+			},
+			{
+				path: 'edbBasicbase',
+				component: () => import('@/views/dataEntry_manage/databaseList.vue'),
+				name: '数据查看',
 				hidden: false,
 				meta:{
 					name_en:'Indics'

+ 78 - 0
src/routes/modules/knowledgeRoutes.js

@@ -0,0 +1,78 @@
+/* 知识资源 */
+
+export default [{
+  path: '/',
+  component: () => import('@/views/Home.vue'),
+  name: '知识资源',
+  hidden: false,
+  meta:{
+    name_en:""
+  },
+  children: [{
+      path: "/knowledge_event",
+      name: "事件库",
+      component: () => import('@/views/knowledge_manage/list.vue'),
+      meta:{
+        name_en:""
+      },
+    },
+    {
+      path: "/knowledge_policy",
+      name: "政策库",
+      component: () => import('@/views/knowledge_manage/list.vue'),
+      meta:{
+        name_en:""
+      },
+    },
+    {
+      path: "/knowledge_viewpoint",
+      name: "观点库",
+      component: () => import('@/views/knowledge_manage/list.vue'),
+      meta:{
+        name_en:""
+      },
+    },
+    {
+      path: "/knowledge_know",
+      name: "知识库",
+      component: () => import('@/views/knowledge_manage/list.vue'),
+      meta:{
+        name_en:""
+      },
+    },
+    {
+      path: "/knowledgeEdit",
+      name: "编辑",
+      component: () => import('@/views/knowledge_manage/edit.vue'),
+      meta:{
+        name_en:"",
+        pathFrom: "knowledge_event",
+        pathName: "事件库",
+        pathName_en:""
+      },
+    },
+    {
+      path: "/knowledgeDetail",
+      name: "详情",
+      component: () => import('@/views/knowledge_manage/edit.vue'),
+      meta:{
+        name_en:"",
+        pathFrom: "knowledge_event",
+        pathName: "事件库",
+        pathName_en:""
+      },
+    },
+    {
+      path: "/knowledge_tag",
+      name: "标签管理",
+      component: () => import('@/views/knowledge_manage/tagSetting.vue'),
+      meta:{
+        name_en:"",
+        pathFrom: "knowledge_event",
+        pathName: "事件库",
+        pathName_en:""
+      },
+    },
+
+  ]
+}]

+ 2 - 2
src/routes/modules/oldRoutes.js

@@ -138,7 +138,7 @@ export default [
       {
         path: "classifylist",
         component: classifylist,
-        name: "分类列表",
+        name: "分类管理",
         hidden: false,
         meta: {
           keepAlive: false,
@@ -153,7 +153,7 @@ export default [
         meta: {
           name_en:"Chapter Setting",
           pathFrom: "classifylist",
-          pathName: "分类列表",
+          pathName: "分类管理",
           pathName_en:"Category list"
         },
       },

+ 1 - 1
src/routes/modules/semanticsRoutes.js

@@ -90,7 +90,7 @@ export default [{
     },
     {
       path: "aISummeryPage",
-      name: "AI纪要",
+      name: "智能分析",
       component: () => import('@/views/semantics_manage/summery/index.vue'),
       meta:{
         name_en:"AI Summery"

+ 1 - 1
src/styles/element-ui.scss

@@ -16,7 +16,7 @@ $--font-path: '~element-ui/lib/theme-chalk/fonts';
 .color_primary{color:$color-primary};
 .el-submenu.is-opened>ul{ overflow:hidden; }
 .el-submenu.is-opened>ul li{ background:#fff; }
-.el-submenu__title>span{ font:14px "微软雅黑"; letter-spacing:1px; }
+.el-submenu__title>span{ font:15px "微软雅黑"; letter-spacing:1px; }
 .el-submenu__title>i:nth-of-type(1){ color:#1F2E4D; font-size:14px; }
 .el-submenu__title>i:nth-of-type(2){ line-height:16px; z-index:10; right:0; left:100px; }
 .el-submenu.item .el-submenu__title{ text-align:left; }

+ 53 - 1
src/utils/buttonConfig.js

@@ -363,6 +363,14 @@ export const edbDataPermission = {
     edbData_checkRelatedEdb:'edbData:checkRelatedEdb',//查看关联指标
     edbData_checkCalcChart:'edbData:checkCalcChart',//查看计算指标
     edbData_enableOrDisable:'edbData:enableOrDisable',//启用/停用
+
+
+    /* 拆分 数据查看特有权限 */
+    edbData_edbCollect_collect:'edbData:edbCollect:collect',//收藏/移出
+    edbBaseData_view:'edbBaseData:view',//查看`
+    edbData_edbCollectClassify_save:'edbData:edbCollectClassify:save',//收藏分类编辑
+    edbData_edbCollectClassify_remove:'edbData:edbCollectClassify:remove',//收藏分类删除
+    edbData_edbCollectClassify_move:'edbData:edbCollectClassify:move',//收藏分类移动
 }
 /*
  * ---------------------------------------------------------------------------ETA预测指标------------------------------------------------
@@ -814,6 +822,7 @@ export const baseConfigPermission = {
     etaBaseConfig_watermark:'etaBaseConfig:watermark',
     etaBaseConfig_watermark_ybChart:'etaBaseConfig:watermark:ybChart',//如果没权限,表单不显示也不校验
     etaBaseConfig_approve:'etaBaseConfig:approve',//研报审批
+    etaBaseConfig_biApprove:'etaBaseConfig:biApprove',//BI看板审批
     etaBaseConfig_login:'baseSetting:loginSetting',//登录
     etaBaseConfig_watermark_ybShare:'etaBaseConfig:watermark:ybShare',//如果没权限,表单不显示也不校验
     etaBaseConfig_source_see:'baseSetting:sourceSetting:see',//资源库查看
@@ -865,6 +874,41 @@ export const chartThemePermission = {
     chartTheme_chartsource:'chartTheme:chartsource',//图表的数据来源
 }
 
+export const knowledgePermission = {
+    //事件库
+    event_add: 'event:add',//添加
+    event_import: 'event:import',//excel导入
+    event_classifyEdit: 'event:classifyEdit',//分类管理
+    event_tagEdit: 'event:tagEdit',//标签管理
+    event_edit: 'event:edit',
+    event_del: 'event:del',
+
+    //政策库
+    policy_add: 'policy:add',
+    policy_import: 'policy:import',
+    policy_classifyEdit: 'policy:classifyEdit',
+    policy_tagEdit: 'policy:tagEdit',
+    policy_edit: 'policy:edit',
+    policy_del: 'policy:del',
+
+    //观点库
+    viewpoint_add: 'viewpoint:add',
+    viewpoint_import: 'viewpoint:import',
+    viewpoint_classifyEdit: 'viewpoint:classifyEdit',
+    viewpoint_tagEdit: 'viewpoint:tagEdit',
+    viewpoint_edit: 'viewpoint:edit',
+    viewpoint_del: 'viewpoint:del',
+
+    //知识库
+    know_add: 'know:add',
+    know_import: 'know:import',
+    know_classifyEdit: 'know:classifyEdit',
+    know_tagEdit: 'know:tagEdit',
+    know_edit: 'know:edit',
+    know_del: 'know:del',
+}
+
+
 /* BI看板配置 */
 export const BIBoardPermission = {
     BIBoard_add:'BI:addBoard',//添加
@@ -877,6 +921,12 @@ export const BIBoardPermission = {
     BIBoard_sort:'BI:sort',//
 }
 
+/* 首页配置 */
+export const homePagePermission = {
+    home_boarddetail:'home:boardDetail',
+    home_setbiboard:'home:setBiBoard',//
+}
+
 
 //创建了新的ManageBtn记得添加到这里
 const btnMap  = {
@@ -896,7 +946,9 @@ const btnMap  = {
     outlinkConfigPermission,
     chartThemePermission,
     toolBoxPermission,
-    BIBoardPermission
+    knowledgePermission,
+    BIBoardPermission,
+    homePagePermission
 }
 
 /**

+ 10 - 4
src/views/BI_manage/components/BoardContent.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="BI-board-content">
-    <div class="BI-board-list">
+    <div class="BI-board-list" :style="{height:renderHeight}">
       <table-no-data v-if="value.length===0" style="flex:1"/>
       <div
         class="BI-board-item-box"
@@ -33,6 +33,7 @@
 </template>
 
 <script>
+import apiBiBoard from '@/api/modules/BIBoard.js'
 import TableNoData from '../../../components/tableNoData.vue';
 import ChartBox from './ChartBox.vue';
 import TableBox from './TableBox.vue';
@@ -44,13 +45,18 @@ export default {
       type: Array,
       default: () => []
     },
+    boardInfo:{},//看板详情数据
     canDrag: {//能否拖动
       type: Boolean,
-      default: true
+      default: false
     },
     canDelete:{//能否删除
       type: Boolean,
       default: false
+    },
+    renderHeight:{
+      type:String,
+      default:"calc(100vh - 300px)"
     }
   },
   data() {
@@ -73,10 +79,10 @@ export default {
     dragStart(index) {
       this.draggedIndex = index;
     },
-    drop(index) {
+    async drop(index) {
       if (this.draggedIndex === null) return
       // Swap the two items
-      const temp = this.value[this.draggedIndex];
+      const temp=this.value[this.draggedIndex]
       this.$set(this.value, this.draggedIndex, this.value[index]);
       this.$set(this.value, index, temp);
       this.draggedIndex = null;

+ 4 - 3
src/views/BI_manage/components/ChartBox.vue

@@ -1,12 +1,13 @@
 <template>
-  <div class="chart-box" v-if="compData" ref="compRef" v-loading="loading">
+  <div class="chart-box" v-if="compData" ref="compRef" v-loading="loading" element-loading-text="拼命加载中">
     <div class="top-title-box">
-      <div class="title" @click="goDetail">{{ chartInfo.ChartName }}</div>
+      <div class="title" @click="goDetail">{{ chartInfo&&chartInfo.ChartName }}</div>
       <div class="opt-box">
         <img
           class="icon"
           src="~@/assets/img/icons/refresh_blue_new.png"
           alt=""
+          v-permission="permissionBtn.BIBoardPermission.BIBoard_refresh"
           @click="refreshHandle"
         />
         <slot name="drag"></slot>
@@ -120,7 +121,7 @@ export default {
     async handleGetChartData() {
       const res = await dataBaseInterface.getChartByCode({ UniqueCode: this.compData.UniqueCode })
       this.loading = false
-      if (res.Ret !== 200) return;
+      if (res.Ret !== 200||!res.Data.ChartInfo) return;
       this.chartInfo = res.Data.ChartInfo;
 
       this.chartInfo.SeasonExtraConfig && (this.SeasonExtraConfig = JSON.parse(this.chartInfo.SeasonExtraConfig))

+ 52 - 7
src/views/BI_manage/components/CommonClassify.vue

@@ -10,20 +10,22 @@
     append-to-body
   >
     <div class="common-classify-wrap">
-      <el-button type="text" icon="el-icon-plus" @click="showEdit=true">添加分类</el-button>
+      <el-button type="text" icon="el-icon-plus" @click="showEdit=true;editData=null">添加分类</el-button>
+      <table-no-data v-if="list.length===0"/>
       <div class="classify-list-box">
-        <div class="item-box" v-for="item in 10" :key="item">
-          <el-input disabled style="flex:1"></el-input>
-          <img class="icon" src="~@/assets/img/icons/edit-blue.png" alt="">
-          <img class="icon" src="~@/assets/img/icons/delete-red.png" alt="">
+        <div class="item-box" v-for="item in list" :key="item.BiDashboardClassifyId">
+          <el-input disabled style="flex:1" :value="item.BiDashboardClassifyName"></el-input>
+          <img class="icon" src="~@/assets/img/icons/edit-blue.png" alt="" @click="handleShowEdit(item)">
+          <img class="icon" src="~@/assets/img/icons/delete-red.png" alt="" @click="handleDelete(item)">
         </div>
       </div>
     </div>
-    <EditCommonClassify v-model="showEdit"/>
+    <EditCommonClassify v-model="showEdit" :editData="editData" @change="handleEditSuccessBack"/>
   </el-dialog>
 </template>
 
 <script>
+import apiBiBoard from '@/api/modules/BIBoard.js'
 import EditCommonClassify from './EditCommonClassify.vue'
 export default {
   name: "CommonClassify",
@@ -38,20 +40,63 @@ export default {
       default: false
     }
   },
+  watch: {
+    show(n){
+      if(n){
+        this.getList()
+      }
+    }
+  },
   data() {
     return {
-      showEdit:false
+      showEdit:false,
+      editData:null,
+      list:[]
     }
   },
   methods: {
     handleClose() {
       this.$emit('showChange', false)
     },
+
+    handleShowEdit(e){
+      this.editData=e
+      this.showEdit=true
+    },
+
+    async handleDelete(e){
+      const res=await apiBiBoard.deleteCommonClassify({
+        BiDashboardClassifyId:e.BiDashboardClassifyId
+      })
+      if(res.Ret!==200) return
+      this.$message.success('删除成功')
+      this.handleEditSuccessBack()
+    },
+
+    handleEditSuccessBack(){
+      this.$emit('change')
+      this.getList()
+    },
+
+    async getList(){
+      const res=await apiBiBoard.commonClassifyList()
+      if(res.Ret===200){
+        this.list=res.Data||[]
+      }
+    }
   },
 }
 </script>
+<style lang="scss">
+.classify-list-box{
+  .el-input.is-disabled .el-input__inner{
+  color: #333;
+}
+}
 
+</style>
 <style lang="scss" scoped>
+
 .common-classify-wrap{
   .classify-list-box{
     margin: 20px 0;

+ 22 - 5
src/views/BI_manage/components/EditCommonClassify.vue

@@ -40,6 +40,7 @@
 </template>
 
 <script>
+import apiBiBoard from '@/api/modules/BIBoard.js'
 export default {
   name: "EditCommonClassify",
   model: {
@@ -50,6 +51,14 @@ export default {
     show: {
       type: Boolean,
       default: false
+    },
+    editData:null
+  },
+  watch: {
+    show(n){
+      if(n&&this.editData){
+        this.formData.name=this.editData.BiDashboardClassifyName
+      }
     }
   },
   data() {
@@ -64,16 +73,24 @@ export default {
       this.$emit('showChange', false)
     },
     saveHandle() {
-      this.$refs.ruleForm.validate((valid) => {
-        if (valid) {
-
-        }
+      this.$refs.ruleForm.validate(async(valid) => {
+        if (!valid) return
+        const res=this.editData?await apiBiBoard.editCommonClassify({
+          ClassifyName:this.formData.name,
+          BiDashboardClassifyId:this.editData.BiDashboardClassifyId
+        }) :await apiBiBoard.addCommonClassify({
+          ClassifyName:this.formData.name
+        })
+        if(res.Ret!==200) return
+        this.$message.success('保存成功')
+        this.formData.name=''
+        this.$emit('change')
+        this.handleClose()
       })
     }
   },
 }
 </script>
-
 <style lang="scss" scoped>
 .dia-bot {
   display: flex;

+ 90 - 20
src/views/BI_manage/components/SetCommon.vue

@@ -10,32 +10,55 @@
     width="680px"
     @close="handleClose"
   >
-    <div class="BI-share-wrap">
+    <div class="BI-share-wrap" v-if="boardInfo">
       <div class="board-title">
-        <div style="flex:1">看板名称</div>
-        <el-tag size="mini">审批状态</el-tag>
+        <div style="flex: 1">{{boardInfo.BiDashboardName}}</div>
+        <el-tag size="mini" type="warning" v-if="boardInfo.State === 4">待审批</el-tag>
+        <el-tag size="mini" type="danger" v-if="boardInfo.State === 5">已驳回</el-tag>
+        <el-tag size="mini" type="success" v-if="boardInfo.State === 6">已通过</el-tag>
       </div>
-      <el-select placeholder="请选择分类" style="width:100%;margin:20px 0"></el-select>
-      <div class="tips">提示:个人看板设为公共看板,请先选择公共看板分类,提交审批,审批通过后可设置公开!</div>
-      <div class="tips">提示:设置公开看板失败,若要编辑,请先执行撤销操作!<el-button type="text">撤销</el-button></div>
-      <div class="tips">提示:审批通过后,个人看板则设置公开成功!</div>
-      <div class="tips">提示:设置公开看板成功,若要编辑,请先撤销操作(即取消公开)!<el-button type="text">撤销</el-button></div>
-      
+      <el-select
+        v-model="classify"
+        placeholder="请选择分类"
+        style="width: 100%; margin: 20px 0"
+        :disabled="boardInfo.State !== 1"
+      >
+        <el-option v-for="item in list" :key="item.BiDashboardClassifyId" :value="item.BiDashboardClassifyId" :label="item.BiDashboardClassifyName"></el-option>
+      </el-select>
+      <div class="tips" v-if="boardInfo.State === 1">
+        提示:个人看板设为公共看板,请先选择公共看板分类,提交审批,审批通过后可设置公开!
+      </div>
+      <div class="tips" v-if="boardInfo.State === 5">
+        提示:设置公开看板失败,若要编辑,请先执行撤销操作!
+        <el-button type="text" @click="handleBackCommon">撤销</el-button>
+      </div>
+      <div class="tips" v-if="boardInfo.State === 4">
+        提示:审批通过后,个人看板则设置公开成功!
+      </div>
+      <div class="tips" v-if="boardInfo.State === 6">
+        提示:设置公开看板成功,若要编辑,请先撤销操作(即取消公开)!
+        <el-button type="text" @click="handleBackCommon">撤销</el-button>
+      </div>
+
       <div class="dia-bot">
-        <el-button
-          type="primary"
-          plain
-          @click="handleClose"
-          style="margin-right: 20px"
-          >{{ $t("Dialog.cancel_btn") }}</el-button
-        >
-        <el-button type="primary" @click="saveHandle">提交审批</el-button>
+        <template v-if="boardInfo.State === 1">
+          <el-button
+            type="primary"
+            plain
+            @click="handleClose"
+            style="margin-right: 20px"
+            >{{ $t("Dialog.cancel_btn") }}</el-button
+          >
+          <el-button type="primary" @click="saveHandle">提交审批</el-button>
+        </template>
+        <el-button v-else type="primary" @click="handleClose">知道了</el-button>
       </div>
     </div>
   </el-dialog>
 </template>
 
 <script>
+import apiBiBoard from '@/api/modules/BIBoard.js'
 export default {
   name: "setCommon",
   model: {
@@ -46,19 +69,67 @@ export default {
     show: {
       type: Boolean,
       default: false
+    },
+    boardInfo: {},//state 1:未公开; 4-待审批;5-已驳回;6-已通过
+  },
+  watch: {
+    show(n){
+      if(n){
+        this.classify=this.boardInfo.BiDashboardClassifyId||''
+        this.getClassifyList()
+      }
     }
   },
   data() {
     return {
+      list:[],
+      classify:''
     }
   },
   created() {
   },
   methods: {
     handleClose() {
+      this.classify=''
       this.$emit('showChange', false)
     },
-    
+
+    handleBackCommon(){
+      apiBiBoard.cancelBoardCommon({
+        BiDashboardId:this.boardInfo.BiDashboardId,
+      }).then(res=>{
+        if(res.Ret===200){
+          this.$message.success('撤销成功')
+          this.handleClose()
+          this.$emit('change')
+        }
+      })
+    },
+
+    saveHandle(){
+      if(!this.classify){
+        this.$message.warning('请选择分类')
+        return
+      }
+      apiBiBoard.setBoardCommon({
+        BiDashboardId:this.boardInfo.BiDashboardId,
+        ClassifyId:this.classify
+      }).then(res=>{
+        if(res.Ret===200){
+          this.$message.success('提交成功')
+          this.handleClose()
+          this.$emit('change')
+        }
+      })
+    },
+
+    async getClassifyList(){
+      const res=await apiBiBoard.commonClassifyList()
+      if(res.Ret===200){
+        this.list=res.Data||[]
+      }
+    }
+
   },
 }
 </script>
@@ -69,9 +140,8 @@ export default {
   padding: 20px;
   border: 1px dashed #c8cdd9;
 }
-.board-title{
+.board-title {
   display: flex;
-  
 }
 .dia-bot {
   display: flex;

+ 82 - 8
src/views/BI_manage/components/SetShare.vue

@@ -15,10 +15,13 @@
         <span style="color: #0052d9">共享看板</span>
         <el-switch v-model="open"> </el-switch>
         <el-cascader
+          style="width:450px"
+          v-show="open"
           v-model="select_users"
           :options="researcherList"
           :show-all-levels="false"
           filterable
+          collapse-tags
           :props="{
             value: 'ItemId',
             label: 'ItemName',
@@ -29,17 +32,17 @@
           }"
           clearable
           placeholder="选择共享人"
-          :key="cascaderIdx"
-          @remove-tag="removeResearchersChange"
+          ref="selectUserEl"
         />
       </div>
-      <div class="select-user-box">
+      <div class="select-user-box" v-if="open">
         <el-tag
-          v-for="tag in select_users"
-          :key="tag.name"
+          v-for="tag in select_user_names"
+          :key="tag.ItemId"
           closable
+          @close="handleDeleteUser(tag.ItemId)"
         >
-          {{ tag.name }}
+          {{ tag.ItemName }}
         </el-tag>
       </div>
 
@@ -61,6 +64,7 @@
 
 <script>
 import { dataAuthInterface } from '@/api/api.js';
+import apiBiBoard from '@/api/modules/BIBoard.js'
 export default {
   name: "setShare",
   model: {
@@ -71,27 +75,94 @@ export default {
     show: {
       type: Boolean,
       default: false
+    },
+    boardInfo:{}
+  },
+  watch: {
+    select_users(n){
+      if(this.open&&n){
+        this.getSelectUserNames()
+      }
+    },
+    show(n){
+      if(n){
+        this.open=this.boardInfo.IsGrant?true:false
+        this.getSelectUser()
+      }
     }
   },
   data() {
     return {
       open: false,
-      select_users: [],
+      select_users: '',
       researcherList: [],
-      cascaderIdx: 1
+      select_user_names:[],
     }
   },
   created() {
     this.getSystemUserList()
   },
   methods: {
+    async saveHandle(){
+      if(!this.open){
+        const res=await apiBiBoard.cancelBoardShare({
+          BiDashboardId:this.boardInfo.BiDashboardId
+        })
+        if(res.Ret!==200)return
+        this.$message.success('保存成功')
+        this.handleClose()
+        this.$emit('change')
+        return
+      }
+
+      if(!this.select_users){
+        this.$message.warning('请选择共享人')
+        return
+      }
+      const res=await apiBiBoard.setBoardShare({
+        BiDashboardId:this.boardInfo.BiDashboardId,
+        AdminIdStr:this.select_users.join(',')
+      })
+      if(res.Ret===200){
+        this.$message.success('保存成功')
+        this.handleClose()
+        this.$emit('change')
+      }
+    },
+
+    getSelectUserNames(){
+      this.$nextTick(()=>{
+          const data=this.$refs.selectUserEl.getCheckedNodes()
+          this.select_user_names=data.map(item=>{
+            return item.data
+          })
+        })
+    },
+
+    getSelectUser(){
+      apiBiBoard.getBoardShareUsers({
+        BiDashboardId:this.boardInfo.BiDashboardId
+      }).then(res=>{
+        if(res.Ret===200&&res.Data){
+          this.select_users=res.Data.split(',')
+          this.getSelectUserNames()
+        }
+      })
+    },
+
     handleClose() {
+      this.open=false
+      this.select_users=''
+      this.select_user_names=[]
       this.$emit('showChange', false)
     },
     async getSystemUserList() {
       const res = await dataAuthInterface.userSearch();
       if (res.Ret !== 200) return
       this.researcherList = res.Data || []
+    },
+    handleDeleteUser(val){
+      this.select_users = this.select_users.filter(item => item !== val)
     }
   },
 }
@@ -102,6 +173,9 @@ export default {
   margin-top: 20px;
   padding: 20px;
   border: 1px dashed #c8cdd9;
+  display: flex;
+  flex-wrap: wrap;
+  gap: 5px;
 }
 .dia-bot {
   display: flex;

+ 186 - 14
src/views/BI_manage/components/TableBox.vue

@@ -1,22 +1,84 @@
 <template>
-  <div class="table-box" v-if="compData" ref="compRef" v-loading="loading">
+  <div
+    class="table-box"
+    v-if="compData"
+    ref="compRef"
+    v-loading="loading"
+    element-loading-text="拼命加载中"
+  >
     <div class="top-title-box">
-      <div class="title">{{ compData.ExcelName }}</div>
+      <div class="title" @click="goDetail">{{ info&&info.ExcelName }}</div>
       <div class="opt-box">
         <img
           class="icon"
           src="~@/assets/img/icons/refresh_blue_new.png"
           alt=""
+          v-permission="permissionBtn.BIBoardPermission.BIBoard_refresh"
+          @click="handleRefresh"
         />
         <slot name="drag"></slot>
         <slot name="delete"></slot>
       </div>
     </div>
-    <img class="bg" :src="compData.ExcelImage" alt="" />
+    <!-- 无权限 -->
+    <div class="nodata" v-if="!info">
+      <noDataAuth text="暂无数据" />
+    </div>
+    <div class="table-render-wrap" v-else>
+    <div class="table-wrapper pc-sty" >
+      <table
+        cellpadding="0"
+        cellspacing="0"
+        :style="`font-size: ${info.Config.FontSize || 12}px`"
+      >
+        <tbody>
+          <tr v-for="(item, index) in info.TableInfo.TableDataList" :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>
+    </div>
   </div>
 </template>
 
 <script>
+import apiBiBoard from '@/api/modules/BIBoard.js'
+import * as sheetInterface from "@/api/modules/sheetApi.js";
 export default {
   props: {
     compData: null
@@ -24,12 +86,13 @@ export default {
   data() {
     return {
       loading: true,
-      observer:null,
+      observer: null,
       isVisible: false, // 是否可见
+      info:null,
     }
   },
   mounted() {
-    console.log('表格组件挂载', this.compData.ExcelInfoId);
+    console.log('表格组件挂载',);
     this.createObserver();
   },
   beforeUnmount() {
@@ -38,12 +101,41 @@ export default {
     }
   },
   methods: {
+    goDetail() {
+      const pathMap = new Map([
+        [1, '/sheetList'],
+        [2, '/sheetTimeList'],
+        [3, '/sheetMixedList'],
+      ])
+      const href = this.$router.resolve({
+        path: pathMap.get(this.info.Source),
+        query: {
+          code: this.info.UniqueCode,
+          id: this.info.ExcelInfoId
+        }
+      }).href
+      window.open(href, "_blank")
+    },
+
+    handleRefresh: _.debounce(async function () {
+      if(this.loading) return
+      this.loading = true
+      const res = await sheetInterface.refreshCustomSheet({
+        ExcelInfoId: this.info.ExcelInfoId,
+      });
+      this.loading=false
+
+      if (res.Ret !== 200) return;
+      this.$message.success(this.$t('ETable.Msg.refresh_success_msg') );
+      this.handleGetTableData()
+    }, 300),
+
     // 获取表格数据
-    handleGetTableData(){
-      setTimeout(() => {
-        console.log('表格组件加载结束', this.compData.ExcelInfoId);
-        this.loading=false
-      }, 2000);
+    async handleGetTableData() {
+      const res = await apiBiBoard.tableDetail({ UniqueCode: this.compData.UniqueCode })
+      this.loading = false
+      if (res.Ret !== 200) return;
+      this.info=res.Data
     },
 
     // 利用判断是否进入可视区域 来加载数据 
@@ -58,7 +150,7 @@ export default {
       this.observer.observe(this.$refs.compRef); // 监听组件
     },
     handleIntersect(entries) {
-      if(this.isVisible) return 
+      if (this.isVisible) return
       entries.forEach(entry => {
         // 判断是否在可视范围内
         if (entry.isIntersecting) {
@@ -79,6 +171,8 @@ export default {
   height: 100%;
   padding: 20px;
   box-sizing: border-box;
+  display: flex;
+  flex-direction: column;
   .top-title-box {
     display: flex;
     margin-bottom: 10px;
@@ -107,9 +201,87 @@ export default {
       }
     }
   }
-  .bg {
-    width: 100%;
-    height: 200px;
+  ::-webkit-scrollbar {
+  width: 6px;
+  height: 6px;
+}
+::-webkit-scrollbar-track {
+  background: rgb(239, 239, 239);
+  border-radius: 2px;
+}
+::-webkit-scrollbar-thumb {
+  background: #ccc;
+  border-radius: 10px;
+}
+::-webkit-scrollbar-thumb:hover {
+  background: #888;
+}
+::-webkit-scrollbar-corner {
+  background: #666;
+}
+.table-render-wrap{
+  width: 100%;
+  flex: 1;
+  height: 100%;
+  overflow-y: auto;
+}
+.table-wrapper {
+  max-width: calc(100vw - 20px);
+  margin: 0 auto;
+  overflow: auto;
+}
+table {
+  width: 100%;
+  font-size: 14px;
+  color: #333;
+  td,
+  th {
+    // min-width: 120px;
+    word-break: break-all;
+    word-wrap: break-word;
+    line-height: 1.2em;
+    border: 1px solid #dcdfe6;
+    // height: 40px;
+    text-align: center;
+    background-color: #fff;
+    border-left: none;
+    border-top: none;
+    &:first-child {
+			border-left: 1px solid #dcdfe6;
+		}
+  }
+
+  .data-cell{
+    color: #333;
+    &.one-bg {
+      background-color: #EFEEF1;
+    }
+    &.two-bg {
+      background-color: #fff;
+    }
+  }
+
+  .thead-sticky {
+    position: sticky;
+    top: 0;
+  }
+
+  .head-column {
+    background-color: #505B78;
+    color: #fff;
+  }
+  .split-word {
+    span { display: inline; }
   }
 }
+
+.pc-sty table {
+  table-layout: auto;
+  td,th {
+    width: auto;
+    height: auto;
+    padding: 0.4em 0;
+  }
+}
+}
 </style>

+ 3 - 3
src/views/BI_manage/editBoard.vue

@@ -18,7 +18,7 @@
       </div>
     </div>
     <!-- 看板内容模块 -->
-    <BIBoardContent v-model="boardDataList" :canDelete="true" />
+    <BIBoardContent v-model="boardDataList" :canDelete="true" :canDrag="true" />
 
     <!-- 选择图表 -->
     <SelectChart
@@ -114,7 +114,7 @@ export default {
 
     handleAddComp(type, data) {
       const arr = data || []
-      if (this.boardData.length + arr.length > MAX_COUNT) {
+      if (this.boardDataList.length + arr.length > MAX_COUNT) {
         this.$message.warning('添加已达上限(上限50)!')
         return
       }
@@ -124,7 +124,7 @@ export default {
           UniqueCode:item.UniqueCode,
           BiDashboardDetailId:getUniqueId()
         }
-        this.boardData.push(obj)
+        this.boardDataList.push(obj)
       });
 
       this.showSelectChart = false

+ 177 - 32
src/views/BI_manage/index.vue

@@ -43,7 +43,7 @@
         >
       </div>
     </div>
-    <div class="opt-box">
+    <div class="opt-box" >
       <!-- 我的看板  -->
       <el-select
         v-model="selectBoardId"
@@ -63,36 +63,47 @@
         :props="{ emitPath: false }"
         :options="shareBoardList"
         v-if="navType === 2"
+        key="2"
       ></el-cascader>
       <!-- 公共看板 -->
       <el-cascader
         v-model="selectBoardId"
-        :props="{ emitPath: false }"
+        :props="{ emitPath: false,value:'GroupId',label:'GroupName',children:'Children'  }"
         :options="commonBoardList"
         v-if="navType === 3"
+        key="3"
       ></el-cascader>
 
-      <div class="right-opt-box">
+      <div class="right-opt-box" v-if="boardInfo">
         <el-button
           v-if="navType === 1&&permissionBtn.isShowBtn('BIBoardPermission','BIBoard_setcommon')"
           type="text"
           @click="showSetCommon = true"
           >设置公共</el-button
         >
-        <el-button type="text" @click="showSetShare = true">设置共享</el-button>
-        <el-button type="text" @click="handleGoEdit">编辑</el-button>
-        <el-button type="text" style="color: #f00">删除</el-button>
+        <el-button 
+          type="text" 
+          @click="showSetShare = true" 
+          v-if="navType !== 3&&permissionBtn.isShowBtn('BIBoardPermission','BIBoard_setshare')&&currentBoardIsSelf"
+        >设置共享</el-button>
+        <el-button 
+          type="text" 
+          @click="handleGoEdit" 
+          v-if="canEdit"
+        >{{boardInfo.IsEditing?boardInfo.Editor.Editor+'编辑中...':'编辑'}}</el-button>
+        <el-button type="text" style="color: #f00" v-if="canDelete" @click="handleDeleteBoard">删除</el-button>
+        <el-button type="text" v-if="navType === 1&&[4,5,6].includes(boardInfo.State)" @click="handleBackSetCommon">撤销</el-button>
       </div>
     </div>
     <!-- 看板内容模块 -->
-    <BIBoardContent v-model="boardDataList" :canDrag="false" />
+    <BIBoardContent v-model="boardDataList" :boardInfo="boardInfo"/>
 
     <!-- 设置共享 -->
-    <set-share v-model="showSetShare" />
+    <set-share v-model="showSetShare" :boardInfo="boardInfo" @change="handleSetShareBack"/>
     <!-- 设置公共 -->
-    <SetCommon v-model="showSetCommon" />
+    <SetCommon v-model="showSetCommon" :boardInfo="boardInfo" @change="handleSetCommonBack"/>
     <!-- 公共看板分类 -->
-    <CommonClassify v-model="showCommonClassify" />
+    <CommonClassify v-model="showCommonClassify" @change="getCommonBoardList('update')"/>
   </div>
 </template>
 
@@ -105,6 +116,21 @@ import SetShare from './components/SetShare.vue'
 
 export default {
   components: { BIBoardContent, SetShare, SetCommon, CommonClassify },
+  computed: {
+    currentBoardIsSelf(){//判断当前看板是否为当前用户创建的
+      if(!this.boardInfo) return false
+      const localAdminId=localStorage.getItem('AdminId')
+      return localAdminId==this.boardInfo.SysAdminId
+    },
+    canEdit(){
+      if(!this.boardInfo) return false
+      return this.navType !== 3&&this.permissionBtn.isShowBtn('BIBoardPermission','BIBoard_edit')&&this.boardInfo.State===1
+    },
+    canDelete(){
+      if(!this.boardInfo) return false
+      return this.navType !== 3&&this.permissionBtn.isShowBtn('BIBoardPermission','BIBoard_delete')&&this.currentBoardIsSelf&&this.boardInfo.State===1
+    }
+  },
   data() {
     return {
       navType: 1,// 
@@ -112,7 +138,7 @@ export default {
       boardInfo: null,//看板详情数据
       boardDataList: [],//看板数据
 
-      selectBoardId: 0,//当前选择的看板id
+      selectBoardId: '',//当前选择的看板id
       myBoardList: [],
       shareBoardList: [],
       commonBoardList: [],
@@ -128,10 +154,53 @@ export default {
     }
   },
   created() {
-    this.getMyBoardList()
+    if(this.$route.query.id){
+      
+      this.selectBoardId=Number(this.$route.query.id)
+      this.navType=Number(this.$route.query.type)
+      if(this.$route.query.type==1){
+        this.getMyBoardList('init')
+      }else if(this.$route.query.type==2){
+        this.getShareBoardList('init')
+      }else if(this.$route.query.type==3){
+        this.getCommonBoardList('init')
+      }
+
+    }else{
+      this.getMyBoardList()
+    }
+    
   },
   methods: {
-    handleGoEdit() {
+    // 撤回设置公共
+    handleBackSetCommon(){
+      apiBiBoard.cancelBoardCommon({
+        BiDashboardId:this.boardInfo.BiDashboardId,
+      }).then(res=>{
+        if(res.Ret===200){
+          this.$message.success('撤销成功')
+          this.getBoardDetail()
+        }
+      })
+    },
+
+    async handleGoEdit() {
+      if(this.boardInfo.IsEditing&&this.boardInfo.Editor.AdminId!==Number(localStorage.getItem('AdminId'))){
+        this.$message.warning(`${this.boardInfo.Editor.Editor}${this.$t('Slides.editing_progress_msg') }...`)
+        return
+      }
+      const res=await apiBiBoard.editBoardLock({BiDashboardId:this.selectBoardId,Status:0})
+      if(res.Ret!==200) return
+      if(res.Data&&res.Data.IsEditing&&res.Data.AdminId!==Number(localStorage.getItem('AdminId'))){
+        this.boardInfo.Editor=res.Data
+        this.boardInfo.IsEditing=true
+        this.$message.warning(`${res.Data.Editor}${this.$t('Slides.editing_progress_msg') }...`)
+        return
+      }
+      //调接口加锁然后跳转
+      const resLock = await apiBiBoard.editBoardLock({BiDashboardId:this.selectBoardId,Status:1})
+      if(resLock.Ret!==200) return
+
       this.$router.push({
         path: "/editBIBoard",
         query: {
@@ -140,21 +209,65 @@ export default {
       })
     },
 
+    // 删除看板
+    async handleDeleteBoard(){
+      await this.$confirm('删除后不可恢复,是否确认删除?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+      const res=await apiBiBoard.deleteBoard({
+        BiDashboardId:this.boardInfo.BiDashboardId
+      })
+      if(res.Ret!==200) return
+      this.$message.success('删除成功')
+      this.selectBoardId =''
+      this.boardDataList = []
+      this.boardInfo = null
+      if (this.navType === 1) {
+        this.getMyBoardList()
+        return
+      }
+      if (this.navType === 2) {
+        this.getShareBoardList()
+        return
+      }
+    },
+
     // 获取看板详情
     async getBoardDetail() {
       const res = await apiBiBoard.boardDetail({ DashboardId: this.selectBoardId })
       if (res.Ret === 200) {
         this.boardInfo = res.Data
         this.boardDataList = res.Data.List || []
-        console.log(this.permissionBtn);
       }
     },
 
+    // 设置公共回调
+    handleSetCommonBack(){
+      this.getBoardDetail()
+    },
+
+    // 设置共享回调
+    handleSetShareBack(){
+      if(this.navType===1){
+        this.getBoardDetail()
+        return
+      }
+      if(this.navType===2){
+        this.getShareBoardList()
+        return
+      }
+      
+    },
+
     // 我的看板列表
-    async getMyBoardList() {
+    async getMyBoardList(type) {
       const res = await apiBiBoard.myBoardList()
       if (res.Ret === 200) {
         this.myBoardList = res.Data || []
+        // 编辑了分类回调 不更新选择的看板仅仅更新公共看板列表数据
+        if(['update','init'].includes(type)) return
         if (this.myBoardList.length > 0) {
           this.selectBoardId = this.myBoardList[0].BiDashboardId
         }
@@ -162,17 +275,18 @@ export default {
     },
 
     // 共享看板列表
-    async getShareBoardList() {
+    async getShareBoardList(type) {
       const res = await apiBiBoard.shareBoardList()
       if (res.Ret === 200) {
         const myArr = res.Data.MyList || []
         const otherArr = res.Data.OtherList || []
-        const temarr = [...myArr, ...otherArr]
+        const boardIds = []
         this.shareBoardList = [
           {
             label: '我共享的',
             value: 'my_share',
             children: myArr.map(item => {
+              boardIds.push(item.BiDashboardId)
               return {
                 label: item.BiDashboardName,
                 value: item.BiDashboardId
@@ -180,30 +294,62 @@ export default {
             })
           },
           {
-            label: '共享给我的',
+            label: '收到共享',
             value: 'other_share',
             children: otherArr.map(item => {
+              const cArr=item.DashboardList.map(_i=>{
+                boardIds.push(_i.BiDashboardId)
+                return{
+                  label: _i.BiDashboardName,
+                  value: _i.BiDashboardId,
+                }
+              })
               return {
-                label: item.BiDashboardName,
-                value: item.BiDashboardId
+                label: item.GroupName,
+                value: item.GroupId,
+                children:cArr
               }
             })
           }
         ]
-
-        if (temarr.length > 0) {
-          this.selectBoardId = temarr[0].BiDashboardId
+        // 编辑了分类回调 不更新选择的看板仅仅更新公共看板列表数据
+        if(['update','init'].includes(type)) return
+        if (boardIds.length > 0) {
+          this.selectBoardId = boardIds[0]
         }
       }
     },
 
     // 公共看板列表
-    async getCommonBoardList() {
+    async getCommonBoardList(type) {
       const res = await apiBiBoard.commonBoardList()
       if (res.Ret === 200) {
-        this.commonBoardList = res.Data || []
-        if (this.commonBoardList.length > 0) {
-          this.selectBoardId = this.commonBoardList[0].BiDashboardId
+        const arr = res.Data || []
+        let boardIdArr=[]
+
+        arr.forEach(item1 => {
+          item1.GroupId=item1.GroupId+item1.GroupName
+          if(item1.Children){
+            item1.Children.forEach(item2=>{
+              const dArr=item2.DashboardList||[]
+              item2.GroupId=item2.GroupId+item2.GroupName
+              item2.Children=dArr.map(item3=>{
+                boardIdArr.push(item3.BiDashboardId)
+                return {
+                  GroupId:item3.BiDashboardId,
+                  GroupName:item3.BiDashboardName
+                }
+              })
+            })
+          }
+        });
+
+        this.commonBoardList=arr
+        // 编辑了分类回调 不更新选择的看板仅仅更新公共看板列表数据
+        if(['update','init'].includes(type)) return
+        // 选择第一个看板
+        if(boardIdArr.length>0){
+          this.selectBoardId = boardIdArr[0]
         }
       }
     },
@@ -212,9 +358,9 @@ export default {
       if (this.navType === e) return
       this.navType = e
 
-      this.selectBoardId = 0
+      this.selectBoardId = ''
       this.boardDataList = []
-      this.boardDetail = null
+      this.boardInfo = null
       if (this.navType === 1) {
         this.getMyBoardList()
         return
@@ -254,7 +400,7 @@ export default {
       position: absolute;
       right: 20px;
       top: 14px;
-      border-left: 1px solid $border-color;
+      /*border-left: 1px solid $border-color;*/
       padding-left: 10px;
     }
   }
@@ -266,5 +412,4 @@ export default {
     }
   }
 }
-</style>
-<!-- 1+3+1+1+2+3+2=13 (后台) -->
+</style>

+ 10 - 1
src/views/Home.vue

@@ -42,7 +42,7 @@
                         ? $setting.theme_color
                         : '#666'
                     }`"
-                    @click="(e) => e.preventDefault()"
+                    @click="handleClickSubMenuItem(item, $event)"
                   >
                     <img
                       :src="getMenuIcon(item)"
@@ -284,6 +284,10 @@
           </div>
 
           <div class="right_section">
+            <div style="display:flex;align-items:center;gap:0 5px" @click="handleGoSJJD">
+              <img style="width:24px" src="~@/assets/img/icons/home_sjjd.png" alt="">
+              <span>数据节点</span>
+            </div>
             <div class="userinfo">
               <div class="userinfo-fingerpost">
                 <!-- <el-button
@@ -625,6 +629,11 @@ export default {
       ])
       return iconMap.get(item.name) || require('@/assets/icons/menu/icon01.png')
     },
+    
+    // 跳转数据节点
+    handleGoSJJD(){
+      window.open('https://www.baidu.com', '_blank')
+    },
 
     handleClickSubMenuItem(item, e) {
       e.preventDefault();

+ 81 - 32
src/views/approve_manage/approveDetail.vue

@@ -1,13 +1,13 @@
 <template>
     <!-- 审批详情:查看、进行审批操作 -->
-    <div class="approve-detail-wrap" v-if="isETAApprove">
+    <div class="approve-detail-wrap" v-if="isETAApprove || IsBIApprove">
         <div class="approve-detail">
             <div class="approve-info">
-                <span>{{$t('AprrovalDetailPage.report_name_info')}}:{{reportInfo.title||''}}</span>
-                <span>{{$t('AprrovalDetailPage.classification_info')}}:{{reportInfo.classify||''}}</span>
-                <span style="min-width: 100px;">{{$t('AprrovalDetailPage.initiator_info')}}:{{reportInfo.approver||''}}</span>
+                <span>{{ mainType == 'report'?$t('AprrovalDetailPage.report_name_info'):$t('AprrovalPage.kanban_name')}}:{{reportInfo.title||''}}</span>
+                <span v-if="mainType == 'report'" style="margin-left: 60px;">{{$t('AprrovalDetailPage.classification_info')}}:{{reportInfo.classify||''}}</span>
+                <span style="min-width: 100px;margin-left: 60px;">{{$t('AprrovalPage.submitter_lable')}}:{{reportInfo.approver||''}}</span>
             </div>
-            <div class="approve-content" 
+            <div v-if="mainType == 'report'" class="approve-content" 
                 v-loading="isLoading"
                 element-loading-text="研报加载中...">
                 <component v-if="reportInfo.reportId&&!isError"
@@ -21,6 +21,11 @@
                 ></component>
                 <tableNoData v-if="isError" text="无法获取到报告内容,该报告可能已被删除!"></tableNoData>
             </div>
+            <div v-else class="approve-content" 
+                v-loading="isLoading"
+                element-loading-text="看板加载中...">
+                <BIBoardContent :value="boardDataList" renderHeight="calc(100vh - 250px)" />
+            </div>
         </div>
         <div class="approve-tool">
             <div class="tool-btn">
@@ -31,7 +36,7 @@
                     v-if="formType==='approve'&&approveInfo.isCurrentApprover&&permissionBtn.isShowBtn('approvePermission','reportApprove_agree')">{{$t('AprrovalDetailPage.agree_btn')}}</el-button>
                 <el-button type="primary" @click="changeApprove('return')"
                     v-if="formType==='myself'&&approveInfo.state!==4&&permissionBtn.isShowBtn('approvePermission','reportApprove_repeal')">{{$t('AprrovalDetailPage.cancel_btn')}}</el-button>
-                <el-button type="primary" plain @click="$router.replace(`/approveList?formType=${formType}`)">{{$t('AprrovalDetailPage.back_btn')}}</el-button>
+                <el-button type="primary" plain @click="$router.replace(`/approveList?formType=${formType}&mainType=${mainType}`)">{{$t('AprrovalDetailPage.back_btn')}}</el-button>
             </div>
             <div class="approve-timeline-wrap">
                 <p>{{$t('AprrovalDetailPage.approval_process')}}</p>
@@ -65,12 +70,13 @@ import RejectDialog from './components/rejectDialog.vue';
 import {approveInterence} from '@/api/modules/approve.js';
 import {departInterence} from '@/api/api.js'
 import reportApproveConfig from "@/mixins/reportApproveConfig.js"
+import apiBiBoard from '@/api/modules/BIBoard.js'
+import BIBoardContent from '@/views/BI_manage/components/BoardContent.vue';
 
 const ApproveType = ['','依次审批','会签','或签']
 const ApproveState = ['','待审批','已同意','已驳回']
 export default {
     mixins:[reportApproveConfig],
-    components: { RejectDialog },
     data() {
         return {
             isError:false,
@@ -78,6 +84,7 @@ export default {
             isDetailDialogShow:false,
             TimeLineData:[],
             formType:'detail',//进入审批详情的方式:approve(待处理)/detail(已处理)/myself(我发起的)
+            mainType:'report', //report(研报) bi(bi看板)
             reportInfo:{ //报告相关信息
                 reportId:0,//研报or智能研报的报告id
                 title:'',
@@ -92,12 +99,13 @@ export default {
                 isCurrentApprover:false,//审批进行中的节点审批人是否是当前用户,控制通过&驳回按钮显示
             },
             waterMarkStr:'',//水印
+            boardDataList:[],
         };
     },
     computed:{
         UserId(){
             return Number(localStorage.getItem("AdminId"));
-        }
+        },
     },
     methods: {
         getApproveDetail(){
@@ -124,12 +132,42 @@ export default {
                 this.approveInfo.stateText=['','pending','passed','reject','return'][Approve.State]
             })
         },
+        getBiApproveDetail(){ 
+            const {type,approveId} = this.$route.query
+            if(!approveId) return 
+            approveInterence.getBiApproveDetail({
+                BiApproveId:+approveId
+            }).then(res=>{
+                if(res.Ret!==200) return
+                //格式化时间线数据 
+                this.formatTimeLineData(res.Data) 
+                const {Bi={},Approve={}} = res.Data||{}
+                this.reportInfo = {
+                    BiId:Bi.BiId||0,
+                    title:Bi.BiTitle||'',
+                    classify:Bi.BiClassify||'',
+                    approver:Approve.ApplyUserName||'',
+                }
+                this.formType = type||'detail'
+                this.approveInfo.state=Approve.State
+                this.approveInfo.stateText=['','pending','passed','reject','return'][Approve.State]
+                this.getBoardDetail();
+            })
+        },
+        async getBoardDetail() {
+            this.isLoading = true;
+            const res = await apiBiBoard.boardDetail({ DashboardId: +this.reportInfo.BiId })
+            this.isLoading = false;
+            if (res.Ret === 200) {
+                this.boardDataList = res.Data.List || []
+            }
+        },
         //转换接口数据
         formatTimeLineData({Approve={},ApproveFlowNodes=[]}){
             //发起人节点
             const startNode = {
                 nodeType:1,
-                nodeText:`${this.$t('AprrovalDetailPage.initiator_info')}:`,
+                nodeText:`${this.$t('AprrovalPage.submitter_lable')}:`,
                 nodeStatus:'passed',
                 approveList:[{
                     approverName:Approve.ApplyUserName||'',
@@ -140,7 +178,7 @@ export default {
             let currentIndex = 0
             let Nodes = ApproveFlowNodes.map((i,index)=>{
                 //找到当前节点的index
-                if(i.ReportApproveNodeId===Approve.CurrNodeId){
+                if((i.ReportApproveNodeId===Approve.CurrNodeId && this.mainType == 'report') || (i.BiApproveNodeId===Approve.CurrNodeId && this.mainType == 'bi')){
                     currentIndex = index
                 }
                 //审批节点只有一个人时不显示是什么审批流
@@ -148,7 +186,7 @@ export default {
                 const node = {
                     nodeType:2,
                     nodeText:`${this.$t('AprrovalDetailPage.approval_by',{num:i.Users.length}) }`+(i.Users.length>1?strApproveType:''),
-                    nodeStatus:i.ReportApproveNodeId===Approve.CurrNodeId?'process':'future',
+                    nodeStatus:(i.ReportApproveNodeId===Approve.CurrNodeId && this.mainType == 'report') || (i.BiApproveNodeId===Approve.CurrNodeId && this.mainType == 'bi')?'process':'future',
                     approveType:ApproveType[i.ApproveType]
                 }
                 const approveList = i.Users.map(u=>{
@@ -161,7 +199,7 @@ export default {
                     }
                 })
                 //检测当前节点的User与当前用户是否匹配 且审批需要是待审批状态
-                if(i.ReportApproveNodeId===Approve.CurrNodeId&&Approve.State===1){
+                if((i.ReportApproveNodeId===Approve.CurrNodeId&&Approve.State===1&&this.mainType == 'report') || (i.BiApproveNodeId===Approve.CurrNodeId&&this.mainType=='bi'&&Approve.State===1)){
                     //当前节点的User中,有没有当前用户
                     const hasUser = i.Users.findIndex(u=>u.UserId===this.UserId)
                     if(hasUser!==-1){
@@ -229,7 +267,7 @@ export default {
                 //在最后加上撤销节点
                 Nodes.push({
                     nodeType:3,
-                    nodeText:`${this.$t('AprrovalDetailPage.initiator_info')}:`,
+                    nodeText:`${this.$t('AprrovalPage.submitter_lable')}:`,
                     nodeStatus:'return',
                     approveList:[{
                         approverName:(Approve.ApplyUserName||'')+'(已撤销)',
@@ -266,20 +304,22 @@ export default {
                 return 
             }
             let res = null
-            if(type==='return'){
-                res = await approveInterence.cancelApprove({
-                    ReportApproveId:Number(approveId)
-                })
+            if(type==='return'){ 
+                res = this.mainType == 'report' ?  await approveInterence.cancelApprove({ReportApproveId:Number(approveId)})
+                                                :  await approveInterence.cancelBiApprove({BiApproveId:Number(approveId)});
             }
-            if(type==='pass'){
-                res = await approveInterence.passApprove({
-                    ReportApproveId:Number(approveId),
-                    ReportUrl:this.generatePdfLinks(this.reportInfo.reportCode,this.reportInfo.type)
-                })
+            if(type==='pass'){ 
+                res = this.mainType == 'report' ?  await approveInterence.passApprove({
+                                                    ReportApproveId:Number(approveId),
+                                                    ReportUrl:this.generatePdfLinks(this.reportInfo.reportCode,this.reportInfo.type)
+                                                })
+                                                :   await approveInterence.passBiApprove({
+                                                    BiApproveId:Number(approveId),
+                                                })
             }
             if(res.Ret!==200) return 
             this.$message.success( type==='return'?this.$t('AprrovalPage.revoke_success') :this.$t('AprrovalDetailPage.passed_success'));
-            type!=='reject'&&(this.$router.replace("/approveList"))
+            type!=='reject'&&(this.$router.replace(`/approveList?mainType=${this.mainType}`))
         },
         generatePdfLinks(code,type){
             if(type == 1){
@@ -295,14 +335,20 @@ export default {
         },
         rejectApprove(reason){
             this.isDetailDialogShow = false
-            approveInterence.rejectApprove({
-                ReportApproveId:Number(this.$route.query.approveId),
-                ApproveRemark:reason||''
-            }).then(res=>{
+            let req = this.mainType == 'report' ? approveInterence.rejectApprove({
+                                                    ReportApproveId:Number(this.$route.query.approveId),
+                                                    ApproveRemark:reason||''
+                                                })
+                                                : approveInterence.rejectBiApprove({
+                                                    BiApproveId:Number(this.$route.query.approveId),
+                                                    ApproveRemark:reason||''
+                                                });
+            req.then(res=>{
                 if(res.Ret!==200) return 
                 this.$message.success(this.$t('AprrovalDetailPage.rejected_success') )
-                this.$router.replace("/approveList")
+                this.$router.replace(`/approveList?mainType=${this.mainType}`)
             })
+            
         },
         getSystemUserInfo(){
             departInterence.systemUserInfo().then(res=>{
@@ -320,10 +366,14 @@ export default {
         },
     },
     mounted(){
-        this.getApproveDetail()
-        this.getSystemUserInfo()
+        this.mainType = this.$route.query.mainType || 'report';
+        if(this.mainType == 'report') {
+          this.getApproveDetail();
+          this.getSystemUserInfo();
+        }
+        if(this.mainType == 'bi') this.getBiApproveDetail();
     },
-    components: { TimeLine, ReportDetail, Reportdtl, RejectDialog }
+    components: { TimeLine, ReportDetail, Reportdtl, RejectDialog, BIBoardContent }
 };
 </script>
 
@@ -401,7 +451,6 @@ export default {
         flex-direction: column;
         .approve-info{
             display: flex;
-            gap:60px;
             padding:15px 20px;
             border-bottom: 1px solid #C8CDD9;
         }

+ 57 - 20
src/views/approve_manage/approveEdit.vue

@@ -1,23 +1,23 @@
 <template>
     <!-- 添加编辑审批流 -->
-    <div class="approve-edit-wrap approve-page-wrap" v-if="isETAApprove">
+    <div class="approve-edit-wrap approve-page-wrap" v-if="isETAApprove || IsBIApprove">
         <div class="head-box">
             <el-form :inline="true" :model="approveForm" ref="approve-form" :rules="formRules"
                 label-width="180px" label-position="left">
                 <el-form-item :label="$t('SystemManage.ReportApprove.table_col01')" prop="name">
                     <el-input v-model="approveForm.name" :placeholder="$t('ApprovalEdit.name_placeholder')"></el-input>
                 </el-form-item>
-                <el-form-item :label="$t('SystemManage.ReportApprove.table_col02')" prop="classify">
+                <el-form-item :label="mainType == 'report' ?$t('SystemManage.ReportApprove.table_col02') : $t('AprrovalPage.association_kanban')" prop="classify">
                     <el-cascader v-model="approveForm.classify"
-                        :placeholder="$t('ApprovalEdit.report_placeholder')" clearable
+                        :placeholder="mainType == 'report' ? $t('ApprovalEdit.report_placeholder') : $t('AprrovalPage.select_associated_Kanban_tip')" clearable
                         :disabled="this.$route.query.flowId"
-                        :options="classifyTree"
-                        :props="{value:'ClassifyId',label:'ClassifyName',children:'Children'}"
+                        :options="mainType == 'report' ? classifyTree : biClassifyTree"
+                        :props="mainType == 'report' ? {value:'ClassifyId',label:'ClassifyName',children:'Children'} : {value:'BiDashboardClassifyId',label:'BiDashboardClassifyName',children:'Children'}"
                         style="margin-right: auto;margin-left: 15px;"></el-cascader>
                 </el-form-item>
             </el-form>
             <div class="form-btn">
-                <el-button type="primary" plain @click="$router.back()">{{$t('Dialog.cancel_btn')}}</el-button>
+                <el-button type="primary" plain @click="routerBack">{{$t('Dialog.cancel_btn')}}</el-button>
                 <el-button v-permission="permissionBtn.approveFlowPermission.reportApprove_save"
                     type="primary" @click="checkFlow">{{$t('Dialog.confirm_save_btn')}}</el-button>
             </div>
@@ -66,6 +66,7 @@ export default {
                 classify:'',
                 /* flowNodes:null */
             },
+            mainType:'report',
         };
     },
     computed:{
@@ -111,31 +112,48 @@ export default {
             }
             this.modifyFlow(Nodes)
         },
-        async modifyFlow(Nodes){
+        async modifyFlow(Nodes){ 
             const {name,classify} = this.approveForm
-            const params = {
+            const id = this.$route.query.flowId||0;
+
+            const params = this.mainType == 'report' ? {
                 FlowName:name,
                 ReportType:classify[0],
                 ClassifyFirstId:classify[1]||0,
                 ClassifySecondId:classify[2]||0,
                 ClassifyThirdId:classify[3]||0,
                 Nodes
-            }
+            } : {
+                BiApproveFlowId:+id,
+                FlowName:name,
+                ClassifyId:classify[0],
+                Nodes
+            };
             let res
-            const id = this.$route.query.flowId||0
             if(id){
-                res = await approveInterence.editApproveFlow({
-                    ...params,
-                    ReportApproveFlowId:Number(id)
-                })
+                res = this.mainType == 'report' ? await approveInterence.editApproveFlow({...params,ReportApproveFlowId:Number(id)})
+                                                : await approveInterence.editBiApproveFlow(params);
             }else{
-                res = await approveInterence.addNewApproveFlow(params)
+                res = this.mainType == 'report' ? await approveInterence.addNewApproveFlow(params) : await approveInterence.addNewBiApproveFlow(params) ;
             }
             if(res.Ret!==200) return
             this.$message.success(/* `${id?'编辑':'新增'}成功` */ id?this.$t('ApprovalEdit.edit_success_text'):this.$t('ApprovalEdit.add_success_text'))
-            this.$router.push('/approveSetting')
+            this.$router.push({
+                path:'/approveSetting',
+                query:{
+                    mainType: this.mainType || ''
+                }
+            })
         },
-        getFlowDetail(){
+        routerBack(){
+            this.$router.replace({
+                path:'/approveSetting',
+                query:{
+                    mainType: this.mainType || ''
+                }
+            })
+        },
+        getReportFlowDetail(){
             const id = this.$route.query.flowId||0
             if(id){
                 approveInterence.getApproveFlowDetail({
@@ -157,10 +175,29 @@ export default {
                     this.approveForm.flowNodes = Nodes||[]
                 })
             }
-        }
+        },
+        getBiFlowDetail(){
+            const id = this.$route.query.flowId||0;
+            approveInterence.getBiApproveFlowDetail({
+                BiApproveFlowId:Number(id)
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                const {FlowName,Nodes,ClassifyId} = res.Data||{};
+                this.approveForm.name = FlowName||'';
+                this.approveForm.classify = [ClassifyId];
+                this.approveForm.flowNodes = Nodes||[];
+            })
+        },
+        afterGetBaseConfig(){ //渲染之后执行否则组件会监听不到
+            if(this.$route.query.flowId){
+                this.$route.query.mainType == 'report' ? this.getReportFlowDetail() : this.getBiFlowDetail();
+            }
+        },
+
     },
-    async mounted(){
-        this.getClassifyTree()
+    created(){
+        this.mainType = this.$route.query.mainType;
+        this.$route.query.mainType == 'report' ? this.getClassifyTree() : this.getBIClassifyTree() ;
     },
     components: { FlowEdiotr }
 };

+ 145 - 41
src/views/approve_manage/approveList.vue

@@ -1,6 +1,11 @@
 <template>
     <!-- 审批管理列表页 -->
-    <div class="approve-list-wrap approve-page-wrap" v-if="isETAApprove">
+    <div class="approve-list-wrap approve-page-wrap" v-if="isETAApprove || IsBIApprove">
+        <div class="head-tab">
+            <el-radio-group v-model="activeMainTab" style="margin-bottom: 10px;" @input="handleMainClick">
+                <el-radio-button v-for="item in mainTabs" :key="item.name" :label="item.name">{{ item.label }}</el-radio-button>
+            </el-radio-group>
+        </div>
         <div class="head-tab">
             <el-tabs v-model="activeTab" @tab-click="handleClick">
                 <el-tab-pane :label="$t('AprrovalPage.be_processed_tab')" name="pending"></el-tab-pane>
@@ -11,9 +16,9 @@
         <div class="approve-list">
             <div class="select-box">
                 <el-cascader v-model="classify"
-                    :placeholder="$t('AprrovalPage.associated_report_ipt')" clearable
-                    :options="classifyTree"
-                    :props="{value:'ClassifyId',label:'ClassifyName',children:'Children'}"
+                    :placeholder="activeMainTab == 'report' ? $t('AprrovalPage.associated_report_ipt') : $t('AprrovalPage.select_associated_Kanban_tip')" clearable
+                    :options="activeMainTab == 'report' ? classifyTree : biClassifyTree"
+                    :props="activeMainTab == 'report' ? {value:'ClassifyId',label:'ClassifyName',children:'Children'} : {value:'BiDashboardClassifyId',label:'BiDashboardClassifyName',children:'Children'}"
                     @change="handleCurrentChange(1)">
                 </el-cascader>
                 <div class="select-time-box">
@@ -51,7 +56,7 @@
                 </el-select>
 
                 <el-input v-model="keyword" prefix-icon="el-icon-search" clearable @input="handleCurrentChange(1)"
-                    :placeholder="$t('AprrovalPage.report_title_ipt')" style="width:260px;margin-left: auto;"></el-input>
+                    :placeholder="activeMainTab == 'report'?$t('AprrovalPage.report_title_ipt'):$t('AprrovalPage.enter_Kanban_name_tip')" style="width:260px;margin-left: auto;"></el-input>
             </div>
             <div class="list-box">
                 <el-table 
@@ -80,7 +85,7 @@
                     <el-table-column :label="$t('Table.column_operations')" align="center">
                         <template slot-scope="{row}">
                             <template v-if="activeTab==='pending'">
-                                <el-button type="text" style="padding:0;" @click="toApproveDetail(row,'approve')"
+                                <el-button type="text" style="padding:0;" @click="toApproveDetail(row,'approve')"    
                                     v-if="permissionBtn.isShowBtn('approvePermission','reportApprove_approve')">{{$t('AprrovalPage.approve_table')}}</el-button>
                             </template>
                             <template v-if="activeTab==='processed'">
@@ -136,11 +141,18 @@ import {
         approve_pending_columns,
         approve_processed_columns,
         approve_originate_columns,
+        biapprove_pending_columns,
+        biapprove_processed_columns,
+        biapprove_originate_columns,
+
     } from './config/tableConfig'
 const columnsMap = {
-    'pending':approve_pending_columns,
-    'processed':approve_processed_columns,
-    'originate':approve_originate_columns
+    'pending_report':approve_pending_columns,
+    'processed_report':approve_processed_columns,
+    'originate_report':approve_originate_columns,
+    'pending_bi':biapprove_pending_columns,
+    'processed_bi':biapprove_processed_columns,
+    'originate_bi':biapprove_originate_columns,
 }
 const tabMap = {
     'pending':1,
@@ -151,6 +163,8 @@ export default {
     mixins:[approveMixins,reportApproveConfig],
     data() {
         return {
+            mainTabs:[],
+            activeMainTab:'',
             activeTab: 'pending',
             /* 筛选项 */
             timeType:1,
@@ -170,10 +184,32 @@ export default {
             total: 0,
 
             currentData: {},
-            isDetailDialogShow: false
+            isDetailDialogShow: false,
         };
     },
     methods: {
+        handleReportClassifyId(){
+            const ids = {
+                ClassifyFirstId:0,
+                ClassifySecondId:0,
+                ClassifyThirdld:0,
+            }
+            if(this.classify.length === 2){
+                ids.ClassifyFirstId = this.classify[this.classify.length-1]||0;
+                ids.ClassifySecondId = 0;
+                ids.ClassifyThirdld = 0;
+            } else if(this.classify.length === 3){
+                ids.ClassifyFirstId = this.classify[this.classify.length-2]||0
+                ids.ClassifySecondId = this.classify[this.classify.length-1]||0
+                ids.ClassifyThirdld = 0;
+            } else {  //分类最多只有三级
+                ids.ClassifyFirstId = this.classify.length > 1 ? this.classify[this.classify.length-3]||0 : 0;
+                ids.ClassifySecondId = this.classify.length > 1 ? this.classify[this.classify.length-2]||0 : 0;
+                ids.ClassifyThirdld = this.classify.length > 1 ? this.classify[this.classify.length-1]||0 : 0;
+            }
+
+            return ids
+        },
         getTableData(){
             this.tableLoading = true
             this.tableData=[]
@@ -186,8 +222,9 @@ export default {
             const selectParams = {
                 //关联报告
                 ReportType:this.classify[0]||0,
-                ClassifyFirstId:this.classify[this.classify.length-2]||0,
-                ClassifySecondId:this.classify[this.classify.length-1]||0,
+                ClassifyFirstId:this.handleReportClassifyId().ClassifyFirstId||0,
+                ClassifySecondId:this.handleReportClassifyId().ClassifySecondId||0,
+                ClassifyThirdld:this.handleReportClassifyId().ClassifyThirdld||0,
                 //时间
                 TimeType:this.timeType,
                 StartTime:this.timeDate?this.timeDate[0]||'':'',
@@ -198,53 +235,93 @@ export default {
                 //处理状态
                 ApproveState:this.ApproveState,
             }
-            approveInterence.getApproveList({
-                ...baseParams,
-                ...selectParams
-            }).then(res=>{
-                this.tableLoading=false
-                if(res.Ret!==200) return 
-                const {List=[],Paging={}} = res.Data||{}
-                this.tableData = List||[]
-                this.total = Paging.Totals||0
-            })
+            const biApproveParams = {
+                ClassifyId:this.classify[0] || 0,
+                TimeType:this.timeType,
+                StartTime:this.timeDate?this.timeDate[0]||'':'',
+                EndTime:this.timeDate?this.timeDate[1]||'':'',
+                SortRule:this.SortRule,
+                SortField:this.SortField,
+                ApproveState:this.ApproveState,
+            }
+
+            if(this.activeMainTab == 'report'){
+                approveInterence.getApproveList({
+                    ...baseParams,
+                    ...selectParams
+                }).then(res=>{
+                    this.tableLoading=false
+                    if(res.Ret!==200) return 
+                    const {List=[],Paging={}} = res.Data||{}
+                    this.tableData = List||[]
+                    this.total = Paging.Totals||0
+                }).catch(err=>{this.tableLoading=false})
+            } else {
+                approveInterence.getBiApproveList({
+                    ...baseParams,
+                    ...biApproveParams,
+                }).then(res=>{
+                    this.tableLoading=false
+                    if(res.Ret!==200) return 
+                    const {List=[],Paging={}} = res.Data||{}
+                    this.tableData = List||[]
+                    this.total = Paging.Totals||0
+                }).catch(err=>{this.tableLoading=false})
+            }
+            
         },
         handleCurrentChange(page) {
             this.page = page;
             this.getTableData()
         },
         sortChange({ prop, order }) {
+            if(!order){
+                this.SortRule = 0;
+                this.SortField = 0;
+                this.handleCurrentChange(1)
+                return
+            }
             this.SortRule = order==='ascending'?1:2
             this.SortField= prop==='CreateTime'?1
                             :prop==='HandleTime'?2:3
             this.handleCurrentChange(1)
         },
+        handleMainClick(tabName){
+          this.activeMainTab = tabName;
+          this.classify = '';
+          this.keyword = '';
+          this.activeTab = 'pending';
+          tabName == 'report' ? this.getClassifyTree() : this.getBIClassifyTree();
+          this.handleClick()
+        },
         handleClick() {
             this.timeType = 1
             this.timeDate=''
+            this.SortRule=0
             this.SortField=0
-            this.SortField=0
-            this.tableColumns = columnsMap[this.activeTab];
+            this.ApproveState = '';
+            this.tableColumns = columnsMap[`${this.activeTab}_${this.activeMainTab}`];
             this.$refs.reftable&&this.$refs.reftable.clearSort()
             this.handleCurrentChange(1)
         },
-        handleShowDetail(data) {
+        handleShowDetail(data) { 
             this.currentData = data;
             this.isDetailDialogShow = true;
         },
-        toApproveDetail(data,type){
+        toApproveDetail(data,type){ 
             this.$router.push({
                 path:'/approveDetail',
                 query:{
+                    mainType:this.activeMainTab,
                     type,
-                    approveId:data.ReportApproveId
+                    approveId:this.activeMainTab == 'report' ? data.ReportApproveId : data.BiApproveId,
                 }
             })
         },
-        cancelApprove(item){
-            approveInterence.cancelApprove({
-                ReportApproveId:Number(item.ReportApproveId)
-            }).then(res=>{
+        cancelApprove(item){ 
+            let req = this.activeMainTab == 'report' ? approveInterence.cancelApprove({ReportApproveId:Number(item.ReportApproveId)})
+                      : approveInterence.cancelBiApprove({BiApproveId:Number(item.BiApproveId)});
+            req.then(res=>{
                 if(res.Ret!==200) return 
                 this.$message.success(this.$t('AprrovalPage.revoke_success') )
                 this.handleCurrentChange(1)
@@ -260,6 +337,10 @@ export default {
             if(e==='处理时间') return this.$t('AprrovalPage.processing_time_lable') 
             if(e==='处理结果') return this.$t('AprrovalPage.processing_result_lable') 
             if(e==='审批时间') return this.$t('AprrovalPage.approval_time') 
+            if(e==='BI看板名称') return this.$t('AprrovalPage.kanban_name') 
+            if(e==='关联分类') return this.$t('AprrovalPage.associative_classification') 
+            if(e==='关联看板') return this.$t('AprrovalPage.association_kanban') 
+            if(e==='处理状态') return this.$t('AprrovalPage.processing_state') 
             if(e==='已通过') return this.$t('AprrovalPage.approved_option') 
             if(e==='已驳回') return this.$t('AprrovalPage.rejected_option') 
             if(e==='已撤销') return this.$t('AprrovalPage.revoked_option') 
@@ -273,18 +354,41 @@ export default {
             }else{
                 row.DetailImgUrl&&this.handleDownloadResource(row.DetailImgUrl,`${row.ReportTitle}`)
             }
-        }
+        },
+        afterGetBaseConfig(){  //执行完reportApproveConfig中getBaseConfig之后执行  mounted之后执行
+           if(this.isETAApprove) 
+            this.mainTabs.push({
+                    label:this.$t('AprrovalPage.research_approval_btn'),
+                    name:'report' 
+            });
+           if(this.IsBIApprove)
+           this.mainTabs.push({
+                label:this.$t('SystemManage.BaseConfig.bIDashboard_approval'),
+                name:'bi'  
+            });
+           this.activeMainTab = this.mainTabs.length > 0 ? this.mainTabs[0].name : '';
+           if(!this.mainTabs.length) return;
+           const {formType='approve',mainType='report'} = this.$route.query
+
+           if(mainType) {
+                let valid = this.mainTabs.find(_ => mainType == _.name);
+                this.activeMainTab = valid ? valid.name : this.mainTabs[0].name;
+           }
+           
+
+           const formTypeMap = {
+                'approve':'pending',
+                'detail':'processed',
+                'myself':'originate'
+           }
+           this.activeTab = formTypeMap[formType]||'pending'
+           this.tableColumns = columnsMap[`${this.activeTab}_${this.activeMainTab}`] || approve_pending_columns;
+           this.getTableData()
+        },
     },
     mounted(){
-        this.getClassifyTree()
-        const {formType='approve'} = this.$route.query
-        const formTypeMap = {
-            'approve':'pending',
-            'detail':'processed',
-            'myself':'originate'
-        }
-        this.activeTab = formTypeMap[formType]||'pending'
-        this.getTableData()
+        this.getClassifyTree();
+        this.getBIClassifyTree();
     },
     components: { RejectDialog }
 };

+ 151 - 54
src/views/approve_manage/approveSetting.vue

@@ -1,20 +1,26 @@
 <template>
     <!-- 审批流配置列表 -->
-    <div class="approve-setting-wrap approve-page-wrap" v-if="isETAApprove">
+    <div class="approve-setting-wrap approve-page-wrap" v-if="isETAApprove || IsBIApprove">
+        <div style="margin-bottom: 10px;">
+            <el-radio-group v-model="activeMainTab" style="margin-bottom: 10px;" @input="handleTabClick">
+                    <el-radio-button v-for="item in mainTabs" :key="item.name" :label="item.name">{{ item.label }}</el-radio-button>
+            </el-radio-group>
+        </div>
         <div class="head-box">
-            <el-button v-permission="permissionBtn.approveFlowPermission.reportApprove_add"
-                type="primary" @click="$router.push('/approveEdit')">{{$t('SystemManage.ReportApprove.add_btn')}}</el-button>
+            <el-input v-model="Keyword" @input="handleCurrentChange(1)"
+                :placeholder="$t('SystemManage.ReportApprove.placeholder02')" prefix-icon="el-icon-search" clearable style="width:360px;"></el-input>
             <el-cascader v-model="classify"
-                :placeholder="$t('SystemManage.ReportApprove.placeholder01')" clearable
-                :options="classifyTree"
-                :props="{value:'ClassifyId',label:'ClassifyName',children:'Children'}"
+                :placeholder="activeMainTab == 'report' ? $t('SystemManage.ReportApprove.placeholder01') : $t('AprrovalPage.select_associated_Kanban_tip')" clearable
+                :options="activeMainTab == 'report' ? classifyTree : biClassifyTree"
+                :props="activeMainTab == 'report' ? {value:'ClassifyId',label:'ClassifyName',children:'Children'} : {value:'BiDashboardClassifyId',label:'BiDashboardClassifyName',children:'Children'}"
                 @change="handleSearchChange"
-                style="margin-right: auto;margin-left: 15px;"></el-cascader>
-            <el-input v-model="Keyword" @input="handleCurrentChange(1)"
-                :placeholder="$t('SystemManage.ReportApprove.placeholder02')" prefix-icon="el-icon-search" clearable style="width:260px;"></el-input>
+                style="margin-right: auto;margin-left: 25px;width: 240px;"></el-cascader>
+            <el-button v-permission="permissionBtn.approveFlowPermission.reportApprove_add"
+                type="primary" @click="handleAddFlow">{{$t('SystemManage.ReportApprove.add_btn')}}</el-button>
+            
         </div>
-        <div class="list-box">
-            <el-table :data="tableData" @sort-change="sortChange" border>
+        <div class="list-box" v-loading="dataLoading" element-loading-text="数据加载中...">
+            <el-table :data="tableData" @sort-change="sortChange" border ref="reftable">
                 <el-table-column
                     v-for="item in tableColumns"
                     :key="item.key"
@@ -59,7 +65,7 @@ export default {
     mixins:[approveMixins,reportApproveConfig],
     computed:{
         tableColumns(){
-            return [{
+            return this.activeMainTab == 'report' ? [{
                 label:this.$t('SystemManage.ReportApprove.table_col01'),
                 key:'FlowName'
             },{
@@ -69,96 +75,187 @@ export default {
                 label:this.$t('SystemManage.ReportApprove.table_col03'),
                 key:'CreateTime',
                 sortable:'custom'
+            }] : [{
+                label:this.$t('SystemManage.ReportApprove.table_col01'),
+                key:'FlowName'
+            },{
+                label:this.$t('AprrovalPage.association_kanban'),
+                key:'ClassifyName'
+            },{
+                label:this.$t('SystemManage.ReportApprove.table_col03'),
+                key:'CreateTime',
+                sortable:'custom'
             }]
-        }
+        },
     },
     data() {
         return {
             /* 列表筛选项 */
-            ClassifyFirstId:0,//研报倒数第二级分类id
-            ClassifySecondId:0,//研报最后一级分类id
+            ClassifyFirstId:0,//研报第一级分类id
+            ClassifySecondId:0,//研报第二级分类id
+            ClassifyThirdld:0,//研报第三级分类id
             ReportType:0,//研报类型 1-中文研报;2-英文研报;3-智能研报
             SortRule:0,//排序规则:1-正序; 2-倒序(默认)
+            ClassifyId:0,//bi审批看板选中分类id
             Keyword:'',
             classify:'',
 
             tableData:[],
-            // tableColumns:[{
-            //     label:'审批流名称',
-            //     key:'FlowName'
-            // },{
-            //     label:'关联报告',
-            //     key:'ReportClassify'
-            // },{
-            //     label:'创建时间',
-            //     key:'CreateTime',
-            //     sortable:'custom'
-            // }],
             page:1,
             pageSize:10,
             total:0,
+            mainTabs:[],
+            activeMainTab:'', //report-研报审批  bi-bi看板审批
+            dataLoading:false,
         };
     },
     methods: {
+        handleTabClick(tabName){
+          this.activeMainTab = tabName;
+          this.Keyword = '';
+          this.classify = '';
+          this.SortRule = 0;
+          this.page = 1;
+          this.total = 0;
+          this.ReportType = 0;
+          this.ClassifyFirstId = 0;
+          this.ClassifySecondId = 0;
+          this.ClassifyThirdld = 0;
+          this.ClassifyId = 0;
+          this.$refs.reftable&&this.$refs.reftable.clearSort();
+          tabName == 'report' ? this.getClassifyTree() : this.getBIClassifyTree();
+          this.getTableData();
+        },
         handleCurrentChange(page){
             this.page = page
             this.getTableData()
         },
         handleSearchChange(){
-            this.ReportType = this.classify[0]||0
-            this.ClassifySecondId = this.classify[this.classify.length-1]||0
-            if(this.classify.length>=3){
-                this.ClassifyFirstId = this.classify[this.classify.length-2]||0
-            }else{
-                this.ClassifyFirstId = 0
+            if(this.activeMainTab == 'report'){
+                // this.ClassifySecondId = this.classify[this.classify.length-1]||0
+                // if(this.classify.length>=3){
+                //     this.ClassifyFirstId = this.classify[this.classify.length-2]||0
+                // }else{
+                //     this.ClassifyFirstId = 0
+                // }
+                this.ReportType = this.classify[0]||0
+                this.handleReportClassifyId()
+            } else {
+                this.ClassifyId = this.classify[0] || 0;
             }
             this.handleCurrentChange(1)
         },
+        handleReportClassifyId(){
+            if(this.classify.length === 2){
+                this.ClassifyFirstId = this.classify[this.classify.length-1]||0;
+                this.ClassifySecondId = 0;
+                this.ClassifyThirdld = 0;
+            } else if(this.classify.length === 3){
+                this.ClassifyFirstId = this.classify[this.classify.length-2]||0
+                this.ClassifySecondId = this.classify[this.classify.length-1]||0
+                this.ClassifyThirdld = 0;
+            } else {  //分类最多只有三级
+                this.ClassifyFirstId = this.classify.length > 1 ? this.classify[this.classify.length-3]||0 : 0;
+                this.ClassifySecondId = this.classify.length > 1 ? this.classify[this.classify.length-2]||0 : 0;
+                this.ClassifyThirdld = this.classify.length > 1 ? this.classify[this.classify.length-1]||0 : 0;
+            }
+        },
         sortChange({prop,order}){
             this.SortRule = order==='ascending'?1:2
+            if(!order) this.SortRule = 0;
             this.handleCurrentChange(1)
         },
         getTableData(){
-            approveInterence.getApproveFlowList({
+            let params = {
                 PageSize:this.pageSize,
                 CurrentIndex:this.page,
-                ReportType:this.ReportType,
-                ClassifyFirstId:this.ClassifyFirstId,
-                ClassifySecondId:this.ClassifySecondId,
                 Keyword:this.Keyword,
-                SortRule:this.SortRule
-            }).then(res=>{
-                if(res.Ret!==200) return 
-                const {List=[],Paging={}} = res.Data||{}
-                this.tableData = List||[]
-                this.total = Paging.Totals||0
+                SortRule:this.SortRule,
+            }
+            this.dataLoading = true;
+            if(this.activeMainTab == 'report'){
+                approveInterence.getApproveFlowList({
+                    ...params,
+                    ReportType:this.ReportType,
+                    ClassifyFirstId:this.ClassifyFirstId,
+                    ClassifySecondId:this.ClassifySecondId,
+                    ClassifyThirdld:this.ClassifyThirdld,
+                }).then(res=>{
+                    if(res.Ret!==200) return 
+                    const {List=[],Paging={}} = res.Data||{}
+                    this.tableData = List||[]
+                    this.total = Paging.Totals||0;
+                    this.dataLoading = false;
+                }).catch(err=>{this.dataLoading = false;})
+            }
+            if(this.activeMainTab == 'bi'){
+                approveInterence.getBiApproveFlowList({
+                    ...params,
+                    ClassifyId:this.ClassifyId
+                }).then(res=>{
+                    if(res.Ret != 200) return;
+                    const {List=[],Paging={}} = res.Data||{}
+                    this.tableData = List||[]
+                    this.total = Paging.Totals||0;
+                    this.dataLoading = false;
+                }).catch(err=>{this.dataLoading = false;})
+            } 
+            
+        },
+        handleAddFlow(){
+            this.$router.push({
+                path:'/approveEdit',
+                query:{
+                    mainType:this.activeMainTab,
+                }
             })
         },
         handleEditFlow(item){
             this.$router.push({
                 path:'/approveEdit',
                 query:{
-                    flowId:item.ReportApproveFlowId
+                    mainType:this.activeMainTab,
+                    flowId:this.activeMainTab == 'report' ? item.ReportApproveFlowId :  item.BiApproveFlowId,
                 }
             })
         },
         handleDeleteFlow(item){
             this.$confirm(this.$t('MsgPrompt.delete_info_msg'),this.$t('Confirm.prompt'),{
                 type:"warning"
-            }).then(()=>{
-                approveInterence.deleteApproveFlow({
-                    ReportApproveFlowId:item.ReportApproveFlowId
-                }).then(res=>{
-                    if(res.Ret!==200) return 
-                    this.$message.success(this.$t('MsgPrompt.delete_msg'))
-                    this.handleCurrentChange(1)
-                })
+            }).then(async ()=>{
+                let res = this.activeMainTab == 'report' 
+                          ? await approveInterence.deleteApproveFlow({ReportApproveFlowId:item.ReportApproveFlowId})
+                          : await approveInterence.deleteBiApproveFlow({BiApproveFlowId:item.BiApproveFlowId});
+                if(res.Ret!==200) return 
+                this.$message.success(this.$t('MsgPrompt.delete_msg'))
+                this.handleCurrentChange(1)
             }).catch(()=>{})
-        }
+        },
+        afterGetBaseConfig(){ //执行完reportApproveConfig中getBaseConfig之后执行  mounted之后执行
+            if(this.isETAApprove) 
+                this.mainTabs.push({
+                        label:this.$t('AprrovalPage.research_approval_btn'),
+                        name:'report' 
+                });
+           if(this.IsBIApprove)
+                this.mainTabs.push({
+                    label:this.$t('SystemManage.BaseConfig.bIDashboard_approval'),
+                    name:'bi'  
+                });
+           this.activeMainTab = this.mainTabs.length > 0 ? this.mainTabs[0].name : '';
+           if(!this.mainTabs.length) return;
+           
+           if(this.$route.query.mainType) {
+                let valid = this.mainTabs.find(_ => this.$route.query.mainType == _.name);
+                this.activeMainTab = valid ? valid.name : this.mainTabs[0].name;
+           }
+
+           this.getTableData();
+        },
     },
     mounted(){
-        this.getClassifyTree()
-        this.getTableData()
+        this.getClassifyTree();
+        this.getBIClassifyTree();
     },
 };
 </script>

+ 3 - 0
src/views/approve_manage/components/rejectDialog.vue

@@ -57,6 +57,9 @@ export default {
                 this.$message.warning("请输入驳回理由")
                 return
             } */
+           if(this.content.length > 500){
+              return this.$message.warning('内容不能超过500字') 
+           };
             this.$emit('edit',this.content)
         }
     },

+ 1 - 0
src/views/approve_manage/components/timeLineItem.vue

@@ -111,6 +111,7 @@ export default {
                     /* padding-left: 40px; */
                     color:#AD352F;
                     background-color: #FFF0ED;
+                    word-break: break-all;
                 }
             }
         }

+ 68 - 3
src/views/approve_manage/config/tableConfig.js

@@ -1,4 +1,4 @@
-//审批管理-待处理
+//审批管理-待处理_研报审批
 export const approve_pending_columns = [
     {
         key:'ReportTitle',
@@ -18,13 +18,33 @@ export const approve_pending_columns = [
         label:'审批状态',
     }
 ]
+//审批管理-待处理_BI看板审批
+export const biapprove_pending_columns = [
+    {
+        key:'BiTitle',
+        label:'BI看板名称'
+    },{
+        key:'ClassifyName',
+        label:'关联看板'
+    },{
+        key:'ApplyUserName',
+        label:'提交人'
+    },{
+        key:'CreateTime',
+        label:'提交时间',
+        sortable:'custom'
+    },{
+        key:'RecordState',
+        label:'审批状态',
+    }
+]
 export const appreve_pending_status = [
     {
         type:1,
         label:'待审批'
     }
 ]
-//审批管理-已处理
+//审批管理-已处理-研报审批
 export const approve_processed_columns=[
     {
         key:'ReportTitle',
@@ -48,6 +68,30 @@ export const approve_processed_columns=[
         label:'处理结果',
     }
 ]
+//审批管理-已处理-bi看板审批
+export const biapprove_processed_columns=[
+    {
+        key:'BiTitle',
+        label:'BI看板名称'
+    },{
+        key:'ClassifyName',
+        label:'关联看板'
+    },{
+        key:'ApplyUserName',
+        label:'提交人'
+    },{
+        key:'CreateTime',
+        label:'提交时间',
+        sortable:'custom'
+    },{
+        key:'HandleTime',
+        label:'处理时间',
+        sortable:'custom'
+    },{
+        key:'RecordState',
+        label:'处理状态',
+    }
+]
 export const approve_processed_status = [
     {
         type:1,
@@ -57,7 +101,7 @@ export const approve_processed_status = [
         label:'已驳回'
     }
 ]
-//审批管理-我发起的
+//审批管理-我发起的-研报审批
 export const approve_originate_columns=[
     {
         key:'ReportTitle',
@@ -78,6 +122,27 @@ export const approve_originate_columns=[
         label:'审批状态',
     }
 ]
+//审批管理-我发起的-bi看板审批
+export const biapprove_originate_columns=[
+    {
+        key:'BiTitle',
+        label:'BI看板名称'
+    },{
+        key:'ClassifyName',
+        label:'关联看板'
+    },{
+        key:'CreateTime',
+        label:'提交时间',
+        sortable:'custom'
+    },{
+        key:'ApproveTime',
+        label:'审批时间',
+        sortable:'custom'
+    },{
+        key:'State',
+        label:'审批状态',
+    }
+]
 export const approve_originate_status=[
     {
         type:1,

+ 7 - 0
src/views/approve_manage/mixins/approveMixins.js

@@ -13,6 +13,7 @@ export default{
     data(){
         return {
             classifyTree:[],
+            biClassifyTree:[],
         }
     },
     methods:{
@@ -27,5 +28,11 @@ export default{
                 }
             })
         },
+        getBIClassifyTree(){
+            approveInterence.getBiApproveClassifyTree().then(res=>{
+                if(res.Ret != 200) return;
+                this.biClassifyTree = res.Data
+            })
+        },
     }
 }

+ 1 - 1
src/views/chartRelevance_manage/components/chartCard.vue

@@ -195,7 +195,7 @@ export default {
           this.chartInfo = data.ChartInfo;
           this.tableData=data.EdbInfoList||[]
           this.statisticFrequencyData = data.DataResp;
-          this.setStatisticFrequency();
+          this.statisticFrequencyData&&this.setStatisticFrequency();
           break
       }
     },

+ 1 - 1
src/views/chartRelevance_manage/components/saveEdbToBaseDia.vue

@@ -148,7 +148,7 @@ export default {
 				if(res.Ret !== 200) return
 				//this.filterNodes(res.Data.AllNodes,1);
       }else {
-				res = await dataBaseInterface.menuListV3()
+				res = await dataBaseInterface.menuListV3({ClassifyType:2})
 				if(res.Ret !== 200) return
 				//this.filterNodes(res.Data.AllNodes,2);
 			}

+ 2 - 2
src/views/chartRelevance_manage/crossVarietyAnalysis/components/edbTableSection.vue

@@ -189,8 +189,8 @@ export default {
     },
 
     /* 查看数据 跳转指标库展开具体指标 */
-    viewTarget({ UniqueCode,EdbInfoId,EdbInfoCategoryType,ClassifyId }) {
-      let path = EdbInfoCategoryType ? '/predictEdb' : '/database';
+    viewTarget({ UniqueCode,EdbInfoId,EdbInfoCategoryType,ClassifyId,EdbType }) {
+      let path = EdbInfoCategoryType ? '/predictEdb' : (EdbType===1?'/edbBasicbase':'/database');
       let {href} = this.$router.resolve({path, query: {
         code: UniqueCode,
         id: EdbInfoId,

+ 2 - 2
src/views/chartRelevance_manage/relevance/components/multipleIndForm.vue

@@ -99,7 +99,7 @@
                 <div class="table-radio-wrap">
                     <el-radio-group v-model="factorData.EdbInfoType" @input="changeEdbType">
                         <el-radio :label="0">ETA指标</el-radio>
-                        <el-radio :label="1">预测指标</el-radio>
+                        <el-radio :label="1">衍生指标</el-radio>
                     </el-radio-group>
                     
                 </div>
@@ -337,7 +337,7 @@ export default {
         },
         async getClassifyOpt(){
             const res= this.factorData.EdbInfoType===0
-                        ?await dataBaseInterface.menuListV3()
+                        ?await dataBaseInterface.menuListV3({ClassifyType:2})
                         :await preDictEdbInterface.classifyListV2()
             if (res.Ret !== 200) return
 

+ 12 - 16
src/views/classify_manage/chapterSettingV2.vue

@@ -69,7 +69,7 @@
                     :placeholder="$t('ReportManage.CategoryList.related_variety_inputhint')"></el-input>
                 </el-form-item>
                 <!-- 关联品种 -->
-                <el-form-item prop="variety" :label="$t('ReportManage.CategoryList.related_variety')" v-if="reportVarietyList.length">
+                <!-- <el-form-item prop="variety" :label="$t('ReportManage.CategoryList.related_variety')" v-if="reportVarietyList.length">
                     <template slot="label">
                         <el-tooltip class="item" effect="dark" :content="$t('ReportManage.CategoryList.related_variety_hint')">
                             <div>
@@ -86,7 +86,7 @@
                         :props="{value:'PermissionId',label:'PermissionName',children:'Child',multiple: true,emitPath:false}" 
                         style="width:317px;"
                     ></el-cascader>
-                </el-form-item>
+                </el-form-item> -->
             </el-form>
         </div>
         <div solt="footer" style="padding: 20px 0;text-align: center;">
@@ -121,18 +121,17 @@ export default {
             addForm:{
                 ReportChapterTypeName:"",
                 // ResearchType:"",.
-                ChartPermissionIdList:''
             },
             researchType:'',// day-晨报;week-周报
             parentClassifyName: '',
 
-            reportVarietyList:[],//中文品种列表
+            // reportVarietyList:[],//中文品种列表
         }
     },
     mounted(){
         this.parentClassifyName = this.$route.query.classifyName || ''
         this.getList()
-        this.getReportVarietyList()
+        // this.getReportVarietyList()
     },
     methods: {
         getList(type){
@@ -147,7 +146,6 @@ export default {
             this.dialogTitle=this.$t('ReportManage.CategoryList.add_section')
             this.addDialogShow=true
             this.addForm.ReportChapterTypeName=''
-            this.addForm.ChartPermissionIdList=''
             this.addForm.ReportChapterTypeId=0
             console.log(this.addForm);
         },
@@ -158,7 +156,6 @@ export default {
                 ...this.addForm,
                 ReportChapterTypeName:row.ReportChapterTypeName,
                 ReportChapterTypeId:row.ReportChapterTypeId,
-                ChartPermissionIdList:row.ChartPermissionIdList||''
             }
             this.dialogTitle=this.$t('ReportManage.CategoryList.edit_section')
             this.addDialogShow=true
@@ -172,7 +169,6 @@ export default {
             let params={
                 ...this.addForm,
                 ClassifyId: Number(this.$route.query.id),
-                ChartPermissionIdList:this.addForm.ChartPermissionIdList||[]
             }
             // 请求方法
             let requestMethod;
@@ -211,14 +207,14 @@ export default {
         
 
         // 获取品种数据
-        getReportVarietyList(){
-            reportV2Interface.getClassifyPermissionList({
-                ClassifyId: Number(this.$route.query.id),
-            }).then(res=>{
-                this.reportVarietyList=res.Data||[]
-                this.filterNodes(this.reportVarietyList)
-            })
-        },
+        // getReportVarietyList(){
+        //     reportV2Interface.getClassifyPermissionList({
+        //         ClassifyId: Number(this.$route.query.id),
+        //     }).then(res=>{
+        //         this.reportVarietyList=res.Data||[]
+        //         this.filterNodes(this.reportVarietyList)
+        //     })
+        // },
 
         //启用\禁用设置
         handleEnableSet(item){

+ 12 - 14
src/views/classify_manage/classifylistV2.vue

@@ -120,7 +120,7 @@
                         </el-cascader>
                     </el-form-item>
                     <!-- 关联品种 -->
-                    <el-form-item prop="variety" :label="$t('ReportManage.CategoryList.related_variety')" v-if="canSetPermission">
+                    <!-- <el-form-item prop="variety" :label="$t('ReportManage.CategoryList.related_variety')" v-if="canSetPermission">
                         <template slot="label">
                             <el-tooltip class="item" effect="dark" :content="$t('ReportManage.CategoryList.related_variety_hint')">
                                 <div>
@@ -137,7 +137,7 @@
                             :props="{value:'PermissionId',label:'PermissionName',children:'Child',multiple: true,emitPath:false}" 
                             style="min-width:400px;"
                         ></el-cascader>
-                    </el-form-item>
+                    </el-form-item> -->
                 </el-form>
                 <div v-html="tips" style="color:#999;"></div>
             </div>
@@ -253,13 +253,12 @@ export default {
             isTransferReport: false,
             transferForm: {},
 
-            tips: `注:若上级分类已关联报告,则新建的第一个子分类默认继承上级分类(父分类)关联的品种、报告、审批流,且关联品种支持编辑。  `
-
+            tips: `注:若上级分类已关联报告,则新建的第一个子分类默认继承上级分类(父分类)关联的品种、报告、审批流。`
         }
     },
     mounted(){
         this.getList()
-        this.getReportVarietyList()
+        // this.getReportVarietyList()
     },
     methods: {
         /* 报告转移 */
@@ -294,7 +293,7 @@ export default {
                 let item = this.$refs.classifyRef.getCheckedNodes(true)
                 console.log(item)
                 if(item&&item.length) {
-                    this.classifyForm.variety = item[0].data.ChartPermissionIdList
+                    // this.classifyForm.variety = item[0].data.ChartPermissionIdList
                 }
             }
         },
@@ -330,7 +329,6 @@ export default {
                 classify_id:item.Id,
                 classify_name:item.ClassifyName,
                 parent_id: item.ParentId,
-                variety:item.ChartPermissionIdList||'',//关联的品种
                 isLastLevel: !item.Child
             }
         },
@@ -340,7 +338,7 @@ export default {
             let params = {
                 ClassifyName: classify_name,
                 ParentId: parent_id,
-                ChartPermissionIdList:this.classifyForm.variety||[]
+                // ChartPermissionIdList:this.classifyForm.variety||[]
             }
 
             const { Ret,Msg } = classify_id 
@@ -364,12 +362,12 @@ export default {
         },
 
         // 获取品种数据
-        getReportVarietyList(){
-            reportVarietyInterence.filterVarietyOpts().then(res=>{
-                console.log(res);
-                this.reportVarietyList=res.Data||[]
-            })
-        },
+        // getReportVarietyList(){
+        //     reportVarietyInterence.filterVarietyOpts().then(res=>{
+        //         console.log(res);
+        //         this.reportVarietyList=res.Data||[]
+        //     })
+        // },
 
         //启用\禁用设置
         handleEnableSet(item){

+ 1 - 1
src/views/dataEntry_manage/adjustdata/adjustData.vue

@@ -357,7 +357,7 @@ export default {
 
     /* 获取目录结构 */
 		getMenu() {
-			dataBaseInterface.menuListV3().then((res) => {
+			dataBaseInterface.menuListV3({ClassifyType:2}).then((res) => {
 				if (res.Ret === 200) {
 					this.filterNodes(res.Data.AllNodes||[])
 					this.classifyOptions = res.Data.AllNodes || [];

+ 1 - 1
src/views/dataEntry_manage/codecount/index.vue

@@ -398,7 +398,7 @@ export default {
 
 		/* 获取目录结构 */
 		getMenu() {
-			dataBaseInterface.menuListV3().then((res) => {
+			dataBaseInterface.menuListV3({ClassifyType:2}).then((res) => {
 				if (res.Ret !== 200) return
 					this.filterNodes(res.Data.AllNodes||[]);
 					this.menuOptions = res.Data.AllNodes || [];

+ 112 - 0
src/views/dataEntry_manage/databaseComponents/addCollectClassifyDia.vue

@@ -0,0 +1,112 @@
+<template>
+  <el-dialog
+		:visible.sync="show"
+		:close-on-click-modal="false"
+		:modal-append-to-body='false'
+    :title="form.classifyId?'编辑目录':'新增目录'"
+		@close="closeDia"
+		custom-class="edbCollect-classify-dialog"
+		center
+		width="650px"
+		v-dialogDrag
+  >
+    <el-form 
+        :model="classifyForm" 
+        :rules="formRules" 
+        ref="formRef" 
+        hide-required-asterisk
+        label-width="auto"
+    >
+        <!-- 目录名称 -->
+        <el-form-item prop="classifyName" label="目录名称">
+            <el-input 
+                type="text" 
+                v-model="classifyForm.classifyName" 
+                placeholder="请输入目录名称"
+                style="width:80%"
+            />
+        </el-form-item>
+    </el-form>
+
+    <div class="footer" style="margin-top: 20px;">
+        <el-button
+          @click="closeDia"
+        >{{ $t('Dialog.cancel_btn') }}</el-button>
+        <el-button
+          @click="saveClassifyHandle"
+        type="primary"
+        >{{ $t('Dialog.confirm_save_btn') }}</el-button>
+    </div>
+  </el-dialog>  
+</template>
+
+<script>
+import { edbCollectInterface } from '@/api/modules/chartApi'
+export default {
+  props: {
+    show: {
+      type: Boolean
+    },
+    form: {
+      type:Object
+    }
+  },
+  watch: {
+    show(newVal) {
+      if(!newVal) return 
+      this.classifyForm.classifyName = this.form.name;
+    }
+  },
+  data() {
+    return {
+      classifyForm: {
+        classifyName:""
+      },
+
+      formRules: {
+        classifyName: [{ required:true,message:'目录名称不能为空',trigger:'blur'}]
+      }
+    }
+  },
+  methods: {
+    closeDia() {
+      this.$refs.formRef.resetFields()
+      this.$emit('update:show',false)
+    },
+
+    async saveClassifyHandle() {
+      await this.$refs.formRef.validate()
+      
+      const res = this.form.classifyId
+        ? await edbCollectInterface.editCollectClassify({
+            ClassifyName: this.classifyForm.classifyName,
+            ClassifyId: this.form.classifyId
+          })
+        : await edbCollectInterface.addCollectClassify({
+            ClassifyName: this.classifyForm.classifyName,
+          })
+
+      if(res.Ret !== 200) return
+      this.$message.success(this.form.classifyId?'编辑成功':'新增成功');
+      this.closeDia()
+      this.$emit('confirm')
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.edbCollect-classify-dialog {
+  .el-form {
+    padding: 0 40px;
+  }
+  .footer {
+    display: flex;
+    justify-content: center;
+    margin: 40px 0;
+    .el-button {
+      width: 130px;
+    }
+  }
+}
+</style>

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

@@ -400,7 +400,7 @@ export default {
 		async getMenu() {
 			const res = this.edbSource === 'predict'
 				? await preDictEdbInterface.classifyListV2()
-				: await dataBaseInterface.menuListV3()
+				: await dataBaseInterface.menuListV3({ClassifyType:2})
 				if (res.Ret !== 200) return
 				//this.edbSource !== 'predict' && this.filterNodes(res.Data.AllNodes);
 				// this.options = res.Data.AllNodes || [];

+ 1 - 1
src/views/dataEntry_manage/databaseComponents/batchComputedSave.vue

@@ -370,7 +370,7 @@ export default {
 		},
         // 获取指标分类
         async getClassifyOpt(){
-            const res=await dataBaseInterface.menuListV3()
+            const res=await dataBaseInterface.menuListV3({ClassifyType:2})
             if (res.Ret !== 200) return
             this.filterNodes(res.Data.AllNodes||[]);
 			this.classifyOpt = res.Data.AllNodes || [];

+ 172 - 172
src/views/dataEntry_manage/databaseComponents/batchComputedV2.vue

@@ -46,203 +46,203 @@
 
                     <!-- 超级季节性 -->
                     <template v-if="computedType==35">
-                    <el-form-item required :label="$t('EtaBasePage.label_n_val')" style="width:280px">
-                        <el-input v-model="formData.nNum" :placeholder="$t('Edb.InputHolderAll.input_n_value')" type="number" style="width:200px"></el-input>
-                    </el-form-item>
-                    <el-form-item :label="$t('EtaBasePage.label_calendar')"  style="width:180px">
-                        <el-select v-model="formData.calendarType" style="width:120px">
-                            <el-option :label="$t('Chart.calendar_gre')" value="公历"></el-option>
-                            <el-option :label="$t('Chart.calendar_lunar_text')" value="农历"></el-option>
-                        </el-select>
-                    </el-form-item>
+                        <el-form-item required :label="$t('EtaBasePage.label_n_val')" style="width:280px">
+                            <el-input v-model="formData.nNum" :placeholder="$t('Edb.InputHolderAll.input_n_value')" type="number" style="width:200px"></el-input>
+                        </el-form-item>
+                        <el-form-item :label="$t('EtaBasePage.label_calendar')"  style="width:180px">
+                            <el-select v-model="formData.calendarType" style="width:120px">
+                                <el-option :label="$t('Chart.calendar_gre')" value="公历"></el-option>
+                                <el-option :label="$t('Chart.calendar_lunar_text')" value="农历"></el-option>
+                            </el-select>
+                        </el-form-item>
                     </template>
 
                     <!-- 降频 -->
                     <template v-if="computedType==51">
-                    <el-form-item required :label="$t('Edb.Detail.e_fre')" style="width:180px">
-                        <el-select v-model="formData.frequency" style="width:120px">
-                            <el-option v-for="opt in frequencyArr" :key="opt.value" :label="opt.label" :value="opt.value"></el-option>
-                        </el-select>
-                    </el-form-item>
-                    <el-form-item :label="$t('EtaBasePage.label_val_type')"  style="width:200px">
-                        <el-select v-model="formData.valueType" style="width:120px">
-                            <el-option key="期末值" :label="$t('EtaBasePage.val_type_end')" value="期末值"/>
-							<el-option key="平均值" :label="$t('EtaBasePage.val_type_average')" value="平均值"/>
-                        </el-select>
-                    </el-form-item>
+                        <el-form-item required :label="$t('Edb.Detail.e_fre')" style="width:180px">
+                            <el-select v-model="formData.frequency" style="width:120px">
+                                <el-option v-for="opt in frequencyArr" :key="opt.value" :label="opt.label" :value="opt.value"></el-option>
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item :label="$t('EtaBasePage.label_val_type')"  style="width:200px">
+                            <el-select v-model="formData.valueType" style="width:120px">
+                                <el-option key="期末值" :label="$t('EtaBasePage.val_type_end')" value="期末值"/>
+                                <el-option key="平均值" :label="$t('EtaBasePage.val_type_average')" value="平均值"/>
+                            </el-select>
+                        </el-form-item>
                     </template>
 
                     <!-- 累计值 -->
                     <template v-if="computedType=='accumulate'">
-                    <el-form-item>
-                        <el-radio v-model="subComputedType" :label="62">
-                            <!-- 累计值 -->
-                            {{$t('Edb.CalculatesAll.cumulate')}}
-                        </el-radio>
-                    </el-form-item>
-                    <el-form-item required :label="$t('Edb.Detail.e_fre')" style="width:180px" v-if="subComputedType==62">
-                        <el-select v-model="formData.frequency" style="width:120px">
-                            <el-option v-for="opt in frequencyArr" :key="opt.value" :label="opt.label" :value="opt.value"></el-option>
-                        </el-select>
-                    </el-form-item>
-                    <el-form-item :label="$t('Edb.CalculatesAll.latest_processing')"  style="width:210px" v-if="subComputedType==62">
-                        <el-select v-model="formData.newValue" style="width:120px">
-                            <el-option :label="$t('EtaBasePage.default_select_text')" :value="0"/>
-							<el-option :label="$t('EtaBasePage.mean_imputation_select_text')" :value="1"/>
-                        </el-select>
-                    </el-form-item>
-                    <el-form-item>
-                        <el-radio v-model="subComputedType" :label="63">
-                            <!-- /* '年初至今累计值' */ -->
-                            {{$t('Edb.CalculatesAll.cumulate_oneyear')}}
-                        </el-radio>
-                    </el-form-item>
+                        <el-form-item>
+                            <el-radio v-model="subComputedType" :label="62">
+                                <!-- 累计值 -->
+                                {{$t('Edb.CalculatesAll.cumulate')}}
+                            </el-radio>
+                        </el-form-item>
+                        <el-form-item required :label="$t('Edb.Detail.e_fre')" style="width:180px" v-if="subComputedType==62">
+                            <el-select v-model="formData.frequency" style="width:120px">
+                                <el-option v-for="opt in frequencyArr" :key="opt.value" :label="opt.label" :value="opt.value"></el-option>
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item :label="$t('Edb.CalculatesAll.latest_processing')"  style="width:210px" v-if="subComputedType==62">
+                            <el-select v-model="formData.newValue" style="width:120px">
+                                <el-option :label="$t('EtaBasePage.default_select_text')" :value="0"/>
+                                <el-option :label="$t('EtaBasePage.mean_imputation_select_text')" :value="1"/>
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item>
+                            <el-radio v-model="subComputedType" :label="63">
+                                <!-- /* '年初至今累计值' */ -->
+                                {{$t('Edb.CalculatesAll.cumulate_oneyear')}}
+                            </el-radio>
+                        </el-form-item>
                     </template>
 
                     <!-- 指数修匀 -->
                     <template v-if="computedType==72">
-                    <el-form-item required :label="$t('EtaBasePage.alpha_value_lable')" style="width:220px">
-                        <el-input v-model.trim="formData.alphaValue" style="width:140px" :placeholder="$t('Edb.InputHolderAll.input_alpha_val')"></el-input>
-                    </el-form-item>
-                    </template>
+                        <el-form-item required :label="$t('EtaBasePage.alpha_value_lable')" style="width:220px">
+                            <el-input v-model.trim="formData.alphaValue" style="width:140px" :placeholder="$t('Edb.InputHolderAll.input_alpha_val')"></el-input>
+                        </el-form-item>
+                        </template>
 
-                    <!-- 与常数计算 -->
-                    <template v-if="computedType=='withNum'">
-                    <el-form-item required :label="$t('EtaBasePage.formula_lable')">
-                        <el-input v-model="formData.formula" :placeholder="$t('EtaBasePage.input_formula_msg')" clearable style="width: 200px"/>
-                        <span>
-                            <!-- 公式示例:A+100,或A*2 -->
-                            {{$t('EtaBasePage.formula_example_text')}}
-                        </span>
-                    </el-form-item>
+                        <!-- 与常数计算 -->
+                        <template v-if="computedType=='withNum'">
+                        <el-form-item required :label="$t('EtaBasePage.formula_lable')">
+                            <el-input v-model="formData.formula" :placeholder="$t('EtaBasePage.input_formula_msg')" clearable style="width: 200px"/>
+                            <span>
+                                <!-- 公式示例:A+100,或A*2 -->
+                                {{$t('EtaBasePage.formula_example_text')}}
+                            </span>
+                        </el-form-item>
                     </template>
 
                     <!-- 与单指标计算 -->
                     <template v-if="computedType=='withEDB'">
-                    <el-form-item required :label="$t('EtaBasePage.metric_label_b')">
-                        <el-select
-                            v-model="select_target"
-                            v-loadMore="searchLoad"
-                            :filterable="!select_target"
-                            clearable
-                            :placeholder="$t('Edb.InputHolderAll.input_name')"
-                            style="width: 250px"
-                            remote
-                            :remote-method="getTarget"
-                            @click.native="inputFocusHandle"
-                            @change="chooseTarget"
-                            @blur="search_have_more = false"
-                        >
-                            <i slot="prefix" class="el-input__icon el-icon-search"></i>
-                            <el-option
-                                v-for="item in searchOptions"
-                                :key="item.EdbInfoId"
-                                :label="$parent.currentLang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName"
-                                :value="item.EdbInfoId"
-                                :disabled="!item.HaveOperaAuth"
+                        <el-form-item required :label="$t('EtaBasePage.metric_label_b')">
+                            <el-select
+                                v-model="select_target"
+                                v-loadMore="searchLoad"
+                                :filterable="!select_target"
+                                clearable
+                                :placeholder="$t('Edb.InputHolderAll.input_name')"
+                                style="width: 250px"
+                                remote
+                                :remote-method="getTarget"
+                                @click.native="inputFocusHandle"
+                                @change="chooseTarget"
+                                @blur="search_have_more = false"
                             >
-                                <div>
-									<img 
-										:src="$icons.lock_ico2" 
-										width="18" 
-										height="18" 
-										style="vertical-align:middle" 
-										v-if="!item.HaveOperaAuth"
-									/>
-									{{$parent.currentLang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName}}
-								</div>
-                            </el-option>
-                        </el-select>
-                    </el-form-item>
-                    <el-form-item required :label="$t('EtaBasePage.formula_lable')">
-                        <el-input v-model="formData.formula" :placeholder="$t('EtaBasePage.input_formula_msg')" clearable style="width: 200px"/>
-                        <span>
-                            <!-- 公式示例:A+B,或A/B,A/(A+B) -->
-                         {{$t('EtaBasePage.formula_example_text_a_b')}}
-                        </span>
-                    </el-form-item>
-                    <el-form-item :label="$t('EtaBasePage.create_edb_time_index')">
-                        <el-cascader
-							v-model="formData.timeSeriesVal"
-							style="width:180px"
-							:options="timeSeriesOpt"
-							:props="{emitPath:false}"
-							:show-all-levels="false"
-							:placeholder="$t('Edb.please_select')"
-						></el-cascader>
-                    </el-form-item>
-                    <el-form-item :label="$t('EtaBasePage.null_val_deal')">
-                        <el-select
-							v-model="formData.nullValueWay"
-							:placeholder="$t('Edb.please_select')"
-                            style="width:180px"
-						>
-							<el-option
-								v-for="item in nullWayOptions"
-								:key="item.value"
-								:label="item.label"
-								:value="item.value"
-							>
-							</el-option>
-						</el-select>
-                    </el-form-item>
-                    <el-form-item :label="$t('EtaBasePage.max_null_val')" v-if="showMaxNullDeal">
-                        <el-select
-							v-model="formData.maxNullWay"
-							:placeholder="$t('Edb.please_select')"
-						>
-							<el-option :label="$t('EtaBasePage.equal_zeto')" :value="1" />
-							<el-option label="跳过空值" :value="2" />
-						</el-select>
-                    </el-form-item>
+                                <i slot="prefix" class="el-input__icon el-icon-search"></i>
+                                <el-option
+                                    v-for="item in searchOptions"
+                                    :key="item.EdbInfoId"
+                                    :label="$parent.currentLang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName"
+                                    :value="item.EdbInfoId"
+                                    :disabled="!item.HaveOperaAuth"
+                                >
+                                    <div>
+                                        <img 
+                                            :src="$icons.lock_ico2" 
+                                            width="18" 
+                                            height="18" 
+                                            style="vertical-align:middle" 
+                                            v-if="!item.HaveOperaAuth"
+                                        />
+                                        {{$parent.currentLang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName}}
+                                    </div>
+                                </el-option>
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item required :label="$t('EtaBasePage.formula_lable')">
+                            <el-input v-model="formData.formula" :placeholder="$t('EtaBasePage.input_formula_msg')" clearable style="width: 200px"/>
+                            <span>
+                                <!-- 公式示例:A+B,或A/B,A/(A+B) -->
+                            {{$t('EtaBasePage.formula_example_text_a_b')}}
+                            </span>
+                        </el-form-item>
+                        <el-form-item :label="$t('EtaBasePage.create_edb_time_index')">
+                            <el-cascader
+                                v-model="formData.timeSeriesVal"
+                                style="width:180px"
+                                :options="timeSeriesOpt"
+                                :props="{emitPath:false}"
+                                :show-all-levels="false"
+                                :placeholder="$t('Edb.please_select')"
+                            ></el-cascader>
+                        </el-form-item>
+                        <el-form-item :label="$t('EtaBasePage.null_val_deal')">
+                            <el-select
+                                v-model="formData.nullValueWay"
+                                :placeholder="$t('Edb.please_select')"
+                                style="width:180px"
+                            >
+                                <el-option
+                                    v-for="item in nullWayOptions"
+                                    :key="item.value"
+                                    :label="item.label"
+                                    :value="item.value"
+                                >
+                                </el-option>
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item :label="$t('EtaBasePage.max_null_val')" v-if="showMaxNullDeal">
+                            <el-select
+                                v-model="formData.maxNullWay"
+                                :placeholder="$t('Edb.please_select')"
+                            >
+                                <el-option :label="$t('EtaBasePage.equal_zeto')" :value="1" />
+                                <el-option label="跳过空值" :value="2" />
+                            </el-select>
+                        </el-form-item>
                     </template>
 
                     <!-- 多指标求和/平均 -->
                     <template v-if="computedType=='multipleEDB'">
-                    <el-form-item style="margin-right:30px">
-                    <el-radio-group :disabled="isEdit" v-model="subComputedType">
-                        <el-radio :label="81"><!--  -->{{$t('EtaBasePage.sum_radio_label')}}</el-radio>
-                        <el-radio :label="82"><!-- 求平均 -->{{$t('EtaBasePage.average_radio_label')}}</el-radio>
-                    </el-radio-group>
-                    </el-form-item>
-                    <el-form-item :label="$t('EtaBasePage.create_edb_time_index')">
-                        <el-cascader
-							v-model="formData.timeSeriesVal"
-							style="width:180px"
-							:options="timeSeriesOpt"
-							:props="{emitPath:false}"
-							:show-all-levels="false"
-							:placeholder="$t('Edb.please_select')"
-						></el-cascader>
-                    </el-form-item>
-                    <el-form-item :label="$t('EtaBasePage.null_val_deal')">
-                        <el-select
-							v-model="formData.nullValueWay"
-							:placeholder="$t('Edb.please_select')"
-                            style="width:180px"
-						>
-							<el-option
-								v-for="item in nullWayOptions"
-								:key="item.value"
-								:label="item.label"
-								:value="item.value"
-							>
-							</el-option>
-						</el-select>
-                    </el-form-item>
+                        <el-form-item style="margin-right:30px">
+                        <el-radio-group :disabled="isEdit" v-model="subComputedType">
+                            <el-radio :label="81"><!--  -->{{$t('EtaBasePage.sum_radio_label')}}</el-radio>
+                            <el-radio :label="82"><!-- 求平均 -->{{$t('EtaBasePage.average_radio_label')}}</el-radio>
+                        </el-radio-group>
+                        </el-form-item>
+                        <el-form-item :label="$t('EtaBasePage.create_edb_time_index')">
+                            <el-cascader
+                                v-model="formData.timeSeriesVal"
+                                style="width:180px"
+                                :options="timeSeriesOpt"
+                                :props="{emitPath:false}"
+                                :show-all-levels="false"
+                                :placeholder="$t('Edb.please_select')"
+                            ></el-cascader>
+                        </el-form-item>
+                        <el-form-item :label="$t('EtaBasePage.null_val_deal')">
+                            <el-select
+                                v-model="formData.nullValueWay"
+                                :placeholder="$t('Edb.please_select')"
+                                style="width:180px"
+                            >
+                                <el-option
+                                    v-for="item in nullWayOptions"
+                                    :key="item.value"
+                                    :label="item.label"
+                                    :value="item.value"
+                                >
+                                </el-option>
+                            </el-select>
+                        </el-form-item>
                     </template>
 
                     <!-- 升频 -->
                     <template v-if="computedType==14">
-                    <el-form-item :label="$t('EtaBasePage.null_val_deal')" prop="emptyType">
-                        <el-select
-                            v-model="formData.emptyType"
-                            :placeholder="$t('Edb.InputHolderAll.input_fre')"
-                        >
-                            <el-option :label="$t('EtaBasePage.null_val_deal_2')" :value="0"></el-option>
-                            <el-option :label="$t('EtaBasePage.null_val_deal_3')" :value="3"></el-option>
-                        </el-select>
-				    </el-form-item>
+                        <el-form-item :label="$t('EtaBasePage.null_val_deal')" prop="emptyType">
+                            <el-select
+                                v-model="formData.emptyType"
+                                :placeholder="$t('Edb.InputHolderAll.input_fre')"
+                            >
+                                <el-option :label="$t('EtaBasePage.null_val_deal_2')" :value="0"></el-option>
+                                <el-option :label="$t('EtaBasePage.null_val_deal_3')" :value="3"></el-option>
+                            </el-select>
+                        </el-form-item>
                     </template>
 
                 </div>
@@ -884,7 +884,7 @@ export default {
 		},
         // 获取指标分类
         async getClassifyOpt(){
-            const res=await dataBaseInterface.menuListV3()
+            const res=await dataBaseInterface.menuListV3({ClassifyType:-1})
             if (res.Ret !== 200) return
             this.filterNodes(res.Data.AllNodes||[]);
 			this.classifyOpt = res.Data.AllNodes || [];

+ 1 - 0
src/views/dataEntry_manage/databaseComponents/chartTrendRender.vue

@@ -227,6 +227,7 @@ export default {
 		
 		getDataByPath() {
 			const apiMap = {
+				'/edbBasicbase': this.getEdbData,
 				'/database': this.getEdbData,
 				'/analyseVariety': this.getPlantEdbData
 			}

+ 114 - 0
src/views/dataEntry_manage/databaseComponents/collectEdbMenu.vue

@@ -0,0 +1,114 @@
+<template>
+    <el-tree
+        ref="catalogTree"
+        class="catalog-tree other-tree"
+        empty-text="暂无图库"
+        :data="data"
+        :allow-drop="canDropHandle"
+        draggable
+        node-key="ClassifyId"
+        :expand-on-click-node="false"
+        @current-change="(data,node)=>{$parent.nodeChange(data,node)}"
+        @node-drop="handleDropClassify"
+        >
+        <div class="custom-tree-node" slot-scope="{ data }">
+            <span class="tree-label">{{ data.ClassifyName }}</span>
+            <div class="right-item right-item-box" >
+                <img
+                  src="~@/assets/img/set_m/edit.png"
+                  alt=""
+                  style="width: 15px; height: 14px; margin-right: 8px"
+                  @click.stop="$parent.handleOpenCollectClassify(data)"
+                  v-if="!data.EdbCode&&$parent.isEdbBtnShow('edbData_edbCollectClassify_save')"
+                />
+
+                <img
+                  src="~@/assets/img/set_m/del_icon.png"
+                  alt=""
+                  style="width: 14px; height: 14px;"
+                  @click.stop="removeCollectNode(data)"
+                  v-if="!data.EdbCode&&$parent.isEdbBtnShow('edbData_edbCollectClassify_remove')"
+                />
+            </div>
+        </div>
+    </el-tree>
+</template>
+
+<script>
+import { edbCollectInterface } from '@/api/modules/chartApi'
+export default {
+  props: {
+    data: {
+      type: Object
+    }
+  },
+  data() {
+    return {
+    }
+  },
+  methods: {
+    removeCollectNode({ClassifyId}) {
+      this.$confirm('若删除该目录,则目录下收藏的所有指标将被清除, 是否继续?',
+          '提示',
+          { type: 'warning' }
+      ).then(async () => {
+        const res = await edbCollectInterface.delCollectClassify({
+          ClassifyId
+        })
+
+        if(res.Ret !== 200) return
+        this.$message.success('删除成功')
+
+        this.$emit('change')
+      })
+      
+    },
+
+    async handleDropClassify(dragNode,dropNode,type) {
+      console.log(dragNode,dropNode,type)
+      let PrevClassifyId,NextClassifyId;
+
+      let list = dropNode.parent.childNodes;
+      let targetIndex = list.findIndex(_ => _.data.ClassifyId===dragNode.data.ClassifyId)
+
+      if(targetIndex===0){
+        const data=list[targetIndex+1].data
+        NextClassifyId = data.ClassifyId
+        PrevClassifyId = 0
+      }else if(targetIndex===list.length-1){
+        const data=list[targetIndex-1].data
+        PrevClassifyId = data.ClassifyId
+        NextClassifyId = 0
+      }else{
+        PrevClassifyId=list[targetIndex-1].data.ClassifyId
+        NextClassifyId=list[targetIndex+1].data.ClassifyId
+      }
+
+      let params = {
+        ClassifyId: dragNode.data.ClassifyId,
+        PrevClassifyId,
+        NextClassifyId
+      }
+
+      const res = await edbCollectInterface.moveCollectClassify(params)
+      if(res.Ret !== 200) return 
+      this.$message.success('移动成功')
+    },
+
+    canDropHandle(draggingNode, dropNode, type) {
+      return dropNode.level===draggingNode.level&&type!=='inner'
+    },
+
+    initSelect(id) {
+      console.log(id)
+      this.$nextTick(() => {
+        this.$refs.catalogTree.setCurrentKey(id);
+      })
+    }
+  }
+}
+</script>
+
+<style>
+
+</style>

+ 1 - 1
src/views/dataEntry_manage/databaseComponents/computedDialog.vue

@@ -522,7 +522,7 @@ export default {
 		async getMenu() {
 			const res = this.edbSource === 'predict'
 				? await preDictEdbInterface.classifyListV2()
-				: await dataBaseInterface.menuListV3()
+				: await dataBaseInterface.menuListV3({ClassifyType:2})
 				if (res.Ret !== 200) return
 				
 				this.filterNodes(res.Data.AllNodes||[]);

+ 2 - 35
src/views/dataEntry_manage/databaseComponents/dataAssociateChart.vue

@@ -22,48 +22,15 @@
                         :style="{background: `no-repeat top/cover url('${!chart.HaveOperaAuth ? $icons.lock_big : chart.ChartImage}')`}"></div>
                     <div class="chart-item-bottom">
                         <span>{{$t('Chart.list_chart_time')}}: {{ chart.CreateTime.slice(0,10) }}</span>
-                        <span class="join_txt" @click="addMychartHandle(chart)" v-if="chart.HaveOperaAuth">
+                        <!-- <span class="join_txt" @click="addMychartHandle(chart)" v-if="chart.HaveOperaAuth">
                             <img :src="$icons.chart_join_ico"
                                 style="width: 13px; height: 12px; vertical-align: middle"/>
-                            <!-- 加入我的图库 -->
                             {{$t('Chart.chart_addmy_btn')}}
-                        </span>
+                        </span> -->
                     </div>
                 </div>
 
             </div>
-            <!-- <el-col
-                :span="6"
-                style="margin-bottom: 20px; padding-right: 20px"
-                v-for="chart in list"
-                :key="chart.ChartInfoId"
-            >
-                <el-card class="public-chart-item">
-                    <div slot="header" class="item-top">
-                        <span class="text_oneLine">{{ chart.ChartName }}</span>
-                    </div>
-                    <img
-                        :src="chart.ChartImage"
-                        alt=""
-                        class="chart-img"
-                        @click="detailShowHandle(chart)"
-                    />
-                    <div class="item-bottom">
-                        <span>创建时间: {{ chart.CreateTime.slice(0,10) }}</span>
-                        <span
-                            class="join_txt"
-                            @click="addMychartHandle(chart)"
-                        >
-                            <img
-                                :src="$icons.chart_join_ico"
-                                alt=""
-                                style="width: 13px; height: 12px; vertical-align: middle"
-                            />
-                            加入我的图库
-                        </span>
-                    </div>
-                </el-card>
-            </el-col> -->
         </div>
         </template>
 

+ 1 - 1
src/views/dataEntry_manage/databaseComponents/diffusionIndexDia.vue

@@ -347,7 +347,7 @@ export default {
 		async getMenu() {
 			const res = this.isPredict
       ? await preDictEdbInterface.classifyListV2()
-      : await dataBaseInterface.menuListV3()
+      : await dataBaseInterface.menuListV3({ClassifyType:2})
 				if (res.Ret === 200) {
 					this.filterNodes(res.Data.AllNodes||[]);
 					this.options = res.Data.AllNodes || [];

+ 149 - 0
src/views/dataEntry_manage/databaseComponents/edbCollectDia.vue

@@ -0,0 +1,149 @@
+<template>
+  <div class="edbCollectDia-container">
+    <el-dialog
+      :visible.sync="show"
+      :close-on-click-modal="false"
+      :modal-append-to-body="false"
+      title="收藏"
+      @close="cancelHandle"
+      custom-class="dialog"
+      center
+      width="560px"
+      v-dialogDrag
+    >
+      <div class="dialog-min">
+        <div class="classify-cont">
+          <el-tag
+            v-for="item in classifyArr"
+            :class="['classify-tag',{'act': checkedClassifys.includes(item.ClassifyId)}]"
+            :key="item.ClassifyId"
+            type="info"
+            effect="plain"
+            @click="chooseClassify(item.ClassifyId)"
+          >
+            {{ item.ClassifyName }}
+          </el-tag>
+        </div>
+        <span class="add-cont" @click="$parent.handleOpenCollectClassify">
+          <i class="el-icon-circle-plus-outline" />新增
+        </span>
+      </div>
+      <div class="dia-bot">
+        <el-button type="primary" style="margin-right: 20px" @click="saveHandle"
+          >{{$t('Dialog.confirm_save_btn')}}</el-button
+        >
+        <el-button type="primary" plain @click="cancelHandle">{{$t('Dialog.cancel_btn')}}</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { edbCollectInterface } from '@/api/modules/chartApi'
+export default {
+	name:'',
+	props: {
+		show: {
+			type: Boolean,
+		},
+    edbId: {
+      type: Number,
+    },
+    add_ids: {
+      type: Array,
+      default: []
+    }
+	},
+	watch: {
+		show(newval) {
+			if(newval) {
+				this.getClassify();
+			}
+		}
+	},
+	data () {
+		return {
+			classifyArr:[],//分类列表
+      checkedClassifys: [],
+			addRules: {
+				name:[
+					{ required: true, message: /* '分类名称不能为空' */this.$t('Chart.Vailds.classify_msg'), trigger: 'blur' },
+				],
+			}
+		};
+	},
+	methods: {
+		/* 获取分类列表 */
+		getClassify() {
+			edbCollectInterface.getEdbCollectClassifyOne()
+				.then(res => {
+					if(res.Ret !== 200) return
+					this.classifyArr = res.Data || [];
+          this.checkedClassifys = _.cloneDeep(this.add_ids);
+				})
+		},
+
+    chooseClassify(id) {
+      if(this.checkedClassifys.includes(id)) {
+        let index = this.checkedClassifys.indexOf(id);
+        this.checkedClassifys.splice(index, 1);
+      }else {
+        this.checkedClassifys.push(id);
+      }
+    },
+
+    /* 加入收藏 */
+    saveHandle() {
+      if(!this.checkedClassifys.length) return this.$message.warning('请选择分类');
+      edbCollectInterface.edbCollect({
+        EdbInfoId: this.edbId,
+        ClassifyIdList: this.checkedClassifys
+      }).then(res => {
+        if(res.Ret !== 200) return 
+        this.$message.success('收藏成功')
+        this.$emit('success',this.checkedClassifys)
+        this.cancelHandle()
+      })
+    },
+    
+		cancelHandle() {
+      this.checkedClassifys = [];
+			this.$emit('update:show')
+		}
+	},
+}
+</script>
+<style lang="scss">
+.edbCollectDia-container {
+  .el-dialog--center .el-dialog__body {
+    padding: 25px 25px 30px !important;
+  }
+  .dialog-min {
+    .classify-cont {
+      padding: 30px 10px;
+      border: 1px dashed #999;
+      display: flex;
+      flex-wrap: wrap;
+      margin-bottom: 20px;
+      .classify-tag {
+        margin: 5px;
+        padding: 0 20px;
+        cursor: pointer;
+        &.act {
+          background: #409eff;
+          color: #fff;
+        }
+      }
+    }
+    .add-cont {
+      color: #409eff;
+      cursor: pointer;
+    }
+  }
+  .dia-bot {
+    margin: 52px 0 30px;
+    display: flex;
+    justify-content: center;
+  }
+}
+</style>

+ 1 - 1
src/views/dataEntry_manage/databaseComponents/fittingResidueDia.vue

@@ -390,7 +390,7 @@ export default {
 		async getMenu() {
 			const res=this.isPredict
 				?await preDictEdbInterface.classifyListV2()
-				:await dataBaseInterface.menuListV3()
+				:await dataBaseInterface.menuListV3({ClassifyType:2})
 
 				if (res.Ret === 200) {
 					

+ 1 - 1
src/views/dataEntry_manage/databaseComponents/jointTargetDia.vue

@@ -549,7 +549,7 @@ export default {
 
 		/* 获取目录结构 */
 		async getMenu() {
-			const res=this.isPredict?await preDictEdbInterface.classifyListV2():await dataBaseInterface.menuListV3()
+			const res=this.isPredict?await preDictEdbInterface.classifyListV2():await dataBaseInterface.menuListV3({ClassifyType:2})
 			// dataBaseInterface.menuList().then(res => {
 				if(res.Ret === 200) {
 					if(!this.isPredict){

+ 5 - 1
src/views/dataEntry_manage/databaseComponents/openDialog.vue

@@ -99,6 +99,9 @@ export default {
 		},
 		formData: {
 			type: Object,//{parentArr父级数据,isEDB:true 是否为指标}
+		},
+		isBasicBase: {
+			type: Boolean
 		}
 	},
 	watch: {
@@ -175,7 +178,8 @@ export default {
           res = await dataBaseInterface.nodeAdd({
 						ClassifyName: this.formData.levelVal||'',
 						ParentId:this.formData.parent_id || 0,
-						Level: this.formData.level
+						Level: this.formData.level,
+						ClassifyType: this.isBasicBase ? 0 : 2
 					})
         }
 				

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

@@ -597,7 +597,7 @@ export default {
 
 		/* 获取目录结构 */
 		getMenu() {
-			dataBaseInterface.menuListV3().then((res) => {
+			dataBaseInterface.menuListV3({ClassifyType:2}).then((res) => {
 				if (res.Ret === 200) {
 					this.filterNodes(res.Data.AllNodes||[]);
 					this.options = res.Data.AllNodes || [];
@@ -868,8 +868,10 @@ export default {
             if(this.tableData[0].EdbType===2){
                 this.$emit('lookHistory',this.select_target)
             }else{
-                const {ClassifyId,UniqueCode,EdbInfoId} = this.tableData[0]
-                let {href} = this.$router.resolve({path:`/database`,query:{code:UniqueCode,id:EdbInfoId,classifyId:ClassifyId}});
+                const {ClassifyId,UniqueCode,EdbInfoId,HaveOperaAuth} = this.tableData[0]
+								if(!HaveOperaAuth) return this.$message.warning('暂无指标权限')
+
+                let {href} = this.$router.resolve({path:'/edbBasicbase',query:{code:UniqueCode,id:EdbInfoId,classifyId:ClassifyId}});
                 window.open(href,'_blank');
             }
         },

+ 5 - 3
src/views/dataEntry_manage/databaseComponents/smoothEdbDialog.vue

@@ -476,7 +476,7 @@ export default {
         async getMenu() {
             const res = this.isPredict
                 ? await preDictEdbInterface.classifyListV2()
-                : await dataBaseInterface.menuListV3()
+                : await dataBaseInterface.menuListV3({ClassifyType:2})
             if(res.Ret!==200) return 
             // this.catalogArr = res.Data.AllNodes || [];
             if(!this.isPredict){
@@ -560,8 +560,10 @@ export default {
             if(this.tableData[0].EdbType===2){
                 this.$emit('lookHistory',this.select_target)
             }else{
-                const {ClassifyId,UniqueCode,EdbInfoId} = this.tableData[0]
-                let {href} = this.$router.resolve({path:`/database`,query:{code:UniqueCode,id:EdbInfoId,classifyId:ClassifyId}});
+                const {ClassifyId,UniqueCode,EdbInfoId,HaveOperaAuth} = this.tableData[0]
+                if(!HaveOperaAuth) return this.$message.warning('暂无指标权限')
+                
+                let {href} = this.$router.resolve({path:'/edbBasicbase',query:{code:UniqueCode,id:EdbInfoId,classifyId:ClassifyId}});
                 window.open(href,'_blank');
             }
         },

+ 396 - 225
src/views/dataEntry_manage/databaseList.vue

@@ -2,23 +2,23 @@
 	<div class="database_container">
 		<div class="database_top">
 			<div class="top-left">
-				<el-button v-permission="permissionBtn.edbDataPermission.edbData_addEdb"
-					type="primary" @click="addHandler"><!-- 添加指标 -->{{$t('EtaBasePage.add_edb_btn')}}</el-button>
-				<el-button v-permission="permissionBtn.edbDataPermission.edbData_calcuEdb"
-					type="primary" @click="addComputedHandler"><!-- 计算指标 -->{{$t('EtaBasePage.calculation_edb_btn')}}</el-button>
-				<el-button v-permission="permissionBtn.edbDataPermission.edbData_replaceEdb"
-					type="primary" @click="replaceEdbHandler"><!-- 替换指标 -->{{$t('EtaBasePage.replace_edb_btn')}}</el-button>
-				<el-button v-permission="permissionBtn.edbDataPermission.edbData_codeRun"
-					type="primary" @click="$router.push({path: '/codecount'})"><!-- 代码运算 -->{{$t('EtaBasePage.algorithm_btn')}}</el-button>
-				<el-button v-permission="permissionBtn.edbDataPermission.edbData_dataAdjust"
-					type="primary" @click="$router.push({path: '/adjustdata'})"><!-- 数据调整 -->{{$t('EtaBasePage.adjustment_btn')}}</el-button>
-				<!-- <el-button v-permission="permissionBtn.edbDataPermission.edbData_batchUpdate"
-					type="primary" plain @click="updateHandler">一键刷新</el-button> -->
+				<template v-if="!isBasicBase">
+					<el-button v-permission="permissionBtn.edbDataPermission.edbData_addEdb"
+						type="primary" @click="addHandler"><!-- 添加指标 -->{{$t('EtaBasePage.add_edb_btn')}}</el-button>
+					<el-button v-permission="permissionBtn.edbDataPermission.edbData_calcuEdb"
+						type="primary" @click="addComputedHandler"><!-- 计算指标 -->{{$t('EtaBasePage.calculation_edb_btn')}}</el-button>
+					<el-button v-permission="permissionBtn.edbDataPermission.edbData_replaceEdb"
+						type="primary" @click="replaceEdbHandler"><!-- 替换指标 -->{{$t('EtaBasePage.replace_edb_btn')}}</el-button>
+					<el-button v-permission="permissionBtn.edbDataPermission.edbData_codeRun"
+						type="primary" @click="$router.push({path: '/codecount'})"><!-- 代码运算 -->{{$t('EtaBasePage.algorithm_btn')}}</el-button>
+					<el-button v-permission="permissionBtn.edbDataPermission.edbData_dataAdjust"
+						type="primary" @click="$router.push({path: '/adjustdata'})"><!-- 数据调整 -->{{$t('EtaBasePage.adjustment_btn')}}</el-button>
+				</template>
 			</div>
 			<div class="top-right">
 
-
 				<el-select
+					v-if="classifyShowType==='public'"
 					v-model="search_txt"
 					v-loadMore="searchLoad"
 					ref="searchRef"
@@ -49,9 +49,20 @@
 						</div>
 					</el-option>
 				</el-select>
+
+				<el-input
+					v-else
+					v-model="searchCollectWord" 
+					:placeholder="$t('Edb.InputHolderAll.input_name_orid')"
+					style="width: 260px;"
+					@change="getEdbChartList"
+					clearable
+				>
+					<i slot="prefix" class="el-input__icon el-icon-search"/>
+				</el-input>
 			</div>
 		</div>
-		<div class="database-label">
+		<!-- <div class="database-label">
 			<edb-label-list 
 				:currentLang="currentLang"
 				:labelList="labelList"
@@ -60,7 +71,7 @@
 				@deleteLabel="deleteLabel"
 				@moveLabel="({oldIndex,newIndex})=>{labelList[oldIndex] = labelList.splice(newIndex, 1, labelList[oldIndex])[0];}"
 				/>
-		</div>
+		</div> -->
 		<div class="database_main box" id="box" v-if="showData">
 			<!-- 展开收起目录按钮 -->
 			<span
@@ -70,138 +81,156 @@
 			>
 				<i :class="{'el-icon-d-arrow-left':isMainLeftShow,'el-icon-d-arrow-right':!isMainLeftShow}"></i>
 			</span>
-			<!-- <target-tree /> -->
+			
 			<div class="main-left left" id="left" v-show="isMainLeftShow">
+
 				<div class="tree-cont">
-					<div style="padding-bottom:20px;padding-right:20px;display:flex;justify-content:space-between">
+					<el-radio-group 
+						v-model="classifyShowType" 
+						@input="handleChangeClassifyType" 
+						v-if="isBasicBase"
+					>
+						<el-radio-button label="public">
+							公共指标库
+						</el-radio-button>
+						<el-radio-button label="own">
+							个人收藏
+						</el-radio-button>
+					</el-radio-group>
+
+					<div style="padding:20px 0;padding-right:20px;display:flex;justify-content:space-between">
 						<span><!-- 目录 -->{{$t('EtaBasePage.tab_menu')}}</span>
-						<el-checkbox 
+						<!-- <el-checkbox 
 							v-model="IsOnlyMe"
 							@change="onlyMeHandler"
-						><!-- 只看我的 -->{{$t('Edb.only_see_mine')}}</el-checkbox>
+						>{{$t('Edb.only_see_mine')}}</el-checkbox> -->
 					</div>
 					<div class="target_tree">
-					<el-tree
-						ref="menuTree"
-						:data="treeData"
-						node-key="UniqueCode"
-						:props="defaultProp"
-						:allow-drag="canDragHandle"
-						:allow-drop="canDropHandle"
-						:current-node-key="select_node"
-						:default-expanded-keys="defaultShowNodes"
-						:draggable="isEdbBtnShow('moveCatalog')"
-						:expand-on-click-node="false"
-						check-strictly
-						empty-text="暂无目录"
-						lazy
-						:load="getLazyTreeData"
-						@node-expand="handleNodeExpand"
-						@node-collapse="handleNodeCollapse"
-						@current-change="nodeChange"
-						@node-drop="dropOverHandle"
-						@node-drag-end="dropMouseLeave"
-						@node-drag-leave="dropMouseLeave"
-						@node-drag-enter="dropMouseOver"
-					>
-						<span
-							class="custom-tree-node"
-							slot-scope="{ node, data }"
+						<!-- 指标目录 -->
+						<el-tree
+							v-if="classifyShowType==='public'"
+							ref="menuTree"
+							:data="treeData"
+							node-key="UniqueCode"
+							:props="defaultProp"
+							:allow-drag="canDragHandle"
+							:allow-drop="canDropHandle"
+							:current-node-key="select_node"
+							:default-expanded-keys="defaultShowNodes"
+							:draggable="isEdbBtnShow('moveCatalog')"
+							:expand-on-click-node="false"
+							check-strictly
+							empty-text="暂无目录"
+							lazy
+							:load="getLazyTreeData"
+							@node-expand="handleNodeExpand"
+							@node-collapse="handleNodeCollapse"
+							@current-change="nodeChange"
+							@node-drop="dropOverHandle"
+							@node-drag-end="dropMouseLeave"
+							@node-drag-leave="dropMouseLeave"
+							@node-drag-enter="dropMouseOver"
 						>
-							<el-input
-								ref="editVal"
-								style="width: 90px"
-								placeholder="请输入值"
-								class="label-input"
-								v-model="new_label"
-								v-if="data.isEdit&&isEdbBtnShow('editCatalog')"
-								@blur="changeValue(node, data)"
-							/>
-							<span 
-								@dblclick.stop="editNodeLabel(node, data)" 
-								v-else 
-								class="text_oneLine node_label" 
-								:style="`width:${(select_node === data.UniqueCode && node.Nodewidth) || ''}`"
-								:id="`node${data.UniqueCode}`"
-							>
-								<img 
-									:src="$icons.lock_ico2" 
-									width="18" 
-									height="18" 
-									style="vertical-align:middle" 
-									v-if="!data.HaveOperaAuth&&data.EdbInfoId"
-								/>
-								<span>{{ currentLang==='en' ? (data.ClassifyNameEn||data.ClassifyName) : data.ClassifyName }}</span>
-							</span>
 							<span
-								style="display: flex; align-items: center"
-								v-if="select_node===data.UniqueCode&&data.HaveOperaAuth"
+								class="custom-tree-node"
+								slot-scope="{ node, data }"
 							>
-								<!-- <img
-									src="~@/assets/img/data_m/move_ico.png"
-									alt=""
-									style="width: 14px; height: 14px; margin-right: 8px"
-									v-if="data.Button.MoveButton&&isEdbBtnShow('moveCatalog')"
-								/> -->
-								<!-- 添加子项 -->
-								<img
-									src="~@/assets/img/set_m/add.png"
-									alt=""
-									style="width: 14px; height: 14px; margin-right: 8px"
-									@click.stop="addNode(node,data)"
-									v-if="data.Button.AddButton&&isEdbBtnShow('editCatalog')&&node.level<6"
-								/>
-								<!-- 编辑节点 如果是分类,判断data.Button.OpButton不变;如果是指标,不显示(ETA1.0.3) -->
-								<img
-									src="~@/assets/img/set_m/edit.png"
-									alt=""
-									style="width: 15px; height: 14px; margin-right: 8px"
-									@click.stop="editNode(node,data)"
-									v-if="!data.EdbCode&&(data.Button.OpButton)&&isEdbBtnShow('editCatalog')"
+								<el-input
+									ref="editVal"
+									style="width: 90px"
+									placeholder="请输入值"
+									class="label-input"
+									v-model="new_label"
+									v-if="data.isEdit&&isEdbBtnShow('editCatalog')"
+									@blur="changeValue(node, data)"
 								/>
-								<!-- 删除节点 如果是分类,判断data.Button.DeleteButton不变;如果是指标,不显示(ETA1.0.3) -->
-								<img
-									slot="reference"
-									src="~@/assets/img/set_m/del.png"
-									alt=""
-									style="width: 14px; height: 14px;"
-									@click.stop="removeNode(node,data)"
-									v-if="!data.EdbCode&&(data.Button.DeleteButton)&&isEdbBtnShow('deleteCatalog')"
-								/>
-								<!-- 查看计算指标 -->
-								<!-- <i class="el-icon-view" 
-									v-if="data.EdbType===2&&![58,59,67,68,74].includes(data.Source)&&isEdbBtnShow('checkCalcChart')" 
-									@click.stop="viewNode(node,data)"></i> -->
-								<!-- 查看关联图表 -->
-								<!-- <img 
-									v-if="data.Button.ShowChartRelation&&isEdbBtnShow('checkRelatedChart')" 
-									@click.stop="showAssociateChart=true,showAssociateComputeData=false"
-									src="~@/assets/img/icons/associate_chart.png" 
-									style="width: 14px; height: 14px;margin-left: 8px"
-									alt=""
-								/> -->
-								<!-- 查看关联指标 -->
-								<!-- <img 
-									v-if="data.Button.ShowEdbRelation&&isEdbBtnShow('checkRelatedEdb')" 
-									@click.stop="showAssociateComputeData=true,showAssociateChart=false"
-									src="~@/assets/img/icons/associate_data.png" 
-									style="width: 14px; height: 14px;margin-left: 8px"
-									alt=""
-								/> -->
+								<span 
+									@dblclick.stop="editNodeLabel(node, data)" 
+									v-else 
+									class="text_oneLine node_label" 
+									:style="`width:${(select_node === data.UniqueCode ? '40%' :'90%') || ''}`"
+									:id="`node${data.UniqueCode}`"
+								>
+									<img 
+										:src="$icons.lock_ico2" 
+										width="18" 
+										height="18" 
+										style="vertical-align:middle" 
+										v-if="!data.HaveOperaAuth&&data.EdbInfoId"
+									/>
+									<span>{{ currentLang==='en' ? (data.ClassifyNameEn||data.ClassifyName) : data.ClassifyName }}</span>
+								</span>
+								<span
+									style="display: flex; align-items: center"
+									v-if="select_node===data.UniqueCode&&data.HaveOperaAuth"
+								>
+									<!-- <img
+										src="~@/assets/img/data_m/move_ico.png"
+										alt=""
+										style="width: 14px; height: 14px; margin-right: 8px"
+										v-if="data.Button.MoveButton&&isEdbBtnShow('moveCatalog')"
+									/> -->
+									<!-- 添加子项 -->
+									<img
+										src="~@/assets/img/set_m/add.png"
+										alt=""
+										style="width: 14px; height: 14px; margin-right: 8px"
+										@click.stop="addNode(node,data)"
+										v-if="data.Button.AddButton&&isEdbBtnShow('editCatalog')&&node.level<9"
+									/>
+									<!-- 编辑节点 如果是分类,判断data.Button.OpButton不变;如果是指标,不显示(ETA1.0.3) -->
+									<img
+										src="~@/assets/img/set_m/edit.png"
+										alt=""
+										style="width: 15px; height: 14px; margin-right: 8px"
+										@click.stop="editNode(node,data)"
+										v-if="!data.EdbCode&&(data.Button.OpButton)&&isEdbBtnShow('editCatalog')"
+									/>
+									<!-- 删除节点 如果是分类,判断data.Button.DeleteButton不变;如果是指标,不显示(ETA1.0.3) -->
+									<img
+										slot="reference"
+										src="~@/assets/img/set_m/del_icon.png"
+										alt=""
+										style="width: 14px; height: 14px;"
+										@click.stop="removeNode(node,data)"
+										v-if="!data.EdbCode&&(data.Button.DeleteButton)&&isEdbBtnShow('deleteCatalog')"
+									/>
+								
+								</span>
 							</span>
-						</span>
-					</el-tree>
-					</div>
-					<div class="noDepart" @click="addLevelOneHandle" v-if="CanOpClassify&&isEdbBtnShow('editCatalog')">
-						<img
-							src="~@/assets/img/set_m/add_ico.png"
-							alt=""
-							style="width: 16px; height: 16px; margin-right: 10px"
+						</el-tree>
+
+						<!-- 收藏目录 -->
+						<collectEdbMenu
+							v-else
+							:data="treeData"
+							@change="getTreeData"
+							ref="collectEdbMenuRef"
 						/>
-						<span>{{$t('EtaBasePage.add_first_menu_btn')}}</span>
 					</div>
+
+					<template>
+						<!-- 新增分类 -->
+						<div class="noDepart" @click="addLevelOneHandle" v-if="classifyShowType==='public'&&CanOpClassify&&isEdbBtnShow('editCatalog')">
+							<img
+								src="~@/assets/img/set_m/add_ico.png"
+								alt=""
+								style="width: 16px; height: 16px; margin-right: 10px"
+							/>
+							<span>{{$t('EtaBasePage.add_first_menu_btn')}}</span>
+						</div>
+						<!-- 新增收藏分类 -->
+						<div class="noDepart" @click="handleOpenCollectClassify" v-if="classifyShowType==='own'&&isEdbBtnShow('edbData_edbCollectClassify_save')">
+							<img
+								src="~@/assets/img/set_m/add_ico.png"
+								alt=""
+								style="width: 16px; height: 16px; margin-right: 10px"
+							/>
+							<span>{{$t('EtaBasePage.add_first_menu_btn')}}</span>
+						</div>
+					</template>
 				</div>
-				<span class="move-btn resize" v-drag id="resize" @mousemove="dynamicNode&&resetNodeStyle(dynamicNode)">
+				<span class="move-btn resize" v-drag id="resize" >
 				</span>
 				<span
 					v-show="isMainLeftShow"
@@ -222,31 +251,51 @@
 			<div class="main-right right list" id="right" v-show="isShowList">
 				<p>{{$t('EtaBasePage.total_show',{limit: Total||0})}}</p>
 				<div class="list-wrap" ref="listRef" @scroll="loadMoreHandle" v-if="Total">
-					<div class="chart-list-item-wrap">
+					<!-- <div class="chart-list-item-wrap"> -->
+					<draggable
+							v-model="chartList"
+							class="chart-list-item-wrap"
+							animation="300"
+							tag="div"
+							:disabled="classifyShowType!=='own'"
+							@start="menuDragStart"
+							@update="menuDragenter"
+							@end="collectDragOver"
+					>
 						<div class="list-item" v-for="item in chartList" :key="item.EdbInfoId">
 							<div class="header">
-								<span v-show="currentLang=='zh'">{{ item.EdbName }}</span> 
-								<span v-show="currentLang=='en'">{{ item.EdbNameEn || item.EdbName }}</span>
+								<span class="text_oneLine">{{ item.EdbName }}</span>
+
+								<img 
+									v-if="classifyShowType==='own'"
+									src="~@/assets/img/data_m/move_ico.png"
+									class="move"
+									style="width: 14px; height: 14px;"
+								/>
 							</div>
 							<div class="image" @click="detailShowHandle(item)"
-								:style="{background: `no-repeat top/cover url('${!item.HaveOperaAuth ? $icons.lock_big : item.ChartImage}')`}">
+								:style="{background: `no-repeat top/cover url('${ item.ChartImage}')`}">
 							</div>
 							<div class="info">
-								{{$t('EtaBasePage.time_show')}}:{{item.CreateTime.substring(0,10)}}
+								{{$t('EtaBasePage.time_show')}}:{{item.CreateTime?item.CreateTime.substring(0,10):''}}
 								<!-- wind和钢联化工的指标、计算指标显示 启用/停用-->
 								<span v-if="([2,34].includes(item.Source) || item.EdbType==2) && isEdbBtnShow('enableOrDisable')&&item.IsSupplierStop!=1" 
 								class="enable-toggle-btn" :style="{'color': item.NoUpdate==1?'#0052D9':'#D54941'}"
 								@click="toggleEdbRefreshStatus(item)">{{item.NoUpdate==1?$t('SystemManage.DataRefresh.enable'):$t('SystemManage.DataRefresh.disable') }}</span>
+
+								<span class="deletesty" v-if="classifyShowType==='own'&&isEdbBtnShow('edbData_edbCollect_collect')" @click="handleRemoveCollect(item)">移出</span>
 							</div>
 							<img src="~@/assets/img/icons/edb-stopping.png" class="stop-mark" v-if="([2,34].includes(item.Source) || item.EdbType==2) && ( item.IsSupplierStop==1 || (item.IsSupplierStop==0&&item.NoUpdate==1))" />
 						</div>
-					</div>
+					</draggable>	
+					<!-- </div> -->
 					
 				</div>
 				<div v-if="!Total" class="nodata">
 					<tableNoData :text="$t('Table.no_edb_msg')"/>
 				</div>
 			</div>
+
 			<!-- 指标详情 -->
 			<div class="main-right right detail-wrap" id="right" v-show="isShowDetail">
 				<div class="detail" v-if="EdbData.HaveOperaAuth">
@@ -258,10 +307,19 @@
 							</el-tab-pane>
 						</el-tabs>
 						<div class="edb-tool-icon edb-tool" style="align-items: center;">
-							<el-button v-if="([2,34].includes(EdbData.Source) || EdbData.EdbType==2) && isEdbBtnShow('enableOrDisable')&&EdbData.IsSupplierStop!=1" 
-								type="text" :style="{'color': EdbData.NoUpdate==1?'#0052D9':'#D54941'}"
+							<el-button 
+								v-if="([2,34].includes(EdbData.Source) || EdbData.EdbType==2) && isEdbBtnShow('enableOrDisable')&&EdbData.IsSupplierStop!=1" 
+								type="text" 
+								:style="{'color': EdbData.NoUpdate==1?'#0052D9':'#D54941'}"
 								@click="toggleEdbRefreshStatus(EdbData,'detail')" 
 							>{{EdbData.NoUpdate==1?$t('SystemManage.DataRefresh.enable'):$t('SystemManage.DataRefresh.disable') }}<!-- 启用/停用 --></el-button>
+
+							<el-button 
+								v-if="isBasicBase&&isEdbBtnShow('edbData_edbCollect_collect')"
+								type="text"
+								:style="classifyShowType==='own'?'color:#D54941':''"
+								@click="classifyShowType==='own'?handleRemoveCollect():handleCollectEdb()" 
+							>{{classifyShowType==='own'?'移出':'收藏'}}</el-button>
 							<el-button 
 								v-if="isEdbBtnShow('update')"
 								type="text" 
@@ -403,14 +461,14 @@
 				
 			</div>
 		</div>
-		<!-- 输入英文指标弹窗 -->
-		<!-- <set-en-name-dia :isOpenDialog="setEnName" @cancel="setEnName=false" 
-		:formData="formItemArray" @updateEnName="updateEnName" cType="ebd" /> -->
+
+
 
 		<!-- 目录弹窗 -->
 		<openDialog 
 			:isOpenDialog="isOpenDialog"
 			:title="dialog_title"
+			:isBasicBase="isBasicBase"
 			:formData="dialogForm"
 			@closeDia="isOpenDialog=false"
 			@sucessCallback="sucessCallback"
@@ -551,11 +609,7 @@
 			@success="updateNewest"
 		/>
 
-		 <!-- 指标历史记录 -->
-    <!-- <edbHistoryDialog
-      :isOpenDialog.sync="isLookHistory"
-      :edbId="lookEdbId"
-    /> -->
+
 		<!-- 指数修匀弹窗 -->
 		<SmoothEdbDialog 
 			:is-open-smooth="computed_type==='alpha'"
@@ -589,11 +643,27 @@
 		<!-- 指标已经被引用 -->
 		<edbHasUsedDia :show.sync="edbHasUsedDiaShow" :dataList="hasUsedList"/>
 
+		<!-- 指标收藏弹窗 -->
+		<edbCollectDia
+			ref="edbCollectRef"
+			:show.sync="isOpenEdbCollectDia"
+			:edbId="selected_edbid"
+			:add_ids="EdbData?EdbData.CollectClassifyIdList:[]"
+			@success="arr=>{tableData[0].CollectClassifyIdList = arr}"
+		/>
+
+		<!-- 添加收藏分类弹窗 -->
+		<addCollectClassifyDia
+			:show.sync="isOpenCollectClassifyDia"
+			:form="collectClassifyForm"
+			@confirm="getTreeData();isOpenEdbCollectDia&&$refs.edbCollectRef.getClassify()"
+		/>
 	</div>
 </template>
 
 <script>
 import { dataBaseInterface } from '@/api/api.js';
+import { edbCollectInterface } from '@/api/modules/chartApi';
 import { getComputedTypes,getBatchComputedTypes,getFormulaTip } from './databaseComponents/util';
 
 import openDialog from './databaseComponents/openDialog';
@@ -601,7 +671,7 @@ import addTargetDiaBase from './databaseComponents/addTargetDiaBase';
 import completeTargetDia from './databaseComponents/completeTargetDia'
 import computedDialog from './databaseComponents/computedDialog';
 import operationDialog from './databaseComponents/operationDialog';
-import createChart from './databaseComponents/createChart';
+// import createChart from './databaseComponents/createChart';
 import updateDialog from './databaseComponents/updateDialog';
 import replaceDialog from './databaseComponents/replaceDialog';
 import jointTargetDia from './databaseComponents/jointTargetDia';
@@ -620,6 +690,9 @@ import SmoothEdbDialog from './databaseComponents/smoothEdbDialog.vue';
 import batchComputedV2 from './databaseComponents/batchComputedV2.vue';
 import setLangInfoDia from './components/setLangInfo.vue'
 import edbHasUsedDia from './components/edbHasUsedDia.vue';
+import collectEdbMenu from './databaseComponents/collectEdbMenu.vue';
+import edbCollectDia from './databaseComponents/edbCollectDia.vue';
+import addCollectClassifyDia from './databaseComponents/addCollectClassifyDia.vue';
 export default {
 	name: '',
 	components: {
@@ -628,7 +701,7 @@ export default {
 		completeTargetDia,
 		computedDialog,
 		operationDialog,
-		createChart,
+		// createChart,
 		updateDialog,
 		replaceDialog,
 		jointTargetDia,
@@ -646,7 +719,10 @@ export default {
 		SmoothEdbDialog,
 		batchComputedV2,
 		setLangInfoDia,
-		edbHasUsedDia
+		edbHasUsedDia,
+		collectEdbMenu,
+		edbCollectDia,
+		addCollectClassifyDia
 	},
 	directives: {
 		drag(el, bindings,vnode) {
@@ -728,8 +804,7 @@ export default {
 			edb_source:0,//指标来源 显示计算按钮
 			calculateLoading: false,//计算指标刷新loading
 			refreshLoading: false,//基础指标刷新loading
-			/* 一键成图弹窗 */
-			isCreateChart: false,
+
 			/* 一键更新弹窗 */
 			isUpdate:false,
 			/* 替换指标弹窗 */
@@ -784,7 +859,16 @@ export default {
 			isLangInfoDia: false,
 
 			edbHasUsedDiaShow:false,
-			hasUsedList:[]
+			hasUsedList:[],
+
+			/* 目录分类 */
+			classifyShowType:'public',
+			searchCollectWord:'',
+			//指标收藏弹窗
+			isOpenEdbCollectDia: false,
+			//收藏分类弹窗
+			isOpenCollectClassifyDia: false,
+			collectClassifyForm: {}
 		};
 	},
 	watch: {
@@ -826,6 +910,11 @@ export default {
 		},
 	},
 	computed: {
+		/* 是否是数据查看库 */
+		isBasicBase() {
+			return this.$route.path === '/edbBasicbase'
+		},
+
 		/* 计算弹窗控制 */
 		computedShowTypes() {
 			return this.computed_source===1 ? getComputedTypes() : getBatchComputedTypes();
@@ -841,11 +930,7 @@ export default {
 				return role;
 			}
 		},
-		/* 登录角色id */
-		roleId() {
-			let id = parseInt(localStorage.getItem('AdminId'));
-			return id;
-		},
+
 		//指标详情,也就是tableData[0]
 		EdbData(){
 			return this.tableData[0]?this.tableData[0]:{Button:{},DataInsertConfig:{},DataList:[]}
@@ -964,30 +1049,51 @@ export default {
 				'checkRelatedEdb':edbDataPermission.edbData_checkRelatedEdb,//查看关联指标
 				'checkCalcChart':edbDataPermission.edbData_checkCalcChart,//查看计算指标
 				'enableOrDisable':edbDataPermission.edbData_enableOrDisable,//启用/停用
+
+				'edbData_edbCollect_collect': edbDataPermission.edbData_edbCollect_collect,//收藏移出
+				'edbData_edbCollectClassify_save': edbDataPermission.edbData_edbCollectClassify_save,//收藏分类编辑
+				'edbData_edbCollectClassify_remove': edbDataPermission.edbData_edbCollectClassify_remove,//收藏分类删除
+				'edbData_edbCollectClassify_move': edbDataPermission.edbData_edbCollectClassify_move,//收藏分类移动
+				'edbData_edbCollectClassify_remove': edbDataPermission.edbData_edbCollectClassify_remove,//收藏分类移动
 			}
 			return checkPermissionBtn(BtnMap[type])
 		},
 		/* 获取树分类数据 */
-		getTreeData(params) {
-			
-			dataBaseInterface.targetCatalog({IsOnlyMe:this.IsOnlyMe,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
-						}
+		async getTreeData(params) {
+			const res = this.classifyShowType==='own'
+				? await edbCollectInterface.getEdbCollectClassify({ParentId:0})
+				: await dataBaseInterface.targetCatalog({
+						IsOnlyMe:this.IsOnlyMe,
+						ParentId:0,
+						ClassifyType: this.isBasicBase ? 0 : 2
 					})
-					this.CanOpClassify = res.Data.CanOpClassify;
-					// this.currentLang = res.Data.Language === 'EN' ? 'en' : 'ch';
-					// this.setLangIntoStore()
+
+	
+					if(res.Ret!==200) return 
 					this.showData = true;
-					/* 处理树展开和选中图表 */
-					params && this.selectCurrentNode(params);
-					!params && this.select_node && this.$refs.menuTree.setCurrentKey(this.select_node);
-				}
-			})
+
+					if(this.classifyShowType==='public') {
+						const arr=res.Data.AllNodes || []
+						this.treeData=arr.map(item=>{
+							return {
+								...item,
+								// isLeaf:item.Children.length?false:true
+							}
+						})
+						
+						this.CanOpClassify = res.Data.CanOpClassify;
+
+						/* 处理树展开和选中图表 */
+						params && this.selectCurrentNode(params);
+						!params && this.select_node && this.$refs.menuTree.setCurrentKey(this.select_node);
+					}else {
+						this.treeData = res.Data||[]
+						this.select_classifyId =
+							this.select_classifyId ||
+							(this.treeData.length ? this.treeData[0].ClassifyId:0);
+
+						this.$refs.collectEdbMenuRef&&this.$refs.collectEdbMenuRef.initSelect(this.select_classifyId)
+					}
 		},
 		/* 获取最新的指标 默认展示 */
 		getNewTargetList: _.throttle(function() {
@@ -1029,7 +1135,7 @@ export default {
 						// 展开目录
 						this.defaultShowNodes=classify_arr.map(item=>item.UniqueCode)
 						//设置tree高亮
-						this.$nextTick(()=>{
+						this.$refs.menuTree&&this.$nextTick(()=>{
 							setTimeout(() => {
 								this.$refs.menuTree.setCurrentKey(UniqueCode);
 							}, 1000);
@@ -1054,10 +1160,9 @@ export default {
 							this.$refs.edb_detail_data.$refs.valueUl.scrollTop=0
 						}
 					}
-					this.$nextTick(()=>{
+					this.$refs.menuTree&&this.$nextTick(()=>{
 						const _node = this.$refs.menuTree.getNode(this.select_node)
-						this.dynamicNode = _node;
-						this.dynamicNode&&this.resetNodeStyle(this.dynamicNode)
+						// this.dynamicNode = _node;
 						//滚动到高亮位置
 						setTimeout(() => {
 							let node = document.getElementById(`node${this.select_node}`)||{}
@@ -1079,22 +1184,27 @@ export default {
 			})
 		}),
 		//获取指标图表列表
-		getEdbChartList(){
-			dataBaseInterface.getEdbChartList({
-				PageSize:this.PageSize,
-				CurrentIndex:this.CurrentIndex,
-				ClassifyId:this.select_classifyId,
-				IsOnlyMe:this.IsOnlyMe
-			}).then(res=>{
+		async getEdbChartList(){
+			const res = this.classifyShowType === 'own' 
+				? await edbCollectInterface.getCollectEdb({
+						PageSize:this.PageSize,
+						CurrentIndex:this.CurrentIndex,
+						ClassifyId:this.select_classifyId,
+						Keyword: this.searchCollectWord
+					})
+ 				:	await dataBaseInterface.getEdbChartList({
+						PageSize:this.PageSize,
+						CurrentIndex:this.CurrentIndex,
+						ClassifyId:this.select_classifyId,
+						IsOnlyMe:this.IsOnlyMe,
+						EdbType: this.isBasicBase?1:2
+					})
 				if(res.Ret!==200) return
 				if(res.Data){
 					this.chartList = this.CurrentIndex===1?res.Data.List:[...this.chartList,...res.Data.List]
 					this.Total = res.Data.Paging.Totals||0
 					this.IsListEnd = res.Data.Paging.IsEnd
 				}
-
-
-			})
 		},
 		// 切换刷新状态
 		async toggleEdbRefreshStatus(item,type='list'){
@@ -1139,7 +1249,8 @@ export default {
 		searchApi(query,page=1) {
 			dataBaseInterface.targetSearchByPage({
 				KeyWord:query,
-				CurrentIndex: page
+				CurrentIndex: page,
+				EdbType: this.isBasicBase?1:2
 			}).then(res => {
 				if(res.Ret !== 200) return
 
@@ -1245,24 +1356,11 @@ export default {
 			this.select_classifyId = !data.EdbInfoId?data.ClassifyId:0;
 			this.select_node = data.UniqueCode;
 			this.selected_edbid = data.EdbInfoId;
-			this.resetNodeStyle(node);
-			this.dynamicNode = node;
+			// this.dynamicNode = node;
 			this.showAssociateChart=false
 			this.showAssociateComputeData=false
 		},
-		resetNodeStyle: _.debounce(function(node) {
-			const tree = $('.target_tree')[0];
-			let width = tree.offsetWidth;
-			console.log(width)
-			// let label_wid = width > 500 ? 'auto' : (width <= 300 && width < 360) ?  100 : 0.7*width;
-			let label_wid =
-				width > 500
-					? 'auto'
-					: width <= 260
-					? 80
-					: 0.4 * width;
-			this.$set(node, 'Nodewidth', label_wid + 'px');
-		},200),
+
 		/* 双击label出现input修改框 */
 		editNodeLabel(node, data) {
 			//目录名称可以双击修改 指标不能
@@ -1644,7 +1742,8 @@ export default {
 				PrevClassifyId,
 				NextClassifyId,
 				PrevEdbInfoId,
-				NextEdbInfoId
+				NextEdbInfoId,
+				ClassifyType: this.isBasicBase ? 0 : 2
 			}
 			console.log(params);
 			dataBaseInterface.classifyMoveSort(params).then(res=>{
@@ -1967,10 +2066,6 @@ export default {
 			})
 		},
 
-		/* 	一键成图 */
-		createChartHandle() {
-			this.isCreateChart = true;
-		},
 		
 		/* 重新刷新 重新计算后重置刷数据 */
 		initDataStatus() {
@@ -2041,7 +2136,7 @@ export default {
 				return
 			}
 			//根据页面宽度 判断标签数量是否达到上限
-			const listWidth = document.querySelector('.database-label').offsetWidth
+			const listWidth = document.querySelector('.database-label')&&document.querySelector('.database-label').offsetWidth
 			const minWidth=170+20
 			const maxNum = Math.floor(listWidth/minWidth)
 			if(this.labelList.length>=maxNum){
@@ -2078,11 +2173,11 @@ export default {
 		},
 		changeTreeNode(){
 			this.$refs.menuTree.setCurrentKey(this.select_node);
-			this.$nextTick(()=>{
-				const _node = this.$refs.menuTree.getCurrentNode()
-				this.dynamicNode = _node;
-				this.dynamicNode&&this.resetNodeStyle(this.dynamicNode)
-			})
+			// this.$nextTick(()=>{
+			// 	const _node = this.$refs.menuTree.getCurrentNode()
+			// 	this.dynamicNode = _node;
+			// 	this.dynamicNode&&this.resetNodeStyle(this.dynamicNode)
+			// })
 		},
 		//只看我的
 		onlyMeHandler(){
@@ -2098,7 +2193,11 @@ export default {
 				resolve(this.treeData)
 			}else{
 				let arr=[]
-				const res=await dataBaseInterface.targetCatalog({ParentId:node.data.ClassifyId,IsOnlyMe:this.IsOnlyMe})
+				const res=await dataBaseInterface.targetCatalog({
+					ParentId:node.data.ClassifyId,
+					IsOnlyMe:this.IsOnlyMe,
+					ClassifyType: this.isBasicBase ? 0 : 2
+				})
 				if (res.Ret === 200) {
 					const temarr = res.Data.AllNodes || [];
 					arr=temarr.map(item=>{
@@ -2144,7 +2243,7 @@ export default {
 				classifyId:ClassifyId
 			};
 			this.selectCurrentNode(params);
-			this.select_classifyId = 0;
+			if(this.classifyShowType==='public') this.select_classifyId = 0;
 		},
 		// 添加wind wsd指标成功
 		addTargetSuccess(params){
@@ -2156,7 +2255,75 @@ export default {
 			this.$nextTick(()=>{//重新打开计算指标选择类型弹窗
 				this.isOpenComputed=true
 			})
-		}
+		},
+
+		/* 切换分类类型 */
+		handleChangeClassifyType() {
+			this.defaultShowNodes = [];
+			this.chartList = [];
+			this.Total = 0;
+			this.selected_edbid = 0;
+			this.select_classifyId = 0;
+			this.search_txt = '';
+			this.searchCollectWord = '';
+			this.getTreeData()
+			this.classifyShowType==='public'&&this.getEdbChartList()
+		},
+
+		/* 收藏指标 */
+		handleCollectEdb() {
+			this.isOpenEdbCollectDia = true
+		},
+
+		async handleRemoveCollect(item=null) {
+			const res = await edbCollectInterface.edbCollectCancel({
+				ClassifyId: this.select_classifyId,
+				EdbInfoId: item?item.EdbInfoId:this.selected_edbid
+			})
+
+			if(res.Ret !== 200) return 
+			this.$message.success('取消收藏成功')
+			if(this.selected_edbid) {
+				this.chartList = []
+				this.selected_edbid = 0
+			}
+			this.getEdbChartList()
+		},
+
+		handleOpenCollectClassify(data=null) {
+			this.collectClassifyForm = {
+				name: data?data.ClassifyName:'',
+				classifyId:data?data.ClassifyId:0
+			}
+			this.isOpenCollectClassifyDia = true
+		},
+
+		/* 收藏指标拖动 */
+		async collectDragOver({oldIndex,newIndex}) {
+			if(oldIndex===newIndex) return
+			let NextEdbInfoId,PrevEdbInfoId;
+			if(newIndex===0){
+        PrevEdbInfoId=0
+        NextEdbInfoId=this.chartList[newIndex+1].EdbInfoId
+      }else if(newIndex===this.chartList.length-1){
+        PrevEdbInfoId = this.chartList[newIndex-1].EdbInfoId
+        NextEdbInfoId = 0
+      }else{
+        PrevEdbInfoId = this.chartList[newIndex-1].EdbInfoId
+        NextEdbInfoId = this.chartList[newIndex+1].EdbInfoId
+      }
+			
+			let params = {
+				ClassifyId: this.select_classifyId,
+				EdbInfoId: this.chartList[newIndex].EdbInfoId,
+				NextEdbInfoId,
+				PrevEdbInfoId,
+			}
+
+			const res = await edbCollectInterface.moveCollectEdb(params)
+			if(res.Ret !== 200) return 
+			this.$message.success('移动成功')
+		},
 	},
 	//离开页面时保存标签
 	beforeRouteLeave(to,from,next){
@@ -2164,7 +2331,7 @@ export default {
 		next()
 	},
 	mounted() {
-		this.getlabelList()
+		// this.getlabelList()
 		this.getEdbChartList()
 		this.$route.query.code 
 		? this.getTreeData({code: this.$route.query.code,id: this.$route.query.id,classifyId:this.$route.query.classifyId})
@@ -2254,7 +2421,7 @@ export default {
 		} */
 		.main-left {
 			width: 400px;
-			min-width: 300px;
+			min-width: 400px;
 			background: #fff;
 			margin-right: 20px;
 			border: 1px solid #ececec;
@@ -2271,7 +2438,7 @@ export default {
 			}
 			.target_tree {
 				color: #333;
-				height: calc(100vh - 400px); 
+				height: calc(100vh - 420px); 
 				overflow: auto;
 				.label-input .el-input__inner {
 					height: 25px;
@@ -2283,6 +2450,7 @@ export default {
 					align-items: center;
 					display: block;
 					flex: 1;
+					max-width: 92%;
 					.node_label {
 						margin-right: 2px;
 					}
@@ -2453,9 +2621,12 @@ export default {
 						box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
 						position: relative;
 						.header{
+							display: flex;
+							justify-content: space-between;
+							align-items: center;
 							padding:10px;
 							box-sizing: border-box;
-							text-align: left;
+							/* text-align: left; */
 						}
 						.info{
 							padding:10px;

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

@@ -540,7 +540,7 @@ export const chartSetMixin = {
       chartSetMap[this.chartInfo.ChartType]&&chartSetMap[this.chartInfo.ChartType](newval)
 
       //myeta内或者数据指标库内
-      if(this.$route.path === '/mychart'||this.$route.path==='/database')  this.showData = true;
+      if(['/mychart','/database','/edbBasicbase'].includes(this.$route.path))  this.showData = true;
     },
 
     /* 曲线图设置 */
@@ -2452,7 +2452,7 @@ export const chartSetMixin = {
       const chartTheme =  this.chartInfo.ChartThemeStyle ? JSON.parse(this.chartInfo.ChartThemeStyle) : null;
 
       const { DataList,LeftMaxValue,LeftMinValue,RightMaxValue,RightMinValue } = this.statisticFrequencyData;
-      
+      if(!DataList) return 
       let xAxis = {
         ...scatterXAxis,
         tickWidth: 1,
@@ -2813,8 +2813,8 @@ export const chartSetMixin = {
     },
 
     /* 查看数据 跳转指标库展开具体指标 */
-    viewTarget({ UniqueCode,EdbInfoId,EdbInfoCategoryType,ClassifyId }) {
-      let path = EdbInfoCategoryType ? '/predictEdb' : '/database';
+    viewTarget({ UniqueCode,EdbInfoId,EdbInfoCategoryType,ClassifyId,EdbType }) {
+      let path = EdbInfoCategoryType ? '/predictEdb' : (EdbType===1?'/edbBasicbase':'/database');
       let {href} = this.$router.resolve({path, query: {
         code: UniqueCode,
         id: EdbInfoId,

+ 2 - 2
src/views/datasheet_manage/components/CustomTable.vue

@@ -966,9 +966,9 @@ export default {
       if(res.Ret !== 200) return
 
        //EdbInfoType=1 跳预测指标详情,=0跳指标库详情
-      const {ClassifyId,UniqueCode,EdbInfoId,EdbInfoType} = res.Data;
+      const {ClassifyId,UniqueCode,EdbInfoId,EdbInfoType,EdbType} = res.Data;
       let {href} = this.$router.resolve({
-        path:EdbInfoType===1?'/predictEdb':'/database',
+        path:EdbInfoType===1?'/predictEdb':(EdbType===1?'/edbBasicbase':'/database'),
         query:{code:UniqueCode,id:EdbInfoId,classifyId:ClassifyId}
       });
       window.open(href,'_blank');

+ 1 - 1
src/views/datasheet_manage/customAnalysis/components/createTargetForm.vue

@@ -122,7 +122,7 @@ export default {
 
     /* 获取分类 */
 		getMenu() {
-			dataBaseInterface.menuListV3().then((res) => {
+			dataBaseInterface.menuListV3({ClassifyType:2}).then((res) => {
 				if (res.Ret !== 200) return
         this.filterNodes(res.Data.AllNodes||[]);
 				this.classifyOption = res.Data.AllNodes || [];

+ 6 - 2
src/views/edbHistoryPage.vue

@@ -185,7 +185,9 @@ export default {
                         ClassifyId:this.treeData.ClassifyId, 
                         UniqueCode:this.treeData.UniqueCode, 
                         EdbInfoId:this.treeData.EdbInfoId, 
-                        EdbInfoType:this.treeData.EdbInfoType
+                        EdbInfoType:this.treeData.EdbInfoType,
+                        EdbType:this.treeData.EdbType,
+                        HaveOperaAuth:this.treeData.HaveOperaAuth,
                     },
                     isRoot:true,
                     isLeaf:(this.treeData.Child && this.treeData.Child.length>0)?false:true,
@@ -232,7 +234,9 @@ export default {
                             ClassifyId:element.ClassifyId, 
                             UniqueCode:element.UniqueCode, 
                             EdbInfoId:element.EdbInfoId, 
-                            EdbInfoType:element.EdbInfoType
+                            EdbInfoType:element.EdbInfoType,
+                            EdbType:element.EdbType,
+                            HaveOperaAuth:element.HaveOperaAuth,
                         },
                         isRoot:false,
                         isLeaf:(element.Child && element.Child.length>0)?false:true,

+ 0 - 66
src/views/home_manage/components/BIWrap.vue

@@ -1,66 +0,0 @@
-<template>
-  <div class="item-wrap">
-    <div class="lable-text">BI看板</div>
-    <div class="list-box">
-      <div class="list-item" v-for="item in 7" :key="item">
-        <div class="title">煤炭市场价格走势及影响因素(0921)</div>
-        <div class="author">创建人</div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-export default {
-
-}
-</script>
-
-<style lang="scss" scoped>
-.item-wrap {
-  box-shadow: 0px 2px 12px 0px #0000001a;
-  border: 1px solid #c8cdd9;
-  background-color: #fff;
-  padding: 11px 16px;
-  border-radius: 8px;
-  width: calc(50% - 50px);
-  .lable-text {
-    padding-bottom: 13px;
-    border-bottom: 1px solid #c8cdd9;
-    &::before {
-      content: "";
-      display: inline-block;
-      width: 4px;
-      height: 12px;
-      background-color: #10CFDB;
-      margin-right: 12px;
-      position: relative;
-      top: 1px;
-    }
-  }
-  .list-box{
-    padding-top: 10px;
-    .list-item{
-      margin-top: 10px;
-      padding: 10px 20px;
-      background: #FFFFFF;
-      border: 1px solid #EBEFF6;
-      box-shadow: 0px 2px 4px 0px #00000005;
-      display: flex;
-      align-items: center;
-      border-radius: 8px;
-      &::before{
-        content: '';
-        display: inline-block;
-        width: 8px;
-        height: 8px;
-        margin-right: 10px;
-        background: #94E1EC;
-      }
-      .title{
-        flex: 1;
-      }
-    }
-  }
-}
-</style>

+ 0 - 81
src/views/home_manage/components/PointViewWrap.vue

@@ -1,81 +0,0 @@
-<template>
-  <div class="item-wrap">
-    <div class="lable-text">观点库</div>
-    <div class="content-box">
-      <div class="content-lable">已关注观点</div>
-      <div class="info-list">
-        <div class="info-item" v-for="item in 10" :key="item">
-          <div class="time">2018.3.20 12:00:00</div>
-          <div class="text">稳地价、稳房价、稳预期”成为楼市调控主基调</div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-export default {
-
-}
-</script>
-
-<style lang="scss" scoped>
-.item-wrap {
-  box-shadow: 0px 2px 12px 0px #0000001a;
-  border: 1px solid #c8cdd9;
-  background-color: #fff;
-  padding: 11px 16px;
-  border-radius: 8px;
-  width: calc(50% - 50px);
-  .lable-text {
-    padding-bottom: 13px;
-    border-bottom: 1px solid #c8cdd9;
-    &::before {
-      content: "";
-      display: inline-block;
-      width: 4px;
-      height: 12px;
-      background-color: #0052D9;
-      margin-right: 12px;
-      position: relative;
-      top: 1px;
-    }
-  }
-  .content-box {
-    margin-top: 13px;
-    padding: 15px;
-    background: #ECF2FE;
-    border: 1px solid #DAE8FF;
-    border-radius: 4px;
-    .content-lable {
-      color: #0052D9;
-      font-size: 16px;
-      font-weight: bold;
-    }
-    .info-list {
-      margin-top: 30px;
-      .info-item {
-        display: flex;
-        align-items: center;
-        margin-bottom: 10px;
-        color: #666;
-        &::before {
-          content: "";
-          display: inline-block;
-          width: 8px;
-          height: 8px;
-          background-color: #0052D9;
-          margin-right: 10px;
-        }
-        .time {
-          flex: 1;
-          text-align: center;
-        }
-        .text {
-          flex: 2;
-        }
-      }
-    }
-  }
-}
-</style>

+ 0 - 81
src/views/home_manage/components/PolicyWrap.vue

@@ -1,81 +0,0 @@
-<template>
-  <div class="item-wrap">
-    <div class="lable-text">政策库</div>
-    <div class="content-box">
-      <div class="content-lable">已关注政策</div>
-      <div class="info-list">
-        <div class="info-item" v-for="item in 10" :key="item">
-          <div class="time">2018.3.20 12:00:00</div>
-          <div class="text">稳地价、稳房价、稳预期”成为楼市调控主基调</div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-export default {
-
-}
-</script>
-
-<style lang="scss" scoped>
-.item-wrap{
-  box-shadow: 0px 2px 12px 0px #0000001A;
-  border: 1px solid #C8CDD9;
-  background-color: #fff ;
-  padding: 11px 16px;
-  border-radius: 8px;
-  width: calc(50% - 50px);
-  .lable-text{
-    padding-bottom: 13px;
-    border-bottom: 1px solid #C8CDD9;
-     &::before{
-       content: '';
-       display: inline-block;
-       width: 4px;
-       height: 12px;
-       background-color: #E37318;
-       margin-right: 12px;
-       position: relative;
-       top: 1px;
-     }
-  }
-  .content-box{
-    margin-top: 13px;
-    padding: 15px;
-    background: #FFF1E9;
-    border: 1px solid #FFD9C2;
-    border-radius: 4px;
-    .content-lable{
-      color: #E37318;
-      font-size: 16px;
-      font-weight: bold;
-    }
-    .info-list{
-      margin-top: 30px;
-      .info-item{
-        display: flex;
-        align-items: center;
-        margin-bottom: 10px;
-        color: #666;
-        .time{
-          flex: 1;
-          text-align: center;
-        }
-        .text{
-          flex: 2;
-          &::before{
-            content: '';
-            display: inline-block;
-            width: 8px;
-            height: 8px;
-            background-color: #F7BA1E;
-            margin-right: 10px;
-          }
-        }
-      }
-    }
-  }
-}
-</style>

+ 0 - 82
src/views/home_manage/components/ReportWrap.vue

@@ -1,82 +0,0 @@
-<template>
-  <div class="item-wrap">
-    <div class="lable-text">报告列表</div>
-    <div class="list-box">
-      <div class="list-item" v-for="item in 3" :key="item">
-        <div class="title">煤炭市场价格走势及影响因素(0921)</div>
-        <div class="des-text">
-          摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容摘要内容
-        </div>
-        <div class="time-text">2024.09.20</div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-export default {
-
-}
-</script>
-
-<style lang="scss" scoped>
-.item-wrap {
-  box-shadow: 0px 2px 12px 0px #0000001a;
-  border: 1px solid #c8cdd9;
-  background-color: #fff;
-  padding: 11px 16px;
-  border-radius: 8px;
-  width: calc(50% - 50px);
-  .lable-text {
-    padding-bottom: 13px;
-    border-bottom: 1px solid #c8cdd9;
-    &::before {
-      content: "";
-      display: inline-block;
-      width: 4px;
-      height: 12px;
-      background-color: #8a18e3;
-      margin-right: 12px;
-      position: relative;
-      top: 1px;
-    }
-  }
-  .list-box {
-    padding-top: 10px;
-    .list-item {
-      margin-top: 10px;
-      padding: 10px 20px;
-      background: #ffffff;
-      border: 1px solid #ebeff6;
-      box-shadow: 0px 2px 4px 0px #00000005;
-      border-radius: 8px;
-      color: #666;
-      .title {
-        color: #333;
-        &::before {
-          content: "";
-          display: inline-block;
-          width: 8px;
-          height: 8px;
-          margin-right: 10px;
-          background: #e6c6ff;
-        }
-      }
-      .des-text{
-        margin: 5px 0;
-        line-height: 1.7;
-        padding-left: 18px;
-        display: -webkit-box;
-        overflow: hidden;
-        text-overflow: ellipsis;
-        -webkit-line-clamp: 2;
-        line-break: anywhere;
-        -webkit-box-orient: vertical;
-      }
-      .time-text{
-        padding-left: 18px;
-      }
-    }
-  }
-}
-</style>

+ 217 - 0
src/views/home_manage/components/SelectBoard.vue

@@ -0,0 +1,217 @@
+<template>
+  <el-dialog
+    title="设置首页内容"
+    :visible.sync="show"
+    :modal-append-to-body="false"
+    :close-on-click-modal="false"
+    :center="true"
+    v-dialogDrag
+    custom-class="dialogclass"
+    width="680px"
+    @close="handleClose"
+  >
+    <div class="set-board-wrap">
+      <div>BI看板</div>
+      <el-cascader
+        style="width:500px"
+        v-model="selectBoardId"
+        :props="{ emitPath: false }"
+        :options="list"
+        ref="selectBoardEl"
+      ></el-cascader>
+    </div>
+    <div class="dia-bot">
+        <el-button
+          type="primary"
+          plain
+          @click="handleClose"
+          style="margin-right: 20px"
+          >{{ $t("Dialog.cancel_btn") }}</el-button
+        >
+        <el-button type="primary" @click="saveHandle">{{
+          $t("Dialog.confirm_save_btn")
+        }}</el-button>
+      </div>
+  </el-dialog>
+</template>
+
+<script>
+import apiBiBoard from '@/api/modules/BIBoard.js'
+export default {
+  name: "selectBoard",
+  model: {
+    prop: 'show',
+    event: 'showChange'
+  },
+  props: {
+    show: {
+      type: Boolean,
+      default: false
+    },
+    boardId:'',
+    homeBoardInfo:null
+  },
+  watch: {
+    show(n) {
+      if (n) {
+        if(this.boardId&&this.homeBoardInfo){
+          if(this.homeBoardInfo.FromType===1){
+            this.selectBoardId='我的看板_'+this.boardId
+          }else if(this.homeBoardInfo.FromType===2){
+            this.selectBoardId='共享看板_'+this.boardId
+          }else{
+            this.selectBoardId='公共看板_'+this.boardId
+          }
+        }
+        
+        this.getList()
+      }
+    }
+  },
+  data() {
+    return {
+      list: [
+        {
+          label: '我的看板',
+          value: '我的看板',
+          children: []
+        },
+        {
+          label: '共享看板',
+          value: '共享看板',
+          children: []
+        },
+        {
+          label: '公共看板',
+          value: '公共看板',
+          children: []
+        }
+      ],
+      selectBoardId: ''
+    }
+  },
+  methods: {
+    async saveHandle(){
+      if(!this.selectBoardId){
+        this.$message.warning('请选择BI看板')
+        return
+      }
+      let FromType=3
+      const elData=this.$refs.selectBoardEl.getCheckedNodes()
+      if(elData[0].path[0]==='我的看板'){
+        FromType=1
+      }else if(elData[0].path[0]==='共享看板'){
+        FromType=2
+      }else{
+        FromType=3
+      }
+
+      const res=await apiBiBoard.setHomePageBoard({
+        BiDashboardId:Number(this.selectBoardId.split('_')[1]),
+        FromType:FromType
+      })
+      if(res.Ret===200){
+        this.$message.success('保存成功')
+        this.handleClose()
+        this.$emit('change')
+      }
+    },
+
+    // 看板列表
+    // 由于一个看板既可以在我的也可以在共享也可以在公共 所以id加个前缀
+    async getList(type) {
+      const resMy = await apiBiBoard.myBoardList()
+      if (resMy.Ret === 200) {
+        const arr = resMy.Data || []
+        this.list[0].children = arr.map(item => {
+          return {
+            label: item.BiDashboardName,
+            value: '我的看板_'+item.BiDashboardId
+          }
+        })
+      }
+
+      const resShare = await apiBiBoard.shareBoardList()
+      if (resShare.Ret === 200) {
+        const myArr = resShare.Data.MyList || []
+        const otherArr = resShare.Data.OtherList || []
+        this.list[1].children = [
+          {
+            label: '我共享的',
+            value: 'my_share',
+            children: myArr.map(item => {
+              return {
+                label: item.BiDashboardName,
+                value: '共享看板_'+item.BiDashboardId
+              }
+            })
+          },
+          {
+            label: '收到共享',
+            value: 'other_share',
+            children: otherArr.map(item => {
+              const cArr=item.DashboardList.map(_i=>{
+                return{
+                  label: _i.BiDashboardName,
+                  value: '共享看板_'+_i.BiDashboardId,
+                }
+              })
+              return {
+                label: item.GroupName,
+                value: item.GroupId,
+                children:cArr
+              }
+            })
+          }
+        ]
+      }
+
+      const resCommon = await apiBiBoard.commonBoardList()
+      if(resCommon.Ret===200){
+        const arr=resCommon.Data||[]
+        this.list[2].children=arr.map(item1=>{
+          let obj1={
+            label:item1.GroupName,
+            value:item1.GroupId+item1.GroupName,
+            children:[]
+          }
+          obj1.children=item1.Children?item1.Children.map(item2=>{
+            let obj2={
+              label:item2.GroupName,
+              value:item2.GroupId+item2.GroupName,
+              children:[]
+            }
+            obj2.children=item2.DashboardList?item2.DashboardList.map(item3=>{
+              return {
+                label:item3.BiDashboardName,
+                value:'公共看板_'+item3.BiDashboardId,
+              }
+            }):[]
+            return obj2
+          }):[]
+
+          return obj1
+        })
+      }
+    },
+
+    handleClose() {
+      this.boardId = ''
+      this.$emit('showChange', false)
+    },
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.set-board-wrap{
+  display: flex;
+  align-items: center;
+  gap: 0 10px;
+}
+.dia-bot {
+  display: flex;
+  justify-content: center;
+  margin: 60px 0 40px 0;
+}
+</style>

+ 68 - 12
src/views/home_manage/index.vue

@@ -1,26 +1,82 @@
 <template>
   <div class="home-page">
-    <policy-wrap/>
-    <Point-view-wrap/>
-    <BIWrap/>
-    <ReportWrap/>
+    <div class="top-nav-box">
+      <div class="name">{{boardInfo&&boardInfo.BiDashboardName}}</div>
+      <div class="btns">
+        <el-button type="text" v-if="boardInfo&&permissionBtn.isShowBtn('homePagePermission','home_boarddetail')" @click="handleGoDetail">看板详情</el-button>
+        <el-button type="text" @click="showSet=true" v-permission="permissionBtn.homePagePermission.home_setbiboard">设置看板</el-button>
+      </div>
+    </div>
+    <!-- 看板内容模块 -->
+    <BIBoardContent v-model="boardDataList"/>
+
+    <!-- 设置看板 -->
+    <SelectBoard v-model="showSet" :boardId="boardId" :homeBoardInfo="homeBoardInfo" @change="getBoardData"/>
   </div>
 </template>
 
 <script>
-import BIWrap from './components/BIWrap.vue'
-import PointViewWrap from './components/PointViewWrap.vue'
-import PolicyWrap from './components/PolicyWrap.vue'
-import ReportWrap from './components/ReportWrap.vue'
+import BIBoardContent from '@/views/BI_manage/components/BoardContent.vue'
+import SelectBoard from './components/SelectBoard.vue'
+import apiBiBoard from '@/api/modules/BIBoard.js'
 export default {
-  components:{PolicyWrap,PointViewWrap,BIWrap,ReportWrap}
+  components:{BIBoardContent,SelectBoard},
+  data() {
+    return {
+      homeBoardInfo:null,
+      boardId:'',
+      boardInfo:null,
+      boardDataList:[],
+      showSet:false
+    }
+  },
+  created() {
+    this.getBoardData()
+  },
+  methods: {
+    handleGoDetail(){
+      this.$router.push({
+        path:'/BIBoard',
+        query:{
+          id:this.boardId,
+          type:this.homeBoardInfo.FromType
+        }
+      })
+    },
+
+    async getBoardInfo(){
+      const res=await apiBiBoard.boardDetail({ DashboardId: this.boardId })
+      if(res.Ret===200){
+        this.boardInfo = res.Data
+        this.boardDataList = res.Data.List || []
+      }
+    },
+
+    async getBoardData(){
+      const res=await apiBiBoard.getHomePageBoard()
+      if(res.Ret===200&&res.Data){
+        this.homeBoardInfo=res.Data
+        this.boardId=res.Data.BiDashboardId
+        this.getBoardInfo()
+      }
+    }
+  },
 }
 </script>
 
 <style lang="scss" scoped>
 .home-page{
-  display: flex;
-  flex-wrap: wrap;
-  gap: 20px;
+  $border-color: #c8cdd9;
+  background-color: #fff;
+  border: 1px solid $border-color;
+  .top-nav-box {
+    padding: 14px 20px;
+    border-bottom: 1px solid $border-color;
+    display: flex;
+    justify-content: space-between;
+    .name{
+      flex: 1;
+    }
+  }
 }
 </style>

+ 1 - 1
src/views/intervalAnalysis/components/batchSelectEdb.vue

@@ -482,7 +482,7 @@ export default {
 
     // 获取指标分类
     async getClassifyOpt() {
-      const res = await dataBaseInterface.menuListV3()
+      const res = await dataBaseInterface.menuListV3({ClassifyType:2})
       if (res.Ret !== 200) return
       this.filterNodes(res.Data.AllNodes || []);
       this.classifyOpt = res.Data.AllNodes || [];

+ 1 - 1
src/views/intervalAnalysis/components/saveMultipleEdb.vue

@@ -255,7 +255,7 @@ export default {
     },
 
     async getClassifyOpts() {
-      const res = this.tableData[0].EdbInfoCategoryType === 1 ? await preDictEdbInterface.classifyListV2() : await dataBaseInterface.menuListV3()
+      const res = this.tableData[0].EdbInfoCategoryType === 1 ? await preDictEdbInterface.classifyListV2() : await dataBaseInterface.menuListV3({ClassifyType:2})
       if (res.Ret === 200) {
         this.filterNodes(res.Data.AllNodes || []);
         this.classifyOpts = res.Data.AllNodes || [];

+ 1 - 1
src/views/intervalAnalysis/components/saveSingleEdb.vue

@@ -186,7 +186,7 @@ export default {
     },
 
     async getClassifyOpts() {
-      const res = this.tableData[0].EdbInfoCategoryType === 1 ? await preDictEdbInterface.classifyListV2() : await dataBaseInterface.menuListV3()
+      const res = this.tableData[0].EdbInfoCategoryType === 1 ? await preDictEdbInterface.classifyListV2() : await dataBaseInterface.menuListV3({ClassifyType:2})
       if (res.Ret === 200) {
         this.filterNodes(res.Data.AllNodes || []);
         this.classifyOpts = res.Data.AllNodes || [];

+ 380 - 0
src/views/knowledge_manage/components/classifyDia.vue

@@ -0,0 +1,380 @@
+<template>
+<div>
+    <el-dialog
+      :visible.sync="show"
+      :close-on-click-modal="false"
+      :modal-append-to-body="false"
+      @close="cancelHandle"
+      custom-class="knowledge-classify"
+      top="10vh"
+      v-dialogDrag
+      title="分类设置"
+      width="650px"
+    >
+      <div class="main">
+        <el-tree
+          ref="treeRef"
+          class="classify-tree"
+          :data="classifyOptions"
+          node-key="ClassifyId"
+          :props="{
+            value: 'ClassifyId',
+            label: 'ClassifyName',
+            children: 'Child',
+          }"
+          :expand-on-click-node="false"
+          check-strictly
+          empty-text="暂无分类"
+          draggable
+          :allow-drop="canDropHandle"
+          @node-drop="dropOverHandle"
+          @current-change="handleNodeChange"
+        >
+          <div class="custom-tree-node" slot-scope="{ node, data }">
+            <span
+              class="text_oneLine node_label"
+            >
+              {{ data.ClassifyName  }}
+            </span>
+
+            <div v-if="selectItem.ClassifyId===data.ClassifyId">
+                <img
+									src="~@/assets/img/data_m/move_ico.png"
+									class="handle-icon"
+								/>
+								<!-- 添加子项 -->
+								<img
+									src="~@/assets/img/set_m/add.png"
+									class="handle-icon"
+									@click.stop="handleAddNode(data,node)"
+									v-if="node.level<3"
+								/>
+								<!-- 编辑目录 -->
+								<img
+									src="~@/assets/img/set_m/edit.png"
+                  class="handle-icon"
+									@click.stop="handleEditNode(data,node)"
+								/>
+                
+								<!-- 删除目录 -->
+                <el-popconfirm
+                  title="确认删除该分类吗?"
+                  @onConfirm="handleRemoveNode(data)"
+                >
+                  <img
+                    slot="reference"
+                    src="~@/assets/img/set_m/del_icon.png"
+                    class="handle-icon"
+                  />
+                </el-popconfirm>
+
+            </div>
+          </div>
+        </el-tree>
+
+
+        <div class="clasify-add-cont" @click="handleAddNode(null)">
+          <img
+            src="~@/assets/img/set_m/add_ico.png"
+            alt=""
+          />
+          <span>添加一级目录</span>
+        </div>
+      </div>
+
+    </el-dialog>
+    
+    <!-- 分类编辑弹窗 -->
+    <el-dialog
+      :visible.sync="isClassifyEditDia"
+      :close-on-click-modal="false"
+      :modal-append-to-body="false"
+      @close="isClassifyEditDia=false"
+      top="10vh"
+      v-dialogDrag
+      title="分类编辑"
+      width="650px"
+    >
+      <el-form
+          ref="classifyFormRef"
+          label-position="right"
+          label-width="120px"
+          hide-required-asterisk
+          :model="classifyForm"
+          :rules="formRules"
+      >
+          <el-form-item label="上级分类" prop="parentClassifyId" v-if="classifyForm.parentClassifyId">
+              <span>{{classifyForm.parentName}}</span>
+          </el-form-item>
+          
+          <el-form-item label="分类名称" prop="classifyName">
+              <el-input
+                v-model="classifyForm.classifyName"
+                style="width: 80%"
+                placeholder="请输入指标名称"
+              />
+          </el-form-item>
+         
+      </el-form>
+
+      <div class="btn-bottom">
+				<el-button type="primary" plain @click="isClassifyEditDia=false">取消</el-button>
+        <el-button type="primary" @click="handleSaveClassify">确定</el-button>
+      </div>
+      
+    </el-dialog>
+</div>
+
+</template>
+<script>
+import { eventInterface } from '@/api/modules/knowledge';
+export default {
+  props: {
+    show: {
+      type: Boolean
+    },
+    ResourceType: {
+      type: Number
+    }
+  },
+  watch: {
+    show(nval) {
+      nval && this.getClassify()
+    }
+  },
+  data() {
+    return {
+      classifyOptions: [],
+      selectItem:{},
+
+      //编辑分类弹窗
+      isClassifyEditDia:false,
+      classifyForm: {
+        classifyName: '',
+        classifyId: 0,
+        parentClassifyId: 0,
+      }
+    }
+  },
+  mounted(){
+
+  },
+  methods:{
+    async getClassify() {
+      const res = await eventInterface.getClassify({
+        ResourceType: this.ResourceType
+      })
+      if(res.Ret !== 200) return
+
+      this.classifyOptions = res.Data.List
+    },
+
+    //添加
+    handleAddNode(data,node) {
+      console.log(data,node)
+      this.classifyForm = {
+        classifyName: '',
+        classifyId: 0,
+        parentClassifyId: data?data.ClassifyId:0,
+        parentName: data?data.ClassifyName:''
+      }
+      this.isClassifyEditDia = true
+    },
+
+    //编辑
+    handleEditNode(data,node) {
+      this.classifyForm = {
+        classifyName: data.ClassifyName,
+        classifyId: data.ClassifyId,
+        parentClassifyId: data.ParentId,
+        parentName: node.parent.data.ClassifyName
+      }
+      this.isClassifyEditDia = true
+    },
+
+    //删除
+    async handleRemoveNode({ClassifyId}) {
+      const res = await eventInterface.delClassifyCheck({ClassifyId, ResourceType: this.ResourceType})
+
+      if(res.Ret !== 200) return
+      if(res.Data.Code!==0) return this.$message.warning(res.Data.Msg)
+
+      const delRes = await eventInterface.delClassify({ClassifyId, ResourceType: this.ResourceType})
+
+      if(delRes.Ret !== 200) return 
+      
+      this.$message.success('删除成功')
+      this.getClassify()
+    },
+
+    handleNodeChange(data) {
+      this.selectItem = data;
+    },  
+
+    //保存分类信息
+    async handleSaveClassify() {
+      const { classifyName,parentClassifyId,classifyId } = this.classifyForm
+      let params = {
+        ResourceType: this.ResourceType,
+        ClassifyName: classifyName,
+        ParentId: parentClassifyId
+      }
+      const res = classifyId 
+        ? await eventInterface.editClassify({ ClassifyId: classifyId,...params })
+        : await eventInterface.addClassify(params)
+
+      if(res.Ret !==200) return 
+
+      this.$message.success(classifyId?'编辑成功':'新增成功')
+      this.getClassify()
+      this.isClassifyEditDia = false
+    },
+
+    cancelHandle() {
+      this.$emit('update:show',false)
+    },
+
+    //拖动结束
+    async dropOverHandle(b,a,i,e) {
+        // 被拖拽节点对应的 Node、结束拖拽时最后进入的节点、被拖拽节点的放置位置
+        const classifyId=b.data.ClassifyId
+        let list=a.parent.childNodes;
+        let PrevClassifyId=0,NextClassifyId=0,targetIndex=0;
+        list.forEach((item,index) => {
+            if(item.data.ClassifyId===classifyId){
+                targetIndex=index
+            }
+        });
+        if(targetIndex===0){
+            NextClassifyId=list[1].data.ClassifyId
+        }else if(targetIndex===list.length-1){
+            PrevClassifyId=list[list.length-1].data.ClassifyId
+        }else{
+            PrevClassifyId=list[targetIndex-1].data.ClassifyId
+            NextClassifyId=list[targetIndex+1].data.ClassifyId
+        }
+
+        const params={
+            ClassifyId:classifyId,
+            PrevClassifyId,
+            NextClassifyId,
+            ResourceType: this.ResourceType
+        }
+        console.log(params);
+        const res = await eventInterface.moveClassify(params)
+
+        if(res.Ret!==200) return
+
+        this.$message.success('移动成功')
+        this.getClassify()
+    },
+
+    //控制同级拖动
+    canDropHandle(draggingNode, dropNode, type){
+      console.log(draggingNode, dropNode, type)
+        if(type==='inner') return false
+        if(draggingNode.level!==dropNode.level) return false
+        if(draggingNode.data.ParentId!=dropNode.data.ParentId) return false
+
+        return true
+    },
+  },
+}
+</script>
+<style scoped lang='scss'>
+  .main {
+    padding: 0 30px;
+    .classify-tree {
+      height: 50vh;
+      min-height: 300px;
+      overflow-y: auto;
+      .custom-tree-node {
+        width: 100%;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+      }
+      .handle-icon {
+        width: 16px;
+        height: 16px;
+        margin: 0 4px;
+      }
+    }
+    .clasify-add-cont {
+      margin: 30px 0;
+      display: flex;
+      justify-content: center;
+      color: #409eff;
+      cursor: pointer;
+      >img {
+        width: 16px;
+        height: 16px;
+        margin-right: 10px;
+      }
+    }
+
+  }
+  .btn-bottom {
+    display: flex;
+    justify-content: center;
+    gap: 20px;
+    margin: 40px 0;
+    >.el-button {
+      width: 120px;
+    }
+  }
+</style>
+<style lang="scss">
+.knowledge-classify{
+  .classify-tree {
+    .el-tree__drop-indicator {
+      height: 3px;
+      background-color: #409eff;
+    }
+
+    .el-tree-node__content {
+      margin-bottom: 14px !important;
+    }
+
+    .el-tree-node__children {
+      .el-tree-node {
+        margin-bottom: 0px !important;
+        padding-left: 18px;
+      }
+
+      .el-tree-node__content {
+        margin-bottom: 5px !important;
+        padding-left: 0 !important;
+      }
+    }
+
+    .expanded.el-icon-caret-right:before {
+      content: url('~@/assets/img/set_m/down.png') !important;
+    }
+
+    .el-icon-caret-right:before {
+      content: url('~@/assets/img/set_m/slide.png') !important;
+    }
+    .el-tree-node__expand-icon{
+      padding-top: 10px;
+    }
+
+    .el-tree-node__expand-icon.is-leaf.el-icon-caret-right:before {
+      content: '' !important;
+    }
+
+    .el-tree-node__expand-icon.expanded {
+      -webkit-transform: rotate(0deg);
+      transform: rotate(0deg);
+    }
+
+    .el-tree-node.is-current>.el-tree-node__content {
+      background-color: #f0f4ff !important;
+    }
+
+    .el-tree-node__content {
+      padding-right: 10px !important;
+    }
+  }
+}  
+</style>

+ 44 - 0
src/views/knowledge_manage/components/eventPreview.vue

@@ -0,0 +1,44 @@
+<template>
+  <div class="event-preview">
+
+    <iframe 
+      :src="fileUrl" 
+      frameborder="0" 
+      v-if="eventDetail.IsFile" 
+      width='100%' 
+      height='550' 
+    />
+
+    <div 
+      v-else
+      class="event-html" 
+      v-html="eventDetail.Content" 
+    ></div>
+  </div>
+</template>
+<script>
+export default {
+  props: {
+    eventDetail: {
+      type: Object
+    }
+  },
+  computed: {
+    fileUrl() {
+      return this.eventDetail.FileUrl.endsWith('.pdf') ? this.eventDetail.FileUrl : `https://view.officeapps.live.com/op/view.aspx?src=${this.eventDetail.FileUrl}`
+    }
+  },
+  data() {
+    return {
+
+    }
+  },
+}
+</script>
+<style scoped lang='scss'>
+.event-preview {
+  .event-html {
+    white-space: pre-wrap;
+  }
+}
+</style>

+ 240 - 0
src/views/knowledge_manage/components/importExcelDia.vue

@@ -0,0 +1,240 @@
+<template>
+  <el-dialog
+    :title="$t('ManualEntryPage.tit_insert_data')"
+    :visible.sync="show"
+    :close-on-click-modal="false"
+    :modal-append-to-body="false"
+    center
+    v-dialogDrag
+    @close="cancelHandle"
+    custom-class="dialog-cont"
+    width="40%"
+  >
+    <div slot="title" style="display: flex; align-items: center">
+      <img
+        :src="$icons.imp"
+        style="color: #fff; width: 16px; height: 16px; margin-right: 5px"
+      />
+      <span style="font-size: 16px">{{$t('ManualEntryPage.tit_insert_data')}}</span>
+    </div>
+    <div class="down-min">
+      <dataLoading :loading="isLoading"/>
+
+      <div class="section-item">
+        <div class="templete-wrap">
+          <div class="item" v-for="tem in templateList" :key="tem.name">
+            <a :href="tem.url" download="模板">
+              <el-button type="primary" icon="el-icon-download">下载导入模板</el-button>
+            </a>
+            <div>
+              <img :src="temImg" alt="" width="150" style="display:block;margin:10px 0;">
+              <span class="editsty" @click="handlePreviewImg"><!-- 查看大图 -->{{$t('ManualEntryPage.view_big_img')}}</span>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div class="section-item">
+        <h3>上传导入模板</h3>
+        <el-upload
+          class="upload-demo"
+          :http-request="handleSuccess"
+          :before-upload="beforeUploadFile"
+          :on-progress="handleStarting"
+          :show-file-list="false"
+          accept=".xlsx"
+        >
+          <el-button type="primary" icon="el-icon-upload">导入数据</el-button>
+        </el-upload>
+      </div>
+    </div>
+    <div class="down-tip-txt">
+      <span>{{$t('ManualEntryPage.step_one')}}</span>
+      <span>{{$t('ManualEntryPage.step_two')}}</span>
+      <span>{{$t('ManualEntryPage.step_three')}}
+        <a
+          style="display: inline; color: #0052D9"
+          :href="downloadErrorlist"
+          download
+          >{{$t('ManualEntryPage.down_fail_list')}}</a
+        >。</span
+      >
+    </div>
+
+    <el-image-viewer 
+        v-if="showImgViewer" 
+        :on-close="()=>{this.previewList=[];this.showImgViewer = false}" 
+        :url-list="previewList" 
+    />
+  </el-dialog>
+</template>
+
+<script>
+import { dataInterence } from "api/api.js";
+import { eventInterface } from '@/api/modules/knowledge';
+import ElImageViewer from 'element-ui/packages/image/src/image-viewer'
+export default {
+  name: "",
+  components: { ElImageViewer },
+  props: {
+    show: {
+      type: Boolean,
+    },
+    ResourceType: {
+      type: Number
+    }
+  },
+  computed: {
+    temImg() {
+      const imgSourceMap = {
+        '/knowledge_event': require('@/assets/img/knowledge/tem_1.png'),
+        '/knowledge_policy': require('@/assets/img/knowledge/tem_2.png'),
+        '/knowledge_viewpoint': require('@/assets/img/knowledge/tem_3.png'),
+        '/knowledge_know': require('@/assets/img/knowledge/tem_4.png'),
+      }
+
+      return imgSourceMap[this.$route.path] && imgSourceMap[this.$route.path]
+    }
+  },
+  data() {
+    return {
+      downloadErrorlist:
+        process.env.VUE_APP_API_ROOT +
+        "/knowledge/resource/download_fail" +
+        `?${localStorage.getItem("auth")}&ResourceType=${this.ResourceType}`, //失败列表下载
+
+      templateList: [
+        {
+          name:/* "模板1"  */this.$t('ManualEntryPage.tem_msg',{index:1}),
+          url: process.env.VUE_APP_API_ROOT + `/knowledge/resource/template?ResourceType=${this.ResourceType}&${localStorage.getItem("auth")}`
+        }
+      ],
+      isLoading: false,
+
+      showImgViewer: false,
+      previewList: []
+    };
+  },
+  methods: {
+    cancelHandle() {
+      this.$emit('update:show',false)
+    },
+    // 校验文件和大小
+    beforeUploadFile(file) {
+      let extension = file.name.substring(file.name.lastIndexOf(".") + 1);
+      let size = file.size / 1024 / 1024; //M
+      if (extension !== "xlsx" && extension !== "xls") {
+        this.$message.warning("只能上传后缀是.xlsx和.xls的文件");
+        return false;
+      }
+      if (size > 10) {
+        this.$message.warning("文件大小不得超过10M");
+        return false;
+      }
+    },
+    handleStarting() {
+      this.isLoading = true;
+    },
+    // 上传
+    async handleSuccess(e) {
+      let {file} = e;
+      
+      this.isLoading = true;
+      let formData = new FormData()
+      formData.append('EntryFile',file)
+      formData.append('ResourceType',this.ResourceType)
+      
+      const res = await eventInterface.excelImportUpload(formData)
+
+      this.isLoading = false;
+
+      if(res.Ret !== 200) return
+        // 0成功 1部分失败 -1全部失败
+      let str = `
+          <h2 style="margin-bottom:30px">导入成功</h2>
+          <p> 本次共成功导入${res.Data.SuccessCount}条数据</p>
+        `;
+      if (res.Data.Status === 1) {
+        str = `
+            <h2 style="margin-bottom:30px">部分导入失败</h2>
+            <p>${this.$t('ManualEntryPage.upload_tip_msg2',{success_count:res.Data.SuccessCount,fail_count:res.Data.FailCount})}</p>
+            <a style="display:inline;color:#5882EF;" href="${this.downloadErrorlist}" download>${this.$t('ManualEntryPage.down_fail_list2')}</a>
+          `;
+      } else if (res.Data.Status === -1) {
+        str = `
+            <h2 style="margin-bottom:30px">导入失败!</h2>
+            <a style="display:inline;color:#5882EF;" href="${this.downloadErrorlist}" download>${this.$t('ManualEntryPage.down_fail_list2')}</a>
+          `;
+      }
+      this.$alert(str, "", {
+        dangerouslyUseHTMLString: true,
+        center: true,
+        showConfirmButton: false,
+      });
+      this.cancelHandle()
+      this.$emit("success");
+    },
+
+    handlePreviewImg() {
+      this.previewList=[this.temImg]
+      this.showImgViewer=true 
+    }
+  },
+};
+</script>
+<style lang="scss" scoped>
+.dialog-cont {
+  max-width: 800px;
+  .down-min {
+    position: relative;
+    margin: 20px 0 50px;
+    .arrow-ico {
+      width: 140px;
+      height: 14px;
+      display: block;
+      background: url("~@/assets/img/data_m/arrow_ico.png") no-repeat center;
+      background-size: 100%;
+      margin: 0 50px;
+    }
+    .icon {
+      width: 100px;
+      height: 100px;
+      display: block;
+      margin-bottom: 36px;
+      &.down_ico {
+        background: url("~@/assets/img/data_m/down_ico.png") no-repeat center;
+        background-size: cover;
+      }
+      &.up_ico {
+        background: url("~@/assets/img/data_m/up_ico.png") no-repeat center;
+        background-size: cover;
+      }
+    }
+  }
+  .down-tip-txt {
+    font-size: 14px;
+    color: #1f2e4d;
+    line-height: 25px;
+    padding-bottom: 10px;
+    span {
+      display: block;
+      margin-bottom: 18px;
+    }
+  }
+
+  .section-item {
+    padding: 20px 0;
+    &:first-child {
+      border-bottom: 1px solid #C8CDD9;
+    }
+    h3 {
+      font-size: 16px;
+      margin-bottom: 20px;
+    }
+    .templete-wrap {
+      display: flex;
+      gap: 20px;
+    }
+  }
+}
+</style>

+ 248 - 0
src/views/knowledge_manage/components/importFileDia.vue

@@ -0,0 +1,248 @@
+<template>
+   <el-dialog
+      :visible.sync="show"
+      :close-on-click-modal="false"
+      :modal-append-to-body="false"
+      @close="cancelHandle"
+      custom-class="knowledge-import-dialog"
+      top="10vh"
+      v-dialogDrag
+      title="事件信息"
+      width="650px"
+    >
+      <el-form
+        ref="formRef"
+        hide-required-asterisk
+        :model="eventForm"
+        :rules="formRules"
+        label-width="100px"
+      >
+        <el-form-item prop="title" label="标题">
+          <el-input 
+            v-model="eventForm.title" 
+            placeholder="请输入标题"
+            style="width:80%"
+          />
+        </el-form-item>
+        <el-form-item prop="classifyId" label="分类">
+          <el-cascader
+              :options="classifyOptions"
+              v-model="eventForm.classifyId"
+              :props="{
+                value: 'ClassifyId',
+                label: 'ClassifyName',
+                children: 'Child',
+                emitPath:false
+              }"
+              clearable
+              placeholder="请选择分类"
+              style="width:80%"
+          ></el-cascader>
+        </el-form-item>
+
+        <el-form-item prop="source" label="来源">
+          <el-input 
+            v-model="eventForm.source" 
+            placeholder="请输入来源"
+            style="width:80%"
+            clearable
+          />
+          <!-- <el-select
+              v-model="eventForm.source"
+              placeholder="请选择来源"
+              size="medium"
+              clearable
+              style="width:80%"
+          >
+              <el-option 
+                v-for="item in sourcesOptions" 
+                :key="item"
+                :label="item" 
+                :value="item" 
+              />
+          </el-select> -->
+        </el-form-item>
+        <el-form-item prop="tagId" label="标签">
+          <el-select
+              v-model="eventForm.tagId"
+              placeholder="请选择标签"
+              size="medium"
+              clearable
+              style="width:80%"
+          >
+              <el-option 
+                v-for="item in tagsOptions" 
+                :key="item.TagId"
+                :label="item.TagName" 
+                :value="item.TagId" 
+              />
+          </el-select>
+        </el-form-item>
+        <el-form-item prop="startTime" label="开始时间">
+          <el-date-picker
+            v-model="eventForm.startTime"
+            :value-format="formatTime"
+            :format="formatTime"
+            :type="[2,3].includes(ResourceType)?'date':'datetime'"
+            placeholder="请选择开始时间"
+            style="width:80%"
+          />
+        </el-form-item>
+        <el-form-item prop="endTime" v-if="![2,3].includes(ResourceType)" label="结束时间">
+          <el-date-picker
+            v-model="eventForm.endTime"
+            :value-format="formatTime"
+            :format="formatTime"
+            :type="[2,3].includes(ResourceType)?'date':'datetime'"
+            placeholder="请选择结束时间"
+            style="width:80%"
+          />
+        </el-form-item>
+      </el-form>
+
+      <div class="btn-bottom">
+        <el-button type="primary" plain @click="cancelHandle">取消</el-button>
+        <el-button type="primary" @click="handleConfirmEvent">确定</el-button>
+      </div>
+  </el-dialog>  
+</template>
+<script>
+import { eventInterface } from '@/api/modules/knowledge';
+export default {
+  props: {
+    show: {
+      type: Boolean
+    },
+    ResourceType: {
+      type: Number
+    },
+    importFileUrl: {
+      type: String
+    }
+  },
+  computed: {
+    formatTime() {
+      return [2,3].includes(this.ResourceType) ? 'yyyy-MM-dd' : 'yyyy-MM-dd HH:mm:ss'
+    }
+  },
+  watch: {
+    show(nval) {
+      if(!nval) return 
+
+      this.getClassifyList();
+      // this.getSourceList();
+      this.getTagsList();
+    }
+  },
+  data() {
+    return {
+      eventForm: {
+        title: '',
+        classifyId: 0,
+        source:'',
+        tagId:'',
+        startTime:'',
+        endTime:''
+      },
+      formRules:{
+        title:[
+          { required: true, message: '标题不能为空', trigger: 'blur' },
+        ],
+        classifyId:[
+          { required: true, message: '分类不能为空', trigger: 'blur' },
+        ],
+        source:[
+          { required: true, message: '来源不能为空', trigger: 'blur' },
+        ],
+        startTime:[
+          { required: true, message: '开始时间不能为空', trigger: 'blur' },
+        ],
+      },
+      
+      classifyOptions: [],
+      sourcesOptions:[],
+      tagsOptions:[],
+    }
+  },
+  mounted(){
+
+  },
+  methods:{
+    async getClassifyList() {
+      const res = await eventInterface.getClassify({
+        ResourceType: this.ResourceType
+      })
+      if(res.Ret !== 200) return
+
+      this.classifyOptions = res.Data.List || []
+    },
+
+    async getSourceList() {
+      const res = await eventInterface.getSourcesList({
+        ResourceType: this.ResourceType
+      })
+      if(res.Ret !== 200) return
+
+      this.sourcesOptions = res.Data.List || []
+    },
+
+    async getTagsList() {
+      const res = await eventInterface.getTagList({ResourceType:this.ResourceType})
+      if(res.Ret !== 200) return
+
+      this.tagsOptions=res.Data.List || []
+    },
+
+
+    async handleConfirmEvent() {
+      await this.$refs.formRef.validate()
+      
+      const { 
+        title,
+        classifyId,
+        source,
+        tagId,
+        startTime,
+        endTime
+      } = this.eventForm;
+      let params = {
+        ResourceType: this.ResourceType,
+        ClassifyId: classifyId,
+        Title: title,
+        Content: '',
+        SourceFrom: source,
+        TagId: tagId || 0,
+        StartTime: startTime,
+        EndTime: endTime || '',
+        FileUrl: this.importFileUrl
+      }
+      const res = await eventInterface.addEvent(params)
+
+      if(res.Ret !== 200) return 
+
+      this.$message.success('添加成功')
+
+      this.$emit('confirm')
+      this.cancelHandle()
+    },
+
+    cancelHandle() {
+      this.$refs.formRef.resetFields()
+      this.$emit('update:show',false)
+    }
+  },
+}
+</script>
+<style scoped lang='scss'>
+.el-form {
+  padding: 0 40px;
+}
+.btn-bottom {
+  display: flex;
+  justify-content: center;
+  margin: 30px 0;
+  .el-button {
+    width: 130px;
+  }
+}
+</style>

+ 355 - 0
src/views/knowledge_manage/edit.vue

@@ -0,0 +1,355 @@
+<template>
+  <div class="knowledge-edit-box">
+    <header>
+      <el-form
+        ref="formRef"
+        label-position="left"
+        hide-required-asterisk
+        inline
+        label-width="0"
+        :model="eventForm"
+        :rules="formRules"
+        :disabled="!isEdit"
+      >
+        <el-form-item prop="title">
+          <el-input 
+            v-model="eventForm.title" 
+            placeholder="请输入标题"
+            />
+        </el-form-item>
+        <el-form-item prop="classifyId">
+          <el-cascader
+              :options="classifyOptions"
+              v-model="eventForm.classifyId"
+              :props="{
+                value: 'ClassifyId',
+                label: 'ClassifyName',
+                children: 'Child',
+                emitPath:false
+              }"
+              clearable
+              placeholder="请选择分类"
+          ></el-cascader>
+        </el-form-item>
+
+        <el-form-item prop="source">
+          <el-input 
+            v-model="eventForm.source" 
+            placeholder="请输入来源"
+            clearable
+          />
+          <!-- <el-select
+              v-model="eventForm.source"
+              placeholder="请选择来源"
+              size="medium"
+              clearable
+          >
+              <el-option 
+                v-for="item in sourcesOptions" 
+                :key="item"
+                :label="item" 
+                :value="item" 
+              />
+          </el-select> -->
+        </el-form-item>
+        <el-form-item prop="tagId">
+          <el-select
+              v-model="eventForm.tagId"
+              placeholder="请选择标签"
+              size="medium"
+              clearable
+          >
+              <el-option 
+                v-for="item in tagsOptions" 
+                :key="item.TagId"
+                :label="item.TagName" 
+                :value="item.TagId" 
+              />
+          </el-select>
+        </el-form-item>
+        <el-form-item prop="startTime">
+          <label>开始时间</label>
+          <el-date-picker
+            v-model="eventForm.startTime"
+            :value-format="formatTime"
+            :format="formatTime"
+            :type="[2,3].includes(ResourceType)?'date':'datetime'"
+            placeholder="请选择开始时间"
+          />
+        </el-form-item>
+        <el-form-item prop="endTime" v-if="![2,3].includes(ResourceType)">
+          <label>结束时间</label>
+          <el-date-picker
+            v-model="eventForm.endTime"
+            :value-format="formatTime"
+            :format="formatTime"
+            :type="[2,3].includes(ResourceType)?'date':'datetime'"
+            placeholder="请选择结束时间"
+          />
+        </el-form-item>
+
+      </el-form>
+
+      <el-button type="primary" @click="handleEdit" v-if="!isEdit">编辑</el-button>
+    </header>
+    <div class="main">
+      <!-- 编辑 -->
+      <template v-if="isEdit&&(!eventDetail||(eventDetail&&!eventDetail.IsFile))">
+        <editor 
+          ref="editorRef"
+        />
+
+        <div class="btn-bottom">
+          <el-button type="primary" plain @click="handleBack">取消</el-button>
+          <el-button type="primary" @click="handleConfirmEvent">确定</el-button>
+        </div>
+      </template>
+
+      <!-- 详情 -->
+      <template v-if="!isEdit || (eventDetail&&eventDetail.IsFile)">
+        <eventPreview
+          :eventDetail="eventDetail||{}"
+        />
+
+        <div class="btn-bottom" v-if="isEdit&&eventDetail.IsFile">
+          <el-button type="primary" plain @click="handleBack">取消</el-button>
+          <el-button type="primary" @click="handleConfirmEvent">确定</el-button>
+        </div>
+      </template>
+    </div>
+  </div>
+</template>
+<script>
+import { eventInterface } from '@/api/modules/knowledge';
+import editor from '@/views/semantics_manage/summery/components/editor.vue';
+import eventPreview from './components/eventPreview.vue';
+export default {
+  components: { editor,eventPreview },
+  computed: {
+    isEdit() {
+      return this.$route.path==='/knowledgeEdit'
+    },
+    currentPath() {
+      const pathMap = {
+        0:'/knowledge_event',
+        1:'/knowledge_policy',
+        2:'/knowledge_viewpoint',
+        3:'/knowledge_know',
+      }
+
+      return pathMap[this.ResourceType] && pathMap[this.ResourceType]
+    },
+    formatTime() {
+      return [2,3].includes(this.ResourceType) ? 'yyyy-MM-dd' : 'yyyy-MM-dd HH:mm:ss'
+    }
+  },
+  data() {
+    return {
+      ResourceType: Number(this.$route.query.source),
+      id: Number(this.$route.query.id),
+      eventDetail: null,
+      eventForm: {
+        title: '',
+        classifyId: 0,
+        source:'',
+        tagId:'',
+        startTime:'',
+        endTime:''
+      },
+      formRules:{
+        title:[
+          { required: true, message: '标题不能为空', trigger: 'blur' },
+        ],
+        classifyId:[
+          { required: true, message: '分类不能为空', trigger: 'blur' },
+        ],
+        source:[
+          { required: true, message: '来源不能为空', trigger: 'blur' },
+        ],
+        startTime:[
+          { required: true, message: '开始时间不能为空', trigger: 'blur' },
+        ],
+      },
+      
+      classifyOptions:[],
+      sourcesOptions:[],
+      tagsOptions:[],
+    }
+  },
+  beforeRouteEnter(to,from,next) {
+    
+    if(to.query.source){
+      let pathMap = {
+        0: { name: '事件库',path:'knowledge_event' },
+        1: { name: '政策库',path:'knowledge_policy' },
+        2: { name: '观点库',path:'knowledge_viewpoint' },
+        3: { name: '知识库',path:'knowledge_know' },
+      }
+      to.meta.pathFrom=pathMap[to.query.source].path;
+      to.meta.pathName=pathMap[to.query.source].name;
+    }
+    next()
+
+  },
+  mounted(){
+    this.getClassifyList()
+    // this.getSourceList()
+    this.getTagsList()
+
+    this.id && this.getEventDetail()
+  },
+  methods:{
+
+    async getClassifyList() {
+      const res = await eventInterface.getClassify({
+        ResourceType: this.ResourceType
+      })
+      if(res.Ret !== 200) return
+
+      this.classifyOptions = res.Data.List || []
+    },
+
+    async getSourceList() {
+      const res = await eventInterface.getSourcesList({
+        ResourceType: this.ResourceType
+      })
+      if(res.Ret !== 200) return
+
+      this.sourcesOptions = res.Data.List || []
+    },
+
+    async getTagsList() {
+      const res = await eventInterface.getTagList({ResourceType:this.ResourceType})
+      if(res.Ret !== 200) return
+
+      this.tagsOptions=res.Data.List || []
+    },
+
+    async getEventDetail() {
+      const res = await eventInterface.getEventDetail({
+        ResourceType: this.ResourceType,
+        KnowledgeResourceId: this.id
+      })
+
+      if(res.Ret !== 200) return
+      this.eventDetail = {
+        ...res.Data,
+        StartTime: res.Data.StartTime 
+          ? this.$moment(res.Data.StartTime).format([2,3].includes(this.ResourceType)?'YYYY-MM-DD':'YYYY-MM-DD HH:mm:ss') 
+          : '',
+        EndTime:res.Data.EndTime 
+          ? this.$moment(res.Data.EndTime).format([2,3].includes(this.ResourceType)?'YYYY-MM-DD':'YYYY-MM-DD HH:mm:ss') 
+          : '',
+      };
+      this.eventForm = {
+        title: this.eventDetail.Title,
+        classifyId: this.eventDetail.ClassifyId,
+        source: this.eventDetail.SourceFrom,
+        tagId: this.eventDetail.TagId||'',
+        startTime: this.eventDetail.StartTime,
+        endTime:this.eventDetail.EndTime
+      }
+      
+      this.$refs.editorRef&&this.$refs.editorRef.initData(this.eventDetail.Content)
+    },
+
+    async handleConfirmEvent() {
+      await this.$refs.formRef.validate()
+      const { 
+        title,
+        classifyId,
+        source,
+        tagId,
+        startTime,
+        endTime
+      } = this.eventForm;
+      let params = {
+        ResourceType: this.ResourceType,
+        ClassifyId: classifyId,
+        Title: title,
+        Content: this.$refs.editorRef?this.$refs.editorRef.content:'',
+        SourceFrom: source,
+        TagId: tagId || 0,
+        StartTime: startTime,
+        EndTime: endTime || '',
+        FileUrl: this.eventDetail?this.eventDetail.FileUrl:''
+      }
+      const res = this.id
+        ? await eventInterface.editEvent({
+          ...params,
+          KnowledgeResourceId: this.id
+        })
+        : await eventInterface.addEvent(params)
+
+      if(res.Ret !== 200) return 
+
+      this.$message.success(this.id?'编辑成功':'添加成功')
+      
+      this.$router.replace({
+        path: this.currentPath
+      })
+    },
+
+    handleBack() {
+      this.$router.replace({
+        path: this.currentPath
+      })
+    },
+
+    handleEdit() {
+      this.$router.push({
+        path:'/knowledgeEdit',
+        query: {
+          id: this.id,
+          source: this.ResourceType
+        }
+      })
+    }
+  },
+}
+</script>
+<style scoped lang='scss'>
+  .knowledge-edit-box {
+    height: calc(100vh - 120px);
+    display: flex;
+    flex-direction: column;
+    header,.main{
+      padding: 20px;
+      background: #fff;
+      border: 1px solid #C8CDD9;
+      border-radius: 4px;
+    }
+    header {
+      display: flex;
+      justify-content: space-between;
+      flex-wrap: wrap;
+      .el-button {
+        width: 130px;
+      }
+    }
+    .main {
+      flex: 1;
+      margin-top: 20px;
+      overflow-y: auto;
+      .btn-bottom {
+        display: flex;
+        gap: 20px;
+        justify-content: flex-end;
+        margin-top: 20px;
+        .el-button {
+          width: 130px;
+        }
+      }
+    }
+  }
+</style>
+<style lang="scss">
+  .knowledge-edit-box {
+    .fr-element {
+      height: calc(100vh - 500px);
+    }
+    #froala-editor-documentContent {
+      display: none !important;
+    }
+  }
+</style>

+ 545 - 0
src/views/knowledge_manage/list.vue

@@ -0,0 +1,545 @@
+<template>
+  <div class="knowledge-box">
+      <header>
+        <div class="left-filter">
+          <el-button 
+            type="primary" 
+            @click="$router.push({path:'/knowledgeEdit',query: { source: ResourceType }})"
+            v-if="checkBtnAuth('add')"
+          >添加{{ titlePath }}</el-button>
+          <el-dropdown 
+            split-button
+            type="primary" 
+            @click="isImportExcelDia=true"
+            v-if="checkBtnAuth('import')"
+            @command="handleImport"
+          >
+            Excel导入
+            <el-dropdown-menu slot="dropdown">
+              <el-dropdown-item command="file">文件导入</el-dropdown-item>
+            </el-dropdown-menu>
+          </el-dropdown>
+          <el-button 
+            type="primary" 
+            plain 
+            @click="isOpenClassifyDia=true"
+            v-if="checkBtnAuth('classifyEdit')"
+          >分类管理</el-button>
+          <el-button 
+            type="primary" 
+            plain 
+            @click="handleGoTagSet"
+            v-if="checkBtnAuth('tagEdit')"
+          >标签管理</el-button>
+        </div>
+
+        <div class="right-filter">
+          <el-popover 
+            placement="bottom" 
+            trigger="click" 
+            :visible-arrow="false"
+            popper-class="report-select-popover"
+            width="350" 
+            style="display: inline-block;"
+          >
+              <div class="select-wrap">
+                  <div class="select-top">
+                    <h4>筛选条件</h4>
+                    <span @click="handleClearFilter"><i class="el-icon-delete"/>清空所选条件</span>
+                  </div>
+                  <div class="select-item">
+                    <el-cascader
+                        v-model="filterForm.classifys"
+                        :options="classifyOptions"
+                        :props="{
+                          value: 'ClassifyId',
+                          label: 'ClassifyName',
+                          children: 'Child',
+                          emitPath:false,
+                          multiple:true,
+                        }"
+                        :show-all-levels="false"
+                        clearable
+                        placeholder="请选择分类"
+                        style="width:100%;"
+                        @change="filterChange"
+                    ></el-cascader>
+                  </div>
+                  <div class="select-item">
+                      <el-select
+                          v-model="filterForm.sources"
+                          placeholder="请选择来源"
+                          size="medium"
+                          clearable
+                          style="width:100%;"
+                          multiple
+                          @change="filterChange"
+                      >
+                          <el-option 
+                            v-for="item in sourcesOptions" 
+                            :key="item"
+                            :label="item" 
+                            :value="item" 
+                          />
+                      </el-select>
+                  </div>
+  
+                  <div class="select-item">
+                      <el-select
+                          v-model="filterForm.tags"
+                          placeholder="请选择标签"
+                          size="medium"
+                          clearable
+                          style="width:100%;"
+                          multiple
+                          @change="filterChange"
+                      >
+                          <el-option 
+                            v-for="item in tagsOptions" 
+                            :key="item.TagId"
+                            :label="item.TagName" 
+                            :value="item.TagId" 
+                          />
+                      </el-select>
+                  </div>
+                  <div class="select-item">
+                      <el-select
+                          v-model="filterForm.users"
+                          placeholder="请选择用户"
+                          size="medium"
+                          clearable
+                          style="width:100%;"
+                          multiple
+                          @change="filterChange"
+                      >
+                          <el-option 
+                            v-for="item in usersOptions" 
+                            :key="item.AdminId"
+                            :label="item.AdminRealName" 
+                            :value="item.AdminId" 
+                          />
+                      </el-select>
+                  </div>
+
+                  <!-- <div class="select-bot">
+                    <el-button type="primary" plain>取消</el-button>
+                    <el-button type="primary">确认</el-button>
+                  </div> -->
+              </div>
+              <div class="select-btn" slot="reference">
+                  <img src="~@/assets/icons/filter.svg">
+                  <span class="select-num">{{selectNum}}</span>
+                  <span>筛选条件</span>
+              </div>
+          </el-popover>
+
+          <el-input
+            @input="filterChange"
+            placeholder="标题名称"
+            v-model="filterForm.keyWord"
+            clearable
+            style="width:300px"
+            prefix-icon="el-icon-search"
+          />
+        </div>
+      </header>
+
+      <div class="main">
+        <el-table
+          :data="tableData"
+          style="box-shadow: 0px 3px 6px rgba(155, 170, 219, 0.2);margin-top: 20px"
+          border
+          ref="table"
+        >
+          <el-table-column
+            v-for="item in tableColums"
+            :key="item.key"
+            :label="item.label"
+            :width="item.widthsty"
+            :min-width="item.minwidthsty"
+            align="center"
+          >
+            <template slot-scope="{row}">
+              <span v-if="item.key==='Title'" class="editsty" @click="lookDetailHandle(row,'look')">{{row[item.key]}}</span>
+              <span v-else>{{row[item.key]}}</span>
+            </template>
+          </el-table-column>
+
+          <el-table-column
+            :label="$t('Table.column_operations')"
+            align="center"
+          >
+            <template slot-scope="{row}">
+              <div>
+                <span class="editsty" @click="lookDetailHandle(row,'edit')" v-if="checkBtnAuth('edit')">{{$t('Table.edit_btn')}}</span>
+
+                <span class="deletesty" @click="handleDelItem(row)" v-if="checkBtnAuth('del')">{{$t('Table.delete_btn')}}</span>
+              </div>
+            </template>
+          </el-table-column>
+          <div class="nodata" slot="empty">
+            <tableNoData :text="$t('Table.prompt_slogan')" size="mini"/>
+          </div>
+        </el-table>
+
+        <div style="height:35px;margin: 20px 0;">
+          <m-page
+            :page_no="filterForm.pageNo"
+            :pageSize="filterForm.pageSize"
+            :total="total"
+            @handleCurrentChange="pageChange"
+          />
+        </div>
+      </div>
+
+      <input type="file" @change="fileSelectedImport" id="file"  style="display: none;">
+
+      <!-- 分类管理弹窗 -->
+      <classifyDia
+        :show.sync="isOpenClassifyDia"
+        :ResourceType="ResourceType"
+      />
+
+      <!-- 导入excel弹窗 -->
+      <importExcelDia
+        :show.sync="isImportExcelDia"
+        :ResourceType="ResourceType"
+        @success="getTableData"
+      />
+      
+      <!-- 导入文件信息弹窗 -->
+      <importFileDia
+        :show.sync="isImportFileDia"
+        :importFileUrl="importFileUrl"
+        :ResourceType="ResourceType"
+        @confirm="getTableData"
+      />
+  </div>
+</template>
+<script>
+import { eventInterface } from '@/api/modules/knowledge';
+import classifyDia from './components/classifyDia.vue'
+import importExcelDia from './components/importExcelDia.vue';
+import importFileDia from './components/importFileDia.vue';
+import mPage from '@/components/mPage.vue'
+export default {
+  components: { mPage,classifyDia,importExcelDia,importFileDia },
+  computed: {
+    ResourceType() {
+      const apiMap = {
+        '/knowledge_event': 0,
+        '/knowledge_policy': 1,
+        '/knowledge_viewpoint': 2,
+        '/knowledge_know': 3,
+      }
+
+      return apiMap[this.$route.path] && apiMap[this.$route.path]
+    },
+    titlePath() {
+      const titleMap = {
+        '/knowledge_event': '事件',
+        '/knowledge_policy': '政策',
+        '/knowledge_viewpoint': '观点',
+        '/knowledge_know': '知识',
+      }
+
+      return titleMap[this.$route.path] && titleMap[this.$route.path]
+    },
+    tableColums() {
+      return [
+        { label: [2,3].includes(this.ResourceType)?'时间':'开始时间',key: 'StartTime' },
+        { label: '标题',key: 'Title',minwidthsty:'150px' },
+        { label: '来源',key: 'SourceFrom' },
+        { label: '分类',key: 'ClassifyFullName' },
+        { label: '标签',key: 'TagName' },
+        { label: '添加人',key: 'AdminRealName' },
+      ]
+    },
+
+    selectNum() {
+      let num = 0;
+
+      this.filterForm.classifys.length && num++;
+      this.filterForm.sources.length && num++;
+      this.filterForm.tags.length && num++;
+      this.filterForm.users.length && num++;
+
+      return num
+    }
+  },
+  data() {
+    return {
+      filterForm: {
+        pageNo: 1,
+        pageSize:15,
+        classifys: [],
+        sources: [],
+        tags: [],
+        users: [],
+        keyWord:"",
+      },
+      classifyOptions:[],
+      sourcesOptions:[],
+      tagsOptions:[],
+      usersOptions:[],
+      total: 0,
+      tableData: [],
+
+      //分类弹窗
+      isOpenClassifyDia: false,
+      
+      //excel导入弹窗
+      isImportExcelDia: false,
+
+      //文件导入弹窗
+      isImportFileDia: false,
+      importFileUrl:''
+    }
+  },
+  mounted(){
+    this.getClassifyOptions();
+    this.getSourceOptions();
+    this.getTagOptions()
+    this.getUsersOptions()
+    this.getTableData()
+  },
+  methods:{
+    async getClassifyOptions() {
+      const res = await eventInterface.getClassify({
+        ResourceType: this.ResourceType
+      })
+      if(res.Ret !== 200) return
+
+      this.classifyOptions = res.Data.List || []
+    },
+
+    async getSourceOptions() {
+      const res = await eventInterface.getSourcesList({
+        ResourceType: this.ResourceType
+      })
+      if(res.Ret !== 200) return
+
+      this.sourcesOptions = res.Data.List || []
+    },
+    async getTagOptions() {
+      const res = await eventInterface.getTagList({ResourceType:this.ResourceType})
+      if(res.Ret !== 200) return
+
+      this.tagsOptions=res.Data.List || []
+    },
+
+    async getUsersOptions() {
+      const res = await eventInterface.getUsersList({ ResourceType:this.ResourceType })
+      if(res.Ret !== 200) return
+
+      this.usersOptions=res.Data.List || []
+    },
+
+
+    async getTableData() {
+      const { pageNo,
+        pageSize,
+        classifys,
+        sources,
+        tags,
+        users,
+        keyWord } = this.filterForm;
+      let params = {
+        PageSize:pageSize,
+        CurrentIndex:pageNo,
+        ClassifyIds:classifys.join(','),
+        SysUserIds:users.join(','),
+        TagIds:tags.join(','),
+        Keyword:keyWord,
+        SourceFrom: sources.join(','),
+        ResourceType: this.ResourceType
+      }
+      const res = await eventInterface.getEventList(params)
+
+      if(res.Ret !==200 ) return 
+
+      this.tableData = res.Data.List||[]
+      this.total = res.Data.Paging.Totals
+    },
+
+    filterChange() {
+      this.filterForm.pageNo = 1;
+      this.getTableData()
+    },
+
+    pageChange(page) {
+      this.filterForm.pageNo = page;
+      this.getTableData()
+    },
+
+    handleClearFilter() {
+      this.filterForm.classifys = []
+      this.filterForm.sources = []
+      this.filterForm.tags = []
+      this.filterForm.users = []
+      this.filterChange()
+    },
+
+    lookDetailHandle(item,type) {
+      const { href } = this.$router.resolve({
+        path: type==='look'?'/knowledgeDetail':'/knowledgeEdit',
+        query: {
+          id: item.KnowledgeResourceId,
+          source: this.ResourceType
+        }
+      }) 
+
+      window.open(href,'_blank')
+    },
+
+    handleDelItem({KnowledgeResourceId}) {
+      this.$confirm(
+        `确定删除该${ this.titlePath }吗?`, 
+        '提示',
+        {
+        type: 'warning'
+      }).then(async() => {
+        const res = await eventInterface.delEvent({
+          KnowledgeResourceId,
+          ResourceType: this.ResourceType
+        })
+
+        if(res.Ret !==200) return 
+        this.$message.success('删除成功')
+        this.getTableData()
+      })
+    },
+
+    handleGoTagSet() {
+      this.$router.push({
+        path: '/knowledge_tag',
+        query: {
+          source: this.ResourceType
+        }
+      })
+    },
+
+
+    handleImport(type) {
+      if(type === 'file') {
+        $(`#file`).click()
+      }
+    },
+    //选择文件上传
+    async fileSelectedImport(){ 
+      let file = document.getElementById('file').files[0];
+      let reg = new RegExp(/\.pdf|\.docx|\.pptx|\.ppt$/,'i')
+
+      if(file){
+        if(!reg.test(file.name)) return this.$message.warning('只能上传pdf/docx/ppt等文件');
+        if(file.size > 5.1*1024*1024) return this.$message.warning("上传文件大小不超过50MB");
+
+        let downloadHint = this.$message({
+            type:"info",
+            message:'上传中,请稍后······',
+            duration:0,
+            iconClass:'el-icon-loading'
+        })
+
+        let formData = new FormData()
+        formData.append('File',file)
+        formData.append('ResourceType',this.ResourceType)
+
+        const res = await eventInterface.fileImportUpload(formData)
+
+        downloadHint.close()
+        if(res.Ret !== 200) return
+
+        this.importFileUrl = res.Data.FileUrl
+        
+        this.isImportFileDia = true;
+      } 
+		},
+
+    checkBtnAuth(key) {
+      const {isShowBtn}=this.permissionBtn
+       const authMap = {
+        '/knowledge_event': 'event',
+        '/knowledge_policy': 'policy',
+        '/knowledge_viewpoint': 'viewpoint',
+        '/knowledge_know': 'know',
+      }
+
+      let permission_prefix = authMap[this.$route.path]&&authMap[this.$route.path]
+
+      return isShowBtn('knowledgePermission',`${permission_prefix}_${key}`)
+    }
+  },
+}
+</script>
+<style scoped lang='scss'>
+*{ box-sizing: border-box; }
+.knowledge-box {
+  padding: 20px;
+  background: #fff;
+  border: 1px solid #C8CDD9;
+  border-radius: 4px;
+  min-height: calc(100vh - 120px);
+
+  header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    >div {
+      display: flex;
+      gap: 10px;
+    }
+    .select-btn{
+        cursor: pointer;
+        width:130px;
+        height: 36px;
+        text-align: center;
+        background-color: #ECF2FE;
+        border-radius: 4px;
+        box-sizing: border-box;
+        line-height:36px;
+        img,span{
+          display: inline-block;
+          vertical-align: middle;
+        }
+        .select-num{
+          width:20px;
+          height:20px;
+          line-height: 20px;
+          border-radius: 50%;
+          background-color:#0052D9;
+          color:white;
+          font-size: 12px;
+      }
+    }
+  }
+}
+
+.select-wrap{
+  padding:8px;
+  margin:0 20px;
+  .select-top {
+    display: flex;
+    justify-content: space-between;
+    >span { color: #999;}
+  }
+  .select-item{
+      margin-top:20px;
+  }
+  .select-bot {
+    display: flex;
+    justify-content: center;
+    margin-top: 20px;
+    .el-button{
+      width: 120px;
+    }
+  }
+}
+</style>
+<style lang="scss">
+.knowledge-box {
+  .el-table td{
+    padding: 6px 0;
+  }
+}
+</style>

+ 271 - 0
src/views/knowledge_manage/tagSetting.vue

@@ -0,0 +1,271 @@
+<template>
+    <div class="knowledge-tag-page">
+        <div class="top-wrap">
+            <el-button 
+                type="primary"
+                @click="handleAddTag"
+            >添加标签</el-button>
+        </div>
+        <div class="content-box">
+            <el-tree
+			    :data="list"
+				node-key="TagId"
+                :props="{
+                    label: 'TagName',
+                    children: 'Child'
+                }"
+				check-strictly
+				empty-text="暂无标签"
+                draggable
+                :allow-drop="canDropHandle"
+                @node-drop="dropOverHandle"
+			>
+				<div
+					class="classify-item-wrap"
+					slot-scope="{ data }"
+				>
+                    <div>
+                        <span>{{data.TagName}}</span>
+                    </div>
+					
+                    <div class="opt-box">
+                        <img class="icon-drag" src="~@/assets/img/data_m/move_ico2.png" alt="">
+                        <img class="icon-set" src="~@/assets/img/icons/variety_set.png" alt="" @click.stop="handleEditTag(data)">
+                        <img class="icon-del" src="~@/assets/img/set_m/del_icon.png"  @click="handleDelTag(data)"/>
+                    </div>
+				</div>
+			</el-tree>
+        </div>
+
+        <!-- 添加/编辑 -->
+    <el-dialog 
+        v-if="addDialogShow"
+        :title="tagForm.id?'编辑标签':'添加标签'" 
+        :modal-append-to-body='false' 
+        :visible.sync="addDialogShow" 
+        :close-on-click-modal="false" 
+        :center="true" 
+        v-dialogDrag 
+        width="620px" 
+        @close="addDialogShow=false"
+    >
+        <div style="display: flex;align-items: center;justify-content: center;">
+            <el-form :model="tagForm" label-width="auto" :rules="tagFormRules" ref="tagFormRef">
+                <!-- 名称 -->
+                <el-form-item label="标签名称" prop="TagName">
+                    <el-input 
+                        v-model="tagForm.TagName" 
+                        style="width: 317px;" 
+                        placeholder="请输入标签名称">
+                    </el-input>
+                </el-form-item>
+            </el-form>
+        </div>
+        <div solt="footer" style="padding: 20px 0;text-align: center;">
+            <el-button size="medium" style="width:130px;" @click="addDialogShow=false">{{ $t('Dialog.cancel_btn') }}</el-button>
+            <el-button type="primary" size="medium" style="margin-left: 16px;width:130px ;" @click="handleSaveEditTag">{{ $t('Dialog.confirm_save_btn') }}</el-button>
+      </div>
+    </el-dialog>
+        
+    </div>
+</template>
+
+<script>
+import mDialog from '@/components/mDialog.vue';
+import { getchapterTypeList,addChapterType,editChapterType,} from 'api/api.js';
+import { eventInterface } from '@/api/modules/knowledge';
+import {setChapterEnable,setChapterSort} from '@/api/modules/oldApi.js'
+export default {
+    name:"tagSetting",
+    components:{ mDialog },
+    data() {
+        return {
+            list:[],
+            // 添加/编辑弹窗
+            addDialogShow:false,
+            tagForm:{
+                TagName:"",
+                TagId:0
+            },
+            ResourceType: Number(this.$route.query.source),
+
+            reportVarietyList:[],//中文品种列表
+        }
+    },
+    beforeRouteEnter(to,from,next) {
+    
+        if(to.query.source){
+            let pathMap = {
+                0: { name: '事件库',path:'knowledge_event' },
+                1: { name: '政策库',path:'knowledge_policy' },
+                2: { name: '观点库',path:'knowledge_viewpoint' },
+                3: { name: '知识库',path:'knowledge_know' },
+            }
+            to.meta.pathFrom=pathMap[to.query.source].path;
+            to.meta.pathName=pathMap[to.query.source].name;
+        }
+        next()
+
+    },
+    mounted(){
+        this.getList()
+    },
+    methods: {
+        async getList(){
+
+            const res = await eventInterface.getTagList({ResourceType:this.ResourceType})
+                if(res.Ret !== 200) return
+
+                this.list=res.Data.List || []
+        },
+
+        handleAddTag(){
+            this.addDialogShow=true
+            this.tagForm = {
+                TagName:"",
+                TagId:0
+            }
+        },
+
+        handleEditTag(row){
+            this.tagForm={
+                TagName:row.TagName,
+                TagId:row.TagId
+            }
+            this.addDialogShow=true
+        },
+
+
+        handleDelTag({TagId}) {
+            this.$confirm(
+                '确定删除该标签吗?', 
+                '提示',
+                {
+                type: 'warning'
+            }).then(async() => {
+                const res = await eventInterface.delTag({
+                    TagId,
+                    ResourceType:this.ResourceType
+                })
+
+                if(res.Ret !== 200) return 
+
+                this.$message.success('删除成功')
+                this.getList()
+            })
+        },
+
+        // 保存
+        async handleSaveEditTag(){
+            await this.$refs.tagFormRef.validate()
+            // 添加小程序是否显示参数 0显示,1隐藏
+            let params={
+                ...this.tagForm,
+                ResourceType:this.ResourceType
+            }
+
+            const res = params.TagId
+                ? await eventInterface.editTag(params)
+                : await eventInterface.addTag(params)
+
+            if(res.Ret !== 200) return
+
+            this.$message.success(
+                params.TagId
+                ?'编辑成功'
+                :'添加成功'
+            )
+            this.addDialogShow=false
+            this.getList()
+        },
+
+        //控制只能同级拖动
+        canDropHandle(draggingNode, dropNode, type){
+            if(type==='inner') return false //禁止向内部拖动
+            return true
+        },
+
+        //拖动结束
+        async dropOverHandle(b,a,i,e) {
+            // 被拖拽节点对应的 Node、结束拖拽时最后进入的节点、被拖拽节点的放置位置
+            const TagId=b.data.TagId
+            let index=this.list.findIndex(item=>item.TagId===TagId)
+            const PrevTagId=index==0?0:this.list[index-1].TagId
+            const NextTagId=index==this.list.length-1?0:this.list[index+1].TagId
+
+            
+            const params={
+                TagId,
+                PrevTagId,
+                NextTagId,
+                ResourceType:this.ResourceType
+            }
+            const res = await eventInterface.moveTag(params)
+
+            if(res.Ret!==200) return
+            this.$message.success('移动成功')
+        },
+        
+    },
+}
+</script>
+
+<style lang="scss">
+.el-cascader .el-input{
+  width: 100%;
+}
+.knowledge-tag-page{
+    .content-box{
+        .el-tree-node__content{
+            padding-top: 10px;
+            padding-bottom: 10px;
+            border-bottom: 1px solid #C8CDD9;
+        }
+    }
+}
+
+</style>
+<style lang="scss" scoped>
+.top-wrap{
+    display: flex;
+    justify-content: space-between;
+    background: #FFFFFF;
+    border-radius: 4px;
+    padding: 20px;
+}
+.content-box{
+    padding: 20px;
+    margin-top: 20px;
+    height: calc(100vh - 260px);
+    overflow-y: auto;
+    background-color: #FFFFFF;
+    .classify-item-wrap{
+        flex: 1;
+        padding-right: 20px;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        .tag{
+            display: inline-block;
+            min-width: 76px;
+            line-height: 30px;
+            text-align: center;
+            &.open{
+                background-color: #ECF2FE;
+                color: #0052D9;
+            }
+            &.close{
+                background-color: #0052D9;
+                color: #fff;
+            }
+        }
+        .opt-box{
+            .icon-drag,.icon-set,.icon-del{
+                width: 16px;
+                height: 16px;
+                margin-left: 10px;
+            }
+        }
+    } 
+}
+</style>

+ 4 - 4
src/views/mychart_manage/components/chartDetailDia.vue

@@ -108,19 +108,19 @@
               >
                 <span><i class="el-icon-refresh" style="font-size: 15px;"/>&nbsp;<!-- 刷新 -->{{$t('Edb.detail_refresh_btn')}} </span>
               </span>
-              <span
+              <!-- <span
                   class="span-item"
                   style="margin-left: 7px"
                   @click="$parent.addMychartHandle(chartInfo)"
-                  v-if="['/database'].includes($route.path)"
+                  v-if="['/database','/edbBasicbase'].includes($route.path)"
               >
                   <img
                       :src="$icons.chart_join_ico"
                       alt=""
                       style="width: 13px; height: 12px; vertical-align: middle"
                   />
-                  <!-- 加入我的图库 -->{{$t('Chart.chart_addmy_btn')}}
-              </span>
+                  {{$t('Chart.chart_addmy_btn')}}
+              </span> -->
               <span
                 v-permission="permissionBtn.myETAPermission.myChart_edit"
                 class="span-item"

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

@@ -81,7 +81,7 @@
             </el-option>
           </el-select>
         </el-form-item>
-        <el-form-item label="预测指标名称" prop="edbName">
+        <el-form-item label="衍生指标名称" prop="edbName">
           <el-input
           v-model="formData.edbName"
           style="width: 90%"

+ 1 - 1
src/views/predictEdb_manage/predictEdb.vue

@@ -854,7 +854,7 @@ export default {
 
 		/* 添加指标 */
 		addEdbHandle() {
-			if(!this.treeData.length) return this.$message.warning('请先添加预测指标分类');
+			if(!this.treeData.length) return this.$message.warning('请先添加衍生指标分类');
 			this.$router.push({
 				path:'/addpredictEdb'
 			})

+ 15 - 15
src/views/report_manage/reportV2/components/chapterEditWrapper.vue

@@ -169,7 +169,7 @@
                     <el-dropdown-item 
                       :command="{type:'adTag',item}" 
                       v-if="permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportMange_chapter_editTag)"><!-- 添加标签 -->{{$t('ReportManage.ReportList.add_labels_section')}}</el-dropdown-item>
-                    <el-dropdown-item :command="{type:'upAudio',item}"><!-- 上传录音 -->{{$t('ReportManage.ReportList.up_recording_lable')}}</el-dropdown-item>
+                    <!-- <el-dropdown-item :command="{type:'upAudio',item}">上传录音{{$t('ReportManage.ReportList.up_recording_lable')}}</el-dropdown-item> -->
                   </el-dropdown-menu>
                 </el-dropdown>
               </div>
@@ -207,7 +207,7 @@
                 placeholder="请输入章节名称"
               />
           </el-form-item>
-          <el-form-item prop="varietys">
+          <!-- <el-form-item prop="varietys">
               <template slot="label">
                   <el-tooltip class="item" effect="dark">
                       <div slot="content" v-html="varietyTip"></div>
@@ -234,7 +234,7 @@
                   style="width:350px;"
                   clearable
               ></el-cascader>
-          </el-form-item>
+          </el-form-item> -->
           <el-form-item prop="editors" :label="$t('ReportManage.ReportList.label_chap_editor')">
             <el-cascader
               v-model="chapterInfo.editors"
@@ -301,7 +301,7 @@
 
 
     <!-- 上传音频弹窗 -->
-    <m-dialog
+    <!-- <m-dialog
       :show.sync="isOpenUploadAudio"
       :title="$t('ReportManage.smart_audio_upload_btn')"
       width="450px"
@@ -338,7 +338,7 @@
                 <el-button type="primary" @click="handleSaveAudio" :loading="uploadAudioLoading">{{uploadAudioLoading ? $t('ReportManage.smart_btn.uploading') :$t('Dialog.confirm_btn')}}</el-button>
             </div>
         </div>
-    </m-dialog>
+    </m-dialog> -->
 
     <!-- 版图设置弹窗 -->
     <smartTerritorSet 
@@ -394,11 +394,11 @@ export default {
 
       /* 章节弹窗 */
       isOpenChapterDia: false,
-      reportVarietyOpts: [],
+      // reportVarietyOpts: [],
       userOpts: [],
       chapterInfo: {
         id: 0,
-        varietys:[],
+        // varietys:[],
         editors:[],
         chapterName:'',
         tags: '',
@@ -528,7 +528,7 @@ export default {
       if(item.ReportChapterId) {
         this.chapterInfo = {
           id: item.ReportChapterId,
-          varietys:item.PermissionIdList,
+          // varietys:item.PermissionIdList,
           editors:item.GrandAdminIdList,
           chapterName:item.Title,
           tags: ''
@@ -536,7 +536,7 @@ export default {
       }else {
         this.chapterInfo = {
           id: 0,
-          varietys:this.reportVarietyOpts.map(_ =>_.PermissionId)||[],
+          // varietys:this.reportVarietyOpts.map(_ =>_.PermissionId)||[],
           editors:[],
           chapterName:'',
           tags: ''
@@ -552,7 +552,7 @@ export default {
 
       let params = {
         Title: this.chapterInfo.chapterName,
-        PermissionIdList: this.chapterInfo.varietys,
+        // PermissionIdList: this.chapterInfo.varietys,
         AdminIdList: this.chapterInfo.editors
       }
 
@@ -611,7 +611,7 @@ export default {
     openAddChapterTag(item) {
       this.chapterInfo = {
         id: item.ReportChapterId,
-        varietys:[],
+        // varietys:[],
         editors:[],
         chapterName: item.Title,
         tags: item.Trend
@@ -690,9 +690,9 @@ export default {
         case 'adTag': 
           this.openAddChapterTag(item)
           break
-        case 'upAudio': 
-          this.openUploadAudio(item)
-          break
+        // case 'upAudio': 
+        //   this.openUploadAudio(item)
+        //   break
         case 'wxShare':
           this.handleGetWechatImg(item)
           break
@@ -740,7 +740,7 @@ export default {
         this.$emit('checkClassifyNameArr',classify)
       }
 
-      this.reportVarietyOpts = res.Data.PermissionList||[];
+      // this.reportVarietyOpts = res.Data.PermissionList||[];
       this.userOpts = res.Data.GrandAdminList||[];
 
     },

+ 11 - 11
src/views/report_manage/reportV2/components/reportBaseInfoDia.vue

@@ -52,11 +52,11 @@
           />
         </el-form-item>
 
-        <el-form-item prop="relationVariety" :label="$t('ReportManage.ReportList.label_relation_variety')" v-if="formData.relationVariety.length">
+        <!-- <el-form-item prop="relationVariety" :label="$t('ReportManage.ReportList.label_relation_variety')" v-if="formData.relationVariety.length">
           <div class="permission-wrap">
             <el-tag v-for="item in formData.relationVariety" :key="item.ChartPermissionId">{{item.PermissionName}}</el-tag>
           </div>
-        </el-form-item>
+        </el-form-item> -->
 
         <el-form-item prop="title" :label="$t('ReportManage.ReportList.label_report_tit')">
           <el-input
@@ -252,7 +252,7 @@ export default {
             isPublcPublish: this.reportInfo.IsPublicPublish
           }
 
-          this.getRelationPermission()
+          // this.getRelationPermission()
       }
     },
   },
@@ -408,7 +408,7 @@ export default {
 
     //分类变化 获取关联品种 
     handleChangeClassify(val) {
-      this.getRelationPermission()
+      // this.getRelationPermission()
       this.handleUpdateBaseInfo()
     },
 
@@ -443,7 +443,7 @@ export default {
 
           if(this.formData.type===1) { //默认只带出作者
             this.formData.author = res.Data.List
-              ? res.Data.List[0].Author.split(",")
+              ? (res.Data.List[0].Author?res.Data.List[0].Author.split(","):[])
               : [];
           }else {
             this.chooseInheritReport(res.Data.List[0])
@@ -502,14 +502,14 @@ export default {
     },
 
     //获取关联品种
-    async getRelationPermission() {
-      if(!this.formData.classify.length) return
+    // async getRelationPermission() {
+    //   if(!this.formData.classify.length) return
 
-      const res = await classifyPermissionInterface.classifyPermissionList({ClassifyId:this.formData.classify[this.formData.classify.length-1]})
+    //   const res = await classifyPermissionInterface.classifyPermissionList({ClassifyId:this.formData.classify[this.formData.classify.length-1]})
 
-        if(res.Ret!==200) return
-        this.formData.relationVariety = res.Data || []
-    },
+    //     if(res.Ret!==200) return
+    //     this.formData.relationVariety = res.Data || []
+    // },
 
     // 获取选择的分类名称
     getSelectClassifyName() {

+ 2 - 2
src/views/report_manage/reportV2/list.vue

@@ -626,8 +626,8 @@ export default {
         {label:"下载长图",permission:this.permissionBtn.isShowBtn('reportManageBtn','reportManage_exportImg'),States:[2,6],text:'ReportManage.smart_btn.download_long_image'},
         {label:"推送消息",permission:this.permissionBtn.isShowBtn('reportManageBtn','reportManage_sendMsg'),States:[2,6],text:'ReportManage.smart_push_notification_btn'},
         {label:"已推送消息",permission:this.permissionBtn.isShowBtn('reportManageBtn','reportManage_sendMsg'),States:[2,6],text:'ReportManage.smart_notification_pushed'},
-        {label:"音频上传",permission:this.permissionBtn.isShowBtn('reportManageBtn','reportManage_audioUpload'),States:true,text:'ReportManage.smart_audio_upload_btn'},
-        {label:"音频下载A",permission:this.permissionBtn.isShowBtn('reportManageBtn','reportManage_audioDownload'),States:true,text:'ReportManage.smart_audio_download_btn'},
+        // {label:"音频上传",permission:this.permissionBtn.isShowBtn('reportManageBtn','reportManage_audioUpload'),States:true,text:'ReportManage.smart_audio_upload_btn'},
+        // {label:"音频下载A",permission:this.permissionBtn.isShowBtn('reportManageBtn','reportManage_audioDownload'),States:true,text:'ReportManage.smart_audio_download_btn'},
         // {label:"音频下载",permission:this.permissionBtn.isShowBtn('reportManageBtn','reportManage_audioDownload'),States:true,text:'ReportManage.smart_audio_download_btn'},
       ],
 

+ 1 - 1
src/views/report_manage/reportV2/normalReport/components/ETASandBox.vue

@@ -4,7 +4,7 @@
             <div class="right">
                 <el-input
                     class="search-box"
-					:placeholder="$t('ReportManage.ReportList.no_reports_msg')"
+					placeholder="逻辑图名称"
 					v-model="keyword"
 					size="medium"
 					prefix-icon="el-icon-search"

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