Browse Source

Merge branch 'master' into eta2.0.0

Karsa 3 months ago
parent
commit
b9e407d5df
100 changed files with 10136 additions and 417 deletions
  1. 4 2
      src/api/api.js
  2. 21 1
      src/api/modules/chartApi.js
  3. 8 1
      src/api/modules/predictEdbApi.js
  4. 429 0
      src/api/modules/reportV2.js
  5. 210 1
      src/api/modules/semanticsApi.js
  6. 231 1
      src/api/modules/thirdBaseApi.js
  7. BIN
      src/assets/img/data_m/move_ico.png
  8. 1 0
      src/assets/img/icons/baseinfo_ico.svg
  9. 4 0
      src/assets/img/icons/preview_ico.svg
  10. 4 0
      src/assets/img/icons/publish_ico.svg
  11. 5 0
      src/assets/img/icons/save_ico.svg
  12. 4 0
      src/assets/img/icons/submit_ico.svg
  13. 4 0
      src/assets/img/icons/timing_ico.svg
  14. 14 0
      src/assets/img/icons/wx_round.svg
  15. 10 1
      src/components/lzTable.vue
  16. 0 1
      src/components/selectUnit.vue
  17. 51 3
      src/lang/commonLang.js
  18. 58 1
      src/lang/modules/DataSources/En.js
  19. 59 1
      src/lang/modules/DataSources/Zh.js
  20. 20 0
      src/lang/modules/EtaBase/En.js
  21. 20 0
      src/lang/modules/EtaBase/Zh.js
  22. 29 2
      src/lang/modules/EtaBase/commonLang.js
  23. 37 0
      src/lang/modules/EtaChart/En.js
  24. 34 0
      src/lang/modules/EtaChart/Zh.js
  25. 110 0
      src/lang/modules/EtaChart/commonLang.js
  26. 4 4
      src/lang/modules/ReportManagement/CategoryList.js
  27. 112 8
      src/lang/modules/ReportManagement/ReportList.js
  28. 4 4
      src/lang/modules/ReportManagement/SmartReport.js
  29. 27 0
      src/lang/modules/SemanticsManage/indexEn.js
  30. 28 0
      src/lang/modules/SemanticsManage/indexZh.js
  31. 17 0
      src/lang/modules/ToolBox/CommodityPriceChart.js
  32. 2 2
      src/lang/modules/systemManage/ReportApprove.js
  33. 5 2
      src/mixins/reportApproveConfig.js
  34. 8 0
      src/routes/modules/dataRoutes.js
  35. 28 16
      src/routes/modules/oldRoutes.js
  36. 17 1
      src/routes/modules/semanticsRoutes.js
  37. 7 0
      src/styles/global.scss
  38. 31 1
      src/utils/buttonConfig.js
  39. 12 0
      src/utils/common.js
  40. 1 1
      src/views/Login.vue
  41. 4 4
      src/views/approve_manage/approveDetail.vue
  42. 14 8
      src/views/approve_manage/approveEdit.vue
  43. 2 2
      src/views/approve_manage/components/flowNode/approveNode.vue
  44. 1 1
      src/views/approve_manage/mixins/approveMixins.js
  45. 7 5
      src/views/chartRelevance_manage/components/chartCard.vue
  46. 7 6
      src/views/chartRelevance_manage/crossVarietyAnalysis/chartEditor.vue
  47. 8 6
      src/views/chartRelevance_manage/mixins/classifyMixin.js
  48. 28 14
      src/views/classify_manage/chapterSettingV2.vue
  49. 1 0
      src/views/classify_manage/classifyEnlistV2.vue
  50. 137 28
      src/views/classify_manage/classifylistV2.vue
  51. 36 11
      src/views/dataEntry_manage/addChart.vue
  52. 48 11
      src/views/dataEntry_manage/chartSetting.vue
  53. 46 2
      src/views/dataEntry_manage/codecount/index.vue
  54. 180 0
      src/views/dataEntry_manage/components/addAverageDialog.vue
  55. 490 115
      src/views/dataEntry_manage/components/addMarkerDialog.vue
  56. 319 0
      src/views/dataEntry_manage/components/addRightEdbDialog.vue
  57. 9 1
      src/views/dataEntry_manage/components/barOptionSection.vue
  58. 3 2
      src/views/dataEntry_manage/components/chartReleationEdbTable.vue
  59. 245 3
      src/views/dataEntry_manage/components/markersSection.vue
  60. 27 4
      src/views/dataEntry_manage/components/setLangInfo.vue
  61. 15 2
      src/views/dataEntry_manage/databaseComponents/addTargetDiaBase.vue
  62. 1 1
      src/views/dataEntry_manage/databaseComponents/batchComputedV2.vue
  63. 10 7
      src/views/dataEntry_manage/databaseComponents/chartTrendRender.vue
  64. 1 1
      src/views/dataEntry_manage/databaseComponents/operationDialog.vue
  65. 48 5
      src/views/dataEntry_manage/editChart.vue
  66. 192 11
      src/views/dataEntry_manage/mixins/addOreditMixin.js
  67. 187 16
      src/views/dataEntry_manage/mixins/chartPublic.js
  68. 211 0
      src/views/dataEntry_manage/thirdBase/components/addIndicsDia.vue
  69. 2 2
      src/views/dataEntry_manage/thirdBase/components/batchAddEdbDia.vue
  70. 422 0
      src/views/dataEntry_manage/thirdBase/components/batchAddIndicsDia.vue
  71. 721 0
      src/views/dataEntry_manage/thirdBase/components/highFrequency/addHighFrequencyData.vue
  72. 473 0
      src/views/dataEntry_manage/thirdBase/components/highFrequency/addToIndexDatabaseBatch.vue
  73. 635 0
      src/views/dataEntry_manage/thirdBase/components/highFrequency/classifySetting.vue
  74. 1022 0
      src/views/dataEntry_manage/thirdBase/highFrequencyData.vue
  75. 44 9
      src/views/dataEntry_manage/thirdBase/steelChemicalbase.vue
  76. 1 1
      src/views/datasheet_manage/components/BalanceAddChart.vue
  77. 7 5
      src/views/datasheet_manage/components/BalanceSheetChartItem.vue
  78. 1 1
      src/views/datasheet_manage/components/MixedTable.vue
  79. 295 26
      src/views/futures_manage/chartEditor.vue
  80. 10 7
      src/views/futures_manage/commodityChartBase.vue
  81. 137 0
      src/views/futures_manage/components/xAxisSet.vue
  82. 39 13
      src/views/mychart_manage/components/chartDetailDia.vue
  83. 148 4
      src/views/ppt_manage/mixins/mixins.js
  84. 10 3
      src/views/ppt_manage/mixins/pptMixins.js
  85. 3 4
      src/views/ppt_manage/newVersion/components/catalog/transReport.vue
  86. 8 2
      src/views/ppt_manage/newVersion/pptCatalog.vue
  87. 7 5
      src/views/predictEdb_manage/addPredicEdb.vue
  88. 1 1
      src/views/predictEdb_manage/components/chartInfo.vue
  89. 7 5
      src/views/predictEdb_manage/components/edbDetail.vue
  90. 7 5
      src/views/predictEdb_manage/predictEdb.vue
  91. 1 1
      src/views/report_manage/addreportNew.vue
  92. 1 1
      src/views/report_manage/editChapterReport.vue
  93. 1 1
      src/views/report_manage/editreportNew.vue
  94. 1 1
      src/views/report_manage/reportAuthor.vue
  95. 869 0
      src/views/report_manage/reportV2/components/chapterEditWrapper.vue
  96. 201 0
      src/views/report_manage/reportV2/components/chooseCooperaUserDia.vue
  97. 195 0
      src/views/report_manage/reportV2/components/chooseInherReportDia.vue
  98. 585 0
      src/views/report_manage/reportV2/components/reportBaseInfoDia.vue
  99. 167 0
      src/views/report_manage/reportV2/components/reportEditHeader.vue
  100. 168 0
      src/views/report_manage/reportV2/components/reportPreview.vue

+ 4 - 2
src/api/api.js

@@ -19,7 +19,8 @@ import {
   coalWordInterface,
   bloombergInterface,
   ccfDataInterface,
-  windInterface
+  windInterface,
+  highFrequencyDataInterface
 } from './modules/thirdBaseApi';
 
 //手工指标 手工数据 手工数据权限
@@ -130,7 +131,8 @@ export {
   coalWordInterface,
   bloombergInterface,
   ccfDataInterface,
-  windInterface
+  windInterface,
+  highFrequencyDataInterface
 };
 
 //老接口 研报 ppt等

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

@@ -688,6 +688,15 @@ const dataBaseInterface = {
 		setChartImage: params => {
 			return http.post('/datamanage/chart_info/image/set',params)
 		},
+		/**
+		 * 设置图表缩略图 formData
+		 * @param {Img} string 
+		 * @param {Chartlnfold} number 
+		 * @returns 
+		 */
+		setChartThumbnail: params => {
+			return http.post('/datamanage/chart_info/image/set_by_svg',params)
+		},
 		/**
 		 * 通过unicode获取图表信息
 		 * @param {UniqueCode} params 
@@ -869,6 +878,9 @@ const dataBaseInterface = {
 	sectionScatterPreviewData: params => {
 		return http.post('/datamanage/chart_info/preview/time_section',params)
 	},
+	seasonPreviewData:params=>{
+		return http.post('/datamanage/chart_info/preview/season',params)
+	},
 
 	 /* 批量计算
 	 * @param {*} params 
@@ -981,7 +993,15 @@ const dataBaseInterface = {
 	saveEdbChartImg:(params)=>{
 		return http.post('/datamanage/edb_info/image/set',params)
 	},
-
+	/**
+	 * 设置图表缩略图 formData
+	 * @param {Number} EdbInfoId 
+	 * @param {String} Img 
+	 * @returns 
+	 */
+	saveEdbChartThumbnail:(params)=>{
+		return http.post('/datamanage/edb_info/image/set_by_svg',params)
+	},
 	/** 
 	 * 获取图表批量刷新结果
 	 * @param {Object} params

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

@@ -166,7 +166,14 @@ export const edbSearch = params => {
 export const setImg = params => {
 	return http.post('/datamanage/predict_edb_info/image/set',params)
 }
-
+/**
+ * 设置缩略图 formData
+ * @param {*} params EdbInfoId  Img
+ * @returns 
+ */
+export const setThumbnail = params => {
+	return http.post('/datamanage/predict_edb_info/image/set_by_svg',params)
+}
 /**
  * 指标刷新
  * @param {*} params EdbInfoId

+ 429 - 0
src/api/modules/reportV2.js

@@ -0,0 +1,429 @@
+//研报改版  一些接口复用以前的 一些新增的 都捞过来放一块
+import http from "@/api/http.js"
+
+
+/* 新增的接口 */
+export const reportV2Interface = {
+
+  /**
+   * 获取有权限的列表 
+   * @param {
+   *  CurrentIndex PageSize KeyWord ClassifyIdFirst ClassifyIdSecond ClassifyIdThird
+   * } params 
+   * @returns 
+   */
+  getAuthReportList: params => {
+    return http.get('/report/list/authorized',params)
+  },
+
+  /**
+   * 报告基础信息
+   * @param {*ReportId} params 
+   * @returns 
+   */
+  getRportBase: params => {
+    return http.get('/report/detail/base',params)
+  },
+
+  /**
+   * 修改章节基础信息
+   * @param {*} params 
+   * @returns 
+   */
+  editChapterBase: params => {
+    return http.post('/report/chapter/base_info/edit',params)
+  },
+
+  /**
+   * 章节拖动排序
+   * @param {*ReportChapterId PrevReportChapterId NextReportChapterId} params 
+   * @returns 
+   */
+  moveChapter: params => {
+    return http.post('/report/chapter/move',params)
+  },
+
+	/**
+	 * 删除章节
+	 * @param {*ReportChapterId} params 
+	 * @returns 
+	 */
+	removeChapter: params => {
+		return http.post('/report/chapter/del',params)
+	},
+
+	/**
+	 * 添加章节
+	 * 
+	 * @param {* Title  ReportId PermissionIdList AdminIdList} params 
+	 * @returns 
+	 */
+	addChapter: params => {
+		return http.post('/report/chapter/add',params)
+	},
+
+	/**
+	 * 上传章节音频
+	 * @param {*ReportChapterId File} params 
+	 * @returns 
+	 */
+	uploadChpterAudio: params => {
+		return http.post('/report/chapter/voice/upload',params)
+	},
+
+	/**
+	 * 校验所有章节是否发布
+	 * @param {*ReportId} params 
+	 * @returns 
+	 */
+	checkChaterPublishState: params => {
+		return http.get('/report/chapter/un_publish/list',params)
+	},
+
+	/**
+	 * 设置版图
+	 * @param {*ReportId HeadImg HeadResourceId EndImg EndResourceId CanvasColor} params 
+	 * @returns 
+	 */
+	setReportLayoutImg: params => {
+		return http.post('/report/layout_img/edit',params)
+	},
+
+	/**
+	 * 获取分类关联的品种列表
+	 * @param {*ClassifyId} params 
+	 * @returns 
+	 */
+	getClassifyPermissionList: params => {
+		return	http.get('/classify/permission/list',params)
+	},
+
+	/**
+	 * 保存章节标题 
+	 * @param {*ReportChapterId Title} params 
+	 * @returns 
+	 */
+	saveChapterTitle: params => {
+		return http.post('/report/chapter/title/edit',params)
+	}
+
+}
+
+
+const reportlist = params => { return http.get('/report/list',params); };  //获取报告列表
+
+const classifylist = params => { return http.get('/classify/list',params); };  //获取分类列表
+
+ const reportpublish = params => { return http.post('/report/publish',params); };  //批量发布报告
+ const reportpublishcancle = params => { return http.post('/report/publish/cancle',params); };  //取消发布报告
+ const voiceupload = params => { return http.post('/voice/upload',params); };  //上传音频
+ const resourceVoiceupload = params => { return http.post('/resource/voice/upload',params); };  //上传音频
+ const reportadd = params => { return http.post('/report/add',params); };  //新增报告
+ const reportedit = params => { return http.post('/report/edit',params); };  //编辑报告
+ const reportdelete = params => { return http.post('/report/delete',params); };  //删除报告
+ const reportdetail = params => { return http.get('/report/detail',params); };  //获取报告详情
+ const classifyIdDetail = params => { return http.get('/report/classifyIdDetail',params); };  //通过二级分类id获取报告详情
+ const sendTemplateMsg = params => { return http.post('/report/sendTemplateMsg',params); };  //推送消息
+ const reportauthor = params => { return http.get('/report/author',params); };  //获取作者
+ const getDraft = params => { return http.get('/report/getDraft',params); };  //获取草稿
+ const autosave = params => { return http.post('/report/saveReportContent',params); };  //保存
+ const reportSetPrepublish=params=>{return http.post('/report/pre_publish',params);};//报告设置定时发布
+
+ const classifyparent = params => { return http.get('/classify/parent',params); };  //获取父级分类
+ const classifyadd = params => { return http.post('/classify/add',params); };  //新增分类
+ const classifydelete = params => { return http.post('/classify/delete',params); };  //删除分类
+ const classifyedit = params => { return http.post('/classify/edit',params); };  //编辑分类
+ const checkDeleteClassify = params => { return http.get('/classify/checkDeleteClassify',params); };  //检测分类
+ const classifyTelList = params=>{return http.get('/classify/tel_list',params)};//电话会分类
+
+
+
+ /* 客群消息推送接口 */
+const messagePushPost= params => {
+	return http.post('/report/ths/sendTemplateMsg',params)
+}
+
+// 晨周报章节类型列表
+const dayWeekReportChapterList=params=>{
+	return http.get('/report/getDayWeekReportChapterTypeList',params)
+}
+
+//新增晨周报
+const addDayWeekReport=params=>{
+	return http.post('/report/addDayWeekReport',params)
+}
+
+//编辑晨周报
+const editDayWeekReport=params=>{
+	return http.post('/report/editDayWeekReport',params)
+}
+
+// 晨周报章节列表
+const dayWeekChapterList=params=>{
+	return http.get('/report/getReportChapterList',params)
+}
+
+//章节标签列表
+const chapterTrendTagList=()=>{
+	return http.get('/report/getChapterTrendTag',{})
+}
+
+//编辑章节标签
+const editChapterTrendTag=params=>{
+	return http.post('/report/editChapterTrendTag',params)
+}
+
+//晨报周报章节详情
+const chapterDetail=params=>{
+	return http.get('/report/getDayWeekChapter',params)
+}
+
+//晨报数据指标列表
+const dayTicketList=params=>{
+	return http.get('/report/getDayReportTickerList',params)
+}
+
+//保存晨报周报章节报告
+const saveChapterReport=params=>{
+	return http.post('/report/editDayWeekChapter',params)
+}
+
+//获取晨报/周报上一篇内容
+const getChapterReportBefore=params=>{
+	return http.get('/report/getLastDayWeekReportChapter',params)
+}
+
+//判断晨报周报当前章节是否为最后一篇发布的
+const getChapterReportIsLast=params=>{
+	return http.get('/report/isLastDayWeekReportChapter',params)
+}
+
+//发布晨报周报章节
+const publishChapterReport=params=>{
+	return http.post('/report/publishDayWeekReportChapter',params)
+}
+
+//发布晨报周报
+const publishDayOrWeekReport=params=>{
+	return http.post('/report/publishDayWeekReport',params)
+}
+
+//晨报周报更新暂停的时间
+const dayWeekPauseTime=params=>{
+	return http.get('/report/getDayWeekReportPauseTime',{})
+}
+
+//晨报周报设置更新规则
+const dayWeekUpdateRule=params=>{
+	return http.post('/report/setDayWeekReportUpdateRule',params)
+}
+
+// 周报校验音频
+const weekReportValidAudio=params=>{
+	return http.get('/report/CheckDayWeekReportChapterVideo',params)
+}
+
+
+const chapterQRCodeImg=params=>{
+	return http.post('/report/getSunCode',params)
+}
+
+/* 推送客户群设置 */
+// 获取待推送报告类型
+/**
+ * @returns 
+ * List - 报告类型列表
+ * 
+ */
+const getBeingPushedReportType=()=>{
+	return http.get('/yb/ths_send/report_type',{})
+}
+// 获取待推送列表
+/**
+ * 
+ * @param {
+ * Title 推送标题
+ * ReportType 内容类型
+ * CreateTimeStart 创建开始日期
+ * CreateTimeEnd 创建结束日期
+ * PushTimeStart 推送开始日期
+ * PushTimeEnd 推送结束日期
+ * PageSize 每页条数
+ * CurrentIndex 当前页数
+ * } params 
+ * @returns 
+ */
+const getBeingPushedReportList=params=>{
+	return http.get('/yb/ths_send/list',params)
+}
+// 设置推送时间
+/** 
+ * @param {
+ * SendId 序号
+ * PushTime 新的推送时间
+ * } params 
+ * @returns 
+ */
+const setPushingTime=params=>{
+	return http.post('/yb/ths_send/modify_push_time',params)
+}
+
+//研报标记状态
+/**
+ * 
+ * @param {
+ * Status 编辑状态
+ * ReportId 报告ID
+ * } params
+ * @returns 
+ */
+const markReport = params =>{
+  return http.post('/report/mark',params)
+}
+
+// 获取章节类型列表
+/**
+ * @param params.ReportType Enum-报告类型:day-晨报;week-周报
+ * @param params.PageSize Integer-每页条数
+ * @param params.CurrentIndex Integer-当前页数
+ * @returns 章节类型列表
+ */
+const getchapterTypeList=params=>{
+ return http.get('/report/chapter_type/list',params)
+}
+
+// 新增章节类型
+/**
+ * @param params.ReportChapterTypeName String-章节名称
+ * @param params.Sort Integer-排序
+ * @param params.ReportType Enum-报告类型:day-晨报;week-周报
+ * @param params.SelectedImage String-选中的icon
+ * @param params.UnselectedImage String-未选中的icon
+ * @param params.WordsImage String-带字的icon
+ * @param params.EditImgUrl String-后台-章节列表封面图
+ * @param params.IsShow Enum-小程序端是否展示:0-隐藏;1-显示
+ */
+const addChapterType=params=>{
+	return http.post('/report/chapter_type/add',params)
+ }
+
+ // 编辑章节类型
+/**
+ * @param params.ReportChapterTypeId Integer-章节ID
+ * @param params.ReportChapterTypeName String-章节名称
+ * @param params.Sort Integer-排序
+ * @param params.ReportType Enum-报告类型:day-晨报;week-周报
+ * @param params.SelectedImage String-选中的icon
+ * @param params.UnselectedImage String-未选中的icon
+ * @param params.WordsImage String-带字的icon
+ * @param params.EditImgUrl String-后台-章节列表封面图
+ * @param params.IsShow Enum-小程序端是否展示:0-隐藏;1-显示
+ */
+const editChapterType=params=>{
+	return http.post('/report/chapter_type/edit',params)
+ }
+ 
+// 删除章节
+/**
+ * @param params.ReportChapterTypeId Integer-章节ID
+ */
+const deleteChapterType=params=>{
+	return http.post('/report/chapter_type/del',params)
+}
+
+// 获取章节类型的权限列表
+/**
+ * @param params.ReportChapterTypeId Integer-章节ID
+ * @returns 权限列表
+ */
+const getchapterTPermissionList=params=>{
+	return http.get('/report/chapter_type/permission_list',params)
+ }
+
+// 设置章节类型的权限
+/**
+ * @param params.ReportChapterTypeId Integer-章节ID
+ * @param params.ChartPermissionIdList Array<Integer>-权限IDs
+ */
+const setchapterTPermission=params=>{
+	return http.post('/report/chapter_type/auth_setting',params)
+}
+
+//章节启用\禁用
+const setChapterEnable=params=>{
+	return http.post('/report/chapter_type/enabled/set',params)
+}
+
+//章节拖动排序
+const setChapterSort=params=>{
+	return http.post('/report/chapter_type/move',params)
+}
+
+// 同时推送客群和模板消息
+const reportMessageSend=params=>{
+	return http.post('/report/sendMsg',params)
+}
+
+// 中英文研报、智能研报转pdf和长图
+const report2PdfImg=params=>{
+	return http.post('/smart_report/get_pdf_url',params)
+}
+
+
+
+export {
+	reportlist,
+	reportpublish,
+	reportpublishcancle,
+	voiceupload,
+	resourceVoiceupload,
+	reportadd,
+	reportedit,
+	reportdelete,
+	reportdetail,
+	classifyIdDetail,
+	sendTemplateMsg,
+	reportauthor,
+	getDraft,
+	autosave,
+	reportSetPrepublish,
+	classifylist,
+	classifyparent,
+	classifyadd,
+	classifydelete,
+	classifyedit,
+	checkDeleteClassify,
+	messagePushPost,
+	dayWeekReportChapterList,
+	addDayWeekReport,
+	dayWeekChapterList,
+	chapterTrendTagList,
+	editChapterTrendTag,
+	editDayWeekReport,
+	chapterDetail,
+	dayTicketList,
+	saveChapterReport,
+	getChapterReportBefore,
+	getChapterReportIsLast,
+	publishChapterReport,
+	publishDayOrWeekReport,
+	dayWeekPauseTime,
+	dayWeekUpdateRule,
+	chapterQRCodeImg,
+  classifyTelList,
+	getBeingPushedReportType,
+	getBeingPushedReportList,
+	setPushingTime,
+  markReport,
+	getchapterTypeList,
+	addChapterType,
+	editChapterType,
+	deleteChapterType,
+	getchapterTPermissionList,
+	setchapterTPermission,
+	reportMessageSend,
+	weekReportValidAudio,
+	setChapterEnable,
+	setChapterSort,
+	report2PdfImg
+}

+ 210 - 1
src/api/modules/semanticsApi.js

@@ -516,5 +516,214 @@ const asrInterface = {
 }
 
 
+/* ai纪要 */
+const aiSummeryInterface = {
+  /**
+   * 获取纪要分类
+   * @param {*} params IsShowMe
+   * @returns 
+   */
+  getClassify: params => {
+    return http.get('/ai/summary/classify/list',params)
+  },
+
+  /**
+   * 新增纪要分类
+   * @param {*} params 
+   * "ClassifyName": "测试分类2",
+    "ParentId": 0,
+    "Level": 0
+   * @returns 
+   */
+  classifyAdd: params => {
+    return http.post('/ai/summary/classify/add',params)
+  },
+
+  /**
+   * 编辑纪要分类
+   * @param {*} params 
+   * "ClassifyName": "测试分类2",
+    "AiSummaryClassifyId": 1011 
+   * @returns 
+   */
+  classifyEdit: params => {
+    return http.post('/ai/summary/classify/edit',params)
+  },
+
+  /**
+   * 删除分类监测
+   * @param {*AiSummaryClassifyId} params 
+   * @returns 
+   */
+  classifyDelCheck: params => {
+    return http.post('/ai/summary/classify/delete/check',params)
+  },
+
+  /**
+   * 删除分类
+   * @param {*AiSummaryClassifyId} params 
+   * @returns 
+   */
+  classifyDel: params => {
+    return http.post('/ai/summary/classify/delete',params)
+  },
+
+  /**
+   * 移动分类
+   * @param {*} params 
+   * {
+      "AiSummaryClassifyId": 1015,
+      "AiSummaryId": 0,
+      "ParentClassifyId": 0,
+      "PrevId": 0,
+      "NextId": 1013,
+      "PrevType": 1,
+      "NextType": 1
+    }
+   * @returns 
+   */
+  classifyMove: params => {
+    return http.post('/ai/summary/classify/move',params)
+  },
+
+  /**
+   * 纪要搜索
+   * @param {*} params IsShowMe PageSize CurrentIndex KeyWord
+   * @returns 
+   */
+  summerySearch: params => {
+    return http.get('/ai/summary/list',params)
+  },
+
+  /**
+   * 提示词新增
+   * @param {* PromptContent Title} params 
+   * @returns 
+   */
+  promptAdd: params => {
+    return http.post('/ai/prompt/add',params)
+  },
+
+  /**
+   * 提示词编辑
+   * @param {*} params 
+   * "PromptContent": "提示词内容2",
+    "Title": "标题",
+    "AiPromptId": 637,
+   * @returns 
+   */
+  promptEdit: params => {
+    return http.post('/ai/prompt/edit',params)
+  },
+
+  /**
+   * 提示词删除
+   * @param {*AiPromptId} params 
+   * @returns 
+   */
+  promptDel: params => {
+    return http.post('/ai/prompt/delete',params)
+  },
+
+  /**
+   * 移动提示词
+   * @param {*} params 
+   * "AiPromptId": 638,
+    "PrevAiPromptId": 640,
+    "NextAiPromptId": 641
+   * @returns 
+   */
+  promptMove: params => {
+    return http.post('/ai/prompt/move',params)
+  },
+
+  /**
+   * 提示词详情
+   * @param {*AiPromptId} params 
+   * @returns 
+   */
+  promptDetail: params => {
+    return http.get('/ai/prompt/detail',params)
+  },
+
+  /**
+   * 我的提示词库
+   * @param {*} params 
+   * @returns 
+   */
+  getMyPromptClassify: params => {
+    return http.get('/ai/prompt/list',params)
+  },
+
+  /**
+   * 公共提示词库
+   * @param {*} params 
+   * @returns 
+   */
+  getPublicPromptClassify: params => {
+    return http.get('/ai/prompt/groups',params)
+  },
+
+  /**
+   * 设置提示词共享状态
+   * @param {*AiPromptId} params 
+   * @returns 
+   */
+  setPromptPublic: params => {
+    return http.post('/ai/prompt/share',params)
+  },
+
+  /**
+   * 生成结果
+   * @param {*} params 
+   * "AiChatTopicId": 307, 
+    "OriginContent": "", 
+    "OpenaiFileId": [
+    "cq73762tnn0umrare230"
+    ], 
+    "Prompt": "你是一名产品经理,分析下这张图", 
+    "Model": "Kimi" 
+   * @returns 
+   */
+  createAiSummery: params => {
+    return http.post('/ai/summary/generate',params)
+  },
+
+  /**
+   * 保存纪要
+   * @param {*} params 
+   *  "SaDocId": 0,
+      "OriginContent": "你是谁",
+      "SummaryContent": "我是一个人工智能,被训练来回答问题和提供帮助。虽然我没有个人身份或情感,但我会尽我所能为您提供有用的信息和支持。如果您有任何问题,请随时向我咨询!",
+      "ClassifyId": 1012,
+      "Title": "测试",
+      "Prompt": "",
+      "OpenaiFileName": "",
+      "OpenaiFilePath": ""
+   */
+  summerySave: params => {
+    return http.post('/ai/summary/add',params)
+  },
+
+  /**
+   * 纪要详情
+   * @param {*} params AiSummaryId
+   * @returns 
+   */
+  summeryDetail: params => {
+    return http.get('/ai/summary/detail',params)
+  },
+
+  /**
+   * 获取所有层级分类不包含纪要
+   * @param {*} params 
+   * @returns 
+   */
+  getSummeryAllClassify: params => {
+    return http.get('/ai/summary/classifyList',params)
+  }
+} 
+
+
 
-export {tagInterface,documentInterface,semanticInterface,asrInterface}
+export {tagInterface,documentInterface,semanticInterface,asrInterface,aiSummeryInterface}

+ 231 - 1
src/api/modules/thirdBaseApi.js

@@ -400,6 +400,62 @@ const steelInterface = {
 	 */
 	edbRefresh: params => {
 		return http.get('/datamanage/mysteel_chemical/refresh',params)
+	},
+	/**
+	 * 批量搜索指标
+	 * @param {Object} params 
+	 * @param {String} params.BaseFromMysteelChemicalClassifyIds 目录列表 用,隔开
+	 * @param {String} params.Keyword
+	 * @returns 
+	 */
+	searchEdbBatch:params=>{
+		return http.get('/datamanage/mysteel_chemical/batch_search',params)
+	},
+	/**
+	 * 重名检测
+	 * @param {Array} params 
+	 * @param {String} params[].EdbCode
+	 * @param {String} params[].EdbName
+	 * @param {String} params[].Frequency
+	 * @returns 
+	 */
+	batchCheckEdbName:params=>{
+		return http.post('/datamanage/mysteel_chemical/name_check',params)
+	},
+	/**
+	 * 添加检测
+	 * @param {Object} params 
+	 * @param {Object[]} params.IndexCodes  指标IDs
+	 * @returns 
+	 */
+	batchAddEdbCheck:params=>{
+		return http.post('/datamanage/mysteel_chemical/edb_info/add_check',params)
+	},
+	/**
+	 * 批量添加到指标库
+	 * @param {Array} params
+	 * @param {String} params[].EdbCode
+	 * @param {String} params[].EdbName
+	 * @param {String} params[].Unit
+	 * @param {Number} params[].ClassifyId 指标库的id
+	 * @param {String} params[].Frequency
+	 * @returns 
+	 */
+	batchAddToLib:params=>{
+		return http.post('/datamanage/mysteel_chemical/batch_add',params)
+	},
+	/**
+	 * 单个添加到指标库
+	 * @param {Object} params 
+	 * @param {String} params.EdbCode
+	 * @param {String} params.EdbName
+	 * @param {String} params.Unit
+	 * @param {String} params.Frequency
+	 * @param {Number} params.ClassifyId
+	 * @returns 
+	 */
+	AddToLib:params=>{
+		return http.post('/datamanage/mysteel_chemical/edb_info/add',params)
 	}
 }
 
@@ -1027,6 +1083,179 @@ const windInterface={
 	}
 }
 
+/* CCF化纤信息 */
+const highFrequencyDataInterface={
+	/**
+	 * 分类树
+	 * @param {} params 
+	 * @returns 
+	 */
+	classifyListTree: params => {
+		return http.get('/datamanage/ths_hf/classify/tree',params);
+	},
+	/**
+	 * 分类列表 懒加载
+	 * @param {} params ParentId
+	 * @returns 
+	*/
+	classifyList: params => {
+		return http.get('/datamanage/ths_hf/classify/list',params);
+	},
+	/**
+	 * 添加分类
+	 * @param {} params ClassifyName ParentId-第一级传0 Level-第一级传0, 其余传上一级的层级
+	 * @returns 
+	*/
+	classifyAdd: params => {
+		return http.post('/datamanage/ths_hf/classify/add',params);
+	},
+	/**
+	 * 编辑分类
+	 * @param {} params ClassifyId ClassifyName
+	 * @returns 
+	*/
+	classifyEdit: params => {
+		return http.post('/datamanage/ths_hf/classify/edit',params);
+	},
+	/**
+	 * 删除分类 ClassifyId
+	 */
+	classifyDelete: params => {
+		return http.post('/datamanage/ths_hf/classify/remove',params);
+	},
+	/**
+	 * 移动分类 
+	 * "ClassifyId": 0, //分类ID
+		"ParentClassifyId": 0, //父级分类ID
+		"PrevClassifyId": 0, //上一个兄弟节点分类ID
+		"NextClassifyId": 0, //下一个兄弟节点分类ID
+		"ItemId": 0, //指标ID, 如果指标ID有值,则移动对象为指标,否则认为移动对象为分类
+		"PrevItemId": 0, //上一个指标ID
+		"NextItemId": 0 //下一个指标ID
+	*/
+	classifyMove: params => {
+		return http.post('/datamanage/ths_hf/classify/move',params);
+	},
+	/**
+	 * 获取高频数据列表 
+	 * PageSize、CurrentIndex、ClassifyId(多选)、IncludeChild(是否关联子分类)、Frequency(多选)、SysAdminId(多选)、
+	 * Keywords、SortField、SortType
+	*/
+	getTableDataApi:params=>{
+		return http.get('/datamanage/ths_hf/index/list',params);
+	},
+	/**
+	 * 检验高频数据指标是否重复 
+	 * StockCode、EdbCode、StartTime、EndTime、Interval(number)、Fill、CPS、BaseDate
+	*/
+	checkHighFreData:params=>{
+		return http.get('/datamanage/ths_hf/index/exist_check',params);
+	},
+	/**
+	 * 搜索高频数据指标 
+	 * StockCode、EdbCode、StartTime、EndTime、Interval(number)、Fill、CPS、BaseDate
+	*/
+	searchHighFreData:params=>{
+		return http.get('/datamanage/ths_hf/index/search',params);
+	},
+	/**
+	 * 批量添加高频数据指标 
+	 * StartTime、EndTime、Interval(number)、Fill、CPS、BaseDate
+	 * IndexList:[{ClassifyId,StockCode,EdbCode,IndexName,Frequency,Unit}]
+	*/
+	addHighFreDatas:params=>{
+		return http.post('/datamanage/ths_hf/index/add',params);
+	},
+	/**
+	 * 高频数据详情
+	 * IndexId(number)、DataDate(数据日期(非必填,默认为有数据的最新日期))
+	*/
+	highFreDataDetail:params=>{
+		return http.get('/datamanage/ths_hf/index/detail',params);
+	},
+	/**
+	 * 高频数据编辑
+	 * IndexId(number)、IndexName、ClassifyId、Unit
+	*/
+	highFreDataEdit:params=>{
+		return http.post('/datamanage/ths_hf/index/edit',params);
+	},
+	/**
+	 * 高频数据刷新
+	 * IndexId(number)
+	*/
+	highFreDataRefresh:params=>{
+		return http.post('/datamanage/ths_hf/index/refresh',params);
+	},
+	/**
+	 * 高频数据删除
+	 * IndexId(number)
+	*/
+	highFreDataDelete:params=>{
+		return http.post('/datamanage/ths_hf/index/remove',params);
+	},
+	/**
+	 * 高频数据列表选择
+	 * ClassifyId IncludeChild Frequency SysAdminId Keywords ListIds SelectAll
+	*/
+	highFreDataChoice:params=>{
+		return http.get('/datamanage/ths_hf/index/list_choice',params);
+	},
+	/**
+	 * 批量操作
+	 * IndexIds(array) OptType(1-移动分类; 2-删除; 3-刷新) MoveClassifyId RefreshType(1-最近6小时; 2-全部刷新(操作为3时必填))
+	*/
+	highFreDataBatchOperation:params=>{
+		return http.post('/datamanage/ths_hf/index/multi_opt',params);
+	},
+	/**
+	 * 获取新增指标(批量新增前)
+	 * {
+		* IndexIds(array) 
+		* ConvertRule:{
+			*	ConvertType //转换类型: 1-指定时间值; 2-区间计算值
+			*	ConvertFixed:{
+					FixedDay, //指定时间值日期: 1-当日; 2-前一日
+					FixedTime
+				},
+				ConvertArea:{
+					StartDay, //起始时间日期: 1-当日; 2-前一日
+					StartTime,
+					EndDay,//截止时间日期: 1-当日; 2-前一日
+					EndTime,
+					CalculateType //计算类型: 1-区间均值; 2-最大值; 3-最小值
+				}
+		* }
+	 * }
+	*/
+	highFreDataSavePre:params=>{
+		return http.post('/datamanage/ths_hf/index/save2edb_pre',params);
+	},
+	/**
+	 * 批量新增指标
+	 * {
+		* NewIndexes(array) 
+		* ConvertRule:{
+			*	ConvertType //转换类型: 1-指定时间值; 2-区间计算值
+			*	ConvertFixed:{
+					FixedDay, //指定时间值日期: 1-当日; 2-前一日
+					FixedTime
+				},
+				ConvertArea:{
+					StartDay, //起始时间日期: 1-当日; 2-前一日
+					StartTime,
+					EndDay,//截止时间日期: 1-当日; 2-前一日
+					EndTime,
+					CalculateType //计算类型: 1-区间均值; 2-最大值; 3-最小值
+				}
+		* }
+	 * }
+	*/
+	highFreDataSave:params=>{
+		return http.post('/datamanage/ths_hf/index/save2edb',params);
+	},
+}
+
 export { 
 	lzDataInterface,
 	glDataInterface,
@@ -1046,5 +1275,6 @@ export {
 	coalWordInterface,
 	bloombergInterface,
 	ccfDataInterface,
-	windInterface
+	windInterface,
+	highFrequencyDataInterface
 }

BIN
src/assets/img/data_m/move_ico.png


File diff suppressed because it is too large
+ 1 - 0
src/assets/img/icons/baseinfo_ico.svg


+ 4 - 0
src/assets/img/icons/preview_ico.svg

@@ -0,0 +1,4 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M2.93819 5.46945V3.40708C2.93819 3.14802 3.14818 2.93806 3.40728 2.93806H5.46994C5.72904 2.93806 5.93903 2.72809 5.93903 2.46903C5.93903 2.20996 5.72904 2 5.46994 2H2.46909C2.20999 2 2 2.20996 2 2.46903V5.46945C2 5.72852 2.20999 5.93848 2.46909 5.93848C2.7265 5.93848 2.93819 5.72852 2.93819 5.46945ZM10.5334 2.93806H12.5927C12.8518 2.93806 13.0618 3.14802 13.0618 3.40708V5.46945C13.0618 5.72852 13.2718 5.93848 13.5309 5.93848C13.79 5.93848 14 5.72852 14 5.46945V2.46903C14 2.20996 13.79 2 13.5309 2H10.5334C10.2743 2 10.0644 2.20996 10.0644 2.46903C10.0644 2.72809 10.276 2.93806 10.5334 2.93806ZM5.46825 13.0603H3.40728C3.14818 13.0603 2.93819 12.8503 2.93819 12.5912V10.5322C2.93819 10.2732 2.7282 10.0632 2.46909 10.0632C2.20999 10.0632 2 10.2732 2 10.5322V13.5293C2 13.7883 2.20999 13.9983 2.46909 13.9983H5.46825C5.72735 13.9983 5.93734 13.7883 5.93734 13.5293C5.93734 13.2702 5.72735 13.0603 5.46825 13.0603ZM13.0618 10.5322V12.5929C13.0618 12.852 12.8518 13.0619 12.5927 13.0619H10.5334C10.2743 13.0619 10.0644 13.2719 10.0644 13.531C10.0644 13.79 10.2743 14 10.5334 14H13.5309C13.79 14 14 13.79 14 13.531V10.5339C14 10.2749 13.79 10.0649 13.5309 10.0649C13.2718 10.0632 13.0618 10.2732 13.0618 10.5322Z" fill="#0052D9"/>
+<path d="M8 5.59888C9.5061 5.59888 10.8019 6.58141 11.4093 8H12C11.3605 6.2408 9.81237 5 8 5C6.18931 5 4.64114 6.2408 4 8H4.59066C5.19815 6.58328 6.49558 5.59888 8 5.59888ZM8 10.4011C6.4939 10.4011 5.19815 9.41859 4.59066 8H4C4.64114 9.7592 6.18931 11 8 11C9.81069 11 11.3605 9.75733 12 8H11.4093C10.8035 9.41859 9.5061 10.4011 8 10.4011ZM6.56121 8C6.56121 8.88334 7.20572 9.60012 8 9.60012C8.79428 9.60012 9.43879 8.88334 9.43879 8C9.43879 7.11666 8.79428 6.39988 8 6.39988C7.20572 6.39988 6.56121 7.11666 6.56121 8ZM8.90029 8C8.90029 8.55209 8.49811 9.00125 8 9.00125C7.50358 9.00125 7.10139 8.55396 7.10139 8C7.10139 7.44791 7.50358 6.99875 8 6.99875C8.49811 7.00062 8.90029 7.44791 8.90029 8Z" fill="#0052D9"/>
+</svg>

+ 4 - 0
src/assets/img/icons/publish_ico.svg

@@ -0,0 +1,4 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M4.74769 17.4324C4.19134 17.4317 3.658 17.2233 3.2646 16.8528C2.8712 16.4823 2.64985 15.98 2.64908 15.4561C2.64908 14.3664 3.59054 13.4798 4.74769 13.4798H10.1965C10.2716 13.0217 10.4212 12.5773 10.6401 12.1622H7.85772L9.28769 8.59764C9.3011 8.58447 9.31451 8.55921 9.3285 8.53451C9.36916 8.46974 9.39556 8.39792 9.40613 8.32334C9.41669 8.24876 9.4112 8.17294 9.38999 8.1004C9.36877 8.02785 9.33226 7.96008 9.28264 7.90111C9.23301 7.84213 9.17129 7.79318 9.10115 7.75715C8.63788 7.50327 8.25371 7.13905 7.98725 6.70107C7.72079 6.26309 7.58142 5.76679 7.58315 5.26202C7.58315 3.68204 8.94142 2.40346 10.6063 2.40346C12.2835 2.40346 13.6411 3.69357 13.6411 5.27464C13.6405 5.77884 13.5002 6.27415 13.2342 6.71171C12.9682 7.14927 12.5857 7.51396 12.1243 7.76978C12.0975 7.78185 12.0707 7.79448 12.0573 7.81918C11.8183 7.99486 11.7512 8.30778 11.9115 8.55921C11.9244 8.58447 11.9506 8.60862 11.964 8.63388L12.5983 10.2122C12.9629 10.0179 13.3529 9.86893 13.7583 9.76917L13.2162 8.43405C13.6411 8.12561 13.9983 7.74225 14.2678 7.30534C14.6541 6.68603 14.8562 5.98024 14.8531 5.26202C14.8564 4.73596 14.7487 4.21452 14.5361 3.72802C14.3236 3.24153 14.0104 2.79968 13.6149 2.42816C12.8157 1.66343 11.7512 1.25005 10.6063 1.25005C10.0467 1.24751 9.49211 1.35043 8.97532 1.55276C8.45853 1.75508 7.98994 2.05273 7.59714 2.42816C6.80253 3.18152 6.3573 4.20072 6.35896 5.26257C6.35896 5.97734 6.55891 6.69212 6.94424 7.30588C7.22405 7.74507 7.58315 8.13375 8.00987 8.44722L6.50819 12.1622H4.74769C4.28837 12.1622 3.83354 12.2474 3.40918 12.4129C2.98482 12.5785 2.59924 12.8211 2.27445 13.127C1.94966 13.4328 1.69202 13.7959 1.51625 14.1956C1.34047 14.5952 1.25 15.0235 1.25 15.4561C1.25 15.8887 1.34047 16.317 1.51625 16.7166C1.69202 17.1163 1.94966 17.4794 2.27445 17.7852C2.59924 18.0911 2.98482 18.3337 3.40918 18.4993C3.83354 18.6648 4.28837 18.75 4.74769 18.75H15C13.7211 18.7511 12.4932 18.2778 11.5822 17.4324H4.74769Z" fill="#0052D9"/>
+<path d="M14.3747 10C12.0124 10 10 11.6502 10 13.7503C10 15.7751 11.9252 17.5 14.3747 17.5C16.8248 17.5 18.75 15.8504 18.75 13.7503C18.75 11.6502 16.7376 10 14.3747 10ZM16.3871 13.3004H14.9002V16.225H13.9376V13.3004H12.4501L14.3747 11.2003L16.3871 13.3004Z" fill="#0052D9"/>
+</svg>

+ 5 - 0
src/assets/img/icons/save_ico.svg

@@ -0,0 +1,5 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M14.7723 1.1297C15.0455 1.3226 15.0776 1.6633 14.8429 1.88887L10.1474 6.41202C10.0917 6.4657 10.0237 6.50979 9.94727 6.54177C9.87088 6.57375 9.78761 6.593 9.70221 6.59842C9.61681 6.60383 9.53095 6.59531 9.44954 6.57334C9.36813 6.55137 9.29276 6.51637 9.22773 6.47036C9.1627 6.42434 9.10929 6.3682 9.07054 6.30514C9.0318 6.24209 9.00848 6.17335 9.00192 6.10285C8.99535 6.03236 9.00568 5.96148 9.0323 5.89428C9.05891 5.82708 9.10131 5.76486 9.15705 5.71118L13.8535 1.18804C13.9092 1.13434 13.9772 1.09024 14.0536 1.05825C14.13 1.02625 14.2133 1.007 14.2987 1.00158C14.3841 0.996165 14.47 1.00469 14.5514 1.02667C14.6328 1.04866 14.7082 1.08366 14.7732 1.1297H14.7723Z" fill="#0052D9"/>
+<path d="M3.01946 1.00082C2.48401 1.00082 1.97047 1.21872 1.59177 1.60661C1.21307 1.9945 1.00021 2.52063 1 3.0693V12.9299C0.999896 13.2017 1.05205 13.4709 1.15349 13.722C1.25493 13.9732 1.40367 14.2014 1.59121 14.3936C1.77874 14.5859 2.0014 14.7384 2.24646 14.8424C2.49153 14.9464 2.7542 15 3.01946 15H11.9789C12.2443 15.0002 12.5071 14.9468 12.7522 14.843C12.9974 14.7391 13.2203 14.5867 13.4079 14.3945C13.5956 14.2023 13.7445 13.9741 13.8461 13.723C13.9477 13.4718 14 13.2026 14 12.9307V5.63025C14 5.4805 13.9419 5.33689 13.8386 5.23101C13.7353 5.12512 13.5951 5.06563 13.449 5.06563C13.3028 5.06563 13.1627 5.12512 13.0594 5.23101C12.956 5.33689 12.898 5.4805 12.898 5.63025V12.9307C12.898 13.4501 12.4866 13.8708 11.9797 13.8708H3.02026C2.77687 13.8708 2.54343 13.7718 2.37126 13.5955C2.19908 13.4192 2.10224 13.1801 2.10203 12.9307V3.07012C2.10203 2.54994 2.51261 2.12923 3.01946 2.12923H11.1355C11.2817 2.12923 11.4218 2.06974 11.5251 1.96386C11.6285 1.85797 11.6865 1.71436 11.6865 1.56461C11.6865 1.41487 11.6285 1.27126 11.5251 1.16537C11.4218 1.05949 11.2817 1 11.1355 1H3.01946V1.00082Z" fill="#0052D9"/>
+<path d="M3.52554 5C3.38626 5 3.25268 5.05824 3.1542 5.16191C3.05571 5.26558 3.00038 5.40619 3.00038 5.5528C3.00038 5.69941 3.05571 5.84002 3.1542 5.94369C3.25268 6.04736 3.38626 6.1056 3.52554 6.1056H6.25562C6.3949 6.1056 6.52848 6.04736 6.62697 5.94369C6.72545 5.84002 6.78078 5.69941 6.78078 5.5528C6.78078 5.40619 6.72545 5.26558 6.62697 5.16191C6.52848 5.05824 6.3949 5 6.25562 5H3.52554ZM3 8.4996C3 8.19466 3.23509 7.9472 3.52554 7.9472H6.88506C7.02434 7.9472 7.15791 8.00544 7.2564 8.10911C7.35489 8.21278 7.41022 8.35339 7.41022 8.5C7.41022 8.64661 7.35489 8.78722 7.2564 8.89089C7.15791 8.99456 7.02434 9.0528 6.88506 9.0528H3.52554C3.4565 9.0529 3.38811 9.03867 3.32431 9.0109C3.2605 8.98314 3.20253 8.9424 3.15371 8.89101C3.10488 8.83962 3.06618 8.77859 3.0398 8.71142C3.01343 8.64426 2.9999 8.57228 3 8.4996ZM3.52554 10.8944C3.38626 10.8944 3.25268 10.9526 3.1542 11.0563C3.05571 11.16 3.00038 11.3006 3.00038 11.4472C3.00038 11.5938 3.05571 11.7344 3.1542 11.8381C3.25268 11.9418 3.38626 12 3.52554 12H9.47484C9.61412 12 9.7477 11.9418 9.84618 11.8381C9.94467 11.7344 10 11.5938 10 11.4472C10 11.3006 9.94467 11.16 9.84618 11.0563C9.7477 10.9526 9.61412 10.8944 9.47484 10.8944H3.52554Z" fill="#0052D9"/>
+</svg>

+ 4 - 0
src/assets/img/icons/submit_ico.svg

@@ -0,0 +1,4 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M9 3V5H10V2.5C10 2.22386 9.77614 2 9.5 2H1.5C1.22386 2 1 2.22386 1 2.5V13.5C1 13.7761 1.22386 14 1.5 14H9.5C9.77614 14 10 13.7761 10 13.5V11H9V13H2V3H9Z" fill="#0052D9"/>
+<path d="M11.2316 5.25423L13.4774 7.50001L5.99994 7.49999L5.99994 8.49999L13.4774 8.50001L11.2316 10.7458L11.9387 11.4529L15.038 8.35356C15.2333 8.1583 15.2333 7.84172 15.038 7.64646L11.9387 4.54712L11.2316 5.25423Z" fill="#0052D9"/>
+</svg>

+ 4 - 0
src/assets/img/icons/timing_ico.svg

@@ -0,0 +1,4 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M9.375 5V10.4862L12.5003 13.75L13.3842 12.8661L10.625 9.96839V5H9.375Z" fill="#0052D9"/>
+<path d="M18.75 10C18.75 14.8325 14.8325 18.75 10 18.75C5.16751 18.75 1.25 14.8325 1.25 10C1.25 5.16751 5.16751 1.25 10 1.25C14.8325 1.25 18.75 5.16751 18.75 10ZM17.5 10C17.5 5.85786 14.1421 2.5 10 2.5C5.85786 2.5 2.5 5.85786 2.5 10C2.5 14.1421 5.85786 17.5 10 17.5C14.1421 17.5 17.5 14.1421 17.5 10Z" fill="#0052D9"/>
+</svg>

+ 14 - 0
src/assets/img/icons/wx_round.svg

@@ -0,0 +1,14 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_6030_16278)">
+<path d="M6.23633 7.52735C6.23633 7.70094 6.30529 7.86743 6.42804 7.99018C6.55079 8.11293 6.71728 8.18189 6.89087 8.18189C7.06447 8.18189 7.23096 8.11293 7.35371 7.99018C7.47646 7.86743 7.54542 7.70094 7.54542 7.52735C7.54542 7.35375 7.47646 7.18727 7.35371 7.06451C7.23096 6.94176 7.06447 6.8728 6.89087 6.8728C6.71728 6.8728 6.55079 6.94176 6.42804 7.06451C6.30529 7.18727 6.23633 7.35375 6.23633 7.52735Z" fill="#50B674"/>
+<path d="M9.16357 7.50904C9.16357 7.68263 9.23253 7.84912 9.35529 7.97187C9.47804 8.09462 9.64452 8.16358 9.81812 8.16358C9.99172 8.16358 10.1582 8.09462 10.281 7.97187C10.4037 7.84912 10.4727 7.68263 10.4727 7.50904C10.4727 7.33544 10.4037 7.16896 10.281 7.0462C10.1582 6.92345 9.99172 6.85449 9.81812 6.85449C9.64452 6.85449 9.47804 6.92345 9.35529 7.0462C9.23253 7.16896 9.16357 7.33544 9.16357 7.50904Z" fill="#50B674"/>
+<path d="M10.7998 10.4365C10.7998 10.557 10.8477 10.6726 10.9329 10.7579C11.0182 10.8431 11.1338 10.891 11.2543 10.891C11.3749 10.891 11.4905 10.8431 11.5758 10.7579C11.661 10.6726 11.7089 10.557 11.7089 10.4365C11.7089 10.3159 11.661 10.2003 11.5758 10.1151C11.4905 10.0298 11.3749 9.98193 11.2543 9.98193C11.1338 9.98193 11.0182 10.0298 10.9329 10.1151C10.8477 10.2003 10.7998 10.3159 10.7998 10.4365Z" fill="#50B674"/>
+<path d="M13.1089 10.4726C13.1089 10.5932 13.1568 10.7088 13.242 10.794C13.3273 10.8793 13.4429 10.9272 13.5634 10.9272C13.684 10.9272 13.7996 10.8793 13.8848 10.794C13.9701 10.7088 14.018 10.5932 14.018 10.4726C14.018 10.3521 13.9701 10.2364 13.8848 10.1512C13.7996 10.066 13.684 10.0181 13.5634 10.0181C13.4429 10.0181 13.3273 10.066 13.242 10.1512C13.1568 10.2364 13.1089 10.3521 13.1089 10.4726Z" fill="#50B674"/>
+<path d="M10 0C4.47273 0 0 4.47273 0 10C0 15.5273 4.47273 20 10 20C15.5273 20 20 15.5273 20 10C20 4.47273 15.5273 0 10 0ZM8.29091 12.3091C7.76364 12.3091 7.34545 12.2 6.81818 12.0909L5.34545 12.8182L5.76364 11.5636C4.70909 10.8364 4.09091 9.89091 4.09091 8.72727C4.09091 6.72727 5.98182 5.16364 8.29091 5.16364C10.3455 5.16364 12.1636 6.41818 12.5273 8.10909C12.4 8.09091 12.2545 8.09091 12.1273 8.09091C10.1273 8.09091 8.56364 9.58182 8.56364 11.4182C8.56364 11.7273 8.61818 12.0182 8.69091 12.2909C8.54545 12.2909 8.41818 12.3091 8.29091 12.3091ZM14.4364 13.7818L14.7455 14.8364L13.6 14.2C13.1818 14.3091 12.7636 14.4182 12.3455 14.4182C10.3455 14.4182 8.78182 13.0545 8.78182 11.3818C8.78182 9.70909 10.3455 8.34545 12.3455 8.34545C14.2364 8.34545 15.9091 9.70909 15.9091 11.3818C15.9091 12.3091 15.2909 13.1455 14.4364 13.7818Z" fill="#50B674"/>
+</g>
+<defs>
+<clipPath id="clip0_6030_16278">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>

+ 10 - 1
src/components/lzTable.vue

@@ -22,6 +22,11 @@
 									: frequencyMap.get(data[item])
 								: data[item] 
 							}}
+							<span v-if="item==='Opt'&&$route.path==='/steelChemical'&&data['IndexCode'] ">
+								<el-button type="text" @click.stop="$emit('addToLib',data)"
+									v-if="!data.EdbInfoId&&permissionBtn.isShowBtn('dataSourcePermission','mysteelData_addEdb')"
+								>{{$t('ManualEdbListPage.add_tobase_btn')}}</el-button>
+							</span>
 						</template>
 					</template>
 					<!-- 百川盈孚数据源 频度和单位需要可编辑 -->
@@ -87,6 +92,9 @@ export default {
 				arr=['IndexName','IndexCode','FrequencyName','UnitName','UpdateTime']
 			}else if(this.source === 'glhg'){
 				arr=['IndexName','IndexCode','FrequencyName','UnitName','UpdateTime','IsStop']
+				if(this.$route.path==='/steelChemical'){
+					arr.push('Opt')
+				}
 			}else if(sourceTypeOne.includes(this.source)){
 				arr=['IndexName','IndexCode','Frequency','Unit','ModifyTime']
 			}
@@ -118,7 +126,8 @@ export default {
 					['FrequencyName', this.$t('Edb.Detail.e_fre')],
 					['UnitName', this.$t('Edb.Detail.e_unit')],
 					['UpdateTime', this.$t('Edb.Detail.e_update_time')],
-					['IsStop',this.$t('Edb.Detail.e_status')]
+					['IsStop',this.$t('Edb.Detail.e_status')],
+					['Opt',this.$t('Table.column_operations')],
 				])
 			}else if(sourceTypeOne.includes(this.source)){
 				temMap=new Map([

+ 0 - 1
src/components/selectUnit.vue

@@ -53,7 +53,6 @@ export default {
         value:{
             handler(){
                 if(this.value){
-                    console.log('value',this.value)
                     this.unit = this.getUnitTrans(this.value)
                 }
             },

+ 51 - 3
src/lang/commonLang.js

@@ -68,7 +68,11 @@ export default {
     complete_btn: {
       en: 'Complete',
       zh: '完成'
-    }
+    },
+    operation_prompt: {
+      en: 'Operation Prompt',
+      zh: '操作提示'
+    },
   },
   Table: {
     add_btn: {
@@ -91,6 +95,14 @@ export default {
       en: "Copy",
       zh: "复制",
     },
+    detail_btn:{
+      en: "Detail",
+      zh: "详情",
+    },
+    refresh_btn:{
+      en: "Refresh",
+      zh: "刷新",
+    },
     column_operations: {
       en: "Operations",
       zh: "操作",
@@ -196,6 +208,10 @@ export default {
       en: "Entry Successful",
       zh: "录入成功",
     },
+    submit_msg: {
+      en: "Submit Successful",
+      zh: "提交成功",
+    },
     delete_info_msg: {
       en: "Are you sure you want to permanently delete this file?",
       zh: "删除后不可恢复,是否确认删除?",
@@ -228,6 +244,10 @@ export default {
       en: "Delete failed",
       zh: "删除失败",
     },
+    add_fail_msg: {
+      en: "Failed to add new",
+      zh: "新增失败",
+    },
     known: {
       en: "Known",
       zh: "知道了",
@@ -319,7 +339,15 @@ export default {
     request_frequency:{
       zh:'请求频繁,请数据加载完成后再试!',
       en:'Request frequency, please try again after the data is loaded!'
-    }
+    },
+    please_complete:{
+      en: 'Please fill it out completely',
+      zh: '请填写完整'
+    },
+    name_none: {
+      zh: '名称不能为空',
+      en: 'Name can not be empty'
+    },
   },
   Common: {
     category: {
@@ -378,6 +406,10 @@ export default {
       en: 'No Charts',
       zh: '暂无图表'
     },
+    no_cont_msg: {
+      en: 'No Content',
+      zh: '暂无内容'
+    },
     exp_excel: {
       en: ' Export Excel',
       zh: '导出excel',
@@ -417,7 +449,23 @@ export default {
     sim_hei:{
       en:'SimHei',
       zh:'黑体'
-    }
+    },
+    latest:{
+      en:'latest',
+      zh:'最新'
+    },
+    fixed:{
+      en:'fixed',
+      zh:'固定'
+    },  
+    yes_text: {
+      en: 'Yes',
+      zh: '是'
+    },
+    no_text: {
+      en: 'No',
+      zh: '否'
+    },
   },
   Edb,
   Chart,

+ 58 - 1
src/lang/modules/DataSources/En.js

@@ -107,6 +107,7 @@ export default {
   /* 钢联化工数据库 */
   SteelChemicalPage: {
     add_edb_btn: 'Add indicator',
+    batch_add_edb_btn:'Batch Add to Indicator Library',
     add_classify_btn: 'Add Category',
     refresh_one_btn:'One-click Update',
     del_edb_msg:'After deletion, this indicator cannot be referenced. Are you sure you want to delete it?',
@@ -128,8 +129,12 @@ export default {
     ph_edbid:'Indicator ID can not be empty',
     ph_classify:'Affiliated Category can not be empty',
     add_loading_msg:'The loading time is approximately five minutes; closing the popup will not affect the loading process',
-    add_max_msg: 'The number of additions has reached the upper limit (upper limit 100)!',
+    add_max_msg: 'The number of additions has reached the upper limit (upper limit 150)!',
     ph_classify_name: 'Please select a category name',
+    batch_add_max_msg:'The number of indicators added in batch does not exceed 30',
+    batch_add_hint1:'Some indicators are incomplete. Please check',
+    batch_add_hint2:'Some indicator names already exist. Please enter a new one',
+    batch_add_placeholder:'Place select Indicator category',
   },
 
   /* un数据页面 */
@@ -233,6 +238,58 @@ export default {
     add_edb_hint:'Max 30 indicators for bulk add!',
     add_edb_check_hint1:'Incomplete Indicator Info',
     add_edb_check_hint2:'Indicator name exists, please re-enter'
+  },
+
+  /* 高频数据 */
+  HighFrequencyData:{
+    add_high_frequency_data:'Add High-Freqcy Data',
+    select_classify_prompt:'Please select category',
+    associative_sub_classify:'Linked to Subcategory',
+    classify_setting:'Classification Settings',
+    add_to_eta_indicators:'Add to ETA Indicators',
+    batch_operation:'Batch Operation',
+    data_source_classify:'Data Source Classification',
+    data_date: 'Date of data',
+    belong_to_classify:'Category',
+    period:'Period',
+    adjustment:'Adjustment',
+    base_point:"Base Point",
+    no_interval_handle:'Non-Trading Interval',
+    move_to_new_classify:'Move to new classification',
+    last_six_hours:'The last 6 hours',
+    refresh_all:'Full refresh (Choose carefully, or it may exceed the quota)',
+
+    data_transformation: "Data Transformation",
+    edb_save:'Indicator Saving',
+    get_point_time:'Value at a Specified Time',
+    today:'Current Day',
+    yesterday:'Previous day',
+    get_range_time:'Interval Calculation',
+    range_average_value:'Interval Average',
+    range_max_value:'Maximum Value',
+    range_min_value:'Minimum Value',
+
+    stock_code_numer_prompt:'The total number of stock codes does not exceed 10.',
+    index_code_numer_prompt:'The total number of indicator codes does not exceed 20.',
+    start_time_right_end_time:'The start time cannot be greater than the deadline.',
+    batch_operation_limit:'The upper limit of batch operation is 500 indicators.',
+    index_has_exist_prompt:'The following indicator names are duplicated with the existing indicators in the indicator library. Please modify the indicator name and confirm.',
+    indicator_been_referenced_prompt:'The indicator has been referenced.',
+
+    no_rehabilitation:'No',
+    forward_rehabilitation_1:'Pre-restoration rights (calculation of dividend plan)',
+    backward_rehabilitation_1:'Post-restoration rights (calculation of dividend plan)',
+    forward_rehabilitation_3:'Pre-restoration rights (calculation of exchange price)',
+    backward_rehabilitation_3:'Post-restoration rights (calculation of exchange price)',
+    forward_rehabilitation_2:'Pre-restoration rights for full circulation (calculation of dividend plan)',
+    backward_rehabilitation_2:'Post-restoration rights for full circulation (calculation of dividend plan)',
+    forward_rehabilitation_4:'Pre-restoration rights for full circulation (calculation of exchange pricen)',
+    backward_rehabilitation_4:'Post-restoration rights for full circulation (calculation of exchange price)',
+
+    original:'Original',
+    previous:'Previous',
+    blank:'Blank',
+
   }
   
 }

+ 59 - 1
src/lang/modules/DataSources/Zh.js

@@ -108,6 +108,7 @@ export default {
   /* 钢联化工数据库 */
   SteelChemicalPage: {
     add_edb_btn: '新增指标',
+    batch_add_edb_btn:'批量加入指标库',
     add_classify_btn: '添加分类',
     refresh_one_btn:'一键更新',
     del_edb_msg:'删除后该指标不能被引用,确认删除吗?',
@@ -127,8 +128,14 @@ export default {
     ph_edbid:'指标ID不能为空',
     ph_classify:'所属分类不能为空',
     add_loading_msg:'加载时间大概五分钟,关闭弹窗不影响加载',
-    add_max_msg: '添加数量已达上限(上限100)!',
+    add_max_msg: '添加数量已达上限(上限150)!',
     ph_classify_name: '请选择分类名称',
+    batch_add_max_msg:'批量添加指标数量不超过30个',
+    batch_classify_msg:'请选择指标',
+    batch_add_hint1:'部分指标信息未填写完整,请检查',
+    batch_add_hint2:'部分指标名称已存在,请重新填写',
+    batch_add_placeholder:'请选择指标库目录',
+
   },
 
   /* un数据页面 */
@@ -235,5 +242,56 @@ export default {
     add_edb_hint:'批量添加指标数量不得超过30个!',
     add_edb_check_hint1:'指标信息未填写完整',
     add_edb_check_hint2:'指标名称已存在,请重新填写'
+  },
+
+  /* 高频数据 */
+  HighFrequencyData:{
+    add_high_frequency_data:'添加高频数据',
+    select_classify_prompt:'请选择分类',
+    associative_sub_classify:'关联子分类',
+    classify_setting:'分类设置',
+    add_to_eta_indicators:'批量添加到指标库',
+    batch_operation:'批量操作',
+    data_source_classify:'数据源分类',
+    data_date: '数据日期',
+    belong_to_classify:'所属分类',
+    period:'时间周期',
+    adjustment:"复权方式",
+    base_point:"复权基点",
+    no_interval_handle:'非交易间隔处理',
+    move_to_new_classify:'移动至新分类',
+    last_six_hours:'最近6个小时',
+    refresh_all:'全部刷新(慎选,或超出额度)',
+
+    data_transformation: "数据转换",
+    edb_save:'指标保存',
+    get_point_time:'取指定时间的值',
+    today:'当日',
+    yesterday:'前一日',
+    get_range_time:'区间计算值',
+    range_average_value:'区间均值',
+    range_max_value:'最大值',
+    range_min_value:'最小值',
+
+    stock_code_numer_prompt:'证券代码总数不超过10个',
+    index_code_numer_prompt:'指标代码总数不超过20个',
+    start_time_right_end_time:'起始时间不能大于截止时间',
+    batch_operation_limit:'批量操作的上限为500个指标',
+    index_has_exist_prompt:'以下指标名称与指标库已有指标重复,请修改指标名称后确定',
+    indicator_been_referenced_prompt:'指标已被引用',
+
+    no_rehabilitation:'不复权',
+    forward_rehabilitation_1:'前复权(分红方案计算)',
+    backward_rehabilitation_1:'后复权(分红方案计算)',
+    forward_rehabilitation_3:'前复权(交易所价格计算)',
+    backward_rehabilitation_3:'后复权(交易所价格计算)',
+    forward_rehabilitation_2:'全流通前复权(分红方案计算)',
+    backward_rehabilitation_2:'全流通后复权(分红方案计算)',
+    forward_rehabilitation_4:'全流通前复权(交易所价格计算)',
+    backward_rehabilitation_4:'全流通后复权(交易所价格计算)',
+
+    original:'不处理',
+    previous:'沿用之前数据',
+    blank:'空值',
   }
 }

+ 20 - 0
src/lang/modules/EtaBase/En.js

@@ -29,13 +29,16 @@ export default {
     date_serie: 'Date Series',
     stock_input_pholder: 'Please enter the stock code, only one stock code can be queried at a time',
     edb_input_pholder: 'Please enter the indicator codes, separated by commas for multiple indicator codes',
+    stocks_input_pholder: 'Please enter the stock codes, separated by commas for multiple stock codes',
     edb_wind_tip: 'When entering "CG" in the Wind Financial Terminal, a code generator will pop up, which can be used to obtain codes for other indicators',
     edb_ifind_tip: 'Use Excel iFind plug-in / date series function, according to the selected indicator to obtain the indicator code, futures and stock common code can be ticked below',
     future_common_edb: 'Future Common indicators',
     stock_common_edb: 'Stock Common indicators',
+    option_selectable:'Parameter (Optional)',
     pre_price: 'Previous Closing Price',
     op_price: 'Opening Price',
     high_price: 'Highest Price',
+    average_price: 'Average Price',
     low_price: 'Lowest Price',
     close_price: 'Closing Price',
     settle_price: 'Settlement Price',
@@ -165,6 +168,7 @@ export default {
     table_col_creator:'Creator',
     label_all_check:'Select All List',
     full_metric_name:'Full Metric Name',
+    origin_full_metric_name:'Full name of the original indicator',
     add_to_selections:'Add to Selections',
     serial_num:'Serial Number',
     search_value_days_options:'Search Nearest Value Within 35 Days Before and After',
@@ -209,6 +213,22 @@ export default {
     field_instru: '*Field Description',
     res_show_col1: 'Date',
     res_show_col2: 'Value',
+    opt_tip_btn:'Operation instruction',
+    opt_tip_btn_text:`<div>1. Enter the code in the code input box to invoke the index library indicators for analysis and calculation. After running, output the analysis results:</div>
+    <div>2. Click on the index information, select the data source and search for the index ID/index name, then display the table structure where the index is located, and you can copy and fetch the index code with one click:</div>
+    <div>3. Add a line of code at the end of the calculation for formatted output, where "raw" is the data after final calculation (fill in with actual variable names):</div>
+    <div>result = format_data(raw, "data_time", "value")</div>
+    <div>4. Here is a runnable code example (the code to fetch index data needs to be replaced according to the system query):</div>
+    <br />
+    <div># Fetching Index Data Code:</div>
+    <div>sql1 = f'""'SELECT data_time,\`value\` FROM edb_data_ths WHERE edb_code = 'S004414853' ;'""'</div>
+    <div>raw = pandas_fetch_all(sql1, db)</div>
+    <div># Index Calculation Method Code:</div>
+    <div>raw['value'] = raw['value'] + 1</div>
+    <div># Date Format Conversion Code:</div>
+    <div>raw['data_time'] = raw['data_time'].apply(lambda x: x.strftime("%Y-%m-%d"))</div>
+    <div># Print Calculation Result Code:</div>
+    <div>result = format_data(raw, "data_time", "value")</div>`
   },
 
   /* 数据调整页面 */

+ 20 - 0
src/lang/modules/EtaBase/Zh.js

@@ -29,14 +29,17 @@ export default {
     date_serie: '日期序列',
     stock_input_pholder: '请输入证券代码,每次只查询一个证券代码',
     edb_input_pholder: '请输入指标代码,多个指标代码用英文逗号分隔',
+    stocks_input_pholder: '请输入证券代码,多个证券代码用英文逗号分隔',
     edb_wind_tip: 'wind金融终端输入”CG“会弹出代码生成器,可在代码生成器上获取其他指标的代码',
     edb_ifind_tip: '可用Excel同花顺插件/日期序列功能,根据所选指标获取指标代码,期货和股票常用代码可在下方勾选',
     future_common_edb: '期货常用指标',
     stock_common_edb: '股票常用指标',
+    option_selectable:'参数(可选)',
     pre_price: '前收盘价',
     op_price: '开盘价',
     high_price: '最高价',
     low_price: '最低价',
+    average_price: '均价',
     close_price: '收盘价',
     settle_price: '结算价',
     trade_volume: '成交量',
@@ -165,6 +168,7 @@ export default {
     table_col_creator:'创建人',
     label_all_check:'列表全选',
     full_metric_name:'指标全称',
+    origin_full_metric_name:'原指标全称',
     add_to_selections:'加入已选指标',
     serial_num:'序号',
     search_value_days_options:'查找前后35天最近值',
@@ -210,6 +214,22 @@ export default {
     field_instru: '*字段说明',
     res_show_col1: '日期',
     res_show_col2: '值',
+    opt_tip_btn:'操作说明',
+    opt_tip_btn_text:`<div>1、在代码输入框中输入代码,可调用指标库指标进行分析计算,运行后输出分析结果;</div>
+    <div>2、点击指标信息,选择数据来源并检索指标ID/指标名称后,展示指标所在表结构,可一键复制调取指标代码;</div>
+    <div>3、代码运算的最后需要加一行代码用于格式化输出,其中raw是最后计算后的数据(变量名以实际名填写):</div>
+    <div>result = format_data(raw, "data_time", "value")</div>
+    <div>4、以下是可运行的代码示例(其中调取指标数据代码需根据系统查询替换):</div>
+    <br />
+    <div>#调取指标数据代码:</div>
+    <div>sql1 = f'""'SELECT data_time,\`value\` FROM edb_data_ths WHERE edb_code = 'S004414853' ;'""'</div>
+    <div>raw = pandas_fetch_all(sql1, db)</div>
+    <div>#指标计算方式代码:</div>
+    <div>raw['value'] = raw['value'] + 1</div>
+    <div>#日期格式转化代码:</div>
+    <div>raw['data_time'] = raw['data_time'].apply(lambda x: x.strftime("%Y-%m-%d"))</div>
+    <div>#打印运算结果代码:</div>
+    <div>result = format_data(raw, "data_time", "value")</div>`
   },
 
   /* 数据调整页面 */

+ 29 - 2
src/lang/modules/EtaBase/commonLang.js

@@ -204,6 +204,10 @@ export default {
       zh:'起始时间',
       en:'Start Time'
     },
+    e_deadline_time: {
+      zh:'截止时间',
+      en:'Deadline'
+    },
     e_end_time: {
       zh: '结束时间',
       en: 'End Time'
@@ -236,9 +240,21 @@ export default {
       zh:'最近更新',
       en:'Recent Update'
     },
+    e_start_time_whole:{
+      zh:'指标开始时间',
+      en:'Indicator Start Time'
+    },
+    e_latest_time_whole:{
+      zh:'指标最新时间',
+      en:'Indicator Latest Time'
+    },
     e_stock_code: {
       zh:'证券代码',
-      en:' Security Code'
+      en:'Security Code'
+    },
+    e_indicator_code: {
+      zh:'指标代码',
+      en:'Indicator Code'
     },
     e_opera: {
       zh:'操作',
@@ -280,6 +296,10 @@ export default {
       zh:'所属目录',
       en:'catalogue'
     },
+    calculation_mode:{
+      zh:'计算方式',
+      en:'Calculation Method'
+    },
   },
 
   /* 单位 */
@@ -736,6 +756,10 @@ export default {
       zh: '请选择日期',
       en: 'Please select date'
     },
+    input_time: {
+      zh: '请选择时间',
+      en: 'Please select time'
+    },
     select_edb_name:{
       zh: '请选择指标名称',
       en: 'Please select an indicator name'
@@ -763,8 +787,11 @@ export default {
     input_value: {
       zh: '请输入值',
       en: 'Please input a value'
+    },
+    select_creator: {
+      zh: '请选择创建人',
+      en: 'Please select creator'
     }
-    
   },
   
   /* 公示说明 */

+ 37 - 0
src/lang/modules/EtaChart/En.js

@@ -28,6 +28,13 @@ export default {
       1、If the start date is earlier than the end date, the default is not to cross the year, and you can check the check box to cross the year.</br>
       2、If the start date is later than or equal to the end date, it will cross the year and the check is not allowed.
     `,
+    dynamic_time_tip:`
+    <p>Purpose: To set a dynamically updating end time based on the system date or the latest date of the indicator.</p>
+    <p> For example, the end of the last month, this "end of the month" will dynamically update as the latest date is updated. </p>
+    <p>Method: 1. Select the base date. The default is the system date (the current natural date), or you can choose the latest date of the indicator (which updates with the indicator).</p>
+    <p> On the premise of choosing the latest date of the indicator, you can perform period shifting, assuming a shift of 1 period, then select the date of the previous period of the indicator.</p> 
+    <p>2. Based on the base date, you can perform date transformations. The transformation methods include date displacement and specified frequency, which can be freely combined.</p>
+    <p> The default is to specify a frequency (the first day of the current month) plus a date transformation (-1 day), which means to provide the end date of the last month. </p>`,
     label_cross_year:'Cross the year',
     label_legend_set:'Legend Name Settings',
     no_set_msg: 'No configuration available',
@@ -51,6 +58,10 @@ export default {
     edit_plotline_btn: 'Edit Marker Line',
     edit_plotarea_btn: 'Edit Marker Area',
     add_intro_btn: 'Add Chart Description',
+    add_right_edb_btn:'Add Right Axis',
+    limits_btn:'Limits Area',
+    avg_line_btn:'Average Line',
+    std_btn:'StdEV Area',
     label_select_serie:'Select axis',
     label_select_seris_placeholder:'Please select the date axis',
     label_line_scale:'Marker line position',
@@ -67,6 +78,32 @@ export default {
     section_pos_top: 'Top',
     section_pos_center: 'Center',
     section_pos_bot: 'Bottom',
+    right_edb_type_on_year:'Left Axis Year-on-Year',
+    right_edb_type_lib:'Indicator Library',
+    right_edb_type_pred:'Predictive Indicators',
+    right_edb_gen_style:'Generate Style',
+    right_edb_gen_column:'Column',
+    right_edb_gen_mark:'Mark Point',
+    right_edb_mark_shape:'Mark Point Shape',
+    right_edb_color_set:'Color and transparency',
+    right_edb_mark_size:'Mark Point Size',
+    right_edb_legend:'Legend Name',
+    right_edb_format:'Number Format',
+    right_edb_format_per:'Percent',
+    right_edb_format_dec:'Decimal',
+    right_edb_mark_connect_text:'Mark Point Line',
+    right_edb_mark_connected:'Connected',
+    right_edb_mark_not_connected:'Not Connected',
+    right_edb_mark_connect_line_color:'Line Color',
+    right_edb_mark_connect_line_style:'Line Style',
+    right_edb_mark_connect_line_width:'Line Width',
+    limit_range:'Range of Limits',
+    average_range:'Range of Average',
+    std_range:'Range of STDEV',
+    year_placeholder:'Please enter year',
+    linewidth_placeholder:'Please enter line width',
+    multiple_placeholder:'Please enter the multiple',
+    year_on_right:'Year On Year(Right Axis)',
 
     //截面散点图区域
     label_serie_set:'Series {index} Configuration',

+ 34 - 0
src/lang/modules/EtaChart/Zh.js

@@ -28,6 +28,10 @@ export default {
       1、若开始日期小于结束日期,则默认不跨年,允许勾选跨年</br>
       2、若开始日期大于等于结束日期,则跨年,不允许取消勾选
     `,
+    dynamic_time_tip:`<p>配置目的:根据系统日期或者指标最新日期,设置一个动态更新的结束时间。比如上个月的月末,这个“月末”会随着最新日期的更新而动态更新。</p>
+    <p>配置方法:1、选择基准日期。默认选则系统日期(当前的自然日期),也可选指标最新日期(跟随指标的更新而更新)。在选择指标最新日期的前提下,可进行期数前移,假设前移1期,则选择指标上一期的日期。</p>
+    <p>2、根据基准日期,可进行日期变换。变换方式有日期位移和指定频率两种,可自由组合。默认给出指定频率(当月第一天)加日期变换(-1天),意味着给出上个月的月末日期。</p>
+    <p>配置示例:把起始日期设置在指标最新日期所在年份上一年的年末。基准日期选则指标最新日期,日期变换添加指定频率为当年第一天,再添加日期位移为-1。</p>`,
     label_cross_year:'跨年',
     label_legend_set:'图例名称设置',
     no_set_msg: '暂无配置',
@@ -51,6 +55,10 @@ export default {
     edit_plotline_btn: '编辑标识线',
     edit_plotarea_btn: '编辑标识区',
     add_intro_btn: '添加图表说明',
+    add_right_edb_btn:'添加右轴指标',
+    limits_btn:'同期上下限',
+    avg_line_btn:'同期均线',
+    std_btn:'同期标准差',
     label_select_serie:'选择坐标轴',
     label_select_seris_placeholder:'请选择日期坐标轴',
     label_line_scale:'标识线所在刻度',
@@ -67,6 +75,32 @@ export default {
     section_pos_top: '顶部',
     section_pos_center: '居中',
     section_pos_bot: '底部',
+    right_edb_type_on_year:'左轴指标同比',
+    right_edb_type_lib:'指标库',
+    right_edb_type_pred:'预测指标',
+    right_edb_gen_style:'生成样式',
+    right_edb_gen_column:'柱形',
+    right_edb_gen_mark:'标记点',
+    right_edb_mark_shape:'标记点形状',
+    right_edb_color_set:'颜色及透明度',
+    right_edb_mark_size:'标记点大小',
+    right_edb_legend:'图例名称',
+    right_edb_format:'数字格式',
+    right_edb_format_per:'百分数',
+    right_edb_format_dec:'小数',
+    right_edb_mark_connect_text:'标记点连线',
+    right_edb_mark_connected:'有',
+    right_edb_mark_not_connected:'无',
+    right_edb_mark_connect_line_color:'连线颜色',
+    right_edb_mark_connect_line_style:'连线线型',
+    right_edb_mark_connect_line_width:'连线粗细',
+    limit_range:'上下限取数范围',
+    average_range:'均线取数范围',
+    std_range:'取数范围',
+    year_placeholder:'请输入年份',
+    linewidth_placeholder:'请输入线宽',
+    multiple_placeholder:'请输入倍数',
+    year_on_right:'同比(右轴)',
 
     //截面散点图区域
     label_serie_set:'系列{index}配置',

+ 110 - 0
src/lang/modules/EtaChart/commonLang.js

@@ -56,6 +56,10 @@ export default {
     zh: '农历',
     en: 'Lunar Calendar'
   },
+  calendar_lunar_text: {
+    zh: '春节对齐',
+    en: 'Lunar Calendar'
+  },
   chart_share_btn:{
     zh:'分享',
     en:'Share'
@@ -456,7 +460,113 @@ export default {
     text_size: {
       zh:'字号',
       en:'Size'
+    },
+    chart_first_edb:{
+        zh:'图上第一个指标',
+        en:'The first indicator on the graph'
+    },
+    chart_other_edb:{
+        zh:'其他指标',
+        en:'Other indicator',
+    },
+    time_interval:{
+        zh:'时间区间',
+        en:'Time Interval'
+    },
+    follow_chart:{
+        zh:'跟随图表',
+        en:'follow the chart'
+    },
+    custom:{
+        zh:'自定义',
+        en:'custom'
+    },
+    plot_style:{
+        zh:'样式',
+        en:'style'
+    },
+    plot_calculation:{
+        zh:'计算方式',
+        en:'Calculation'
+    },
+    cal_range_val:{
+        zh:'区间',
+        en:'Range'
+    },
+    cal_range_mean:{
+        zh:'均值',
+        en:'Mean'
+    },
+    cal_range_plus:{
+        zh:'加',
+        en:'Plus'
+    },
+    cal_range_times:{
+        zh:'倍',
+        en:'times'
+    },
+    cal_range_times2:{
+        zh:'倍数',
+        en:'times'
+    },
+    cal_range_std:{
+        zh:'标准差',
+        en:'STDEV'
+    },
+    cal_range_count:{
+        zh:'个数',
+        en:'Count'
+    },
+    cal_range_value:{
+        zh:'数值',
+        en:'Value'
+    },
+    cal_range_quantile:{
+        zh:'分位',
+        en:'Quantile'
+    },
+    time_base:{
+        zh:'基准日期',
+        en:'Base Date'
+    },
+    sys_time:{
+        zh:'系统日期',
+        en:'System Date'
+    },
+    edb_new_time:{
+        zh:'指标最新日期',
+        en:'Indicator Latest Date'
+    },
+    edb_periods:{
+        zh:'期数',
+        en:'periods'
+    },
+    edb_periods_lead:{
+        zh:'前移',
+        en:' forward lead'
+    },
+    edb_period:{
+        zh:'期',
+        en:'periods'
+    },
+    edb_time_fix:{
+        zh:'固定',
+        en:'Fix'
+    },
+    edb_time_now:{
+        zh:'至今',
+        en:'So Far'
+    },
+    edb_time_dyn:{
+        zh:'动态',
+        en:'Dynamic'
+    },
+    pass_year:{
+        zh:'过去',
+        en:'pass'
     }
+
+
   },
 
   /* form校验 */

+ 4 - 4
src/lang/modules/ReportManagement/CategoryList.js

@@ -104,8 +104,8 @@ export const CategoryListEn = {
     section_settings: "Section Settings",
     add_section: "Add Section",
     edit_section: "Edit Section",
-    section_name: "Section Name",
-    section_name_hint: "Enter Section Name",
+    section_name: "Section Type",
+    section_name_hint: "Enter Section Type",
     parent_category: "Parent Category",
     parent_none: "none",
     related_variety: "Related Variety",
@@ -225,8 +225,8 @@ export const CategoryListZh = {
     section_settings: "章节设置",
     add_section: "添加章节",
     edit_section: "编辑章节",
-    section_name: "章节名称",
-    section_name_hint: "请输入章节名称",
+    section_name: "章节类型",
+    section_name_hint: "请输入章节类型",
     parent_category: "上级分类",
     parent_none:'无',
     related_variety: "关联品种",

+ 112 - 8
src/lang/modules/ReportManagement/ReportList.js

@@ -24,8 +24,8 @@ export const ReportListEn = {
   information_title: "Basic information",
   new_report_radio: "New report",
   inherit_report_radio: "Inherit report",
-  please_select_category: "Please select a category",
-  input_title_please: "Please input title",
+  please_select_category: "Please select a Report category",
+  input_title_please: "Please input Report title",
   please_input_abstract: "Please input abstract",
   please_select_author: "Please select the author",
   please_select_frequency: "Please select the frequency",
@@ -36,10 +36,12 @@ export const ReportListEn = {
   no_reports_msg: "There are currently no reports for this category",
   chart_insertion_progress: "Batch chart insertion in progress",
   last_save_time: "Last save time",
+  click_clear_btn: "Clear Content",
   click_refresh_btn: "Rfrsh",
   preview_btn: "Preview",
   save_draft_btn: "Draft",
   scheduled_publish_btn: "Schedule",
+  submit_chapter_btn:'Submit Section',
   publish_btn: "Publish",
   submission_btn: "Submission",
   new_method_btn: "New method",
@@ -57,7 +59,7 @@ export const ReportListEn = {
   intercommodity_analysis_radio: "Cross-Comm",
   just_mine_radio: "Just Mine",
   insert_sandbox_tabs: "Insert Sandbox",
-  no_reports_msg: "Sandbox Name/Commodity",
+  no_sandbox_msg: "Sandbox Name/Commodity",
   insert_table_tabs: "Insert Table",
   table_name_tabs: "Table Name",
   bulk_insertion_tabs: "My gallery batch insert",
@@ -87,7 +89,7 @@ export const ReportListEn = {
   img_uplaod_title: "Image Upload",
   click_img_upload: "Click to Upload Image",
   select_img_card: "Select Image",
-  img_name_ipt: "Please input image name",
+  img_name_ipt: "Please input layout name",
   select_img_type: "Please select an image type",
   page_header_op: "Page Header",
   page_trailer_op: "Page Trailer",
@@ -105,6 +107,7 @@ export const ReportListEn = {
   recorded_audio: "The recording has been uploaded.",
   not_recorded_audio: "The recording has not been uploaded.",
   weChat_share: "WeChat share",
+  copy_share_link:'Copy Link',
   set_tags_title: "Set tags",
   select_ipt_pld: "Enter or select",
   input_email_subject: "Please input email subject",
@@ -120,6 +123,55 @@ export const ReportListEn = {
   upload_img_error_msg: "Some images have not finished uploading, please wait.",
   all_update_publish_msg: "This report's varieties have all been updated. Clicking 'Publish' will also release the weekly report. Are you sure you want to publish both simultaneously?",
   is_publish_report_msg: "You have not uploaded an audio recording file yet. Are you sure you want to publish the report?",
+
+
+
+  tab_public:'Public Research Report',
+  tab_share:'Shared Research Report',
+  tab_mine:'My Research Report',
+  /* 添加报告弹窗 */
+  label_add_way:'Addition Method',
+  label_report_tit:'Report Title',
+  choose_inherit_report: 'Select Inherited Report',
+  label_report_classify:'Report Category',
+  label_relation_variety: 'Associated Varieties',
+  label_report_abstract:'Report Abstract',
+  label_report_author:'Report Author',
+  label_frequency:'Frequency',
+  label_createtime:'CreateTime',
+  label_coop:'Collaboration Method',
+  choose_cooper:'Select Collaborators',
+  coop_own: 'Individual',
+  coop_more: 'Collaborative (Multiple People)',
+  label_report_layout:'Report Layout',
+  layout_default:'Standard Layout',
+  layout_smart:'Intelligent Layout',
+  label_public:'Public Release',
+
+  tit_report_chap:'Research Report Section',
+  btn_add_chap: 'Add Section',
+  /* 添加章节弹窗 */
+  label_chap_name:'Section Name',
+  label_chap_editor:'Editor',
+  tit_choose_inher:'Select Report',
+  ph_report_tit: 'Please input the report title',
+  check_report_len: 'Only one report can be selected',
+  ph_select_user: 'Please select user',
+  del_chapter_msg: 'Are you sure you want to delete this section?',
+  report_empty_msg:'Please input the report content',
+  img_set_btn: 'Layout Settings',
+  no_chapter_msg:'No section information available',
+  chapter_nosubmit_msg:'{name},the content of the section has not been submitted',
+
+  choose_head_img:'Select Header',
+  choose_end_img:'Select Footer',
+  canvas_set:'Canvas Settings',
+  choose_layout_img:'Select Layout',
+  variety_tip:`If a section is associated with a variety, then the reading permissions for the section are controlled by the permissions of the associated variety;<br>
+  If a section is not associated with any variety, then the reading permissions for the section are controlled by the permissions of the category-associated varieties;`,
+  chapter_has_submit:'Submitted',
+  chapter_no_submit:'Not Submitted',
+  choose_msg: 'Choose'
 };
 
 /* 中文 */
@@ -144,8 +196,8 @@ export const ReportListZh = {
   information_title: "基础信息",
   new_report_radio: "新增报告",
   inherit_report_radio: "继承报告",
-  please_select_category: "请选择分类",
-  input_title_please: "请输入标题",
+  please_select_category: "请选择报告分类",
+  input_title_please: "请输入报告标题",
   please_input_abstract: "请输入摘要",
   please_select_author: "请选择作者",
   please_select_frequency: "请选择频度",
@@ -156,10 +208,12 @@ export const ReportListZh = {
   no_reports_msg: "此分类暂无报告",
   chart_insertion_progress: "图表批量插入中...",
   last_save_time: "最近保存时间",
+  click_clear_btn: "一键清空内容",
   click_refresh_btn: "一键刷新",
   preview_btn: "预览",
   save_draft_btn: "存草稿",
   scheduled_publish_btn: "定时发布",
+  submit_chapter_btn:'提交章节',
   publish_btn: "发布",
   submission_btn: "提交",
   new_method_btn: "新增方式",
@@ -178,7 +232,7 @@ export const ReportListZh = {
   intercommodity_analysis_radio: "跨品种分析",
   just_mine_radio: "只看我的",
   insert_sandbox_tabs: "沙盘插入",
-  no_reports_msg: "沙盘名称/品种",
+  no_sandbox_msg: "沙盘名称/品种",
   insert_table_tabs: "表格插入",
   table_name_tabs: "表格名称",
   bulk_insertion_tabs: "我的图库批量插入",
@@ -208,7 +262,7 @@ export const ReportListZh = {
   img_uplaod_title: "图片上传",
   click_img_upload: "点击上传图片",
   select_img_card: "选择图片",
-  img_name_ipt: "请输入图名称",
+  img_name_ipt: "请输入图名称",
   select_img_type: "请选择图片类型",
   page_header_op: "版头",
   page_trailer_op: "版尾",
@@ -226,6 +280,7 @@ export const ReportListZh = {
   recorded_audio: "已传录音",
   not_recorded_audio: "未传录音",
   weChat_share: "微信分享",
+  copy_share_link:'复制链接',
   set_tags_title: "设置标签",
   select_ipt_pld: "输入或者选择",
   input_email_subject: "请输入邮件主题",
@@ -240,4 +295,53 @@ export const ReportListZh = {
   upload_img_error_msg: "有图片未上传完成,请稍等",
   all_update_publish_msg: "本期报告品种已全部更新,点击发布将同时发布周报,确认同时发布吗?",
   is_publish_report_msg: "您还未上传录音文件,确定发布报告吗?",
+
+
+
+  tab_public:'公共研报',
+  tab_share:'共享研报',
+  tab_mine:'我的研报',
+  /* 添加报告弹窗 */
+  label_add_way:'新增方式',
+  label_report_tit:'报告标题',
+  choose_inherit_report: '选择继承报告',
+  label_report_classify:'报告分类',
+  label_relation_variety: '关联品种',
+  label_report_abstract:'报告摘要',
+  label_report_author:'报告作者',
+  label_frequency:'频度',
+  label_createtime:'创建时间',
+  label_coop:'协作方式',
+  choose_cooper:'选择协作人',
+  coop_own: '个人',
+  coop_more: '多人协作',
+  label_report_layout:'报告布局',
+  layout_default:'常规布局',
+  layout_smart:'智能布局',
+  label_public:'公开发布',
+
+  tit_report_chap:'研报章节',
+  btn_add_chap: '添加章节',
+  /* 添加章节弹窗 */
+  label_chap_name:'章节名称',
+  label_chap_editor:'编辑人',
+  tit_choose_inher:'选择报告',
+  ph_report_tit: '请输入报告标题',
+  check_report_len: '只能选择一篇报告',
+  ph_select_user: '请选择用户',
+  del_chapter_msg: '是否确认删除该章节?',
+  report_empty_msg:'请输入报告内容',
+  img_set_btn: '版图设置',
+  no_chapter_msg:'暂无章节信息',
+  chapter_nosubmit_msg:'{name}内容未提交',
+
+  choose_head_img:'选择版头',
+  choose_end_img:'选择版尾',
+  canvas_set:'画布设置',
+  choose_layout_img:'选择版图',
+  variety_tip:`若章节关联品种,则章节阅读权限受章节关联品种的权限控制;<br>
+  若章节不关联品种,则章节阅读权限受分类关联品种的权限控制;`,
+  chapter_has_submit:'已提交',
+  chapter_no_submit:'未提交',
+  choose_msg: '选择'
 };

+ 4 - 4
src/lang/modules/ReportManagement/SmartReport.js

@@ -35,7 +35,7 @@ export const SmartReportEn = {
   smart_notification_pushed: "Notification Pushed",
   smart_filtering_criteria_btn: "Filter options",
   smart_title_creator_btn: "Title/Creator",
-  smart_report_type: "Report type",
+  smart_report_type: "Category",
   smart_creator_btn: "Creator",
   table_col02:'Operator',
   smart_release_approval_time: "Release/Approval Time",
@@ -52,7 +52,7 @@ export const SmartReportEn = {
   smart_release_prompt_btn: "Release prompt",
   smart_template_msg: "The report has been set to be released regularly. Do you want to publish the report immediately and push the template message?",
   smart_push_template_btn: "Do you want to publish the report immediately and push template messages?",
-  smart_status_table: "status",
+  smart_status_table: "Report status",
   smart_abstract_table: "Abstract",
   smart_select_file: "Select file",
   smart_sync_policy_report: "Sync Policy Report",
@@ -163,7 +163,7 @@ export const SmartReportZh = {
   smart_notification_pushed: "已推送消息",
   smart_filtering_criteria_btn: "筛选条件",
   smart_title_creator_btn: "标题 / 创建人",
-  smart_report_type: "报告类型",
+  smart_report_type: "分类",
   smart_creator_btn: "创建人",
   table_col02:'更新人',
   smart_release_approval_time: "发布/审批时间",
@@ -180,7 +180,7 @@ export const SmartReportZh = {
   smart_release_prompt_btn: "发布提示",
   smart_template_msg: "该报告已设置定时发布,是否立即发布报告并推送模板消息?",
   smart_push_template_btn: "是否立即发布报告,并推送模板消息?",
-  smart_status_table: "状态",
+  smart_status_table: "报告状态",
   smart_abstract_table: "摘要",
   smart_select_file: "选择文件",
   smart_sync_policy_report: "同步策略报告",

+ 27 - 0
src/lang/modules/SemanticsManage/indexEn.js

@@ -11,5 +11,32 @@ export default {
     DocumentManagement: DocumentManagementEn,
     TagManagement: TagManagementEn,
     ASRpage:ASRPageEn,
+
+    /* ai纪要 */
+    AiSummeryPage: {
+      btn_add_summery: 'Add Summery',
+      btn_add_prompt: 'Add Prompt',
+      tab_summery: 'Summerys',
+      tab_prompt: 'Prompts',
+      
+      ph_search:'Please enter the name of the summery',
+      public_prompt:'Public Prompt',
+      my_prompt:'My Prompt',
+      add_first_classify:'Add Primary Directory',
+
+      source_tab1:'Original Text',
+      source_tab2:'Document Library',
+      source_tab3:'Upload File',
+      rechoose:'Re-select',
+      source_title:'Title',
+      
+      label_prompt:'Prompt',
+      label_model:'Large Model',
+      send_btn:'Send',
+      new_send_btn:'New Dialogue',
+      summery_name:'Summery Name',
+      summery_clasify:'Summery category',
+      ph_classify:"Please select a summary category"
+    }
   },
 };

+ 28 - 0
src/lang/modules/SemanticsManage/indexZh.js

@@ -10,5 +10,33 @@ export default {
     DocumentManagement: DocumentManagementZh,
     TagManagement: TagManagementZh,
     ASRpage:ASRPageZh,
+
+    /* ai纪要 */
+    AiSummeryPage: {
+      btn_add_summery: '添加纪要',
+      btn_add_prompt: '添加提示词',
+      tab_summery: '纪要库',
+      tab_prompt: '提示词库',
+      
+      ph_search:'请输入纪要名称',
+      public_prompt:'公共提示词',
+      my_prompt:'我的提示词',
+      add_first_classify:'添加一级目录',
+
+      source_tab1:'原文',
+      source_tab2:'文档库',
+      source_tab3:'上传文件',
+      rechoose:'重新选择',
+      source_title:'标题',
+      
+      label_prompt:'提示词',
+      label_model:'大模型',
+      send_btn:'发送',
+      new_send_btn:'新对话中发送',
+
+      summery_name:'纪要名称',
+      summery_clasify:'纪要分类',
+      ph_classify:"请选择纪要分类"
+    }
   },
 };

+ 17 - 0
src/lang/modules/ToolBox/CommodityPriceChart.js

@@ -33,6 +33,14 @@ export const CommodityPriceChartEn = {
     tips_msg04:'Please set up the trading profit configuration first.',
     tips_msg05:'Indicator not selected yet',
     tips_msg06:'Please add a date.',
+
+    xAxis_set_name:'Horizontal axis settings',
+    del_edb_empty_tips:'Are you sure you want to delete all spot indicators? The chart will be cleared after the operation.',
+    tips_msg07:'date reference cannot be empty',
+    tips_msg08:"Choose a spot indicator as the date reference, and the added date rules will be calculated based on that indicator's date",
+    tips_msg09:'Please select a date reference',
+    date_reference:'date reference',
+    xAxis_name:'Horizontal axis name',
 };
   
 /* 中文 */
@@ -66,6 +74,15 @@ export const CommodityPriceChartZh = {
     tips_msg04:'请先设置盘面利润配置',
     tips_msg05:'暂未选择指标',
     tips_msg06:'请添加日期',
+
+    xAxis_set_name:'横坐标设置',
+    del_edb_empty_tips:'现货指标全部删除后,图表会被清除,确认操作吗?',
+    tips_msg07:'日期基准不能为空',
+    tips_msg08:'选择一个现货指标为日期基准,添加的日期规则以该指标日期进行计算',
+    tips_msg09:'请选择日期基准',
+    date_reference:'日期基准',
+    xAxis_name:'横坐标名称',
+
 };
   
 /**

+ 2 - 2
src/lang/modules/systemManage/ReportApprove.js

@@ -30,7 +30,7 @@ export const ReportApproveEn = {
     approval_type03:'Or Sign (Approval or rejection by any one approver is sufficient)',
     des01:'Multiple approvers review and approve in sequence; The node passes only when all approvers agree; Approve in order of selection',
     des02:'The node passes only when all approvers agree; There is no sequence in approval.',
-    des03:'If any approver agrees, the node wil pass; There is no sequence in approval.',
+    des03:'Approval by one reviewer is sufficient.',
     warning_msg01:'Please select at least one person',
     search_btn:'Search',
     has_selected:'has been selected',
@@ -65,7 +65,7 @@ export const ReportApproveZh = {
     approval_type03:'或签(一名审批人同意或拒绝即可)',
     des01:'多个审批人依次进行审批;只有当所有审批人同意,该节点才能通过;按选择顺序审批',
     des02:'所有审批人同意,该节点才能通过;审批无先后顺序',
-    des03:'任意一名审批人同意,该节点即通过;审批无先后顺序',
+    des03:'一名审批人同意即可',
     warning_msg01:'请至少选择一人',
     search_btn:'搜索',
     has_selected:'项',

+ 5 - 2
src/mixins/reportApproveConfig.js

@@ -43,14 +43,17 @@ export default{
             const {IsReportApprove='',ReportApproveType=''} = res.Data
             this.IsReportApprove = IsReportApprove==='true'?true:false,
             this.ReportApproveType = ReportApproveType
+
+            console.log(this.isApprove)
         },
         //检查是否有审批流
         checkClassifyNameArr(type=1,classify=[]){
             this.checkLoading=true
             let params = {
                 ReportType:type,
-                ClassifyFirstId:classify[classify.length-2]||0,
-                ClassifySecondId:classify[classify.length-1]||0,
+                ClassifyFirstId:classify[0]||0,
+                ClassifySecondId:classify[1]||0,
+                ClassifyThirId:classify[2]||0,
             }
             approveInterence.checkClassifyApprove(params).then(res=>{
                 this.checkLoading=false

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

@@ -384,6 +384,14 @@ export default [
           name_en:'Wind'
         },
       },
+      {
+        path: "highFrequencyData",
+        component: () => import("@/views/dataEntry_manage/thirdBase/highFrequencyData.vue"),
+        name: "高频数据",
+        meta:{
+          name_en:'High Frequency Data'
+        }
+      },
     ],
   },
 ];

+ 28 - 16
src/routes/modules/oldRoutes.js

@@ -62,7 +62,26 @@ export default [
   {
     path: "/smartReportDetail",
     name: "智能报告",
-    component: () => import("@/views/smartReport/reportDetail.vue"),
+    component: () => import("@/views/report_manage/reportV2/smartReport/reportDetail.vue"),
+  },
+
+
+  {
+    path: '/reportEditV2',
+    name:'编辑研报',
+    component: () => import("@/views/report_manage/reportV2/normalReport/editReport.vue")
+  },
+  {
+    path: '/smpartReportEditV2',
+    name:'编辑研报',
+    component: () => import("@/views/report_manage/reportV2/smartReport/editReport.vue")
+  },
+
+  {
+    path: "/reportdtlV2",
+    component: () => import("@/views/report_manage/reportV2/normalReport/reportdtl.vue"),
+    name: "预览报告",
+    hidden: true,
   },
 
   // 主页
@@ -200,21 +219,6 @@ export default [
           pathName_en:"Add/Edit Day or Week Report"
         },
       },
-      // {
-      //   path: "reportupdate",
-      //   component: () => import("@/views/report_manage/dayWeekUpdate.vue"),
-      //   name: "更新管理",
-      //   hidden: true,
-      //   meta: {
-      //     keepAlive: false,
-      //   },
-      // },
-      // {
-      //   path: "reportlabel",
-      //   component: () => import("@/views/report_manage/tagLib.vue"),
-      //   name: "标签库",
-      //   hidden: true,
-      // },
       {
         path: "reportEnList",
         component: () =>
@@ -306,6 +310,14 @@ export default [
             name_en:"Smart Report"
         }
       },
+      {
+        path: 'reportNew',
+        name:'研报中心',
+        component: () => import("@/views/report_manage/reportV2/list.vue"),
+        meta:{
+          name_en:"Report Center"
+        }
+      }
     ],
   },
 

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

@@ -87,6 +87,22 @@ export default [{
       meta:{
         name_en:"ASR"
       },
-    }
+    },
+    {
+      path: "aISummeryPage",
+      name: "AI纪要",
+      component: () => import('@/views/semantics_manage/summery/index.vue'),
+      meta:{
+        name_en:"AI Summery"
+      },
+    },
+    {
+      path: "summeryEdit",
+      name: "添加纪要",
+      component: () => import('@/views/semantics_manage/summery/summeryEdit.vue'),
+      meta:{
+        name_en:"Add Summery"
+      },
+    },
   ]
 }]

+ 7 - 0
src/styles/global.scss

@@ -153,4 +153,11 @@ button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusri
     .chart-instruction {
         width:30%;
     }
+}
+// 联级选择器 浮窗高度拉高
+.el-cascader-menu__wrap{
+    height: calc(100% + 7px);
+    // height: auto;    
+    max-height: 408px;
+    // overflow-x: auto;
 }

+ 31 - 1
src/utils/buttonConfig.js

@@ -33,8 +33,15 @@ export const reportManageBtn={
     reportManage_reportList:'reportManage:reportList',//研报列表的选项
     reportManage_reportList_uv:'reportManage:reportList:uv',//研报列表-PV/UV
     reportManage_reportList_sendTime:'reportManage:reportList:sendTime',//研报列表-报告推送时间
-    reportManage_dayWeekReportAdd:'reportManage:dayWeekReportAdd',//添加晨报周报
+    // reportManage_dayWeekReportAdd:'reportManage:dayWeekReportAdd',//添加晨报周报
     reportManage_reportAdd:'reportManage:reportAdd',//添加研报
+
+    reportManage_clearCont:'reportMange:clearCont',//一键清空内容
+
+    reportMange_chapter_add: 'reportMange:chapter:add',//章节添加
+    reportMange_chapter_sort: 'reportMange:chapter:sort',//章节排序
+    reportMange_chapter_share: 'reportMange:chapter:share',//章节分享
+    reportMange_chapter_editTag: 'reportMange:chapter:editTag',//章节添加标签
 }
 /*
  *--------智能研报列表----------- 
@@ -236,6 +243,8 @@ export const dataSourcePermission = {
     mysteelData_classifyOpt_add:'mysteelData:classifyOpt:add',//添加目录和子项
     mysteelData_classifyOpt_edit:'mysteelData:classifyOpt:edit',//编辑
     mysteelData_classifyOpt_delete:'mysteelData:classifyOpt:delete',//删除
+    mysteelData_addEdb:'mysteelData:addEdb',//单个指标加入指标库
+    mysteelData_batchAddEdb:'mysteelData:batchAddEdb',//批量加入指标库
     /*--------SMM原始数据库---- */
     smmData_export:'smmData:export',
     smmData_classifyOpt_add:'smmData:classifyOpt:add',//添加目录和子项
@@ -283,6 +292,16 @@ export const dataSourcePermission = {
     /*--------CCF化纤信息--- */
     ccfData_view:'ccfData:view',//查看
     ccfData_exportExcel:'ccfData:exportExcel',//导出
+    /*--------高频数据--- */
+    highFrequency_adds:'highFrequency:adds',//添加高频数据
+    highFrequency_addTo_database:'highFrequency:addTo:database',//批量添加至指标库
+    highFrequency_operations:'highFrequency:operations',//批量操作
+    highFrequency_operation_detail:'highFrequency:operation:detail',//操作-详情
+    highFrequency_operation_refresh:'highFrequency:operation:refresh',//操作-刷新
+    highFrequency_operation_delete:'highFrequency:operation:delete',//操作-删除
+    highFrequency_classify_move:'highFrequency:classify:move',//分类设置-移动
+    highFrequency_classify_delete:'highFrequency:classify:delete',//分类设置-删除
+    highFrequency_classify_editAdd:'highFrequency:classify:editAdd',//分类设置-编辑/添加
 }
 
 /*
@@ -542,6 +561,17 @@ export const semanticPermission = {
     ASR_deleteVoice:'ASR:deleteVoice',//删除音频
     ASR_copyText:'ASR:copyText',//复制
     ASR_toggleTimestampShow:'ASR:toggleTimestampShow',//隐藏/显示时间戳
+
+    /* ai纪要 */
+    AiSummery_add: 'AiSummery:add',//添加纪要
+    AiSummery_view: 'AiSummery:view',//查看
+    AiSummery_prompt_add: 'AiSummery:prompt:add',//添加提示词
+    AiSummery_classify_edit: 'AiSummery:classify:edit',//添加编辑纪要分类
+    AiSummery_classify_move: 'AiSummery:classify:move',//移动分类
+    AiSummery_classify_del: 'AiSummery:classify:del',//删除分类
+    AiSummery_prompt_classify_move: 'AiSummery:prompt:classify:move',//提示词分类移动
+    AiSummery_prompt_classify_del: 'AiSummery:prompt:classify:del',//提示词分类删除
+    AiSummery_prompt_classify_edit: 'AiSummery:prompt:classify:edit',//提示词分类修改
 }
 /*
  * --------------------------------------------------------------------------统计分析------------------------------------------------

+ 12 - 0
src/utils/common.js

@@ -355,4 +355,16 @@ export const waitRequestReturn=(flag,callBack,timeout)=>{
   }else{
     callBack()
   }
+}
+
+/* 获取url的query */
+export function GetQueryString(url) {
+  let urlStr=url.split('?')[1]
+  let obj={}
+  let paramsArr=urlStr.split('&')
+  for (let index = 0; index < paramsArr.length; index++) {
+      let arr=paramsArr[index].split('=')
+      obj[arr[0]]=arr[1]
+  }
+  return obj
 }

+ 1 - 1
src/views/Login.vue

@@ -608,7 +608,7 @@ export default {
                 case "rai_researcher":
                 case "ficc_researcher":
                 case "researcher":
-                    path = "/reportlist";
+                    path = "/reportNew";
                     break;
                 // case "compliance": //合规
                 //     path = "/contractapprovallist";

+ 4 - 4
src/views/approve_manage/approveDetail.vue

@@ -58,8 +58,8 @@
 </template>
 
 <script>
-import ReportDetail from '@/views/smartReport/reportDetail.vue';
-import Reportdtl from '@/views/report_manage/reportdtl.vue'
+import ReportDetail from '@/views/report_manage/reportV2/smartReport/reportDetail.vue';
+import Reportdtl from '@/views/report_manage/reportV2/normalReport/reportdtl.vue'
 import TimeLine from './components/timeLine.vue';
 import RejectDialog from './components/rejectDialog.vue';
 import {approveInterence} from '@/api/modules/approve.js';
@@ -116,8 +116,8 @@ export default {
                     title:Report.ReportTitle||'',
                     classify:Report.ReportClassify||'',
                     approver:Approve.ApplyUserName||'',
-                    componentName:Report.ReportType===3?'ReportDetail':'Reportdtl',
-                    type:Report.ReportType
+                    componentName:Report.ReportLayout===2?'ReportDetail':'Reportdtl',
+                    type:Report.ReportLayout===2?3:Report.ReportType
                 }
                 this.formType = type||'detail'
                 this.approveInfo.state=Approve.State

+ 14 - 8
src/views/approve_manage/approveEdit.vue

@@ -5,7 +5,7 @@
             <el-form :inline="true" :model="approveForm" ref="approve-form" :rules="formRules"
                 label-width="180px" label-position="left">
                 <el-form-item :label="$t('SystemManage.ReportApprove.table_col01')" prop="name">
-                    <el-input v-model="approveForm.name" :disabled="this.$route.query.flowId" :placeholder="$t('ApprovalEdit.name_placeholder')"></el-input>
+                    <el-input v-model="approveForm.name" :placeholder="$t('ApprovalEdit.name_placeholder')"></el-input>
                 </el-form-item>
                 <el-form-item :label="$t('SystemManage.ReportApprove.table_col02')" prop="classify">
                     <el-cascader v-model="approveForm.classify"
@@ -116,8 +116,9 @@ export default {
             const params = {
                 FlowName:name,
                 ReportType:classify[0],
-                ClassifyFirstId:classify[classify.length-2]||0,
-                ClassifySecondId:classify[classify.length-1]||0,
+                ClassifyFirstId:classify[1]||0,
+                ClassifySecondId:classify[2]||0,
+                ClassifyThirdId:classify[3]||0,
                 Nodes
             }
             let res
@@ -141,13 +142,18 @@ export default {
                     ReportApproveFlowId:Number(id)
                 }).then(res=>{
                     if(res.Ret!==200) return 
-                    const {FlowName,ReportType,ClassifySecondId,Nodes} = res.Data||{}
+                    const {FlowName,ReportType,ClassifyFirstId,ClassifySecondId,Nodes,ClassifyThirdId} = res.Data||{}
                     this.approveForm.name = FlowName||''
                     //递归获取所有父级id
-                    const classify = this.classifyTree.find(i=>i.ClassifyId===ReportType)||{}
-                    const tempArr = findParentNode(classify.Children||[],ClassifySecondId)
-                    tempArr.push(ReportType)
-                    this.approveForm.classify = tempArr.reverse()
+                    // const classify = this.classifyTree.find(i=>i.ClassifyId===ReportType)||{}
+                    // const tempArr = findParentNode(classify.Children||[],ClassifySecondId)
+                    // tempArr.push(ReportType)
+                    // this.approveForm.classify = tempArr.reverse()
+                    this.approveForm.classify = ClassifyThirdId 
+                        ? [ReportType,ClassifyFirstId,ClassifySecondId,ClassifyThirdId]
+                        : ClassifySecondId
+                        ? [ReportType,ClassifyFirstId,ClassifySecondId]
+                        : [ReportType,ClassifyFirstId]
                     this.approveForm.flowNodes = Nodes||[]
                 })
             }

+ 2 - 2
src/views/approve_manage/components/flowNode/approveNode.vue

@@ -57,14 +57,14 @@
                     <div class="block" style="margin-top:30px;">
                         <p>{{$t('SystemManage.ReportApprove.mutl_person')}}</p>
                         <el-radio-group v-model="approveType">
-                            <el-radio :label="1">
+                            <!-- <el-radio :label="1">
                                 {{$t('SystemManage.ReportApprove.approval_type01')}}
                                 <el-tooltip effect="dark" placement="top" :content="$t('SystemManage.ReportApprove.des01')" >
                                     <span class="hint-text">
                                         <i class="el-icon-info"></i>
                                     </span>
                                 </el-tooltip>
-                            </el-radio>
+                            </el-radio> -->
                             <el-radio :label="2">
                                 {{$t('SystemManage.ReportApprove.approval_type02')}}
                                 <el-tooltip effect="dark" placement="top" :content="$t('SystemManage.ReportApprove.des02')" >

+ 1 - 1
src/views/approve_manage/mixins/approveMixins.js

@@ -1,7 +1,7 @@
 import {approveInterence} from '@/api/modules/approve.js'
 const filterNodes = (arr,hasDisabled)=>{
     arr.length &&arr.forEach((item) => {
-        hasDisabled&&(item.disabled = item.HasFlow)
+        hasDisabled&&(item.disabled = (item.Children&&item.Children.length)?false:item.HasFlow)
         item.Children.length && filterNodes(item.Children,hasDisabled);
         if (!item.Children.length) {
             delete item.Children;

+ 7 - 5
src/views/chartRelevance_manage/components/chartCard.vue

@@ -253,11 +253,13 @@ export default {
     },
 
     async setImageHandle(form,id) {
-      let { Data } = await dataBaseInterface.uploadImgSvg(form);
-      await dataBaseInterface.setChartImage({
-        ChartInfoId: id,
-        ImageUrl: Data.ResourceUrl,
-      });
+      // let { Data } = await dataBaseInterface.uploadImgSvg(form);
+      // await dataBaseInterface.setChartImage({
+      //   ChartInfoId: id,
+      //   ImageUrl: Data.ResourceUrl,
+      // });
+      form.append('ChartInfoId',id)
+      await dataBaseInterface.setChartThumbnail(form)
     },
 
     /* 更新图表 */

+ 7 - 6
src/views/chartRelevance_manage/crossVarietyAnalysis/chartEditor.vue

@@ -429,12 +429,13 @@ export default {
       this.setImageHandle(form,data);
     },
     async setImageHandle(form,{ UniqueCode,ChartInfoId }) {
-      let { Data } = await dataBaseInterface.uploadImgSvg(form);
-      await dataBaseInterface.setChartImage({
-        ChartInfoId: ChartInfoId,
-        ImageUrl: Data.ResourceUrl,
-      });
-
+      // let { Data } = await dataBaseInterface.uploadImgSvg(form);
+      // await dataBaseInterface.setChartImage({
+      //   ChartInfoId: ChartInfoId,
+      //   ImageUrl: Data.ResourceUrl,
+      // });
+      form.append('ChartInfoId',ChartInfoId)
+      await dataBaseInterface.setChartThumbnail(form)
 			this.$message.success(/* '保存成功' */this.$t('StatisticAnalysis.FittingEquationChart.detail_dialog_save_success'));
 			this.$router.replace({
 				path: '/crossVarietyChartList',

+ 8 - 6
src/views/chartRelevance_manage/mixins/classifyMixin.js

@@ -437,12 +437,14 @@ export default {
     },
 
     async setImageHandle(form) {
-      let { Data } = await dataBaseInterface.uploadImgSvg(form);
-
-      await dataBaseInterface.setChartImage({
-        ChartInfoId: this.select_id,
-        ImageUrl: Data.ResourceUrl,
-      });
+      // let { Data } = await dataBaseInterface.uploadImgSvg(form);
+
+      // await dataBaseInterface.setChartImage({
+      //   ChartInfoId: this.select_id,
+      //   ImageUrl: Data.ResourceUrl,
+      // });
+      form.append('ChartInfoId',this.select_id)
+      await dataBaseInterface.setChartThumbnail(form)
     },
 
     copyChartConfirm(type) {

+ 28 - 14
src/views/classify_manage/chapterSettingV2.vue

@@ -15,7 +15,7 @@
                     children: 'Child'
                 }"
 				check-strictly
-				:empty-text="$t('Common.no_classify_msg')"
+				:empty-text="$t('ReportManage.ReportList.no_chapter_msg')"
                 draggable
                 :allow-drop="canDropHandle"
                 @node-drop="dropOverHandle"
@@ -65,11 +65,11 @@
                 </el-form-item>
                 <!-- 上级分类 -->
                 <el-form-item :label="$t('ReportManage.CategoryList.parent_category')">
-                    <el-input  disabled :value="researchType=='day'?'晨报':'周报'" style="width: 317px;" 
+                    <el-input  disabled :value="parentClassifyName" style="width: 317px;" 
                     :placeholder="$t('ReportManage.CategoryList.related_variety_inputhint')"></el-input>
                 </el-form-item>
                 <!-- 关联品种 -->
-                <el-form-item prop="variety" :label="$t('ReportManage.CategoryList.related_variety')">
+                <el-form-item prop="variety" :label="$t('ReportManage.CategoryList.related_variety')" v-if="reportVarietyList.length">
                     <template slot="label">
                         <el-tooltip class="item" effect="dark" :content="$t('ReportManage.CategoryList.related_variety_hint')">
                             <div>
@@ -104,15 +104,12 @@ import { getchapterTypeList,addChapterType,editChapterType,} from 'api/api.js';
 import {setChapterEnable,setChapterSort} from '@/api/modules/oldApi.js'
 import {reportVarietyInterence} from '@/api/modules/reportVariety'
 import {classifyPermissionInterface} from '@/api/modules/classifyApi.js'
+import { reportV2Interface } from '@/api/modules/reportV2.js'
 export default {
     name:"chapterSetting",
     components:{mDialog},
     beforeRouteEnter(to, from, next) {
-        if(to.query.reportType=='day'){
-            to.matched[1].name='晨报章节设置'
-        }else{
-            to.matched[1].name='周报章节设置'
-        }
+        to.matched[1].name='章节设置'
         next()
     },
     data() {
@@ -123,23 +120,23 @@ export default {
             addDialogShow:false,
             addForm:{
                 ReportChapterTypeName:"",
-                ResearchType:"",
+                // ResearchType:"",.
                 ChartPermissionIdList:''
             },
             researchType:'',// day-晨报;week-周报
+            parentClassifyName: '',
 
             reportVarietyList:[],//中文品种列表
         }
     },
     mounted(){
-        // 类型 周报-晨报
-        this.addForm.ResearchType=this.researchType=this.$route.query.reportType=='week'?'week':'day'
+        this.parentClassifyName = this.$route.query.classifyName || ''
         this.getList()
         this.getReportVarietyList()
     },
     methods: {
         getList(type){
-            getchapterTypeList({ReportType:this.researchType}).then(res=>{
+            getchapterTypeList({ClassifyId:Number(this.$route.query.id)}).then(res=>{
                 if(res.Ret == 200){
                     this.list=res.Data.List || []
                 }
@@ -151,6 +148,7 @@ export default {
             this.addDialogShow=true
             this.addForm.ReportChapterTypeName=''
             this.addForm.ChartPermissionIdList=''
+            this.addForm.ReportChapterTypeId=0
             console.log(this.addForm);
         },
 
@@ -171,7 +169,11 @@ export default {
         this.$refs.addForm.validate((valid)=>{
           if(valid){
             // 添加小程序是否显示参数 0显示,1隐藏
-            let params={...this.addForm,ChartPermissionIdList:this.addForm.ChartPermissionIdList||[]}
+            let params={
+                ...this.addForm,
+                ClassifyId: Number(this.$route.query.id),
+                ChartPermissionIdList:this.addForm.ChartPermissionIdList||[]
+            }
             // 请求方法
             let requestMethod;
             // console.log(params);
@@ -197,12 +199,24 @@ export default {
         })
       },
 
+
+        filterNodes(arr) {
+            arr.length && arr.forEach(item => {
+                item.Child && item.Child.length && this.filterNodes(item.Child)
+                if((item.Child && !item.Child.length)) {
+                    delete item.Child
+                }
+            })
+        },
         
 
         // 获取品种数据
         getReportVarietyList(){
-            reportVarietyInterence.filterVarietyOpts().then(res=>{
+            reportV2Interface.getClassifyPermissionList({
+                ClassifyId: Number(this.$route.query.id),
+            }).then(res=>{
                 this.reportVarietyList=res.Data||[]
+                this.filterNodes(this.reportVarietyList)
             })
         },
 

+ 1 - 0
src/views/classify_manage/classifyEnlistV2.vue

@@ -313,6 +313,7 @@ export default {
 .classify-page{
     .content-box{
         .el-tree-node__content{
+            height: fit-content;
             padding-top: 10px;
             padding-bottom: 10px;
             border-bottom: 1px solid #C8CDD9;

+ 137 - 28
src/views/classify_manage/classifylistV2.vue

@@ -18,6 +18,7 @@
                 </div>
             </div>
             <div style="display:flex;padding:10px;gap:10px">
+                <!-- <el-button type="primary" @click="transferReport">分类报告转移</el-button> -->
                 <!-- 添加分类 -->
                 <el-button 
                     type="primary"
@@ -62,7 +63,7 @@
                     <div class="opt-box">
                         <!-- 章节设置 -->
                         <span class="editsty" 
-                            v-if="['晨报','周报'].includes(data.ClassifyName)" 
+                            v-if="!data.Child || (data.Child&&!data.Child.length)" 
                             @click="chapterSetting(data)" 
                             v-permission="permissionBtn.classifyBtn.classifyList_cnClassify_chapterSetting">
                             {{ $t('ReportManage.CategoryList.section_settings') }}
@@ -99,14 +100,27 @@
                     </el-form-item>
                     <!-- 上级分类 -->
                     <el-form-item prop="parent_id" :label="$t('ReportManage.CategoryList.parent_category')">
-                        <el-select v-model="classifyForm.parent_id" 
-                            :placeholder="$t('ReportManage.CategoryList.related_variety_inputhint')" style="width:400px;">
-                            <el-option :label="$t('ReportManage.CategoryList.parent_none')" :value="0"></el-option>
-                            <el-option v-for="(item,index) in classifyparentArr" :key="index" :label="item.ClassifyName" :value="item.Id"></el-option>
-                        </el-select>
+
+                        <el-cascader
+                            v-model="classifyForm.parent_id" 
+                            :options="classifyparentArr"
+                            :disabled="classifyForm.classify_id"
+                            style="width:400px;"
+                            ref="classifyRef"
+                            :props="{ 
+                                checkStrictly: true,
+                                value: 'Id',
+                                label: 'ClassifyName',
+                                children:'Child',
+                                emitPath:false
+                            }"
+                            clearable
+                            @change="changeClassify"
+                        >
+                        </el-cascader>
                     </el-form-item>
                     <!-- 关联品种 -->
-                    <el-form-item prop="variety" :label="$t('ReportManage.CategoryList.related_variety')" v-if="classifyForm.parent_id&&permissionBtn.classifyBtn.classifyList_cnClassify_connect_variety">
+                    <el-form-item prop="variety" :label="$t('ReportManage.CategoryList.related_variety')" v-if="canSetPermission">
                         <template slot="label">
                             <el-tooltip class="item" effect="dark" :content="$t('ReportManage.CategoryList.related_variety_hint')">
                                 <div>
@@ -125,6 +139,7 @@
                         ></el-cascader>
                     </el-form-item>
                 </el-form>
+                <div v-html="tips" style="color:#999;"></div>
             </div>
             <div slot="footer" style="margin-top: 20px;">
                 <el-button
@@ -138,6 +153,59 @@
                 >{{ $t('Dialog.confirm_save_btn') }}</el-button>
             </div>
         </m-dialog>
+
+        <!-- 转移报告弹窗 -->
+        <m-dialog
+            title="分类报告转移"
+            :show.sync="isTransferReport"
+            width="650px"
+        >
+
+            <div>
+                <el-form
+                    :model="transferForm"
+                    hide-required-asterisk
+                    label-width="auto"
+                >
+                    <el-form-item prop="classify_name" label="原分类">
+                        <el-cascader
+                          v-model="transferForm.oldClassify"
+                          @change="filterChange"
+                          :options="classifyparentArr"
+                          clearable
+                          placeholder="请选择分类"
+                          style="width:100%;"
+                      ></el-cascader>
+                    </el-form-item>
+                    <!-- 上级分类 -->
+                    <el-form-item prop="parent_id" label="转移至分类">
+
+                        <el-cascader
+                          v-model="transferForm.newClassify"
+                          @change="filterChange"
+                          :options="classifyparentArr"
+                          clearable
+                          placeholder="请选择分类"
+                          style="width:100%;"
+                      ></el-cascader>
+                    </el-form-item>
+                    
+                </el-form>
+            </div>
+
+            <div slot="footer" style="margin-top: 20px;">
+                <el-button
+                @click="isTransferReport=false"
+                style="width: 132px; height: 40px"
+                >{{ $t('Dialog.cancel_btn') }}</el-button>
+                <el-button
+                @click="handleSaveTransferReport"
+                type="primary"
+                style="width: 132px; height: 40px"
+                >{{ $t('Dialog.confirm_save_btn') }}</el-button>
+            </div>
+
+        </m-dialog>
     </div>
 </template>
 
@@ -146,8 +214,21 @@ import mDialog from '@/components/mDialog.vue';
 import { classifylist,classifyparent,classifyadd,classifyedit } from 'api/api.js';
 import {reportVarietyInterence} from '@/api/modules/reportVariety'
 import {classifyPermissionInterface} from '@/api/modules/classifyApi.js'
+import { reportV2Interface } from '@/api/modules/reportV2.js'
 export default {
     components:{mDialog},
+    computed: {
+        canSetPermission() {
+            /* 编辑最小级分类可设置品种 新增分类可设置跑品种 */
+            if(!this.permissionBtn.classifyBtn.classifyList_cnClassify_connect_variety) return false
+            
+            if(this.classifyForm.classify_id) {
+                return this.classifyForm.isLastLevel?true:false
+            }else {
+                return true
+            }
+        }
+    },
     data() {
         return {
             typeVal:1,
@@ -167,6 +248,13 @@ export default {
             classifyparentArr:[],
 
             reportVarietyList:[],//中文品种列表
+
+            /* 转移报告弹窗 */
+            isTransferReport: false,
+            transferForm: {},
+
+            tips: `注:若上级分类已关联报告,则新建的第一个子分类默认继承上级分类(父分类)关联的品种、报告、审批流,且关联品种支持编辑。  `
+
         }
     },
     mounted(){
@@ -174,32 +262,59 @@ export default {
         this.getReportVarietyList()
     },
     methods: {
+        /* 报告转移 */
+        transferReport() {
+            this.isTransferReport = true;
+            this.transferForm = {
+                oldClassify: '',
+                newClassify: ''
+            }
+        },
+        
+        handleSaveTransferReport() {
+            
+        },
+
+
         async getList(type){
             const res=await classifylist({
                 KeyWord:this.searchVal,
             })
             if(res.Ret===200){
                 this.list=res.Data.List||[]
+                
+                this.classifyparentArr=_.cloneDeep(this.list)
+                this.filterNodes(this.classifyparentArr)
             }
         },
 
-        // 晨报周报 去设置章节
+        /* 添加分类默认关联父级品种 */
+        async changeClassify(id) {
+            if(!this.classifyForm.classify_id) {
+                let item = this.$refs.classifyRef.getCheckedNodes(true)
+                console.log(item)
+                if(item&&item.length) {
+                    this.classifyForm.variety = item[0].data.ChartPermissionIdList
+                }
+            }
+        },
+
+        // 去设置章节
 		chapterSetting(row){
-			let reportType;
-			if(row.ClassifyName=='周报'){
-				reportType='week'
-			}else{
-				reportType='day'
-			}
-			this.$router.push({path:'chapterSetting',query:{reportType}})
+			this.$router.push({path:'chapterSetting',query:{ id:row.Id,classifyName: row.ClassifyName }})
 		},
 
+        filterNodes(arr) {
+            arr.length && arr.forEach(item => {
+                item.Child && item.Child.length && this.filterNodes(item.Child)
+                if(!item.Child || (item.Child&&!item.Child.length)  || item.Level===2) {
+                    delete item.Child
+                }
+            })
+        },
+
         async addClassify(){
-            this.classifyparentArr=[];
-            const res=await classifyparent()
-            if(res.Ret===200){
-                this.classifyparentArr=res.Data||[]
-            }
+
             this.classifyForm={
                 show:true,
                 classify_id:0,
@@ -209,14 +324,6 @@ export default {
             }
         },
         async handleEdit(item){
-            this.classifyparentArr=[];
-            const res=await classifyparent()
-            if(res.Ret===200){
-                // 编辑的是子分类或者没有子分类的才能选择上级分类
-                if(!item.Child){
-                    this.classifyparentArr=res.Data||[]
-                }
-            }
             
             this.classifyForm={
                 show:true,
@@ -224,6 +331,7 @@ export default {
                 classify_name:item.ClassifyName,
                 parent_id: item.ParentId,
                 variety:item.ChartPermissionIdList||'',//关联的品种
+                isLastLevel: !item.Child
             }
         },
         async setClassifyHandle(){
@@ -335,6 +443,7 @@ export default {
 .classify-page{
     .content-box{
         .el-tree-node__content{
+            height: fit-content;
             padding-top: 10px;
             padding-bottom: 10px;
             border-bottom: 1px solid #C8CDD9;

+ 36 - 11
src/views/dataEntry_manage/addChart.vue

@@ -205,7 +205,8 @@
             <el-collapse-item v-for="(item,index) in tableData" :key="item.EdbInfoId" :disabled="[2,5].includes(chartInfo.ChartType)">
               <template slot="title">
                 <span class="text_oneLine">{{currentLang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName}}</span>
-								<i class="el-icon-delete del-icon" @click.stop="delTarget(item)"></i>
+								<!-- 当为季节性图的第二个轴时,隐藏删除按钮 -->
+								<i class="el-icon-delete del-icon" @click.stop="delTarget(item)" v-if="!(chartInfo.ChartType===2&&index===1)"></i>
               </template>
               <ul class="setting-cont" v-if="sameOptionType.includes(chartInfo.ChartType)">
 
@@ -357,7 +358,11 @@
 						v-if="tableData.length"
 						ref="markerSectionRef"
 						:chartInfo="chartInfo"
+						:tableData="tableData"
 						@update="setChartMarkerInfo"
+						@updateSeason="updateSeasonChart"
+						@previewSeason="previewSeasonChart"
+						@previewSeasonRight="previewSeasonRight"
 					/>
         </div>
 
@@ -602,7 +607,7 @@
 								@change="getPreviewSplineInfo"
 							>
 								<el-radio-button label="公历">{{$t('Chart.calendar_gre')}}</el-radio-button>
-								<el-radio-button label="农历">{{$t('Chart.calendar_lunar')}}</el-radio-button>
+								<el-radio-button label="农历">{{$t('Chart.calendar_lunar_text')}}</el-radio-button>
 							</el-radio-group>
 
 							<!-- 图表说明 -->
@@ -779,8 +784,8 @@ export default {
 			this.$refs.diaForm.validate((valid) => {
 				if(valid) {
 					// 季节图只允许添加一个指标
-					if(this.chartInfo.ChartType === 2 && this.tableData.length > 1) 
-						return this.$message.warning(/* '您选择的图表样式为季节性图表,只支持单指标画图' */this.$t('Chart.OptMsg.season_one_msg'));
+					if(this.chartInfo.ChartType === 2 && this.tableData.length > 1){}
+						//return this.$message.warning(/* '您选择的图表样式为季节性图表,只支持单指标画图' */this.$t('Chart.OptMsg.season_one_msg'));
 
 					else if([7,11].includes(this.chartInfo.ChartType)  && !this.$refs.BarOptRef.dateList.length)  
 						return this.$message.warning(/*'请添加日期'*/this.$t('ToolBox.CommodityPriceChart.tips_msg06'));
@@ -892,6 +897,25 @@ export default {
 							MinMaxSave:Number(hasLimitChange)
 						}
 					}
+					//如果是季节性图,在这里加上同期/右轴的参数
+					if(this.chartInfo.ChartType===2){
+						//const {MaxMinLimits={},SamePeriodAverage={},SamePeriodStandardDeviation={}} = this.chartInfo.SeasonAverageConfig||{}
+						const {SeasonRightConfig={}} = this.chartInfo
+						const tempData = _.cloneDeep(this.chartInfo.SeasonAverageConfig||{})
+						const {MaxMinLimits={},SamePeriodAverage={},SamePeriodStandardDeviation={}} = tempData||{}
+						delete MaxMinLimits.List
+						delete SamePeriodAverage.List
+						delete SamePeriodStandardDeviation.List
+						const tempConfig = _.cloneDeep(SeasonRightConfig)
+						delete tempConfig.EdbInfoList
+						params.SeasonExtraConfig = {
+							...this.SeasonExtraConfig,
+							MaxMinLimits:MaxMinLimits.IsAdd?MaxMinLimits:{},
+							SamePeriodAverage:SamePeriodAverage.IsAdd?SamePeriodAverage:{},
+							SamePeriodStandardDeviation:SamePeriodStandardDeviation.IsAdd?SamePeriodStandardDeviation:{},
+							RightAxis:SeasonRightConfig.IsAdd?tempConfig:{}//右轴的具体配置
+						}
+					}
 					dataBaseInterface.chartAdd(params).then(res => {
 						if(res.Ret !== 200) return;
 							this.setChartImage(res.Data);
@@ -913,13 +937,14 @@ export default {
       this.setImageHandle(form,data);
     },
     async setImageHandle(form,{ UniqueCode,ChartInfoId }) {
-      let { Data } = await dataBaseInterface.uploadImgSvg(form);
-      // let { Data } = await dataBaseInterface.uploadImg(form);
-      await dataBaseInterface.setChartImage({
-        ChartInfoId: ChartInfoId,
-        ImageUrl: Data.ResourceUrl,
-      });
-
+      // let { Data } = await dataBaseInterface.uploadImgSvg(form);
+      // // let { Data } = await dataBaseInterface.uploadImg(form);
+      // await dataBaseInterface.setChartImage({
+      //   ChartInfoId: ChartInfoId,
+      //   ImageUrl: Data.ResourceUrl,
+      // });
+      form.append('ChartInfoId',ChartInfoId)
+      await dataBaseInterface.setChartThumbnail(form)
 			// this.$message.success('添加成功');
 			this.$message.success(this.$t('MsgPrompt.add_msg2'));
 			this.$router.replace({

+ 48 - 11
src/views/dataEntry_manage/chartSetting.vue

@@ -542,7 +542,7 @@
                         @change="getPreviewChartInfo"
                       >
                         <el-radio-button label="公历">{{$t('Chart.calendar_gre')}}</el-radio-button>
-                        <el-radio-button label="农历">{{$t('Chart.calendar_lunar')}}</el-radio-button>
+                        <el-radio-button label="农历">{{$t('Chart.calendar_lunar_text')}}</el-radio-button>
                       </el-radio-group>
 
                       <!-- 图表说明 -->
@@ -1698,6 +1698,12 @@ export default {
       }
       if (res.Ret !== 200) return;
       this.chartInfo = res.Data.ChartInfo;
+      //如果是季节性图,存储额外参数(同期/右轴)
+      if(this.chartInfo.ChartType===2){
+        const {MaxMinLimits={},SamePeriodAverage={},SamePeriodStandardDeviation={},RightAxis={}} = res.Data.DataResp||{}
+        this.chartInfo.SeasonAverageConfig = {MaxMinLimits,SamePeriodAverage,SamePeriodStandardDeviation}
+        this.chartInfo.SeasonRightConfig = RightAxis
+      }
       this.tableData = res.Data.EdbInfoList;
 
       // //将指标添加进标签列表中
@@ -1834,13 +1840,42 @@ export default {
           ConvertType:Number(_.ConvertType),
           ConvertValue:Number(_.ConvertValue),
           ConvertUnit:Number(_.IsConvert)?_.ConvertUnit:'',
-          ConvertEnUnit:Number(_.IsConvert)?_.ConvertEnUnit:''
-        }))
+          ConvertEnUnit:Number(_.IsConvert)?_.ConvertEnUnit:'',
+          IsAxis:_.IsAxis
+        })),
+        MarkersLines:this.chartInfo.MarkersLines||''
+      }
+      //季节性图 更改SeasonExtraConfig
+      //如果是季节性图,带上额外参数(同期/右轴)
+      if(this.chartInfo.ChartType===2){
+        const {MaxMinLimits={},SamePeriodAverage={},SamePeriodStandardDeviation={}} = this.chartInfo.SeasonAverageConfig||{}
+        const {SeasonRightConfig={}} = this.chartInfo
+        params.SeasonExtraConfig = {
+            ...this.SeasonExtraConfig,
+            MaxMinLimits:MaxMinLimits.IsAdd?MaxMinLimits:{},
+            SamePeriodAverage:SamePeriodAverage.IsAdd?SamePeriodAverage:{},
+            SamePeriodStandardDeviation:SamePeriodStandardDeviation.IsAdd?SamePeriodStandardDeviation:{},
+            RightAxis:SeasonRightConfig.IsAdd?SeasonRightConfig:{}
+        }
       }
-
       const res = await dataBaseInterface.getSplinePreviewData(params)
 
       if(res.Ret !== 200) return
+      //标识线回显
+      this.chartInfo.MarkersLines = res.Data.ChartInfo.MarkersLines||''
+      if(this.chartInfo.ChartType===2){
+        //更新对应数据
+        const {DataResp} = res.Data
+        const {MaxMinLimits,SamePeriodAverage,SamePeriodStandardDeviation,
+                RightAxis={
+                    IndicatorType:1,
+                    EdbInfoList:[]
+                }} = DataResp
+        this.chartInfo.SeasonAverageConfig = {
+            MaxMinLimits,SamePeriodAverage,SamePeriodStandardDeviation
+        }
+        this.chartInfo.SeasonRightConfig = RightAxis
+      }
 
       const { EdbInfoList } = res.Data;
 
@@ -2381,13 +2416,15 @@ export default {
         this.setImageHandle(form);
     },
     async setImageHandle(form) {
-      let { Data } = await dataBaseInterface.uploadImgSvg(form);
-
-      // let { Data } = await dataBaseInterface.uploadImg(form);
-      await dataBaseInterface.setChartImage({
-        ChartInfoId: this.selected_chartid,
-        ImageUrl: Data.ResourceUrl,
-      });
+      // let { Data } = await dataBaseInterface.uploadImgSvg(form);
+
+      // // let { Data } = await dataBaseInterface.uploadImg(form);
+      // await dataBaseInterface.setChartImage({
+      //   ChartInfoId: this.selected_chartid,
+      //   ImageUrl: Data.ResourceUrl,
+      // });
+      form.append('ChartInfoId',this.selected_chartid)
+      await dataBaseInterface.setChartThumbnail(form)
     },
 
     /* 分享图表 */

+ 46 - 2
src/views/dataEntry_manage/codecount/index.vue

@@ -1,7 +1,14 @@
 <template>
 	<el-card class="codecount-container">
 		<div slot="header" class="header">
-			<span><!-- 代码运算 -->{{$t('EtaBasePage.algorithm_btn')}}</span>
+			<div class="header-left">
+				<span><!-- 代码运算 -->{{$t('EtaBasePage.algorithm_btn')}}</span>
+				<span class="opt-btn" @click="operationTipShow=true">
+					<img src="~@/assets/img/data_m/icon01.png" alt="">
+					<!-- 操作说明 -->
+					<span>{{$t('CodeCountPage.opt_tip_btn')}}</span> 
+				</span>
+			</div>
 			<div>
 				<el-button type="primary" @click="runCodeHandle"><!-- 运行 -->{{$t('CodeCountPage.run_btn')}}</el-button>
 				<el-button type="primary" plain @click="saveHandle" v-if="!isView"><!-- 保存 -->{{$t('Dialog.confirm_save_btn')}}</el-button>
@@ -171,6 +178,20 @@
 				</el-tabs>
 			</el-col>
 		</div>
+		<!-- 操作说明 -->
+		<el-dialog
+			:title="$t('CodeCountPage.opt_tip_btn')"
+			:visible.sync="operationTipShow"
+			:close-on-click-modal="false"
+			center
+			v-dialogDrag
+			:append-to-body="true"
+			width="900px"
+		> 
+			<div class="dialog-container">
+				<div style="line-height:20px;color:#000000;font-size: 14px;word-break: normal;" v-html="$t('CodeCountPage.opt_tip_btn_text')"></div>
+			</div>
+		</el-dialog>
 	</el-card>
 </template>
 
@@ -218,7 +239,9 @@ export default {
 				sheetArr:[],
 				sheet_name: '',
 				sql_code: ''
-			}
+			},
+
+			operationTipShow:false
 		};
 	},
 	watch: {
@@ -467,6 +490,24 @@ export default {
 		justify-content: space-between;
 		align-items: center;
 		font-size: 16px;
+		.header-left{
+			display:flex;
+			align-items: center;
+			.opt-btn{
+				display:inline-flex;
+				align-items: center;
+				margin-left: 10px;
+				cursor: pointer;
+				img{
+					width: 32px;
+					height: 34px;
+				}
+				span{
+					color:rgb(64, 158, 255);
+				}
+			}
+		}
+
 	}
 	.bottom {
 		height: calc(100vh - 240px);
@@ -509,6 +550,9 @@ export default {
 		}
 	}
 }
+.dialog-container{
+	padding:0 60px 60px ;
+}
 </style>
 <style lang="scss">
 .codecount-container {

+ 180 - 0
src/views/dataEntry_manage/components/addAverageDialog.vue

@@ -0,0 +1,180 @@
+<template>
+    <!-- 添加同期上下限/均线/标准差 -->
+    <el-dialog
+        :visible.sync="isShow"
+        :close-on-click-modal="false"
+        :append-to-body="true"
+        @close="$emit('close')"
+        custom-class="average-edit-dialog"
+        center
+        width="650px"
+        v-dialogDrag
+        top="8vh"
+        :title="dialogTitle"
+    >
+        <div class="container">
+            <el-form :model="averageForm" :rules="formRules" hide-required-asterisk
+                ref="averageFormRef"
+                label-position="right"
+                label-width="120px">
+                <!-- 倍数 -->
+                <el-form-item :label="$t('Chart.Detail.cal_range_times2')" prop="Multiple" v-if="averageType===3">
+                    <el-input-number 
+                        v-model="averageForm.Multiple" 
+                        controls-position="right" 
+                        :min="0" step-strictly
+                        :step="0.1"
+                        style="width: 90px"
+                        />
+                </el-form-item>
+                <el-form-item prop="Year"
+                    :label="rangeLabelMap[averageType]" >
+                    <span><!-- 过去 -->{{ $t('Chart.Detail.pass_year') }}</span>
+                    <el-input-number 
+                        v-model="averageForm.Year" 
+                        controls-position="right" 
+                        :min="2" step-strictly
+                        style="width: 90px" 
+                        />
+                    <span><!-- 年 -->{{ $t('Edb.FreAll.year_min') }}</span>
+                </el-form-item>
+                <!-- 颜色 -->
+                <el-form-item :label="$t('EtaChartAddPage.right_edb_color_set')" prop="Color">
+                    <el-color-picker
+                      style="width: 90px"
+                      v-model="averageForm.Color"
+                      show-alpha
+                      :predefine="predefineColors"
+                    ></el-color-picker>
+                </el-form-item>
+                <!-- 线型 -->
+                <el-form-item :label="$t('EtaChartAddPage.label_line_sty')" prop="LineType" v-if="averageType===2">
+                    <el-select v-model="averageForm.LineType">
+                        <el-option v-for="lineItem in lineStylesOpts"
+                            :key="lineItem.value"
+                            :label="lineItem.label"
+                            :value="lineItem.value"
+                        >
+                            <svg width="60" height="10" viewBox="0 0 60 10" fill="none" xmlns="http://www.w3.org/2000/svg" v-html="lineItem.svg">
+                            </svg>
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+                <!-- 粗细 -->
+                <el-form-item :label="$t('Chart.Detail.size')" prop="LineWidth" v-if="averageType===2">
+                    <el-input-number 
+                        v-model="averageForm.LineWidth" 
+                        controls-position="right" 
+                        :min="1" step-strictly
+                        style="width: 90px"/>
+                </el-form-item>
+                <el-form-item :label="$t('EtaChartAddPage.right_edb_legend')" prop="Legend">
+                    <el-input v-model="averageForm.Legend"  style="width: 300px;"/>
+                </el-form-item>
+            </el-form>
+        </div>
+        <div slot="footer" class="dialog-footer" style="text-align: center;">
+            <el-button @click="$emit('close')">{{$t('Dialog.cancel_btn')}}</el-button>
+            <el-button type="primary" @click="confirmPerson">{{$t('Dialog.confirm_save_btn')}}</el-button>
+        </div>
+    </el-dialog>
+</template>
+
+<script>
+import { defaultOpts } from '@/utils/defaultOptions';
+import {lineStylesOpts} from '@/views/system_manage/chartTheme/common/config'
+export default {
+    props:{
+        isShow:{
+            type:Boolean,
+            default:false
+        },
+        averageType:{
+            type:Number,
+            default:1, //1同期上下限 2同期均线 3同期标准差
+        },
+        formData:{
+            type:Object,
+            default:{}
+        }
+    },
+    computed:{
+        dialogTitle(){
+            const titleMap = {
+                1:/* '添加同期上下限' */`${this.$t('Table.add_btn')}${this.$i18n.locale!=='zh'?' ':''}${this.$t('EtaChartAddPage.limits_btn')}`,
+                2:/* '添加同期均线' */`${this.$t('Table.add_btn')}${this.$i18n.locale!=='zh'?' ':''}${this.$t('EtaChartAddPage.avg_line_btn')}`,
+                3:/* '添加同期标准差' */`${this.$t('Table.add_btn')}${this.$i18n.locale!=='zh'?' ':''}${this.$t('EtaChartAddPage.std_btn')}`
+            }
+            return titleMap[this.averageType]
+        },
+        rangeLabelMap(){
+            return {
+                1:/* '上下限取数范围' */ this.$t('EtaChartAddPage.limit_range'),
+                2:/* '均线取数范围' */ this.$t('EtaChartAddPage.average_range'),
+                3:/* '取数范围' */ this.$t('EtaChartAddPage.std_range')
+            }
+        },
+        formRules(){ //方便英文翻译
+            return {
+                Legend:[{required:true,message:/* '请输入图例名称' */this.$t('EtaChartAddPage.legend_placeholder')}],
+                Year:[{required:true,message:/* '请输入年份' */this.$t('EtaChartAddPage.year_placeholder')}],
+                LineWidth:[{required:true,message:/* '请选择线宽' */this.$t('EtaChartAddPage.linewidth_placeholder')}],
+                Multiple:[{required:true,message:/* '请选择倍数' */this.$t('EtaChartAddPage.multiple_placeholder')}],
+            }
+        }
+    },
+    watch:{
+        isShow(newval){
+            if(newval){
+                Object.assign(this.averageForm,this.formData)
+                /* if(!this.averageForm.Legend){
+                    this.getLegend()
+                } */
+                this.$refs.averageFormRef&&this.$refs.averageFormRef.clearValidate()
+            }
+        }
+    },
+    data() {
+        return {
+            averageForm:{
+                Legend:'',//图例名称
+                Year:5,//上下限取数范围/均线取数范围/取数范围
+                Color:'#075EEE',//颜色及透明度
+                LineType:'Solid',//线型
+                LineWidth:1,//线宽
+                Multiple:1,//倍数
+            },
+            predefineColors: defaultOpts.colors.slice(0, 2),
+            lineStylesOpts:lineStylesOpts,
+        };
+    },
+    methods: {
+        getLegend(){
+            const nameMap = {
+                1:'年区间',
+                2:'年均值',
+                3:'年标准差'
+            }
+            this.averageForm.Legend = this.averageForm.Year+nameMap[this.averageType]
+        },
+        async confirmPerson(){
+            //校验
+            await this.$refs.averageFormRef.validate()
+            this.$emit('modify',{data:this.averageForm,type:this.averageType})
+        }
+    },
+};
+</script>
+
+<style lang="scss">
+.average-edit-dialog{
+    .container{
+        padding:0 60px;
+        .el-input{
+            width:100%;
+        }
+        .el-color-picker__trigger { width: 100%;padding: 0;border-radius: 4px; }
+        .number-input .el-input__inner { padding: 0 2px 0 10px; }
+    }
+}
+</style>

+ 490 - 115
src/views/dataEntry_manage/components/addMarkerDialog.vue

@@ -6,7 +6,7 @@
 		@close="cancelHandle"
 		custom-class="marker-edit-dialog"
 		center
-		width="650px"
+		width="950px"
 		v-dialogDrag
     top="8vh"
     :title="form.title"
@@ -24,7 +24,7 @@
               v-model="markerForm.axis"
               :placeholder="$t('EtaChartAddPage.label_select_seris_placeholder')"
               style="width:200px;"
-              @change="markerForm.axisName=axisLabelMap[markerForm.axis]"
+              @change="markerForm.axisName=axisLabelMap[markerForm.axis];markerForm.markLineType=1;"
             >
               <el-option :label="$t('Chart.Detail.l_axis')" :value="1" v-if="canSelectLeftYaxis"/>
               <el-option :label="$t('Chart.Detail.h_axis')" :value="3" v-if="canSelectXaxis"/>
@@ -35,45 +35,55 @@
           <el-form-item :label="form.markerType==='line'?$t('EtaChartAddPage.label_line_scale'):$t('EtaChartAddPage.label_area_scale')" prop="value">
             <!-- 标识线 -->
             <template v-if="form.markerType==='line'">
-              <!-- 时间轴1,2,4,6的y轴数字 x轴日期  -->
-              <template v-if="[1,2,4,6].includes(chartInfo.ChartType)">
-                <el-date-picker
-                  v-if="markerForm.axis===3"
-                  v-model="markerForm.value"
-                  :popper-class="{'month-day-picker':chartInfo.ChartType===2}"
-                  type="date"
-                  style="width: 200px;"
-                  :placeholder="$t('EtaChartAddPage.label_date_choose')"
-                  :clearable="false"
-                  :format="chartInfo.ChartType===2?'MM-dd':'yyyy-MM-dd'"
-                  :value-format="chartInfo.ChartType===2?'MM-dd':'yyyy-MM-dd'"
-                ></el-date-picker>
+              <div class="mark-value-wrap form-item-content">
+                <!-- 固定值:原标识线输入框 -->
+                <div class="default-value">
+                    <el-radio v-model="markerForm.markLineType" :label="1" style="margin-right: 20px;">{{$t('PredictEditPage.rule_fix')}}</el-radio>
+                    <!-- 时间轴1,2,4,6的y轴数字 x轴日期  -->
+                    <template v-if="[1,2,4,6].includes(chartInfo.ChartType)">
+                        <el-date-picker
+                            v-if="markerForm.axis===3"
+                            v-model="markerForm.value"
+                            :popper-class="{'month-day-picker':chartInfo.ChartType===2}"
+                            type="date"
+                            style="width: 100px;"
+                            :placeholder="$t('EtaChartAddPage.label_date_choose')"
+                            :clearable="false"
+                            :format="chartInfo.ChartType===2?'MM-dd':'yyyy-MM-dd'"
+                            :value-format="chartInfo.ChartType===2?'MM-dd':'yyyy-MM-dd'"
+                        ></el-date-picker>
 
-                <el-input
-                  v-else
-                  v-model="markerForm.value"
-                  class="number-input"
-                  style="width: 200px;"
-                  type="number"
-                  :placeholder="$t('Edb.InputHolderAll.input_number')"
-                />
-
-              </template>
+                        <el-input
+                            v-else
+                            v-model="markerForm.value"
+                            class="number-input"
+                            style="width: 100px;"
+                            type="number"
+                            :placeholder="$t('Edb.InputHolderAll.input_number')"
+                            :disabled="markerForm.markLineType===2"
+                        />
+                    </template>
 
-              <!-- 柱形图,散点,截面散点只可选数字 -->
-              <template v-else-if="[5,7,10].includes(chartInfo.ChartType)">
-                <el-input
-                  v-model="markerForm.value"
-                  style="width: 200px;"
-                  type="number"
-                  class="number-input"
-                  :placeholder="$t('Edb.InputHolderAll.input_number')"
-                  clearable
-                />
-              </template>
+                    <!-- 柱形图,散点,截面散点只可选数字 -->
+                    <template v-else-if="[5,7,10].includes(chartInfo.ChartType)">
+                        <el-input
+                            v-model="markerForm.value"
+                            style="width: 100px;"
+                            type="number"
+                            class="number-input"
+                            :placeholder="$t('Edb.InputHolderAll.input_number')"
+                            :disabled="markerForm.markLineType===2"
+                            clearable
+                        />
+                    </template>
+                </div>
+                <!-- 指标计算 -->
+                <div class="custom-value" v-if="markerForm.axis!==3">
+                    <el-radio v-model="markerForm.markLineType" :label="2" style="margin-left: 20px;">{{ $t('Edb.CalculatesAll.indicator_calculation') }}</el-radio>
+                </div>
+              </div>
             </template>
 
-
             <!-- 标识区 -->
             <template v-else>
               <!-- 时间轴1,2,4,6的y轴数字 x轴日期  -->
@@ -108,6 +118,7 @@
                     class="number-input"
                     style="width: 90px;"
                     type="number"
+                    @change="e => {markerForm.fromValue=Number(e);}"
                     :placeholder="$t('Edb.InputHolderAll.input_number')"
                   />
                   <!-- 至 -->{{$t('Common.to')}}
@@ -116,6 +127,7 @@
                     class="number-input"
                     style="width: 90px;"
                     type="number"
+                    @change="e => {markerForm.toValue=Number(e);}"
                     :placeholder="$t('Edb.InputHolderAll.input_number')"
                   />
 
@@ -129,6 +141,7 @@
                   class="number-input"
                   style="width: 90px;"
                   type="number"
+                  @change="e => {markerForm.fromValue=Number(e);}"
                   :placeholder="$t('Edb.InputHolderAll.input_number')"
                 />
                 <!-- 至 -->{{$t('Common.to')}}
@@ -137,81 +150,271 @@
                   class="number-input"
                   style="width: 90px;"
                   type="number"
+                  @change="e => {markerForm.toValue=Number(e);}"
                   :placeholder="$t('Edb.InputHolderAll.input_number')"
                 />
 
               </div>
             </template>
-            
-          </el-form-item>
-          <el-form-item :label="$t('EtaChartAddPage.label_line_sty')" prop="dashStyle" v-if="form.markerType==='line'">
-            <el-select 
-              v-model="markerForm.dashStyle"
-              style="width:200px;"
-            >
-              <el-option 
-                v-for="item in dashOptions" 
-                :key="item.value" 
-                :label="item.label" 
-                :value="item.value"
-              >
-                <svg width="60" height="10" viewBox="0 0 60 10" fill="none" xmlns="http://www.w3.org/2000/svg" v-html="item.svg"></svg>
-              </el-option>
-            </el-select>
-          </el-form-item>
-          <el-form-item :label="$t('Chart.Detail.color')" prop="color" style="margin-bottom:8px;">
-            <el-color-picker
-              v-model="markerForm.color"
-              :predefine="predefineColors"
-              show-alpha
-              style="width: 90px"
-            />
-          </el-form-item>
-          <el-form-item :label="$t('Chart.Detail.size')" prop="lineWidth" v-if="form.markerType==='line'">
-            <el-input
-              v-model="markerForm.lineWidth"
-              style="width: 90px"
-              type="number"
-              :min="1"
-            />
-          </el-form-item>
-          <el-form-item :label="form.markerType==='line'?$t('EtaChartAddPage.label_line_intru'):$t('EtaChartAddPage.label_area_intru')" prop="text">
-            <el-input
-              v-model="markerForm.text"
-              style="width: 200px"
-              :placeholder="$t('Chart.InputHolderAll.input_content')"
-            />
-          </el-form-item>
-          <el-form-item :label="$t('EtaChartAddPage.label_text_pos')" prop="textPosition">
-            <el-select 
-              v-model="markerForm.textPosition"
-              style="width:200px;"
-            >
-              <el-option 
-                v-for="item in verticalPositions" 
-                :key="item.value" 
-                :label="item.label" 
-                :value="item.value"
-              />
-            </el-select>
-          </el-form-item>
-          <el-form-item :label="$t('EtaChartAddPage.label_text_color')" prop="textColor" style="margin-bottom:8px;">
-            <el-color-picker
-              v-model="markerForm.textColor"
-              show-alpha
-              :predefine="predefineColors"
-              style="width: 90px"
-            />
-          </el-form-item>
-          <el-form-item :label="$t('EtaChartAddPage.label_text_size')" prop="textFontSize">
-            <el-input
-              v-model="markerForm.textFontSize"
-              class="number-input"
-              style="width: 90px"
-              type="number"
-              :min="1"
-            />
           </el-form-item>
+
+          <!-- 标识线-指标计算部分 -->
+          <div class="custom-value-setting-wrap" v-if="form.markerType==='line'&&markerForm.markLineType===2">
+            <!-- 指标选择 -->
+            <el-form-item :label="$t('Edb.eta_name')">
+                <div class="edb-box-wrap form-item-content">
+                    <!-- 固定第一个指标 -->
+                    <div class="fixed-edb" style="margin-right: 20px;width:45%;">
+                        <el-radio v-model="markerForm.edbType" :label="0">{{ $t('Chart.Detail.chart_first_edb') }}</el-radio>
+                        <p>{{tableData&&tableData[0].EdbName||''}}</p>
+                    </div>
+                    <!-- 指标/预测指标库的指标 -->
+                    <div class="other-edb">
+                        <el-radio v-model="markerForm.edbType" :label="1" style="margin-right: 20px;">{{$t('Chart.Detail.chart_other_edb')}}</el-radio>
+                        <!-- /datamanage/edb_info/filter_by_es/all -->
+                        <el-select style="width: 200px;"
+                            filterable remote clearable
+                            :placeholder="$t('ToolBox.ForexCalendar.edb_input')"
+                            v-model="searchObj"
+                            :remote-method="searchHandle"
+                            value-key="EdbInfoId"
+                            @click.native="searchHandle('')"
+                            @change="searchChange">
+                            <i slot="prefix" class="el-input__icon el-icon-search"></i>
+                            <el-option
+                                v-for="item in searchOptions"
+                                :key="item.EdbInfoId"
+                                :label="item.EdbName"
+                                :value="item"/>
+                        </el-select>
+                        <p>{{ markerForm.edbType&&markerForm.edbName||'' }}</p>
+                    </div>
+                </div>
+            </el-form-item>
+            <!-- 时间区间选择 -->
+            <el-form-item :label="$t('Chart.Detail.time_interval')">
+                <div class="time-area-wrap">
+                    <el-radio v-model="markerForm.timeInterval" :label="0" :disabled="[7,10].includes(chartInfo.ChartType)">{{ $t('Chart.Detail.follow_chart') }}</el-radio>
+                    <el-radio v-model="markerForm.timeInterval" :label="1">{{ $t('Chart.Detail.custom') }}</el-radio>
+                </div>
+            </el-form-item>
+            <!-- 如果时间区间选择自定义 -->
+            <div class="custom-time-wrap" v-if="markerForm.timeInterval===1">
+                <!-- 起始时间 -->
+                <el-form-item :label="$t('Table.start_time')">
+                    <div class="form-item-content">
+                        <div class="format">
+                            <el-radio v-model="markerForm.startTime.timeType" :label="1" style="margin-right: 0;"><!-- 固定 -->{{ $t('Chart.Detail.edb_time_fix') }}</el-radio>
+                            <el-date-picker
+                                v-model="markerForm.startTime.date"
+                                popper-class="x-range-picker-date"
+                                style="width: 140px;"
+                                placeholder="请输入固定时间"
+                                :clearable="false"
+                                format="yyyy-MM-dd"
+                                value-format="yyyy-MM-dd"
+                            ></el-date-picker>
+                        </div>
+                        <div class="format">
+                            <el-radio v-model="markerForm.startTime.timeType" :label="2" style="margin-left:20px;margin-right:0"><!-- 动态 -->{{ $t('Chart.Detail.edb_time_dyn') }}</el-radio>
+                            <el-tooltip effect="dark" placement="top">
+                                <div slot="content" v-html="$t('EtaChartAddPage.dynamic_time_tip')"></div>
+                                <i class="el-icon-question" style="font-size: 16px;"></i>
+                            </el-tooltip>
+                        </div>
+                    </div>
+                </el-form-item>
+                <!-- 起始时间为动态 -->
+                <div class="start-time-custom-wrap" v-if="markerForm.startTime.timeType===2">
+                    <!-- 基准日期 -->
+                    <el-form-item :label="$t('Chart.Detail.time_base')">
+                        <div class="form-item-content">
+                            <div class="format">
+                                <el-radio v-model="markerForm.startTime.conf.baseDate" :label="0"><!-- 系统日期 -->{{ $t('Chart.Detail.sys_time') }}</el-radio>
+                            </div>
+                            <div class="format" style="display: flex;align-items: center;">
+                                <p>
+                                    <el-radio v-model="markerForm.startTime.conf.baseDate" :label="1" style="margin-right:5px;"><!-- 指标最新日期 -->{{ $t('Chart.Detail.edb_new_time') }}</el-radio>
+                                </p>
+                                <p><!-- 期数前移 -->{{ $t('Chart.Detail.edb_periods') }}{{ $t('Chart.Detail.edb_periods_lead') }}
+                                    <el-input style="width:60px" type="number" class="number-input"
+                                    v-model.number="markerForm.startTime.conf.moveForward" 
+                                    @change="e => {markerForm.startTime.conf.moveForward=Number(e);}"
+                                    />
+                                    <!-- 期 -->{{ $t('Chart.Detail.edb_period') }}
+                                </p>
+                            </div>
+                        </div>
+                        
+                    </el-form-item>
+                    <!-- 日期变换 -->
+                    <dateMoveWaySec ref="startTime"></dateMoveWaySec>
+                   
+                </div>
+                
+                <!-- 结束时间 -->
+                <el-form-item :label="$t('Edb.Detail.e_end_time')">
+                    <div class="form-item-content">
+                        <div class="format">
+                            <el-radio v-model="markerForm.endTime.timeType" :label="3"><!-- 至今 -->{{ $t('Chart.Detail.edb_time_now') }}</el-radio>
+                        </div>
+                        <div class="format">
+                            <el-radio v-model="markerForm.endTime.timeType" :label="1" style="margin-right: 0;"><!-- 固定 -->{{ $t('Chart.Detail.edb_time_fix') }}</el-radio>
+                            <el-date-picker
+                                v-model="markerForm.endTime.date"
+                                popper-class="x-range-picker-date"
+                                style="width: 140px;"
+                                placeholder="请输入固定时间"
+                                :clearable="false"
+                                format="yyyy-MM-dd"
+                                value-format="yyyy-MM-dd"
+                            ></el-date-picker>
+                        </div>
+                        <div class="format">
+                            <el-radio v-model="markerForm.endTime.timeType" :label="2" style="margin-right: 0;"><!-- 动态 -->{{ $t('Chart.Detail.edb_time_dyn') }}</el-radio>
+                            <el-tooltip effect="dark" placement="top">
+                                <div slot="content" v-html="$t('EtaChartAddPage.dynamic_time_tip')"></div>
+                                <i class="el-icon-question" style="font-size: 16px;"></i>
+                            </el-tooltip>
+                        </div>
+                    </div>
+                    
+                </el-form-item>
+                <!-- 结束时间为动态 -->
+                <div class="end-time-custom-wrap" v-if="markerForm.endTime.timeType===2">
+                    <!-- 基准日期 -->
+                    <el-form-item :label="$t('Chart.Detail.time_base')">
+                        <div class="form-item-content">
+                            <div class="format">
+                                <el-radio v-model="markerForm.endTime.conf.baseDate" :label="0"><!-- 系统日期 -->{{ $t('Chart.Detail.sys_time') }}</el-radio>
+                            </div>
+                            <div class="format" style="display: flex;align-items: center;">
+                                <p>
+                                    <el-radio v-model="markerForm.endTime.conf.baseDate" :label="1" style="margin-right:5px;"><!-- 指标最新日期 -->{{ $t('Chart.Detail.edb_new_time') }}</el-radio>
+                                </p>
+                                <p><!-- 期数前移 -->{{ $t('Chart.Detail.edb_periods') }}{{ $t('Chart.Detail.edb_periods_lead') }}
+                                    <el-input style="width:60px" type="number" class="number-input"
+                                    v-model.number="markerForm.endTime.conf.moveForward" 
+                                    @change="e => {markerForm.endTime.conf.moveForward=Number(e);}"
+                                    />
+                                    <!-- 期 -->{{ $t('Chart.Detail.edb_period') }}
+                                </p>
+                            </div>
+                        </div>
+                        
+                    </el-form-item>
+                    <!-- 日期变换 -->
+                    <dateMoveWaySec ref="endTime"></dateMoveWaySec>
+                </div>
+            </div>
+            <!-- 计算方式 -->
+            <el-form-item :label="$t('Chart.Detail.plot_calculation')">
+                <div class="form-item-content">
+                    <!--区间均值-->
+                    <div class="format">
+                        <el-radio v-model="markerForm.calculation" :label="1">{{ $t('Chart.Detail.cal_range_val') }}{{ $t('Chart.Detail.cal_range_mean') }}</el-radio>
+                    </div>
+                    <!--区间均值加N倍标准差-->
+                    <div class="format">
+                        <el-radio v-model="markerForm.calculation" :label="2" style="margin-right:0;">{{ $t('Chart.Detail.cal_range_val') }}{{ $t('Chart.Detail.cal_range_mean') }}</el-radio>
+                        <p style="display:inline-block">{{ $t('Chart.Detail.cal_range_plus') }}
+                            <el-input 
+                            style="width:60px" 
+                            v-model.number="markerForm.calculationValue" 
+                            @change="e => {markerForm.calculationValue=Number(e);}"
+                            type="number" class="number-input"></el-input>{{ $t('Chart.Detail.cal_range_times') }} {{ $t('Chart.Detail.cal_range_std') }}</p>
+                    </div>
+                    <!--区间分位-->
+                    <div class="format">
+                        <el-radio v-model="markerForm.calculation" :label="3" style="margin-right:0;">{{ $t('Chart.Detail.cal_range_val') }}</el-radio>
+                        <p style="display:inline-block">
+                            <el-input style="width:60px" v-model="calculationValue" type="number" class="number-input"></el-input>%
+                            <el-select v-model="calculationType" style="width:80px">
+                                <el-option :label="$t('Chart.Detail.cal_range_count')" :value="3"></el-option>
+                                <el-option :label="$t('Chart.Detail.cal_range_value')" :value="4"></el-option>
+                            </el-select>{{ $t('Chart.Detail.cal_range_quantile') }}
+                        </p>
+                    </div>
+                </div>
+            </el-form-item>
+          </div>
+
+          <!-- 标识线样式 可收起 -->
+          <div class="mark-box" @click="isMarkStyleShow = !isMarkStyleShow;">
+            <span><i :class="isMarkStyleShow?'el-icon-arrow-down':'el-icon-arrow-right'"></i></span><span>{{ $t('Chart.Detail.plot_style') }}</span>
+          </div>
+          <div class="mark-style-wrap" v-show="isMarkStyleShow">
+            <el-form-item :label="$t('EtaChartAddPage.label_line_sty')" prop="dashStyle" v-if="form.markerType==='line'">
+                <el-select 
+                v-model="markerForm.dashStyle"
+                style="width:200px;"
+                >
+                <el-option 
+                    v-for="item in dashOptions" 
+                    :key="item.value" 
+                    :label="item.label" 
+                    :value="item.value"
+                >
+                    <svg width="60" height="10" viewBox="0 0 60 10" fill="none" xmlns="http://www.w3.org/2000/svg" v-html="item.svg"></svg>
+                </el-option>
+                </el-select>
+            </el-form-item>
+            <el-form-item :label="$t('Chart.Detail.color')" prop="color" style="margin-bottom:8px;">
+                <el-color-picker
+                v-model="markerForm.color"
+                :predefine="predefineColors"
+                show-alpha
+                style="width: 90px"
+                />
+            </el-form-item>
+            <el-form-item :label="$t('Chart.Detail.size')" prop="lineWidth" v-if="form.markerType==='line'">
+                <el-input
+                v-model="markerForm.lineWidth"
+                style="width: 90px"
+                type="number"
+                @change="e => {markerForm.lineWidth=Number(e);}"
+                :min="1"
+                />
+            </el-form-item>
+            <el-form-item :label="form.markerType==='line'?$t('EtaChartAddPage.label_line_intru'):$t('EtaChartAddPage.label_area_intru')" prop="text">
+                <el-input
+                v-model="markerForm.text"
+                style="width: 200px"
+                :placeholder="$t('Chart.InputHolderAll.input_content')"
+                />
+            </el-form-item>
+            <el-form-item :label="$t('EtaChartAddPage.label_text_pos')" prop="textPosition">
+                <el-select 
+                v-model="markerForm.textPosition"
+                style="width:200px;"
+                >
+                <el-option 
+                    v-for="item in verticalPositions" 
+                    :key="item.value" 
+                    :label="item.label" 
+                    :value="item.value"
+                />
+                </el-select>
+            </el-form-item>
+            <el-form-item :label="$t('EtaChartAddPage.label_text_color')" prop="textColor" style="margin-bottom:8px;">
+                <el-color-picker
+                v-model="markerForm.textColor"
+                show-alpha
+                :predefine="predefineColors"
+                style="width: 90px"
+                />
+            </el-form-item>
+            <el-form-item :label="$t('EtaChartAddPage.label_text_size')" prop="textFontSize">
+                <el-input
+                v-model="markerForm.textFontSize"
+                class="number-input"
+                style="width: 90px"
+                type="number"
+                @change="e => {markerForm.textFontSize=Number(e);}"
+                :min="1"
+                />
+            </el-form-item>
+          </div>
       </el-form>
     </div>
 
@@ -223,8 +426,10 @@
   </el-dialog>
 </template>
 <script>
+import dateMoveWaySec from '@/views/datasheet_manage/components/dateMoveWaySection.vue'
 import { defaultOpts } from '@/utils/defaultOptions';
 import { verticalPositions } from '@/views/system_manage/chartTheme/common/config';
+import {ForexCalendarInterface} from '@/api/modules/toolBoxApi';
 export default {
   props: {
     isShow: {
@@ -241,18 +446,40 @@ export default {
 
     chartInfo: {
       type:Object
+    },
+    tableData:{
+        type:Array
     }
-
+  },
+  components:{
+    dateMoveWaySec
   },
   watch: {
     isShow(nval) {
       if(!nval) return
-
+      this.searchObj = ''
       if(this.form.editIndex) { //表单回显
         this.editIndex = this.form.editIndex;
         this.markerForm = {
           ...this.form.data
         }
+        //标识线特殊处理
+        if(this.form.markerType==='line'){
+            if(!this.markerForm.markLineType){
+                Object.assign(this.markerForm,this.markerExtraConfig)
+                //柱形图 截面散点图禁用时间区间-跟随图表
+                if([7,10].includes(this.chartInfo.ChartType)){
+                    this.markerForm.timeInterval = 1
+                }
+            }else{
+                //重置计算方式的值
+                const {calculation} = this.markerForm
+                if(calculation===3){
+                    this.calculationValue = this.markerForm.calculationValue
+                    this.markerForm.calculationValue = 1
+                }
+            }
+        }
       }else {
         this.editIndex = 0;
         
@@ -262,8 +489,8 @@ export default {
           axis: this.canSelectLeftYaxis?1:0,
           axisName:this.axisLabelMap[this.canSelectLeftYaxis?1:0],
           value: '',
-          from: '',
-          to:'',
+          fromValue: '',
+          toValue:'',
           lineWidth: 2,
           dashStyle: 'ShortDashDot',
           color: '#999',
@@ -273,7 +500,27 @@ export default {
           textFontSize: themeOpt.markerOptions.style.fontSize,
           isShow: true,
         }
+        //标识线特殊处理
+        if(this.form.markerType==='line'){
+           this.markerForm = {
+            ...this.markerForm,
+            ...this.markerExtraConfig
+           }
+            this.calculationValue = 50
+            //柱形图 截面散点图禁用时间区间-跟随图表
+            if([7,10].includes(this.chartInfo.ChartType)){
+                this.markerForm.timeInterval = 1
+            }
+        }
       }
+    },
+    'markerForm.axis':{
+        handler(newval,oldval){
+            //从横轴切换到其他轴/其他轴切换到横轴 清空value值
+            if(oldval===3||newval===3){
+                this.markerForm.value = ''
+            }
+        }
     }
   },
   computed: {
@@ -326,8 +573,53 @@ export default {
         text: '',
         textPosition: 'top',
         textColor: '#999',
-        textFontSize: 12
+        textFontSize: 12,
+        //markerType:'line'
+      },
+      //eta1.9.4新增标识线设置
+      markerExtraConfig:{
+        markLineType:1,//标识线所在刻度 1固定值 2指标计算
+        edbType:0,//指标 0图上第一个指标 1其他指标 -
+        edbInfoId:0,//选择的指标id 图上第一个指标取tableData[0] 其他指标取 searchObj
+        edbName:'',//回显指标用
+        timeInterval:0,//时间区间 0跟随图表 1自定义
+        startTime:{//当timeInterval为1时,有值
+            timeType:1,//起始时间类型 1 固定 2动态
+            date:'2020-01-01',//固定的时间值,timeType为2时为空
+            conf:{
+                baseDate:0,//基准日期 0系统日期 1指标最新日期
+                moveForward:0,//baseDate为1时,表示前移的期数
+                dateChange:[
+                    {//和 datasheet_manage/components/dateMoveWaySection 保持一致
+                        ChangeType:1,//1日期位移 2指定频率
+                        Day: 0,
+                        Month: 0,
+                        Year: 0,
+                        Frequency: '本周',
+                        FrequencyDay: '周一'
+                    }
+                ]//日期变换的值,最多两项,最少0项,
+            },
+
+        },
+        endTime:{
+            timeType:3,//起始时间类型 3至今 1 固定 2动态
+            date:'2024-01-01',//固定的时间值,timeType不为1时为空
+            conf:{
+                baseDate:0,//基准日期 0系统日期 1指标最新日期
+                moveForward:0,
+                dateChange:[]
+            },
+        },
+        calculation:1,//计算方式 1区间均值 2区间均值+标准差 3区间百分位个数分位 4区间百分位数值分位
+        calculationValue:1,//计算方式对应值,calculation为2时表示标准差的倍数,为3时表示个数分位的百分数
       },
+      calculationType:3,
+      calculationValue:50,
+     /*  calculationSelect:[
+        {lable:'个数',value:3},
+        {label:'数值',value:4}
+      ], */
 
       axisLabelMap: { //暂时没有横轴的代表key 规定为3好了
         1: '左轴',
@@ -335,6 +627,10 @@ export default {
         2: '右二轴',
         3: '横轴',
       },
+
+      isMarkStyleShow:false,
+      searchObj:'',
+      searchOptions:[]
     }
   },
   mounted(){
@@ -344,15 +640,52 @@ export default {
 
     async saveMarker() {
 
-      if(this.form.markerType==='line'&&!this.markerForm.value) return this.$message.warning(/* '标识线所在刻度不能为空' */this.$t('Chart.Vailds.plotline_msg'))
+      if(this.form.markerType==='line'&&this.markerForm.markLineType===1&&!this.markerForm.value) return this.$message.warning(/* '标识线所在刻度不能为空' */this.$t('Chart.Vailds.plotline_msg'))
 
       else if(this.form.markerType==='area'&&(!this.markerForm.fromValue||!this.markerForm.toValue)) return this.$message.warning(/* '标识区所在范围不能为空' */this.$t('Chart.Vailds.plotarea_msg'))
       
       else if(this.form.markerType==='area'&&this.markerForm.fromValue===this.markerForm.toValue) return this.$message.warning(/* '标识区所在范围不能相同' */this.$t('Chart.Vailds.plotarea_same_msg'))
 
+      //其他判断
+      if(this.form.markerType==='line'){
+        if(this.markerForm.markLineType===2&&this.markerForm.edbType===1&&!this.searchObj){
+            return this.$message.warning(/* '请选择指标' */this.$t('Edb.InputHolderAll.input_select_edb'))
+        }
+        //起始日期为动态 获取日期变换
+        if(this.markerForm.startTime.timeType===2){
+            this.markerForm.startTime.conf.dateChange = this.$refs.startTime.dateChangeArr||[]
+            //key的第一个字母改为小写
+            this.markerForm.startTime.conf.dateChange = this.markerForm.startTime.conf.dateChange.map(i=>{
+                return Object.fromEntries(
+                    Object.keys(i).map(key => [key.charAt(0).toLowerCase() + key.slice(1), i[key]])
+                );
+            })
+        }
+        //结束日期为动态 获取日期变换
+        if(this.markerForm.endTime.timeType===2){
+            this.markerForm.endTime.conf.dateChange = this.$refs.endTime.dateChangeArr||[]
+            this.markerForm.startTime.conf.dateChange = this.markerForm.startTime.conf.dateChange.map(i=>{
+                return Object.fromEntries(
+                    Object.keys(i).map(key => [key.charAt(0).toLowerCase() + key.slice(1), i[key]])
+                );
+            })
+        }
+        if(this.markerForm.edbType===1){
+            this.markerForm.edbInfoId = this.searchObj.EdbInfoId||0
+            this.markerForm.edbName = this.searchObj.EdbName||''
+        }else{
+            this.markerForm.edbInfoId = this.tableData&&this.tableData[0].EdbInfoId||0
+        }
+      }
       
       let item = _.cloneDeep(this.markerForm)
-      
+
+      //格式化某些值
+      //form.calculation+calculationType 共同判断计算方式
+      if(this.markerForm.calculation===3){
+            item.calculation = this.calculationType
+            item.calculationValue = Number(this.calculationValue)
+      }
       this.editIndex 
         ? this.$emit('edit',{
             index: this.editIndex,
@@ -365,13 +698,33 @@ export default {
    
     cancelHandle() {
       this.$emit('update:isShow',false)
-    }
+    },
+    searchHandle(keyword){
+        ForexCalendarInterface.searchEdbInfo({
+            KeyWord:keyword,
+            CurrentIndex:1,
+            PageSize:100,
+        }).then(res=>{
+            if(res.Ret!==200) return 
+            this.searchOptions = res.Data.List||[]
+        })
+    },
+    searchChange(){
+        if(typeof this.searchObj === 'object'){
+            //获取需要的数据
+            this.markerForm.edbInfoId = this.searchObj.EdbInfoId
+            this.markerForm.edbName = this.searchObj.EdbName
+        }else{
+            this.markerForm.edbInfoId = 0
+            this.markerForm.edbName = ''
+        }
+    },
   },
 }
 </script>
 <style scoped lang='scss'>
 .main {
-  padding-left: 20%;
+  padding-left: 5%;
 }
 .bottom {
   margin: 30px 0;
@@ -383,6 +736,28 @@ export default {
 .marker-edit-dialog {
   .el-color-picker__trigger { width: 100%;padding: 0;border-radius: 4px; }
   .number-input .el-input__inner { padding: 0 2px 0 10px; }
+  .form-item-content{
+    display: flex;
+    .format{
+        margin-right: 30px;
+    }
+  }
+  .date-change-ways{
+    margin-bottom: 20px;
+    .header{
+        label{
+            text-align: left !important;
+            width:120px !important;
+        }
+    }
+  }
+  .mark-box{
+    background-color: #EBEFF6;
+    border:1px solid #C8CDD9;
+    padding:12px;
+    cursor: pointer;
+    margin-bottom: 20px;
+  }
 
 }
 .month-day-picker {

+ 319 - 0
src/views/dataEntry_manage/components/addRightEdbDialog.vue

@@ -0,0 +1,319 @@
+<template>
+    <!-- 添加右轴指标 -->
+    <el-dialog
+        :visible.sync="isShow"
+        :close-on-click-modal="false"
+        :append-to-body="true"
+        @close="$emit('close')"
+        custom-class="average-edit-dialog"
+        center
+        width="650px"
+        v-dialogDrag
+        top="8vh"
+        :title="$t('EtaChartAddPage.add_right_edb_btn')"
+    >
+        <div class="container">
+           <div class="type-select">
+                <el-radio-group v-model="rightEdbForm.IndicatorType" @change="indicatorTypeChange">
+                    <el-radio :label="1"><!-- 左轴指标同比 -->{{ $t('EtaChartAddPage.right_edb_type_on_year') }}</el-radio>
+                    <el-radio :label="2"><!-- 指标库 -->{{ $t('EtaChartAddPage.right_edb_type_lib') }}</el-radio>
+                    <el-radio :label="3"><!-- 预测指标 -->{{ $t('EtaChartAddPage.right_edb_type_pred') }}</el-radio>
+                </el-radio-group>
+                <el-select v-if="rightEdbForm.IndicatorType!==1"
+                    v-model="search_txt"
+                    v-loadMore="searchLoad"
+                    ref="searchRef"
+                    :filterable="!search_txt"
+                    remote
+                    clearable
+                    :placeholder="$t('Edb.InputHolderAll.input_name_orid')"
+                    style="width:90%;margin-top: 20px;display: block;"
+                    :remote-method="searchHandle"
+                    @click.native="inputFocusHandle"
+                    @change="selectTarget($event && searchOptions.find(_ => _.EdbInfoId === $event))"
+                >
+                    <i slot="prefix" class="el-input__icon el-icon-search"></i>
+                    <el-option
+                        v-for="item in searchOptions"
+                        :key="item.EdbInfoId"
+                        :label="chart_lang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName"
+                        :value="item.EdbInfoId"
+                        :disabled="!item.HaveOperaAuth"
+                    >
+                        <edbDetailPopover :info="item">
+                            <div slot="reference">
+                                <img 
+                                    :src="$icons.lock_ico2" 
+                                    width="18" 
+                                    height="18" 
+                                    style="vertical-align:middle" 
+                                    v-if="!item.HaveOperaAuth"
+                                />
+                                {{chart_lang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName }}
+                            </div>
+                        </edbDetailPopover>
+                    </el-option>
+                </el-select>
+           </div>
+           <div class="form-box">
+            <el-form :model="rightEdbForm" :rules="formRules" hide-required-asterisk
+                label-position="right"
+                label-width="120px">
+                <!-- 生成样式-->
+                <el-form-item :label="$t('EtaChartAddPage.right_edb_gen_style')">
+                    <el-select v-model="rightEdbForm.Style">
+                        <el-option :label="$t('EtaChartAddPage.right_edb_gen_column')" value="column"></el-option>
+                        <el-option :label="$t('EtaChartAddPage.right_edb_gen_mark')" value="mark"></el-option>
+                    </el-select>
+                </el-form-item>
+                <!-- 如果选择标记点 -->
+                <!-- 标记点形状 -->
+                <el-form-item :label="$t('EtaChartAddPage.right_edb_mark_shape')" v-if="rightEdbForm.Style==='mark'">
+                    <el-select v-model="rightEdbForm.Shape">
+                        <el-option 
+                            v-for="markItem in markTypesOpts" 
+                            :key="markItem.value"
+                            :label="markItem.label"
+                            :value="markItem.value"
+                            >
+                            <div style="display: flex;align-items: center;justify-content: center;height: 100%;" v-html="markItem.svg">
+                            </div>
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+                <!-- 柱形/标记点的 颜色及透明度 -->
+                <el-form-item :label="$t('EtaChartAddPage.right_edb_color_set')">
+                    <el-color-picker
+                      style="width: 90px"
+                      v-model="rightEdbForm.ChartColor"
+                      show-alpha
+                      :predefine="predefineColors"
+                    ></el-color-picker>
+                </el-form-item>
+                <!-- 如果选择标记点 -->
+                <!-- 标记点大小 -->
+                <el-form-item :label="$t('EtaChartAddPage.right_edb_mark_size')" v-if="rightEdbForm.Style==='mark'">
+                    <el-input-number 
+                        v-model="rightEdbForm.Size" 
+                        controls-position="right" 
+                        :min="1" 
+                        style="width: 90px"/>
+                </el-form-item>
+                <el-form-item :label="$t('EtaChartAddPage.right_edb_legend')">
+                    <el-input v-model="rightEdbForm.Legend"></el-input>
+                </el-form-item>
+                <!-- 如果选择左轴同比 -->
+                <el-form-item :label="$t('EtaChartAddPage.right_edb_format')" v-if="rightEdbForm.IndicatorType===1">
+                    <el-radio-group v-model="rightEdbForm.NumFormat">
+                        <el-radio :label="1"><!-- 百分数 -->{{ $t('EtaChartAddPage.right_edb_format_per') }}</el-radio>
+                        <el-radio :label="2"><!-- 小数 -->{{ $t('EtaChartAddPage.right_edb_format_dec') }}</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+                <!-- 如果选择标记点 -->
+                <!-- 标记点连线 -->
+                <el-form-item :label="$t('EtaChartAddPage.right_edb_mark_connect_text')" v-if="rightEdbForm.Style==='mark'">
+                    <el-radio-group v-model="rightEdbForm.IsConnected">
+                        <el-radio :label="0">{{$t('EtaChartAddPage.right_edb_mark_not_connected')}}</el-radio>
+                        <el-radio :label="1">{{ $t('EtaChartAddPage.right_edb_mark_connected') }}</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+                <!-- 如果选择连线 -->
+                <template v-if="rightEdbForm.IsConnected">
+                    <el-form-item :label="$t('EtaChartAddPage.right_edb_mark_connect_line_color')">
+                        <el-color-picker
+                        style="width: 90px"
+                        v-model="rightEdbForm.LineColor"
+                        show-alpha
+                        :predefine="predefineColors"
+                        ></el-color-picker>
+                    </el-form-item>
+                    <el-form-item :label="$t('EtaChartAddPage.right_edb_mark_connect_line_style')">
+                        <el-select v-model="rightEdbForm.LineStyle">
+                            <el-option v-for="lineItem in lineStylesOpts"
+                                :key="lineItem.value"
+                                :label="lineItem.label"
+                                :value="lineItem.value"
+                            >
+                                <svg width="60" height="10" viewBox="0 0 60 10" fill="none" xmlns="http://www.w3.org/2000/svg" v-html="lineItem.svg">
+                                </svg>
+                            </el-option>
+                        </el-select>
+                    </el-form-item>
+                    <el-form-item :label="$t('EtaChartAddPage.right_edb_mark_connect_line_width')">
+                        <el-input-number 
+                            v-model="rightEdbForm.LineWidth" 
+                            controls-position="right" 
+                            :min="1" 
+                            style="width: 90px"/>
+                    </el-form-item>
+                </template>
+            </el-form>
+           </div>
+        </div>
+        <div slot="footer" class="dialog-footer" style="text-align: center;">
+            <el-button @click="$emit('close')">{{$t('Dialog.cancel_btn')}}</el-button>
+            <el-button type="primary" @click="confirmPerson">{{$t('Dialog.confirm_save_btn')}}</el-button>
+        </div>
+    </el-dialog>
+</template>
+
+<script>
+import { dataBaseInterface } from '@/api/api.js';
+import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
+import { defaultOpts } from '@/utils/defaultOptions';
+import { markTypesOpts,lineStylesOpts } from '@/views/system_manage/chartTheme/common/config'
+export default {
+    props:{
+        isShow:{
+            type:Boolean,
+            default:false
+        },
+        tableData:{
+            type:Array
+        },
+        formData:{
+            type:Object,
+            default:{}
+        },
+        edbData:{
+            type:Object,
+        }
+    },
+    computed:{
+        formRules(){ //方便英文翻译
+            return {}
+        }
+    },
+    watch:{
+        isShow(newval){
+            if(newval){
+                Object.assign(this.rightEdbForm,this.formData)
+                this.rightEdbData = this.edbData
+                this.search_txt = this.edbData.EdbInfoId||''
+                this.searchOptions = this.edbData&&this.edbData.EdbInfoId?[this.edbData]:[]
+                if(!this.rightEdbForm.Legend){
+                    this.rightEdbForm.Legend = this.$t('EtaChartAddPage.year_on_right')
+                }
+            }
+        }
+    },
+    data() {
+        return {
+            search_page:1,
+            current_search:'',
+            search_txt:'',
+            search_have_more:false,
+            searchOptions:[],
+            rightEdbForm:{
+                IndicatorType:1,//1左轴同比 2指标库 3预测指标
+                Style:'column',//生成样式 column/mark
+                Shape:'circle',//标记点形状
+                ChartColor:'#075EEE',//颜色
+                Size:3,//标记点大小
+                Legend:'',//图例名称
+                NumFormat:1,//数值格式 1百分比 2小数
+                IsConnected:0,//连线 0无 1有
+                LineColor:'rgba(102, 102, 102, 1)',//线条颜色
+                LineWidth:1,//线条粗细
+                LineStyle:'Solid',//线条线型
+            },
+            rightEdbData:{},
+            markTypesOpts,lineStylesOpts,
+            predefineColors: defaultOpts.colors.slice(0, 2),
+        };
+    },
+    methods: {
+        indicatorTypeChange(){
+            //清空指标信息
+            this.search_txt=''
+            this.searchOptions=[]
+            this.rightEdbData={}
+        },
+        /* 搜索 */
+        searchHandle(query) {
+            this.search_page = 1;
+            this.current_search = query;
+            this.searchApi(this.current_search)
+        },
+
+        async searchApi(query,page=1) {
+            let params = {
+                KeyWord:query,
+                CurrentIndex: page,
+            }
+            const res = this.rightEdbForm.IndicatorType === 2
+                ? await dataBaseInterface.targetSearchByPage(params)
+                : await preDictEdbInterface.edbSearch(params)
+
+                if(res.Ret !== 200) return
+                const { List,Paging } = res.Data;
+                this.search_have_more = page < Paging.Pages;
+                this.searchOptions = page === 1 ? List : this.searchOptions.concat(List);
+        },
+
+        /* 聚焦获取当前检索 */
+        inputFocusHandle(e) {
+            this.search_page = 1;
+            this.current_search = e.target.value;
+            this.searchApi(this.current_search);
+        },
+        searchLoad() {
+            if(!this.search_have_more) return;
+            this.searchApi(this.current_search,++this.search_page);
+        },
+        //选择指标,获取详情,保存基本信息
+        async selectTarget(item){
+            if(!item) return 
+            //检查添加指标是否已存在
+            let have_bol = this.tableData.every(i => i.EdbInfoId === item.EdbInfoId);
+            if(have_bol){
+                // this.$message.warning('录入指标已存在');
+                this.search_txt = ''
+                return this.$message.warning(this.$t('Chart.OptMsg.edb_haved_msg'));
+            }
+            //以曲线图的参数获取指标详情
+            let params = {
+                EdbInfoId: item.EdbInfoId,
+                ChartType: 1,
+                Calendar: undefined,
+                DateType: 3,
+                StartYear:0,
+                StartDate: '',
+                EndDate: '',
+            } 
+            const res = await dataBaseInterface.chartInfo(params)
+            if(res.Ret!==200) return 
+            const tableItem = res.Data.EdbInfoList[0]
+            this.rightEdbData = {
+                EdbInfoId: tableItem.EdbInfoId,
+                EdbInfoType:tableItem.EdbInfoType,
+                LeadValue:tableItem.LeadValue,
+                LeadUnit:tableItem.LeadUnit,
+                IsAxis:0,
+            }
+        },
+        confirmPerson(){
+            //校验
+            if(this.rightEdbForm.IndicatorType!==1&&!this.search_txt){
+                return this.$message.warning(/* '请选择指标!' */this.$t('Edb.InputHolderAll.input_select_edb'))
+            }
+            if(!this.rightEdbForm.Legend){
+                return this.$message.warning(/* '请输入图例名称' */this.$t('EtaChartAddPage.legend_placeholder'))
+            }
+            this.$emit('modify',{form:this.rightEdbForm,data:this.rightEdbData})
+        }
+    },
+};
+</script>
+
+<style scoped lang="scss">
+.average-edit-dialog{
+    .type-select{
+        padding-bottom: 30px;
+        border-bottom: 1px solid #C8CDD9;
+    }
+    .form-box{
+        margin-top: 30px;
+    }
+}
+</style>

+ 9 - 1
src/views/dataEntry_manage/components/barOptionSection.vue

@@ -264,7 +264,11 @@ export default {
         })
       }
       this.cancelDialog()
-
+      // 商品价格曲线修改日期重置x轴
+      if(this.$route.path === '/addCommodityChart'){
+        this.$parent.xAxisList=[]
+      }
+      
       this.getBarData()
     },
 
@@ -305,6 +309,10 @@ export default {
     /* 移除日期 */
     removeDate(index) {
       this.dateList.splice(index,1)
+      // 商品价格曲线修改日期重置x轴
+      if(this.$route.path === '/addCommodityChart'){
+        this.$parent.xAxisList=[]
+      }
       this.getBarData();
     },
   },

+ 3 - 2
src/views/dataEntry_manage/components/chartReleationEdbTable.vue

@@ -67,7 +67,8 @@
         width="140"
     >
         <template slot-scope="scope" v-if="scope.row.HaveOperaAuth">
-            <span @click="delTarget(scope.row)" class="deletesty"><!-- 删除 -->{{$t('Table.delete_btn')}}&nbsp;</span>
+            <!-- 如果是季节性图的右轴,隐藏删除按钮 -->
+            <span @click="delTarget(scope.row)" class="deletesty" v-if="!(scope.$index===1&&chartInfo.ChartType===2)"><!-- 删除 -->{{$t('Table.delete_btn')}}&nbsp;</span>
             <span v-permission="permissionBtn.chartLibPermission.chartLib_copyData"
                 class="editsty" @click="copyCode(scope.row)">
                 <i class="el-icon-document-copy" />&nbsp;<!-- 复制数据 -->{{$t('Edb.detail_copydata_btn')}}</span
@@ -151,7 +152,7 @@ export default {
           key: 'SourceName',
         },
       ]
-    }
+    },
   },
   data() {
     return {

+ 245 - 3
src/views/dataEntry_manage/components/markersSection.vue

@@ -1,5 +1,27 @@
 <template>
   <div class="chart-markers-section">
+    <!-- 季节性图升级-添加右轴指标-->
+    <div class="section-item" v-if="chartInfo.ChartType===2">
+        <div class="average-item" v-if="rightEdbForm.IsAdd">
+            <span>{{$t('Chart.Detail.r_axis')}}</span>
+            <div style="flex-shrink:0">
+                <i class="el-icon-view icon" :style="rightEdbForm.IsShow?'color:#0052D9':'color:#999'" @click="rightEdbForm.IsShow=!rightEdbForm.IsShow;previewSeason('updateSeason')"/>
+                <i class="el-icon-edit icon" style="margin:0 6px" @click="isAddRightEdbDialogShow=true"/>
+                <i class="el-icon-delete icon" @click="deleteRightEdb"/>
+            </div>
+        </div>
+        <div v-else
+            class="add-cont"
+            @click="isAddRightEdbDialogShow=true"
+        >
+            <img
+                src="~@/assets/img/set_m/add_ico.png"
+                alt=""
+                style="width: 16px; height: 16px; margin-right: 10px"
+            />
+            <span>{{$t('EtaChartAddPage.add_right_edb_btn')}}</span>
+        </div>
+    </div>
     <!-- 雷达不要 -->
     <template v-if="chartInfo.ChartType!==11">
       <!-- 标示线 -->
@@ -55,6 +77,73 @@
 
       </div>
     </template>
+    <!-- 季节性图升级-同期上下限/均线/标准差-->
+    <template v-if="chartInfo.ChartType===2">
+        <div class="section-item">
+            <div class="average-item" v-if="averageArea.IsAdd">
+                <span>{{ $t('EtaChartAddPage.limits_btn') }}:{{ averageArea.Year||0 }}</span>
+                <div style="flex-shrink:0">
+                    <i class="el-icon-view icon" :style="averageArea.IsShow?'color:#0052D9':'color:#999'" @click="averageArea.IsShow=!averageArea.IsShow;previewSeason('updateSeason')"/>
+                    <i class="el-icon-edit icon" style="margin:0 6px" @click="openAverageDialog(averageArea,1,'edit')"/>
+                    <i class="el-icon-delete icon" @click="deleteAverage(1)"/>
+                </div>
+            </div>
+            <div v-else
+                class="add-cont"
+                @click="openAverageDialog(averageArea,1)"
+            >
+                <img
+                    src="~@/assets/img/set_m/add_ico.png"
+                    alt=""
+                    style="width: 16px; height: 16px; margin-right: 10px"
+                />
+                <span><!-- 添加同期上下限 -->{{$t('Table.add_btn')}}{{$i18n.locale!=='zh'?' ':''}}{{ $t('EtaChartAddPage.limits_btn') }}</span>
+            </div>
+        </div>
+        <div class="section-item">
+            <div class="average-item" v-if="averageLine.IsAdd">
+                <span>{{ $t('EtaChartAddPage.avg_line_btn') }}:{{averageLine.Year||0}}</span>
+                <div style="flex-shrink:0">
+                    <i class="el-icon-view icon" :style="averageLine.IsShow?'color:#0052D9':'color:#999'" @click="averageLine.IsShow=!averageLine.IsShow;previewSeason('updateSeason')"/>
+                    <i class="el-icon-edit icon" style="margin:0 6px" @click="openAverageDialog(averageLine,2,'edit')"/>
+                    <i class="el-icon-delete icon" @click="deleteAverage(2)"/>
+                </div>
+            </div>
+            <div v-else
+                class="add-cont"
+                @click="openAverageDialog(averageLine,2)"
+            >
+                <img
+                    src="~@/assets/img/set_m/add_ico.png"
+                    alt=""
+                    style="width: 16px; height: 16px; margin-right: 10px"
+                />
+                <span><!-- 添加同期均线 -->{{$t('Table.add_btn')}}{{$i18n.locale!=='zh'?' ':''}}{{ $t('EtaChartAddPage.avg_line_btn') }}</span>
+            </div>
+        </div>
+        <div class="section-item">
+            <div class="average-item" v-if="averageStd.IsAdd">
+                <span>{{ $t('EtaChartAddPage.std_btn') }}:{{averageStd.Year||0}}</span>
+                <div style="flex-shrink:0">
+                    <i class="el-icon-view icon" :style="averageStd.IsShow?'color:#0052D9':'color:#999'" @click="averageStd.IsShow=!averageStd.IsShow;previewSeason('updateSeason')"/>
+                    <i class="el-icon-edit icon" style="margin:0 6px" @click="openAverageDialog(averageStd,3,'edit')"/>
+                    <i class="el-icon-delete icon" @click="deleteAverage(3)"/>
+                </div>
+            </div>
+            <div v-else
+                class="add-cont"
+                @click="openAverageDialog(averageStd,3)"
+            >
+                <img
+                    src="~@/assets/img/set_m/add_ico.png"
+                    alt=""
+                    style="width: 16px; height: 16px; margin-right: 10px"
+                />
+                <span><!-- 添加同期标准差 -->{{$t('Table.add_btn')}}{{$i18n.locale!=='zh'?' ':''}}{{ $t('EtaChartAddPage.std_btn') }}</span>
+            </div>
+        </div>
+    </template>
+
 
     <!-- 图表说明 -->
     <div class="section-item">
@@ -93,6 +182,7 @@
         rightIndex: $parent.rightIndex,
         rightTwoIndex: $parent.rightTwoIndex
       }"
+      :tableData="tableData"
       @add="addMarkerItem"
       @edit="editMarkerItem"
     />
@@ -138,17 +228,62 @@
         <el-button @click="chartInductionDiaForm.show=false"><!-- 取消 -->{{$t('Dialog.cancel_btn')}}</el-button>
       </div>
     </m-dialog>
-
+    <!-- 同期上下限/均线/标准差弹窗 -->
+    <addAverageDialog 
+        :isShow="isAddAverageDialogShow"
+        :averageType="averageType"
+        :formData="averageForm"
+        @close="isAddAverageDialogShow=false"
+        @modify="addAverage"
+    />
+    <!-- 右轴指标弹窗 -->
+    <addRightEdbDialog 
+        :isShow="isAddRightEdbDialogShow"
+        :tableData="tableData"
+        :formData="rightEdbForm"
+        :edbData="rightEdbInfo"
+        @close="isAddRightEdbDialogShow=false"
+        @modify="addRightEdb"
+    />
   </div>  
 </template>
 <script>
 import addMarkerDialog from './addMarkerDialog.vue'
 import mDialog from '@/components/mDialog.vue'
+import addAverageDialog from './addAverageDialog.vue'
+import addRightEdbDialog from './addRightEdbDialog.vue'
+
+const baseAverageForm = {
+    Legend:'',//图例名称
+    Year:5,//上下限取数范围/均线取数范围/取数范围
+    Color:'#075EEE',//颜色及透明度
+    LineType:'Solid',//线型
+    LineWidth:1,//线宽
+    Multiple:1,//倍数
+}
+const baseRightForm = {
+    IndicatorType:1,//1左轴同比 2指标库 3预测指标
+    Style:'column',//生成样式 column/mark
+    Shape:'circle',//标记点形状
+    ChartColor:'#075EEE',//颜色
+    Size:3,//标记点大小
+    Legend:'',//图例名称
+    NumFormat:1,//数值格式 1百分比 2小数
+    IsConnected:0,//连线 0无 1有
+    LineColor:'rgba(102, 102, 102, 1)',//线条颜色
+    LineWidth:1,//线条粗细
+    LineStyle:'Solid',//线条线型
+    IsShow:false,
+    IsAdd:false
+}
 export default {
-  components: { addMarkerDialog,mDialog },
+  components: { addMarkerDialog,mDialog, addAverageDialog, addRightEdbDialog },
   props: {
     chartInfo: {
       type: Object
+    },
+    tableData:{
+        type:Array
     }
   },
   data() {
@@ -173,7 +308,26 @@ export default {
       chartInductionDiaForm: {
         show: false,
         text: '',
-      }
+      },
+
+      /* 同期上下限/均线/标准差弹窗 */
+      isAddAverageDialogShow:false,
+      averageType:1,//1同期上下限 2同期均线 3同期标准差
+      averageForm:{},//初始化和回显用
+      averageMap:{
+        0:'',
+        1:{name:'averageArea'},//同期上下限
+        2:{name:'averageLine'},//同期均线
+        3:{name:'averageStd'},//同期标准差
+      },
+      averageArea:{IsAdd:false,IsShow:false},
+      averageLine:{IsAdd:false,IsShow:false},
+      averageStd:{IsAdd:false,IsShow:false},
+
+      /* 右轴指标弹窗 */
+      isAddRightEdbDialogShow:false,
+      rightEdbForm:{},//初始化和回显用
+      rightEdbInfo:{},//右轴不为同比时,有值
     }
   },
   methods:{
@@ -259,6 +413,85 @@ export default {
         color: this.chartInfo.ChartThemeStyle?JSON.parse(this.chartInfo.ChartThemeStyle).markerOptions.style.color:'#333',
         fontSize: this.chartInfo.ChartThemeStyle?JSON.parse(this.chartInfo.ChartThemeStyle).markerOptions.style.fontSize:12
       };
+    },
+    //打开同期弹窗
+    openAverageDialog(data,type,openType='add'){
+        if(openType==='add'){
+            this.averageForm = {
+                ...baseAverageForm,
+                IsAdd:false,
+                IsShow:false
+            }
+            //要默认颜色不一样
+            if(type===1){
+                this.averageForm.Color = 'rgba(153, 153, 153, 0.5)'
+            }
+            if(type===2){
+                this.averageForm.Color = '#ccc'
+                this.averageForm.LineType = 'ShortDash'
+            }
+        }else{
+            this.averageForm = data
+        }
+        this.averageType = type
+        this.isAddAverageDialogShow = true
+    },
+    //添加同期设置
+    addAverage({data,type}){
+        Object.assign(this[this.averageMap[type].name],data)
+        this[this.averageMap[type].name].IsAdd = true
+        this[this.averageMap[type].name].IsShow = true
+        this.isAddAverageDialogShow=false
+        this.previewSeason('previewSeason')
+    },
+    //取消添加同期设置
+    deleteAverage(type){
+        this[this.averageMap[type].name].IsAdd = false
+        this.previewSeason('previewSeason')
+    },
+    //添加右轴指标
+    addRightEdb({form,data}){
+        const tableData = {
+            ...data,
+            IsAxis:0,
+            Unit:form.NumFormat===1?'%':'',
+            UnitEn:''
+
+        }
+        this.rightEdbInfo = tableData
+        Object.assign(this.rightEdbForm,form)
+        this.rightEdbForm.IsAdd = true
+        this.rightEdbForm.IsShow = true
+        this.isAddRightEdbDialogShow = false
+        this.$emit('previewSeasonRight',{rightConfig:this.rightEdbForm,tableData})
+    },
+    //取消添加右轴指标
+    deleteRightEdb(){
+        this.rightEdbForm.IsAdd = false
+        this.rightEdbForm.IsShow = false
+        this.$emit('previewSeasonRight',{rightConfig:this.rightEdbForm,tableData:this.rightEdbInfo})
+        this.rightEdbForm = {}
+        Object.assign(this.rightEdbForm,baseRightForm)
+    },
+    //更新季节性图 同期/右轴
+    //预览图表
+    previewSeason(eventName='previewSeason'){
+        this.$emit(eventName,{
+            SeasonAverageConfig:{
+                MaxMinLimits:this.averageArea,
+                SamePeriodAverage:this.averageLine,
+                SamePeriodStandardDeviation:this.averageStd
+            },
+            SeasonRightEdbConfig:this.rightEdbForm
+        })
+    },
+    //季节性图配置数据回显
+    initSeasonData(data){
+        Object.assign(this.averageArea,data.MaxMinLimits)
+        Object.assign(this.averageLine,data.SamePeriodAverage)
+        Object.assign(this.averageStd,data.SamePeriodStandardDeviation)
+        Object.assign(this.rightEdbForm,data.RightAxis)
+        this.rightEdbInfo = data.RightInfo
     }
   },
 }
@@ -278,6 +511,15 @@ export default {
         padding: 12px 15px;
       }
     }
+    .average-item{
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        padding: 12px 15px;
+        border: 1px solid #DCDFE6;
+        background: #F0F2F5;
+        margin-bottom: 15px;
+    }
     .icon {font-size: 18px;cursor: pointer;}
     .el-icon-delete{
       color: #f00;

+ 27 - 4
src/views/dataEntry_manage/components/setLangInfo.vue

@@ -195,7 +195,17 @@
                 <el-input v-model="it.value" :placeholder="it.placeholder" ></el-input>
               </el-form-item>
             </el-collapse-item>
+
+            <!-- 商品价格曲线 -->
+            <el-collapse-item v-if="formData.chartInfo&&[2,5].includes(formData.chartInfo[0].source)" :title="$t('ToolBox.CommodityPriceChart.xAxis_name')" name="横坐标名称">
+              <div class="set-xaxis-box" >
+                  <el-input class="inp-item" v-model="it.name" v-for="it,index in copyFormData.xData" :key="index"></el-input>
+              </div>
+            </el-collapse-item>
           </el-collapse>
+
+          
+
         </div>
 			</el-form>
 
@@ -227,16 +237,18 @@ export default {
         ChartNameEn:'',
         ChartEdbInfoList:[
 
-        ]
+        ],
+        xData:[]
       },
       copyFormData:{
         chartInfo:[],
-        chartsList:[]
+        chartsList:[],
+        xData:[]
       },
       activeNames: [0],
 
       fromEdbList: [],
-      updateInfo: {}
+      updateInfo: {},
     }
   },
   props:{
@@ -282,7 +294,8 @@ export default {
     cancel(){
       this.copyFormData={
         chartInfo:[],
-        chartsList:[]
+        chartsList:[],
+        xData:[]
       }
       this.$emit('cancel')
     },
@@ -354,6 +367,7 @@ export default {
         chartEdbInfoListTem.push(params)
       })
       this.langData.ChartEdbInfoList=chartEdbInfoListTem
+      this.langData.xData=this.copyFormData.xData
       this.$emit('updateLang',this.langData)
     },
 
@@ -416,6 +430,15 @@ export default {
     .el-collapse-item__content{
       padding:18px 8px 0 8px;
     }
+    .set-xaxis-box{
+      display: flex;
+      flex-wrap: wrap;
+      gap: 10px;
+      justify-content: space-between;
+      .inp-item{
+        width: 48%;
+      }
+    }
   }
 }
 

+ 15 - 2
src/views/dataEntry_manage/databaseComponents/addTargetDiaBase.vue

@@ -54,6 +54,10 @@
 							<el-option :label="item.label" :value="item.value" 
 							v-for="item in THSIndexCodeTypeArr" :key="item.value"></el-option>
 						</el-select>
+						<span class="selectable-option-row" v-if="fromType=='同花顺'">
+							<span>{{ $t('EtaBasePage.option_selectable') }}</span>
+							<el-input v-model="ExtraPars" style="width: 130px;margin-left: 10px;" />
+						</span>
 						<el-checkbox-group v-model="indexCodeSelected">
 							<el-checkbox :label="item.value" v-for="item in indexCodeArr" :key="item.value">{{ item.label }}</el-checkbox>
 						</el-checkbox-group>
@@ -284,6 +288,7 @@ export default {
 			search_company_txt: '',
 			securityCodeText:"",
 			indexCodeText:'',
+			ExtraPars:'',
 			indexCode:[],
 			edbIndexDatas:[],
 			edbTableHeadKey: [
@@ -341,6 +346,7 @@ export default {
 			this.search_company_txt = '';
 			this.wsdAddStep=1
 			this.securityCodeText=""
+			this.ExtraPars=''
 			this.indexCodeText=''
 			this.indexCode=[]
 			this.indexCodeSelected=[]
@@ -460,6 +466,7 @@ export default {
 			if(this.fromDatabase=='1'){
 				this.fromDatabase='0'
 				this.securityCodeText=""
+				this.ExtraPars=''
 				this.indexCodeText=''
 				this.indexCode=[]
 				this.indexCodeSelected=[]
@@ -550,7 +557,8 @@ export default {
 						Source:Number(this.fromCode.get(this.fromType)),
 						SubSource:this.fromDatabase,
 						EdbCode:Array.from(new Set([...this.indexCode,...this.indexCodeSelected])).join(','),
-						StockCode:this.securityCodeText
+						StockCode:this.securityCodeText,
+						ExtraPars:this.ExtraPars
 					}
 					dataBaseInterface.edbExistCheck(params).then(res=>{
 						if(res.Ret == 200){
@@ -584,7 +592,8 @@ export default {
 												Frequency:'日度',
 												EdbName:isCommon?`${item.StockCode}${isCommon.label}`:`${item.StockCode}${item.EdbCode}`,
 												EdbCode:item.EdbCode,
-												StockCode:item.StockCode
+												StockCode:item.StockCode,
+												ApiExtraPars:this.ExtraPars
 											}
 											this.BatchList.push(params)
 											let datas = item.DataList || []
@@ -746,6 +755,10 @@ export default {
 			width:400px;
 			margin-right: 10px;
 		}
+		.selectable-option-row{
+			display: inline-flex;
+			align-items: center;
+		}
 	}
 	.warn_txt {
 		font-size: 16px;

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

@@ -52,7 +52,7 @@
                     <el-form-item :label="$t('EtaBasePage.label_calendar')"  style="width:180px">
                         <el-select v-model="formData.calendarType" style="width:120px">
                             <el-option :label="$t('Chart.calendar_gre')" value="公历"></el-option>
-                            <el-option :label="$t('Chart.calendar_lunar')" value="农历"></el-option>
+                            <el-option :label="$t('Chart.calendar_lunar_text')" value="农历"></el-option>
                         </el-select>
                     </el-form-item>
                     </template>

+ 10 - 7
src/views/dataEntry_manage/databaseComponents/chartTrendRender.vue

@@ -110,7 +110,7 @@
 							@change="getDataByPath"
 					>
 							<el-radio-button label="公历">{{$t('Chart.calendar_gre')}}</el-radio-button>
-							<el-radio-button label="农历">{{$t('Chart.calendar_lunar')}}</el-radio-button>
+							<el-radio-button label="农历">{{$t('Chart.calendar_lunar_text')}}</el-radio-button>
 					</el-radio-group>
 				</div>
 			</div>
@@ -294,13 +294,16 @@ export default {
 			});
 			let form = new FormData();
 			form.append("Img", svg);
-			let { Data,Ret } = await dataBaseInterface.uploadImgSvg(form);
+			form.append('EdbInfoId',EdbInfo.EdbInfoId)
+      await dataBaseInterface.saveEdbChartThumbnail(form)
+			
+			// let { Data,Ret } = await dataBaseInterface.uploadImgSvg(form);
 
-			if(Ret!==200 || !Data) return 
-			await dataBaseInterface.saveEdbChartImg({
-				EdbInfoId: EdbInfo.EdbInfoId,
-				ImageUrl: Data.ResourceUrl,
-			});
+			// if(Ret!==200 || !Data) return 
+			// await dataBaseInterface.saveEdbChartImg({
+			// 	EdbInfoId: EdbInfo.EdbInfoId,
+			// 	ImageUrl: Data.ResourceUrl,
+			// });
 		},
 
 		/* 获取装置指标数据 */

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

@@ -476,7 +476,7 @@ export default {
 		calendarOptions(){
 			return [
 				{label: this.$t('Chart.calendar_gre'),key: 1},
-				{label: this.$t('Chart.calendar_lunar'),key: 2},
+				{label: this.$t('Chart.calendar_lunar_text'),key: 2},
 			]
 		}
 	},

+ 48 - 5
src/views/dataEntry_manage/editChart.vue

@@ -212,7 +212,8 @@
             <el-collapse-item v-for="(item,index) in tableData" :key="item.EdbInfoId" :disabled="[2,5].includes(chartInfo.ChartType)">
               <template slot="title">
                 <span class="text_oneLine">{{currentLang==='en'?(item.EdbNameEn||item.EdbName):item.EdbName}}</span>
-								<i class="el-icon-delete del-icon" @click.stop="delTarget(item)"></i>
+								<!-- 当为季节性图的第二个轴时,隐藏删除按钮 -->
+								<i class="el-icon-delete del-icon" @click.stop="delTarget(item)" v-if="!(chartInfo.ChartType===2&&index===1)"></i>
               </template>
               <ul class="setting-cont">
 								<!-- 堆叠图 或组合图中的堆叠类型 非第一项隐藏配置 -->
@@ -364,7 +365,11 @@
 						ref="markerSectionRef"
 						:chartType="chartInfo.ChartType"
 						:chartInfo="chartInfo"
+						:tableData="tableData"
 						@update="setChartMarkerInfo"
+						@updateSeason="updateSeasonChart"
+						@previewSeason="previewSeasonChart"
+						@previewSeasonRight="previewSeasonRight"
 					/>
         </div>
 			</div>
@@ -606,7 +611,7 @@
 								@change="getPreviewSplineInfo"
 							>
 								<el-radio-button label="公历">{{$t('Chart.calendar_gre')}}</el-radio-button>
-								<el-radio-button label="农历">{{$t('Chart.calendar_lunar')}}</el-radio-button>
+								<el-radio-button label="农历">{{$t('Chart.calendar_lunar_text')}}</el-radio-button>
 							</el-radio-group>
 
 							<!-- 图表说明 -->
@@ -788,12 +793,31 @@ export default {
 						Unit: ChartInfo.ChartType===7 
 							? (this.currentLang==='en'?BarChartInfo.UnitEn:BarChartInfo.Unit) 
 							: (this.currentLang==='en'?ChartInfo.UnitEn:ChartInfo.Unit),
-						SourcesFromVisable: ChartInfo.SourcesFrom ? JSON.parse(ChartInfo.SourcesFrom).isShow : true
+						SourcesFromVisable: ChartInfo.SourcesFrom ? JSON.parse(ChartInfo.SourcesFrom).isShow : true,
 					};
+					
 					//处理下历史默认来源
 					this.setDefaultSourceFrom();
 
+					//初始化标识线/区/图表说明
 					this.$refs.markerSectionRef.initData(ChartInfo);
+					//季节性图处理SeasonAverageConfig,SeasonRightEdbConfig
+					if(this.chartInfo.ChartType===2){
+						const {MaxMinLimits,SamePeriodAverage,SamePeriodStandardDeviation,RightAxis} = res.Data.DataResp
+						this.chartInfo.SeasonAverageConfig = {MaxMinLimits,SamePeriodAverage,SamePeriodStandardDeviation}
+						this.chartInfo.SeasonRightConfig = RightAxis
+						const tempData = _.cloneDeep(this.chartInfo.SeasonAverageConfig)
+						tempData.RightAxis = _.cloneDeep(RightAxis)
+						tempData.RightInfo = _.cloneDeep((RightAxis.EdbInfoList&&RightAxis.EdbInfoList[0])||{})
+						if(tempData.RightAxis.IndicatorType!==1){
+							tempData.RightInfo = EdbInfoList[1]||{}
+						}
+						delete tempData.MaxMinLimits.List
+						delete tempData.SamePeriodAverage.List
+						delete tempData.SamePeriodStandardDeviation.List
+						delete tempData.RightAxis.EdbInfoList
+						this.$refs.markerSectionRef.initSeasonData(tempData)
+					}
 
 					this.tableData = EdbInfoList;
 					this.updateData = this.tableData.map(item=>{
@@ -892,8 +916,8 @@ export default {
 			this.$refs.diaForm.validate((valid) => {
 				if(valid) {
 					// 季节图只允许添加一个指标
-					if(this.chartInfo.ChartType === 2 && this.tableData.length > 1)  
-						return this.$message.warning(/* '您选择的图表样式为季节性图表,只支持单指标画图' */this.$t('Chart.OptMsg.season_one_msg'));
+					if(this.chartInfo.ChartType === 2 && this.tableData.length > 1) {} 
+						//return this.$message.warning(/* '您选择的图表样式为季节性图表,只支持单指标画图' */this.$t('Chart.OptMsg.season_one_msg'));
 
 					if(this.chartInfo.ChartType === 7 && !this.$refs.BarOptRef.dateList.length)  
 						return this.$message.warning(/*'请添加日期'*/this.$t('ToolBox.CommodityPriceChart.tips_msg06'));
@@ -1011,6 +1035,25 @@ export default {
 							MinMaxSave:Number(hasLimitChange)
 						}
 					}
+					//如果是季节性图,在这里加上同期/右轴的参数
+					if(this.chartInfo.ChartType===2){
+						//const {MaxMinLimits={},SamePeriodAverage={},SamePeriodStandardDeviation={}} = this.chartInfo.SeasonAverageConfig||{}
+						const {SeasonRightConfig={}} = this.chartInfo
+						const tempData = _.cloneDeep(this.chartInfo.SeasonAverageConfig||{})
+						const {MaxMinLimits={},SamePeriodAverage={},SamePeriodStandardDeviation={}} = tempData||{}
+						delete MaxMinLimits.List
+						delete SamePeriodAverage.List
+						delete SamePeriodStandardDeviation.List
+						const tempConfig = _.cloneDeep(SeasonRightConfig)
+						delete tempConfig.EdbInfoList
+						params.SeasonExtraConfig = {
+							...this.SeasonExtraConfig,
+							MaxMinLimits:MaxMinLimits.IsAdd?MaxMinLimits:{},
+							SamePeriodAverage:SamePeriodAverage.IsAdd?SamePeriodAverage:{},
+							SamePeriodStandardDeviation:SamePeriodStandardDeviation.IsAdd?SamePeriodStandardDeviation:{},
+							RightAxis:SeasonRightConfig.IsAdd?tempConfig:{}//右轴的具体配置
+						}
+					}
 					dataBaseInterface.chartEdit(params).then(res => {
 						if(res.Ret !== 200) return;
 						

+ 192 - 11
src/views/dataEntry_manage/mixins/addOreditMixin.js

@@ -155,8 +155,15 @@ export default {
 					this.chartInfo.LeftMax = '';
 					this.chartInfo.LeftMin = '';
 					this.chartInfo.MarkersLines = "";
+					this.$refs.markerSectionRef&&this.$refs.markerSectionRef.initData(this.chartInfo||{});
 					this.chartInfo.MarkersAreas = "";
 				}
+				//从普通图切换到柱形图,截面散点,雷达图 清空MarkersLines
+				if(![7,10,11].includes(oldval)&&[7,10,11].includes(newval)){
+					this.chartInfo.MarkersLines = ""
+					this.$refs.markerSectionRef&&this.$refs.markerSectionRef.initData(this.chartInfo||{});
+				}
+
 
 				this.initStatus();
 
@@ -168,6 +175,7 @@ export default {
 					this.tableData.length===1 && this.selectTarget(this.tableData[0],'switch');
 					this.tableData.length > 1 && this.setChartOptionHandle(this.tableData);
 				}
+
       },
 		}
 	},
@@ -220,7 +228,8 @@ export default {
 				EndDate: this.year_select === 5 ? dateArray[1] : '',
 				IsConvert:Number(IsConvert),
 				ConvertType,ConvertValue:Number(ConvertValue),
-				ConvertUnit,ConvertEnUnit
+				ConvertUnit,ConvertEnUnit,
+				IsAxis:this.tableData[index].IsAxis
 			}).then(res=>{
 				if(res.Ret!==200) return 
 				const {EdbInfoList=[]} = res.Data||{}
@@ -361,6 +370,7 @@ export default {
 
 		},
 
+
 		/* 添加柱形图 /雷达图指标数组 */
 		setBarEdbList(edb) {
 			let have_bol = this.tableData.some(item => item.EdbInfoId === edb.EdbInfoId);
@@ -403,7 +413,8 @@ export default {
 				Sort: {
 					Sort: sort.sort,
 					DateIndex: Number(sort.sortIndex)
-				}
+				},
+				MarkersLines:this.chartInfo.MarkersLines
 			}
 
 			dataBaseInterface.getBarData(params).then(res => {
@@ -433,6 +444,9 @@ export default {
 				
 				//默认来源搞一下
 				this.setDefaultSourceFrom();
+				//标识线回显
+				this.chartInfo.MarkersLines = res.Data.ChartInfo.MarkersLines||''
+				this.$refs.markerSectionRef&&this.$refs.markerSectionRef.initData(res.Data.ChartInfo||{});
 			})
 		},
 
@@ -506,10 +520,25 @@ export default {
 						ConvertType,
 						ConvertValue:Number(ConvertValue),
 						ConvertUnit:IsConvert?ConvertUnit:'',
-						ConvertEnUnit:IsConvert?ConvertEnUnit:''
+						ConvertEnUnit:IsConvert?ConvertEnUnit:'',
+						IsAxis:_.IsAxis
 					}
-				})
-		}
+				}),
+				MarkersLines:this.chartInfo.MarkersLines||''
+			}
+			//季节性图 更改SeasonExtraConfig
+			//如果是季节性图,存储额外参数(同期/右轴)
+			if(this.chartInfo.ChartType===2){
+				const {MaxMinLimits={},SamePeriodAverage={},SamePeriodStandardDeviation={}} = this.chartInfo.SeasonAverageConfig||{}
+				const {SeasonRightConfig={}} = this.chartInfo
+				params.SeasonExtraConfig = {
+					...this.SeasonExtraConfig,
+					MaxMinLimits:MaxMinLimits.IsAdd?MaxMinLimits:{},
+					SamePeriodAverage:SamePeriodAverage.IsAdd?SamePeriodAverage:{},
+					SamePeriodStandardDeviation:SamePeriodStandardDeviation.IsAdd?SamePeriodStandardDeviation:{},
+					RightAxis:SeasonRightConfig.IsAdd?SeasonRightConfig:{}
+				}
+			}
 
       const res = await dataBaseInterface.getSplinePreviewData(params)
 
@@ -527,17 +556,33 @@ export default {
 				chartDataHandle.map(item =>{
 					this.SeasonExtraConfig.ChartLegend.push({Name:item.Years,Value:item.ChartLegend})
 				})
+				//更新对应数据
+				const {DataResp} = res.Data
+				const {MaxMinLimits,SamePeriodAverage,SamePeriodStandardDeviation,
+						RightAxis={
+							IndicatorType:1,
+							EdbInfoList:[]
+						}} = DataResp
+				this.chartInfo.SeasonAverageConfig = {
+					MaxMinLimits,SamePeriodAverage,SamePeriodStandardDeviation
+				}
+				this.chartInfo.SeasonRightConfig = RightAxis
 			}
 
       this.tableData.forEach((item) => {
         let edbData = EdbInfoList.find(_ => _.EdbInfoId===item.EdbInfoId);
-        item.DataList = edbData.DataList;
-				//更新起始时间和最近更新时间
-        item.StartDate = edbData.StartDate;
-        item.ModifyTime = edbData.ModifyTime;
-				
-        if(edbData.EdbInfoCategoryType===1) item.MoveLatestDate = edbData.MoveLatestDate;
+		if(edbData){
+			item.DataList = edbData.DataList;
+			//更新起始时间和最近更新时间
+			item.StartDate = edbData.StartDate;
+			item.ModifyTime = edbData.ModifyTime;
+			if(edbData.EdbInfoCategoryType===1) item.MoveLatestDate = edbData.MoveLatestDate;
+		}
+        
       });
+			//标识线回显
+			this.chartInfo.MarkersLines = res.Data.ChartInfo.MarkersLines||''
+			this.$refs.markerSectionRef&&this.$refs.markerSectionRef.initData(res.Data.ChartInfo||{});
 		},
 
 		/* 年份改变 重新刷新图表接口  保存当前的图表配置和上下限 只改变图表 */
@@ -625,6 +670,16 @@ export default {
 			this.$nextTick(()=>{
 				// 等待 tableData的 监听里面的获取到 起始时间和最近日期
 				this.setChartDefault()
+				//如果标识线含有指标计算部分,请求一次preview
+				const markerLinesArr = JSON.parse(this.chartInfo.MarkersLines||'[]')
+				if(markerLinesArr.find(i=>i.markLineType===2)){
+					//柱形图单独设置
+					if(this.chartInfo.ChartType===7){
+						this.barDateList.length && this.$refs.BarOptRef.getBarData();
+					}else{
+						this.getPreviewSplineInfo()
+					}
+				}
 			})
 		},
 
@@ -1068,11 +1123,22 @@ export default {
 			this.chartInfo.MarkersAreas = JSON.stringify(markerAreasArr);
 			this.chartInfo.Instructions = JSON.stringify(chartInstruction);
 
+			//markersLines含有指标计算的部分,调preview
+			if(markerLinesArr.find(i=>i.markLineType===2)){
+				//柱形图单独设置
+				if(this.chartInfo.ChartType===7){
+					this.barDateList.length && this.$refs.BarOptRef.getBarData();
+				}else{
+					this.getPreviewSplineInfo()
+				}
+			}
+
 			this.reLoadChartOption();
 		},
 		
 		//更新标识线,区 重绘图 不用重新获取数据 
 		reLoadChartOption() {
+			console.log('reloadChartOption')
 			if(!this.options.series) return
 			
 			const chartTypeMap = {
@@ -1084,6 +1150,121 @@ export default {
 				? chartTypeMap[this.chartInfo.ChartType]() 
 				: this.setChartOptionHandle(this.tableData);
 		},
+		//更新季节性图额外配置显示隐藏(不重新获取数据)
+		updateSeasonChart({SeasonAverageConfig,SeasonRightEdbConfig}){
+			if(this.chartInfo.SeasonAverageConfig){
+				const {MaxMinLimits,SamePeriodAverage,SamePeriodStandardDeviation} = SeasonAverageConfig
+				this.chartInfo.SeasonAverageConfig.MaxMinLimits.IsShow = MaxMinLimits.IsShow||false
+				this.chartInfo.SeasonAverageConfig.SamePeriodAverage.IsShow = SamePeriodAverage.IsShow||false
+				this.chartInfo.SeasonAverageConfig.SamePeriodStandardDeviation.IsShow = SamePeriodStandardDeviation.IsShow||false
+			}
+			if(this.chartInfo.SeasonRightConfig){
+				this.chartInfo.SeasonRightConfig.IsShow = SeasonRightEdbConfig.IsShow||false
+			}
+			this.reLoadChartOption()
+		},
+		//预览季节性图(请求接口)
+		previewSeasonChart({SeasonAverageConfig={},SeasonRightEdbConfig={IndicatorType:1}}){
+			this.chartInfo.SeasonAverageConfig = SeasonAverageConfig
+			let db_arr = 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:'',
+						IsAxis:_.IsAxis
+					}
+			})
+			const 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,
+				StartYear:this.count_year || 0,
+				ChartEdbInfoList:SeasonRightEdbConfig.IndicatorType===1?[db_arr[0]]:db_arr,//如果右轴为左轴同比,则只取第一个
+			}
+			const {MaxMinLimits={},SamePeriodAverage={},SamePeriodStandardDeviation={}} = SeasonAverageConfig
+			const SeasonExtraConfig = {
+				...this.SeasonExtraConfig,
+				MaxMinLimits:MaxMinLimits.IsAdd?SeasonAverageConfig.MaxMinLimits:{},
+				SamePeriodAverage:SamePeriodAverage.IsAdd?SamePeriodAverage:{},
+				SamePeriodStandardDeviation:SamePeriodStandardDeviation.IsAdd?SamePeriodStandardDeviation:{},
+				RightAxis:SeasonRightEdbConfig.IsAdd?SeasonRightEdbConfig:{}//右轴的具体配置
+			}
+			params.SeasonExtraConfig = SeasonExtraConfig
+			dataBaseInterface.getSplinePreviewData(params).then(res=>{
+				if(res.Ret!==200) return 
+				const {DataResp} = res.Data
+				const {MaxMinLimits,SamePeriodAverage,SamePeriodStandardDeviation,
+						RightAxis={
+							IndicatorType:1,
+							EdbInfoList:[]
+						}} = DataResp
+				//包含同期的具体数据,用于绘图展示和传参
+				this.chartInfo.SeasonAverageConfig = {
+					MaxMinLimits,SamePeriodAverage,SamePeriodStandardDeviation
+				}
+				//更新SearonRightConfig
+				this.chartInfo.SeasonRightConfig = RightAxis
+				//更新chartLimit.rightMin/rightMax
+				const {EdbInfoList=[]} = res.Data
+				let MinData=0,MaxData
+				if(RightAxis.IndicatorType===1){
+					MinData = RightAxis.EdbInfoList[0].MinData||0
+					MaxData = RightAxis.EdbInfoList[0].MaxData||0
+				}else{
+					MinData = EdbInfoList[1]&&EdbInfoList[1].MinData||0
+					MaxData = EdbInfoList[1]&&EdbInfoList[1].MaxData||0
+				}
+				this.chartLimit.rightMin = MinData
+				this.chartLimit.rightMax = MaxData
+				//如果右轴有设置更新tableData&updateData
+				if(RightAxis.IsAdd){
+					this.tableData = EdbInfoList
+					this.updateData = this.tableData.map(item=>{
+						return this.formatUpdateData(item)
+					})
+					//弹窗回显
+					this.$refs.markerSectionRef.rightEdbInfo =RightAxis.IndicatorType!==1? _.cloneDeep(EdbInfoList[1]):{}
+				}else{
+					//右轴为指标时有修改tableData的行为 会重绘图表 而右轴为同比时不会 这里手动重绘一次
+					this.reLoadChartOption()
+				}
+				
+			})
+
+		},
+		//预览季节性图右轴
+		previewSeasonRight({rightConfig,tableData}){
+			this.chartInfo.SeasonRightConfig = rightConfig
+			if(rightConfig.IsAdd){
+				//若为指标/预测指标
+				if(rightConfig.IndicatorType!==1){
+					const tempItem = this.formatUpdateData(tableData)
+					if(rightConfig.IndicatorType!==1){
+						if(this.tableData.length>1){
+							this.tableData[1] = tableData
+						}else{
+							this.tableData.push(tableData)
+							this.updateData.push(tempItem)
+						}
+					}
+				}
+				//若为左轴同比,啥也不做
+			}else{
+				if(rightConfig.IndicatorType!==1){
+					this.delTarget(tableData)
+				}
+			}
+			this.previewSeasonChart({SeasonAverageConfig:this.chartInfo.SeasonAverageConfig,SeasonRightEdbConfig:rightConfig})
+		},
 		//获取图表全局设置
 		async getChartBaseSetting(){
 			//目前是用基本配置的接口,后续有多个配置再改

+ 187 - 16
src/views/dataEntry_manage/mixins/chartPublic.js

@@ -10,6 +10,11 @@ import futuresInterface from '@/api/modules/futuresBaseApi';
 import chartRelevanceApi from '@/api/modules/chartRelevanceApi';
 import { fittingEquationInterface,statisticFeatureInterface,crossVarietyInterface } from '@/api/modules/chartRelevanceApi';
 
+//获取RGBA的透明度
+const parseRgbaColor = (color='rgba(51, 51, 51, 1)') => {
+    const arr = color.match(/(\d(\.\d+)?)+/g) || ['','','',1];
+    return parseFloat(arr[3]||1)
+}
 /* 散点x轴 */
 const scatterXAxis = {
   tickPosition: 'inside',
@@ -471,6 +476,7 @@ export const chartSetMixin = {
       this.formItemArray={}
       this.formItemArray.chartInfo=[]
       this.formItemArray.chartsList=[]
+      this.formItemArray.xData=[]
       this.formItemArray.chartInfo.push({
         label:/* '图表名称' */this.$t('Chart.Detail.chart_name'),
         value: this.currentLang==='en'?this.chartInfo.ChartNameEn:this.chartInfo.ChartName,
@@ -501,6 +507,18 @@ export const chartSetMixin = {
         })
       }
 
+      // 商品价格曲线增加编辑X轴
+      if([2,5].includes(this.chartInfo.Source)){
+        const arr=this.commodityXData||[]
+        console.log(arr);
+        this.formItemArray.xData=arr.map(item=>{
+          return {
+            name:this.currentLang==='en'?item.NameEn:item.Name,
+          }
+        })
+
+      }
+
       //价格曲线
       if(this.chartInfo.Source===2) {
         this.formItemArray.chartInfo.push({
@@ -564,13 +582,23 @@ export const chartSetMixin = {
     async updateLang(paramsData) {
       let res=null
       if([2,5].includes(this.chartInfo.Source)){//商品价格
+        const ChartEdbInfoList=paramsData.ChartEdbInfoList.map(i=>{
+          return {
+            EdbInfoId:i.EdbInfoId,
+            EdbName:i.EdbName,
+            Unit:i.Unit
+          }
+        })
+        const XDataList=paramsData.xData.map(x=>x.name)
         res=await futuresInterface.setChartLangInfo({
           ChartInfoId: paramsData.ChartInfoId,
           ChartName: paramsData.ChartName,
-          Unit: paramsData.ChartEdbInfoList[0].Unit || '',
-          EdbName: paramsData.ChartEdbInfoList[0].EdbName || '',
+          // Unit: paramsData.ChartEdbInfoList[0].Unit || '',
+          // EdbName: paramsData.ChartEdbInfoList[0].EdbName || '',
           FutureGoodName: paramsData.FutureGoodName || '',
-          ProfitName: paramsData.ProfitName || ''
+          ProfitName: paramsData.ProfitName || '',
+          ChartEdbInfoList:ChartEdbInfoList,
+          XDataList:XDataList
         })
       }else if(this.chartInfo.Source===3){//相关性
         res=await chartRelevanceApi.setChartLangInfo({
@@ -580,7 +608,7 @@ export const chartSetMixin = {
       }else if(this.chartInfo.Source===6){//拟合方程
         res=await fittingEquationInterface.setChartLangInfo({
           ChartInfoId: paramsData.ChartInfoId,
-          ChartNameEn: paramsData.ChartName
+          ChartName: paramsData.ChartName
         })
       }else if([7,8,9].includes(this.chartInfo.Source)){//统计特征
         res=await statisticFeatureInterface.setChartLangInfo({
@@ -1086,7 +1114,8 @@ export const chartSetMixin = {
     setSeasonChart(newval) {
       /* 季节性图的图表配置 */
       this.leftIndex = 0;
-      this.rightIndex = -1;
+      const {SeasonRightConfig={}} = this.chartInfo
+      this.rightIndex = SeasonRightConfig.IsShow?1:-1;
       this.rightTwoIndex = -1;
       const chartData = newval[0];
       // 农历数据需要去除第一项  农历和公历处理逻辑一样
@@ -1108,19 +1137,23 @@ export const chartSetMixin = {
         //获取对应轴的上下限
         //预测指标-走势图;图表配置-主题设置;不使用自定义上下限,剔除
         const useTableLimit = ['/predictEdb','/chartThemeSet','/addpredictEdb','/editpredictEdb','/viewBalanceSheet','/editBalanceSheet'].includes(this.$route.path)
-        let minLimit = 0,maxLimit = 0
+        let minLimit = 0,maxLimit = 0,rightMin=0,rightMax=0
         if(useTableLimit){
             minLimit = chartData.MinData
             maxLimit = chartData.MaxData
+            //这几个页面的季节性图没有右轴,若有,取SearonRightConfig.EdbInfoList[0]的MinData/MaxData
         }else{
             minLimit = this.chartLimit.min||0
             maxLimit = this.chartLimit.max||0
+            //加上右轴
+            if(this.rightIndex!=-1){
+                rightMin = this.chartLimit.rightMin||0
+                rightMax = this.chartLimit.rightMax||0
+            }
         }
-
-      //数据列
+      //数据列-常规左轴
       for (let index in chartDataHandle) {
         let j = chartDataHandle[index]
-        // console.log(j,index);
         //预测指标配置
         let predict_params =  chartData.EdbInfoCategoryType === 1 ? this.getSeasonPredictParams(j.CuttingDataTimestamp) : {};
         // 图表可配置的线条数就10条,第11条用第1条的配置,索引取下模
@@ -1147,6 +1180,81 @@ export const chartSetMixin = {
         seasonData.push(serie_item);
       }
 
+      //数据列-同期上下限/均线/标准差
+      const {MaxMinLimits={},SamePeriodAverage={},SamePeriodStandardDeviation={}} = this.chartInfo.SeasonAverageConfig||{}
+      if(MaxMinLimits.IsShow&&MaxMinLimits.List&&MaxMinLimits.List.length){
+        let serieItem = {
+            type:'arearange',//上下限是一个范围
+            data:[],
+            name:MaxMinLimits.Legend||'同期上下限',
+            color:MaxMinLimits.Color||'#075EEE' ,
+            fillOpacity:parseRgbaColor(MaxMinLimits.Color||'')>0.75?0.75:parseRgbaColor(MaxMinLimits.Color||'') //透明度最高0.75 
+        }
+        MaxMinLimits.List.forEach(item=>{
+            serieItem.data.push([item.DataTimestamp,item.MinValue,item.MaxValue])
+        })
+        seasonData.push(serieItem)
+      }
+      if(SamePeriodAverage.IsShow&&SamePeriodAverage.List){
+        let serieItem = {
+            type:'line',
+            data:[],
+            lineWidth:SamePeriodAverage.LineWidth,
+            dashStyle:SamePeriodAverage.LineType,
+            name:SamePeriodAverage.Legend||'同期均值',
+            color:SamePeriodAverage.Color||'#075EEE'
+        }
+        SamePeriodAverage.List.forEach(item=>{
+            serieItem.data.push([item.DataTimestamp,item.Value])
+        })
+        seasonData.push(serieItem)
+      }
+      if(SamePeriodStandardDeviation.IsShow&&SamePeriodStandardDeviation.List){
+        let serieItem = {
+            type:'arearange',//标准差也是一个范围
+            data:[],
+            name:SamePeriodStandardDeviation.Legend||'同期标准差',
+            color:SamePeriodStandardDeviation.Color||'#075EEE',
+            fillOpacity:parseRgbaColor(SamePeriodStandardDeviation.Color||'')>0.75?0.75:parseRgbaColor(SamePeriodStandardDeviation.Color||'')
+        }
+        SamePeriodStandardDeviation.List.forEach(item=>{
+            serieItem.data.push([item.DataTimestamp,item.MinValue,item.MaxValue])
+        })
+        seasonData.push(serieItem)
+      }
+      //数据列-右轴
+      if(SeasonRightConfig.IsShow){
+        //右轴的设置
+        let serieConfig = SeasonRightConfig.Style==='column'?{
+            //柱形
+            type:'column',
+            color:SeasonRightConfig.ChartColor
+        }:{
+            //标记点
+            type:'spline',
+            lineWidth:SeasonRightConfig.LineWidth,
+            dashStyle:SeasonRightConfig.LineStyle,
+            color:SeasonRightConfig.IsConnected?SeasonRightConfig.LineColor:'rgba(255, 255, 255, 0)',//没有连线颜色设置为透明
+            marker:{
+                enabled:true,
+                symbol:SeasonRightConfig.Shape,
+                fillColor:SeasonRightConfig.ChartColor,
+                radius:SeasonRightConfig.Size
+            },
+        }
+        let serieItem = {
+            ...serieConfig,
+            name:SeasonRightConfig.Legend||'',
+            data:[],
+            yAxis:1,
+        }
+        const DataList = (SeasonRightConfig.IndicatorType===1?SeasonRightConfig.EdbInfoList[0].DataList:newval[1].DataList)||[]
+        DataList.forEach(item=>{
+            serieItem.data.push([item.DataTimestamp,item.Value])
+        })
+        seasonData.push(serieItem)
+      }
+
       //y轴
       const textZh = chartData.ConvertUnit||chartData.Unit
       const textEn = chartData.ConvertEnUnit||chartData.UnitEn||chartData.ConvertUnit||chartData.Unit
@@ -1183,6 +1291,44 @@ export const chartSetMixin = {
         plotBands: this.setAxisPlotAreas(1),
         plotLines: this.setAxisPlotLines(1)
       }];
+      //如果有右轴,seasonYdata加上右轴
+      if(SeasonRightConfig.IsShow){
+        const rightEdb = (SeasonRightConfig.IndicatorType===1?SeasonRightConfig.EdbInfoList[0]:newval[1])||{Unit:''}
+        //左轴同比:text为空或% 右轴指标:取指标单位
+        if(SeasonRightConfig.IndicatorType===1){
+            rightEdb.Unit = SeasonRightConfig.NumFormat===1?'%':''
+        }else{
+            rightEdb.Unit = newval[1]&&(newval[1].ConvertUnit||newval[1].Unit)||''
+        }
+        seasonYdata.push({
+            ...seasonOptions.yAxis,
+            opposite: true,//右轴
+            labels: {
+                formatter: function () {
+                  let val = this.value;
+                  return val;
+                },
+                align: 'center',
+                style: {
+                  ...chartTheme&&chartTheme.yAxisOptions.style
+                }
+              },
+              title: {
+                text: rightEdb.Unit||'',
+                style:{
+                  ...chartTheme&&chartTheme.yAxisOptions.style
+                },
+                align: 'high',
+                rotation: 0,
+                y: -12,
+                x: -rightEdb.Unit.length*12 ,
+                textAlign: 'right',
+                reserveSpace: false,
+              },
+              max: Number(rightMax),
+              min: Number(rightMin),
+        })
+      }
 
       /* x轴显示月日 */
       const xAxis = {
@@ -1560,7 +1706,7 @@ export const chartSetMixin = {
       //x轴
       let xAxis = {
         ...scatterXAxis,
-        categories: this.commodityXData.map(_ =>_.Name),
+        categories: this.commodityXData.filter(_=>_.IsHide===0).map(_ =>_.Name),
         tickWidth: 1,
         labels: {
           style: {
@@ -1643,8 +1789,9 @@ export const chartSetMixin = {
             
             if(haveContract) {
               // 利润曲线指标名
+              const isEdb=commodityEdbList.some(_=>_.EdbInfoId===haveContract)
               let edb_name = chartInfo.Source === 5 
-                ? (index === 0 ? obj_item.NameList[index] : `${chartInfo.ProfitName}(${obj_item.NameList[index]})`)
+                ? (isEdb ? obj_item.NameList[index] : `${chartInfo.ProfitName}(${obj_item.NameList[index]})`)
                 : commodityEdbList.find(_ => _.EdbInfoId === obj_item.XEdbInfoIdList[index]).EdbName;
               str+=`<b>${ edb_name }</b>`
   
@@ -1668,8 +1815,9 @@ export const chartSetMixin = {
             
             if(haveContract) {
               // 利润曲线指标名
+              const isEdb=commodityEdbList.some(_=>_.EdbInfoId===haveContract)
               let edb_name = chartInfo.Source === 5
-                ? (index === 0 ? obj_item.NameList[index] : `${chartInfo.ProfitName}(${obj_item.NameList[index]})`)
+                ? (isEdb? obj_item.NameList[index] : `${chartInfo.ProfitName}(${obj_item.NameList[index]})`)
                 : commodityEdbList.find(_ => _.EdbInfoId === obj_item.XEdbInfoIdList[index]).EdbName;
               str+=`<b>${ edb_name }</b>`
   
@@ -1693,8 +1841,9 @@ export const chartSetMixin = {
 
             if(haveContract) {
               // 利润曲线指标名
+              const isEdb=commodityEdbList.some(_=>_.EdbInfoId===haveContract)
               let edb_name = chartInfo.Source === 5
-                ? (index === 0 ? obj_item.NameList[index] : `${chartInfo.ProfitNameEn}(${obj_item.NameList[index]})`)
+                ? (isEdb ? obj_item.NameList[index] : `${chartInfo.ProfitNameEn}(${obj_item.NameList[index]})`)
                 : commodityEdbList.find(_ => _.EdbInfoId === obj_item.XEdbInfoIdList[index]).EdbNameEn;
               str+=`<b>${ edb_name }</b>`
   
@@ -1742,7 +1891,16 @@ export const chartSetMixin = {
             return item
           }
         })
-        return arr;
+
+        // 根据设置的x轴显示隐藏去除值
+        let temArr=[]
+        this.commodityXData.forEach((i,index)=>{
+          if(i.IsHide!==1){
+            temArr.push(arr[index]||null)
+          }
+        })
+
+        return temArr;
     },
 
     /* 获取图表详情后赋值柱状图数据 */
@@ -2818,8 +2976,7 @@ export const chartSetMixin = {
         let markerValue='';
         if(isXDateAxis) {
           //季节图x轴额外拼个年份
-          let nowYear = ChartType===2 ? new Date(this.tableData[0].DataList[1].DataList
-[0].DataTimestamp).getFullYear() : '';
+          let nowYear = ChartType===2 ? new Date(this.tableData[0].DataList[1].DataList[0].DataTimestamp).getFullYear() : '';
           console.log(nowYear)
           markerValue = ChartType===2 
             ? new Date(`${nowYear}-${_.value}`).getTime()
@@ -2912,6 +3069,7 @@ export const chartSetMixin = {
 				});
 			}
 		},
+
     /* ----自定义上下限相关--- */
         /* 计算y轴上下限 */
         calcYAxislimit(tableData=[]) {
@@ -2964,6 +3122,19 @@ export const chartSetMixin = {
                 this.chartLimit.rightTwoMin = 0
                 this.chartLimit.rightTwoMax = 0
             }
+            //季节性图-右轴为左轴同比,单独处理
+            if(this.chartInfo.ChartType===2){
+                if(this.chartInfo.SeasonRightConfig&&this.chartInfo.SeasonRightConfig.IsAdd&&this.chartInfo.SeasonRightConfig.IsShow){
+                    if(this.chartInfo.SeasonRightConfig.IndicatorType===1){
+                        this.chartLimit.rightMin = this.chartInfo.SeasonRightConfig.EdbInfoList[0].MinData||0
+                        this.chartLimit.rightMax = this.chartInfo.SeasonRightConfig.EdbInfoList[0].MaxData||0
+                    }else{
+                        this.chartLimit.rightMin = this.tableData[1].MinData||0
+                        this.chartLimit.rightMax = this.tableData[1].MaxData||0
+                    }
+                    
+                }
+            }
             console.table([{
                     'y轴': '左轴',
                     '最大值': this.chartLimit.max,

+ 211 - 0
src/views/dataEntry_manage/thirdBase/components/addIndicsDia.vue

@@ -0,0 +1,211 @@
+<template>
+    <!-- 单个指标添加进指标库 -->
+    <el-dialog
+        :visible.sync="isOpenDialog"
+        :close-on-click-modal="false"
+        :modal-append-to-body="false"
+        top="5vh"
+        :title="$t('ManualEdbListPage.add_tobase_btn')"
+        @close="$emit('close')"
+        custom-class="add-indics-dia"
+        center
+        width="798px"
+        v-dialogDrag
+    >
+        <div class="dialog-container">
+            <el-form
+                ref="targetForm"
+                label-position="right"
+                label-width="120px"
+                hide-required-asterisk
+                :model="formData"
+                :rules="formRules"
+            >
+                <el-form-item :label="$t('Table.edb_name')" prop="edb_name">
+                    <el-input
+                    v-model="formData.edb_name"
+                    style="width: 80%"
+                    :placeholder="$t('Table.edb_name')"></el-input>
+                </el-form-item>
+                <el-form-item :label="$t('Edb.Detail.select_catalogue')" prop="menu">
+                    <el-cascader
+                    v-model="formData.menu"
+                    :options="options"
+                    :props="levelProps"
+                    style="width: 80%"
+                    clearable
+                    :placeholder="$t('CustomAnalysisPage.select_appropriate_category')"/>
+                </el-form-item>
+                <el-form-item :label="$t('Table.frequency')" prop="frequency">
+                    <el-select 
+                    v-model="formData.frequency" 
+                    :placeholder="$t('CustomAnalysisPage.select_frequency')" 
+                    style="width:80%"
+                    clearable>
+                        <el-option
+                            v-for="item in frequencyArr"
+                            :key="item.value"
+                            :label="item.label"
+                            :value="item.value">
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item :label="$t('Table.unit')">
+                    <selectUnit 
+                            v-model="formData.unit" 
+                            style="width: 80%"
+                        />
+                </el-form-item>
+            </el-form>
+        </div>
+        <div class="footer-container" slot="footer">
+            <el-button type="primary" @click="handleAddEdb" :loading="btnloading">{{ $t('Dialog.confirm_save_btn') }}</el-button>
+            <el-button type="primary" plain @click="$emit('close')">{{ $t('Dialog.cancel_btn') }}</el-button>
+        </div>
+    </el-dialog>
+</template>
+
+<script>
+import { dataBaseInterface } from '@/api/api.js';
+import { steelInterface } from "@/api/modules/thirdBaseApi";
+import selectUnit from '@/components/selectUnit.vue';
+import { frequencySelectList } from '@/utils/defaultOptions';
+export default {
+    components: { selectUnit },
+    props:{
+        isOpenDialog:{
+            type:Boolean,
+            default:false
+        },
+        edbData:{
+            type:Object,
+            defalut:{}
+        }
+    },
+    computed:{
+        formRules(){
+            return {
+                edb_name:[
+                    { required: true, message: /* '指标名称不能为空' */this.$t('Edb.Valids.name_msg'), trigger: 'blur' },
+                ],
+                menu:[
+                    { required: true, message: /* '所属目录不能为空' */this.$t('Edb.Valids.menu_msg'), trigger: 'blur' },
+                ],
+                frequency:[
+                    { required: true, message: /* '频率不能为空' */this.$t('Edb.Valids.fre_msg'), trigger: 'blur' },
+                ],
+                unit:[
+                    { required: true, message: /* '单位不能为空' */this.$t('Edb.Valids.unit_msg'), trigger: 'blur' },
+                ],
+            }
+        }
+    },
+    watch:{
+        isOpenDialog(newval){
+            if(newval){
+                this.initDia()
+            }
+        }
+    },
+    data() {
+        return {
+            formData:{
+                code:'',
+                edb_name:'',
+                menu:'',
+                frequency:'',
+                unit:'',
+            },
+            options:[],
+            levelProps: {
+                label: 'ClassifyName',
+                value: 'ClassifyId',
+                children: 'Children',
+                emitPath: false,
+                checkStrictly: true
+            },
+            frequencyArr:frequencySelectList(),
+            btnloading:false,
+        };
+    },
+    methods: {
+        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.options = res.Data.AllNodes || [];
+        },
+        async handleAddEdb(){
+            //校验表单
+            try{
+                await this.$refs.targetForm.validate()
+            }catch(e){
+                return 
+            }
+            const {code,edb_name,menu,frequency,unit} = this.formData
+            this.btnloading = true
+            //添加检测
+            const resAddCheck = await steelInterface.batchAddEdbCheck({
+                IndexCodes:[code]
+            })
+            if(resAddCheck.Ret!==200) return (this.btnloading=false)
+            //已存在提示并关闭该弹窗
+            if(resAddCheck.Data[0]&&resAddCheck.Data[0].EdbExist){
+                this.$emit('close')
+                return this.$message.warning(this.$t('YsDataPage.haved_all_msg'))
+            }
+            //重名校验
+            const resCheck = await steelInterface.batchCheckEdbName([{
+                EdbCode:code,
+                EdbName:edb_name,
+                Frequency:frequency,
+            }])
+            if(resCheck.Ret!==200) return (this.btnloading=false)
+            if(resCheck.Data[0]&&resCheck.Data[0].Exist){
+                return this.$message.warning(this.$t('BloombergPage.add_edb_check_hint2'))&&(this.btnloading=false)
+            }
+            //添加至指标库
+            const res = await steelInterface.AddToLib({
+                EdbCode:code,
+                EdbName:edb_name,
+                Unit:unit,
+                Frequency:frequency,
+                ClassifyId:Number(menu),
+            })
+            if(res.Ret!==200) return (this.btnloading=false)
+            this.$message.success(this.$t('MsgPrompt.add_msg2'))
+            this.$emit('addCallback')
+        },
+        initDia(){
+            this.btnloading=false
+            this.getClassifyOpt()
+            const {IndexName,UnitName,FrequencyName,IndexCode} = this.edbData
+            this.formData = {
+                code:IndexCode,
+                edb_name:IndexName,
+                menu:'',
+                frequency:FrequencyName,
+                unit:UnitName
+            }
+        }
+    },
+};
+</script>
+
+<style lang="scss">
+.add-indics-dia{
+    .el-cascader .el-input {
+        width: 100%;
+    }
+}
+</style>

+ 2 - 2
src/views/dataEntry_manage/thirdBase/components/batchAddEdbDia.vue

@@ -185,8 +185,8 @@ import { steelInterface } from "@/api/modules/thirdBaseApi";
       addEdbItem(){
         this.$refs.edbFormDataListRef.validate(valid=>{
           if(valid){
-            if(this.edbForm.edbDataList.length>=100){
-              this.$message.warning(/* '添加数量已达上限(上限100)!' */this.$t('SteelChemicalPage.add_max_msg'))
+            if(this.edbForm.edbDataList.length>=150){
+              this.$message.warning(/* '添加数量已达上限(上限150)!' */this.$t('SteelChemicalPage.add_max_msg'))
               return 
             }
             let lastItem = this.edbForm.edbDataList[this.edbForm.edbDataList.length-1]

+ 422 - 0
src/views/dataEntry_manage/thirdBase/components/batchAddIndicsDia.vue

@@ -0,0 +1,422 @@
+<template>
+    <!-- 批量添加至指标库 -->
+    <el-dialog
+        :visible.sync="isOpenDialog"
+        :close-on-click-modal="false"
+        :modal-append-to-body="false"
+        top="5vh"
+        :title="$t('SteelChemicalPage.batch_add_edb_btn')"
+        @close="$emit('close')"
+        custom-class="batch-add-edb-dia"
+        center
+        width="70%"
+        v-dialogDrag
+    >
+        <div class="dialog-container">
+            <div class="select-box">
+                <el-cascader v-model="searchClassify"
+                    :options="classifyList"
+                    :props="{
+                        children:'Children',
+                        label:'ClassifyName',
+                        value:'BaseFromMysteelChemicalClassifyId',
+                        multiple:true,
+                        emitPath:false,
+                    }"
+                    :placeholder="$t('Edb.InputHolderAll.input_classify')"
+                    @change="getEdbList"
+                ></el-cascader>
+                <el-input style="width:240px;" v-model="searchName"
+                    :placeholder="$t('Edb.InputHolderAll.input_name_orid')"
+                    prefix-icon="el-icon-search"
+                    @input="getEdbList"
+                />
+            </div>
+            <div class="select-table">
+                <el-table :data="edbList" border 
+                :row-class-name="tableRowClassName"
+                @selection-change="handleSelectionChange" 
+                v-loading="tableLoading">
+                    <el-table-column  type="selection" width="55" align="center"></el-table-column>
+                    <el-table-column :label="$t('Edb.Detail.e_id')" align="center" width="120" prop="edbId"></el-table-column>
+                    <el-table-column :label="$t('Table.edb_name')" align="center">
+                        <template slot-scope="{row}">
+                            <el-input v-model="row.edbName" :placeholder="$t('Table.edb_name')"></el-input>
+                        </template>
+                    </el-table-column>
+                    <el-table-column :label="$t('Edb.Detail.e_fre')" align="center" width="140">
+                        <template slot-scope="{row}">
+                            <el-select 
+                                v-model="row.frequency" 
+                                :placeholder="$t('CustomAnalysisPage.select_frequency')" 
+                                clearable>
+                                <el-option
+                                    v-for="item in frequencyArr"
+                                    :key="item.value"
+                                    :label="item.label"
+                                    :value="item.value">
+                                </el-option>
+                            </el-select>
+                        </template>
+                    </el-table-column>
+                    <el-table-column :label="$t('Edb.Detail.e_unit')" align="center" width="140">
+                        <template slot-scope="{row}">
+                            <selectUnit v-model="row.unit" />
+                        </template>
+                    </el-table-column>
+                    <!-- 操作 -->
+                    <el-table-column align="center">
+                        <template slot="header" slot-scope="{row}">
+                            <!-- <span>{{$t('EtaBasePage.catalogue_directory')}}</span> -->
+                            <el-radio-group v-model="classifyType" @change="handleClassifyTypeChange">
+                                <el-radio :label="1" style="margin-right:5px"><!-- 分目录 -->{{$t('EtaBasePage.subdirectory_radio')}}</el-radio>
+                                <el-radio :label="2"><!-- 同目录 -->{{$t('EtaBasePage.directory_radio')}}</el-radio>
+                            </el-radio-group>
+                            <el-cascader v-if="classifyType===2" v-model="selectClassify"
+                                :options="edbClassifyList"
+                                :props="{
+                                    label: 'ClassifyName',
+                                    value: 'ClassifyId',
+                                    children: 'Children',
+                                    checkStrictly: true,
+                                    emitPath:false
+                                }"
+                                :placeholder="$t('SteelChemicalPage.batch_add_placeholder')"
+                            >
+                            </el-cascader>
+                        </template>
+                        <template slot-scope="{row,$index}">
+                            <el-cascader 
+                                v-model="row.classify"
+                                :options="edbClassifyList"
+                                :props="{
+                                    label: 'ClassifyName',
+                                    value: 'ClassifyId',
+                                    children: 'Children',
+                                    checkStrictly: true,
+                                    emitPath:false
+                                }"
+                                :placeholder="$t('SteelChemicalPage.batch_add_placeholder')"
+                                style="width:100%;"
+                                :disabled="classifyType===2"
+                            ></el-cascader>
+                        </template>
+                    </el-table-column>
+                    <div class="no-data" slot="empty">
+                        <tableNoData :text="$t('Table.prompt_slogan')"/>
+                    </div>
+                </el-table>
+            </div>
+        </div>
+        <div class="footer-container" slot="footer">
+            <el-button type="primary" plain @click="$emit('close')">{{ $t('Dialog.cancel_btn') }}</el-button>
+            <el-button type="primary" @click="handleAddEdb" :loading="btnloading">{{ $t('ManualEdbListPage.add_tobase_btn') }}</el-button>
+        </div>
+        <!-- 操作提示弹窗 -->
+        <el-dialog 
+            :title="$t('BloombergPage.operation_prompt')"
+            :visible.sync="isHintDiaShow"
+            :close-on-click-modal="false"
+            :modal-append-to-body="false"
+            @close="handleCloseDia"
+            width="578px"
+            v-dialogDrag
+            center>
+            <div class="hint-dialog-wrap">
+                <p style="margin-bottom: 20px;">{{ hintText }}</p>
+                <ul>
+                    <li v-for="(item,index) in hintList" :key="index" class="hint-item" @click="gotoEdbDetail(item)">
+                        {{ index+1 }}、{{ item.IndexName }}({{ item.IndexCode }})
+                    </li>
+                </ul>
+            </div>
+            <div style="text-align: center;margin-bottom: 30px;">
+                    <el-button type="primary" @click="handleCloseDia">{{$t('Dialog.known')}}</el-button>
+                </div>
+        </el-dialog>
+    </el-dialog>
+</template>
+
+<script>
+import { steelInterface } from "@/api/modules/thirdBaseApi";
+import { dataBaseInterface } from '@/api/api.js';
+import selectUnit from '@/components/selectUnit.vue';
+import { frequencySelectList } from '@/utils/defaultOptions';
+export default {
+    components:{ selectUnit },
+    props:{
+        isOpenDialog:{
+            type:Boolean,
+            default:false
+        }
+    },
+    watch:{
+        isOpenDialog(newval){
+            if(newval){
+                this.initDia()
+            }
+        }
+    },
+    data() {
+        return {
+            classifyList:[],//钢联化工数据库的目录
+            searchName:'',
+            searchClassify:'',
+            classifyType:1,//1分目录 2同目录
+            selectClassify:'',
+            frequencyArr:frequencySelectList(),
+            edbList:[
+                /* {
+                    edbId:'123456',
+                    edbName:'指标名称指标名称',
+                    frequency:'日度',
+                    unit:'吨',
+                    classify:'',
+                    isHighlight:false
+                }, */
+            ],
+            tableLoading:false,
+            edbClassifyList:[],//指标库目录
+            selectEdbList:[],//勾选的指标
+
+            isHintDiaShow:false,
+            hintList:[],
+            hintText:'',
+            btnloading:false,
+        };
+    },
+    methods: {
+        tableRowClassName({row}){
+            return row.isHighlight?'highlight-row':''
+        },
+        initDia(){
+            this.getClassifyList()
+            this.getClassifyOpt()
+            this.searchClassify = ''
+            this.searchName = ''
+            this.edbList = []
+            this.selectEdbList = []
+            this.selectClassify=''
+            this.btnloading=false
+        },
+        //获取钢联化工数据库目录
+        getClassifyList(){
+            steelInterface.classifyList().then((res) => {
+                if(res.Ret!==200) return 
+                this.classifyList = res.Data||[]
+            })
+        },
+        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.edbClassifyList = res.Data.AllNodes || [];
+        },
+        //获取对应目录下的钢联化工指标
+        getEdbList(){
+            //每一次筛选项改变清空选择框
+            this.selectEdbList = []
+            this.classifyType = 1
+            //tableData
+            this.tableLoading = true
+            steelInterface.searchEdbBatch({
+                BaseFromMysteelChemicalClassifyIds:Array.isArray(this.searchClassify)?this.searchClassify.join(','):'',
+                Keyword:this.searchName||''
+            }).then(res=>{
+                this.tableLoading = false
+                if(res.Ret!==200) return 
+                this.edbList = res.Data?res.Data.map(item=>{
+                    return {
+                        edbId:item.IndexCode||'',
+                        edbName:item.IndexName||'',
+                        frequency:item.FrequencyName||'',
+                        unit:item.UnitName||'',
+                        classify:'',
+                        isHighlight:false
+                    }
+                }):[]
+            })
+           
+        },
+        handleSelectionChange(val){
+            this.selectEdbList = val
+        },
+        handleAddEdb(){
+            //校验所选指标
+            if(!this.selectEdbList.length){
+                return this.$message.warning(this.$t('Edb.InputHolderAll.input_select_edb'))
+            }
+            if(this.selectEdbList.length>30){
+                return this.$message.warning(this.$t('SteelChemicalPage.batch_add_max_msg'))
+            }
+            //校验所选指标信息是否完整
+            if(this.classifyType===2&&!this.selectClassify){
+                return this.$message.warning(this.$t('CustomAnalysisPage.select_appropriate_category'))
+            }
+            //重置tableData的高亮
+            this.edbList.forEach(i=>i.isHighlight=false)
+            let messageList = [] //有问题的列表
+            this.selectEdbList.forEach((item)=>{
+                item.isHighlight=false
+                if(!this.checkEdbData(item)){
+                    item.isHighlight = true
+                    messageList.push(item)
+                }
+            })
+            //message轻提示 同时标出不完整的行
+            if(messageList.length){
+                return this.$message.warning(/* '部分指标信息未填写完整,请检查' */this.$t('SteelChemicalPage.batch_add_hint1'))
+            }
+
+            this.btnloading = true
+            //添加检测
+            steelInterface.batchAddEdbCheck({
+                IndexCodes:this.selectEdbList.map(i=>i.edbId)
+            }).then(res=>{
+                if(res.Ret!==200) return (this.btnloading=false)
+                const edbList = res.Data||[]
+                const afterAddList = edbList.filter(i=>i.EdbExist===1) //已添加进指标库的指标
+                const beforeAddList = edbList.filter(i=>i.EdbExist===0) //需要添加进指标库的指标
+                //已选择的指标均添加进指标库 弹窗提示
+                if(!beforeAddList.length){
+                    return this.showHintDialog('all',afterAddList)
+                }
+                //剩余指标进行重名校验
+                this.batchNameCheck(afterAddList,beforeAddList)
+            })
+            
+        },
+        //重名检测
+        batchNameCheck(afterAddList,beforeAddList){
+            const indexCodeList = beforeAddList.map(i=>i.IndexCode)
+            let checkList = []
+            indexCodeList.forEach(i=>{
+                const item = this.selectEdbList.find(s=>s.edbId===i)
+                item&&checkList.push(item)
+            })
+            steelInterface.batchCheckEdbName(checkList.map(i=>{
+                return {
+                    EdbCode:i.edbId,
+                    EdbName:i.edbName,
+                    Frequency:i.frequency
+                }
+            })).then(res=>{
+                if(res.Ret!==200) return (this.btnloading=false)
+                const checkedList = res.Data.filter(i=>i.Exist)
+                if(checkedList.length){
+                    checkedList.forEach(i=>{
+                        const item = this.selectEdbList.find(s=>s.edbId===i.EdbCode)
+                        item&&(item.isHighlight = true)
+                    })
+                    return this.$message.warning(/* '部分指标名称已存在,请重新填写' */this.$t('SteelChemicalPage.batch_add_hint2'))&&(this.btnloading=false)
+                }else{
+                    //通过重名校验后添加进指标库
+                    this.batchAddEdb(afterAddList,checkList)
+                }
+            })
+            
+        },
+        checkEdbData(edbData){
+            return edbData.edbName&&edbData.frequency&&edbData.unit&&(this.classifyType===1?edbData.classify:true)
+        },
+        //显示操作提示弹窗
+        showHintDialog(type,list){
+            this.btnloading = false
+            this.isHintDiaShow = true
+            this.hintList = list
+            this.hintText = type==='all'
+            ?this.$t('YsDataPage.haved_all_msg') //本次添加的指标均已在指标库中,请勿重复添加!
+            :this.$t('YsDataPage.haved_some_msg') //指标库中已存在以下指标,会自动过滤!
+        },
+        //添加进指标库
+        batchAddEdb(afterAddList=[],checkList){
+            //checkList
+            steelInterface.batchAddToLib(checkList.map(i=>{
+                return {
+                    EdbCode:i.edbId,
+                    EdbName:i.edbName,
+                    Unit:i.unit,
+                    Frequency:i.frequency,
+                    ClassifyId:this.classifyType===1?Number(i.classify):Number(this.selectClassify),
+                }
+            })).then(res=>{
+                if(res.Ret!==200) return (this.btnloading=false)
+                //若afterAddList有值 弹窗提示部分指标已加入
+                if(afterAddList.length){
+                    this.showHintDialog('',afterAddList)
+                }else{
+                    this.$message.success(this.$t('MsgPrompt.add_msg2'))
+                    this.$emit('close')
+                }
+            })
+            
+            
+        },
+        //跳转至指标库
+        gotoEdbDetail(data){
+            const {EdbClassifyId,EdbInfoId,EdbUniqueCode} = data||{}
+            const href = this.$router.resolve({
+                path:'/database',
+                query:{
+                    code:EdbUniqueCode,
+                    id:EdbInfoId,
+                    classifyId:EdbClassifyId,
+                }
+            }).href
+            window.open(href,"_blank")
+        },
+        handleCloseDia(){
+            //两个弹窗都关掉
+            this.isHintDiaShow=false
+            this.$emit('close')
+        }
+    },
+};
+</script>
+
+<style lang="scss">
+.batch-add-edb-dia{
+    .dialog-container{
+        .el-input{
+            width:100%;
+        }
+        .el-table .highlight-row{
+            background-color:#fef0f0 !important;
+        }
+    }
+}
+</style>
+<style scoped lang="scss">
+.batch-add-edb-dia{
+    .dialog-container{
+        .select-box{
+            margin-bottom:20px;
+        }
+        .select-table{
+            max-height:600px;
+            overflow-y:auto;
+        }
+    }
+    .hint-dialog-wrap{
+            padding-bottom:30px;
+            .hint-item{
+                cursor: pointer;
+                margin-bottom: 10px;
+                &:hover{
+                    color:#409EFF;
+                    text-decoration: underline;
+                }
+            }
+        }
+}
+</style>

+ 721 - 0
src/views/dataEntry_manage/thirdBase/components/highFrequency/addHighFrequencyData.vue

@@ -0,0 +1,721 @@
+<template>
+  <div>
+		<el-dialog :visible.sync="isAddShow" :close-on-click-modal="false" :modal-append-to-body='false' 
+    @close="cancelHandle" top="5vh" center :width="addStep==1?'1250px':'1208px'" v-dialogDrag 
+    :title="$t('HighFrequencyData.add_high_frequency_data')">
+      <div class="dialog-container" v-loading="isLoadingData" :element-loading-text="$t('Table.loading')">
+        <div v-if="addStep==1">
+          <div class="data-query-box">
+            <el-input :placeholder="$t('EtaBasePage.stocks_input_pholder')" v-model.trim="securityCodeText" 
+            class="query-index-input" style="margin-bottom: 20px;" @blur="codeInputBlur('stock')"></el-input>
+            <div class="query-index-code">
+              <el-input :placeholder="$t('EtaBasePage.edb_input_pholder')" v-model.trim="indexCodeText" 
+              class="query-index-input" @blur="codeInputBlur('index')"></el-input>
+            </div>
+            <el-checkbox-group v-model="indexCodeSelected" style="margin-bottom: 20px;" @change="indexCodeSelectHandle">
+              <el-checkbox :label="item.value" v-for="item in indexCodeArr" :key="item.value" style="margin-right: 20px;">{{ item.label }}</el-checkbox>
+            </el-checkbox-group>
+            <div class="high-frequency-code-row" style="margin-top: -10px;" v-if="indexCode && indexCode.length>0">
+							<div class="high-frequency-code-item" v-for="item in indexCode" :key="item">
+								<div class="high-frequency-code-item-text">{{ item }}</div>
+								<img src="~@/assets/img/icons/close_icon_black.png" @click="deleteCode(item)" />
+							</div>
+						</div>
+            <div class="time-range-row">
+              <!-- 起始时间 -->
+              <div class="start-time-row">
+                <span>{{ $t('Edb.Detail.e_start_time') }}</span>
+                <el-date-picker
+                  class="date-picker"
+                  v-model="otherParams.startDate"
+                  value-format="yyyy-MM-dd"
+                  type="date"
+                  :placeholder="$t('Edb.InputHolderAll.input_date')">
+                </el-date-picker>
+                <el-time-picker
+                  class="time-picker"
+                  value-format="HH:mm:ss"
+                  v-model="otherParams.startTime"
+                  :placeholder="$t('Edb.InputHolderAll.input_time')">
+                </el-time-picker>
+              </div>
+              <div class="end-time-row"><!-- 截止时间 -->
+                <span>{{ $t('Edb.Detail.e_deadline_time') }}</span>
+                <el-radio v-model="otherParams.deadlineType" label="1">{{ $t('Common.latest') }}</el-radio>
+                <el-radio v-model="otherParams.deadlineType" label="2">{{ $t('Common.fixed') }}</el-radio>
+                <template v-if="otherParams.deadlineType=='2'">
+                  <el-date-picker
+                    class="date-picker"
+                    value-format="yyyy-MM-dd"
+                    v-model="otherParams.deadlineDate"
+                    type="date"
+                    :placeholder="$t('Edb.InputHolderAll.input_date')">
+                  </el-date-picker>
+                  <el-time-picker
+                    class="time-picker"
+                    value-format="HH:mm:ss"
+                    v-model="otherParams.deadlineTime"
+                    :placeholder="$t('Edb.InputHolderAll.input_time')">
+                  </el-time-picker>
+                </template>
+              </div>
+            </div>
+            <div class="time-cycle">
+              <!-- 时间周期 -->
+              <div class="time-cycle-item">
+                <span>{{ $t('HighFrequencyData.period') }}</span>
+                <el-select v-model="otherParams.period" :placeholder="$t('Edb.please_select')">
+                  <el-option
+                    v-for="item in periodList"
+                    :key="item"
+                    :label="item"
+                    :value="item">
+                  </el-option>
+                </el-select>
+              </div>
+              <!-- 复权方式 -->
+              <div class="time-cycle-item">
+                <span>{{ $t('HighFrequencyData.adjustment') }}</span>
+                <el-select v-model="otherParams.adjustment" :placeholder="$t('Edb.please_select')">
+                  <el-option
+                    v-for="item in adjustmentList"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value">
+                  </el-option>
+                </el-select>
+              </div>
+              <!-- 复权基点 -->
+              <div class="time-cycle-item" v-show="otherParams.adjustment!='no'">
+                <span>{{ $t('HighFrequencyData.base_point') }}</span>
+                <el-date-picker
+                  class="date-picker"
+                  v-model="otherParams.basePoint"
+                  value-format="yyyy-MM-dd"
+                  type="date"
+                  :placeholder="$t('Edb.InputHolderAll.input_date')">
+                </el-date-picker>
+              </div>
+            </div>
+            <div class="interval">
+              <span>{{ $t('HighFrequencyData.no_interval_handle') }}</span>
+              <el-select v-model="otherParams.noIntervalHandle" :placeholder="$t('Edb.please_select')">
+                <el-option
+                  v-for="item in noIntervalHandleList"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value">
+                </el-option>
+              </el-select>
+            </div>
+          </div>
+          <div class="dia-bot">
+            <el-button type="primary" @click="nextHandle" :disabled="!isCodeComplete"
+            style="width: 120px;" :loading="isLoadingData" ><!-- 下一步 -->{{$t('EtaBasePage.next_step')}}
+            </el-button>
+          </div>
+        </div>
+        <template v-else>
+          <div class="edb-table-preview">
+            <table width="auto" border="0">
+              <thead>
+                <tr v-for="(item, index) in edbTableHeadKey" :key="item">
+                  <td class="sticky" style="text-align: center;left: 0;text-align: center;position: sticky;z-index: 101;">
+                    {{ edbTableHeadData.get(item) }}
+                    <template v-if="item == 'ClassifyId'">
+                      <br />
+                      <el-radio-group v-model="classifyType" @change="handleClassifyTypeChange" style="margin-top: 5px;">
+                        <el-radio :label="0" style="margin-right: 8px;"><!-- 同目录 -->{{$t('EtaBasePage.directory_radio')}}</el-radio>
+                        <el-radio :label="1"><!-- 分目录 -->{{$t('EtaBasePage.subdirectory_radio')}}</el-radio>
+                      </el-radio-group>
+                    </template>
+                  </td>
+                  <td v-for="(data, sub_index) in edbIndexDatas" :key="sub_index" class="body-td"
+                  :class="highLightIndex.includes(data.IndexName) && item=='IndexName' ?'exist-highlight':''">
+                    <template v-if="item === 'ClassifyId'">
+                      <el-cascader :options="classifyList" v-model="data[item]" :placeholder="$t('Edb.InputHolderAll.input_menu')"
+                       :disabled="(classifyType===0&&sub_index>0)" @change="handleClassifyChange(data)"
+                      :props="{label: 'ClassifyName',
+                        value: 'ClassifyId',
+                        children: 'Children',
+                        checkStrictly: true,
+                        emitPath:false}">
+                      </el-cascader>
+                    </template>
+                    <template v-else-if="item === 'Unit'">
+                      <el-autocomplete
+                        v-model.trim="data[item]"
+                        :fetch-suggestions="querySearchUnit"
+                        :placeholder="$t('Edb.InputHolderAll.input_unit')"
+                        suffix-icon="el-icon-arrow-down"
+                        size="mini"
+                      ></el-autocomplete>
+                    </template>
+                    <template v-else-if="item === 'IndexName'">
+                      <el-input v-model.trim="data[item]" :placeholder="$t('Edb.InputHolderAll.input_name')" size="mini"></el-input>
+                    </template>
+                    <template v-else>
+                      <div style="padding: 0 7px;">{{ data[item] }}</div>
+                    </template>
+                  </td>
+                </tr>
+              </thead>
+              <tbody v-if="edbIndexDatas && edbIndexDatas.length>0">
+                <tr>
+                  <td class="body-td sticky" style="left: 0;text-align: center;height: 330px;text-align: center;position: sticky;z-index: 101;">
+                    <!-- 数据详情 -->{{$t('Edb.data_detail_tab')}}
+                  </td>
+                  <!-- <template > -->
+                    <td class="body-td" style="height: 330px;padding: 0;" v-for="(item,index) in edbIndexDatas" :key="index">
+                      <!-- {{ 'edbIndexDatas[index1].DataList[index].DataTime' }} -->
+                      <div class="td-box">
+                        <div class="data-item" v-for="(item1,index1) in edbIndexDatas[index].DataList">
+                          <span >{{ edbIndexDatas[index].DataList[index1].DataTime }}</span>
+                          <span >{{ edbIndexDatas[index].DataList[index1].Value }}</span>
+                        </div>
+                      </div>
+                    </td>
+                    <!-- <td></td>
+                  </template> -->
+                </tr>
+              </tbody>
+            </table>
+          </div>
+          <div class="dia-bot">
+            <el-button @click="prevHandle" style="width: 120px;"><!-- 上一步 -->{{$t('Dialog.prev_step')}}</el-button>
+            <el-button type="primary" @click="saveHandle" style="width: 120px;margin-left: 50px;"><!-- 保存 -->{{$t('Dialog.confirm_save_btn')}}</el-button>
+          </div>
+        </template>
+      </div>
+
+		</el-dialog>
+    <el-dialog :visible.sync="checkFailShow" :close-on-click-modal="false" :modal-append-to-body='false' 
+			width="600px" :title="$t('Dialog.operation_prompt')">
+			<div class="check-fail-box">
+				<div>
+					<div style="margin-bottom: 20px;">{{$t('EtaBasePage.exist_edb_tips')}}</div>
+					<div v-for="(item,index) in existIndexList" :key="index">
+						{{ index+1+'、'+item.text }}
+					</div>
+				</div>
+				<div class="check-fail-button">
+					<el-button type="primary" @click="checkFailShow=false" style="width: 120px;">{{$t('MsgPrompt.known')}}</el-button>
+				</div>
+			</div>
+		</el-dialog>
+  </div>
+</template>
+
+<script>
+import { highFrequencyDataInterface } from '@/api/api.js'
+  export default {
+    name:"addHighFrequencyData",
+    props: {
+      isAddShow: {
+        type: Boolean,
+        default:false
+      },
+      unitList:{
+        type:Boolean,
+        default:()=>[]
+      },
+      classifyList:{
+        type:Boolean,
+        default:()=>[]
+      }
+    },
+    data() {
+      return {
+        isLoadingData:false,
+        addStep:1,
+        securityCodeText:"",
+        securityCodeLimit:10,
+        indexCodeText:"",
+        indexCode:[],
+        indexCodeLimit:20,
+        indexCodeSelected:[],
+        periodList:[1,3,5,10,15,30,60],
+        otherParams:{
+          startDate:this.$moment(new Date()).subtract(6, 'months').format('YYYY-MM-DD'),
+          startTime:'09:15:00',
+          deadlineType:'1',
+          deadlineDate:this.$moment(new Date()).format('YYYY-MM-DD'),
+          deadlineTime:'09:15:00',
+          period:1,
+          adjustment:'no',
+          basePoint:'1900-01-01',
+          noIntervalHandle:'Original'
+        },
+        edbIndexDatas:[],
+        checkFailShow:false,
+        existIndexList:[],
+        edbTableHeadKey: [
+          "ClassifyId",
+          "Unit",
+          "Frequency",
+          "IndexName",
+          "EdbCode",
+        ],
+        classifyType:0,
+        highLightIndex:[],
+      }
+    },
+    computed:{
+      isCodeComplete(){
+        return this.securityCodeText && (this.indexCode.length>0 || this.indexCodeSelected.length>0) && this.otherParams.startDate && 
+                this.otherParams.startTime && this.otherParams.period && this.otherParams.adjustment && this.otherParams.basePoint && 
+                (this.otherParams.deadlineType=='1' || (this.otherParams.deadlineType=='2' && this.otherParams.deadlineDate && this.otherParams.deadlineTime) )&&
+                this.otherParams.noIntervalHandle
+      },
+      // 常用的指标代码
+      indexCodeArr(){
+        return [
+          {value:'open',label:this.$t('EtaBasePage.op_price')/* "开盘价" */},
+          {value:'high',label:this.$t('EtaBasePage.high_price')/* "最高价" */},
+          {value:'low',label:this.$t('EtaBasePage.low_price')/* "最低价" */},
+          {value:'avgprice',label:this.$t('EtaBasePage.average_price')/* "均价" */},
+          {value:'close',label:this.$t('EtaBasePage.close_price')/* "收盘价" */},
+          {value:'volume',label:this.$t('EtaBasePage.trade_volume')/* "成交量" */},
+          {value:'amt',label:this.$t('EtaBasePage.turnover')/* "成交额" */},
+          {value:'pct_chg',label:this.$t('EtaBasePage.incre_decre')/* "涨跌幅" */},
+          {value:'oi',label:this.$t('EtaBasePage.open_inter')/* "持仓量" */}
+        ]
+      },
+      // currentLang() {
+      //   return this.$store.state.lang
+      // },
+      adjustmentList(){
+        return [
+          {label:this.$t('HighFrequencyData.no_rehabilitation'),value:'no'},
+          {label:this.$t('HighFrequencyData.forward_rehabilitation_1'),value:'forward1'},
+          {label:this.$t('HighFrequencyData.backward_rehabilitation_1'),value:'backward1'},
+          {label:this.$t('HighFrequencyData.forward_rehabilitation_3'),value:'forward3'},
+          {label:this.$t('HighFrequencyData.backward_rehabilitation_3'),value:'backward3'},
+          {label:this.$t('HighFrequencyData.forward_rehabilitation_2'),value:'forward2'},
+          {label:this.$t('HighFrequencyData.backward_rehabilitation_2'),value:'backward2'},
+          {label:this.$t('HighFrequencyData.forward_rehabilitation_4'),value:'forward4'},
+          {label:this.$t('HighFrequencyData.backward_rehabilitation_4'),value:'backward4'},
+        ]
+      },
+      noIntervalHandleList(){
+        return [
+          {label:this.$t('HighFrequencyData.original'),value:'Original'},
+          {label:this.$t('HighFrequencyData.previous'),value:'Previous'},
+          {label:this.$t('HighFrequencyData.blank'),value:'Blank'}
+        ]
+      },
+      edbTableHeadData(){
+        return new Map([
+          ["ClassifyId", /* "所属目录" */this.$t('EtaBasePage.belong_menu')],
+          ["Unit", /* "单位" */this.$t('Edb.Detail.e_unit')],
+          ["Frequency", /* "频度" */this.$t('Edb.Detail.e_fre')],
+          ["IndexName", /* "指标名称" */this.$t('Edb.Detail.e_name')],
+          ["StockCode", /* "证券代码" */this.$t('Edb.Detail.e_stock_code')],
+          ["EdbCode", /* "指标代码" */this.$t('Edb.Detail.e_code')],
+        ])
+      },
+    },
+    methods: {
+      init(){
+        this.isLoadingData=false
+        this.addStep=1
+        this.securityCodeText=""
+        this.indexCodeText=""
+        this.indexCode=[]
+        this.indexCodeSelected=[]
+        this.otherParams={
+          startDate:this.$moment(new Date()).subtract(6, 'months').format('YYYY-MM-DD'),
+          startTime:'09:15:00',
+          deadlineType:'1',
+          deadlineDate:this.$moment(new Date()).format('YYYY-MM-DD'),
+          deadlineTime:'09:15:00',
+          period:1,
+          adjustment:'no',
+          basePoint:'1900-01-01',
+          noIntervalHandle:'Original'
+        }
+      },
+      cancelHandle() {
+        this.init()
+        this.$emit('update:isAddShow',false)
+      },
+      //搜索单位
+      querySearchUnit(queryString, cb){
+        let results = queryString ? this.unitList.filter(item=>item.value.indexOf(queryString) === 0) : this.unitList;
+        // 调用 callback 返回建议列表的数据
+        cb(results);
+      },
+      // 指标代码和证券代码输入失焦
+      codeInputBlur(type){
+        if(type=='stock'){
+          if(!this.securityCodeText) return
+          this.securityCodeText=this.securityCodeText.replaceAll(' ','')
+          let arr = this.securityCodeText.split(',')
+          if(arr.length>this.securityCodeLimit){
+            this.$message.warning(this.$t('HighFrequencyData.stock_code_numer_prompt'))
+            this.securityCodeText=arr.slice(0,this.securityCodeLimit).join(',')
+          }
+        }else{
+          if(!this.indexCodeText) return  
+          this.indexCodeText=this.indexCodeText.replaceAll(' ','')
+          let arr = Array.from(new Set([...this.indexCode,...this.indexCodeText.split(',')]))
+          if(arr.length+this.indexCodeSelected.length>this.indexCodeLimit){
+            this.$message.warning(this.$t('HighFrequencyData.index_code_numer_prompt'))
+            this.indexCode=arr.slice(0,(this.indexCodeLimit-this.indexCodeSelected.length))
+          }else{
+            this.indexCode=arr
+          }
+          this.indexCodeText=''
+        }
+      },
+      deleteCode(code){
+        this.indexCode = this.indexCode.filter(it => it!=code)
+      },
+      indexCodeSelectHandle(){
+        if(this.indexCode.length+this.indexCodeSelected.length>this.indexCodeLimit){
+          this.$message.warning(this.$t('HighFrequencyData.index_code_numer_prompt'))
+          this.indexCodeSelected=this.indexCodeSelected.slice(0,(this.indexCodeLimit-this.indexCode.length))
+        }
+      },
+      nextHandle(){
+        let StartTime = this.otherParams.startDate+" "+this.otherParams.startTime
+        let EndTime = this.otherParams.deadlineType=='2'?this.otherParams.deadlineDate+" "+this.otherParams.deadlineTime:''
+        if(EndTime && !(new Date(EndTime)>new Date(StartTime))){
+          return this.$message.warning(this.$t('HighFrequencyData.start_time_right_end_time'))
+        }
+        setTimeout(()=>{
+          if(this.isCodeComplete){
+            let params={
+              EdbCode:Array.from(new Set([...this.indexCode,...this.indexCodeSelected])).join(','),
+              StockCode:this.securityCodeText,
+              StartTime,
+              EndTime,
+              Interval:+this.otherParams.period,
+              Fill:this.otherParams.noIntervalHandle,
+              CPS:this.otherParams.adjustment,
+              BaseDate:this.otherParams.basePoint
+            }
+            this.isLoadingData=true
+            highFrequencyDataInterface.checkHighFreData(params).then(res=>{
+              if(res.Ret == 200){
+                if(res.Data.ExistIndex && res.Data.ExistIndex.length>0){
+                  // 有重复
+                  this.existIndexList=[]
+                  let existEdbInfo=res.Data.ExistIndex || []
+                  let text=''
+                  existEdbInfo.map(item =>{
+                    text=`${item.IndexName}(${item.IndexCode})`
+                    this.existIndexList.push({text,id:item.IndexId})
+                  })
+                  this.checkFailShow=true
+                  this.isLoadingData=false
+                }else{
+                  // 没有重复
+                  highFrequencyDataInterface.searchHighFreData(params).then(res => {
+                    if(res.Ret == 200){
+                      let stockList = res.Data || []
+                      this.edbIndexDatas=[]
+                      stockList.map((item,index) =>{
+                        let batchParams={
+                          ClassifyId:0,
+                          Unit:'',
+                          Frequency:item.Frequency+'m',
+                          IndexName:item.IndexName,
+                          EdbCode:item.EdbCode,
+                          StockCode:item.StockCode
+                        }
+                        let datas = item.IndexData || []
+                        let datasLength = datas.length
+                        if( datasLength<10){
+                          for (let i = datasLength; i < 10; i++) {
+                            datas.push({DataTime:'',Value:''})													
+                          }
+                        }
+                        this.edbIndexDatas.push({...batchParams,DataList:datas})
+                      })
+
+                      let edbIndexDataLength = this.edbIndexDatas.length
+                      //填充空的列
+                      for (let i = edbIndexDataLength; i < 4; i++) {
+                        this.edbIndexDatas.push({
+                          ClassifyId:0,
+                          Unit:'',
+                          Frequency:'',
+                          IndexName:'',
+                          EdbCode:'',
+                          StockCode:'',
+                          DataList:new Array(10).fill({DataTime:'',Value:''})
+                        })
+                      }
+                      this.highLightIndex=[]
+                      this.classifyType=0
+
+                      this.addStep=2
+                    }
+                  }).finally(()=>{
+                    this.isLoadingData=false
+                  })
+                }
+              }
+            })
+          }
+        },10)
+      },
+      prevHandle(){
+        this.addStep=1
+      },
+      // 同目录修改
+      handleClassifyChange(e,index){
+        if(this.classifyType===0){
+          // 修改所有的指标的目录为第一个
+          this.edbIndexDatas.forEach(item=>{
+            item.ClassifyId=e.ClassifyId
+          })
+        }
+      },
+      handleClassifyTypeChange(){
+        this.handleClassifyChange(this.edbIndexDatas[0])
+      },
+      saveHandle(){
+        let flag = this.edbIndexDatas.some(it => {
+          return (it.StockCode && it.EdbCode) && ((!it.ClassifyId) || (!it.Unit) || (!it.IndexName))
+        })
+        if(flag){
+          this.$message.warning(/* "指标信息未填写完整" */this.$t('BloombergPage.add_edb_check_hint1'))
+          return 
+        }
+        this.isLoadingData=true
+        const IndexList=this.edbIndexDatas.map(data=>{
+          if(data.StockCode && data.EdbCode){
+            return {
+              ClassifyId:data.ClassifyId,
+              StockCode:data.StockCode,
+              EdbCode:data.EdbCode,
+              IndexName:data.IndexName,
+              Frequency:data.Frequency,
+              Unit:data.Unit,
+            }
+          }else{
+            return ''
+          }
+        }).filter(Boolean)
+        let StartTime = this.otherParams.startDate+" "+this.otherParams.startTime
+        let EndTime = this.otherParams.deadlineType=='2'?this.otherParams.deadlineDate+" "+this.otherParams.deadlineTime:''
+        let addParams={
+          IndexList,
+          StartTime,
+          EndTime,
+          Interval:+this.otherParams.period,
+          Fill:this.otherParams.noIntervalHandle,
+          CPS:this.otherParams.adjustment,
+          BaseDate:this.otherParams.basePoint
+        }
+        highFrequencyDataInterface.addHighFreDatas(addParams).then(res=>{
+          console.log(res,'mres');
+          if(res.Ret == 200){
+            this.$message.success(/* "添加指标成功" */this.$t('MsgPrompt.add_msg2'))
+            this.$emit('addSuccessHandle')	
+            this.cancelHandle()	
+          }
+          // else if(res.Ret == 403){
+          //   this.highLightIndex=res.Data?res.Data.ExistEdbName || []:[]
+          // }
+        }).finally(()=>{
+          this.isLoadingData=false
+        })
+      }
+    },
+  }
+</script>
+
+<style lang="scss" scoped>
+.dialog-container{
+  padding: 0 35px 35px;
+  .data-query-box{
+		padding-top: 20px;
+		.query-index-code{
+			display: flex;
+			align-items: center;
+			margin-bottom: 20px;
+		}
+		.query-index-input{
+			min-width: 490px;
+			width:490px;
+			margin-right: 10px;
+		}
+    .high-frequency-code-row{
+			margin-top: 10px;
+			min-height: 60px;
+			display: flex;
+			align-items: center;
+			flex-wrap: wrap;
+			.high-frequency-code-item{
+				height: 40px;
+				background-color: #EBEFF6;
+				display: flex;
+				align-items: center;
+				margin-right: 10px;
+				padding: 10px;
+				box-sizing: border-box;
+				margin-bottom: 10px;
+				.high-frequency-code-item-text{
+					color: #333333;
+					margin-right: 10px;
+				}
+				img{
+					height: 16px;
+					width: 16px;
+					cursor: pointer;
+				}
+			}
+		}
+    .time-range-row{
+      display: flex;
+      align-items: center;
+      margin-bottom: 20px;
+      .start-time-row{
+        margin-right: 40px;
+      }
+      .start-time-row,.end-time-row{
+        display: flex;
+        align-items: center;
+        span{
+          white-space: nowrap;
+          margin-right: 10px
+        }
+        .date-picker{
+          width: 240px;
+          margin-right: 10px
+        }
+        .time-picker{
+          width: 120px;
+        }
+      }
+      .end-time-row{
+        .el-radio{
+          margin-right: 10px;
+        }
+      }
+    }
+    .time-cycle{
+      display: flex;
+      align-items: center;
+      margin-bottom: 20px;
+      .time-cycle-item{
+        margin-right: 10px;
+        span{
+          margin-right: 10px;
+          white-space: nowrap;
+        }
+        .el-select{
+          width: 140px;
+        }
+        .el-date-editor{
+          width: 240px;
+        }
+      }
+    }
+    .interval{
+      display: flex;
+      align-items: center;
+      margin-bottom: 20px;
+      span{
+        margin-right: 10px;
+        white-space: nowrap;
+      }
+      .el-select{
+        width: 140px;
+      }
+    }
+	}
+  .dia-bot {
+		margin: 60px 0 0;
+		display: flex;
+		justify-content: center;
+	}
+}
+.check-fail-box{
+  padding: 0 0 15px 40px;	
+  color: #333333;
+  .check-fail-button{
+    margin-top: 80px;
+    display: flex;
+    justify-content: flex-end;
+  }
+}
+.edb-table-preview {
+  overflow: auto;
+  height: calc(100% - 124px);
+  &::-webkit-scrollbar {
+    width: 5px !important;
+  }
+  table {
+    border-color: #dcdfe6;
+    border-bottom: 1px solid #dcdfe6;
+    border-right: 1px solid #dcdfe6;
+    border-collapse: separate;
+  }
+  td {
+    height: 30px;
+    // text-align: center;
+    color: #333;
+    box-sizing: border-box;
+    padding: 0 5px;
+    background-color: #fff;
+    border-top: 1px solid #dcdfe6;
+    border-left: 1px solid #dcdfe6;
+  }
+  .body-td{
+    max-width: 217px;
+    min-width: 217px;
+  }
+  thead {
+    position: sticky;
+    z-index: 2;
+    top: 0;
+  }
+  .td-box{
+    height: 100%;
+    width: 100%;
+    overflow: auto;
+    .data-item{
+      border-bottom: 1px solid #dcdfe6;
+      padding: 0 5px;
+      box-sizing: border-box;
+      min-height: 30px;
+      display: flex;
+      align-items: center;
+      flex-wrap: wrap;
+      gap: 8px;
+      span{
+        white-space: nowrap;
+      }
+    }
+  }
+  .exist-highlight{
+    border: red solid 1px;
+  }
+}
+</style>
+<style lang="scss">
+.edb-table-preview{
+  border: 1px solid #dcdfe6;
+  .el-cascader{
+    width: 100%;
+  }
+  .el-autocomplete{
+    width: 100%;
+  }
+  .el-select{
+    width: 100%;
+  }
+  .el-input{
+    width: 100%;
+    input{
+      border: none;
+      padding-left: 7px;
+      font-size: 14px;
+    }
+  }
+}
+</style>

+ 473 - 0
src/views/dataEntry_manage/thirdBase/components/highFrequency/addToIndexDatabaseBatch.vue

@@ -0,0 +1,473 @@
+<template>
+  <el-dialog :visible.sync="isAddShow" :close-on-click-modal="false" :modal-append-to-body='false' 
+  @close="cancelHandle" top="5vh" center width="1090px" v-dialogDrag 
+  :title="$t('HighFrequencyData.add_high_frequency_data')">
+    <div class="dialog-container" v-loading="isLoadingData" :element-loading-text="$t('Table.loading')">
+      <div class="data-set-box" v-if="baseAddStep==1">
+        <div class="zone-title">{{ $t('HighFrequencyData.data_transformation') }} </div>
+        <div class="data-set-row">
+          <!-- 取指定时间的值 -->
+          <el-radio v-model="dataSetParams.getMethod" :label="1">{{ $t('HighFrequencyData.get_point_time') }}</el-radio>
+          <div class="radio-box" v-show="dataSetParams.getMethod==1" style="padding-left: 76px;">
+            <div class="time-item" style="width: 234px;">
+              <el-radio v-model="dataSetParams.pointTimeType" :label="1" 
+              @change="(value)=> radioChangeHandle(value,'pointTimeValue')">{{ $t('HighFrequencyData.today') }}</el-radio>
+              <el-time-picker v-show="dataSetParams.pointTimeType==1"
+                class="time-picker" value-format="HH:mm:ss"
+                v-model="dataSetParams.pointTimeValue"
+                :placeholder="$t('Edb.InputHolderAll.input_time')">
+              </el-time-picker>
+            </div>
+            <div class="time-item">
+              <el-radio v-model="dataSetParams.pointTimeType" :label="2" 
+              @change="(value)=> radioChangeHandle(value,'pointTimeValue')">{{ $t('HighFrequencyData.yesterday') }}</el-radio>
+              <el-time-picker v-show="dataSetParams.pointTimeType==2"
+                class="time-picker" value-format="HH:mm:ss"
+                v-model="dataSetParams.pointTimeValue"
+                :placeholder="$t('Edb.InputHolderAll.input_time')">
+              </el-time-picker>
+            </div>
+          </div>
+        </div>
+        <div class="data-set-row">
+          <el-radio v-model="dataSetParams.getMethod" :label="2">{{ $t('HighFrequencyData.get_range_time') }}</el-radio>
+          <!-- 起始时间 -->
+          <div class="radio-box" v-show="dataSetParams.getMethod==2">
+            <div class="data-set-row-text">{{ $t('Edb.Detail.e_start_time') }}</div>
+            <div class="time-item" style="width: 234px;">
+              <el-radio v-model="dataSetParams.rangeStartTimeType" :label="1"
+              @change="(value)=> radioChangeHandle(value,'rangeStartTimeValue')">{{ $t('HighFrequencyData.today') }}</el-radio>
+              <el-time-picker v-show="dataSetParams.rangeStartTimeType==1"
+                class="time-picker" value-format="HH:mm:ss"
+                v-model="dataSetParams.rangeStartTimeValue"
+                :placeholder="$t('Edb.InputHolderAll.input_time')">
+              </el-time-picker>
+            </div>
+            <div class="time-item">
+              <el-radio v-model="dataSetParams.rangeStartTimeType" :label="2"
+              @change="(value)=> radioChangeHandle(value,'rangeStartTimeValue')">{{ $t('HighFrequencyData.yesterday') }}</el-radio>
+              <el-time-picker v-show="dataSetParams.rangeStartTimeType==2"
+                class="time-picker" value-format="HH:mm:ss"
+                v-model="dataSetParams.rangeStartTimeValue"
+                :placeholder="$t('Edb.InputHolderAll.input_time')">
+              </el-time-picker>
+            </div>
+          </div>
+          <!-- 截止时间 -->
+          <div class="radio-box" v-show="dataSetParams.getMethod==2">
+            <div class="data-set-row-text">{{ $t('Edb.Detail.e_deadline_time') }}</div>
+            <div class="time-item" style="width: 234px;">
+              <el-radio v-model="dataSetParams.rangeDeadlineTimeType" :label="1"
+              @change="(value)=> radioChangeHandle(value,'rangeDeadlineTimeValue')">{{ $t('HighFrequencyData.today') }}</el-radio>
+              <el-time-picker v-show="dataSetParams.rangeDeadlineTimeType==1"
+                class="time-picker" value-format="HH:mm:ss"
+                v-model="dataSetParams.rangeDeadlineTimeValue"
+                :placeholder="$t('Edb.InputHolderAll.input_time')">
+              </el-time-picker>
+            </div>
+            <div class="time-item">
+              <el-radio v-model="dataSetParams.rangeDeadlineTimeType" :label="2"
+              @change="(value)=> radioChangeHandle(value,'rangeDeadlineTimeValue')">{{ $t('HighFrequencyData.yesterday') }}</el-radio>
+              <el-time-picker v-show="dataSetParams.rangeDeadlineTimeType==2"
+                class="time-picker" value-format="HH:mm:ss"
+                v-model="dataSetParams.rangeDeadlineTimeValue"
+                :placeholder="$t('Edb.InputHolderAll.input_time')">
+              </el-time-picker>
+            </div>
+          </div>
+          <!-- 计算方式 -->
+          <div class="radio-box" v-show="dataSetParams.getMethod==2">
+            <div class="data-set-row-text">{{ $t('Edb.Detail.calculation_mode') }}</div>
+            <el-radio v-model="dataSetParams.calculationMode" :label="1" style="margin-right: 20px;">{{ $t('HighFrequencyData.range_average_value') }}</el-radio>
+            <el-radio v-model="dataSetParams.calculationMode" :label="2" style="margin-right: 20px;">{{ $t('HighFrequencyData.range_max_value') }}</el-radio>
+            <el-radio v-model="dataSetParams.calculationMode" :label="3" style="margin-right: 20px;">{{ $t('HighFrequencyData.range_min_value') }}</el-radio>
+          </div>
+        </div>
+      </div>
+      <template v-else>
+        <div class="data-show-box" v-if="baseAddStep==2?(dataList && dataList.length>0):(existDataList && existDataList.length>0)">
+          <div class="zone-title" style="margin-bottom: 10px;">{{ $t('HighFrequencyData.edb_save') }}</div>
+          <el-table :data="baseAddStep==2?dataList:existDataList" border max-height="440px">
+            <el-table-column :label="$t('EtaBasePage.origin_full_metric_name')" align="center" prop="IndexName"/>
+            <el-table-column :label="$t('EtaBasePage.gen_metric_name_label')" align="center" prop="NewIndexName">
+              <template slot-scope="scope">
+                <el-input v-model="scope.row.NewIndexName" size="mini" class="table-input" :placeholder="$t('EtaBasePage.metric_name_input')"/>
+              </template>
+            </el-table-column>
+            <el-table-column :label="$t('Edb.Detail.e_unit')" align="center" width="80px" prop="Unit" />
+            <el-table-column :label="$t('Edb.Detail.e_fre')" align="center" width="80px" prop="NewFrequency" />
+            <el-table-column align="center" width="210px">
+              <template slot="header" slot-scope="scope">
+                <span style="margin-right:8px;display:inline-block"> <!-- 目录 -->{{$t('EtaBasePage.catalogue_directory')}}</span>
+                <el-radio-group v-model="classifyType" @change="handleClassifyTypeChange">
+                  <el-radio :label="0" style="margin-right: 8px;"><!-- 同目录 -->{{$t('EtaBasePage.directory_radio')}}</el-radio>
+                  <el-radio :label="1"><!-- 分目录 -->{{$t('EtaBasePage.subdirectory_radio')}}</el-radio>
+                </el-radio-group>
+              </template>
+              <template slot-scope="{row,$index}">
+                <el-cascader size="mini"
+                  v-model="row.ClassifyId"
+                  :options="classifyOpt"
+                  :props="levelProps"
+                  :placeholder="$t('Edb.InputHolderAll.input_menu')"
+                  :disabled="(classifyType===0&&$index>0)"
+                  @change="handleClassifyChange(row,$index)"/>
+              </template>
+            </el-table-column>
+            <el-table-column align="center" width="50px">
+              <template slot="header" slot-scope="scope">
+                <img src="~@/assets/img/icons/delete-red.png" class="delete-icon" @click="deleteAllHandle"/>
+              </template>
+              <template slot-scope="{row,$index}">
+                <img src="~@/assets/img/icons/delete-red.png" class="delete-icon" @click="deleteHandle(row,$index)"/>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+        <tableNoData v-else></tableNoData>
+      </template>
+    </div>
+    <div class="dialog-btn">
+      <template v-if="baseAddStep==1">
+        <el-button type="primary" plain @click="cancelHandle" >{{$t('Dialog.cancel_btn')}}</el-button>
+        <el-button type="primary" @click="nextHandle" :disabled="!isCodeComplete"
+          style="min-width: 120px;" :loading="isLoadingData" ><!-- 下一步 -->{{$t('EtaBasePage.next_step')}}
+        </el-button>
+      </template>
+      <template v-else>
+        <el-button @click="prevHandle" style="min-width: 120px;" :loading="isLoadingData"><!-- 上一步 -->{{$t('Dialog.prev_step')}}</el-button>
+        <el-button type="primary" @click="addToDatabase" v-if="baseAddStep!=1" :loading="isLoadingData">{{$t('Dialog.confirm_btn')}}</el-button>
+      </template>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { dataBaseInterface } from '@/api/api.js';
+import { highFrequencyDataInterface } from '@/api/api.js'
+
+  export default {
+    name:"addToIndexDatabaseBatch",
+    props: {
+      isAddShow: {
+        type: Boolean,
+        default:false
+      },
+      IndexIds:{
+        type: Array,
+        default:() =>[]
+      }
+    },
+    data() {
+      return {
+        classifyOpt:[],
+        levelProps: {
+          label: 'ClassifyName',
+          value: 'ClassifyId',
+          children: 'Children',
+          checkStrictly: true,
+          emitPath:false
+        },
+        baseAddStep:1,
+        dataSetParams:{
+          getMethod:1,
+          pointTimeType:1,
+          pointTimeValue:'09:30:00',
+          rangeStartTimeType:1,
+          rangeStartTimeValue:'09:30:00',
+          rangeDeadlineTimeType:1,
+          rangeDeadlineTimeValue:'09:30:00',
+          calculationMode:1
+        },
+        isLoadingData:false,
+        dataList:[],
+        existDataList:[],//重复的数据
+        existDataDeleteIds:[],//重复数据中删除id列表
+        classifyType:0
+      }
+    },
+    watch:{
+      isAddShow(value){
+        if(value){
+          this.getClassifyOpt()
+        }
+      }
+    },
+    computed:{
+      isCodeComplete(){
+        return (this.dataSetParams.getMethod==1 && this.dataSetParams.pointTimeValue && this.dataSetParams.pointTimeType) || 
+              (this.dataSetParams.getMethod==2 && this.dataSetParams.rangeStartTimeValue && this.dataSetParams.rangeStartTimeType 
+                && this.dataSetParams.rangeDeadlineTimeValue && this.dataSetParams.rangeDeadlineTimeType  && this.dataSetParams.calculationMode) 
+      },
+    },
+    methods: {
+      // 获取指标分类
+      async getClassifyOpt(){
+        const res=await dataBaseInterface.menuListV3()
+        if (res.Ret !== 200) return
+        this.filterNodes(res.Data.AllNodes||[]);
+        this.classifyOpt = res.Data.AllNodes || [];
+      },
+      filterNodes(arr) {
+        arr.length &&
+          arr.forEach((item) => {
+            item.Children.length && this.filterNodes(item.Children);
+            if (!item.Children.length) {
+              delete item.Children;
+            }
+          });
+      },
+      radioChangeHandle(value,prop){
+        switch (value) {
+          case 1:
+            this.dataSetParams[prop]="09:30:00"
+            break;
+          case 2:
+            this.dataSetParams[prop]="21:30:00"
+            break;
+          default:
+            break;
+        }
+      },
+      // 同目录修改
+      handleClassifyChange(e,index){
+        if(this.classifyType===0){
+          // 修改所有的指标的目录为第一个
+          this.dataList.forEach(item=>{
+            item.ClassifyId=e.ClassifyId
+          })
+        }
+      },
+      handleClassifyTypeChange(){
+        this.handleClassifyChange(this.dataList[0])
+      },
+      cancelHandle(){
+        this.dataSetParams={
+          getMethod:1,
+          pointTimeType:1,
+          pointTimeValue:'09:30:00',
+          rangeStartTimeType:1,
+          rangeStartTimeValue:'09:30:00',
+          rangeDeadlineTimeType:1,
+          rangeDeadlineTimeValue:'09:30:00',
+          calculationMode:1
+        }
+        this.baseAddStep=1
+        this.dataList=[]
+        this.isLoadingData=false
+        this.existDataList=[]
+        this.existDataDeleteIds=[]
+        this.classifyType=0
+        this.$emit('update:isAddShow',false)
+      },
+      nextHandle(){
+        if(this.dataSetParams.getMethod==2){
+          let StartTime = this.$moment('2024-07-10 '+this.dataSetParams.rangeStartTimeValue).subtract(this.dataSetParams.rangeStartTimeType-1,'days') .format('YYYY-MM-DD HH:mm:ss')
+          let EndTime = this.$moment('2024-07-10 '+this.dataSetParams.rangeDeadlineTimeValue).subtract(this.dataSetParams.rangeDeadlineTimeType-1,'days') .format('YYYY-MM-DD HH:mm:ss')
+          if(!(new Date(EndTime)>new Date(StartTime))){
+            return this.$message.warning(this.$t('HighFrequencyData.start_time_right_end_time'))
+          }
+        }
+        setTimeout(()=>{
+          if(this.isCodeComplete){
+            let params={
+              ConvertRule:{
+                ConvertType:this.dataSetParams.getMethod,
+                ConvertFixed:{
+                  FixedDay:this.dataSetParams.pointTimeType,
+                  FixedTime:this.dataSetParams.pointTimeValue,
+                },
+                ConvertArea:{
+                  StartDay:this.dataSetParams.rangeStartTimeType,
+                  StartTime:this.dataSetParams.rangeStartTimeValue,
+                  EndDay:this.dataSetParams.rangeDeadlineTimeType,
+                  EndTime:this.dataSetParams.rangeDeadlineTimeValue,
+                  CalculateType:this.dataSetParams.calculationMode
+                },
+              },
+              IndexIds:this.IndexIds
+            }
+            // console.log(params,'params');
+            this.isLoadingData=true
+            highFrequencyDataInterface.highFreDataSavePre(params).then(res=>{
+              if(res.Ret == 200){
+                this.dataList=res.Data||[]
+                this.baseAddStep=2
+              }
+            }).finally(()=>{
+              this.isLoadingData=false
+            })
+          }
+        },10)
+      },
+      prevHandle(){
+        this.baseAddStep = this.baseAddStep-1 || 1
+      },
+      deleteHandle(row,index){
+        if(this.baseAddStep==2){
+          this.dataList.splice(index,1)
+        }else{
+          this.existDataDeleteIds.push(row.IndexId)
+          this.existDataList.splice(index,1)
+        }
+      },
+      deleteAllHandle(){
+        if(this.baseAddStep==2){
+          this.dataList=[]
+        }else{
+          this.existDataDeleteIds=this.existDataList.map(it => it.IndexId)
+          this.existDataList=[]
+        }
+      },
+      addToDatabase(){
+        for (let i = 0; i < this.dataList.length; i++) {
+          const element = this.dataList[i];
+          if(!element.NewIndexName){
+            return this.$message.warning(this.$t('EtaBasePage.metric_name_input'))
+          }
+          if(!element.ClassifyId){
+            return this.$message.warning(this.$t('Edb.InputHolderAll.input_menu'))
+          }
+        }
+        if(this.existDataDeleteIds && this.existDataDeleteIds.length>0){
+          // 处理重复数据时,删除掉了部分
+          this.dataList = this.dataList.filter(it => !this.existDataDeleteIds.includes(it.IndexId))
+        }
+        (this.existDataList && this.existDataList.length>0) && this.dataList.map(item =>{
+          let existItem = this.existDataList.find(it => it.IndexId == item.IndexId)
+          if(existItem){
+            item.NewIndexName=existItem.NewIndexName
+            item.ClassifyId=existItem.ClassifyId
+          }
+        })
+        // console.log(this.dataList,'this.dataList');
+        let params={
+          ConvertRule:{
+            ConvertType:this.dataSetParams.getMethod,
+            ConvertFixed:{
+              FixedDay:this.dataSetParams.pointTimeType,
+              FixedTime:this.dataSetParams.pointTimeValue,
+            },
+            ConvertArea:{
+              StartDay:this.dataSetParams.rangeStartTimeType,
+              StartTime:this.dataSetParams.rangeStartTimeValue,
+              EndDay:this.dataSetParams.rangeDeadlineTimeType,
+              EndTime:this.dataSetParams.rangeDeadlineTimeValue,
+              CalculateType:this.dataSetParams.calculationMode
+            },
+          },
+          NewIndexes:this.dataList
+        }
+        this.isLoadingData=true
+        highFrequencyDataInterface.highFreDataSave(params).then(res=>{
+          if(res.Ret == 200){
+            let resData = res.Data||{}
+            this.existDataList=[]
+            this.existDataDeleteIds=[]
+            let allSuccess=true
+            if(resData.Exist && resData.Exist.length>0){
+              // 已存在              
+              this.existDataList = [...this.existDataList,...resData.Exist]
+              this.baseAddStep=3
+              this.$message.warning(this.$t('HighFrequencyData.index_has_exist_prompt'))
+              allSuccess=false
+            }
+            if(resData.Fail && resData.Fail.length>0){
+              let message = '';
+              resData.Fail.forEach(item => {
+                message+=`${item.NewIndexName}:${this.$t('MsgPrompt.add_fail_msg')}</br>`
+              })
+              // 失败的
+              this.existDataList = [...this.existDataList,...resData.Fail]
+              this.baseAddStep=3
+              this.$message.error(message)
+              allSuccess=false
+            }
+            if(allSuccess){
+              this.$message.success(this.$t('MsgPrompt.add_msg2'))
+              this.cancelHandle()	
+            }
+          }
+        }).finally(()=>{
+          this.isLoadingData=false
+        })
+      }
+    },
+  }
+</script>
+
+<style lang="scss" scoped>
+.dialog-container{
+  padding: 0 35px 35px;
+  .zone-title{
+    font-size: 16px;
+    line-height: 24px;
+    font-weight: bold;
+    color: #333333;
+  }
+  .data-set-box{
+    .data-set-row{
+      padding-top: 10px;
+      .radio-box{
+        margin-top: 20px;
+        display: flex;
+        align-items: center;
+        .data-set-row-text{
+          margin-right: 20px;
+        }
+        .time-item{
+          margin-right: 40px;
+          display: flex;
+          align-items: center;
+          .el-radio{
+            margin-right: 10px;
+          }
+          .el-input{
+            width: 172px;
+          }
+        }
+      }
+    }
+  }
+  .data-show-box{
+    margin-top: 20px;
+  }
+}
+.dialog-btn{
+  text-align: center;
+  padding: 40px 0 25px;
+  .el-button{
+    min-width: 120px;
+  }
+}
+.delete-icon{
+  height: 16px;
+  width: 16px;
+  cursor: pointer;
+}
+</style>
+<style lang="scss">
+.data-show-box{
+  .el-input{
+    width: 100%;
+    input{
+      border: none;
+      text-align: center;
+    }
+  }
+  .table-input{
+    input{
+      padding: 0;
+    }
+  }
+  .el-table tr{
+    background-color: #fff !important;
+    &:hover>td{
+        background-color: transparent !important; /* 或者其他想要的颜色值 */
+    }
+  }
+  .el-table td{
+    padding: 10px 0;
+  }
+}
+</style>

+ 635 - 0
src/views/dataEntry_manage/thirdBase/components/highFrequency/classifySetting.vue

@@ -0,0 +1,635 @@
+<template>
+  <div>
+    <el-dialog :visible.sync="showIt" :close-on-click-modal="false" append-to-body v-dialogDrag top="5vh"
+    width="600px" :title="$t('HighFrequencyData.classify_setting')" @close="classifySetClose">
+      <div class="dialog-container">
+        <el-tree
+          ref="treeRef"
+          class="target_tree"
+          :data="classify"
+          node-key="UniqueCode"
+          :props="defaultProp"
+          :allow-drag="canDragHandle"
+          :allow-drop="canDropHandle"
+          :current-node-key="select_node"
+          :default-expanded-keys="defaultShowNodes"
+          draggable
+          :expand-on-click-node="false"
+          check-strictly
+          :empty-text="$t('Common.no_classify_msg')"
+          lazy
+          :load="getLazyTreeData"
+          @node-expand="handleNodeExpand"
+          @node-collapse="handleNodeCollapse"
+          @current-change="nodeChange"
+          @node-drop="dropOverHandle"
+          @node-drag-end="dropMouseLeave"
+          @node-drag-leave="dropMouseLeave"
+          @node-drag-enter="dropMouseOver"
+        >
+          <span class="custom-tree-node" slot-scope="{ node, data }">
+            <el-input
+              ref="editVal"
+              class="label-input"
+              v-model="new_label"
+              v-if="data.isEdit"
+              @blur="changeValue(node, data)"
+            />
+            <span
+              @dblclick.stop="editNodeLabel(node, data)"
+              v-else
+              class="text_oneLine node_label"
+              :id="`node${data.UniqueCode}`"
+            > 
+              <span v-if="data.IndexId">{{ data.IndexName }}</span>
+              <span v-else>{{ currentLang==='en' ? (data.ClassifyNameEn || data.ClassifyName) : data.ClassifyName }}</span>
+            </span>
+            <span
+              style="display: flex; align-items: center"
+              v-if="select_node === data.UniqueCode"
+            >
+              <img
+                src="~@/assets/img/data_m/move_ico.png"
+                alt=""
+                style="width: 14px; height: 14px; margin-right: 8px"
+                v-permission="permissionBtn.dataSourcePermission.highFrequency_classify_move"
+              />
+              <!-- 添加子项 -->
+              <img
+                v-if="!data.IndexId && data.Level<6"
+                src="~@/assets/img/set_m/add.png"
+                style="width: 14px; height: 14px; margin-right: 8px"
+                @click.stop="addNode(node, data)"
+                v-permission="permissionBtn.dataSourcePermission.highFrequency_classify_editAdd"
+              />
+              <!-- 编辑子项 -->
+              <img
+                v-if="!data.IndexId"
+                src="~@/assets/img/set_m/edit.png"
+                style="width: 15px; height: 14px; margin-right: 8px"
+                @click.stop="editNode(node, data)"
+                v-permission="permissionBtn.dataSourcePermission.highFrequency_classify_editAdd"
+              />
+              <!-- 删除子项 -->
+              <img
+                v-if="!data.IndexId"
+                slot="reference"
+                src="~@/assets/img/set_m/del.png"
+                style="width: 14px; height: 14px"
+                @click.stop="removeNode(node, data)"
+                v-permission="permissionBtn.dataSourcePermission.highFrequency_classify_delete"
+              />
+            </span>
+          </span>
+        </el-tree>
+        <div class="add-top-classify" @click="addLevelOneHandle" v-permission="permissionBtn.dataSourcePermission.highFrequency_classify_editAdd">
+          <img
+            src="~@/assets/img/sand_new/add_ico.png"
+            alt=""
+            style="width: 16px; height: 16px; margin-right: 10px"
+          />
+          <span>{{$t('EtaBasePage.add_first_menu_btn')}}</span>
+        </div>
+      </div>
+    </el-dialog>
+    <!-- 新增、编辑目录 -->
+    <el-dialog
+      :visible.sync="isOpenDialog"
+      :close-on-click-modal="false"
+      append-to-body 
+      @close="cancelHandle"
+      custom-class="dialog"
+      center
+      width="560px"
+      v-dialogDrag>
+        <div slot="title" style="display:flex;align-items:center;">
+          <img :src="title=='添加'?$icons.add:title=='编辑'?$icons.edit:''" style="color:#fff;width:16px;height:16px;margin-right:5px;">
+          <span style="font-size:16px;">{{title==='添加' ? $t('Table.add_btn') : $t('Table.edit_btn')}}</span>
+        </div>
+        <div class="dialog-main">
+          <el-form
+          ref="diaForm"
+          label-position="left"
+          hide-required-asterisk
+          label-width="120px"
+          :model="dialogForm"
+          :rules="formRules">
+              <el-form-item :label="$t('EtaBasePage.parent_menu')" v-if="dialogForm.level>0">
+                <el-tooltip class="item" effect="dark" :content="getParentName" placement="top">
+                      <span class="parentStr">{{getParentName}}</span>
+                  </el-tooltip>
+              </el-form-item>
+              <el-form-item :label="$t('EtaBasePage.menu_name')" prop="levelVal">
+                <el-input
+                v-model="dialogForm.levelVal"
+                style="width: 80%"
+                :placeholder="$t('Dialog.require_vaild')"></el-input>
+              </el-form-item>
+          </el-form>
+        </div>
+        <div class="dia-bot">
+          <el-button type="primary" style="margin-right:20px" @click="saveHandle"><!-- 保存 -->{{$t('Dialog.confirm_save_btn')}}</el-button>
+          <el-button type="primary" plain @click="cancelHandle"><!-- 取消 -->{{$t('Dialog.cancel_btn')}}</el-button>
+        </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { highFrequencyDataInterface } from '@/api/api.js'
+  export default {
+    name:'classifySetting',
+    props:{
+      showIt:{
+        Type:Boolean,
+        default:false
+      }
+    },
+    computed:{
+      currentLang() {
+        return this.$store.state.lang
+      },
+      getParentName(){
+        const arr=this.dialogForm.parentArr||[]
+        let strArr=arr.reverse().map(item=>{
+          return this.currentLang==='en'?item.classifyNameEn:item.classifyName
+        })
+        
+        return strArr.join('/')
+      }
+    },
+    data() {
+      return {
+        classify:[],
+        defaultProp: {
+          label: 'ClassifyName',
+          children: 'Children',
+          isLeaf:'isLeaf'
+        },//树结构配置项
+        select_node:'',//当前选中的节点
+        defaultShowNodes:[], //默认展开的节点
+        new_label: '',//新的节点label值
+        formRules: {
+          levelVal:[
+            { required: true, message: this.$t('EtaBasePage.input_menu_msg'), trigger: 'blur' },
+          ]
+        },
+        dialogForm:{
+          level:''
+        },
+        title:"",
+
+        requestDataList:false, //是否需要请求数据列表 修改分类名名称 移动分类、指标位置
+        requestClassifyList:false,//是否需要请求分类列表(筛选项中的) 新增、修改、删除、移动分类位置
+      }
+    },
+    watch:{
+      showIt(value){
+        if(value){
+          this.requestDataList=false
+          this.requestClassifyList=false
+          this.getClassify()
+        }
+      }
+    },
+    methods: {
+      //控制页面按钮权限
+      canBtnShow(type){
+        const {dataSourcePermission,checkPermissionBtn}=this.permissionBtn
+        const BtnMap = {
+          'editAddClassify':dataSourcePermission.highFrequency_classify_editAdd,//编辑/添加分类
+          'moveClassify':dataSourcePermission.highFrequency_classify_move,//移动分类
+        }
+        return checkPermissionBtn(BtnMap[type])
+      },
+      getClassify(){
+        highFrequencyDataInterface.classifyList({ParentId:0}).then(res=>{
+          if(res.Ret == 200){
+            this.classify=res.Data||[]
+            this.classify.map(cl => cl.Children || (cl.Children=[]))
+            console.log(this.classify,'classify');
+          }
+        })
+      },
+      //绑定el-tree的load属性
+      async getLazyTreeData (node,resolve){
+        console.log(node);
+        if(node.level===0){
+          resolve(this.classify)
+        }else{
+          let arr=[]
+          const res=await highFrequencyDataInterface.classifyList({ParentId:node.data.ClassifyId})
+          if (res.Ret === 200) {
+            const temarr = res.Data || [];
+            arr=temarr.map(item=>{
+              return {
+                ...item,
+                isLeaf:item.IndexId?true:false,
+                Children:[]
+              }
+            })
+          }
+          resolve(arr)
+        }
+        this.select_node && this.$refs.treeRef && this.$nextTick(() => {
+          this.$refs.treeRef.setCurrentKey(this.select_node);
+          let node = document.getElementById(`node${this.select_node}`)||{}
+          let parent = document.getElementsByClassName('target_tree')[0];
+          //parent可视区间:[scrollTop,scrollTop+offsetHeight]
+          //node位置:node.offsetTop
+          const overTop = node.offsetTop+node.clientHeight+30<parent.scrollTop
+          const overBottom = node.offsetTop+node.clientHeight+30>parent.scrollTop+parent.offsetHeight
+          if(overTop){
+            parent.scrollTop = node.offsetTop-60
+          }
+          if(overBottom){
+            parent.scrollTop =  node.offsetTop - parent.offsetHeight/2
+          }
+        });
+      },
+      // 树节点展开
+      handleNodeExpand (data) {
+        // 保存当前展开的节点
+        let flag = this.defaultShowNodes.some((item) => item === data.UniqueCode);
+        if (!flag) { // 不存在则存到数组里
+          this.defaultShowNodes.push(data.UniqueCode)
+        }
+      },
+      // 树节点关闭
+      handleNodeCollapse (data) {
+        this.defaultShowNodes.some((item, index) => {
+          if (item === data.UniqueCode) {
+            // 删除关闭节点
+            this.defaultShowNodes.length = index
+          }
+        })
+      },
+      /* 节点变化时 */
+      nodeChange(data,node) {
+        this.select_node = data.UniqueCode;
+      },
+      /* 判断节点是否能被拖拽 */
+      canDragHandle({data}) {
+        return this.canBtnShow('moveClassify')
+      },
+      /* 判断节点是否能被拖入 */
+      canDropHandle(draggingNode, dropNode, type) {
+        let canDrop=false
+        
+        // 如果拖动的是指标
+        if(draggingNode.data.IndexId){
+          if(!(dropNode.level===1&&type!=='inner')){
+            canDrop=true
+          }
+        }else{//拖动的是目录
+          // console.log(dropNode.level,draggingNode.level);
+          //目录层级不能改变
+          if((dropNode.level+1==draggingNode.level&&type==='inner'&&!dropNode.data.IndexId)||(dropNode.level===draggingNode.level&&type!=='inner')){
+            canDrop=true
+          }
+        }
+        return canDrop
+      },
+      /* 拖拽完成 */
+      dropOverHandle(b,a,i,e) {
+        // 被拖拽节点对应的 Node、结束拖拽时最后进入的节点、被拖拽节点的放置位置
+        console.log(b,a,i);
+        const isIndex=b.data.IndexId?true:false
+        let list=a.parent.childNodes;
+        let targetIndex=0,PrevClassifyId=0,NextClassifyId=0,ParentClassifyId=0;
+        let ClassifyId=0,ItemId=0,PrevItemId=0,NextItemId=0;
+
+        ClassifyId=isIndex?0:b.data.ClassifyId
+        ItemId=isIndex?b.data.IndexId:0
+        
+
+        if(i!=='inner'){
+          ParentClassifyId=a.parent.data.ClassifyId||0
+          list.forEach((item,index)=>{
+            if(isIndex){
+              if(item.data.IndexId===b.data.IndexId){
+                targetIndex=index
+              }
+            }else{
+              if(item.data.ClassifyId===b.data.ClassifyId){
+                targetIndex=index
+              }
+            }
+            
+          })
+
+          console.log(targetIndex);
+          
+          if(targetIndex===0){
+            const data=list[targetIndex+1].data
+            NextClassifyId=data.EdbCode?0:data.ClassifyId
+            NextItemId=data.EdbCode?data.IndexId:0
+          }else if(targetIndex===list.length-1){
+            const data=list[targetIndex-1].data
+            PrevClassifyId=data.EdbCode?0:data.ClassifyId
+            PrevItemId=data.EdbCode?data.IndexId:0
+          }else{
+            const pData=list[targetIndex-1].data
+            PrevClassifyId=pData.EdbCode?0:pData.ClassifyId
+
+            PrevItemId=pData.EdbCode?pData.IndexId:0
+
+            const nData=list[targetIndex+1].data
+            NextClassifyId=nData.EdbCode?0:nData.ClassifyId
+            NextItemId=nData.EdbCode?nData.IndexId:0
+          }
+        }else{
+          ParentClassifyId=a.data.ClassifyId||0
+        }
+
+        const params={
+          ClassifyId,
+          ParentClassifyId,
+          ItemId,
+          PrevClassifyId,
+          NextClassifyId,
+          PrevItemId,
+          NextItemId
+        }
+        // console.log(params);
+        highFrequencyDataInterface.classifyMove(params).then(res=>{
+          if(res.Ret===200){
+            this.$message.success(this.$t('MsgPrompt.move_sort_success'))
+          }
+          this.requestDataList=true
+          !isIndex && (this.requestClassifyList=true)
+          if(i=='inner'){
+            let code = a.data.UniqueCode
+            let flag = 	this.defaultShowNodes.some((item) => {
+              return item === code
+            });
+            code && !flag && this.defaultShowNodes.push(code);
+          }
+
+
+          this.getClassify() 
+        })
+      },
+      /* 拖拽覆盖添加背景色 */
+      dropMouseOver(node1,node2,e) {
+        // console.log(e.layerY);
+        // 被拖拽节点对应的 Node、所进入节点对应的 Node、event
+        if(!node2.data.IndexId&&(node1.level>node2.level||(node1.data.IndexId>0&&!node2.data.IndexId)) && (e.target.childNodes[0].className.includes('el-tree-node__content') 
+        || e.target.className.includes('el-tree-node__content'))) {
+          // console.log(e.target.childNodes[0])
+          e.target.childNodes[0].className.includes('el-tree-node__content') 
+          ? e.target.childNodes[0].style.backgroundColor = '#409eff' 
+          : e.target.style.backgroundColor = '#409eff';
+        }
+      },
+      /* 拖拽离开/拖拽完成重置背景色 */
+      dropMouseLeave(node1,node2,e) {
+        let arrs = $('.el-tree-node__content');
+        for( let a of arrs ) {
+          a.style.backgroundColor = 'transparent';
+        }
+      },
+      /* 双击label出现input修改框 */
+      editNodeLabel(node, data) {
+        //目录名称可以双击修改 指标不能
+        if(!data.IndexId &&this.canBtnShow('editAddClassify')) {
+          this.$set(data,'isEdit',true)
+          this.new_label = this.currentLang==='en' ? data.ClassifyNameEn : data.ClassifyName;
+          this.$nextTick(() => {
+            this.$refs.editVal.focus();
+          });
+        }
+      },
+      /* input失去焦点恢复node 修改最新的值*/
+      changeValue(node, data) {
+        this.$set(data,'isEdit',false)
+        if(!this.new_label) return this.$message.warning(this.$t('MsgPrompt.name_none'))
+        if(this.new_label!=(this.currentLang==='en' ? data.ClassifyNameEn : data.ClassifyName)) {
+          highFrequencyDataInterface.classifyEdit({
+            ClassifyId: data.ClassifyId,
+            ClassifyName: this.new_label
+          }).then(res => {
+            if(res.Ret === 200) {
+              this.getClassify();
+            }
+          })
+        }
+      },
+      /* 添加节点 */
+      addNode(node,data) {
+        this.title = '添加';
+        let arr=[]
+        arr=this.getNodeParentData(node,arr)
+        /* 添加目录 */
+        this.dialogForm = {
+          parentArr:arr,
+          parent_id: data.ClassifyId,
+          level: node.level,
+          levelVal:'',
+          uniqueCode:data.UniqueCode
+        }
+        this.isOpenDialog = true;
+      },
+      // 递归节点
+      getNodeParentData(data,arr){
+        if(data.level===0) return
+        arr.push({classifyName:this.currentLang==='en'?data.data.ClassifyNameEn:data.data.ClassifyName,classifyId:data.data.ClassifyId})
+        this.getNodeParentData(data.parent,arr)
+        return arr
+      },
+      /* 编辑节点 */
+      editNode(node,data) {
+        this.title = '编辑';
+        let arr=[]
+        arr=this.getNodeParentData(node.parent,arr)
+        /* 编辑目录 */
+        this.dialogForm = {
+          parentArr:arr,
+          levelVal: this.currentLang==='en'?data.ClassifyNameEn:data.ClassifyName,
+          classify_id: data.ClassifyId,
+          level: node.level-1,
+          uniqueCode:data.UniqueCode
+        }
+        this.isOpenDialog = true;
+      },
+      /* 删除节点校验 */
+      removeNode(node,data) {
+        this.$confirm(
+          this.$t('Edb.MsgPrompt.del_menu_confirm'),
+          /* 提示 */this.$t('Dialog.warn_tit'),
+          {
+          confirmButtonText: /* '确定' */this.$t('Dialog.confirm_btn'),
+          cancelButtonText: /* '取消' */this.$t('Dialog.cancel_btn'),
+          type: 'warning'
+        }).then(() => {
+          highFrequencyDataInterface.classifyDelete({
+            ClassifyId: data.ClassifyId,
+          }).then(res => {
+            if(res.Ret === 200) {
+            this.$message.success(this.$t('MsgPrompt.delete_msg'));
+            this.getClassify();
+            this.requestClassifyList=true
+          }
+          })
+        }).catch(() => {});
+      },
+      /* 添加一级目录 */
+      addLevelOneHandle() {
+        this.title = '添加';
+        this.dialogForm = {
+          parent_id: '',
+          level: 0,
+          levelVal:'',
+        }
+        this.isOpenDialog = true;
+      },
+      async saveHandle(){
+        await this.$refs.diaForm.validate();
+        let res = null;
+        if(this.title==='添加') {
+          res = await highFrequencyDataInterface.classifyAdd({
+            ClassifyName: this.dialogForm.levelVal||'',
+            ParentId:this.dialogForm.parent_id || 0,
+            Level: this.dialogForm.level
+          })
+        }else if(this.title==='编辑') {
+          res = await highFrequencyDataInterface.classifyEdit({
+            ClassifyName: this.dialogForm.levelVal||'',
+            ClassifyId:this.dialogForm.classify_id || 0
+          })
+        }
+        if(res.Ret !== 200) return
+        this.$message.success(res.Msg);
+        this.getClassify();
+        if(this.title==='添加'){
+          //新增分类完成之后,展开父节点显示刚新增的分类,若已展开节点则不做处理
+          let code = this.dialogForm.uniqueCode
+          let flag = 	this.defaultShowNodes.some((item) => {
+            return item === code
+          });
+          code && !flag && this.defaultShowNodes.push(code);
+        }else if(this.title==='编辑'){
+          this.requestDataList=true
+        }
+        this.requestClassifyList=true
+        this.cancelHandle()
+      },
+      cancelHandle(){
+        this.isOpenDialog=false
+        this.dialogForm={
+          level:''
+        }
+        this.$refs.diaForm.clearValidate();
+      },
+      classifySetClose(){
+        this.$emit('closeHandle',{requestClassifyList:this.requestClassifyList,requestDataList:this.requestDataList})
+      }
+    },
+    mounted(){
+      this.getClassify()
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+  .dialog-container{
+    padding: 0 35px 25px;
+  }
+  .parentStr{
+		display: block;
+		width: 304px;
+		overflow: hidden;
+		white-space: nowrap;
+		text-overflow: ellipsis;
+	}
+	.dialog-main {
+		padding-left: 50px;
+	}
+	.el-cascader .el-input {
+		width: 100%;
+	}
+	.dia-bot {
+		margin: 52px 0 30px;
+		display: flex;
+		justify-content: center;
+
+	}
+</style>
+<style lang="scss">
+@import "~@/styles/theme-vars.scss";
+.target_tree {
+  color: #333;
+  height: 630px; 
+  overflow: auto;
+  .label-input .el-input__inner {
+    height: 25px;
+    line-height: 25px;
+  }
+  .el-input{
+    width: 100%;
+    padding-right: 10px;
+  }
+  .custom-tree-node {
+    display: flex !important;
+    justify-content: space-between;
+    align-items: center;
+    display: block;
+    flex: 1;
+    width: calc(100% - 30px);
+    .node_label {
+      margin-right: 2px;
+    }
+    .el-icon-view {
+      color: #409eff;
+      font-size: 18px;
+      margin-left: 5px;
+    }
+  }
+  .el-tree__drop-indicator{
+    height:3px;
+    background-color:$theme-color;
+  }
+  .el-tree-node__content {
+    margin-bottom: 10px !important;
+  }
+  .el-tree-node__children {
+    .el-tree-node {
+      margin-bottom: 0px !important;
+      padding-left: 18px;
+    }
+    .el-tree-node__content {
+      margin-bottom: 5px !important;
+      padding-left: 0 !important;
+    }
+  }
+  .expanded.el-icon-caret-right:before {
+    content: url('~@/assets/img/set_m/down_black.png') !important;
+  }
+  .el-icon-caret-right:before {
+    content: url('~@/assets/img/set_m/slide_black.png') !important;
+  }
+  .el-tree-node__expand-icon.is-leaf.el-icon-caret-right:before {
+    content: '' !important;
+  }
+  .el-tree-node__expand-icon.expanded {
+    -webkit-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  .el-tree-node.is-current > .el-tree-node__content {
+    background-color: #f0f4ff !important;
+  }
+  .el-tree-node__content {
+    padding-right: 10px !important;
+  }
+}
+.add-top-classify {
+  margin: 20px 0 0;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: $theme-color;
+  font-size: 16px;
+  cursor: pointer;
+}
+		
+</style>

+ 1022 - 0
src/views/dataEntry_manage/thirdBase/highFrequencyData.vue

@@ -0,0 +1,1022 @@
+<template>
+    <div class="hight-frequency-data-container">
+        <div class="top-box">
+            <div class="select-box">
+                <span>{{$t('SystemManage.DataRefresh.select_source')}}</span>
+                <el-select :placeholder="$t('SystemManage.DataRefresh.select_source_pld')" v-model="Source" @change="handleSourceChange">
+                    <el-option v-for="item in SourceList" :key="item.Source" 
+                    :label="$i18nt.locale==='zh'?item.SourceName:item.SourceNameEn||item.SourceName" :value="item.Source"/>
+                </el-select>
+                <el-select v-model="Sequence" @change="handleSequenceChange">
+                    <el-option v-for="item in SequenceList" :key="item.Sequence" 
+                    :label="$i18nt.locale==='zh'?item.SequenceName:item.SequenceNameEn||item.SequenceName" :value="item.Sequence"/>
+                </el-select>
+                <!-- 添加高频数据 -->
+                <el-button type="primary" @click="addHighFrequencyDiaShow" v-permission="permissionBtn.dataSourcePermission.highFrequency_adds"
+                >{{$t('HighFrequencyData.add_high_frequency_data')}}</el-button>
+            </div>
+        </div>
+        <div class="table-box">
+          <div class="table-select">
+            <div class="select-list">
+              <el-cascader :placeholder="$t('HighFrequencyData.select_classify_prompt')"
+                v-model="classifyArr" @change="searchListDelay" :options="classifyListTree" 
+                style="max-width: 160px;"
+                key="isAssociativeSub"
+                v-if="searchParams.isAssociativeSub"
+                :show-all-levels="false" collapse-tags
+                :props="classifyProps" 
+                clearable/>
+              <el-cascader :placeholder="$t('HighFrequencyData.select_classify_prompt')"
+                v-model="classifyArr" @change="searchListDelay" :options="classifyListTree" 
+                style="max-width: 160px;" v-else key="noIsAssociativeSub"
+                :show-all-levels="false" collapse-tags
+                :props="classifyProps" 
+                clearable/>
+              <div class="associative-box">
+                <span>{{$t('HighFrequencyData.associative_sub_classify')}}</span>
+                <el-switch v-model="searchParams.isAssociativeSub" @change="changeAssociativeSub"></el-switch>
+                <span class="span-button" @click="setClassify" 
+                v-permission="[permissionBtn.dataSourcePermission.highFrequency_classify_move,permissionBtn.dataSourcePermission.highFrequency_classify_delete,
+                  permissionBtn.dataSourcePermission.highFrequency_classify_editAdd,'or']"
+                >{{$t('HighFrequencyData.classify_setting')}}</span>
+              </div>
+              <el-select :placeholder="$t('Edb.InputHolderAll.input_fre')" v-model="frequencyArr" @change="searchListDelay" multiple collapse-tags clearable>
+                <el-option v-for="i in frequencyList" :key="i.value"
+                    :label="i.label" :value="i.value"
+                />
+              </el-select>
+              <el-cascader
+                :placeholder="$t('Edb.InputHolderAll.select_creator')" v-model="userArr" @change="searchListDelay"
+                :props="{
+                    value: 'ItemId',
+                    label: 'ItemName',
+                    children: 'Children',
+                    emitPath: false,
+                    multiple:true,
+                }"
+                :options="userList"
+                collapse-tags
+                :show-all-levels="false"
+                clearable
+                filterable 
+              />
+              <el-input :placeholder="$t('Edb.InputHolderAll.input_name_orid')" prefix-icon="el-icon-search" clearable
+              v-model="searchParams.keyWord" @input="searchList"></el-input>
+            </div>
+            <div class="select-other">
+              <el-checkbox :indeterminate="isIndeterminate" v-model="isCheckAll" @change="listCheckAllChange">{{$t('SystemManage.DataRefresh.all_list')}}</el-checkbox>
+              <!-- 批量添加到指标库 -->
+              <el-button type="primary" @click="batchAddToDatabaseOpen"
+                :disabled="!selectedTotal>0" :loading="batchLoading"
+                v-permission="permissionBtn.dataSourcePermission.highFrequency_addTo_database"
+              >{{$t('HighFrequencyData.add_to_eta_indicators')}}</el-button>
+              <!-- 批量操作 -->
+              <el-button type="primary" @click="openBatchOperationDia"
+                :disabled="!selectedTotal>0" :loading="batchLoading"
+                v-permission="permissionBtn.dataSourcePermission.highFrequency_operations"
+              >{{$t('HighFrequencyData.batch_operation')}}</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>
+            <!-- 指标ID -->
+            <el-table-column prop="IndexCode" :label="$t('Edb.Detail.e_id')" align="center" show-overflow-tooltip>
+              <template slot-scope="{row}">
+                <span>{{row.IndexCode}}</span>
+              </template>
+            </el-table-column>
+            <!-- 指标名称 -->
+            <el-table-column prop="IndexName" :label="$t('Edb.Detail.e_name')" align="center" show-overflow-tooltip>
+              <template slot-scope="{row}">
+                <span>{{row.IndexName}}</span>
+              </template>
+            </el-table-column>
+            <!-- 频度 -->
+            <el-table-column prop="Frequency" :label="$t('Edb.Detail.e_fre')" align="center">
+              <template slot-scope="{row}">
+                <span>{{row.Frequency}}</span>
+              </template>
+            </el-table-column>
+            <!-- 单位 -->
+            <el-table-column prop="Unit" :label="$t('Edb.Detail.e_unit')" align="center">
+              <template slot-scope="{row}">
+                <span>{{row.Unit}}</span>
+              </template>
+            </el-table-column>
+            <!-- 指标开始时间 -->
+            <el-table-column prop="StartDate" :label="$t('Edb.Detail.e_start_time_whole')" align="center" sortable="custom">
+              <template slot-scope="{row}">
+                <span>{{row.StartDate}}</span>
+              </template>
+            </el-table-column>
+            <!-- 指标最新时间 -->
+            <el-table-column prop="EndDate" :label="$t('Edb.Detail.e_latest_time_whole')" align="center" sortable="custom">
+              <template slot-scope="{row}">
+                <span>{{row.EndDate}}</span>
+              </template>
+            </el-table-column>
+            <!-- 更新时间 -->
+            <el-table-column prop="ModifyTime" :label="$t('Edb.Detail.e_update_time')" align="center" sortable="custom">
+              <template slot-scope="{row}">
+                <span>{{row.ModifyTime}}</span>
+              </template>
+            </el-table-column>
+            <!-- 最新值 -->
+            <el-table-column prop="LatestValue" :label="$t('Edb.Detail.e_latest_value')" align="center" sortable="custom">
+              <template slot-scope="{row}">
+                <span>{{row.LatestValue}}</span>
+              </template>
+            </el-table-column>
+            <!-- 数据源分类 -->
+            <el-table-column prop="ClassifyPath" :label="$t('HighFrequencyData.data_source_classify')" align="center" show-overflow-tooltip>
+              <template slot-scope="{row}">
+                <span>{{row.ClassifyPath}}</span>
+              </template>
+            </el-table-column>
+            <el-table-column prop="Operation" :label="$t('Table.column_operations')" align="center">
+              <template slot-scope="{row}">
+                <span class="table-operation-item" @click="detailIndexHandle(row)" 
+                v-permission="permissionBtn.dataSourcePermission.highFrequency_operation_detail">{{ $t('Table.detail_btn') }}</span>
+                <span class="table-operation-item" @click="refreshIndexHandle(row)"
+                v-permission="permissionBtn.dataSourcePermission.highFrequency_operation_refresh">{{ $t('Table.refresh_btn') }}</span>
+                <span class="table-operation-item del-item" @click="deleteIndexHandle(row)"
+                v-permission="permissionBtn.dataSourcePermission.highFrequency_operation_delete">{{ $t('Table.delete_btn') }}</span>
+              </template>
+            </el-table-column>
+          </el-table>
+          <el-pagination 
+            :current-page="searchParams.currentPage"
+            :page-size="searchParams.pageSize"
+            :total="total"
+            @current-change="handleCurrentChange"
+          />
+        </div>
+        <!-- 数据详情 -->
+        <el-dialog custom-class="custom-dialog"
+          :title="$t('Edb.data_detail_tab')"
+          :visible.sync="detailDiaShow"
+          :close-on-click-modal="false"
+          :modal-append-to-body="false"
+          @close="detailDiaShow=false"
+          width="980px"
+          top="5vh"
+          v-dialogDrag
+          center
+        >
+          <div class="dialog-container">
+            <div class="detail-date-select-zone">
+              <span>{{ $t('HighFrequencyData.data_date') }}</span>
+              <el-date-picker v-model="detailRequestParams.DataDate" type="date" :clearable="false" @change="getIndexDetailFun"
+                :placeholder="$t('EtaBasePage.input_date_msg')" style="max-width:240px" value-format="yyyy-MM-dd"></el-date-picker>
+            </div>
+            <div class="detail-data-zone">
+              <div class="detail-data-zone-header">
+                <table border class="header-table">
+                    <tr>
+                      <td>{{ $t('Edb.Detail.e_name') }}</td>
+                      <td>
+                        <el-input v-model.trim="indexDetail.IndexName" :placeholder="$t('Edb.InputHolderAll.input_name')" size="mini"></el-input>
+                      </td>
+                    </tr>
+                    <tr>
+                      <td>{{ $t('Edb.Detail.e_stock_code') }}</td>
+                      <td>{{ indexDetail.ZqCode }}</td>
+                    </tr>
+                    <tr>
+                      <td>{{ $t('Edb.Detail.e_indicator_code') }}</td>
+                      <td>{{ indexDetail.ZbCode }}</td>
+                    </tr>
+                </table>
+                <table border class="header-table">
+                    <tr>
+                      <td>{{ $t('HighFrequencyData.belong_to_classify') }}</td>
+                      <td>
+                        <el-cascader :options="classifyListTree" v-model="indexDetail.ClassifyId" 
+                        size="mini"
+                        :props="{label: 'ClassifyName',
+                          value: 'ClassifyId',
+                          children: 'Children',
+                          checkStrictly: true,
+                          emitPath:false}">
+                        </el-cascader>
+                      </td>
+                    </tr>
+                    <tr>
+                      <td>{{ $t('Edb.Detail.e_unit') }}</td>
+                      <td>
+                        <el-autocomplete
+                          v-model.trim="indexDetail.Unit"
+                          :fetch-suggestions="querySearchUnit"
+                          :placeholder="$t('Edb.InputHolderAll.input_unit')"
+                          suffix-icon="el-icon-arrow-down"
+                          size="mini"
+                        ></el-autocomplete>
+                      </td>
+                    </tr>
+                    <tr>
+                      <td>{{ $t('Edb.Detail.e_fre') }}</td>
+                      <td>{{indexDetail.Frequency}}</td>
+                    </tr>
+                </table>
+              </div>
+              <div class="detail-data-list" ref="detailDataListRef">
+                <table class="body-table" >
+                  <template v-if="indexDetail.DataList && indexDetail.DataList.length>0">
+                    <tr v-for="(item,index) in indexDetail.DataList" :key="index">
+                      <td>{{ item.DataTime }}</td>
+                      <td>{{ item.Value }}</td>
+                    </tr>
+                  </template>
+                  <tableNoData v-else></tableNoData>
+                </table>
+              </div>
+            </div>
+          </div>
+          <!-- 弹窗按钮 -->
+          <div class="dialog-btn">
+            <el-button type="primary" plain @click="detailDiaShow=false">{{$t('Dialog.cancel_btn')}}</el-button>
+            <el-button type="primary" @click="editDataHandle">{{$t('Dialog.confirm_btn')}}</el-button>
+          </div>
+        </el-dialog>
+        <!-- 批量操作 -->
+        <el-dialog custom-class="custom-dialog"
+          :title="$t('HighFrequencyData.batch_operation')"
+          :visible.sync="batchOperationDialogShow"
+          :close-on-click-modal="false"
+          :modal-append-to-body="false"
+          @close="batchOperationClose"
+          width="600px"
+          top="5vh"
+          v-dialogDrag
+        >
+          <div class="dialog-container">
+            <div class="batch-option-row">
+              <el-radio v-model="batchOperationData.type" :label="1">{{ $t('HighFrequencyData.move_to_new_classify') }}</el-radio>
+              <el-cascader :options="classifyListTree" v-model="batchOperationData.newClassify" 
+              style="width: 160px;"
+              :placeholder="$t('HighFrequencyData.select_classify_prompt')"
+              :props="{label: 'ClassifyName',
+              value: 'ClassifyId',
+              children: 'Children',
+              checkStrictly: true,
+              emitPath:false}">
+              </el-cascader>
+            </div>
+            <div class="batch-option-row">
+              <el-radio v-model="batchOperationData.type" :label="2" style="margin-right: 10px;">{{ $t('Edb.detail_del_btn') }}</el-radio>
+            </div>
+            <div class="batch-option-row">
+              <el-radio v-model="batchOperationData.type" :label="3">{{ $t('Edb.detail_refresh_btn') }}</el-radio>
+              <div class="radio-box" v-show="batchOperationData.type==3">
+                <el-radio v-model="batchOperationData.refreshType" :label="1">{{ $t('HighFrequencyData.last_six_hours') }}</el-radio>
+                <el-radio v-model="batchOperationData.refreshType" :label="2">{{ $t('HighFrequencyData.refresh_all') }}</el-radio>
+              </div>
+            </div>
+          </div>
+          <!-- 弹窗按钮 -->
+          <div class="dialog-btn">
+            <el-button type="primary" plain @click="batchOperationDialogShow=false">{{$t('Dialog.cancel_btn')}}</el-button>
+            <el-button type="primary" @click="batchOpeartion">{{$t('Dialog.confirm_btn')}}</el-button>
+          </div>
+        </el-dialog>
+        <!-- 分类设置 -->
+        <classifySetting :showIt.sync="classifySettingShow" @closeHandle="classifyCloseHandle" />
+        <!-- 添加高频数据 -->
+        <addHighFrequencyData :isAddShow.sync="addHighFrequencyShow" :unitList="unitList" :classifyList="classifyListTree"  @addSuccessHandle="addHighFrequencySuccess" />
+        <!-- 批量添加到到指标库 -->
+        <addToIndexDatabaseBatch :isAddShow.sync="batchAddToDatabaseShow" :IndexIds="choiceIdList"/>
+    </div>
+</template>
+
+<script>
+import {dataRefreshInterface,dataAuthInterface} from '@/api/modules/dataApi.js';
+import { dataInterence,highFrequencyDataInterface } from '@/api/api.js'
+import classifySetting from './components/highFrequency/classifySetting.vue';
+import addHighFrequencyData from './components/highFrequency/addHighFrequencyData.vue'
+import addToIndexDatabaseBatch from './components/highFrequency/addToIndexDatabaseBatch.vue';
+
+  export default {
+    name:'highFrequencyData',
+    components:{classifySetting,addHighFrequencyData,addToIndexDatabaseBatch},
+    data() {
+        return {
+            Source:'',
+            SourceList:[],
+            Sequence:'',
+            SequenceList:[],
+
+            classifyListTree:[],
+            userList:[],
+            unitList:[],
+            searchParams:{
+              classify:'',//分类
+              isAssociativeSub:true,//是否关联子分类
+              frequency:'',//频度
+              user:'',//创建人
+              keyWord:'',//关键字
+              sortType:'',//升序降序
+              sortParam:'',//排序字段
+              pageSize:10,
+              currentPage:1,
+            },
+            classifyArr:[],
+            frequencyArr:[],
+            userArr:[],
+            tableData: [],
+            tableDataIds:[],
+            total:0,
+
+            //全部全选
+            isIndeterminate:false,
+            isCheckAll:false,
+            isSelectAll:false,//为true时,selectList是剔除的指标,为false时selectList是已选择的指标
+            //已选择/已剔除的指标id
+            selectList:[],//监听table的select-all select
+            choiceIdList:[], //后端返回的选中的列表
+
+            detailDiaShow:false,
+            indexDetail:{},
+            detailRequestParams:{
+              IndexId:0,
+              DataDate:''
+            },
+
+            classifySettingShow:false,
+
+            addHighFrequencyShow:false,
+
+            batchOperationDialogShow:false,
+            batchOperationData:{
+              type:1,
+              newClassify:0,
+              refreshType:1
+            },
+
+            batchAddToDatabaseShow:false,
+            batchLoading:false
+        };
+    },
+    computed:{
+      selectedTotal(){
+        if(this.isSelectAll){
+          return this.total - (this.selectList ? this.selectList.length : 0)
+        }else{
+          return this.selectList ? this.selectList.length : 0
+        }
+      },
+      frequencyList() {
+        return [
+          {value: "1m",label: "1m"},
+          {value: "3m",label: '3m'},
+          {value: "5m",label: "5m"},
+          {value: "10m",label: "10m"},
+          {value: "15m",label: "15m"},
+          {value: "30m",label: "30m"},
+          {value: "60m",label: "60m"}
+        ];
+      },
+      classifyProps(){
+        return {
+          checkStrictly:(!this.searchParams.isAssociativeSub),
+          value:'ClassifyId',
+          label:'ClassifyName',
+          children:'Children',
+          emitPath:this.searchParams.isAssociativeSub,
+          multiple:true
+        }
+      }
+    },
+    watch:{
+      classifyArr(value){
+        if(value && value.length>0){
+          const classifyIds = [...new Set(value.join(',').split(','))]
+          this.searchParams.classify=classifyIds.join(',')
+        }else{
+          this.searchParams.classify=''
+        }
+      },
+      frequencyArr(value){
+        if(value && value.length>0){
+          this.searchParams.frequency=value.join(',')
+        }else{
+          this.searchParams.frequency=''
+        }
+      },
+      userArr(value){
+        if(value && value.length>0){
+          this.searchParams.user=value.join(',')
+        }else{
+          this.searchParams.user=''
+        }
+      },
+    },
+    methods: {
+        //添加高频数据
+        addHighFrequencyDiaShow(){
+          this.addHighFrequencyShow=true
+        },
+        addHighFrequencySuccess(){
+          this.searchParams.currentPage = 1
+          this.getTableData()
+        },
+        //获取数据源列表
+        getSourceList(){
+          this.SourceList=[{Source: 1,SourceName: "同花顺",SourceNameEn: "同花顺"}]
+          this.Source = this.SourceList[0].Source
+        },
+        getSequenceList(){
+          this.SequenceList=[{Sequence: 1,SequenceName: "高频序列",SequenceNameEn: "高频序列"}]
+          this.Sequence = this.SequenceList[0].Sequence
+        },
+        //数据源改变
+        handleSourceChange(){
+        },
+        // 序列改变
+        handleSequenceChange(){
+        },
+        //获取分类列表
+        async getClassifyList(){
+          const res = await highFrequencyDataInterface.classifyListTree()
+          if(res.Ret!==200) return 
+          this.classifyListTree = res.Data||[]
+        },
+        //获取用户列表
+        getUserList() {
+          dataAuthInterface.userSearch({
+              KeyWord: ''
+          }).then(res => {
+              if(res.Ret !== 200) return 
+              this.userList = res.Data||[]
+          })
+        },
+        // 获取指标单位
+        async getUnitList(){
+          let res=await dataInterence.getTargetUnitList()
+          if(res.Ret===200){
+            this.unitList=res.Data&&res.Data.map(item=>{
+              return {value:item}
+            })
+          }
+        },
+        //搜索单位
+        querySearchUnit(queryString, cb){
+          let results = queryString ? this.unitList.filter(item=>item.value.indexOf(queryString) === 0) : this.unitList;
+          // 调用 callback 返回建议列表的数据
+          cb(results);
+        },
+        changeAssociativeSub(value){
+          // 清空
+          this.classifyArr=[]
+          this.searchListDelay()
+        },
+        searchListDelay(){
+          setTimeout(()=>{
+            this.searchList()
+          },0)
+        },
+        //表格筛选项改变时触发
+        searchList(){
+          this.searchParams.currentPage = 1
+          this.getTableData('search')
+        },
+        handleCurrentChange(page){
+            this.searchParams.currentPage = page
+            this.getTableData()
+        },
+        async getTableData(type){
+          const {frequency,user,classify,keyWord,sortParam,sortType,currentPage,pageSize,isAssociativeSub} = this.searchParams
+          let params={
+            ClassifyId:classify,
+            IncludeChild:isAssociativeSub,
+            SysAdminId:user,
+            Frequency:frequency,
+            Keywords:keyWord,
+            SortField:sortParam,
+            SortType:sortType,
+            PageSize:Number(pageSize) || 10,
+            CurrentIndex:Number(currentPage)||1
+          }
+          // console.log(params,'params');
+          const res = await highFrequencyDataInterface.getTableDataApi(params)
+          if(res.Ret!==200) return 
+          const {Paging,List} = res.Data||{}
+          this.tableData = List||[]
+          if(this.tableData.length === 0 && this.searchParams.currentPage>1 && Paging.Pages){
+            // 最后一页的最后一个被删除了 当前页码没数据 去最后一页 非要改
+            this.searchParams.currentPage > Paging.Pages ?
+            (this.searchParams.currentPage =  Paging.Pages || 1) :
+            (this.searchParams.currentPage--)
+            this.getTableData(type)
+            return 
+          }
+          this.total = Paging.Totals||0
+          if(this.tableData.length>0){
+            this.tableDataIds = this.tableData.map(it => it.IndexId)
+          }else{
+            this.tableDataIds = []
+          }
+          if(type==='search'){
+              //如果是表格筛选项改变导致重新请求数据
+              //清除所选
+              this.selectList = []
+              this.listCheckAllChange(false)
+          }else{
+              //若不是,数据获取完成后,查询列表全选的值
+              //若当页有数据在selectList内,则勾选/剔除
+              this.adjustSelection()
+          }
+        },
+        //勾选/取消勾选表格项
+        adjustSelection(){
+            if(!this.isSelectAll){
+              this.tableData.map(it =>{
+                    let row = this.selectList.includes(it.IndexId)?it:''
+                    if(row){
+                        this.$nextTick(()=>{
+                          this.$refs.edbDataRef.toggleRowSelection(row,true)
+                        })
+                    }
+                })
+            }else{
+              this.tableData.map(it =>{
+                let row = this.selectList.includes(it.IndexId)?'':it
+                if(row){
+                  this.$nextTick(()=>{
+                    this.$refs.edbDataRef.toggleRowSelection(row,true)
+                  })
+                }
+              })
+            }
+        },
+        //列表全选改变
+        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){
+            // 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){
+            let check = false; 
+            if(selection.some(it => it.IndexId == row.IndexId)){
+                // 勾选
+                if(this.isSelectAll){
+                    check=false
+                }else{
+                    check=true
+                }
+            }else{
+                // 取消勾选
+                if(this.isSelectAll){
+                    check=true
+                }else{
+                    check=false
+                }
+            }
+            if(check){
+              this.selectList.push(row.IndexId)
+            }else{
+              this.selectList=this.selectList.filter(it => it!=row.IndexId)
+            }
+        },
+        selectAllHandle(selection){
+          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))
+          }
+        },
+        handleSortChange({prop,order}){
+          let propMap = new Map([
+            ["StartDate",1],
+            ["EndDate",2],
+            ["ModifyTime",3],
+            ["LatestValue",4]
+          ])
+          if(order){
+            this.searchParams.sortParam = propMap.get(prop)
+            this.searchParams.sortType = order==='ascending'?1:2
+          }else{
+            this.searchParams.sortParam = ''
+            this.searchParams.sortType = ''
+          }
+          this.searchList()
+        },
+        // 详情
+        async detailIndexHandle(row){
+          this.detailRequestParams.IndexId = row.IndexId
+          this.detailRequestParams.DataDate = ''
+          await this.getIndexDetailFun()
+          this.detailDiaShow=true
+          this.$nextTick(()=>{
+            this.$refs.detailDataListRef && (this.$refs.detailDataListRef.scrollTop=0)
+          })
+        },
+        async getIndexDetailFun(){
+          await highFrequencyDataInterface.highFreDataDetail(this.detailRequestParams).then(res=>{
+            if(res.Ret == 200){
+              let resData = res.Data||{}
+              let indexData = resData.Index || {}
+              this.detailRequestParams.DataDate = resData.DataDate
+              this.indexDetail={
+                IndexId:indexData.IndexId,
+                IndexName:indexData.IndexName,
+                ZqCode:indexData.StockCode,
+                ZbCode:indexData.Indicator,
+                ClassifyId:indexData.ClassifyId,
+                Unit:indexData.Unit,
+                Frequency:indexData.Frequency,
+                DataList:resData.DataList||[]
+              }
+            }
+          })
+        },
+        editDataHandle(){
+          if(!(this.indexDetail.IndexName && this.indexDetail.ClassifyId && this.indexDetail.Unit)){
+            return this.$message.warning(this.$t('MsgPrompt.please_complete'))
+          }
+          let params={
+            IndexId:this.indexDetail.IndexId,
+            IndexName:this.indexDetail.IndexName,
+            ClassifyId:this.indexDetail.ClassifyId,
+            Unit:this.indexDetail.Unit,
+          }
+          highFrequencyDataInterface.highFreDataEdit(params).then(res=>{
+            if(res.Ret == 200){
+              this.$message.success(this.$t('MsgPrompt.operate_success_msg'))
+              this.detailDiaShow=false
+              this.getTableData()
+            }
+          })
+        },
+        // 刷新
+        refreshIndexHandle(row){
+          highFrequencyDataInterface.highFreDataRefresh({
+            IndexId:row.IndexId
+          }).then(res=>{
+            if(res.Ret!==200) return
+            this.$message.success(/* "刷新成功"  */this.$t('MsgPrompt.refresh_success_msg'))
+            this.getTableData()
+          })
+        },
+        // 删除
+        deleteIndexHandle(row){
+          this.$confirm(this.$t('Edb.MsgPrompt.del_edb_confirm'),this.$t('Dialog.warn_tit'),{
+            confirmButtonText:/* "确定" */this.$t('Dialog.confirm_btn'),
+            cancelButtonText:/* "取消" */this.$t('Dialog.cancel_btn'),
+            type:"warning"
+          }).then(()=>{
+            highFrequencyDataInterface.highFreDataDelete({
+              IndexId:row.IndexId
+            }).then(res=>{
+              if(res.Ret!==200) return
+              this.$message.success(/* "删除成功"  */this.$t('MsgPrompt.delete_msg'))
+              this.selectList=this.selectList.filter(it => it!=row.IndexId)
+              this.getTableData()
+            })
+          }).catch(()=>{})
+        },
+        setClassify(){
+          this.classifySettingShow=true
+        },
+        classifyCloseHandle({requestClassifyList,requestDataList}){
+          if(requestDataList) this.getTableData('search')
+          if(requestClassifyList) this.getClassifyList()
+          this.classifySettingShow=false
+        },
+        async openBatchOperationDia(){
+          if(this.selectedTotal>500){
+            return this.$message.warning(this.$t('HighFrequencyData.batch_operation_limit'))
+          }
+          this.batchLoading = true
+          let flag = await this.getHighFreDataChoiceList()
+          this.batchLoading = false
+          this.batchOperationDialogShow=!!flag
+        },
+        async getHighFreDataChoiceList(){
+          let params={
+            ClassifyId:this.searchParams.classify,
+            IncludeChild:this.searchParams.isAssociativeSub,
+            Frequency:this.searchParams.frequency,
+            SysAdminId:this.searchParams.user,
+            Keywords:this.searchParams.keyWord,
+            ListIds:this.selectList.join(','),
+            SelectAll:this.isSelectAll,
+          }
+          return await highFrequencyDataInterface.highFreDataChoice(params).then(res=>{
+            if(res.Ret == 200){
+              const choiceList = res.Data || []
+              this.choiceIdList=choiceList.map(cl=> cl.IndexId)
+              return true 
+            }else{
+              return false
+            }
+          })
+        },
+        batchOperationClose(){
+          this.batchOperationDialogShow=false
+          this.batchOperationData={
+            type:1,
+            newClassify:0,
+            refreshType:1
+          }
+        },
+        batchOpeartion(){
+          if(this.batchOperationData.type==1 && !this.batchOperationData.newClassify) return this.$message.warning(this.$t('HighFrequencyData.select_classify_prompt'))
+          let params={
+            IndexIds:this.choiceIdList,
+            OptType:this.batchOperationData.type,
+            MoveClassifyId:this.batchOperationData.newClassify,
+            RefreshType:this.batchOperationData.refreshType
+          }
+          highFrequencyDataInterface.highFreDataBatchOperation(params).then(res=>{
+            if(res.Ret == 200){
+              if(this.batchOperationData.type==2){
+                // 批量删除
+                let deleteFails=res.Data.Fail || []
+                let deleteSuccess=res.Data.Success || []
+                if(deleteSuccess.length) this.$message.success(this.$t('MsgPrompt.operate_success_msg'))
+
+                if(deleteFails){
+                  let message = '';
+                  deleteFails.forEach(item => {
+                    message+=`${item.IndexName}:${this.$t('HighFrequencyData.indicator_been_referenced_prompt')}</br>`
+                  })
+                  // 和成功提示错开
+                  this.$nextTick(()=>{
+                    this.$message({
+                      dangerouslyUseHTMLString: true,
+                      message,
+                      type: 'error'
+                    })
+                  })
+                }
+                // 删除之后 调整选中
+                this.listCheckAllChange(false)
+              }else{
+                this.$message.success(this.$t('MsgPrompt.operate_success_msg'))
+              }
+              this.getTableData()
+              this.batchOperationDialogShow=false
+            }
+          })
+        },
+        async batchAddToDatabaseOpen(){
+          if(this.selectedTotal>500){
+            return this.$message.warning(this.$t('HighFrequencyData.batch_operation_limit'))
+          }
+          this.batchLoading = true
+          let flag = await this.getHighFreDataChoiceList()
+          this.batchLoading = false
+          this.batchAddToDatabaseShow=!!flag
+        }
+    },
+    mounted(){
+        this.getSourceList()
+        this.getSequenceList()
+        this.getClassifyList()
+        this.getUserList()
+        this.getUnitList()
+        this.getTableData()
+    }
+  }
+</script>
+
+<style scoped lang="scss">
+.hight-frequency-data-container{
+    min-height: calc(100vh - 120px);
+    display: flex;
+    flex-direction: column;
+    .top-box{
+        box-sizing: border-box;
+        margin-bottom: 16px;
+        display: flex;
+        .select-box{
+          span{
+            margin-right:10px;
+          }
+          .el-select{
+            margin-right:10px;
+            width:160px;
+          }
+        }
+    }
+    .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:10px;
+            .el-select,.el-cascader,.el-input{
+              max-width: 210px;
+            }
+            .associative-box{
+              display: flex;
+              align-items: center;
+              gap: 10px;
+              color: #333333;
+              .span-button{
+                color:#0052D9 ;
+                cursor: pointer;
+              }
+            }
+          }
+          .select-other{
+            margin-left: 10px;
+            .el-button{
+                margin-left:10px;
+            }
+          }
+      }
+      .el-table{
+          margin:20px 0;
+      }
+      .el-pagination{
+        text-align: right;
+        background-color: white;
+        padding: 10px 0;
+      }
+      .table-operation-item{
+        padding: 0 3px;
+        cursor: pointer;
+        color: #0052D9;
+        white-space: nowrap;
+      }
+      .del-item{
+        color: #D54941;
+      }
+    }
+    .custom-dialog{
+      .dialog-container{
+        overflow: hidden;
+        padding: 0 35px;
+        .detail-date-select-zone{
+          display:flex;
+          margin-bottom: 30px;
+          align-items:center;
+          span{
+            margin-right: 20px;
+          }
+          .el-input{
+            width: 240px;
+          }
+        }
+        .detail-data-zone{
+          display: flex;
+          flex-direction: column;
+          justify-content: center;
+          .detail-data-zone-header{
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            .header-table{
+              font-size: 14px;
+              border:solid 1px #C8CDD9;
+              box-sizing: border-box;
+              tr{
+                box-sizing: border-box;
+                td{
+                  padding: 10px;
+                  width: 270px;
+                  color: #666666;
+                  box-sizing: border-box;
+                  &:first-child{
+                      width: 150px;
+                      text-align: center;
+                      font-weight: bold;
+                      color: #333333;
+                  }
+                }
+              }
+            }
+          }
+          .detail-data-list{
+            height: 260px;
+            overflow: auto;
+            margin: 40px auto 30px auto;
+            .body-table{
+              border-left: solid 1px #C8CDD9;
+              border-right: solid 1px #C8CDD9;
+              tr{
+                box-sizing: border-box;
+                td{
+                  min-width: 150px;
+                  text-align: center;
+                  padding: 8px 10px;
+                  color: #666666;
+                  box-sizing: border-box;
+                  &:first-child{
+                    width: 260px;
+                    border-right:solid 1px #C8CDD9;
+                  }
+                }
+              }
+            }
+          }
+        }
+        // 批量操作
+        .batch-option-row{
+          margin-bottom: 20px;
+          .radio-box{
+            margin-top: 20px;
+            padding-left: 50px;
+            .el-radio{
+              margin-right: 20px;
+            }
+          }
+        }
+      }
+      .dialog-btn{
+        text-align: center;
+        padding: 40px 0 25px;
+        .el-button{
+          min-width: 120px;
+        }
+      }
+    }
+}
+</style>
+<style lang="scss">
+.custom-dialog{
+  .el-input{
+    width: 100%!important;
+  }
+}
+
+.detail-data-zone-header{
+  .el-cascader{
+    width: 100%;
+  }
+  .el-autocomplete{
+    width: 100%;
+  }
+  .el-select{
+    width: 100%;
+  }
+  .el-input{
+    width: 100%;
+    input{
+      border: none;
+      padding: 0;
+      font-size: 14px;
+    }
+  }
+}
+</style>

+ 44 - 9
src/views/dataEntry_manage/thirdBase/steelChemicalbase.vue

@@ -18,11 +18,15 @@
       <div class="left-top">
         <div>
           <el-button v-permission="permissionBtn.dataSourcePermission.mysteelData_add"
-          type="primary" size="medium" @click="addTargetBatch"
-            ><!-- 新增指标 -->{{$t('SteelChemicalPage.add_edb_btn')}}</el-button
+          type="primary" size="medium" @click="addTargetBatch" style="margin-bottom: 10px;"
+            ><!-- 新增指标(加入钢联化工数据库) -->{{$t('SteelChemicalPage.add_edb_btn')}}</el-button
           >
-          <el-button
-          v-permission="permissionBtn.dataSourcePermission.mysteelData_export"
+          <el-button style="margin-left: 0;margin-bottom: 10px;" v-permission="permissionBtn.dataSourcePermission.mysteelData_batchAddEdb"
+          type="primary" size="medium" @click="isBatchAddIndicsDiaShow = true"
+            ><!-- 批量加入指标库 -->{{$t('SteelChemicalPage.batch_add_edb_btn')}}</el-button
+          >
+          <el-button style="margin-left: 0;"
+            v-permission="permissionBtn.dataSourcePermission.mysteelData_export"
             type="primary"
             plain
             size="medium"
@@ -170,6 +174,7 @@
               tableType="header"
               ref="table"
               source="glhg"
+              @addToLib="handleAddToLib"
             />
           </div>
           <div class="data-cont" v-if="dateArr.length">
@@ -252,7 +257,20 @@
     <batch-add-edb-dia :isOpenDialog.sync="batchAddDiaShow" 
     :classifyList="classifyList" 
     @successCallback="addSuccessCallback"/>
+    <!-- 批量添加至指标库弹窗 -->
+    <batchAddIndicsDia 
+        :isOpenDialog="isBatchAddIndicsDiaShow"
+        @close="isBatchAddIndicsDiaShow=false"
+    />
+    <!-- 单个添加至指标库弹窗 -->
+    <addIndicsDia 
+        :isOpenDialog="isAddIndicsDiaShow"
+        :edbData="currentIndicData"
+        @close="isAddIndicsDiaShow=false;"
+        @addCallback="isAddIndicsDiaShow=false;getFrequency();"
+    />
   </div>
+
 </template>
 
 <script>
@@ -261,11 +279,13 @@ import { steelInterface } from "@/api/modules/thirdBaseApi";
 import mDialog from "@/components/mDialog.vue";
 import targetDialog from "./components/targetDialog.vue";
 import batchAddEdbDia from "./components/batchAddEdbDia.vue";
+import batchAddIndicsDia from "./components/batchAddIndicsDia"
+import addIndicsDia from "./components/addIndicsDia"
 import leftMixin from "./mixins/leftMixin.js";
 export default {
   name: "",
   mixins: [leftMixin],
-  components: { lzTable, mDialog, targetDialog,batchAddEdbDia },
+  components: { lzTable, mDialog, targetDialog,batchAddEdbDia,batchAddIndicsDia,addIndicsDia },
   data() {
     return {
       isLeftWrapShow:true,
@@ -309,7 +329,11 @@ export default {
       addTargetDialog: false, //添加指标弹窗
       edbForm: {},
       //批量添加指标弹窗
-      batchAddDiaShow:false
+      batchAddDiaShow:false,
+
+      isBatchAddIndicsDiaShow:false, //批量添加至指标库弹窗
+      isAddIndicsDiaShow:false,//单个添加至指标库弹窗
+      currentIndicData:{},//当前选中指标
     };
   },
   methods: {
@@ -704,6 +728,17 @@ export default {
         });
     },
 
+    handleAddToLib(data){
+        //添加前校验 ID是否已存在指标库中
+        //打开弹窗
+        this.currentIndicData = data
+        this.isAddIndicsDiaShow = true
+    },
+    addToLibCallback(){
+        //添加成功回调 
+        this.isAddIndicsDiaShow = false
+    },
+
     /* 添加后回调 */
     addSuccessCallback({ code, id,selectClassifyNodes,indexCode }) {
       indexCode && (this.index_code = indexCode)
@@ -760,8 +795,8 @@ export default {
     width: 5px !important;
   } */
   .left-cont {
-    min-width: 330px;
-    width: 330px;
+    min-width: 390px;
+    width: 390px;
     flex-shrink: 0;
     margin-right: 20px;
     padding: 30px 0;
@@ -772,7 +807,7 @@ export default {
     }
     .scroll-wrap {
       padding: 0 20px;
-      height: calc(100vh - 280px);
+      height: calc(100vh - 320px);
       overflow-y: auto;
       margin-right: 20px;
     }

+ 1 - 1
src/views/datasheet_manage/components/BalanceAddChart.vue

@@ -360,7 +360,7 @@
               <!-- 公历 -->
               <el-radio-button label="公历">{{$t('Chart.calendar_gre')}}</el-radio-button>
               <!-- 农历 -->
-              <el-radio-button label="农历">{{$t('Chart.calendar_lunar')}}</el-radio-button>
+              <el-radio-button label="农历">{{$t('Chart.calendar_lunar_text')}}</el-radio-button>
             </el-radio-group>
           </div>
           <!-- 季节图设置图例名称按钮 -->

+ 7 - 5
src/views/datasheet_manage/components/BalanceSheetChartItem.vue

@@ -119,12 +119,14 @@ export default {
             });
             let form = new FormData();
             form.append('Img', svg);
-            let { Data } = await dataBaseInterface.uploadImgSvg(form);
+            // let { Data } = await dataBaseInterface.uploadImgSvg(form);
 
-            await dataBaseInterface.setChartImage({
-                ChartInfoId: this.chartInfo.ChartInfoId,
-                ImageUrl: Data.ResourceUrl,
-            });
+            // await dataBaseInterface.setChartImage({
+            //     ChartInfoId: this.chartInfo.ChartInfoId,
+            //     ImageUrl: Data.ResourceUrl,
+            // });
+            form.append('ChartInfoId',this.chartInfo.ChartInfoId)
+            await dataBaseInterface.setChartThumbnail(form)
         },
 
         handleAddMyChart(){

+ 1 - 1
src/views/datasheet_manage/components/MixedTable.vue

@@ -1529,7 +1529,7 @@ export default {
       if(!source) return
       let concatSourceArr = this.sourceFrom.text?`${this.sourceFrom.text},${source}`.split(','):[source];
       let sourceStr = Array.from(new Set(concatSourceArr)).join(',');
-      this.sourceFrom.text=sourceStr
+      this.$set(this.sourceFrom,'text',sourceStr)
       this.$emit('updateSourceName')
     },
     // ==================================================合并单元格

+ 295 - 26
src/views/futures_manage/chartEditor.vue

@@ -111,9 +111,47 @@
 							:placeholder="$t('ToolBox.CommodityPriceChart.please_select_classify')"
 						/>
 					</el-form-item>
+					<el-form-item :label="$t('ToolBox.CommodityPriceChart.date_reference')" prop="basisEdb">
+						<el-select 
+							:placeholder="$t('ToolBox.CommodityPriceChart.tips_msg09')" 
+							v-model="chartInfo.basisEdb" 
+							style="width: 90%"
+							@change="handleBasisEdbChange"
+						>
+							<el-option 
+								v-for="item in tableData" 
+								:key="item.EdbInfoId"
+								:label="item.EdbName"
+								:value="item.EdbInfoId"
+							/>
+						</el-select>
+						<el-tooltip class="item" effect="dark" :content="$t('ToolBox.CommodityPriceChart.tips_msg08')" placement="top">
+							<i class="el-icon-info"></i>
+						</el-tooltip>
+					</el-form-item>
 				</el-form>
 
 				<div class="targetset-cont">
+					<!-- 选择的指标模块 -->
+					<div class="basis-edb-wrap" v-if="tableData.length>0">
+						<div class="label-btn" @click="isShowxAxisSet=true">{{$t('ToolBox.CommodityPriceChart.xAxis_set_name')}}</div>
+						<div 
+							class="item-basis-edb" 
+							v-for="item,index in tableData" 
+							:key="item.EdbInfoId"
+						>
+							<span class="name">{{$i18n.locale == 'zh'?item.EdbName:item.EdbNameEn||item.EdbName}}</span>
+							<div class="opt-box">
+								<img 
+									class="icon" 
+									:src="item.isHide?require('@/assets/img/icons/eyes-hide-active.png') : require('@/assets/img/icons/eyes-show-active.png')" 
+									alt=""
+									@click="handleChangeBasisEdbHide(item,index)"
+								>
+								<img class="icon" src="~@/assets/img/icons/delete-red.png" alt="" @click="handleBasisEdbDel(index,item)">
+							</div>
+						</div>
+					</div>
 					
 					<!-- 价格曲线日期配置 -->
 					<bar-option
@@ -190,6 +228,12 @@
 		:data="profitInfo"
 		@ensure="setProfitBack"
 	/>
+	<!-- 横坐标设置 -->
+	<xAxisSet 
+		:isShow.sync="isShowxAxisSet"
+		:opts="xAxisList"
+		@change="handleXAxisDataChange"
+	/>
   </div>
 </template>
 
@@ -200,8 +244,9 @@ import { chartSetMixin } from '@/views/dataEntry_manage/mixins/chartPublic';
 import Chart from '@/views/dataEntry_manage/components/chart';
 import barOption from '@/views/dataEntry_manage/components/barOptionSection.vue';
 import plateProfitDia from './components/plateProfitDia.vue';
+import xAxisSet from './components/xAxisSet.vue';
 export default {
-  components: { Chart,barOption,plateProfitDia },
+  components: { Chart,barOption,plateProfitDia,xAxisSet },
 	directives: {
     drag(el, bindings) {
       el.onmousedown = function (e) {
@@ -246,6 +291,9 @@ export default {
 				classify:[
 					{ required: true, message: this.$t('ToolBox.CommodityPriceChart.tips_msg03')||'图表分类不能为空', trigger: 'blur' },
 				],
+				basisEdb:[
+					{ required: true, message: this.$t('ToolBox.CommodityPriceChart.tips_msg07')||'日期基准不能为空', trigger: 'blur' },
+				]
 			}
 		}
 	},
@@ -262,6 +310,7 @@ export default {
 				futures_id: '',
 				classify: '',
 				Source: this.$route.query.scence==='profit' ? 5 : 2,
+				basisEdb:'',//选择的基准指标
 			},
 
 			classifyOptions: [],//分类option
@@ -278,11 +327,21 @@ export default {
 			profitInfo: {
 				list: [],
 				formula: ''
-			}
+			},
 
+			// 横坐标设置
+			isShowxAxisSet:false,
+			xAxisList:[],
     };
   },
   methods: {
+		// 刷新数据
+		handleRefreshChartData(){
+			// 价格曲线判断 this.chartInfo.futures_id
+			if(this.chartInfo.Source===2&&!this.chartInfo.futures_id) return
+			this.tableData.length && this.$refs.BarOptRef.getBarData();
+			console.log('刷新图表');
+		},
 
 		/* 获取图表详情 */
 		getChartInfo() {
@@ -291,22 +350,41 @@ export default {
         })
         .then((res) => {
           if (res.Ret !== 200) return;
-					const { ChartInfo,BarChartInfo,EdbInfoList,DataResp } = res.Data;
+					let { ChartInfo,BarChartInfo,EdbInfoList,DataResp,XDataList } = res.Data;
 
           this.chartInfo = ChartInfo.Source===5 ? {
 						...ChartInfo,
 						classify: ChartInfo.ChartClassifyId,
 						ProfitNameEn: DataResp.ProfitNameEn,
 						ProfitName: DataResp.ProfitName,
+						basisEdb:DataResp.Extra.BaseEdbInfoId
 					} : {
 						...ChartInfo,
 						classify: ChartInfo.ChartClassifyId,
-						futures_id: BarChartInfo.EdbInfoIdList.find(_ => _.Source===2).EdbInfoId
+						futures_id: BarChartInfo.EdbInfoIdList.find(_ => _.Source===2).EdbInfoId,
+						basisEdb:BarChartInfo.BaseEdbInfoId
 					};
+					if(ChartInfo.Source===5){
+						XDataList=DataResp.Extra.XDataList
+					}
+
+					// this.tableData = [EdbInfoList[0]];
+					this.tableData=EdbInfoList.filter(_e=>_e.Source).map((_e,index)=>{
+						return{
+							EdbInfoId:_e.EdbInfoId,
+							EdbName:_e.EdbName,
+							EdbNameEn:_e.EdbNameEn,
+							isHide:XDataList[index].IsHide?true:false
+						}
+					})
+					this.xAxisList=XDataList.map((_item,index)=>{
+						return {
+							..._item,
+							// 判断是否为选择的指标
+							EdbInfoId:EdbInfoList[index]&&EdbInfoList[index].Source?EdbInfoList[index].EdbInfoId:0,
+						}
+					})
 
-					this.search_txt = EdbInfoList[0].EdbInfoId;
-					this.tableData = [EdbInfoList[0]];
-					this.searchOptions = this.tableData;
 
 					this.initDateOptions = ChartInfo.Source===5 ? {
 						DateList: DataResp.Extra.DateList,
@@ -326,23 +404,118 @@ export default {
     /* 选择指标 获取指标详情并push到表格中*/
 		selectTarget(edb) {
 			if(!edb){
-				this.tableData = [];
+				// this.tableData = [];
 				return
 			} 
+			// 不允许添加重复的指标
+			if(this.tableData.some(_=>_.EdbInfoId===edb.EdbInfoId)){
+				this.$message.warning(this.$t('OnlineExcelPage.already_exists_msg'))
+				return
+			}
+
+			this.tableData.push({...edb,isHide:false});
+			console.log(this.xAxisList);
+			// 向横坐标配置项中插入值
+			if(this.xAxisList.length){
+				const index=this.xAxisList.findIndex(i=>i.EdbInfoId===0)
+				console.log(index);
+				if(index!=-1){
+					this.xAxisList.splice(index,0,{
+						EdbInfoId:edb.EdbInfoId,
+						IsHide:0,
+						Name:edb.EdbName,
+						NameEn:edb.EdbNameEn
+					})
+				}else{
+					this.xAxisList.push({
+						EdbInfoId:edb.EdbInfoId,
+						IsHide:0,
+						Name:edb.EdbName,
+						NameEn:edb.EdbNameEn
+					})
+				}
+			}
+			
+			
+			this.search_txt=''
+			this.search_page = 1;
+			this.searchOptions=[]
+			if(!this.chartInfo.basisEdb){
+				this.chartInfo.basisEdb=this.tableData[0].EdbInfoId
+			}
+			this.handleRefreshChartData()
+		},
+
+		// 选择的指标显示隐藏状态改变
+		handleChangeBasisEdbHide(item,index){
+			item.isHide=!item.isHide
+			this.xAxisList[index].IsHide=item.isHide?1:0
+			this.handleRefreshChartData()
+		},
+		// 删除选择的指标
+		async handleBasisEdbDel(index,item){
+			if(this.tableData.length===1){
 
-			this.tableData = [edb];
-			this.commodityChartData.length && this.chartInfo.futures_id && this.$refs.BarOptRef.getBarData();
+				await this.$confirm(this.$t('ToolBox.CommodityPriceChart.del_edb_empty_tips'),this.$t('Dialog.warn_tit'),{
+					type:'warning'
+				}) 
+			}
+			
+			this.tableData.splice(index,1)
+			this.xAxisList.splice(index,1)
+			if(this.chartInfo.basisEdb===item.EdbInfoId){
+				this.chartInfo.basisEdb=''
+				this.xAxisList=[]
+				return
+			}
+			this.handleRefreshChartData()
+		},
+		// 横坐标设置修改回调
+		handleXAxisDataChange(arr){
+			console.log('横坐标修改回调',arr);
+			this.xAxisList=arr
+			// 修改tableData
+			const temArr=this.tableData.filter(_e=>arr.some(_i=>_i.EdbInfoId===_e.EdbInfoId))
+			console.log(temArr)
+
+			temArr.forEach(item=>{
+				arr.forEach(_item=>{
+					if(_item.EdbInfoId===item.EdbInfoId){
+						item.isHide=_item.IsHide?true:false
+					}
+				})
+			})
+
+			this.tableData=temArr
+			if(temArr.length===0){
+				this.chartInfo.basisEdb=''
+				this.xAxisList=[]
+				return
+			}
+			this.handleRefreshChartData()
+			
 		},
 
 		/* 选择期货 */
 		changeFuturesHandle(val) {
 			if(!val) return
-			this.commodityChartData.length && this.tableData.length && this.$refs.BarOptRef.getBarData();
+			this.xAxisList=[]
+			this.handleRefreshChartData()
+		},
+
+		// 日期基准变更
+		handleBasisEdbChange(val){
+			if(!val) return
+			this.xAxisList=[]
+			this.handleRefreshChartData()
 		},
 
     /* 获取数据 */
 		async getPreviewData({sort,dateList}) {
-			if(!dateList.length) this.commodityChartData = [];
+			if(!dateList.length) {
+				this.commodityChartData = []
+				this.xAxisList=[]
+			};
 			if(!this.tableData.length || !dateList.length) return
 
 			this.chartInfo.Source===2
@@ -353,6 +526,22 @@ export default {
 
 		/* 价格曲线预览 */
 		async getCommodityPreview(dateList) {
+			if(!this.chartInfo.basisEdb){
+				this.$message.warning(this.$t('ToolBox.CommodityPriceChart.tips_msg09')||'请选择日期基准');
+				return
+			}
+			if(!this.chartInfo.futures_id){
+				this.$message.warning(this.$t('ToolBox.CommodityPriceChart.please_select_future')||'请选择期货');
+				return
+			}
+
+			const xDataListArr=this.xAxisList.map(_item=>{
+				return {
+					Name:_item.Name,
+					NameEn:_item.NameEn,
+					IsHide:_item.IsHide
+				}
+			})
 			let params = {
 				EdbInfoIdList: [
 					...this.tableData.map(_ => ({EdbInfoId: _.EdbInfoId,Name:'',Source: 1})),
@@ -365,6 +554,8 @@ export default {
 					Name: '',
 					Color: _.Color
 				})),
+				BaseEdbInfoId:this.chartInfo.basisEdb,
+				XDataList:xDataListArr||[]
 			}
 
 			const res = await futuresInterface.getChartData(params);
@@ -374,6 +565,13 @@ export default {
 			this.commodityEdbList = EdbInfoList;
 			this.commodityChartData = YDataList;
 			this.commodityXData = XDataList;
+			this.xAxisList=XDataList.map((_item,index)=>{
+				return {
+					..._item,
+					// 判断是否为选择的指标
+					EdbInfoId:EdbInfoList[index]&&EdbInfoList[index].Source?EdbInfoList[index].EdbInfoId:0,
+				}
+			})
 
 			//初始状态设置上下限极值
 			if(!this.chartInfo.LeftMin) {
@@ -389,12 +587,22 @@ export default {
 		/* 利润曲线预览 */
 		async getProfitPreview(dateList) {
 			if(!this.profitInfo.list.length) return this.$message.warning(this.$t('ToolBox.CommodityPriceChart.tips_msg04')||'请先设置盘面利润配置')
-
+			if(!this.chartInfo.basisEdb){
+				this.$message.warning(this.$t('ToolBox.CommodityPriceChart.tips_msg09')||'请选择日期基准');
+				return
+			}
+			const xDataListArr=this.xAxisList.map(_item=>{
+				return {
+					Name:_item.Name,
+					NameEn:_item.NameEn,
+					IsHide:_item.IsHide
+				}
+			})
 			const { list,formula } = this.profitInfo;
 			let params = {
 				FutureGoodEdbInfoIdList: list,
 				CalculateFormula: formula,
-				BaseEdbInfoId: this.tableData[0].EdbInfoId,
+				BaseEdbInfoId: this.chartInfo.basisEdb,
 				DateList: dateList.map(_ => ({
 					Type: _.Type,
 					Date: _.Date,
@@ -402,7 +610,10 @@ export default {
 					Name: '',
 					Color: _.Color
 				})),
+				EdbInfoIdList:this.tableData.map(i=>i.EdbInfoId),
+				XDataList:xDataListArr||[]
 			}
+			console.log('刷新利润曲线');
 
 			const res = await futuresInterface.previewProfitData(params);
 			if(res.Ret !== 200) return
@@ -413,6 +624,13 @@ export default {
 			this.commodityEdbList = EdbInfoList;
 			this.commodityChartData = YDataList;
 			this.commodityXData = XDataList;
+			this.xAxisList=XDataList.map((_item,index)=>{
+				return {
+					..._item,
+					// 判断是否为选择的指标
+					EdbInfoId:EdbInfoList[index]&&EdbInfoList[index].Source?EdbInfoList[index].EdbInfoId:0,
+				}
+			})
 			this.chartInfo = {
 				...this.chartInfo,
 				ProfitName,
@@ -499,19 +717,26 @@ export default {
 				ChartType:8,
 				DateType: 6,
 			}
-			
+
 			this.chartInfo.Source === 2 ? this.handleSaveCommodity(public_param) : this.handleSaveProfit(public_param);
 		},
 		
 		/* 商品价格曲线保存 */
 		async handleSaveCommodity(public_param) {
+			const xDataListArr=this.xAxisList.map(_item=>{
+				return {
+					Name:_item.Name,
+					NameEn:_item.NameEn,
+					IsHide:_item.IsHide
+				}
+			})
 			let params =  {
 				...public_param,
 				LeftMin: String(this.chartLimit.min),
 				LeftMax: String(this.chartLimit.max),
 				BarChartInfo: {
 					EdbInfoIdList: [
-						...this.tableData.map(_ => ({EdbInfoId: _.EdbInfoId,Name:'',Source: 1})),
+						...this.tableData.map(_ => ({EdbInfoId: _.EdbInfoId,Source: 1})),
 						{ EdbInfoId: this.chartInfo.futures_id,Name: '',Source: 2 }
 					],
 					DateList: this.$refs.BarOptRef.dateList.map(item => ({
@@ -520,8 +745,10 @@ export default {
 						Value: item.Value,
 						Name: '',
 						Color: item.Color
-					}))
-				}
+					})),
+					BaseEdbInfoId:this.chartInfo.basisEdb,
+					XDataList:xDataListArr||[]
+				},
 			}
 
 			const { Ret,Data } = this.chart_code
@@ -536,6 +763,13 @@ export default {
 		async handleSaveProfit(public_param) {
 			if(!this.profitInfo.list.length)  return this.$message.warning(this.$t('ToolBox.CommodityPriceChart.tips_msg04')||'请先设置盘面利润配置');
 			const { list,formula } = this.profitInfo;
+			const xDataListArr=this.xAxisList.map(_item=>{
+				return {
+					Name:_item.Name,
+					NameEn:_item.NameEn,
+					IsHide:_item.IsHide
+				}
+			})
 			let params = {
 				...public_param,
 				LeftMin: String(this.chartLimit.min),
@@ -543,7 +777,7 @@ export default {
 				Extra: {
 					FutureGoodEdbInfoIdList: list,
 					CalculateFormula: formula,
-					BaseEdbInfoId: this.tableData[0].EdbInfoId,
+					BaseEdbInfoId: this.chartInfo.basisEdb,
 					DateList: this.$refs.BarOptRef.dateList.map(_ => ({
 						Type: _.Type,
 						Date: _.Date,
@@ -551,6 +785,8 @@ export default {
 						Name: '',
 						Color: _.Color
 					})),
+					EdbInfoIdList:this.tableData.map(i=>i.EdbInfoId),
+					XDataList:xDataListArr||[]
 				}
 			}
 
@@ -576,12 +812,13 @@ export default {
     },
     
     async setImageHandle(form,{ UniqueCode,ChartInfoId }) {
-      let { Data } = await dataBaseInterface.uploadImgSvg(form);
-      await dataBaseInterface.setChartImage({
-        ChartInfoId: ChartInfoId,
-        ImageUrl: Data.ResourceUrl,
-      });
-
+      // let { Data } = await dataBaseInterface.uploadImgSvg(form);
+      // await dataBaseInterface.setChartImage({
+      //   ChartInfoId: ChartInfoId,
+      //   ImageUrl: Data.ResourceUrl,
+      // });
+			form.append('ChartInfoId',ChartInfoId)
+			await dataBaseInterface.setChartThumbnail(form)
 			this.$message.success(this.chart_code ? this.$t('MsgPrompt.add_msg2')||'添加成功' : this.$t('MsgPrompt.saved_msg')||'保存成功');
 			this.$router.replace({
 				path: '/commordityChartBase',
@@ -600,7 +837,11 @@ export default {
 		/* 盘面利润数据 */
 		setProfitBack(obj) {
 			this.profitInfo = obj;
-			this.tableData.length && this.$refs.BarOptRef.dateList.length && this.getPreviewData({sort:null,dateList:this.$refs.BarOptRef.dateList});
+			if(this.tableData.length && this.$refs.BarOptRef.dateList.length){
+				// 重置x轴
+				this.xAxisList=[]
+				this.getPreviewData({sort:null,dateList:this.$refs.BarOptRef.dateList});
+			}
 		},
 	},
   mounted() {
@@ -753,6 +994,34 @@ export default {
 					display: flex;
 					margin-bottom: 20px;
 				}
+
+				.basis-edb-wrap{
+					.label-btn{
+						cursor: pointer;
+						color: #409eff;
+						margin-bottom: 10px;
+					}
+					.item-basis-edb{
+						background-color: #F0F2F5;
+						border: 1px solid #DCDFE6;
+						padding: 10px 5px;
+						margin-bottom: 5px;
+						display: flex;
+						.name{
+							flex: 1;
+						}
+						.opt-box{
+							display: flex;
+							align-items: center;
+							gap: 0 5px;
+							.icon{
+								width: 16px;
+								height: 16px;
+								cursor: pointer;
+							}
+						}
+					}
+				}
 			}
 		}
 		.move-btn {

+ 10 - 7
src/views/futures_manage/commodityChartBase.vue

@@ -575,12 +575,14 @@ export default {
     },
 
     async setImageHandle(form) {
-      let { Data } = await dataBaseInterface.uploadImgSvg(form);
-
-      await dataBaseInterface.setChartImage({
-        ChartInfoId: this.selected_chartid,
-        ImageUrl: Data.ResourceUrl,
-      });
+      // let { Data } = await dataBaseInterface.uploadImgSvg(form);
+
+      // await dataBaseInterface.setChartImage({
+      //   ChartInfoId: this.selected_chartid,
+      //   ImageUrl: Data.ResourceUrl,
+      // });
+			form.append('ChartInfoId',this.chartInfo.ChartInfoId)
+			await dataBaseInterface.setChartThumbnail(form)
     },
 
 		copyChartConfirm(type) {
@@ -717,7 +719,8 @@ export default {
 					ProfitNameEn: res.Data.DataResp.ProfitNameEn,
 					ProfitName: res.Data.DataResp.ProfitName,
 				} : res.Data.ChartInfo;
-				this.tableData = [res.Data.EdbInfoList[0]]
+				// this.tableData = [res.Data.EdbInfoList[0]]
+				this.tableData=res.Data.EdbInfoList.filter(_e=>_e.Source)
 				this.initCommodityData(res.Data)
 			})
 		},

+ 137 - 0
src/views/futures_manage/components/xAxisSet.vue

@@ -0,0 +1,137 @@
+<template>
+  <el-dialog
+    :visible.sync="isShow"
+    :close-on-click-modal="false"
+    :modal-append-to-body="true"
+		append-to-body
+    :title="$t('ToolBox.CommodityPriceChart.xAxis_set_name')"
+    @close="cancelHandle"
+    custom-class="xAxis-set-dialog"
+    center
+    width="800px"
+    top="8vh"
+    v-dialogDrag
+  >
+    <div class="list-wrap">
+      <ul class="list-box">
+        <li v-for="item,index in arr" :key="`${item.EdbInfoId}_${index}`" class="item">
+          <el-input v-model="item.label"></el-input>
+          <img
+            class="icon"
+            :src="
+              item.IsHide
+                ? require('@/assets/img/icons/eyes-hide-active.png')
+                : require('@/assets/img/icons/eyes-show-active.png')
+            "
+            alt=""
+            @click="handleChangeBasisEdbHide(item, index)"
+          />
+          <img class="icon" src="~@/assets/img/icons/delete-red.png" alt="" v-if="item.EdbInfoId" @click="handleBasisEdbDel(index,item)">
+        </li>
+      </ul>
+			<div class="btns">
+				<el-button type="primary" plain @click="cancelHandle">{{$t('Dialog.cancel_btn')}}</el-button>
+				<el-button type="primary" @click="handleSave">{{$t('Dialog.confirm_save_btn')}}</el-button>
+			</div>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+export default {
+  props: {
+    isShow: {
+      type: Boolean,
+    },
+    opts: []
+  },
+  watch: {
+    isShow(n) {
+      console.log('isShow', this.opts);
+      if (n) {
+        const arr = this.opts || []
+        this.arr = arr.map(item => {
+          return {
+						...item,
+            label: this.$i18n.locale == 'zh' ? item.Name : item.NameEn,
+          }
+        })
+      }
+    }
+  },
+  data() {
+    return {
+      arr: []
+    }
+  },
+  methods: {
+    cancelHandle() {
+      this.$emit('update:isShow', false);
+    },
+
+		handleSave(){
+			this.arr.forEach(item => {
+				if(this.$i18n.locale == 'zh'){
+					item.Name=item.label
+				}else{
+					item.NameEn=item.label
+				}
+			});
+      if(this.arr.length){
+        this.$emit('change',this.arr)
+      }
+			this.cancelHandle()
+		},
+
+		handleChangeBasisEdbHide(item,index){
+			item.IsHide=item.IsHide?0:1
+		},
+
+		handleBasisEdbDel(item,index){
+			const count=this.arr.filter(i=>i.EdbInfoId)
+			if(count.length===1){
+				this.$confirm(this.$t('ToolBox.CommodityPriceChart.del_edb_empty_tips'),this.$t('Dialog.warn_tit'),{
+					type:'warning'
+				}).then(()=>{
+					this.arr.splice(index,1)
+				}).catch(()=>{})
+				return 
+			}
+			this.arr.splice(index,1)
+		}
+
+
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.list-wrap{
+	.list-box{
+		display: flex;
+		flex-wrap: wrap;
+		gap: 20px 0;
+		.item{
+			width: 50%;
+			padding: 0 10px;
+			display: flex;
+			align-items: center;
+			box-sizing: border-box;
+			.el-input{
+				width: 300px;
+			}
+			.icon{
+				width: 16px;
+				height: 16px;
+				margin-left: 10px;
+				display: block;
+			}
+		}
+	}
+	.btns{
+		margin-top: 20px;
+		padding: 30px 0;
+		text-align: center;
+	}
+}
+</style>

+ 39 - 13
src/views/mychart_manage/components/chartDetailDia.vue

@@ -353,7 +353,7 @@
                   @change="getPreviewChartInfo"
                 >
                   <el-radio-button label="公历">{{$t('Chart.calendar_gre')}}</el-radio-button>
-                  <el-radio-button label="农历">{{$t('Chart.calendar_lunar')}}</el-radio-button>
+                  <el-radio-button label="农历">{{$t('Chart.calendar_lunar_text')}}</el-radio-button>
                 </el-radio-group>
 
                 <!-- 图表说明 -->
@@ -639,13 +639,20 @@ export default {
           this.refreshLoading = false;
           if (res.Ret !== 200) return;
           this.chartInfo = res.Data.ChartInfo;
-          
+
+          this.chartInfo.SeasonExtraConfig && (this.SeasonExtraConfig = JSON.parse(this.chartInfo.SeasonExtraConfig))
+
           if(!this.chartInfo.HaveOperaAuth) return
 
           if([1,11].includes(this.chartInfo.Source)) {
             //处理下历史默认来源
             this.setDefaultSourceFrom();
-            
+            //季节性图处理SeasonAverageConfig,SeasonRightEdbConfig
+            if(this.chartInfo.ChartType===2){
+                const {MaxMinLimits,SamePeriodAverage,SamePeriodStandardDeviation,RightAxis} = res.Data.DataResp
+                this.chartInfo.SeasonAverageConfig = {MaxMinLimits,SamePeriodAverage,SamePeriodStandardDeviation}
+                this.chartInfo.SeasonRightConfig = RightAxis
+            }
             this.tableData = res.Data.EdbInfoList;
             //初始化上下限
             this.setLimitData(this.tableData)
@@ -661,7 +668,8 @@ export default {
             //雷达图
             this.chartInfo.ChartType === 11 && this.initRadarData(res.Data);
           }else if([2,5].includes(this.chartInfo.Source)) {
-            this.tableData = [res.Data.EdbInfoList[0]];
+            // this.tableData = [res.Data.EdbInfoList[0]];
+            this.tableData=res.Data.EdbInfoList.filter(_e=>_e.Source)
             this.chartInfo = res.Data.ChartInfo.Source===5 ? {
               ...res.Data.ChartInfo,
               ProfitNameEn: res.Data.DataResp.ProfitNameEn,
@@ -778,14 +786,30 @@ export default {
           ConvertType:Number(_.ConvertType),
           ConvertValue:Number(_.ConvertValue),
           ConvertUnit:Number(_.IsConvert)?_.ConvertUnit:'',
-          ConvertEnUnit:Number(_.IsConvert)?_.ConvertEnUnit:''
-        }))
+          ConvertEnUnit:Number(_.IsConvert)?_.ConvertEnUnit:'',
+          IsAxis:_.IsAxis
+        })),
+        MarkersLines:this.chartInfo.MarkersLines||''
       }
 
       const res = await dataBaseInterface.getSplinePreviewData(params)
 
       if(res.Ret !== 200) return
-
+      //标识线回显
+      this.chartInfo.MarkersLines = res.Data.ChartInfo.MarkersLines||''
+      if(this.chartInfo.ChartType===2){
+        //更新对应数据
+        const {DataResp} = res.Data
+        const {MaxMinLimits,SamePeriodAverage,SamePeriodStandardDeviation,
+                RightAxis={
+                    IndicatorType:1,
+                    EdbInfoList:[]
+                }} = DataResp
+        this.chartInfo.SeasonAverageConfig = {
+            MaxMinLimits,SamePeriodAverage,SamePeriodStandardDeviation
+        }
+        this.chartInfo.SeasonRightConfig = RightAxis
+      }
       const { EdbInfoList } = res.Data;
 
       this.tableData.forEach((item) => {
@@ -1225,12 +1249,14 @@ export default {
         this.setImageHandle(form);
     },
     async setImageHandle(form) {
-      let { Data } = await dataBaseInterface.uploadImgSvg(form);
-      // let { Data } = await dataBaseInterface.uploadImg(form);
-      await dataBaseInterface.setChartImage({
-        ChartInfoId: this.chartInfo.ChartInfoId,
-        ImageUrl: Data.ResourceUrl,
-      });
+      // let { Data } = await dataBaseInterface.uploadImgSvg(form);
+      // // let { Data } = await dataBaseInterface.uploadImg(form);
+      // await dataBaseInterface.setChartImage({
+      //   ChartInfoId: this.chartInfo.ChartInfoId,
+      //   ImageUrl: Data.ResourceUrl,
+      // });
+      form.append('ChartInfoId',this.chartInfo.ChartInfoId)
+			await dataBaseInterface.setChartThumbnail(form)
     },
 
     /* 点击表格行展开配置项 */

+ 148 - 4
src/views/ppt_manage/mixins/mixins.js

@@ -2,6 +2,12 @@
 import Highcharts from 'highcharts';
 import { defaultOpts, seasonOptions,getTerminal,browser } from '@/utils/defaultOptions';
 
+//获取RGBA的透明度
+const parseRgbaColor = (color='rgba(51, 51, 51, 1)') => {
+    const arr = color.match(/(\d(\.\d+)?)+/g) || ['','','',1];
+    return parseFloat(arr[3]||1)
+}
+
 // 散点x轴
 const scatterXAxis = {
   tickPosition: 'inside',
@@ -443,7 +449,7 @@ export default {
     setSeasonChart() {
       /* 季节性图的图表配置 */
       const chartData = this.dataList[0];
-
+      const {SeasonRightConfig={}} = this.chartInfo
        /* 主题样式*/
       const chartTheme =  this.chartInfo.ChartThemeStyle ? JSON.parse(this.chartInfo.ChartThemeStyle) : null;
 
@@ -460,9 +466,14 @@ export default {
         seasonData = []
 
         //获取对应轴的上下限
-        let minLimit = 0,maxLimit = 0
+        let minLimit = 0,maxLimit = 0,rightMin=0,rightMax=0
         minLimit = this.chartLimit.min||0
         maxLimit = this.chartLimit.max||0
+        //右轴
+        if(SeasonRightConfig.IsShow){
+            rightMin = this.chartLimit.rightMin||0
+            rightMax = this.chartLimit.rightMax||0
+        }
       //数据列
       for (let index in chartDataHandle) {
         let j = chartDataHandle[index]
@@ -493,6 +504,81 @@ export default {
         seasonData.push(serie_item);
       }
 
+      //数据列-同期上下限/均线/标准差
+      const {MaxMinLimits={},SamePeriodAverage={},SamePeriodStandardDeviation={}} = this.chartInfo.SeasonAverageConfig||{}
+      if(MaxMinLimits.IsShow&&MaxMinLimits.List&&MaxMinLimits.List.length){
+        let serieItem = {
+            type:'arearange',//上下限是一个范围
+            data:[],
+            name:MaxMinLimits.Legend||'同期上下限',
+            color:MaxMinLimits.Color||'#075EEE',
+            fillOpacity:parseRgbaColor(MaxMinLimits.Color||'')>0.75?0.75:parseRgbaColor(MaxMinLimits.Color||'') //透明度最高0.75 
+        }
+        MaxMinLimits.List.forEach(item=>{
+            serieItem.data.push([item.DataTimestamp,item.MinValue,item.MaxValue])
+        })
+        seasonData.push(serieItem)
+      }
+      if(SamePeriodAverage.IsShow&&SamePeriodAverage.List){
+        let serieItem = {
+            type:'line',
+            data:[],
+            lineWidth:SamePeriodAverage.LineWidth,
+            dashStyle:SamePeriodAverage.LineType,
+            name:SamePeriodAverage.Legend||'同期均值',
+            color:SamePeriodAverage.Color||'#075EEE'
+        }
+        SamePeriodAverage.List.forEach(item=>{
+            serieItem.data.push([item.DataTimestamp,item.Value])
+        })
+        seasonData.push(serieItem)
+      }
+      if(SamePeriodStandardDeviation.IsShow&&SamePeriodStandardDeviation.List){
+        let serieItem = {
+            type:'arearange',//标准差也是一个范围
+            data:[],
+            name:SamePeriodStandardDeviation.Legend||'同期标准差',
+            color:SamePeriodStandardDeviation.Color||'#075EEE',
+            fillOpacity:parseRgbaColor(SamePeriodStandardDeviation.Color||'')>0.75?0.75:parseRgbaColor(SamePeriodStandardDeviation.Color||'')
+        }
+        SamePeriodStandardDeviation.List.forEach(item=>{
+            serieItem.data.push([item.DataTimestamp,item.MinValue,item.MaxValue])
+        })
+        seasonData.push(serieItem)
+      }
+      //数据列-右轴
+      if(SeasonRightConfig.IsShow){
+        //右轴的设置
+        let serieConfig = SeasonRightConfig.Style==='column'?{
+            //柱形
+            type:'column',
+            color:SeasonRightConfig.ChartColor
+        }:{
+            //标记点
+            type:'spline',
+            lineWidth:SeasonRightConfig.LineWidth,
+            dashStyle:SeasonRightConfig.LineStyle,
+            color:SeasonRightConfig.IsConnected?SeasonRightConfig.LineColor:'rgba(255, 255, 255, 0)',//没有连线颜色设置为透明
+            marker:{
+                enabled:true,
+                symbol:SeasonRightConfig.Shape,
+                fillColor:SeasonRightConfig.ChartColor,
+                radius:SeasonRightConfig.Size
+            },
+        }
+        let serieItem = {
+            ...serieConfig,
+            name:SeasonRightConfig.Legend||'右轴',
+            data:[],
+            yAxis:1,
+        }
+        const DataList = (SeasonRightConfig.IndicatorType===1?SeasonRightConfig.EdbInfoList[0].DataList:this.dataList[1].DataList)||[]
+        DataList.forEach(item=>{
+            serieItem.data.push([item.DataTimestamp,item.Value])
+        })
+        seasonData.push(serieItem)
+      }
+
       //y轴
       const textZh = chartData.ConvertUnit||chartData.Unit
       const textEn = chartData.ConvertEnUnit||chartData.UnitEn||chartData.ConvertUnit||chartData.Unit
@@ -531,6 +617,44 @@ export default {
         plotBands: this.setAxisPlotAreas(1),
         plotLines: this.setAxisPlotLines(1)
       }];
+      //如果有右轴,seasonYdata加上右轴
+      if(SeasonRightConfig.IsShow){
+        const rightEdb = (SeasonRightConfig.IndicatorType===1?SeasonRightConfig.EdbInfoList[0]:this.dataList[1])||{unit:''}
+        //左轴同比:text为空或% 右轴指标:取指标单位
+        if(SeasonRightConfig.IndicatorType===1){
+            rightEdb.Unit = SeasonRightConfig.NumFormat===1?'%':''
+        }else{
+            rightEdb.Unit = this.dataList[1]&&(this.dataList[1].ConvertUnit||this.dataList[1].Unit)||''
+        }
+        seasonYdata.push({
+            ...seasonOptions.yAxis,
+            opposite: true,//右轴
+            labels: {
+                formatter: function () {
+                  let val = this.value;
+                  return val;
+                },
+                align: 'center',
+                style: {
+                  ...chartTheme&&chartTheme.yAxisOptions.style
+                }
+              },
+              title: {
+                text: rightEdb.Unit||'',
+                style:{
+                  ...chartTheme&&chartTheme.yAxisOptions.style
+                },
+                align: 'high',
+                rotation: 0,
+                y: -12,
+                x: -rightEdb.Unit.length*12 ,
+                textAlign: 'right',
+                reserveSpace: false,
+              },
+              max: Number(rightMax),
+              min: Number(rightMin),
+        })
+      }
 
       // 季节图x轴显示月/日 周度指标额外处理时间轴显示
       const xAxis = {
@@ -857,7 +981,7 @@ export default {
       //x轴
       let xAxis = {
         ...scatterXAxis,
-        categories: this.commodityXData.map(_ =>_.Name),
+        categories: this.commodityXData.filter(_=>_.IsHide===0).map(_ =>_.Name),
         tickWidth: 1,
         labels: {
           y: 14,
@@ -1039,7 +1163,14 @@ export default {
             return item
           }
         })
-        return arr;
+        // 根据设置的x轴显示隐藏去除值
+        let temArr=[]
+        this.commodityXData.forEach((i,index)=>{
+          if(i.IsHide!==1){
+            temArr.push(arr[index]||null)
+          }
+        })
+        return temArr;
     },
 
     /* 商品价格曲线获取详情赋值 */
@@ -2045,6 +2176,19 @@ export default {
             this.chartLimit.rightTwoMin = 0
             this.chartLimit.rightTwoMax = 0
         }
+        //季节性图-右轴为左轴同比,单独处理
+        if(this.chartInfo.ChartType===2){
+            if(this.chartInfo.SeasonRightConfig&&this.chartInfo.SeasonRightConfig.IsShow){
+                if(this.chartInfo.SeasonRightConfig.IndicatorType===1){
+                    this.chartLimit.rightMin = this.chartInfo.SeasonRightConfig.EdbInfoList[0].MinData||0
+                    this.chartLimit.rightMax = this.chartInfo.SeasonRightConfig.EdbInfoList[0].MaxData||0
+                }else{
+                    this.chartLimit.rightMin = tableData[1].MinData||0
+                    this.chartLimit.rightMax = tableData[1].MaxData||0
+                }
+                
+            }
+        }
     },
     calcLimit(arr) {
         return {

+ 10 - 3
src/views/ppt_manage/mixins/pptMixins.js

@@ -216,7 +216,8 @@ export default {
             PublishTime,
             Editor,
             CoverContent,
-            TitleSetting
+            TitleSetting,
+            AdminId
         } = res.Data
         const pptDate = formatPPTDate(this.currentLang, PptDate)
         let legalContent = JSON.parse(Content)
@@ -248,7 +249,8 @@ export default {
             PublishTime,
             Editor,
             CoverContent,
-            TitleSetting:legalTitleSetting
+            TitleSetting:legalTitleSetting,
+            AdminId
         }
       }else{
         this.result = {status:'',content:'获取ppt数据失败!'}
@@ -281,7 +283,12 @@ export default {
       if([1,11].includes(this.chartInfo.Source)) { //常规图
         //处理下历史默认来源
         this.setDefaultSourceFrom();
-        
+        //季节性图处理SeasonAverageConfig,SeasonRightEdbConfig
+        if(this.chartInfo.ChartType===2){
+            const {MaxMinLimits={},SamePeriodAverage={},SamePeriodStandardDeviation={},RightAxis={}} = Data.DataResp||{}
+            this.chartInfo.SeasonAverageConfig = {MaxMinLimits,SamePeriodAverage,SamePeriodStandardDeviation}
+            this.chartInfo.SeasonRightConfig = RightAxis
+        }
         this.dataList = Data.EdbInfoList;
         //初始化上下限
         this.setLimitData(this.dataList)

+ 3 - 4
src/views/ppt_manage/newVersion/components/catalog/transReport.vue

@@ -40,6 +40,7 @@
 
 <script>
 import {classifyTelList} from 'api/api.js';
+import { classifylist } from '@/api/modules/reportV2.js';
 import * as reportEnInterface from '@/api/modules/reportEnApi';
 export default {
   props:{
@@ -85,12 +86,10 @@ export default {
   methods: {
     async getClassifylist(){
       const res = this.$parent.currentLang!=='en'
-                  ?await classifyTelList()
+                  ?await classifylist({CurrentIndex:0,PageSize:1000,KeyWord:''})
                   :await reportEnInterface.classifyList({CurrentIndex:0,PageSize:1000,KeyWord:''})
       if(res.Ret===200){
-        this.reportList = this.$parent.currentLang!=='en'
-                          ?res.Data
-                          :res.Data.List
+        this.reportList = res.Data.List || []
       }
       this.getListLoading = false
     },

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

@@ -419,6 +419,11 @@ export default {
       ]
     },
 
+    // 登录账号id
+    RoleId() {
+      return  Number(localStorage.getItem('AdminId'))
+    }
+
   },
   watch:{
     searchTitle(newVal){
@@ -623,6 +628,7 @@ export default {
     },
     //设置操作按钮
     setToolList(pptDetail={}){
+      console.log(pptDetail)
       //公共目录:显示除 删除, 编辑 外的全部按钮
       if(this.treeName==='public'){
         this.pptToolList = toolList.filter((i)=>{
@@ -654,7 +660,7 @@ export default {
           'publish':checkPermissionBtn(pptPermission.ppt_publish),
           'present':checkPermissionBtn(pptPermission.ppt_show),
           'download':checkPermissionBtn(pptPermission.ppt_download),
-          'transform':checkPermissionBtn(pptPermission.ppt_toReport),
+          'transform':checkPermissionBtn(pptPermission.ppt_toReport)&&this.RoleId===pptDetail.AdminId,
           'transEn':checkPermissionBtn(pptPermission.ppt_toEn),
           'edit':checkPermissionBtn(pptPermission.ppt_save),
           'copy':checkPermissionBtn(pptPermission.ppt_copy),
@@ -1223,7 +1229,7 @@ export default {
     getTransSet(data){
       pptInterface.transReport({
         PptId:this.pptItem.PptId,
-        ClassifyIdSecond:data.type,
+        ClassifyId:data.type,
         Title:data.title
       }).then(res=>{
         if(res.Ret===200){

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

@@ -993,11 +993,13 @@ export default {
     },
 
     async setImageHandle(form) {
-      let { Data } = await dataBaseInterface.uploadImgSvg(form);
-      await preDictEdbInterface.setImg({
-        EdbInfoId: this.formData.edb_id,
-        ImageUrl: Data.ResourceUrl,
-      });
+      // let { Data } = await dataBaseInterface.uploadImgSvg(form);
+      // await preDictEdbInterface.setImg({
+      //   EdbInfoId: this.formData.edb_id,
+      //   ImageUrl: Data.ResourceUrl,
+      // });
+      form.append("EdbInfoId", this.formData.edb_id);
+      await preDictEdbInterface.setThumbnail(form)
     },
 
     refreshData() {

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

@@ -74,7 +74,7 @@
                 @change="seasonTypeChange2"
             >
                 <el-radio-button label="公历">{{$t('Chart.calendar_gre')}}</el-radio-button>
-				<el-radio-button label="农历">{{$t('Chart.calendar_lunar')}}</el-radio-button>
+				<el-radio-button label="农历">{{$t('Chart.calendar_lunar_text')}}</el-radio-button>
             </el-radio-group>
 
             <div class="range-cont left">

+ 7 - 5
src/views/predictEdb_manage/components/edbDetail.vue

@@ -177,11 +177,13 @@ export default {
         },
 
         async setImageHandle(form) {
-            let { Data } = await dataBaseInterface.uploadImgSvg(form);
-            await preDictEdbInterface.setImg({
-                EdbInfoId: this.id,
-                ImageUrl: Data.ResourceUrl,
-            });
+            // let { Data } = await dataBaseInterface.uploadImgSvg(form);
+            // await preDictEdbInterface.setImg({
+            //     EdbInfoId: this.id,
+            //     ImageUrl: Data.ResourceUrl,
+            // });
+            form.append("EdbInfoId", this.id);
+            await preDictEdbInterface.setThumbnail(form)
         },
         getData(){
             preDictEdbInterface.edbDataInfo({

+ 7 - 5
src/views/predictEdb_manage/predictEdb.vue

@@ -938,11 +938,13 @@ export default {
     },
 
     async setImageHandle(form) {
-      let { Data } = await dataBaseInterface.uploadImgSvg(form);
-      await preDictEdbInterface.setImg({
-        EdbInfoId: this.select_id,
-        ImageUrl: Data.ResourceUrl,
-      });
+      // let { Data } = await dataBaseInterface.uploadImgSvg(form);
+      // await preDictEdbInterface.setImg({
+      //   EdbInfoId: this.select_id,
+      //   ImageUrl: Data.ResourceUrl,
+      // });
+			form.append("EdbInfoId", this.select_id);
+      await preDictEdbInterface.setThumbnail(form)
     },
 
 		/* 添加一级目录 */

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

@@ -825,7 +825,7 @@ export default {
 				const t=new Date().getTime()
 				item.domId=item.UniqueCode+t //避免多次添加同一图表 id相同
 				htmlStr=htmlStr+`<p style='text-align:left; margin-top:10px;'>
-							<iframe id='${item.domId}' src='${LINK_CHART_URL}?code=${item.UniqueCode}' width='100%' height='350' style='border-width:0px; min-height:350px;'></iframe>
+							<iframe id='${item.domId}' src='${LINK_CHART_URL}?code=${item.UniqueCode}&lang=${this.currentLang}' width='100%' height='350' style='border-width:0px; min-height:350px;'></iframe>
 						</p>`
 			})
 			this.$nextTick(()=>{

+ 1 - 1
src/views/report_manage/editChapterReport.vue

@@ -796,7 +796,7 @@ export default {
         htmlStr =
           htmlStr +
           `<p style='text-align:left; margin-top:10px;'>
-							<iframe id='${item.domId}' src='${LINK_CHART_URL}?code=${item.UniqueCode}' width='100%' height='350' style='border-width:0px; min-height:350px;'></iframe>
+							<iframe id='${item.domId}' src='${LINK_CHART_URL}?code=${item.UniqueCode}&lang=${this.currentLang}' width='100%' height='350' style='border-width:0px; min-height:350px;'></iframe>
 						</p>`;
       });
       this.$nextTick(() => {

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

@@ -832,7 +832,7 @@ export default {
 				const t=new Date().getTime()
 				item.domId=item.UniqueCode+t //避免多次添加同一图表 id相同
 				htmlStr=htmlStr+`<p style='text-align:left; margin-top:10px;'>
-							<iframe id='${item.domId}' src='${LINK_CHART_URL}?code=${item.UniqueCode}' width='100%' height='350' style='border-width:0px; min-height:350px;'></iframe>
+							<iframe id='${item.domId}' src='${LINK_CHART_URL}?code=${item.UniqueCode}&lang=${this.currentLang}' width='100%' height='350' style='border-width:0px; min-height:350px;'></iframe>
 						</p>`
 			})
 			this.$nextTick(()=>{

+ 1 - 1
src/views/report_manage/reportAuthor.vue

@@ -14,7 +14,7 @@
       </div>
     </div>
     <div class="main-bottom" v-if="authTabsOpt.length">
-      <ul class="tab-ul">
+      <ul class="tab-ul" v-if="authTabsOpt.length>1">
         <li :class="['tab-li',default_tab===tab.key && 'act']" v-for="tab in authTabsOpt" :key="tab.key" @click="default_tab=tab.key">{{getContentMenuOptText(tab.label)}}</li>
       </ul>
       <el-table

+ 869 - 0
src/views/report_manage/reportV2/components/chapterEditWrapper.vue

@@ -0,0 +1,869 @@
+<template>
+  <div class="left-chapter-box">
+    <div class="box-top">
+      <h3>{{reportBase.Title}}</h3>
+
+      <ul class="handle-list">
+        <li v-if="reportBase.ReportLayout===2&&isCreator" @click="openTerritorySet">
+          <el-tooltip
+            effect="dark" 
+            :content="$t('ReportManage.ReportList.img_set_btn')" 
+            placement="top"
+          >
+            <i class="el-icon-setting" style="color:#0052D9;font-size:20px;"></i>
+          </el-tooltip>
+        </li>
+
+        <li @click="$emit('openBaseInfo')" v-if="isCreator">
+          <el-tooltip
+            effect="dark" 
+            :content="$t('ReportManage.ReportList.information_title')" 
+            placement="top"
+          >
+            <img src="~@/assets/img/icons/baseinfo_ico.svg" class="handle-icon" alt="">
+          </el-tooltip>
+        </li>
+        <li @click="$emit('handlePreviewReport')">
+          <el-tooltip
+            effect="dark" 
+            :content="$t('ReportManage.ReportList.preview_btn')" 
+            placement="top"
+          >
+            <img src="~@/assets/img/icons/preview_ico.svg" class="handle-icon" alt="">
+          </el-tooltip>
+        </li>
+        
+        <template v-if="!isApprove||!hasApproveFlow">
+            <li 
+                class="action-item" 
+                :class="{'disabled':puiblishLoading}"
+                @click="handlePublishReport('dsfb')"
+                v-if="permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_publish)"
+                >
+                  <el-tooltip
+                    effect="dark" 
+                    :content="$t('ReportManage.ReportList.scheduled_publish_btn')" 
+                    placement="top"
+                  >
+                    <img src="~@/assets/img/icons/timing_ico.svg" class="handle-icon" alt="">
+                  </el-tooltip>
+            </li>
+            <li 
+                class="action-item" 
+                :class="{'disabled':puiblishLoading}"
+                @click="handlePublishReport('fb')"
+                v-if="permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_publish)"
+            >
+                <el-tooltip
+                  effect="dark" 
+                  :content="$t('ReportManage.ReportList.publish_btn')" 
+                  placement="top"
+                >
+                  <img src="~@/assets/img/icons/publish_ico.svg" class="handle-icon" alt="">
+                </el-tooltip>
+            </li>
+        </template>
+        <template v-if="isApprove&&hasApproveFlow">
+            <li 
+                class="action-item" 
+                :class="{'disabled':puiblishLoading}"
+                @click="handlePublishReport('submit')"
+                v-if="permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_publish)"
+            >
+              <el-tooltip
+                effect="dark" 
+                :content="$t('ReportManage.ReportList.submission_btn')" 
+                placement="top"
+              >
+                <img src="~@/assets/img/icons/submit_ico.svg" class="handle-icon" alt="">
+              </el-tooltip>
+            </li>
+        </template>
+      </ul>
+    </div>
+
+    <div class="box-main">
+      <div class="main-top">
+        <h3><!-- 研报章节 -->{{$t('ReportManage.ReportList.tit_report_chap')}}</h3>
+        <el-button 
+          type="primary" 
+          size="small" 
+          @click="openAddChapter"
+          v-if="isCreator&&permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportMange_chapter_add)"
+        ><!-- 添加章节 -->{{$t('ReportManage.ReportList.btn_add_chap')}}</el-button>
+      </div>
+      
+      <ul class="chapter-list" v-if="chapterList.length">
+        <draggable
+            v-model="chapterList"
+            animation="300"
+            :group="{ name: 'chapter', pull: false, put: false }"
+            @start="dragStartHandler"
+            @update="dragenter"
+            @end="dragOverHandler"
+            :disabled="!isCreator"
+          >
+          <li 
+            v-for="item in chapterList" 
+            :key="item.ReportChapterId" 
+            @click="chooseChapter(item)"
+            :class="selectChapterId===item.ReportChapterId&&'act'"
+          >
+            <div class="card-top" v-if="item.TypeName">
+              <div class="type-name" >{{item.TypeName}}</div>
+            </div>
+
+            <div class="card-top">
+              <span style="font-size: 16px;">{{item.Title}}</span>
+            </div>
+            
+            <div class="card-bottom">
+              <span 
+                :style="{color:item.PublishState===2?'#67C23A':'#000'}" 
+                v-if="item.CanEdit"
+              >
+                {{item.PublishState===2 ? $t('ReportManage.ReportList.chapter_has_submit') : $t('ReportManage.ReportList.chapter_no_submit') }}
+                <el-popover
+                    placement="top"
+                    trigger="click"
+                >   
+                    <img style="width:150px" :src="item.QRCodeImg" alt="">
+
+                    <img 
+                      src="~@/assets/img/icons/wx_round.svg" 
+                      class="handle-icon"
+                      slot="reference"
+                      v-if="permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportMange_chapter_share)&&item.PublishState===2"
+                      style="font-size:18px;color:#0052D9;cursor:pointer;"
+                      @click.stop="handleGetWechatImg(item)"
+                    />
+                </el-popover>
+              </span>
+              <span v-else style="color:#E37318">{{item.Editor}}<!-- 编辑中... -->{{$t('ReportManage.smart_btn.editing')}}</span>
+              <div>
+                <img
+                  src="~@/assets/img/data_m/move_ico.png"
+                  alt=""
+                  style="width: 16px; height: 16px;margin-right:5px;"
+                />
+
+                
+                <el-dropdown 
+                  trigger="click" 
+                  @command="handleChapterItem"
+                  v-if="item.IsAuth"
+                >
+                  <span class="el-dropdown-link">
+                    <i class="el-icon-s-operation editsty" style="font-size: 18px;"></i>
+                  </span>
+
+                  <el-dropdown-menu slot="dropdown">
+                    <el-dropdown-item 
+                      :command="{type:'beseInfo',item}"
+                      v-if="isCreator"
+                    ><!-- 基础信息 -->{{$t('ReportManage.ReportList.information_title')}}</el-dropdown-item>
+                    <el-dropdown-item 
+                      :command="{type:'del',item}"
+                      v-if="isCreator"
+                    ><!-- 删除 -->{{$t('Table.delete_btn')}}</el-dropdown-item>
+                    <el-dropdown-item 
+                      :command="{type:'adTag',item}" 
+                      v-if="permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportMange_chapter_editTag)"><!-- 添加标签 -->{{$t('ReportManage.ReportList.add_labels_section')}}</el-dropdown-item>
+                    <el-dropdown-item :command="{type:'upAudio',item}"><!-- 上传录音 -->{{$t('ReportManage.ReportList.up_recording_lable')}}</el-dropdown-item>
+                  </el-dropdown-menu>
+                </el-dropdown>
+              </div>
+            </div>
+          </li>
+        </draggable>  
+      </ul>
+
+      <div class="chapter-list" v-else>
+       <tableNoData :text="$t('ReportManage.ReportList.no_chapter_msg')" size="mini"/>
+      </div>
+    </div>
+
+    <!-- 添加章节弹窗 -->
+    <m-dialog
+      :title="chapterInfo.id?'编辑章节':'添加章节'" 
+      :show.sync="isOpenChapterDia" 
+      width="650px"
+      @close="isOpenChapterDia=false"
+    >
+      <div class="chapter-dialog-main">
+        <el-form 
+          :model="chapterInfo" 
+          :rules="chapterRules" 
+          ref="formRef" 
+          label-position="left"
+          hide-required-asterisk
+          label-width="120px"
+        >
+          <el-form-item prop="chapterName" :label="$t('ReportManage.ReportList.label_chap_name')">
+              <el-input
+                type="text" 
+                v-model="chapterInfo.chapterName"
+                style="width:350px;"
+                placeholder="请输入章节名称"
+              />
+          </el-form-item>
+          <el-form-item prop="varietys">
+              <template slot="label">
+                  <el-tooltip class="item" effect="dark">
+                      <div slot="content" v-html="varietyTip"></div>
+                      <div>
+                          <span>{{ $t('ReportManage.CategoryList.related_variety') }}</span>
+                          <i class="el-icon-info"></i>
+                      </div>
+                  </el-tooltip>
+              </template>
+
+              <el-cascader
+                  :options="reportVarietyOpts" 
+                  v-model="chapterInfo.varietys" 
+                  placeholder="请选择关联品种"
+                  collapse-tags
+                  :show-all-levels="false"
+                  :props="{
+                    value:'PermissionId',
+                    label:'PermissionName',
+                    children:'Child',
+                    multiple: true,
+                    emitPath:false
+                  }" 
+                  style="width:350px;"
+                  clearable
+              ></el-cascader>
+          </el-form-item>
+          <el-form-item prop="editors" :label="$t('ReportManage.ReportList.label_chap_editor')">
+            <el-cascader
+              v-model="chapterInfo.editors"
+              :options="userOpts"
+              :show-all-levels="false"
+              collapse-tags
+              filterable
+              :props="{
+                value:'AdminId',
+                label:'AdminName',
+                children:'Children',
+                emitPath: false,
+                multiple: true
+              }"
+              clearable
+              placeholder="请选择编辑人"
+              style="width:350px;"
+            />
+
+          </el-form-item>
+        </el-form>
+      </div>
+      <div slot="footer" style="margin-top: 20px;">
+        <el-button
+          @click="$refs.formRef.resetFields();isOpenChapterDia=false"
+          style="width: 132px; height: 40px"
+        ><!-- 取消 -->{{$t('Dialog.cancel_btn')}}</el-button>
+        <el-button
+          @click="handleSaveChapter"
+          type="primary"
+          style="width: 132px; height: 40px"
+        ><!-- 保存 -->{{$t('Dialog.confirm_save_btn')}}</el-button>
+      </div>
+
+    </m-dialog>
+
+    <!-- 添加标签弹窗 -->
+    <m-dialog
+      :show.sync="isOpenChapterTag"
+      :title="$t('ReportManage.ReportList.set_tags_title')"
+      width="450px"
+    >
+      <div class="edit-tag-wrap">
+          <span style="margin-right: 20px">{{chapterInfo.chapterName}}</span>
+          <el-select
+            v-model="chapterInfo.tags"
+            filterable
+            allow-create
+            default-first-option
+            :placeholder="$t('ReportManage.ReportList.select_ipt_pld')">
+            <el-option
+                v-for="item in tagOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value">
+            </el-option>
+          </el-select>
+          <div style="margin:30px 0;text-align:center">
+              <el-button type="primary" plain @click="isOpenChapterTag=false">{{$t('Dialog.cancel_btn')}}</el-button>
+              <el-button type="primary" @click="handleSaveChapterTag">{{$t('Dialog.confirm_btn')}}</el-button>
+          </div>
+      </div>
+    </m-dialog>
+
+
+    <!-- 上传音频弹窗 -->
+    <m-dialog
+      :show.sync="isOpenUploadAudio"
+      :title="$t('ReportManage.smart_audio_upload_btn')"
+      width="450px"
+      @close="isOpenUploadAudio=false;uploadAudioLoading=false;"
+    >
+        <div class="edit-tag-wrap">
+            <div>
+              <el-input
+                v-model="chapterInfo.audioName"
+                readonly
+                style="width: 65%"
+                :placeholder="$t('ReportManage.ReportList.upload_audio_file')"
+              ></el-input>
+              <el-upload
+                style="display: inline-block; margin-left: 10px"
+                action=""
+                accept=".mp3,.m4a"
+                :http-request="handleUpload"
+                :before-upload="handelBeforeUploadAudio"
+                :show-file-list="false"
+                :disabled="startUploadAudio"
+              >
+                <el-button type="primary" :loading="startUploadAudio"
+                  >{{$t('ReportManage.ReportList.up_recording_lable')}}</el-button
+                >
+              </el-upload>
+
+              <p style="color: #999; font-size: 12px;margin-top: 10px;">
+                {{$t('ReportManage.ReportList.note_audio_minutes')}}
+              </p>
+            </div>
+            <div style="margin-top:30px;text-align:center">
+                <el-button type="primary" plain @click="isOpenUploadAudio=false;uploadAudioLoading=false;">{{$t('Dialog.cancel_btn')}}</el-button>
+                <el-button type="primary" @click="handleSaveAudio" :loading="uploadAudioLoading">{{uploadAudioLoading ? $t('ReportManage.smart_btn.uploading') :$t('Dialog.confirm_btn')}}</el-button>
+            </div>
+        </div>
+    </m-dialog>
+
+    <!-- 版图设置弹窗 -->
+    <smartTerritorSet 
+      :isShow.sync="isOpenTerritorDia"
+      :info="reportBase"
+      @change="handleChangeImgSet"
+    />
+
+  </div>
+</template>
+<script>
+import draggable from 'vuedraggable';
+import mDialog from '@/components/mDialog.vue';
+import smartTerritorSet from './smartTerritorSetDia.vue'
+import { chapterTrendTagList } from '@/api/api.js';
+import { 
+  dayWeekChapterList,
+  reportV2Interface,
+  chapterQRCodeImg,
+  editChapterTrendTag,
+  markReport
+} from '@/api/modules/reportV2'
+export default {
+  components: { draggable,mDialog,smartTerritorSet },
+  props: {
+    isApprove: {
+      type: Boolean
+    },
+    hasApproveFlow: {
+      type: Boolean
+    }
+  },
+  computed: {
+    isCreator() {
+      let roleId = Number(localStorage.getItem('AdminId'))
+      return roleId === this.reportBase.AdminId;
+    },
+    RoleId() {
+      return Number(localStorage.getItem('AdminId'))
+    }
+  },
+  data() {
+    return {
+      chapterList: [],
+
+      startIndex: 0,
+      preIndex: 0,
+      nextIndex: 0,
+
+      reportBase: {},
+      selectChapterId: 0, //选中章节Id
+      editChapterId: 0,//编辑章节Id
+
+      /* 章节弹窗 */
+      isOpenChapterDia: false,
+      reportVarietyOpts: [],
+      userOpts: [],
+      chapterInfo: {
+        id: 0,
+        varietys:[],
+        editors:[],
+        chapterName:'',
+        tags: '',
+        audioName:'',
+        audioFile: ''
+      },
+      chapterRules: {
+        chapterName: [{
+          required:true,message:'章节名称不能为空',trigger:'blur'
+        }]
+      },
+
+      varietyTip:`若章节关联品种,则章节阅读权限受章节关联品种的权限控制;<br>
+        若章节不关联品种,则章节阅读权限受分类关联品种的权限控制;
+      `,
+
+      /* 标签弹窗 */
+      isOpenChapterTag: false,
+      tagOptions: [],
+
+      /* 上传录音弹窗 */
+      isOpenUploadAudio: false,
+      uploadAudioLoading: false,
+
+      /* 版图设置弹窗 */
+      isOpenTerritorDia: false
+    }
+  },
+  mounted(){
+    this.getChapterList(true);
+    this.getReportBaseInfo();
+    this.getChapterTrendTagList()
+  },
+  methods:{
+    /* 发布总报告 */
+    async handlePublishReport(tp) {
+      //校验章节是否都已发布
+      let res = await reportV2Interface.checkChaterPublishState({
+        ReportId: Number(this.$route.query.id)
+      })
+      if(res.Data&&res.Data.length>0){
+        let str = res.Data.map(_ =>_.Title).join(',')
+        return this.$message.warning(this.$t('ReportManage.ReportList.chapter_nosubmit_msg',{name: str}))
+      } 
+
+      this.$emit('handlePublish',tp)
+    },
+
+    /* 版图设置 */
+    openTerritorySet() {
+      this.isOpenTerritorDia = true;
+    },
+    /* 版图设置保存 */
+    async handleChangeImgSet(info) {
+      console.log(info)
+      
+      const res = await reportV2Interface.setReportLayoutImg({
+        ReportId: Number(this.$route.query.id),
+        HeadImg: info.headImg,
+        EndImg: info.endImg,
+        HeadResourceId: info.headImgId,
+        EndResourceId: info.endImgId,
+        CanvasColor: info.bgColor,
+      })
+
+      if(res.Ret !== 200) return 
+       
+      this.$message.success(this.$t('MsgPrompt.set_success_msg'))
+      
+      this.reportBase.HeadImg = info.headImg;
+      this.reportBase.EndImg = info.endImg;
+      this.reportBase.HeadResourceId = info.headImgId;
+      this.reportBase.EndResourceId = info.endImgId;
+      this.reportBase.CanvasColor = info.bgColor;
+    },
+
+    async handleMarkOver(ReportChapterId=0) {
+      await markReport({
+        Status: 3,
+        ReportId: Number(this.$route.query.id),
+        ReportChapterId,
+      });
+    },
+
+    //选择章节 预览
+    async chooseChapter(item) {
+      this.editChapterId && this.handleMarkOver(this.editChapterId);
+
+      if(item.IsAuth) {
+         //编辑前标记一下
+          const res = await markReport({
+            Status: 1,
+            ReportId: Number(this.$route.query.id),
+            ReportChapterId: item.ReportChapterId
+          });
+          
+          if (res.Ret === 200) {
+            if (res.Data.Status === 1) {
+              this.$message.warning(res.Data.Msg || "该研报正在编辑,不可重复编辑");
+              item.CanEdit = false;
+              item.Editor = res.Data.Editor || "";
+              return;
+            } else if (res.Data.Status === 0) {
+              item.CanEdit = true;
+              item.Editor = res.Data.Editor || "";
+            }
+          } else {
+            this.$message.error(res.ErrMsg || "未知错误,请稍后重试");
+            return;
+          }
+
+        this.editChapterId = item.ReportChapterId;
+        this.selectChapterId = item.ReportChapterId;
+      }else {
+        this.selectChapterId = item.ReportChapterId;
+        this.editChapterId = 0;
+      }
+
+      this.$emit('change',{ selectChapterId: this.selectChapterId,editChapterId:this.editChapterId })
+    },
+
+    //添加章节弹窗
+    openAddChapter(item=null) {
+      console.log(item)
+      if(item.ReportChapterId) {
+        this.chapterInfo = {
+          id: item.ReportChapterId,
+          varietys:item.PermissionIdList,
+          editors:item.GrandAdminIdList,
+          chapterName:item.Title,
+          tags: ''
+        }
+      }else {
+        this.chapterInfo = {
+          id: 0,
+          varietys:this.reportVarietyOpts.map(_ =>_.PermissionId)||[],
+          editors:[],
+          chapterName:'',
+          tags: ''
+        }
+      }
+
+      this.isOpenChapterDia = true;
+    },
+
+    /* 保存章节编辑 */
+    async handleSaveChapter() {
+      await this.$refs.formRef.validate()
+
+      let params = {
+        Title: this.chapterInfo.chapterName,
+        PermissionIdList: this.chapterInfo.varietys,
+        AdminIdList: this.chapterInfo.editors
+      }
+
+      const res = this.chapterInfo.id 
+        ? await reportV2Interface.editChapterBase({
+          ReportChapterId: this.chapterInfo.id,
+          ...params
+        })
+        : await reportV2Interface.addChapter({
+            ReportId: this.reportBase.Id,
+            ...params
+          })
+      if(res.Ret !== 200) return
+
+      this.$message.success(res.Msg)
+      this.isOpenChapterDia = false;
+      this.getChapterList();
+      this.$emit('update',{ Title: this.chapterInfo.chapterName })
+    },
+
+    /* 删除章节 */
+    handleDelChapter(item) {
+      this.$confirm(this.$t('ReportManage.ReportList.del_chapter_msg'),this.$t('Confirm.prompt'),{
+        type: 'warning'
+      }).then( async() => {
+          const res = await reportV2Interface.removeChapter({
+            ReportChapterId: item.ReportChapterId
+          })
+    
+          if(res.Ret!==200) return
+          this.$message.success(this.$t('MsgPrompt.delete_msg'))
+          this.chapterList.splice(this.chapterList.findIndex(_=>_.ReportChapterId===item.ReportChapterId),1)
+
+          this.selectChapterId = 0;
+          this.editChapterId = 0;
+          this.$emit('change',{ selectChapterId: this.selectChapterId,editChapterId:this.editChapterId })
+
+      }).catch(() =>{})
+
+    },
+
+    /* 获取章节分享太阳码 */
+    async handleGetWechatImg(item) {
+      if(item.QRCodeImg) return
+      
+      const res=await chapterQRCodeImg({
+        CodeScene:JSON.stringify({chapterId:item.ReportChapterId.toString()}),
+        CodePage:'pages-report/chapterDetail'
+      })
+      if(res.Ret!==200) return
+
+      this.$set(this.chapterList,this.chapterList.findIndex(_ => _.ReportChapterId===item.ReportChapterId),{...item,QRCodeImg:res.Data})
+    },
+
+    //添加章节标签
+    openAddChapterTag(item) {
+      this.chapterInfo = {
+        id: item.ReportChapterId,
+        varietys:[],
+        editors:[],
+        chapterName: item.Title,
+        tags: item.Trend
+      }
+      this.isOpenChapterTag = true;
+    },
+
+    /* 保存关联章节标签 */
+    async handleSaveChapterTag() {
+      const res = await editChapterTrendTag({
+          ReportChapterId:Number(this.chapterInfo.id),
+          Trend: this.chapterInfo.tags
+      })
+
+      if(res.Ret!==200) return
+
+      this.$message.success(res.Msg)
+      this.isOpenChapterTag=false
+
+      this.getChapterList()
+    },
+
+    /* 上传音频 */
+    openUploadAudio(item) {
+      this.chapterInfo.id= item.ReportChapterId,
+      this.chapterInfo.audioName = item.VideoName,
+      this.chapterInfo.audioFile = '',
+        
+      this.isOpenUploadAudio = true;
+    },
+
+    handelBeforeUploadAudio(e) {
+      if (
+        e.name.indexOf(".mp3") == -1 &&
+        e.name.indexOf(".wav") == -1 &&
+        e.name.indexOf(".wma") == -1 &&
+        e.name.indexOf(".m4a") == -1
+      ) {
+        // this.$message.warning("上传失败,上传音频格式不正确");
+        this.$message.warning(this.$t('ReportManage.ReportList.upload_audio_error_msg'));
+        upload_audio_error_msg
+        return false;
+      }
+    },
+
+    async handleUpload(e) {
+      this.chapterInfo.audioName = e.file.name;
+      this.chapterInfo.audioFile  = e.file;
+    },
+
+    async handleSaveAudio() {
+      
+      this.uploadAudioLoading = true;
+      let params = new FormData();
+        params.append("file", this.chapterInfo.audioFile);
+        params.append("ReportChapterId", this.chapterInfo.id);
+      const res = await reportV2Interface.uploadChpterAudio(params)
+
+      this.uploadAudioLoading = false;
+      if(res.Ret !== 200) return
+      this.isOpenUploadAudio = false;
+
+      this.getChapterList()
+    },
+
+    /* 章节操作 */
+    handleChapterItem({type,item}) {
+      console.log(type,item)
+      switch(type) {
+        case 'beseInfo': 
+          this.openAddChapter(item);
+          break
+        case 'del':
+          this.handleDelChapter(item)
+          break
+        case 'adTag': 
+          this.openAddChapterTag(item)
+          break
+        case 'upAudio': 
+          this.openUploadAudio(item)
+          break
+        case 'wxShare':
+          this.handleGetWechatImg(item)
+          break
+      }
+    },
+
+    /* 获取章节列表 */
+    async getChapterList(isInit=false) {
+      if(!this.$route.query.id) return 
+
+      const res = await dayWeekChapterList({
+        ReportId: Number(this.$route.query.id)
+      })
+      if(res.Ret !== 200) return 
+
+      this.chapterList = res.Data || []
+
+      isInit && this.selectDefaultChapter()
+    },
+
+
+    selectDefaultChapter() {
+      let firstChapter = this.chapterList.find(_ => _.CanEdit || !_.IsAuth)
+      if(firstChapter) {
+        this.chooseChapter(firstChapter)
+      }
+    },
+
+
+     /* 获取报告基础信息用户范围 品种范围 */
+    async getReportBaseInfo(type='init') {
+      if(!this.$route.query.id) return 
+
+      const res = await reportV2Interface.getRportBase({
+         ReportId: Number(this.$route.query.id)
+      })
+
+      if(res.Ret!==200) return
+      this.reportBase = res.Data;
+
+      if(res.Data.PrePublishTime) this.$parent.taskTime = res.Data.PrePublishTime;
+
+      if(type!=='notCheck') {
+        let classify = [res.Data.ClassifyIdFirst,res.Data.ClassifyIdSecond,res.Data.ClassifyIdThird]
+        this.$emit('checkClassifyNameArr',classify)
+      }
+
+      this.reportVarietyOpts = res.Data.PermissionList||[];
+      this.userOpts = res.Data.GrandAdminList||[];
+
+    },
+    
+
+     //获取章节标签数据(仅在获取章节列表成功后获取一次)
+    async getChapterTrendTagList(){
+        const res=await chapterTrendTagList()
+        if(res.Ret!==200) return
+        
+        let arr=res.Data||[]
+
+        this.tagOptions=arr.map(item=>({value:item.KeyWord,label:item.KeyWord}))
+    },
+
+    /* 拖动开始 记录位置 */
+    dragStartHandler({ oldIndex }) {
+      this.startIndex = this.chapterList[oldIndex].ReportChapterId;
+    },
+
+    /* 拖动结束 替换  */
+    async dragOverHandler() {
+      const res = await reportV2Interface.moveChapter({
+          ReportChapterId: this.startIndex,
+          PrevReportChapterId: this.preIndex,
+          NextReportChapterId: this.nextIndex
+      })
+      
+      if (res.Ret !== 200) return;
+      this.$message.success(res.Msg)
+    },
+
+    /* 移动后的上一个位置id 若移到第一位则取0 获取后一个id 若是最后一个取0*/
+    dragenter({ newIndex }) {
+      console.log(newIndex)
+      this.preIndex = newIndex > 0 ? this.chapterList[newIndex - 1].ReportChapterId : 0;
+      this.nextIndex = newIndex ===  this.chapterList.length - 1 ? 0 : this.chapterList[newIndex + 1].ReportChapterId
+    },
+  },
+}
+</script>
+<style scoped lang='scss'>
+*{box-sizing: border-box;}
+.left-chapter-box {
+  width: 350px;
+  margin-right: 20px;
+  background: #fff;
+  .box-top,.box-main {
+    padding: 15px;
+  }
+
+  .box-top {
+    padding-bottom: 0;
+    .handle-list {
+      margin: 30px 0 10px;
+      display: flex;
+      gap: 0 20px;
+      li { 
+        cursor: pointer;display: flex;align-items: center;
+          &.disabled {
+              pointer-events: none;
+              cursor: not-allowed;
+              color:#999;
+          }
+          .handle-icon {
+            width: 18px;
+            height: 18px;
+          }
+      }
+    }
+  }
+  .box-main {
+    padding-right: 0;
+    border-top: 1px solid #DCDFE6;
+    .main-top {
+      padding-right: 15px;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+    }
+  }
+
+  .chapter-list {
+    margin-top: 20px;
+    padding-right: 15px;
+    height: calc(100vh - 210px);
+    overflow-y: auto;
+    li {
+      padding: 15px;
+      background: #F8F8F8;
+      border-radius: 6px;
+      margin-bottom: 15px;
+      border: 1px solid #C8CDD9;
+      &.act {
+        background: #ECF2FE;
+        border: 1px solid #0052D9;
+      }
+
+      .type-name {
+        background: #0052D9;
+        padding: 2px 12px;
+        color: #fff;
+        border-radius: 10px;
+        width: fit-content;
+        margin-bottom: 10px;
+      }
+
+      .card-top {
+        display: flex;
+        justify-content: space-between;
+      }
+
+      .card-bottom {
+        display: flex;
+        justify-content: space-between;
+        margin-top: 30px;
+      }
+    }
+  }
+}
+</style>
+<style lang="scss">
+.chapter-dialog-main {
+  .el-cascader .el-input {
+    width: 100%;
+  }
+}
+</style>

+ 201 - 0
src/views/report_manage/reportV2/components/chooseCooperaUserDia.vue

@@ -0,0 +1,201 @@
+<template>
+  <el-dialog
+    v-dialogDrag
+    :title="$t('ReportManage.ReportList.choose_cooper')"
+    width="650px"
+    :visible.sync="isShow"
+    :modal-append-to-body="false"
+    :close-on-click-modal="false"
+    :append-to-body="false"
+    @close="closeDia"
+  >
+      <div class="dialog-wrap">
+        <div class="before-transfer transfer">
+            <div class="search">
+                <el-input 
+                  :placeholder="'搜索'" 
+                  suffix-icon="el-icon-search" 
+                  style="width:100%;"
+                  v-model="searchText" 
+                  @input="$refs['trans-tree'].filter(searchText)"
+                ></el-input>
+            </div>
+            <div class="content">
+                <el-tree 
+                    node-key="NodeIdKey"
+                    ref="trans-tree"
+                    show-checkbox
+                    :data="treeData"
+                    :props="{
+                        label:'NodeName',
+                        children:'Children'
+                    }"
+                    :filter-node-method="filterNode"
+                    @check-change="handleCheckChange"
+                ></el-tree>
+            </div>
+        </div>
+        <div class="after-transfer transfer">
+            <div class="head">
+                <span>已选{{choosedList.length}}项</span>
+                <span class="btn-text delete" @click="clearUser">{{$t('SystemManage.ReportApprove.clear_btn')}}</span>
+            </div>
+            <ul
+              class="content"
+            >
+                <li class="list-item" v-for="item in choosedList" :key="item.NodeIdKey">
+                    <span class="name">{{item.NodeName}}</span>
+                    <span class="icon-btn" style="color:#C0C4CC;">
+                        <i class="el-icon-close" @click.stop="removeItem(item)"></i>
+                    </span>
+                </li>
+            </ul>
+        </div>
+      </div>
+      <div class="dialog-btn">
+          <el-button type="primary" plain @click="closeDia">{{$t('Dialog.cancel_btn')}}</el-button>
+          <el-button type="primary" @click="handleSaveChecked">{{$t('Dialog.confirm_btn')}}</el-button>
+      </div>
+  </el-dialog>
+</template>
+<script>
+import { departInterence } from "@/api/api.js";
+import { traverseTree } from "@/utils/commonOptions"
+export default {
+  props: {
+    isShow: {
+      type: Boolean
+    },
+    users: {
+      type: Array,
+      default: () => []
+    }
+  },
+  data() {
+    return {
+      searchText: '',
+      treeData: [],
+      choosedList: []
+    }
+  },
+  watch: {
+    isShow(nval) {
+      if(!nval) return
+
+      this.getTreeData()
+    }
+  },
+  methods:{
+    closeDia() {
+      this.choosedList = [];
+      this.searchText = '';
+      this.$emit('update:isShow',false)
+    },
+
+    handleSaveChecked() {
+      if(!this.choosedList) return this.$message.warning('请选择用户')
+
+      this.$emit('save',this.choosedList.map(_ => ({
+        NodeId: _.NodeId,
+        NodeName: _.NodeName
+      })))
+
+      this.closeDia()
+    },
+
+    async getTreeData() {
+      const res = await departInterence.getSystemUser({
+                KeyWord: ''
+      })
+
+      if(res.Ret !== 200) return
+      this.treeData = res.Data||[];
+      //遍历加上唯一的key
+      traverseTree(
+          {Children:this.treeData},
+          {
+              childKey:'Children',
+              nodeKey:'NodeIdKey',
+              cb:(node)=>node.NodeType===3,
+              cb2:(node)=>node.NodeId+''
+          }
+      )
+      
+      this.$nextTick(()=>{
+          const keys = this.users.map(i=>{
+              return i.NodeId
+          })
+          this.$refs["trans-tree"].setCheckedKeys(keys)
+          this.choosedList = _.cloneDeep(this.users)
+      })
+    },
+
+    filterNode(value,data) {
+      if(!value) return true
+
+      return data.NodeName.indexOf(value)!==-1
+    },
+
+    handleCheckChange() {
+      this.choosedList = this.$refs['trans-tree'].getCheckedNodes(true).filter(_ => _.NodeType===3)
+    },
+
+    clearUser() {
+      this.$refs["trans-tree"].setCheckedKeys([])
+      this.choosedList = []
+    },
+
+    //清除已选
+    removeItem(item) {
+      const {NodeIdKey} = item
+      this.$refs["trans-tree"].setChecked(NodeIdKey,false,false)
+      const index = this.choosedList.findIndex(i=>i.NodeIdKey===NodeIdKey)
+      index!==-1&&this.choosedList.splice(index,1)
+    }
+  },
+}
+</script>
+<style scoped lang='scss'>
+.dialog-wrap {
+  display: flex;
+  align-items: center;
+  gap:12px;
+    .transfer{
+        display: flex;
+        flex-direction: column;
+        width:254px;
+        height: 400px;
+        border:1px solid #DCDCDC;
+        border-radius: 6px;
+        padding:8px;
+        .head,.search,.content{
+            padding:10px;
+        }
+        .head{
+            display: flex;
+            justify-content: space-between;
+            .btn-text{
+                cursor: pointer;
+                &.delete{
+                    color:red;
+                }
+            }
+        }
+        .content{
+            flex:1;
+            overflow-y: scroll;
+            margin-bottom: 10px;
+            .list-item{
+                cursor: pointer;
+                padding:6px 0;
+                display: flex;
+                justify-content: space-between;
+            }
+        }
+    }
+}
+.dialog-btn{
+    margin:40px 0;
+    text-align: center;
+}
+</style>

+ 195 - 0
src/views/report_manage/reportV2/components/chooseInherReportDia.vue

@@ -0,0 +1,195 @@
+<template>
+  <el-dialog
+    v-dialogDrag
+    :title="$t('ReportManage.ReportList.tit_choose_inher')"
+    width="650px"
+    :visible.sync="isShow"
+    :modal-append-to-body="false"
+    :append-to-body="false"
+    @close="closeDia"
+  >
+      <div class="dialog-wrap">
+        <div style="margin-bottom: 20px;">
+          <el-input
+              @input="filterChange"
+              :placeholder="$t('ReportManage.ReportList.ph_report_tit')"
+              v-model="searchTxt"
+              clearable
+              size="medium"
+              style="width:250px"
+              prefix-icon="el-icon-search"
+          />
+        </div>
+        <el-table
+          :data="reportList"
+          style="box-shadow: 0px 3px 6px rgba(155, 170, 219, 0.2)"
+          border
+          @selection-change="handleSelectionChange"
+        >
+          <el-table-column
+            type="selection"
+            width="55">
+          </el-table-column>
+          <el-table-column
+            v-for="item in tableColums"
+            :key="item.label"
+            :label="item.label"
+            :width="item.widthsty"
+            :min-width="item.minwidthsty"
+            align="center"
+          >
+            <template slot-scope="{row}">
+              <span v-if="item.key==='Title'">
+                <span
+                >{{ row.Title }}</span
+                >
+                <span
+                  v-if="row.MsgSendTime"
+                  >({{ row.MsgSendTime.substring(5, 7)
+                  }}{{ row.MsgSendTime.substring(8, 10) }})</span
+                >
+                <span
+                  v-else-if="row.PublishTime"
+                  >({{ row.PublishTime.substring(5, 7)
+                  }}{{ row.PublishTime.substring(8, 10) }})</span
+                >
+                <span
+                  v-else-if="row.CreateTime"
+                  >({{ row.CreateTime.substring(5, 7)
+                  }}{{ row.CreateTime.substring(8, 10) }})</span
+                >
+              </span>
+
+              <span v-else-if="item.key==='Classify'">
+                {{ row.ClassifyNameFirst }}
+                <span v-if="row.ClassifyNameSecond">/ {{ row.ClassifyNameSecond }}</span>
+                <span v-if="row.ClassifyNameThird">/ {{ row.ClassifyNameThird }}</span>
+              </span>
+
+              <span v-else-if="item.key==='CreateTime'">
+                {{ $moment(row.CreateTime).format('YYYY-MM-DD') }}
+              </span>
+
+              <span v-else>{{ row[item.key] }}</span>
+            </template>
+          </el-table-column>
+          <div slot="empty" style="padding: 30px 0;">
+            <tableNoData text="暂无数据" size="mini"/>
+          </div>
+        </el-table>
+        <div style="margin-top:10px;height:40px;">
+          <m-page 
+              class="table-page"
+              :total="total" 
+              :pageSize="pageSize"
+              :page_no="pageNo"
+              :pagercount="5"
+              @handleCurrentChange="pageNumberChange"
+          />
+
+        </div>
+       
+      </div>
+      <div class="dialog-btn">
+          <el-button type="primary" plain @click="closeDia">{{$t('Dialog.cancel_btn')}}</el-button>
+          <el-button type="primary" @click="handleSave">{{$t('Dialog.confirm_btn')}}</el-button>
+      </div>
+  </el-dialog>
+</template>
+<script>
+import { reportV2Interface } from '@/api/modules/reportV2.js';
+import mPage from '@/components/mPage.vue'
+export default {
+  components: { mPage },
+  props: {
+    isShow: {
+      type: Boolean
+    },
+    id: {
+      type: Number,
+      default: 0
+    }
+  },
+  computed: {
+    tableColums() {
+      return [
+        { label: this.$t('ReportManage.smart_report_title'),key: 'Title' },
+        { label: this.$t('ReportManage.smart_report_type'),key: 'Classify' },
+        { label: '创建时间',key: 'CreateTime' },
+      ]
+    }
+  },
+  data() {
+    return {
+      reportList: [],
+      pageNo: 1,
+      pageSize: 5,
+      total: 0,
+      searchTxt: '',
+      checkList: []
+    }
+  },
+  watch: {
+    isShow(nval) {
+      if(!nval) return
+    }
+  },
+  methods:{
+    closeDia() {
+      this.reportList = [];
+      this.pageNo = 1;
+      this.total = 0
+      this.searchTxt = '';
+      this.checkList = [];
+
+      this.$emit('update:isShow',false)
+    },
+
+    handleSave() {
+      if(this.checkList.length!==1) return this.$message.warning(/* '只能选择一篇报告' */this.$t('ReportManage.ReportList.check_report_len'))
+
+      this.$emit('success',this.checkList[0])
+      this.closeDia();
+    },
+
+    handleSelectionChange(val) {
+      this.checkList = val;
+    },
+
+    filterChange() {
+      this.pageNo = 1;
+      this.getReportList()
+    },
+
+    pageNumberChange(page) {
+      this.pageNo = page;
+      this.getReportList()
+    },
+
+    getReportList() {
+      reportV2Interface.getAuthReportList({
+          CurrentIndex: this.pageNo,
+          PageSize:this.pageSize,
+          Keyword:this.searchTxt
+        })
+        .then((res) => {
+          if (res.Ret !== 200) return;
+          
+          this.reportList = res.Data.List || [];
+          this.total = res.Data.Paging.Totals;
+        })
+    }
+  },
+}
+</script>
+<style scoped lang='scss'>
+.dialog-wrap {
+
+}
+.dialog-btn{
+    margin:40px 0;
+    text-align: center;
+    display: flex;
+    justify-content: center;
+}
+</style>

+ 585 - 0
src/views/report_manage/reportV2/components/reportBaseInfoDia.vue

@@ -0,0 +1,585 @@
+<template>
+  <div>
+    <el-dialog
+      :title="$t('ReportManage.ReportList.information_title')"
+      :visible.sync="show"
+      :modal-append-to-body="false"
+      :close-on-click-modal="false"
+      :center="true"
+      v-dialogDrag
+      custom-class="dialogclass"
+      width="800px"
+      top="5vh"
+      @close="handleClose"
+    >
+      <el-form
+        :model="formData"
+        :rules="rules"
+        ref="baseinfoForm"
+        class="baseinfo-form-wrap"
+        label-width="125px"
+      >
+        <el-form-item prop="type" :label="$t('ReportManage.ReportList.label_add_way')">
+          <el-radio-group
+            v-model="formData.type"
+            :disabled="id"
+            @change="handleUpdateBaseInfo"
+          >
+            <el-radio :label="1">{{
+              $t("ReportManage.ReportList.new_report_radio")
+            }}</el-radio>
+            <el-radio :label="2">{{
+              $t("ReportManage.ReportList.inherit_report_radio")
+            }}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+
+        <el-form-item prop="classify" :label="$t('ReportManage.ReportList.label_report_classify')">
+          <el-cascader
+            ref="cascader"
+            :options="classifyArr"
+            :disabled="id"
+            v-model="formData.classify"
+            :props="{
+              value: 'Id',
+              label: 'ClassifyName',
+              children: 'Child'
+            }"
+            :placeholder="$t('ReportManage.ReportList.please_select_category')"
+            size="medium"
+            style="width: 400px"
+            @change="handleChangeClassify"
+          />
+        </el-form-item>
+
+        <el-form-item prop="relationVariety" :label="$t('ReportManage.ReportList.label_relation_variety')" v-if="formData.relationVariety.length">
+          <div class="permission-wrap">
+            <el-tag v-for="item in formData.relationVariety" :key="item.ChartPermissionId">{{item.PermissionName}}</el-tag>
+          </div>
+        </el-form-item>
+
+        <el-form-item prop="title" :label="$t('ReportManage.ReportList.label_report_tit')">
+          <el-input
+            :placeholder="$t('ReportManage.ReportList.input_title_please')"
+            v-model="formData.title"
+            style="width:400px"
+          >
+            <el-button slot="append" type="primary" v-if="formData.type===2&&!id" @click="isChooseInherReport=true"><!-- 选择继承报告 -->{{$t('ReportManage.ReportList.choose_inherit_report')}}</el-button>
+          </el-input>
+
+        </el-form-item>
+        
+        <el-form-item prop="abstract" :label="$t('ReportManage.ReportList.label_report_abstract')">
+          <el-input
+            type="textarea"
+            :placeholder="$t('ReportManage.ReportList.please_input_abstract')"
+            v-model="formData.abstract"
+            style="width: 400px"
+          ></el-input>
+        </el-form-item>
+
+        <el-form-item prop="author" :label="$t('ReportManage.ReportList.label_report_author')">
+          <el-select
+            v-model="formData.author"
+            multiple
+            :placeholder="$t('ReportManage.ReportList.please_select_author')"
+            size="medium"
+            style="width: 400px"
+          >
+            <el-option
+              v-for="(item, i) in authorlist"
+              :key="i"
+              :label="item.ReportAuthor"
+              :value="item.ReportAuthor"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+
+        <el-form-item prop="time" :label="$t('ReportManage.ReportList.label_createtime')">
+          <el-date-picker
+            v-model="formData.time"
+            type="date"
+            value-format="yyyy-MM-dd"
+            :placeholder="$t('ReportManage.ReportList.please_select_date')"
+            size="medium"
+            :clearable="false"
+            style="width: 400px"
+          ></el-date-picker>
+        </el-form-item>
+
+        <el-form-item prop="cooperationType" :label="$t('ReportManage.ReportList.label_coop')">
+          <el-radio-group
+            v-model="formData.cooperationType"
+            :disabled="id||formData.type===2"
+            @change="formData.cooperationUsers=[]"
+          >
+            <el-radio :label="1"><!-- 个人 -->{{$t('ReportManage.ReportList.coop_own')}}</el-radio>
+            <el-radio :label="2"><!-- 多人协作 -->{{$t('ReportManage.ReportList.coop_more')}}</el-radio>
+          </el-radio-group>
+
+          <el-button 
+            type="text" 
+            v-if="formData.cooperationType===2"
+            style="margin-left: 20px"
+            @click="handleChooseCooper"
+          ><!-- 选择协作人 -->{{$t('ReportManage.ReportList.choose_cooper')}}</el-button>
+          
+          <div class="choosed-cooper" v-if="formData.cooperationUsers.length">
+            <el-tag
+              v-for="(item,index) in formData.cooperationUsers"
+              :key="item.NodeId"
+              size="mini"
+              effect="dark"
+              closable
+              @close="removeCooper(index)"
+            >
+              {{ item.NodeName }}
+            </el-tag>
+          </div>
+        </el-form-item>
+        <el-form-item prop="reportLayout" :label="$t('ReportManage.ReportList.label_report_layout')">
+          <el-radio-group
+            v-model="formData.reportLayout"
+            :disabled="id||formData.type===2"
+          >
+            <el-radio :label="1"><!-- 常规布局 -->{{$t('ReportManage.ReportList.layout_default')}}</el-radio>
+            <el-radio :label="2"><!-- 智能布局 -->{{$t('ReportManage.ReportList.layout_smart')}}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item prop="isPublcPublish">
+          <template slot="label">
+            <span><!-- 公开发布 -->{{$t('ReportManage.ReportList.label_public')}}</span>
+            <el-tooltip class="item" effect="dark" placement="top">
+              <div slot="content" v-html="publishTip"></div>
+              <i class="el-icon-info"/>
+            </el-tooltip>
+          </template>
+
+          <el-radio-group
+            v-model="formData.isPublcPublish"
+          >
+            <el-radio :label="1">{{$t('Common.yes_text')}}</el-radio>
+            <el-radio :label="2">{{$t('Common.no_text')}}</el-radio>
+          </el-radio-group>
+        </el-form-item>
+
+      </el-form>
+      <div style="text-align: center; margin-top: 60px; margin-bottom: 40px">
+        <el-button
+          type="primary"
+          plain
+          style="width: 120px"
+          @click="handleClose"
+          >{{ $t("Dialog.cancel_btn") }}</el-button
+        >
+        <el-button type="primary" style="width: 120px" @click="handleConfirm">{{
+          $t("Dialog.confirm_btn")
+        }}</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 选择协作人弹窗 -->
+    <chooseCooperaUserDia
+      :isShow.sync="isChooseCooperaUser"
+      :users="formData.cooperationUsers"
+      @save="getChooseCooperaUser"
+    />
+
+    <!-- 选择继承报告弹窗 -->
+    <chooseInherReportDia
+      :isShow.sync="isChooseInherReport"
+      @success="chooseInheritReport"
+    />
+  </div>
+</template>
+
+<script>
+import { apiSmartReport } from "@/api/modules/smartReport";
+import { reportV2Interface,classifylist,reportadd } from '@/api/modules/reportV2.js';
+import { classifyPermissionInterface } from '@/api/api.js';
+import chooseCooperaUserDia from './chooseCooperaUserDia.vue';
+import chooseInherReportDia from './chooseInherReportDia.vue';
+export default {
+  name: "BaseInfo",
+  components: { chooseCooperaUserDia,chooseInherReportDia },
+  model: {
+    prop: "show",
+    event: "showChange",
+  },
+  props: {
+    show: {
+      type: Boolean,
+      default: false,
+    },
+    id: {
+      type: Number,
+      default: 0,
+    },
+    reportInfo: {
+      type: Object
+    }
+  },
+  watch: {
+    show(n) {
+      if (!n) return
+      
+      this.getclassifylist();
+      this.getreportauthor();
+      
+      if (this.reportInfo) {
+          this.formData = {
+            type: this.reportInfo.AddType,
+            inheritId: 0,
+            classify: this.reportInfo.ClassifyIdThird
+              ? [this.reportInfo.ClassifyIdFirst,this.reportInfo.ClassifyIdSecond,this.reportInfo.ClassifyIdThird]
+              : this.reportInfo.ClassifyIdSecond 
+              ? [this.reportInfo.ClassifyIdFirst,this.reportInfo.ClassifyIdSecond]
+              : [this.reportInfo.ClassifyIdFirst],
+            relationVariety: [],
+            title: this.reportInfo.Title,
+            abstract: this.reportInfo.Abstract,
+            author: this.reportInfo.Author?this.reportInfo.Author.split(","):[],
+            frequency: this.reportInfo.Frequency,
+            time: this.reportInfo.CreateTime,
+            cooperationType: this.reportInfo.CollaborateType,//协作方式
+            cooperationUsers: this.reportInfo.GrandAdminList
+              ? this.reportInfo.GrandAdminList.map(_ => ({
+                  NodeId: _.AdminId,
+                  NodeName: _.AdminName
+                }))
+              : [],
+            reportLayout: this.reportInfo.ReportLayout,//报告布局
+            isPublcPublish: this.reportInfo.IsPublicPublish
+          }
+
+          this.getRelationPermission()
+      }
+    },
+  },
+  data() {
+    return {
+      formData: {
+        type: 1,
+        inheritId: 0,//继承report id
+        classify: [],
+        relationVariety: [],
+        title: "",
+        abstract: "",
+        author: ["投研团队"],
+        frequency: "日度",
+        time: this.$moment().format("YYYY-MM-DD") || "",
+        cooperationType: 1,//协作方式
+        cooperationUsers: [],
+        reportLayout: 1,//报告布局
+        isPublcPublish: 1
+      },
+      publishTip: `若选择是,则发布后所有人可见;<br>
+        若选择否,则发布后,仅创建人和审批人可见;`,
+
+      classifyArr: [],
+      authorlist: [],
+
+      //协作人弹窗
+      isChooseCooperaUser: false,
+
+      //继承报告弹窗
+      isChooseInherReport:false
+    };
+  },
+  computed: {
+    rules() {
+      return {
+        type: [
+          {
+            required: true,
+            message: this.$t("ReportManage.ReportList.please_report_type_select"),
+            trigger: "change",
+          },
+        ],
+        classify: [
+          {
+            required: true,
+            message: this.$t("ReportManage.ReportList.please_report_type_select"),
+            trigger: "change",
+          },
+        ],
+        title: [
+          {
+            required: true,
+            message: this.$t("ReportManage.ReportList.please_report_title_input"),
+            trigger: "blur",
+          },
+        ],
+      };
+    },
+  },
+  methods: {
+    handleClose() {
+      this.formData = {
+        type: 1,
+        inheritId: 0,
+        classify: [],
+        relationVariety: [],
+        title: "",
+        abstract: "",
+        author: ["投研团队"],
+        frequency: "日度",
+        time: this.$moment().format("YYYY-MM-DD") || "",
+        cooperationType: 1,//协作方式
+        cooperationUsers: [],
+        reportLayout: 1,//报告布局
+        isPublcPublish: 1
+      }
+
+      this.$emit("showChange", false);
+    },
+
+    async handleConfirm() {
+      await this.$refs.baseinfoForm.validate()
+
+      const params = {
+        AddType: this.formData.type,
+        ClassifyIdFirst: this.formData.classify[0]
+          ? this.formData.classify[0]
+          : 0,
+        ClassifyNameFirst: "",
+        ClassifyIdSecond: this.formData.classify[1]
+          ? this.formData.classify[1]
+          : 0,
+        ClassifyNameSecond: "",
+        ClassifyIdThird: this.formData.classify[2]
+          ? this.formData.classify[2]
+          : 0,
+        ClassifyNameThird: "",
+        Title: this.formData.title,
+        Abstract: this.formData.abstract,
+        Author:
+          this.formData.author.length > 0
+            ? this.formData.author.join(",")
+            : "",
+        CreateTime: this.formData.time,
+        ReportLayout: this.formData.reportLayout,
+        CollaborateType: this.formData.cooperationType,
+        IsPublicPublish: this.formData.isPublcPublish,
+        InheritReportId: this.formData.inheritId,
+        GrantAdminIdList: this.formData.cooperationUsers.map(_ => _.NodeId)
+      };
+
+      this.classifyArr.forEach((item) => {
+        if (item.value === params.ClassifyIdFirst) {
+          params.ClassifyNameFirst = item.label;
+          const arr = item.children || [];
+          arr.forEach((_item) => {
+            if (_item.value === params.ClassifyIdSecond) {
+              params.ClassifyNameSecond = _item.label;
+              _item.children && _item.children.forEach(last_item => {
+                if (last_item.value === params.ClassifyIdThird) {
+                  params.ClassifyNameThird = last_item.label
+                }
+              })
+            }
+          });
+        }
+      });
+      // 编辑
+      if (this.id) {
+        this.$emit("save", params);
+        return;
+      }
+      reportadd(params).then((res) => {
+        if (res.Ret === 200) {
+
+          let { href } = this.$router.resolve({
+            path: this.formData.reportLayout===1 
+              ? '/reportEditV2'
+              : "/smpartReportEditV2",
+            query: { 
+              id: res.Data.ReportId,
+              coopType: params.CollaborateType
+            },
+          });
+          window.open(href, "_blank");
+
+          this.handleClose();
+        }
+      });
+    },
+
+
+    //分类变化 获取关联品种 
+    handleChangeClassify(val) {
+      this.getRelationPermission()
+      this.handleUpdateBaseInfo()
+    },
+
+    handleUpdateBaseInfo() {
+      this.formData.inheritId = 0;
+
+      if (this.formData.type === 1) {
+        if (this.formData.classify.length === 2) {
+          this.formData.title = this.getSelectClassifyName()[1];
+        }
+        return;
+      }
+      if(!this.formData.classify.length&&this.formData.type===2) return
+
+      
+      //获取上次报告
+      reportV2Interface
+        .getAuthReportList({
+          ClassifyIdFirst: this.formData.classify[0],
+          ClassifyIdSecond: this.formData.classify[1],
+          ClassifyIdThird: this.formData.classify[3],
+          CurrentIndex: 1,
+          PageSize:1,
+          Keyword:''
+        }).then((res) => {
+          if (res.Ret !== 200) return;
+          if (!res.Data.List) {
+            this.$message.warning(
+              this.$t("ReportManage.ReportList.no_reports_msg")
+            );
+            return false;
+          }
+
+          this.chooseInheritReport(res.Data.List[0])
+        });
+    },
+
+    /* 选择继承报告 */
+    async chooseInheritReport(item) {
+      const { Id,Title,Abstract,Author,CollaborateType,ReportLayout,IsPublicPublish,ClassifyIdFirst,ClassifyIdSecond,ClassifyIdThird } = item;
+
+      this.formData.title = Title;
+      this.formData.abstract = Abstract;
+      this.formData.author = Author
+        ? Author.split(",")
+        : "";
+      this.formData.cooperationType = CollaborateType;
+      this.formData.inheritId = Id;
+      this.formData.reportLayout = ReportLayout;
+      this.formData.isPublcPublish = IsPublicPublish;
+      this.formData.classify = ClassifyIdThird
+        ? [ClassifyIdFirst,ClassifyIdSecond,ClassifyIdThird]
+        : ClassifyIdSecond 
+        ? [ClassifyIdFirst,ClassifyIdSecond]
+        : [ClassifyIdFirst]
+      
+      //继承的章节报告默认带出协作人
+      if(CollaborateType===1) {
+        this.formData.cooperationUsers = [];
+      }else {
+        const res = await reportV2Interface.getRportBase({
+          ReportId: Id
+        })
+        if(res.Ret!==200) return
+        
+        this.formData.cooperationUsers = res.Data.GrandAdminList
+          ? res.Data.GrandAdminList.map(_ => ({
+              NodeId: _.AdminId,
+              NodeName: _.AdminName
+            }))
+          : [];
+      }
+    },
+
+    //选择协作人
+    handleChooseCooper() {
+      this.isChooseCooperaUser = true
+    },
+
+    getChooseCooperaUser(val) {
+      this.formData.cooperationUsers = val;
+    },
+
+    removeCooper(index) {
+      this.formData.cooperationUsers.splice(index,1)
+    },
+
+    //获取关联品种
+    async getRelationPermission() {
+      if(!this.formData.classify.length) return
+
+      const res = await classifyPermissionInterface.classifyPermissionList({ClassifyId:this.formData.classify[this.formData.classify.length-1]})
+
+        if(res.Ret!==200) return
+        this.formData.relationVariety = res.Data || []
+    },
+
+    // 获取选择的分类名称
+    getSelectClassifyName() {
+      let arr = [];
+      this.classifyArr.forEach((item) => {
+        if (
+          this.formData.classify[0] &&
+          item.value === this.formData.classify[0]
+        ) {
+          arr.push(item.label);
+          if (item.children && item.children.length > 0) {
+            item.children.forEach((_item) => {
+              if (
+                this.formData.classify[1] &&
+                _item.value === this.formData.classify[1]
+              ) {
+                arr.push(_item.label);
+              }
+            });
+          }
+        }
+      });
+      return arr;
+    },
+
+    // 获取分类
+    getclassifylist() {
+      //获取分类列表
+      let params = { CurrentIndex: 0, PageSize: 1000, KeyWord: "",Enabled:1 };
+
+      classifylist(params).then((res) => {
+        if (res.Ret == 200 && Array.isArray(res.Data.List)) {
+          this.classifyArr = res.Data.List||[];
+        }
+      });
+    },
+    // 获取作者
+    getreportauthor() {
+      apiSmartReport.reportAuthor({}).then((res) => {
+        if (res.Ret == 200) {
+          this.authorlist = res.Data.List || [];
+        }
+      });
+    },
+  },
+  mounted() {
+  },
+};
+</script>
+
+<style lang="scss">
+.baseinfo-form-wrap {
+  width: 85%;
+  margin: 0 auto;
+  .el-input {
+    width: 100%;
+  }
+  .el-input-group__append {
+    background-color: #0052D9;
+    color: #fff;
+  }
+  .el-form-item {
+    margin-left: auto;
+    margin-right: auto;
+  }
+  .choosed-cooper {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 10px;
+  }
+  .permission-wrap {
+    width: 80%;
+    display: flex;
+    flex-wrap: wrap;
+    gap: 5px;
+  }
+}
+</style>

+ 167 - 0
src/views/report_manage/reportV2/components/reportEditHeader.vue

@@ -0,0 +1,167 @@
+<template>
+  <div class="top-action-wrap">
+    <template>
+      <el-input 
+        v-if="reportInfo&&reportInfo.ReportChapterId" 
+        v-model="reportInfo.Title"
+        style="width:240px;"
+        :placeholder="$t('ReportManage.ReportList.label_chap_name')"
+        @change="handleUpdateTitle"
+      ></el-input>
+      
+      <div v-else class="title text_oneLine">{{reportInfo&&reportInfo.Title}}</div>
+    </template>
+    
+      <ul class="action-list">
+          <li 
+            class="action-item" 
+            @click="$emit('handleClearContent')"
+            v-if="permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_clearCont)"
+            >
+              <img src="~@/assets/img/smartReport/icon01.png" alt="">
+              <span><!-- 一键清空内容 -->{{$t('ReportManage.ReportList.click_clear_btn')}}</span>
+          </li>
+          <li v-if="!reportInfo.ReportChapterId" class="action-item" @click="$emit('openBaseInfo')">
+              <img src="~@/assets/img/smartReport/icon01.png" alt="">
+              <span>{{$t('ReportManage.ReportList.information_title')}}</span>
+          </li>
+          <li class="action-item" @click="$emit('handleRefreshAllChart')">
+              <img src="~@/assets/img/smartReport/icon02.png" alt="">
+              <span><!-- 一键刷新 -->{{$t('ReportManage.ReportList.click_refresh_btn')}}</span>
+          </li>
+          <li class="action-item" @click="$emit('handlePreviewReport')">
+              <img src="~@/assets/img/smartReport/icon03.png" alt="">
+              <span>{{$t('ReportManage.ReportList.preview_btn')}}</span>
+          </li>
+          <li class="action-item" @click="$emit('handleSaveContent')">
+              <img src="~@/assets/img/smartReport/icon01.png" alt="">
+              <span>{{$t('ReportManage.ReportList.save_draft_btn')}}</span>
+          </li>
+        
+        <!-- 章节报告,只有提交 提交即是发布 -->
+        <template v-if="reportInfo&&reportInfo.ReportChapterId">
+            <li 
+                class="action-item" 
+                :class="{'disabled':checkLoading}"
+                @click="$emit('handlePublishOpt')"
+            >
+                <img src="~@/assets/img/smartReport/icon01.png" alt="">
+                <span>{{$t('ReportManage.ReportList.submit_chapter_btn')}}</span>
+            </li>
+        </template>
+
+        <!-- 单人报告 -->
+        <template v-else>
+            <template v-if="!isApprove||!hasApproveFlow">
+                <li 
+                    class="action-item" 
+                    :class="{'disabled':checkLoading}"
+                    @click="$emit('handlePublishOpt','dsfb')"
+                    v-if="permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_publish)"
+                    >
+                    <img src="~@/assets/img/smartReport/icon01.png" alt="">
+                    <span>{{$t('ReportManage.ReportList.scheduled_publish_btn')}}</span>
+                </li>
+                <li 
+                    class="action-item" 
+                    :class="{'disabled':checkLoading}"
+                    @click="$emit('handlePublishOpt','fb')"
+                    v-if="permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_publish)"
+                >
+                    <img src="~@/assets/img/smartReport/icon01.png" alt="">
+                    <span>{{$t('ReportManage.ReportList.publish_btn')}}</span>
+                </li>
+            </template>
+            <template v-if="isApprove&&hasApproveFlow">
+                <li 
+                    class="action-item" 
+                    :class="{'disabled':checkLoading}"
+                    @click="$emit('handlePublishOpt','submit')"
+                    v-if="permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_publish)"
+                >
+                    <img src="~@/assets/img/smartReport/icon01.png" alt="">
+                    <span>{{$t('ReportManage.ReportList.submission_btn')}}</span>
+                </li>
+            </template>
+        </template>
+
+          
+      </ul>
+  </div>
+</template>
+<script>
+import {
+	reportV2Interface
+} from '@/api/modules/reportV2';
+export default {
+  props: {
+    reportInfo: {
+        type: Object
+    },
+    isApprove: {
+        type: Boolean
+    },
+    hasApproveFlow: {
+        type: Boolean
+    }
+  },
+  methods:{
+    async handleUpdateTitle() {
+      let res = await reportV2Interface.saveChapterTitle({
+        ReportChapterId: this.reportInfo.ReportChapterId,
+        Title: this.reportInfo.Title
+      })
+      if(res.Ret !== 200) return
+      this.$emit('update')
+    }
+  },
+  mounted() {
+  }
+}
+</script>
+<style scoped lang='scss'>
+.top-action-wrap{
+    position: sticky;
+    top: 0px;
+    background-color: #fff;
+    box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.10);
+    height: 60px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 0 24px;
+    .title{
+        line-height: 60px;
+        font-size: 16px;
+    }
+    .action-list{
+        display: flex;
+        align-items: center;
+        flex-shrink: 0;
+        .action-item{
+            height: 36px;
+            display: flex;
+            align-items: center;
+            border-right: 1px solid #C8CDD9;
+            padding: 0 30px;
+            font-size: 16px;
+            cursor: pointer;
+            img{
+                width: 16px;
+                height: 16px;
+                margin-right: 4px;
+                position: relative;
+                top: 2px;
+            }
+            &:last-child{
+                border-right: none;
+            }
+            &.disabled{
+                pointer-events: none;
+                cursor: not-allowed;
+                color:#999;
+            }
+        }
+    }
+}
+</style>

+ 168 - 0
src/views/report_manage/reportV2/components/reportPreview.vue

@@ -0,0 +1,168 @@
+<template>
+  <el-drawer
+    :visible.sync="show"
+    :modal-append-to-body="false"
+    direction="rtl"
+    @close="handleClose"
+    :show-close="false"
+    size="70%"
+    custom-class="reportPreivew-drawer"
+  > 
+    <template slot="title">
+      <div class="header">
+        <span>报告预览</span>
+        <i class="el-icon-close" @click="handleClose"></i>
+      </div>
+    </template>
+
+    <div style="max-width:1200px; margin:10px auto 70px;" v-loading="isLoading" element-loading-text="研报加载中...">
+      <component
+        v-if="show"
+        :is="reportIdInfo.ReportLayout===1?'reportDetail':'smartReportDetail'"
+        :reportId="reportIdInfo.Id"
+        @reportStartLoading="loading=true"
+        @reportEndLoading="loading=false"
+      />
+    </div>
+
+    <ul class="fixed-handles">
+        <li v-permission="permissionBtn.reportManageBtn.reportManage_reportView_copyWechat" :data-clipboard-text='linkUrl' @click="copyHandle" class="copy">
+            <el-button type="text"><!-- 复制链接 -->{{$t('ReportManage.ReportList.copy_share_link')}}</el-button>
+        </li>
+        <li v-permission="permissionBtn.reportManageBtn.reportManage_reportView_wechartShare" @mouseenter="isShowCode=true" @mouseleave="isShowCode=false" style="position:relative">
+            <el-button type="text"><!-- 微信分享 -->{{$t('ReportManage.ReportList.weChat_share')}}</el-button>
+
+          <vue-qr :text="linkUrl" :margin="0" colorDark="#333" colorLight="#fff" :dotScale="1" :size="100" style="position:absolute;left:-20px;top:-120px;" v-if="isShowCode"></vue-qr>
+        </li>
+        <li v-if="showDownPDF">
+            <el-button type="text" @click="$emit('itemclick',{type:'下载Pdf',data: reportIdInfo})"><!-- 下载PDF -->{{$t('ReportManage.smart_btn.download_pdf')}}</el-button>
+        </li>
+        <li v-if="showDowmImg">
+            <el-button type="text" @click="$emit('itemclick',{type:'下载长图',data: reportIdInfo})"><!-- 下载长图 -->{{$t('ReportManage.smart_btn.download_long_image')}}</el-button>
+        </li>
+
+    </ul>
+
+  </el-drawer>
+</template>
+<script>
+import { reportdetail,departInterence } from 'api/api.js';
+import http from '@/api/http.js';
+import vueQr from 'vue-qr'
+import reportDetail from '../normalReport/reportdtl.vue';
+import smartReportDetail from '../smartReport/reportDetail.vue';
+export default {
+  props: {
+    show: {
+      type: Boolean
+    },
+    reportIdInfo: {
+      type: Object
+    }
+  },
+  components: { reportDetail,smartReportDetail,vueQr },
+  computed: {
+    linkUrl(){
+      let str=''
+      const baseUrl= localStorage.getItem('dynamicOutLinks') ? JSON.parse(localStorage.getItem('dynamicOutLinks')).ReportViewUrl : '';
+      if(this.reportIdInfo.ReportCode){
+        // 设置水印文案
+        let waterMarkStr= localStorage.getItem('waterMarkStr');
+
+        str= this.reportIdInfo.ReportLayout===1 
+          ? `${baseUrl}/reportshare_crm_report?code=${this.reportIdInfo.ReportCode}&flag=${waterMarkStr}& ${this.reportIdInfo.Title}`
+          : `${baseUrl}/reportshare_smart_report?code=${this.reportIdInfo.ReportCode}& ${this.reportIdInfo.Title}`
+      }
+      
+      return str
+    },
+
+    showDownPDF() {
+      return [2,6].includes(this.reportIdInfo.State) && this.permissionBtn.isShowBtn('reportManageBtn','reportManage_exportPdf') && this.reportIdInfo.DetailPdfUrl
+    },
+
+    showDowmImg() {
+       return [2,6].includes(this.reportIdInfo.State) && this.permissionBtn.isShowBtn('reportManageBtn','reportManage_exportImg') && this.reportIdInfo.DetailImgUrl
+    }
+  },
+  watch: {
+    show(nval) {
+      if(!nval) return
+
+    }
+  },
+  data() {
+    return {
+      reportInfo:{},
+    
+      handlesOpt: [
+        { key:'copyLink',label:'复制链接' },
+        { key:'wxShare',label:'微信分享' },
+        { key:'downPdf',label:'下载PDF' },
+        { key:'downPic',label:'下载长图' },
+      ],
+      loading: false,
+
+      isShowCode: false
+    }
+  },
+  methods:{
+    handleClose() {
+      $('.el-drawer__body')[0].scrollTop = 0
+      this.$emit('update:show',false)
+    },
+
+    /* 复制链接 */
+    copyHandle() {
+      var clipboard = new this.Clipboard('.copy')
+      clipboard.on('success', e => {
+        this.$message.success('复制链接成功')
+        e.clearSelection() // 释放内存
+        clipboard.destroy()
+      })
+      // // 浏览器不支持
+      clipboard.on('error', e => {
+        this.$message.warning('浏览器暂不支持')
+        // 释放内存
+        clipboard.destroy()
+      })
+    }
+  },
+}
+</script>
+<style lang="scss">
+  .reportPreivew-drawer {
+    .el-drawer__header {
+      margin-bottom: 0;
+      padding-bottom: 20px;
+      border-bottom: 1px solid #ccc;
+    }
+    
+    .el-drawer__body {
+      position: relative;
+      overflow-y: auto;
+    }
+  }
+</style>
+<style scoped lang='scss'>
+.header {
+  display: flex;
+  justify-content: space-between;
+  font-size: 16px;
+  color: #333;
+}
+
+
+  .fixed-handles {
+    width: 100%;
+    height: 60px;
+    padding: 0 15px;
+    position: fixed;
+    bottom: 0;
+    background: #fff;
+    border-top: 1px solid #ccc;
+    display: flex;
+    align-items: center;
+    gap: 40px;
+  }
+</style>

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