소스 검색

Merge branch 'master' into eta1.6.8

Karsa 1 년 전
부모
커밋
708b25c94c
77개의 변경된 파일5202개의 추가작업 그리고 747개의 파일을 삭제
  1. 5 1
      src/api/api.js
  2. 16 0
      src/api/modules/chartApi.js
  3. 135 1
      src/api/modules/dataApi.js
  4. 7 0
      src/api/modules/setApi.js
  5. 23 1
      src/api/modules/sheetApi.js
  6. 77 20
      src/api/modules/thirdBaseApi.js
  7. BIN
      src/assets/img/eta_base_config/record_information.jpg
  8. 8 41
      src/components/lzTable.vue
  9. 8 2
      src/main.js
  10. 2 2
      src/routes/modules/chartRoutes.js
  11. 12 0
      src/routes/modules/dataRoutes.js
  12. 6 0
      src/routes/modules/oldRoutes.js
  13. 9 2
      src/utils/buttonConfig.js
  14. 2 2
      src/utils/calculate.js
  15. 26 4
      src/views/Login.vue
  16. 4 1
      src/views/chartRelevance_manage/components/selectTarget.vue
  17. 78 3
      src/views/dataEntry_manage/addChart.vue
  18. 6 1
      src/views/dataEntry_manage/chartSetting.vue
  19. 3 3
      src/views/dataEntry_manage/components/SaveChartOther.vue
  20. 96 0
      src/views/dataEntry_manage/css/coalCommon.scss
  21. 2 1
      src/views/dataEntry_manage/databaseComponents/edbDetailData.vue
  22. 14 0
      src/views/dataEntry_manage/databaseList.vue
  23. 79 3
      src/views/dataEntry_manage/editChart.vue
  24. 126 19
      src/views/dataEntry_manage/mixins/addOreditMixin.js
  25. 33 21
      src/views/dataEntry_manage/mixins/chartPublic.js
  26. 26 14
      src/views/dataEntry_manage/onlineExcelCopy.vue
  27. 388 0
      src/views/dataEntry_manage/thirdBase/coalWord.vue
  28. 293 0
      src/views/dataEntry_manage/thirdBase/icpiConsumption.vue
  29. 13 12
      src/views/datasheet_manage/addSheet.vue
  30. 115 7
      src/views/datasheet_manage/common/customTable.js
  31. 273 121
      src/views/datasheet_manage/components/MixedTable.vue
  32. 14 2
      src/views/datasheet_manage/components/SheetExcel.vue
  33. 288 0
      src/views/datasheet_manage/components/calculateDateDia.vue
  34. 133 64
      src/views/datasheet_manage/components/calculateEdbDia.vue
  35. 173 0
      src/views/datasheet_manage/components/dateMoveWaySection.vue
  36. 108 166
      src/views/datasheet_manage/components/insertDateDia.vue
  37. 133 24
      src/views/datasheet_manage/components/selectTargetValueDia.vue
  38. 13 2
      src/views/datasheet_manage/components/sheetClassifyDia.vue
  39. 197 0
      src/views/datasheet_manage/components/toolBarSection.vue
  40. 6 2
      src/views/datasheet_manage/customAnalysis/addAnalysisSheet.vue
  41. 16 2
      src/views/datasheet_manage/customAnalysis/components/bottomSection.vue
  42. 4 1
      src/views/datasheet_manage/customAnalysis/components/createTargetForm.vue
  43. 34 3
      src/views/datasheet_manage/customAnalysis/components/rightSection.vue
  44. 37 1
      src/views/datasheet_manage/customAnalysis/list.vue
  45. 18 2
      src/views/datasheet_manage/customSheetEdit.vue
  46. 23 17
      src/views/datasheet_manage/mixedSheetEdit.vue
  47. 72 18
      src/views/datasheet_manage/mixins/classifyMixin.js
  48. 53 3
      src/views/datasheet_manage/sheetList.vue
  49. 9 3
      src/views/edbHistoryPage.vue
  50. 12 7
      src/views/mychart_manage/components/chartDetailDia.vue
  51. 1 1
      src/views/mychart_manage/index.vue
  52. 25 17
      src/views/ppt_manage/mixins/mixins.js
  53. 53 14
      src/views/ppt_manage/mixins/pptMixins.js
  54. 10 5
      src/views/ppt_manage/newVersion/components/catalog/chooseShareUserDia.vue
  55. 11 4
      src/views/ppt_manage/newVersion/components/editor/AddFormat.vue
  56. 7 1
      src/views/ppt_manage/newVersion/components/editor/ChangeFormatDialog.vue
  57. 8 8
      src/views/ppt_manage/newVersion/components/formatEl/ChartEl.vue
  58. 82 0
      src/views/ppt_manage/newVersion/components/formatPage/FormatEle.vue
  59. 1 1
      src/views/ppt_manage/newVersion/components/formatPage/FormatNine.vue
  60. 94 0
      src/views/ppt_manage/newVersion/components/formatPage/FormatTen.vue
  61. 88 0
      src/views/ppt_manage/newVersion/components/formatPage/FormatTwelve.vue
  62. 40 0
      src/views/ppt_manage/newVersion/components/formatPreview/FormatPreEle.vue
  63. 44 0
      src/views/ppt_manage/newVersion/components/formatPreview/FormatPreTen.vue
  64. 41 0
      src/views/ppt_manage/newVersion/components/formatPreview/FormatPreTwelve.vue
  65. 94 25
      src/views/ppt_manage/newVersion/css/format.scss
  66. 1 1
      src/views/ppt_manage/newVersion/pptEnPresent.vue
  67. 22 3
      src/views/ppt_manage/newVersion/pptEnPublish.vue
  68. 1 1
      src/views/ppt_manage/newVersion/pptPresent.vue
  69. 38 5
      src/views/ppt_manage/newVersion/pptPublish.vue
  70. 230 41
      src/views/ppt_manage/newVersion/utils/config.js
  71. 47 4
      src/views/ppt_manage/newVersion/utils/untils.js
  72. 32 14
      src/views/supply_manage/components/varietySetDia.vue
  73. 259 0
      src/views/system_manage/components/refreshConfig.vue
  74. 732 0
      src/views/system_manage/dataRefreshSetting.vue
  75. 2 2
      src/views/system_manage/departManage.vue
  76. 8 1
      src/views/system_manage/etaBaseConfig.vue
  77. 3 0
      src/vuex/modules/ppt.js

+ 5 - 1
src/api/api.js

@@ -13,7 +13,9 @@ import {
   databankInterface,
   yongyiInterface,
   fwmtInterface,
-  guangqiInterface
+  guangqiInterface,
+  icpiInterface,
+  coalWordInterface
 } from './modules/thirdBaseApi';
 
 //手工指标 手工数据 手工数据权限
@@ -119,6 +121,8 @@ export {
   yongyiInterface,
   fwmtInterface,
   guangqiInterface,
+  icpiInterface,
+  coalWordInterface
 };
 
 //老接口 研报 ppt等

+ 16 - 0
src/api/modules/chartApi.js

@@ -943,6 +943,22 @@ const dataBaseInterface = {
 	 */
 	getRadarPreviewData: params => {
 		return http.post('/datamanage/chart_info/preview/radar',params)
+	},
+	  /**
+		 * 获取数据转换后Edb数据
+		 * @param {Object} params 
+		 * @param {Number} params.IsConvert 是否数据转换
+		 * @param {Number} params.ConvertType 数据转换类型 1乘 2除 3对数
+		 * @param {Number} params.ConvertValue 数据转换值
+		 * @param {String} params.ConvertUnit 数据转换单位
+		 * @param {String} params.ConvertEnUnit 数据转换单位英文
+		 * @param {*} params.SeasonStartDate
+		 * @param {*} params.SeasonEndDate
+		 * @param {*} params.EdbInfoId
+		 * @returns 
+		 */
+	getChangeEdbData:params=>{
+		return http.get('/datamanage/chart_info/convert/detail',params)
 	}
 	
 }

+ 135 - 1
src/api/modules/dataApi.js

@@ -385,8 +385,142 @@ const dataAuthInterface = {
 		return http.get('/datamanage/manual/classify/all_list',params)
 	}
 }
+/* 数据刷新设置 */
+const dataRefreshInterface = {
+    /**
+     * 获取数据源列表,Child不为空则显示第二个筛选框
+     * @param {*} params 
+     * @returns 
+     */
+    getDataSourceList:params=>{
+        return http.get("/datamanage/edb_info/refresh/source_list",params)
+    },
+    /**
+     * 获取数据源刷新的默认设置
+     * @param {Object} params 
+     * @param {Number} params.Source
+     * @param {Number} params.SubSource
+     * @param {String} params.Frequency
+     * @returns 
+     */
+    getDefaultConfig:params=>{
+        return http.get("/datamanage/edb_info/refresh/default_config",params)
+    },
+    /**
+     * 获取终端列表
+     * @param {Object} params 
+     * @param {Number} params.Source
+     * @returns 
+     */
+    getTerminalList:params=>{
+        return http.get("/data_stat/terminal/code",params)
+    },
+    /**
+     * 获取分类列表
+     * @param {Object} params 
+     * @param {Number} params.Source 
+     * @returns 
+     */
+    getClassifyList:params=>{
+        return http.get("/datamanage/edb_info/refresh/classify_list",params)
+    },
+    /**
+     * 获取筛选后的指标列表
+     * @param {Object} params 
+     * @param {Number} params.Source 
+     * @param {Number} params.SubSource
+     * @param {Number} params.ClassifyId
+     * @param {String} params.TerminalCode
+     * @param {Number} params.SysUserId
+     * @param {String} params.Frequency
+     * @param {String} params.Keyword
+     * @param {String} params.Status
+     * @param {String} params.SortParam 排序字段:end_date(最新日期)
+     * @param {String} params.SortType 排序类型,正序:asc;逆序:desc
+     * @param {Number} params.PageSize
+     * @param {Number} params.CurrentIndex
+     * @returns 
+     */
+    getEdbTableList:params=>{
+        return http.get("/datamanage/edb_info/refresh/edb_list",params)
+    },
+    /**
+     * 单独设置指标刷新时间
+     * @param {Object} params 
+     * @param {Number} params.Source
+     * @param {Number} params.SubSource
+     * @param {String} params.ClassifyId 筛选项 多选
+     * @param {String} params.TerminalCode 筛选项
+     * @param {String} params.SysUserId 筛选项 多选
+     * @param {String} params.Frequency 筛选项 多选
+     * @param {String} params.Keyword 筛选项
+     * @param {String} params.Status 筛选项
+     * @param {Boolean} params.IsSelectAll
+     * @param {Object[]} params.EdbSelectIdList
+     * @param {Object[]} params.List
+     * @param {String} params.List[].RefreshFrequency
+     * @param {Number} params.List[].RefreshFrequencyDay
+     * @param {String} params.List[].RefreshTime
+     * @param {Number} params.List[].RefreshAllData
+     * @param {Number} params.List[].RefreshDataNum
+     * @returns 
+     */
+    setRefreshTime(params){
+        return http.post("/datamanage/edb_info/refresh/config/save",params)
+    },
+    /**
+     * 设置默认的指标刷新时间
+     * @param {Object} params 
+     * @param {Number} params.Source
+     * @param {Number} params.SubSource
+     * @param {String} params.Frequency 
+     * @param {Object[]} params.List
+     * @param {String} params.List[].RefreshFrequency
+     * @param {Number} params.List[].RefreshFrequencyDay
+     * @param {String} params.List[].RefreshTime
+     * @param {Number} params.List[].RefreshAllData
+     * @param {Number} params.List[].RefreshDataNum
+     * @returns 
+     */
+    setDefaultTime(params){
+        return http.post("/datamanage/edb_info/refresh/default_config/save",params)
+    },
+    /**
+     * 设置指标刷新状态
+     * @param {Object} params 
+     * @param {Number} params.Source
+     * @param {Number} params.SubSource
+     * @param {String} params.ClassifyId 筛选项 多选
+     * @param {String} params.TerminalCode 筛选项
+     * @param {String} params.SysUserId 筛选项 多选
+     * @param {String} params.Frequency 筛选项 多选
+     * @param {String} params.Keyword 筛选项
+     * @param {String} params.Status 筛选项
+     * @param {Boolean} params.IsSelectAll
+     * @param {Object[]} params.EdbSelectIdList
+     * @param {String} params.ModifyStatus 需要更改的状态,枚举值:启用、暂停
+     * @returns 
+     */
+    setRefreshStatus(params){
+        return http.post("/datamanage/edb_info/refresh/status/save",params)
+    },
+    /**
+     * 获取单个指标的刷新配置
+     * @param {Object} params 
+     * @param {Number} params.EdbInfoId
+     * @param {Number} params.Source
+     * @param {Number} params.SubSource
+     * @returns 
+     */
+    getSimgleEdbRefreshTime(params){
+        return http.get("/datamanage/edb_info/refresh/edb_config",params)
+    },
+
+
+}
 
 export {
 	dataInterence,
-	dataAuthInterface
+	dataAuthInterface,
+    dataRefreshInterface
 }

+ 7 - 0
src/api/modules/setApi.js

@@ -337,6 +337,13 @@ const departInterence = {
 	 */
 	getPhoneAreaCode:params=>{
 		return http.get('/user_login/area_code/list',params)
+	},
+	/**
+	 * 获取备案信息
+	 * @returns 
+	*/
+	getICPLicense:params=>{
+		return http.get('/user_login/icp_license',params)
 	}
 
 }

+ 23 - 1
src/api/modules/sheetApi.js

@@ -263,7 +263,7 @@ export const insertData = params => {
  * @returns 
  */
 export const getDateLatelyData = params => {
-	return http.get('/datamanage/edb_info/date_data/before_after',params)
+	return http.post('/datamanage/edb_info/date_data/before_after',params)
 }
 
 /**
@@ -309,6 +309,28 @@ export const getRefreshResult = (params)=>{
     return http.post('/datamanage/excel_info/table/batch_refresh/result',params)
 }
 
+
+/**
+ * 日期计算
+ * @param {
+ * 	Formula,
+ * 	DateList: [{Date,Tag}]
+ * } params 
+ * @returns 
+ */
+export const getDateCalculate = params => {
+	return http.post('/datamanage/excel_info/mixed/date_calculate',params)
+}
+
+/**
+ * 根据id获取指标基础信息 无数据
+ * @param {*EdbInfoIds} params 
+ * @returns 
+ */
+export const getEdbBaseInfo = params => {
+	return http.get('/datamanage/excel_info/base_edb_info',params)
+}
+
 /* =====自定义分析==== */
 
 export const sheetAnalysisInterface = {

+ 77 - 20
src/api/modules/thirdBaseApi.js

@@ -779,30 +779,30 @@ const yongyiInterface={
 
 /* 汾渭煤炭树 */
 const fwmtInterface={
-	/**
+		/**
 	 * 分类列表
 	 * @param {} params 
 	 * @returns 
 	 */
-	classifyList: params => {
-		return http.get('/datamanage/fenwei/classify',params);
-	},
-	/**
-	 * 获取指标列表详情
-	 */
-	dataList: params => {
-		return http.get('/datamanage/fenwei/index/data',params);
-	},
-	//单个指标数据
-	getTargetDataList:params=>{
-		return http.get('/datamanage/fenwei/single_data',params);
-	},
-	// 搜索
-	getTargetListByName:params=>{
-		return http.get('/datamanage/fenwei/search_list',params);
-	}
+		classifyList: params => {
+			return http.get('/datamanage/fenwei/classify',params);
+		},
+		/**
+		 * 获取指标列表详情
+		 */
+		dataList: params => {
+			return http.get('/datamanage/fenwei/index/data',params);
+		},
+		//单个指标数据
+		getTargetDataList:params=>{
+			return http.get('/datamanage/fenwei/single_data',params);
+		},
+		// 搜索
+		getTargetListByName:params=>{
+			return http.get('/datamanage/fenwei/search_list',params);
+		}
 }
-
+/* 广期所 */
 const guangqiInterface={
 		/**
 		 * 分类列表
@@ -856,6 +856,61 @@ const guangqiInterface={
 	},
 }
 
+/* ICPI消费价格指数 */
+const icpiInterface={
+	/**
+	 * 分类列表
+	 * @param {} params 
+	 * @returns 
+	 */
+	classifyList: params => {
+		return http.get('/data_source/icpi/classify/list',params);
+	},
+	/**
+	 * 获取指标列表详情
+	 * BaseFromIcpiClassifyId PageSize CurrentIndex
+	 */
+	dataList: params => {
+		return http.get('/data_source/icpi/index/data',params);
+	}
+}
+
+/* 煤炭江湖 */
+const coalWordInterface={
+	/**
+	 * 分类列表
+	 * @param {} params 
+	 * @returns 
+	 */
+	classifyList: params => {
+		return http.get('/entry/data/mtjh/classify',params);
+	},
+	/**
+	 * 获取指标列表详情 Area PageSize CurrentIndex
+	 */
+	dataList: params => {
+		return http.get('/entry/data/mtjh/data',params);
+	},
+	/**
+	 * 单个指标数据 IndexCode PageSize CurrentIndex
+	*/
+	getTargetDataList:params=>{
+		return http.get('/entry/data/mtjh/single_data',params);
+	},
+	/**
+	 * 搜索 Keyword
+	*/
+	targetListSearch:params=>{
+		return http.get('/entry/data/mtjh/search',params);
+	},
+	/**
+	 * 获取频度列表 Area
+	*/
+	getFrequencyList:params=>{
+		return http.get('/entry/data/mtjh/frequency',params)
+	},
+}
+
 export { 
 	lzDataInterface,
 	glDataInterface,
@@ -869,5 +924,7 @@ export {
   databankInterface,
   yongyiInterface,
   fwmtInterface,
-	guangqiInterface
+	guangqiInterface,
+	icpiInterface,
+	coalWordInterface
 }

BIN
src/assets/img/eta_base_config/record_information.jpg


+ 8 - 41
src/components/lzTable.vue

@@ -69,19 +69,11 @@ export default {
 		headerArr(){
 			let arr=['QuotaName','LzCode','Frequency','UnitName','ModifyTime']
 
+			let sourceTypeOne = ['smm','coal','baiinfo','yyzx','icpi','coalWord']
+
 			if(this.source==='gl'){
 				arr=['IndexName','IndexCode','FrequencyName','UnitName','UpdateTime']
-			}
-			if(this.source==='smm'){
-				arr=['IndexName','IndexCode','Frequency','Unit','ModifyTime']
-			}
-			if(this.source==='coal'){
-				arr=['IndexName','IndexCode','Frequency','Unit','ModifyTime']
-			}
-			if(this.source==='baiinfo'){
-				arr=['IndexName','IndexCode','Frequency','Unit','ModifyTime']
-			}
-			if(this.source==='yyzx'){
+			}else if(sourceTypeOne.includes(this.source)){
 				arr=['IndexName','IndexCode','Frequency','Unit','ModifyTime']
 			}
 
@@ -95,6 +87,7 @@ export default {
 				['UnitName', '单位'],
 				['ModifyTime', '更新时间'],
 			])
+			let sourceTypeOne = ['smm','coal','baiinfo','yyzx','icpi','coalWord']
 
 			if(this.source==='gl'){
 				temMap=new Map([
@@ -104,35 +97,7 @@ export default {
 					['UnitName', '单位'],
 					['UpdateTime', '更新时间'],
 				])
-			}
-			if(this.source==='smm'){
-				temMap=new Map([
-					['IndexName', '指标名称'],
-					['IndexCode', '指标ID'],
-					['Frequency', '频度'],
-					['Unit', '单位'],
-					['ModifyTime', '更新时间'],
-				])
-			}
-			if(this.source==='coal'){
-				temMap=new Map([
-					['IndexName', '指标名称'],
-					['IndexCode', '指标ID'],
-					['Frequency', '频度'],
-					['Unit', '单位'],
-					['ModifyTime', '更新时间'],
-				])
-			}
-			if(this.source==='baiinfo'){
-				temMap=new Map([
-					['IndexName', '指标名称'],
-					['IndexCode', '指标ID'],
-					['Frequency', '频度'],
-					['Unit', '单位'],
-					['ModifyTime', '更新时间'],
-				])
-			}
-			if(this.source==='yyzx'){
+			}else if(sourceTypeOne.includes(this.source)){
 				temMap=new Map([
 					['IndexName', '指标名称'],
 					['IndexCode', '指标ID'],
@@ -146,8 +111,10 @@ export default {
 		},
 		dynamic_key(){
 			let key='InputValue'
-			if(['smm','baiinfo','coal','yyzx'].includes(this.source)){
+			if(['smm','baiinfo','coal','yyzx','icpi'].includes(this.source)){
 				key='Value'
+			}else if(this.source=='coalWord'){
+				key='DealValue'
 			}
 
 			return key

+ 8 - 2
src/main.js

@@ -11,6 +11,7 @@ import "font-awesome/css/font-awesome.min.css";
 import "@/utils/dialog.js";
 import "@/utils/option-scroll.js";
 import "@/utils/buttonPermission.js";
+import { dataBaseInterface } from '@/api/api.js';
 import { mixins } from "@/mixins";
 Vue.mixin(mixins);
 
@@ -24,7 +25,7 @@ import{endCalc,optionTimeCalc,init}from'@/utils/TimeOnPage.js';
 import setting from '@/mixins/theme.js'
 Vue.prototype.$setting = setting;
 
-Vue.prototype.toHistoryPage = (EdbInfoId,from=[])=>{
+Vue.prototype.toHistoryPage =  async(EdbInfoId,from=[])=>{
     console.log('from',from)
     let pathArr = from.map(p=>{
         return {
@@ -37,10 +38,15 @@ Vue.prototype.toHistoryPage = (EdbInfoId,from=[])=>{
         path:'/edbHistory'
     })
     sessionStorage.setItem('edbHistoryPath',JSON.stringify(pathArr))
+
+    //改为传code获取溯源 改的地方太多了在这里直接获取code算了
+    const {Ret,Data} = await dataBaseInterface.targetDetail({EdbInfoId})
+    if(Ret!==200) return
+
     const href = router.resolve({
         path:'/edbHistory',
         query:{
-            edbId:EdbInfoId,
+            code:Data.UniqueCode,
         }
     }).href
     window.open(href,"_blank")

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

@@ -102,7 +102,7 @@ export default [
 		children:[
 			{
 				path:"sheetList",
-				name:"在线Excel",
+				name:"共享表格",
 				component:()=>import('@/views/datasheet_manage/sheetList.vue')
 			},
 			{
@@ -121,7 +121,7 @@ export default [
 				component:()=>import('@/views/datasheet_manage/addSheet.vue'),
 				meta: { 
 					pathFrom: "sheetList",
-					pathName: "在线Excel",
+					pathName: "共享表格",
 				}
 			},
 			{

+ 12 - 0
src/routes/modules/dataRoutes.js

@@ -80,6 +80,12 @@ export default [
         name: "天然气历史数据",
         hidden: true,
       },
+      {
+        path: "ICPIconsumption",
+        component: () => import("@/views/dataEntry_manage/thirdBase/icpiConsumption.vue"),
+        name: "ICPI消费价格指数",
+        hidden: false,
+      },
       {
         path: "zhengzhoushop",
         component: () =>
@@ -233,6 +239,12 @@ export default [
           keepAlive: false,
         },
       },
+      {
+        path: "coalWord",
+        component: () => import("@/views/dataEntry_manage/thirdBase/coalWord.vue"),
+        name: "煤炭江湖",
+        hidden: false
+      },
     ],
   },
 ];

+ 6 - 0
src/routes/modules/oldRoutes.js

@@ -366,6 +366,12 @@ export default [
         name: "数据源终端管理",
         hidden: true,
       },
+      {
+        path: "dataRefreshSetting",
+        component: () => import("@/views/system_manage/dataRefreshSetting.vue"),
+        name: "数据刷新设置",
+        hidden: true,
+      },
     ],
   },
   // 外部链接

+ 9 - 2
src/utils/buttonConfig.js

@@ -241,7 +241,10 @@ export const dataSourcePermission = {
     dataSource_account_edit:'dataSourceAccount:edit',//编辑
     dataSource_account_enable:'dataSourceAccount:enable',//禁用/启用
     /*--------涌益咨询---- */
-    yyzxData_export:'yyzx:exportData'
+    yyzxData_export:'yyzx:exportData',
+    /*--------煤炭江湖---- */
+    coalWordData_view:'coalWord:view', // 查看
+    coalWordData_export:'coalWord:export', // 导出
 }
 
 /*
@@ -595,7 +598,11 @@ export const sysDepartPermission = {
     sysRole_addRole:'sysRole:addRole',//添加角色
     /*-----------英文权限配置-------- */
     enAuthManage_del:'enAuthManage:del',
-    enAuthManage_settingAuth:'enAuthManage:settingAuth'
+    enAuthManage_settingAuth:'enAuthManage:settingAuth',
+    /*-----------数据刷新设置-------- */
+    refresh_default:'refresh:default', //默认刷新时间 
+    refresh_time:'refresh:time', //设置刷新时间
+    refresh_state:'refresh:state', //设置刷新状态
 }
 /*-----------数据操作权限-------- */
 export const operateAuthPermission = {

+ 2 - 2
src/utils/calculate.js

@@ -21,9 +21,9 @@ function multiply(a, b) {
 
 // 除法
 function divide(a, b) {
-  const precision = getPrecision(b) - getPrecision(a);
+  const precision = Math.max(getPrecision(b), getPrecision(a));
   const divisor = Math.pow(10, precision);
-  return Math.round((a / b) * divisor) / divisor;
+  return (a * divisor) / (b * divisor);
 }
 
 // 获取浮点数的精度

+ 26 - 4
src/views/Login.vue

@@ -134,6 +134,9 @@
                 </div>
 			</div>
 		</div>
+        <div class="record-info">
+            <span v-for="(item,index) in recordInformation" :key="index">{{ item }}</span>
+        </div>
 		<!-- 验证弹窗 -->
 		<el-dialog
 			class="check-dialog"
@@ -288,14 +291,14 @@ export default {
                         </filter>
                         </defs></svg>`
                 },
-            ]
-
-        
+            ],
+            recordInformation:[]
         };
     },
     created() {
         this.keyupSubmit(); //回车登录
         this.getPhoneCode();//获取手机号区号
+        this.getRecordInfo();//获取备案信息
     },
     mounted(){
         this.getRememberedInfo()
@@ -402,6 +405,13 @@ export default {
                 this.areaCode = res.Data||[]
             })
         },
+        getRecordInfo(){
+            departInterence.getICPLicense().then(res=>{
+                if(res.Ret == 200){
+                    this.recordInformation = res.Data.ConfVal.split(/\s{2,}/)
+                }
+            })
+        },
         handleClick(tab) {
             //调用对应model的init方法
             this.$refs[tab.name]&&this.$refs[tab.name].modelInit()
@@ -651,7 +661,7 @@ export default {
 	// overflow: hidden;
 	#login_wrapper {
 		width: 100%;
-		height: 100%;
+		height: calc(100% - 36px);
 		background-color: #fff;
 		position: relative;
 
@@ -810,6 +820,18 @@ export default {
 			}
 		}
 	}
+    .record-info{
+        display: flex;
+        flex-wrap: wrap;
+        justify-content: center;
+        width: 100%;
+        font-size: 15px;
+        color: #C0C4CC;
+        text-align: center;
+        span{
+            margin: 0 6px;
+        }
+    }
 	.remember-cont {
 		position: relative;
 		margin-bottom: 35px;

+ 4 - 1
src/views/chartRelevance_manage/components/selectTarget.vue

@@ -73,7 +73,7 @@
       remote
       clearable
       placeholder="请选择指标名称"
-      :style="`width: 100%; ${filter?'margin-top: 20px':''}`"
+      :style="`width: ${width}; ${filter?'margin-top: 20px':''}`"
       :remote-method="searchHandle"
       @click.native="inputFocusHandle"
       @change="handleSelectTarget"
@@ -113,6 +113,9 @@ export default {
       },
       filter: { //是否要预测和eta的筛选
         default: true
+      },
+      width: {
+        default:'100%'
       }
     },
     watch:{

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

@@ -112,7 +112,7 @@
 							placeholder="请选择所属分类"
 						/>
 					</el-form-item>
-					<el-form-item label="图表单位" prop="Unit" v-if="[7,11].includes(chartInfo.ChartType)">
+					<el-form-item label="图表单位" prop="Unit" v-if="[11].includes(chartInfo.ChartType)">
 						<el-select
 							v-model="chartInfo.Unit"
 							filterable
@@ -559,6 +559,34 @@
 						highlight-current-row
 						border
 					>
+						<el-table-column type="expand" v-if="![10,11].includes(chartInfo.ChartType)">
+							<template slot-scope="{row,$index}">
+								<div class="expand-wrap">
+									<div class="data-change">
+										<el-checkbox v-model="updateData[$index].IsConvert">数据转换</el-checkbox>
+										<el-select v-model="updateData[$index].ConvertType">
+											<el-option label="乘以" :value="1"></el-option>
+											<el-option label="除以" :value="2"></el-option>
+											<el-option label="对数" :value="3"></el-option>
+										</el-select>
+									<el-input type="number" v-model="updateData[$index].ConvertValue"></el-input>
+									</div>
+									<div class="unit-change">
+										<label>单位</label>
+										<el-input v-model="updateData[$index].ConvertUnit"></el-input>
+										<label>英文单位</label>
+										<el-input v-model="updateData[$index].ConvertEnUnit"></el-input>
+									</div>
+									<!--柱形图-->
+									<div class="use-change" v-if="chartInfo.ChartType===7">
+										<el-radio v-model="useUnit" :label="$index">设置为图表单位</el-radio>
+									</div>
+									<div class="confirm-btn">
+										<el-button type="text" @click="changeTableData($index)">保存</el-button>
+									</div>
+								</div>
+							</template>
+						</el-table-column>
 						<el-table-column
 							v-for="item in tableColums"
 							:key="item.label"
@@ -722,7 +750,9 @@ export default {
 			needWatch: true,
 			IsNameDefault:true,
 
-			UnitOptions:unitArr
+			UnitOptions:unitArr,
+
+			useUnit:''
 
     };
   },
@@ -746,7 +776,7 @@ export default {
 						}
 					}
 
-					let db_arr = this.tableData.map(item => ({
+					let db_arr = this.tableData.map((item,index) => ({
 							ChartColor: item.ChartColor,
 							PredictChartColor: item.PredictChartColor,
 							ChartStyle: item.ChartStyle,
@@ -762,6 +792,34 @@ export default {
 							MinData: Number(item.MinData)
 						})
 					)
+					if(![10,11].includes(this.chartInfo.ChartType)){
+						//每个数据转换需要检测是否合法
+						for(let i=0;i<db_arr.length;i++){
+							const {IsConvert,ConvertType,ConvertValue} = this.updateData[i]
+							//计算方式是否合法
+							if(IsConvert&&!this.checkConver(ConvertType,ConvertValue)){
+								return this.$message.warning(`第${i+1}个指标数据转换不合法,请检查数值`)
+							}
+							//如果类型为对数,检测数据是否包含负数
+							if(IsConvert&&ConvertType===3){
+								if(!this.checkEdbData(this.tableData[i].DataList)){
+									return this.$message.warning(`第${i+1}个指标数据含有负数或0,无法进行对数运算,请检查`)
+								}
+							}
+						}
+						db_arr = db_arr.map((item,index)=>{
+							const {IsConvert,ConvertType,ConvertValue,ConvertUnit,ConvertEnUnit} = this.updateData[index]
+							return {
+								...item,
+								IsConvert:Number(IsConvert),
+								ConvertType:IsConvert?ConvertType:1,
+								ConvertValue:IsConvert?Number(ConvertValue):100,
+								ConvertUnit:IsConvert?ConvertUnit:'',
+								ConvertEnUnit:IsConvert?ConvertEnUnit:''
+							}
+						})
+					}
+					
 
 					const { ChartType,ChartName,ChartThemeId,SourcesFrom,Instructions,MarkersLines,MarkersAreas,ChartThemeStyle } = this.chartInfo;
 					let public_param = {
@@ -1201,6 +1259,23 @@ export default {
 			}
 		}
 	}
+	.expand-wrap{
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		gap:30px;
+		.el-checkbox{
+			margin-right: 15px;
+		}
+		.el-input{
+			width:100px;
+			height:27px;
+			line-height: 27px;
+			.el-input__icon{
+				line-height: 27px;
+			}
+		}
+	}
 }
 </style>
 <style lang="scss">

+ 6 - 1
src/views/dataEntry_manage/chartSetting.vue

@@ -30,7 +30,7 @@
         </div>
         
         <ul class="left-tab">
-          <li :class="['tab',{'act': leftShowLabel===tab}]" v-for="tab in ['目录','坐标轴']" :key="tab" @click="leftShowLabel=tab">{{tab}}</li>
+          <li :class="['tab',{'act': leftShowLabel===tab}]" v-for="tab in ['目录']" :key="tab" @click="leftShowLabel=tab">{{tab}}</li>
           <li >
             <el-checkbox v-model="isOnlyMe" 
                 v-permission="permissionBtn.chartLibPermission.chartLib_isOnlyMine"
@@ -1713,6 +1713,11 @@ export default {
           EdbInfoType: _.EdbInfoType,
           LeadValue: _.EdbInfoType ? 0 : Number(_.LeadValue),
           LeadUnit: _.EdbInfoType ? '' : _.LeadUnit,
+          IsConvert:Number(_.IsConvert),
+          ConvertType:Number(_.ConvertType),
+          ConvertValue:Number(_.ConvertValue),
+          ConvertUnit:Number(_.IsConvert)?_.ConvertUnit:'',
+          ConvertEnUnit:Number(_.IsConvert)?_.ConvertEnUnit:''
         }))
       }
 

+ 3 - 3
src/views/dataEntry_manage/components/SaveChartOther.vue

@@ -6,7 +6,7 @@
 		@close="cancelHandle"
 		custom-class="saveother-dialog"
 		center
-		width="560px"
+		width="700px"
 		v-dialogDrag
     title="另存为"
   >
@@ -20,7 +20,7 @@
       <el-form-item label="图表名称" prop="name">
         <el-input
           v-model="form.name"
-          style="width: 80%"
+          style="width: 100%"
           placeholder="必填项"
           clearable
         />
@@ -35,7 +35,7 @@
             children: 'Children',
             emitPath: false
           }"
-          style="width: 80%"
+          style="width: 100%"
           placeholder="请选择所属分类"
         />
       </el-form-item>

+ 96 - 0
src/views/dataEntry_manage/css/coalCommon.scss

@@ -0,0 +1,96 @@
+// 煤炭江湖页面的同款样式
+
+.coal-similarity-container {
+  display: flex;
+  position: relative;
+  box-sizing: border-box;
+  .slide-btn-icon{
+        &.slide-left{
+            left:225px;
+        }
+        &.slide-right{
+            left: 0;
+        }
+    }
+  .minHeight {
+    height: calc(100vh - 120px);
+    background-color: #fff;
+    box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+    border-radius: 4px;
+    box-sizing: border-box;
+  }
+  div::-webkit-scrollbar {
+    width: 5px !important;
+  }
+  .left-cont {
+    min-width: 240px;
+    width:240px;
+    margin-right: 20px;
+    padding: 30px 0;
+    overflow: hidden;
+    .left-top {
+      padding: 0 20px;
+    }
+    .classify-list {
+      padding: 0 20px;
+      margin-top: 20px;
+      height: calc(100vh - 280px);
+      overflow-y: auto;
+      .classify-item {
+        font-size: 14px;
+        color: #666;
+        margin-bottom: 20px;
+        &:hover {
+          cursor: pointer;
+          color: #409eff;
+        }
+        &.act {
+          color: #409eff;
+        }
+      }
+    }
+  }
+  .right-cont {
+    flex:1;
+    padding: 30px;
+    overflow-x: auto;
+    box-sizing: border-box;
+    display: flex;
+    flex-direction: column;
+    .right-box {
+      max-width: 100%;
+      flex-grow: 1;
+      min-height: 600px;
+      // border-right: 1px solid #dcdfe6;
+      box-sizing: border-box;
+      overflow: auto;
+      .data-header {
+        width: 100%;
+        position: sticky;
+        top: 0;
+        z-index: 2;
+      }
+      .data-cont {
+        height: calc(100vh - 444px);
+      }
+      .nodata {
+        width: 100%;
+        font-size: 16px;
+        color: #999;
+        padding-top: 100px;
+      }
+    }
+    .frequency-list {
+      margin-top: 20px;
+      display: flex;
+      flex-wrap: wrap;
+      gap:20px;
+      .el-button{
+            margin-left: 0 !important;
+        }
+      .frequency-btn {
+        width: 112px;
+      }
+    }
+  }
+}

+ 2 - 1
src/views/dataEntry_manage/databaseComponents/edbDetailData.vue

@@ -35,7 +35,8 @@
 					<span>{{ item.label }}</span>
 				</template>
 				<template slot-scope="scope">
-					<span>{{ scope.row[item.key] }}</span>
+					<span v-if="item.key==='NoUpdate'">{{scope.row[item.key]?'暂停':'启用'}}</span>
+					<span v-else>{{ scope.row[item.key] }}</span>
 				</template>
 			</el-table-column>
 			<div slot="empty" style="padding: 50px 0 320px;">

+ 14 - 0
src/views/dataEntry_manage/databaseList.vue

@@ -644,6 +644,11 @@ export default {
 					key: 'ModifyTime',
 					minwidthsty: '120px',
 				},
+				{
+					label:'刷新状态',
+					key:'NoUpdate',
+					widthsty:'100px'
+				},
 				{
 					label: '添加人',
 					key: 'SysUserRealName',
@@ -1324,6 +1329,11 @@ export default {
 		},
 		/* 刷新获取指标最新数据 */
 		refreshTargetHandle: _.debounce(function() {
+			//如果该指标为暂停刷新,则提示
+			if(this.EdbData.NoUpdate){
+				this.$message.warning("该指标已暂停刷新")
+				return
+			}
 			if(this.selected_edbid) {
 				this.loading = this.$loading({
 					lock: true,
@@ -1765,6 +1775,10 @@ export default {
 
 		/* 基础指标刷新 */
 		refreshBaseHandler() {
+			if(this.EdbData.NoUpdate){
+				this.$message.warning("该指标已暂停刷新")
+				return 
+			}
 			this.refreshLoading = true;
 			this.loading = this.$loading({
 					lock: true,

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

@@ -120,7 +120,7 @@
 							placeholder="请选择所属分类"
 						/>
 					</el-form-item>
-					<el-form-item label="图表单位" prop="Unit" v-if="[7,11].includes(chartInfo.ChartType)">
+					<el-form-item label="图表单位" prop="Unit" v-if="[11].includes(chartInfo.ChartType)">
 						<el-select
 							v-model="chartInfo.Unit"
 							filterable
@@ -136,7 +136,7 @@
 								:value="item">
 							</el-option>
 						</el-select>
-					</el-form-item>
+					</el-form-item> 
 				</el-form>
 
 				<div class="xaxis-range-cont" v-if="chartInfo.ChartType===2 && tableData && tableData.length>0">
@@ -554,6 +554,34 @@
 						highlight-current-row
 						border
 					>
+						<el-table-column type="expand" v-if="![10,11].includes(chartInfo.ChartType)">
+							<template slot-scope="{row,$index}">
+								<div class="expand-wrap">
+									<div class="data-change">
+										<el-checkbox v-model="updateData[$index].IsConvert">数据转换</el-checkbox>
+										<el-select v-model="updateData[$index].ConvertType">
+											<el-option label="乘以" :value="1"></el-option>
+											<el-option label="除以" :value="2"></el-option>
+											<el-option label="对数" :value="3"></el-option>
+										</el-select>
+									<el-input type="number" v-model="updateData[$index].ConvertValue"></el-input>
+									</div>
+									<div class="unit-change">
+										<label>单位</label>
+										<el-input v-model="updateData[$index].ConvertUnit"></el-input>
+										<label>英文单位</label>
+										<el-input v-model="updateData[$index].ConvertEnUnit"></el-input>
+									</div>
+									<!--柱形图-->
+									<div class="use-change" v-if="chartInfo.ChartType===7">
+										<el-radio v-model="useUnit" :label="$index">设置为图表单位</el-radio>
+									</div>
+									<div class="confirm-btn">
+										<el-button type="text" @click="changeTableData($index)">保存</el-button>
+									</div>
+								</div>
+							</template>
+						</el-table-column>
 						<el-table-column
 							v-for="item in tableColums"
 							:key="item.label"
@@ -743,7 +771,11 @@ export default {
 
 					this.$refs.markerSectionRef.initData(ChartInfo);
 
-          this.tableData = EdbInfoList;
+					this.tableData = EdbInfoList;
+					this.updateData = this.tableData.map(item=>{
+						return this.formatUpdateData(item)
+					})
+			
 
 					this.calendar_type = this.chartInfo.Calendar; //日历类型
 					this.setDefaultPreviewOption() // 设置配置项
@@ -860,6 +892,33 @@ export default {
 							MinData: Number(item.MinData)
 						})
 					)
+					if(![10,11].includes(this.chartInfo.ChartType)){
+						//每个数据转换需要检测是否合法
+						for(let i=0;i<db_arr.length;i++){
+							const {IsConvert,ConvertType,ConvertValue} = this.updateData[i]
+							//计算方式是否合法
+							if(IsConvert&&!this.checkConver(ConvertType,ConvertValue)){
+								return this.$message.warning(`第${i+1}个指标数据转换不合法,请检查数值`)
+							}
+							//如果类型为对数,检测数据是否包含负数
+							if(IsConvert&&ConvertType===3){
+								if(!this.checkEdbData(this.tableData[i].DataList)){
+									return this.$message.warning(`第${i+1}个指标数据含有负数或0,无法进行对数运算,请检查`)
+								}
+							}
+						}
+						db_arr = db_arr.map((item,index)=>{
+							const {IsConvert,ConvertType,ConvertValue,ConvertUnit,ConvertEnUnit} = this.updateData[index]
+							return {
+								...item,
+								IsConvert:Number(IsConvert),
+								ConvertType:IsConvert?ConvertType:1,
+								ConvertValue:IsConvert?Number(ConvertValue):100,
+								ConvertUnit:IsConvert?ConvertUnit:'',
+								ConvertEnUnit:IsConvert?ConvertEnUnit:''
+							}
+						})
+					}
 
 					const { ChartType,ChartName,ChartThemeId,SourcesFrom,Instructions,MarkersLines,MarkersAreas,ChartThemeStyle } = this.chartInfo;
 					let public_param = {
@@ -1293,6 +1352,23 @@ export default {
 			}
 		}
 	}
+	.expand-wrap{
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		gap:30px;
+		.el-checkbox{
+			margin-right: 15px;
+		}
+		.el-input{
+			width:100px;
+			height:27px;
+			line-height: 27px;
+			.el-input__icon{
+				line-height: 27px;
+			}
+		}
+	}
 }
 </style>
 <style lang="scss">

+ 126 - 19
src/views/dataEntry_manage/mixins/addOreditMixin.js

@@ -81,7 +81,9 @@ export default {
 			isShowSourceDialog: false,
 			sourceEditForm: {
 
-			}
+			},
+			updateData:[],
+			useUnit:''
 		}
 	},
 	computed: {
@@ -160,6 +162,90 @@ export default {
 	},
 
 	methods: {
+        //转换从接口获取的tableData数据
+		formatUpdateData(data){
+			return {
+				...data,
+				IsConvert:Boolean(data.IsConvert),
+				ConvertType:data.ConvertType||1,
+				ConvertValue:data.ConvertValue||100,
+				ConvertUnit:data.IsConvert?data.ConvertUnit:data.ConvertUnit||data.Unit,
+				ConvertEnUnit:data.ConvertEnUnit||data.UnitEn||''
+			}
+		},
+		//接口获取更新后的数据
+		changeTableData(index){
+			const {IsConvert,ConvertType,ConvertValue,ConvertUnit,ConvertEnUnit,EdbInfoId} = this.updateData[index]
+			//计算方式是否合法
+			if(!this.checkConver(ConvertType,ConvertValue)){
+				this.updateData[index].IsConvert = false
+				return this.$message.warning("数据转换不合法,请检查数值")
+			}
+			//如果类型为对数,检测数据是否包含负数
+			if(ConvertType===3){
+				if(!this.checkEdbData(this.tableData[index].DataList)){
+					this.updateData[index].IsConvert = false
+					return this.$message.warning("指标数据含有负数或0,无法进行对数运算")
+				}
+			}
+			//柱形图单独设置
+			if(this.chartInfo.ChartType===7){
+				return this.setChangeBarData(index)
+			}
+			//请求接口...
+			let dateArray=this.chartInfo.ChartType==2?this.season_year:this.select_date
+			dataBaseInterface.getChangeEdbData({
+				EdbInfoId,
+				ChartType: this.chartInfo.ChartType,
+				DateType: this.year_select,
+				StartYear:this.count_year,
+				StartDate:
+						this.year_select === 5 || this.year_select === 6
+							? dateArray[0]
+							: '',
+				EndDate: this.year_select === 5 ? dateArray[1] : '',
+				IsConvert:Number(IsConvert),
+				ConvertType,ConvertValue:Number(ConvertValue),
+				ConvertUnit,ConvertEnUnit
+			}).then(res=>{
+				if(res.Ret!==200) return 
+				const {EdbInfoList=[]} = res.Data||{}
+				if(index===this.useUnit&&this.chartInfo.ChartType===7){
+					this.chartInfo.Unit = ConvertUnit
+					this.chartInfo.UnitEn = ConvertEnUnit
+				}
+				//this.tableData.splice(index,1,temp)
+				//需要保留tableData[]的其他属性,仅修改属性
+				this.tableData[index].DataList = EdbInfoList[0].DataList
+				this.tableData[index].ConvertUnit = EdbInfoList[0].ConvertUnit
+				this.tableData[index].ConvertEnUnit = EdbInfoList[0].ConvertEnUnit
+				this.tableData[index].MaxData = EdbInfoList[0].MaxData
+				this.tableData[index].MinData = EdbInfoList[0].MinData
+			})
+		},
+		setChangeBarData(index){
+			const {ConvertType,ConvertValue,ConvertUnit,ConvertEnUnit} = this.updateData[index]
+			if(index===this.useUnit&&this.chartInfo.ChartType===7){
+				this.chartInfo.Unit = ConvertUnit||'无'
+				this.chartInfo.UnitEn = ConvertEnUnit
+			}
+			this.barDateList.length && this.$refs.BarOptRef.getBarData();
+		},
+		checkConver(type,value){
+			//对数:value>1
+			//乘除:value!=0
+			if(!value) return false
+			if(type===3){
+				return value>1
+			}else{
+				return value!=0
+			}
+		},
+		checkEdbData(data){
+			const ValueArr = data.map(i=>(i.Value||0))
+			const minData = Math.min(...ValueArr)
+			return minData>0
+		},
 		/* 选择指标 获取指标详情并push到表格中*/
 		selectTarget(item,type='') {
 			if(!item) return
@@ -207,6 +293,8 @@ export default {
 							this.tableData.push(tableItem);
 							this.isSetExtremeValue = true;
 							// console.log(this.tableData)
+							const tempItem = this.formatUpdateData(tableItem)
+							this.updateData.push(tempItem)
 							
 							//默认拼接来源
 							if(!this.chartInfo.SourcesFrom) {
@@ -249,6 +337,8 @@ export default {
 			this.search_txt = '';
 			this.chartInfo.Unit = this.chartInfo.Unit||edb.Unit
 			this.tableData.push(edb)
+			const tempItem = this.formatUpdateData(edb)
+			this.updateData.push(tempItem)
 		},
 
 		/* 奇怪柱形图的日期配置项现在不止柱形图用了 获取数据时扩展一下 */
@@ -266,9 +356,14 @@ export default {
 			if(!this.tableData.length || !dateList.length) return
 
 			let params = {
-				EdbInfoIdList: this.tableData.map(_ => ({
+				EdbInfoIdList: this.tableData.map((_,index) => ({
 					EdbInfoId: _.EdbInfoId,
-					Name:_.EdbAliasName
+					Name:_.EdbAliasName,
+					IsConvert:Number(this.updateData[index].IsConvert),
+					ConvertType:this.updateData[index].ConvertType,
+					ConvertValue:Number(this.updateData[index].ConvertValue),
+					ConvertUnit:this.updateData[index].ConvertUnit,
+					ConvertEnUnit:this.updateData[index].ConvertEnUnit,
 				})),
 				DateList: dateList,
 				Sort: {
@@ -354,25 +449,33 @@ export default {
 		async getPreviewSplineInfo() {
 			let dateArray=this.chartInfo.ChartType==2?this.season_year:this.select_date
 			let params = {
-        ChartType: this.chartInfo.ChartType,
-        DateType: this.year_select,
-        StartDate: [5 , 6].includes(this.year_select)
-          ? dateArray[0]
-          : '',
-        EndDate: this.year_select === 5 ? dateArray[1]: '',
-        Calendar: this.calendar_type,
+				ChartType: this.chartInfo.ChartType,
+				DateType: this.year_select,
+				StartDate: [5 , 6].includes(this.year_select)
+					? dateArray[0]
+					: '',
+				EndDate: this.year_select === 5 ? dateArray[1]: '',
+				Calendar: this.calendar_type,
 				StartYear:this.count_year || 0,
 				// ETA1.0.5 去除了这两个入参
-        // SeasonStartDate: this.season_year ? this.season_year[0] : '',
-        // SeasonEndDate: this.season_year ? this.season_year[1] : '',
+				// SeasonStartDate: this.season_year ? this.season_year[0] : '',
+				// SeasonEndDate: this.season_year ? this.season_year[1] : '',
 				SeasonExtraConfig:this.SeasonExtraConfig,
-        ChartEdbInfoList: this.tableData.map(_ => ({
-          EdbInfoId: _.EdbInfoId,
-          EdbInfoType: _.EdbInfoType,
-          LeadValue: _.EdbInfoType ? 0 : Number(_.LeadValue),
-          LeadUnit: _.EdbInfoType ? '' : _.LeadUnit,
-        }))
-      }
+				ChartEdbInfoList: this.tableData.map((_,index) => {
+					const {IsConvert,ConvertType,ConvertValue,ConvertUnit,ConvertEnUnit} = this.updateData[index]
+					return {
+						EdbInfoId: _.EdbInfoId,
+						EdbInfoType: _.EdbInfoType,
+						LeadValue: _.EdbInfoType ? 0 : Number(_.LeadValue),
+						LeadUnit: _.EdbInfoType ? '' : _.LeadUnit,
+						IsConvert:Number(IsConvert),
+						ConvertType,
+						ConvertValue:Number(ConvertValue),
+						ConvertUnit:IsConvert?ConvertUnit:'',
+						ConvertEnUnit:IsConvert?ConvertEnUnit:''
+					}
+				})
+		}
 
       const res = await dataBaseInterface.getSplinePreviewData(params)
 
@@ -557,6 +660,7 @@ export default {
 		delTarget(item) {
 			let index = this.tableData.findIndex(obj => obj.EdbInfoId === item.EdbInfoId);
 			this.tableData.splice(index, 1);
+			this.updateData.splice(index, 1)
 			this.$message.success('删除成功')
 
 			//添加图表时重置默认样式
@@ -565,6 +669,9 @@ export default {
 			if(!this.tableData.length) {
 				this.chartInfo.MarkersLines = ""
 				this.chartInfo.MarkersAreas = ""
+				this.chartInfo.Unit = ""
+				this.chartInfo.UnitEn = ""
+				this.useUnit = ''
 			}
 		},
 

+ 33 - 21
src/views/dataEntry_manage/mixins/chartPublic.js

@@ -590,13 +590,15 @@ export const chartSetMixin = {
         );
 
         //y轴
+        const textZh = item.ConvertUnit||item.Unit
+        const textEn = item.ConvertEnUnit||item.UnitEn||item.ConvertUnit||item.Unit
         let yItem = {
           ...basicYAxis,
           title: {
-            text: item.Unit,
-            textCh:item.Unit, // 中文
+            text: textZh,
+            textCh:textZh, // 中文
             // 中文不存在,无论英文有无都显示空
-            textEn:item.UnitEn||item.Unit, // 英文
+            textEn:textZh?textEn:'', // 英文
             style:{
               ...chartTheme&&chartTheme.yAxisOptions.style
             },
@@ -767,13 +769,15 @@ export const chartSetMixin = {
         : newval.findIndex((item) => item.IsAxis===2);
 
         //y轴
+        const textZh = item.ConvertUnit||item.Unit
+        const textEn = item.ConvertEnUnit||item.UnitEn||item.ConvertUnit||item.Unit
         let yItem = {
           ...basicYAxis,
           title: {
-            text: item.Unit,
-            textCh:item.Unit, // 中文
+            text: textZh,
+            textCh:textZh, // 中文
             // 中文不存在,无论英文有无都显示空
-            textEn:item.UnitEn||item.Unit, // 英文
+            textEn:textZh?textEn:'', // 英文
             style:{
               ...chartTheme&&chartTheme.yAxisOptions.style
             },
@@ -916,6 +920,8 @@ export const chartSetMixin = {
       }
 
       //y轴
+      const textZh = chartData.ConvertUnit||chartData.Unit
+      const textEn = chartData.ConvertEnUnit||chartData.UnitEn||chartData.ConvertUnit||chartData.Unit
       seasonYdata = [{
         ...seasonOptions.yAxis,
         labels: {
@@ -929,10 +935,10 @@ export const chartSetMixin = {
           }
         },
         title: {
-          text:  `${chartData.Unit}`,
-          textCh:chartData.Unit, // 中文
+          text:  `${textZh}`,
+          textCh:textZh, // 中文
           // 中文不存在,无论英文有无都显示空
-          textEn:chartData.UnitEn||chartData.Unit, // 英文
+          textEn:textZh?textEn:'', // 英文
           style:{
             ...chartTheme&&chartTheme.yAxisOptions.style
           },
@@ -991,10 +997,11 @@ export const chartSetMixin = {
     /* 散点图设置  只允许2指标画图第一个指标值为x轴 第二个指标为y轴  */
     setScatterChart(newval) {
       console.log(newval);
-      this.leftIndex = 0;
+      this.leftIndex = 1;
       this.rightIndex = -1;
       this.rightTwoIndex = -1;
       if(newval.length !== 2) {
+        this.leftIndex = -1
         this.options = {}
         return
       };
@@ -1058,23 +1065,26 @@ export const chartSetMixin = {
       }
     
       // 目前指标限制死2个 为了简单 配置项直接关联第一个指标算了  自定义极值只在新增时用
-      if(!this.chartInfo.ChartInfoId && this.isSetExtremeValue) {
+      //ETA1.5.8 增加数据转换功能,不用第一个指标了
+      /* if(!this.chartInfo.ChartInfoId) {
         let maxYData = Math.max(...real_data.map(_ => _.y));
         let minYData = Math.min(...real_data.map(_ => _.y));
         newval[0].MaxData = maxYData;
         newval[0].MinData = minYData;
-        this.isSetExtremeValue = false;
-      }
+      } */
+
 
       const { IsOrder,ChartColor } = newval[0];
       //y轴
+      const textYZh = newval[1].ConvertUnit||newval[1].Unit
+      const textYEn = newval[1].ConvertEnUnit||newval[1].UnitEn||newval[1].ConvertUnit||newval[1].Unit
       let yAxis = {
         ...basicYAxis,
         title: {
-          text:  `${newval[1].Unit}`,
-          textCh:newval[1].Unit,// 中文
+          text:  `${textYZh}`,
+          textCh:textYZh,// 中文
           // 中文不存在,无论英文有无都显示空
-          textEn:newval[1].UnitEn||newval[1].Unit, // 英文
+          textEn:textYZh?textYEn:'', // 英文
           style:{
             ...chartTheme&&chartTheme.yAxisOptions.style
           },
@@ -1097,21 +1107,23 @@ export const chartSetMixin = {
         },
         opposite: false,
         reversed: IsOrder,
-        min: Number(newval[0].MinData),
-        max: Number(newval[0].MaxData),
+        min: Number(newval[1].MinData),
+        max: Number(newval[1].MaxData),
         tickWidth: 1,
         plotBands: this.setAxisPlotAreas(1),
         plotLines: this.setAxisPlotLines(1)
       }
 
       //x轴
+      const textXZh = newval[0].ConvertUnit||newval[0].Unit
+      const textXEn = newval[0].ConvertEnUnit||newval[0].UnitEn||newval[0].ConvertUnit||newval[0].Unit
       const xAxis = {
         ...scatterXAxis,
         title: {
-          text:  `${newval[0].Unit}`,
-          textCh:newval[0].Unit, // 中文
+          text:  `${textXZh}`,
+          textCh:textXZh, // 中文
           // 中文不存在,无论英文有无都显示空
-          textEn:newval[0].UnitEn||newval[0].Unit, // 英文
+          textEn:textXZh?textXEn:'', // 英文
           style: {
             ...chartTheme&&chartTheme.xAxisOptions.style
           },

+ 26 - 14
src/views/dataEntry_manage/onlineExcelCopy.vue

@@ -263,9 +263,23 @@ created() {
         }
       }
 
-      // 处理复制粘贴造成的漏洞 - 还原数据
+      // 处理复制粘贴造成的漏洞 - 还原数据 PS:这个钩子函数只有在单元格在可是区域内才会执行
       this.options.hook.cellRenderBefore=(cell,position,sheet,ctx)=>{
-        // console.log('cellRenderBeforecellRenderBefore');
+        // 清除两边空格
+        if(cell && cell.m && typeof(cell.m)=='string'){
+          cell.m = cell.m.trim()  
+        }
+        if(cell && cell.v && typeof(cell.v)=='string'){
+          cell.v = cell.v.trim()  
+        }
+        /**
+         * 从excel整个单元格复制,到这里进入编辑模式的粘贴,出来个cell.ct.s,不知道啥东西,官网也没写
+         * 看似有内容,实则保存没内容,因为cell.m和cell.v 都是空。直接清掉了
+         */
+        if(cell && cell.ct && cell.ct.s){
+          cell.ct.s='' 
+        }
+        
         // 是否更改了受保护的数据
         let haveUpdatedProtectedData=false
         if([3,4].includes(position.r) && position.c>=0 && position.c<=dataList.length){
@@ -318,7 +332,6 @@ created() {
           this.refreshManual()
         }
       }
-
       // 拿出所有数组
       let arr = dataList.map((item => item.DataList)).flat()
       // 拿出所有数组的日期并展平排序
@@ -509,27 +522,16 @@ created() {
         this.secondClassName = this.secondClassifyArray[0].ClassifyName
       }
       luckysheet.refresh()
-      // for (let i= 1;  i< col+1 ; i++) {
-      //   luckysheet.setCellValue(0,i,this.firstClassName,{isRefresh:false})
-      //   luckysheet.setCellValue(1,i,this.secondClassName,{isRefresh:i==col?true:false})
-      // }
     },
     // 切换选择二级分类
     changeSecondClassify(id){
       let col = this.options.column
       let item = this.secondClassifyArray.find(item => item.ClassifyId == id)
       this.secondClassName=item.ClassifyName
-      // for (let i= 1;  i< col+1; i++) {
-      //   luckysheet.setCellValue(1,i,this.secondClassName,{isRefresh:i==col?true:false})
-      // }
       luckysheet.refresh()
     },
     // 切换选择频度
     changeFrequency(value){
-      // let col = this.options.column
-      // for (let i= 1;  i< col+1; i++) {
-      //   luckysheet.setCellValue(2,i,value,{isRefresh:i==col?true:false})
-      // }
       luckysheet.refresh()
     },
     saveExcel(){
@@ -537,6 +539,16 @@ created() {
         if(valid){
           this.saveLoading=true
           let data = luckysheet.getAllSheets()
+          for (let i = 0; i < data[0].data.length; i++) {
+            // 清除日期列的两边的空格,防止保存时日期变成0000-00-00
+            const element = data[0].data[i][0];
+            if(element && element.v && typeof(element.v)=='string'){
+              element.v = element.v.trim()  
+            }
+            if(element && element.m && typeof(element.m)=='string'){
+              element.m = element.m.trim()  
+            }
+          }
           dataInterence.saveOnlineExcel({...data[0],ClassifyId:this.dataForm.secondClassify}).then(res=>{
           if(res.Ret == 200) {
             this.setCache('submit')

+ 388 - 0
src/views/dataEntry_manage/thirdBase/coalWord.vue

@@ -0,0 +1,388 @@
+<template>
+  <div class="coal-word-container coal-similarity-container" >
+    <span
+        class="slide-btn-icon"
+        :class="{'slide-left':isLeftWrapShow,'slide-right':!isLeftWrapShow}"
+        @click="isLeftWrapShow = !isLeftWrapShow"
+    >
+        <i :class="{'el-icon-d-arrow-left':isLeftWrapShow,'el-icon-d-arrow-right':!isLeftWrapShow}"></i>
+    </span>
+    <div class="left-cont minHeight" v-show="isLeftWrapShow">
+      <div class="left-top">
+        <el-button
+          style="width: 100%;margin-bottom: 10px;"
+          type="primary"
+          plain
+          size="medium"
+          @click="exportClick"
+          :loading="btnload"
+          v-permission="permissionBtn.dataSourcePermission.coalWordData_export" 
+          >导出Excel</el-button
+        >
+        <el-autocomplete
+          style="margintop: 20px; width: 100%"
+          prefix-icon="el-icon-search"
+          v-model="leftSearchVal"
+          :fetch-suggestions="handleLeftSearch"
+          :trigger-on-focus="false"
+          placeholder="指标名称/指标ID"
+          @select="handleSelectLeftSearchval"
+          @blur="searchvalBlur"
+          @clear="searchvalClear"
+          popper-class="el-autocomplete-suggestion-data-entry"
+          clearable
+        >
+          <template slot-scope="scope">
+            <div v-if="scope.item.nodata" style="text-align: center">
+              暂无数据
+            </div>
+            <div v-else>
+              {{ scope.item.IndexName }}
+            </div>
+          </template>
+        </el-autocomplete>
+      </div>
+      <ul class="classify-list">
+        <li
+          :class="['classify-item', { act: select_classify == item.Area }]"
+          v-for="item in classifyList"
+          :key="item.Area"
+          @click="changeClassify(item)"
+        >
+          {{ item.Area }}
+        </li>
+      </ul>
+    </div>
+    <div
+      class="right-cont minHeight"
+      v-loading="dataloading"
+      element-loading-text="获取数据中..."
+    >
+      <div class="right-box" v-if="rightShow"
+        v-infinite-scroll="loadNext"
+        :infinite-scroll-disabled="!haveMore"
+        :infinite-scroll-immediate="false">
+        <template v-if="dateArr.length">
+          <div class="data-header">
+            <lz-table
+              :tableOption="tableOption"
+              tableType="header"
+              ref="table"
+              source="coalWord"
+            />
+          </div>
+          <div class="data-cont" >
+            <lz-table
+              :tableOption="tableOption"
+              tableType="data"
+              :dateArr="dateArr"
+              source="coalWord"
+            />
+          </div>
+        </template>
+        <tableNoData v-else text="暂无数据" class="nodata"></tableNoData>
+      </div>
+      <div class="frequency-list" v-if="rightShow">
+        <el-button
+          type="primary"
+          class="frequency-btn"
+          :plain="select_frequency !== item"
+          v-for="item in frequencyList"
+          :key="item"
+          @click="changeFrequency(item)"
+          >{{ item }}</el-button
+        >
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import lzTable from "@/components/lzTable.vue";
+import { coalWordInterface } from "@/api/api.js";
+export default {
+  name: "coalWord",
+  components: { lzTable },
+  watch: {
+    select_classify(newval) {
+      if (!this.isAuto) return;
+      this.select_frequency = "";
+      newval && this.getFrequency();
+    },
+    select_frequency(newval) {
+      if (!this.isAuto) return;
+      newval && this.getDataList();
+    },
+  },
+  computed: {
+    exportApi() {
+      // 数据导出接口
+      let urlStr = this.exportBase;
+      // token
+      urlStr += `?${localStorage.getItem("auth") || ""}`;
+      // 分类名称
+      urlStr += `&Area=${this.select_classify}`;
+      // 指标Id
+      urlStr += `&IndexCode=${this.leftSearchTradeCode}`;
+      return this.escapeStr(urlStr);
+    },
+  },
+  created() {
+    if(this.permissionBtn.isShowBtn('dataSourcePermission','coalWordData_view')){
+      this.getClassify();
+    }else{
+      this.rightShow=true
+    }
+  },
+  data() {
+    return {
+      isLeftWrapShow:true,
+      dataloading: false,
+      rightShow: false,
+      exportBase: process.env.VUE_APP_API_ROOT + "/entry/export/mtjh", //数据导出接口
+      select_classify: "",
+      classifyList: [],
+      select_frequency: "",
+      PageSize:20,
+      CurrentIndex:1,
+      haveMore:true,
+      frequencyType: new Map([
+        [1, "日度"],
+        [2, "周度"],
+        [3, "月度"],
+        [4, "季度"],
+        [5, "年度"],
+        [99, "无固定频率"],
+      ]),
+      frequencyList: [],
+      tableOption: [],
+      dateArr: [], //最长的日期数组
+      btnload: false,
+      leftSearchVal: "", //左侧搜索值
+      leftSearchTradeCode: "", //如果是搜索选择的 则有此code
+      isAuto: true, // 改变分类时是否自动获取数据
+    };
+  },
+  methods: {
+    /* 获取分类 */
+    getClassify() {
+      coalWordInterface.classifyList().then((res) => {
+        if (res.Ret !== 200) return;
+        this.classifyList = res.Data || [];
+        this.select_classify =
+          this.select_classify || this.classifyList[0].Area;
+      });
+    },
+    /* 获取频度 */
+    getFrequency(defaultSelect) {
+      coalWordInterface.getFrequencyList({
+        Area: this.select_classify,
+      }).then((res) => {
+        if (res.Ret !== 200) return;
+        this.frequencyList = res.Data || []
+        //设置当前选中的频度,若传入有默认选项则选中默认频度,否则选中列表第一个
+        this.select_frequency = defaultSelect || this.frequencyList[0];
+        //如果有默认频度,结束后恢复watcher
+        this.$nextTick(() => {
+          if (defaultSelect) this.isAuto = true;
+        });
+      });
+    },
+    /* 获取数据 */
+    getDataList() {
+      this.dataloading = true;
+      coalWordInterface.dataList({
+        Area: this.select_classify,
+        PageSize: this.PageSize,
+        CurrentIndex:this.CurrentIndex,
+        Frequency: this.select_frequency,
+      }).then((res) => {
+        this.rightShow = true;
+        if (res.Ret !== 200) return;
+
+        // 找出最多的页码 判断是否还有数据
+        let page_arrs = res.Data.map((item) => item.Paging?item.Paging.Pages:0);
+        let totalPage = Math.max.apply(Math, page_arrs);
+        this.haveMore = this.CurrentIndex < totalPage ? true : false;
+        // 设置表格数据
+        this.setDataList(res.Data || []);
+
+        this.CurrentIndex == 1 &&
+          this.$nextTick(() => {
+            this.initWidth();
+          });
+      }).finally(()=>{
+        this.dataloading = false;
+      })
+    },
+    /* 滚动加载 */
+    loadNext() {
+      this.CurrentIndex++;
+      if(this.leftSearchTradeCode){
+        this.getTargetDataList()
+      }else{
+        this.getDataList();
+      }
+    },
+    /* 改变分类 */
+    changeClassify(item) {
+      if(this.dataloading) return 
+      this.select_classify = item.Area;
+      this.leftSearchVal = "";
+      this.leftSearchTradeCode = ""
+      this.CurrentIndex=1
+    },
+    /* 改变频度 */
+    changeFrequency(item) {
+      if(this.select_frequency == item) return 
+      this.select_frequency = item;
+      this.leftSearchVal = "";
+      this.CurrentIndex=1
+    },
+    initWidth() {
+      $(".right-box")[0].style.width =
+      this.$refs.table ? this.$refs.table.$el.clientWidth + 2 + "px":0
+      $(".right-box")[0].scrollTop = 0;
+      $(".right-box")[0].scrollLeft = 0;
+    },
+    /* 数据导出 */
+    exportClick() {
+      this.btnload = true;
+      console.log({
+        Area:this.select_classify,
+        IndexCode:this.leftSearchTradeCode
+      },this.exportApi);
+      const link = document.createElement("a");
+      link.href = this.exportApi;
+      link.download = "";
+      link.click();
+      setTimeout(() => {
+        this.btnload = false;
+      }, 2000);
+    },
+
+    //左侧搜索
+    async handleLeftSearch(query, cb) {
+      cb([]);
+      if (!query) return;
+      const res = await coalWordInterface.targetListSearch({
+        Keyword: query,
+      });
+      if (res.Ret === 200) {
+        let arr = res.Data || [];
+        if (!arr.length) {
+          cb([{ nodata: true }]);
+        } else {
+          cb(arr);
+        }
+      }
+    },
+    // 选中左侧搜索值
+    handleSelectLeftSearchval(e) {
+      if (!e.IndexCode || this.dataloading) return;
+      this.leftSearchTradeCode = e.IndexCode;
+      this.leftSearchVal = e.IndexName;
+      this.select_classify = e.Area
+      // 关闭watcher
+      this.isAuto = false;
+      this.getFrequency(e.Frequency);
+      this.CurrentIndex=1
+      this.getTargetDataList()
+      this.$nextTick(() => {
+        this.handleScrollLeftWrap();
+      });
+    },
+    searchvalBlur(){
+      if((!this.leftSearchVal) && this.leftSearchTradeCode){
+        this.searchvalClear()
+      }   
+    },
+    searchvalClear(){
+      this.CurrentIndex=1
+      this.leftSearchTradeCode=''
+      this.getDataList();
+    },
+    // 左侧滚动
+    handleScrollLeftWrap() {
+      let top = $(".act")[0].offsetTop;
+      $(".classify-list").animate({
+        scrollTop: top - 200,
+      });
+    },
+    // 获取单个指标数据
+    getTargetDataList() {
+      if (!this.leftSearchTradeCode) return;
+      this.dataloading = true;
+
+      try {
+        coalWordInterface.getTargetDataList({
+          IndexCode: this.leftSearchTradeCode,
+          Pagesize: this.PageSize,
+          CurrentIndex: this.CurrentIndex
+        }).then(res=>{
+          if (res.Ret !== 200) return;
+
+          this.haveMore = this.CurrentIndex < res.Data.Paging.Pages ? true : false;
+          this.setDataList([res.Data])
+
+          this.CurrentIndex == 1 &&
+            this.$nextTick(() => {
+              this.initWidth();
+            });
+        }).finally(()=>{
+          this.dataloading = false;
+        })
+      } catch (err) {
+        console.error(err);
+        this.dataloading = false;
+      }
+    },
+    // 设置表格数据
+    setDataList(data) {
+      if(this.CurrentIndex ==1){
+        this.tableOption = data;
+        /* 不满6个追加6个空的显示一排 别问 问就是为了美观  */
+        if (data.length < 6){
+          for (let i = 0; i < 6; i++) {
+            this.tableOption.push({
+              DataList: [],
+            });
+            if (this.tableOption.length >= 6) break;
+          }
+        }
+      }else{
+        this.tableOption.forEach((item) => {
+          data.forEach((_item) => {
+            if (item.IndexCode === _item.IndexCode) {
+              item.DataList = item.DataList.concat(_item.DataList);
+            }
+          });
+        });
+      }   
+      // 合并所有日期
+      let arr = this.tableOption.map((item) => item.DataList);
+      let obj = [];
+      arr.forEach((dataList) => {
+        obj.push(...dataList.map((item) => item.DataTime));
+      });
+      // 日期去重倒序排序
+      this.dateArr = [...new Set(obj)].sort().reverse();
+      //数据最大长度小于12个 追加数据满12个 别问 问就是为了美观
+      if (this.dateArr.length < 12){
+        for (let i = 0; i < 12; i++) {
+          this.dateArr.push("");
+          if (this.dateArr.length >= 12) break;
+        }
+      }
+
+    },
+    // 对[#,;]转义
+    escapeStr(str) {
+      return str.replace(/#/g, escape("#")).replace(/;/g, escape(";"));
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+@import "../css/coalCommon.scss";
+</style>

+ 293 - 0
src/views/dataEntry_manage/thirdBase/icpiConsumption.vue

@@ -0,0 +1,293 @@
+<template>
+  <div class="icpc-container coal-similarity-container">
+    <span
+        class="slide-btn-icon"
+        :class="{'slide-left':isLeftWrapShow,'slide-right':!isLeftWrapShow}"
+        @click="isLeftWrapShow = !isLeftWrapShow"
+    >
+        <i :class="{'el-icon-d-arrow-left':isLeftWrapShow,'el-icon-d-arrow-right':!isLeftWrapShow}"></i>
+    </span>
+    <div class="left-cont minHeight" v-show="isLeftWrapShow">
+      <div class="left-top">
+        <el-button
+          style="width: 100%;"
+          type="primary"
+          plain
+          size="medium"
+          @click="exportClick"
+          :loading="btnload"
+          >导出Excel</el-button
+        >
+        <el-autocomplete
+          style="margin-top: 20px; width: 100%"
+          prefix-icon="el-icon-search"
+          v-model="leftSearchVal"
+          :fetch-suggestions="handleLeftSearch"
+          :trigger-on-focus="false"
+          placeholder="指标名称/指标ID"
+          @select="handleSelectLeftSearchval"
+          popper-class="el-autocomplete-suggestion-data-entry"
+          @clear="clearSearchVal"
+          clearable
+        >
+          <template slot-scope="scope">
+            <div v-if="scope.item.nodata" style="text-align: center">
+              暂无数据
+            </div>
+            <div v-else>
+              {{ scope.item.IndexName }}
+            </div>
+          </template>
+        </el-autocomplete>
+      </div>
+      <ul class="classify-list">
+        <li
+          :class="['classify-item', { act: select_classify === item.BaseFromIcpiClassifyId }]"
+          v-for="item in classifyList"
+          :key="item.BaseFromIcpiClassifyId"
+          @click="changeClassify(item)"
+        >
+          {{ item.ClassifyName }}
+        </li>
+      </ul>
+    </div>
+    <div
+      class="right-cont minHeight"
+      v-loading="dataloading"
+      element-loading-text="获取数据中..."
+    >
+      <div class="right-box" v-if="rightShow" @scroll="scrollHandle">
+        <template v-if="dateArr.length">
+          <div class="data-header">
+            <lz-table
+              :tableOption="tableOption"
+              tableType="header"
+              ref="table"
+              source="icpi"
+            />
+          </div>
+          <div class="data-cont">
+            <lz-table
+              :tableOption="tableOption"
+              tableType="data"
+              :dateArr="dateArr"
+              source="icpi"
+            />
+          </div>
+        </template>
+        <tableNoData v-else text="暂无数据" class="nodata"></tableNoData>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import lzTable from "@/components/lzTable.vue";
+import { lzDataInterface } from "@/api/api.js";
+import { icpiInterface } from "@/api/api.js";
+
+export default {
+  name: "icpiConsumption",
+  components: { lzTable },
+  data() {
+    return {
+      isLeftWrapShow:true,
+      dataloading: false,
+      rightShow: false,
+      exportBase: process.env.VUE_APP_API_ROOT + "/data_source/icpi/export/icpiDataList", //数据导出接口
+      select_classify: "",
+      classifyList: [],
+      tableOption: [],
+      dateArr: [], //最长的日期数组
+      btnload: false,
+
+      leftSearchVal: "", //左侧搜索值
+      pageParams:{
+        PageSize:20,
+        CurrentIndex:1,
+        KeyWord:''
+      },
+      havemore:true
+    };
+  },
+  computed: {
+    exportIcpiApi() {
+      // 数据导出接口
+      let urlStr = this.exportBase;
+      // token
+      urlStr += `?${localStorage.getItem("auth") || ""}`;
+      // 分类Id参数
+      urlStr += `&BaseFromIcpiClassifyId=${this.select_classify}`;
+      urlStr += `&KeyWord=${this.pageParams.KeyWord}`;
+      return this.escapeStr(urlStr);
+    },
+  },
+  created() {
+    this.getClassify();
+  },
+  methods: {
+    /* 获取分类 */
+    getClassify() {
+      icpiInterface.classifyList().then((res) => {
+        if (res.Ret !== 200) return;
+        this.classifyList = res.Data || [];
+        this.select_classify =
+          this.select_classify || this.classifyList[0].BaseFromIcpiClassifyId;
+        
+        this.getDataList()
+      });
+    },
+
+    /* 获取数据 */
+    getDataList() {
+      this.dataloading = true;
+      icpiInterface.dataList({
+        BaseFromIcpiClassifyId: Number(this.select_classify),
+        PageSize:this.pageParams.PageSize,
+        CurrentIndex:this.pageParams.CurrentIndex,
+        KeyWord:this.pageParams.KeyWord
+      }).then((res) => {
+        this.rightShow = true;
+        if (res.Ret !== 200) return;
+
+        // 找出最多的页码 判断是否还有数据
+        let page_arrs = res.Data.map((item) => item.Paging?item.Paging.Pages:0);
+        let totalPage = Math.max.apply(Math, page_arrs);
+        this.havemore = this.pageParams.CurrentIndex < totalPage ? true : false;
+        
+        // 设置表格数据
+        this.setDataList(res.Data);
+        this.$nextTick(() => {
+          this.initWidth();
+        });
+      }).finally(()=>{
+        this.dataloading = false;
+      })
+    },
+    /* 改变品种 */
+    changeClassify(item) {
+      this.select_classify = item.BaseFromIcpiClassifyId;
+      this.leftSearchVal = ""
+      this.pageParams.KeyWord=''
+      this.pageParams.CurrentIndex=1
+      this.getDataList()
+    },
+
+    initWidth() {
+      $(".right-box")[0].style.width =
+      this.$refs.table ? this.$refs.table.$el.clientWidth + 2 + "px":'0';
+      $(".right-box")[0].scrollTop = 0;
+      $(".right-box")[0].scrollLeft = 0;
+    },
+    // 对[#,;]转义
+    escapeStr(str) {
+      return str.replace(/#/g, escape("#")).replace(/;/g, escape(";")); 
+    },
+    /* 导出 */
+    exportClick() {
+      this.btnload = true;
+      const link = document.createElement("a");
+      link.href = this.exportIcpiApi;
+      link.download = "";
+      link.click();
+      setTimeout(() => {
+        this.btnload = false;
+      }, 2000);
+    },
+
+    //左侧搜索
+    async handleLeftSearch(query, cb) {
+      cb([]);
+      if (!query) return;
+      const res = await icpiInterface.dataList({
+        KeyWord: query
+      });
+      if (res.Ret === 200) {
+        let arr = res.Data || [];
+        if (!arr.length) {
+          cb([{ nodata: true }]);
+        } else {
+          cb(arr);
+        }
+      }
+    },
+    // 选中左侧搜索值
+    handleSelectLeftSearchval(e) {
+      if (!e.BaseFromIcpiIndexId) return;
+      this.rightShow = false;
+      this.leftSearchVal = e.IndexName;
+      this.pageParams.KeyWord=e.IndexName
+      this.select_classify = e.BaseFromIcpiClassifyId;
+      this.pageParams.CurrentIndex=1
+      this.getDataList()
+      this.$nextTick(() => {
+        this.rightShow = true;
+        this.handleScrollLeftWrap();
+      });
+    },
+    clearSearchVal(){
+      this.pageParams.KeyWord=''
+      this.getDataList()
+    },
+    // 左侧滚动
+    handleScrollLeftWrap() {
+      let top = $(".act")[0].offsetTop;
+      $(".classify-list").animate({
+        scrollTop: top - 200,
+      });
+    },
+    /* 滚动加载 */
+    scrollHandle(e) {
+      const dom = e.target;
+      let total = dom.scrollTop + dom.clientHeight;
+      if (total >= dom.scrollHeight && this.havemore) {
+        this.pageParams.CurrentIndex++;
+        // console.log("load下一页");
+        this.getDataList();
+      }
+    },
+    // 设置表格数据
+    setDataList(data) {
+      if(this.pageParams.CurrentIndex==1){
+        this.tableOption = data;
+        /* 不满7个追加7个空的显示一排 别问 问就是为了美观  */
+        if (this.tableOption.length < 7){
+          for (let i = 0; i < 7; i++) {
+            this.tableOption.push({
+              DataList: [],
+            });
+            if (this.tableOption.length >= 7) break;
+          }
+        }
+      }else{
+        this.tableOption.forEach((item) => {
+          data.forEach((_item) => {
+            if (item.IndexCode === _item.IndexCode) {
+              item.DataList = item.DataList.concat(_item.DataList);
+            }
+          });
+        });
+      }
+
+      // 合并所有日期
+      let arr = this.tableOption.map((item) => item.DataList);
+      let obj = [];
+      arr.forEach((dataList) => {
+        obj.push(...dataList.map((item) => item.DataTime));
+      });
+      // 日期去重倒序排序
+      this.dateArr = [...new Set(obj)].sort().reverse();
+      //数据最大长度小于13个 追加数据满13个 别问 问就是为了美观
+      if (this.dateArr.length < 13){
+        for (let i = 0; i < 13; i++) {
+          this.dateArr.push("");
+          if (this.dateArr.length >= 13) break;
+        }
+      }
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+@import "../css/coalCommon.scss";
+</style>

+ 13 - 12
src/views/datasheet_manage/addSheet.vue

@@ -11,19 +11,20 @@
           </el-input>
         </li>
         <li>
-          <el-select 
-            v-model="sheetForm.classify" 
-            placeholder="请选择表格分类"
-            style="width:240px"
+          <el-cascader
+            v-model="sheetForm.classify"
+            :options="classifyArr"
+            style="width:240px;"
+            :props="{
+              label: 'ExcelClassifyName',
+              value: 'ExcelClassifyId',
+              children: 'Children',
+              emitPath: false,
+              checkStrictly: true
+            }"
             clearable
-          >
-							<el-option
-								v-for="item in classifyArr"
-								:key="item.ExcelClassifyId"
-								:label="item.ExcelClassifyName"
-								:value="item.ExcelClassifyId"
-              />
-						</el-select>
+            placeholder="请选择表格分类"
+          />
         </li>
       </ul>
       <div v-if="updateTime" style="color:#999999;margin-right: 30px;">最近保存时间:{{ updateTime }}</div>

+ 115 - 7
src/views/datasheet_manage/common/customTable.js

@@ -1,3 +1,4 @@
+import { multiply,divide } from '@/utils/calculate';
 // 字母列标
 export function getColumnHeaderCode(len) {
   let tag_arr = [];
@@ -138,23 +139,24 @@ export function setCellBg(e) {
 export function getRightClickMenu(pos,canEdit=false) {
 
   let cellMenu = [
-    { label: "根据表格中日期选择指标值", key: "choose-target" },
+    { label: "根据日期选择指标值", key: "choose-target" },
     // { label: "插入指标值", key: "insert-value" },
-    { label: "导入系统日期", key: "insert-sys-date" },
-    { label: "导入指标日期", key: "insert-edb-date" },
+    { label: "导入日期", key: "insert-date" },
+    // { label: "导入指标日期", key: "insert-edb-date" },
+    { label: "日期计算", key: "insert-date-calculate" },
     { label: "指标计算",
       key: "insert-edb-calculate",
       children: [
         { label: '累计值转月/季值',source: 1,fromEdbKey:5 },
         { label: '同比值',source: 3,fromEdbKey:6 },
         { label: '同差值',source: 4,fromEdbKey:7 },
-        { label: 'N数值移动平均计算',source: 5,fromEdbKey:8 },
-        { label: 'N数值环比值',source: 6,fromEdbKey:12 },
-        { label: 'N数值环差值',source: 7,fromEdbKey:13 },
+        { label: 'N期移动均值',source: 5,fromEdbKey:8 },
+        { label: 'N环比值',source: 6,fromEdbKey:12 },
+        { label: 'N环差值',source: 7,fromEdbKey:13 },
         { label: '升频',source: 8,fromEdbKey:14 },
         { label: '时间移位',source: 10,fromEdbKey:22 },
         { label: '超季节性',source: 11,fromEdbKey:35 },
-        { label: '年化',source: 12,fromEdbKey:52 },
+        { label: '年化',source: 12,fromEdbKey:52 },
         { label: '降频',source: 9,fromEdbKey:51 },
         { label: '累计值',source: 13,fromEdbKey:62 },
         { label: '指数修匀',source: 15,fromEdbKey:'alpha' },
@@ -261,3 +263,109 @@ export function findCellKeyByFactor(str) {
 
   return el ? (el.dataset.key||'') : null;
 }
+
+/* 判断值是否是一个数字或数字字符串 */
+export function isNumberVal(value) {
+   let reg = /^[-]?(?:\d*\.?\d+|\d+%|\d*\.\d+%)$/;
+   
+   return reg.test(value);
+}
+
+/* 增加减少小数点位数 */
+export function transDecimalPlace(str,{pn,nt}) {
+
+  if(!isNumberVal(str)) return '';
+
+  let s = str.replace(/%/,''),
+      decimalPlaces = getDecimalPlaces(str),
+      decimalNum=pn;
+  
+  //是否是原数字后设置百分比的
+  let transPercent = (nt==='percent'&&!str.endsWith('%')) ? true : false;
+
+  //原百分比设置为数字的
+  let transDecimal = (nt==='number'&&str.endsWith('%')) ? true : false
+
+  //后缀 百分号
+  let suffix = ((str.endsWith('%')&&nt!=='number')||transPercent) ? '%' : '';
+
+  let num = parseFloat(s);
+
+  if(decimalPlaces===0) { //整数
+    if(transPercent) {
+      return decimalNum > 0 
+        ? `${multiply(num,100)}.${'0'.repeat(decimalNum)}${suffix}`
+        : `${multiply(num,100)}${suffix}`;
+    }
+
+    if(transDecimal) {
+      return decimalNum > 0 
+        ? `${divide(num,100)}${'0'.repeat(decimalNum)}`
+        : `${divide(num,100)}`;
+    }
+
+    // 补零
+    return decimalNum > 0 
+      ? `${s}.${'0'.repeat(decimalNum)}${suffix}`
+      : `${s}${suffix}`;
+  }
+
+  if(decimalNum > 0) {
+    let addPointStr = `${s}${'0'.repeat(decimalNum)}`;
+    
+    return transPercent 
+      ? `${parseFloat(multiply(num,100)).toFixed(decimalPlaces+decimalNum-2)}${suffix}`
+      : transDecimal
+        ? `${parseFloat(divide(num,100)).toFixed(decimalPlaces+decimalNum+2)}`
+        : `${addPointStr}${suffix}`
+  }else {
+    let maxDecimal = Math.max(0,decimalNum+decimalPlaces);
+    let maxDecimalPercent = Math.max(0,maxDecimal-2);
+
+    return transPercent 
+      ? `${parseFloat(multiply(num,100)).toFixed(maxDecimalPercent)}${suffix}`
+      : transDecimal
+        ? `${parseFloat(divide(num,100)).toFixed(maxDecimal+2)}`
+        : `${parseFloat(num.toFixed(maxDecimal))}${suffix}`
+  }
+}
+
+/* 计算小数点位数 */
+export function getDecimalPlaces(numStr) {
+  // 移除百分号,如果有的话
+  numStr = numStr.replace('%', '');
+
+  // 如果没有小数点,说明小数点位数为 0
+  if (!numStr.includes('.')) {
+    return 0;
+  }
+
+  // 获取当前小数点后的位数
+  const decimalPlaces = numStr.split('.')[1].length;
+
+  return decimalPlaces;
+}
+
+/* 格式化单元格值 显示转换 */
+export function transNumPercentType(str,type) {
+  console.log(str,type)
+
+  let isPercent = str.endsWith('%'),s=str.replace(/%/,'');
+  
+  if(isPercent && type==='percent') { //百分数转百分
+    return str
+  }
+
+  if(!isPercent && type==='number') { //数字转数字
+    return str
+  }
+
+  let num = parseFloat(s)
+
+  if(type==='percent') {
+    const percenStr = parseFloat(multiply(num,100)) + '%';
+    return percenStr;
+  }else {
+    return parseFloat(divide(num,100));
+  }
+}

+ 273 - 121
src/views/datasheet_manage/components/MixedTable.vue

@@ -1,6 +1,9 @@
 <template>
   <div class="table-wrapper" @keydown="handlekeyDownKeys">
     <template v-if="config.data.length">
+
+      <!-- 工具栏 -->
+      <toolBarSection v-if="!disabled" :cell="selectCell" @updateCell="updateCellStyle"/>
       
       <!-- 公式显示区 -->
       <div class="formula-wrapper" v-if="!disabled">
@@ -64,8 +67,9 @@
             >
 
             <!-- 插入单元格禁止编辑 -->
+            <!-- [4,5,6,7,8].includes(cell.DataType)&&!cell.CanEdit -->
             <template 
-              v-if="([4,5,6,7].includes(cell.DataType)&&!cell.CanEdit)
+              v-if="!cell.CanEdit
               ||disabled
               ||(cell.DataType===1&&[1,2].includes(cell.DataTimeType))"
             >
@@ -96,9 +100,19 @@
                   :data-rindex="rowHeader[index]"
                   :data-cindex="columnHeader[cell_index]"
                   :data-key="cell.Uid"
-                >{{ cell.ShowValue }}</span>
+                >{{ cell.ShowStyle?cell.ShowFormatValue:cell.ShowValue }}</span>
               </el-popover>
 
+              <!-- 数字格式化显示 -->
+              <span 
+                v-else-if="cell.ShowStyle"
+                :data-rindex="rowHeader[index]"
+                :data-cindex="columnHeader[cell_index]"
+                :data-key="cell.Uid"
+              >
+                {{cell.ShowFormatValue}}
+              </span>
+
               <span
                 :data-rindex="rowHeader[index]"
                 :data-cindex="columnHeader[cell_index]"
@@ -111,17 +125,19 @@
                 v-else
                 v-model="cell.Value"
                 :ref="`inputRef${cell.Uid}`"
-                :fetch-suggestions="searchTarget"
                 popper-class="edb-select-popover"
                 :data-key="cell.Uid"
                 :data-rindex="rowHeader[index]"
                 :data-cindex="columnHeader[cell_index]"
-                :highlight-first-item="cell.DataType===2"
-                @select="selectTarget($event,cell)"
-                @click="clickCell($event, cell)"
+                :fetch-suggestions="searchTarget"
                 @change.native="changeVal($event, cell)"
                 @keydown.native="keyEnterHandle($event,cell)"
+                @blur="() => {$set(cell,'CanEdit',false)}"
               >
+                <!-- @select="selectTarget($event,cell)"
+                  @click="clickCell($event, cell)"
+                :highlight-first-item="cell.DataType===2"
+                 -->
                 <template slot-scope="scope">
                     <edbDetailPopover :info="scope.item">
                       <div slot="reference" v-if="cell.DataType===2" class="edb-item">
@@ -139,14 +155,33 @@
       </table>
 
       <!-- 右键菜单 -->
-      <div class="contextMenu-wrapper" id="contextMenu-wrapper" @mouseleave="hideContextMenu">
+      <div class="contextMenu-wrapper" id="contextMenu-wrapper" @mouseleave="()=>{activeNames=[];hideContextMenu()}">
         <div :class="['item',{'deletesty': menu.key==='reset'}]" v-for="menu in config.contextMenuOption" :key="menu.key" @click="handleContext(menu.key)">
-          {{menu.label}}
+          <span v-if="!menu.children">{{menu.label}}</span>
           
-          <i class="el-icon-arrow-right" v-if="menu.children"></i>
+          <el-collapse v-model="activeNames" @change="handleChange" v-if="menu.children">
+            <el-collapse-item name="1">
+              <template slot="title">
+                 {{menu.label}}
+              </template>
+              
+              <div class="subMenu-wrapper">
+                <div slot="reference" class="item" v-for="submenu in menu.children" :key="submenu.key" @click="edbCalculateInsertOpen(submenu)">
+                    <el-popover
+                      width="300"
+                      trigger="hover"
+                      placement="right"
+                    >
+                      <div v-html="formulaTip.get(submenu.fromEdbKey)"></div>
+                      <div slot="reference" style="width:100%">{{submenu.label}}</div>   
+                    </el-popover>
+                </div>
+              </div>
+            </el-collapse-item>
+          </el-collapse>  
 
           <!-- 二级菜单 -->
-          <div class="subMenu-wrapper" v-if="menu.children">
+          <!-- <div class="subMenu-wrapper" v-if="menu.children">
             <div slot="reference" class="item" v-for="submenu in menu.children" :key="submenu.key" @click="edbCalculateInsertOpen(submenu)">
                 <el-popover
                   width="300"
@@ -157,7 +192,7 @@
                   <div slot="reference" style="width:100%">{{submenu.label}}</div>   
                 </el-popover>
             </div>
-          </div>
+          </div> -->
         </div>
       </div>
     </template>
@@ -169,6 +204,7 @@
     <!-- 选择指标 -->
     <selectTargetValueDia
       :isShow.sync="isSelectTargetValueDialog"
+      :info="insertTargetValueInfo"
       @insert="insertSelectData"
       ref="selectTargetValueRef"
     />
@@ -187,6 +223,14 @@
       :info="insertCalculateInfo"
       @insert="insertCalculateData"
     />
+
+    <!-- 日期计算弹窗 -->
+    <calculateDateDia
+      ref="calculateDateDiaRef"
+      :isShow.sync="isInsertCalculateDate"
+      :info="insertCalculateDateInfo"
+      @insert="insertCalculateDateValue"
+    />
   </div>
 </template>
 <script>
@@ -206,7 +250,9 @@ import {
   findCellByFactor,
   splitString,
   toUpperCase,
-  findCellKeyByFactor
+  findCellKeyByFactor,
+  isNumberVal,
+  transDecimalPlace
 } from "../common/customTable";
 import * as sheetInterface from "@/api/modules/sheetApi.js";
 import { dataBaseInterface } from '@/api/api.js';
@@ -214,6 +260,8 @@ import md5 from '@/utils/md5.js';
 import selectTargetValueDia from './selectTargetValueDia.vue';
 import insertDateDia from './insertDateDia.vue';
 import calculateEdbDia from './calculateEdbDia.vue';
+import calculateDateDia from './calculateDateDia.vue';
+import toolBarSection from './toolBarSection.vue';
 import { formulaTip } from '@/views/dataEntry_manage/databaseComponents/util';
 export default {
   props: {
@@ -222,7 +270,13 @@ export default {
       default: false,
     }
   },
-  components: { selectTargetValueDia,insertDateDia,calculateEdbDia },
+  components: { 
+    selectTargetValueDia,
+    insertDateDia,
+    calculateEdbDia,
+    calculateDateDia,
+    toolBarSection
+  },
   computed: {
     //列头
     columnHeader() {
@@ -259,15 +313,14 @@ export default {
     return {
       config: {
         /* 单元格类型 
-          1手动日期格 DataTimeType 0
-          2指标格 
+          1手动日期格 DataTimeType 0 /系统日期导入格 DataTimeType 1  /指标日期导入格 DataTimeType 2
+          2指标格 //eta1.5.6又弃用了
           3自定义输入 
-          4插入值 表格里有关联的日期和指标格  //隐藏 又不要这个功能
+          4插入值 表格里有关联的日期和指标格  // eta1.1.6弃用
           5弹窗里的插入值 有关联日期格 
           6公式计算单元格 
-          1系统日期导入格 DataTimeType 1
-          1指标日期导入格 DataTimeType 2
           7指标计算的插入值单元格
+          8日期计算值单元格
         */
         data: [], 
         contextMenuOption: [],
@@ -281,7 +334,8 @@ export default {
 
       insertRelationArr: [], //表格单元格依赖关系数组
 
-      isSelectTargetValueDialog: false,
+      isSelectTargetValueDialog: false,//选择指标插入值弹窗
+      insertTargetValueInfo: {},//编辑 关联info
 
       cellrelationEdbInfo: {}, //指标浮窗信息
 
@@ -290,11 +344,7 @@ export default {
       calculateClickCell: null,//双击公式单元格时的单元格信息 用于之后选其他单元格拼接公式
 
       isInsertDateDialog: false,//导入日期弹窗
-      insertDateInfo: {
-        key: '',
-      },
-
-      calculateChainList: [],//公式链 key数组 后端需要
+      insertDateInfo: {},
 
       isInsertCalculate: false,//插入指标计算值
       insertCalculateInfo: {},//指标计算单元格info
@@ -303,6 +353,11 @@ export default {
       
       hasInit:false,
 
+      isInsertCalculateDate: false,//日期计算弹窗
+      insertCalculateDateInfo: {},//日期计算info
+
+      activeNames: []
+
     };
   },
   mounted() {
@@ -310,8 +365,10 @@ export default {
   },
   methods: {
 
-    /* 输入时实时搜索 满足日期格式不搜索 有=视为输入公式不搜索 */
+    /* 输入时实时搜索 满足日期格式不搜索 有=视为输入公式不搜索  eta1.5.6弃用了*/
     async searchTarget(query,cb) {
+      return cb([])
+      
       //又要过滤掉2020-05-这样的奇葩其他格式 不让检索
       let dateOtherRegex = /^(?:(?:19|20)\d\d)([-])(0[1-9]|1[0-2])(-?)$/
       if(!query
@@ -344,13 +401,6 @@ export default {
       
       setFocus(e);
 
-      /* 如果当前有公式单元格在编辑就拼接当前单元格进公式 */
-      // if(this.calculateClickCell && this.calculateClickCell.Uid!==cell.Uid) {
-      //   console.log(this.calculateClickCell)
-      //   const { cindex,rindex } = e.target.dataset;
-      //   this.calculateClickCell.Value += `${cindex}${rindex}`
-      // }
-
       //是插值单元格时寻找关联依赖的单元格 设置选框
       if([4,5,7].includes(cell.DataType)) {
         const { key } = e.target.dataset;
@@ -362,10 +412,13 @@ export default {
       }
 
       //选择指标弹窗打开时选择日期更新弹窗数据
-      this.isSelectTargetValueDialog&&this.$refs.selectTargetValueRef.chooseEdb(this.$refs.selectTargetValueRef.edbInfo)
+      this.isSelectTargetValueDialog&&this.$refs.selectTargetValueRef.changeRleationDate(this.selectCell)
 
       //计算指标弹窗打开时选择日期更新弹窗数据
-      this.isInsertCalculate&&this.$refs.calculateEdbDiaRef.showResult&&this.$refs.calculateEdbDiaRef.calculateHandle()
+      this.isInsertCalculate&&this.$refs.calculateEdbDiaRef.changeRleationDate(this.selectCell)
+
+      //日期计算弹窗打开选中日期框时且有选中item时更新选中值
+      cell.DataType===1&&this.isInsertCalculateDate&&this.$refs.calculateDateDiaRef.selectIndex&&this.$refs.calculateDateDiaRef.setSelectItemValue(this.selectCell)
     },
 
     /* 插入值 往左往上寻找同行同列是否有符合条件的一指标一日期 */
@@ -389,17 +442,6 @@ export default {
       const res = await sheetInterface.insertData({EdbInfoId,Date})
       if(res.Ret !==200) return
 
-      //日期无值也要建立关联关系
-      // if(!res.Data&&!DataTimeType){
-      //   this.selectCell.DataType = 3;
-      //   this.selectCell.DataTimeType = 0;
-      //   this.selectCell.ShowValue = '';
-      //   this.selectCell.Value = '';
-      //   this.selectCell.DataTime = '';
-      //   this.selectCell.EdbInfoId = 0;
-      //   this.$message.warning('所选指标的所选日期无值')
-      //   return
-      // }
 
       res.Data ? this.$message.success('插入成功') : this.$message.warning('当前日期暂无值') 
 
@@ -507,7 +549,6 @@ export default {
       // 是日期格式 DataType为1
       // 自定义内容 DataType 3
       //有=号为输入公式 DataType 6
-
       const {value} = e.target;
       if(!value){ //无值重置单元格
         cell.DataType = 3;
@@ -526,6 +567,7 @@ export default {
           cell.DataType = 1;
           cell.Extra='';
           cell.ShowValue = dateFormat;
+          cell.DataTime = dateFormat;
           cell.Value = dateFormat;
         }else if(value.startsWith('=')) { //公式单元格
           cell.DataType = 6;
@@ -546,6 +588,12 @@ export default {
         }
       }
 
+      /* 不是数字类型,清除原来设置的格式 */
+      if(!isNumberVal(value)){
+        cell.ShowStyle = '';
+        cell.ShowStyle = '';
+      } ;
+
       //判断是否是有插入值的依赖单元格 更新值或重置关系
       this.checkCellRelation(cell)
     },
@@ -563,44 +611,49 @@ export default {
 
       //去处理每一组关联的情况
       haveRelationArr.forEach( async(relation) => {
-        const { relation_date,relation_edb } = relation;
+        const { relation_date,relation_edb,type } = relation;
   
         if((relation_date.key === key && cell.DataType === 1) || (relation_edb.key === key && cell.DataType === 2)) { //单元格类型不变只变值仍有关联关系 更新值
-  
-          //刷新插入值结果
-          let params = null;
-          if(relation_date.key === key && cell.DataType === 1) { //修改的是依赖日期格
-            let { EdbInfoId } = findCellByKey(this.config.data,relation.key)
-            params = {
-              EdbInfoId,
-              Date: cell.ShowValue
+
+          //类型4的表格插值才调接口刷数据 之后关联的有其他类型插值 区分一下
+          if(type === 4) {
+
+            //刷新插入值结果
+            let params = null;
+            if(relation_date.key === key && cell.DataType === 1) { //修改的是依赖日期格
+              let { EdbInfoId } = findCellByKey(this.config.data,relation.key)
+              params = {
+                EdbInfoId,
+                Date: cell.ShowValue
+              }
+    
+            } else if( relation_edb.key === key && cell.DataType === 2) { //修改的依赖指标格
+              let {ShowValue} = findCellByKey(this.config.data,relation_date.key)
+              params = {
+                EdbInfoId: cell.EdbInfoId,
+                Date: ShowValue
+              }
             }
+    
+            const res = await sheetInterface.insertData(params)
+            if(res.Ret !==200) return
   
-          } else if( relation_edb.key === key && cell.DataType === 2) { //修改的依赖指标格
-            let {ShowValue} = findCellByKey(this.config.data,relation_date.key)
-            params = {
-              EdbInfoId: cell.EdbInfoId,
-              Date: ShowValue
-            }
+            //现在日期无值也不清除关系了
+            // !res.Data && this.updateInsertCell(relation.key);
+            
+            this.config.data.forEach(row => {
+              row.forEach(cell => {
+                if(cell.Uid === relation.key) {
+                    cell.DataType = relation.type;
+                    cell.ShowValue = res.Data;
+                    cell.Value = res.Data;
+                    cell.EdbInfoId = params.EdbInfoId;
+                    cell.DataTime = params.Date;
+                }
+              })
+            })
           }
   
-          const res = await sheetInterface.insertData(params)
-          if(res.Ret !==200) return
-
-          //现在日期无值也不清除关系了
-          // !res.Data && this.updateInsertCell(relation.key);
-          
-          this.config.data.forEach(row => {
-            row.forEach(cell => {
-              if(cell.Uid === relation.key) {
-                  cell.DataType = relation.type;
-                  cell.ShowValue = res.Data;
-                  cell.Value = res.Data;
-                  cell.EdbInfoId = params.EdbInfoId;
-                  cell.DataTime = params.Date;
-              }
-            })
-          })
   
         }else {
           // 清除插入值单元格式和关联关系
@@ -620,6 +673,7 @@ export default {
             cell.DataTime = '';
             cell.ShowValue = '';
             cell.Value = '';
+            cell.ShowStyle = ''
           }
         })
       })
@@ -684,7 +738,7 @@ export default {
         pos = 'cell'
       }
       this.config.contextMenuOption = pos === 'cell' 
-        ? getRightClickMenu(pos,(cell.DataType===1&&[1,2].includes(cell.DataTimeType))||cell.DataType===7)
+        ? getRightClickMenu(pos,(cell.DataType===1&&[1,2].includes(cell.DataTimeType))||[5,7,8].includes(cell.DataType))
         : getRightClickMenu(pos)
 
       this.$nextTick(() => {
@@ -715,9 +769,12 @@ export default {
     /* 右键事件 */
     async handleContext(key) {
 
+      //可右键编辑的单元格类型
       let editHandlesMap = {
         1: this.insertDateOpen,
-        7: this.edbCalculateInsertOpen
+        5: this.selectTargetOpen,
+        7: this.edbCalculateInsertOpen,
+        8: this.insertDateCalculateOpen
       }
 
       const keyMap = {
@@ -728,8 +785,9 @@ export default {
         'insert-row-down': this.insertRow,//向下插入行
         'insert-value': this.insertValue,//插入值
         'choose-target': this.selectTargetOpen,//选择指标插入值
-        'insert-sys-date': this.insertDateOpen,//导入系统日期
-        'insert-edb-date': this.insertDateOpen,//导入指标日期
+        'insert-date': this.insertDateOpen,//导入系统日期
+        // 'insert-edb-date': this.insertDateOpen,//导入指标日期
+        'insert-date-calculate': this.insertDateCalculateOpen,//日期计算弹窗
         'reset': this.clearCell, //清空
         'cell-edit': this.selectCell ? editHandlesMap[this.selectCell.DataType] : null
       }
@@ -740,38 +798,49 @@ export default {
 
     /* 打开选择指标弹窗  
     打开弹窗后仍可以在页面上点击 多存一个选择指标时的当前单元格信息 */
-    selectTargetOpen() {
+    selectTargetOpen(type) {
       this.insertTargetCell = this.selectCell;
       resetDialogCellStyle();
       setRelationStyle({ key:this.insertTargetCell.Uid },'td-choose-insert-target')
+      if(type === 'cell-edit') {
+        this.insertTargetValueInfo = {
+          ...this.insertTargetCell
+        }
+      }else {
+        this.insertTargetValueInfo = {}
+      }
       this.isSelectTargetValueDialog = true;
 
-      this.isInsertCalculate = false;
-      this.$refs.calculateEdbDiaRef.initData();
+      this.resetDialogStatus('insertEdbVal')
     },
 
     /* 插入选择指标的值 */
-    insertSelectData({ edbId,value,date }) {
+    insertSelectData({ edbId,value,relationDate,relationUid,str }) {
 
       this.insertTargetCell.DataType = 5;
       this.insertTargetCell.ShowValue = value;
-      this.insertTargetCell.Value = value;
+      this.insertTargetCell.Value = str;
       this.insertTargetCell.EdbInfoId = edbId;
-      this.insertTargetCell.DataTime = date;
+      this.insertTargetCell.DataTime = relationDate;
+      this.insertTargetCell.ShowFormatValue = this.insertTargetCell.ShowStyle ? transDecimalPlace(value,JSON.parse(this.insertTargetCell.ShowStyle)) : '';
 
-      this.$message.success('插入成功')
+      value ? this.$message.success('插入成功') : this.$message.warning('该日期当前无值')
 
       //如果有关联表格日期就建立新的关联关系
-      if(date) {
+      if(relationDate&&relationUid) {
         let relation = {
           insert_cell: {
             key: this.insertTargetCell.Uid,
-            relation_date: this.selectCell.Uid,
+            relation_date: relationUid,
             relation_edb: '',
           }
         }
   
         this.setRelation(relation,5);
+      }else { //重新插值后之后原来有关联的清除关系
+        let haveIndex = this.insertRelationArr.findIndex(_ => _.key===this.insertTargetCell.Uid);
+        haveIndex!==-1 && this.insertRelationArr.splice(haveIndex,1)
+        resetRelationStyle();
       }
 
     },
@@ -786,6 +855,8 @@ export default {
       this.selectCell.DataTime = '';
       this.selectCell.DataTimeType = 0;
       this.selectCell.EdbInfoId = 0;
+      this.selectCell.ShowStyle = '';
+      this.selectCell.ShowFormatValue = '';
 
       this.checkCellRelation(this.selectCell)
     },
@@ -898,22 +969,32 @@ export default {
       resetDialogCellStyle();
 
       if(type === 'cell-edit') { //编辑日期
-        const { DataTimeType } = this.insertTargetCell;
         this.insertDateInfo = {
-          key: DataTimeType===1? 'insert-sys-date' : 'insert-edb-date',
           ...this.insertTargetCell
         }
       }else {
         this.insertDateInfo = {
-          key:type
+          // key:type
         }
       }
       this.isInsertDateDialog = true;
+      this.resetDialogStatus();
+    },
 
-      this.isSelectTargetValueDialog = false;
-      this.$refs.selectTargetValueRef.initData();
-      this.isInsertCalculate = false;
-      this.$refs.calculateEdbDiaRef.initData();
+    /* 弹窗都是无遮罩的 弹一个就重置其他的 */
+    resetDialogStatus(type='init') {
+      if(type!=='insertEdbVal') {
+        this.$refs.selectTargetValueRef&&this.$refs.selectTargetValueRef.initData();
+        this.isSelectTargetValueDialog = false;
+      }
+      if(type!=='insertEdbCalculateVal') {
+        this.$refs.calculateEdbDiaRef&&this.$refs.calculateEdbDiaRef.initData();
+        this.isInsertCalculate = false;
+      }
+      if(type!=='insertDateCalculateVal') {
+        this.$refs.calculateDateDiaRef&&this.$refs.calculateDateDiaRef.initData();
+        this.isInsertCalculateDate = false;
+      }
     },
 
     /* 插入系统/指标日期 */
@@ -942,7 +1023,7 @@ export default {
 
         this.insertCalculateInfo = {
           ...menuInfo,
-          formStr: Value,
+          ...this.insertTargetCell
         }
       }else {
         this.insertCalculateInfo = {
@@ -951,36 +1032,70 @@ export default {
       }
       this.isInsertCalculate = true;
 
-      this.isSelectTargetValueDialog = false;
-      this.$refs.selectTargetValueRef.initData();
+      this.resetDialogStatus('insertEdbCalculateVal')
     },
 
     /* 导入指标计算值 */
     insertCalculateData(item) {
-      console.log(item)
-      const { InsertValue,EdbInfoId,Str,Date } = item;
+      // console.log(item)
+      const { InsertValue,EdbInfoId,Str,relationDate,relationUid } = item;
       this.insertTargetCell.DataType = 7;
       this.insertTargetCell.ShowValue = InsertValue;
       this.insertTargetCell.Value = Str;
       this.insertTargetCell.EdbInfoId = EdbInfoId;
-      this.insertTargetCell.DataTime = Date;
+      this.insertTargetCell.DataTime = relationDate;
+      this.insertTargetCell.ShowFormatValue = this.insertTargetCell.ShowStyle ? transDecimalPlace(InsertValue,JSON.parse(this.insertTargetCell.ShowStyle)) : '';
 
-      this.$message.success('插入成功')
+      InsertValue ? this.$message.success('插入成功') : this.$message.warning('该日期当前无值')
 
       //如果有关联表格日期就建立新的关联关系
-      if(Date) {
+      if(relationDate&&relationUid) {
         let relation = {
           insert_cell: {
             key: this.insertTargetCell.Uid,
-            relation_date: this.selectCell.Uid,
+            relation_date: relationUid,
             relation_edb: '',
           }
         }
   
         this.setRelation(relation,7);
+      }else { //重新插值后之后原来有关联的清除关系
+        let haveIndex = this.insertRelationArr.findIndex(_ => _.key===this.insertTargetCell.Uid);
+        haveIndex!==-1 && this.insertRelationArr.splice(haveIndex,1)
+        resetRelationStyle();
       }
     },
 
+    /* 日期计算弹窗 */
+    insertDateCalculateOpen(type) {
+      this.insertTargetCell = this.selectCell;
+      resetDialogCellStyle()
+      setRelationStyle({ key:this.insertTargetCell.Uid },'td-choose-insert-target')
+
+      if(type === 'cell-edit') { //编辑
+        this.insertCalculateDateInfo = {
+          ...this.insertTargetCell
+        }
+      }else {
+        this.insertCalculateDateInfo = {}
+      }
+      this.isInsertCalculateDate = true;
+      this.resetDialogStatus('insertDateCalculateVal');
+    },
+
+    /* 插入日期计算值 */
+    insertCalculateDateValue(data) {
+      const { insertValue,str } = data;
+      this.insertTargetCell.DataType = 8;
+      this.insertTargetCell.ShowValue = insertValue;
+      this.insertTargetCell.Value = str;
+      this.insertTargetCell.EdbInfoId = 0;
+      this.insertTargetCell.DataTime = '';
+      this.insertTargetCell.ShowFormatValue = this.insertTargetCell.ShowStyle ? transDecimalPlace(insertValue,JSON.parse(this.insertTargetCell.ShowStyle)) : '';
+
+      this.$message.success('插入成功')
+    },
+
     /* 初始化8行5列 */
     initData(initData=null) {
       console.log('initData');
@@ -994,6 +1109,8 @@ export default {
         this.config.data = new Array(8).fill("").map((_,_rindex) => {
           return new Array(5).fill("").map((cell,_cindex) => ({
             ShowValue: "",
+            ShowStyle: '',
+            ShowFormatValue: '',
             Value: "",
             DataType: 3,
             DataTimeType: 0,
@@ -1036,10 +1153,14 @@ export default {
         cell.Value = this.copyCellItem.Value;
         cell.DataTime = this.copyCellItem.DataTime;
         cell.EdbInfoId = this.copyCellItem.EdbInfoId;
+        cell.ShowStyle = this.copyCellItem.ShowStyle;
+        cell.ShowFormatValue = this.copyCellItem.ShowFormatValue;
       }else {
         cell.DataType = 3;
         cell.ShowValue = this.copyCellItem.ShowValue;
         cell.Value = this.copyCellItem.ShowValue;
+        cell.ShowStyle = this.copyCellItem.ShowStyle;
+        cell.ShowFormatValue = this.copyCellItem.ShowFormatValue;
         cell.DataTime = '';
         cell.EdbInfoId = 0;
       }
@@ -1048,26 +1169,24 @@ export default {
       e.preventDefault();
     },
 
-    /* 单元格enter时切换编辑状态 */
+    /* 单元格enter失焦 */
     keyEnterHandle(e,cell) {
       if(e.keyCode===13) {
         //非得搞个要回车失焦
         e.target.nodeName && e.target.blur();
         this.$refs[`inputRef${e.target.dataset.key}`]&&this.$refs[`inputRef${e.target.dataset.key}`][0].close()
 
-        cell.DataType===6 && this.$set(cell,'CanEdit',false)
-        // this.calculateClickCell = null
+        // cell.DataType===6 && this.$set(cell,'CanEdit',false)
+        // this.$set(cell,'CanEdit',false)
       }
     },
 
-    /* 支持公式单元格双击切换状态 */
+    /* 双击切换状态 插值单元格不允许切换 可切换类型1,2,3,6*/
     dblClickCellHandle(e,cell) {
-      if(this.disabled || cell.DataType!==6) return
+      if(this.disabled || ![1,2,3,6].includes(cell.DataType) || [1,2].includes(cell.DataTimeType)) return
 
       this.$set(cell,'CanEdit',true)
-
-      // this.calculateClickCell = cell;
-      // setRelationStyle({ key:cell.Uid },'td-choose-insert-target')
+      console.log(cell)
 
       this.$nextTick(() => {
         if(e.target.childNodes[0].childNodes[0].childNodes[1].nodeName==='INPUT') e.target.childNodes[0].childNodes[0].childNodes[1].focus();
@@ -1091,6 +1210,13 @@ export default {
       if(e.keyCode === 9) {
         e.preventDefault();
       }
+    },
+
+    /* 改变单元格显示文本 */
+    updateCellStyle({ShowStyle,ShowFormatValue}) {
+      
+      this.$set(this.selectCell,'ShowStyle',ShowStyle)
+      this.$set(this.selectCell,'ShowFormatValue',ShowFormatValue)
     }
   },
 };
@@ -1232,6 +1358,9 @@ export default {
     left: -9999px;
     background: #fff;
     padding: 10px 0;
+    min-width: 180px;
+    max-height: 400px;
+    overflow-y: auto;
     /* border: 1px solid #999; */
     box-shadow: 0 1px 4px #999;
     .item {
@@ -1246,15 +1375,21 @@ export default {
     }
 
     .subMenu-wrapper {
-      display: none;
+      width: 180px;
+      /* display: none; */
       padding: 10px 0;
-      box-shadow: 0 1px 4px #999;
-      background: #fff;
-      position: absolute;
-      right: -172px;
+      /* box-shadow: 0 1px 4px #999; */
+      /* background: #fff; */
+      /* position: absolute;
+      right: -178px;
       top:-205px;
       max-height: 400px;
-      overflow-y: auto;
+      overflow-y: auto; */
+      .item {
+        &:hover {
+          background: #fff;
+        }
+      }
     }
   }
 }
@@ -1286,4 +1421,21 @@ export default {
     }
   }
 }
+.el-collapse {
+  border: none !important;
+  .el-collapse-item__header {
+    padding: 0;
+    height: auto;
+    line-height: normal;
+    margin-bottom: 0 !important;
+    background: transparent !important;
+  }
+  .el-collapse-item__wrap {
+    background: transparent !important;
+    border: none !important;
+  }
+  .el-collapse-item__content {
+    padding: 0 !important;
+  }
+}
 </style>

+ 14 - 2
src/views/datasheet_manage/components/SheetExcel.vue

@@ -54,12 +54,13 @@ export default {
     },
 
     copyData() {
-      let rangeArr = luckysheet.getRangeArray('twoDimensional');
+      let rangeArr = luckysheet.getRangeValue();
+      console.log(rangeArr)
       let str = ''
       rangeArr.forEach((item,r_index) => {
         let row = ''
         item.forEach((cell,index) => {
-          row+= `${index!==0?'\t':''}${cell||''}`
+          row+= `${index!==0?'\t':''}${cell?(cell.m||this.getCellContent(cell.ct.s)):''}`
         })
         str+= r_index===rangeArr.length-1 ? row : `${row}\n`
       });
@@ -67,6 +68,17 @@ export default {
       copyFit(str)
     },
 
+    // 单元格内的文字分段
+    getCellContent(arr) {
+      if(!arr||!arr.length) return ''
+      let cellStr = ''
+      arr.forEach(_ => {
+        cellStr+=_.v.replace(/\r/,'').replace(/\n/,'')
+      })
+
+      return cellStr;
+    },
+
     updateEmit(){
       this.$emit("updated")
     }

+ 288 - 0
src/views/datasheet_manage/components/calculateDateDia.vue

@@ -0,0 +1,288 @@
+<template>
+<div v-dialogDrag v-if="isShow" >
+	<div class="calculate-date-dialog el-dialog" >
+		<div class="header el-dialog__header">
+			<span>日期计算</span>
+			<i class="el-icon-close" @click="cancelHandle"/>
+		</div>
+		<div class="dialog-main">
+			<ul class="add-cont">
+				<li class="add-li" v-for="(list, index) in addList" :key="index">
+					<span class="li-tag">{{ list.Tag }}</span>
+          <el-input
+						v-model="list.Date"
+						placeholder="选择日期"
+						style="width: 240px"
+						readonly
+						@focus="selectIndex=index+1"
+						@keyup.native="e => { e.keyCode===13 && initSelect}" 
+						:class="{'select': selectIndex===index+1}"
+					/>
+					
+					<i
+						class="el-icon-error del-tag"
+						v-if="index > 1"
+						@click="addList.splice(index,1)"
+					/>
+				</li>
+			</ul>
+			<div class="add-icon" @click="addTargetHandle">
+				<i
+					class="el-icon-circle-plus-outline"
+					style="color: #5882ef; font-size: 16px"
+				/>
+				添加更多日期
+			</div>
+			<div class="computed-min">
+				<div class="computed-section">
+					<label class="label">计算公式</label>
+					<el-input placeholder="请输入公式" v-model="formula" clearable @focus="initSelect">
+					</el-input>
+				</div>	
+        <div class="example-txt">公式示例:A-B 以数字形式返回日期A和日期B的天数差</div>
+			</div>
+		</div>
+		<div class="dia-bot">
+			<el-button
+				type="primary"
+				style="margin-right: 20px"
+				@click="saveHandle"
+				>确定</el-button
+			>
+			<el-button type="primary" plain @click="cancelHandle">取消</el-button>
+		</div>
+	</div>
+</div>
+</template>
+
+<script>
+import * as sheetInterface from "@/api/modules/sheetApi.js";
+import { resetDialogCellStyle,findCellByKey } from "../common/customTable";
+const tag_arr = [];
+for(let i=0;i<26;i++) tag_arr.push(String.fromCharCode(65+i));
+export default {
+	name: '',
+	props: {
+		isShow: {
+			type: Boolean,
+		},
+		info: {
+			type: Object,
+		}
+	},
+	watch: {
+		isShow(newval) {
+			if(!newval) return
+
+			/* 回显 */
+			if(this.info.Value) {
+				let valueObj = JSON.parse(this.info.Value);
+
+				this.formula = valueObj.Formula;
+				//日期有动态日期更新的问题 需要每次找单元格信息重新赋值最新的日期
+				this.addList = valueObj.RelationCellList.map(_ => ({
+					..._,
+					Date: findCellByKey(this.$parent.config.data,_.Uid).ShowValue
+				}));
+			}
+			
+		},
+	},
+	data() {
+		return {
+			selectIndex: 1,//默认选中第一个框
+			addList: [
+				{
+					Tag: tag_arr[0],
+					Uid: '', //关联表格中日期格子的uid
+					Date: '',
+				},
+				{
+					Tag: tag_arr[1],
+					Uid: '',
+					Date: '',
+				},
+			],
+			formula: '', //计算公式
+
+		};
+	},
+	methods: {
+		/* 添加额外的指标列 */
+		addTargetHandle() {
+			if(this.addList.length >= 26) return this.$message.warning('添加指标个数已达上限')
+			let tag = this.addList[this.addList.length-1].Tag;
+			let index = tag_arr.findIndex(item => item === tag);
+			const item = {
+				Tag: tag_arr[index+1],
+				Uid: '',
+				Date: ''
+			};
+			this.addList.push(item);
+		},
+
+		/* 选择日期时更新选中item的值 */
+		setSelectItemValue(cell) {
+			let item = this.addList[this.selectIndex-1];
+
+			this.$set(this.addList,this.selectIndex-1,{
+				...item,
+				Uid: cell.Uid,
+				Date: cell.ShowValue
+			})
+		},
+
+		async saveHandle() {
+			if (!this.formula) return this.$message.warning('计算公式不能为空');
+
+			let dateList = this.addList.filter(_ => _.Date&&_.Uid);
+			const res = await sheetInterface.getDateCalculate({
+				Formula: this.formula,
+				DateList: dateList
+			})
+			if(res.Ret !== 200) return
+
+			let backData = {
+				insertValue: res.Data.ShowValue,
+        str: JSON.stringify({
+					Formula: this.formula,
+					RelationCellList: dateList
+				})
+			}
+
+			this.$emit('insert',backData)
+			this.cancelHandle()
+		},
+
+		initSelect() {
+			this.selectIndex = 0;
+		},
+
+		initData() {
+			this.selectIndex = 1;
+			this.addList = [
+				{
+					Tag: tag_arr[0],
+					Uid: '',
+					Date: '',
+				},
+				{
+					Tag: tag_arr[1],
+					Uid: '',
+					Date: '',
+				},
+			];
+			this.formula = '';
+
+		},
+		cancelHandle() {
+			this.initData();
+			this.$emit('update:isShow',false);
+			resetDialogCellStyle()
+		},
+	},
+	mounted() {},
+};
+</script>
+<style lang="scss" scoped>
+@import "~@/styles/theme-vars.scss";
+.calculate-date-dialog {
+	width:750px;
+	background: #fff;
+  position: fixed;
+  top: 20%;
+  left: 50%;
+  border-radius: 2px;
+  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
+  z-index: 9999;
+	overflow: hidden;
+	div::-webkit-scrollbar {
+		width: 6px !important;
+	}
+	.header { 
+    font-size: 16px;
+    background: $theme-color;
+    color: #fff;
+    padding: 15px;
+    display: flex;
+    align-content: center;
+    justify-content: space-between;
+    .el-icon-close {
+      font-size: 20px;
+      cursor: pointer;
+    }
+  }
+	.dialog-main {
+		padding: 25px 42px 25px 25px;
+		
+		@media screen and (max-height:850px){
+			box-sizing: border-box;
+			height: 65vh;
+			overflow-y: auto;
+		}
+		.el-cascader .el-input {
+			width: 340px;
+		}
+		.add-cont {
+			display: flex;
+			flex-wrap: wrap;
+			justify-content: space-between;
+			max-height: 300px;
+			overflow: hidden;
+			overflow-y: auto;
+			padding-right: 40px;
+			.add-li {
+				position: relative;
+				margin-bottom: 48px;
+				.li-tag {
+					font-size: 16px;
+					margin-right: 8px;
+				}
+				.del-tag {
+					position: absolute;
+					right: -30px;
+					top: 12px;
+					font-size: 16px;
+					cursor: pointer;
+				}
+			}
+		}
+		.add-icon {
+			margin:10px 0;
+			font-size: 16px;
+			color: #5882ef;
+			cursor: pointer;
+		}
+		.computed-min {
+			margin: 50px 0;
+			padding-bottom: 40px;
+			border-bottom: 1px dashed #aab4cc;
+			.computed-section {
+				display: flex;
+				margin-top: 20px;
+			}
+			.label {
+				padding:10px 10px 10px 0;
+			}
+			.example-txt {
+				margin-top: 10px;
+				padding-left: 60px;
+				color: #999;
+			}
+		}
+	}
+	.dia-bot {
+		padding-bottom: 40px;
+		display: flex;
+		justify-content: center;
+	}
+}
+</style>
+<style lang="scss">
+  .calculate-date-dialog {
+    .select .el-input__inner {
+      border: 2px dashed #18ad18;
+      border-radius: 4px;
+    }
+  }
+</style>

+ 133 - 64
src/views/datasheet_manage/components/calculateEdbDia.vue

@@ -13,7 +13,7 @@
           <template v-if="info.fromEdbKey===5">
             <el-radio-group 
               v-model="formData.source"
-              @change="changeSource"
+              @change="()=>{ $refs.selectRef.targetTypeChange();changeSource() }"
             >
               <el-radio :label="1">累计值转月</el-radio>
               <el-radio :label="2">累计值转季值</el-radio>
@@ -23,7 +23,7 @@
           <template v-else-if="info.fromEdbKey===62"> 
             <el-radio-group 
               v-model="formData.source"
-              @change="changeSource"
+              @change="()=>{ $refs.selectRef.targetTypeChange(); changeSource() }"
             >
               <el-radio :label="13">累计值</el-radio>
               <el-radio :label="14">年初至今累计值</el-radio>
@@ -46,7 +46,7 @@
                 v-for="(item,index) in edbArrFromTable" 
                 :key="index"
                 @click="selectTableEdbHandle(item)"
-              >{{ item.ShowValue }}</el-tag>
+              >{{ item.EdbName }}</el-tag>
           </div>
         </section>
         
@@ -70,7 +70,6 @@
 								style="width: 100px"
 								placeholder=""
 								size="mini"
-								@change="changeParams"
 							>
 								<el-option
 									v-for="item in moveTypeOpions"
@@ -87,14 +86,12 @@
 								size="mini"
 								v-model="formData.moveVal"
 								@keyup.native="filterCode(formData)"
-                @change="changeParams"
 							></el-input>
 							<el-select
 								v-model="formData.moveUnit"
 								size="mini"
 								placeholder=""
 								style="width: 100px"
-                @change="changeParams"
 							>
 								<el-option
 									v-for="item in fre_options"
@@ -112,7 +109,6 @@
 								style="width: 200px"
 								placeholder="请输入N数值"
 								type="number"
-								@change="changeParams"
 							/>
 						</el-form-item>
 
@@ -121,7 +117,6 @@
 								v-model="formData.calendarType"
 								placeholder="请选择日历"
 								style="width: 200px"
-								@change="changeParams"
 							>
 								<el-option
 									v-for="item in calendarOptions"
@@ -139,7 +134,6 @@
 								placeholder="请选择频度"
 								style="width: 200px"
 								clearable
-                @change="changeParams"
 							>
 								<el-option
 									v-for="item in frequencyArr"
@@ -156,7 +150,6 @@
 								v-model="formData.valueType"
 								placeholder="请选择数据取值类型"
 								style="width: 200px"
-                @change="changeParams"
 							>
 								<el-option key="期末值" label="期末值" value="期末值"/>
 								<el-option key="平均值" label="平均值" value="平均值"/>
@@ -168,14 +161,42 @@
                 v-model="formData.alphaValue" 
                 placeholder="请选择alpha值"
                 style="width: 200px"
-                @change="changeParams"
               />
 						</el-form-item>
 					</el-form>
         </section>
 
+        <section>
+          <!-- 依赖日期选择方式 -->
+          <ul class="date-select-cont">
+            <li class="flex">
+              <div class="flex">
+                <el-radio v-model="dateSelectForm.Type" :label="1">指标最新日期</el-radio>
+                <div>
+                  <label class="el-form-item__label">期数前移</label>
+                  <el-input
+                    v-model="dateSelectForm.MoveForward"
+                    type="number"
+                    :min="0"
+                    style="margin-right:10px;width:80px"
+                    @change="e => {dateSelectForm.MoveForward=Number(e);}"
+                  />期
+                </div>
+              </div>
+              <div class="flex">
+                <el-radio v-model="dateSelectForm.Type" :label="2" style="margin-left:50px">表格日期</el-radio>
+                <span v-if="dateSelectForm.relationDate&&dateSelectForm.Type===2">{{dateSelectForm.relationDate}}</span>
+
+              </div>
+            </li>
+            <li>
+              <dateMoveWaySec ref="dateMoveWayRef"/>
+            </li>
+          </ul>
+        </section>
+
         <!-- 计算结果 -->
-        <section class="result-section" v-if="showResult">
+        <!-- <section class="result-section" v-if="showResult">
           <label>计算结果:</label>
           <ul class="data-cont" v-if="calculateShowData.length">
               <li 
@@ -189,11 +210,10 @@
           </ul>
 
           <tableNoData text="无对应的数据" size="mini" v-else/>
-        </section>
+        </section> -->
 
         <section class="bot">
-          <el-button type="primary" @click="insertData" v-if="showResult">插入值</el-button>
-          <el-button type="primary" @click="calculateHandle" v-else>计算</el-button>
+          <el-button type="primary" @click="calculateHandle">插入值</el-button>
           <el-button type="primary" plain @click="cancelHandle">取消</el-button>
 
         </section>
@@ -207,9 +227,10 @@
 import { dataBaseInterface } from '@/api/api.js';
 import * as sheetInterface from "@/api/modules/sheetApi.js";
 import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
-import { resetDialogCellStyle } from "../common/customTable";
+import { resetDialogCellStyle,findCellByKey } from "../common/customTable";
 import selectTarget from '@/views/chartRelevance_manage/components/selectTarget.vue';
 import edbDetailSection from './edbDetailSection.vue';
+import dateMoveWaySec from './dateMoveWaySection.vue'
 import { formRules } from '@/views/dataEntry_manage/databaseComponents/util';
 export default {
   props: {
@@ -220,30 +241,17 @@ export default {
       type: Object
     }
   },
-  components: { selectTarget,edbDetailSection },
-  computed: {
-    edbArrFromTable() {
-      let arr = this.$parent.config.data.flat().filter(_ =>_.DataType === 2);
-      let filterArr =  []
-      
-      arr.forEach(item => {
-        if(filterArr.findIndex(_ => _.EdbInfoId===item.EdbInfoId)===-1) {
-          filterArr.push(item)
-        }
-      })
-      
-       return filterArr
-    }
-  },
+  components: { selectTarget,edbDetailSection,dateMoveWaySec },
   watch: {
     isShow(nval) {
       if(!nval) return
-      console.log(this.info)
-      const { source,formStr } = this.info;
+      
+      this.getTableEdbList()
+      const { source } = this.info;
 
       this.formData.source = source;
       //回显
-      if(formStr) {
+      if(this.info.Value) {
         const {
           Source,
           Frequency,
@@ -251,8 +259,11 @@ export default {
           EdbInfoId,
           MoveFrequency,
           MoveType, 
-          Calendar 
-        } = JSON.parse(formStr);
+          Calendar,
+          DataTime,
+          MoveForward,
+          DateChange
+        } = JSON.parse(this.info.Value);
 
         this.formData = {
           source: Source,
@@ -265,7 +276,18 @@ export default {
           valueType: Formula,
           alphaValue: Formula,
         }
+
+        this.dateSelectForm = {
+          Type: DataTime ? 2 : 1,
+          MoveForward: MoveForward || 0,
+          relationUid: this.info.DataTime ? this.getRelationCellKey() : '',
+          relationDate: this.info.DataTime ? this.getNewCellDate() : '',//日期会动态更新 需要找关联单元格最新的数据
+        }
         this.selectTableEdbHandle({EdbInfoId})
+
+        this.$nextTick(() => {
+          DateChange&&this.$refs.dateMoveWayRef.initData(DateChange)
+        })
       }
     }
   },
@@ -286,6 +308,8 @@ export default {
       formRules,
       frequencyArr: ['日度', '周度','旬度', '月度', '季度', '年度'],
 
+      edbArrFromTable: [],
+
       showResult: false,
       calculateShowData: [], //计算全部数据
       chooseItem: {
@@ -311,12 +335,56 @@ export default {
 				{label: '公历',key: 1},
 				{label: '农历',key: 2},
 			],
+
+      dateSelectForm: {
+        Type:1,
+        MoveForward: 0,
+        relationDate: '',//关联的表格日期
+        relationUid: '',//关联格子的uid
+      }
     }
   },
   mounted(){
 
   },
   methods:{
+    /* 获取表格中关联的表格列表 单元格2 5 7*/
+    async getTableEdbList() {
+        let arr = this.$parent.config.data.flat().filter(_ =>[2,5,7].includes(_.DataType)).map(_ => _.EdbInfoId);
+        let filterArr =  Array.from(new Set(arr));
+
+        if(!filterArr.length) return
+
+        let res = await sheetInterface.getEdbBaseInfo({EdbInfoIds: filterArr.join(',')})
+        if(res.Ret !==200) return
+
+        this.edbArrFromTable = res.Data.List;
+    },
+
+    // 在选择表格中日期的话在弹窗中显示所选日期 关联uid
+    changeRleationDate(cell) {
+      this.dateSelectForm.relationDate=cell.DataType===1 ? cell.ShowValue : '';
+      this.dateSelectForm.relationUid=this.dateSelectForm.relationDate ? cell.Uid : '';
+    },
+
+    /* 找日期关联的key 本来想存在单元格内部后端不想动原来结构 还是自己根据关联关系找吧 */
+    getRelationCellKey() {
+      let relationObj = this.$parent.insertRelationArr.find(_=> _.key === this.info.Uid)
+      if(!relationObj) return ''
+
+      return relationObj.relation_date.key
+    },
+
+    /* 先找关联日期的key  再根据key找单元格数据取到最新的日期 */
+    getNewCellDate() {
+      let relationKey = this.getRelationCellKey();
+      if(!relationKey) return '';
+
+      let relationDateCell = findCellByKey(this.$parent.config.data,relationKey)
+      
+      return relationDateCell.ShowValue
+    },
+
     /* 计算结果 */
     async calculateHandle() {
       await this.$refs.form.validate();
@@ -336,7 +404,10 @@ export default {
         'alpha': 'alphaValue'
       }
 
-      let DataTime = this.$parent.selectCell.DataType === 1 ? this.$parent.selectCell.ShowValue : ''
+      let DataTime = '';
+      if(this.dateSelectForm.Type===2) { //选框为表格日期再去取Date
+        DataTime = this.dateSelectForm.relationDate
+      }
 
       let params = {
         DataTime,
@@ -346,43 +417,29 @@ export default {
         EdbInfoId: this.selectEdbInfo.EdbInfoId,
         MoveFrequency: moveUnit,
         MoveType: moveType, 
-        Calendar: calendarType
+        Calendar: calendarType,
+        MoveForward: this.dateSelectForm.MoveForward,
+        DateChange: this.$refs.dateMoveWayRef.dateChangeArr,
       }
 
       const res = await sheetInterface.getMixedCalculateData(params)
       if(res.Ret!==200) return 
 
       this.showResult = true;
-      this.calculateShowData = res.Data.List || [];
-
-      // if(!this.calculateShowData.length && DataTime) return this.$message.warning('所选指标所选日期无值')
-
-      let InsertValue = this.calculateShowData.length 
-        ? (this.calculateShowData.find(_ => _.DataTime===DataTime) ? this.calculateShowData.find(_ => _.DataTime===DataTime).Value.toString() : this.calculateShowData[0].Value.toString()) 
-        : ''
-      this.chooseItem = {
-          Date:DataTime,
-          EdbInfoId: this.selectEdbInfo.EdbInfoId,
-          InsertValue,
-          Str: JSON.stringify(params)
-        }
       
-    },
-
-    /* 已计算过改参数重新计算 */
-    changeParams() {
-      this.showResult && this.calculateHandle()
-    },
-
-    /* 插入值 */
-    insertData() {
+      this.chooseItem = {
+        relationDate: DataTime,
+        relationUid: this.dateSelectForm.Type===2 ? this.dateSelectForm.relationUid : '',
+        EdbInfoId: this.selectEdbInfo.EdbInfoId,
+        InsertValue: res.Data.ShowValue||"",
+        Str: JSON.stringify(params)
+      }
 
-      // if(this.$parent.selectCell.DataType !== 1) return this.$message.warning('请在表格中选择日期')
-        
-      if(!this.calculateShowData.length) return this.$message.warning('该日期无数据')
+      // if(!this.calculateShowData.length) return this.$message.warning('该日期无数据')
       
       this.$emit('insert',this.chooseItem)
       this.cancelHandle();
+      
     },
 
     /* 选择指标 */
@@ -414,7 +471,7 @@ export default {
       const { EdbInfoId,EdbInfoType,EdbName,Frequency } = res.Data;
 
       if(this.formData.source===1&&Frequency!=='月度') return this.$message.warning('只能选择月度指标')
-      else if(this.formData.source===2&&Frequency!=='季度') return this.$message.warning('能选择季度指标')
+      else if(this.formData.source===2&&Frequency!=='季度') return this.$message.warning('能选择季度指标')
       else if(this.formData.source===8&&Frequency==='日度') return this.$message.warning('不能选择日度指标')
       else if(this.formData.source===14&&Frequency==='年度') return this.$message.warning('不能选择年度指标')
 
@@ -446,6 +503,8 @@ export default {
 				calendarType: '公历',
 				valueType: '期末值'
       }
+      this.dateSelectForm = {Type:1,MoveForward: 0,relationDate: '',relationUid: ''}
+      this.$refs.dateMoveWayRef&&this.$refs.dateMoveWayRef.initData();
     },
 
     cancelHandle() {
@@ -516,6 +575,16 @@ export default {
         }
       }
     }
+
+    .date-select-cont {
+      li {
+        margin: 20px 0;
+      }
+      .flex {
+        display: flex;
+        align-items: center;
+      }
+    }
   }
 }  
 </style>

+ 173 - 0
src/views/datasheet_manage/components/dateMoveWaySection.vue

@@ -0,0 +1,173 @@
+<template>
+  <div class="date-change-ways">
+    <div class="header date-item">
+      <label class="el-form-item__label">日期变换</label>
+                
+      <el-select v-model="dateChangeSelect" placeholder="请选择" style="width:110px">
+        <el-option label="日期位移" :value="1"/>
+        <el-option label="指定频率" :value="2"/>
+      </el-select>
+
+      <el-button type="text" style="margin: 0 10px;" @click="addDateChange">添加</el-button>
+    </div>
+    
+    <ul v-if="dateChangeArr.length" class="date-change-list">
+      <li v-for="(dateItem,index) in dateChangeArr" :key="dateItem.ChangeType" class="date-change-li">
+
+        <div v-if="dateItem.ChangeType===1" class="date-item">
+          <el-tag type="info" style="margin-right:15px">日期位移</el-tag>
+          <div>
+            <el-input
+              v-model="dateItem.Day"
+              type="number"
+              style="margin-right:10px;width:80px"
+              @change="e => {dateItem.Day=Number(e);}"
+            />天
+            <el-input
+              v-model="dateItem.Month"
+              type="number"
+              style="margin-right:10px;width:80px"
+              @change="e => {dateItem.Month=Number(e);}"
+            />月
+            <el-input
+              v-model="dateItem.Year"
+              type="number"
+              style="margin-right:10px;width:80px"
+              @change="e => {dateItem.Year=Number(e);}"
+            />年
+          </div>
+          <i class="el-icon-delete" @click="removeDateItem(index)"></i>
+        </div>
+
+        <div v-else-if="dateItem.ChangeType===2" class="date-item">
+          <el-tag type="info" style="margin-right:15px">指定频率</el-tag>
+          <el-select
+              style="max-width: 120px;"
+              v-model="dateItem.Frequency"
+              placeholder="请选择频度"
+              @change="dateItem.FrequencyDay=frequencyDaysOptions[0].name;"
+          >
+            <el-option
+                v-for="item in frequencyOptions"
+                :key="item.value"
+                :label="item.name"
+                :value="item.value"
+            />
+          </el-select>
+
+          <el-select
+              style="max-width: 120px;margin:0 10px"
+              v-model="dateItem.FrequencyDay"
+              placeholder="请选择"
+          >
+            <el-option
+                v-for="item in frequencyDaysOptions"
+                :key="item.name"
+                :label="item.name"
+                :value="item.name"
+            />
+          </el-select>
+
+          <i class="el-icon-delete" @click="removeDateItem(index)"></i>
+        </div>
+      </li>
+    </ul>
+  </div>
+</template>
+<script>
+export default {
+  computed: {
+    frequencyDaysOptions() {
+      let typeMap = {
+        '本周': [
+          { name: '周一' },
+          { name: '周二' },
+          { name: '周三' },
+          { name: '周四' },
+          { name: '周五' },
+          { name: '周六' },
+          { name: '周日' },
+        ]
+      }
+      
+      let obj = this.dateChangeArr.find(_ => _.ChangeType===2);
+      if(!obj) return []
+
+      return typeMap[obj.Frequency] 
+        ? typeMap[obj.Frequency] 
+        : [{name:'第一天'},{name:'最后一天'}]
+    }
+  },
+  data() {
+    return {
+      dateChangeSelect: 1,
+      dateChangeArr: [],
+
+      frequencyOptions: [
+        { name: '本周', value: '本周' },
+        { name: '本旬', value: '本旬' },
+        { name: '本月', value: '本月' },
+        { name: '本季', value: '本季' },
+        { name: '本半年', value: '本半年' },
+        { name: '本年', value: '本年' },
+      ],
+    }
+  },
+  methods:{
+    /* 提加日期变换数组 */
+    addDateChange() {
+      let haveObj = this.dateChangeArr.find(_ => _.ChangeType===this.dateChangeSelect);
+      if(haveObj) return this.$message.warning(this.dateChangeSelect===1?'已添加日期位移':'已添加指定频率')
+      let item = {
+        ChangeType: this.dateChangeSelect,
+        Day: 0,
+        Month: 0,
+        Year: 0,
+        Frequency: '本周',
+        FrequencyDay: '周一'
+      }
+
+      this.dateChangeArr.push(item)
+    },
+
+    /* 参数更新时刷数据 */
+    changeParams() {
+      this.$emit('updateData')
+    },
+
+    initData(data=null) {
+      if(data) {
+        this.dateChangeArr = data || [];
+      }else {
+        this.dateChangeSelect = 1;
+        this.dateChangeArr = []
+      }
+    },
+
+    removeDateItem(index) {
+      this.dateChangeArr.splice(index,1)
+    }
+  },
+}
+</script>
+<style scoped lang='scss'>
+.date-change-ways {
+  padding-left: 20px;
+  .date-change-list {
+    padding-left: 68px;
+  }
+  .date-change-li {
+    margin: 10px 0;
+  }
+  .date-item {
+    display: flex;
+    align-items: center;
+    .el-icon-delete {
+      color: #f00;
+      font-size: 16px;
+      margin:0 10px;
+      cursor: pointer;
+    }
+  }
+}
+</style>

+ 108 - 166
src/views/datasheet_manage/components/insertDateDia.vue

@@ -3,86 +3,21 @@
 		:visible.sync="isShow"
 		:close-on-click-modal="false"
 		:modal-append-to-body='false'
-    :title="titleMap[info.key]"
+    title="导入日期"
 		@close="cancelHandle"
 		custom-class="dialog"
 		center
-		width="560px"
+		width="650px"
 		v-dialogDrag>
 			<div class="dialog-main">
-          <!-- 导入系统日期 -->
-            <ul v-if="info.key==='insert-sys-date'">
-              <li class="form-item">
-                <label>导入方式</label>
-                <el-select
-                    v-model="formData.Source"
-                    placeholder="请选择导入方式"
-                    @change="init('form')"
-                >
-                  <el-option
-                      v-for="item in wayOptions"
-                      :key="item.value"
-                      :label="item.name"
-                      :value="item.value"
-                  />
-                </el-select>
 
-                <template v-if="formData.Source===3">
-                  <el-select
-                      style="max-width: 120px;margin:0 10px"
-                      v-model="formData.Frequency"
-                      placeholder="请选择频度"
-                      @change="formData.Day=frequencyDaysOptions[0].name"
-                  >
-                    <el-option
-                        v-for="item in frequencyOptions"
-                        :key="item.value"
-                        :label="item.name"
-                        :value="item.value"
-                    />
-                  </el-select>
-
-                  <el-select
-                      style="max-width: 120px;"
-                      v-model="formData.Day"
-                      placeholder="请选择"
-                  >
-                    <el-option
-                        v-for="item in frequencyDaysOptions"
-                        :key="item.name"
-                        :label="item.name"
-                        :value="item.name"
-                    />
-                  </el-select>
-                </template>
-
-                <el-tooltip effect="dark" style="margin-left:10px">
-                  <div
-                    slot="content"
-                    v-html="tips[info.key]"
-                    style="line-height: 20px;"
-                  ></div>
-                  <i class="el-icon-question" style="font-size:18px;"/>
-                </el-tooltip>
-              </li>
-              <template v-if="formData.Source===2">
-                <li class="form-item">
-                  <label>天数</label>
-                  <el-input
-                    v-model="formData.CalculateNum"
-                    type="number"
-                    style="margin-right:10px;width:200px"
-                    @change="e => {formData.CalculateNum=Number(e)}"
-                  />
-                  {{formData.CalculateFrequency}}
-                </li>
-                <li style="color:#999">示例:5,表示当前日期+5天的日期; -5,表示当前日期-5天的日期;</li>
-              </template>
-            </ul>
-
-          <!-- 导入指标日期 -->
-          <ul v-else> 
+          <ul>
             <li class="form-item">
+              <el-radio 
+                v-model="dateChangeSelect"
+                style="margin-right:12px"
+                :label="2"
+              >指标日期</el-radio>
 
               <selectTarget
                 :defaultId="search_edb"
@@ -90,29 +25,47 @@
                 ref="selectRef"
                 @select="e => { selectEdbInfo = e ||{} }"
                 :filter="false"
+                width="240px"
               />
-
-              <el-tooltip effect="dark" style="margin-left:10px">
-                <div
-                  slot="content"
-                  v-html="tips[info.key]"
-                  style="line-height: 20px;"
-                ></div>
-                <i class="el-icon-question" style="font-size:18px;"/>
-              </el-tooltip>
+              
+              <span v-show="selectEdbInfo.Frequency" style="margin: 0 10px">频度: {{ selectEdbInfo.Frequency }}</span>
+              <span v-show="selectEdbInfo.LatestDate">最新日期: {{ selectEdbInfo.LatestDate }}</span>
             </li>
-            <li class="form-item" v-if="selectEdbInfo.Frequency">
-              <label>更新频度</label>
-              {{ selectEdbInfo.Frequency }}
+            <li class="form-item" style="padding-left:10px">
+              <label class="el-form-item__label">期数前移</label>
+              <el-input
+                v-model="formData.MoveForward"
+                type="number"
+                :min="0"
+                style="margin-right:10px;width:80px"
+                @change="e => {formData.MoveForward=Number(e)}"
+              />期
             </li>
-            <li class="form-item" v-if="selectEdbInfo.LatestDate">
-              <label>最新日期</label>
-              {{ selectEdbInfo.LatestDate }}
+            <li class="form-item">
+              <el-radio 
+                v-model="dateChangeSelect"
+                :label="1"
+                style="margin-right:12px"
+              >系统日期</el-radio>
+              
+              <span>{{ $moment().format('YYYY-MM-DD') }}</span>
+            </li>
+            <li class="form-item">
+              <dateMoveWaySec ref="dateMoveWayRef"/>
             </li>
           </ul>
 			</div>
+
+      <el-popover
+        placement="top-start"
+        width="500"
+        trigger="click">
+        <p style="padding:20px;line-height:25px;" v-html="tips"/>
+        <el-button slot="reference" class="tip-label" type="text">公式说明</el-button>
+      </el-popover>
+
 			<div class="dia-bot">
-				<el-button type="primary" style="margin-right:20px" @click="saveInsertHandle">保存</el-button>
+				<el-button type="primary" style="margin-right:20px" @click="saveInsertHandle">确定</el-button>
 				<el-button type="primary" plain @click="cancelHandle">取消</el-button>
 			</div>
 	</el-dialog>
@@ -121,6 +74,7 @@
 import * as sheetInterface from "@/api/modules/sheetApi.js";
 import { dataBaseInterface } from '@/api/api.js';
 import selectTarget from '@/views/chartRelevance_manage/components/selectTarget.vue'
+import dateMoveWaySec from './dateMoveWaySection.vue'
 export default {
   props: {
     isShow: {
@@ -130,17 +84,21 @@ export default {
       type: Object
     }
   },
-  components: { selectTarget },
+  components: { selectTarget,dateMoveWaySec },
   watch: {
     isShow : { 
       async handler(nval) {
         if(nval && this.info.Value) { //处理日期编辑回显
           const valueObj = JSON.parse(this.info.Value);
 
+          // this.formData = {
+          //   ...this.formData,
+          //   ...valueObj
+          // }
           this.formData = {
-            ...this.formData,
-            ...valueObj
+            MoveForward: valueObj.MoveForward
           }
+          this.dateChangeSelect = this.info.DataTimeType;
 
           if(this.info.DataTimeType===2) { //指标日期时获取指标详情
             const { Data } = await dataBaseInterface.targetDetail({EdbInfoId: valueObj.EdbInfoId})
@@ -151,69 +109,44 @@ export default {
             this.search_edb = valueObj.EdbInfoId;
             this.searchOptions = [this.selectEdbInfo];
           }
+
+          this.$nextTick(() => {
+            this.$refs.dateMoveWayRef&&this.$refs.dateMoveWayRef.initData(valueObj.DateChange)
+          })
         }
       }
     }  
 
   },
-  computed: {
-    frequencyDaysOptions() {
-      let typeMap = {
-        '本周': [
-          { name: '周一' },
-          { name: '周二' },
-          { name: '周三' },
-          { name: '周四' },
-          { name: '周五' },
-          { name: '周六' },
-          { name: '周日' },
-        ]
-      }
-      return typeMap[this.formData.Frequency] 
-        ? typeMap[this.formData.Frequency] 
-        : [{name:'第一天'},{name:'最后一天'}]
-    }
-  },
+
   data() {
     return {
       formData: {
-        Source: 1,
-        Frequency: '本周',
-        Day: '周一',
-        CalculateNum: 0,
-        CalculateFrequency: '日'
+        // Source: 1,
+        // Frequency: '本周',
+        // Day: '周一',
+        // CalculateNum: 0,
+        // CalculateFrequency: '日'
+        MoveForward: 0,
       },
 
-      wayOptions: [
-        { name: '直接导入', value: 1 },
-        { name: '日期计算', value: 2 },
-        { name: '指定频率', value: 3 },
-      ],
-      frequencyOptions: [
-        { name: '本周', value: '本周' },
-        { name: '本旬', value: '本旬' },
-        { name: '本月', value: '本月' },
-        { name: '本季', value: '本季' },
-        { name: '本半年', value: '本半年' },
-        { name: '本年', value: '本年' },
-      ],
-
-      search_edb: '',
-      searchOptions:[],
+      tips: `
+        公式说明:<br>
+        1、指标日期:取所选指标最新日期,跟随最新日期更新。<br>
+        2、系统日期:取系统日期,跟随系统日期更新。<br>
+        3、日期位移示例:<br>
+        原日期 2023/10/12,日期位移函数设置为5天0月0年,则转换后日期为2023/10/17。<br>
+        原日期 2023/10/12,日期位移函数设置为30天0月0年,则转换后日期为2023/11/11。<br>
+        原日期2023/10/30,日期位移函数设置为0天1月0年,则转换后日期为2023/11/30。<br>
+        原日期2023/10/31,日期位移函数设置为0天1月0年,则转换后日期为2023/12/1。<br>
+        4、日期位移与指定频率互相叠加,示例:<br>
+        原日期 2023/10/12, 先日期位移1月(2023/11/12),后频率设置本月最后一天,则转化后的日期为2023/11/30。<br>
+        原日期 2023/10/12 ,先频率设置本月最后一天(2023/10/31),后日期位移1月,则转化后的日期为2023/12/1。
+      `,
 
-      titleMap: {
-        'insert-sys-date': '导入系统日期',
-        'insert-edb-date': '导入指标日期'
-      },
+      selectEdbInfo: {},
 
-      tips: {
-        'insert-sys-date': `1、直接导入:直接取系统日期,跟随系统日期更新<br>
-        2、日期计算:取系统日期进行公式计算,跟随系统日期更新 <br>
-        3、指定频率:取系统日期相关的指定日期,跟随系统日期更新`,
-        'insert-edb-date': '取指标的最新日期,跟随指标最新日期更新'
-      },
-
-      selectEdbInfo: {}
+      dateChangeSelect: 2,//日期方式选择 1系统日期 2指标日期
 
     }
   },
@@ -221,48 +154,51 @@ export default {
     // 保存插入信息
     async saveInsertHandle() {
 
-      if(this.info.key==='insert-edb-date' && !this.selectEdbInfo.EdbInfoId) return this.$message.warning('请选择指标')
+      if(this.dateChangeSelect===2 && !this.selectEdbInfo.EdbInfoId) return this.$message.warning('请选择指标')
       
       let backData = {}
       //插入系统日期
-      if(this.info.key==='insert-sys-date') {
+      // if(this.info.key==='insert-sys-date') {
+
+        let valueParam = {
+          EdbInfoId: this.selectEdbInfo.EdbInfoId||0,
+          MoveForward: this.formData.MoveForward,
+          DateChange: this.$refs.dateMoveWayRef.dateChangeArr
+        }
+
         let { Data } = await sheetInterface.getSystemDate({
-          DataTimeType: 1,
-          Value: JSON.stringify(this.formData)
+          DataTimeType: this.dateChangeSelect,
+          Value: JSON.stringify(valueParam)
         })
         
         backData = {
           insertValue: Data.Date,
-          dataTimeType: 1,
-          str: JSON.stringify(this.formData)
-        }
-      }else { //指标日期
-        backData = {
-          insertValue: this.selectEdbInfo.LatestDate,
-          dataTimeType: 2,
-          str:  JSON.stringify({EdbInfoId: this.selectEdbInfo.EdbInfoId})
+          dataTimeType: this.dateChangeSelect,
+          str: JSON.stringify(valueParam)
         }
-      }
+      // }else { //指标日期
+      //   backData = {
+      //     insertValue: this.selectEdbInfo.LatestDate,
+      //     dataTimeType: 2,
+      //     str:  JSON.stringify({EdbInfoId: this.selectEdbInfo.EdbInfoId})
+      //   }
+      // }
       this.$emit('insert',backData)
       this.cancelHandle()
     },
 
-    init(type='') {
+    init() {
 
       this.formData = {
-        Source: this.formData.Source,
-        Frequency: '本周',
-        Day: '周一',
-        CalculateNum: 0,
-        CalculateFrequency: '日'
+        MoveForward: 0,
       }
 
       this.search_edb = '';
       this.searchOptions = [];
       if(this.$refs.selectRef) this.$refs.selectRef.search_txt='';
-
-      if(!type) this.formData.Source = 1;
       this.selectEdbInfo = {}
+      this.dateChangeSelect = 2;
+      this.$refs.dateMoveWayRef.initData();
     },
     cancelHandle() {
       this.init()
@@ -273,9 +209,9 @@ export default {
 </script>
 <style scoped lang='scss'>
 .dialog-main {
-  padding: 20px;
+  padding: 0 20px;
   .form-item { 
-    margin: 15px 0; 
+    margin: 20px 0; 
     display: flex;
     align-items: center;
     label { width: 80px;flex-shrink: 0; }
@@ -286,4 +222,10 @@ export default {
   display: flex;
   justify-content: center;
 }
+.tip-label {
+  position: absolute;
+  bottom: 20px;
+  right: 20px;
+  cursor: pointer;
+}
 </style>

+ 133 - 24
src/views/datasheet_manage/components/selectTargetValueDia.vue

@@ -12,18 +12,45 @@
         @select="chooseEdb"
       />
 
-      <ul class="data-cont">
+      <!-- <ul class="data-cont">
         <template v-if="result.List&&result.List.length">
           <li 
             v-for="(item,index) in result.List" 
             :key="index" 
-            :class="[{'choose': item.DataTime===chooseItem.date || (!chooseItem.date&&index===0)},'data-li']"
+            :class="[{'choose': item.DataTime===result.Date},'data-li']"
           >
             <span>{{item.DataTime}}</span>
             <span style="min-width:150px">{{item.Value}}</span>
           </li>
         </template>
         <tableNoData size="mini" v-else/>
+      </ul> -->
+
+      <!-- 依赖日期选择方式 -->
+      <ul class="date-select-cont">
+        <li class="flex">
+          <div class="flex">
+            <el-radio v-model="dateSelectForm.Type" :label="1">指标最新日期</el-radio>
+            <div>
+              <label class="el-form-item__label">期数前移</label>
+              <el-input
+                v-model="dateSelectForm.MoveForward"
+                type="number"
+                :min="0"
+                style="margin-right:10px;width:80px"
+                @change="e => {dateSelectForm.MoveForward=Number(e);}"
+              />期
+            </div>
+          </div>
+          <div class="flex">
+            <el-radio v-model="dateSelectForm.Type" :label="2" style="margin-left:50px">表格日期</el-radio>
+            <span v-if="dateSelectForm.relationDate&&dateSelectForm.Type===2">{{dateSelectForm.relationDate}}</span>
+
+          </div>
+        </li>
+        <li>
+          <dateMoveWaySec ref="dateMoveWayRef"/>
+        </li>
       </ul>
 
       <div class="dia-bot">
@@ -39,15 +66,41 @@
 </template>
 <script>
 import * as sheetInterface from "@/api/modules/sheetApi.js";
+import { dataBaseInterface } from '@/api/api.js';
 import selectTarget from '@/views/chartRelevance_manage/components/selectTarget.vue';
-import { resetDialogCellStyle } from "../common/customTable";
+import { resetDialogCellStyle,findCellByKey } from "../common/customTable";
+import dateMoveWaySec from './dateMoveWaySection.vue'
 export default {
   props: {
     isShow: {
       type: Boolean,
+    },
+    info: {
+      type: Object
+    }
+  },
+  components: { selectTarget,dateMoveWaySec },
+  watch: {
+    isShow(nval) {
+      if(!nval) return
+
+      console.log(this.info)
+      if(this.info.DataType===5) {
+        const valueObj = this.info.Value ? JSON.parse(this.info.Value) : {};
+        this.dateSelectForm = {
+          Type: this.info.DataTime ? 2 : 1,
+          MoveForward: valueObj.MoveForward || 0,
+          relationDate: this.info.DataTime ? this.getNewCellDate() : '',//日期会动态更新 需要找关联单元格最新的数据
+          relationUid: this.info.DataTime ? this.getRelationCellKey() : ''
+        }
+
+        this.getEdbInfo(this.info.EdbInfoId);
+        this.$nextTick(() => {
+          valueObj.DateChange&&this.$refs.dateMoveWayRef.initData(valueObj.DateChange)
+        })
+      }
     }
   },
-  components: { selectTarget },
   data() {
     return {
       result: {},
@@ -55,6 +108,13 @@ export default {
       chooseItem: {
         edbId: 0,
         value:''
+      },
+
+      dateSelectForm: {
+        Type:1,
+        MoveForward: 0,
+        relationDate: '',//关联的表格日期
+        relationUid: '',//关联格子的uid
       }
     }
   },
@@ -67,38 +127,76 @@ export default {
       } 
 
       this.edbInfo = edb;
+    },
+
+    // 在选择表格中日期的话在弹窗中显示所选日期 关联uid
+    changeRleationDate(cell) {
+      this.dateSelectForm.relationDate=cell.DataType===1 ? cell.ShowValue : '';
+      this.dateSelectForm.relationUid=this.dateSelectForm.relationDate ? cell.Uid : '';
+    },
+
+    /* 获取指标信息回显 */
+    async getEdbInfo(EdbInfoId) {
+      const { Data } = await dataBaseInterface.targetDetail({EdbInfoId})
+
+      const { EdbName,LatestDate,Frequency } = Data;
+      this.edbInfo = { EdbName,LatestDate,Frequency,EdbInfoId };
+      this.$refs.selectRef.search_txt = EdbName;
+    },
+
+    /* 找日期关联的key 本来想存在单元格内部后端不想动原来结构 还是自己根据关联关系找吧 */
+    getRelationCellKey() {
+      let relationObj = this.$parent.insertRelationArr.find(_=> _.key === this.info.Uid)
+      if(!relationObj) return ''
+
+      return relationObj.relation_date.key
+    },
+
+    /* 先找关联日期的key  再根据key找单元格数据取到最新的日期 */
+    getNewCellDate() {
+      let relationKey = this.getRelationCellKey();
+      if(!relationKey) return '';
+
+      let relationDateCell = findCellByKey(this.$parent.config.data,relationKey)
+      
+      return relationDateCell.ShowValue
+    },
 
-      let Date = this.$parent.selectCell.DataType === 1 ? this.$parent.selectCell.ShowValue : ''
+
+    //插入值的时候再去计算结果
+    async insertData() {
+      if(!this.edbInfo) return this.$message.warning('请先选择指标')
+
+      let Date='';
+      if(this.dateSelectForm.Type===2) { //选框为表格日期再去取Date
+        Date = this.dateSelectForm.relationDate;
+      }
 
       const res = await sheetInterface.getDateLatelyData({ 
-        EdbInfoId: edb.EdbInfoId,
+        EdbInfoId: this.edbInfo.EdbInfoId,
+        MoveForward: this.dateSelectForm.MoveForward,
+        DateChange: this.$refs.dateMoveWayRef.dateChangeArr,
         Date
       })
       if(res.Ret !== 200) return
 
       this.result = res.Data;
-      // if(!this.result.Date && Date) return this.$message.warning('所选指标所选日期无值')
 
       let value = (this.result.List&&this.result.List.length)
-        ? (this.result.List.find(_ => _.DataTime===Date) ? this.result.List.find(_ => _.DataTime===Date).Value.toString() : this.result.List[0].Value.toString()) 
+        ? this.result.List.find(_ => _.DataTime===this.result.Date) ? this.result.List.find(_ => _.DataTime===this.result.Date).Value.toString() : ''
         : ''
+
       this.chooseItem = {
-        date: Date,
-        edbId: edb.EdbInfoId,
-        value
+        relationDate: Date,
+        relationUid: this.dateSelectForm.Type===2 ? this.dateSelectForm.relationUid : '',
+        edbId: this.edbInfo.EdbInfoId,
+        value,
+        str: JSON.stringify({
+          MoveForward: this.dateSelectForm.MoveForward,
+          DateChange: this.$refs.dateMoveWayRef.dateChangeArr
+        })
       }
 
-      console.log( this.chooseItem)
-
-    },
-
-    insertData() {
-      // if(this.$parent.selectCell.DataType !== 1){
-      //   this.$message.warning('请在表格中选择日期')
-      //   return
-      // }
-      if(!this.chooseItem.value) return this.$message.warning('该日期无数据')
-
       this.$emit('insert',this.chooseItem)
       this.cancelHandle();
     },
@@ -108,6 +206,8 @@ export default {
       this.result = {};
       this.edbInfo=null;
       this.chooseItem = { edbId: 0,value: '',date: '' }
+      this.dateSelectForm = {Type:1,MoveForward: 0,relationDate: '',relationUid: '',}
+      this.$refs.dateMoveWayRef&&this.$refs.dateMoveWayRef.initData();
     },
 
     cancelHandle() {
@@ -125,7 +225,7 @@ export default {
   position: fixed;
   top: 20%;
   left: 55%;
-  width: 500px;
+  width: 650px;
   border-radius: 2px;
   box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
   z-index: 9999;
@@ -164,10 +264,19 @@ export default {
       }
     }
     .dia-bot {
-      margin-top: 20px; 
+      margin-top: 30px; 
       display: flex;
       justify-content: center;
     }
+    .date-select-cont {
+      li {
+        margin: 20px 0;
+      }
+      .flex {
+        display: flex;
+        align-items: center;
+      }
+    }
   }
 }
 </style>

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

@@ -20,6 +20,9 @@
 				:model="formData"
 				:rules="formRules">
 				
+          <el-form-item label="上级目录" prop="classify_name" v-if="formData.parentClassifyId">
+            <span>{{formData.parentName}}</span>
+          </el-form-item>
           <el-form-item label="分类名称" prop="classify_name">
             <el-input
             v-model="formData.classify_name"
@@ -96,9 +99,17 @@ export default {
 
 		/* 表格分类接口 */
 		async sheetClassifyApi(classify_name,classify_id) {
+			const { parentClassifyId } = this.formData;
+
+			let params = {
+				ExcelClassifyName:classify_name,
+				Source: this.$parent.sourceMap[this.$route.path],
+				ParentId: parentClassifyId
+			}
+
 			const { Ret,Msg } = !classify_id
-        ? await sheetInterface.classifyAdd({ ExcelClassifyName:classify_name,Source: this.$parent.sourceMap[this.$route.path] })
-        : await sheetInterface.classifyEdit({ ExcelClassifyName:classify_name, ExcelClassifyId:classify_id,Source: this.$parent.sourceMap[this.$route.path] })
+        ? await sheetInterface.classifyAdd(params)
+        : await sheetInterface.classifyEdit({ ExcelClassifyId:classify_id,...params })
         
       if( Ret !== 200) return
       this.$message.success(Msg);

+ 197 - 0
src/views/datasheet_manage/components/toolBarSection.vue

@@ -0,0 +1,197 @@
+<template>
+  <!-- 混合表格顶部工具栏 -->
+  <div class="toolbar-wrapper">
+    <div 
+      class="tool-btn-item" v-for="tool in toolIcons" 
+      :key="tool.key" 
+      @click="dealToolHandles(tool)"
+    >
+      <button>
+        <!-- icon -->
+        <template v-if="tool.type==='icon'">
+          <span class="icon-wrap" v-html="tool.icon"></span>
+        </template>
+
+        <template v-if="tool.type==='select'">
+          <el-select 
+            v-model="option.nt" 
+            style="width: 90px" 
+            size="small" 
+            v-if="tool.key==='cell-type-edit'"
+            @change="changeCellType"
+          >
+            <el-option
+              v-for="item in numberTypeOptions"
+              :key="item.key"
+              :value="item.key"
+              :label="item.label"
+            >
+            </el-option>
+          </el-select>
+        </template>
+      </button>
+    </div>
+  </div>
+</template>
+<script>
+import { transDecimalPlace,isNumberVal,getDecimalPlaces,transNumPercentType } from '../common/customTable';
+export default {
+  props: {
+    cell: {
+      type: Object,
+    },
+  },
+  watch: {
+    cell(nval) {
+      if(nval.ShowStyle) {
+        this.option = {
+          ...JSON.parse(nval.ShowStyle)
+        }
+      }else {
+        this.option = {
+          nt: "",//numberType
+          pn: 0,//ponitNum
+        }
+      }
+    }
+  },
+  data() {
+    return {
+      option: {
+        nt: "",//numberType  number percent
+        pn: 0,//ponitNum
+      },
+
+      toolIcons: [
+        {
+          icon: `<svg viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+              <g id="increase-decimal" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+                  <g id="Increase-Decimal" transform="translate(1.000000, 1.000000)">
+                      <polygon id="Shape" fill="#333" fill-rule="nonzero" transform="translate(3.500000, 2.500000) rotate(-270.000000) translate(-3.500000, -2.500000) " points="3.5 6 6 3.5 4 3.5 4 -1 3 -1 3 3.5 1 3.5"></polygon>
+                      <path d="M12,0 C12.6360153,0 13.1340996,0.274932615 13.4942529,0.84097035 C13.8314176,1.37466307 14,2.09433962 14,3 C14,3.90566038 13.8314176,4.62533693 13.4942529,5.15902965 C13.1340996,5.71698113 12.6360153,6 12,6 C11.3563218,6 10.8582375,5.71698113 10.5057471,5.15902965 C10.1685824,4.62533693 10,3.90566038 10,3 C10,2.09433962 10.1685824,1.37466307 10.5057471,0.84097035 C10.8582375,0.274932615 11.3563218,0 12,0 Z M12,0.800539084 C11.5632184,0.800539084 11.256705,1.05121294 11.0804598,1.56873315 C10.9578544,1.91644205 10.8965517,2.393531 10.8965517,3 C10.8965517,3.59838275 10.9578544,4.0754717 11.0804598,4.43126685 C11.256705,4.94070081 11.5632184,5.19946092 12,5.19946092 C12.4291188,5.19946092 12.7356322,4.94070081 12.9195402,4.43126685 C13.0421456,4.0754717 13.1034483,3.59838275 13.1034483,3 C13.1034483,2.393531 13.0421456,1.91644205 12.9195402,1.56873315 C12.7356322,1.05121294 12.4291188,0.800539084 12,0.800539084 Z" id="0" fill="#333"></path>
+                      <path d="M12,8 C12.6360153,8 13.1340996,8.27493261 13.4942529,8.84097035 C13.8314176,9.37466307 14,10.0943396 14,11 C14,11.9056604 13.8314176,12.6253369 13.4942529,13.1590296 C13.1340996,13.7169811 12.6360153,14 12,14 C11.3563218,14 10.8582375,13.7169811 10.5057471,13.1590296 C10.1685824,12.6253369 10,11.9056604 10,11 C10,10.0943396 10.1685824,9.37466307 10.5057471,8.84097035 C10.8582375,8.27493261 11.3563218,8 12,8 Z M12,8.80053908 C11.5632184,8.80053908 11.256705,9.05121294 11.0804598,9.56873315 C10.9578544,9.91644205 10.8965517,10.393531 10.8965517,11 C10.8965517,11.5983827 10.9578544,12.0754717 11.0804598,12.4312668 C11.256705,12.9407008 11.5632184,13.1994609 12,13.1994609 C12.4291188,13.1994609 12.7356322,12.9407008 12.9195402,12.4312668 C13.0421456,12.0754717 13.1034483,11.5983827 13.1034483,11 C13.1034483,10.393531 13.0421456,9.91644205 12.9195402,9.56873315 C12.7356322,9.05121294 12.4291188,8.80053908 12,8.80053908 Z" id="0-copy" fill="#333"></path>
+                      <path d="M6,8 C6.63601533,8 7.13409962,8.27493261 7.49425287,8.84097035 C7.83141762,9.37466307 8,10.0943396 8,11 C8,11.9056604 7.83141762,12.6253369 7.49425287,13.1590296 C7.13409962,13.7169811 6.63601533,14 6,14 C5.35632184,14 4.85823755,13.7169811 4.50574713,13.1590296 C4.16858238,12.6253369 4,11.9056604 4,11 C4,10.0943396 4.16858238,9.37466307 4.50574713,8.84097035 C4.85823755,8.27493261 5.35632184,8 6,8 Z M6,8.80053908 C5.56321839,8.80053908 5.25670498,9.05121294 5.08045977,9.56873315 C4.95785441,9.91644205 4.89655172,10.393531 4.89655172,11 C4.89655172,11.5983827 4.95785441,12.0754717 5.08045977,12.4312668 C5.25670498,12.9407008 5.56321839,13.1994609 6,13.1994609 C6.42911877,13.1994609 6.73563218,12.9407008 6.91954023,12.4312668 C7.04214559,12.0754717 7.10344828,11.5983827 7.10344828,11 C7.10344828,10.393531 7.04214559,9.91644205 6.91954023,9.56873315 C6.73563218,9.05121294 6.42911877,8.80053908 6,8.80053908 Z" id="0-copy-2" fill="#333"></path>
+                      <path d="M7.99363057,4 C8.27388535,4 8.50318471,4.08917197 8.70700637,4.29299363 C8.89808917,4.48407643 9,4.72611465 9,5.00636943 C9,5.2866242 8.89808917,5.51592357 8.70700637,5.71974522 C8.50318471,5.89808917 8.27388535,6 7.99363057,6 C7.7133758,6 7.47133758,5.89808917 7.29299363,5.71974522 C7.08917197,5.51592357 7,5.2866242 7,5.00636943 C7,4.72611465 7.08917197,4.48407643 7.29299363,4.29299363 C7.47133758,4.08917197 7.7133758,4 7.99363057,4 Z" id="." fill="#333"></path>
+                      <path d="M0.993630573,12 C1.27388535,12 1.50318471,12.089172 1.70700637,12.2929936 C1.89808917,12.4840764 2,12.7261146 2,13.0063694 C2,13.2866242 1.89808917,13.5159236 1.70700637,13.7197452 C1.50318471,13.8980892 1.27388535,14 0.993630573,14 C0.713375796,14 0.47133758,13.8980892 0.292993631,13.7197452 C0.0891719745,13.5159236 0,13.2866242 0,13.0063694 C0,12.7261146 0.0891719745,12.4840764 0.292993631,12.2929936 C0.47133758,12.089172 0.713375796,12 0.993630573,12 Z" id=".-copy" fill="#333"></path>
+                  </g>
+              </g>
+          </svg>`,
+          key: "add-point",
+          type: 'icon',
+          title: '增加小数位数'
+        },
+        { 
+          icon: `<svg viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+              <g id="decrease-decimal" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+                  <g transform="translate(1.000000, 1.000000)">
+                      <polygon id="Shape" fill="#333" fill-rule="nonzero" transform="translate(3.500000, 10.500000) rotate(-90.000000) translate(-3.500000, -10.500000) " points="3.5 14 6 11.5 4 11.5 4 7 3 7 3 11.5 1 11.5"></polygon>
+                      <path d="M12,0 C12.6360153,0 13.1340996,0.274932615 13.4942529,0.84097035 C13.8314176,1.37466307 14,2.09433962 14,3 C14,3.90566038 13.8314176,4.62533693 13.4942529,5.15902965 C13.1340996,5.71698113 12.6360153,6 12,6 C11.3563218,6 10.8582375,5.71698113 10.5057471,5.15902965 C10.1685824,4.62533693 10,3.90566038 10,3 C10,2.09433962 10.1685824,1.37466307 10.5057471,0.84097035 C10.8582375,0.274932615 11.3563218,0 12,0 Z M12,0.800539084 C11.5632184,0.800539084 11.256705,1.05121294 11.0804598,1.56873315 C10.9578544,1.91644205 10.8965517,2.393531 10.8965517,3 C10.8965517,3.59838275 10.9578544,4.0754717 11.0804598,4.43126685 C11.256705,4.94070081 11.5632184,5.19946092 12,5.19946092 C12.4291188,5.19946092 12.7356322,4.94070081 12.9195402,4.43126685 C13.0421456,4.0754717 13.1034483,3.59838275 13.1034483,3 C13.1034483,2.393531 13.0421456,1.91644205 12.9195402,1.56873315 C12.7356322,1.05121294 12.4291188,0.800539084 12,0.800539084 Z" id="0" fill="#333"></path>
+                      <path d="M12,8 C12.6360153,8 13.1340996,8.27493261 13.4942529,8.84097035 C13.8314176,9.37466307 14,10.0943396 14,11 C14,11.9056604 13.8314176,12.6253369 13.4942529,13.1590296 C13.1340996,13.7169811 12.6360153,14 12,14 C11.3563218,14 10.8582375,13.7169811 10.5057471,13.1590296 C10.1685824,12.6253369 10,11.9056604 10,11 C10,10.0943396 10.1685824,9.37466307 10.5057471,8.84097035 C10.8582375,8.27493261 11.3563218,8 12,8 Z M12,8.80053908 C11.5632184,8.80053908 11.256705,9.05121294 11.0804598,9.56873315 C10.9578544,9.91644205 10.8965517,10.393531 10.8965517,11 C10.8965517,11.5983827 10.9578544,12.0754717 11.0804598,12.4312668 C11.256705,12.9407008 11.5632184,13.1994609 12,13.1994609 C12.4291188,13.1994609 12.7356322,12.9407008 12.9195402,12.4312668 C13.0421456,12.0754717 13.1034483,11.5983827 13.1034483,11 C13.1034483,10.393531 13.0421456,9.91644205 12.9195402,9.56873315 C12.7356322,9.05121294 12.4291188,8.80053908 12,8.80053908 Z" id="0-copy" fill="#333"></path>
+                      <path d="M6,0 C6.63601533,0 7.13409962,0.274932615 7.49425287,0.84097035 C7.83141762,1.37466307 8,2.09433962 8,3 C8,3.90566038 7.83141762,4.62533693 7.49425287,5.15902965 C7.13409962,5.71698113 6.63601533,6 6,6 C5.35632184,6 4.85823755,5.71698113 4.50574713,5.15902965 C4.16858238,4.62533693 4,3.90566038 4,3 C4,2.09433962 4.16858238,1.37466307 4.50574713,0.84097035 C4.85823755,0.274932615 5.35632184,0 6,0 Z M6,0.800539084 C5.56321839,0.800539084 5.25670498,1.05121294 5.08045977,1.56873315 C4.95785441,1.91644205 4.89655172,2.393531 4.89655172,3 C4.89655172,3.59838275 4.95785441,4.0754717 5.08045977,4.43126685 C5.25670498,4.94070081 5.56321839,5.19946092 6,5.19946092 C6.42911877,5.19946092 6.73563218,4.94070081 6.91954023,4.43126685 C7.04214559,4.0754717 7.10344828,3.59838275 7.10344828,3 C7.10344828,2.393531 7.04214559,1.91644205 6.91954023,1.56873315 C6.73563218,1.05121294 6.42911877,0.800539084 6,0.800539084 Z" id="0-copy-2" fill="#333"></path>
+                      <path d="M7.99363057,12 C8.27388535,12 8.50318471,12.089172 8.70700637,12.2929936 C8.89808917,12.4840764 9,12.7261146 9,13.0063694 C9,13.2866242 8.89808917,13.5159236 8.70700637,13.7197452 C8.50318471,13.8980892 8.27388535,14 7.99363057,14 C7.7133758,14 7.47133758,13.8980892 7.29299363,13.7197452 C7.08917197,13.5159236 7,13.2866242 7,13.0063694 C7,12.7261146 7.08917197,12.4840764 7.29299363,12.2929936 C7.47133758,12.089172 7.7133758,12 7.99363057,12 Z" id="." fill="#333"></path>
+                      <path d="M0.993630573,4 C1.27388535,4 1.50318471,4.08917197 1.70700637,4.29299363 C1.89808917,4.48407643 2,4.72611465 2,5.00636943 C2,5.2866242 1.89808917,5.51592357 1.70700637,5.71974522 C1.50318471,5.89808917 1.27388535,6 0.993630573,6 C0.713375796,6 0.47133758,5.89808917 0.292993631,5.71974522 C0.0891719745,5.51592357 0,5.2866242 0,5.00636943 C0,4.72611465 0.0891719745,4.48407643 0.292993631,4.29299363 C0.47133758,4.08917197 0.713375796,4 0.993630573,4 Z" id=".-copy" fill="#333"></path>
+                  </g>
+              </g>
+          </svg>`, 
+          key: "del-point", 
+          type: 'icon',
+          title: '减少小数位数' 
+        },
+        { 
+          icon: '',
+          key: 'cell-type-edit',
+          type:'select',
+          title:'' 
+        }
+      ],
+
+      numberTypeOptions: [
+        { label: "数字", key: "number" },
+        { label: "百分位", key: "percent" },
+      ],
+    };
+  },
+  methods: {
+    dealToolHandles({key}) {
+      //单元格不是数字就不用转了
+      if(!isNumberVal(this.cell.ShowValue)) return
+
+      const handlesMap = {
+        'add-point': this.changeCellPoint,
+        'del-point': this.changeCellPoint,
+      }
+
+      handlesMap[key]&&handlesMap[key](key)
+    },
+
+    /* 处理小数点位数 */
+    changeCellPoint(key) {
+      let value = _.cloneDeep(this.cell.ShowValue)
+      key==='add-point' ? this.option.pn++ : this.option.pn--;
+      
+      //判断小数点后尾数 整数最小pn为0 小数最小为负位数
+      if(this.option.pn <= parseInt(`-${getDecimalPlaces(value)}`)) {
+        this.option.pn = parseInt(`-${getDecimalPlaces(value)}`)
+      }
+
+      //百分比格式的话 pn最小为位数-2
+      if(this.option.nt==='percent' && this.option.pn <= parseInt(`-${getDecimalPlaces(value)-2}`)) {
+        this.option.pn = parseInt(`-${getDecimalPlaces(value)-2}`)
+      }
+
+      let nval = transDecimalPlace(value,this.option)
+      // console.log(nval)
+
+      this.$emit('updateCell',{
+        ShowStyle: JSON.stringify(this.option),
+        ShowFormatValue: nval
+      })
+    },
+
+    /* 处理百分位或数字格式 */
+    changeCellType() {
+      if(!isNumberVal(this.cell.ShowValue)) return
+      this.option.pn = 0
+
+      let value = _.cloneDeep(this.cell.ShowValue)
+
+      let nval = transNumPercentType(value,this.option.nt)
+
+      this.$emit('updateCell',{
+        ShowStyle: JSON.stringify(this.option),
+        ShowFormatValue: nval
+      })
+    }
+  },
+};
+</script>
+<style scoped lang="scss">
+.toolbar-wrapper {
+  width: fit-content;
+  display: flex;
+  overflow: hidden;
+  background: #fff;
+  border: 1px solid #ccc;
+  border-bottom: none;
+  padding: 2px 12px;
+  .tool-btn-item {
+    margin: 5px;
+    display: flex;
+    align-items: center;
+    button {
+      border: none;
+      padding: 4px;
+      background: #fff;
+      &:hover {
+        background: #ccc;
+      }
+
+      .icon-wrap {
+        width: 20px;
+        height: 20px;
+        display: inline-block;
+      }
+    }
+  }
+}
+</style>

+ 6 - 2
src/views/datasheet_manage/customAnalysis/addAnalysisSheet.vue

@@ -34,6 +34,7 @@
         ref="edbWrapRef"
         v-if="$route.path==='/createTaregtBySheet'"
         :list="edbList"
+        :sheetDetailInfo="this.sheetDetailInfo"
         @choose="chooseEdbHandle"
       />
     </div>
@@ -306,7 +307,7 @@ export default {
         }))
 
         this.isLoading = false;
-        this.getTargetList()
+        //this.getTargetList()
       }
     },
 
@@ -410,7 +411,10 @@ export default {
 
       if(!edbInfoId) this.$refs.createTargetRef.initData();
 
-      this.getTargetList()
+      //this.getTargetList()
+      if(this.$refs.edbWrapRef){
+        this.$refs.edbWrapRef.getTargetList('init')
+      }
     },
 
     /* 获取生成指标列表 */

+ 16 - 2
src/views/datasheet_manage/customAnalysis/components/bottomSection.vue

@@ -11,7 +11,7 @@
       </div>
 
       <div>
-        <el-select 
+        <!-- <el-select 
           v-model="select_classify"
           placeholder="请选择表格目录"
           clearable
@@ -23,7 +23,21 @@
             :label="item.ExcelClassifyName"
             :value="item.ExcelClassifyId"
           />
-        </el-select>
+        </el-select> -->
+        <el-cascader
+          v-model="select_classify"
+          :options="classifyArr"
+          style="width:350px;"
+          :props="{
+            label: 'ExcelClassifyName',
+            value: 'ExcelClassifyId',
+            children: 'Children',
+            emitPath: false,
+            checkStrictly: true
+          }"
+          clearable
+          placeholder="请选择表格分类"
+        />
         <el-button type="primary" style="margin-left:30px" @click="saveSheetHandle">保存</el-button>
           <el-tooltip class="item" effect="dark" content="根据用户选择的sheet页上传文件" placement="top-start">
           <i class="el-icon-warning"/>

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

@@ -239,7 +239,10 @@ export default {
     handleSaveTarget: _.debounce(async function() {
       if(!this.formData.dateSeries) return this.$message.warning('日期序列不能为空')
       if(!this.formData.valueSeries) return this.$message.warning('数值序列不能为空')
-
+      //如果选区超过10000,提示
+      if(this.formData.dateArr.length>10000||this.formData.valueArr.length>10000){
+        return this.$message.warning("选区过多,请调整选区")
+      }
       await this.$refs.formRef.validate();
       this.initSelect();
       this.$emit('save')

+ 34 - 3
src/views/datasheet_manage/customAnalysis/components/rightSection.vue

@@ -1,6 +1,10 @@
 <template>
   <div class="right-section-wrapper">
     <div class="create-cont">
+        <div class="search-box">
+            <el-input placeholder="请输入指标ID/指标名称" prefix-icon="el-icon-search" clearable
+                v-model="keyWord" @input="getTargetList"/>
+        </div>
       <ul class="edb-list" v-if="edbList.length">
         <li :class="['edb-item',{'selected':selectEdb.EdbInfoId===item.EdbInfoId}]" v-for="(item,index) in edbList" :key="index" @click="chooseEdb(item)">
           <span>{{item.EdbName}}</span>
@@ -17,21 +21,30 @@
   </div>
 </template>
 <script>
+import * as sheetInterface from '@/api/modules/sheetApi.js';
 export default {
   props: {
     list: {
       type: Array
+    },
+    sheetDetailInfo:{
+        type:Object
     }
   },
   watch: {
-    list(nval) {
+    /* list(nval) {
       this.edbList = nval;
+    }, */
+    sheetDetailInfo(newVal){
+        if(newVal&&newVal.ExcelInfoId)
+            this.getTargetList('init')
     }
   },
   data() {
     return {
       edbList:[],
       selectEdb: {},
+      keyWord:''
     }
   },
   mounted(){
@@ -57,7 +70,21 @@ export default {
         classifyId:ClassifyId
       }});
 			window.open(href,'_blank');
-    }
+    },
+    async getTargetList(type) {
+      this.selectEdb={}
+      const res = await sheetInterface.sheetAnalysisInterface.edbListBySheet({
+        ExcelInfoId: this.sheetDetailInfo.ExcelInfoId,
+        Keyword:this.keyWord
+      })
+
+      if(res.Ret !== 200) return
+      
+      this.edbList = res.Data || [];
+      if(type!=='init'&&this.edbList.length){
+        this.chooseEdb(this.edbList[0])
+      }
+    },
   },
 }
 </script>
@@ -73,7 +100,7 @@ export default {
   .create-cont {
     .edb-list {
       padding: 30px;
-      max-height: 640px;
+      max-height: 520px;
       overflow-y: auto;
       .edb-item {
         display: flex;
@@ -106,6 +133,10 @@ export default {
         }
       }
     }
+    .search-box{
+        padding:30px;
+        padding-bottom: 0;
+    }
   }
 }
 </style>

+ 37 - 1
src/views/datasheet_manage/customAnalysis/list.vue

@@ -96,6 +96,14 @@
                   alt=""
                   style="width: 14px; height: 14px; margin-right: 8px"
                 />
+                 <!-- 添加子 -->
+								<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.ExcelInfoId&&isSheetBtnShow('classifyOpt_edit')&&node.level<3"
+								/>
                 <img
                   src="~@/assets/img/set_m/edit.png"
                   alt=""
@@ -496,17 +504,45 @@ export default {
       this.dialog_title = "添加";
       this.classifyForm = {
         classify_name: "",
+        parentClassifyId: 0,
+        parentName:''
+      };
+      this.classifyDia = true;
+    },
+
+    // 递归节点
+		getNodeParentData(data,arr){
+			if(data.level===0) return
+			arr.push({ExcelClassifyName:data.data.ExcelClassifyName,ExcelClassifyId:data.data.ExcelClassifyId})
+			this.getNodeParentData(data.parent,arr)
+			return arr
+		},
+
+    /* 添加节点 */
+    addNode(node,data) {
+      let arr = []
+      arr = this.getNodeParentData(node,arr).reverse();
+      this.dialog_title = "添加";
+      /* 编辑目录 */
+      this.classifyForm = {
+        classify_name: "",
+        parentClassifyId: data.ExcelClassifyId,
+        parentName: arr.map(_=>_.ExcelClassifyName).join('/')
       };
       this.classifyDia = true;
     },
 
     /* 编辑节点 */
-    editNode(node, { ExcelClassifyName, ExcelClassifyId }) {
+    editNode(node, { ExcelClassifyName, ExcelClassifyId,ParentId }) {
+      let arr = []
+      arr = ParentId ? this.getNodeParentData(node.parent,arr).reverse() : [];
       this.dialog_title = "编辑";
       /* 编辑目录 */
       this.classifyForm = {
         classify_name: ExcelClassifyName,
         classify_id: ExcelClassifyId,
+        parentClassifyId: ParentId,
+        parentName: arr.map(_=>_.ExcelClassifyName).join('/')
       };
       this.classifyDia = true;
     },

+ 18 - 2
src/views/datasheet_manage/customSheetEdit.vue

@@ -26,7 +26,7 @@
             </el-input>
           </li>
           <li>
-            <el-select 
+            <!-- <el-select 
               v-model="sheetForm.classify" 
               placeholder="请选择表格分类"
               style="width:240px;"
@@ -38,7 +38,23 @@
                   :label="item.ExcelClassifyName"
                   :value="item.ExcelClassifyId"
                 />
-              </el-select>
+              </el-select> -->
+
+
+            <el-cascader
+              v-model="sheetForm.classify"
+              :options="classifyArr"
+              style="width:240px;"
+              :props="{
+                label: 'ExcelClassifyName',
+                value: 'ExcelClassifyId',
+                children: 'Children',
+                emitPath: false,
+                checkStrictly: true
+              }"
+              clearable
+              placeholder="请选择表格分类"
+            />
           </li>
           <li>
             <el-select 

+ 23 - 17
src/views/datasheet_manage/mixedSheetEdit.vue

@@ -6,24 +6,25 @@
           <el-input
             v-model="sheetForm.name"
             placeholder="请输入表格名称"
-            style="width:240px"
+            style="width:220px"
             clearable>
           </el-input>
         </li>
         <li>
-          <el-select 
-            v-model="sheetForm.classify" 
-            placeholder="请选择表格分类"
+          <el-cascader
+            v-model="sheetForm.classify"
+            :options="classifyArr"
+            style="width:220px;"
+            :props="{
+              label: 'ExcelClassifyName',
+              value: 'ExcelClassifyId',
+              children: 'Children',
+              emitPath: false,
+              checkStrictly: true
+            }"
             clearable
-            style="min-width:240px"
-          >
-							<el-option
-								v-for="item in classifyArr"
-								:key="item.ExcelClassifyId"
-								:label="item.ExcelClassifyName"
-								:value="item.ExcelClassifyId"
-              />
-						</el-select>
+            placeholder="请选择表格分类"
+          />
         </li>
         <li>
           表格说明
@@ -41,6 +42,7 @@
       </ul>
       <div>
         <span v-if="updateTime" style="color:#999999 ;">最近保存时间:{{updateTime}}</span>
+        <el-button type="primary" size="medium" @click="()=>{ sheetInit=false;getDetail('refresh')}" style="margin-left:10px" icon="el-icon-refresh-right">更新</el-button>
         <el-button type="primary" size="medium" @click="saveSheetHandle" style="margin-left:10px" v-if="hasPermission">保存</el-button>
         <el-button type="primary" size="medium" plain @click="backHandle">返回</el-button>
       </div>
@@ -97,9 +99,11 @@ export default {
       sheetId: this.$route.query.id || '',
       classifyArr: [],
       rules: `表格说明:<br>
-        1、手动输入:单击每个单元格可直接输入文本、数字、日期(格式示例:2023-05-23),输入内容可匹配指标名称,ETA指标库和ETA预测指标库指标均可搜索,在下拉框中选择指标,则该单元格为已选指标行/列。<br>
-        2、插入指标值:右键单元格,点击“插入指标值”,则查询该单元格行、列最近的日期和指标名称,将查找到的指标对应日期的值填入该单元格,指标值总是在右下角。<br>
-        3、更新与计算规则:表格中指标值的日期不自动更新,数值不支持单元格计算`,
+        1、手动输入:单击每个单元格可直接输入文本、数字、日期(格式示例:2023-05-23)<br>
+        2、根据表格中日期选择指标值:在弹窗中搜索并选择指标,默认选择指标最新日期,可插入指标值,随着指标更新;也支持选择指标后,在表格中选择或输入一个日期,则插入该指标在选定日期的值。<br>
+        3、导入日期:导入系统或指标相关的日期,可进一步进行日期变换,跟随系统日期或指标日期更新。<br>
+        4、日期计算:对表格中日期进行计算。<br>
+        5、指标计算:选择指标进行计算,插入指标计算值。`,
       sheetForm: {
         sheetType: 1
       },
@@ -124,7 +128,7 @@ export default {
     },
 
     /* 获取表格详情 */
-    async getDetail() {
+    async getDetail(type='init') {
       if(!this.sheetId) return
 
       const res = await sheetInterface.sheetDetail({
@@ -153,6 +157,8 @@ export default {
       this.updateTime =  this.$moment(ModifyTime).format('YYYY-MM-DD HH:mm:ss')
 
       this.$refs.mixedTableRef.initData(TableData);
+      
+      type==='refresh' && this.$message.success('表格数据已更新')
     },
 
     /* 获取分类 */

+ 72 - 18
src/views/datasheet_manage/mixins/classifyMixin.js

@@ -77,7 +77,7 @@ export default {
 					? 'auto'
 					: width <= 260
 					? 90
-					: 0.7 * width;
+					: 0.6 * width;
 			this.$set(node, 'Nodewidth', label_wid + 'px');
 		},200),
 
@@ -118,6 +118,7 @@ export default {
         this.new_label !== data.ClassifyName && sheetInterface.classifyEdit({
           ExcelClassifyId: data.ExcelClassifyId,
           ExcelClassifyName: this.new_label,
+          ParentId: data.ParentId,
           Source: this.sourceMap[this.$route.path]
         }).then(res => {
           if(res.Ret !== 200) return
@@ -131,11 +132,67 @@ export default {
     dropOverHandle(b, a, i, e) {
       // console.log(i, a);
       // 被拖拽节点对应的 Node、结束拖拽时最后进入的节点、被拖拽节点的放置位置
-      // 一/二级目录
-      if ([1].includes(b.level)) this.handleMoveCatalogue(b, a, i, e);
+      let isSheet = b.data.ExcelInfoId ? true : false;
+      let list=a.parent.childNodes;
+			let targetIndex=0,PrevClassifyId=0,NextClassifyId=0,ParentClassifyId=0;
+      
+			let ClassifyId=isSheet?0:b.data.ExcelClassifyId,ExcelInfoId=isSheet?b.data.ExcelInfoId:0,PrevExcelInfoId=0,NextExcelInfoId=0;
 
-      // 指标层
-      if (b.level === 2) this.handleMoveSheet(b, a, i, e);
+
+      if(i!=='inner'){
+				ParentClassifyId=a.parent.data.ExcelClassifyId||0
+				list.forEach((item,index)=>{
+					if(isSheet){
+						if(item.data.ExcelInfoId===b.data.ExcelInfoId){
+							targetIndex=index
+						}
+					}else{
+						if(item.data.ExcelClassifyId===b.data.ExcelClassifyId){
+							targetIndex=index
+						}
+					}
+					
+				})
+				
+				
+				if(targetIndex===0){
+					const data=list[targetIndex+1].data
+					NextClassifyId=data.ExcelInfoId?0:data.ExcelClassifyId
+					NextExcelInfoId=data.ExcelInfoId?data.ExcelInfoId:0
+				}else if(targetIndex===list.length-1){
+					const data=list[targetIndex-1].data
+					PrevClassifyId=data.ExcelInfoId?0:data.ExcelClassifyId
+					PrevExcelInfoId=data.ExcelInfoId?data.ExcelInfoId:0
+				}else{
+					const pData=list[targetIndex-1].data
+					PrevClassifyId=pData.ExcelInfoId?0:pData.ExcelClassifyId
+
+					PrevExcelInfoId=pData.ExcelInfoId?pData.ExcelInfoId:0
+
+					const nData=list[targetIndex+1].data
+					NextClassifyId=nData.ExcelInfoId?0:nData.ExcelClassifyId
+					NextExcelInfoId=nData.ExcelInfoId?nData.ExcelInfoId:0
+				}
+			}else{
+				ParentClassifyId=a.data.ExcelClassifyId||0
+			}
+      
+      let params = {
+        ClassifyId,
+        ParentClassifyId,
+        NextClassifyId,
+        PrevClassifyId,
+        ExcelInfoId,
+        NextExcelInfoId,
+        PrevExcelInfoId,
+        Source: this.sourceMap[this.$route.path]
+      }
+      sheetInterface.classifyMove(params)
+        .then((res) => {
+          if (res.Ret !== 200) return;
+          this.$message.success("移动成功!");
+          this.getTreeData();
+        });
     },
 
     // 移动的为一级目录
@@ -273,20 +330,17 @@ export default {
     /* 判断节点是否能被拖入 */
     canDropHandle(draggingNode, dropNode, type) {
       let canDrop = false;
-      // 移动的是一级目录
-      if (draggingNode.level === 1 && dropNode.level === 1 &&type!=='inner') {
-        canDrop = true;
-      }
 
-      // 二级
-      if (draggingNode.level === 2) {
-        if (
-          (dropNode.level === 1 && type === "inner") ||
-          (dropNode.level === 2 && type !== "inner")
-        ) {
-          canDrop = true;
-        }
-      }
+      // 指标
+			if(draggingNode.data.ExcelInfoId){
+				if(!(dropNode.level===1&&type!=='inner')){
+					canDrop=true
+				}
+			}else{//目录
+				if((dropNode.level+1==draggingNode.level&&type==='inner')||(dropNode.level===draggingNode.level&&type!=='inner')){
+					canDrop=true
+				}
+			}
 
       return canDrop;
     },

+ 53 - 3
src/views/datasheet_manage/sheetList.vue

@@ -12,9 +12,17 @@
         <div class="datasheet_top">
           <el-button v-if="permissionBtn.checkPermissionBtn(permissionBtn.etaTablePermission.etaTable_excel)&&sourceMap[$route.path]===1" type="primary" style="margin-right:20px" @click="goAddSheetHandle"
           >添加Excel表格</el-button >
+
           <el-button v-if="permissionBtn.checkPermissionBtn(permissionBtn.etaTablePermission.etaTable_customize_data_sheetAdd)&&sourceMap[$route.path]===2" type="primary" style="margin-right:20px" @click="goAddSheetHandle">添加时间序列表格</el-button >
+
           <el-button v-if="permissionBtn.checkPermissionBtn(permissionBtn.etaTablePermission.etaTable_customize_mix_sheetAdd)&&sourceMap[$route.path]===3" type="primary" @click="goAddSheetHandle">添加混合表格</el-button >
 
+          <el-checkbox 
+            v-model="isShowMe"
+            style="margin-left:20px"
+            @change="() => { getTreeData();getPublicList() }"
+          >只看我的</el-checkbox>
+
         </div>
         <div class="search-cont">
           <el-select
@@ -90,6 +98,14 @@
                   alt=""
                   style="width: 14px; height: 14px; margin-right: 8px"
                 />
+                <!-- 添加子 -->
+								<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.ExcelInfoId&&isSheetBtnShow('classifyOpt_edit')&&node.level<3"
+								/>
                 <img
                   src="~@/assets/img/set_m/edit.png"
                   alt=""
@@ -425,6 +441,8 @@ export default {
       },
       autoSaveType:'',//自动保存类型,有的自动保存后需要其他操作
       cancelAutoSave:false, //自动保存时延迟的
+
+      isShowMe: false//只看我的
     };
   },
   watch: {
@@ -502,7 +520,10 @@ export default {
 
     /* 获取表格分类 */
     getTreeData(params = null) {
-      sheetInterface.classifyList({Source: this.sourceMap[this.$route.path]}).then((res) => {
+      sheetInterface.classifyList({
+        Source: this.sourceMap[this.$route.path],
+        IsShowMe: this.isShowMe
+      }).then((res) => {
         const { Ret, Data } = res;
         if (Ret !== 200) return;
 
@@ -552,17 +573,45 @@ export default {
       this.dialog_title = "添加";
       this.classifyForm = {
         classify_name: "",
+        parentClassifyId: 0,
+        parentName:''
+      };
+      this.classifyDia = true;
+    },
+
+    // 递归节点
+		getNodeParentData(data,arr){
+			if(data.level===0) return
+			arr.push({ExcelClassifyName:data.data.ExcelClassifyName,ExcelClassifyId:data.data.ExcelClassifyId})
+			this.getNodeParentData(data.parent,arr)
+			return arr
+		},
+
+    /* 添加节点 */
+    addNode(node,data) {
+      let arr = []
+      arr = this.getNodeParentData(node,arr).reverse();
+      this.dialog_title = "添加";
+      /* 编辑目录 */
+      this.classifyForm = {
+        classify_name: "",
+        parentClassifyId: data.ExcelClassifyId,
+        parentName: arr.map(_=>_.ExcelClassifyName).join('/')
       };
       this.classifyDia = true;
     },
 
     /* 编辑节点 */
-    editNode(node, { ExcelClassifyName, ExcelClassifyId }) {
+    editNode(node, { ExcelClassifyName, ExcelClassifyId,ParentId }) {
+      let arr = []
+      arr = ParentId ? this.getNodeParentData(node.parent,arr).reverse() : [];
       this.dialog_title = "编辑";
       /* 编辑目录 */
       this.classifyForm = {
         classify_name: ExcelClassifyName,
         classify_id: ExcelClassifyId,
+        parentClassifyId: ParentId,
+        parentName: arr.map(_=>_.ExcelClassifyName).join('/')
       };
       this.classifyDia = true;
     },
@@ -774,7 +823,8 @@ export default {
         CurrentIndex: this.sheet_page,
         PageSize: this.sheet_pages_size,
         ExcelClassifyId: this.select_classify || 0,
-        Source: this.sourceMap[this.$route.path]
+        Source: this.sourceMap[this.$route.path],
+        IsShowMe: this.isShowMe
       }).then((res) => {
         if (res.Ret !== 200) return;
 

+ 9 - 3
src/views/edbHistoryPage.vue

@@ -29,7 +29,10 @@ export default {
         renderContent(h, data) {
             return (
                 <el-tooltip content={data.RuleTitle} placement='top' popper-class='node-tooltip'>
-                    <span class='node'>{data.EdbName}</span>
+                    {
+                        data.IsStop?<span class='node stop'>{data.EdbName+'(暂停更新)'}</span>
+                        :<span class='node'>{data.EdbName}</span>
+                    }
                 </el-tooltip>
             )
         },
@@ -42,13 +45,13 @@ export default {
             window.open(href, '_blank');
         },
         async getData() {
-            const res = await dataBaseInterface.getEdbCreateHistory({ EdbInfoId: Number(this.$route.query.edbId) })
+            const res = await dataBaseInterface.getEdbCreateHistory({ UniqueCode: this.$route.query.code})
             if (res.Ret !== 200) return
             this.treeData = res.Data;
         }
     },
     mounted(){
-        if(this.$route.query.edbId){
+        if(this.$route.query.code){
             this.getData()
         }
     }
@@ -110,6 +113,9 @@ export default {
                 }
             }
         }
+        .stop{
+            color:red;
+        }
     }
     .org-tree-node-children {
         .org-tree-node ~ .org-tree-node{

+ 12 - 7
src/views/mychart_manage/components/chartDetailDia.vue

@@ -338,7 +338,7 @@
                   `"
                   >来源:{{JSON.parse(chartInfo.SourcesFrom).text}}</span>
               </div>
-
+              
                <!-- 公历农历切换 只用于季节性图 -->
               <el-radio-group
                 v-if="chartInfo.ChartType === 2 && !chartInfo.WarnMsg"
@@ -360,6 +360,7 @@
                   fontSize: ${ JSON.parse(chartInfo.Instructions).fontSize }px
                 `"
               ></div>
+              <div class="chart-author">作者:{{chartInfo.SysUserRealName}}</div>
             </div>
 
           </div>
@@ -374,16 +375,16 @@
             border
           >
             <!-- 可配置展开 只用于默认图 季节性隐藏-->
-            <el-table-column type="expand" v-if="sameOptionType.includes(chartInfo.ChartType) && chartInfo.ChartType!==5 && chartInfo.Source===1">
+            <!-- <el-table-column type="expand" v-if="sameOptionType.includes(chartInfo.ChartType) && chartInfo.ChartType!==5 && chartInfo.Source===1">
               <template slot-scope="props">
                 <div class="options-cont">
-                  <!-- 堆叠图 或组合图中的堆叠类型 非第一项隐藏配置 -->
+                  //堆叠图 或组合图中的堆叠类型 非第一项隐藏配置
                   <template v-if="showYOptionsHandle(props.row,props.$index)">
                       <el-checkbox v-model="props.row.IsOrder">逆序</el-checkbox>
                       <el-radio-group v-model="props.row.IsAxis" size="mini">
                         <el-radio-button :label="1">左轴</el-radio-button>
                         <el-radio-button :label="0">右轴</el-radio-button>
-                        <!-- 指标有右轴时才可以选右2轴 不然没有右2这个概念的意义 -->
+                        //指标有右轴时才可以选右2轴 不然没有右2这个概念的意义
                         <el-radio-button 
                           v-if="[1,6].includes(chartInfo.ChartType)"
                           :label="2" 
@@ -491,7 +492,7 @@
                   </div>
                 </div>
               </template>
-            </el-table-column>
+            </el-table-column> -->
             <el-table-column
               v-for="item in tableColums"
               :key="item.label"
@@ -517,7 +518,6 @@
               label="操作"
               key="Copy"
               align="center"
-              v-if="chartInfo.Source!==1 || ![1,4,6].includes(chartInfo.ChartType)"
               width="110"
             >
               <template slot-scope="scope">
@@ -847,6 +847,11 @@ export default {
           EdbInfoType: _.EdbInfoType,
           LeadValue: _.EdbInfoType ? 0 : Number(_.LeadValue),
           LeadUnit: _.EdbInfoType ? '' : _.LeadUnit,
+          IsConvert:Number(_.IsConvert),
+          ConvertType:Number(_.ConvertType),
+          ConvertValue:Number(_.ConvertValue),
+          ConvertUnit:Number(_.IsConvert)?_.ConvertUnit:'',
+          ConvertEnUnit:Number(_.IsConvert)?_.ConvertEnUnit:''
         }))
       }
 
@@ -1626,7 +1631,7 @@ export default {
       .chart-author {
         color: #333;
         position: absolute;
-        bottom: 20px;
+        bottom: 10px;
         right: 38px;
       }
       .chartWrapper {

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

@@ -623,7 +623,7 @@ export default {
     /* 切换分类 */
     chooseClassify({MyChartClassifyId,fromPublic,AdminId}) {
       if(fromPublic!==1){
-        this.$refs.catalogTree.setCurrentKey(null)
+        this.$refs.catalogTree&&this.$refs.catalogTree.setCurrentKey(null)
       }
       this.select_classify = MyChartClassifyId;
       this.ispublic = fromPublic;

+ 25 - 17
src/views/ppt_manage/mixins/mixins.js

@@ -116,12 +116,14 @@ export default {
         //轴位置值相同的下标
         let sameSideIndex = chartData.findIndex(i => i.IsAxis === item.IsAxis);
         //y轴
+        const textZh = item.ConvertUnit||item.Unit
+        const textEn = item.ConvertEnUnit||item.UnitEn||item.ConvertUnit||item.Unit
         let yItem = {
           ...basicYAxis,
           title: {
-            text: item.Unit,
-            textCh:item.Unit,//中文单位
-            textEn:item.Unit?item.UnitEn:'',//英文单位,但如果无中文单位则不显示
+            text: textZh,
+            textCh:textZh,//中文单位
+            textEn:textZh?textEn:'',//英文单位,但如果无中文单位则不显示
             style:{
               ...chartTheme&&chartTheme.yAxisOptions.style
             },
@@ -280,9 +282,9 @@ export default {
         let yItem = {
           ...basicYAxis,
           title: {
-            text:item.Unit,
-            textCh:item.Unit,//中文单位
-            textEn:item.Unit?item.UnitEn:'',//英文单位,但如果无中文单位则不显示
+            text:item.ConvertUnit||item.Unit,
+            textCh:item.ConvertUnit||item.Unit,//中文单位
+            textEn:item.ConvertEnUnit||item.UnitEn||item.ConvertUnit||item.Unit,//英文单位,但如果无中文单位则不显示
             style:{
               ...chartTheme&&chartTheme.yAxisOptions.style
             },
@@ -423,6 +425,8 @@ export default {
       }
 
       //y轴
+      const textZh = chartData.ConvertUnit||chartData.Unit
+      const textEn = chartData.ConvertEnUnit||chartData.UnitEn||chartData.ConvertUnit||chartData.Unit
       seasonYdata = [{
         ...seasonOptions.yAxis,
         labels: {
@@ -436,10 +440,10 @@ export default {
           }
         },
         title: {
-          text:  `${chartData.Unit}`,
-          textCh:chartData.Unit, // 中文
+          text:  `${textZh}`,
+          textCh:textZh, // 中文
           // 中文不存在,无论英文有无都显示空
-          textEn:chartData.UnitEn||chartData.Unit, // 英文
+          textEn:textZh?textEn:'', // 英文
           style:{
             ...chartTheme&&chartTheme.yAxisOptions.style
           },
@@ -557,11 +561,13 @@ export default {
 
       const { IsOrder,ChartColor,MaxData,MinData } = chartData[0];
       //y轴
+      const textYZh = chartData[1].ConvertUnit||chartData[1].Unit
+      const textYEn = chartData[1].ConvertEnUnit||chartData[1].UnitEn||chartData[1].ConvertUnit||chartData[1].Unit
       let yAxis = {
         title: {
-          text:  `${chartData[1].Unit}`,
-          textCh:chartData[1].Unit,
-          textEn:chartData[1].Unit?chartData[1].UnitEn:'',
+          text:  `${textYZh}`,
+          textCh:textYZh,
+          textEn:textYZh?textYEn:'',
           style:{
             ...chartTheme&&chartTheme.yAxisOptions.style
           },
@@ -581,8 +587,8 @@ export default {
         },
         opposite: false,
         reversed: IsOrder,
-        min: Number(MinData),
-        max: Number(MaxData),
+        min: Number(chartData[1].MinData),
+        max: Number(chartData[1].MaxData),
         tickWidth: 1,
         tickLength: 5,
         lineWidth: 1,
@@ -617,6 +623,8 @@ export default {
         series.data.push([_.x,_.y])
       })
       
+      const textXZh = chartData[0].ConvertUnit||chartData[0].Unit
+      const textXEn = chartData[0].ConvertEnUnit||chartData[0].UnitEn||chartData[0].ConvertUnit||chartData[0].Unit
       this.options = {
         title: {
           text:''
@@ -626,9 +634,9 @@ export default {
         xAxis: {
           ...scatterXAxis,
           title: {
-            text:  `${chartData[0].Unit}`,
-            textCh:chartData[0].Unit,
-            textEn:chartData[0].Unit?chartData[0].UnitEn:'',
+            text:  `${textXZh}`,
+            textCh:textXZh,
+            textEn:textXZh?textXEn:'',
             style: {
               ...chartTheme&&chartTheme.xAxisOptions.style
             },

+ 53 - 14
src/views/ppt_manage/mixins/pptMixins.js

@@ -12,7 +12,7 @@ import futuresInterface from '@/api/modules/futuresBaseApi';
 import { fittingEquationInterface,statisticFeatureInterface,crossVarietyInterface } from '@/api/modules/chartRelevanceApi';
 import chartRelevanceApi from '@/api/modules/chartRelevanceApi.js';
 import { defaultOpts } from '@/utils/defaultOptions';
-import {formatPPTDate,checkPPTpageElemant,getStrSize,isShowPPTTitle,toTextProps,toJson,rgbaToHex} from '../newVersion/utils/untils.js';
+import {formatPPTDate,checkPPTpageElemant,getStrSize,isShowPPTTitle,toTextProps,toJson,rgbaToHex,getChartInfo} from '../newVersion/utils/untils.js';
 import FormatOne from '../newVersion/components/formatPage/FormatOne.vue';
 import FormatTwo from '../newVersion/components/formatPage/FormatTwo.vue';
 import FormatThree from '../newVersion/components/formatPage/FormatThree.vue';
@@ -22,9 +22,12 @@ import FormatSix from '../newVersion/components/formatPage/FormatSix.vue';
 import FormatSeven from '../newVersion/components/formatPage/FormatSeven.vue';
 import FormatEight from '../newVersion/components/formatPage/FormatEight.vue';
 import FormatNine from '../newVersion/components/formatPage/FormatNine.vue';
+import FormatTen from '../newVersion/components/formatPage/FormatTen.vue';
+import FormatEle from '../newVersion/components/formatPage/FormatEle.vue';
+import FormatTwelve from '../newVersion/components/formatPage/FormatTwelve.vue';
 export default {
   components:{ FormatOne,FormatTwo,FormatThree,
-    FormatFour,FormatFive,FormatSix,FormatSeven,FormatEight,FormatNine},
+    FormatFour,FormatFive,FormatSix,FormatSeven,FormatEight,FormatNine,FormatTen,FormatEle,FormatTwelve},
   data(){
     return{
       chartInfo:null,
@@ -467,12 +470,17 @@ export default {
       await this.listHandle(chartElements);
       this.initCharts(chartElements, page);
     },
-    async listHandle(chartElements) {
-			for(let i=0;i<chartElements.length;i++) {
-        if(!this.optionMap[chartElements[i].chartId])
-				await this.getchartData(chartElements[i].chartId);
-			}
-		},
+    async listHandle(chartElements,fromType='') {
+        for(let i=0;i<chartElements.length;i++) {
+            if(!this.optionMap[chartElements[i].chartId])
+                await this.getchartData(chartElements[i].chartId);
+                //由于演示页的图表没有await加载,在这里更新每一张图表的信息
+                if(fromType==='present'){
+                    let temp = getChartInfo(this.optionMap[chartElements[i].chartId])
+                    this.$store.commit('SET_CHART_INFO',{chartId:chartElements[i].chartId,chartInfo:temp})
+                }
+            }
+        },
     async sheetListHandle(sheetElements){
       for(let i=0;i<sheetElements.length;i++){
         if(!this.sheetDataMap[sheetElements[i].sheetId])
@@ -532,10 +540,32 @@ export default {
     /* 主题样式*/
     const chartTheme =  ChartThemeStyle ? JSON.parse(ChartThemeStyle) : null;
 
+      console.log(options)
       this.$nextTick(() => {
         let is_linear = options.series 
           ? options.series.some(_ => _.chartType === 'linear')
           : false ;
+
+          /* 根据板式控制的季节图x轴的刻度数
+              板式1 不管  其余3个
+              板式10 12的曲线,堆积柱,组合 也固定3个 其余板式不管
+            */
+          const { modelId } = this.pageList[index];
+          let minData=[],maxData=[];
+          if([1,2,4,6].includes(MyChartType)) {
+            options.series.forEach(item => {
+              minData.push(item.data[0][0])
+              maxData.push(item.data[item.data.length-1][0])
+            })
+          }
+          
+          let tickInterval = undefined;
+          if((modelId!==1&&MyChartType===2) 
+            || ([1,4,6].includes(MyChartType)&&[10,12].includes(modelId))) {
+              tickInterval = (Math.max(...maxData)-Math.min(...minData))/4;
+          }
+        
+
         //title样式
         let titleHTML = null
         //中英文发布页需设置title换行
@@ -545,14 +575,15 @@ export default {
         const isPublish = this.$route.path==='/pptpublish'||this.$route.path==='/pptenpublish'
         if(isShowTitle){
           titleHTML = `<div style="
-            textAlign:${chartTheme&&chartTheme.titleOptions.align};
-            fontSize:${chartTheme&&chartTheme.titleOptions.style.fontSize}px;
-            color:${chartTheme&&chartTheme.titleOptions.style.color}
+            text-align:${chartTheme&&chartTheme.titleOptions.align};
+            font-size:${chartTheme&&chartTheme.titleOptions.style.fontSize}px;
+            color:${chartTheme&&chartTheme.titleOptions.style.color};
+            height:18px;
           ">
             ${options.MyChartTitle}
           </div>`
         }
-
+        const titleOption = isPublish&&isShowTitle?{marginTop:25}:{}
         let SpecialOption = {
           chart: {
             ...defaultOpts.chart,
@@ -561,7 +592,8 @@ export default {
             animation: false,
             backgroundColor: "rgba(0,0,0,0)",
             renderTo:$(`#${refName}`)[0],
-            ...options.chart||{}
+            ...options.chart||{},
+            ...titleOption
           },
           legend: {
             ...defaultOpts.legend,
@@ -572,13 +604,14 @@ export default {
             text: isShowTitle?newStr:null,
             margin:0,
             useHTML:false,
+            floating:true,
             style:{...chartTheme&&chartTheme.titleOptions.style},
             align: (chartTheme&&chartTheme.titleOptions.align) || (total>count?'left':'center'),
           }:{
             text: titleHTML,
             useHTML:true,
             margin:0,
-            style:{left:0}
+            style:{textAlign:chartTheme&&chartTheme.titleOptions.align,left:0,width:'100%'}
           },
           plotOptions: {
             ...defaultOpts.plotOptions,
@@ -590,6 +623,10 @@ export default {
               }
             },
           },
+          xAxis: {
+            ...options.xAxis,
+            tickInterval: is_linear ? undefined : tickInterval
+          }
         }
         //奇怪柱不堆叠
         let secialBarOpt = (options.series.some(_ => _.chartType === 'linear') && options.series.some(_ => _.chartType === 'linear')) ? {
@@ -603,6 +640,8 @@ export default {
 
         if(!$(`#${refName}`)[0]) return
 
+        console.log(SpecialOption)
+
         if(is_linear)
           Highcharts.chart({
             // Highcharts 配置

+ 10 - 5
src/views/ppt_manage/newVersion/components/catalog/chooseShareUserDia.vue

@@ -14,7 +14,7 @@
       <div style="margin-bottom: 20px;">
         <label style="margin-right: 40px">共享用户</label>
         <el-radio-group v-model="share_type" size="mini" @change="select_users=[]">
-          <el-radio :label="1">全部ficc研究员</el-radio>
+          <el-radio :label="1">全部用户</el-radio>
           <el-radio :label="2">指定成员</el-radio>
         </el-radio-group>
       </div>
@@ -26,8 +26,10 @@
         :show-all-levels="false"
         filterable
         :props="{
+          value:'ItemId',
+          label:'ItemName',
+          children:'Children',
           expandTrigger: 'hover',
-          children: 'ResearcherList',
           emitPath: false,
           multiple: true
         }"
@@ -54,7 +56,7 @@
 </template>
 
 <script>
-import { roadshowInterence,pptInterface } from '@/api/api.js';
+import { roadshowInterence,pptInterface,dataAuthInterface } from '@/api/api.js';
 import {pptEnInterface} from '@/api/modules/pptEnApi.js';
 export default {
   props: {
@@ -89,9 +91,12 @@ export default {
 
     /* 获取研究员列表 */
     async getResearcherList() {
-      const res = await roadshowInterence.getResearcherList();
+      // const res = await roadshowInterence.getResearcherList();
+      // 换成全部系统用户
+      const res = await dataAuthInterface.userSearch();
       if (res.Ret !== 200) return
-      this.researcherList = this.formatResearcherList(res.Data);
+      // this.researcherList = this.formatResearcherList(res.Data);
+      this.researcherList = res.Data || []
     },
 
     // 对获取到的研究员列表做处理

+ 11 - 4
src/views/ppt_manage/newVersion/components/editor/AddFormat.vue

@@ -29,6 +29,9 @@ import FormatPreSix from "@/views/ppt_manage/newVersion/components/formatPreview
 import FormatPreSeven from "@/views/ppt_manage/newVersion/components/formatPreview/FormatPreSeven";
 import FormatPreEight from "@/views/ppt_manage/newVersion/components/formatPreview/FormatPreEight";
 import FormatPreNine from "@/views/ppt_manage/newVersion/components/formatPreview/FormatPreNine";
+import FormatPreTen from "@/views/ppt_manage/newVersion/components/formatPreview/FormatPreTen";
+import FormatPreEle from "@/views/ppt_manage/newVersion/components/formatPreview/FormatPreEle";
+import FormatPreTwelve from "@/views/ppt_manage/newVersion/components/formatPreview/FormatPreTwelve";
 import {countComponentName} from '@/views/ppt_manage/newVersion/utils/untils';
 export default {
   name: "AddFormat",
@@ -47,7 +50,10 @@ export default {
     FormatPreSix,
     FormatPreSeven,
     FormatPreEight,
-    FormatPreNine
+    FormatPreNine,
+    FormatPreTen,
+    FormatPreEle,
+    FormatPreTwelve
   },
   data() {
     return {
@@ -91,11 +97,12 @@ export default {
     width: calc(100% - 40px);
     /* height: 120px; */
     display: flex;
+    /* flex-wrap: wrap; */
     justify-content: space-between;
     .format-item {
-      width: 95px;
-      height: 70px;
-      padding: 10px 10px 20px 10px;
+      width: 80px;
+      height: 56px;
+      padding: 5px;
       border: 1px solid transparent;
       cursor: pointer;
       &:hover {

+ 7 - 1
src/views/ppt_manage/newVersion/components/editor/ChangeFormatDialog.vue

@@ -45,6 +45,9 @@ import FormatPreSix from "@/views/ppt_manage/newVersion/components/formatPreview
 import FormatPreSeven from "@/views/ppt_manage/newVersion/components/formatPreview/FormatPreSeven";
 import FormatPreEight from "@/views/ppt_manage/newVersion/components/formatPreview/FormatPreEight";
 import FormatPreNine from "@/views/ppt_manage/newVersion/components/formatPreview/FormatPreNine";
+import FormatPreTen from "@/views/ppt_manage/newVersion/components/formatPreview/FormatPreTen";
+import FormatPreEle from "@/views/ppt_manage/newVersion/components/formatPreview/FormatPreEle";
+import FormatPreTwelve from "@/views/ppt_manage/newVersion/components/formatPreview/FormatPreTwelve";
 import {countComponentName} from '@/views/ppt_manage/newVersion/utils/untils';
 export default {
   props:{
@@ -65,7 +68,10 @@ export default {
     FormatPreSix,
     FormatPreSeven,
     FormatPreEight,
-    FormatPreNine
+    FormatPreNine,
+    FormatPreTen,
+    FormatPreEle,
+    FormatPreTwelve
   },
   data() {
     return {

+ 8 - 8
src/views/ppt_manage/newVersion/components/formatEl/ChartEl.vue

@@ -1,11 +1,10 @@
 <template>
-<div style="width:100%;height:100%; position:relative;" class="flex-center el-wrap"
+<div style="width:100%;height:100%; position:relative;" class="flex-center el-wrap chart-out-wrap"
   :draggable="isBtnShow"
 >
   <div
     class="chart-wrap"
     :id="`${$parent.isPreview?'preview_':''}chart_${index}_${position}`"
-    :style="(chartSourcesFrom&&chartSourcesFrom.isShow || chartInstructions&&chartInstructions.isShow) ? 'margin-bottom:20px' : ''"
   >
     <img :id="`${$parent.isPreview?'preview_':''}img_${index}_${position}`" />
   </div>
@@ -121,9 +120,9 @@ export default {
 <style scoped lang="scss">
 .tool-list{
   position:absolute;
-  width:90%;
-  top:2%;
-  left:5%;
+  width:95%;
+  top:0;
+  left:2%;
   display: flex;
   justify-content: space-between;
   .dragBtn,.copyBtn,.addBtn,.closeBtn{
@@ -133,11 +132,12 @@ export default {
     margin-left: auto;
   }
 }
+//图表自定义信息
 .chart-bottom-insruction-info{
-  width: 90%;
+  width: 95%;
   position: absolute;
-  left: 5%;
-  bottom: 20px;
+  left: 2%;
+  //bottom: 4%;//top,bottom在具体版式单独设置
   align-items: center;
   justify-content: space-between;
 }

+ 82 - 0
src/views/ppt_manage/newVersion/components/formatPage/FormatEle.vue

@@ -0,0 +1,82 @@
+<template>
+    <div class="total-wrap flex-column wrap-format-new format-ele" :style="{'pointer-events' :isPreview?'none':'auto'}">
+        <div class="line flex-center">
+            <div class="line-item flex-center" 
+                :style="pageItem.layers&&!isLayerShow()?TypeName(1)==='ChartEl'?'z-index:5':'z-index:3':''">
+                <component :data-position="1" :is="TypeName(1)" :ref="RefName(1)" :index="pageIndex" :position="1"
+                    :item="Item(1)" @dragstart.native="onDragStart" @dragover.native="onDragOver" @drop.native="onDrop"
+                    @getText="getText($event,1)" />
+            </div>
+            <div class="line-item flex-center"
+                :style="pageItem.layers&&!isLayerShow()?TypeName(2)==='ChartEl'?'z-index:5':'z-index:3':''">
+                <component :data-position="2" :is="TypeName(2)" :ref="RefName(2)" :index="pageIndex" :position="2"
+                    :item="Item(2)" @dragstart.native="onDragStart" @dragover.native="onDragOver" @drop.native="onDrop"
+                    @getText="getText($event,2)" />
+            </div>
+        </div>
+        <div class="line flex-center">
+            <div class="line-item flex-center"
+                :style="pageItem.layers&&!isLayerShow()?TypeName(3)==='ChartEl'?'z-index:5':'z-index:3':''">
+                <component :data-position="3" :is="TypeName(3)" :ref="RefName(3)" :index="pageIndex" :position="3"
+                    :item="Item(3)" @dragstart.native="onDragStart" @dragover.native="onDragOver" @drop.native="onDrop"
+                    @getText="getText($event,3)" />
+            </div>
+            <div class="line-item flex-center"
+                :style="pageItem.layers&&!isLayerShow()?TypeName(4)==='ChartEl'?'z-index:5':'z-index:3':''">
+                <component :data-position="4" :is="TypeName(4)" :ref="RefName(4)" :index="pageIndex" :position="4"
+                    :item="Item(4)" @dragstart.native="onDragStart" @dragover.native="onDragOver" @drop.native="onDrop"
+                    @getText="getText($event,4)" />
+            </div>
+        </div>
+        <div class="wrap-full-bottom bottom-15 flex-center"
+            :style="pageItem.layers&&!isLayerShow()?TypeName(5)==='ChartEl'?'z-index:5':'z-index:3':''">
+            <component :data-position="5" :is="TypeName(5)" :ref="RefName(5)" :index="pageIndex" :position="5"
+                :item="Item(5)" @dragstart.native="onDragStart" @dragover.native="onDragOver" @drop.native="onDrop"
+                @getText="getText($event,5)"></component>
+        </div>
+        <!-- 图层编辑模式 -->
+        <div class="layers" :id="`layers_${pageItem.id}`" v-if="isLayerShow()" @click.stop="clickLayer"
+            @contextmenu.stop="showLayerContentMenu">
+            <template v-for="item in pageItem.layers">
+                <component :is="getLayerElName(item)" :key="item.id" :elementInfo="item"
+                    :isActive="item.id===activeLayerEl.id&&!isClickLayer" :isLayerEdit="true"
+                    @click.stop.native="changeActEl(item)" @chooseThis="changeActEl(item)" v-on="$listeners">
+                </component>
+            </template>
+        </div>
+        <!-- 非图层编辑模式 -->
+        <template v-else>
+            <template v-for="item in pageItem.layers">
+                <component :is="getLayerElName(item)" :key="item.id" :elementInfo="item" :isActive="false"
+                    :isLayerEdit="false"></component>
+            </template>
+        </template>
+    </div>
+</template>
+
+<script>
+    import mixin from "./mixins";
+    import {
+        defaultPosition
+    } from "../../utils/config";
+    export default {
+        name: "formatEle",
+        mixins: [mixin],
+        data() {
+            return {
+                modelId: 11,
+                positionInfo: defaultPosition[11]
+            }
+        },
+    };
+</script>
+<style scoped lang="scss">
+.format-ele{
+    .line{
+        height: 41%;
+        .line-item{
+            width: 50%;
+        }
+    }
+}
+</style>

+ 1 - 1
src/views/ppt_manage/newVersion/components/formatPage/FormatNine.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="total-wrap flex-column" :style="{'pointer-events' :isPreview?'none':'auto'}">
+  <div class="total-wrap flex-column format-nine" :style="{'pointer-events' :isPreview?'none':'auto'}">
 <!--     <div class="wrap-full-top top-70 flex-center" 
       :style="{zIndex:pageItem.layers&&!isLayerShow()?'3':'',
       justifyContent:'space-between'}"> -->

+ 94 - 0
src/views/ppt_manage/newVersion/components/formatPage/FormatTen.vue

@@ -0,0 +1,94 @@
+<template>
+    <div class="total-wrap flex-column wrap-format-new format-ten" :style="{'pointer-events' :isPreview?'none':'auto'}">
+        <div class="line flex-center">
+            <div class="line-item flex-center"
+                :style="pageItem.layers&&!isLayerShow()?TypeName(1)==='ChartEl'?'z-index:5':'z-index:3':''">
+                <component :data-position="1" :is="TypeName(1)" :ref="RefName(1)" :index="pageIndex" :position="1"
+                    :item="Item(1)" @dragstart.native="onDragStart" @dragover.native="onDragOver" @drop.native="onDrop"
+                    @getText="getText($event,1)" />
+            </div>
+            <div class="line-item flex-center"
+                :style="pageItem.layers&&!isLayerShow()?TypeName(2)==='ChartEl'?'z-index:5':'z-index:3':''">
+                <component :data-position="2" :is="TypeName(2)" :ref="RefName(2)" :index="pageIndex" :position="2"
+                    :item="Item(2)" @dragstart.native="onDragStart" @dragover.native="onDragOver" @drop.native="onDrop"
+                    @getText="getText($event,2)" />
+            </div>
+            <div class="line-item flex-center"
+                :style="pageItem.layers&&!isLayerShow()?TypeName(3)==='ChartEl'?'z-index:5':'z-index:3':''">
+                <component :data-position="3" :is="TypeName(3)" :ref="RefName(3)" :index="pageIndex" :position="3"
+                    :item="Item(3)" @dragstart.native="onDragStart" @dragover.native="onDragOver" @drop.native="onDrop"
+                    @getText="getText($event,3)" />
+            </div>
+        </div>
+        <div class="line flex-center">
+            <div class="line-item flex-center"
+                :style="pageItem.layers&&!isLayerShow()?TypeName(4)==='ChartEl'?'z-index:5':'z-index:3':''">
+                <component :data-position="4" :is="TypeName(4)" :ref="RefName(4)" :index="pageIndex" :position="4"
+                    :item="Item(4)" @dragstart.native="onDragStart" @dragover.native="onDragOver" @drop.native="onDrop"
+                    @getText="getText($event,4)" />
+            </div>
+            <div class="line-item flex-center"
+                :style="pageItem.layers&&!isLayerShow()?TypeName(5)==='ChartEl'?'z-index:5':'z-index:3':''">
+                <component :data-position="5" :is="TypeName(5)" :ref="RefName(5)" :index="pageIndex" :position="5"
+                    :item="Item(5)" @dragstart.native="onDragStart" @dragover.native="onDragOver" @drop.native="onDrop"
+                    @getText="getText($event,5)" />
+            </div>
+            <div class="line-item flex-center"
+                :style="pageItem.layers&&!isLayerShow()?TypeName(6)==='ChartEl'?'z-index:5':'z-index:3':''">
+                <component :data-position="6" :is="TypeName(6)" :ref="RefName(6)" :index="pageIndex" :position="6"
+                    :item="Item(6)" @dragstart.native="onDragStart" @dragover.native="onDragOver" @drop.native="onDrop"
+                    @getText="getText($event,6)" />
+            </div>
+        </div>
+        <div class="wrap-full-bottom bottom-15 flex-center"
+            :style="pageItem.layers&&!isLayerShow()?TypeName(7)==='ChartEl'?'z-index:5':'z-index:3':''">
+            <component :data-position="7" :is="TypeName(7)" :ref="RefName(7)" :index="pageIndex" :position="7"
+                :item="Item(7)" @dragstart.native="onDragStart" @dragover.native="onDragOver" @drop.native="onDrop"
+                @getText="getText($event,7)"></component>
+        </div>
+        <!-- 图层编辑模式 -->
+        <div class="layers" :id="`layers_${pageItem.id}`" v-if="isLayerShow()" @click.stop="clickLayer"
+            @contextmenu.stop="showLayerContentMenu">
+            <template v-for="item in pageItem.layers">
+                <component :is="getLayerElName(item)" :key="item.id" :elementInfo="item"
+                    :isActive="item.id===activeLayerEl.id&&!isClickLayer" :isLayerEdit="true"
+                    @click.stop.native="changeActEl(item)" @chooseThis="changeActEl(item)" v-on="$listeners">
+                </component>
+            </template>
+        </div>
+        <!-- 非图层编辑模式 -->
+        <template v-else>
+            <template v-for="item in pageItem.layers">
+                <component :is="getLayerElName(item)" :key="item.id" :elementInfo="item" :isActive="false"
+                    :isLayerEdit="false"></component>
+            </template>
+        </template>
+    </div>
+</template>
+
+<script>
+    import mixin from "./mixins";
+    import {
+        defaultPosition
+    } from "../../utils/config";
+    export default {
+        name: "formatTen",
+        mixins: [mixin],
+        data() {
+            return {
+                modelId: 10,
+                positionInfo: defaultPosition[10]
+            }
+        },
+    };
+</script>
+<style lang="scss" scoped>
+.format-ten{
+    .line{
+        height:41%;
+        .line-item{
+            width:33%;
+        }
+    }
+}
+</style>

+ 88 - 0
src/views/ppt_manage/newVersion/components/formatPage/FormatTwelve.vue

@@ -0,0 +1,88 @@
+<template>
+    <div class="total-wrap flex-column wrap-format-new format-twelve" :style="{'pointer-events' :isPreview?'none':'auto'}">
+        <div class="line flex-center">
+            <div class="line-item flex-center"
+                :style="pageItem.layers&&!isLayerShow()?TypeName(1)==='ChartEl'?'z-index:5':'z-index:3':''">
+                <component :data-position="1" :is="TypeName(1)" :ref="RefName(1)" :index="pageIndex" :position="1"
+                    :item="Item(1)" @dragstart.native="onDragStart" @dragover.native="onDragOver" @drop.native="onDrop"
+                    @getText="getText($event,1)" />
+            </div>
+            <div class="line-item flex-center"
+                :style="pageItem.layers&&!isLayerShow()?TypeName(2)==='ChartEl'?'z-index:5':'z-index:3':''">
+                <component :data-position="2" :is="TypeName(2)" :ref="RefName(2)" :index="pageIndex" :position="2"
+                    :item="Item(2)" @dragstart.native="onDragStart" @dragover.native="onDragOver" @drop.native="onDrop"
+                    @getText="getText($event,2)" />
+            </div>
+            <div class="line-item flex-center"
+                :style="pageItem.layers&&!isLayerShow()?TypeName(3)==='ChartEl'?'z-index:5':'z-index:3':''">
+                <component :data-position="3" :is="TypeName(3)" :ref="RefName(3)" :index="pageIndex" :position="3"
+                    :item="Item(3)" @dragstart.native="onDragStart" @dragover.native="onDragOver" @drop.native="onDrop"
+                    @getText="getText($event,3)" />
+            </div>
+        </div>
+        <div class="line flex-center">
+            <div class="line-item flex-center"
+                :style="pageItem.layers&&!isLayerShow()?TypeName(4)==='ChartEl'?'z-index:5':'z-index:3':''">
+                <component :data-position="4" :is="TypeName(4)" :ref="RefName(4)" :index="pageIndex" :position="4"
+                    :item="Item(4)" @dragstart.native="onDragStart" @dragover.native="onDragOver" @drop.native="onDrop"
+                    @getText="getText($event,4)" />
+            </div>
+            <div class="line-item flex-center"
+                :style="pageItem.layers&&!isLayerShow()?TypeName(5)==='ChartEl'?'z-index:5':'z-index:3':''">
+                <component :data-position="5" :is="TypeName(5)" :ref="RefName(5)" :index="pageIndex" :position="5"
+                    :item="Item(5)" @dragstart.native="onDragStart" @dragover.native="onDragOver" @drop.native="onDrop"
+                    @getText="getText($event,5)" />
+            </div>
+            <div class="line-item flex-center"
+                :style="pageItem.layers&&!isLayerShow()?TypeName(6)==='ChartEl'?'z-index:5':'z-index:3':''">
+                <component :data-position="6" :is="TypeName(6)" :ref="RefName(6)" :index="pageIndex" :position="6"
+                    :item="Item(6)" @dragstart.native="onDragStart" @dragover.native="onDragOver" @drop.native="onDrop"
+                    @getText="getText($event,6)" />
+            </div>
+        </div>
+        <!-- 图层编辑模式 -->
+        <div class="layers" :id="`layers_${pageItem.id}`" v-if="isLayerShow()" @click.stop="clickLayer"
+            @contextmenu.stop="showLayerContentMenu">
+            <template v-for="item in pageItem.layers">
+                <component :is="getLayerElName(item)" :key="item.id" :elementInfo="item"
+                    :isActive="item.id===activeLayerEl.id&&!isClickLayer" :isLayerEdit="true"
+                    @click.stop.native="changeActEl(item)" @chooseThis="changeActEl(item)" v-on="$listeners">
+                </component>
+            </template>
+        </div>
+        <!-- 非图层编辑模式 -->
+        <template v-else>
+            <template v-for="item in pageItem.layers">
+                <component :is="getLayerElName(item)" :key="item.id" :elementInfo="item" :isActive="false"
+                    :isLayerEdit="false"></component>
+            </template>
+        </template>
+    </div>
+</template>
+
+<script>
+    import mixin from "./mixins";
+    import {
+        defaultPosition
+    } from "../../utils/config";
+    export default {
+        name: "formatTen",
+        mixins: [mixin],
+        data() {
+            return {
+                modelId: 10,
+                positionInfo: defaultPosition[10]
+            }
+        },
+    };
+</script>
+<style scoped lang="scss">
+.format-twelve{
+    .line{
+        height:48%;
+    }
+    .line-item{
+        width:33%;
+    }
+}
+</style>

+ 40 - 0
src/views/ppt_manage/newVersion/components/formatPreview/FormatPreEle.vue

@@ -0,0 +1,40 @@
+<template>
+    <div class="format-pre-wrap flex-center" style="flex-direction: column;">
+      <div class="line flex-center" style="justify-content: space-between;">
+        <img style="object-fit:fill !important;"
+          src="~@/assets/img/ppt_m/format-pic.png" />
+        <img style="object-fit:fill !important;"
+          src="~@/assets/img/ppt_m/format-pic.png" />
+      </div>
+      <div class="line flex-center" style="justify-content: space-between;">
+        <img style="object-fit:fill !important;"
+          src="~@/assets/img/ppt_m/format-pic.png" />
+        <img style="object-fit:fill !important;"
+          src="~@/assets/img/ppt_m/format-pic.png" />
+      </div>
+      <div class="line flex-center" style="width:100%;height:30%;">
+        <div class="full text" style="width:97%;height:90%;"></div>
+      </div>
+    </div>
+  </template>
+  
+  <script>
+  export default {
+    name: "formatPreEle",
+    data() {
+      return {};
+    },
+    methods: {},
+  };
+  </script>
+  
+  <style scoped lang="scss">
+  .format-pre-wrap{
+    .line{
+        img{
+            width:40%;
+        }
+    }
+  }
+  </style>
+  

+ 44 - 0
src/views/ppt_manage/newVersion/components/formatPreview/FormatPreTen.vue

@@ -0,0 +1,44 @@
+<template>
+    <div class="format-pre-wrap flex-center" style="flex-direction: column;">
+      <div class="line flex-center" style="justify-content: space-between;">
+        <img style="object-fit:fill !important;"
+          src="~@/assets/img/ppt_m/format-pic.png" />
+        <img style="object-fit:fill !important;"
+          src="~@/assets/img/ppt_m/format-pic.png" />
+        <img style="object-fit:fill !important;"
+          src="~@/assets/img/ppt_m/format-pic.png" />
+      </div>
+      <div class="line flex-center" style="justify-content: space-between;">
+        <img style="object-fit:fill !important;"
+          src="~@/assets/img/ppt_m/format-pic.png" />
+        <img style="object-fit:fill !important;"
+          src="~@/assets/img/ppt_m/format-pic.png" />
+        <img style="object-fit:fill !important;"
+          src="~@/assets/img/ppt_m/format-pic.png" />
+      </div>
+      <div class="line flex-center" style="width:100%;height:30%;">
+        <div class="full text" style="width:97%;height:90%;"></div>
+      </div>
+    </div>
+  </template>
+  
+  <script>
+  export default {
+    name: "formatPreTen",
+    data() {
+      return {};
+    },
+    methods: {},
+  };
+  </script>
+  
+  <style scoped lang="scss">
+  .format-pre-wrap{
+    .line{
+        img{
+            width:30%;
+        }
+    }
+  }
+  </style>
+  

+ 41 - 0
src/views/ppt_manage/newVersion/components/formatPreview/FormatPreTwelve.vue

@@ -0,0 +1,41 @@
+<template>
+    <div class="format-pre-wrap flex-center" style="flex-direction: column;">
+      <div class="line flex-center" style="justify-content: space-between;">
+        <img style="object-fit:fill !important;"
+          src="~@/assets/img/ppt_m/format-pic.png" />
+        <img style="object-fit:fill !important;"
+          src="~@/assets/img/ppt_m/format-pic.png" />
+        <img style="object-fit:fill !important;"
+          src="~@/assets/img/ppt_m/format-pic.png" />
+      </div>
+      <div class="line flex-center" style="justify-content: space-between;">
+        <img style="object-fit:fill !important;"
+          src="~@/assets/img/ppt_m/format-pic.png" />
+        <img style="object-fit:fill !important;"
+          src="~@/assets/img/ppt_m/format-pic.png" />
+        <img style="object-fit:fill !important;"
+          src="~@/assets/img/ppt_m/format-pic.png" />
+      </div>
+    </div>
+  </template>
+  
+  <script>
+  export default {
+    name: "formatPreTwelve",
+    data() {
+      return {};
+    },
+    methods: {},
+  };
+  </script>
+  
+  <style scoped lang="scss">
+  .format-pre-wrap{
+    .line{
+        img{
+            width:33%;
+        }
+    }
+  }
+  </style>
+  

+ 94 - 25
src/views/ppt_manage/newVersion/css/format.scss

@@ -144,8 +144,12 @@ $marginTop:14%;
       width: 100%;
       height: calc(100% - #{$marginTop});
       display: flex;
+      .chart-bottom-insruction-info{
+            margin-top: 0 !important;
+        }
     }
-    //版式1,6
+    //24.1.25 产品调整各个版式的位置,将chart-wrap宽度置为100% 高度尽量调高
+    //版式1,6 
     .full {
         width: 100%;
         height: 100%;
@@ -154,10 +158,9 @@ $marginTop:14%;
         align-items: flex-start;
         //chart容器
         .chart-wrap {
+            top:3%;
             width: 90%;
             height: 90%;
-            margin-top: 10px;
-            /* background-color: rgba(255, 192, 203, 0.507); */
         }
         .editor-wrap {
             width: 90%;
@@ -169,6 +172,9 @@ $marginTop:14%;
             top:0;
             right:calc(5% - 10px);
         }
+        .chart-bottom-insruction-info{
+            bottom:4%;
+        }
     }
 
     //版式2
@@ -178,10 +184,9 @@ $marginTop:14%;
         position: absolute;
         left: 0;
         top:0;
-        .chart-wrap {
-            width: 90%;
-            height: 80%;
-            /* background-color: rgba(0, 128, 0, 0.389); */
+        .chart-wrap{
+            width:100%;
+            height:80%;
         }
         .editor-wrap {
           width: 90%;
@@ -191,6 +196,9 @@ $marginTop:14%;
             top:calc(10% - 10px);
             right:calc(5% - 10px);
         }
+        .chart-bottom-insruction-info{
+            top:89%;
+        }
     }
 
     .word-full-right {
@@ -206,9 +214,12 @@ $marginTop:14%;
             height: 80%;
         }
         .chart-wrap {
-          width: 90%;
+          width: 100%;
           height: 80%;
-      }
+        }
+        .chart-bottom-insruction-info{
+            top:89%;
+        }
     }
 
     //版式345 7
@@ -224,13 +235,16 @@ $marginTop:14%;
             position: relative;
             &.top {
                 .chart-wrap {
-                    width: 90%;
+                    width: 100%;
                     height: 84%;
                 }
                 .closeBtn{
                     top:calc(4% - 10px);
                     right:2.5%;
                 }
+                .chart-bottom-insruction-info{
+                    top:89%;
+                }
             }
 
             &.bottom {
@@ -242,22 +256,24 @@ $marginTop:14%;
                     top:-1.5% !important;
                   }
                   .tool-list{
-                    top:-20px !important;
+                    top:-10px !important;
                   }
                 }
                 .chart-wrap {
-                    width: 90%;
+                    width: 100%;
                     height: 84%;
-                    /* background-color: coral; */
                 }
                 .closeBtn{
                     top:0;
                     right:2.5%;
                 }
+                .chart-bottom-insruction-info{
+                    top:84%;
+                }
             }
         }
         .chart-wrap {
-            width: 90%;
+            width: 100%;
             height: 80%;
         }
         .editor-wrap {
@@ -268,6 +284,9 @@ $marginTop:14%;
             top:calc(10% - 10px);
             right:calc(5% - 10px);
         }
+        .chart-bottom-insruction-info{
+            top:90%;
+        }
     }
 
     .wrap-full-right {
@@ -282,13 +301,16 @@ $marginTop:14%;
             position:relative;
             &.top {
                 .chart-wrap {
-                  width: 90%;
+                  width: 100%;
                   height: 84%;
                 }
                 .closeBtn{
                   top:calc(4% - 10px);
                   right:2.5%;
                 }
+                .chart-bottom-insruction-info{
+                    top:89%;
+                }
             }
 
             &.bottom {
@@ -300,11 +322,11 @@ $marginTop:14%;
                     top:-1.5% !important;
                   }
                   .tool-list{
-                    top:-20px !important;
+                    top:-10px !important;
                   }
                 }
                 .chart-wrap {
-                    width: 90%;
+                    width: 100%;
                     height: 84%;
                      /* background-color: royalblue; */
                 }
@@ -312,6 +334,9 @@ $marginTop:14%;
                     top:0;
                     right:2.5%;
                 }
+                .chart-bottom-insruction-info{
+                    top:84%;
+                }
             }
         }
         .editor-wrap {
@@ -319,13 +344,16 @@ $marginTop:14%;
             height: 84%;
         }
         .chart-wrap {
-            width: 90%;
+            width: 100%;
             height: 80%;
         }
         .closeBtn{
             top:calc(10% - 10px);
             right:calc(5% - 10px);
         }
+        .chart-bottom-insruction-info{
+            top:90%;
+        }
     }
 
     //版式8 9
@@ -335,9 +363,15 @@ $marginTop:14%;
       position:relative;
       &.top-70{
         height:70%;
+        .chart-bottom-insruction-info{
+            top:93%;
+        }
       }
       &.bottom-30{
         height: 30%;
+        .chart-bottom-insruction-info{
+            top:85%;
+        }
       }
       .half{
         height:100%;
@@ -363,9 +397,8 @@ $marginTop:14%;
         }
       }
       .chart-wrap {
-        width: 90%;
+        width: 100%;
         height: 90%;
-       /*  margin-top: 10px; */
       }
       .editor-wrap {
         width: 90%;
@@ -388,6 +421,11 @@ $marginTop:14%;
 
       }
     }
+    .format-nine{
+        .chart-bottom-insruction-info{
+            top:93%;
+        }
+    }
     
     //layer-mask 更改版式345 9布局, ↑原先样式保留不动
     .wrap-full-left-half{
@@ -398,7 +436,7 @@ $marginTop:14%;
       &.top {
         top:0;
         .chart-wrap {
-            width: 90%;
+            width: 100%;
             height: 84%;
         }
         .closeBtn{
@@ -416,7 +454,7 @@ $marginTop:14%;
           }
         }
         .chart-wrap {
-            width: 90%;
+            width: 100%;
             height: 84%;
         }
         .closeBtn{
@@ -437,7 +475,7 @@ $marginTop:14%;
       &.top {
         top:0;
         .chart-wrap {
-          width: 90%;
+          width: 100%;
           height: 84%;
         }
         .closeBtn{
@@ -455,7 +493,7 @@ $marginTop:14%;
           }
         }
         .chart-wrap {
-            width: 90%;
+            width: 100%;
             height: 84%;
         }
         .closeBtn{
@@ -470,7 +508,7 @@ $marginTop:14%;
     }
     .half{
       .chart-wrap {
-        width: 90%;
+        width: 100%;
         height: 90%;
        /*  margin-top: 10px; */
       }
@@ -480,4 +518,35 @@ $marginTop:14%;
       }
     }
 
+    //版式10 11 12
+    .wrap-format-new{
+        .line{
+            .line-item{
+                height:100%;
+                .chart-wrap{
+                    width:100%;
+                    height:90%;
+                }
+                .editor-wrap{
+                    width:90%;
+                    height:90%
+                }
+                .chart-bottom-insruction-info{
+                    top:92%;
+                }
+            }
+        }
+
+        .wrap-full-bottom {
+            position: absolute;
+            bottom: 0;
+        }
+        .bottom-15{
+            height: 18%;
+            .chart-bottom-insruction-info{
+                top:80%;
+            }
+        }
+    }
+
 }

+ 1 - 1
src/views/ppt_manage/newVersion/pptEnPresent.vue

@@ -301,7 +301,7 @@ export default {
         const sheetElements = this.pageList[i].elements.filter((item)=>{
           return item.type === 'sheet'
         })
-        this.listHandle(chartElements);
+        this.listHandle(chartElements,'present');
         this.sheetListHandle(sheetElements);
       }
       this.currentKey = 1

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

@@ -5,7 +5,9 @@
           <el-radio v-model="transChartType" :label="1">传服务器</el-radio>
           <el-radio v-model="transChartType" :label="2">本地转</el-radio>
         </div> -->
-        <el-dropdown split-button type="primary" @click="transHandle" @command="handleCommand" :disabled="isPublish">
+        <el-button  type="primary" plain style="width:182px;height:40px;" @click="$router.push({path:'/pptenlist'})">返回列表</el-button>
+        <el-button  type="primary" style="width:182px;height:40px;margin-left: 0;" @click="downloadPPT" :disabled="isPublish">下载</el-button>
+        <el-dropdown split-button style="width:182px;height:40px;" type="primary" @click="transHandle" @command="handleCommand" :disabled="isPublish">
           {{layoutStr}}
           <el-dropdown-menu slot="dropdown">
             <el-dropdown-item :command="1">10:7</el-dropdown-item>
@@ -13,7 +15,6 @@
             <el-dropdown-item :command="3">4:3</el-dropdown-item>
           </el-dropdown-menu>
         </el-dropdown>
-				<el-button  type="primary" plain style="width:120px;height:40px;" @click="$router.push({path:'/pptenlist'})">返回列表</el-button>
       </div>
       <!--全加载-->
       <template v-if="loadingAll">
@@ -131,6 +132,16 @@ export default {
       } 
       this.isPublish = false
     },
+    async downloadPPT(){
+        this.loadingInstance = this.$loading({
+            lock:true,
+            fullscreen: true,
+            text: "生成ppt中...",
+        });
+        this.isPublish = true
+        await this.pageToPptx('dowload') 
+        this.isPublish = false
+    },
     //计算ppt的版式名称
     getComponentName(modelId){
         return countComponentName(modelId);
@@ -226,7 +237,7 @@ export default {
       this.checkImg(base64Url,'svg')
     },
     //生成pptx
-    async pageToPptx(){
+    async pageToPptx(type){
       //开始计时
       const start = Date.now()
       const SlideMaster = _.cloneDeep(pptSlideMasterEn) 
@@ -441,6 +452,11 @@ export default {
       const end = Date.now()
       console.log("转换ppt用时:",Math.floor((end-start)/1000),' s')
       //pptx2.writeFile({ fileName: "test.pptx" });//本地测试用
+      //直接下载
+      if(type==='dowload'){
+        pptx2.writeFile({ fileName: `${this.coverInfo.page.Title||'unname'}.pptx` });
+        return
+      }
       this.publishLoading = this.$loading({
         fullscreen:true,
         text:"发布中..."
@@ -743,6 +759,9 @@ $titleColor:#333333;
     top:20px;
     right:3%;
     z-index:10;
+    display: flex;
+    flex-direction: column;
+    gap:20px;
   }
   .fixed-wrap{
     position:fixed;

+ 1 - 1
src/views/ppt_manage/newVersion/pptPresent.vue

@@ -299,7 +299,7 @@ export default {
         const sheetElements = this.pageList[i].elements.filter((item)=>{
           return item.type === 'sheet'
         })
-        this.listHandle(chartElements);
+        this.listHandle(chartElements,'present');
         this.sheetListHandle(sheetElements);
       }
       this.currentKey = 1

+ 38 - 5
src/views/ppt_manage/newVersion/pptPublish.vue

@@ -6,7 +6,9 @@
           <el-radio v-model="transChartType" :label="1">传服务器</el-radio>
           <el-radio v-model="transChartType" :label="2">本地转</el-radio>
         </div> -->
-        <el-dropdown split-button type="primary" @click="transHandle" @command="handleCommand" :disabled="isPublish">
+        <el-button  type="primary" plain style="width:182px;height:40px;" @click="$router.push({path:'/pptlist'})">返回列表</el-button>
+        <el-button  type="primary" style="width:182px;height:40px;margin-left: 0;" @click="downloadPPT" :disabled="isPublish">下载</el-button>
+        <el-dropdown split-button style="width:182px;height:40px;" type="primary" @click="transHandle" @command="handleCommand" :disabled="isPublish">
           {{layoutStr}}
           <el-dropdown-menu slot="dropdown">
             <el-dropdown-item :command="1">10:7</el-dropdown-item>
@@ -14,7 +16,6 @@
             <el-dropdown-item :command="3">4:3</el-dropdown-item>
           </el-dropdown-menu>
         </el-dropdown>
-				<el-button  type="primary" plain style="width:120px;height:40px;" @click="$router.push({path:'/pptlist'})">返回列表</el-button>
       </div>
       <!--全加载-->
       <template v-if="loadingAll">
@@ -26,7 +27,12 @@
           </div>
           <!-- 内容 -->
           <div class="ppt-item" v-for="(item,index) in pageList" :key="item.id">
-            <div class="title-wrap">
+            <div class="title-wrap"
+            :style="`
+                top:${lineClamp===2?'2%':getStrCount(item.title)<58?'5.5%':'0'};
+                height:${lineClamp===2?'12%':getStrCount(item.title)<58?'7%':'14%'};
+                -webkit-line-clamp:${lineClamp===2?2:3};`" 
+            :class="{'title-ellipsis':getStrCount(item.title)>lineClamp*57}">
               {{item.title}} 
             </div>
             <component
@@ -59,7 +65,7 @@ import Cover from './components/Cover.vue';
 import CustomCover from './components/CustomCover.vue';
 import TransReport from './components/catalog/transReport.vue';
 //import {pageList} from './utils/mock';
-import {countComponentName,pptConfigInit,toTextProps,toJson,svg2Base64,getImgRealSize,calcScale,getShapeOptions,createRandomCode,getTableData,getChartInfo,pptInit,rgbaToHex } from './utils/untils';
+import {countComponentName,pptConfigInit,toTextProps,toJson,svg2Base64,getImgRealSize,calcScale,countStrSize,getShapeOptions,createRandomCode,getTableData,getChartInfo,pptInit,rgbaToHex } from './utils/untils';
 import {marginTop,modelConfig,pptSlideMaster} from './utils/config';
 import pptmixin from '../mixins/pptMixins';
 import mixins from '../mixins/mixins';
@@ -120,7 +126,16 @@ export default {
       this.coefficient = coefficient
     }
   },
+  computed:{
+    lineClamp(){
+        return this.LayoutType===2?2:3
+    },
+  },
   methods: {
+    //计算title的字节数
+    getStrCount(title){
+        return countStrSize(title)
+    },
     async transHandle(){
       //需要校验PPT
       const {result,hintText} = this.checkPPT()
@@ -139,6 +154,16 @@ export default {
       }
       this.isPublish = false
     },
+    async downloadPPT(){
+        this.loadingInstance = this.$loading({
+            lock:true,
+            fullscreen: true,
+            text: "生成ppt中...",
+        });
+        this.isPublish = true
+        await this.pageToPptx('dowload') 
+        this.isPublish = false
+    },
     //计算ppt的版式名称
     getComponentName(modelId){
         return countComponentName(modelId);
@@ -238,7 +263,7 @@ export default {
       this.checkImg(base64Url,'svg')
     },
     //生成pptx
-    async pageToPptx(){
+    async pageToPptx(type){
       //开始计时
       const start = Date.now()
       const SlideMaster = _.cloneDeep(pptSlideMaster) 
@@ -456,6 +481,11 @@ export default {
       const end = Date.now()
       console.log("转换ppt用时:",Math.floor((end-start)/1000),' s')
       //pptx2.writeFile({ fileName: "test.pptx" });//本地测试用
+      //直接下载
+      if(type==='dowload'){
+        pptx2.writeFile({ fileName: `${this.coverInfo.page.Title||'unname'}.pptx` });
+        return
+      }
       this.publishLoading = this.$loading({
         fullscreen:true,
         text:"发布中..."
@@ -783,6 +813,9 @@ $titleColor:#333333;
     top:20px;
     right:3%;
     z-index:10;
+    display: flex;
+    flex-direction: column;
+    gap:20px;
   }
   .fixed-wrap{
     position:fixed;

+ 230 - 41
src/views/ppt_manage/newVersion/utils/config.js

@@ -83,6 +83,16 @@ export const formatPre = [{
     },{
       modelId:9,
       text:'上2图+文字'
+    },{
+        modelId:10,
+        text:'上6图+文字'
+    },
+    {
+        modelId:11,
+        text:'上4图+文字'
+    },{
+        modelId:12,
+        text:'上6图'
     }
 ]
 //版式id对应组件名
@@ -95,7 +105,10 @@ export const modelMap = {
     6: 'Six',
     7: 'Seven',
     8: 'Eight',
-    9: 'Nine'
+    9: 'Nine',
+    10:'Ten',
+    11:'Ele',
+    12:'Twelve'
 }
 //版式信息,用于判断图表/文字插入哪个位置
 export const modelInfo = {
@@ -167,7 +180,31 @@ export const modelInfo = {
       elChartNum:2,
       elTextNum:1,
       elTextPosition: 3
-    }
+    },
+    12:{
+        elNum:6,
+        elType:['chart','chart','chart','chart','chart','chart'],
+        positions:[1,2,3,4,5,6],
+        elChartNum:6,
+        elTextNum:0,
+        /* elTextPosition: 7 */
+    },
+    11:{
+        elNum:5,
+        elType:['chart','chart','chart','chart','text'],
+        positions:[1,2,3,4,5],
+        elChartNum:4,
+        elTextNum:1,
+        elTextPosition: 5
+      },
+    10:{
+        elNum:7,
+        elType:['chart','chart','chart','chart','chart','chart','text'],
+        positions:[1,2,3,4,5,6],
+        elChartNum:6,
+        elTextNum:1,
+        elTextPosition: 7
+    },
 }
 
 //给标题预留的位置,单位%
@@ -176,6 +213,7 @@ const titleHeight = 7
 const restHeight = 100 - marginTop
 //版式位置宽高设置,x,y,width,height都是基于整张ppt的百分比
 //百分比的值来自./css/format.scss ->.chart-wrap,.editor-wrap
+//用于发布页生成PPT
 export const modelConfig = [{
         modelId: 1,
         elements: [{
@@ -190,15 +228,15 @@ export const modelConfig = [{
         modelId: 2,
         elements: [{
             position: 1,
-            width: 100*0.6*0.9, 
+            width: 100*0.6, 
             height:(restHeight)*0.8 ,
-            x: (100*0.6-100*0.6*0.9)/2,
+            x: 0,
             y: ((restHeight)-(restHeight)*0.8)/2
         }, {
             position: 2,
-            width: 100*0.4*0.9, 
+            width: 100*0.4, 
             height: (restHeight)*0.8,
-            x: 60+(100*0.4-100*0.4*0.9)/2,// or 60
+            x: 60,// or 60
             y: ((restHeight)-(restHeight)*0.8)/2
         }]
     },
@@ -206,20 +244,20 @@ export const modelConfig = [{
         modelId: 3,
         elements: [{
             position: 1,
-            width: 100*0.5*0.9,
+            width: 100*0.5,
             height: (restHeight)*0.5*0.84,
-            x: (100*0.5-100*0.5*0.9)/2,
+            x: 0,
             y: ((restHeight)*0.5-(restHeight)*0.5*0.84)/2
         }, {
             position: 2,
-            width: 100*0.5*0.9,
+            width: 100*0.5,
             height: (restHeight)*0.5*0.84,
-            x: (100*0.5-100*0.5*0.9)/2,
+            x: 0,
             //这个位置的图表布局是align-items: flex-start,所以紧接着上一个图表
             y: 50-7/* +((restHeight)*0.5-(restHeight)*0.5*0.84)/2 */,//or 50
         }, {
             position: 3,
-            width: 100*0.5*0.9,
+            width: 100*0.5,
             height: (restHeight)*0.84,
             x: 50,
             y: ((restHeight)-(restHeight)*0.84)/2
@@ -229,27 +267,27 @@ export const modelConfig = [{
         modelId: 4,
         elements: [{
             position: 1,
-            width: 100*0.5*0.9,
+            width: 100*0.5,
             height: (restHeight)*0.5*0.84,
-            x: (100*0.5-100*0.5*0.9)/2,
+            x: 0,
             y: ((restHeight)*0.5-(restHeight)*0.5*0.84)/2
         }, {
             position: 2,
-            width: 100*0.5*0.9,
+            width: 100*0.5,
             height: (restHeight)*0.5*0.84,
-            x: (100*0.5-100*0.5*0.9)/2,
+            x: 0,
             y: 50-7/* +((restHeight)*0.5-(restHeight)*0.5*0.84)/2 */,//or 50
         }, {
             position: 3,
-            width: 100*0.5*0.9,
+            width: 100*0.5,
             height: (restHeight)*0.5*0.84,
-            x: 50+(100*0.5-100*0.5*0.9)/2,//or 50
+            x: 50,//or 50
             y: ((restHeight)*0.5-(restHeight)*0.5*0.84)/2
         }, {
             position: 4,
-            width: 100*0.5*0.9,
+            width: 100*0.5,
             height: (restHeight)*0.5*0.84,
-            x: 50+(100*0.5-100*0.5*0.9)/2,
+            x: 50,
             y: 50-7/* +((restHeight)*0.5-(restHeight)*0.5*0.84)/2 */,//or 50
         }]
     },
@@ -257,27 +295,27 @@ export const modelConfig = [{
         modelId: 5,
         elements: [{
             position: 1,
-            width: 100*0.5*0.9,
+            width: 100*0.5,
             height: (restHeight)*0.5*0.84,
-            x: (100*0.5-100*0.5*0.9)/2,
+            x: 0,
             y: ((restHeight)*0.5-(restHeight)*0.5*0.84)/2
         }, {
             position: 2,
-            width: 100*0.5*0.9,
+            width: 100*0.5,
             height: (restHeight)*0.5*0.84,
-            x: (100*0.5-100*0.5*0.9)/2,
+            x: 0,
             y: 50-7/* +((restHeight)*0.5-(restHeight)*0.5*0.84)/2 */,//or 50
         }, {
             position: 3,
-            width: 100*0.5*0.9,
+            width: 100*0.5,
             height: (restHeight)*0.5*0.84,
-            x: 50+(100*0.5-100*0.5*0.9)/2,//or 50
+            x: 50,//or 50
             y: ((restHeight)*0.5-(restHeight)*0.5*0.84)/2
         }, {
             position: 4,
-            width: 100*0.5*0.9,
+            width: 100*0.5,
             height: (restHeight)*0.5*0.84,
-            x: 50+(100*0.5-100*0.5*0.9)/2,
+            x: 50,
             y: 50-7/* +((restHeight)*0.5-(restHeight)*0.5*0.84)/2 */,//or 50
         }]
     },
@@ -295,15 +333,15 @@ export const modelConfig = [{
         modelId:7,
         elements:[{
             position:1,
-            width:100*0.5*0.9,
+            width:100*0.5,
             height:(restHeight)*0.8,
-            x:(100*0.5 - 100*0.5*0.9)/2,
+            x:0,
             y:((restHeight)-(restHeight)*0.8)/2
         },{
             position:2,
-            width:100*0.5*0.9,
+            width:100*0.5,
             height:(restHeight)*0.8,
-            x:50+(100*0.5 - 100*0.5*0.9)/2,
+            x:50,
             y:((restHeight)-(restHeight)*0.8)/2
         }]
     },
@@ -311,16 +349,16 @@ export const modelConfig = [{
       modelId:8,
       elements:[{
         position:1,
-        width:100*0.9,
+        width:100,
         height:(restHeight)*0.7*0.9,
-        x:(100-100*0.9)/2,
+        x:0,
         y:(restHeight*0.7-restHeight*0.7*0.9)/2
       },
       {
         position:2,
-        width:100*0.9,
+        width:100,
         height:(restHeight)*0.3*0.8,
-        x:(100-100*0.9)/2,
+        x:0,
         y:60
       }]
     },
@@ -328,26 +366,152 @@ export const modelConfig = [{
       modelId:9,
       elements:[{
         position:1,
-        width:100*0.5*0.9,
+        width:100*0.5,
         height:(restHeight)*0.7*0.9,
-        x:(100*0.5-100*0.5*0.9)/2,
+        x:0,
         y:(restHeight*0.7-restHeight*0.7*0.9)/2
       },
       {
         position:2,
-        width:100*0.5*0.9,
+        width:100*0.5,
         height:(restHeight)*0.7*0.9,
-        x:50+(100*0.5-100*0.5*0.9)/2,
+        x:50,
         y:(restHeight*0.7-restHeight*0.7*0.9)/2
       },
       {
         position:3,
         width:100*0.9,
         height:(restHeight)*0.3*0.8,
-        x:(100-100*0.9)/2,
+        x:0,
         y:60
       }
     ]
+    },{
+        modelId:12,
+        elements:[{
+            position:1,
+            width:33,
+            height:(restHeight)*0.48*0.9,
+            x:0,
+            y:(restHeight*0.48*0.1)/2
+        },{
+            position:2,
+            width:33,
+            height:(restHeight)*0.48*0.9,
+            x:33,
+            y:(restHeight*0.48*0.1)/2
+        },
+        {
+            position:3,
+            width:33,
+            height:(restHeight)*0.48*0.9,
+            x:33*2,
+            y:(restHeight*0.48*0.1)/2
+        },
+        {
+            position:4,
+            width:33,
+            height:(restHeight)*0.48*0.9,
+            x:0,
+            y:(restHeight)*0.48
+        },
+        {
+            position:5,
+            width:33,
+            height:(restHeight)*0.48*0.9,
+            x:33,
+            y:(restHeight)*0.48
+        },
+        {
+            position:6,
+            width:33,
+            height:(restHeight)*0.48*0.9,
+            x:33*2,
+            y:(restHeight)*0.48
+        }]
+    },{
+        modelId:11,
+        elements:[{
+            position:1,
+            width:50,
+            height:(restHeight)*0.40*0.9,
+            x:0,
+            y:(restHeight*0.4*0.1)/2
+        },{
+            position:2,
+            width:50,
+            height:(restHeight)*0.40*0.9,
+            x:50,
+            y:(restHeight*0.4*0.1)/2
+        },{
+            position:3,
+            width:50,
+            height:(restHeight)*0.40*0.9,
+            x:0,
+            y:38
+        },{
+            position:4,
+            width:50,
+            height:(restHeight)*0.40*0.9,
+            x:50,
+            y:38
+        },{
+            position:5,
+            width:100*0.9,
+            height:(restHeight)*0.18*0.8,
+            x:0,
+            y:74
+        }]
+    },{
+        modelId:10,
+        elements:[{
+            position:1,
+            width:33,
+            height:(restHeight)*0.4*0.9,
+            x:0,
+            y:(restHeight*0.4*0.1)/2
+        },{
+            position:2,
+            width:33,
+            height:(restHeight)*0.4*0.9,
+            x:33,
+            y:(restHeight*0.4*0.1)/2
+        },
+        {
+            position:3,
+            width:33,
+            height:(restHeight)*0.4*0.9,
+            x:33*2,
+            y:(restHeight*0.4*0.1)/2
+        },
+        {
+            position:4,
+            width:33,
+            height:(restHeight)*0.4*0.9,
+            x:0,
+            y:38
+        },
+        {
+            position:5,
+            width:33,
+            height:(restHeight)*0.4*0.9,
+            x:33,
+            y:38
+        },
+        {
+            position:6,
+            width:33,
+            height:(restHeight)*0.4*0.9,
+            x:33*2,
+            y:38
+        },
+        {
+            position:7,
+            width:100,
+            height:(restHeight)*0.18*0.8,
+            x:0,
+            y:74
+        }]
     }
 ]
 //ppt母版
@@ -579,6 +743,7 @@ export const BaseTextShape = {
   richContent:''
 }
 //默认情况下,版式内部位置对应的组件元素
+//用于版式渲染,版式内切换元素位置
 export const defaultPosition = {
   1:{//modelId
     1:{type:'chart'},//position
@@ -619,7 +784,31 @@ export const defaultPosition = {
     1:{type:'chart'},
     2:{type:'chart'},
     3:{type:'text'}
-  }
+  },
+  12:{
+    1:{type:'chart'},
+    2:{type:'chart'},
+    3:{type:'chart'},
+    4:{type:'chart'},
+    5:{type:'chart'},
+    6:{type:'chart'},
+  },
+  11:{
+    1:{type:'chart'},
+    2:{type:'chart'},
+    3:{type:'chart'},
+    4:{type:'chart'},
+    5:{type:'text'},
+  },
+  10:{
+    1:{type:'chart'},
+    2:{type:'chart'},
+    3:{type:'chart'},
+    4:{type:'chart'},
+    5:{type:'chart'},
+    6:{type:'chart'},
+    7:{type:'text'}
+  },
 }
 //画笔工具栏
 export const boardTool = [

+ 47 - 4
src/views/ppt_manage/newVersion/utils/untils.js

@@ -140,7 +140,7 @@ export const toTextProps = (json) => {
       if ('tagName' in item && item.tagName === 'br') {
         slices.push({ text: '', options: { breakLine: true } })
       } else if ('content' in item) {
-            const transStr = /(&lt;|&gt;|&ldquo;|&rdquo;|&amp;|&lsquo;|&rsquo;|&mdash;|&ge;|&le;|&middot;)/g
+            const transStr = /(&lt;|&gt;|&ldquo;|&rdquo;|&amp;|&lsquo;|&rsquo;|&mdash;|&ge;|&le;|&middot;|&oslash;|&Oslash;|&empty;)/g
             const text = item.content.replace(/\n/g, '').replace(/&nbsp;/g, ' ').replace(transStr, replacer)
             const options = {}
 
@@ -205,6 +205,7 @@ export const toTextProps = (json) => {
   return slices
 }
 //将text中被转义的字符转义回来,如:a<b 在富文本内会被转义成 a&lt;b
+//https://www.cnblogs.com/tiancixiong/p/13581746.html
 const replacer = (_, p1) => {
     return {
         "&lt;": "<",
@@ -217,7 +218,10 @@ const replacer = (_, p1) => {
         "&mdash;":'——',
         "&ge;":'≥',
         "&le;":'≤',
-        "&middot;":'·'
+        "&middot;":'·',
+        "&oslash;":'ø',
+        "&Oslash;":'Ø',
+        "&empty;":'∅'
     } [p1]
 }
 //根据字符串的字节长,在指定位置换行
@@ -292,6 +296,7 @@ export const changeCatalogArr = (arr)=>{
 }
 //计算各个版式下,文本框占据的真实宽度
 //基准:编辑页ppt-item的最大宽高:w:900px;h:630
+//用于transform:scale 文本元素,如果该版式没有文本框,可以直接给一个空数组
 export const getTextContentSize = (model,position)=>{
     const modelMapWidth = {
         1:{
@@ -330,7 +335,26 @@ export const getTextContentSize = (model,position)=>{
           1:[1,1,0.5,0.9],
           2:[1,1,0.5,0.9],
           3:[1,1,0.9]
-        }
+        },
+        12:{
+            1:[],2:[],3:[],4:[],5:[],6:[],7:[],
+        },
+        11:{
+            1:[1,1,0.45,1,0.9],
+            2:[1,1,0.45,1,0.9],
+            3:[1,1,0.45,1,0.9],
+            4:[1,1,0.45,1,0.9],
+            5:[1,1,0.9],
+        },
+        10:{
+            1:[1,1,0.33,1,0.9],
+            2:[1,1,0.33,1,0.9],
+            3:[1,1,0.33,1,0.9],
+            4:[1,1,0.33,1,0.9],
+            5:[1,1,0.33,1,0.9],
+            6:[1,1,0.33,1,0.9],
+            7:[1,1,0.9],
+        },
     }
     const modelMapHeight = {
         1:{
@@ -365,7 +389,26 @@ export const getTextContentSize = (model,position)=>{
           1:[0.86,0.7,1,0.9],
           2:[0.86,0.7,1,0.9],
           3:[0.86,0.3,0.8]
-        }
+        },
+        12:{
+            1:[],2:[],3:[],4:[],5:[],6:[],
+        },
+        11:{
+            1:[0.86,0.4,1,0.9],
+            2:[0.86,0.4,1,0.9],
+            3:[0.86,0.4,1,0.9],
+            4:[0.86,0.4,1,0.9],
+            5:[0.86,0.18,0.8],
+        },
+        10:{
+            1:[0.86,0.4,1,0.9],
+            2:[0.86,0.4,1,0.9],
+            3:[0.86,0.4,1,0.9],
+            4:[0.86,0.4,1,0.9],
+            5:[0.86,0.4,1,0.9],
+            6:[0.86,0.4,1,0.9],
+            7:[0.86,0.18,0.8],
+        },
     }
     const baseWidth=900,baseHeight=630
     const width = modelMapWidth[model][position].reduce((pre,curr)=>{

+ 32 - 14
src/views/supply_manage/components/varietySetDia.vue

@@ -33,7 +33,9 @@
             :show-all-levels="false"
             filterable
             :props="{
-              children: 'ResearcherList',
+              value:'ItemId',
+              label:'ItemName',
+              children:'Children',
               emitPath: false,
               multiple: true
             }"
@@ -63,7 +65,8 @@
 </template>
 
 <script>
-import {roadshowInterence} from '@/api/modules/roadshowApi.js';
+// import {roadshowInterence} from '@/api/modules/roadshowApi.js';
+import { dataAuthInterface } from '@/api/api.js';
 import * as supplyApi from '@/api/modules/supplyApi.js';
 export default {
   props: {
@@ -89,7 +92,8 @@ export default {
 
     'formData.users': {
       handler(nval) {
-        this.chooseUsers = this.researcherList.length && nval.map(_ => this.getUserName(_)).filter(_ => _);
+        // this.chooseUsers = this.researcherList.length && nval.map(_ => this.getUserName(_)).filter(_ => _);
+        this.chooseUsers = this.researcherList.length && this.getUserName()
       }
     }
   },
@@ -138,15 +142,21 @@ export default {
     },
 
     getUserName(id) {
-      let name = '';
-      this.researcherList.forEach(item => {
-        item.ResearcherList && item.ResearcherList.forEach(item2 => {
-            if(item2.AdminId === id) {
-              name = item2.RealName || '';
-            }
-        })
+      let checkedNodes=this.$refs.cascader.getCheckedNodes() || []
+      return checkedNodes.map(item =>{
+        return item.label
       })
-      return name
+
+      // let name = '';
+      // this.researcherList.forEach(item => {
+      //   console.log(item);
+      //   item.ResearcherList && item.ResearcherList.forEach(item2 => {
+      //       if(item2.ItemId === id) {
+      //         name = item2.ItemName || '';
+      //       }
+      //   })
+      // })
+      // return name
     },
 
     // 选择的研究员发生改变
@@ -158,12 +168,20 @@ export default {
 
     /* 获取研究员列表 */
     async getResearcherList() {
-      const res = await roadshowInterence.getResearcherList();
+      // const res = await roadshowInterence.getResearcherList();
+      // 换成全部系统用户
+      const res = await dataAuthInterface.userSearch();
       if (res.Ret !== 200) return
       
-      this.researcherList = this.formatResearcherList(res.Data);
+      // this.researcherList = this.formatResearcherList(res.Data);
+      this.researcherList = res.Data || []
 
-      if(this.form.VarietyId) this.chooseUsers = this.researcherList.length && this.formData.users.map(_ => this.getUserName(_)).filter(_ => _);
+      // if(this.form.VarietyId) this.chooseUsers = this.researcherList.length && this.formData.users.map(_ => this.getUserName(_)).filter(_ => _);
+      if(this.form.VarietyId){
+        this.$nextTick(()=>{
+          this.chooseUsers = this.researcherList.length && this.getUserName()
+        })
+      }
     },
 
     // 对获取到的研究员列表做处理

+ 259 - 0
src/views/system_manage/components/refreshConfig.vue

@@ -0,0 +1,259 @@
+<template>
+    <!-- 刷新配置 + 添加删除-->
+    <div class="refresh-config-wrap">
+        <!-- form -->
+        <el-form :model="dynamicForm" ref="dynamicForm" label-width="110px" class="dynamic-form">
+            <div class="group" v-for="(item,index) in dynamicForm.configList" :key="item.key">
+                <div class="delete btn-box" @click="deleteSetting(index)"
+                    v-if="index!==0"><i class="el-icon-delete"></i>删除</div>
+                <el-form-item label="刷新频率" class="item">
+                    <el-form-item :prop="`configList[${index}].frequency`" :rules="{required:true,message:'请选择刷新频率',trigger: 'blur'}">
+                        <el-select v-model="item.frequency">
+                            <el-option v-for="i in frequencyType" :key="i.key" 
+                                :label="i.label" :value="i.key"/>
+                        </el-select>
+                    </el-form-item>
+                    
+                    <!-- 每周 -->
+                    <el-form-item :prop="`configList[${index}].frequency_week`" v-if="item.frequency.includes('周')" :rules="{required:true,message:'请选择刷新频率',trigger: 'blur'}">
+                        <el-select v-model="item.frequency_week" class="full-input" key="week">
+                            <el-option v-for="i in weekList" :key="i.key" 
+                                :label="i.label" :value="i.key"/>
+                        </el-select>
+                    </el-form-item>
+                    
+                    <!-- 每旬、月、季、半年、年 -->
+                    <el-form-item :prop="`configList[${index}].frequency_last`" v-if="!item.frequency.includes('日')&&!item.frequency.includes('周')"
+                        :rules="{required:true,message:'请选择刷新频率',trigger: 'blur'}">
+                        <el-select v-model="item.frequency_last" :key="item.key" key="option">
+                            <el-option v-for="i in timeOptionList" :key="i.key" 
+                                :label="i.label" :value="i.key"/>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item :prop="`configList[${index}].frequency_n`" v-if="item.frequency_last==='n'&&!item.frequency.includes('日')&&!item.frequency.includes('周')"
+                        :rules="{required:true,message:'请选择刷新频率',trigger: 'blur'}">
+                        <el-input v-model="item.frequency_n" type="number" :min="1" :max="n_limit_map[item.frequency]||10">
+                            <template slot="prefix">N=</template>
+                        </el-input>
+                    </el-form-item>
+                </el-form-item>
+                <el-form-item class="item" label="时间">
+                    <el-form-item :prop="`configList[${index}].time`" :rules="{required:true,message:'请选择刷新时间',trigger: 'blur'}">
+                        <el-select v-model="item.time" class="full-input" key="single">
+                            <el-option v-for="i in timeList" :key="i" 
+                                :label="i" :value="i"/>
+                        </el-select>
+                    </el-form-item>
+                </el-form-item>
+                <el-form-item v-if="Source!==11"
+                    :prop="`configList[${index}].num`" label="刷新单元格数" class="item" :rules="{required:true,message:'请输入刷新单元格数',trigger: 'blur'}">
+                    <el-input v-model="item.num" type="number"></el-input>
+                    <el-checkbox v-model="item.isAll">全部刷新</el-checkbox>
+                </el-form-item>
+                <div class="line"></div>
+                <div class="add btn-box" @click="addSetting"
+                    v-if="index===dynamicForm.configList.length-1&&index<maxSetting-1">
+                    <i class="el-icon-circle-plus-outline"></i>添加刷新时间</div>
+            </div>
+        </el-form>
+    </div>
+</template>
+
+<script>
+const config = {
+    frequency:'',//刷新频率:
+    frequency_week:'',//频率为每周时,选择
+    frequency_last:'',//第N天或最后一天
+    frequency_n:1,
+    time:'',//时间
+    num:7,//刷新单元格数
+    isAll:false,//全部刷新
+}
+export default {
+    props:{
+        Source:{
+            type:Number,
+        },
+        defaultForm:{
+            type:Object
+        }
+    },
+    data() {
+        return {
+            maxSetting:5,//可设置的刷新时间数量
+            dynamicForm:{
+                configList:[{
+                        ...config,
+                        key:0
+                    }
+                ]
+            },
+            frequencyType:[
+                {label:'每自然日',key:'每自然日'},
+                {label:'每交易日',key:'每交易日'},
+                {label:'每周',key:'每周'},
+                {label:'每旬',key:'每旬'},
+                {label:'每月',key:'每月'},
+                {label:'每季',key:'每季'},
+                {label:'每半年',key:'每半年'},
+                {label:'每年',key:'每年'},
+            ],
+            //每周,可多选
+            weekList:[
+                {key:1,label:'周一'},
+                {key:2,label:'周二'},
+                {key:3,label:'周三'},
+                {key:4,label:'周四'},
+                {key:5,label:'周五'},
+                {key:6,label:'周六'},
+                {key:7,label:'周日'}
+            ],
+            //每旬、月、季、半年、年
+            timeOptionList:[
+                {label:'第N天',key:'n'},
+                {label:'最后一天',key:'last'}
+            ],
+            //时间选项,仅整点
+            timeList:[
+                '00:00','00:30','01:00','01:30','02:00','02:30','03:00','03:30',
+                '04:00','04:30','05:00','05:30','06:00','06:30','07:00','07:30',
+                '08:00','08:30','09:00','09:30','10:00','10:30','11:00','11:30',
+                '12:00','12:30','13:00','13:30','14:00','14:30','15:00','15:30',
+                '16:00','16:30','17:00','17:30','18:00','18:30','19:00','19:30',
+                '20:00','20:30','21:00','21:30','22:00','22:30','23:00','23:30'
+            ],
+            //N 范围 1-~
+            n_limit_map:{
+                '每旬':11,
+                '每月':31,
+                '每季':92,
+                '每半年':184,
+                '每年':365
+            },
+        };
+    },
+    watch:{
+        defaultForm:{
+            handler(newVal){
+                this.dynamicForm = this.formatForm(newVal)
+            },
+            deep:true
+        }
+    },
+    methods: {
+        addSetting(){
+            this.dynamicForm.configList.push({
+                ...config,
+                key:Date.now()
+            })
+        },
+        deleteSetting(index){
+            this.dynamicForm.configList.splice(index,1)
+        },
+        //将接口数据转换成form支持的格式
+        formatForm(form){
+            const {configList=[]} = form
+            if(!configList.length){
+                return {
+                    configList:[{
+                        ...config,
+                        key:0
+                    }]
+                }
+            }
+            const formatList = configList.map((item)=>{
+                let isOther = false
+                if(!item.RefreshFrequency.includes("周")&&!item.RefreshFrequency.includes("日")){
+                    isOther = true
+                }
+                return {
+                    frequency:item.RefreshFrequency,
+                    frequency_week:item.RefreshFrequency.includes("周")?item.RefreshFrequencyDay:'',
+                    frequency_last:isOther?(item.RefreshFrequencyDay===0?'last':'n'):'',
+                    frequency_n:item.RefreshFrequencyDay,
+                    time:item.RefreshTime,
+                    num:item.RefreshDataNum,
+                    isAll:Boolean(item.RefreshAllData)
+                }
+            })
+            return {
+                configList:formatList
+            }
+        },
+        //将数据转换成接口形式
+        getFormList(){
+            const list = this.dynamicForm.configList.map((item)=>{
+                //RefreshFrequencyDay: 每自然日、每交易日传0;每周传1~7;其他传n,最后一天n=0
+                let FrequencyDay = 0
+                if(item.frequency.includes("日")){
+                    FrequencyDay = 0
+                }else if(item.frequency.includes("周")){
+                    FrequencyDay = item.frequency_week
+                }else{
+                    FrequencyDay = item.frequency_last==='last'?0:item.frequency_n
+                }
+                return {
+                    RefreshFrequency:item.frequency,
+                    RefreshFrequencyDay:Number(FrequencyDay),
+                    RefreshTime:item.time,
+                    RefreshAllData:Number(item.isAll),
+                    RefreshDataNum:Number(item.num),
+                }
+            })
+            return list
+        }
+    },
+};
+</script>
+
+<style lang="scss">
+.refresh-config-wrap{
+        .dynamic-form{
+            .group{
+                position:relative;
+                padding: 30px 0 8px 0;
+                /* border-bottom: 1px solid #EBEFF6; */
+                &:first-child{
+                    padding-top: 0;
+                }
+                .line{
+                    height:1px;
+                    background-color: #EBEFF6;
+                }
+                .btn-box{
+                    cursor: pointer;
+                    i{
+                        margin-right: 8px;
+                        font-size: 16px;
+                    }
+                    &.add{
+                        display:inline-block;
+                        margin-top: 20px;
+                        color:#0052D9;
+                    }
+                    &.delete{
+                        position: absolute;
+                        right:10px;
+                        top:10px;
+                        color:#AD352F;
+                    }
+                }
+                .item{
+                    .el-input{
+                        width:110px;
+                    }
+                    .full-input{
+                        width: 100%;
+                        .el-input{
+                            width:100%;
+                        }
+                    }
+                    >.el-form-item__content{
+                        display: flex;
+                        gap:10px;
+                    }
+                }
+            }
+        }
+}
+</style>

+ 732 - 0
src/views/system_manage/dataRefreshSetting.vue

@@ -0,0 +1,732 @@
+<template>
+    <!-- 数据源刷新设置 -->
+    <div class="data-refresh-setting-wrap">
+        <div class="top-box">
+            <div class="select-box">
+                <span>选择数据源</span>
+                <el-select placeholder="请选择数据源" v-model="Source" @change="handleSourceChange">
+                    <el-option v-for="item in SourceList" :key="item.Source" 
+                    :label="item.SourceName" :value="item.Source"/>
+                </el-select>
+                <el-select placeholder="请选择数据源" v-model="SubSource" v-if="SubSourceList.length" @change="handleSubSourceChange">
+                    <el-option v-for="item in SubSourceList" :key="item.Source" 
+                    :label="item.SubSourceName" :value="item.SubSource"/>
+                </el-select>
+                <el-button type="primary" @click="showDialog(true)"
+                    v-permission="permissionBtn.sysDepartPermission.refresh_default"
+                >默认刷新时间</el-button>
+            </div>
+            
+            <el-input placeholder="指标ID/指标名称" prefix-icon="el-icon-search" clearable
+                v-model="selectOption.keyWord" @input="selectOptionChange('keyWord')"
+                v-if="![34,11].includes(Source)&&Source"></el-input>
+            
+        </div>
+        <div class="table-box" v-if="hasSelectOption">
+            <div class="table-select" v-loading="selectOptionLoading">
+                <div class="select-list">
+                    <el-select placeholder="终端编码" no-match-text="请选择完整数据源" clearable
+                        v-model="selectOption.terminalCode" @change="selectOptionChange('terminalCode')">
+                        <el-option v-for="i in terminalCodeList" :key="i.TerminalCode"
+                            :label="i.Name" :value="i.TerminalCode"/>
+                    </el-select>
+                    <el-cascader placeholder="ETA指标库分类" no-match-text="请选择完整数据源" clearable
+                        v-model="selectOption.classify" @change="selectOptionChange('classify')"
+                        :options="edbClassifyList" 
+                        :show-all-levels="false"
+                        collapse-tags
+                        :props="{
+                            emitPath:true,
+                            value:'ClassifyId',
+                            label:'ClassifyName',
+                            children:'Children',
+                            multiple:true
+                        }" />
+                    <el-cascader
+                        placeholder="创建人" no-match-text="请选择完整数据源" style="height: 40px;"
+                        v-model="selectOption.user" @change="selectOptionChange('user')"
+                        :options="userList"
+                        :props="{
+                            value: 'ItemId',
+                            label: 'ItemName',
+                            children: 'Children',
+                            emitPath: false,
+                            multiple:true,
+                        }"
+                        collapse-tags
+                        :show-all-levels="false"
+                        clearable
+                        filterable 
+                    />
+                    <el-select placeholder="频度" v-model="selectOption.frequency" @change="selectOptionChange('frequency')" multiple collapse-tags clearable>
+                        <el-option v-for="i in frequencyList" :key="i"
+                            :label="i" :value="i"
+                        />
+                    </el-select>
+                    <el-select placeholder="刷新状态" v-model="selectOption.state" @change="selectOptionChange('state')" clearable>
+                        <el-option label="启用刷新" value="启用"/>
+                        <el-option label="暂停刷新" value="暂停"/>
+                    </el-select>
+                </div>
+                <div class="select-other">
+                    <el-checkbox :indeterminate="isIndeterminate" v-model="isCheckAll" @change="listCheckAllChange">列表全选</el-checkbox>
+                    <el-button type="primary" @click="showDialog(false)"
+                        v-permission="permissionBtn.sysDepartPermission.refresh_time"
+                        :disabled="!tableData.length"
+                    >设置刷新时间</el-button>
+                    <el-button type="primary" @click="isSetStateDialogShow=true"
+                        v-permission="permissionBtn.sysDepartPermission.refresh_state"
+                        :disabled="!tableData.length"
+                    >设置刷新状态</el-button>
+                </div>
+            </div>
+            <el-table :data="tableData" border
+                ref="edbDataRef"
+                @selection-change="selectionChange"
+                @select="selectHandle" 
+                @select-all="selectAllHandle"
+                @sort-change="handleSortChange"
+                >
+                <!-- 多选 -->
+                <el-table-column
+                    align="center"
+                    type="selection"
+                    width="55">
+                </el-table-column>
+                <el-table-column v-for="column in columns" :key="column.key"
+                    :prop="column.key"
+                    :label="column.label"
+                    :min-width="column.minWidth"
+                    :sortable="column.sortable?column.sortable:false"
+                    align="center"
+                    >
+                    <template slot-scope="{row}">
+                        <span v-if="column.key==='IsStop'">
+                            {{row.IsStop?'暂停刷新':'启用刷新'}}
+                        </span>
+                        <span v-else>
+                            {{row[column.key]}}
+                        </span>
+                    </template>
+                </el-table-column>
+            </el-table>
+            <el-pagination 
+                :current-page="currentPage"
+                :page-size="pageSize"
+                :total="total"
+                @current-change="handleCurrentChange"
+            />
+        </div>
+        <!-- 默认刷新时间,设置刷新时间 -->
+        <el-dialog custom-class="refresh-setting-dialog"
+            :title="(isDefault?'默认':'设置')+'刷新时间'"
+            :visible.sync="isSetTimeDialogShow"
+            :close-on-click-modal="false"
+            :modal-append-to-body="false"
+            @close="isSetTimeDialogShow=false"
+            width="578px"
+            top="5vh"
+            v-dialogDrag
+            center
+        >
+            <div class="dialog-container" v-loading="defaultDialogLoading">
+                <!-- 默认刷新时间设置数据频度 -->
+                <div class="default-box" v-if="isDefault&&Source!==11">
+                    <label style="display: block;width:88px;text-align:right;padding-right: 12px;">数据频度</label>
+                    <el-select style="margin-left: 10px;" v-model="defaultFrequency" @change="handleDefaultChange">
+                        <el-option v-for="i in frequencyList" :key="i"
+                            :label="i" :value="i"
+                        />
+                    </el-select>
+                </div>
+                <!-- 刷新配置 -->
+                <div class="refresh-box">
+                    <RefreshConfig
+                        ref="refreshconfig"
+                        :Source="Source"
+                        :defaultForm="defaultForm"
+                    ></RefreshConfig>
+                </div>
+                
+            </div>
+            <!-- 弹窗按钮 -->
+            <div class="dialog-btn">
+                <el-button type="primary" plain @click="isSetTimeDialogShow=false">取消</el-button>
+                <el-button type="primary" @click="handleSetRefreshTime">确定</el-button>
+            </div>
+        </el-dialog>
+        <!-- 设置刷新状态 -->
+        <el-dialog custom-class="refresh-setting-dialog"
+            title="设置刷新状态"
+            :visible.sync="isSetStateDialogShow"
+            :close-on-click-modal="false"
+            :modal-append-to-body="false"
+            @close="isSetStateDialogShow=false"
+            width="578px"
+            top="5vh"
+            v-dialogDrag
+            center
+        >
+            <div class="dialog-container" style="text-align: center;margin:60px 0;">
+                <el-radio label="暂停" v-model="isState">暂停刷新</el-radio>
+                <el-radio label="启用" v-model="isState">启用刷新</el-radio>
+            </div>
+            <!-- 弹窗按钮 -->
+            <div class="dialog-btn">
+                <el-button type="primary" plain @click="isSetStateDialogShow=false">取消</el-button>
+                <el-button type="primary" @click="setRefreshStatus">确定</el-button>
+            </div>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import RefreshConfig from './components/refreshConfig.vue';
+import {dataRefreshInterface,dataAuthInterface} from '@/api/modules/dataApi.js';
+export default {
+    components: { RefreshConfig },
+    data() {
+        return {
+            Source:'',
+            SourceList:[],
+            SubSource:'',
+            SubSourceList:[],
+
+            frequencyList:['日度','周度','旬度','月度','季度','半年度','年度'],
+            terminalCodeList:[],
+            edbClassifyList:[],
+            userList:[],
+
+            selectOption:{
+                frequency:'',//频度
+                user:'',//创建人
+                classify:'',//分类
+                state:'',//状态
+                terminalCode:'',//终端编码
+                keyWord:'',//关键字
+                sortType:'',//升序降序
+                sortParam:'',//排序字段
+            },
+            hasSelectOption:false,
+            selectOptionLoading:false,
+
+            columns: [
+                {key: 'IndexCode',label: '指标编码'},
+                {key: 'IndexName',label: '指标全称',minWidth:150},
+                {key: 'EndDate',label: '最新日期',sortable:'custom'},
+                {key: 'EndValue',label: '最新值'},
+                {key: 'SysUserRealName',label: '创建人'}, 
+                {key: 'Frequency',label: '频度'},
+                {key: 'RefreshTime',label: '刷新时间',minWidth:150},
+                {key: 'IsStop',label: '刷新状态'}
+            ],
+            tableData: [],
+            tableDataIds:[],
+            pageSize:10,
+            currentPage:1,
+            total:0,
+
+            isSetTimeDialogShow: false,//设置刷新时间弹窗
+            defaultDialogLoading:false,//可能需要获取默认设置,增加loading
+            isDefault:false,//是否是默认刷新时间
+            defaultForm:{},//默认刷新时间的配置
+            defaultFrequency:'日度',//默认刷新时间的频率
+
+            isSetStateDialogShow:false,//设置刷新状态弹窗
+            isState:'启用',//启用刷新or暂停刷新
+            //全部全选
+            isIndeterminate:false,
+            isCheckAll:false,
+            isSelectAll:false,//为true时,selectList是剔除的指标,为false时selectList是已选择的指标
+            //已选择/已剔除的指标id
+            selectList:[],//监听table的select-all select
+            selectionReactCancel:false,
+        };
+    },
+    methods: {
+        //展示刷新时间弹窗
+        showDialog(isDefault){
+            this.isDefault = isDefault
+            this.isSetTimeDialogShow = true
+            if(isDefault){
+                //判断数据源是否选择
+                if(!this.Source){
+                    this.$message.warning("请选择数据源")
+                    return
+                }
+                /* if(this.SubSourceList.length&&!this.SubSource){
+                    this.$message.warning("请选择完整数据源")
+                    return
+                } */
+                //SMM不带频度
+                if(this.Source===11){
+                    this.defaultFrequency=''
+                }else{
+                    this.defaultFrequency = '日度'
+                }
+                this.handleDefaultChange()
+            }else{
+                //单独设置指标,需判断指标是否为单个
+                if((this.total===1&&!this.selectList.length)||(!this.isSelectAll&&this.selectList.length===1)){
+                    //单个则回显刷新时间
+                    this.getEdbRefreshDetail()
+                }else{
+                    this.defaultForm={}
+                }
+                
+            }
+        },
+        //获取对应频度下的默认刷新时间
+        handleDefaultChange(){
+            this.defaultDialogLoading = true
+            dataRefreshInterface.getDefaultConfig({
+                Frequency:this.defaultFrequency,
+                Source:Number(this.Source),
+                SubSource:Number(this.SubSource)
+            }).then(res=>{
+                this.defaultDialogLoading = false
+                if(res.Ret!==200) return 
+                let configList = res.Data||[]
+                configList = configList.map((item,index)=>{
+                    return {
+                        ...item,
+                        key:index
+                    }
+                })
+                this.defaultForm = {
+                    configList
+                }
+            })
+        },
+        //获取单个指标的刷新时间
+        getEdbRefreshDetail(){
+            this.defaultDialogLoading = true
+            let EdbInfoId = 0
+            if(this.total===1){
+                EdbInfoId = this.tableData[0].EdbInfoId
+            }else{
+                EdbInfoId = this.selectList[0]
+            }
+            dataRefreshInterface.getSimgleEdbRefreshTime({
+                EdbInfoId,
+                Source:Number(this.Source),
+                SubSource:Number(this.SubSource)
+            }).then(res=>{
+                this.defaultDialogLoading = false
+                if(res.Ret!==200) return 
+                let configList = res.Data||[]
+                configList = configList.map((item,index)=>{
+                    return {
+                        ...item,
+                        key:index
+                    }
+                })
+                this.defaultForm = {
+                    configList
+                }
+            })
+        },
+        //获取数据源列表
+        getSourceList(){
+            dataRefreshInterface.getDataSourceList().then(res=>{
+                if(res.Ret!==200) return 
+                this.SourceList = res.Data||[]
+            })
+        },
+        //一级数据源改变时,二级数据源和筛选项也重新赋值
+        handleSourceChange(){
+            const source = this.SourceList.find(i=>i.Source===this.Source)||{Child:[]}
+            this.SubSourceList = source.Child
+            this.SubSource=''
+            this.hasSelectOption = ![34,11].includes(this.Source)
+            if(this.hasSelectOption){
+                this.resetSelect()
+                this.tableData = []
+            }
+            //如果没有二级数据源,则请求表格筛选项数据;钢联化工,SMM没有筛选项数据
+            if(!this.SubSourceList.length&&this.hasSelectOption){
+                this.getSelectOption()
+                this.selectOptionChange()
+            }
+            //如果有二级数据源,默认选中第一个
+            if(this.SubSourceList.length){
+                this.SubSource = this.SubSourceList[0].SubSource
+                this.handleSubSourceChange()
+            }
+        },
+        handleSubSourceChange(){
+            this.getSelectOption()
+            this.selectOptionChange()
+        },
+        //获取终端编码列表
+        async getTerminalCodeList(){
+            if(!this.Source) return 
+            const res = await dataRefreshInterface.getTerminalList({
+                Source:Number(this.Source)
+            })
+            if(res.Ret!==200) return 
+            this.terminalCodeList = res.Data?res.Data.List||[]:[]
+        },
+        //获取分类列表
+        async getClassifyList(){
+            if(!this.Source) return 
+            const res = await dataRefreshInterface.getClassifyList({
+                Source:Number(this.Source)
+            })
+            if(res.Ret!==200) return 
+            this.edbClassifyList = res.Data||[]
+        },
+        //获取用户列表
+        getUserList() {
+            dataAuthInterface.userSearch({
+                KeyWord: ''
+            }).then(res => {
+                if(res.Ret !== 200) return 
+                this.userList = res.Data||[]
+            })
+        },
+        async getSelectOption(){
+            this.selectOptionLoading = true
+            //获取终端编码列表
+            await this.getClassifyList()
+            //获取分类列表
+            await this.getTerminalCodeList()
+            this.selectOptionLoading = false
+        },
+        //切换数据源时重置表格选项
+        resetSelect(){
+            this.terminalCodeList=[]
+            this.edbClassifyList = []
+            this.selectOption = {
+                frequency:'',
+                user:'',
+                classify:'',
+                state:'',
+                terminalCode:''
+            }
+            this.selectList=[]
+        },
+        //表格筛选项改变时触发
+        selectOptionChange(type){
+            this.currentPage = 1
+            this.getTableData('optionChange')
+        },
+        handleCurrentChange(page){
+            this.currentPage = page
+            this.getTableData()
+        },
+        async getTableData(type){
+            const {frequency,user,classify,state,terminalCode,keyWord,sortParam,sortType} = this.selectOption
+            const classifyArr = Array.isArray(classify)?classify:[]
+            const classifyId = [...new Set(classifyArr.join(',').split(','))]
+            const res = await dataRefreshInterface.getEdbTableList({
+                Source:Number(this.Source),
+                SubSource:Number(this.SubSource),
+                ClassifyId:classifyId.join(','),
+                TerminalCode:terminalCode,
+                SysUserId:Array.isArray(user)?user.join(','):user,
+                Frequency:Array.isArray(frequency)?frequency.join(','):frequency,
+                Keyword:keyWord,
+                Status:state,
+                SortParam:sortParam,
+                SortType:sortType,
+                PageSize:Number(this.pageSize),
+                CurrentIndex:Number(this.currentPage)
+            })
+            if(res.Ret!==200) return 
+            const {Paging,List} = res.Data||{}
+            this.tableData = List||[]
+            this.total = Paging.Totals||0
+            if(this.tableData.length>0){
+              this.tableDataIds = this.tableData.map(it => it.EdbInfoId)
+            }else{
+              this.tableDataIds = []
+            }
+            if(type==='optionChange'){
+                //如果是表格筛选项改变导致重新请求数据
+                //数据获取完成后,列表全选,表格全选
+                this.selectList = []
+                this.listCheckAllChange(true)
+            }else{
+                //若不是,数据获取完成后,查询列表全选的值
+                //若当页有数据在selectList内,则勾选/剔除
+                this.adjustSelection()
+            }
+        },
+        //勾选/取消勾选表格项
+        adjustSelection(){
+            this.selectionReactCancel=true
+            if(!this.isSelectAll){
+                this.selectList.map(it =>{
+                    let row = this.tableData.find(da => da.EdbInfoId==it)
+                    if(row){
+                        setTimeout(()=>{
+                            this.$refs.edbDataRef.toggleRowSelection(row,true)
+                        },10)
+                    }
+                })
+            }else{
+                this.$refs.edbDataRef && this.$refs.edbDataRef.clearSelection()
+                this.$refs.edbDataRef &&this.$refs.edbDataRef.toggleAllSelection()
+                this.selectList.map(it =>{
+                    let row = this.tableData.find(da => da.EdbInfoId==it)
+                    if(row){
+                        setTimeout(()=>{
+                            this.$refs.edbDataRef.toggleRowSelection(row,false)
+                        },50)
+                    }
+                })
+            }
+            setTimeout(()=>{
+                this.selectionReactCancel=false
+            },50)
+        },
+        //列表全选改变
+        listCheckAllChange(value){
+            this.selectList = []
+            this.isSelectAll = value
+            this.$refs.edbDataRef && this.$refs.edbDataRef.clearSelection()
+            if(value){
+                this.$refs.edbDataRef && this.$refs.edbDataRef.toggleAllSelection()
+            }
+        },
+        selectionChange(selection){
+            if(this.selectionReactCancel) return 
+            // selectAllHandle的触发在selectionChange后面,将selectionChange的逻辑延迟一下
+            setTimeout(()=>{
+                // 去重
+                let duplicateArr = Array.from(new Set(this.selectList))
+                //isSelectAll为true时,selectList表示需要剔除的项
+                //isSelectAll为false时,selectList表示需要勾选的项
+                //全选
+                if((duplicateArr.length == this.total && (!this.isSelectAll))|| (duplicateArr.length == 0 && this.isSelectAll)){
+                    this.isCheckAll = true
+                    this.isIndeterminate=false
+                //全不选
+                }else if((duplicateArr.length == 0 && (!this.isSelectAll))|| (duplicateArr.length == this.total && this.isSelectAll)){
+                    this.isCheckAll = false
+                    this.isIndeterminate=false
+                //半选
+                }else{
+                    this.isCheckAll = false
+                    this.isIndeterminate=true
+                }
+            },1)
+        },
+        selectHandle(selection,row){
+            if(this.selectionReactCancel) return 
+            let check = false; 
+            if(selection.some(it => it.EdbInfoId == row.EdbInfoId)){
+                // 勾选
+                if(this.isSelectAll){
+                    check=false
+                }else{
+                    check=true
+                }
+            }else{
+                // 取消勾选
+                if(this.isSelectAll){
+                    check=true
+                }else{
+                    check=false
+                }
+            }
+            if(check){
+                this.selectList.push(row.EdbInfoId)
+                }else{
+                this.selectList=this.selectList.filter(it => it!=row.EdbInfoId)
+            }
+        },
+        selectAllHandle(selection){
+            if(this.selectionReactCancel) return 
+            let check = false; 
+            if(selection && selection.length>0){
+                // 全选
+                if(this.isSelectAll){
+                    check=false
+                }else{
+                    check=true
+                }
+            }else{
+                // 全不选
+                if(this.isSelectAll){
+                    check=true
+                }else{
+                    check=false
+                }
+            }
+            if(check){
+                this.selectList =  [...this.selectList,...this.tableDataIds]
+            }else{
+                this.selectList = this.selectList.filter(it => !this.tableDataIds.includes(it))
+            }
+        },
+        //设置刷新时间
+        async handleSetRefreshTime(){
+            //校验表格
+            try{
+                await this.$refs.refreshconfig.$refs.dynamicForm.validate()
+            }catch(e){
+                console.log(e)
+                return
+            }
+            //转换数据格式
+            const list = this.$refs.refreshconfig.getFormList()
+            //判断是否是默认时间,走不同接口
+            if(this.isDefault){
+                this.setDefaultTime(list)
+            }else{
+                this.setRefreshTime(list)
+            }
+        },
+        setRefreshTime(list){
+            const {frequency,user,classify,state,terminalCode,keyWord} = this.selectOption
+            const classifyArr = Array.isArray(classify)?classify:[]
+            const classifyId = [...new Set(classifyArr.join(',').split(','))]
+            dataRefreshInterface.setRefreshTime({
+                Source:Number(this.Source),
+                SubSource:Number(this.SubSource),
+                ClassifyId:classifyId.join(','),
+                TerminalCode:terminalCode,
+                SysUserId:Array.isArray(user)?user.join(','):user,
+                Frequency:Array.isArray(frequency)?frequency.join(','):frequency,
+                Keyword:keyWord,
+                Status:state,
+                IsSelectAll:this.isSelectAll,
+                EdbSelectIdList:this.selectList,
+                List:list
+            }).then(res=>{
+                if(res.Ret!==200) return
+                this.$message.success("设置刷新时间成功")
+                this.selectOptionChange()
+                this.isSetTimeDialogShow = false
+            })
+        },
+        setDefaultTime(list){
+            dataRefreshInterface.setDefaultTime({
+                Source:Number(this.Source),
+                SubSource:Number(this.SubSource),
+                Frequency:this.defaultFrequency,
+                List:list
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.$message.success("设置默认刷新时间成功")
+                this.isSetTimeDialogShow = false
+            })
+        },
+        setRefreshStatus(){
+            const {frequency,user,classify,state,terminalCode,keyWord} = this.selectOption
+            const classifyArr = Array.isArray(classify)?classify:[]
+            const classifyId = [...new Set(classifyArr.join(',').split(','))]
+            dataRefreshInterface.setRefreshStatus({
+                Source:Number(this.Source),
+                SubSource:Number(this.SubSource),
+                ClassifyId:classifyId.join(','),
+                TerminalCode:terminalCode,
+                SysUserId:Array.isArray(user)?user.join(','):user,
+                Frequency:Array.isArray(frequency)?frequency.join(','):frequency,
+                Keyword:keyWord,
+                Status:state,
+                IsSelectAll:this.isSelectAll,
+                EdbSelectIdList:this.selectList,
+                ModifyStatus:this.isState
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.$message.success("设置刷新状态成功")
+                this.selectOptionChange()
+                this.isSetStateDialogShow = false
+            })
+        },
+        handleSortChange({prop,order}){
+            if(order){
+                this.selectOption.sortParam = 'end_date'
+                this.selectOption.sortType = order==='ascending'?'asc':'desc'
+            }else{
+                this.selectOption.sortParam = ''
+                this.selectOption.sortType = ''
+            }
+            this.selectOptionChange()
+        }
+    },
+    mounted(){
+        this.getSourceList()
+        this.getUserList()
+    }
+};
+</script>
+
+<style scoped lang="scss">
+.data-refresh-setting-wrap{
+    min-height: calc(100vh - 120px);
+    display: flex;
+    flex-direction: column;
+    .top-box,.table-box{
+        box-sizing: border-box;
+        padding:20px;
+        background-color: #fff;
+        border:1px solid #C8CDD9;
+        border-radius: 4px;
+    }
+    .top-box{
+        margin-bottom: 20px;
+        display: flex;
+        justify-content: space-between;
+        .el-input{
+            width:260px;
+        }
+        .select-box{
+            .el-select{
+                margin:0 20px;
+            }
+        }
+    }
+    .table-box{
+        flex:1;
+        .el-select{
+            min-width:180px;
+        }
+        .table-select{
+            display: flex;
+            justify-content: space-between;
+            .select-list{
+                flex:1;
+                display: flex;
+                flex-wrap: wrap;
+                gap:20px;
+            }
+            .select-other{
+                .el-button{
+                    margin-left:30px;
+                }
+            }
+        }
+        .el-table{
+            margin:20px 0;
+        }
+        .el-pagination{
+            text-align: right;
+        }
+    }
+    .refresh-setting-dialog{
+        margin-bottom: 0;
+        .dialog-container{
+            overflow: hidden;
+            .default-box{
+                display: flex;
+                align-items: center;
+                padding-bottom: 30px;
+                margin-bottom: 30px;
+                border-bottom: 1px solid #EBEFF6;
+            }
+            .refresh-box{
+                max-height: 65vh;
+                overflow-y: auto;
+            }
+        }
+        .dialog-btn{
+            text-align: center;
+            padding: 25px 0;
+        }
+    }
+}
+</style>

+ 2 - 2
src/views/system_manage/departManage.vue

@@ -127,8 +127,8 @@
 									class="editsty" 
 									@click.stop="handleChangeStatus(scope.row)"
 								>{{scope.row.Enabled===0?'启用':'禁用'}}</span>
-								<span v-permission="permissionBtn.sysDepartPermission.sysDepart_del"
-									class="deletesty" @click.stop="delUser(scope.row)">删除</span>
+								<!-- <span v-permission="permissionBtn.sysDepartPermission.sysDepart_del"
+									class="deletesty" @click.stop="delUser(scope.row)">删除</span> -->
 							</div>
 						</template>
 					</el-table-column>

+ 8 - 1
src/views/system_manage/etaBaseConfig.vue

@@ -76,6 +76,12 @@
                         <ConfigAnnotation picName="emailContentTemplate" @showImage="previewImage" picHintText=""/>
                     </el-form-item>
                 </div>
+                <div class="side">
+                    <el-form-item label="备案信息" prop="ICPLicense">
+                        <el-input type="text" v-model="formData.ICPLicense" placeholder="文本中输入≥2个空格表示文本分段,小屏时换行展示" />
+                        <ConfigAnnotation picHintText="" picName="ICPLicense" @showImage="previewImage"/>
+                    </el-form-item>
+                </div>
             </div>
             <!-- 研报设置 -->
             <div class="part" v-show="partType===2">
@@ -372,7 +378,7 @@ export default {
 
                 IsReportApprove:false,//是否开启研报审批
                 ReportApproveType:'eta',//研报审批选项
-
+                ICPLicense:'', //备案信息
             },//表单预设值
             rules: {
                 Disclaimer:[{ required: true, message: '请输入免责声明', trigger: 'blur' }],
@@ -453,6 +459,7 @@ export default {
                 'pptBgPic':[require('@/assets/img/eta_base_config/ppt_bgpic.jpg')],
                 'pptBackPic':[require('@/assets/img/eta_base_config/ppt_back.jpg')],
                 'emailContentTemplate':[require('@/assets/img/eta_base_config/email_content_template.png')],
+                'ICPLicense':[require('@/assets/img/eta_base_config/record_information.jpg')]
             },
             /* loading */
             configLoading:null,

+ 3 - 0
src/vuex/modules/ppt.js

@@ -20,6 +20,9 @@ const ppt = {
     //设置图表信息
     SET_CHART_INFO_MAP(state,chartInfoMap){
       state.chartInfoMap = chartInfoMap
+    },
+    SET_CHART_INFO(state,{chartId,chartInfo}){
+        state.chartInfoMap[chartId] = chartInfo
     }
   },
   actions:{},