Эх сурвалжийг харах

Merge branch 'lang_dev' into lang_dev_jw

jwyu 1 жил өмнө
parent
commit
6f4bb7b504
100 өөрчлөгдсөн 6613 нэмэгдсэн , 1291 устгасан
  1. 4 4
      src/App.vue
  2. 21 0
      src/api/modules/aiApi.js
  3. 29 0
      src/api/modules/chartApi.js
  4. 135 1
      src/api/modules/dataApi.js
  5. 7 1
      src/api/modules/setApi.js
  6. 23 1
      src/api/modules/sheetApi.js
  7. BIN
      src/assets/img/eta_base_config/ETA_title.png
  8. BIN
      src/assets/img/eta_base_config/record_information.jpg
  9. BIN
      src/assets/img/icons/ai-upload.png
  10. BIN
      src/assets/img/icons/file-upload.png
  11. BIN
      src/assets/img/icons/file_type_pdf.png
  12. BIN
      src/assets/img/icons/file_type_ppt.png
  13. BIN
      src/assets/img/icons/file_type_unknown.png
  14. 3 1
      src/lang/commonLang.js
  15. 1 0
      src/lang/en.js
  16. 160 0
      src/lang/modules/ETATables/En.js
  17. 172 0
      src/lang/modules/ETATables/Zh.js
  18. 182 0
      src/lang/modules/ETATables/commonLang.js
  19. 22 11
      src/lang/modules/SemanticsManage/DocumentComparison.js
  20. 6 8
      src/lang/modules/SemanticsManage/DocumentManagement.js
  21. 4 5
      src/lang/modules/SemanticsManage/TagManagement.js
  22. 28 26
      src/lang/modules/StatisticAnalysis/StatisticFeatureChart.js
  23. 1 0
      src/lang/zh.js
  24. 2 2
      src/routes/modules/chartRoutes.js
  25. 6 0
      src/routes/modules/oldRoutes.js
  26. 5 1
      src/utils/buttonConfig.js
  27. 2 2
      src/utils/calculate.js
  28. 47 15
      src/views/Login.vue
  29. 6 3
      src/views/chartRelevance_manage/components/selectTarget.vue
  30. 77 2
      src/views/dataEntry_manage/addChart.vue
  31. 7 1
      src/views/dataEntry_manage/chartSetting.vue
  32. 1 1
      src/views/dataEntry_manage/components/SaveChartOther.vue
  33. 356 0
      src/views/dataEntry_manage/databaseComponents/batchComputedSave.vue
  34. 982 0
      src/views/dataEntry_manage/databaseComponents/batchComputedV2.vue
  35. 93 6
      src/views/dataEntry_manage/databaseComponents/computedDialog.vue
  36. 14 10
      src/views/dataEntry_manage/databaseComponents/diffusionIndexDia.vue
  37. 2 1
      src/views/dataEntry_manage/databaseComponents/edbDetailData.vue
  38. 7 0
      src/views/dataEntry_manage/databaseComponents/fittingResidueDia.vue
  39. 14 0
      src/views/dataEntry_manage/databaseComponents/jointTargetDia.vue
  40. 71 13
      src/views/dataEntry_manage/databaseComponents/operationDialog.vue
  41. 85 1
      src/views/dataEntry_manage/databaseComponents/util.js
  42. 134 10
      src/views/dataEntry_manage/databaseList.vue
  43. 78 2
      src/views/dataEntry_manage/editChart.vue
  44. 125 19
      src/views/dataEntry_manage/mixins/addOreditMixin.js
  45. 33 21
      src/views/dataEntry_manage/mixins/chartPublic.js
  46. 26 14
      src/views/dataEntry_manage/onlineExcelCopy.vue
  47. 5 3
      src/views/dataEntry_manage/thirdBase/icpiConsumption.vue
  48. 23 22
      src/views/datasheet_manage/addSheet.vue
  49. 115 7
      src/views/datasheet_manage/common/customTable.js
  50. 26 23
      src/views/datasheet_manage/components/CustomTable.vue
  51. 246 99
      src/views/datasheet_manage/components/MixedTable.vue
  52. 22 17
      src/views/datasheet_manage/components/addDateCellDia.vue
  53. 288 0
      src/views/datasheet_manage/components/calculateDateDia.vue
  54. 75 51
      src/views/datasheet_manage/components/calculateEdbDia.vue
  55. 176 0
      src/views/datasheet_manage/components/dateMoveWaySection.vue
  56. 17 13
      src/views/datasheet_manage/components/edbDetailSection.vue
  57. 98 164
      src/views/datasheet_manage/components/insertDateDia.vue
  58. 136 27
      src/views/datasheet_manage/components/selectTargetValueDia.vue
  59. 14 3
      src/views/datasheet_manage/components/sheetClassifyDia.vue
  60. 4 4
      src/views/datasheet_manage/components/sheetListWrap.vue
  61. 203 0
      src/views/datasheet_manage/components/toolBarSection.vue
  62. 11 7
      src/views/datasheet_manage/customAnalysis/addAnalysisSheet.vue
  63. 22 8
      src/views/datasheet_manage/customAnalysis/components/bottomSection.vue
  64. 25 19
      src/views/datasheet_manage/customAnalysis/components/createTargetForm.vue
  65. 35 4
      src/views/datasheet_manage/customAnalysis/components/rightSection.vue
  66. 96 57
      src/views/datasheet_manage/customAnalysis/list.vue
  67. 42 21
      src/views/datasheet_manage/customSheetEdit.vue
  68. 39 33
      src/views/datasheet_manage/mixedSheetEdit.vue
  69. 76 22
      src/views/datasheet_manage/mixins/classifyMixin.js
  70. 109 56
      src/views/datasheet_manage/sheetList.vue
  71. 7 1
      src/views/edbHistoryPage.vue
  72. 12 7
      src/views/mychart_manage/components/chartDetailDia.vue
  73. 176 23
      src/views/operation_manage/AIQA/AIQA.vue
  74. 42 4
      src/views/operation_manage/AIQA/components/messageItem.vue
  75. 25 17
      src/views/ppt_manage/mixins/mixins.js
  76. 51 15
      src/views/ppt_manage/mixins/pptMixins.js
  77. 9 4
      src/views/ppt_manage/newVersion/components/catalog/chooseShareUserDia.vue
  78. 8 8
      src/views/ppt_manage/newVersion/components/formatEl/ChartEl.vue
  79. 7 36
      src/views/ppt_manage/newVersion/components/formatPage/FormatEle.vue
  80. 1 1
      src/views/ppt_manage/newVersion/components/formatPage/FormatNine.vue
  81. 7 34
      src/views/ppt_manage/newVersion/components/formatPage/FormatTen.vue
  82. 7 34
      src/views/ppt_manage/newVersion/components/formatPage/FormatTwelve.vue
  83. 94 25
      src/views/ppt_manage/newVersion/css/format.scss
  84. 5 5
      src/views/ppt_manage/newVersion/pptEditor.vue
  85. 6 6
      src/views/ppt_manage/newVersion/pptEnEditor.vue
  86. 1 1
      src/views/ppt_manage/newVersion/pptEnPresent.vue
  87. 43 5
      src/views/ppt_manage/newVersion/pptEnPublish.vue
  88. 1 1
      src/views/ppt_manage/newVersion/pptPresent.vue
  89. 40 11
      src/views/ppt_manage/newVersion/pptPublish.vue
  90. 76 76
      src/views/ppt_manage/newVersion/utils/config.js
  91. 11 15
      src/views/report_manage/reportAuthor.vue
  92. 14 19
      src/views/report_manage/reportVariety.vue
  93. 23 27
      src/views/semantics_manage/document/documentEditPage.vue
  94. 14 18
      src/views/semantics_manage/documentPage.vue
  95. 17 15
      src/views/semantics_manage/semantics/semanticsEditPage.vue
  96. 10 10
      src/views/semantics_manage/semanticsPage.vue
  97. 9 17
      src/views/semantics_manage/tagPage.vue
  98. 32 14
      src/views/supply_manage/components/varietySetDia.vue
  99. 259 0
      src/views/system_manage/components/refreshConfig.vue
  100. 732 0
      src/views/system_manage/dataRefreshSetting.vue

+ 4 - 4
src/App.vue

@@ -244,9 +244,9 @@ div::-webkit-scrollbar-corner {
   background: #666;
 }
 /*firefox*/
-div{
+/* div{
     scrollbar-width: thin;
-}
+} */
 .customName:hover {
   text-decoration: underline;
 }
@@ -296,9 +296,9 @@ ul::-webkit-scrollbar-corner {
   background: #666;
 }
 /*firefox*/
-ul{
+/* ul{
     scrollbar-width: thin;
-}
+} */
 
 textarea {
   font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",

+ 21 - 0
src/api/modules/aiApi.js

@@ -47,5 +47,26 @@ export const aiQAInterence = {
      */
     editTopicName:params=>{
         return http.post('/ai/topic/edit',params)
+    },
+    /**
+     * AI文件上传
+     * @param {FormData} params
+     * @param {Object} params.File 文件
+     * @param {Number} params.AiChatTopicId 窗口Id
+     * @returns 
+    */
+    fileUpload:params=>{
+        return http.post('/ai/file/upload',params)
+    },
+    /**
+     * AI文件检索
+     * @param {Object} params
+     * @param {Number} params.AiChatTopicId
+     * @param {String} params.Ask
+     * @param {Array} params.OpenaiFileId [String]
+     * @returns 
+    */
+    fileRetrieve:params=>{
+        return http.post('/ai/file/retrieve',params)
     }
 }

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

@@ -410,6 +410,14 @@ const dataBaseInterface = {
 	edbAddBatch: params => {
 		return http.post('/datamanage/edb_info/batch/add',params)
 	},
+	// 批量计算指标时获取当前筛选条件下选择的指标
+	getBatchFilterAddEdbList:params=>{
+		return http.get('/datamanage/edb_info/calculate/multi/choice',params)
+	},
+	//批量计算指标时待选指标的搜索列表
+	getBatchAddEdbSearchList:params=>{
+		return http.get('/datamanage/edb_info/calculate/multi/search',params)
+	},
 	//========================================chart
 	// /**
 	//  * 
@@ -839,6 +847,11 @@ const dataBaseInterface = {
 		return http.post('/datamanage/edb_info/calculate/batch/save/batch',params)
 	},
 
+	//批量计算编辑
+	batchCalculateTargetEdit: params => {
+		return http.post('/datamanage/edb_info/calculate/batch/edit/batch',params)
+	},
+
 	/**
 	 * 获取计算指标与基础指标关联信息
 	 * @param EdbInfoId
@@ -943,6 +956,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 - 1
src/api/modules/setApi.js

@@ -337,8 +337,14 @@ const departInterence = {
 	 */
 	getPhoneAreaCode:params=>{
 		return http.get('/user_login/area_code/list',params)
+	},
+	/**
+	 * 获取登录页的信息 
+	 * @returns ETATitle登录标题 Icp备案信息
+	*/
+	getBaseInfo:params=>{
+		return http.get('/user_login/base_info',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 = {

BIN
src/assets/img/eta_base_config/ETA_title.png


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


BIN
src/assets/img/icons/ai-upload.png


BIN
src/assets/img/icons/file-upload.png


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


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


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


+ 3 - 1
src/lang/commonLang.js

@@ -1,5 +1,6 @@
 import Edb from './modules/EtaBase/commonLang';
 import Chart from './modules/EtaChart/commonLang';
+import ETable from './modules/ETATables/commonLang';
 
 // 通用文字翻译
 export default {
@@ -278,5 +279,6 @@ export default {
     }
   },
   Edb,
-  Chart
+  Chart,
+  ETable
 };

+ 1 - 0
src/lang/en.js

@@ -22,4 +22,5 @@ export default {
   Common:transformLanguageData(commonLang.Common,'en'),
   Edb: transformLanguageData(commonLang.Edb, "en"),
   Chart: transformLanguageData(commonLang.Chart, "en"),
+  ETable: transformLanguageData(commonLang.ETable, "en"),
 };

+ 160 - 0
src/lang/modules/ETATables/En.js

@@ -0,0 +1,160 @@
+export default {
+  /* 在线EXCEL */
+  OnlineExcelPage: {
+    add_excel_btn: "Add excel spreadsheet",
+    add_timeline_table_btn: "Add a timeline table",
+    add_mixed_table_btn: "Add mixed table",
+    excel_name_ipt: "Excel name",
+    please_value_ipt: "Please enter a value",
+    add_category_table_btn: "Add table category",
+    please_table_name_ipt: "Please enter the Table name",
+    author_info: "Author:",
+    recent_save_time_info: "Recent save time:",
+    table_classification_label: "Table classification",
+    select_appropriate_category_lable: "Please select the appropriate category",
+    please_table_classification_msg: "Please add a table classification first",
+    the_tables_no_delete_msg: "The tables associated with this category cannot be deleted",
+    input_content_msg: "Please input table content",
+    editing_msg: "Editing",
+    all_table_num: "{count} tables in total",
+    creation_time_tle: "Creation time",
+    no_table_available_show: "No table available",
+    date_row_table: "Date",
+    add_date_wrapper: "Add Date",
+    add_text_wrapper: "Add Text",
+    indicator_name_lbl: "Indicator name",
+    indicator_alias_lbl: "Indicator alias",
+    edit_indicator_tle: "Edit Indicator",
+    dlt_the_all_msg: "Deleting the first indicator will clear all content from the table. Are you sure you want to delete it?",
+    please_keep_one_msg: "Please keep at least one indicator date",
+    error_parameter_not_msg: "Formula error, parameter does not exist",
+    lastest_date_lab: "Lastest date",
+    insert_success_msg: "Insert sucessfully",
+    the_date_no_val_msg: "The current date has no value at the moment",
+    formula_val_error_msg: "Formula parameters incorrect",
+    keep_one_column_msg: "Please keep at least one column",
+    keep_one_row_msg: "Please keep at least one row",
+    no_here_val_msg: "Unable to insert value here",
+    TableInstructionsText: `Table Instructions:<br />
+    1. Manual Input: Click on each cell to directly enter text, numbers, or dates (format example: 2023-05-23). The entered content can match the names of metrics. Metrics from both the ETA Metric Library and the ETA Forecast Metric Library are searchable. If a metric is selected from the dropdown list, then that cell becomes a designated row/column for the selected metric.<br />
+    2. Insert Metric Value: Right-click on a cell and click "Insert Metric Value". The system will query for the closest date and metric name based on the cell's row and column, and then populate the cell with the value of the metric corresponding to that date. The metric value is always positioned in the lower right corner of the cell.<br />
+    3. Update and Calculation Rules: The dates associated with metric values in the table do not update automatically, and values do not support calculations within cells.`,
+    select_table_category: "Please select table category",
+    saving_loading_text: "Saving...",
+    table_explaination_text: "Table explaination",
+    currently_editing_msg: "is currently being edited",
+    already_exists_msg: "Indicator already exists",
+    please_add_table_msg: "Please add a table",
+    data_row_label: "Indicator column+Date row",
+    data_column_label: "Indicator row+Date column",
+    select_table_contents: "Please select the table of contents",
+    the_sheet_page_selected: "Upload files based on the sheet page selected by th user",
+    please_select_sheet_msg: "Please select the sheet page to save",
+    please_select_category_msg: "Please select a category",
+    table_name_empty_msg: "Table name cannot be empty",
+    name_empty_msg: "name cannot be empty",
+    date_type_label: "date type",
+    past_date_label: "Past date",
+    future_date_label: " uture dates",
+    number_lable: "Number of periods",
+    please_enter_number: "Please enter the number of periods",
+    deadline_lable: "deadline",
+    please_enter_deadline: "Please enter the deadline",
+    deadline_cannot_be_empty: "The deadline cannot be empty",
+    number_cannot_be_empty: "The number of periods cannot be empty",
+    label_move_way: "Moving Mode",
+    label_n_val: "N equals to",
+    label_calendar: "Calendar",
+    please_select_frequency: "Please select the frequency",
+    label_val_type: "Data retrieval",
+    select_data_type: "Please select data value type",
+    select_criteria_btn: "Selection Criteria",
+    insert_value_btn: "Insert value",
+    there_data_no_msg: "There is no data for that date.",
+    there_data_no_msg: "Insert method",
+    there_data_no_msg: "Please select the import method",
+    days_label: "days",
+    update_frequency_label: "Update frequency",
+    lastest_date_label: "Lastest date",
+    example_show_text: "Example: 5, represents the date 5 days from today; -5, represents the date 5 days ago from today.",
+    selected_indicators_label: "indicators",
+    no_indicators_available_table: "No indicators available.",
+    cannot_be_empty_table: "Table Categories cannot be empty",
+    table_data_update_msg: "The table data has been updated",
+    formula_lable: "Formula",
+    parent_directory_lable: "Parent directory",
+  },
+
+  /* 自定义分析  */
+  CustomAnalysisPage: {
+    up_file_btn: "Upload files",
+    generate_indicators_btn: "Generate indicators",
+    up_save_tooltip: "Update all the indicators generated by the current table based on the latest content saved in the table",
+    refresh_loading: "Refresh indicators",
+    refreshing_loading: "Indicators refreshing...",
+    no_file_type_msg: "Upload failed, format does not comply with xlsx",
+    up_file_five_msg: "The maximum upload file size cannot exceed 5M",
+    up_new_file_msg: "A file with the same name already exists. Please upload a new file",
+    parsing_file_error_msg: "Parsing file failed",
+    select_one_region_msg: "Only one area can be selected at the same time",
+    only_allowed_select_msg: "The sequence only allows selection of the same row or column",
+    select_date_sequence: "Please select a date sequence",
+    select_date_numerical: "Please select a numerical sequence",
+    select_appropriate_category: "Please select the appropriate category",
+    select_frequency: "Please select frequency",
+    rules_edbName: "Indicator name cannot be empty",
+    rules_classify: "Category cannot be empty",
+    rules_frequency: "Frequency cannot be empty",
+    rules_unit: "Unit cannot be empty",
+    date_sequence_cannot_msg: "The date sequence cannot be empty",
+    numerical_sequence_cannot_msg: "The numerical sequence cannot be empty",
+  },
+
+  ETableChildren: {
+    date_calculation_btn: "Date calculation",
+    select_date_pld: "Select Date",
+    add_more_dates: "Add more dates",
+    formula_lable: "Formula",
+    formula_enter_pld: "Please enter a formula",
+    example_a_b: "Example formula: A-B returns the difference in days between date a and date B as a number",
+    indicators_cap_reached: "The number of added indicators has reached the upper limit",
+    input_formula_valid: "Calculation Formula can not be blank",
+    date_change_label: "Date transformation ",
+    date_displacement_label: "Date displacement",
+    specified_frequency_tag: "Specified frequency",
+    added_frequency_offset_msg: "Specified frequency has been added.",
+    added_date_offset_msg: "Added date offset",
+    impord_date_title: "Import Date",
+    indicator_date_radio: "Date of indicator",
+    frequency_lable: "Frequency",
+    lagging_period_label: "Lagging period",
+    system_date_rai: "System Date",
+    term_ipt: "Term",
+    formula_explanation_btn: "Formula Explanation",
+    tips_text: `Formula Explanation:<br>1. Index Date: Takes the latest date of the selected index, which updates along with the latest date.<br>2. System Date: Takes the system date, which updates along with the system date.<br>3. Date Offset Examples:<br>Original date 2023/10/12, date offset function set to 5 days 0 months 0 years, the converted date will be 2023/10/17.<br>Original date 2023/10/12, date offset function set to 30 days 0 months 0 years, the converted date will be 2023/11/11.<br>Original date 2023/10/30, date offset function set to 0 days 1 month 0 years, the converted date will be 2023/11/30.<br>Original date 2023/10/31, date offset function set to 0 days 1 month 0 years, the converted date will be 2023/12/1.<br>4. Date Offset and specified frequency can be overlaid, for example:<br>Original date 2023/10/12, first date offset by 1 month (2023/11/12), then frequency set to the last day of the month, the converted date will be 2023/11/30.<br>Original date 2023/10/12, first frequency set to the last day of the month (2023/10/31), then date offset by 1 month, the converted date will be 2023/12/1.`,
+    latest_date_indicator: "Latest Date of Indicator",
+    advance_the_term: "Advance of the term",
+    table_date_rai: "Table date",
+    select_metric_first_msg: "Please select a metric first.",
+    number_label: "Number",
+    percentile_label: "Percentile",
+    number_reduce_title: "Reduce the number of decimal places",
+    number_increase_title: "Increase the number of decimal places",
+    enter_n_value: "Please enter N value",
+    select_calendar_pld: "Please select a calendar",
+    frequentness_lable: "frequentness",
+    final_value_lable: "Final value",
+    average_value_lable: "Average value",
+    alpha_value_lable: "Alpha value",
+    calculate_result: "Calculate the result",
+    no_corresponding_data: "No corresponding data",
+    calculation_btn: "calculation",
+    only_select_msg: "Only monthly indicators can be selected",
+    no_quarterly_msg: "Unable to select quarterly indicators",
+    no_day_msg: "Cannot select daily indicators",
+    no_year_msg: "Unable to select annual indicators",
+    no_year_msg: "Unable to select annual indicators",
+    ahead_lable: "ahead",
+    lagging_lable: "lagging",
+  },
+};

+ 172 - 0
src/lang/modules/ETATables/Zh.js

@@ -0,0 +1,172 @@
+export default {
+  /* 在线EXCEL */
+  OnlineExcelPage: {
+    add_excel_btn: "添加Excel表格",
+    add_timeline_table_btn: "添加时间序列表格",
+    add_mixed_table_btn: "添加混合表格",
+    excel_name_ipt: "表格名称",
+    please_value_ipt: "请输入值",
+    add_category_table_btn: "添加表格分类",
+    please_table_name_ipt: "请输入表格名称",
+    author_info: "作者:",
+    recent_save_time_info: "最近保存时间:",
+    table_classification_label: "表格分类",
+    select_appropriate_category_lable: "请选择所属分类",
+    please_table_classification_msg: "请先添加表格分类",
+    the_tables_no_delete_msg: "该分类下关联表格不可删除",
+    input_content_msg: "请输入表格内容",
+    editing_msg: "编辑中",
+    currently_editing_msg: "正在编辑中",
+    all_table_num: "共{count}张表格",
+    creation_time_tle: "创建时间",
+    no_table_available_show: "暂无表格",
+    date_row_table: "日期",
+    add_date_wrapper: "添加日期",
+    add_text_wrapper: "添加文本",
+    indicator_name_lbl: "指标名称",
+    indicator_alias_lbl: "指标别名",
+    edit_indicator_tle: "编辑指标",
+    dlt_the_all_msg: "第一个指标删除后将清除表格所有内容,确认删除吗?",
+    please_keep_one_msg: "请至少保留一个指标日期",
+    error_parameter_not_msg: "公式有误,参数不存在",
+    lastest_date_lab: "最新日期",
+    insert_success_msg: "插入成功",
+    the_date_no_val_msg: "当前日期暂无值",
+    formula_val_error_msg: "公式参数有误",
+    keep_one_column_msg: "请至少保留一列",
+    keep_one_row_msg: "请至少保留一行",
+    no_here_val_msg: "无法在此处插入值",
+    select_table_category: "请选择表格分类",
+    saving_loading_text: "保存中...",
+    table_explaination_text: "表格说明",
+    already_exists_msg: "指标已存在",
+    please_add_table_msg: "请添加表格",
+    data_row_label: "指标列+日期行",
+    data_column_label: "指标行+日期列",
+    select_table_contents: "请选择表格目录",
+    the_sheet_page_selected: "根据用户选择的sheet页上传文件",
+    please_select_sheet_msg: "请选择要保存的sheet页",
+    please_select_category_msg: "请选择分类",
+    table_name_empty_msg: "表格名称不能为空",
+    name_empty_msg: "名称不能为空",
+    TableInstructionsText: `表格说明:<br>
+    1、手动输入:单击每个单元格可直接输入文本、数字、日期(格式示例:2023-05-23),输入内容可匹配指标名称,ETA指标库和ETA预测指标库指标均可搜索,在下拉框中选择指标,则该单元格为已选指标行/列。<br>
+    2、插入指标值:右键单元格,点击“插入指标值”,则查询该单元格行、列最近的日期和指标名称,将查找到的指标对应日期的值填入该单元格,指标值总是在右下角。<br>
+    3、更新与计算规则:表格中指标值的日期不自动更新,数值不支持单元格计算`,
+    date_type_label: "日期类型",
+    past_date_label: "过去日期",
+    future_date_label: "未来日期",
+    number_lable: "期数",
+    please_enter_number: "请输入期数",
+    deadline_lable: "截止日期",
+    please_enter_deadline: "请输入截止日期",
+    deadline_cannot_be_empty: "截止日期不能为空",
+    number_cannot_be_empty: "期数不能为空",
+    label_move_way: "移动方式",
+    label_n_val: "N等于",
+    label_calendar: "日历",
+    please_select_frequency: "请选择频度",
+    label_val_type: "数据取值",
+    select_data_type: "请选择数据取值类型",
+    select_criteria_btn: "选择指标",
+    insert_value_btn: "插入值",
+    there_data_no_msg: "该日期无数据",
+    there_data_no_msg: "导入方式",
+    there_data_no_msg: "请选择导入方式",
+    days_label: "天数",
+    update_frequency_label: "更新频度",
+    lastest_date_label: "最新日期",
+    example_show_text: "示例:5,表示当前日期+5天的日期; -5,表示当前日期-5天的日期;",
+    selected_indicators_label: "已选指标:",
+    no_indicators_available_table: "暂无指标",
+    cannot_be_empty_table: "表格分类不能为空",
+    table_data_update_msg: "表格数据已更新",
+    formula_lable: "公式",
+    parent_directory_lable: "上级目录",
+  },
+
+  /* 自定义分析  */
+  CustomAnalysisPage: {
+    up_file_btn: "上传文件",
+    generate_indicators_btn: "生成指标",
+    up_save_tooltip: "根据表格保存的最新内容,更新当前表格生成的所有指标",
+    refresh_loading: "刷新指标",
+    refreshing_loading: "指标刷新中...",
+    no_file_type_msg: "上传失败,格式不符合xlsx",
+    up_file_five_msg: "上传文件最大不能超过5M",
+    up_new_file_msg: "已有同名文件,请上传新文件",
+    parsing_file_error_msg: "解析文件失败",
+    select_one_region_msg: "同时只允许选择一块区域",
+    only_allowed_select_msg: "序列只允许选择同行或同列",
+    select_date_sequence: "请选择日期序列",
+    select_date_numerical: "请选择数值序列",
+    select_appropriate_category: "请选择所属目录",
+    select_frequency: "请选择频率",
+    rules_edbName: "指标名称不能为空",
+    rules_classify: "目录不能为空",
+    rules_frequency: "频率不能为空",
+    rules_unit: "单位不能为空",
+    date_sequence_cannot_msg: "日期序列不能为空",
+    numerical_sequence_cannot_msg: "数值序列不能为空",
+  },
+
+  ETableChildren: {
+    date_calculation_btn: "日期计算",
+    select_date_pld: "选择日期",
+    add_more_dates: "添加更多日期",
+    formula_lable: "计算公式",
+    formula_enter_pld: "请输入公式",
+    example_a_b: "公式示例:A-B 以数字形式返回日期A和日期B的天数差",
+    indicators_cap_reached: "添加指标个数已达上限",
+    input_formula_valid: "计算公式不能为空",
+    date_change_label: "日期变换",
+    date_displacement_label: "日期位移",
+    specified_frequency_tag: "指定频率",
+    added_frequency_offset_msg: "已添加指定频率",
+    added_date_offset_msg: "已添加日期位移",
+    impord_date_title: "导入日期",
+    indicator_date_radio: "指标日期",
+    frequency_lable: "频度",
+    lagging_period_label: "期数前移",
+    system_date_rai: "系统日期",
+    term_ipt: "期",
+    formula_explanation_btn: "公式说明",
+    tips_text:`
+    公式说明:<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。
+  `,
+  latest_date_indicator: "指标最新日期",
+  advance_the_term: "期数前移",
+  table_date_rai: "表格日期",
+  select_metric_first_msg: "请先选择指标",
+  number_label: "数字",
+  percentile_label: "百分位",
+  number_reduce_title: "减少小数位数",
+  number_increase_title: "增加小数位数",
+  enter_n_value: "请输入N数值",
+  select_calendar_pld: "请选择日历",
+  frequentness_lable: "频度",
+  final_value_lable: "期末值",
+  average_value_lable: "平均值",
+  alpha_value_lable: "alpha值",
+  calculate_result: "计算结果",
+  no_corresponding_data: "无对应的数据",
+  calculation_btn: "计算",
+  only_select_msg: "只能选择月度指标",
+  no_quarterly_msg: "不能选择季度指标",
+  no_day_msg: "不能选择日度指标",
+  no_year_msg: "不能选择年度指标",
+  no_year_msg: "不能选择年度指标",
+  ahead_lable: "领先",
+  lagging_lable: "滞后",
+  },
+};

+ 182 - 0
src/lang/modules/ETATables/commonLang.js

@@ -0,0 +1,182 @@
+export default {
+  Btn: {
+    refresh_btn: {
+      zh: "刷新",
+      en: "Refresh",
+    },
+    download_btn: {
+      zh: "下载",
+      en: "Download",
+    },
+    edit_btn: {
+      en: "Edit",
+      zh: "编辑",
+    },
+    save_as: {
+      en: "Save as",
+      zh: "另存为",
+    },
+    save_btn: {
+      en: "Save",
+      zh: "保存 ",
+    },
+    delete_btn: {
+      en: "Delete",
+      zh: "删除",
+    },
+    add_btn: {
+      en: "Add",
+      zh: "添加",
+    },
+    back_btn: {
+      en: "Return",
+      zh: "返回",
+    },
+    all_btn: {
+      en: "All",
+      zh: "全部",
+    },
+    cancel_btn: {
+      en: "Cancel",
+      zh: "取消",
+    },
+    renew_btn: {
+      en: "Renew",
+      zh: "更新",
+    },
+  },
+  Msg: {
+    is_del_table_msg: {
+      en: "Once deleted, this table will no longer be referable. Are you sure you want to delete it?",
+      zh: "删除后该表格将不能再引用,确认删除吗?",
+    },
+    refresh_success_msg: {
+      en: "Refresh successfully",
+      zh: "刷新成功",
+    },
+    move_success_msg: {
+      en: "Move succeeded",
+      zh: "移动成功!",
+    },
+    sdded_success_msg: {
+      en: "Added succeeded",
+      zh: "添加成功!",
+    },
+    please_select: {
+      en: "Please select",
+      zh: "请选择",
+    },
+  },
+  Date: {
+    monday: {
+      zh: "周一",
+      en: "Monday",
+    },
+    tuesday: {
+      zh: "周二",
+      en: "Tuesday",
+    },
+    wednesday: {
+      zh: "周三",
+      en: "Wednesday",
+    },
+    thursday: {
+      zh: "周四",
+      en: "Thursday",
+    },
+    friday: {
+      zh: "周五",
+      en: "Friday",
+    },
+    saturday: {
+      zh: "周六",
+      en: "Saturday",
+    },
+    sunday: {
+      zh: "周日",
+      en: "Sunday",
+    },
+    this_week: {
+      zh: "本周",
+      en: "This week",
+    },
+    day: {
+      zh: "日",
+      en: "Day",
+    },
+    this_ten_days: {
+      zh: "本旬",
+      en: "This ten day",
+    },
+    this_month: {
+      zh: "本月",
+      en: "This month",
+    },
+    this_season: {
+      zh: "本季",
+      en: "This season",
+    },
+    this_half_year: {
+      zh: "本半年",
+      en: "This half year",
+    },
+    this_year: {
+      zh: "本年",
+      en: "This year",
+    },
+    day: {
+      zh: "天",
+      en: "Day",
+    },
+    month: {
+      zh: "月",
+      en: "Month",
+    },
+    year: {
+      zh: "年",
+      en: "Year",
+    },
+    week_min: {
+      zh: "周",
+      en: "week",
+    },
+    quarter_min: {
+      zh: "季",
+      en: "season",
+    },
+    day_lable: {
+      zh: "日度",
+      en: "Daliy",
+    },
+    week_lable: {
+      zh: "周度",
+      en: "Weekly",
+    },
+    dekad_lable: {
+      zh: "旬度",
+      en: "Every ten days",
+    },
+    month_lable: {
+      zh: "月度",
+      en: "Monthly",
+    },
+    quarter_lable: {
+      zh: "季度",
+      en: "Quarterly",
+    },
+    year_lable: {
+      zh: "年度",
+      en: "Yearly",
+    },
+    calendar_gre: {
+      zh: '公历',
+      en: 'Gregorian Calendar'
+    },
+    calendar_lunar: {
+      zh: '农历',
+      en: 'Lunar Calendar'
+    },
+  },
+};
+
+//ETable

+ 22 - 11
src/lang/modules/SemanticsManage/DocumentComparison.js

@@ -36,6 +36,17 @@ export const DocumentComparisonEn = {
   radio_no: "No",
   upload_result_image: "Upload Result Image",
   please_keep_least_one_document: "Please keep at least one document.",
+  copy_office_btn: "Copy to Office",
+  copy_wechat_btn: "to WeChat",
+  download_btn: "Download",
+  classify_name_tips: "The category name cannot be empty",
+  chrome_version_msg: "The browser does not support highlighting effects, please switch to Chrome browser version 105 or above.",
+  save_as_success_msg: "Save As successful.",
+  up_img_success_msg: "Upload of result image successful.",
+  paragraph_content_ipt: "Please enter paragraph content.",
+  document_name_no_empty: "The document name cannot be empty",
+  article_content_enter: "Please enter article content.",
+  least_one_paragraph_msg: "Please keep at least one paragraph.",
 };
 
 /* 中文 */
@@ -73,15 +84,15 @@ export const DocumentComparisonZh = {
   radio_no: "否",
   upload_result_image: "是否上传结果图片",
   please_keep_least_one_document: "请至少保留一个文档",
+  copy_office_btn: "复制到Office",
+  copy_wechat_btn: "复制到微信",
+  download_btn: "下载",
+  classify_name_tips: "分类名称不能为空",
+  chrome_version_msg: "该浏览器不支持高亮效果,请切换至chrome浏览器105版本以上",
+  save_as_success_msg: "另存为成功",
+  up_img_success_msg: "上传结果图片成功",
+  paragraph_content_ipt: "请输入段落内容",
+  document_name_no_empty: "文档名称不能为空",
+  article_content_enter: "请输入文章内容",
+  least_one_paragraph_msg: "请至少保留一段",
 };
-
-/*
-暂无分类
-文档名称不能为空
-请输入文章内容
-请输入段落内容
-共{{catalogList.length}}个文档
-复制到Office
-下载
-复制到微信
-*/

+ 6 - 8
src/lang/modules/SemanticsManage/DocumentManagement.js

@@ -21,6 +21,9 @@ export const DocumentManagementEn = {
   add_next_section: "Add Next Section",
   number_tags_attached: "Number of Tags Attached",
   error_notifications: "Already associated with comparison results, deletion not allowed.",
+  all_num_document: "{num}documents in total",
+  select_img_mag: "Please select images in png or jpeg format",
+  img_no_empty_msg: "The category image cannot be empty",
 };
 
 /* 中文 */
@@ -42,12 +45,7 @@ export const DocumentManagementZh = {
   add_next_section: "添加下一段",
   number_tags_attached: "已打标签数",
   error_notifications: "已关联对比结果,不允许删除",
+  all_num_document: "共{num}个文档",
+  select_img_mag: "请选择png、jpeg格式的图片",
+  img_no_empty_msg: "分类图片不能为空",
 };
-
-/*
-暂无分类
-共{{catalogList.length}}个文档
-分类名称不能为空
-分类图片不能为空
-移动成功
-*/

+ 4 - 5
src/lang/modules/SemanticsManage/TagManagement.js

@@ -12,6 +12,8 @@ export const TagManagementEn = {
   column_content_number: "Number of Contents",
   column_creation_time: "Creation Time",
   edit_tag_btn: "Edit Tag",
+  tag_name_long_msg: "The tag name is too long, please re-edit",
+  delete_tag_msg: "After deletion, it cannot be recovered. Are you sure you want to delete this tag?",
 };
 
 /* 中文 */
@@ -24,9 +26,6 @@ export const TagManagementZh = {
   column_content_number: "内容数量",
   column_creation_time: "创建时间",
   edit_tag_btn: "编辑标签",
+  tag_name_long_msg: "标签名称过长,请重新编辑",
+  delete_tag_msg: "删除后不可恢复,是否确认删除该标签?",
 };
-
-/**
- * 标签名称过长,请重新编辑
- * 删除后不可恢复,是否确认删除该标签
-*/

+ 28 - 26
src/lang/modules/StatisticAnalysis/StatisticFeatureChart.js

@@ -4,34 +4,36 @@
 
 /* 英文 */
 export const StatisticFeatureChartEn = {
-    limit_name:'up and dowm limited',
-    select_edb:'Select index',
-    standard_deviation:'Standard deviation',
-    rolling_period:'Rolling period',
-    percentile:'percentile',
-    time_length:'Length of time',
-    frequency_distribution:'Frequency distribution',
-    time_period:'Time period',
-    frequency_band_number:'Frequency band number',
-    near_month:'Last {num} months',
-    near_year:'Last {num} years',
+  limit_name: "up and dowm limited",
+  select_edb: "Select index",
+  standard_deviation: "Standard deviation",
+  rolling_period: "Rolling period",
+  percentile: "percentile",
+  time_length: "Length of time",
+  frequency_distribution: "Frequency distribution",
+  time_period: "Time period",
+  frequency_band_number: "Frequency band number",
+  near_month: "Last {num} months",
+  near_year: "Last {num} years",
+  selecr_indicator_pld: "Please select the type of indicator",
 };
-  
+
 /* 中文 */
 export const StatisticFeatureChartZh = {
-    limit_name:'上下限',
-    select_edb:'选择指标',
-    standard_deviation:'标准差',
-    rolling_period:'滚动期数',
-    percentile:'百分位',
-    time_length:'时间长度',
-    frequency_distribution:'频率分布',
-    time_period:'时间段',
-    frequency_band_number:'频段数',
-    near_month:'最近{num}月',
-    near_year:'最近{num}年',
+  limit_name: "上下限",
+  select_edb: "选择指标",
+  standard_deviation: "标准差",
+  rolling_period: "滚动期数",
+  percentile: "百分位",
+  time_length: "时间长度",
+  frequency_distribution: "频率分布",
+  time_period: "时间段",
+  frequency_band_number: "频段数",
+  near_month: "最近{num}月",
+  near_year: "最近{num}年",
+  selecr_indicator_pld: "请选择指标种类",
 };
-  
+
 /**
-* $t('StatisticAnalysis.StatisticFeatureChart.XXX')
-*/
+ * $t('StatisticAnalysis.StatisticFeatureChart.XXX')
+ */

+ 1 - 0
src/lang/zh.js

@@ -23,4 +23,5 @@ export default {
   Common:transformLanguageData(commonLang.Common,'zh'),
   Edb: transformLanguageData(commonLang.Edb, "zh"),
   Chart: transformLanguageData(commonLang.Chart, "zh"),
+  ETable: transformLanguageData(commonLang.ETable, "zh"),
 };

+ 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: "共享表格",
 				}
 			},
 			{

+ 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,
+      },
     ],
   },
   // 外部链接

+ 5 - 1
src/utils/buttonConfig.js

@@ -598,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);
 }
 
 // 获取浮点数的精度

+ 47 - 15
src/views/Login.vue

@@ -3,7 +3,7 @@
 		<div id="login_wrapper">
       
             <img class="login-bg" :src="$setting.login_bg" alt />
-            <img class="login-icon" :src="$setting.login_logo" />
+            <!-- <img class="login-icon" :src="$setting.login_logo" /> -->
 			<!-- <el-form
 				:model="ruleForm"
 				:rules="rules"
@@ -66,7 +66,8 @@
 			</el-form>  -->
 			<div class="login-box" id="login-container" v-if="activeModel!=='forgetPassModel'">
                 <div class="fixed-login-cont">
-                    <span class="login-title">ETA — 让投研领先市场半步</span>
+                    <span class="login-title">{{ loginTitle }}</span>
+                    <span class="login-sub-title">ETA — 让投研领先市场半步</span>
                     <el-tabs v-model="activeModel" >
                         <!-- <el-tab-pane label="账号登录" name="ordinaryModel">
                             <OrdinaryModel ref="ordinaryModel"
@@ -134,6 +135,10 @@
                 </div>
 			</div>
 		</div>
+        <div class="record-info">
+            <a v-for="(item,index) in recordInformation" :key="index" target="_blank"
+            href="https://beian.miit.gov.cn/#/Integrated/index">{{item}}</a>
+        </div>
 		<!-- 验证弹窗 -->
 		<el-dialog
 			class="check-dialog"
@@ -288,14 +293,15 @@ export default {
                         </filter>
                         </defs></svg>`
                 },
-            ]
-
-        
+            ],
+            recordInformation:[],
+            loginTitle:''
         };
     },
     created() {
         this.keyupSubmit(); //回车登录
         this.getPhoneCode();//获取手机号区号
+        this.getRecordInfo();//获取备案信息
     },
     mounted(){
         this.getRememberedInfo()
@@ -402,6 +408,14 @@ export default {
                 this.areaCode = res.Data||[]
             })
         },
+        getRecordInfo(){
+            departInterence.getBaseInfo().then(res=>{
+                if(res.Ret == 200){
+                    this.recordInformation = res.Data.Icp?res.Data.Icp.ConfVal.split(/\s{2,}/):[]
+                    this.loginTitle = res.Data.ETATitle?res.Data.ETATitle.ConfVal:''
+                }
+            })
+        },
         handleClick(tab) {
             //调用对应model的init方法
             this.$refs[tab.name]&&this.$refs[tab.name].modelInit()
@@ -651,7 +665,7 @@ export default {
 	// overflow: hidden;
 	#login_wrapper {
 		width: 100%;
-		height: 100%;
+		height: calc(100% - 36px);
 		background-color: #fff;
 		position: relative;
 
@@ -665,19 +679,25 @@ export default {
 			height: 90%;
 		}
 
-		.login-icon {
-			position: absolute;
-			top: 40px;
-			right: 40px;
-		}
+		// .login-icon {
+		// 	position: absolute;
+		// 	top: 40px;
+		// 	right: 40px;
+		// }
 		.login-title {
-			color: #333;
-			font-size: 32px;
+			color: #0052D9;
+			font-size: 28px;
 			display: block;
 			text-align: center;
-			margin-bottom: 60px;
+			margin-bottom: 25px;
+		}
+		.login-sub-title {
+			color: #7780B1;
+			font-size: 18px;
+			display: block;
+			text-align: center;
+			margin-bottom: 20px;
 		}
-
 		#login-container ,.login-box{
 			box-sizing: border-box;
 			border-radius: 10px;
@@ -810,6 +830,18 @@ export default {
 			}
 		}
 	}
+    .record-info{
+        display: flex;
+        flex-wrap: wrap;
+        justify-content: center;
+        width: 100%;
+        a{
+            font-size: 15px;
+            color: #C0C4CC;
+            text-align: center;
+            margin: 0 6px;
+        }
+    }
 	.remember-cont {
 		position: relative;
 		margin-bottom: 35px;

+ 6 - 3
src/views/chartRelevance_manage/components/selectTarget.vue

@@ -3,7 +3,7 @@
     <el-select
       style="width: 100%"
       v-model="targetType"
-      placeholder="请选择指标种类"
+      :placeholder="$t('StatisticAnalysis.StatisticFeatureChart.selecr_indicator_pld')"
       @change="targetTypeChange"
       v-if="selectStyleType===1&&filter"
     >
@@ -29,7 +29,7 @@
     <div v-else-if="selectStyleType===3&&filter" style="display:flex;align-items:center">
       <el-select
         v-model="targetType"
-        placeholder="请选择指标种类"
+        :placeholder="$t('StatisticAnalysis.StatisticFeatureChart.selecr_indicator_pld')"
         @change="targetTypeChange"
         style="width: 150px;"
       >
@@ -73,7 +73,7 @@
       remote
       clearable
       :placeholder="$t('Edb.InputHolderAll.select_edb_name')"
-      :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:{

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

@@ -562,6 +562,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"
@@ -725,7 +753,9 @@ export default {
 			needWatch: true,
 			IsNameDefault:true,
 
-			UnitOptions:unitArr
+			UnitOptions:unitArr,
+
+			useUnit:''
 
     };
   },
@@ -749,7 +779,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,
@@ -765,6 +795,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 = {
@@ -1205,6 +1263,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">

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

@@ -1373,7 +1373,8 @@ export default {
 
 			if(targetIndex===0){
 				PrevClassifyId=0
-				NextClassifyId=list[targetIndex+1].data.ChartClassifyId
+        // i=='inner'时,list里面只有一个Node时会数组越界,后面会对'inner'的重新处理,这里不报错就行
+				NextClassifyId=list[targetIndex+1] ? list[targetIndex+1].data.ChartClassifyId : 0
 			}else if(targetIndex===list.length-1){
 				PrevClassifyId=list[targetIndex-1].data.ChartClassifyId
 				NextClassifyId=0
@@ -1710,6 +1711,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:''
         }))
       }
 

+ 1 - 1
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="$t('Chart.chart_copy_btn')"
   >

+ 356 - 0
src/views/dataEntry_manage/databaseComponents/batchComputedSave.vue

@@ -0,0 +1,356 @@
+<template>
+    <div class="batch-computed-save-wrap">
+        <el-table 
+            :data="list" 
+            border 
+            height="500px"
+        >
+            <el-table-column label="指标全称" align="center" prop="EdbName"/>
+            <el-table-column label="生成指标名称" align="center">
+                <template slot-scope="scope">
+                    <el-input :disabled="operationForm.view" v-model="scope.row.name" placeholder="请填写指标名称" style="width:100%"/>
+                </template>
+            </el-table-column>
+            <el-table-column label="单位" align="center" width="200px">
+                <template slot-scope="scope">
+                    <selectUnit :disabled="operationForm.view||[6].includes(sourceTypeVal)" v-model="scope.row.unit"/>
+                </template>
+            </el-table-column>
+            <el-table-column label="频度" align="center" width="200px">
+                <template slot-scope="scope">
+                    <el-select
+						v-model="scope.row.frequency"
+						placeholder="请选择频率"
+                        @change="handleFrequencyChange(scope)"
+                        :disabled="operationForm.view||[5,6,14,61,63].includes(sourceTypeVal)"
+					>
+						<el-option
+							v-for="item in frequencyArr"
+							:key="item"
+							:label="item"
+							:value="item"
+						>
+						</el-option>
+					</el-select>
+                </template>
+            </el-table-column>
+            <el-table-column align="center" width="300px">
+                <template slot="header" slot-scope="scope">
+                    <span style="margin-right:40px;display:inline-block">目录</span>
+                    <el-radio-group :disabled="operationForm.view" v-model="classifyType" @change="handleClassifyTypeChange">
+                        <el-radio :label="0">分目录</el-radio>
+                        <el-radio :label="1">同目录</el-radio>
+                    </el-radio-group>
+                </template>
+                <template slot-scope="{row,$index}">
+                    <el-cascader
+						v-model="row.classify"
+						:options="classifyOpt"
+						:props="levelProps"
+						placeholder="请选择指标目录"
+                        :disabled="(classifyType===1&&$index>0)||operationForm.view"
+                        @change="handleClassifyChange(row,$index)"
+					/>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div style="text-align:center;margin:60px 0 40px 0" v-if="!operationForm.view">
+            <el-button type="primary" plain @click="handleClose">取消</el-button>
+            <el-button type="primary" @click="handleSubmit" :loading="loading">{{loading ? '批量计算中...' : '批量计算'}}</el-button>
+        </div>
+    </div>
+</template>
+
+<script>
+import { dataBaseInterface } from '@/api/api.js';
+import {generateSeriesArray} from './util'
+const tag_arr = generateSeriesArray();
+export default {
+    props:{
+        computedType:null,
+        subComputedType:null,
+        selectList:null,
+        formData:null,
+        select_target:null,
+        operationForm:null,
+        isEdit:false
+    },
+    computed: {
+        sourceTypeVal(){
+            if(!this.computedType) return 0
+            if(this.subComputedType) return this.subComputedType
+            return ['withNum','withEDB'].includes(this.computedType)?4:this.computedType
+        }
+    },
+    data() {
+        return {
+            frequencyArr: ['日度', '周度','旬度','月度', '季度', '年度'],
+
+            list:[],
+
+            classifyType:0,
+            classifyOpt: [],
+			levelProps: {
+				label: 'ClassifyName',
+				value: 'ClassifyId',
+				children: 'Children',
+				checkStrictly: true,
+                emitPath:false
+			},
+
+            loading:false,
+
+            computedArr:[],//多指标求和\平均的指标数组
+        }
+    },
+    mounted() {
+        this.initData()
+        this.getClassifyOpt()
+    },
+    methods: {
+        // 初始化数据
+        initData(){
+            let arr=[]
+
+            // 如果是多指标求和\平均
+            if(this.computedType==='multipleEDB'){
+                this.computedArr=this.selectList
+                // 如果是编辑时
+                if(this.isEdit){
+                    this.list=[{
+                        EdbName:this.operationForm.EdbInfoDetail.EdbName,
+                        EdbInfoId:this.operationForm.EdbInfoDetail.EdbInfoId,
+                        name:this.operationForm.EdbInfoDetail.EdbName,
+                        unit:this.operationForm.EdbInfoDetail.Unit,
+                        frequency:this.operationForm.EdbInfoDetail.Frequency,
+                        classify:this.operationForm.EdbInfoDetail.ClassifyId
+                    }]
+                    return
+                }
+                arr=[{...this.selectList[0]}]
+            }else{
+                arr=this.selectList
+            }
+            
+            
+            arr.forEach(item=>{
+                this.setDefaultVal(item)
+            })
+            
+        },
+        // 设置默认值
+        setDefaultVal(item){
+            const obj={
+                EdbName:item.EdbName,
+                EdbInfoId:item.EdbInfoId,
+                name:'',
+                unit:'',
+                frequency:'',
+                classify:''
+            }
+            const tMap=new Map([
+				['日度','D'],
+				['周度','W'],
+				['旬度','T'],
+				['月度','M'],
+				['季度','Q'],
+				['年度','Y'],
+			])
+			const name_map = {
+                4:item.EdbName,
+				5: `${item.EdbName}转月值`,
+				8: `${item.EdbName}/${this.formData.nNum}${tMap.get(item.Frequency)}MA`,
+				14: `${item.EdbName}/日频`,
+				6: `${item.EdbName}同比`,
+				7: `${item.EdbName}同差`,
+				12: `${item.EdbName}${this.formData.nNum}${item.Frequency.slice(0,1)}环比`,
+				13: `${item.EdbName}${this.formData.nNum}${item.Frequency.slice(0,1)}环差`,
+				35: `${item.EdbName}超季节性/${this.formData.nNum}年${this.formData.calendarType==='公历'?'':'/'+this.formData.calendarType}`,
+				52: `${item.EdbName}年化值`,
+				51: `${item.EdbName}/${this.formData.frequency.substr(0,1)}频`,
+				61:  `${item.EdbName}转季值`,
+				62:  `${item.EdbName}累计值/${this.formData.frequency}`,
+				63:  `${item.EdbName}年初至今累计值`,
+                72:`${item.EdbName}指数修匀`,
+				75: `${item.EdbName}日均值`,
+                81:item.EdbName,
+                82:item.EdbName,
+			}
+			
+			let frequerncyMap = {
+				14: '日度',
+				61: '季度',
+                62:this.formData.frequency,
+                51:this.formData.frequency,
+			}
+
+            obj.name=name_map[this.sourceTypeVal] || ''
+            obj.frequency=frequerncyMap[this.sourceTypeVal]|| item.Frequency
+            obj.classify=item.ClassifyId||''
+
+            if([5,8,14,7,35,75].includes(this.sourceTypeVal)){
+                obj.unit=item.Unit
+            }else if([4].includes(this.sourceTypeVal)){
+                obj.unit=''
+            }else{
+                obj.unit='无'
+            }
+            
+
+            this.list.push(obj)
+        },
+        // 频度变化 修改指标名
+		handleFrequencyChange(e){
+			if(!this.sourceTypeVal||![51,62].includes(this.sourceTypeVal)) return;
+            const obj=this.list[e.$index]
+			const name_map = {
+				51: `${obj.EdbName}/${obj.frequency.substr(0,1)}频`,
+				62:  `${obj.EdbName}累计值/${obj.frequency}`,
+			}
+			this.list[e.$index].name=name_map[this.sourceTypeVal]
+		},
+
+        // 同目录修改
+        handleClassifyChange(e,index){
+            if(this.classifyType===1){
+                // 修改所有的指标的目录为第一个
+                this.list.forEach(item=>{
+                    item.classify=e.classify
+                })
+            }
+        },
+
+        handleClassifyTypeChange(){
+            this.handleClassifyChange(this.list[0])
+        },
+
+        // 提交计算
+        async handleSubmit(){
+            const edbList=this.list.map((item,index)=>{
+                return{
+                    CalculateId:tag_arr[index],
+                    ClassifyId:item.classify,
+                    EdbName:item.name,
+                    Frequency:item.frequency,
+                    Unit:item.unit,
+                    FromEdbInfoId:this.isEdit?0:item.EdbInfoId,
+                    EdbInfoId:this.isEdit?item.EdbInfoId:0
+                }
+            })
+            const valueMap = {
+				51: 'valueType',
+                72:'alphaValue'
+			}
+            const params={
+                EdbList:edbList,
+                Formula:valueMap[this.sourceTypeVal] ? String(this.formData[valueMap[this.sourceTypeVal]]) : String(this.formData.nNum),
+                Source:this.sourceTypeVal,
+                CalculateFormula:this.sourceTypeVal===4? JSON.stringify([{f:this.formData.formula,d:''}]) : this.formData.formula,
+                EdbInfoIdArr:this.select_target?[{EdbInfoId:this.select_target,FromTag:'B'}]:[],
+                MoveType:0,
+                MoveFrequency:'',
+                Calendar:this.formData.calendarType,
+                EmptyType: this.formData.nullValueWay,
+				MaxEmptyType: this.formData.maxNullWay,
+                Extra:JSON.stringify({
+                    LastValType:this.formData.newValue,
+                    DateTag:this.formData.timeSeriesVal
+                })
+            }
+            // 处理多指标求和\平均 情况的数据
+            if(this.computedType==='multipleEDB'){
+                const arr=this.computedArr.map((item,index)=>{
+                    return{
+                        EdbInfoId:item.EdbInfoId,
+                        FromTag:tag_arr[index]
+                    }
+                })
+                params.EdbInfoIdArr=arr
+            }
+            console.log(params);
+
+            let isEnough = params.EdbList.every(item => item.EdbName&&item.Unit&&item.ClassifyId&&item.Frequency)
+            if(!isEnough) return this.$message.warning('请填写完整信息');
+
+            this.loading=true
+            const tipMsg=setTimeout(() => {
+                this.$message.success('请等待计算完成,该过程可能持续2-3分钟')
+            }, 500);
+            const res=this.isEdit?await dataBaseInterface.batchCalculateTargetEdit(params) : await dataBaseInterface.batchCalculateTargetAdd(params)
+            this.loading=false
+            clearTimeout(tipMsg)
+            
+            if(res.Ret !== 200) return
+
+            const { Fail,Success } = res.Data;
+
+            if(Fail.length) {
+                let message = '';
+                Fail.forEach(item => {
+                    message+=`${item.CalculateId}:${item.Msg}</br>`
+                })
+
+                this.$message({
+                    dangerouslyUseHTMLString: true,
+                    message,
+                    type: 'error'
+                })
+                this.dealFailHandle(Fail)
+            }else {
+                this.$message.success('添加成功');
+                // this.init();
+                this.$emit('addCallBack','add',{ code:Success[0].UniqueCode,id:Success[0].EdbInfoId,classifyId:Success[0].ClassifyId});
+            }
+
+        },
+
+        // 处理批量添加失败的指标
+        dealFailHandle(data){
+            let temarr=[]
+            data.forEach(item=>{
+                const index=tag_arr.indexOf(item.CalculateId)
+                temarr.push(this.list[index])
+            })
+            this.list=temarr
+        },
+
+
+        handleClose(){
+            this.$emit('close')
+        },
+        filterNodes(arr) {
+			arr.length &&
+				arr.forEach((item) => {
+					item.Children.length && this.filterNodes(item.Children);
+					if (!item.Children.length) {
+						delete item.Children;
+					}
+				});
+		},
+        // 获取指标分类
+        async getClassifyOpt(){
+            const res=await dataBaseInterface.menuListV3()
+            if (res.Ret !== 200) return
+            this.filterNodes(res.Data.AllNodes||[]);
+			this.classifyOpt = res.Data.AllNodes || [];
+        },
+    },
+}
+</script>
+
+<style lang="scss">
+.batch-computed-save-wrap{
+    .el-input{
+        input{
+            border: none;
+            text-align: center;
+        }
+    }
+    .el-table tr{
+        background-color: #fff !important;
+        &:hover>td{
+            background-color: transparent !important; /* 或者其他想要的颜色值 */
+        }
+    }
+}
+</style>

+ 982 - 0
src/views/dataEntry_manage/databaseComponents/batchComputedV2.vue

@@ -0,0 +1,982 @@
+<template>
+    <el-dialog
+		:visible.sync="isShow"
+		:close-on-click-modal="false"
+		:modal-append-to-body="false"
+		@close="handleClose"
+		custom-class="batch-computed-dialog fit-screen-dialog"
+		center
+		top="5vh"
+		v-dialogDrag
+        :title="showSave?'批量计算-结果保存':'批量计算-选择指标和计算公式'"
+	>
+        <div class="batch-computed-wrap" v-if="!showSave">
+            <el-form inline :disabled="operationForm.view">
+            <div class="type-wrap">
+                <div style="margin-right:50px">
+                    <span>计算公式</span>
+                    <el-select :disabled="isEdit" v-model="computedType" @change="handleComputedTypeChange" placeholder="请选择">
+                        <el-option 
+                            v-for="opt in computedBatchTypes" 
+                            :key="opt.type" 
+                            :label="opt.name"
+                            :value="opt.type"
+                        />
+                    </el-select>
+                </div>
+                <div style="flex:1">
+                    <!-- 累计值转月/季值 -->
+                    <el-form-item v-if="computedType=='toMonthSeason'">
+                        <el-radio-group v-model="subComputedType" @change="handleComputedSubTypeChange">
+                            <el-radio :label="5">转月值</el-radio>
+                            <el-radio :label="61">转季值</el-radio>
+                        </el-radio-group>
+                    </el-form-item>
+
+                    <!-- N期移动均值、N期环比值、N期环差值 -->
+                    <el-form-item required v-if="[8,12,13].includes(computedType)" label="N等于" style="width:280px">
+                        <el-input v-model="formData.nNum" placeholder="请输入N数值" type="number" style="width:200px"></el-input>
+                    </el-form-item>
+
+                    <!-- 超级季节性 -->
+                    <template v-if="computedType==35">
+                    <el-form-item required label="N等于" style="width:280px">
+                        <el-input v-model="formData.nNum" placeholder="请输入N数值" type="number" style="width:200px"></el-input>
+                    </el-form-item>
+                    <el-form-item label="日历"  style="width:180px">
+                        <el-select v-model="formData.calendarType" style="width:120px">
+                            <el-option label="公历" value="公历"></el-option>
+                            <el-option label="农历" value="农历"></el-option>
+                        </el-select>
+                    </el-form-item>
+                    </template>
+
+                    <!-- 降频 -->
+                    <template v-if="computedType==51">
+                    <el-form-item required label="频度" style="width:180px">
+                        <el-select v-model="formData.frequency" style="width:120px">
+                            <el-option v-for="opt in frequencyArr" :key="opt" :label="opt" :value="opt"></el-option>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item label="数据取值"  style="width:200px">
+                        <el-select v-model="formData.valueType" style="width:120px">
+                            <el-option key="期末值" label="期末值" value="期末值"/>
+							<el-option key="平均值" label="平均值" value="平均值"/>
+                        </el-select>
+                    </el-form-item>
+                    </template>
+
+                    <!-- 累计值 -->
+                    <template v-if="computedType=='accumulate'">
+                    <el-form-item>
+                        <el-radio v-model="subComputedType" :label="62">累计值</el-radio>
+                    </el-form-item>
+                    <el-form-item required label="频度" style="width:180px" v-if="subComputedType==62">
+                        <el-select v-model="formData.frequency" style="width:120px">
+                            <el-option v-for="opt in frequencyArr" :key="opt" :label="opt" :value="opt"></el-option>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item label="最新值处理"  style="width:210px" v-if="subComputedType==62">
+                        <el-select v-model="formData.newValue" style="width:120px">
+                            <el-option label="默认" :value="0"/>
+							<el-option label="均值填充" :value="1"/>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item>
+                        <el-radio v-model="subComputedType" :label="63">年初至今累计值</el-radio>
+                    </el-form-item>
+                    </template>
+
+                    <!-- 指数修匀 -->
+                    <template v-if="computedType==72">
+                    <el-form-item required label="alpha值" style="width:220px">
+                        <el-input v-model.trim="formData.alphaValue" style="width:140px" placeholder="请输入alpha值"></el-input>
+                    </el-form-item>
+                    </template>
+
+                    <!-- 与常数计算 -->
+                    <template v-if="computedType=='withNum'">
+                    <el-form-item required label="公式">
+                        <el-input v-model="formData.formula" placeholder="请输入公式" clearable style="width: 200px"/>
+                        <span>公式示例:A+100,或A*2</span>
+                    </el-form-item>
+                    </template>
+
+                    <!-- 与单指标计算 -->
+                    <template v-if="computedType=='withEDB'">
+                    <el-form-item required label="指标B">
+                        <el-select
+                            v-model="select_target"
+                            v-loadMore="searchLoad"
+                            :filterable="!select_target"
+                            clearable
+                            placeholder="请输入指标名称"
+                            style="width: 250px"
+                            remote
+                            :remote-method="getTarget"
+                            @click.native="inputFocusHandle"
+                            @change="chooseTarget"
+                            @blur="search_have_more = false"
+                        >
+                            <i slot="prefix" class="el-input__icon el-icon-search"></i>
+                            <el-option
+                                v-for="item in searchOptions"
+                                :key="item.EdbInfoId"
+                                :label="$parent.currentLang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName"
+                                :value="item.EdbInfoId"
+                            />
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item required label="公式">
+                        <el-input v-model="formData.formula" placeholder="请输入公式" clearable style="width: 200px"/>
+                        <span>公式示例:A+B,或A/B,A/(A+B)</span>
+                    </el-form-item>
+                    <el-form-item label="生成指标时间序列">
+                        <el-cascader
+							v-model="formData.timeSeriesVal"
+							style="width:180px"
+							:options="timeSeriesOpt"
+							:props="{emitPath:false}"
+							:show-all-levels="false"
+							placeholder="请选择"
+						></el-cascader>
+                    </el-form-item>
+                    <el-form-item label="空值处理">
+                        <el-select
+							v-model="formData.nullValueWay"
+							placeholder="请选择"
+                            style="width:180px"
+						>
+							<el-option
+								v-for="item in nullWayOptions"
+								:key="item.value"
+								:label="item.label"
+								:value="item.value"
+							>
+							</el-option>
+						</el-select>
+                    </el-form-item>
+                    <el-form-item label="MAX、MIN空值处理" v-if="showMaxNullDeal">
+                        <el-select
+							v-model="formData.maxNullWay"
+							placeholder="请选择"
+						>
+							<el-option label="等于0" :value="1" />
+							<el-option label="跳过空值" :value="2" />
+						</el-select>
+                    </el-form-item>
+                    </template>
+
+                    <!-- 多指标求和/平均 -->
+                    <template v-if="computedType=='multipleEDB'">
+                    <el-form-item style="margin-right:30px">
+                    <el-radio-group :disabled="isEdit" v-model="subComputedType">
+                        <el-radio :label="81">求和</el-radio>
+                        <el-radio :label="82">求平均</el-radio>
+                    </el-radio-group>
+                    </el-form-item>
+                    <el-form-item label="生成指标时间序列">
+                        <el-cascader
+							v-model="formData.timeSeriesVal"
+							style="width:180px"
+							:options="timeSeriesOpt"
+							:props="{emitPath:false}"
+							:show-all-levels="false"
+							placeholder="请选择"
+						></el-cascader>
+                    </el-form-item>
+                    <el-form-item label="空值处理">
+                        <el-select
+							v-model="formData.nullValueWay"
+							placeholder="请选择"
+                            style="width:180px"
+						>
+							<el-option
+								v-for="item in nullWayOptions"
+								:key="item.value"
+								:label="item.label"
+								:value="item.value"
+							>
+							</el-option>
+						</el-select>
+                    </el-form-item>
+                    </template>
+
+
+                </div>
+            </div>
+            </el-form>
+            <div class="filter-wrap" style="margin-top:20px">
+                <p style="margin-bottom:10px">待选指标(选择指标数量不超过{{MAXAddNUM}})</p>
+                <div>
+                    <el-cascader
+						v-model="filter.classify"
+						:options="classifyOpt"
+						:props="classifyProps"
+						clearable
+                        collapse-tags
+						placeholder="指标分类"
+                        style="width: 240px"
+                        @change="handleFilter"
+					/>
+                    <el-select
+						v-model="filter.frequency"
+						placeholder="请选择频率"
+						style="width: 140px"
+						clearable
+                        multiple
+                        collapse-tags
+                        @change="handleFilter"
+                        :disabled="[5,61].includes(subComputedType)"
+					>
+						<el-option
+							v-for="item in frequencyArr"
+							:key="item"
+							:label="item"
+							:value="item"
+						>
+						</el-option>
+					</el-select>
+                    <el-cascader
+                        v-model="filter.user"
+                        placeholder="创建人"
+                        :options="sysUserOpts"
+                        :props="sysUserProps"
+                        collapse-tags
+                        :show-all-levels="false"
+                        clearable
+                        filterable
+                        style="width:240px"
+                        @change="handleFilter"
+                    />
+                    <el-input 
+                        placeholder="指标ID/指标名称" 
+                        v-model="filter.keyword"
+                        style="width: 200px"
+                        @keydown.enter.native="handleFilter"
+                    >
+                        <i slot="prefix" class="el-input__icon el-icon-search"></i>
+                    </el-input>
+                    <el-checkbox 
+                        label="列表全选" 
+                        v-model="isCheckAll" 
+                        :indeterminate="isCheckIndeterminate" 
+                        style="margin-left:10px"
+                        @change="listCheckAllChange"
+                        :disabled="operationForm.view"
+                    />
+                </div>
+            </div>
+            <div class="table-wrap">
+                <div class="left-box">
+                    <el-table 
+                        :data="list" 
+                        border 
+                        @sort-change="sortChange"  
+                        @selection-change="selectionChange"
+                        ref="edbDataRef" 
+                        @select="selectHandle" 
+                        @select-all="selectAllHandle"
+                        height="500px"
+                        v-loading="listLoading"
+                    >
+                        <el-table-column type="selection" min-width="50" align="center"/>
+                        <el-table-column label="指标全称" show-overflow-tooltip align="center" prop="EdbName"/>
+                        <el-table-column label="最新日期" align="center" prop="EndDate" width="120px" />
+                        <el-table-column label="最新值" align="center" show-overflow-tooltip prop="EndValue" width="80px"/>
+                        <el-table-column label="创建人" align="center" show-overflow-tooltip prop="SysUserRealName" width="80px"/>
+                        <el-table-column label="频度" align="center" prop="Frequency" width="50px"/>
+                        <el-table-column label="单位" show-overflow-tooltip align="center" prop="Unit" width="50px"/>
+                    </el-table>
+                    <m-page 
+                        style="margin-top:10px"
+                        class="table-page" 
+                        v-show="total"
+                        :total="total" 
+                        :pageSize="pageSize"
+                        :page_no="page"
+                        :pagercount="5"
+                        @handleCurrentChange="pageNumberChange"
+                    />
+                </div>
+                <div style="padding-top:200px;margin:0 30px">
+                    <el-button type="primary" :disabled="operationForm.view" :loading="addLoading" @click="getAddEdbListData">加入已选指标</el-button>
+                </div>
+                <div class="right-box">
+                    <el-table 
+                        :data="selectList" 
+                        border 
+                        height="500px"
+                    >
+                        <el-table-column label="序号" width="50px" align="center" prop="No" v-if="computedType=='multipleEDB'">
+                            <template slot-scope="scope">
+                                {{scope.$index|getNoText}}
+                            </template>
+                        </el-table-column>
+                        <el-table-column label="指标全称" show-overflow-tooltip align="center" prop="EdbName"/>
+                        <el-table-column width="50px" align="center" v-if="!operationForm.view">
+                            <template slot="header" slot-scope="scope">
+                                <img @click="handleDelSelect('all')" style="width:15px;height:15px;cursor: pointer;" src="~@/assets/img/ai_m/delete.png" alt="">
+                            </template>
+                            <template slot-scope="scope">
+                                <img @click="handleDelSelect(scope)" style="width:15px;height:15px;cursor: pointer;" src="~@/assets/img/ai_m/delete.png" alt="">
+                            </template>
+                        </el-table-column>
+                    </el-table>
+                </div>
+            </div>
+            <div style="text-align:center;margin:60px 0 40px 0">
+                <el-button type="primary" plain @click="handleCloseSelf">取消</el-button>
+                <el-button type="primary" @click="handleNextStep">下一步</el-button>
+            </div>
+        </div>
+        <!-- 结果保存 -->
+        <batchComputedSave 
+            :select_target="select_target"
+            :computedType="computedType" 
+            :subComputedType="subComputedType" 
+            :selectList="selectList" 
+            :formData="formData" 
+            :isEdit="isEdit"
+            :operationForm="operationForm"
+            @close="showSave=false" 
+            @addCallBack="handleAddSuccess"
+            v-else
+        />
+    </el-dialog>
+</template>
+
+<script>
+import mPage from '@/components/mPage.vue'
+import {computedBatchTypesV2} from './util'
+import { dataBaseInterface,departInterence } from '@/api/api.js';
+import batchComputedSave from './batchComputedSave.vue';
+import {generateSeriesArray} from './util'
+const tag_arr = generateSeriesArray();
+export default {
+    components:{mPage,batchComputedSave},
+    props:{
+        isShow:{
+            type: Boolean
+        },
+        operationForm: {
+			type: Object,
+		},
+        type: {
+			type: Number
+		},
+    },
+    filters:{
+        getNoText(e){
+            return tag_arr[e]
+        }
+    },
+    computed:{
+        // 最大添加指标的上限
+        MAXAddNUM(){
+            let num=50
+            if(this.computedType=='multipleEDB'){
+                num=100
+            }
+            return num
+        },
+        /* max空值处理显示 当输入的公式包含MAX、MIN且空值处理为0时,输入公式失焦后出现右侧选项; */
+		showMaxNullDeal() {
+			let haveMaxOrMin =  this.formData.formula.toUpperCase().includes('MAX') || this.formData.formula.toUpperCase().includes('MIN')
+
+			return haveMaxOrMin && this.formData.nullValueWay===4
+		},
+        timeSeriesOpt(){
+            let arr=[
+                {
+                    label:`指标A`,
+                    value:'A'
+                },
+                {
+                    label:`指标B`,
+                    value:'B'
+                }
+            ]
+            if(this.computedType=='multipleEDB'){
+                arr=this.selectList.map((item,index)=>{
+                    return{
+                        label:`指标${tag_arr[index]}`,
+                        value:tag_arr[index]
+                    }
+                })
+            }
+            return [
+                {
+                    label:'指定指标时间序列',
+					value:'0',
+                    children:arr
+                },
+                {
+					label:'所有指标时间序列并集',
+					value:'all',
+				}
+            ]
+        },
+
+        frequencyArr(){
+            if(this.computedType==75){
+                return ['周度','旬度','月度', '季度', '年度']
+            }
+            return ['日度', '周度','旬度','月度', '季度', '年度']
+        }
+    },
+    watch: {
+        isShow(n){
+            if(!n){
+                this.subComputedType=''
+                this.select_target=''
+                this.selectList=[]
+                this.tableDataCheckedList=[]
+                this.tableDataIds=[]
+                this.isCheckAll=false
+                this.isCheckIndeterminate=false
+                this.checkAllStatus=false
+                this.selectionReactCancel=false
+                this.isEdit=false
+                this.showSave=false
+                this.computedType=computedBatchTypesV2[0].type
+                this.filter={
+                    classify:'',
+                    frequency:'',
+                    user:'',
+                    keyword:''
+                }
+                this.formData={
+                    nNum:1,
+                    calendarType:'公历',
+                    frequency:'',
+                    valueType:'期末值',
+                    newValue:0,
+                    alphaValue:'',
+                    formula:'',
+                    timeSeriesVal:'A',
+                    nullValueWay:0,
+                    maxNullWay:1,
+                }
+            }else{
+                // 编辑多指标求和\平均
+                if([81,82].includes(this.type)){
+                    this.initData()
+                }
+                this.handleFilter()
+            }
+        }
+    },
+    data() {
+        return {
+            showSave:false,//显示结果保存模块
+            computedBatchTypes:computedBatchTypesV2,//计算类型筛选项
+            computedType:computedBatchTypesV2[0].type,//当前选中的计算类型
+            subComputedType:'',//二级计算类型
+            formData:{
+                nNum:1,
+                calendarType:'公历',
+                frequency:'',
+                valueType:'期末值',
+                newValue:0,
+                alphaValue:'',
+                formula:'',
+                timeSeriesVal:'A',
+                nullValueWay:0,
+                maxNullWay:1,
+            },
+
+            select_target:'',
+			searchOptions:[],//指标列表
+            search_have_more:false,
+            search_page: 1,
+			current_search: '',
+
+            filter:{
+                classify:'',
+                frequency:'',
+                user:'',
+                keyword:''
+            },
+
+            // frequencyArr: ['日度', '周度','旬度','月度', '季度', '年度'],
+            classifyOpt: [],
+			classifyProps: {
+				label: 'ClassifyName',
+				value: 'ClassifyId',
+				children: 'Children',
+				multiple: true,
+                emitPath:false
+			},
+            sysUserOpts:[],
+            sysUserProps:{
+                value: "AdminId",
+                label: "RealName",
+                children: "ChildrenList",
+                multiple: true,
+                emitPath:false
+            },
+
+            nullWayOptions: [
+				{ label: '查找前后35天最近值',value: 0 },
+				{ label: '不计算',value: 1 },
+				{ label: '前值填充',value: 2 },
+				{ label: '后值填充',value: 3 },
+				{ label: '等于0',value: 4 },
+			],
+
+            isCheckAll:false,//是否全选
+            isCheckIndeterminate:false,// 标志列表当前是全选状态还是不是全选状态和 isCheckAll不一样
+            checkAllStatus:false,
+            selectionReactCancel:false,// 是否不触发 selection的逻辑
+
+            listLoading:false,
+            page:1,
+            pageSize:20,
+            total:0,
+            list:[],
+
+            tableDataCheckedList:[],
+            tableDataIds:[],
+
+            selectList:[],//添加到右侧的数据
+            addLoading:false,
+
+            isEdit:false,//是否为多指标求和等编辑
+
+        }
+    },
+    mounted() {
+        this.getClassifyOpt()
+        this.getEDBList()
+        this.getSysUserList()
+    },
+    
+    methods: {
+        // 编辑时初始化数据
+        initData(){
+            this.isEdit=true
+            const arr=this.operationForm.CalculateList||[]
+            this.selectList=arr.map(item=>{
+                return {
+                    ClassifyId:item.ClassifyId,
+                    EdbInfoId:item.FromEdbInfoId,
+                    EdbName:item.FromEdbName,
+                    Frequency:item.Frequency,
+                    Unit:item.Unit
+                }
+            })
+            this.computedType='multipleEDB'
+            this.subComputedType=this.type
+            this.formData.timeSeriesVal=this.operationForm.EdbInfoDetail.Extra?JSON.parse(this.operationForm.EdbInfoDetail.Extra).DateTag:'A'
+            this.formData.nullValueWay=this.operationForm.EdbInfoDetail.EmptyType||0
+
+        },
+        //批量计算成功回调
+        handleAddSuccess(type,params){
+            this.$emit('addCallBack',type,params)
+        },
+        // 跳转下一步
+        handleNextStep(){
+            if(this.selectList.length===0){
+                this.$message.warning('请选择指标')
+                return
+            }
+            if([8,12,13,35].includes(this.computedType) && !this.formData.nNum){
+                this.$message.warning('请输入N数值')
+                return
+            }
+            if([51].includes(this.computedType)&& !this.formData.frequency){
+                this.$message.warning('请选择频度')
+                return
+            }
+            if(['accumulate'].includes(this.computedType)&&this.subComputedType==62&& !this.formData.frequency){
+                this.$message.warning('请选择频度')
+                return
+            }
+            if(this.computedType==72&&!this.formData.alphaValue){
+                this.$message.warning('请输入alpha值')
+                return
+            }
+            if(this.computedType==72&&(Number(this.formData.alphaValue)<=0||Number(this.formData.alphaValue)>=1)){
+                this.$message.warning('请输入>0,<1的数值的alpha值')
+                return
+            }
+            if(this.computedType=='withEDB'&&!this.select_target){
+                this.$message.warning('请选择指标B')
+                return
+            }
+            if(['withNum','withEDB'].includes(this.computedType)&&!this.formData.formula){
+                this.$message.warning('请输入公式')
+                return
+            }
+
+            this.isCheckAll=false
+            this.isCheckIndeterminate=false
+            this.checkAllStatus=false
+            this.tableDataCheckedList=[]
+            this.tableDataIds=[]
+
+            this.showSave=true
+        },
+
+        // 点击加入已选指标库
+        async getAddEdbListData(){
+            if(!(this.isCheckAll || this.isCheckIndeterminate ) || (!(this.list && this.list.length>0))){
+                this.$message.warning('请选择指标')
+                return
+            }
+            if(this.selectList.length>=this.MAXAddNUM){
+                this.$message.warning('已达批量添加指标数量上限')
+                return
+            }
+            const params={
+                SysUserIds:this.filter.user?this.filter.user.join(','):'',
+                ClassifyIds:this.filter.classify?this.filter.classify.join(','):'',
+                Keyword:this.filter.keyword,
+                Frequency:this.filter.frequency?this.filter.frequency.join(','):'',
+                SelectAll:this.checkAllStatus,
+                EdbInfoIds:this.tableDataCheckedList.join(',')
+            }
+            this.addLoading=true
+            const res=await dataBaseInterface.getBatchFilterAddEdbList(params)
+            this.addLoading=false
+            if(res.Ret!=200) return
+            // 加入到已选指标中 要去重
+            const arr=res.Data.SearchItem||[]
+            const temArr=this.mergeAndDistinct(this.selectList,arr)
+            // 截取数组 防止数量溢出
+            this.selectList=temArr.slice(0,this.MAXAddNUM)
+        },
+        mergeAndDistinct(arr1, arr2) {
+            // 合并两个数组
+            const mergedArray = arr1.concat(arr2);
+
+            // 根据 EdbInfoId 字段进行去重
+            const distinctArray = mergedArray.filter((item, index, self) => {
+                return index === self.findIndex(t => t.EdbInfoId === item.EdbInfoId);
+            });
+
+            return distinctArray;
+        },
+
+        // 删除已选指标库指标
+        handleDelSelect(e){
+            if(this.operationForm.view) return
+            if(e==='all'){
+                this.selectList=[]
+                return
+            }
+            const index=e.$index
+            this.selectList.splice(index,1)
+        },
+
+        // 切换计算类型
+        handleComputedTypeChange(){
+            this.subComputedType=''
+            this.select_target=''
+            this.formData={
+                nNum:1,
+                calendarType:'公历',
+                frequency:'',
+                valueType:'期末值',
+                newValue:0,
+                alphaValue:'',
+                formula:'',
+                timeSeriesVal:'A',
+                nullValueWay:0,
+                maxNullWay:1,
+            }
+            this.filter={
+                classify:'',
+                frequency:'',
+                user:'',
+                keyword:''
+            }
+            this.selectList=[]
+            if(this.computedType=='toMonthSeason'){
+                this.subComputedType=5
+                this.filter.frequency=['月度']
+            }else if(this.computedType=='accumulate'){
+                this.subComputedType=62
+            }else if(this.computedType=='multipleEDB'){
+                this.subComputedType=81
+            }
+            this.handleFilter()
+        },
+        handleComputedSubTypeChange(){
+            if(this.subComputedType==61){
+                this.filter.frequency=['季度']
+            }
+            if(this.subComputedType==5){
+                this.filter.frequency=['月度']
+            }
+            this.selectList=[]
+            this.handleFilter()
+        },
+
+        /* 指标列表 */
+		getTarget(query) {
+			this.search_page = 1;
+			this.current_search = query;
+			this.searchApi(this.current_search);
+		},
+
+		/* 聚焦获取当前检索 */
+		inputFocusHandle(e) {
+			this.search_page = 1;
+			this.current_search = e.target.value;
+			this.searchApi(this.current_search);
+		},
+
+		searchApi(query,page=1) {
+			dataBaseInterface.targetSearchByPage({
+				KeyWord:query,
+				CurrentIndex: page,
+				FilterSource:  1,
+				Frequency: ''
+			}).then(res => {
+				if(res.Ret !== 200) return
+				const { List,Paging } = res.Data;
+				this.search_have_more = page < Paging.Pages;
+				let arr = page === 1 ? List : this.searchOptions.concat(List);
+
+				this.searchOptions = arr;
+					
+			})
+		},
+
+		searchLoad() {
+			if(!this.search_have_more) return;
+			this.searchApi(this.current_search,++this.search_page)
+		},
+
+        handleClose(){
+            this.showSave=false
+            this.$emit('close')
+        },
+        handleCloseSelf(){//仅仅关闭批量计算弹窗
+            this.$emit('closeSelf')
+        },
+
+        filterNodes(arr) {
+			arr.length &&
+				arr.forEach((item) => {
+					item.Children.length && this.filterNodes(item.Children);
+					if (!item.Children.length) {
+						delete item.Children;
+					}
+				});
+		},
+        // 获取指标分类
+        async getClassifyOpt(){
+            const res=await dataBaseInterface.menuListV3()
+            if (res.Ret !== 200) return
+            this.filterNodes(res.Data.AllNodes||[]);
+			this.classifyOpt = res.Data.AllNodes || [];
+        },
+
+        // 获取所有系统用户
+        async getSysUserList() {
+            const res = await departInterence.getQuestionAdminList();
+            if (res.Ret === 200) {
+                this.sysUserOpts = res.Data.List||[];
+            }
+        },
+
+        // 获取指标列表
+        async getEDBList(type){
+            this.listLoading=true
+            const res=await dataBaseInterface.getBatchAddEdbSearchList({
+                CurrentIndex:this.page,
+                PageSize: this.pageSize,
+                SysUserIds:this.filter.user?this.filter.user.join(','):'',
+                ClassifyIds:this.filter.classify?this.filter.classify.join(','):'',
+                Keyword:this.filter.keyword,
+                Frequency:this.filter.frequency?this.filter.frequency.join(','):'',
+                NotFrequency:this.computedType==75?'日度':''
+            })
+            this.listLoading=false
+            if(res.Ret===200){
+                this.list=res.Data.SearchItem||[]
+                this.total=res.Data.Paging.Totals||0
+
+                if(this.list.length>0){
+                    this.tableDataIds = this.list.map(it => it.EdbInfoId)
+                }else{
+                    this.tableDataIds = []
+                }
+
+                if(type == 'adjustSelection'){
+                    this.adjustSelection()
+                }else{
+                    
+                    this.isCheckAll=false
+                    this.checkAllStatus=false
+                    this.isCheckIndeterminate=false
+                    
+                    this.listCheckAllChange(this.isCheckAll)
+                }
+            }
+        },
+
+        pageNumberChange(e){
+            this.page=e
+            this.getEDBList('adjustSelection')
+        },
+
+        handleFilter(e){
+            this.page=1
+            this.list=[]
+            this.getEDBList()
+        },
+
+        // 切换列表全选按钮状态
+        listCheckAllChange(check){
+            this.tableDataCheckedList=[]
+            this.checkAllStatus=check
+            if(check){
+                // 全选
+                this.$refs.edbDataRef && this.$refs.edbDataRef.clearSelection()
+                this.$refs.edbDataRef && this.$refs.edbDataRef.toggleAllSelection()
+            }else{
+                //全不选
+                this.$refs.edbDataRef && this.$refs.edbDataRef.clearSelection()
+            }
+        },
+
+        selectionChange(val){
+            if(this.selectionReactCancel) return 
+        
+            // selectAllHandle的触发在selectionChange后面,将selectionChange的逻辑延迟一下
+            setTimeout(()=>{
+                // 去重
+                let duplicateArr = Array.from(new Set(this.tableDataCheckedList))
+                
+                if((duplicateArr.length == this.total && (!this.checkAllStatus))
+                    || (duplicateArr.length == 0 && this.checkAllStatus)){
+                    this.isCheckAll = true
+                    this.isCheckIndeterminate=false
+                }else if((duplicateArr.length == 0 && (!this.checkAllStatus))
+                    || (duplicateArr.length == this.total && this.checkAllStatus)){
+                    this.isCheckAll = false
+                    this.isCheckIndeterminate=false
+                }else{
+                    this.isCheckAll = false
+                    this.isCheckIndeterminate=true
+                }
+            },1)
+
+        },
+
+        //用户手动勾选数据行的 Checkbox 时触发的事件	
+        selectHandle(selection, row){
+            if(this.selectionReactCancel) return 
+
+            let check=false
+            if(selection.some(it => it.EdbInfoId == row.EdbInfoId)){
+                // 勾选
+                // 勾选
+                if(this.checkAllStatus){
+                    check=false
+                }else{
+                    check=true
+                }
+            }else{
+                // 取消勾选
+                if(this.checkAllStatus){
+                    check=true
+                }else{
+                    check=false
+                }
+            }
+            if(check){
+                this.tableDataCheckedList.push(row.EdbInfoId)
+            }else{
+                this.tableDataCheckedList=this.tableDataCheckedList.filter(it => it!=row.EdbInfoId)
+            }
+        },
+
+        // 用户手动勾选全选 Checkbox 时触发的事件
+        selectAllHandle(selection){
+            if(this.selectionReactCancel) return 
+            let check = false; // 从tableDataCheckedList 添加还是删除
+            if(selection && selection.length>0){
+                // 全选
+                if(this.checkAllStatus){
+                    check=false
+                }else{
+                    check=true
+                }
+            }else{
+                // 全不选
+                if(this.checkAllStatus){
+                    check=true
+                }else{
+                    check=false
+                }
+            }
+            if(check){
+                this.tableDataCheckedList =  [...this.tableDataCheckedList,...this.tableDataIds]
+            }else{
+                this.tableDataCheckedList = this.tableDataCheckedList.filter(it => !this.tableDataIds.includes(it))
+            }
+        },
+
+        adjustSelection(){
+            this.selectionReactCancel=true
+            if(!this.checkAllStatus){
+                this.tableDataCheckedList.map(it =>{
+                    let row = this.list.find(da => da.EdbInfoId==it)
+                    if(row){
+                        setTimeout(()=>{
+                            this.$refs.edbDataRef.toggleRowSelection(row,true)
+                        },10)
+                    }
+                })
+            }else{
+                this.$refs.edbDataRef.toggleAllSelection()
+                this.tableDataCheckedList.map(it =>{
+                    let row = this.list.find(da => da.EdbInfoId==it)
+                    if(row){
+                        setTimeout(()=>{
+                            this.$refs.edbDataRef.toggleRowSelection(row,false)
+                        },50)
+                    }
+                })
+            }
+            setTimeout(()=>{
+                this.selectionReactCancel=false
+            },50)
+        },
+
+
+
+    },
+}
+</script>
+
+<style lang="scss">
+.batch-computed-dialog{
+    max-width: 1200px;
+    width:90vw;
+	overflow: hidden;
+}
+.batch-computed-wrap{
+    .type-wrap{
+        display: flex;
+    }
+    .table-wrap{
+        margin-top: 20px;
+        display: flex;
+        justify-content: space-between;
+        .left-box{
+            width: 50%;
+        }
+        .right-box{
+            flex: 1;
+            flex-shrink: 0;
+        }
+    }
+}
+</style>

+ 93 - 6
src/views/dataEntry_manage/databaseComponents/computedDialog.vue

@@ -70,6 +70,24 @@
 				<!-- 添加更多参数 -->{{$t('EtaBasePage.add_more_param')}}
 			</span>
 			<div class="computed-min">
+				<div class="computed-section" v-if="edbSource !== 'predict'">
+					<div>
+						<label class="label">生成指标时间序列</label>
+						<div style="width:200px;display: inline-block;">
+							<el-cascader
+								v-model="selectTimeSeriesVal"
+								style="width:100%"
+								:options="timeSeriesOpt"
+								:props="{emitPath:false}"
+								:show-all-levels="false"
+								placeholder="请选择"
+								:disabled="calulateForm.view"
+							></el-cascader>
+						</div>
+						
+					</div>
+				</div>
+
 				<div class="computed-section">
 					<div>
 						<label class="label"><!-- 空值处理 -->{{$t('EtaBasePage.null_val_deal')}}
@@ -121,7 +139,7 @@
 					</el-input> -->
 					<ul class="formula-list">
 						<li style="margin-bottom: 15px;">
-							<el-input :placeholder="$t('EtaBasePage.input_formula_msg')" v-model="formulaList[0].formula" clearable :disabled="calulateForm.view" style="width: 220px"/>
+							<el-input :placeholder="$t('EtaBasePage.input_formula_msg')" v-model="formulaList[0].formula" clearable :disabled="calulateForm.view" style="width: 600px"/>
 							
 							<span v-if="formulaDateArr.length" class="date-section-text">{{formulaDateArr[formulaDateArr.length-1]}}(含)之后</span>
 
@@ -243,8 +261,11 @@ import { dataBaseInterface } from '@/api/api.js';
 import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
 import { formRules,frequencyArr } from '../databaseComponents/util';
 import { unitArr } from '@/utils/defaultOptions';
-const tag_arr = [];
-for(let i=0;i<26;i++) tag_arr.push(String.fromCharCode(65+i));
+import {generateSeriesArray} from './util'
+const MAXEDBNUM=50//最大可添加的指标数量
+const tag_arr = generateSeriesArray();
+
+// for(let i=0;i<26;i++) tag_arr.push(String.fromCharCode(65+i));
 export default {
 	name: '',
 	props: {
@@ -280,6 +301,28 @@ export default {
 
 		formulaDateArr() {
 			return this.formulaList.map(_ => _.date).filter(_ => _).sort((a,b) => new Date(a)-new Date(b))
+		},
+
+		timeSeriesOpt(){
+			const arr=[
+				{
+					label:'指定指标时间序列',
+					value:'0',
+					children:[]
+				},
+				{
+					label:'所有指标时间序列并集',
+					value:'all',
+				}
+			]
+			arr[0].children=this.addList.filter(item=>item.target).map(item=>{
+				return {
+					label:`指标${item.tag}`,
+					value:item.tag
+				}
+			})
+
+			return arr
 		}
 	},
 	watch: {
@@ -310,9 +353,43 @@ export default {
 					EdbName: item.edb_name,
 				}))
 
+				if(this.calulateForm.Extra){
+					const ExtraObj=JSON.parse(this.calulateForm.Extra)
+					this.selectTimeSeriesVal=ExtraObj.DateTag
+				}
+				
+
+
 				this.getNewestDate();
 			}
 		},
+
+		'addList':{
+			handler(n){
+				if(this.selectTimeSeriesVal=='all') return
+				const arr=this.addList.filter(item=>item.target).map(item=>{
+					return {
+						label:`指标${item.tag}`,
+						value:item.tag
+					}
+				})
+				if(!arr.length) return
+				if(!this.selectTimeSeriesVal){
+					this.selectTimeSeriesVal=arr[0].value
+				}else{//已经有选择的值了
+					let flag=false
+					arr.forEach(item=>{
+						if(item.value==this.selectTimeSeriesVal){
+							flag=true
+						}
+					})
+					if(!flag){
+						this.selectTimeSeriesVal=arr[0].value
+					}
+				}
+			},
+			deep:true
+		}
 	},
 	data() {
 		return {
@@ -381,6 +458,9 @@ export default {
 				{ label: '后值填充',value: 3 },
 				{ label: '等于0',value: 4 },
 			],
+
+			selectTimeSeriesVal:'',
+
 			formTips: {
 				'null-val': `1、查找前后35天最近值:在参与计算的日期序列上某指标无值时,该指标往前/往后找距离最近的值作为当天的值进行计算,遍历允许跨年,往前最多35天,往后最多35天<br>
 				2、不计算:只要有一个指标在某个日期没有值(即空值),则计算指标在该日期没有值 <br>
@@ -421,7 +501,8 @@ export default {
 		},
 		/* 添加额外的指标列 */
 		addTargetHandle() {
-			if(this.addList.length >= 26) return this.$message.warning(/* '添加指标个数已达上限' */this.$t('EtaBasePage.num_overrun_msg'))
+			const MAXNUM=this.edbSource === 'predict'?26:MAXEDBNUM
+			if(this.addList.length >=MAXNUM) return this.$message.warning(this.$t('EtaBasePage.num_overrun_msg'))
 			let tag = this.addList[this.addList.length-1].tag;
 			let index = tag_arr.findIndex(item => item === tag);
 			const item = {
@@ -535,7 +616,10 @@ export default {
 					Unit: this.formData.unit,
 					EdbInfoIdArr,
 					EmptyType: nullValueWay,
-					MaxEmptyType: maxNullWay
+					MaxEmptyType: maxNullWay,
+					Extra:JSON.stringify({
+						DateTag:this.selectTimeSeriesVal
+					})
 				};
 				this.dataloading = true;
 
@@ -655,7 +739,7 @@ export default {
 		width: 6px !important;
 	}
 	.el-dialog__body {
-		max-height: 700px;
+		max-height: 840px;
 		overflow: auto;
 	}
 	.dialog-main {
@@ -709,6 +793,9 @@ export default {
 			.computed-section {
 				display: flex;
 				margin-top: 20px;
+				.el-cascader .el-input {
+					width: 100%;
+				}
 			}
 			.label {
 				padding:10px 10px 10px 0;

+ 14 - 10
src/views/dataEntry_manage/databaseComponents/diffusionIndexDia.vue

@@ -93,11 +93,11 @@
             />
           </el-form-item>
           <el-form-item :label="$t('Edb.Detail.e_unit')" prop="unit">
-						<selectUnit 
-								v-model="formData.unit" 
-							style="width:340px" 
-							:disabled="!operationForm.edb_id&&[6,7].includes(type)"
-						/>
+			<selectUnit 
+			  	v-model="formData.unit" 
+				style="width:340px" 
+				:disabled="type===53"
+			/>
           </el-form-item>
           <el-form-item :label="$t('Edb.Detail.e_menu')" prop="menu" style="margin-right: 40px;">
             <el-cascader
@@ -150,12 +150,12 @@
 
 <script>
 import { dataBaseInterface } from '@/api/api.js';
-import { formRules } from './util';
+import { formRules,generateSeriesArray,frequencyArr } from './util';
 import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
 import { unitArr } from '@/utils/defaultOptions';
-import { frequencyArr } from './util'
-const tag_arr = [];
-for(let i=0;i<26;i++) tag_arr.push(String.fromCharCode(65+i));
+const MAXEDBNUM=50//最大可添加的指标数量
+const tag_arr = generateSeriesArray();
+// for(let i=0;i<26;i++) tag_arr.push(String.fromCharCode(65+i));
 export default {
 	name:'',
 	props: {
@@ -206,6 +206,9 @@ export default {
 
 				this.formData.select_date.length && this.formData.date_type === 2 && this.setConcatDate()
 			}
+			if(newval&&this.type===53&&!this.operationForm.edb_id){
+				this.formData.unit='无'
+			}
 		}
 	},
 	data () {
@@ -369,7 +372,8 @@ export default {
 
 		/* 添加指标 */
 		addTargetHandle() {
-			if(this.targetList.length === 26) return this.$message.warning(this.$t('EtaBasePage.num_overrun_msg'))
+			const NUM=this.isPredict?26:MAXEDBNUM
+			if(this.targetList.length === NUM) return this.$message.warning(this.$t('EtaBasePage.num_overrun_msg'))
 			let tag = this.targetList[this.targetList.length-1].tag;
 			let index = tag_arr.findIndex(item => item === tag);
 			const item = {

+ 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;">

+ 7 - 0
src/views/dataEntry_manage/databaseComponents/fittingResidueDia.vue

@@ -391,6 +391,13 @@ export default {
 					? this.formData.self_edb_date = [choose_obj.StartDate,choose_obj.EndDate]
 					: this.formData.depend_edb_date = [choose_obj.StartDate,choose_obj.EndDate]
 
+				// 设置目录、频度、单位
+				if(type==='self'){
+					this.formData.menu=choose_obj.ClassifyId
+					this.formData.unit=choose_obj.Unit
+					this.formData.frequency=choose_obj.Frequency
+				}
+				
 			}
 			this.getCorrelationIndex();
 		},

+ 14 - 0
src/views/dataEntry_manage/databaseComponents/jointTargetDia.vue

@@ -79,6 +79,7 @@
 							:remote-method="query=>{searchHandle(query)}"
 							@click.native="inputFocusHandle"
 							@blur="search_have_more = false"
+							@change="chooseTarget(formData.after_edb,'searchOptions')"
 						>
 							<i slot="prefix" class="el-input__icon el-icon-search"></i>
 							<el-option
@@ -106,6 +107,7 @@
 						:remote-method="query=>{searchHandle(query,'month')}"
 						@click.native="e => {inputFocusHandle(e,'month')} "
 						@blur="search_have_more = false"
+						@change="chooseTarget(formData.old_stay_edb,'searchMonthOptions')"
 						>
 							<i slot="prefix" class="el-input__icon el-icon-search"></i>
 							<el-option
@@ -400,6 +402,18 @@ export default {
 		};
 	},
 	methods: {
+		// 选中指标更新默认值
+		chooseTarget(val,key){
+			if(!val) return
+			const arr=key==='searchMonthOptions'?this.searchMonthOptions:this.searchOptions
+			let obj = arr.find(item => item.EdbInfoId === val);
+			console.log(obj);
+			this.formData.edb_name=`${obj.EdbName}/拼接`
+			this.formData.menu=obj.ClassifyId||''
+			this.formData.frequency=obj.Frequency
+			this.formData.unit=obj.Unit
+		},
+
 		/* 搜索 */
 		searchHandle(query,type) {
 			this.search_page = 1;

+ 71 - 13
src/views/dataEntry_manage/databaseComponents/operationDialog.vue

@@ -133,6 +133,7 @@
 								min="0"
 								size="mini"
 								v-model="formData.moveVal"
+								@change="refreshTarget"
 								@keyup.native="filterCode(formData)"
 							></el-input>
 							<el-select
@@ -181,6 +182,7 @@
 								style="width: 340px"
 								clearable
 								:disabled="[5,14,61,63].includes(type)||(!operationForm.edb_id&&[6,7,75].includes(type))"
+								@change="handleFrequencyChange"
 							>
 								<el-option
 									v-for="item in frequencyArr"
@@ -226,6 +228,12 @@
 								<el-option :label="$t('EtaBasePage.val_type_average')" value="平均值"/>
 							</el-select>
 						</el-form-item>
+						<el-form-item label="最新值处理" prop="new_value" v-if="type===62">
+							<el-select v-model="formData.new_value" placeholder="请选择" style="width: 340px">
+								<el-option label="默认" value=""></el-option>
+								<el-option label="均值填充" :value="'均值填充'" v-if="hasNewValueOpt"></el-option> 
+							</el-select>
+						</el-form-item>
 					</el-form>
 				</div>
 			</div>
@@ -267,6 +275,12 @@ export default {
 			type: Object,
 		}
 	},
+	computed: {
+		// 累计值计算时 均值填充判断标识
+		frequencyChangeFlag(){
+			return this.tableData[0]?`${this.tableData[0].Frequency}转${this.formData.frequency}`:''
+		}
+	},
 	watch: {
 		isOperation(newval) {
 			newval && this.getMenu();
@@ -298,10 +312,16 @@ export default {
 					moveType,
 					moveUnit,
 					moveVal,
-					calendar_type
+					calendar_type,
+					new_value:''
 				}
 				this.getDataList();
 
+				if(backData.Extra){
+					const ExtraObj=JSON.parse(backData.Extra)
+					this.formData.new_value=ExtraObj.LastValType==1?'均值填充':''
+				}
+
 				//回显时的默认options
 				this.searchOptions = [
 					{
@@ -316,6 +336,15 @@ export default {
 				: [62,63].includes(this.type)
 				? [{ label: /* '累计值' */this.$t('Edb.CalculatesAll.cumulate'),key: 62 },{ label: /* '年初至今累计值' */this.$t('Edb.CalculatesAll.cumulate_oneyear'),key: 63 }]
 				: []
+		},
+		frequencyChangeFlag(n){
+			const arr=['日度转周度','日度转旬度','周度转旬度']
+			if(n&&arr.includes(n)){
+				this.hasNewValueOpt=false
+				this.formData.new_value=''
+			}else{
+				this.hasNewValueOpt=true
+			}
 		}
 	},
 	computed: {
@@ -413,7 +442,8 @@ export default {
 				moveUnit: '天',
 				moveVal: '',
 				calendar_type: '公历',
-				value_type: '期末值'
+				value_type: '期末值',
+				new_value:'',
 			},
 			options: [],
 			levelProps: {
@@ -447,6 +477,8 @@ export default {
 
 			sourceList: [],
 
+			hasNewValueOpt:true,//最新值处理的选项
+
 		};
 	},
 	methods: {
@@ -593,7 +625,8 @@ export default {
 				moveUnit: '天',
 				moveVal: '',
 				calendar_type: '公历',
-				value_type: '期末值'
+				value_type: '期末值',
+				new_value:''
 			};
 			this.$refs.form.resetFields();
 		},
@@ -621,6 +654,9 @@ export default {
 					MoveFrequency: this.formData.moveUnit,
 					MoveType: this.formData.moveType, 
 					Calendar: this.formData.calendar_type,
+					Extra:JSON.stringify({
+						LastValType:this.formData.new_value==='均值填充'?1:0
+					})
 				}
 
 				const res = this.operationForm.edb_id 
@@ -663,6 +699,26 @@ export default {
 			this.formData.targetName = name_map[this.type] || '';
 		},
 
+		// 频度变化 修改指标名
+		handleFrequencyChange(){
+			if(!this.select_target||this.operationForm.edb_id) return;
+			let obj = this.searchOptions.find(item => item.EdbInfoId === this.select_target);
+			const name_map = {
+				51: `${obj.EdbName}/${this.formData.frequency.substr(0,1)}频`,
+				62:  `${obj.EdbName}累计值/${this.formData.frequency}`,
+			}
+			this.formData.targetName=name_map[this.type] || ''
+		},
+
+		// 时间位移-移动方式修改 修改指标名
+		refreshTarget(){
+			if(this.type==22){
+				if(!this.select_target||this.operationForm.edb_id) return;
+				let obj = this.searchOptions.find(item => item.EdbInfoId === this.select_target);
+				this.formData.targetName=`${obj.EdbName}${this.moveTypeOpions.filter(item=>item.key===this.formData.moveType)[0].label}${this.formData.moveVal}${this.formData.moveUnit}`
+			}
+		},
+
 		/* 单位默认同步基础指标
 		同比 同差 频度同步 单位无 
 		转月 平均值 频度单位同步
@@ -684,20 +740,21 @@ export default {
 				['年度','Y'],
 			])
 			const name_map = {
-				5: obj.EdbName,
+				5: `${obj.EdbName}转月值`,
 				8: `${obj.EdbName}/${this.formData.n_num}${tMap.get(obj.Frequency)}MA`,
-				14: `${obj.EdbName}/${obj.Frequency}升频`,
+				14: `${obj.EdbName}/频`,
 				6: `${obj.EdbName}同比`,
 				7: `${obj.EdbName}同差`,
 				12: `${obj.EdbName}${this.formData.n_num}${obj.Frequency.slice(0,1)}环比`,
 				13: `${obj.EdbName}${this.formData.n_num}${obj.Frequency.slice(0,1)}环差`,
 				35: `${obj.EdbName}超季节性/${this.formData.n_num}年${this.formData.calendar_type==='公历'?'':'/'+this.formData.calendar_type}`,
-				52: `${obj.EdbName}年化`,
-				51: `${obj.EdbName}/${obj.Frequency}降频`,
-				61:  obj.EdbName,
-				62:  obj.EdbName,
-				63:  obj.EdbName,
-				75: `${obj.EdbName}日均值`
+				52: `${obj.EdbName}年化值`,
+				51: `${obj.EdbName}/${obj.Frequency.substr(0,1)}频`,
+				61:  `${obj.EdbName}转季值`,
+				62:  `${obj.EdbName}累计值/${obj.Frequency}`,
+				63:  `${obj.EdbName}年初至今累计值`,
+				75: `${obj.EdbName}日均值`,
+				22:	`${obj.EdbName}${this.moveTypeOpions.filter(item=>item.key===this.formData.moveType)[0].label}${this.formData.moveVal}${this.formData.moveUnit}`
 			}
 			
 			let frequerncyMap = {
@@ -710,13 +767,14 @@ export default {
 				targetName: name_map[this.type] || '',
 				frequency: frequerncyMap[this.type] || obj.Frequency,
 				unit: [5,8,14,7,35,75].includes(this.type) ? obj.Unit : '无',
-				menu: this.type===75 ? obj.ClassifyId : '',
+				menu: obj.ClassifyId || '',
 				n_num: 1,
 				moveType: 1,
 				moveUnit: '天',
 				moveVal: '',
 				calendar_type: this.formData.calendar_type,
-				value_type: this.formData.value_type
+				value_type: this.formData.value_type,
+				new_value:''
 			}
 		},
         handleSelectBtnClick(){

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

@@ -155,6 +155,74 @@ export const computedBatchTypes = [
 	}
 ]
 
+//批量指标类型
+export const computedBatchTypesV2=[
+	{
+		name:'同比值',
+		type:6
+	},
+	{
+		name:'同差值',
+		type:7
+	},
+	{
+		name:'累计值转月/季值',
+		type:'toMonthSeason'
+	},
+	{
+		name:'N期移动均值',
+		type:8
+	},
+	{
+		name:'N期环比值',
+		type:12
+	},
+	{
+		name:'N期环差值',
+		type:13
+	},
+	{
+		name:'升频',
+		type:14
+	},
+	{
+		name:'超级季节性',
+		type:35
+	},
+	{
+		name:'年化值',
+		type:52
+	},
+	{
+		name:'降频',
+		type:51
+	},
+	{
+		name: '累计值',
+		type: 'accumulate'
+	},
+	{
+		name:'指数修匀',
+		type:72
+	},
+	{
+		name:'日均值',
+		type: 75
+	},
+	{
+		name:'与常数计算',
+		type:'withNum'
+	},
+	{
+		name:'与单指标计算',
+		type:'withEDB'
+	},
+	{
+		name:'多指标求和/平均',
+		type:'multipleEDB',//81求和 82求平均
+	},
+]
+
 //频度
 export const frequencyArr = ['日度','周度','旬度','月度','季度','年度'];
 
@@ -302,4 +370,20 @@ export const THSCommonIndexFuturesCodeArr=[
 	{value:'ths_chg_ratio_future',label:bus.$i18nt.t('EtaBasePage.incre_decre')/* "涨跌幅" */},
 	{value:'ths_swing_d_future',label:bus.$i18nt.t('EtaBasePage.fluctua_day')/* "日振幅" */},
 	{value:'ths_open_interest_future',label:bus.$i18nt.t('EtaBasePage.open_inter')/* "持仓量" */},
-]
+]
+// 生成序列数组
+export function generateSeriesArray(){
+	let result = [];
+	const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
+	for(let i=0;i<26;i++) result.push(String.fromCharCode(65+i))
+	for (let i = 0; i < 26; i++) {
+		const firstChar = alphabet[i];
+
+		for (let j = 0; j < 26; j++) {
+			const secondChar = alphabet[j];
+			result.push(firstChar + secondChar);
+		}
+	}
+
+	return result;
+}

+ 134 - 10
src/views/dataEntry_manage/databaseList.vue

@@ -65,6 +65,13 @@
 			<!-- <target-tree /> -->
 			<div class="main-left left" id="left" v-show="isMainLeftShow">
 				<div class="tree-cont">
+					<div style="padding-bottom:20px;padding-right:20px;display:flex;justify-content:space-between">
+						<span>目录</span>
+						<el-checkbox 
+							v-model="IsOnlyMe"
+							@change="onlyMeHandler"
+						>只看我的</el-checkbox>
+					</div>
 					<div class="target_tree">
 					<el-tree
 						ref="menuTree"
@@ -405,15 +412,17 @@
 		width="920px"
 		v-dialogDrag>
 			<div class="dialog-computed-header">
-				<el-radio-group v-model="computed_source" size="medium" @change="computed_type = 0">
-					<el-radio-button :label="1"><!-- 常规计算 -->{{$t('EtaBasePage.normal_calculate_tab')}}</el-radio-button>
-					<el-radio-button :label="2"><!-- 批量计算 -->{{$t('EtaBasePage.batch_calculate_tab')}}</el-radio-button>
+				<el-radio-group :value="1" size="medium">
+					<el-radio-button :label="1">{{$t('EtaBasePage.normal_calculate_tab')}}</el-radio-button>
+					<span @click="showBatchComputedPop=true">
+					<el-radio-button :label="2">{{$t('EtaBasePage.batch_calculate_tab')}}</el-radio-button>
+					</span>
 				</el-radio-group>
 			</div>
 			<ul class="computed-ul">
 				<li
-					:class="['cpmputed-li',{'act':item.type === computed_type}]" 
-					v-for="item in computedShowTypes" 
+					:class="['cpmputed-li',item.type === computed_type?'act':'']" 
+					v-for="item in computedTypes" 
 					:key="item.type" 
 					@click="changeComputedType(item.type)">
 					{{item.name}}
@@ -526,6 +535,16 @@
 			@addCallBack="addComputedCallBack"
 			@lookHistory="id => {toHistoryPage(id,$route.matched);lookEdbId=id;}"
 		/>
+
+		<!-- 批量计算指标 -->
+		<batchComputedV2 
+			:isShow="showBatchComputedPop" 
+			:type="computed_type"
+			:operationForm="operationForm"
+			@close="isOpenComputed=false;showBatchComputedPop=false" 
+			@closeSelf="handleCloseBatchPopSelf"
+			@addCallBack="addComputedCallBack"
+		/>
 	</div>
 </template>
 
@@ -554,6 +573,7 @@ import EdbLabelList from '@/components/edbLabelList.vue';
 import chartTrendRender from './databaseComponents/chartTrendRender.vue';
 import edbDetailData from './databaseComponents/edbDetailData.vue';
 import SmoothEdbDialog from './databaseComponents/smoothEdbDialog.vue';
+import batchComputedV2 from './databaseComponents/batchComputedV2.vue';
 export default {
 	name: '',
 	components: {
@@ -578,6 +598,7 @@ export default {
 		chartTrendRender,
 		edbDetailData,
 		SmoothEdbDialog,
+		batchComputedV2
 	},
 	directives: {
 		drag(el, bindings,vnode) {
@@ -615,6 +636,7 @@ export default {
 	},
 	data() {
 		return {
+			IsOnlyMe:false,//只看我的
 			showData: false,
 			search_txt: '', //搜索词
 			searchOptions:[],//搜索到的筛选列表
@@ -629,7 +651,67 @@ export default {
 			loading:null,
 			showTable:false,
 			page_no: 1,
-		
+			/*表格列 */
+			tableColumsOne: [
+				{
+					label: '指标ID',
+					key: 'EdbCode',
+					minwidthsty: '150px'
+				},
+				{
+					label: '指标名称',
+					key: 'EdbName',
+					enKey:'EdbNameEn',
+					inputTip:'点击输入英文指标名称',
+					minwidthsty: '200px'
+				},
+				{
+					label: '频度',
+					key: 'Frequency',
+					enKey:'FrequencyEn',
+					widthsty: '100px'
+				},
+				{
+					label: '单位',
+					key: 'Unit',
+					enKey:'UnitEn',
+					inputTip:'英文单位',
+					// minwidthsty: '50px'
+					widthsty: '100px'
+				},
+				{
+					label: '数据来源',
+					key: 'SourceName',
+					widthsty: '160px'
+				},
+			],
+			tableColumsTwo: [
+				{
+					label: '指标目录',
+					key: 'Menu',
+					minwidthsty: '150px',
+				},
+				{
+					label: '起始时间',
+					key: 'StartDate',
+					minwidthsty: '115px',
+				},
+				{
+					label: '更新时间',
+					key: 'ModifyTime',
+					minwidthsty: '120px',
+				},
+				{
+					label:'刷新状态',
+					key:'NoUpdate',
+					widthsty:'100px'
+				},
+				{
+					label: '添加人',
+					key: 'SysUserRealName',
+					widthsty: '160px',
+				}
+			],
 			haveMore: true,
 			selected_edbid: 0,//选中的指标id
 			dataList: [],//指标数值
@@ -708,6 +790,8 @@ export default {
 			activeName:'second',
 
 			isMainLeftShow:true,
+
+			showBatchComputedPop:false,
 		};
 	},
 	watch: {
@@ -890,7 +974,7 @@ export default {
 		/* 获取树分类数据 */
 		getTreeData(params) {
 			
-			dataBaseInterface.targetCatalog({ParentId:0}).then(res=>{
+			dataBaseInterface.targetCatalog({IsOnlyMe:this.IsOnlyMe,ParentId:0}).then(res=>{
 				if(res.Ret===200){
 					const arr=res.Data.AllNodes || []
 					this.treeData=arr.map(item=>{
@@ -1001,6 +1085,7 @@ export default {
 				PageSize:this.PageSize,
 				CurrentIndex:this.CurrentIndex,
 				ClassifyId:this.select_classifyId,
+				IsOnlyMe:this.IsOnlyMe
 			}).then(res=>{
 				if(res.Ret!==200) return
 				if(res.Data){
@@ -1368,6 +1453,11 @@ export default {
 		},
 		/* 刷新获取指标最新数据 */
 		refreshTargetHandle: _.debounce(function() {
+			//如果该指标为暂停刷新,则提示
+			if(this.EdbData.NoUpdate){
+				this.$message.warning("该指标已暂停刷新")
+				return
+			}
 			if(this.selected_edbid) {
 				this.loading = this.$loading({
 					lock: true,
@@ -1643,6 +1733,7 @@ export default {
 			this.calulateList = [];
 			this.calulateForm = {};
 			this.operationForm = {};
+			this.computed_type=0
 			this.isOpenComputed = true;
 		},
 		/* 新增计算指标回调 */
@@ -1651,6 +1742,9 @@ export default {
 			this.computed_source = 1;
 			this.showAssociateChart=false
 			this.showAssociateComputeData=false
+			this.showBatchComputedPop=false
+			this.isOpenComputed = false
+			console.log(type, params);
 			// this.getTreeData();
 			type === 'add' ? this.getTreeData(params) : this.getTreeData();
 			type === 'edit' && this.initGetData()
@@ -1746,7 +1840,7 @@ export default {
 						end_date: item.EndDate
 					}
 				})
-				const { EdbInfoId,CalculateFormula,EdbName,Unit,Frequency,EmptyType,MaxEmptyType } = res.EdbInfoDetail;
+				const { EdbInfoId,CalculateFormula,EdbName,Unit,Frequency,EmptyType,MaxEmptyType,Extra } = res.EdbInfoDetail;
 				/* 公式和表单 */
 				this.calulateForm =  {
 					edb_id: EdbInfoId,
@@ -1757,9 +1851,18 @@ export default {
 					frequency: Frequency,
 					emptyType: EmptyType,
 					maxEmptyType: MaxEmptyType,
+					Extra,
 					view
 				};
 			} else  {
+				// 多指标求和求平均
+				if([81,82].includes(type)){
+					this.operationForm={...res,view}
+					this.showBatchComputedPop=true
+					return
+				}
+
+
 				let dataInfo = res.EdbInfoDetail;
 				let old_edb = res.CalculateList;
 
@@ -1769,6 +1872,7 @@ export default {
 					frequency: dataInfo.Frequency,
 					unit: dataInfo.Unit,
 					menu: menuArrId||[],
+					Extra:dataInfo.Extra,
 					view
 				}
 
@@ -1805,11 +1909,16 @@ export default {
 						view
 					}
 				}
+				
 			}
 		},
 
 		/* 基础指标刷新 */
 		refreshBaseHandler() {
+			if(this.EdbData.NoUpdate){
+				this.$message.warning("该指标已暂停刷新")
+				return 
+			}
 			this.refreshLoading = true;
 			this.loading = this.$loading({
 					lock: true,
@@ -1948,13 +2057,21 @@ export default {
 				this.dynamicNode&&this.resetNodeStyle(this.dynamicNode)
 			})
 		},
+		//只看我的
+		onlyMeHandler(){
+			this.getTreeData()
+
+			this.CurrentIndex = 1;
+			this.$refs.listRef.scrollTop = 0;
+			this.getEdbChartList();
+		},
 		//绑定el-tree的load属性
 		async getLazyTreeData (node,resolve){
 			if(node.level===0){
 				resolve(this.treeData)
 			}else{
 				let arr=[]
-				const res=await dataBaseInterface.targetCatalog({ParentId:node.data.ClassifyId})
+				const res=await dataBaseInterface.targetCatalog({ParentId:node.data.ClassifyId,IsOnlyMe:this.IsOnlyMe})
 				if (res.Ret === 200) {
 					const temarr = res.Data.AllNodes || [];
 					arr=temarr.map(item=>{
@@ -2005,6 +2122,13 @@ export default {
 		// 添加wind wsd指标成功
 		addTargetSuccess(params){
 			this.getTreeData(params);
+		},
+
+		handleCloseBatchPopSelf(){
+			this.showBatchComputedPop=false
+			this.$nextTick(()=>{//重新打开计算指标选择类型弹窗
+				this.isOpenComputed=true
+			})
 		}
 	},
 	//离开页面时保存标签
@@ -2120,7 +2244,7 @@ export default {
 			}
 			.target_tree {
 				color: #333;
-				height: calc(100vh - 350px);
+				height: calc(100vh - 400px); 
 				overflow: auto;
 				.label-input .el-input__inner {
 					height: 25px;

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

@@ -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">
@@ -566,6 +566,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"
@@ -755,7 +783,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() // 设置配置项
@@ -872,6 +904,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 = {
@@ -1305,6 +1364,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">

+ 125 - 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) {
@@ -250,6 +338,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)
 		},
 
 		/* 奇怪柱形图的日期配置项现在不止柱形图用了 获取数据时扩展一下 */
@@ -267,9 +357,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: {
@@ -355,25 +450,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)
 
@@ -567,6 +670,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

@@ -648,13 +648,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
             },
@@ -825,13 +827,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
             },
@@ -974,6 +978,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: {
@@ -987,10 +993,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
           },
@@ -1049,10 +1055,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
       };
@@ -1116,23 +1123,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
           },
@@ -1155,21 +1165,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')

+ 5 - 3
src/views/dataEntry_manage/thirdBase/icpiConsumption.vue

@@ -157,9 +157,10 @@ export default {
         
         // 设置表格数据
         this.setDataList(res.Data);
-        this.$nextTick(() => {
-          this.initWidth();
-        });
+        this.CurrentIndex === 1 &&
+          this.$nextTick(() => {
+            this.initWidth();
+          });
       }).finally(()=>{
         this.dataloading = false;
       })
@@ -169,6 +170,7 @@ export default {
       this.select_classify = item.BaseFromIcpiClassifyId;
       this.leftSearchVal = ""
       this.pageParams.KeyWord=''
+      this.pageParams.CurrentIndex=1
       this.getDataList()
     },
 

+ 23 - 22
src/views/datasheet_manage/addSheet.vue

@@ -5,31 +5,32 @@
         <li style="margin-right:30px;">
           <el-input
             v-model="sheetForm.name"
-            placeholder="请输入表格名称"
+            :placeholder="$t('OnlineExcelPage.please_table_name_ipt')"
             clearable
             style="width:240px">
           </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="$t('OnlineExcelPage.select_table_category')"
+          />
         </li>
       </ul>
-      <div v-if="updateTime" style="color:#999999;margin-right: 30px;">最近保存时间:{{ updateTime }}</div>
+      <div v-if="updateTime" style="color:#999999;margin-right: 30px;">{{$t('OnlineExcelPage.recent_save_time_info')}}:{{ updateTime }}</div>
       <div>
-        <el-button type="primary" size="medium" @click="saveSheetHandle" v-if="hasPermission">保存</el-button>
-        <el-button type="primary" size="medium" plain @click="backHandle">返回</el-button>
+        <el-button type="primary" size="medium" @click="saveSheetHandle" v-if="hasPermission">{{$t('ETable.Btn.save_btn')}}</el-button>
+        <el-button type="primary" size="medium" plain @click="backHandle">{{$t('ETable.Btn.back_btn')}}</el-button>
       </div>
     </div>
     
@@ -128,7 +129,7 @@ export default {
 
       this.isCanEdit = res.Data.CanEdit
       if(!res.Data.CanEdit){
-        this.$message.warning(`${res.Data.Editor}正在编辑中`)
+        this.$message.warning(`${res.Data.Editor}${this.$t('OnlineExcelPage.currently_editing_msg')}`)
         setTimeout(()=>{
           this.backHandle()
         },1000)
@@ -164,8 +165,8 @@ export default {
       const { name,classify,infoId } = this.sheetForm;
       luckysheet.exitEditMode()
       let data = luckysheet.getAllSheets()[0];
-      if(!name || !classify) return this.$message.warning(name ? '请选择表格分类' : '请输入表格名称')
-      if(!data.celldata.length) return this.$message.warning('请输入表格内容');
+      if(!name || !classify) return this.$message.warning(name ? this.$t('OnlineExcelPage.select_table_category')  : this.$t('OnlineExcelPage.please_table_name_ipt') )
+      if(!data.celldata.length) return this.$message.warning(this.$t('OnlineExcelPage.input_content_msg') );
       let params={
         ExcelInfoId:infoId,
         ExcelName: name,
@@ -193,13 +194,13 @@ export default {
       luckysheet.exitEditMode()
       //结构类型乱飘 强制定义下
       let data = {...luckysheet.getAllSheets()[0],status:Number(luckysheet.getAllSheets()[0].status)}
-      if(!name || !classify) return this.$message.warning(name ? '请选择表格分类' : '请输入表格名称')
-      if(!data.celldata.length) return this.$message.warning('请输入表格内容');
+      if(!name || !classify) return this.$message.warning(name ? this.$t('OnlineExcelPage.select_table_category')  : this.$t('OnlineExcelPage.please_table_name_ipt') )
+      if(!data.celldata.length) return this.$message.warning(this.$t('OnlineExcelPage.input_content_msg') );
 
       this.loading = this.$loading({
 				target:'.addSheet-wrap',
 				lock: true,
-				text: '保存中...',
+				text: this.$t('OnlineExcelPage.saving_loading_text') ,
 				spinner: 'el-icon-loading',
 				background: 'rgba(255, 255, 255, 0.6)'
 			});

+ 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));
+  }
+}

+ 26 - 23
src/views/datasheet_manage/components/CustomTable.vue

@@ -2,7 +2,7 @@
   <div class="custom-table">
     <div v-if="config.data.length">
       <div class="formula-wrapper" v-if="!disabled">
-        <span style="flex-shrink: 0;color:#C0C4CC">公式</span>
+        <span style="flex-shrink: 0;color:#C0C4CC">{{$t('OnlineExcelPage.formula_lable')}}</span>
         <el-input
           v-show="selectCell.DataType===4"
           v-model="selectCell.Value"
@@ -38,7 +38,7 @@
               <th class="th-tg sm"></th>
 
               <td rowspan="2" v-if="index === 0">
-                日期
+                {{$t('OnlineExcelPage.date_row_table')}}
                 <i class="el-icon-sort" @click="changeSort"></i>
               </td>
               <td 
@@ -177,7 +177,7 @@
               <th class="th-tg sm"></th>
 
               <td colspan="2">
-                日期
+                {{$t('OnlineExcelPage.date_row_table')}}
                 <i class="el-icon-sort" style="transform: rotate(90deg)" @click="changeSort"></i>
               </td>
 
@@ -319,8 +319,8 @@
       <!-- 添加 -->
       <div class="add-fixed" v-if="!disabled" draggable @dragend="dragEnd" :style="isCollapse?'left:70px;':'left:200px;'">
         <div class="add-wrapper" v-show="!isSlideLeft">
-          <div @click="addDateRow"> <i class="el-icon-circle-plus-outline"></i> 添加日期</div>
-          <div @click="addTextRow"> <i class="el-icon-circle-plus-outline"></i> 添加文本</div>
+          <div @click="addDateRow"> <i class="el-icon-circle-plus-outline"></i> {{$t('OnlineExcelPage.add_date_wrapper')}}</div>
+          <div @click="addTextRow"> <i class="el-icon-circle-plus-outline"></i> {{$t('OnlineExcelPage.add_text_wrapper')}}</div>
 
           <span class="slide-icon slide-left" @click="isSlideLeft=!isSlideLeft">
             <i class="el-icon-d-arrow-left"></i>
@@ -341,7 +341,7 @@
     </div>
 
     <div class="nodata" v-else>
-      <tableNoData text="暂无数据"/>
+      <tableNoData :text="$t('Table.prompt_slogan')"/>
     </div>
 
     <!-- 右键菜单 -->
@@ -361,7 +361,7 @@
     <m-dialog
       :show.sync="isEditEdbAliasDialog"
       width="650px"
-      title="编辑指标"
+      :title="$t('OnlineExcelPage.edit_indicator_tle')"
       @close="isEditEdbAliasDialog = false"
     >
       <div style="padding-left:80px">
@@ -372,10 +372,10 @@
           label-width="80px"
           :model="editEdb"
         >
-          <el-form-item label="指标名称">
+          <el-form-item :label="$t('OnlineExcelPage.indicator_name_lbl')">
             <span>{{ editEdb.EdbName }}</span>
           </el-form-item>
-          <el-form-item label="指标别名" prop="EdbAliasName">
+          <el-form-item :label="$t('OnlineExcelPage.indicator_alias_lbl')" prop="EdbAliasName">
             <el-input v-model="editEdb.EdbAliasName" style="width:80%"/>
           </el-form-item>
         </el-form>
@@ -385,10 +385,10 @@
           type="primary"
           style="margin-right: 60px"
           @click="saveEdbAlias"
-          >保存</el-button
+          >{{$t('Dialog.confirm_save_btn')}}</el-button
         >
         <el-button type="primary" plain @click="isEditEdbAliasDialog = false"
-          >取消</el-button
+          >{{$t('Dialog.cancel_btn')}}</el-button
         >
       </div>
     </m-dialog>
@@ -472,22 +472,25 @@ export default {
     },
     isCollapse() {
       return this.$store.state.isCollapse
-    }
-  },
-  data() {
-    return {
-      isSlideLeft: false,
-      formula: '',
-      config: {
+    },
+    config(){
+      return {
         type: this.sheetType,
         order: 2,// 1降序 2升序
         EdbKeys: ["EdbName", "Unit"],
         data: [], //单元格类型 1默认格 2补充格 3自定义输入 4公式求值格 5预测值
         textRowData: [],
         contextMenuOption: [
-          { label: '删除',key: 'del' },
+          { label: this.$t('ETable.Btn.delete_btn') ,key: 'del' },
         ]
-      },
+      }
+    }
+  },
+  data() {
+    return {
+      isSlideLeft: false,
+      formula: '',
+      
 
       //选中的cell
       selectCell: {},
@@ -666,7 +669,7 @@ export default {
       //根据因数找单元格
       let isAllCell = factors.some(_ => findCellByFactor(_)=== null)
       if(isAllCell) {
-        this.$message.warning('公式有误,参数不存在')
+        this.$message.warning(this.$t('OnlineExcelPage.error_parameter_not_msg') )
         return '';
       } 
 
@@ -719,7 +722,7 @@ export default {
       if(rindex==='-1') { //删除列
         console.log('删除列',cindex)
           if(cindex === 'A') {
-            await this.$confirm('第一个指标删除后将清除表格所有内容,确认删除吗?','提示',{ type: 'warning' })
+            await this.$confirm(this.$t('OnlineExcelPage.dlt_the_all_msg') ,this.$t('Confirm.prompt') ,{ type: 'warning' })
             this.reset()
             return
           }
@@ -732,7 +735,7 @@ export default {
       }else if(cindex === '-1') { //删除行
         console.log('删除行',rindex)
 
-        if(this.dateArr.length === 1) return this.$message.warning('请至少保留一个指标日期')
+        if(this.dateArr.length === 1) return this.$message.warning(this.$t('OnlineExcelPage.please_keep_one_msg') )
 
         let index = this.rowHeader.findIndex(_ => _ === rindex)
         if(index >= this.dateArr.length) {

+ 246 - 99
src/views/datasheet_manage/components/MixedTable.vue

@@ -1,10 +1,13 @@
 <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">
-        <span style="flex-shrink: 0;color:#C0C4CC">公式</span>
+        <span style="flex-shrink: 0;color:#C0C4CC">{{$t('OnlineExcelPage.formula_lable')}}</span>
         <el-input
           v-if="selectCell&&selectCell.DataType===6"
           v-model="selectCell.Value"
@@ -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))"
             >
@@ -79,15 +83,15 @@
               >
                 <ul>
                   <li style="display:flex;margin:10px;">
-                    <label style="min-width:80px;">指标名称</label> 
+                    <label style="min-width:80px;">{{$t('OnlineExcelPage.indicator_name_lbl')}}</label> 
                     {{cellrelationEdbInfo.EdbName}}
                   </li>
                   <li style="display:flex;margin:10px;">
-                    <label style="min-width:80px;">最新日期</label> 
+                    <label style="min-width:80px;">{{$t('OnlineExcelPage.lastest_date_lab')}}</label> 
                     {{cellrelationEdbInfo.LatestDate}}
                   </li>
                   <li style="display:flex;margin:10px;">
-                    <label style="min-width:80px;">指标ID</label> 
+                    <label style="min-width:80px;">{{$t('Table.edb_id')}}</label> 
                     {{cellrelationEdbInfo.EdbCode}}
                   </li>
                 </ul>
@@ -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,18 +192,19 @@
                   <div slot="reference" style="width:100%">{{submenu.label}}</div>   
                 </el-popover>
             </div>
-          </div>
+          </div> -->
         </div>
       </div>
     </template>
 
     <div class="nodata" v-else>
-      <tableNoData text="暂无数据"/>
+      <tableNoData :text="$t('Table.prompt_slogan')"/>
     </div>
 
     <!-- 选择指标 -->
     <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)
     },
 
     /* 插入值 往左往上寻找同行同列是否有符合条件的一指标一日期 */
@@ -380,7 +433,7 @@ export default {
         this.selectCell.Value = '';
         this.selectCell.DataTime = '';
         this.selectCell.EdbInfoId = 0;
-        this.$message.warning('无法在此处插入值');
+        this.$message.warning(this.$t('OnlineExcelPage.no_here_val_msg') );
         return
       }
 
@@ -389,19 +442,8 @@ 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('当前日期暂无值') 
+      res.Data ? this.$message.success(this.$t('OnlineExcelPage.insert_success_msg') ) : this.$message.warning(this.$t('OnlineExcelPage.the_date_no_val_msg') ) 
 
       this.selectCell.DataType = 4;
       this.selectCell.ShowValue = res.Data;
@@ -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)
     },
@@ -625,6 +673,7 @@ export default {
             cell.DataTime = '';
             cell.ShowValue = '';
             cell.Value = '';
+            cell.ShowStyle = ''
           }
         })
       })
@@ -643,7 +692,7 @@ export default {
       //根据因数找单元格
       let isAllCell = factors.some(_ => findCellByFactor(_)===null||isNaN(findCellByFactor(_)))
       if(isAllCell) {
-        this.$message.warning('公式参数有误')
+        this.$message.warning(this.$t('OnlineExcelPage.xxformula_val_error_msgx') )
         return '';
       } 
 
@@ -689,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(() => {
@@ -720,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 = {
@@ -733,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
       }
@@ -745,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();
       }
 
     },
@@ -791,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)
     },
@@ -802,7 +868,7 @@ export default {
       if(rindex==='-1') { //删除列
         console.log('删除列',cindex)
 
-        if(this.columnHeader.length === 1) return this.$message.warning('请至少保留一列')
+        if(this.columnHeader.length === 1) return this.$message.warning(this.$t('OnlineExcelPage.keep_one_column_msg') )
 
         let index = this.columnHeader.findIndex(_ => _ === cindex);
 
@@ -819,7 +885,7 @@ export default {
       }else if(cindex === '-1') { //删除行
         console.log('删除行',rindex)
 
-        if(this.rowHeader.length === 1) return this.$message.warning('请至少保留一行')
+        if(this.rowHeader.length === 1) return this.$message.warning(this.$t('OnlineExcelPage.keep_one_row_msg') )
 
         let index = this.rowHeader.findIndex(_ => _ === rindex)
         
@@ -903,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;
+      }
     },
 
     /* 插入系统/指标日期 */
@@ -947,7 +1023,7 @@ export default {
 
         this.insertCalculateInfo = {
           ...menuInfo,
-          formStr: Value,
+          ...this.insertTargetCell
         }
       }else {
         this.insertCalculateInfo = {
@@ -956,34 +1032,68 @@ 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列 */
@@ -999,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,
@@ -1041,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;
       }
@@ -1053,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();
@@ -1096,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)
     }
   },
 };
@@ -1237,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 {
@@ -1251,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;
+        }
+      }
     }
   }
 }
@@ -1291,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>

+ 22 - 17
src/views/datasheet_manage/components/addDateCellDia.vue

@@ -3,7 +3,7 @@
 		:visible.sync="isOpenDialog"
 		:close-on-click-modal="false"
 		:modal-append-to-body='false'
-    title="添加日期"
+    :title="$t('OnlineExcelPage.add_date_wrapper')"
 		@close="cancelHandle"
 		custom-class="dialog"
 		center
@@ -18,28 +18,28 @@
 				:model="formData"
 				:rules="formRules">
 				
-          <el-form-item label="日期类型" prop="dateType">
+          <el-form-item :label="$t('OnlineExcelPage.date_type_label')" prop="dateType">
             <el-radio-group v-model="formData.dateType">
-              <el-radio :label="1">过去日期</el-radio>
-              <el-radio :label="2">未来日期</el-radio>
+              <el-radio :label="1">{{$t('OnlineExcelPage.past_date_label')}}</el-radio>
+              <el-radio :label="2">{{$t('OnlineExcelPage.future_date_label')}}</el-radio>
             </el-radio-group>
           </el-form-item>
-          <el-form-item label="期数" prop="value" v-if="formData.dateType===1">
+          <el-form-item :label="$t('OnlineExcelPage.number_lable')" prop="value" v-if="formData.dateType===1">
             <el-input
               type="number"
-              placeholder="请输入期数"
+              :placeholder="$t('OnlineExcelPage.please_enter_number')"
               :min="1"
               v-model="formData.value"
               @input="filterInput(formData.value)"
               style="width:80%"
             ></el-input>
           </el-form-item>
-          <el-form-item label="截止日期" prop="endDate" v-if="formData.dateType===2">
+          <el-form-item :label="$t('OnlineExcelPage.deadline_lable')" prop="endDate" v-if="formData.dateType===2">
             <el-date-picker
               v-model="formData.endDate"
               type="date"
               value-format="yyyy-MM-dd"
-              placeholder="请输入截止日期"
+              :placeholder="$t('OnlineExcelPage.please_enter_deadline')"
               :picker-options="{
                 disabledDate(time) {
                   return time.getTime() < latestDate;
@@ -51,8 +51,8 @@
 				</el-form>
 			</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>
+				<el-button type="primary" style="margin-right:20px" @click="saveHandle">{{$t('ETable.Btn.save_btn')}}</el-button>
+				<el-button type="primary" plain @click="cancelHandle">{{$t('ETable.Btn.cancel_btn')}}</el-button>
 			</div>
 		</el-dialog>
 </template>
@@ -78,16 +78,21 @@ export default {
         endDate: '',
         value: ''
       },
-      formRules: {
+
+      latestDate: ''
+    }
+  },
+  computed:{
+   formRules(){
+    return {
         endDate: [
-          { required: true, message: '截止日期不能为空', trigger: 'blur' }
+          { required: true, message: this.$t('OnlineExcelPage.deadline_cannot_be_empty') , trigger: 'blur' }
         ],
         value: [
-          { required: true, message: '期数不能为空', trigger: 'blur' }
+          { required: true, message: this.$t('OnlineExcelPage.number_cannot_be_empty') , trigger: 'blur' }
         ]
-      },
-      latestDate: ''
-    }
+      }
+   }
   },
   methods:{
     cancelHandle() {
@@ -126,7 +131,7 @@ export default {
         })
 
       if(res.Ret !== 200) return
-      this.$message.success('添加成功');
+      this.$message.success(this.$t('ETable.Msg.sdded_success_msg') );
       this.$emit('success',{ type: this.formData.dateType===1?'past':'future',data: res.Data})
       this.cancelHandle()
     }

+ 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>{{$t('ETableChildren.date_calculation_btn')}}</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="$t('ETableChildren.select_date_pld')"
+						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"
+				/>
+				{{$t('ETableChildren.add_more_dates')}}
+			</div>
+			<div class="computed-min">
+				<div class="computed-section">
+					<label class="label">{{$t('ETableChildren.formula_lable')}}</label>
+					<el-input :placeholder="$t('ETableChildren.formula_enter_pld')" v-model="formula" clearable @focus="initSelect">
+					</el-input>
+				</div>	
+        <div class="example-txt">{{$t('ETableChildren.example_a_b')}}</div>
+			</div>
+		</div>
+		<div class="dia-bot">
+			<el-button
+				type="primary"
+				style="margin-right: 20px"
+				@click="saveHandle"
+				>{{$t('Dialog.confirm_btn')}}</el-button
+			>
+			<el-button type="primary" plain @click="cancelHandle">{{$t('ETable.btn.cancel_btn')}}</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(this.$t('ETableChildren.indicators_cap_reached') )
+			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(this.$t('ETableChildren.input_formula_valid') );
+
+			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>

+ 75 - 51
src/views/datasheet_manage/components/calculateEdbDia.vue

@@ -15,8 +15,8 @@
               v-model="formData.source"
               @change="changeSource"
             >
-              <el-radio :label="1">累计值转月</el-radio>
-              <el-radio :label="2">累计值转季值</el-radio>
+              <el-radio :label="1">{{$t('Edb.CalculateBtns.to_month')}}</el-radio>
+              <el-radio :label="2">{{$t('Edb.CalculateBtns.to_quarter')}}</el-radio>
             </el-radio-group>
           </template>
 
@@ -25,8 +25,8 @@
               v-model="formData.source"
               @change="changeSource"
             >
-              <el-radio :label="13">累计值</el-radio>
-              <el-radio :label="14">年初至今累计值</el-radio>
+              <el-radio :label="13">{{$t('Edb.CalculateBtns.cumulate')}}</el-radio>
+              <el-radio :label="14">{{$t('Edb.CalculateBtns.cumulate_oneyear')}}</el-radio>
             </el-radio-group>
           </template>
 
@@ -64,7 +64,7 @@
 						:model="formData"
 						:rules="formRules"
 					>
-						<el-form-item label="移动方式" style="display: block;" v-if="info.fromEdbKey === 22" prop="moveVal">
+						<el-form-item :label="$t('OnlineExcelPage.label_move_way')" style="display: block;" v-if="info.fromEdbKey === 22" prop="moveVal">
 							<el-select
 								v-model="formData.moveType"
 								style="width: 100px"
@@ -98,28 +98,28 @@
 							>
 								<el-option
 									v-for="item in fre_options"
-									:key="item"
-									:label="item"
-									:value="item"
+									:key="item.value"
+									:label="item.label"
+									:value="item.value"
 								>
 								</el-option>
 							</el-select>
 						</el-form-item>
 
-						<el-form-item label="N等于" prop="nNum" v-if="[8,12,13,35].includes(info.fromEdbKey)">
+						<el-form-item :label="$t('OnlineExcelPage.label_n_val')" prop="nNum" v-if="[8,12,13,35].includes(info.fromEdbKey)">
 							<el-input
 								v-model="formData.nNum"
 								style="width: 200px"
-								placeholder="请输入N数值"
+								:placeholder="$t('ETableChildren.enter_n_value')"
 								type="number"
 								@change="changeParams"
 							/>
 						</el-form-item>
 
-						<el-form-item label="日历" prop="calendarType" v-if="info.fromEdbKey===35">
+						<el-form-item :label="$t('OnlineExcelPage.label_calendar')" prop="calendarType" v-if="info.fromEdbKey===35">
 							<el-select
 								v-model="formData.calendarType"
-								placeholder="请选择日历"
+								:placeholder="$t('OnlineExcelPage.select_calendar_pld')"
 								style="width: 200px"
 								@change="changeParams"
 							>
@@ -127,46 +127,46 @@
 									v-for="item in calendarOptions"
 									:key="item.key"
 									:label="item.label"
-									:value="item.label"
+									:value="item.key"
 								>
 								</el-option>
 							</el-select>
 						</el-form-item>
 
-            <el-form-item label="频度" prop="frequency" v-if="[9,13].includes(formData.source)">
+            <el-form-item :label="$t('ETableChildren.frequentness_lable')" prop="frequency" v-if="[9,13].includes(formData.source)">
 							<el-select
 								v-model="formData.frequency"
-								placeholder="请选择频度"
+								:placeholder="$t('OnlineExcelPage.please_select_frequency')"
 								style="width: 200px"
 								clearable
                 @change="changeParams"
 							>
 								<el-option
 									v-for="item in frequencyArr"
-									:key="item"
-									:label="item"
-									:value="item"
+									:key="item.value"
+									:label="item.label"
+									:value="item.value"
 								>
 								</el-option>
 							</el-select>
 						</el-form-item>
 
-						<el-form-item label="数据取值" prop="valueType" v-if="info.fromEdbKey===51">
+						<el-form-item :label="$t('OnlineExcelPage.label_val_type')" prop="valueType" v-if="info.fromEdbKey===51">
 							<el-select
 								v-model="formData.valueType"
-								placeholder="请选择数据取值类型"
+								:placeholder="$t('OnlineExcelPage.select_data_type')"
 								style="width: 200px"
                 @change="changeParams"
 							>
-								<el-option key="期末值" label="期末值" value="期末值"/>
-								<el-option key="平均值" label="平均值" value="平均值"/>
+								<el-option key="期末值" :label="$t('ETableChildren.final_value_lable')" value="期末值"/>
+								<el-option key="平均值" :label="$t('ETableChildren.average_value_lable')" value="平均值"/>
 							</el-select>
 						</el-form-item>
 
-						<el-form-item label="alpha值" prop="alphaValue" v-if="info.fromEdbKey==='alpha'">
+						<el-form-item :label="$t('ETableChildren.alpha_value_lable')" prop="alphaValue" v-if="info.fromEdbKey==='alpha'">
               <el-input 
                 v-model="formData.alphaValue" 
-                placeholder="请选择alpha值"
+                :placeholder="$t('Edb.InputHolderAll.input_alpha_val')"
                 style="width: 200px"
                 @change="changeParams"
               />
@@ -176,7 +176,7 @@
 
         <!-- 计算结果 -->
         <section class="result-section" v-if="showResult">
-          <label>计算结果:</label>
+          <label>{{$t('ETableChildren.calculate_result')}}:</label>
           <ul class="data-cont" v-if="calculateShowData.length">
               <li 
                 v-for="(item,index) in calculateShowData" 
@@ -188,13 +188,13 @@
               </li>
           </ul>
 
-          <tableNoData text="无对应的数据" size="mini" v-else/>
+          <tableNoData :text="$t('ETableChildren.no_corresponding_data')" size="mini" v-else/>
         </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" plain @click="cancelHandle">取消</el-button>
+          <el-button type="primary" @click="insertData" v-if="showResult">{{$t('OnlineExcelPage.insert_value_btn')}}</el-button>
+          <el-button type="primary" @click="calculateHandle" v-else>{{$t('ETableChildren.calculation_btn')}}</el-button>
+          <el-button type="primary" plain @click="cancelHandle">{{$t('ETable.Btn.cancel_btn')}}</el-button>
 
         </section>
 
@@ -233,7 +233,44 @@ export default {
       })
       
        return filterArr
-    }
+    },
+    frequencyArr(){
+       return  [
+        {label:this.$t('ETable.Date.day_lable'), value:'日度'},
+        {label:this.$t('ETable.Date.week_lable') , value:'周度'},
+        {label:this.$t('ETable.Date.dekad_lable') , value:'旬度'},
+        {label:this.$t('ETable.Date.month_lable') , value:'月度'},
+        {label:this.$t('ETable.Date.quarter_lable'), value:'季度'},
+        {label:this.$t('ETable.Date.year_lable'), value:'年度'},
+        ]
+    },
+    moveTypeOpions(){
+     return  [
+				{
+					label: this.$t('ETableChildren.ahead_lable') ,
+					key: 1
+				},
+				{
+					label: this.$t('ETableChildren.lagging_lable') ,
+					key: 2
+				},
+		  ]
+    },
+    fre_options(){
+      return   [
+        {label:this.$t('ETable.Date.day'), value:'天'},
+        {label:this.$t('ETable.Date.week_min'), value:'周'},
+        {label:this.$t('ETable.Date.month'), value:'月'},
+        {label:this.$t('ETable.Date.quarter_min'), value:'季'},
+        {label:this.$t('ETable.Date.year'), value:'年'},
+      ]
+    },
+    calendarOptions(){
+      return  [
+				{label: this.$t('ETable.Date.calendar_gre'),key: '公历'},
+				{label: this.$t('ETable.Date.calendar_lunar'),key: '农历'},
+			]
+    },
   },
   watch: {
     isShow(nval) {
@@ -284,7 +321,7 @@ export default {
         alphaValue: 0,
       },
       formRules,
-      frequencyArr: ['日度', '周度','旬度', '月度', '季度', '年度'],
+
 
       showResult: false,
       calculateShowData: [], //计算全部数据
@@ -296,21 +333,8 @@ export default {
       searchOptions: [],
       selectEdbInfo: null,
 
-      moveTypeOpions: [
-				{
-					label: '领先',
-					key: 1
-				},
-				{
-					label: '滞后',
-					key: 2
-				},
-			],
-      fre_options: ['天','周','月','季','年'],
-      calendarOptions: [
-				{label: '公历',key: 1},
-				{label: '农历',key: 2},
-			],
+
+
     }
   },
   mounted(){
@@ -379,7 +403,7 @@ export default {
 
       // 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.$t('OnlineExcelPage.there_data_no_msg') )
       
       this.$emit('insert',this.chooseItem)
       this.cancelHandle();
@@ -413,10 +437,10 @@ 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===8&&Frequency==='日度') return this.$message.warning('不能选择日度指标')
-      else if(this.formData.source===14&&Frequency==='年度') return this.$message.warning('不能选择年度指标')
+      if(this.formData.source===1&&Frequency!=='月度') return this.$message.warning(this.$t('ETableChildren.only_select_msg') )
+      else if(this.formData.source===2&&Frequency!=='季度') return this.$message.warning(this.$t('ETableChildren.no_quarterly_msg') )
+      else if(this.formData.source===8&&Frequency==='日度') return this.$message.warning(this.$t('ETableChildren.no_day_msg') )
+      else if(this.formData.source===14&&Frequency==='年度') return this.$message.warning(this.$t('ETableChildren.no_year_msg') )
 
 
       this.search_edb = EdbName;

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

@@ -0,0 +1,176 @@
+<template>
+  <div class="date-change-ways">
+    <div class="header date-item">
+      <label class="el-form-item__label">{{$t('ETableChildren.date_change_label')}}</label>
+                
+      <el-select v-model="dateChangeSelect" :placeholder="$t('ETable.Msg.please_select')" style="width:110px">
+        <el-option :label="$t('ETableChildren.date_displacement_label')" :value="1"/>
+        <el-option :label="$t('OnlineExcelPage.specified_frequency_tag')" :value="2"/>
+      </el-select>
+
+      <el-button type="text" style="margin: 0 10px;" @click="addDateChange">{{$t('ETable.btn.add_btn')}}</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">{{$t('ETableChildren.date_displacement_label')}}</el-tag>
+          <div>
+            <el-input
+              v-model="dateItem.Day"
+              type="number"
+              style="margin-right:10px;width:80px"
+              @change="e => {dateItem.Day=Number(e);}"
+            />{{$t('ETable.Date.day')}}
+            <el-input
+              v-model="dateItem.Month"
+              type="number"
+              style="margin-right:10px;width:80px"
+              @change="e => {dateItem.Month=Number(e);}"
+            />{{$t('ETable.Date.month')}}
+            <el-input
+              v-model="dateItem.Year"
+              type="number"
+              style="margin-right:10px;width:80px"
+              @change="e => {dateItem.Year=Number(e);}"
+            />{{$t('ETable.Date.year')}}
+          </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">{{$t('ETableChildren.specified_frequency_tag')}}</el-tag>
+          <el-select
+              style="max-width: 120px;"
+              v-model="dateItem.Frequency"
+              :placeholder="$t('OnlineExcelPage.please_select_frequency')"
+              @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="$t('ETable.Msg.please_select')"
+          >
+            <el-option
+                v-for="item in frequencyDaysOptions"
+                :key="item.name"
+                :label="item.lable"
+                :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: '周一' ,lable: this.$t('ETable.Date.monday') },
+          { name: '周二' ,lable: this.$t('ETable.Date.tuesday')},
+          { name: '周三' ,lable: this.$t('ETable.Date.wednesday')},
+          { name: '周四' ,lable: this.$t('ETable.Date.thursday')},
+          { name: '周五' ,lable: this.$t('ETable.Date.friday')},
+          { name: '周六' ,lable: this.$t('ETable.Date.saturday')},
+          { name: '周日' ,lable: this.$t('ETable.Date.sunday')},
+        ]
+      }
+      
+      let obj = this.dateChangeArr.find(_ => _.ChangeType===2);
+      if(!obj) return []
+
+      return typeMap[obj.Frequency] 
+        ? typeMap[obj.Frequency] 
+        : [{name:'第一天'},{name:'最后一天'}]
+    },
+    frequencyOptions(){
+      return  [
+        { name: this.$t('ETable.Date.this_week'), value: '本周' },
+        { name: this.$t('ETable.Date.this_ten_days'), value: '本旬' },
+        { name: this.$t('ETable.Date.this_month'), value: '本月' },
+        { name: this.$t('ETable.Date.this_season'), value: '本季' },
+        { name: this.$t('ETable.Date.this_half_year'), value: '本半年' },
+        { name: this.$t('ETable.Date.this_year'), value: '本年' },
+      ]
+    }
+  },
+  data() {
+    return {
+      dateChangeSelect: 1,
+      dateChangeArr: [],
+
+      
+    }
+  },
+  methods:{
+    /* 提加日期变换数组 */
+    addDateChange() {
+      let haveObj = this.dateChangeArr.find(_ => _.ChangeType===this.dateChangeSelect);
+      if(haveObj) return this.$message.warning(this.dateChangeSelect===1?this.$t('ETableChildren.added_date_offset_msg') :this.$t('ETableChildren.added_frequency_offset_msg') )
+      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>

+ 17 - 13
src/views/datasheet_manage/components/edbDetailSection.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="edb-detail">
-    <label>已选指标:</label>
+    <label>{{$t('OnlineExcelPage.selected_indicators_label')}}</label>
     <el-table
       :data="tableData"
       style="box-shadow: 0px 3px 6px rgba(155, 170, 219, 0.2); margin-top: 10px"
@@ -19,7 +19,7 @@
         </template>
       </el-table-column>
       <div slot="empty">
-        <tableNoData text="暂无指标" size="mini" />
+        <tableNoData :text="$t('OnlineExcelPage.no_indicators_available_table')" size="mini" />
       </div>
     </el-table>
     <ul
@@ -54,40 +54,44 @@ export default {
   },
   data() {
     return {
-      tableColums:[
+      dataList: []
+    };
+  },
+  computed:{
+    tableColums(){
+      return [
 				{
-					label: '指标ID',
+					label: this.$t('Edb.Detail.e_id') || '指标ID',
 					key: 'EdbCode',
 				},
 				{
-					label: '指标名称',
+					label: this.$t('Edb.Detail.e_name') || '指标名称',
 					key: 'EdbName',
 				},
 				{
-					label: '频度',
+					label: this.$t('Edb.Detail.e_fre') ||  '频度',
 					key: 'Frequency',
 				},
 				{
-					label: '单位',
+					label: this.$t('Edb.Detail.e_unit') ||  '单位',
 					key: 'Unit',
 				},
 				{
-					label: '起始时间',
+					label: this.$t('Edb.Detail.e_start_time') ||  '起始时间',
 					key: 'StartDate',
 					minwidthsty: '100px'
 				},
 				{
-					label: '更新时间',
+					label: this.$t('Edb.Detail.e_update_time') ||  '更新时间',
 					key: 'ModifyTime',
 					minwidthsty: '110px'
 				},
 				{
-					label: '来源',
+					label: this.$t('Table.source') || '来源',
 					key: 'SourceName',
 				},
-			],
-      dataList: []
-    };
+			]
+    }
   },
   methods: {},
 };

+ 98 - 164
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="$t('ETableChildren.impord_date_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"
+              >{{$t('ETableChildren.indicator_date_radio')}}</el-radio>
 
               <selectTarget
                 :defaultId="search_edb"
@@ -90,30 +25,48 @@
                 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">{{$t('ETableChildren.frequency_lable')}}: {{ selectEdbInfo.Frequency }}</span>
+              <span v-show="selectEdbInfo.LatestDate">{{$t('OnlineExcelPage.lastest_date_lab')}}: {{ 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">{{$t('ETableChildren.lagging_period_label')}}</label>
+              <el-input
+                v-model="formData.MoveForward"
+                type="number"
+                :min="0"
+                style="margin-right:10px;width:80px"
+                @change="e => {formData.MoveForward=Number(e)}"
+              />{{$t('ETableChildren.term_ipt')}}
             </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"
+              >{{$t('ETableChildren.system_date_rai')}}</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">{{$t('ETableChildren.formula_explanation_btn')}}</el-button>
+      </el-popover>
+
 			<div class="dia-bot">
-				<el-button type="primary" style="margin-right:20px" @click="saveInsertHandle">保存</el-button>
-				<el-button type="primary" plain @click="cancelHandle">取消</el-button>
+				<el-button type="primary" style="margin-right:20px" @click="saveInsertHandle">{{$t('Dialog.confirm_btn')}}</el-button>
+				<el-button type="primary" plain @click="cancelHandle">{{$t('ETable.btn.cancel_btn')}}</el-button>
 			</div>
 	</el-dialog>
 </template>
@@ -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,36 @@ 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:'最后一天'}]
+  computed:{
+    tips(){
+      return this.$t('ETableChildren.tips_text') 
     }
   },
   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:[],
 
-      titleMap: {
-        'insert-sys-date': '导入系统日期',
-        'insert-edb-date': '导入指标日期'
-      },
-
-      tips: {
-        'insert-sys-date': `1、直接导入:直接取系统日期,跟随系统日期更新<br>
-        2、日期计算:取系统日期进行公式计算,跟随系统日期更新 <br>
-        3、指定频率:取系统日期相关的指定日期,跟随系统日期更新`,
-        'insert-edb-date': '取指标的最新日期,跟随指标最新日期更新'
-      },
+      selectEdbInfo: {},
 
-      selectEdbInfo: {}
+      dateChangeSelect: 2,//日期方式选择 1系统日期 2指标日期
 
     }
   },
@@ -221,48 +146,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)
+          dataTimeType: this.dateChangeSelect,
+          str: JSON.stringify(valueParam)
         }
-      }else { //指标日期
-        backData = {
-          insertValue: this.selectEdbInfo.LatestDate,
-          dataTimeType: 2,
-          str:  JSON.stringify({EdbInfoId: this.selectEdbInfo.EdbInfoId})
-        }
-      }
+      // }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 +201,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 +214,10 @@ export default {
   display: flex;
   justify-content: center;
 }
+.tip-label {
+  position: absolute;
+  bottom: 20px;
+  right: 20px;
+  cursor: pointer;
+}
 </style>

+ 136 - 27
src/views/datasheet_manage/components/selectTargetValueDia.vue

@@ -2,7 +2,7 @@
 <div v-dialogDrag v-show="isShow" >
   <div class="select-target-value-dia el-dialog" >
     <div class="header el-dialog__header">
-      <span>选择指标</span>
+      <span>{{$t('OnlineExcelPage.select_criteria_btn')}}</span>
       <i class="el-icon-close" @click="cancelHandle"/>
     </div>
     <div class="main">
@@ -12,25 +12,52 @@
         @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">{{$t('ETableChildren.latest_date_indicator')}}</el-radio>
+            <div>
+              <label class="el-form-item__label">{{$t('ETableChildren.advance_the_term')}}</label>
+              <el-input
+                v-model="dateSelectForm.MoveForward"
+                type="number"
+                :min="0"
+                style="margin-right:10px;width:80px"
+                @change="e => {dateSelectForm.MoveForward=Number(e);}"
+              />{{$t('ETableChildren.term_ipt')}}
+            </div>
+          </div>
+          <div class="flex">
+            <el-radio v-model="dateSelectForm.Type" :label="2" style="margin-left:50px">{{$t('ETableChildren.table_date_rai')}}</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">
         <el-button type="primary" style="margin-right: 20px" @click="insertData"
-          >插入值</el-button
+          >{{$t('OnlineExcelPage.insert_value_btn')}}</el-button
         >
-        <el-button type="primary" plain @click="cancelHandle">取消</el-button>
+        <el-button type="primary" plain @click="cancelHandle">{{$t('ETable.Btn.cancel_btn')}}</el-button>
       </div>
     </div>
     
@@ -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(this.$t('ETableChildren.select_metric_first_msg') )
+
+      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>

+ 14 - 3
src/views/datasheet_manage/components/sheetClassifyDia.vue

@@ -5,7 +5,7 @@
 		:visible.sync="isOpenDialog"
 		:close-on-click-modal="false"
 		:modal-append-to-body='false'
-    :title="title"
+    	:title="title"
 		@close="cancelHandle"
 		custom-class="dialog"
 		center
@@ -20,6 +20,9 @@
 				:model="formData"
 				:rules="formRules">
 				
+          <el-form-item :label="$t('OnlineExcelPage.parent_directory_lable')" prop="classify_name" v-if="formData.parentClassifyId">
+            <span>{{formData.parentName}}</span>
+          </el-form-item>
           <el-form-item :label="$t('Chart.classify_name_label')" prop="classify_name">
             <el-input
             v-model="formData.classify_name"
@@ -105,9 +108,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);

+ 4 - 4
src/views/datasheet_manage/components/sheetListWrap.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="sheet-list-cont">
-    <span>共{{ total }}张表格</span>
+    <span>{{$t('OnlineExcelPage.all_table_num',{count:total})}}</span>
     <div class="sheetlist-wrapper" ref="listRef" @scroll="$emit('loadMoreHandle')">
       <el-col
         :span="6"
@@ -20,14 +20,14 @@
             @click="$emit('detailShowHandle',cell)"
           />
           <div class="item-bottom">
-            <span>创建时间: {{ cell.CreateTime.slice(0, 10) }}</span>
+            <span>{{$t('OnlineExcelPage.creation_time_tle')}}: {{ cell.CreateTime.slice(0, 10) }}</span>
             <div>
               <span
                 v-if="$parent.isSheetBtnShow('download')"
                 class="editsty"
                 style="margin-right: 10px"
                 @click="$emit('downloadExcel',cell)"
-                >下载</span
+                >{{$t('ETable.Btn.download_btn')}}</span
               >
               <!-- <span
                 v-if=" $parent.isSheetBtnShow('del')"
@@ -41,7 +41,7 @@
       </el-col>
     </div>
     <div v-if="!total" class="nodata">
-      <tableNoData text="暂无表格"/>
+      <tableNoData :text="$t('OnlineExcelPage.no_table_available_show')"/>
     </div>
   </div>
 </template>

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

@@ -0,0 +1,203 @@
+<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
+      },
+
+
+    };
+  },
+  computed:{
+    toolIcons(){
+      return [
+        {
+          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: this.$t('ETableChildren.number_increase_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: this.$t('ETableChildren.number_reduce_title') 
+        },
+        { 
+          icon: '',
+          key: 'cell-type-edit',
+          type:'select',
+          title:'' 
+        }
+      ]
+    },
+    numberTypeOptions(){
+        return  [
+        { label: this.$t('ETableChildren.number_label') , key: "number" },
+        { label:this.$t('ETableChildren.percentile_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>

+ 11 - 7
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>
@@ -191,7 +192,7 @@ export default {
         LuckyExcel.transformExcelToLucky(this.uploadSheetsList[Number(this.selectIndex)], (exportJson, luckysheetfile) =>{
                                   
           if(exportJson.sheets==null || exportJson.sheets.length==0){
-              this.$message.warning('解析文件失败')
+              this.$message.warning(this.$t('OnlineExcelPage.parsing_file_error_msg') )
               return;
           }
 
@@ -226,7 +227,7 @@ export default {
       this.loading = this.$loading({
 				target:'.addSheet-wrap',
 				lock: true,
-				text: '保存中...',
+				text: this.$t('OnlineExcelPage.saving_loading_text') ,
 				spinner: 'el-icon-loading',
 				background: 'rgba(255, 255, 255, 0.6)'
 			});
@@ -306,7 +307,7 @@ export default {
         }))
 
         this.isLoading = false;
-        this.getTargetList()
+        //this.getTargetList()
       }
     },
 
@@ -319,9 +320,9 @@ export default {
       let sheet = luckysheet.getSheet();
       let rangeArr = luckysheet.getRangeAxis();
 
-      if(rangeArr.length > 1) return this.$message.warning('同时只允许选择一块区域');
+      if(rangeArr.length > 1) return this.$message.warning(this.$t('OnlineExcelPage.select_one_region_msg') );
       //检查选取是否满足同行/同列
-      if(!this.checkRangeVaild(rangeArr[0])) return this.$message.warning('序列只允许选择同行或同列');
+      if(!this.checkRangeVaild(rangeArr[0])) return this.$message.warning(this.$t('OnlineExcelPage.only_allowed_select_msg') );
 
       let rangeCells = luckysheet.getRangeValue().flat().map(_=>_?_.m:'');
 
@@ -363,7 +364,7 @@ export default {
       this.loading = this.$loading({
 				target:'.addSheet-wrap',
 				lock: true,
-				text: '保存中...',
+				text: this.$t('OnlineExcelPage.saving_loading_text') ,
 				spinner: 'el-icon-loading',
 				background: 'rgba(255, 255, 255, 0.6)'
 			});
@@ -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')
+      }
     },
 
     /* 获取生成指标列表 */

+ 22 - 8
src/views/datasheet_manage/customAnalysis/components/bottomSection.vue

@@ -4,16 +4,16 @@
     <!-- 无同名 -->
     <div>
       <div class="page-list" v-if="sheetPages.length">
-        <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange" style="margin-right:30px">全部</el-checkbox>
+        <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange" style="margin-right:30px">{{$t('ETable.Btn.all_btn')}}</el-checkbox>
         <el-checkbox-group v-model="sheetChecked" @change="handleCheckedChange">
           <el-checkbox v-for="item in sheetPages" :label="item" :key="item">{{item}}</el-checkbox>
         </el-checkbox-group>
       </div>
 
       <div>
-        <el-select 
+        <!-- <el-select 
           v-model="select_classify"
-          placeholder="请选择表格目录"
+          :placeholder="$t('OnlineExcelPage.select_table_contents')"
           clearable
           style="width:350px;"
         >
@@ -23,9 +23,23 @@
             :label="item.ExcelClassifyName"
             :value="item.ExcelClassifyId"
           />
-        </el-select>
-        <el-button type="primary" style="margin-left:30px" @click="saveSheetHandle">保存</el-button>
-          <el-tooltip class="item" effect="dark" content="根据用户选择的sheet页上传文件" placement="top-start">
+        </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="$t('OnlineExcelPage.select_table_category')"
+        />
+        <el-button type="primary" style="margin-left:30px" @click="saveSheetHandle">{{$t('ETable.Btn.save_btn')}}</el-button>
+          <el-tooltip class="item" effect="dark" :content="$t('OnlineExcelPage.the_sheet_page_selected')" placement="top-start">
           <i class="el-icon-warning"/>
         </el-tooltip>
       </div>
@@ -93,8 +107,8 @@ export default {
   },
   methods:{
     saveSheetHandle() {
-      if(!this.sheetChecked.length) return this.$message.warning('请选择要保存的sheet页')
-      if(!this.select_classify) return this.$message.warning('请选择分类')
+      if(!this.sheetChecked.length) return this.$message.warning(this.$t('OnlineExcelPage.please_select_sheet_msg') )
+      if(!this.select_classify) return this.$message.warning(this.$t('OnlineExcelPage.please_select_category_msg') )
 
       this.$emit('save')
     },

+ 25 - 19
src/views/datasheet_manage/customAnalysis/components/createTargetForm.vue

@@ -10,14 +10,14 @@
       :rules="formRules"
     >
       <el-form-item prop="dateSeries">
-        <el-input v-model="formData.dateSeries" placeholder="请选择日期序列" @focus="selectArea='date'" @change="changeFormat('date')" @keyup.native="e => { e.keyCode===13 && initSelect()}" :class="{'select': selectArea==='date'}"></el-input>
+        <el-input v-model="formData.dateSeries" :placeholder="$t('CustomAnalysisPage.select_date_sequence')" @focus="selectArea='date'" @change="changeFormat('date')" @keyup.native="e => { e.keyCode===13 && initSelect()}" :class="{'select': selectArea==='date'}"></el-input>
       </el-form-item>
       <el-form-item prop="valueSeries">
-        <el-input v-model="formData.valueSeries" placeholder="请选择数值序列" @focus="selectArea='value'" @change="changeFormat('value')" @keyup.native="e => { e.keyCode===13 && initSelect()}" :class="{'select': selectArea==='value'}"></el-input>
+        <el-input v-model="formData.valueSeries" :placeholder="$t('CustomAnalysisPage.select_date_numerical')" @focus="selectArea='value'" @change="changeFormat('value')" @keyup.native="e => { e.keyCode===13 && initSelect()}" :class="{'select': selectArea==='value'}"></el-input>
       </el-form-item>
 
       <el-form-item prop="edbName">
-        <el-input v-model="formData.edbName" placeholder="指标名称" @focus="initSelect"></el-input>
+        <el-input v-model="formData.edbName" :placeholder="$t('OnlineExcelPage.indicator_name_lbl')" @focus="initSelect"></el-input>
       </el-form-item>
       <el-form-item prop="classify">
         <el-cascader
@@ -33,13 +33,13 @@
             checkStrictly: true
           }"
           clearable
-          placeholder="请选择所属目录"
+          :placeholder="$t('CustomAnalysisPage.select_appropriate_category')"
         />
       </el-form-item>
       <el-form-item prop="frequency">
         <el-select
           v-model="formData.frequency"
-          placeholder="请选择频率"
+          :placeholder="$t('CustomAnalysisPage.select_frequency')"
           style="width: 100%"
           @focus="initSelect"
           clearable
@@ -58,8 +58,8 @@
       </el-form-item>
       
       <el-form-item>
-        <el-button type="primary" @click="handleSaveTarget">保存</el-button>
-        <el-button type="primary" plain @click="$parent.backHandle('into-detail')">返回</el-button>
+        <el-button type="primary" @click="handleSaveTarget">{{$t('ETable.Btn.save_btn')}}</el-button>
+        <el-button type="primary" plain @click="$parent.backHandle('into-detail')">{{$t('ETable.Btn.back_btn')}}</el-button>
       </el-form-item>
     </el-form>
   </div>
@@ -81,20 +81,23 @@ export default {
 				frequency: '',
 				unit:'',
       },
-      formRules: {
-        // dateSeries: [{ required: true, message: '日期序列不能为空', trigger: 'blur' }],
-        // valueSeries: [{ required: true, message: '数值序列不能为空', trigger: 'blur' }],
-        edbName: [{ required: true, message: '指标名称不能为空', trigger: 'blur' }],
-        classify: [{ required: true, message: '目录不能为空', trigger: 'blur' }],
-        frequency: [{ required: true, message: '频率不能为空', trigger: 'blur' }],
-        unit: [{ required: true, message: '单位不能为空', trigger: 'blur' }],
-      },
+
       frequencyArr:['日度','周度','旬度','月度','季度','年度'],
       classifyOption: [],
 
       isLockUpdate: false,//防止手动改变公式设置选区出发hook事件又更新公式和值 手动设置值即可
     };
   },
+  computed:{
+    formRules(){
+      return {
+        edbName: [{ required: true, message: this.$t('CustomAnalysisPage.rules_edbName') , trigger: 'blur' }],
+        classify: [{ required: true, message: this.$t('CustomAnalysisPage.rules_classify'), trigger: 'blur' }],
+        frequency: [{ required: true, message: this.$t('CustomAnalysisPage.rules_frequency') , trigger: 'blur' }],
+        unit: [{ required: true, message: this.$t('CustomAnalysisPage.rules_unit'), trigger: 'blur' }],
+      }
+    }
+  },
   methods: {
 
     /* 选区时更新公式 */
@@ -142,7 +145,7 @@ export default {
       //检查选取是否满足同行/同列
       if(!this.$parent.checkRangeVaild(rangeArr[0])){
         type==='date'?this.formData.dateSeries = '':this.formData.valueSeries ='';
-        return this.$message.warning('序列只允许选择同行或同列');
+        return this.$message.warning(this.$t('CustomAnalysisPage.only_allowed_select_msg') );
       } 
 
       let rangeCells = luckysheet.getRangeValue().flat().map(_=>_?_.m:'');
@@ -237,9 +240,12 @@ export default {
 
     /* 保存 */
     handleSaveTarget: _.debounce(async function() {
-      if(!this.formData.dateSeries) return this.$message.warning('日期序列不能为空')
-      if(!this.formData.valueSeries) return this.$message.warning('数值序列不能为空')
-
+      if(!this.formData.dateSeries) return this.$message.warning(this.$t('CustomAnalysisPage.date_sequence_cannot_msg') )
+      if(!this.formData.valueSeries) return this.$message.warning(this.$t('CustomAnalysisPage.numerical_sequence_cannot_msg') )
+      //如果选区超过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')

+ 35 - 4
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>
@@ -11,27 +15,36 @@
         </li>
       </ul>
       <div style="padding-top: 50px;" v-else>
-        <tableNoData text="暂无指标"/>
+        <tableNoData :text="$t('Table.no_edb_msg')"/>
       </div>
     </div>
   </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>

+ 96 - 57
src/views/datasheet_manage/customAnalysis/list.vue

@@ -17,10 +17,10 @@
             :loading="isUploadLoading"
             @click="clickUpload"
             v-if="permissionBtn.checkPermissionBtn(permissionBtn.etaTablePermission.etaTable_analysis_upload)"
-          >上传文件</el-button>
+          >{{$t('CustomAnalysisPage.up_file_btn')}}</el-button>
           <input type="file" @change="fileSelected" id="file"  style="display: none;">
           
-          <el-checkbox v-model="isShowMe"  @change="() => { getTreeData();getPublicList() }">只看我的</el-checkbox>
+          <el-checkbox v-model="isShowMe"  @change="() => { getTreeData();getPublicList() }">{{$t('Chart.only_see_mine')}}</el-checkbox>
         </div>
         <div class="search-cont">
           <el-select
@@ -29,7 +29,7 @@
             :filterable="!search_txt"
             remote
             clearable
-            placeholder="表格名称"
+            :placeholder="$t('OnlineExcelPage.excel_name_ipt')"
             style="width: 100%"
             :remote-method="searchHandle"
             @focus="searchHandle('')"
@@ -58,7 +58,7 @@
             draggable
             :expand-on-click-node="false"
             check-strictly
-            empty-text="暂无分类"
+            :empty-text="$t('Common.no_classify_msg')"
             @node-expand="handleNodeExpand"
             @node-collapse="handleNodeCollapse"
             @current-change="nodeChange"
@@ -71,7 +71,7 @@
               <el-input
                 ref="editVal"
                 style="width: 90px"
-                placeholder="请输入值"
+                :placeholder="$t('OnlineExcelPage.please_value_ipt')"
                 class="label-input"
                 v-model="new_label"
                 v-if="data.isEdit&&isSheetBtnShow('classifyOpt_edit')"
@@ -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=""
@@ -120,7 +128,7 @@
               alt=""
               style="width: 16px; height: 16px; margin-right: 10px"
             />
-            <span>添加表格分类</span>
+            <span>{{$t('OnlineExcelPage.add_category_table_btn')}}</span>
           </div>
         </div>
         <span
@@ -145,7 +153,7 @@
             <el-input
               ref="sheetEditTitRef"
               style="width: 400px"
-              placeholder="请输入表格名称"
+              :placeholder="$t('OnlineExcelPage.please_table_name_ipt')"
               class="label-input"
               v-model="sheet_title"
               v-if="sheetDetailInfo.isEditTit"
@@ -158,25 +166,25 @@
               <i class="el-icon-edit"/>
             </div>
             <div class="sheet-anothor-info">
-              <span class="author">作者:{{ sheetDetailInfo.SysUserRealName }}</span>
+              <span class="author">{{$t('OnlineExcelPage.author_info')}}{{ sheetDetailInfo.SysUserRealName }}</span>
               <ul class="action-ul" v-if="sheetDetailInfo.Button">
-                <li style="color:#999999 ;">最近保存时间:{{ saveTime }}</li>
-                <el-tooltip effect="dark" content="在当前表格选择日期列和数据列生成指标" placement="top-start">
+                <li style="color:#999999 ;">{{$t('OnlineExcelPage.recent_save_time_info')}}{{ saveTime }}</li>
+                <el-tooltip effect="dark" :content="$t('CustomAnalysisPage.up_save_tooltip')" placement="top-start">
                     <li class="editsty" @click="HandleToPath" v-if="isSheetBtnShow('createedb')&&sheetDetailInfo.Button.OpEdbButton">
                       <img src="~@/assets/img/icons/choose_bluebg_new.png"/>
-                      <span>生成指标</span>
+                      <span>{{$t('CustomAnalysisPage.generate_indicators_btn')}}</span>
                     </li>
                 </el-tooltip>
 
-                <el-tooltip effect="dark" content="根据表格保存的最新内容,更新当前表格生成的所有指标" placement="top-start">
+                <el-tooltip effect="dark" :content="$t('CustomAnalysisPage.up_save_tooltip')" placement="top-start">
                     <li class="editsty" @click="refreshSheet" v-if="isSheetBtnShow('refresh')&&sheetDetailInfo.Button.RefreshEdbButton">
                       <img src="~@/assets/img/icons/refresh_blue_new.png"/>
-                      <span>{{ isEdbReFreshLoading?'指标刷新中...':'刷新指标'}}</span>
+                      <span>{{ isEdbReFreshLoading? $t('CustomAnalysisPage.refreshing_loading'):$t('CustomAnalysisPage.refresh_loading')}}</span>
                     </li>
                 </el-tooltip>
                 <li class="editsty" @click="saveHandle" v-if="isSheetBtnShow('save')&&sheetDetailInfo.Button.OpButton">
                   <img src="~@/assets/img/icons/save_blue_new.png"/>
-                  <span>保存</span>
+                  <span>{{$t('ETable.Btn.save_btn')}}</span>
                 </li>
                 <!-- <li
                   class="editsty"
@@ -192,12 +200,12 @@
                   v-if="isSheetBtnShow('otherSave')&&sheetDetailInfo.Button.CopyButton"
                 >
                   <img src="~@/assets/img/icons/save_as_blue_new.png"/>
-                  <span>另存为</span>
+                  <span>{{$t('ETable.Btn.save_as')}}</span>
                 </li>
                 <li class="editsty" @click="downloadExcel
                 (sheetDetailInfo)" v-if="isSheetBtnShow('download')&&sheetDetailInfo.Button.DownloadButton">
                   <img src="~@/assets/img/icons/download_blue.png"/>
-                  <span>下载</span>
+                  <span>{{$t('ETable.Btn.download_btn')}}</span>
                 </li>
                 <li
                   class="deletesty"
@@ -205,7 +213,7 @@
                   @click="delSheetHandle({cell:sheetDetailInfo, type:'del'})"
                 >
                   <img src="~@/assets/img/icons/delete-red.png"/>
-                  <span>删除</span>
+                  <span>{{$t('ETable.Btn.delete_btn')}}</span>
                 </li>
               </ul>
             </div>
@@ -251,7 +259,7 @@
     <m-dialog
       :show.sync="isSaveOther"
       width="650px"
-      title="另存为"
+      :title="$t('ETable.Btn.save_as')"
       @close="cancelSaveOther"
     >
       <div style="padding-left: 80px">
@@ -263,14 +271,14 @@
           :model="saveOtherForm"
           :rules="saveOtherFormRule"
         >
-          <el-form-item label="表格名称" prop="name">
+          <el-form-item :label="$t('OnlineExcelPage.excel_name_ipt')" prop="name">
             <el-input
               v-model="saveOtherForm.name"
               style="width: 80%"
-              placeholder="请输入表格名称"
+              :placeholder="$t('OnlineExcelPage.please_table_name_ipt')"
             />
           </el-form-item>
-          <el-form-item label="表格分类" prop="classify">
+          <el-form-item :label="$t('OnlineExcelPage.table_classification_label')" prop="classify">
             <el-cascader
               v-model="saveOtherForm.classify"
               :options="classifyOptions"
@@ -281,7 +289,7 @@
                 emitPath: false,
               }"
               style="width: 80%"
-              placeholder="请选择所属分类"
+              :placeholder="$t('OnlineExcelPage.select_appropriate_category_lable')"
               class="sheet-classify-cascader"
             />
           </el-form-item>
@@ -292,10 +300,10 @@
           type="primary"
           style="margin-right: 60px"
           @click="saveCopyOther"
-          >保存</el-button
+          >{{$t('Dialog.confirm_save_btn')}}</el-button
         >
         <el-button type="primary" plain @click="cancelSaveOther"
-          >取消</el-button
+          >{{$t('Dialog.cancel_btn')}}</el-button
         >
       </div>
     </m-dialog>
@@ -328,6 +336,16 @@ export default {
       }));
 
       return options;
+    },
+    saveOtherFormRule(){
+      return {
+        name: [
+          { required: true, message: this.$t('OnlineExcelPage.table_name_empty_msg') , trigger: "blur" },
+        ],
+        classify: [
+          { required: true, message: this.$t('OnlineExcelPage.cannot_be_empty_table') , trigger: "blur" },
+        ],
+      }
     }
   },
   data() {
@@ -378,14 +396,7 @@ export default {
         name: '',
 				classify: ''
       },
-      saveOtherFormRule: {
-        name: [
-          { required: true, message: "表格名称不能为空", trigger: "blur" },
-        ],
-        classify: [
-          { required: true, message: "表格分类不能为空", trigger: "blur" },
-        ],
-      },
+      
 
       isShowMe: false,
 
@@ -493,20 +504,48 @@ export default {
 
     /* 添加一级目录 */
     addLevelOneHandle() {
+      this.dialog_title =  this.$t('ETable.Btn.add_btn');
+      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 }) {
-      this.dialog_title = "编辑";
+    editNode(node, { ExcelClassifyName, ExcelClassifyId,ParentId }) {
+      let arr = []
+      arr = ParentId ? this.getNodeParentData(node.parent,arr).reverse() : [];
+      this.dialog_title = this.$t('ETable.Btn.edit_btn');
       /* 编辑目录 */
       this.classifyForm = {
         classify_name: ExcelClassifyName,
         classify_id: ExcelClassifyId,
+        parentClassifyId: ParentId,
+        parentName: arr.map(_=>_.ExcelClassifyName).join('/')
       };
       this.classifyDia = true;
     },
@@ -521,20 +560,20 @@ export default {
       const { DeleteStatus } = Data;
 
       DeleteStatus === 1
-        ? this.$confirm("该分类下关联表格不可删除", "删除失败", {
-            confirmButtonText: "知道了",
-            showCancelButton: false,
-            type: "error",
-          })
-        : DeleteStatus === 0 && !ExcelInfoId
-        ? this.$confirm("确定删除当前分类吗?", "提示", {
-            confirmButtonText: "确定",
-            cancelButtonText: "取消",
-            type: "warning",
-          }).then(() => {
-            this.delApi(ExcelClassifyId, ExcelInfoId);
-          })
-        : null;
+      ? this.$confirm(this.$t('OnlineExcelPage.the_tables_no_delete_msg') ,this.$t('MsgPrompt.delete_fail_msg') , {
+          confirmButtonText: this.$t('MsgPrompt.known') ,
+          showCancelButton: false,
+          type: "error",
+        })
+      : DeleteStatus === 0 && !ExcelInfoId
+      ? this.$confirm(this.$t('Chart.OptMsg.classify_del_confirm') , this.$('Confirm.prompt') , {
+          confirmButtonText:  this.$t('Dialog.confirm_btn'),
+          cancelButtonText: this.$t('Dialog.cancel_btn'),
+          type: "warning",
+        }).then(() => {
+          this.delApi(ExcelClassifyId, ExcelInfoId);
+        })
+      : null;
     },
 
     /* 删除方法 */
@@ -623,7 +662,7 @@ export default {
       this.loading = this.$loading({
         target: ".dataSheet-container",
         lock: true,
-        text: "保存中...",
+        text: this.$t('MsgPrompt.saveing_msg') + "...",
         spinner: "el-icon-loading",
         background: "rgba(255, 255, 255, 0.6)",
       });
@@ -646,7 +685,7 @@ export default {
       this.loading.close();
       if (res.Ret !== 200) return;
       this.saveTime = this.$moment().format('YYYY-MM-DD HH:mm:ss')
-      this.$message.success("保存成功");
+      this.$message.success(this.$t('MsgPrompt.saved_msg'));
       this.getTreeData();
     }, 300),
 
@@ -748,9 +787,9 @@ export default {
     /* 删除表格 */
     delSheetHandle({cell, type = ""}) {
       const { ExcelClassifyId, ExcelInfoId  } = cell;
-      this.$confirm("删除后该表格将不能再引用,确认删除吗?", "提示", {
-        confirmButtonText: "确定",
-        cancelButtonText: "取消",
+      this.$confirm(this.$t('ETable.Msg.is_del_table_msg') , this.$t('Confirm.prompt') , {
+        confirmButtonText:  this.$t('Dialog.confirm_btn'),
+        cancelButtonText: this.$t('Dialog.cancel_btn'),
         type: "warning",
       })
         .then(() => {
@@ -787,7 +826,7 @@ export default {
 
       if (res.Ret !== 200) return;
 
-      this.$message.success("保存成功");
+      this.$message.success(this.$t('MsgPrompt.saved_msg'));
       this.cancelSaveOther();
       this.getTreeData();
     },
@@ -820,12 +859,12 @@ export default {
     async fileSelected(){ 
       let file = document.getElementById('file').files[0];
       if(file){
-        if(!file.name.includes('.xlsx')) return this.$message.warning("上传失败,格式不符合xlsx");
-        if(file.size > 5.1*1024*1024) return this.$message.warning("上传文件最大不能超过5M");
+        if(!file.name.includes('.xlsx')) return this.$message.warning(this.$t('CustomAnalysisPage.no_file_type_msg') );
+        if(file.size > 5.1*1024*1024) return this.$message.warning(this.$t('CustomAnalysisPage.up_file_five_msg') );
 
 
         const res = await sheetInterface.sheetAnalysisInterface.checkSheetRepeat({ExcelName: file.name})
-        if(res.Data.IsFind) return this.$message.warning('已有同名文件,请上传新文件')
+        if(res.Data.IsFind) return this.$message.warning(this.$t('CustomAnalysisPage.up_new_file_msg') )
 
         this.$store.commit('sheet/SET_UPLOADFIlES',[file])
         this.$router.push({ path: '/addAnalysisSheet' });

+ 42 - 21
src/views/datasheet_manage/customSheetEdit.vue

@@ -9,10 +9,10 @@
         />
         <div>
           <div v-if="saveTime" style="color:#999999;margin-right:30px ;">
-            最近保存时间:{{ saveTime }}
+            {{$t('OnlineExcelPage.recent_save_time_info')}}{{ saveTime }}
           </div>
-          <el-button type="primary" size="medium" @click="saveSheetHandle" v-if="hasPermission">保存</el-button>
-          <el-button type="primary" size="medium" plain @click="backHandle">返回</el-button>
+          <el-button type="primary" size="medium" @click="saveSheetHandle" v-if="hasPermission">{{$t('ETable.Btn.save_btn')}}</el-button>
+          <el-button type="primary" size="medium" plain @click="backHandle">{{$t('ETable.Btn.back_btn')}}</el-button>
         </div>
       </div>
       <div class="wrap-top-bottom">
@@ -20,15 +20,15 @@
           <li>
             <el-input
               v-model="sheetForm.name"
-              placeholder="请输入表格名称"
+              :placeholder="$t('OnlineExcelPage.please_table_name_ipt')"
               style="width:240px"
               clearable>
             </el-input>
           </li>
           <li>
-            <el-select 
+            <!-- <el-select 
               v-model="sheetForm.classify" 
-              placeholder="请选择表格分类"
+              :placeholder="$t('OnlineExcelPage.select_table_category')"
               style="width:240px;"
               clearable
             >
@@ -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="$t('OnlineExcelPage.select_table_category')"
+            />
           </li>
           <li>
             <el-select 
@@ -54,7 +70,7 @@
               </el-select>
           </li>
           <li>
-            表格说明
+            {{$t('OnlineExcelPage.table_explaination_text')}}
             <el-tooltip
               effect="dark"
             >
@@ -110,6 +126,15 @@ export default {
       return this.sheetButton?
             this.permissionBtn.isShowBtn('etaTablePermission','etaTable_customize_data_save')&&this.sheetButton.OpButton:
             this.permissionBtn.isShowBtn('etaTablePermission','etaTable_customize_data_save')
+    },
+    rules(){
+      return this.$t('OnlineExcelPage.TableInstructionsText') 
+    },
+    sheetTypeOption(){
+      return [
+        { key: 1,label: this.$t('OnlineExcelPage.data_row_label')},
+        { key: 2,label: this.$t('OnlineExcelPage.data_column_label')},
+      ]
     }
   },
   // beforeRouteLeave(to,from,next){
@@ -122,15 +147,11 @@ export default {
     return {
       sheetId: this.$route.query.id || '',
       classifyArr: [],
-      rules: `表格说明:<br>
-        从ETA指标库和ETA预测指标库向表格添加指标,以第一个添加指标的日期序列为准,默认取最新12个值的日期,其他指标匹配日期,若某日期无值,则通过线性插值法【(Y-Y1)/(X-X1)=(Y2-Y1)/(X2-X1)】计算填入,区分颜色表示,日期默认降序,可切换排序,指标更新时,日期和数据值自动更新;`,
+
       sheetForm: {
         sheetType: 1
       },
-      sheetTypeOption: [
-        { key: 1,label: '指标列+日期行' },
-        { key: 2,label: '指标行+日期列' },
-      ],
+
       saveTime:"",
       sheetInit:false,
       isCanEdit:false,
@@ -157,7 +178,7 @@ export default {
       if(res.Ret !== 200)  return
       this.isCanEdit = res.Data.CanEdit
       if(!res.Data.CanEdit){
-        this.$message.warning(`${res.Data.Editor}正在编辑中`)
+        this.$message.warning(`${res.Data.Editor}${this.$t('OnlineExcelPage.currently_editing_msg') }`)
         setTimeout(()=>{
           this.backHandle()
         },1000)
@@ -183,7 +204,7 @@ export default {
       if(!e) return
 
       const { EdbName,EdbInfoId,Unit,Frequency } = e;
-      if(this.$refs.customTableRef.config.data.find(_ => _.EdbInfoId===EdbInfoId)) return this.$message.warning('指标已存在')
+      if(this.$refs.customTableRef.config.data.find(_ => _.EdbInfoId===EdbInfoId)) return this.$message.warning(this.$t('OnlineExcelPage.already_exists_msg') )
       
       const {Data} = this.$refs.customTableRef.config.data.length 
       ? await sheetInterface.getEdbInsertDataOther({
@@ -222,8 +243,8 @@ export default {
       // console.log("触发自动",this.cancelAutoSave);
       if(!this.sheetId || this.cancelAutoSave) return 
       const { name,classify,sheetType } = this.sheetForm;
-      if(!name || !classify) return this.$message.warning(name ? '请选择表格分类' : '请输入表格名称')
-      if(!document.getElementsByClassName('table')[0]) return this.$message.warning('请添加表格')
+      if(!name || !classify) return this.$message.warning(name ? this.$t('OnlineExcelPage.select_table_category')  : this.$t('OnlineExcelPage.please_table_name_ipt') )
+      if(!document.getElementsByClassName('table')[0]) return this.$message.warning(this.$t('OnlineExcelPage.please_add_table_msg') )
       let params = {
         ExcelName: name,
         ExcelType: sheetType,
@@ -248,9 +269,9 @@ export default {
     /* 保存表格 */
     saveSheetHandle: _.debounce(async function() {
       const { name,classify,sheetType } = this.sheetForm;
-      if(!name || !classify) return this.$message.warning(name ? '请选择表格分类' : '请输入表格名称')
+      if(!name || !classify) return this.$message.warning(name ? this.$t('OnlineExcelPage.select_table_category')  : this.$t('OnlineExcelPage.please_table_name_ipt') )
 
-      if(!document.getElementsByClassName('table')[0]) return this.$message.warning('请添加表格')
+      if(!document.getElementsByClassName('table')[0]) return this.$message.warning(this.$t('OnlineExcelPage.please_add_table_msg') )
 
       let canvas = await html2canvas(document.getElementsByClassName('table')[0],{
         scale:2,
@@ -290,7 +311,7 @@ export default {
         return 
       }
       this.sheetId = this.sheetId || res.Data.ExcelInfoId;
-      this.$message.success('保存成功')
+      this.$message.success(this.$t('MsgPrompt.saved_msg') )
       this.saveTime =  this.$moment().format('YYYY-MM-DD HH:mm:ss')
       
       isAdd && this.$router.replace({path:'/addCustomSheet',query:{id:this.sheetId}})

+ 39 - 33
src/views/datasheet_manage/mixedSheetEdit.vue

@@ -5,28 +5,29 @@
         <li>
           <el-input
             v-model="sheetForm.name"
-            placeholder="请输入表格名称"
-            style="width:240px"
+            :placeholder="$t('OnlineExcelPage.please_table_name_ipt')"
+            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="$t('OnlineExcelPage.select_table_category')"
+          />
         </li>
         <li>
-          表格说明
+          {{$t('OnlineExcelPage.table_explaination_text')}}
           <el-tooltip
             effect="dark"
           >
@@ -40,9 +41,10 @@
         </li>
       </ul>
       <div>
-        <span v-if="updateTime" style="color:#999999 ;">最近保存时间:{{updateTime}}</span>
-        <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>
+        <span v-if="updateTime" style="color:#999999 ;">{{$t('OnlineExcelPage.recent_save_time_info')}}{{updateTime}}</span>
+        <el-button type="primary" size="medium" @click="()=>{ sheetInit=false;getDetail('refresh')}" style="margin-left:10px" icon="el-icon-refresh-right">{{$t('ETable.Btn.renew_btn')}}</el-button>
+        <el-button type="primary" size="medium" @click="saveSheetHandle" style="margin-left:10px" v-if="hasPermission">{{$t('ETable.Btn.save_btn')}}</el-button>
+        <el-button type="primary" size="medium" plain @click="backHandle">{{$t('ETable.Btn.back_btn')}}</el-button>
       </div>
     </div>
     
@@ -84,6 +86,15 @@ export default {
       return this.sheetButton?
               this.permissionBtn.isShowBtn('etaTablePermission','etaTable_customize_mix_save')&&this.sheetButton.OpButton:
               this.permissionBtn.isShowBtn('etaTablePermission','etaTable_customize_mix_save')
+    },
+    rules(){
+      return this.$t('OnlineExcelPage.TableInstructionsText') ||''
+    },
+    sheetTypeOption(){
+      return [
+        { key: 1,label: this.$t('OnlineExcelPage.data_row_label')},
+        { key: 2,label: this.$t('OnlineExcelPage.data_column_label')},
+      ]
     }
   },
   // beforeRouteLeave(to,from,next){
@@ -96,19 +107,12 @@ export default {
     return {
       sheetId: this.$route.query.id || '',
       classifyArr: [],
-      rules: `表格说明:<br>
-        1、手动输入:单击每个单元格可直接输入文本、数字、日期(格式示例:2023-05-23),输入内容可匹配指标名称,ETA指标库和ETA预测指标库指标均可搜索,在下拉框中选择指标,则该单元格为已选指标行/列。<br>
-        2、插入指标值:右键单元格,点击“插入指标值”,则查询该单元格行、列最近的日期和指标名称,将查找到的指标对应日期的值填入该单元格,指标值总是在右下角。<br>
-        3、更新与计算规则:表格中指标值的日期不自动更新,数值不支持单元格计算`,
       sheetForm: {
         sheetType: 1
       },
       sheetButton:'',
       sheetInit:false,
-      sheetTypeOption: [
-        { key: 1,label: '指标列+日期行' },
-        { key: 2,label: '指标行+日期列' },
-      ],
+     
 
       updateTime: '',
       isCanEdit:false,
@@ -124,7 +128,7 @@ export default {
     },
 
     /* 获取表格详情 */
-    async getDetail() {
+    async getDetail(type='init') {
       if(!this.sheetId) return
 
       const res = await sheetInterface.sheetDetail({
@@ -134,7 +138,7 @@ export default {
       if(res.Ret !== 200)  return
       this.isCanEdit = res.Data.CanEdit
       if(!res.Data.CanEdit){
-        this.$message.warning(`${res.Data.Editor}正在编辑中`)
+        this.$message.warning(`${res.Data.Editor}${this.$t('OnlineExcelPage.currently_editing_msg') }`)
         setTimeout(()=>{
           this.backHandle()
         },2000)
@@ -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(this.$t('OnlineExcelPage.table_data_update_msg') )
     },
 
     /* 获取分类 */
@@ -167,9 +173,9 @@ export default {
     autoSaveFun:_.debounce(async function(){
       if(!this.sheetId || this.cancelAutoSave) return 
       const { name,classify,sheetType } = this.sheetForm;
-      if(!name || !classify) return this.$message.warning(name ? '请选择表格分类' : '请输入表格名称')
+      if(!name || !classify) return this.$message.warning(name ? this.$t('OnlineExcelPage.select_table_category')  : this.$t('OnlineExcelPage.please_table_name_ipt') )
       let checkAllEmpty = this.$refs.mixedTableRef.config.data.flat(1).some(_ => _.ShowValue);
-      if(!checkAllEmpty) return this.$message.warning('请输入表格内容')
+      if(!checkAllEmpty) return this.$message.warning(this.$t('OnlineExcelPage.input_content_msg') )
       let params = {
         ExcelName: name,
         ExcelType: 1,
@@ -195,10 +201,10 @@ export default {
     saveSheetHandle: _.debounce(async function() {
 
       const { name,classify,sheetType } = this.sheetForm;
-      if(!name || !classify) return this.$message.warning(name ? '请选择表格分类' : '请输入表格名称')
+      if(!name || !classify) return this.$message.warning(name ? this.$t('OnlineExcelPage.select_table_category')  : this.$t('OnlineExcelPage.please_table_name_ipt') )
 
       let checkAllEmpty = this.$refs.mixedTableRef.config.data.flat(1).some(_ => _.ShowValue);
-      if(!checkAllEmpty) return this.$message.warning('请输入表格内容')
+      if(!checkAllEmpty) return this.$message.warning(this.$t('OnlineExcelPage.input_content_msg') )
 
       let canvas = await html2canvas(document.getElementsByClassName('table')[0],{
         scale:2,
@@ -237,7 +243,7 @@ export default {
       this.updateTime = this.$moment().format('YYYY-MM-DD HH:mm:ss')
       
       this.sheetId = this.sheetId || res.Data.ExcelInfoId;
-      this.$message.success('保存成功')
+      this.$message.success(this.$t('MsgPrompt.saved_msg') )
       isAdd && this.$router.replace({path:'/addMixedSheet',query:{id:this.sheetId}})
     },300),
 

+ 76 - 22
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),
 
@@ -107,17 +107,18 @@ export default {
 		/* input失去焦点恢复node 修改最新的值*/
 		changeValue(data,type='') {
       if(type === 'edit-tit') {
-        if(!this.sheet_title) return this.$message.warning('表格名称不能为空');
+        if(!this.sheet_title) return this.$message.warning(this.$t('OnlineExcelPage.table_name_empty_msg') );
         data.isEditTit = false;
         data.ExcelName = this.sheet_title;
         console.log(data,'data');
       }else {
-        if(!this.new_label) return this.$message.warning('名称不能为空');
+        if(!this.new_label) return this.$message.warning(this.$t('OnlineExcelPage.name_empty_msg') );
         this.$set(data,'isEdit',false)
   
         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.$t('ETable.Msg.move_success_msg'));
+          this.getTreeData();
+        });
     },
 
     // 移动的为一级目录
@@ -171,7 +228,7 @@ export default {
         })
         .then((res) => {
           if (res.Ret !== 200) return;
-          this.$message.success("移动成功!");
+          this.$message.success(this.$t('ETable.Msg.move_success_msg'));
           this.getTreeData();
         });
     },
@@ -216,7 +273,7 @@ export default {
         })
         .then((res) => {
           if (res.Ret !== 200) return;
-          this.$message.success("移动成功!");
+          this.$message.success(this.$t('ETable.Msg.move_success_msg'));
           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;
     },

+ 109 - 56
src/views/datasheet_manage/sheetList.vue

@@ -11,9 +11,17 @@
       <div class="main-left left" id="left" v-show="!isSlideLeft">
         <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 >
+          >{{$t('OnlineExcelPage.add_excel_btn')}}</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">{{$t('OnlineExcelPage.add_timeline_table_btn')}}</el-button >
+
+          <el-button v-if="permissionBtn.checkPermissionBtn(permissionBtn.etaTablePermission.etaTable_customize_mix_sheetAdd)&&sourceMap[$route.path]===3" type="primary" @click="goAddSheetHandle">{{$t('OnlineExcelPage.add_mixed_table_btn')}}</el-button >
+
+          <el-checkbox 
+            v-model="isShowMe"
+            style="margin-left:20px"
+            @change="() => { getTreeData();getPublicList() }"
+          >{{$t('Chart.only_see_mine')}}</el-checkbox>
 
         </div>
         <div class="search-cont">
@@ -23,7 +31,7 @@
             :filterable="!search_txt"
             remote
             clearable
-            placeholder="表格名称"
+            :placeholder="$t('OnlineExcelPage.excel_name_ipt')"
             style="width: 100%"
             :remote-method="searchHandle"
             @focus="searchHandle('')"
@@ -52,7 +60,7 @@
             draggable
             :expand-on-click-node="false"
             check-strictly
-            empty-text="暂无分类"
+            :empty-text="$t('Common.no_classify_msg')"
             @node-expand="handleNodeExpand"
             @node-collapse="handleNodeCollapse"
             @current-change="nodeChange"
@@ -65,7 +73,7 @@
               <el-input
                 ref="editVal"
                 style="width: 90px"
-                placeholder="请输入值"
+                :placeholder="$t('OnlineExcelPage.please_value_ipt')"
                 class="label-input"
                 v-model="new_label"
                 v-if="data.isEdit&&isSheetBtnShow('classifyOpt_edit')"
@@ -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=""
@@ -114,7 +130,7 @@
               alt=""
               style="width: 16px; height: 16px; margin-right: 10px"
             />
-            <span>添加表格分类</span>
+            <span>{{$t('OnlineExcelPage.add_category_table_btn')}}</span>
           </div>
         </div>
         <span
@@ -139,7 +155,7 @@
             <el-input
               ref="sheetEditTitRef"
               style="width: 400px"
-              placeholder="请输入表格名称"
+              :placeholder="$t('OnlineExcelPage.please_table_name_ipt')"
               class="label-input"
               v-model="sheet_title"
               v-if="sheetDetailInfo.isEditTit"
@@ -157,16 +173,16 @@
               {{ sheetDetailInfo.ExcelName }}
             </div> -->
             <div class="sheet-anothor-info">
-              <span class="author">作者:{{ sheetDetailInfo.SysUserRealName }}</span>
+              <span class="author">{{$t('OnlineExcelPage.author_info')}}{{ sheetDetailInfo.SysUserRealName }}</span>
               <ul class="action-ul">
-                <li style="color:#999999 ;">最近保存时间:{{ saveTime }}</li>
+                <li style="color:#999999 ;">{{$t('OnlineExcelPage.recent_save_time_info')}}{{ saveTime }}</li>
                 <li
                   class="editsty"
                   @click="goEditHandle"
                   v-if="(sheetDetailInfo.Button && sheetDetailInfo.Button.OpButton&&isSheetBtnShow('edit') && (!onlineExcelEditing))"
                 >
                   <img src="~@/assets/img/icons/edit_blue_new.png" v-if="!editButtonText"/>
-                  <span>{{ editButtonText?editButtonText:'编辑' }}</span> 
+                  <span>{{ editButtonText?editButtonText:$t('ETable.Btn.edit_btn') }}</span> 
                 </li>
                 <li
                   class="editsty"
@@ -174,7 +190,7 @@
                   v-if="(sheetDetailInfo.Button && sheetDetailInfo.Button.OpButton&&isSheetBtnShow('save') && onlineExcelEditing)"
                 >
                   <img src="~@/assets/img/icons/save_blue_new.png"/>
-                  <span>保存</span> 
+                  <span>{{$t('ETable.Btn.save_btn')}}</span> 
                 </li>
                 <template v-if="[2, 3].includes(sheetDetailInfo.Source)">
                   <li
@@ -183,7 +199,7 @@
                     v-if="sheetDetailInfo.Button.RefreshButton&&isSheetBtnShow('refresh')"
                   >
                   <img src="~@/assets/img/icons/refresh_blue_new.png"/>
-                    <span>刷新</span>
+                    <span>{{$t('ETable.Btn.refresh_btn')}}</span>
                   </li>
                   <li
                     class="editsty"
@@ -191,13 +207,13 @@
                     v-if="sheetDetailInfo.Button.CopyButton&&isSheetBtnShow('otherSave')"
                   >
                     <img src="~@/assets/img/icons/save_as_blue_new.png"/>
-                    <span>另存为</span>
+                    <span>{{$t('ETable.Btn.save_as')}}</span>
                   </li>
                 </template>
                 <li v-if="isSheetBtnShow('download')"
                   class="editsty" @click="downloadExcel(sheetDetailInfo)">
                   <img src="~@/assets/img/icons/download_blue.png"/>
-                  <span>下载</span>
+                  <span>{{$t('ETable.Btn.download_btn')}}</span>
                 </li>
                 <li
                   class="deletesty"
@@ -207,7 +223,7 @@
                   @click="delSheetHandle({cell:sheetDetailInfo, type:'del'})"
                 >
                   <img src="~@/assets/img/icons/delete-red.png"/>
-                  <span>删除</span>
+                  <span>{{$t('ETable.Btn.delete_btn')}}</span>
                 </li>
               </ul>
             </div>
@@ -278,7 +294,7 @@
     <m-dialog
       :show.sync="isSaveOther"
       width="650px"
-      title="另存为"
+      :title="$t('ETable.Btn.save_as')"
       @close="cancelSaveOther"
     >
       <div style="padding-left: 80px">
@@ -290,14 +306,14 @@
           :model="saveOtherForm"
           :rules="saveOtherFormRule"
         >
-          <el-form-item label="表格名称" prop="name">
+          <el-form-item :label="$t('OnlineExcelPage.excel_name_ipt')" prop="name">
             <el-input
               v-model="saveOtherForm.name"
               style="width: 80%"
-              placeholder="请输入表格名称"
+              :placeholder="$t('OnlineExcelPage.please_table_name_ipt')"
             />
           </el-form-item>
-          <el-form-item label="表格分类" prop="classify">
+          <el-form-item :label="$t('OnlineExcelPage.table_classification_label')" prop="classify">
             <el-cascader
               v-model="saveOtherForm.classify"
               :options="classifyOptions"
@@ -308,7 +324,7 @@
                 emitPath: false,
               }"
               style="width: 80%"
-              placeholder="请选择所属分类"
+              :placeholder="$t('OnlineExcelPage.select_appropriate_category_lable')"
               class="sheet-classify-cascader"
             />
           </el-form-item>
@@ -319,10 +335,10 @@
           type="primary"
           style="margin-right: 60px"
           @click="saveCopyOther"
-          >保存</el-button
+          >{{$t('Dialog.confirm_save_btn')}}</el-button
         >
         <el-button type="primary" plain @click="cancelSaveOther"
-          >取消</el-button
+          >{{$t('Dialog.cancel_btn')}}</el-button
         >
       </div>
     </m-dialog>
@@ -362,6 +378,16 @@ export default {
         ExcelClassifyName: _.ExcelClassifyName,
       }));
       return options;
+    },
+    saveOtherFormRule(){
+      return {
+        name: [
+          { required: true, message: this.$t('OnlineExcelPage.table_name_empty_msg') , trigger: "blur" },
+        ],
+        classify: [
+          { required: true, message: this.$t('OnlineExcelPage.cannot_be_empty_table') , trigger: "blur" },
+        ],
+      }
     }
   },
   data() {
@@ -404,14 +430,7 @@ export default {
         name: '',
 				classify: ''
       },
-      saveOtherFormRule: {
-        name: [
-          { required: true, message: "表格名称不能为空", trigger: "blur" },
-        ],
-        classify: [
-          { required: true, message: "表格分类不能为空", trigger: "blur" },
-        ],
-      },
+
       sourceMap: {
         '/sheetList': 1,
         '/sheetTimeList': 2,
@@ -425,6 +444,8 @@ export default {
       },
       autoSaveType:'',//自动保存类型,有的自动保存后需要其他操作
       cancelAutoSave:false, //自动保存时延迟的
+
+      isShowMe: false//只看我的
     };
   },
   watch: {
@@ -483,7 +504,7 @@ export default {
   methods: {
     /* 添加表格 */
     goAddSheetHandle() {
-      if (!this.treeData.length) return this.$message.warning("请先添加表格分类");
+      if (!this.treeData.length) return this.$message.warning(this.$t('OnlineExcelPage.please_table_classification_msg') );
       let type = this.sourceMap[this.$route.path];
 
       let path = {
@@ -502,7 +523,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;
 
@@ -549,20 +573,48 @@ export default {
 
     /* 添加一级目录 */
     addLevelOneHandle() {
-      this.dialog_title = "添加";
+      this.dialog_title = this.$t('ETable.Btn.add_btn') ;
+      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.$t('ETable.Btn.add_btn') ;
+      /* 编辑目录 */
       this.classifyForm = {
         classify_name: "",
+        parentClassifyId: data.ExcelClassifyId,
+        parentName: arr.map(_=>_.ExcelClassifyName).join('/')
       };
       this.classifyDia = true;
     },
 
     /* 编辑节点 */
-    editNode(node, { ExcelClassifyName, ExcelClassifyId }) {
-      this.dialog_title = "编辑";
+    editNode(node, { ExcelClassifyName, ExcelClassifyId,ParentId }) {
+      let arr = []
+      arr = ParentId ? this.getNodeParentData(node.parent,arr).reverse() : [];
+      this.dialog_title = this.$t('ETable.Btn.edit_btn');
       /* 编辑目录 */
       this.classifyForm = {
         classify_name: ExcelClassifyName,
         classify_id: ExcelClassifyId,
+        parentClassifyId: ParentId,
+        parentName: arr.map(_=>_.ExcelClassifyName).join('/')
       };
       this.classifyDia = true;
     },
@@ -577,15 +629,15 @@ export default {
       const { DeleteStatus } = Data;
 
       DeleteStatus === 1
-        ? this.$confirm("该分类下关联表格不可删除", "删除失败", {
-            confirmButtonText: "知道了",
+        ? this.$confirm(this.$t('OnlineExcelPage.the_tables_no_delete_msg') , this.$t('MsgPrompt.delete_fail_msg') , {
+            confirmButtonText: this.$t('MsgPrompt.known') ,
             showCancelButton: false,
             type: "error",
           })
         : DeleteStatus === 0 && !ExcelInfoId
-        ? this.$confirm("确定删除当前分类吗?", "提示", {
-            confirmButtonText: "确定",
-            cancelButtonText: "取消",
+        ? this.$confirm(this.$t('Chart.OptMsg.classify_del_confirm') , this.$t('Confirm.prompt') , {
+            confirmButtonText:  this.$t('Dialog.confirm_btn'),
+            cancelButtonText: this.$t('Dialog.cancel_btn'),
             type: "warning",
           }).then(() => {
             this.delApi(ExcelClassifyId, ExcelInfoId);
@@ -691,12 +743,12 @@ export default {
       luckysheet.exitEditMode();
       //结构类型乱飘 强制定义下
       let data = {...luckysheet.getAllSheets()[0],status:Number(luckysheet.getAllSheets()[0].status)}
-      if (!data.celldata.length) return this.$message.warning("请输入表格内容");
+      if (!data.celldata.length) return this.$message.warning(this.$t('OnlineExcelPage.input_content_msg') );
 
       this.loading = this.$loading({
         target: ".dataSheet-container",
         lock: true,
-        text: "保存中...",
+        text: this.$t('MsgPrompt.saveing_msg') + "...",
         spinner: "el-icon-loading",
         background: "rgba(255, 255, 255, 0.6)",
       });
@@ -723,10 +775,10 @@ export default {
         this.$message.warning(res.Data.Msg)
         this.refreshOnlineExcel()
         this.onlineExcelEditing=false
-        this.editButtonText = `${res.Data.Editor}编辑中`
+        this.editButtonText = `${res.Data.Editor}${this.$t('OnlineExcelPage.editing_msg')}`
         return 
       }
-      this.$message.success("保存成功");
+      this.$message.success(this.$t('MsgPrompt.saved_msg') );
       this.markFinishStatus()
 
       this.getTreeData();
@@ -741,7 +793,7 @@ export default {
       luckysheet.exitEditMode();
       //结构类型乱飘 强制定义下
       let data = {...luckysheet.getAllSheets()[0],status:Number(luckysheet.getAllSheets()[0].status)}
-      if (!data.celldata.length) return this.$message.warning("请输入表格内容");
+      if (!data.celldata.length) return this.$message.warning(this.$t('OnlineExcelPage.input_content_msg') );
 
       data.luckysheet_select_save = [];
       const { ExcelInfoId, ExcelName, ExcelClassifyId } = this.sheetDetailInfo;
@@ -756,7 +808,7 @@ export default {
         this.$message.warning(res.Data.Msg)
         this.refreshOnlineExcel()
         this.onlineExcelEditing=false
-        this.editButtonText = `${res.Data.Editor}编辑中`
+        this.editButtonText = `${res.Data.Editor}${this.$t('OnlineExcelPage.editing_msg') }`
         this.autoSaveType=''
         return 
       }
@@ -774,7 +826,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;
 
@@ -814,7 +867,7 @@ export default {
 
           this.sheetDetailInfo = res.Data;
           this.saveTime = this.$moment(this.sheetDetailInfo.ModifyTime).format('YYYY-MM-DD HH:mm:ss')||''
-          this.editButtonText = this.sheetDetailInfo.CanEdit?'':`${this.sheetDetailInfo.Editor}编辑中`
+          this.editButtonText = this.sheetDetailInfo.CanEdit?'':`${this.sheetDetailInfo.Editor}${this.$t('OnlineExcelPage.editing_msg')}`
 
           this.$nextTick(() => {
             //sheet组件Mounted已经init一次,再次调用会导致工具栏样式错乱
@@ -832,9 +885,9 @@ export default {
     /* 删除表格 */
     delSheetHandle({cell, type = ""}) {
       const { ExcelClassifyId, ExcelInfoId  } = cell;
-      this.$confirm("删除后该表格将不能再引用,确认删除吗?", "提示", {
-        confirmButtonText: "确定",
-        cancelButtonText: "取消",
+      this.$confirm(this.$t('ETable.Msg.is_del_table_msg') , this.$t('Confirm.prompt') , {
+        confirmButtonText:  this.$t('Dialog.confirm_btn'),
+        cancelButtonText: this.$t('Dialog.cancel_btn'),
         type: "warning",
       })
         .then(() => {
@@ -854,7 +907,7 @@ export default {
             3: "/addMixedSheet",
           };
           if(this.sheetDetailInfo.Source === 1) {
-            if(this.editButtonText.indexOf('编辑中')!=-1){
+            if(this.editButtonText.indexOf(this.$t('OnlineExcelPage.editing_msg'))!=-1){
               // 编辑中的状态 重新获取最新的详情数据
               this.refreshOnlineExcel()
             }
@@ -868,7 +921,7 @@ export default {
           }
 
         }else if(res.Data.Status==1){
-          this.editButtonText = `${res.Data.Editor}编辑中`
+          this.editButtonText = `${res.Data.Editor}${this.$t('OnlineExcelPage.editing_msg')}`
           this.$message.warning('当前'+this.editButtonText)
         }
       })
@@ -882,7 +935,7 @@ export default {
       });
 
       if (res.Ret !== 200) return;
-      this.$message.success("刷新成功");
+      this.$message.success(this.$t('ETable.Msg.refresh_success_msg') );
       this.getDetailHandle();
     }, 300),
 
@@ -914,7 +967,7 @@ export default {
 
       if (res.Ret !== 200) return;
 
-      this.$message.success("保存成功");
+      this.$message.success(this.$t('MsgPrompt.saved_msg') );
       this.cancelSaveOther();
       this.getTreeData();
     },

+ 7 - 1
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>
             )
         },
@@ -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:''
         }))
       }
 
@@ -1621,7 +1626,7 @@ export default {
       .chart-author {
         color: #333;
         position: absolute;
-        bottom: 20px;
+        bottom: 10px;
         right: 38px;
       }
       .chartWrapper {

+ 176 - 23
src/views/operation_manage/AIQA/AIQA.vue

@@ -45,7 +45,7 @@
             </div>
             <!-- 仅这一部分滚动 -->
             <div class="window-content-wrap hidden-scrollbar">
-                <div class="content-item" v-for="item in historyList" :key="item.AiChatId">
+                <div class="content-item" v-for="item in historyList" :key="item.AiChatId" >
                     <!-- user 提问 -->
                     <Message-Item :messageInfo="formatMsg(item,'user')"
                         @startTyping="handleStartTyping"
@@ -57,9 +57,22 @@
                         @finishedTyping="handleFinishedTyping"
                     />
                 </div>
-                <New-Window-Hint v-if="activeWindowId===0"/>
+                <New-Window-Hint v-if="activeWindowId===0" />
             </div>
-            <div class="input-box">
+            <div class="input-box" id="input-box">
+                <div class="upload-row">
+                    <el-upload
+                    style="display: inline-block; margin-right: 8px"
+                    accept=".pptx,.pdf"
+                    action=""
+                    :http-request="handleUpload"
+                    :before-upload="handleBeforeUpload"
+                    :show-file-list="false"
+                    :disabled="startUploadAudio">
+                        <img src="~@/assets/img/icons/ai-upload.png" />
+                    </el-upload>
+                    <span>支持格式:PDF、PPTX;大小不超过10MB;要求纯文本,不含图片</span>
+                </div>
                 <textarea rows="6" v-model="inputText" :placeholder="$t('ToolBox.AIQuestion.input_placeholder')" @keydown.enter="handleSendMsg"></textarea>
                 <div class="send-btn" @click="handleSendMsg"><img src="~@/assets/img/ai_m/send.png" />{{$t('ToolBox.AIQuestion.send_btn')}}</div>
             </div>
@@ -116,6 +129,9 @@ export default {
             windowContentLoading:null,
             answerLoading:false,//回答中
             companyName:'',
+            aiFileIds:[],
+            // 上传窗口的队列
+            windowSet:new Set()
         };
     },
     watch:{
@@ -162,16 +178,23 @@ export default {
                 if(res.Ret!==200) return
                 const {List} = res.Data
                 this.historyList = List||[]
+
+                this.aiFileIds=this.historyList.map(item => item.OpenaiFileId).filter(Boolean)
+
                 this.windowContentLoading&&this.windowContentLoading.close()
                 //使用模型
                 this.model = this.historyList.length?this.historyList[this.historyList.length-1].Model:'GPT-4 Turbo'
                 //如果有历史记录,则滚动到底部
-                this.$nextTick(()=>{
-                    const windowContentWrap = document.querySelector('.window-content-wrap')
-                    windowContentWrap.scrollTo({
-                        top:windowContentWrap.scrollHeight,
-                        behavior:'smooth'
-                    })
+                this.windowContentToBottom()
+            })
+        },
+        // 滚动到聊天窗口底部
+        windowContentToBottom(){
+            this.$nextTick(()=>{
+                const windowContentWrap = document.querySelector('.window-content-wrap')
+                windowContentWrap.scrollTo({
+                    top:windowContentWrap.scrollHeight,
+                    behavior:'smooth'
                 })
             })
         },
@@ -184,11 +207,12 @@ export default {
                 messageType:'',
                 modelName:''
             }
-            const {Ask,Answer,CreateTime,ModifyTime,isPlay,Model} = msg
+            const {Ask,Answer,CreateTime,ModifyTime,isPlay,Model,OpenaiFilePath} = msg
             if(type==='user'){
                 msgObj.messageText = Ask||''
                 msgObj.messageType = 'question'
                 msgObj.messageTime = CreateTime||''
+                msgObj.askFileUrl = OpenaiFilePath || ''
             }
             else{
                 msgObj.messageText = Answer||''
@@ -196,6 +220,7 @@ export default {
                 msgObj.messageTime = ModifyTime||''
                 msgObj.modelName = Model||''
                 msgObj.isPlay = Boolean(isPlay)
+                msgObj.askFileUrl = OpenaiFilePath || ''
             }
             return msgObj
         },
@@ -211,6 +236,7 @@ export default {
             this.activeWindow=null
             this.historyList=[]
             this.model='GPT-4 Turbo'
+            this.aiFileIds=[]
             //this.inputText=''
             this.isTyping = false
         },
@@ -319,7 +345,7 @@ export default {
             //mock 加入到historyList中
             const msgObj = {
                 AiChatId:-1,
-                AiChatTopicId:0,
+                AiChatTopicId:this.activeWindowId || 0,
                 Ask:this.inputText,
                 Answer:'回答生成中...',
                 CreateTime:'',
@@ -329,20 +355,23 @@ export default {
             this.historyList.push(msgObj)
             
             //滚动到底部
-            this.$nextTick(()=>{
-                const windowContentWrap = document.querySelector('.window-content-wrap')
-                windowContentWrap.scrollTo({
-                    top:windowContentWrap.scrollHeight,
-                    behavior:'smooth'
-                })
-            })
+            this.windowContentToBottom()
+
             const inputText = this.inputText
             this.inputText = ''
-            aiQAInterence.sendChatMsg({
+            let apiName = "sendChatMsg"
+            let params={
                 AiChatTopicId:this.activeWindowId<=0?0:this.activeWindowId,
                 Ask:inputText,
                 // Model:this.model
-            }).then(res=>{
+            }
+            if(this.aiFileIds && this.aiFileIds.length>0){
+                // 文件检索功能
+                apiName="fileRetrieve"
+                params.OpenaiFileId=this.aiFileIds
+            }
+            // console.log(params,"params");
+            aiQAInterence[apiName](params).then(res=>{
                 this.answerLoading=false
                 //在回答未获取前切换了新窗口
                 if(this.historyList.length===0){
@@ -387,7 +416,10 @@ export default {
             })
         },
         //获取窗口列表
-        getWindowList(){
+        /**
+         * @param {*} topicId AiChatTopicId 定位到具体窗口
+         */
+        getWindowList(topicId){
             this.listWrapLoading = this.$loading({
                 target:document.querySelector('.list-wrap'),
                 background: 'rgba(244, 245, 249, 1)'
@@ -395,6 +427,9 @@ export default {
             aiQAInterence.getTopicList().then(res=>{
                 if(res.Ret!==200) return
                 this.windowList = res.Data.List||[]
+                if(topicId){
+                    this.changeActiveWindow({AiChatTopicId:topicId})
+                }
                 this.listWrapLoading&&this.listWrapLoading.close()
             })
         },
@@ -405,11 +440,112 @@ export default {
                     this.companyName=res.Data.CompanyName||''
                 }
             })
+        },
+        inputBoxDragover(event){
+            event.preventDefault(); //阻止默认行为,允许放置
+        },
+        inputBoxDrop(event){
+            event.preventDefault(); //阻止浏览器默认行为
+            // 获取文件的数据
+            const DataTransferItemList = event.dataTransfer.files
+            if(DataTransferItemList && DataTransferItemList.length){
+                if(DataTransferItemList.length>1){
+                    return this.$message.error("单次只能上传一个文件,请重试");
+                }else{
+                    let file = DataTransferItemList[0]
+                    if(file.type && (file.name.endsWith('.pdf')||file.name.endsWith('.pptx'))){
+                        if(file.size/1024/1024 > 10.1){
+                            this.$message.error("上传文件大小不超过10MB");
+                            return false;
+                        }
+                        this.handleUpload({file})
+                    }else{
+                        return this.$message.error("上传文件格式只支持PDF、PPTX");
+                    }
+                }
+            }else{
+                // 没有文件数据
+                let txt = event.dataTransfer.getData("text/plain")
+                this.inputText=txt
+            }
+        },
+        handleBeforeUpload(e) {
+            if(!(e.name.endsWith('.pdf') || e.name.endsWith('.pptx'))){
+                this.$message.error("上传文件格式只支持PDF、PPTX");
+                return false;
+            }
+            if(!(e.size/1024/1024 < 10.1)){
+                this.$message.error("上传文件大小不超过10MB");
+                return false;
+            }
+        },
+        handleUpload(e){
+            // console.log(this.windowSet,this.activeWindowId);
+            if(this.windowSet.has(this.activeWindowId)){
+                return this.$message.warning("请等待文件上传完成")
+            }
+
+            let {file} = e
+            let downloadHint = this.$message({
+                type:"info",
+                message:'上传中,请稍后······',
+                duration:0,
+                iconClass:'el-icon-loading'
+            })
+            let formData = new FormData()
+            formData.append('File',file)
+            formData.append('AiChatTopicId',this.activeWindowId)
+            this.windowSet.add(this.activeWindowId)
+            aiQAInterence.fileUpload(formData).then(res=>{
+                downloadHint.close()
+                if(res.Ret == 200){
+                    let Data = res.Data || {}
+                    this.$message.success(`${Data.ResourceName}上传成功`)
+                    if(this.windowList.find(item => item.AiChatTopicId == Data.AiChatTopicId)){
+                        // 窗口存在
+                        this.windowSet.delete(Data.AiChatTopicId)
+
+                        if(Data.AiChatTopicId == this.activeWindowId){
+                            this.aiFileIds.push(Data.OpenaiFileId)
+                            const msgObj = {
+                                AiChatId:Data.AiChatId || -1,
+                                AiChatTopicId:Data.AiChatTopicId,
+                                Ask:Data.ResourceName,
+                                OpenaiFilePath:Data.ResourceUrl,
+                                Answer:Data.Answer || '',
+                                CreateTime:Data.CreateTime||'',
+                                ModifyTime:Data.ModifyTime || '',
+                                Model:this.model
+                            }
+                            this.historyList.push(msgObj)
+                            this.windowContentToBottom()
+                        }
+                    }else{
+                        //窗口不存在
+                        this.windowSet.delete(0)
+                        this.getWindowList(this.activeWindowId==0 ? Data.AiChatTopicId:0)
+                    }
+                }
+            }).catch(()=>{
+                downloadHint.close()
+                // 失败,清空
+                this.windowSet.clear()
+            })
         }
     },
     mounted(){
         this.getWindowList()
         this.getBaseConfig()
+        const dropDom = document.getElementById('input-box')
+        dropDom.addEventListener('dragover',this.inputBoxDragover);
+
+        dropDom.addEventListener('drop',this.inputBoxDrop);
+    },
+    beforeDestroy(){
+        const dropDom = document.getElementById('input-box')
+        dropDom.removeEventListener('dragover',this.inputBoxDragover);
+
+        dropDom.removeEventListener('drop',this.inputBoxDrop);
     }
 };
 </script>
@@ -556,13 +692,30 @@ $border-color:#3D52A1;
             }
         }
         .input-box{
-            padding:30px;
+            padding:12px 30px 30px;
             position: relative;
+            .upload-row{
+                display: flex;
+                align-items: center;
+                padding: 0 20px;
+                margin-bottom: 12px;
+                img{
+                    height: 20px;
+                    width: 20px;
+                    vertical-align: bottom;
+                    box-shadow: 3px 3px 8px 0px #182c421f;
+                }
+                span{
+                    color: #A5A5A5;
+                    font-size: 15px;
+                    font-weight: 400;
+                }
+            }
             textarea{
                 width:100%;
                 border-radius: 16px;
                 box-sizing: border-box;
-                padding:20px 85px 20px 20px;
+                padding:20px 95px 20px 20px;
                 font-size: 16px;
                 resize: none;
                 border-color: #E3E3E3;

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

@@ -1,10 +1,21 @@
 <template>
-    <div class="message-item-wrap" :class="messageInfo.messageType">
+    <div class="message-item-wrap" :class="messageInfo.messageType" 
+    v-if="!(messageInfo.messageType=='answer' && messageInfo.askFileUrl && (!messageInfo.messageText))">
+    <!-- 上传文件时,不想有回答 -->
         <div class="message-icon"><img :src="IconSrc"  v-if="IconSrc"/></div>
         <div class="message-info">
             <span class="message-time" :class="messageInfo.messageType">{{messageInfo.messageTime}}</span>
-            <div class="message-text" :class="messageInfo.messageType" v-if="!isPlay">{{messageInfo.messageText}}</div>
-            <div class="message-text typing" :class="messageInfo.messageType" v-else>{{typingText}}</div>
+            <div class="message-text" :class="messageInfo.messageType">
+                <template v-if="messageInfo.askFileUrl">
+                    <div class="message-file" @click="fileClickHandle(messageInfo.askFileUrl)">
+                        <img :src="getFileIcon" />
+                        <span :class="{'typing':isPlay}">{{isPlay ? typingText : messageInfo.messageText}}</span>
+                    </div>
+                </template>
+                <template v-else>
+                    <span :class="{'typing':isPlay}">{{isPlay ? typingText : messageInfo.messageText}}</span>
+                </template>
+            </div>
         </div>
     </div>
 </template>
@@ -55,6 +66,19 @@ export default {
             const {messageType,modelName} = this.messageInfo
             const iconType = messageType==='question'?'user':'GPT-4 Turbo'
             return this.iconMap[iconType]||''
+        },
+        getFileIcon(){
+            if(this.messageInfo.askFileUrl){
+                if(this.messageInfo.askFileUrl.endsWith('.pdf')){
+                    return require('@/assets/img/icons/file_type_pdf.png')
+                }else if(this.messageInfo.askFileUrl.endsWith('.pptx')){
+                    return require('@/assets/img/icons/file_type_ppt.png')
+                }else{
+                    return require('@/assets/img/icons/file_type_unknown.png')
+                }
+            }else{
+                return ''
+            }
         }
     },
     methods: {
@@ -78,6 +102,9 @@ export default {
             this.isPlay = false
             this.typingText=''
             this.$emit('finishedTyping',this.messageInfo)
+        },
+        fileClickHandle(url){
+            window.open(url,"_blank")
         }
     },
 };
@@ -108,13 +135,24 @@ export default {
             padding:14px 20px;
             display: inline-block;
             white-space: pre-line;
+            .message-file{
+                display: flex;
+                align-items: center;
+                cursor: pointer;
+                margin: -4px;
+                img{
+                   height: 24px;
+                   width: 24px; 
+                   margin-right: 8px;
+                }
+            }
             &.answer{
                 background-color: #F4F4F4;
             }
             &.question{
                 background-color: #E3EFFD;
             }
-            &.typing{
+            .typing{
                 &::after{
                     content: '|';
                     animation: blink 1s infinite

+ 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
             },

+ 51 - 15
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';
@@ -470,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])
@@ -535,27 +540,52 @@ 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 => {
+              if(item.data&&item.data.length) {
+                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换行
         //一行可容纳的中文字体数
-        let count = parseInt($(`#${refName}`)[0].offsetWidth / 19)*2;
+        const fontSize = chartTheme?chartTheme.titleOptions.style.fontSize:16
+        let count = parseInt($(`#${refName}`)[0].offsetWidth / fontSize)*1.75
         let {total,newStr} = getStrSize(options.MyChartTitle,count)
         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};
+            min-height:18px;word-break: break-all;
           ">
             ${options.MyChartTitle}
           </div>`
         }
-
         let SpecialOption = {
           chart: {
             ...defaultOpts.chart,
@@ -564,7 +594,7 @@ export default {
             animation: false,
             backgroundColor: "rgba(0,0,0,0)",
             renderTo:$(`#${refName}`)[0],
-            ...options.chart||{}
+            ...options.chart||{},
           },
           legend: {
             ...defaultOpts.legend,
@@ -573,7 +603,7 @@ export default {
           colors: options.colors||chartTheme&&chartTheme.colorsOptions||defaultOpts.colors,
           title: isPublish?{
             text: isShowTitle?newStr:null,
-            margin:0,
+            margin:5,
             useHTML:false,
             style:{...chartTheme&&chartTheme.titleOptions.style},
             align: (chartTheme&&chartTheme.titleOptions.align) || (total>count?'left':'center'),
@@ -581,7 +611,7 @@ export default {
             text: titleHTML,
             useHTML:true,
             margin:0,
-            style:{left:0}
+            style:{textAlign:chartTheme&&chartTheme.titleOptions.align,left:0,width:'100%'}
           },
           plotOptions: {
             ...defaultOpts.plotOptions,
@@ -593,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')) ? {
@@ -606,6 +640,8 @@ export default {
 
         if(!$(`#${refName}`)[0]) return
 
+        console.log(SpecialOption)
+
         if(is_linear)
           Highcharts.chart({
             // Highcharts 配置

+ 9 - 4
src/views/ppt_manage/newVersion/components/catalog/chooseShareUserDia.vue

@@ -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 || []
     },
 
     // 对获取到的研究员列表做处理

+ 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;
 }

+ 7 - 36
src/views/ppt_manage/newVersion/components/formatPage/FormatEle.vue

@@ -1,5 +1,5 @@
 <template>
-    <div class="total-wrap flex-column" :style="{'pointer-events' :isPreview?'none':'auto'}">
+    <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':''">
@@ -70,42 +70,13 @@
         },
     };
 </script>
-<style lang="scss">
-.line{
-    justify-content: space-around !important;
-    .line-item{
-        .el-wrap .chart-wrap{
-            width:90%;
-            height:90%;
-        }
-        .editor-wrap{
-            width:90%;
-            height:90%
-        }
-    }
-}
-</style>
 <style scoped lang="scss">
-    .total-wrap {
-        .line{
-            height:40%;
-            .line-item{
-                width:45%;
-                height:100%;
-                .el-wrap .chart-wrap{
-                    width:90%;
-                    height:90%;
-                }
-            }
-        }
-
-        .wrap-full-bottom {
-            position: absolute;
-            bottom: 0;
-            justify-content: space-around;
-        }
-        .bottom-15{
-            height: 18%;
+.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'}"> -->

+ 7 - 34
src/views/ppt_manage/newVersion/components/formatPage/FormatTen.vue

@@ -1,5 +1,5 @@
 <template>
-    <div class="total-wrap flex-column" :style="{'pointer-events' :isPreview?'none':'auto'}">
+    <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':''">
@@ -82,40 +82,13 @@
         },
     };
 </script>
-<style lang="scss">
-.line{
-    .line-item{
-        .el-wrap .chart-wrap{
-            width:90%;
-            height:90%;
-        }
-        .editor-wrap{
-            width:90%;
-            height:90%
+<style lang="scss" scoped>
+.format-ten{
+    .line{
+        height:41%;
+        .line-item{
+            width:33%;
         }
     }
 }
-</style>
-<style scoped lang="scss">
-    .total-wrap {
-        .line{
-            height:40%;
-            .line-item{
-                width:33%;
-                height:100%;
-                .el-wrap .chart-wrap{
-                    width:90%;
-                    height:90%;
-                }
-            }
-        }
-
-        .wrap-full-bottom {
-            position: absolute;
-            bottom: 0;
-        }
-        .bottom-15{
-            height: 18%;
-        }
-    }
 </style>

+ 7 - 34
src/views/ppt_manage/newVersion/components/formatPage/FormatTwelve.vue

@@ -1,5 +1,5 @@
 <template>
-    <div class="total-wrap flex-column" :style="{'pointer-events' :isPreview?'none':'auto'}">
+    <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':''">
@@ -76,40 +76,13 @@
         },
     };
 </script>
-<style lang="scss">
-.line{
+<style scoped lang="scss">
+.format-twelve{
+    .line{
+        height:48%;
+    }
     .line-item{
-        .el-wrap .chart-wrap{
-            width:90%;
-            height:90%;
-        }
-        .editor-wrap{
-            width:90%;
-            height:90%
-        }
+        width:33%;
     }
 }
-</style>
-<style scoped lang="scss">
-    .total-wrap {
-        .line{
-            height:48%;
-            .line-item{
-                width:33%;
-                height:100%;
-                .el-wrap .chart-wrap{
-                    width:90%;
-                    height:90%;
-                }
-            }
-        }
-
-        .wrap-full-bottom {
-            position: absolute;
-            bottom: 0;
-        }
-        .bottom-15{
-            height: 18%;
-        }
-    }
 </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%;
+            }
+        }
+    }
+
 }

+ 5 - 5
src/views/ppt_manage/newVersion/pptEditor.vue

@@ -378,11 +378,11 @@ export default {
   computed:{
     panelTabs(){
       return  [ 
-        {val:'图表',lable:this.$t('Slides.table_chart') },
-        {val:'MyETA批量',lable:this.$t('Slides.my_eta_batch')},
-        {val:'沙盘', lable:this.$t('Slides.sandbox_name')},
-        {val:'表格', lable:this.$t('Slides.table_name')},
-        {val:'语义分析插入', lable:this.$t('Slides.table_analysis_semantic')},
+        {val:'图表',label:this.$t('Slides.table_chart') },
+        {val:'MyETA批量',label:this.$t('Slides.my_eta_batch')},
+        {val:'沙盘', label:this.$t('Slides.sandbox_name')},
+        {val:'表格', label:this.$t('Slides.table_name')},
+        {val:'语义分析插入', label:this.$t('Slides.table_analysis_semantic')},
       ]
     },
   },

+ 6 - 6
src/views/ppt_manage/newVersion/pptEnEditor.vue

@@ -116,7 +116,7 @@
             <div class="addppt-right-box" v-show="!isEditLayer">
 
               <el-tabs v-model="tabsactive">
-                <el-tab-pane :label="tab" :name="tab" v-for="tab in panelTabs" :key="tab"></el-tab-pane>
+                <el-tab-pane :label="tab.label" :name="tab.val" v-for="tab in panelTabs" :key="tab"></el-tab-pane>
               </el-tabs>
               <div class="chart-tool flex-column" v-show="tabsactive == '图表'">
                 <div class="chart-search">
@@ -405,11 +405,11 @@ export default {
   computed:{
     panelTabs(){
       return  [ 
-        {val:'图表',lable:this.$t('Slides.table_chart') },
-        {val:'MyETA批量',lable:this.$t('Slides.my_eta_batch')},
-        {val:'沙盘', lable:this.$t('Slides.sandbox_name')},
-        {val:'表格', lable:this.$t('Slides.table_name')},
-        {val:'语义分析插入', lable:this.$t('Slides.table_analysis_semantic')},
+        {val:'图表',label:this.$t('Slides.table_chart') },
+        {val:'MyETA批量',label:this.$t('Slides.my_eta_batch')},
+        {val:'沙盘', label:this.$t('Slides.sandbox_name')},
+        {val:'表格', label:this.$t('Slides.table_name')},
+        {val:'语义分析插入', label:this.$t('Slides.table_analysis_semantic')},
       ]
     },
   },

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

@@ -307,7 +307,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

+ 43 - 5
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'})">{{$t('Slides.return_to_list')}}</el-button>
       </div>
       <!--全加载-->
       <template v-if="loadingAll">
@@ -57,7 +58,7 @@ import mixins from '../mixins/mixins';
 import html2canvas from 'html2canvas';
 import pptxgen from "pptxgenjs";
 import moment from 'moment';
-import{dataBaseInterface,getOSSSign} from "@/api/api.js"
+import{pptInterface,dataBaseInterface,getOSSSign} from "@/api/api.js"
 import {pptEnInterface} from '@/api/modules/pptEnApi.js';
 import Highcharts from "highcharts/highstock";
 import HighchartszhCN  from '@/utils/highcahrts-zh_CN'
@@ -135,6 +136,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);
@@ -230,7 +241,7 @@ export default {
       this.checkImg(base64Url,'svg')
     },
     //生成pptx
-    async pageToPptx(){
+    async pageToPptx(type){
       //开始计时
       const start = Date.now()
       const SlideMaster = _.cloneDeep(pptSlideMasterEn) 
@@ -445,6 +456,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:"发布中..."
@@ -475,10 +491,29 @@ export default {
       };
 
       pptx2.write('blob').then((data)=>{
+        // 1走后端接口上传
+        const uploadType=this.$setting.dynamicOutLinks.PptUpdateApi ||
+                        this.$store.state.dynamicOutLinks.PptUpdateApi ||
+                        JSON.parse(localStorage.getItem('dynamicOutLinks')).PptUpdateApi
+        if(uploadType==1){
+          let form = new FormData()
+          form.append("file",data)
+          form.append("PptId",this.$route.query.id) 
+          pptInterface.uploadPPTXFile(form).then(res=>{
+            if(res.Ret===200){
+              this.publishPPT(res.Data.ResourceUrl)
+            }
+          })
+          return
+        }
+
+        
+        // 上传到阿里云oss
+        // this.handleUploadToOSS(data)
         let clientType = this.$setting.dynamicOutLinks.ObjectStorageClient ||
                         this.$store.state.dynamicOutLinks.ObjectStorageClient ||
                         JSON.parse(localStorage.getItem('dynamicOutLinks')).ObjectStorageClient
-        // 上传到 对象存储器 阿里云、mino
+        // 上传到 对象存储器
         uploadFileDirect(clientType,data,temName,options).then(url=>{
           console.log('文件地址',url);
           this.publishPPT(url)
@@ -747,6 +782,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

@@ -305,7 +305,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

+ 40 - 11
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'})">{{$t('Slides.return_to_list')}}</el-button>
       </div>
       <!--全加载-->
       <template v-if="loadingAll">
@@ -155,6 +156,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);
@@ -254,7 +265,7 @@ export default {
       this.checkImg(base64Url,'svg')
     },
     //生成pptx
-    async pageToPptx(){
+    async pageToPptx(type){
       //开始计时
       const start = Date.now()
       const SlideMaster = _.cloneDeep(pptSlideMaster) 
@@ -472,6 +483,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:"发布中..."
@@ -499,15 +515,25 @@ export default {
       };
 
       //console.log('pptx',pptx)
+      //根据配置选择是走后端接口上传还是直接前端上传到oss
       pptx2.write('blob').then((data)=>{
-        // let form = new FormData()
-        // form.append("file",data)
-        // form.append("PptId",this.$route.query.id) 
-        // pptInterface.uploadPPTXFile(form).then(res=>{
-        //   if(res.Ret===200){
-        //     this.publishPPT(res.Data.ResourceUrl)
-        //   }
-        // })
+        // 1走后端接口上传
+        const uploadType=this.$setting.dynamicOutLinks.PptUpdateApi ||
+                        this.$store.state.dynamicOutLinks.PptUpdateApi ||
+                        JSON.parse(localStorage.getItem('dynamicOutLinks')).PptUpdateApi
+        if(uploadType==1){
+          let form = new FormData()
+          form.append("file",data)
+          form.append("PptId",this.$route.query.id) 
+          pptInterface.uploadPPTXFile(form).then(res=>{
+            if(res.Ret===200){
+              this.publishPPT(res.Data.ResourceUrl)
+            }
+          })
+          return
+        }
+
+        
         // 上传到阿里云oss
         // this.handleUploadToOSS(data)
         let clientType = this.$setting.dynamicOutLinks.ObjectStorageClient ||
@@ -799,6 +825,9 @@ $titleColor:#333333;
     top:20px;
     right:3%;
     z-index:10;
+    display: flex;
+    flex-direction: column;
+    gap:20px;
   }
   .fixed-wrap{
     position:fixed;

+ 76 - 76
src/views/ppt_manage/newVersion/utils/config.js

@@ -228,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
         }]
     },
@@ -244,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
@@ -267,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
         }]
     },
@@ -295,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
         }]
     },
@@ -333,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
         }]
     },
@@ -349,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
       }]
     },
@@ -366,23 +366,23 @@ 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
       }
     ]
@@ -390,126 +390,126 @@ export const modelConfig = [{
         modelId:12,
         elements:[{
             position:1,
-            width:33*0.9,
+            width:33,
             height:(restHeight)*0.48*0.9,
-            x:(33*0.1)/2,
+            x:0,
             y:(restHeight*0.48*0.1)/2
         },{
             position:2,
-            width:33*0.9,
+            width:33,
             height:(restHeight)*0.48*0.9,
-            x:(33*0.1)/2+33,
+            x:33,
             y:(restHeight*0.48*0.1)/2
         },
         {
             position:3,
-            width:33*0.9,
+            width:33,
             height:(restHeight)*0.48*0.9,
-            x:(33*0.1)/2+33*2,
+            x:33*2,
             y:(restHeight*0.48*0.1)/2
         },
         {
             position:4,
-            width:33*0.9,
+            width:33,
             height:(restHeight)*0.48*0.9,
-            x:(33*0.1)/2,
-            y:(restHeight)*0.48
+            x:0,
+            y:(restHeight)*0.48+(restHeight*0.48*0.1)/2
         },
         {
             position:5,
-            width:33*0.9,
+            width:33,
             height:(restHeight)*0.48*0.9,
-            x:(33*0.1)/2+33,
-            y:(restHeight)*0.48
+            x:33,
+            y:(restHeight)*0.48+(restHeight*0.48*0.1)/2
         },
         {
             position:6,
-            width:33*0.9,
+            width:33,
             height:(restHeight)*0.48*0.9,
-            x:(33*0.1)/2+33*2,
-            y:(restHeight)*0.48
+            x:33*2,
+            y:(restHeight)*0.48+(restHeight*0.48*0.1)/2
         }]
     },{
         modelId:11,
         elements:[{
             position:1,
-            width:45*0.9,
+            width:50,
             height:(restHeight)*0.40*0.9,
-            x:(45*0.1)/2,
+            x:0,
             y:(restHeight*0.4*0.1)/2
         },{
             position:2,
-            width:45*0.9,
+            width:50,
             height:(restHeight)*0.40*0.9,
-            x:(45*0.1)/2+50,
+            x:50,
             y:(restHeight*0.4*0.1)/2
         },{
             position:3,
-            width:45*0.9,
+            width:50,
             height:(restHeight)*0.40*0.9,
-            x:(45*0.1)/2,
+            x:0,
             y:38
         },{
             position:4,
-            width:45*0.9,
+            width:50,
             height:(restHeight)*0.40*0.9,
-            x:(45*0.1)/2+50,
+            x:50,
             y:38
         },{
             position:5,
             width:100*0.9,
             height:(restHeight)*0.18*0.8,
-            x:(100-100*0.9)/2,
+            x:0,
             y:74
         }]
     },{
         modelId:10,
         elements:[{
             position:1,
-            width:33*0.9,
+            width:33,
             height:(restHeight)*0.4*0.9,
-            x:(33*0.1)/2,
+            x:0,
             y:(restHeight*0.4*0.1)/2
         },{
             position:2,
-            width:33*0.9,
+            width:33,
             height:(restHeight)*0.4*0.9,
-            x:(33*0.1)/2+33,
+            x:33,
             y:(restHeight*0.4*0.1)/2
         },
         {
             position:3,
-            width:33*0.9,
+            width:33,
             height:(restHeight)*0.4*0.9,
-            x:(33*0.1)/2+33*2,
+            x:33*2,
             y:(restHeight*0.4*0.1)/2
         },
         {
             position:4,
-            width:33*0.9,
+            width:33,
             height:(restHeight)*0.4*0.9,
-            x:(33*0.1)/2,
+            x:0,
             y:38
         },
         {
             position:5,
-            width:33*0.9,
+            width:33,
             height:(restHeight)*0.4*0.9,
-            x:(33*0.1)/2+33,
+            x:33,
             y:38
         },
         {
             position:6,
-            width:33*0.9,
+            width:33,
             height:(restHeight)*0.4*0.9,
-            x:(33*0.1)/2+33*2,
+            x:33*2,
             y:38
         },
         {
             position:7,
-            width:100*0.9,
+            width:100,
             height:(restHeight)*0.18*0.8,
-            x:(100-100*0.9)/2,
+            x:0,
             y:74
         }]
     }

+ 11 - 15
src/views/report_manage/reportAuthor.vue

@@ -2,12 +2,12 @@
   <div class="sandList-container">
     <div class="main-top" v-if="authTabsOpt.length">
       <el-button v-if="isAddBtnShow"
-        type="primary" @click="addAuthorHandle">{{ChineseEcnglish.add_author_btn}}</el-button>
+        type="primary" @click="addAuthorHandle">{{$t('ReportManage.AuthorManagement.add_author_btn')}}</el-button>
       <div>
         <el-input
           v-model="search_txt"
           style="width: 250px; margin-right: 20px"
-          :placeholder="ChineseEcnglish.author_input_name"
+          :placeholder="$t('ReportManage.AuthorManagement.author_input_name')"
         >
           <i slot="prefix" class="el-input__icon el-icon-search"></i>
         </el-input>
@@ -40,7 +40,7 @@
           align="center"
         >
           <template slot-scope="{row}">
-            <span v-if="item.key==='Enable'" :style="!row.Enable?'color: #f00':''">{{row.Enable?ChineseEcnglish.column_enabled_btn:ChineseEcnglish.column_disabled_btn}}</span>
+            <span v-if="item.key==='Enable'" :style="!row.Enable?'color: #f00':''">{{row.Enable?$t('ReportManage.AuthorManagement.column_enabled_btn'):$t('ReportManage.AuthorManagement.column_disabled_btn')}}</span>
             <span v-else>{{ row[item.key] }}</span>
           </template>
         </el-table-column>
@@ -51,7 +51,7 @@
             <span class="deletesty" v-if="isDeleteBtnShow"
                 @click="itemHandle(row, 'del')" style="margin-right: 10px">{{$t('Table.delete_btn')}}</span>
             <span class="editsty" v-if="isEnableBtnShow"
-                @click="itemHandle(row, 'set')">{{row.Enable?ChineseEcnglish.column_disabled_btn:ChineseEcnglish.column_enabled_btn}}</span>
+                @click="itemHandle(row, 'set')">{{row.Enable?$t('ReportManage.AuthorManagement.column_disabled_btn'):$t('ReportManage.AuthorManagement.column_enabled_btn')}}</span>
           </template>
         </el-table-column>
 
@@ -83,11 +83,11 @@
           label-position="left"
           hide-required-asterisk
           label-width="95px">
-          <el-form-item :label="ChineseEcnglish.author_input_name" prop="name" :rules="[{ required: true, message: ChineseEcnglish.add_author_rules, trigger: 'blur' }]">
+          <el-form-item :label="$t('ReportManage.AuthorManagement.author_input_name')" prop="name" :rules="[{ required: true, message: $t('ReportManage.AuthorManagement.add_author_rules'), trigger: 'blur' }]">
             <el-input 
               type="text" 
               v-model="authorForm.name" 
-              :placeholder="ChineseEcnglish.please_input"
+              :placeholder="$t('ReportManage.AuthorManagement.please_input')"
               style="width:400px;"
             />
           </el-form-item>
@@ -214,24 +214,20 @@ export default {
                 )
         }
     },
-    // 中英文互译
-    ChineseEcnglish(){
-      return this.$t('ReportManage.AuthorManagement')
-    },
     tableColums(){
       return [
           {
-            label: this.ChineseEcnglish.author_input_name,
+            label: this.$t('ReportManage.AuthorManagement.author_input_name'),
             key: 'ReportAuthor',
             minwidthsty: '100px',
           },
           {
-            label: this.ChineseEcnglish.column_add_time,
+            label: this.$t('ReportManage.AuthorManagement.column_add_time'),
             key: 'CreateTime',
             minwidthsty: '120px',
           },
           {
-            label: this.ChineseEcnglish.column_status,
+            label: this.$t('ReportManage.AuthorManagement.column_status'),
             key: 'Enable',
             widthsty: '120px',
           },
@@ -268,7 +264,7 @@ export default {
     /* 添加作者 */
     addAuthorHandle() {
       this.authorForm = {
-        title: this.ChineseEcnglish.add_author_btn,
+        title: this.$t('ReportManage.AuthorManagement.add_author_btn'),
         name: '',
         report_type: this.authTabsOpt[0].key
       }
@@ -350,7 +346,7 @@ export default {
   mounted() {
     this.$nextTick(()=>{
        this.authorForm =  {
-         title: this.ChineseEcnglish.add_author_btn,
+         title: this.$t('ReportManage.AuthorManagement.add_author_btn'),
          name: '',
          report_type: 1
        }

+ 14 - 19
src/views/report_manage/reportVariety.vue

@@ -2,8 +2,8 @@
     <div class="report-variety-page">
         <div class="top-wrap">
             <el-button type="primary" v-permission="permissionBtn.enChartPermission.enChartPermission_save"
-                @click="showEditBreed=true;getParentVarietyList()">{{ChineseEcnglish.add_product_btn}}</el-button>
-            <el-input :placeholder="ChineseEcnglish.add_product_input" v-model="searchVal" style="max-width: 262px; float: right" @change="handleSearch" clearable>
+                @click="showEditBreed=true;getParentVarietyList()">{{$t('ReportManage.CommodityConfiguration.add_product_btn')}}</el-button>
+            <el-input :placeholder="$t('ReportManage.CommodityConfiguration.add_product_input')" v-model="searchVal" style="max-width: 262px; float: right" @change="handleSearch" clearable>
                 <i slot="prefix" class="el-input__icon el-icon-search"></i>
             </el-input>
         </div>
@@ -16,12 +16,12 @@
                 row-key="EnPermissionId" 
                 :tree-props="{children:'Child',hasChildren:'hasChildren'}"
             >
-                <el-table-column prop="EnPermissionName" :label="ChineseEcnglish.column_top">
+                <el-table-column prop="EnPermissionName" :label="$t('ReportManage.CommodityConfiguration.column_top')">
                     <template slot-scope="scope">
                         <span>{{scope.row.ParentId==0?scope.row.EnPermissionName:''}}</span>
                     </template>
                 </el-table-column>
-                <el-table-column prop="EnPermissionName" :label="ChineseEcnglish.column_second">
+                <el-table-column prop="EnPermissionName" :label="$t('ReportManage.CommodityConfiguration.column_second')">
                     <template slot-scope="scope">
                         <span>{{scope.row.ParentId!=0?scope.row.EnPermissionName:''}}</span>
                     </template>
@@ -40,7 +40,7 @@
         <!-- 品种编辑弹窗 -->
         <el-dialog 
             :modal-append-to-body='false' 
-            :title="!editBreedData.id?ChineseEcnglish.add_product_btn:$t('ReportManage.CommodityConfiguration.edit_variety_title')" 
+            :title="!editBreedData.id?$t('ReportManage.CommodityConfiguration.add_product_btn'):$t('ReportManage.CommodityConfiguration.edit_variety_title')" 
             :visible.sync="showEditBreed" 
             :close-on-click-modal="false"
             :center="true" 
@@ -49,11 +49,11 @@
         >
             <div class="edit-variety-wrap" style="padding-bottom:30px">
                 <el-form label-width="113px">
-                    <el-form-item :label="ChineseEcnglish.product_type">
-                        <el-input :placeholder="ChineseEcnglish.add_product_input" v-model="editBreedData.name" style="width:400px"></el-input>
+                    <el-form-item :label="$t('ReportManage.CommodityConfiguration.product_type')">
+                        <el-input :placeholder="$t('ReportManage.CommodityConfiguration.add_product_input')" v-model="editBreedData.name" style="width:400px"></el-input>
                     </el-form-item>
-                    <el-form-item :label="ChineseEcnglish.add_product_select">
-                        <el-select v-model="editBreedData.parentId" placeholder="请选择" style="width:400px">
+                    <el-form-item :label="$t('ReportManage.CommodityConfiguration.add_product_select')">
+                        <el-select v-model="editBreedData.parentId" :placeholder="$t('ETable.Msg.please_select')" style="width:400px">
                             <el-option
                                 v-for="item in parentVarietyOpts"
                                 :key="item.EnPermissionId"
@@ -62,8 +62,8 @@
                             </el-option>
                         </el-select>
                     </el-form-item>
-                    <el-form-item :label="ChineseEcnglish.add_backend_sorting">
-                        <el-input :placeholder="ChineseEcnglish.add_backend_sorting" min="0" v-model="editBreedData.sort" type="number" style="width:400px"></el-input>
+                    <el-form-item :label="$t('ReportManage.CommodityConfiguration.add_backend_sorting')">
+                        <el-input :placeholder="$t('ReportManage.CommodityConfiguration.add_backend_sorting')" min="0" v-model="editBreedData.sort" type="number" style="width:400px"></el-input>
                     </el-form-item>
                 </el-form>
                 <div style="text-align: center;margin-top:40px">
@@ -151,7 +151,7 @@ export default {
 
         async handleConfirmEidtBreed(){
             if(!this.editBreedData.name){
-                this.$message.warning(this.ChineseEcnglish.add_product_error_msg)
+                this.$message.warning(this.$t('ReportManage.CommodityConfiguration.add_product_error_msg'))
                 return
             }
             let params={
@@ -164,7 +164,7 @@ export default {
             }
             const res=this.editBreedData.id?await reportVarietyENInterence.editVariety(params):await reportVarietyENInterence.addVariety(params)
             if(res.Ret===200){
-                this.$message.success(`${this.editBreedData.id?'编辑':"新增"}成功`)
+                this.$message.success(`${this.editBreedData.id?this.$t('MsgPrompt.edit_msg') :this.$t('MsgPrompt.add_msg')}`)
                 this.getList()
                 this.showEditBreed=false
                 this.getParentVarietyList()
@@ -193,7 +193,7 @@ export default {
                     EnPermissionId:item.EnPermissionId
                 }).then(res=>{
                     if(res.Ret===200){
-                        this.$message.success(this.ChineseEcnglish.delete_success_msg)
+                        this.$message.success(this.$t('ReportManage.CommodityConfiguration.delete_success_msg'))
                         this.getList()
                         this.getParentVarietyList()
                     }
@@ -201,11 +201,6 @@ export default {
             })
         }
     },
-    computed:{
-        ChineseEcnglish(){
-            return this.$t('ReportManage.CommodityConfiguration')
-        }
-    }
 }
 </script>
 

+ 23 - 27
src/views/semantics_manage/document/documentEditPage.vue

@@ -10,11 +10,11 @@
         :model="fileForm"
         :rules="fileFormRules"
       >
-        <el-form-item  label-width="118px" :label="ChineseEcnglish.document_name" prop="Title">
+        <el-form-item  label-width="118px" :label="$t('SemanticsManage.DocumentComparison.document_name')" prop="Title">
           <el-input
             v-model="fileForm.Title"
             style="width: 240px"
-            :placeholder="ChineseEcnglish.select_documents_input"
+            :placeholder="$t('SemanticsManage.DocumentComparison.select_documents_input')"
           />
         </el-form-item>
 <!--         <el-form-item label="文档主题" prop="Theme">
@@ -24,8 +24,8 @@
             placeholder="请输入文档主题"
           />
         </el-form-item> -->
-        <el-form-item  label-width="80px" :label="ChineseEcnglish.select_category" prop="ClassifyId">
-          <el-select :placeholder="ChineseEcnglish.please_select_category" v-model="fileForm.ClassifyId">
+        <el-form-item  label-width="80px" :label="$t('SemanticsManage.DocumentComparison.select_category')" prop="ClassifyId">
+          <el-select :placeholder="$t('SemanticsManage.DocumentComparison.please_select_category')" v-model="fileForm.ClassifyId">
             <el-option 
               v-for="item in classifyOptions" :key="item.SaDocClassifyId"
               :label="item.ClassifyName"
@@ -41,14 +41,14 @@
       <froala :id="`froala-editor-documentContent`" 
         :ref="`froalaEditorDocumentContent`" 
         :tag="'textarea'" 
-        :config="{...froalaConfig,placeholderText:'请输入文章内容'}" 
+        :config="{...froalaConfig,placeholderText:$t('SemanticsManage.DocumentComparison.article_content_enter')}" 
         v-model="documentContent"></froala>
     </div>
     <div class="document-content page-block-wrap overflow-hide-scrollbar" v-else>
       <div class="content-block">
         <div class="block-item" v-for="(item,index) in fileBlockArr" :key="index">
             <!-- 若段落内有选定文字被打标签 item.UsePartNum 则不允许编辑段落内容 -->
-          <textarea v-model="item.innerText" placeholder="请输入段落内容" :disabled="item.UsePartNum!==0"></textarea>
+          <textarea v-model="item.innerText" :placeholder="$t('SemanticsManage.DocumentComparison.paragraph_content_ipt')" :disabled="item.UsePartNum!==0"></textarea>
           <div class="block-item-tool">
             <div class="add-btn" @click="addBlock(index)">
               <img
@@ -56,7 +56,7 @@
                 alt=""
                 style="width: 14px; height: 14px; margin-right: 10px"
               />
-              <span>{{ChineseEcnglish.add_next_section}}</span>
+              <span>{{$t('SemanticsManage.DocumentComparison.add_next_section')}}</span>
             </div>
             <div class="dele-btn" style="margin-left:30px;margin-right:auto;"
               v-if="item.UseNum+item.UsePartNum===0" @click="deleteBlock(index)">
@@ -67,7 +67,7 @@
               />
               <span>{{$t('Table.delete_btn')}}</span>
             </div>
-            <p class="hint-text">{{ChineseEcnglish.number_tags_attached}}:{{item.UseNum+item.UsePartNum}}</p>
+            <p class="hint-text">{{$t('SemanticsManage.DocumentComparison.number_tags_attached')}}:{{item.UseNum+item.UsePartNum}}</p>
           </div>
         </div>
       </div>
@@ -88,17 +88,7 @@ export default {
       fileForm:{Title:'',/* Theme:'', */ClassifyId:''},//文档信息
       classifyOptions:[],//分类列表
       fileBlockArr:[],//文档段落列表
-      fileFormRules:{
-        Title: [
-          { required: true, message: "文档名称不能为空"}
-        ],
-        /* Theme:[
-          { required: true, message: "文档主题不能为空"}
-        ], */
-        ClassifyId:[
-          { required: true, message: "请选择文档分类"}
-        ]
-      },
+
       fileId:0,//为0时是新增 不为0时是文档id
     };
   },
@@ -143,7 +133,7 @@ export default {
     //删除一段
     deleteBlock(index){
       if(index===0&&this.fileBlockArr.length===1){
-        this.$message.warning('请至少保留一段')
+        this.$message.warning(this.$t('SemanticsManage.DocumentComparison.least_one_paragraph_msg') )
         return
       }
       this.fileBlockArr.splice(index,1)
@@ -154,7 +144,7 @@ export default {
       if(!this.checkBlock()) return
       //文章有内容
       if(!this.fileId&&!this.documentContent.length){
-        this.$message.warning('请输入文章内容')
+        this.$message.warning(this.$t('SemanticsManage.DocumentComparison.article_content_enter') )
         return
       }
       let flag = false
@@ -214,7 +204,7 @@ export default {
     checkBlock(){
       for(let i=0;i<this.fileBlockArr.length;i++){
         if(!this.fileBlockArr[i].innerText.length){
-          this.$message.warning('请输入段落内容')
+          this.$message.warning(this.$t('SemanticsManage.DocumentComparison.paragraph_content_ipt') )
           return false
         }
       }
@@ -226,11 +216,17 @@ export default {
     this.getFileData()
     this.getClassifyList()
   },
-  computed:{
-    ChineseEcnglish(){
-      return this.$t('SemanticsManage.DocumentComparison')
-    }
-  }
+  computed: {
+    fileFormRules() {
+      return {
+        Title: [{ required: true, message: this.$t('SemanticsManage.DocumentComparison.document_name_no_empty')  }],
+        /* Theme:[
+          { required: true, message: "文档主题不能为空"}
+        ], */
+        ClassifyId: [{ required: true, message: this.$t('SemanticsManage.DocumentManagement.select_document_category_msg')  }],
+      };
+    },
+  },
 };
 </script>
 <style lang="scss">

+ 14 - 18
src/views/semantics_manage/documentPage.vue

@@ -5,12 +5,12 @@
     <div class="catalog-wrap page-block-wrap catalog-block" id="left">
       <div class="btn-box">
         <el-button v-permission="permissionBtn.semanticPermission.docPage_save"
-            type="primary" @click="toPage('addFile')">{{ChineseEcnglish.add_document_btn}}</el-button>
+            type="primary" @click="toPage('addFile')">{{$t('SemanticsManage.DocumentManagement.add_document_btn')}}</el-button>
       </div>
       <div class="select-wrap">
         <el-select
           filterable remote
-          :placeholder="ChineseEcnglish.input_enter_fiel_content"
+          :placeholder="$t('SemanticsManage.DocumentManagement.input_enter_fiel_content')"
           v-model="searchTitle"
           :remote-method="searchHandle"
           value-key="SaDocId"
@@ -79,9 +79,10 @@
             alt=""
             style="width: 16px; height: 16px; margin-right: 6px"
           />
-          <span>{{ChineseEcnglish.add_category}}</span>
+          <span>{{$t('SemanticsManage.DocumentManagement.add_category')}}</span>
         </div>
-        <span class="total-text" v-if="selectNode&&model==='list'">共{{catalogList.length}}个文档</span>
+        <span class="total-text" v-if="selectNode&&model==='list'">
+          {{$t('SemanticsManage.DocumentManagement.all_num_document',{num:catalogList.length})}}</span>
       </div>
       <span class="move-btn resize" v-drag id="resize"></span>
     </div>
@@ -128,16 +129,16 @@
           </div>
         </draggable> -->
           <div class="empty" v-if="catalogList.length===0">
-            <tableNoData :text="ChineseEcnglish.prompt_slogan"/>
+            <tableNoData :text="$t('SemanticsManage.DocumentManagement.prompt_slogan')"/>
           </div>
       </div>
       <!-- 文件详情 -->
       <div class="detail-file" v-else>
         <div class="file-info">
           <ul>
-            <li class="name">{{ChineseEcnglish.document_name}}:{{docInfo.Title}}</li>
+            <li class="name">{{$t('SemanticsManage.DocumentManagement.document_name')}}:{{docInfo.Title}}</li>
             <!-- <li>文档主题:{{docInfo.Theme}}</li> -->
-            <li>{{ChineseEcnglish.document_category}}:{{docInfo.ClassifyName}}</li>
+            <li>{{$t('SemanticsManage.DocumentManagement.document_category')}}:{{docInfo.ClassifyName}}</li>
           </ul>
           <el-button v-permission="permissionBtn.semanticPermission.docPage_save"
             type="primary" @click="handleEdit('file',selectNode)">{{$t('Table.edit_btn')}}</el-button>
@@ -149,7 +150,7 @@
     </div>
     <!-- 添加/编辑分类弹窗 -->
     <el-dialog
-      :title="classifyForm.classify_id? ChineseEcnglish.edit_category : ChineseEcnglish.add_category "
+      :title="classifyForm.classify_id? $t('SemanticsManage.DocumentManagement.edit_category') : $t('SemanticsManage.DocumentManagement.add_category') "
       :visible.sync="isModifyClassifyShow"
       :close-on-click-modal="false"
       :modal-append-to-body="false"
@@ -166,11 +167,11 @@
           :model="classifyForm"
           :rules="classifyFormRules"
         >
-          <el-form-item label-width="118px" :label="ChineseEcnglish.add_category_name" prop="classify_name">
+          <el-form-item label-width="118px" :label="$t('SemanticsManage.DocumentManagement.add_category_name')" prop="classify_name">
             <el-input
               v-model="classifyForm.classify_name"
               style="width: 80%"
-              :placeholder="ChineseEcnglish.add_category_input_name"
+              :placeholder="$t('SemanticsManage.DocumentManagement.add_category_input_name')"
             />
           </el-form-item>
           <!-- 文档分类的封面图取消 -->
@@ -342,7 +343,7 @@ export default {
       //console.log('upload',e.file);
       //验证图片类型
       if(!['image/png','image/jpg','image/jpeg'].includes(e.file.type)){
-        this.$message.warning('请选择png、jpeg格式的图片')
+        this.$message.warning(this.$t('SemanticsManage.DocumentManagement.select_img_mag') )
         return
       }
       let form = new FormData()
@@ -356,7 +357,7 @@ export default {
     },
     checkImg(rule,value,callback){
       if(!this.classifyForm.classify_img){
-        return callback(new Error('分类图片不能为空'))
+        return callback(new Error(this.$t('SemanticsManage.DocumentManagement.img_no_empty_msg') ))
       }else{
         callback()
       }
@@ -388,7 +389,7 @@ export default {
                 {
                     level:2
             })
-            this.$message.success('移动成功')
+            this.$message.success(this.$t('ETable.Msg.move_success_msg') )
         })
     },
     //根据层级判断是否展示编辑/删除按钮
@@ -398,11 +399,6 @@ export default {
             :this.permissionBtn.isShowBtn('semanticPermission',`docPage_${btnType==='edit'?'save':btnType}`)
     }
   },
-  computed:{
-     ChineseEcnglish (){
-      return this.$t('SemanticsManage.DocumentManagement')
-     }
-  }
 };
 </script>
 

+ 17 - 15
src/views/semantics_manage/semantics/semanticsEditPage.vue

@@ -3,7 +3,7 @@
     <div class="semantics-tool page-block-wrap">
       <div class="tool-btn" @click="handleBtnClick({type:'search'})">
         <img :src="toolIcon['search']" />
-        {{ChineseEcnglish.search_btn}}
+        {{$t('SemanticsManage.DocumentComparison.search_btn')}}
       </div>
       <div class="tool-btns">
         <el-popover
@@ -21,13 +21,13 @@
           <div slot="reference" class="tool-btn" style="padding:0 30px !important;border-right: 1px solid #DCDFE6;"
             @click="handleBtnClick({type:'selectLabel'},isSelectLabelShow?'close':'open')">
             <img :src="toolIcon['eye']" style="width:14px,height:9px"/>
-             {{ChineseEcnglish.select_documents}}
+             {{$t('SemanticsManage.DocumentComparison.select_documents')}}
           </div>
         </el-popover>
         
         <div class="tool-btn" v-for="btn in toolBtnArr" :key="btn.type" @click="handleBtnClick(btn)">
-          <img :src="toolIcon[btn.icon]" :style="btn.icon==='eye'?{'width':'14px','height':'9px'}:{}"/>
-          {{btn.text}}
+          <img :src="toolIcon[btn.icon]" :style="btn.icon==='eye'?{'width':'14px','height':'9px'}:{}"/>          
+          {{getContentMenuOptText(btn.text)}}
         </div>
       </div>
     </div>
@@ -58,7 +58,7 @@
           v-for="(document,index) in showingFiles" :key="document.DocId">
           <div class="file-item-info">
             <p class="file-title">{{document.Title}}</p>
-            <p class="file-sub-info"><!-- <span style="margin-right:30px;">{{document.Theme}}</span> --><span>{{ChineseEcnglish.parent_directory}}:{{document.ClassifyName}}</span></p>
+            <p class="file-sub-info"><!-- <span style="margin-right:30px;">{{document.Theme}}</span> --><span>{{$t('SemanticsManage.DocumentComparison.parent_directory')}}:{{document.ClassifyName}}</span></p>
             <!-- <span class="close-btn" @click.stop="deleteCompareFile(document,index)"><i class="el-icon-circle-close"></i></span> -->
           </div>
           <div class="file-item-content" :id="`file-content-${index}`" 
@@ -242,23 +242,25 @@ export default {
   },
   computed:{
     toolBtnArr(){//操作栏
-      toolBtnArr[0].text = this.ChineseEcnglish.select_documents_comparison
-      toolBtnArr[1].text = this.$t('Dialog.confirm_save_btn')
+      toolBtnArr[0].text = '选择对比文档'
+      toolBtnArr[1].text = '保存'
       // toolBtnArr[2].text = this.select_documents_comparison
       //新增
       if(this.semanticId===0){
-        console.log(toolBtnArr);
         return this.compareFiles.length?toolBtnArr.slice(0,-1):[toolBtnArr[0]]
       }else{
         //编辑
         return toolBtnArr
       }
     },
-    ChineseEcnglish(){
-      return this.$t('SemanticsManage.DocumentComparison')
-    }
   },
   methods: {
+    getContentMenuOptText(e){
+      if(e==='选择对比文档') return this.$t('SemanticsManage.DocumentComparison.select_documents_comparison') 
+      if(e==='保存') return this.$t('Dialog.confirm_save_btn')
+      if(e==='另存为') return this.$t('Table.save_as')
+      return e
+    },
     //获取语义分析详情
     getSemanticData(){
       const {fileId} = this.$route.query
@@ -410,7 +412,7 @@ export default {
         })
         this.$nextTick(()=>{
             if(!CSS.highlights){
-                this.$message.warning('该浏览器不支持高亮效果,请切换至chrome浏览器105版本以上')
+                this.$message.warning(this.$t('SemanticsManage.DocumentComparison.chrome_version_msg') )
                 return
             }
             CSS.highlights&&CSS.highlights.set('show-result',new Highlight(...textAreaRange))
@@ -563,7 +565,7 @@ export default {
       //更新currentPageIndex
       const length = this.compareFiles.length
       if(length===1){
-        this.$message.warning(this.ChineseEcnglish.please_keep_least_one_document)
+        this.$message.warning(this.$t('SemanticsManage.DocumentComparison.please_keep_least_one_document'))
         return
       }
       if(this.currentPageIndex===length-1){
@@ -596,7 +598,7 @@ export default {
       }).then(async (res)=>{
         this.dialogLoading = false
         if(res.Ret!==200) return
-        const hintWord = this.saveType===0?'另存为成功':SaCompareId? this.$t('MsgPrompt.saved_msg') : this.$t('MsgPrompt.add_msg')
+        const hintWord = this.saveType===0?this.$t('SemanticsManage.DocumentComparison.save_as_success_msg') :SaCompareId? this.$t('MsgPrompt.saved_msg') : this.$t('MsgPrompt.add_msg')
         this.$message.success(`${hintWord}`)
         this.semanticId = res.Data.SaCompareId
         this.semanticInfo.SaCompareId = res.Data.SaCompareId
@@ -651,7 +653,7 @@ export default {
         ResultImg:res.Data.ResourceUrl
       }).then(res=>{
         if(res.Ret!==200) return 
-        this.$message.success('上传结果图片成功')
+        this.$message.success(this.$t('SemanticsManage.DocumentComparison.up_img_success_msg') )
         this.checkSemanticId('toList')
       })
     },

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 10 - 10
src/views/semantics_manage/semanticsPage.vue


+ 9 - 17
src/views/semantics_manage/tagPage.vue

@@ -3,8 +3,8 @@
   <div class="document-tag-page-wrap page-block-wrap">
     <div class="tool-box">
       <el-button v-permission="permissionBtn.semanticPermission.tagPage_save"
-        type="primary" @click="handleOperate('add',{})">{{ChineseEcnglish.add_tag_btn}}</el-button>
-      <el-input v-model="searchText" clearable prefix-icon="el-icon-search" :placeholder="ChineseEcnglish.input_content" @input="searchHandle"></el-input>
+        type="primary" @click="handleOperate('add',{})">{{$t('SemanticsManage.TagManagement.add_tag_btn')}}</el-button>
+      <el-input v-model="searchText" clearable prefix-icon="el-icon-search" :placeholder="$t('SemanticsManage.TagManagement.input_content')" @input="searchHandle"></el-input>
     </div>
     <div class="table-box">
       <el-table :data="tableData" border v-loading="tableLoading">
@@ -43,7 +43,7 @@
     </div>
     <!-- 添加标签弹窗 -->
     <el-dialog
-      :title="operate==='edit'? ChineseEcnglish.edit_tag_btn : ChineseEcnglish.add_tag_btn"
+      :title="operate==='edit'? $t('SemanticsManage.TagManagement.edit_tag_btn')  : $t('SemanticsManage.TagManagement.add_tag_btn') "
       :visible.sync="isAddTagShow"
       :close-on-click-modal="false"
       :modal-append-to-body="false"
@@ -54,9 +54,9 @@
     >
       <div class="dialog-container">
         <div class="input-item">
-          {{ChineseEcnglish.tag_name}}:<el-input  :placeholder="ChineseEcnglish.input_content" v-model.trim="currentData.LabelName" required ></el-input>
+          {{$t('SemanticsManage.TagManagement.tag_name')}}:<el-input  :placeholder="$t('SemanticsManage.TagManagement.input_content')" v-model.trim="currentData.LabelName" required ></el-input>
         </div>
-        <p class="form-hint">{{ChineseEcnglish.note_content}}</p>
+        <p class="form-hint">{{$t('SemanticsManage.TagManagement.note_content')}}</p>
       </div>
       <div class="foot-container">
         <el-button @click="isAddTagShow=false">{{ $t('Dialog.cancel_btn')}}</el-button>
@@ -65,7 +65,7 @@
     </el-dialog>
     <!-- 查看内容弹窗 -->
     <el-dialog
-      :title="ChineseEcnglish.tag_content"
+      :title="$t('SemanticsManage.TagManagement.tag_content')"
       :visible.sync="isContentDetailShow"
       :close-on-click-modal="false"
       :modal-append-to-body="false"
@@ -120,11 +120,11 @@ export default {
     async modifyTag(){
       const {SaLabelId,LabelName} = this.currentData
       if(!this.currentData.LabelName){
-        this.$message.warning(this.ChineseEcnglish.input_content)
+        this.$message.warning(this.$t('SemanticsManage.TagManagement.input_content'))
         return
       }
       if(this.currentData.LabelName.length>15){
-        this.$message.warning("标签名称过长,请重新编辑")
+        this.$message.warning(this.$t('SemanticsManage.TagManagement.tag_name_long_msg'))
         return
       }
       let res = null
@@ -162,7 +162,7 @@ export default {
       this.operate = operate
       if(operate==='delete'){
         this.$confirm(
-          '删除后不可恢复,是否确认删除该标签?',
+         this.$t('SemanticsManage.TagManagement.delete_tag_msg'),
           this.$t('Confirm.prompt'),
         {
           confirmButtonText: this.$t('Dialog.confirm_btn'),
@@ -205,9 +205,6 @@ export default {
     }
   },
   computed:{
-    ChineseEcnglish(){
-      return this.$t('SemanticsManage.TagManagement')
-    },
     columnList(){
         return [
           {
@@ -228,11 +225,6 @@ export default {
   mounted(){
     this.getTableData()
   },
-  created(){
-    // this.$nextTick(()=>{
-    //    this.ChineseEcnglish = 
-    // })
-  }
 };
 </script>
 

+ 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>

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно