Browse Source

Merge branch 'master' of http://8.136.199.33:3000/eta_front/eta_front into eta1.9.4

cxmo 9 months ago
parent
commit
b496d80f08
84 changed files with 2472 additions and 660 deletions
  1. 9 0
      src/api/modules/sheetApi.js
  2. 8 4
      src/components/selectUnit.vue
  3. 4 0
      src/lang/commonLang.js
  4. 10 0
      src/lang/modules/ETATables/commonLang.js
  5. 1 1
      src/lang/modules/EtaBase/En.js
  6. 1 1
      src/lang/modules/EtaBase/Zh.js
  7. 21 1
      src/lang/modules/EtaBase/commonLang.js
  8. 2 0
      src/lang/modules/Slides/pptList.js
  9. 26 0
      src/lang/modules/Slides/pptPresent.js
  10. 32 2
      src/lang/modules/systemManage/ChartSet.js
  11. 8 2
      src/routes/modules/dataRoutes.js
  12. 0 1
      src/views/chartRelevance_manage/crossVarietyAnalysis/list.vue
  13. 0 1
      src/views/chartRelevance_manage/fittingEquation/fittingEquationList.vue
  14. 0 7
      src/views/chartRelevance_manage/relevance/list.vue
  15. 0 1
      src/views/chartRelevance_manage/statistic/statisticFeatureList.vue
  16. 0 1
      src/views/dataEntry_manage/chartSetting.vue
  17. 3 2
      src/views/dataEntry_manage/codecount/index.vue
  18. 3 1
      src/views/dataEntry_manage/components/barOptionSection.vue
  19. 1 1
      src/views/dataEntry_manage/components/chartSourceEditDialog.vue
  20. 82 0
      src/views/dataEntry_manage/components/edbHasUsedDia.vue
  21. 25 1
      src/views/dataEntry_manage/databaseComponents/dataAssociateChart.vue
  22. 11 0
      src/views/dataEntry_manage/databaseComponents/dataAssociateComputeData.vue
  23. 1 1
      src/views/dataEntry_manage/databaseComponents/edbDetailData.vue
  24. 4 3
      src/views/dataEntry_manage/databaseComponents/fittingResidueDia.vue
  25. 85 18
      src/views/dataEntry_manage/databaseList.vue
  26. 5 5
      src/views/dataEntry_manage/mixins/addOreditMixin.js
  27. 45 31
      src/views/dataEntry_manage/mixins/chartPublic.js
  28. 22 5
      src/views/datasheet_manage/components/MixedTable.vue
  29. 12 4
      src/views/datasheet_manage/components/calculateEdbDia.vue
  30. 19 4
      src/views/datasheet_manage/components/insertDateDia.vue
  31. 12 3
      src/views/datasheet_manage/components/selectTargetValueDia.vue
  32. 81 11
      src/views/datasheet_manage/customSheetEdit.vue
  33. 76 8
      src/views/datasheet_manage/mixedSheetEdit.vue
  34. 24 2
      src/views/datasheet_manage/sheetList.vue
  35. 0 1
      src/views/futures_manage/commodityChartBase.vue
  36. 0 1
      src/views/mychart_manage/components/chartDetailDia.vue
  37. 0 1
      src/views/mychart_manage/index.vue
  38. 3 0
      src/views/ppt_manage/mixins/layerMixins.js
  39. 41 25
      src/views/ppt_manage/mixins/mixins.js
  40. 186 0
      src/views/ppt_manage/mixins/pptEditorMixins.js
  41. 88 10
      src/views/ppt_manage/mixins/pptMixins.js
  42. 1 0
      src/views/ppt_manage/mixins/virtualScrollMixins.js
  43. 5 1
      src/views/ppt_manage/newVersion/components/IndexItem.vue
  44. 1 0
      src/views/ppt_manage/newVersion/components/TextEditor.vue
  45. 25 2
      src/views/ppt_manage/newVersion/components/catalog/pptContent.vue
  46. 25 2
      src/views/ppt_manage/newVersion/components/catalog/pptContentEn.vue
  47. 73 17
      src/views/ppt_manage/newVersion/components/editor/AddFormat.vue
  48. 3 1
      src/views/ppt_manage/newVersion/components/editor/ChangeFormatDialog.vue
  49. 2 1
      src/views/ppt_manage/newVersion/components/editor/DeletePageDialog.vue
  50. 2 2
      src/views/ppt_manage/newVersion/components/editor/InsertPageDialog.vue
  51. 219 0
      src/views/ppt_manage/newVersion/components/editor/TitleEditorTool.vue
  52. 3 20
      src/views/ppt_manage/newVersion/components/editor/chooseCover/TextEl.vue
  53. 21 2
      src/views/ppt_manage/newVersion/components/formatEl/SheetEl.vue
  54. 2 55
      src/views/ppt_manage/newVersion/components/formatEl/TextEl.vue
  55. 80 0
      src/views/ppt_manage/newVersion/components/formatPage/FormatThirteen.vue
  56. 12 4
      src/views/ppt_manage/newVersion/components/formatPage/mixins.js
  57. 4 1
      src/views/ppt_manage/newVersion/components/formatPreview/FormatPreEle.vue
  58. 26 0
      src/views/ppt_manage/newVersion/components/formatPreview/FormatPreThirteen.vue
  59. 3 22
      src/views/ppt_manage/newVersion/components/layer/Element/TextShape.vue
  60. 111 1
      src/views/ppt_manage/newVersion/css/common.scss
  61. 37 16
      src/views/ppt_manage/newVersion/css/format.scss
  62. 5 5
      src/views/ppt_manage/newVersion/pptCatalog.vue
  63. 114 59
      src/views/ppt_manage/newVersion/pptEditor.vue
  64. 5 4
      src/views/ppt_manage/newVersion/pptEnCatalog.vue
  65. 88 52
      src/views/ppt_manage/newVersion/pptEnEditor.vue
  66. 42 2
      src/views/ppt_manage/newVersion/pptEnPresent.vue
  67. 37 10
      src/views/ppt_manage/newVersion/pptEnPublish.vue
  68. 42 2
      src/views/ppt_manage/newVersion/pptPresent.vue
  69. 37 15
      src/views/ppt_manage/newVersion/pptPublish.vue
  70. 36 5
      src/views/ppt_manage/newVersion/utils/config.js
  71. 146 0
      src/views/ppt_manage/newVersion/utils/tinymceSetting.js
  72. 14 0
      src/views/ppt_manage/newVersion/utils/untils.js
  73. 24 9
      src/views/predictEdb_manage/predictEdb.vue
  74. 1 1
      src/views/report_manage/mixins/editor.js
  75. 1 1
      src/views/report_manage/mixins/reportMixin.js
  76. 1 1
      src/views/report_manage/reportEn/reportEditor.vue
  77. 21 2
      src/views/sandbox_manage/index_new_version.vue
  78. 33 16
      src/views/sandbox_manage/sandFlowNew/index.vue
  79. 0 84
      src/views/sandbox_manage/sandFlowNew/popover.vue
  80. 1 1
      src/views/smartReport/components/TextEdit.vue
  81. 26 0
      src/views/system_manage/chartTheme/common/config.js
  82. 112 62
      src/views/system_manage/chartTheme/components/optionsSection.vue
  83. 2 1
      src/views/system_manage/chartTheme/index.vue
  84. 78 21
      src/views/system_manage/chartTheme/themeSetting.vue

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

@@ -280,6 +280,15 @@ export const refreshCustomSheet = params => {
 	return http.get('/datamanage/excel_info/table/refresh',params)
 }
 
+/**
+ * 表格 获取原始指标来源
+ * @param {*} params  EdbInfoId
+ * @returns  
+ */
+export const getEdbBaseSource = params => {
+	return http.get('/datamanage/excel_info/get_edb_source',params)
+}
+
 /**
  * 下载excel
  * @param {*} params ExcelInfoId authorization

+ 8 - 4
src/components/selectUnit.vue

@@ -50,10 +50,14 @@ export default {
         }
     },
     watch:{
-        value(){
-            if(this.value){
-                this.unit = this.getUnitTrans(this.value)
-            }
+        value:{
+            handler(){
+                if(this.value){
+                    console.log('value',this.value)
+                    this.unit = this.getUnitTrans(this.value)
+                }
+            },
+            immediate:true
         }
     },
     data() {

+ 4 - 0
src/lang/commonLang.js

@@ -338,6 +338,10 @@ export default {
       en:'Add',
       zh:'新增'
     },
+    edit_btn:{
+      en:'Edit',
+      zh:'编辑'
+    },
     to: {
       en: ' To ',
       zh:'至'

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

@@ -240,6 +240,16 @@ export default {
       zh: "更新时间 ",
       en: "Updating Time",
     }
+  },
+  Common:{
+    data_source:{
+      zh: "数据来源",
+      en: "Source",
+    },
+    source:{
+      zh: "来源",
+      en: "Source",
+    }
   }
 };
 

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

@@ -62,7 +62,7 @@ export default {
     origin_edb: 'Original Indicator',
     replace: 'Replace to',
     replace_all: 'Replace all',
-    replace_tip: 'Tip: After the replacement, charts and calculated indicators that refer to the original indicator will be replaced by the replacement indicator.',
+    replace_tip: 'Note: After replacement, all references to the original metric in charts, tables, calculated metrics, and logic diagrams will be substituted with the replacement metric.',
     replace_success_msg: 'This replacement will last for a longer period of time, confirm the replacement?',
     replace_ing_msg: 'The replacement is currently in progress, please be patient',
     input_origin_vaild: 'Original Indicator can not be empty',

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

@@ -62,7 +62,7 @@ export default {
     origin_edb: '原指标',
     replace: '替换为',
     replace_all: '全部替换',
-    replace_tip: '提示:替换后,图表和计算指标引用到原指标的会全部由替换指标替代',
+    replace_tip: '提示:替换后,图、表、计算指标和逻辑图引用到原指标的会全部由替换指标替代',
     replace_success_msg: '本次替换将持续较长时间,是否确认替换?',
     replace_ing_msg: '当前正在替换中,请耐心等待',
     input_origin_vaild: '原指标不能为空',

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

@@ -48,6 +48,22 @@ export default {
     zh:'查看数据',
     en:'View indicators'
   },
+  detail_formula_btn: {
+    zh:'查看公式',
+    en:'Formula'
+  },
+  detail_related_charts_btn: {
+    zh:'关联图',
+    en:'Related Charts'
+  },
+  detail_related_metrics_btn: {
+    zh:'关联指标',
+    en:'Related Metrics'
+  },
+  detail_return_btn:{
+    zh:'返回',
+    en:'Return'
+  },
   detail_del_btn:{
     zh:'删除',
     en:'Delete'
@@ -1213,7 +1229,11 @@ export default {
     },
     del_edb_use_chart: {
       zh: '当前指标已用作画图,不可删除',
-      en: 'The current indicator is being used for drawing and cannot be deleted.'
+      en: 'The current metric is in use for charting and cannot be deleted.'
+    },
+    del_edb_use_table: {
+      zh: '当前指标已被表格引用,不可删除',
+      en: 'The current metric is referenced by a table and cannot be deleted.'
     },
     del_menu_confirm: {
       zh: '确定删除当前目录吗?',

+ 2 - 0
src/lang/modules/Slides/pptList.js

@@ -19,6 +19,7 @@ export const listEn = {
   time_info: "Time",
   operation_info: "Operation",
   publish_info: "Publish",
+  publish_ab:'Pub',
   save_info: "Save",
   rename_successful: "Rename Successful",
   copy_successfully: "Copy Successful",
@@ -142,6 +143,7 @@ export const listZh = {
   time_info: "时间",
   operation_info: "操作",
   publish_info: "发布",
+  publish_ab:'发布',//缩写
   save_info: "保存",
   rename_successful: "重命名成功",
   copy_successfully: "复制成功",

+ 26 - 0
src/lang/modules/Slides/pptPresent.js

@@ -91,6 +91,19 @@ export const presentEn = {
   table_chart: "Chart",
   is_incomplete_please_edit:'Slide {num} content is incomplete, please re-edit!',
   publishing_loading:'Publishing',
+
+  page_title_style_setting:'Title Style Setting',
+  title_location_settings:'Location Settings',
+  title_location_up_down:'up and down',
+  title_location_left_right:'left and right',
+  title_size_settings:'Size Settings',
+  title_size_width:'width',
+  title_size_height:'height',
+  title_content_settings:'Content Settings',
+  apply_to_the_entire:'Apply to the entire PPT',
+  title_style_fontfamily:"Font Family",
+  title_style_fontsize:'Font Size',
+  title_style_color:'Font Color'
 };
 
 /* 中文 */
@@ -182,6 +195,19 @@ export const presentZh = {
   previous_sheet_default: "上一张",
   is_incomplete_please_edit:'第{num}页内容不完整,请重新编辑!',
   publishing_loading:'发布中...',
+
+  page_title_style_setting:'标题编辑模式',
+  title_location_settings:'位置设置',
+  title_location_up_down:'上下',
+  title_location_left_right:'左右',
+  title_size_settings:'大小设置',
+  title_size_width:'宽度',
+  title_size_height:'高度',
+  title_content_settings:'内容设置',
+  apply_to_the_entire:'应用至整个PPT',
+  title_style_fontfamily:"字体设置",
+  title_style_fontsize:'字号设置',
+  title_style_color:'字体颜色'
 };
 
 /**

+ 32 - 2
src/lang/modules/systemManage/ChartSet.js

@@ -5,11 +5,13 @@
 /* 英文 */
 export const ChartSetEn = {
     label00:'Chart Data Source Setting',
-    label00_hint:'Enabling the switch means data source visibility is on by default for new charts and can be toggled manually. Conversely, if disabled, it applies to new charts only, not historical ones.',
+    label00_hint:`<p>The state of "enabled" indicates that when creating a new chart or table, the data source switch is set to "on" by default, and can be manually switched on or off. The "disabled" state works in the same way. </p>
+                <p style="margin-top:10px">Note: This only applies to newly created charts and tables; it does not affect historical charts.</p>`,
     label01:'Chart Types',
     label02:'Chart Library Default Theme',
     add_btn:'Add Custom Theme',
     edit_btn:'Edit Custom Theme',
+    rename:'Rename',
     theme_name:'Theme Name',
     theme_name_placeholder:'Please enter theme name',
     alert_msg:'After deletion, all charts using this theme will adopt the ETA theme. Are you sure you want to proceed with the deletion?',
@@ -35,23 +37,38 @@ export const ChartSetEn = {
     config_opt08:'Font Size',
     config_opt09:'Alignment Method',
     config_opt10:'Background Color',
+    config_opt11:'数据标记',
+    config_opt12:'标记类型',
+    config_opt13:'标记大小',
+    config_opt14:'标记颜色',
+
+    square:'Square',
+    circle:'Circle',
+    // diamond-砖石 highcharts里面菱形标记的值,所以这边用diamond
+    diamond:'Rhomboid',
+    triangle:'Triangle',
+    triangle_down:'Inverted Triangle',
 
     unit01:'st Line',
     unit02:'st Bar',
     unit03:'st Series',
     config_opt05_yes:'Yes',
     config_opt05_no:'No',
+    config_opt11_none:'无',
+    config_opt11_inside:'内置',
     set_hint:'The default theme is set successfully',
 };
   
 /* 中文 */
 export const ChartSetZh = {
     label00:'图表的数据来源',
-    label00_hint:'开启状态表示新建图表时,数据来源展示开关默认开启,可手动切换,关闭状态同理,仅对新增图表生效,历史图表不处理',
+    label00_hint:`<p>开启状态表示新建图表或表格时,数据来源开关默认开启,可手动切换,关闭状态同理。</p>
+                <p style="margin-top:10px">注:仅对新增图表、表格生效,历史图表不处理。</p>`,
     label01:'图表类型',
     label02:'图库默认主题',
     add_btn:'添加自定义主题',
     edit_btn:'编辑自定义主题',
+    rename:'重命名',
     theme_name:'主题名称',
     theme_name_placeholder:'请输入主题名称',
     alert_msg:'删除后,所有采用该主题的图表,将采用ETA主题,是否确定删除?',
@@ -77,12 +94,25 @@ export const ChartSetZh = {
     config_opt08:'字号',
     config_opt09:'对齐方式',
     config_opt10:'背景色',
+    config_opt11:'数据标记',
+    config_opt12:'标记类型',
+    config_opt13:'标记大小',
+    config_opt14:'标记颜色',
+
+    square:'正方形',
+    circle:'圆形',
+    // diamond-砖石 highcharts里面菱形标记的值,所以这边用diamond
+    diamond:'菱形',
+    triangle:'三角形',
+    triangle_down:'倒三角形',
 
     unit01:'条',
     unit02:'根',
     unit03:'系列',
     config_opt05_yes:'是',
     config_opt05_no:'否',
+    config_opt11_none:'无',
+    config_opt11_inside:'内置',
     set_hint:'默认主题设置成功',
 };
   

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

@@ -310,13 +310,19 @@ export default [
         path: 'selfData',
         component: () => import("@/views/dataEntry_manage/thirdBase/selfDataBase.vue"),
         name: "自有数据",
-        hidden: false
+        hidden: false,
+        meta:{
+          name_en:"Proprietary Data"
+        }
       },  
       {
         path: "bloomberg",
         component: () => import("@/views/dataEntry_manage/thirdBase/bloombergSource.vue"),
         name: "Bloomberg",
-        hidden: false
+        hidden: false,
+        meta:{
+          name_en:"Bloomberg"
+        }
       },
       {
         path: "zczx",

+ 0 - 1
src/views/chartRelevance_manage/crossVarietyAnalysis/list.vue

@@ -132,7 +132,6 @@
                 :span="21"
                 style="padding: 20px 0;"
               >
-                <div class="chartEn-mark" v-show="chartInfo.IsEnChart" style="top: 0;left: 0;">En</div>
                 <div class="chart-show-cont"  v-if="!chartInfo.WarnMsg">
                   <div class="chartWrapper" id="chartWrapper">
                     <h2 class="chart-title">{{ currentLang==='en'?(chartInfo.ChartNameEn||chartInfo.ChartName):chartInfo.ChartName }}</h2>

+ 0 - 1
src/views/chartRelevance_manage/fittingEquation/fittingEquationList.vue

@@ -156,7 +156,6 @@
                 :span="21"
                 style="padding: 20px 0;"
               >
-                <div class="chartEn-mark" v-show="chartInfo.IsEnChart" style="top: 0;left: 0;">En</div>
                 <div class="chart-show-cont"  v-if="!chartInfo.WarnMsg">
                   <div class="chartWrapper" id="chartWrapper">
                     <h2 class="chart-title">{{ currentLang==='en'?(chartInfo.ChartNameEn||chartInfo.ChartName):chartInfo.ChartName }}</h2>

+ 0 - 7
src/views/chartRelevance_manage/relevance/list.vue

@@ -154,13 +154,6 @@
         <div class="chart-detail-wrapper" v-if="chartInfo.ChartInfoId">
           <el-row class="bottom-min">
             <el-col :span="21" style="padding: 20px 0">
-              <div
-                class="chartEn-mark"
-                v-show="chartInfo.IsEnChart"
-                style="top: 0; left: 0"
-              >
-                En
-              </div>
               <div class="chart-show-cont" v-if="!chartInfo.WarnMsg">
                 <div class="chartWrapper" id="chartWrapper">
                   <h2 class="chart-title">

+ 0 - 1
src/views/chartRelevance_manage/statistic/statisticFeatureList.vue

@@ -142,7 +142,6 @@
                 :span="21"
                 style="padding: 20px 0;"
               >
-                <div class="chartEn-mark" v-show="chartInfo.IsEnChart" style="top: 0;left: 0;">En</div>
                 <div class="chart-show-cont"  v-if="!chartInfo.WarnMsg">
                   <div class="chartWrapper" id="chartWrapper">
                     <h2 class="chart-title">{{ currentLang==='en'?(chartInfo.ChartNameEn||chartInfo.ChartName):chartInfo.ChartName }}</h2>

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

@@ -391,7 +391,6 @@
                   style="padding-bottom: 30px;"
                 >
                 
-                  <div class="chartEn-mark" v-show="chartInfo.IsEnChart" style="top: 0;left: 0;">En</div>
                   <div class="chart-show-cont"  v-if="!chartInfo.WarnMsg">
                     <div class="chartWrapper" id="chartWrapper">
                       <h2 

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

@@ -67,7 +67,8 @@
 									label: 'ClassifyName',
 									value: 'ClassifyId',
 									children: 'Children',
-									checkStrictly: true
+									checkStrictly: true,
+									emitPath: false,
 								}"
 								@change="menuChange"
 								clearable
@@ -359,7 +360,7 @@ export default {
 				EdbName: edb_name,
 				Frequency: frequency,
 				Unit: unit,
-				ClassifyId: menu&&menu[menu.length-1]
+				ClassifyId: menu
 			}
 			
 			const { Ret,Data } = this.$route.query.edbid ? await dataBaseInterface.editCountCode({ ...params,EdbInfoId: Number(this.$route.query.edbid) }) : await dataBaseInterface.addCountCode(params);

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

@@ -259,8 +259,10 @@ export default {
         this.dateList.push(date_item)
         
         let themeOpt = this.chartInfo.ChartThemeStyle ? JSON.parse(this.chartInfo.ChartThemeStyle) : null;
+        // 看colorsOptions返不返回再说
+        console.log(themeOpt,'themeOpt');
         this.dateList.forEach((item,index) => {
-          item.Color = item.Color || (themeOpt&&themeOpt.colorsOptions[index]||defaultOpts.colors[index]);
+          item.Color = item.Color || (themeOpt &&themeOpt.lineOptionList[index].color || defaultOpts.colors[index]);
         })
       }
       this.cancelDialog()

+ 1 - 1
src/views/dataEntry_manage/components/chartSourceEditDialog.vue

@@ -20,7 +20,7 @@
         <el-form-item :label="$t('Edb.Detail.source')">
           <el-input
             v-model="chartSourceForm.text"
-            :placeholder="$t('Chart.Detail.input_content')"
+            :placeholder="$t('Chart.InputHolderAll.input_content')"
           />
         </el-form-item>
         <el-form-item :label="$t('Chart.Detail.color')" style="margin-bottom:8px;">

+ 82 - 0
src/views/dataEntry_manage/components/edbHasUsedDia.vue

@@ -0,0 +1,82 @@
+<template>
+  <el-dialog
+  :modal-append-to-body='false'
+  :title="$t('Edb.MsgPrompt.del_failed')" 
+  :visible.sync="show"
+  :close-on-click-modal="false"
+  @close="cancelHandle"
+  custom-class="dateDialog"
+  width="650px">
+    <div class="dialog-main">
+      <div class="main-title">
+        <i class="el-icon-error"  style="color: #F56C6C;"></i>
+        <span>{{ $t('Edb.MsgPrompt.del_edb_use_table') }}</span>
+      </div>
+      <div class="main-list">
+        <div class="used-item" v-for="(data,index) in dataList" :key="data.id">
+          <span>{{ index+1 }}、</span><span @click="navigateTo(data.routeUrl)">{{ data.ExcelName }}</span>
+        </div>
+      </div>
+    </div>
+    <div class="dia-bot">
+      <el-button @click="cancelHandle" type="primary" style="width: 120px;"><!-- 知道了 -->{{$t('Dialog.known')}}</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+  export default {
+    name:"",
+    props:{
+      show:{
+        type:Boolean,
+        default:false
+      },
+      dataList:{
+        type:Array,
+        default:()=>[]
+      }
+    },
+    methods:{
+      navigateTo(url){
+        console.log(url);
+        if(!url) return
+        window.open(url, '_blank'); 
+      },
+      cancelHandle(){
+        this.$emit('update:show',false)
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+.main-title{
+  display: flex;
+  align-items: center;
+  font-size: 15px;
+  i{
+    font-size: 20px;
+    margin-right: 10px
+  }
+}
+.main-list{
+  margin: 20px 0 0 30px;
+  max-height: 420px;
+  overflow: auto;
+  .used-item{
+    span{
+      color:#333333 ;
+      cursor: pointer;
+      &:hover{
+        text-decoration: underline
+      }
+    }
+  }
+
+}
+.dia-bot{
+  display: flex;
+  justify-content: flex-end
+}
+</style>

+ 25 - 1
src/views/dataEntry_manage/databaseComponents/dataAssociateChart.vue

@@ -1,10 +1,14 @@
 <template>
     <div class="associate-chart">
         <div v-if="list.length===0&&finished" style="text-align:center;display:block" class="empty-list">
+            <span class="return-btn" @click="()=>{$emit('returnHandle')}">{{$t('Edb.detail_return_btn')}}</span>
             <tableNoData :text="$t('EtaBasePage.no_quote_chart')"/>
         </div>
         <template v-else>
-        <p style="position:relative;font-size:16px">{{$t('Chart.total_chart_show',{limit: chartTotal})}}</p>
+        <p class="associate-chart-title">
+            <span>{{$t('Chart.total_chart_show',{limit: chartTotal})}}</span>
+            <span class="return-btn-tow" @click="()=>{$emit('returnHandle')}">{{$t('Edb.detail_return_btn')}}</span>
+        </p>
         <div
             class="chart-public-list"
             v-infinite-scroll="load"
@@ -203,11 +207,31 @@ export default {
     display: flex;
     flex-direction: column;
 }
+.associate-chart-title{
+    position:relative;
+    font-size:16px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    .return-btn-tow{
+        color: #409eff;
+        font-size: 14px;
+        cursor: pointer;
+    }
+}
 .empty-list{
     min-height: calc(100vh - 300px);
     background-color: #fff;
     margin-top: -30px;
     padding-top: 100px;
+    position: relative;
+    .return-btn{
+        position: absolute;
+        top: 32px;
+        right: 2px;
+        cursor: pointer;
+        color: #409eff;
+    }
 }
 .chart-public-list{
     flex: 1;

+ 11 - 0
src/views/dataEntry_manage/databaseComponents/dataAssociateComputeData.vue

@@ -1,10 +1,12 @@
 <template>
     <div class="main-box">
+        <p class="return-btn" @click="()=>{$emit('returnHandle')}">{{$t('Edb.detail_return_btn')}}</p>
         <el-table 
             :data="list" 
             ref="tableRef" 
             highlight-current-row 
             border
+            style="margin-top: 18px;"
         >
             <el-table-column
                 v-for="item in tableColums"
@@ -134,5 +136,14 @@ export default {
     padding: 30px;
     height: 100%;
     overflow-y: auto;
+    position: relative;
+    .return-btn{
+        color: #409eff;
+        font-size: 14px;
+        cursor: pointer;
+        position: absolute;
+        right: 16px;
+        top: 12px;
+    }
 }
 </style>

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

@@ -10,7 +10,7 @@
 				:min-width="item.minwidthsty"
 				align="center">
 				<template slot="header" slot-scope="scope">
-					<div class="chartEn-mark" style="top: -10px;" v-show="scope.$index ==0 && tableData[0] && tableData[0].IsEnEdb" >En</div>
+					<!-- <div class="chartEn-mark" style="top: -10px;" v-show="scope.$index ==0 && tableData[0] && tableData[0].IsEnEdb" >En</div> -->
 					<span>{{item.label}}</span>
 				</template>	
 				<template slot-scope="scope">

+ 4 - 3
src/views/dataEntry_manage/databaseComponents/fittingResidueDia.vue

@@ -228,7 +228,7 @@ export default {
 				this.formData = {
 					date: backData.date.split(','),
 					edb_name: backData.targetName,
-					menu: backData.menu,
+					menu: backData.menu[backData.menu.length-1],
 					frequency: backData.frequency,
 					unit: backData.unit,
 					self_variate: backData.from_arr[0].FromEdbInfoId,
@@ -278,7 +278,8 @@ export default {
 				label: 'ClassifyName',
 				value: 'ClassifyId',
 				children: 'Children',
-				checkStrictly: true
+				checkStrictly: true,
+				emitPath: false,
 			},
 			/* frequencyArr, */
 			fre_options: ['天','周','月','季','年'],
@@ -534,7 +535,7 @@ export default {
 					Source: this.type,
 					EdbName: edb_name,
 					Unit: unit,
-					ClassifyId: menu[menu.length - 1],
+					ClassifyId: menu,
 					Frequency: frequency,
 					Formula: date.join(','),
 					EdbInfoIdArr: [

+ 85 - 18
src/views/dataEntry_manage/databaseList.vue

@@ -143,12 +143,12 @@
 								style="display: flex; align-items: center"
 								v-if="select_node===data.UniqueCode&&data.HaveOperaAuth"
 							>
-								<img
+								<!-- <img
 									src="~@/assets/img/data_m/move_ico.png"
 									alt=""
 									style="width: 14px; height: 14px; margin-right: 8px"
 									v-if="data.Button.MoveButton&&isEdbBtnShow('moveCatalog')"
-								/>
+								/> -->
 								<!-- 添加子项 -->
 								<img
 									src="~@/assets/img/set_m/add.png"
@@ -175,25 +175,25 @@
 									v-if="!data.EdbCode&&(data.Button.DeleteButton)&&isEdbBtnShow('deleteCatalog')"
 								/>
 								<!-- 查看计算指标 -->
-								<i class="el-icon-view" 
+								<!-- <i class="el-icon-view" 
 									v-if="data.EdbType===2&&![58,59,67,68,74].includes(data.Source)&&isEdbBtnShow('checkCalcChart')" 
-									@click.stop="viewNode(node,data)"></i>
+									@click.stop="viewNode(node,data)"></i> -->
 								<!-- 查看关联图表 -->
-								<img 
+								<!-- <img 
 									v-if="data.Button.ShowChartRelation&&isEdbBtnShow('checkRelatedChart')" 
 									@click.stop="showAssociateChart=true,showAssociateComputeData=false"
 									src="~@/assets/img/icons/associate_chart.png" 
 									style="width: 14px; height: 14px;margin-left: 8px"
 									alt=""
-								/>
+								/> -->
 								<!-- 查看关联指标 -->
-								<img 
+								<!-- <img 
 									v-if="data.Button.ShowEdbRelation&&isEdbBtnShow('checkRelatedEdb')" 
 									@click.stop="showAssociateComputeData=true,showAssociateChart=false"
 									src="~@/assets/img/icons/associate_data.png" 
 									style="width: 14px; height: 14px;margin-left: 8px"
 									alt=""
-								/>
+								/> -->
 							</span>
 						</span>
 					</el-tree>
@@ -219,10 +219,10 @@
 			</div>
 			<!-- 指标关联图模块 -->
 			<div class="main-right right" id="right" style="background:transparent;border:none;box-shadow:none" v-if="showAssociateChart">
-				<dataAssociateChart :edbInfoId="selected_edbid"></dataAssociateChart>
+				<dataAssociateChart :edbInfoId="selected_edbid" @returnHandle="showAssociateChart=false,showAssociateComputeData=false"></dataAssociateChart>
 			</div>
 			<div class="main-right right" id="right" style="background:transparent;border:none;box-shadow:none;padding-top: 30px;box-sizing: border-box;" v-if="showAssociateComputeData">
-				<dataAssociateComputeData :edbInfoId="selected_edbid"></dataAssociateComputeData>
+				<dataAssociateComputeData :edbInfoId="selected_edbid" @returnHandle="showAssociateChart=false,showAssociateComputeData=false"></dataAssociateComputeData>
 			</div>
 			<!-- 指标图表列表 -->
 			<div class="main-right right list" id="right" v-show="isShowList">
@@ -316,6 +316,21 @@
 										type="text" 
 										@click="copyCode"
 									>{{$t('Edb.detail_copydata_btn')}}<!-- 复制数据 --></el-button>
+									<el-button 
+									v-if="EdbData.EdbType===2&&![58,59,67,68,74].includes(EdbData.Source)&&isEdbBtnShow('checkCalcChart')" 
+										type="text" 
+										@click.stop="viewNode"
+									>{{$t('Edb.detail_formula_btn')}}<!-- 查看公式 --></el-button>
+									<el-button 
+										v-if="EdbData.Button.ShowChartRelation&&isEdbBtnShow('checkRelatedChart')"
+										type="text" 
+										@click="showAssociateChart=true,showAssociateComputeData=false" 
+									>{{$t('Edb.detail_related_charts_btn')}}<!-- 关联图 --></el-button>
+									<el-button 
+										v-if="EdbData.Button.ShowEdbRelation&&isEdbBtnShow('checkRelatedEdb')" 
+										type="text"
+										@click="showAssociateComputeData=true,showAssociateChart=false"
+									>{{$t('Edb.detail_related_metrics_btn')}}<!-- 关联指标 --></el-button>
 									<el-button 
 										v-if="EdbData.Button.DeleteButton&&isEdbBtnShow('deleteEdb')"
 										type="text" 
@@ -567,6 +582,10 @@
 			@updateLang="updateLang"
 			cType="ebd" 
 		/>
+
+		<!-- 指标已经被引用 -->
+		<edbHasUsedDia :show.sync="edbHasUsedDiaShow" :dataList="hasUsedList"/>
+
 	</div>
 </template>
 
@@ -597,6 +616,7 @@ import edbDetailData from './databaseComponents/edbDetailData.vue';
 import SmoothEdbDialog from './databaseComponents/smoothEdbDialog.vue';
 import batchComputedV2 from './databaseComponents/batchComputedV2.vue';
 import setLangInfoDia from './components/setLangInfo.vue'
+import edbHasUsedDia from './components/edbHasUsedDia.vue';
 export default {
 	name: '',
 	components: {
@@ -622,7 +642,8 @@ export default {
 		edbDetailData,
 		SmoothEdbDialog,
 		batchComputedV2,
-		setLangInfoDia
+		setLangInfoDia,
+		edbHasUsedDia
 	},
 	directives: {
 		drag(el, bindings,vnode) {
@@ -757,7 +778,10 @@ export default {
 			showBatchComputedPop:false,
 
 			/* 修改对应版本信息弹窗  替换原有设置英文*/
-			isLangInfoDia: false
+			isLangInfoDia: false,
+
+			edbHasUsedDiaShow:false,
+			hasUsedList:[]
 		};
 	},
 	watch: {
@@ -1492,15 +1516,23 @@ export default {
 					 * 0 可删除
 					 * 1 关联指标
 					 * 2 有子目录无指标
+					 * 4 当前指标已用作指标运算,不可删除
+					 * 5 当前指标已用作预测指标,不可删除
+					 * 6 当前指标已被表格引用,不可删除
+					 * 7 当前指标已添加到跨品种分析,不可删除
 					*/
 					const deleteLabelMap = {
 						1: /* '该目录关联指标不可删除' */this.$t('Edb.MsgPrompt.del_not_relate_edb'),
 						2: /* '确认删除当前目录及包含的子目录吗?' */this.$t('Edb.MsgPrompt.del_confirm_menu_or_children'),
 						3: /* '当前指标已用作画图,不可删除' */this.$t('Edb.MsgPrompt.del_edb_use_chart'),
-						4: res.Data.TipsMsg
+						4: res.Data.TipsMsg,
+						5: res.Data.TipsMsg,
+						6: res.Data.TipsMsg,
+						7: res.Data.TipsMsg,
 					}
 
-					if([1,3,4].includes(res.Data.DeleteStatus)) this.$confirm(
+					if([1,3,4,5,7].includes(res.Data.DeleteStatus)){
+						this.$confirm(
 							deleteLabelMap[res.Data.DeleteStatus],
 							/* '删除失败' */this.$t('Edb.MsgPrompt.del_failed'),
 							{
@@ -1508,7 +1540,12 @@ export default {
 							showCancelButton:false,
 							type: 'error'
 						})
-					else if([0,2].includes(res.Data.DeleteStatus)) this.$confirm(
+					}else if(res.Data.DeleteStatus == 6){
+						this.edbHasUsedDiaShow=true
+						this.hasUsedList=res.Data.TableList.map(it =>{
+							return {...it,routeUrl:this.getRouteUrl(it)}
+						})
+					}else if([0,2].includes(res.Data.DeleteStatus)) this.$confirm(
 							res.Data.DeleteStatus === 2 
 							? deleteLabelMap[res.Data.DeleteStatus]
 							: data.EdbCode? this.$t('Edb.MsgPrompt.del_edb_confirm')/* '删除后指标和指标值均不可使用,确认删除吗?' */:/* '确定删除当前目录吗?' */this.$t('Edb.MsgPrompt.del_menu_confirm'), 
@@ -1525,6 +1562,36 @@ export default {
 			})
 
 		},
+		getRouteUrl(table){
+			/**
+			 	1 // 自定义excel
+				2 // 时间序列表格
+				3 // 混合表格
+				4 // 自定义分析表格
+				5 // 平衡表
+			 */
+			let url=''
+			switch (table.Source) {
+				case 1:
+					url = this.$router.resolve({ path: '/sheetAnalysisList',query:{code:table.UniqueCode,id:table.ExcelInfoId}}).href;
+					break;
+				case 2:
+					url = this.$router.resolve({ path: '/sheetTimeList',query:{code:table.UniqueCode,id:table.ExcelInfoId}}).href;
+					break;
+				case 3:
+					url = this.$router.resolve({ path: '/sheetMixedList',query:{code:table.UniqueCode,id:table.ExcelInfoId}}).href;
+					break;
+				case 4:
+					url = this.$router.resolve({ path: '/sheetList',query:{code:table.UniqueCode,id:table.ExcelInfoId}}).href;
+					break;
+				case 5:
+					url = this.$router.resolve({ path: '/viewBalanceSheet',query:{id:table.ExcelInfoId}}).href;
+					break;
+				default:
+					break;
+			}
+			return url
+		},
 		/* 删除方法 */
 		delHandle(ClassifyId,EdbInfoId) {
 			dataBaseInterface.nodeDelete({
@@ -1785,7 +1852,7 @@ export default {
 
 		/* 查看计算公式 打开弹窗 */
 		viewNode(node,data) {
-			const { EdbInfoId,Source } = data;
+			const { EdbInfoId,Source } = this.EdbData;
 
 			//代码运算指标
 			if( Source === 27 ) return this.$router.push({
@@ -1801,7 +1868,7 @@ export default {
 			}).then(res => {
 				if(res.Ret !== 200) return
 				this.setComputedDialogForm(Source,res.Data,true);
-				switch (data.Source) {
+				switch (this.EdbData.Source) {
 					case 23: 
 					case 24: 
 						this.computed_type = 'joint';
@@ -1811,7 +1878,7 @@ export default {
 						this.computed_type = 'alpha';
 						break
 					default:
-						this.computed_type = data.Source;
+						this.computed_type = this.EdbData.Source;
 						break
 				}
 			})

+ 5 - 5
src/views/dataEntry_manage/mixins/addOreditMixin.js

@@ -632,14 +632,14 @@ export default {
 		setAddChartDefault() {
 
 			let themeOpt = this.chartInfo.ChartThemeStyle ? JSON.parse(this.chartInfo.ChartThemeStyle) : null;
-
+			console.log(themeOpt,'themeOpt');
 			this.tableData.forEach((item,index) => {
 				item.ChartColor = item.ChartColor || (themeOpt&&themeOpt.colorsOptions[index]||defaultOpts.colors[index]);
 				item.PredictChartColor = item.PredictChartColor || (themeOpt&&themeOpt.colorsOptions[index]||defaultOpts.colors[index]);
-				item.ChartStyle = item.ChartStyle || (themeOpt&&themeOpt.lineOptions.lineType||'spline');
+				item.ChartStyle = item.ChartStyle || (themeOpt&&themeOpt.lineOptionList[index].lineType||'spline');
 				
 				let configLineWid = index===0?3:1;//兼容预测指标绘图无主题配置
-				this.tableData[index].ChartWidth = this.tableData[index].ChartWidth || (themeOpt&&themeOpt.lineOptions.lineWidth||configLineWid);
+				this.tableData[index].ChartWidth = this.tableData[index].ChartWidth || (themeOpt&&themeOpt.lineOptionList[index].lineWidth||configLineWid);
 			})
 		},
 
@@ -971,10 +971,10 @@ export default {
 			this.tableData.forEach((item,index) => {
 				item.ChartColor = themeOpt.colorsOptions[index];
 				item.PredictChartColor = themeOpt.colorsOptions[index];
-				item.ChartStyle = themeOpt.lineOptions.lineType||'spline';
+				item.ChartStyle = themeOpt.lineOptionList[index].lineType||'spline';
 				item.isAxis = item.isAxis||1;
 
-				this.tableData[index].ChartWidth = themeOpt.lineOptions.lineWidth;
+				this.tableData[index].ChartWidth = themeOpt.lineOptionList[index].lineWidth;
 			})
 
 		},

+ 45 - 31
src/views/dataEntry_manage/mixins/chartPublic.js

@@ -731,7 +731,6 @@ export const chartSetMixin = {
 
       /* 主题样式*/
       const chartTheme =  this.chartInfo.ChartThemeStyle ? JSON.parse(this.chartInfo.ChartThemeStyle) : null;
-
       //拼接标题 数据列
       let data = [];
       let ydata = [];
@@ -824,8 +823,8 @@ export const chartSetMixin = {
         //数据列
         let obj = {
           data: [],
-          type: (chartTheme&&chartTheme.lineOptions.lineType) || 'spline',
-          dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+          type: (chartTheme&&chartTheme.lineOptionList[index].lineType) || 'spline',
+          dashStyle: (chartTheme&&chartTheme.lineOptionList[index].dashStyle)||'Solid',
           yAxis: sameSideIndex,
           name:
             dynamic_arr.length > 1
@@ -836,7 +835,13 @@ export const chartSetMixin = {
           : `${item.EdbAliasName||item.EdbName}${dynamic_tag}`,
           nameEn:item.EdbNameEn?`${item.EdbNameEn}${dynamic_tag_en}`:`${item.EdbAliasName||item.EdbName}${dynamic_tag}`,
           color: item.ChartColor,
-          lineWidth: Number(item.ChartWidth)||(chartTheme&&chartTheme.lineOptions.lineWidth),
+          lineWidth: Number(item.ChartWidth)||(chartTheme&&chartTheme.lineOptionList[index].lineWidth),
+          marker: chartTheme && chartTheme.lineOptionList[index].dataMark && chartTheme.lineOptionList[index].dataMark!='none'?{
+            enabled:true,
+            symbol: chartTheme.lineOptionList[index].markType || 'circle',
+            fillColor:chartTheme.lineOptionList[index].markColor,
+            radius: chartTheme.lineOptionList[index].markSize
+          }:{},
           ...predict_params
         };
         item.DataList = item.DataList || [];
@@ -1034,7 +1039,7 @@ export const chartSetMixin = {
           : `${item.EdbAliasName||item.EdbName}${dynamic_tag}`,
           nameEn:item.EdbNameEn?`${item.EdbNameEn}${dynamic_tag_en}`:`${item.EdbAliasName||item.EdbName}${dynamic_tag}`,
           color: item.ChartColor,
-          lineWidth: Number(item.ChartWidth)||(chartTheme&&chartTheme.lineOptions.lineWidth),
+          lineWidth: Number(item.ChartWidth)||(chartTheme&&chartTheme.lineOptionList[index].lineWidth),
           fillColor: (this.chartInfo.ChartType === 3 || (this.chartInfo.ChartType === 6 && item.ChartStyle === 'areaspline')) ? item.ChartColor : undefined,
           borderWidth: 1,
           borderColor: item.ChartColor,
@@ -1091,9 +1096,10 @@ export const chartSetMixin = {
                             this.isPredictorChart?chartData.DataList.List.filter((item, index) => index > 0):
                             chartData.DataList.filter((item, index) => index > 0):
                             chartData.DataList||[]
-       /* 主题样式*/
-       const chartTheme =  this.chartInfo.ChartThemeStyle ? JSON.parse(this.chartInfo.ChartThemeStyle) : null;
-
+      /* 主题样式*/
+      const chartTheme =  this.chartInfo.ChartThemeStyle ? JSON.parse(this.chartInfo.ChartThemeStyle) : null;
+      // 跟颜色对应
+      chartTheme.lineOptionList=chartTheme.lineOptionList.reverse().slice(-chartDataHandle.length)
       let seasonYdata = [],
         seasonData = [];
 
@@ -1110,17 +1116,25 @@ export const chartSetMixin = {
         }
 
       //数据列
-      for (let j of chartDataHandle) {
+      for (let index in chartDataHandle) {
+        let j = chartDataHandle[index]
+        // console.log(j,index);
         //预测指标配置
         let predict_params =  chartData.EdbInfoCategoryType === 1 ? this.getSeasonPredictParams(j.CuttingDataTimestamp) : {};
-        
+
         let serie_item = {
           data: [],
-          type: (chartTheme&&chartTheme.lineOptions.lineType) || chartData.ChartStyle,
-          dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+          type: (chartTheme&&chartTheme.lineOptionList[index].lineType) || chartData.ChartStyle,
+          dashStyle: (chartTheme&&chartTheme.lineOptionList[index].dashStyle)||'Solid',
           yAxis: 0,
           name: this.isPredictorChart?j.Year:j.ChartLegend,
-          lineWidth: (chartTheme&&chartTheme.lineOptions.lineWidth) || 1,
+          lineWidth: (chartTheme&&chartTheme.lineOptionList[index].lineWidth) || 1,
+          marker: chartTheme && chartTheme.lineOptionList[index].dataMark && chartTheme.lineOptionList[index].dataMark!='none'?{
+            enabled:true,
+            symbol: chartTheme.lineOptionList[index].markType || 'circle',
+            fillColor:chartTheme.lineOptionList[index].markColor,
+            radius: chartTheme.lineOptionList[index].markSize
+          }:{},
           ...predict_params
         };
         const data_array = this.calendar_type === '农历' && this.isPredictorChart?_.cloneDeep(j.Items):_.cloneDeep(j.DataList);
@@ -1415,7 +1429,7 @@ export const chartSetMixin = {
         color: ChartColor,
         chartType: 'linear',
         marker: {
-          radius: (chartTheme&&chartTheme.lineOptions.radius)||5,
+          radius: (chartTheme&&chartTheme.lineOptionList[0].radius)||5,
         },
       }
       real_data.forEach(_ => {
@@ -1586,22 +1600,22 @@ export const chartSetMixin = {
       }
 
       //数据列
-      data.forEach(item => {
+      data.forEach((item,index) => {
         //处理首或/尾全是无效数据的以null填充
         let filterData = this.filterInvalidData(item)
         // console.log(filterData)
       
         let serie_item = {
           data: filterData,
-          type: (chartTheme&&chartTheme.lineOptions.lineType) || 'spline',
-          dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+          type: (chartTheme&&chartTheme.lineOptionList[index].lineType) || 'spline',
+          dashStyle: (chartTheme&&chartTheme.lineOptionList[index].dashStyle)||'Solid',
           yAxis: 0,
           name: item.Name,
           nameCh: item.Name,
           nameEn: item.NameEn,
           color: item.Color,
           chartType: 'linear',
-          lineWidth: (chartTheme&&chartTheme.lineOptions.lineWidth) || 3,
+          lineWidth: (chartTheme&&chartTheme.lineOptionList[index].lineWidth) || 3,
           marker: {
             enabled: false
           }
@@ -1826,18 +1840,18 @@ export const chartSetMixin = {
 
       //处理series
       let seriesData=[]
-      this.relevanceChartData.YDataList.forEach(item=>{
+      this.relevanceChartData.YDataList.forEach((item,index)=>{
         let serie_item = {
           data: item.Value,
-          type: (chartTheme&&chartTheme.lineOptions.lineType) || 'spline',
-          dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+          type: (chartTheme&&chartTheme.lineOptionList[index].lineType) || 'spline',
+          dashStyle: (chartTheme&&chartTheme.lineOptionList[index].dashStyle)||'Solid',
           yAxis: 0,
           name: item.Name,
           nameCh: item.Name,
           nameEn: item.NameEn,
           color: item.Color,
           chartType: 'linear',
-          lineWidth: (chartTheme&&chartTheme.lineOptions.lineWidth) || 3,
+          lineWidth: (chartTheme&&chartTheme.lineOptionList[index].lineWidth) || 3,
           marker: {
             enabled: false
           }
@@ -1951,7 +1965,7 @@ export const chartSetMixin = {
 
       //数据列
       let series = [];
-      DataList.forEach(item => {
+      DataList.forEach((item,index) => {
         //数据列
         let series_item = {
           data: [],
@@ -1963,7 +1977,7 @@ export const chartSetMixin = {
           chartType: 'linear',
           zIndex:1,
           marker: {
-            radius: (chartTheme&&chartTheme.lineOptions.radius)||5,
+            radius: (chartTheme&&chartTheme.lineOptionList[index].radius)||5,
           },
         }
         item.EdbInfoList.forEach(_ => {
@@ -2157,18 +2171,18 @@ export const chartSetMixin = {
 
       //系列
       let series = [];
-      YDataList.forEach(item => {
+      YDataList.forEach((item,index) => {
         let serie_item = {
           data: item.Value,
           pointPlacement: 'on',
-          type: (chartTheme&&chartTheme.lineOptions.lineType) || 'line',
-          dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+          type: (chartTheme&&chartTheme.lineOptionList[index].lineType) || 'line',
+          dashStyle: (chartTheme&&chartTheme.lineOptionList[index].dashStyle)||'Solid',
           yAxis: 0,
           name: item.Name || item.Date,
           nameCh: item.Name || item.Date,
           nameEn: item.Date,
           color: item.Color,
-          lineWidth: (chartTheme&&chartTheme.lineOptions.lineWidth) || 1,
+          lineWidth: (chartTheme&&chartTheme.lineOptionList[index].lineWidth) || 1,
           chartType: 'linear'
         };
         series.push(serie_item)
@@ -2246,14 +2260,14 @@ export const chartSetMixin = {
 
         let series_item = {
           data: item.Value.map(_ =>[_.X,_.Y]),
-          dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
-          type: (chartTheme&&chartTheme.lineOptions.lineType) || 'spline',
+          dashStyle: (chartTheme&&chartTheme.lineOptionList[index].dashStyle)||'Solid',
+          type: (chartTheme&&chartTheme.lineOptionList[index].lineType) || 'spline',
           yAxis: index,
           name: item.Name,
           nameCh: item.Name,
           nameEn: item.NameEn||item.Name,
           color: item.Color,
-          lineWidth: (chartTheme&&chartTheme.lineOptions.lineWidth)||3,
+          lineWidth: (chartTheme&&chartTheme.lineOptionList[index].lineWidth)||3,
           chartType: 'linear',
           zIndex:1
         }

+ 22 - 5
src/views/datasheet_manage/components/MixedTable.vue

@@ -255,6 +255,12 @@ export default {
     disabled: { //是否只预览
       type: Boolean,
       default: false,
+    },
+    sourceFrom:{
+      type: Object,
+      default: ()=>{
+        return {}
+      },
     }
   },
   components: { 
@@ -892,7 +898,7 @@ export default {
     },
 
     /* 插入选择指标的值 */
-    insertSelectData({ edbId,value,relationDate,relationUid,str }) {
+    insertSelectData({ edbId,value,relationDate,relationUid,str,sourceName }) {
 
       this.insertTargetCell.DataType = 5;
       this.insertTargetCell.ShowValue = value;
@@ -903,6 +909,7 @@ export default {
 
       value ? this.$message.success(this.$t('ETable.Msg.insertion_success_msg')) : this.$message.warning(this.$t('ETable.Msg.date_no_data'))
 
+      this.updateSourceFrom(sourceName)
       //如果有关联表格日期就建立新的关联关系
       if(relationDate&&relationUid) {
         let relation = {
@@ -1075,7 +1082,9 @@ export default {
     },
 
     /* 插入系统/指标日期 */
-    insertDatehandle({insertValue,dataTimeType,str}) {
+    insertDatehandle({insertValue,dataTimeType,str,sourceName}) {
+
+      this.updateSourceFrom(sourceName)
 
       this.insertTargetCell.DataType = 1;
       this.insertTargetCell.DataTimeType = dataTimeType;
@@ -1115,7 +1124,7 @@ export default {
     /* 导入指标计算值 */
     insertCalculateData(item) {
       // console.log(item)
-      const { InsertValue,EdbInfoId,Str,relationDate,relationUid } = item;
+      const { InsertValue,EdbInfoId,Str,relationDate,relationUid,sourceName } = item;
       this.insertTargetCell.DataType = 7;
       this.insertTargetCell.ShowValue = InsertValue;
       this.insertTargetCell.Value = Str;
@@ -1125,6 +1134,8 @@ export default {
 
       InsertValue ? this.$message.success(this.$t('ETable.Msg.insertion_success_msg')) : this.$message.warning(this.$t('ETable.Msg.date_no_data'))
 
+      this.updateSourceFrom(sourceName)
+
       //如果有关联表格日期就建立新的关联关系
       if(relationDate&&relationUid) {
         let relation = {
@@ -1175,14 +1186,12 @@ export default {
 
     /* 初始化8行5列 */
     initData(initData=null) {
-      console.log('initData');
       this.hasInit=false
       if(initData) {
         const { CellRelation,Data } = initData;
         this.config.data = Data;
         this.insertRelationArr = JSON.parse(CellRelation);
       }else {
-
         this.config.data = new Array(8).fill("").map((_,_rindex) => {
           return new Array(5).fill("").map((cell,_cindex) => ({
             ShowValue: "",
@@ -1294,6 +1303,14 @@ export default {
       
       this.$set(this.selectCell,'ShowStyle',ShowStyle)
       this.$set(this.selectCell,'ShowFormatValue',ShowFormatValue)
+    },
+    // 更新数据来源
+    updateSourceFrom(source){
+      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.$emit('updateSourceName')
     }
   },
 };

+ 12 - 4
src/views/datasheet_manage/components/calculateEdbDia.vue

@@ -368,7 +368,7 @@ export default {
         MoveForward: 0,
         relationDate: '',//关联的表格日期
         relationUid: '',//关联格子的uid
-      }
+      },
     }
   },
   mounted(){
@@ -452,6 +452,13 @@ export default {
       const res = await sheetInterface.getMixedCalculateData(params)
       if(res.Ret!==200) return 
 
+      let baseSourceName=''
+      await sheetInterface.getEdbBaseSource({EdbInfoId:this.selectEdbInfo.EdbInfoId}).then(res=>{
+        if(res.Ret == 200){
+          // 获取原始指标的来源
+          baseSourceName = res.Data.ExcelSource || ''
+        }
+      })
       this.showResult = true;
       
       this.chooseItem = {
@@ -459,7 +466,8 @@ export default {
         relationUid: this.dateSelectForm.Type===2 ? this.dateSelectForm.relationUid : '',
         EdbInfoId: this.selectEdbInfo.EdbInfoId,
         InsertValue: res.Data.ShowValue||"",
-        Str: JSON.stringify(params)
+        Str: JSON.stringify(params),
+        sourceName:baseSourceName||''
       }
 
       // if(!this.calculateShowData.length) return this.$message.warning('该日期无数据')
@@ -482,8 +490,9 @@ export default {
         : await dataBaseInterface.targetList({EdbInfoId:e.EdbInfoId,CurrentIndex: 1})
 
       if(res.Ret !== 200) return
+      
+      const { EdbInfoId,EdbCode,EdbName,Frequency,Unit,StartDate,ModifyTime,PredictDataList,DataList,HaveOperaAuth } = res.Data.Item;
 
-      const { EdbInfoId,EdbCode,EdbName,Frequency,Unit,StartDate,ModifyTime,SourceName,PredictDataList,DataList,HaveOperaAuth } = res.Data.Item;
       this.selectEdbInfo = {
         EdbCode,
         EdbName,
@@ -491,7 +500,6 @@ export default {
         Unit,
         StartDate,
         ModifyTime,
-        SourceName,
         EdbInfoId,
         HaveOperaAuth,
         DataList: PredictDataList ? [...PredictDataList,...DataList].slice(0,5) : DataList.slice(0,5)

+ 19 - 4
src/views/datasheet_manage/components/insertDateDia.vue

@@ -7,7 +7,7 @@
 		@close="cancelHandle"
 		custom-class="dialog"
 		center
-		width="650px"
+		width="750px"
 		v-dialogDrag>
 			<div class="dialog-main">
 
@@ -151,22 +151,37 @@ export default {
       let backData = {}
       //插入系统日期
       // if(this.info.key==='insert-sys-date') {
-
+        // console.log(this.selectEdbInfo,'this.selectEdbInfo');
+        // return 
         let valueParam = {
           EdbInfoId: this.selectEdbInfo.EdbInfoId||0,
           MoveForward: this.formData.MoveForward,
           DateChange: this.$refs.dateMoveWayRef.dateChangeArr
         }
-
         let { Data } = await sheetInterface.getSystemDate({
           DataTimeType: this.dateChangeSelect,
           Value: JSON.stringify(valueParam)
         })
         
+        // 获取原始指标来源
+        let baseSourceName=''
+        if(this.dateChangeSelect==2){
+          // 获取指标日期的指标的原始来源
+          await sheetInterface.getEdbBaseSource({
+            EdbInfoId:this.selectEdbInfo.EdbInfoId
+          }).then(res=>{
+            if(res.Ret == 200){
+              baseSourceName = res.Data.ExcelSource || ''
+            }
+          })
+        }
+
+
         backData = {
           insertValue: Data.Date,
           dataTimeType: this.dateChangeSelect,
-          str: JSON.stringify(valueParam)
+          str: JSON.stringify(valueParam),
+          sourceName:baseSourceName||''
         }
       // }else { //指标日期
       //   backData = {

+ 12 - 3
src/views/datasheet_manage/components/selectTargetValueDia.vue

@@ -166,7 +166,6 @@ export default {
     //插入值的时候再去计算结果
     async insertData() {
       if(!this.edbInfo) return this.$message.warning(this.$t('ETableChildren.select_metric_first_msg') )
-
       let Date='';
       if(this.dateSelectForm.Type===2) { //选框为表格日期再去取Date
         Date = this.dateSelectForm.relationDate;
@@ -181,11 +180,20 @@ export default {
       if(res.Ret !== 200) return
 
       this.result = res.Data;
-
       let value = (this.result.List&&this.result.List.length)
         ? this.result.List.find(_ => _.DataTime===this.result.Date) ? this.result.List.find(_ => _.DataTime===this.result.Date).Value.toString() : ''
         : ''
 
+      let baseSourceName=''
+      // 获取指标日期的指标的原始来源
+      await sheetInterface.getEdbBaseSource({
+        EdbInfoId:this.edbInfo.EdbInfoId
+      }).then(res=>{
+        if(res.Ret == 200){
+          baseSourceName = res.Data.ExcelSource || ''
+        }
+      })
+
       this.chooseItem = {
         relationDate: Date,
         relationUid: this.dateSelectForm.Type===2 ? this.dateSelectForm.relationUid : '',
@@ -194,7 +202,8 @@ export default {
         str: JSON.stringify({
           MoveForward: this.dateSelectForm.MoveForward,
           DateChange: this.$refs.dateMoveWayRef.dateChangeArr
-        })
+        }),
+        sourceName:baseSourceName||''
       }
 
       this.$emit('insert',this.chooseItem)

+ 81 - 11
src/views/datasheet_manage/customSheetEdit.vue

@@ -91,17 +91,45 @@
       ref="customTableRef"
       @autoSave="autoSaveFun"
     />
+    <div class="chart-source">
+      <span
+        v-if="sheetSourceFrom"
+        :style="`
+        color: ${sheetSourceFrom.isShow ? sheetSourceFrom.color : '#999'};
+        font-size: ${ sheetSourceFrom.fontSize }px;
+      `"
+      ><!-- 数据来源 -->{{$t('ETable.Common.data_source')}}:{{ sheetSourceFrom.text}}</span>
+      <el-switch
+        v-if="sheetSourceFrom"
+        v-model="sheetSourceFrom.isShow"
+        :active-value="true"
+        :inactive-value="false"
+        style="margin:0 15px;"
+        @change="(e) => {sheetSourceFrom.isShow=e,sheetForm.SourcesFrom=JSON.stringify(sheetSourceFrom)}"
+      />
+      <span class="editsty" @click="isShowSourceDialog=true"><!-- 编辑 -->{{$t('Common.edit_btn')}}</span>
+    </div>
+
+    <!-- 数据来源编辑弹窗 -->
+		<chartSourceEditDia
+			:isShow.sync="isShowSourceDialog"
+			:chartInfo="sheetForm"
+			@update="updateSheetSource"
+		/>
   </div>
 </template>
 
 <script>
 import * as sheetInterface from '@/api/modules/sheetApi.js';
 import { dataBaseInterface } from 'api/api.js';
+import {etaBaseConfigInterence} from '@/api/modules/etaBaseConfigApi.js';
 import selectTarget from '@/views/chartRelevance_manage/components/selectTarget.vue';
 import CustomTable from './components/CustomTable.vue'
 import html2canvas from 'html2canvas';
+import chartSourceEditDia from '@/views/dataEntry_manage/components/chartSourceEditDialog.vue';
+
 export default {
-  components: { selectTarget,CustomTable },
+  components: { selectTarget,CustomTable,chartSourceEditDia},
   beforeRouteEnter(to, from, next) {
     if(to.query.id){
       to.matched[1].name=`编辑表格`
@@ -157,7 +185,10 @@ export default {
       isCanEdit:false,
       sheetButton:'',
       // 取消自动保存,比如返回的时候
-      cancelAutoSave:false
+      cancelAutoSave:false,
+      sheetSourceFrom:null,
+      isShowSourceDialog:false,
+      showSourceFrom:true
     }
   },
   methods: {
@@ -169,7 +200,16 @@ export default {
 
     /* 获取表格详情 */
     async getDetail() {
-      if(!this.sheetId) return
+      if(!this.sheetId){
+        const res = await etaBaseConfigInterence.getBaseConfig()
+        if(res.Ret==200){
+          const Data = res.Data||{}
+          this.showSourceFrom = Data.ChartSourceDisplay==='true'?true:false
+        } 
+        this.sheetForm.SourcesFrom = this.setDefaultSource()
+        this.sheetSourceFrom = JSON.parse(this.sheetForm.SourcesFrom)
+        return
+      } 
 
       const res = await sheetInterface.sheetDetail({
 				ExcelInfoId: Number(this.sheetId)
@@ -184,13 +224,16 @@ export default {
         },1000)
         return 
       }
-      const { ExcelName,ExcelClassifyId,ExcelType,TableData,ModifyTime,Button} = res.Data;
+      const { ExcelName,ExcelClassifyId,ExcelType,TableData,ModifyTime,Button,SourcesFrom,ExcelSource} = res.Data;
       this.sheetButton=Button
       this.sheetForm = {
         name: ExcelName,
         classify: ExcelClassifyId,
-        sheetType: ExcelType
+        sheetType: ExcelType,
+        SourcesFrom:SourcesFrom || this.setDefaultSource(ExcelSource)
       }
+
+      this.sheetSourceFrom = JSON.parse(this.sheetForm.SourcesFrom)
       this.saveTime =  this.$moment(ModifyTime).format('YYYY-MM-DD HH:mm:ss')
 
       this.$nextTick(()=>{
@@ -198,11 +241,17 @@ export default {
       })
       this.$refs.customTableRef.initSheetData(TableData);
     },
-
+    setDefaultSource(sourceText){
+      return JSON.stringify({
+        isShow: this.showSourceFrom,
+        text: sourceText,
+        color: "#606266",
+        fontSize: 9
+      })
+    },
     /* 选择指标push指标数组 */
     async handleSelectTarget(e) {
       if(!e) return
-
       const { EdbName,EdbNameEn,UnitEn,EdbInfoId,Unit,Frequency } = e;
       if(this.$refs.customTableRef.config.data.find(_ => _.EdbInfoId===EdbInfoId)) return this.$message.warning(this.$t('OnlineExcelPage.already_exists_msg') )
       
@@ -217,7 +266,7 @@ export default {
         SortType: this.$refs.customTableRef.config.order===1 ? 'desc' : 'asc',
         Num: 12
       })
-      
+      this.updateSourceFrom(Data.ExcelSource)
       this.$refs.customTableRef.updateEdbData({
         Data: Data.Data.map(_ => ({..._,DataTimeType: 1,})),
         EdbAliasName: '',
@@ -253,7 +302,8 @@ export default {
         ExcelClassifyId: classify,
         ExcelImage:'',
         Source: 3,
-        TableData: this.$refs.customTableRef.getSaveParams()
+        TableData: this.$refs.customTableRef.getSaveParams(),
+        SourcesFrom:this.sheetForm.SourcesFrom
       };
       // console.log("自动保存");
       const res = await sheetInterface.sheetEdit({ ExcelInfoId: Number(this.sheetId),...params })
@@ -295,7 +345,8 @@ export default {
         ExcelClassifyId: classify,
         ExcelImage: Data.ResourceUrl,
         Source: 2,
-        TableData: this.$refs.customTableRef.getSaveParams()
+        TableData: this.$refs.customTableRef.getSaveParams(),
+        SourcesFrom:this.sheetForm.SourcesFrom
       };
 
       let isAdd = this.sheetId?false:true
@@ -331,7 +382,20 @@ export default {
     //   sheetInterface.markSheetEditStatus({ExcelInfoId: +this.sheetId,Status:2}).then(res=>{
     //     if(res.Ret != 200) return 
     //   })
-    // }
+    // },
+    updateSheetSource(value){
+      if(value){
+        this.sheetSourceFrom={...this.sheetSourceFrom,...value}
+        this.sheetForm.SourcesFrom=JSON.stringify(this.sheetSourceFrom)
+      }
+    },
+    updateSourceFrom(source){
+      if(!source) return
+      let concatSourceArr = this.sheetSourceFrom.text?`${this.sheetSourceFrom.text},${source}`.split(','):[source];
+      let sourceStr = Array.from(new Set(concatSourceArr)).join(',');
+      this.$set(this.sheetSourceFrom,'text',sourceStr)
+      this.sheetForm.SourcesFrom=JSON.stringify(this.sheetSourceFrom)
+    }
   },
   created() {
     this.getClassify();
@@ -350,6 +414,8 @@ export default {
 .customSheet-wrap {
   min-height: calc(100vh - 120px);
   min-width: 1020px;
+  position: relative;
+  padding-bottom: 30px;
   .wrap-top {
     // display: flex;
     // justify-content: space-between;
@@ -391,6 +457,10 @@ export default {
     }
 
   }
+  .chart-source{
+    position: absolute;
+    bottom: 0;
+  }
 }
 </style>
 <style lang="scss">

+ 76 - 8
src/views/datasheet_manage/mixedSheetEdit.vue

@@ -48,20 +48,49 @@
       </div>
     </div>
     
-    <MixedTable @autoSave="autoSaveFun"
+    <MixedTable @autoSave="autoSaveFun" @updateSourceName="updateSourceFromTable" :sourceFrom="sheetSourceFrom"
       ref="mixedTableRef"
     />
+    <div class="chart-source">
+      <span
+        v-if="sheetSourceFrom"
+        :style="`
+        color: ${sheetSourceFrom.isShow ? sheetSourceFrom.color : '#999'};
+        font-size: ${ sheetSourceFrom.fontSize }px;
+      `"
+      ><!-- 数据来源 -->{{$t('ETable.Common.data_source')}}:{{ sheetSourceFrom.text}}</span>
+      <el-switch
+        v-if="sheetSourceFrom"
+        v-model="sheetSourceFrom.isShow"
+        :active-value="true"
+        :inactive-value="false"
+        style="margin:0 15px;"
+        @change="(e) => {sheetSourceFrom.isShow=e,sheetForm.SourcesFrom=JSON.stringify(sheetSourceFrom)}"
+      />
+      <span class="editsty" @click="isShowSourceDialog=true"><!-- 编辑 -->{{$t('Common.edit_btn')}}</span>
+    </div>
+
+    <!-- 数据来源编辑弹窗 -->
+		<chartSourceEditDia
+			:isShow.sync="isShowSourceDialog"
+			:chartInfo="sheetForm"
+			@update="updateSheetSource"
+		/>
+
   </div>
 </template>
 
 <script>
 import * as sheetInterface from '@/api/modules/sheetApi.js';
 import { dataBaseInterface } from 'api/api.js';
+import {etaBaseConfigInterence} from '@/api/modules/etaBaseConfigApi.js';
 import selectTarget from '@/views/chartRelevance_manage/components/selectTarget.vue';
 import MixedTable from './components/MixedTable.vue'
 import html2canvas from 'html2canvas';
+import chartSourceEditDia from '@/views/dataEntry_manage/components/chartSourceEditDialog.vue';
+
 export default {
-  components: { selectTarget,MixedTable },
+  components: { selectTarget,MixedTable,chartSourceEditDia },
   beforeRouteEnter(to, from, next) {
     if(to.query.id){
       to.matched[1].name=`编辑表格`
@@ -120,6 +149,9 @@ export default {
       cancelAutoSave:false,
 
       updating:false,//更新状态
+      sheetSourceFrom:null,
+      isShowSourceDialog:false,
+      showSourceFrom:true
     }
   },
   methods: {
@@ -131,7 +163,16 @@ export default {
 
     /* 获取表格详情 */
     async getDetail(type='init') {
-      if(!this.sheetId) return
+      if(!this.sheetId){
+        const res = await etaBaseConfigInterence.getBaseConfig()
+        if(res.Ret==200){
+          const Data = res.Data||{}
+          this.showSourceFrom = Data.ChartSourceDisplay==='true'?true:false
+        } 
+        this.sheetForm.SourcesFrom = this.setDefaultSource()
+        this.sheetSourceFrom = JSON.parse(this.sheetForm.SourcesFrom)
+        return
+      } 
 
       const res = await sheetInterface.sheetDetail({
 				ExcelInfoId: Number(this.sheetId)
@@ -150,12 +191,14 @@ export default {
         return 
       }
 
-      const { ExcelName,ExcelClassifyId,TableData,ModifyTime,Button } = res.Data;
+      const { ExcelName,ExcelClassifyId,TableData,ModifyTime,Button,SourcesFrom,ExcelSource } = res.Data;
       this.sheetButton=Button
       this.sheetForm = {
         name: ExcelName,
-        classify: ExcelClassifyId
+        classify: ExcelClassifyId,
+        SourcesFrom:SourcesFrom || this.setDefaultSource(ExcelSource)
       }
+      this.sheetSourceFrom = this.sheetForm.SourcesFrom?JSON.parse(this.sheetForm.SourcesFrom):null
       this.$nextTick(()=>{
         this.sheetInit=true
       })
@@ -165,7 +208,14 @@ export default {
       
       type==='refresh' && this.$message.success(this.$t('OnlineExcelPage.table_data_update_msg') )
     },
-
+    setDefaultSource(sourceText){
+      return JSON.stringify({
+        isShow: this.showSourceFrom,
+        text: sourceText,
+        color: "#606266",
+        fontSize: 9
+      })
+    },
     /* 获取分类 */
     getClassify() {
       sheetInterface.excelClassifyOne({Source: 3}).then(res => {
@@ -187,7 +237,8 @@ export default {
         ExcelClassifyId: classify,
         ExcelImage:'',
         Source: 3,
-        TableData: this.$refs.mixedTableRef.getSaveParams()
+        TableData: this.$refs.mixedTableRef.getSaveParams(),
+        SourcesFrom:this.sheetForm.SourcesFrom
       };
       console.log("自动保存");
       const res = await sheetInterface.sheetEdit({ ExcelInfoId: Number(this.sheetId),...params })
@@ -230,8 +281,10 @@ export default {
         ExcelClassifyId: classify,
         ExcelImage: Data.ResourceUrl,
         Source: 3,
-        TableData: this.$refs.mixedTableRef.getSaveParams()
+        TableData: this.$refs.mixedTableRef.getSaveParams(),
+        SourcesFrom:this.sheetForm.SourcesFrom
       };
+
       let isAdd = this.sheetId?false:true
       const res = this.sheetId
       ? await sheetInterface.sheetEdit({ ExcelInfoId: Number(this.sheetId),...params })
@@ -267,6 +320,15 @@ export default {
     //     if(res.Ret != 200) return 
     //   })
     // }
+    updateSheetSource(value){
+      if(value){
+        this.sheetSourceFrom={...this.sheetSourceFrom,...value}
+        this.sheetForm.SourcesFrom=JSON.stringify(this.sheetSourceFrom)
+      }
+    },
+    updateSourceFromTable(){
+      this.sheetForm.SourcesFrom=JSON.stringify(this.sheetSourceFrom)
+    }
   },
   created() {
     this.getClassify();
@@ -285,6 +347,8 @@ export default {
 .customSheet-wrap {
   min-width: 1070px;
   min-height: calc(100vh - 120px);
+  position: relative;
+  padding-bottom: 30px;
   .wrap-top {
     display: flex;
     justify-content: space-between;
@@ -309,5 +373,9 @@ export default {
       }
     }
   }
+  .chart-source{
+    position: absolute;
+    bottom: 0;
+  }
 }
 </style>

+ 24 - 2
src/views/datasheet_manage/sheetList.vue

@@ -306,6 +306,15 @@
                 :disabled="true"
                 ref="mixedTableRef"
               />
+              <div class="chart-source">
+                <span
+                  v-if="[2,3].includes(sheetDetailInfo.Source) && sheetDetailInfo.SourcesFrom && JSON.parse(sheetDetailInfo.SourcesFrom).isShow"
+                  :style="`
+                  color: ${JSON.parse(sheetDetailInfo.SourcesFrom).color};
+                  font-size: ${ JSON.parse(sheetDetailInfo.SourcesFrom).fontSize }px;
+                `"
+                ><!-- 数据来源 -->{{$t('ETable.Common.source')}}:{{ JSON.parse(sheetDetailInfo.SourcesFrom).text}}</span>
+              </div>
             </div>
           </template>
 
@@ -1062,7 +1071,10 @@ export default {
           this.sheetDetailInfo = res.Data;
           this.saveTime = this.$moment(this.sheetDetailInfo.ModifyTime).format('YYYY-MM-DD HH:mm:ss')||''
           this.editButtonText = this.sheetDetailInfo.CanEdit?'':`${this.sheetDetailInfo.Editor}${this.$t('OnlineExcelPage.editing_msg')}`
-
+          if(!this.sheetDetailInfo.SourcesFrom){
+            this.sheetDetailInfo.SourcesFrom = this.setDefaultSource(this.sheetDetailInfo.ExcelSource)
+          }
+          
           this.$nextTick(() => {
             //sheet组件Mounted已经init一次,再次调用会导致工具栏样式错乱
             //this.sheetDetailInfo.Source === 1 && this.$refs.sheetRef.init();
@@ -1075,7 +1087,14 @@ export default {
           });
         });
     },
-
+    setDefaultSource(sourceText){
+      return JSON.stringify({
+        isShow: true,
+        text: sourceText,
+        color: "#606266",
+        fontSize: 9
+      })
+    },
     /* 删除表格 */
     delSheetHandle({cell, type = ""}) {
       const { ExcelClassifyId, ExcelInfoId  } = cell;
@@ -1419,6 +1438,9 @@ $normal-font: 14px;
           box-sizing: border-box;
           padding: 15px;
           overflow-y: auto;
+          display: flex;
+          flex-direction: column;
+          justify-content: space-between;
           /* min-height: 500px; */
         }
       }

+ 0 - 1
src/views/futures_manage/commodityChartBase.vue

@@ -146,7 +146,6 @@
                 :span="21"
                 style="padding: 20px 0;"
               >
-                <div class="chartEn-mark" v-show="chartInfo.IsEnChart" style="top: 0;left: 0;">En</div>
                 <div class="chart-show-cont"  v-if="!chartInfo.WarnMsg">
                   <div class="chartWrapper" id="chartWrapper">
                     <h2 class="chart-title">{{ currentLang==='en'?(chartInfo.ChartNameEn||chartInfo.ChartName):chartInfo.ChartName }}</h2>

+ 0 - 1
src/views/mychart_manage/components/chartDetailDia.vue

@@ -220,7 +220,6 @@
           </div>
           <div class="cont-bottom" v-loading="refreshLoading">
 
-            <div class="chartEn-mark" v-show="chartInfo.IsEnChart" style="top: unset;left:unset;">En</div>
             <div class="chart-show-cont">
               <div class="chartWrapper" id="chartWrapper">
                 <template v-if="!chartInfo.WarnMsg">

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

@@ -198,7 +198,6 @@
             >
               <el-card class="public-chart-item">
                 <div slot="header" class="item-top">
-                  <div class="chartEn-mark" v-show="chart.IsEnChart" style="top: -10px;left: -10px;">En</div>
                   <span class="text_oneLine" :style="{'padding-left':chart.IsEnChart?'24px':''}">{{ chart_lang === 'en' ? (chart.ChartNameEn||chart.ChartName) : chart.ChartName }}</span>
                   <img
                     v-if="ispublic === 0"

+ 3 - 0
src/views/ppt_manage/mixins/layerMixins.js

@@ -31,6 +31,9 @@ export default {
         this.activeLayerEl = {}
       }
       if(this.isEditLayer){
+        //进入图层编辑模式,需要退出其他模式
+        this.isEditTitle = false
+        
         //如果当前活跃图层没有layers,加上
         if(!this.currentItem.layers){
           this.refleshLayerEl([])

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

@@ -204,14 +204,20 @@ export default {
         //数据列
         let obj = {
           data: [],
-          type: (chartTheme&&chartTheme.lineOptions.lineType) || 'spline',
-          dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+          type: (chartTheme&&chartTheme.lineOptionList[index].lineType) || 'spline',
+          dashStyle: (chartTheme&&chartTheme.lineOptionList[index].dashStyle)||'Solid',
           yAxis: sameSideIndex,
           name:nameCh,
           nameCh:nameCh,
           nameEn:nameEn,
           color: item.ChartColor,
-          lineWidth: Number(item.ChartWidth)||(chartTheme&&chartTheme.lineOptions.lineWidth),
+          lineWidth: Number(item.ChartWidth)||(chartTheme&&chartTheme.lineOptionList[index].lineWidth),
+          marker: chartTheme && chartTheme.lineOptionList[index].dataMark && chartTheme.lineOptionList[index].dataMark!='none'?{
+            enabled:true,
+            symbol: chartTheme.lineOptionList[index].markType || 'circle',
+            fillColor:chartTheme.lineOptionList[index].markColor,
+            radius: chartTheme.lineOptionList[index].markSize
+          }:{},
           ...predict_params
         };
         item.DataList = item.DataList || [];
@@ -437,12 +443,15 @@ export default {
        /* 主题样式*/
       const chartTheme =  this.chartInfo.ChartThemeStyle ? JSON.parse(this.chartInfo.ChartThemeStyle) : null;
 
-
       // 农历数据需要去除第一项 在ETA1.0.5之后,除了这里 农历和公历处理逻辑一样
       const temChartDataList=chartData.DataList||[]
       const chartDataHandle=this.calendar_type === '农历'?
       temChartDataList.filter((item, index) => index > 0):
       temChartDataList
+
+      // 跟颜色对应
+      chartTheme.lineOptionList=chartTheme.lineOptionList.reverse().slice(-chartDataHandle.length)
+
       let seasonYdata = [],
         seasonData = []
 
@@ -451,17 +460,24 @@ export default {
         minLimit = this.chartLimit.min||0
         maxLimit = this.chartLimit.max||0
       //数据列
-      for (let j of chartDataHandle) {
+      for (let index in chartDataHandle) {
+        let j = chartDataHandle[index]
           //预测指标配置
         let predict_params =  chartData.EdbInfoCategoryType === 1 ? this.getSeasonPredictParams(j.CuttingDataTimestamp) : {};
 
         let serie_item = {
           data: [],
-          type: (chartTheme&&chartTheme.lineOptions.lineType) || chartData.ChartStyle,
-          dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+          type: (chartTheme&&chartTheme.lineOptionList[index].lineType) || chartData.ChartStyle,
+          dashStyle: (chartTheme&&chartTheme.lineOptionList[index].dashStyle)||'Solid',
           yAxis: 0,
           name: j.ChartLegend,
-          lineWidth: (chartTheme&&chartTheme.lineOptions.lineWidth) || 1,
+          lineWidth: (chartTheme&&chartTheme.lineOptionList[index].lineWidth) || 1,
+          marker: chartTheme && chartTheme.lineOptionList[index].dataMark && chartTheme.lineOptionList[index].dataMark!='none'?{
+            enabled:true,
+            symbol: chartTheme.lineOptionList[index].markType || 'circle',
+            fillColor:chartTheme.lineOptionList[index].markColor,
+            radius: chartTheme.lineOptionList[index].markSize
+          }:{},
           ...predict_params
         };
         const data_array = _.cloneDeep(j.DataList);
@@ -673,7 +689,7 @@ export default {
         chartType: 'linear',
         color: ChartColor,
         marker: {
-          radius: (chartTheme&&chartTheme.lineOptions.radius)||5,
+          radius: (chartTheme&&chartTheme.lineOptionList[0].radius)||5,
         },
       }
       real_data.forEach(_ => {
@@ -882,21 +898,21 @@ export default {
       }
 
       //数据列
-      data.forEach(item => {
+      data.forEach((item,index) => {
         //处理首或/尾全是无效数据的以null填充
         let filterData = this.filterInvalidData(item)
 
         let serie_item = {
           data: filterData,
-          type: (chartTheme&&chartTheme.lineOptions.lineType) || 'spline',
-          dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+          type: (chartTheme&&chartTheme.lineOptionList[index].lineType) || 'spline',
+          dashStyle: (chartTheme&&chartTheme.lineOptionList[index].dashStyle)||'Solid',
           yAxis: 0,
           name: item.Name,
           nameCh: item.Name,
           nameEn: item.NameEn,
           color: item.Color,
           chartType: 'linear',
-          lineWidth: (chartTheme&&chartTheme.lineOptions.lineWidth) || 3,
+          lineWidth: (chartTheme&&chartTheme.lineOptionList[index].lineWidth) || 3,
           marker: {
             enabled: false
           }
@@ -1100,18 +1116,18 @@ export default {
 
       //处理series
       let seriesData=[]
-      this.relevanceChartData.YDataList.forEach(item=>{
+      this.relevanceChartData.YDataList.forEach((item,index)=>{
         let serie_item = {
           data: item.Value,
-          type: (chartTheme&&chartTheme.lineOptions.lineType) || 'spline',
-          dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+          type: (chartTheme&&chartTheme.lineOptionList[index].lineType) || 'spline',
+          dashStyle: (chartTheme&&chartTheme.lineOptionList[index].dashStyle)||'Solid',
           yAxis: 0,
           name: item.Name,
           nameCh: item.Name,
           nameEn: item.NameEn,
           color: item.Color,
           chartType: 'linear',
-          lineWidth: (chartTheme&&chartTheme.lineOptions.lineWidth) || 3,
+          lineWidth: (chartTheme&&chartTheme.lineOptionList[index].lineWidth) || 3,
           marker: {
             enabled: false
           }
@@ -1237,7 +1253,7 @@ export default {
           chartType: 'linear',
           zIndex:1,
           marker: {
-            radius: (chartTheme&&chartTheme.lineOptions.radius)||5,
+            radius: (chartTheme&&chartTheme.lineOptionList.radius)||5,
           },
         }
         item.EdbInfoList.forEach(_ => {
@@ -1403,14 +1419,14 @@ export default {
 
         let series_item = {
           data: item.Value.map(_ =>[_.X,_.Y]),
-          dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
-          type: (chartTheme&&chartTheme.lineOptions.lineType) || 'spline',
+          dashStyle: (chartTheme&&chartTheme.lineOptionList[index].dashStyle)||'Solid',
+          type: (chartTheme&&chartTheme.lineOptionList[index].lineType) || 'spline',
           yAxis: index,
           name: item.Name,
           nameCh: item.Name,
           nameEn: item.NameEn||item.Name,
           color: item.Color,
-          lineWidth: (chartTheme&&chartTheme.lineOptions.lineWidth)||3,
+          lineWidth: (chartTheme&&chartTheme.lineOptionList[index].lineWidth)||3,
           chartType: 'linear',
           zIndex:1
         }
@@ -1665,18 +1681,18 @@ export default {
 
       //系列
       let series = [];
-      YDataList.forEach(item => {
+      YDataList.forEach((item,index) => {
         let serie_item = {
           data: item.Value,
           pointPlacement: 'on',
-          type: (chartTheme&&chartTheme.lineOptions.lineType) || 'line',
-          dashStyle: (chartTheme&&chartTheme.lineOptions.dashStyle)||'Solid',
+          type: (chartTheme&&chartTheme.lineOptionList[index].lineType) || 'line',
+          dashStyle: (chartTheme&&chartTheme.lineOptionList[index].dashStyle)||'Solid',
           yAxis: 0,
           name: item.Name || item.Date,
           nameCh: item.Name || item.Date,
           nameEn: item.Date,
           color: item.Color,
-          lineWidth: (chartTheme&&chartTheme.lineOptions.lineWidth) || 1,
+          lineWidth: (chartTheme&&chartTheme.lineOptionList[index].lineWidth) || 1,
           chartType: 'linear'
         };
         series.push(serie_item)

+ 186 - 0
src/views/ppt_manage/mixins/pptEditorMixins.js

@@ -8,6 +8,23 @@ import {dataBaseInterface} from "@/api/api.js"
 import * as sheetInterface from '@/api/modules/sheetApi.js';
 import {createRandomCode,checkPPTpageElemant,getChartInfo} from '../newVersion/utils/untils';
 import {modelInfo,defaultPosition} from '../newVersion/utils/config';
+import {titleDefault} from '../newVersion/utils/tinymceSetting';
+function getAllParentNodes(event) {
+    let parentNodes = [];
+    let currentNode = event;
+
+    while (currentNode) {
+        parentNodes.push(currentNode);
+        currentNode = currentNode.parentNode;
+    }
+
+    return parentNodes;
+}
+function NodeCheck(dom,className){
+    const classList = getAllParentNodes(dom).map(d=>d.className)
+    return classList.includes(className)
+}
+let __click__title__outside = null
 export default{
   data(){
     return {
@@ -25,6 +42,10 @@ export default{
 
       refreshLoading:null,//一键刷新的loading
       refreshBtnLoading:false,//一键刷新的按钮loading
+
+      isEditTitle:false,//是否是标题编辑模式
+      titleSetting:null,//存储应用整个PPT的值
+
     }
   },
   directives: {
@@ -46,8 +67,171 @@ export default{
         document.removeEventListener('click',el.__click__outside)
       }
     },
+    'click-title-outside':{
+        bind(el,binding,vnode){
+            const clickHandle = (e)=>{
+                //点击标题区域和标题设置之外的地方,退出标题编辑模式
+                if(!vnode.context.isEditTitle) return
+                if(NodeCheck(e.target,'title-edit-box')||NodeCheck(e.target,'title-editor')){
+                  return false
+                }
+                if(binding.value && typeof binding.value === 'function'){
+                  binding.value(e)
+                }
+              }
+              __click__title__outside = clickHandle
+              document.addEventListener('click',clickHandle)
+        },
+        unbind(el,binding,vnode){
+            document.removeEventListener('click',__click__title__outside)
+        }
+    }
   },
   methods:{
+    testInput(e,item){
+        const text = e.target.innerHTML
+        item.title = text
+    },
+    exitEditTitle(e){
+        this.isEditTitle = false
+    },
+    //切换标题编辑模式
+    handleEditTitle(item){
+        //判断当前ppt是否添加了页面
+        if(this.pageList.length===0){
+            this.$message.warning(this.$t('Slides.msg_page_at_least_one'))
+            return
+        }
+        //如果点击的页不是当前页,将点击页切换至当前页
+        if(this.currentItem.id!==item.id){
+            //this.changeCurrentItem(item,'change')
+            const {id} = item
+            this.isEditLayer = false
+            this.activeLayerEl = {}
+            this.isEditTitle = false
+            
+            this.pageList.map((item,index)=>{
+                if(item.id===id){
+                    this.currentItem = item
+                    this.currentIndex = index
+                }
+            })
+            let height = $('.ppt-editor-item')[0].offsetHeight
+            const index = this.currentIndex
+            //pptEditor的滚动条动画
+            this.$refs.pptEditor.scrollTo({
+                top:height*index,
+                left:0,
+                behavior: 'smooth'
+            })
+        }
+        //this.isEditTitle = !this.isEditTitle
+        this.isEditTitle = true
+        if(this.isEditTitle){
+            //进入标题编辑模式,需要退出其他模式
+            this.isEditLayer = false
+            this.activeLayerEl = {}
+            
+            //初始化该页标题的数据
+            if(!this.currentItem.titleDetail){
+                this.currentItem.titleDetail = this.titleSetting?_.cloneDeep(this.titleSetting):_.cloneDeep(titleDefault)
+                this.$set(this.pageList,this.currentIndex,this.currentItem) 
+            }
+            
+            this.$nextTick(()=>{
+                this.$refs.titleEditor.initFlag = true
+                this.$refs.titleEditor.initTitleEditor()
+            })
+        }
+    },
+    //获取标题内容
+    handleTextChange({val,richContent}){
+        this.currentItem.title = richContent/* val */
+        this.$set(this.pageList,this.currentIndex,this.currentItem) 
+    },
+    //获取标题样式 需要存一份px单位
+    handleTitelStyleChange({top,left,width,height,color,fontSize,fontFamily}){
+        const baseWidth = 900
+        const baseHeight = 630
+        this.currentItem.titleDetail = {
+            top,left,width,height,
+            baseTop:baseHeight*top/100,//px单位,基准为编辑页的ppt大小
+            baseLeft:baseWidth*left/100,
+            baseWidth:baseWidth*width/100,
+            baseHeight:baseHeight*height/100,
+            fontFamily,fontSize,color
+        }
+        this.$set(this.pageList,this.currentIndex,this.currentItem) 
+
+    },
+    //全局改变标题位置
+    changePositionAll({left,top}){
+        //遍历所有PPT页
+        //替换每一页titleDetail的left top
+        //若width,height没有值,则使用默认的,若有值,则不变
+        const defaultWidth = 900
+        const defaultHeight = 630
+        const defaultWidthPercent = 68
+        const defaultHeightPercent = 7
+        this.pageList.forEach(page=>{
+            const {width='',height='',baseWidth='',baseHeight=''} = page.titleDetail||{}
+            page.titleDetail = {
+                top,left,
+                width:width||defaultWidthPercent,
+                height:height||defaultHeightPercent,
+                baseTop:defaultHeight*top/100,//px单位,基准为编辑页的ppt大小
+                baseLeft:defaultWidth*left/100,
+                baseWidth:baseWidth||defaultWidth*width/100,
+                baseHeight:baseHeight||defaultHeight*height/100
+            }
+        })
+        /* this.$message.success('全局设置成功') */
+    },
+    //全局改变标题宽高
+    changeSizeAll({width,height}){
+        //遍历所有PPT页
+        //替换每一页titleDetail的width height
+        //若left,top没有值,则使用默认的,若有值,则不变
+        const defaultWidth = 900
+        const defaultHeight = 630
+        const defaultLeftPercent = 10
+        const defaultTopPercent = 5.5
+        this.pageList.forEach(page=>{
+            const {top='',left='',baseTop='',baseLeft=''} = page.titleDetail||{}
+            page.titleDetail = {
+                width,height,
+                top:top||defaultTopPercent,
+                left:left||defaultLeftPercent,
+                baseWidth:defaultWidth*width/100,
+                baseHeight:defaultHeight*height/100,
+                baseTop:baseTop||defaultHeight*top/100,
+                baseLeft:baseLeft||defaultWidth*left/100,
+            }
+        })
+        //this.$message.success(this.$t('MsgPrompt.set_success_msg'))
+    },
+    //全局改变标题设置,并存储本次设置
+    changeSettingAll(detail){
+        this.titleSetting = detail
+        this.settingAllPage()
+        this.$message.success(this.$t('MsgPrompt.set_success_msg'))
+    },
+    settingAllPage(){
+        const baseWidth = 900
+        const baseHeight = 630
+        this.pageList.forEach((page,index)=>{
+            const {top=6.6,left=10,width=68,height=5,color='#333',fontFamily='helvetica',fontSize=22} = this.titleSetting
+            page.titleDetail = {
+                top,left,width,height,
+                baseTop:baseHeight*top/100,//px单位,基准为编辑页的ppt大小
+                baseLeft:baseWidth*left/100,
+                baseWidth:baseWidth*width/100,
+                baseHeight:baseHeight*height/100,
+                color,fontFamily,fontSize
+            }
+            this.$set(this.pageList,index,page)
+        })
+    },
     //显示切换模板弹窗
     handleChangeFormat(item){
       this.choosedItem = item
@@ -113,6 +297,7 @@ export default{
         modelId: modelId,
         title:this.choosedItem.title,
         elements: elements,
+        titleDetail:this.titleSetting?this.titleSetting:null
       }
       //把这页删掉,添加新的一页
       const index = this.pageList.findIndex((i) => i.id === this.choosedItem.id); 
@@ -143,6 +328,7 @@ export default{
       list.forEach(page=>{
         page.id = createRandomCode()
         page.elements = checkPPTpageElemant(page)
+        page.titleDetail = this.titleSetting?this.titleSetting:null
         pages.push(page)
       })
       //当前PPT没有页

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

@@ -25,6 +25,7 @@ import FormatNine from '../newVersion/components/formatPage/FormatNine.vue';
 import FormatTen from '../newVersion/components/formatPage/FormatTen.vue';
 import FormatEle from '../newVersion/components/formatPage/FormatEle.vue';
 import FormatTwelve from '../newVersion/components/formatPage/FormatTwelve.vue';
+import FormatThirteen from '../newVersion/components/formatPage/FormatThirteen.vue';
 const chunkArray = (array, chunkSize)=>{
     let result = [];
     for (let i = 0; i < array.length; i += chunkSize) {
@@ -34,7 +35,7 @@ const chunkArray = (array, chunkSize)=>{
 }
 export default {
   components:{ FormatOne,FormatTwo,FormatThree,
-    FormatFour,FormatFive,FormatSix,FormatSeven,FormatEight,FormatNine,FormatTen,FormatEle,FormatTwelve},
+    FormatFour,FormatFive,FormatSix,FormatSeven,FormatEight,FormatNine,FormatTen,FormatEle,FormatTwelve,FormatThirteen},
   computed: {
     globalLang() { //全局语言版本 中文ppt可用 英文ppt固定en忽视
       return this.$store.state.lang
@@ -82,6 +83,48 @@ export default {
     }
   },
   methods: {
+    getBasePosition(titleDetail){
+        const {top=6.6,left=10,width=68,height=5} = titleDetail
+        const baseWidth = 900
+        const baseHeight = 630
+        return {
+            baseTop:baseHeight*top/100,
+            baseLeft:baseWidth*left/100,
+            baseWidth:baseWidth*width/100,
+            baseHeight:baseHeight*height/100,
+        }
+    },
+    //配置自定义标题内容
+    setPPTTitle(slide,page){
+        const {titleDetail,title} = page
+        //兼容之前的ppt
+        if(!titleDetail){
+            slide.addText(title, {
+                /* placeholder:"slideTitle", */
+                x:'10%',
+                y:'5.5%',
+                w:'68%',
+                h:'7%',
+                color:'333333'
+              });
+        }else{
+            const {left,top,width,height,color='#333',fontSize=24,fontFamily} = titleDetail
+            const text = toTextProps(toJson(title))
+            const colorObj = color.includes('#')?{color:'333333',transparency:0}:rgbaToHex(color)
+            slide.addText(text,{
+                /* placeholder:"slideTitle", //加上后会走母版slideTitle的设置 */
+                x:left+'%',
+                y:top+'%',
+                w:width+'%',
+                h:height+'%',
+                color:colorObj.color,
+                transparency:colorObj.transparency,
+                fontSize:fontSize*0.7,
+                fontFace:fontFamily,
+            })
+        }
+        return slide
+    },
     //配置自定义封面内容
     setPPTCover(cover,pptCoverContent='',title=''){
         let contentList = []
@@ -172,7 +215,8 @@ export default {
             ModifyTime,
             PublishTime,
             Editor,
-            CoverContent
+            CoverContent,
+            TitleSetting
         } = res.Data
         const pptDate = formatPPTDate(this.currentLang, PptDate)
         let legalContent = JSON.parse(Content)
@@ -180,6 +224,14 @@ export default {
             page.elements = checkPPTpageElemant(page)
             return page
         })
+        let legalTitleSetting = null
+        try{
+            legalTitleSetting = JSON.parse(TitleSetting)
+        }catch(e){
+            console.log(e)
+            legalTitleSetting = null
+        }
+        
         this.pptCoverContent = CoverContent
         this.result = {
             status: 200,
@@ -195,7 +247,8 @@ export default {
             ModifyTime,
             PublishTime,
             Editor,
-            CoverContent
+            CoverContent,
+            TitleSetting:legalTitleSetting
         }
       }else{
         this.result = {status:'',content:'获取ppt数据失败!'}
@@ -484,6 +537,7 @@ export default {
       const sheetElements = page.elements.filter((item)=>{
         return item.type === 'sheet'
       })
+      this.initPageTitle(page)
       if(type==='edit'){
         this.initTexts(textElements,page)
       }
@@ -493,6 +547,16 @@ export default {
       await this.listHandle(chartElements);
       this.initCharts(chartElements, page);
     },
+    //初始化内页标题
+    initPageTitle(page){
+        const index = this.pageList.findIndex((i) => i.id === page.id)
+        this.$nextTick(()=>{
+            const dom = document.getElementById(`page_title__${index}`)
+            if(dom){
+                dom.innerHTML = page.title
+            }
+        })
+    },
     //图表,表格数据统一加载,不按照页
     async initPPTAllPage(pageList){
         let chartElements = []
@@ -554,7 +618,8 @@ export default {
     async sheetListHandle(sheetElements){
       let needGetDataArr = []
       for(let i=0;i<sheetElements.length;i++){
-        if(!this.sheetDataMap[sheetElements[i].sheetId]&&!needGetDataArr.includes(sheetElements[i].sheetId)){
+        if( (!this.sheetDataMap[sheetElements[i].sheetId] || !this.sheetDataMap[sheetElements[i].sheetId].list) 
+          && !needGetDataArr.includes(sheetElements[i].sheetId)){
             needGetDataArr.push(sheetElements[i].sheetId)
         }
       }
@@ -586,13 +651,26 @@ export default {
 				UniqueCode: id
 			})
       if(res.Ret !== 200) return 0
-      const {TableInfo} = res.Data
+      const {TableInfo,SourcesFrom,ExcelSource} = res.Data
       //console.log('get')
-      this.sheetDataMap[id] = _.cloneDeep(TableInfo.TableDataList)
+      this.sheetDataMap[id] ={
+        list:_.cloneDeep(TableInfo.TableDataList),
+        otherParams:{
+          SourcesFrom:SourcesFrom?SourcesFrom:
+                      ExcelSource?this.setDefaultSource(ExcelSource):''
+        }
+      }
       return 1
     },
+    setDefaultSource(sourceText){
+      return JSON.stringify({
+        isShow: true,
+        text: sourceText,
+        color: "#606266",
+        fontSize: 9
+      })
+    },
     initCharts(elements, page) {
-        console.log('initCharts')
       const index = this.pageList.findIndex((i) => i.id === page.id)
       if(index===-1) return
       elements.forEach((item) => {
@@ -1106,8 +1184,8 @@ export default {
 			this.setEnName = false
 		},
 
-    /* 生成ppt时图表追加底部文字 来源/说明 */
-    transChartBottomInfo(slide,{x,y,width,height},data) {
+    /* 生成ppt时 图表、表格 追加底部文字 来源/说明 */
+    transBottomInfo(slide,{x,y,width,height},data) {
       let chartData = data;
       let yPercent = Number(Math.ceil(height.replace(/%/,''))+Math.ceil(y.replace(/%/,'')))+'%';
       // console.log(yPercent)
@@ -1120,7 +1198,7 @@ export default {
                     ? sourceObj.color.substring(1).length<6 
                     ? '000000':sourceObj.color.substring(1)
                     : '666666'
-        slide.addText(`来源:${sourceObj.text}`,{
+        slide.addText(`${this.$t('ETable.Common.source')}:${sourceObj.text}`,{
           x:x,
           y: yPercent,
           w: width,

+ 1 - 0
src/views/ppt_manage/mixins/virtualScrollMixins.js

@@ -1,3 +1,4 @@
+//已停用 可删除
 /** 图库9.0(智能PPT) 虚拟列表 */
 import Highcharts from "highcharts/highstock"
 export default {

+ 5 - 1
src/views/ppt_manage/newVersion/components/IndexItem.vue

@@ -5,7 +5,7 @@
         <div class="wrap">
             <div class="item-flex">
                 <div class="item-icon-left"></div>
-                <div class="item-name">{{pageItem.title}}</div> 
+                <div class="item-name">{{getPlainText(pageItem.title)}}</div> 
                 <div class="item-icon-right none">
                   <el-dropdown @command="handleOperateCommand" trigger="click" v-if="showCloseBtn" v-show="!ctrlKeyActive">
                     <span class="el-dropdown-link"> 
@@ -48,6 +48,7 @@
 </template>
 
 <script>
+import {getPlainText} from '@/views/ppt_manage/newVersion/utils/untils';
 export default {
   props:{
     pageItem:{//ppt页
@@ -118,6 +119,9 @@ export default {
       },
       handleOperateCommand(command){
         this.$emit('operatePpt',{type:command.key,pageItem:this.pageItem})
+      },
+      getPlainText(str){
+        return getPlainText(str)
       }
   },
 };

+ 1 - 0
src/views/ppt_manage/newVersion/components/TextEditor.vue

@@ -1,4 +1,5 @@
 <template>
+    <!-- 需求199上线后停用,可删除 -->
   <!-- <div style="width:100%;height:100%">{{content}}</div> -->
   <Editor v-model="content" 
           :init="setting" ref="editor"

+ 25 - 2
src/views/ppt_manage/newVersion/components/catalog/pptContent.vue

@@ -15,11 +15,28 @@
             <img :src="pptBackImage" class="pptbg" />
           </div>
           <div class="ppt-item" v-else :key="item.id">
-              <div class="title-wrap" :title="item.title" 
+              <!-- <div class="title-wrap" :title="item.title" 
                 :style="`${getStrCount(item.title)<58?'':'top:0;height:14%;'}`"
                 :class="{'title-ellipsis':getStrCount(item.title)>172}">
                 {{item.title}}
-              </div>
+              </div> -->
+              <!-- 自定义标题 -->
+              <div class="custom-title-wrap editor-content" 
+                    :style="item.titleDetail?{
+                        left:(item.titleDetail.baseLeft||90)*contentScale+'px',
+                        top:(item.titleDetail.baseTop||40.9)*contentScale+'px',
+                        width:(item.titleDetail.baseWidth||612)+'px',
+                        height:(item.titleDetail.baseHeight||30.9)+'px',
+                    }:{
+                        left:90*contentScale+'px',top:40.9*contentScale+'px',width:'612px',height:'30.9px'
+                    }">
+                    <div class="title" v-html="item.title"
+                    :style="item.titleDetail?{
+                        color:item.titleDetail.color||'#333',
+                        fontSize:(item.titleDetail.fontSize||22)+'px',
+                        fontFamily:item.titleDetail.fontFamily||'helvetica'
+                    }:{ color:'#333',fontSize:'22px',fontFamily:'helvetica' }"></div>
+                </div>
               <component  :is="getComponentName(item.modelId)"
                           :ref="`pptPage_${index-1}`"
                           :pageIndex="index-1"
@@ -144,6 +161,12 @@ export default {
       await this.initPPTAllPage(this.pageList)
       for(let i=0;i<this.pageList.length;i++){
         if(this.interruptLoad) return
+        if(this.pageList[i].titleDetail){
+            this.pageList[i].titleDetail = {
+                ...this.pageList[i].titleDetail,
+                ...this.getBasePosition(this.pageList[i].titleDetail)
+            }
+        }
         this.loadArr.push(this.pageList[i])
         await this.initPageElements(this.pageList[i],'show')
       } 

+ 25 - 2
src/views/ppt_manage/newVersion/components/catalog/pptContentEn.vue

@@ -14,11 +14,28 @@
             <img :src="pptBackImage" class="pptbg" style="width:100%;height:100%;object-fit: fill !important;"/>
           </div>
           <div class="ppt-item" v-else :key="item.id">
-              <div class="title-wrap" :title="item.title" 
+              <!-- <div class="title-wrap" :title="item.title" 
                 :style="`${getStrCount(item.title)<52?'top:4.5%;left:8%;width:62%;':'top:0;left:8%;width:62%;height:14%;'}`"
                 :class="{'title-ellipsis':getStrCount(item.title)>150}">
                 {{item.title}}
-              </div>
+              </div> -->
+              <!-- 自定义标题 -->
+              <div class="custom-title-wrap editor-content" 
+                    :style="item.titleDetail?{
+                        left:(item.titleDetail.baseLeft||90)*contentScale+'px',
+                        top:(item.titleDetail.baseTop||40.9)*contentScale+'px',
+                        width:(item.titleDetail.baseWidth||612)+'px',
+                        height:(item.titleDetail.baseHeight||30.9)+'px',
+                    }:{
+                        left:90*contentScale+'px',top:40.9*contentScale+'px',width:'612px',height:'30.9px'
+                    }">
+                    <div class="title" v-html="item.title"
+                    :style="item.titleDetail?{
+                        color:item.titleDetail.color||'#333',
+                        fontSize:(item.titleDetail.fontSize||22)+'px',
+                        fontFamily:item.titleDetail.fontFamily||'helvetica'
+                    }:{ color:'#333',fontSize:'22px',fontFamily:'helvetica' }"></div>
+                </div>
               <component  :is="getComponentName(item.modelId)"
                           :ref="`pptPage_${index-1}`"
                           :pageIndex="index-1"
@@ -139,6 +156,12 @@ export default {
       await this.initPPTAllPage(this.pageList)
       for(let i=0;i<this.pageList.length;i++){
         if(this.interruptLoad) return
+        if(this.pageList[i].titleDetail){
+            this.pageList[i].titleDetail = {
+                ...this.pageList[i].titleDetail,
+                ...this.getBasePosition(this.pageList[i].titleDetail)
+            }
+        }
         this.loadArr.push(this.pageList[i])
         await this.initPageElements(this.pageList[i],'show')
       }

+ 73 - 17
src/views/ppt_manage/newVersion/components/editor/AddFormat.vue

@@ -5,16 +5,20 @@
       class="add_ico"
       @click="addPage(chooseModalId)"
     />
+    <el-button type="text" icon="el-icon-arrow-left" :disabled="clickLeftTime===0" @click="scrollPrev"></el-button>
     <div class="format-wrap">
-      <div class="format-item" :class="{'last-choose':chooseModalId===item.modelId}"
-      v-for="item in formatArr" :key="item.modelId">
-        <component
-          :is="previewComponentName(item.modelId)"
-          @click.native="addPage(item.modelId)"
-        />
-        <!-- <p>{{ item.text }}</p> -->
-      </div>
+        <div class="format-trans-wrap" :style="`transform:translateX(${scrollOffset}px);`">
+            <div class="format-item" :class="{'last-choose':chooseModalId===item.modelId}"
+                :style="`margin:0 ${itemOccupyMargin}px;`"
+                    v-for="item in formatArr" :key="item.modelId">
+                    <component
+                    :is="previewComponentName(item.modelId)"
+                    @click.native="addPage(item.modelId)"
+                    />
+                </div>
+        </div>
     </div>
+    <el-button type="text" icon="el-icon-arrow-right" :disabled="clickRightTime===0" @click="scrollNext"></el-button>
   </div>
 </template>
 
@@ -32,6 +36,7 @@ import FormatPreNine from "@/views/ppt_manage/newVersion/components/formatPrevie
 import FormatPreTen from "@/views/ppt_manage/newVersion/components/formatPreview/FormatPreTen";
 import FormatPreEle from "@/views/ppt_manage/newVersion/components/formatPreview/FormatPreEle";
 import FormatPreTwelve from "@/views/ppt_manage/newVersion/components/formatPreview/FormatPreTwelve";
+import FormatPreThirteen from "@/views/ppt_manage/newVersion/components/formatPreview/FormatPreThirteen";
 import {countComponentName} from '@/views/ppt_manage/newVersion/utils/untils';
 export default {
   name: "AddFormat",
@@ -53,15 +58,44 @@ export default {
     FormatPreNine,
     FormatPreTen,
     FormatPreEle,
-    FormatPreTwelve
+    FormatPreTwelve,
+    FormatPreThirteen
   },
   data() {
     return {
       formatArr: formatPre,
-
+      lineShowNum:9,//一行最多能展示几个
+      clickLeftTime:0,//可以按下左按钮的次数,为0时该按钮禁用
+      clickRightTime:0,//可以按下右按钮的次数,为0时该按钮禁用
+      scrollOffset:0,//当前滚动偏移量
+      itemOccupyMargin:0,//当前一个format占用间距
+      itemWidth:92,//当前一个format所占宽度(固定)
     };
   },
   methods: {
+    init(){
+        //初始化按钮次数
+        this.clickLeftTime = 0
+        this.clickRightTime = this.formatArr.length - this.lineShowNum
+        //获取容器宽度,以确定一个format应占宽度
+        const parentWidth = $('.format-wrap').width()
+        this.itemOccupyMargin = ((parentWidth/this.lineShowNum - this.itemWidth - 0.5)/2).toFixed(2)
+    },
+    scrollPrev(){
+        if(this.clickLeftTime<=0) return 
+        this.clickLeftTime--
+        this.clickRightTime++
+        this.scrollFormat(this.clickLeftTime)
+    },
+    scrollNext(){
+        if(this.clickRightTime===0) return
+        this.clickRightTime--
+        this.clickLeftTime++
+        this.scrollFormat(this.clickLeftTime)
+    },
+    scrollFormat(multiple){
+        this.scrollOffset = -(multiple*this.itemWidth+Number(this.itemOccupyMargin))
+    },
     previewComponentName(modelId) {
       return countComponentName(modelId,'pre')
       //return `formatPre${modelMap[modelId]}`;
@@ -70,10 +104,20 @@ export default {
       this.$emit("addPage", modelId);
     },
   },
+  mounted(){
+    this.init()
+  },
 };
 </script>
 <style lang="scss">
 @import "~@/views/ppt_manage/newVersion/css/formatPre.scss";
+.add-icon-wrap{
+    .el-button{
+        i{
+            font-weight: bold;
+        }
+    }
+}
 </style>
 <style scoped lang="scss">
 .add-icon-wrap {
@@ -81,6 +125,8 @@ export default {
   min-height: 64px;
   position: relative;
   padding: 10px 20px;
+  display: flex;
+  align-items: center;
   .add_ico {
     cursor: pointer;
     position: absolute;
@@ -91,15 +137,25 @@ export default {
     height: 28px;
     display: inline-block;
   }
+  .el-button{
+        font-size: 22px;
+        padding:0;
+        &:first-of-type{
+            margin-left: 40px;
+        }
+    }
   .format-wrap {
-    margin-left: 40px;
-    /* background-color: #eef0f3; */
-    width: calc(100% - 40px);
-    /* height: 120px; */
-    display: flex;
-    /* flex-wrap: wrap; */
-    justify-content: space-between;
+    width: calc(100% - 80px);
+    height:68px;
+    overflow-x: hidden;
+    .format-trans-wrap{
+        width:100%;
+        height: 100%;
+        display: flex;
+        flex-wrap: nowrap;
+    }
     .format-item {
+      flex:0 0 auto;
       width: 80px;
       height: 56px;
       padding: 5px;

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

@@ -48,6 +48,7 @@ import FormatPreNine from "@/views/ppt_manage/newVersion/components/formatPrevie
 import FormatPreTen from "@/views/ppt_manage/newVersion/components/formatPreview/FormatPreTen";
 import FormatPreEle from "@/views/ppt_manage/newVersion/components/formatPreview/FormatPreEle";
 import FormatPreTwelve from "@/views/ppt_manage/newVersion/components/formatPreview/FormatPreTwelve";
+import FormatPreThirteen from "@/views/ppt_manage/newVersion/components/formatPreview/FormatPreThirteen";
 import {countComponentName} from '@/views/ppt_manage/newVersion/utils/untils';
 export default {
   props:{
@@ -71,7 +72,8 @@ export default {
     FormatPreNine,
     FormatPreTen,
     FormatPreEle,
-    FormatPreTwelve
+    FormatPreTwelve,
+    FormatPreThirteen
   },
   data() {
     return {

+ 2 - 1
src/views/ppt_manage/newVersion/components/editor/DeletePageDialog.vue

@@ -105,6 +105,7 @@ import FormatNine from '@/views/ppt_manage/newVersion/components/formatPage/Form
 import FormatTen from '@/views/ppt_manage/newVersion/components/formatPage/FormatTen.vue';
 import FormatEle from '@/views/ppt_manage/newVersion/components/formatPage/FormatEle.vue';
 import FormatTwelve from '@/views/ppt_manage/newVersion/components/formatPage/FormatTwelve.vue';
+import FormatThirteen from '@/views/ppt_manage/newVersion/components/formatPage/FormatThirteen.vue';
 import {countComponentName} from '@/views/ppt_manage/newVersion/utils/untils';
 export default {
   props:{
@@ -120,7 +121,7 @@ export default {
     }
   },
   components:{ FormatOne,FormatTwo,FormatThree,
-    FormatFour,FormatFive,FormatSix,FormatSeven,FormatEight,FormatNine,FormatTen,FormatEle,FormatTwelve},  
+    FormatFour,FormatFive,FormatSix,FormatSeven,FormatEight,FormatNine,FormatTen,FormatEle,FormatTwelve,FormatThirteen},  
   data() {
     return {
       startPageNum:null,//开始的页数

+ 2 - 2
src/views/ppt_manage/newVersion/components/editor/InsertPageDialog.vue

@@ -77,7 +77,7 @@
 <script>
 import {pptInterface } from "@/api/api.js";
 import {pptEnInterface} from '@/api/modules/pptEnApi.js';
-import {changeCatalogArr} from '@/views/ppt_manage/newVersion/utils/untils';
+import {changeCatalogArr,getPlainText} from '@/views/ppt_manage/newVersion/utils/untils';
 export default {
   props:{
     insertPageShow:{
@@ -185,7 +185,7 @@ export default {
       data.forEach((item,index)=>{
         let temp = {}
         temp.key = index
-        temp.label = `${this.$i18n.locale == 'zh' ?`第${index+1}页`:` Slide${index+1}`} ${item.title||this.$t('Slides.untitled_title')}`
+        temp.label = `${this.$i18n.locale == 'zh' ?`第${index+1}页`:` Slide${index+1}`} ${getPlainText(item.title||this.$t('Slides.untitled_title'))}`
         temp.disabled = false
         list.push(temp)
       })

+ 219 - 0
src/views/ppt_manage/newVersion/components/editor/TitleEditorTool.vue

@@ -0,0 +1,219 @@
+<template>
+    <div class="title-editor-tool-wrap">
+        <div class="scroll-box">
+            <el-collapse v-model="activeNames" class="tool-list">
+                <!-- 位置设置 -->
+                <el-collapse-item :title="$t('Slides.title_location_settings')" name="position">
+                    <div>
+                        <!-- 上下 -->
+                        <span class="demonstration">{{$t('Slides.title_location_up_down')}}(%)</span>
+                        <el-slider v-model="detail.top" :max="12" :step="0.1"></el-slider>
+                    </div>
+                    <div>
+                        <!-- 左右 -->
+                        <span class="demonstration">{{$t('Slides.title_location_left_right')}}(%)</span>
+                        <el-slider v-model="detail.left" :step="0.1"></el-slider>
+                    </div>
+                    <!-- <el-button type="text" @click="changePosition">应用至整个PPT</el-button> -->
+                </el-collapse-item>
+                <!-- 大小设置 -->
+                <el-collapse-item :title="$t('Slides.title_size_settings')" name="size">
+                    <div>
+                        <!-- 宽度 -->
+                        <span class="demonstration">{{$t('Slides.title_size_width')}}(%)</span>
+                        <el-slider v-model="detail.width" :max="100 - detail.left" :step="0.1"></el-slider>
+                    </div>
+                    <div>
+                        <!-- 高度 -->
+                        <span class="demonstration">{{$t('Slides.title_size_height')}}(%)</span>
+                        <el-slider v-model="detail.height" :max="14-detail.top" :step="0.1"></el-slider>
+                    </div>
+                </el-collapse-item>
+                <!-- <el-collapse-item :title="$t('Slides.title_content_settings')" name="content">
+                    <div class="editor-tool"></div>
+                    <div class="editor" id="editorDom">
+                        <Editor v-model="content" 
+                            :init="setting" 
+                            ref="editor"/>
+                    </div>
+                </el-collapse-item> -->
+            </el-collapse>
+            <div class="other-setting">
+                <div class="setting-item">
+                    <!-- 字体设置 -->
+                    <span>{{$t('Slides.title_style_fontfamily')}}</span>
+                    <el-select v-model="detail.fontFamily">
+                        <el-option v-for="item in fontFamily" :key="item.value"
+                            :label="item.label"
+                            :value="item.value"
+                        />
+                    </el-select>
+                </div>
+                <div class="setting-item">
+                    <!-- 字号设置 -->
+                    <span>{{$t('Slides.title_style_fontsize')}}</span>
+                    <el-select v-model="detail.fontSize">
+                        <el-option v-for="item in fontSizeList" :key="item.value"
+                            :label="item.label"
+                            :value="item.value"
+                        />
+                    </el-select>
+                </div>
+                <div class="setting-item">
+                    <!-- 字体颜色 -->
+                    <span>{{$t('Slides.title_style_color')}}</span>
+                    <el-color-picker
+                        v-model="detail.color"
+                        size="mini"
+                        show-alpha
+                        :predefine="['#333']"
+                    />
+                    </el-tooltip>
+                </div>
+            </div>
+        </div>
+        <!-- 应用至整个PPT -->
+        <el-button type="primary" @click="applyToAll">{{$t('Slides.apply_to_the_entire')}}</el-button>
+    </div>
+</template>
+
+<script>
+import tinymce from "tinymce";
+import Editor from "@tinymce/tinymce-vue";
+import "tinymce/themes/silver";
+import "tinymce/plugins/lists"; //列表插件
+import "tinymce/plugins/quickbars"; //快速栏插件
+import "tinymce/plugins/fullscreen"; //全屏插件
+import "tinymce/plugins/paste"; //黏贴插件
+import "tinymce/icons/default/icons";
+import {setting,fontSizeList,fontFamily} from '../../utils/tinymceSetting'
+export default {
+    components:{Editor},
+    props:{
+        currentItem:{
+            type:Object,
+        }
+    },
+    data() {
+        return {
+            activeNames:'content',
+            content:'&*^%', //若设置为空,则init时没有标题就不会触发watch,随便设置几个字符即可
+            detail:{
+                left:0,top:0,width:0,height:0,
+                color:'#333',fontSize:22,fontFamily:'helvetica'
+            },
+            initFlag:false,
+            setting:{
+                ...setting,
+                language: "zh_CN",
+                language_url: require("../../utils/zh_CN.js"),
+                select:'#editorDom',//将编辑器渲染至该dom
+                fixed_toolbar_container: ".editor-tool",//将toolbar渲染至该dom
+                toolbar_persist:true,//是否一直显示toolbar
+                placeholder:this.$t('Slides.click_input_text_content'),
+            },
+            fontSizeList:fontSizeList,
+            fontFamily:fontFamily,
+
+        };
+    },
+    watch:{
+        //不用富文本用不到
+        content(con){
+            if(this.initFlag){
+                this.initFlag = false
+                return
+            }
+            const { elementId } = this.$refs.editor;
+            let richContent = tinymce.editors[elementId].getContent();
+            let val = tinymce.editors[elementId].getContent({ format: "text" });
+            this.$emit("textChange", { val, richContent });
+        },
+        detail:{
+            handler(newval){
+                //若init还未执行完成,不派发事件
+                if(this.initFlag){
+                    this.initFlag = false
+                    return 
+                }
+                this.$emit("styleChange",newval)
+            },
+            deep:true
+        },
+    },
+    methods: {
+        initTitleEditor(){
+            const {left,top,width,height,fontFamily='helvetica',fontSize=22,color='#333'} = this.currentItem.titleDetail
+            this.detail = {left,top,width,height,fontFamily,fontSize,color}
+            //this.content = this.currentItem.title
+        },
+        changePosition(){
+            const {left,top} = this.detail
+            this.$emit('changePositionAll',{top,left})
+        },
+        changeSize(){
+            this.changePosition()
+            const {width,height} = this.detail
+            this.$emit('changeSizeAll',{width,height})
+        },
+        applyToAll(){
+            this.$emit('applyToAll',this.detail)
+        }
+    },
+};
+</script>
+
+<style scoped lang="scss">
+.title-editor-tool-wrap{
+    flex:1;
+    display:flex;
+    flex-direction: column;
+    overflow-y:hidden;
+    #editorDom{
+        min-height: 200px;
+        border:1px solid #ccc;
+        border-top: none;
+    }
+    .scroll-box{
+        flex:1;
+        overflow-y:auto;
+        overflow-x:hidden;
+        margin-bottom:20px;
+        padding-right:5px;
+        .el-collapse{
+            .el-slider{
+                padding:0 10px;
+            }
+        }
+        .other-setting{
+            margin-top:15px;
+            .setting-item{
+                display:flex;
+                justify-content:space-between;
+                /* align-items:center; */
+                margin-bottom:10px;
+                font-weight: bold;
+                .el-select{
+                    width:100px;
+                }
+            }
+        }
+    }
+}
+</style>
+<style lang="scss">
+.title-editor-tool-wrap{
+    .el-color-picker {
+      display: block;
+      &.el-color-picker--mini {
+        height: 30px;
+      }
+      .el-color-picker__trigger {
+        width: 60px;
+        height: 30px;
+        padding: 0;
+        border: 0;
+      }
+    }
+}
+</style>

+ 3 - 20
src/views/ppt_manage/newVersion/components/editor/chooseCover/TextEl.vue

@@ -46,6 +46,7 @@
         BaseTextShape
     } from '@/views/ppt_manage/newVersion/utils/config';
     import elMixin from './elMixin';
+    import tinymce from "tinymce";
     import Editor from "@tinymce/tinymce-vue";
     import "tinymce/themes/silver";
     import "tinymce/plugins/lists"; //列表插件
@@ -53,6 +54,7 @@
     import "tinymce/plugins/fullscreen"; //全屏插件
     import "tinymce/plugins/paste"; //黏贴插件
     import "tinymce/icons/default/icons";
+    import {setting} from '@/views/ppt_manage/newVersion/utils/tinymceSetting'
     export default {
         mixins: [elMixin],
         props: {
@@ -77,33 +79,14 @@
         data() {
             return {
                 setting: {
+                    ...setting,
                     language: "zh_CN",
                     language_url: require("../../../utils/zh_CN.js"),
-                    menubar: false,
-                    toolbar: [
-                        "indent outdent alignleft aligncenter alignright alignjustify forecolor",
-                        "bold italic underline strikethrough numlist bullist backcolor",
-                        "fontselect fontsizeselect",
-                    ],
-                    quickbars_selection_toolbar: false,
-                    quickbars_insert_toolbar: false,
-                    plugins: "lists quickbars paste",
                     height: 350,
                     inline: true,
                     selector: `#${this.elementInfo.id}-editorDom`,
                     paste_as_text: true,
-                    fontsize_formats: '12px 14px 16px 18px 20px 22px 24px 36px 48px',
-                    font_formats: `微软雅黑='微软雅黑';宋体='宋体';黑体='黑体';仿宋='仿宋';
-                        楷体='楷体';隶书='隶书';幼圆='幼圆';Andale Mono=andale mono,times;
-                        Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;
-                        Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;
-                        Courier New=courier new,courier;Georgia=georgia,palatino;
-                        Helvetica=helvetica;Impact=impact,chicago;
-                        Webdings=webdings;Wingdings=wingdings`,
                     fixed_toolbar_container: ".cover-text-toolbar", //将toolbar放到指定div上
-                    skin_url: "/static/css",
-                    content_url: "/static/css",
-                    //加placeholder
                     placeholder:this.$t('Slides.click_input_text_content')
                 }
             };

+ 21 - 2
src/views/ppt_manage/newVersion/components/formatEl/SheetEl.vue

@@ -52,6 +52,15 @@
       @click.stop="delChart(position)"
       v-if="isBtnShow"
     ></div>
+  <div class="chart-source">
+    <span
+      v-if="sheetSourceFrom && sheetSourceFrom.isShow"
+      :style="`
+      color: ${sheetSourceFrom.isShow ? sheetSourceFrom.color : '#999'};
+      font-size: ${ sheetSourceFrom.fontSize }px;
+    `"
+    ><!-- 来源 -->{{$t('ETable.Common.source')}}:{{ sheetSourceFrom.text}}</span>
+  </div>
 </div>
   
 </template>
@@ -69,13 +78,18 @@ export default {
     return {
       tableData:[],
       type:'sheet',
-      tableKey:0
+      tableKey:0,
+      sheetSourceFrom:{}
     };
   },
   methods:{
     getSheetData(id,value){
       this.tableKey++
-      this.tableData = value
+      if(value){
+        this.tableData = value.list
+        this.sheetSourceFrom=(value.otherParams && value.otherParams.SourcesFrom) ? JSON.parse(value.otherParams.SourcesFrom):''
+      }
+
     }
   },
   mounted(){
@@ -104,4 +118,9 @@ export default {
 			}
   }
 }
+.chart-source{
+  width: 95%;
+  position: absolute;
+  left: 2%;
+}
 </style>

+ 2 - 55
src/views/ppt_manage/newVersion/components/formatEl/TextEl.vue

@@ -43,6 +43,7 @@ import "tinymce/plugins/quickbars"; //快速栏插件
 import "tinymce/plugins/fullscreen"; //全屏插件
 import "tinymce/plugins/paste"; //黏贴插件
 import "tinymce/icons/default/icons";
+import {setting} from '@/views/ppt_manage/newVersion/utils/tinymceSetting'
 export default {
   components:{Editor},
   props:{
@@ -56,36 +57,15 @@ export default {
   data() {
     return {
       setting: {
+        ...setting,
         language: "zh_CN",
         language_url: require("../../utils/zh_CN.js"),
-        menubar: false,
-        toolbar: [
-          "indent outdent alignleft aligncenter alignright alignjustify forecolor",
-          "bold italic underline strikethrough numlist bullist backcolor",
-          "fontselect fontsizeselect",
-        ],
-        quickbars_selection_toolbar:false,  
-        quickbars_insert_toolbar: false,
-        plugins: "lists quickbars paste",
         height: 350,
-        inline: true,
         selector: `#text_${this.index}_${this.position}`,
         paste_as_text: true,
        /*  paste_block_drop: true, 开启后阻止drop事件*/
-        fontsize_formats:'12px 14px 16px 18px 20px 22px 24px 36px 48px',
-        font_formats:`微软雅黑='微软雅黑';宋体='宋体';黑体='黑体';仿宋='仿宋';
-                      楷体='楷体';隶书='隶书';幼圆='幼圆';Andale Mono=andale mono,times;
-                      Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;
-                      Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;
-                      Courier New=courier new,courier;Georgia=georgia,palatino;
-                      Helvetica=helvetica;Impact=impact,chicago;
-                      Webdings=webdings;Wingdings=wingdings`,
-        /* toolbar_persist:true,//始终显示toolbar */
         fixed_toolbar_container: ".richtext-tool",//将toolbar放到指定div上
-        skin_url: "/static/css",
-        content_url: "/static/css",
         placeholder:this.$t('Slides.click_input_text_content')
-       
       },
       content:'',
       initFlag: false,
@@ -150,38 +130,5 @@ export default {
     left:-10px;
     top:-10px;
   }
-  .mce-content-body {
-    width: 100%;
-    height: 100%;
-    padding: 10px;
-    box-sizing: border-box;
-    font-size: 16px;
-    &:focus-visible{
-      outline: 0;
-    }
-    ul{
-      margin-left: 1em;
-      list-style-type: disc;
-    }
-    ol{
-      margin-left: 1em;
-      list-style-type: decimal;
-    }
-  }
-  .mce-edit-focus{
-    outline: 0;
-  }
-  .tox .tox-tbtn--bespoke .tox-tbtn__select-label{
-    width:4.5em !important;
-  }
-  .tox .tox-tbtn{
-    width:32px;
-  }
-  .tox-menu.tox-swatches-menu.tox-selected-menu{
-    left:185px !important;
-  }
-  .mce-content-body:not([dir=rtl])[data-mce-placeholder]:not(.mce-visualblocks)::before {
-    left:10px !important;
-  }
 }
 </style>

+ 80 - 0
src/views/ppt_manage/newVersion/components/formatPage/FormatThirteen.vue

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

+ 12 - 4
src/views/ppt_manage/newVersion/components/formatPage/mixins.js

@@ -1,7 +1,7 @@
 import {checkClipboard,checkClipboardItems,getTextContentSize} from '../../utils/untils';
 import {defaultPosition} from "../../utils/config";
 import { copyFit } from '@/utils/svgToblob.js';
-import Ediotr from '../TextEditor.vue';
+/* import Ediotr from '../TextEditor.vue'; */
 import BaseShape from '../layer/Element/BaseShape.vue';
 import LineShape from "../layer/Element/LineShape.vue";
 import TextShape from "../layer/Element/TextShape.vue";
@@ -11,7 +11,7 @@ import ImageEl from "../formatEl/ImageEl.vue";
 import SheetEl from "../formatEl/SheetEl.vue";
 export default {
     components: {
-        Ediotr,BaseShape,LineShape,TextShape,ChartEl,TextEl,ImageEl,SheetEl
+        /* Ediotr, */BaseShape,LineShape,TextShape,ChartEl,TextEl,ImageEl,SheetEl
       },
     props: {
         pageIndex: {//当前是第几页
@@ -45,6 +45,10 @@ export default {
           type:Boolean,
           default:false
         },
+        isEditTitle:{//父组件是否是标题编辑模式
+            type:Boolean,
+            default:false
+          },
         activeLayerEl:{//当前页面在图层编辑模式时,选中的图层元素
           type:Object,
         },
@@ -100,8 +104,8 @@ export default {
         },
         //判断遮罩layers是否显示
         isLayerShow(){
-          //在图层编辑模式+是当前ppt+是编辑模式
-          return this.isEditLayer&&this.type==='edit'&&this.choosedId===this.pageItem.id
+          //在图层编辑模式/标题编辑模式+是当前ppt+是编辑模式
+          return (this.isEditLayer/* ||this.isEditTitle */)&&this.type==='edit'&&this.choosedId===this.pageItem.id
         },
         //判断该渲染哪个图层组件
         getLayerElName(item){
@@ -117,6 +121,7 @@ export default {
         },
         //切换当前选中的图层元素
         changeActEl(item){
+          if(!this.isEditLayer) return
           this.isClickLayer = false
           //如果该元素已被选中,则什么也不做
           const id = this.activeLayerEl.id
@@ -150,6 +155,7 @@ export default {
         },
         //删除这张图表
         delChart(position) {
+            this.$parent.isEditTitle = false
             this.$emit('delChart', position)
         },
         //自主黏贴事件:ctrl+v
@@ -242,6 +248,7 @@ export default {
             return
           } */
           if(this.choosedId!==this.pageItem.id) return
+          this.$parent.isEditTitle = false
           this.dragElement = e.currentTarget
           if(dragInfo.type!=='text'){
             //设置拖拽反馈图像
@@ -293,6 +300,7 @@ export default {
           }catch(err){
             this.$message.error(/*'复制失败'*/this.$t('MsgPrompt.copy_fail_msg'))
           }
+          this.$parent.isEditTitle = false
         },
         addChart(position){
           const {chartId} = this.pageItem.elements.find(i=>i.position===position)

+ 4 - 1
src/views/ppt_manage/newVersion/components/formatPreview/FormatPreEle.vue

@@ -31,8 +31,11 @@
   <style scoped lang="scss">
   .format-pre-wrap{
     .line{
+        width:100%;
+        height: 30%;
         img{
-            width:40%;
+            width: 50%;
+            height: 100%;
         }
     }
   }

+ 26 - 0
src/views/ppt_manage/newVersion/components/formatPreview/FormatPreThirteen.vue

@@ -0,0 +1,26 @@
+<template>
+    <div class="format-pre-wrap flex-center" style="flex-direction: column;">
+      <div class="half-top flex-center">
+        <img class="full" style="object-fit:fill !important;"
+          src="~@/assets/img/ppt_m/format-pic.png" />
+      </div>
+      <div class="half-bottom flex-center">
+        <img class="full" style="object-fit:fill !important;"
+          src="~@/assets/img/ppt_m/format-pic.png" />
+      </div>
+    </div>
+  </template>
+  
+  <script>
+  export default {
+    name: "formatPreThirteen",
+    data() {
+      return {};
+    },
+    methods: {},
+  };
+  </script>
+  
+  <style scoped lang="scss">
+  </style>
+  

+ 3 - 22
src/views/ppt_manage/newVersion/components/layer/Element/TextShape.vue

@@ -50,6 +50,7 @@
 <script>
 import {BaseTextShape} from '../../../utils/config';
 import shapeMixin from './shapeMixin';
+import tinymce from "tinymce";
 import Editor from "@tinymce/tinymce-vue";
 import "tinymce/themes/silver";
 import "tinymce/plugins/lists"; //列表插件
@@ -57,6 +58,7 @@ import "tinymce/plugins/quickbars"; //快速栏插件
 import "tinymce/plugins/fullscreen"; //全屏插件
 import "tinymce/plugins/paste"; //黏贴插件
 import "tinymce/icons/default/icons";
+import {setting} from '@/views/ppt_manage/newVersion/utils/tinymceSetting'
 export default {
   mixins:[shapeMixin],
   props:{
@@ -71,34 +73,13 @@ export default {
   data() {
     return {
       setting: {
+        ...setting,
         language: "zh_CN",
         language_url: require("../../../utils/zh_CN.js"),
-        menubar: false,
-        toolbar: [
-          "indent outdent alignleft aligncenter alignright alignjustify forecolor",
-          "bold italic underline strikethrough numlist bullist backcolor",
-          "fontselect fontsizeselect",
-        ],
-        quickbars_selection_toolbar:false,  
-        quickbars_insert_toolbar: false,
-        plugins: "lists quickbars paste",
         height: 350,
-        inline: true,
         selector: `#${this.elementInfo.id}-editorDom`,
         paste_as_text: true,
-        fontsize_formats:'12px 14px 16px 18px 20px 22px 24px 36px 48px',
-        font_formats:`微软雅黑='微软雅黑';宋体='宋体';黑体='黑体';仿宋='仿宋';
-                      楷体='楷体';隶书='隶书';幼圆='幼圆';Andale Mono=andale mono,times;
-                      Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;
-                      Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;
-                      Courier New=courier new,courier;Georgia=georgia,palatino;
-                      Helvetica=helvetica;Impact=impact,chicago;
-                      Webdings=webdings;Wingdings=wingdings`,
-        /* toolbar_persist:true,//始终显示toolbar */
         fixed_toolbar_container: ".layer-text-toolbar",//将toolbar放到指定div上
-        skin_url: "/static/css",
-        content_url: "/static/css",
-        //加placeholder
         placeholder:this.$t('Slides.click_input_text_content')
       }
     };

+ 111 - 1
src/views/ppt_manage/newVersion/css/common.scss

@@ -5,7 +5,52 @@ $titleColor:#333333;
     * {
         box-sizing: border-box;
     }
+    .el-tabs__nav-wrap::after {
+        height: 0;
+    }
+    .el-tabs__item { font-size: 16px; }
 
+    //富文本编辑器样式
+    .mce-content-body{
+        width: 100%;
+        height: 100%;
+        padding: 10px;
+        box-sizing: border-box;
+        font-size: 16px;
+        &:focus-visible{
+            outline: 0;
+        }
+        ul{
+            margin-left: 1em;
+            list-style-type: disc;
+          }
+          ol{
+            margin-left: 1em;
+            list-style-type: decimal;
+          }
+    }
+    .mce-edit-focus{
+        outline: 0;
+    }
+    .mce-content-body:not([dir=rtl])[data-mce-placeholder]:not(.mce-visualblocks)::before {
+        left:10px !important;
+    }
+    .mce-content-body.placeholder-hidden:not([dir=rtl])[data-mce-placeholder]:not(.mce-visualblocks)::before{
+        display: none;
+    }
+    .tox .tox-tbtn--bespoke .tox-tbtn__select-label{
+        width:4.5em !important;
+      }
+    .tox-menu.tox-swatches-menu.tox-selected-menu{
+        left:auto !important;
+        right:0;
+    }
+    .tox{
+        .tox-collection__group{
+            max-height: 200px;
+            overflow-y: auto;
+        }
+    }
     //wrap
     .ppt-page-wrap {
         background-color: #fff;
@@ -29,7 +74,7 @@ $titleColor:#333333;
             align-items: center;
             transform-origin: 0 0;
             word-break: break-word;
-            input{
+            input,textarea{
                 font-size: 24px;
                 color:$titleColor;
                 background: transparent;
@@ -48,6 +93,71 @@ $titleColor:#333333;
         -webkit-box-orient:vertical;
         word-break: break-word;
     }
+    .custom-title-wrap{
+        position: absolute;
+        transform-origin: 0 0;
+        &.editor-model{
+            //background-color: #99999946;
+        }
+        &.ppt-editor-title{
+            border:1px dashed #999;
+        }
+        .title{
+            width:100%;
+            height:100%;
+            font-size: 16px;
+            word-break: break-all;
+            ul{
+                margin-left: 1em;
+                list-style-type: disc;
+              }
+              ol{
+                margin-left: 1em;
+                list-style-type: decimal;
+              }
+        }
+        textarea{
+            font-size: 24px;
+            color:$titleColor;
+            background: transparent;
+            border: none;
+            width:100%;
+            height:auto;
+            /* overflow-y: hidden; */
+            resize: none;
+            &.el-textarea__inner{
+                padding:0;
+                line-height: 1;
+                /* height:auto !important; */
+                color:var(--titleColor);
+                font-size:var(--fontSize);
+                font-family: var(--fontFamily);
+            }
+        }
+        .normal-title{
+            font-size: 16px;
+            word-break: break-all;
+        }
+    }
+    .ppt-tool{
+        .layer-edit-box,.title-edit-box{
+          .tool-list{
+            border:none;
+            .el-collapse-item:first-child{
+                .el-collapse-item__content{
+                    padding-bottom: 5px;
+                }
+            }
+            .el-collapse-item__header{
+              margin-bottom: 0;
+              height: 40px;
+            }
+            .el-collapse-item__wrap{
+              overflow: visible;
+            }
+          }
+        }
+      }
 
     .hint-text {
         text-align: center;

+ 37 - 16
src/views/ppt_manage/newVersion/css/format.scss

@@ -144,7 +144,7 @@ $marginTop:14%;
       width: 100%;
       height: calc(100% - #{$marginTop});
       display: flex;
-      .chart-bottom-insruction-info{
+      .chart-bottom-insruction-info,.chart-source{
             margin-top: 0 !important;
         }
     }
@@ -172,7 +172,7 @@ $marginTop:14%;
             top:0;
             right:calc(5% - 10px);
         }
-        .chart-bottom-insruction-info{
+        .chart-bottom-insruction-info,.chart-source{
             bottom:4%;
         }
     }
@@ -196,7 +196,7 @@ $marginTop:14%;
             top:calc(10% - 10px);
             right:calc(5% - 10px);
         }
-        .chart-bottom-insruction-info{
+        .chart-bottom-insruction-info,.chart-source{
             top:89%;
         }
     }
@@ -217,7 +217,7 @@ $marginTop:14%;
           width: 100%;
           height: 80%;
         }
-        .chart-bottom-insruction-info{
+        .chart-bottom-insruction-info,.chart-source{
             top:89%;
         }
     }
@@ -242,7 +242,7 @@ $marginTop:14%;
                     top:calc(4% - 10px);
                     right:2.5%;
                 }
-                .chart-bottom-insruction-info{
+                .chart-bottom-insruction-info,.chart-source{
                     top:89%;
                 }
             }
@@ -267,7 +267,7 @@ $marginTop:14%;
                     top:0;
                     right:2.5%;
                 }
-                .chart-bottom-insruction-info{
+                .chart-bottom-insruction-info,.chart-source{
                     top:84%;
                 }
             }
@@ -284,7 +284,7 @@ $marginTop:14%;
             top:calc(10% - 10px);
             right:calc(5% - 10px);
         }
-        .chart-bottom-insruction-info{
+        .chart-bottom-insruction-info,.chart-source{
             top:90%;
         }
     }
@@ -308,7 +308,7 @@ $marginTop:14%;
                   top:calc(4% - 10px);
                   right:2.5%;
                 }
-                .chart-bottom-insruction-info{
+                .chart-bottom-insruction-info,.chart-source{
                     top:89%;
                 }
             }
@@ -334,7 +334,7 @@ $marginTop:14%;
                     top:0;
                     right:2.5%;
                 }
-                .chart-bottom-insruction-info{
+                .chart-bottom-insruction-info,.chart-source{
                     top:84%;
                 }
             }
@@ -351,25 +351,28 @@ $marginTop:14%;
             top:calc(10% - 10px);
             right:calc(5% - 10px);
         }
-        .chart-bottom-insruction-info{
+        .chart-bottom-insruction-info,.chart-source{
             top:90%;
         }
     }
 
-    //版式8 9
+    //版式8 9 13
     .wrap-full-top,.wrap-full-bottom{
       width:100%;
       height:50%;
       position:relative;
+      .chart-bottom-insruction-info{
+        top:93%;
+      }
       &.top-70{
         height:70%;
-        .chart-bottom-insruction-info{
+        .chart-bottom-insruction-info,.chart-source{
             top:93%;
         }
       }
       &.bottom-30{
         height: 30%;
-        .chart-bottom-insruction-info{
+        .chart-bottom-insruction-info,.chart-source{
             top:85%;
         }
       }
@@ -422,10 +425,28 @@ $marginTop:14%;
       }
     }
     .format-nine{
-        .chart-bottom-insruction-info{
+        .chart-bottom-insruction-info,.chart-source{
             top:93%;
         }
     }
+    .format-thirteen{
+        .wrap-full-top{
+            .chart-wrap{
+                top: 2%;
+            }
+            .chart-bottom-insruction-info{
+                top:92%;
+            }
+        }
+        .wrap-full-bottom{
+            .chart-wrap{
+                top: 0%;
+            }
+            .chart-bottom-insruction-info{
+                top:90%;
+            }
+        }
+    }
     
     //layer-mask 更改版式345 9布局, ↑原先样式保留不动
     .wrap-full-left-half{
@@ -531,7 +552,7 @@ $marginTop:14%;
                     width:90%;
                     height:90%
                 }
-                .chart-bottom-insruction-info{
+                .chart-bottom-insruction-info,.chart-source{
                     top:92%;
                 }
             }
@@ -543,7 +564,7 @@ $marginTop:14%;
         }
         .bottom-15{
             height: 18%;
-            .chart-bottom-insruction-info{
+            .chart-bottom-insruction-info,.chart-source{
                 top:80%;
             }
         }

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

@@ -272,7 +272,7 @@
           <div class="ppt-info">
             <div> {{$t('Slides.author_info')}}:{{pptItem.AdminRealName}}</div>
             <div>
-              {{pptItem.PptxUrl? $t('Slides.publish_info'):$t('Slides.save_info')}}
+              {{pptItem.PptxUrl? $t('Slides.publish_ab'):$t('Slides.save_info')}}
               {{$t('Slides.time_info')}}:{{$moment(pptItem.PptxUrl?pptItem.PublishTime || undefined:pptItem.PptModifyTime || undefined).format('YYYY-MM-DD')}}
             </div>
           </div>
@@ -569,14 +569,14 @@ export default {
         this.$nextTick(()=>{
            //选中节点
           this.$refs[`${this.treeName}Tree`].setCurrentKey(item.nodeKeyId)
-          //展开该节点的父节点
+          //找到该节点的父节点,展开,获取父节点id
           const node = this.$refs[`${this.treeName}Tree`].getCurrentNode()
           !this[`${this.treeName}ExpandKeys`].includes(node.catalogId)&&this[`${this.treeName}ExpandKeys`].push(node.catalogId)
+          this.pptItem.catalogId = node.catalogId||''
           this.selectNode = item
         })
       }else{
         //获取目录下的ppt列表:getCatalogListByGroupId/getCatalogListByAdminId
-
         const res = this.treeName==='public' 
           ? await pptInterface.getCatalogListByAdminId({ AdminId:item.AdminId||''})
           : this.treeName==='private'
@@ -771,13 +771,13 @@ export default {
             this.$refs[`${this.treeName}Tree`].setCurrentKey(data.catalogId)
             //删除的是公共目录下,某目录的最后一个PPT时,该公共目录会消失
             if(this.treeName==='public'&&catalog.PptList.length>1){
-              this.changeModel('list',catalog)
+              this.changeModel('list',catalog||{})
             }else if(this.treeName==='public'&&catalog.PptList.length===1){
               this.changeModel('list',{})
             }
             //但是私有目录不会
             if(this.treeName==='private'){
-              this.changeModel('list',catalog)
+              this.changeModel('list',catalog||{})
             }
           }
         })

+ 114 - 59
src/views/ppt_manage/newVersion/pptEditor.vue

@@ -46,7 +46,7 @@
         </div>
     </div>
     <div class="ppt-editor-wrap ppt-page-wrap" v-loading="isChartLoading" :element-loading-text="chartLoadingText">
-        <div class="ppt-editor" ref="pptEditor" @paste="handlePasteOutSide">
+        <div class="ppt-editor" id="pptEditor" ref="pptEditor" @paste="handlePasteOutSide">
             <!-- 显示全部ppt -->
             <template v-if="pageList.length">
                 <!-- <transition-group name="flip-list"> -->
@@ -54,10 +54,52 @@
                     <AddFormat @addPage="addPage($event,index)" :chooseModalId="chooseModalId"/>
                     <div class="ppt-item" :class="{'choose':currentItem.id===item.id}" 
                         v-loading="item.isUpdating" :element-loading-text="$t('Slides.updating_chart_loading')"
-                        @click="changeCurrentItem(item)">
+                        @click.stop="changeCurrentItem(item)">
                         <!-- 标题 -->
-                        <div class="title-wrap">
-                            <input type="text" :placeholder="$t('Slides.click_to_input_title')" v-model="item.title"/> 
+                        <!-- <div class="title-wrap" style="background-color: #999999;">
+                            <input type="text" placeholder="单击输入标题" v-model="item.title"/> 
+                        </div> -->
+                        <!-- 自定义标题 -->
+                        <div @click.stop
+                            :class="[
+                                'ppt-editor-title',
+                                'custom-title-wrap',
+                                currentItem.id===item.id&&isEditTitle?'editor-model':''
+                                ]" 
+                            :style="item.titleDetail?{
+                                left:item.titleDetail.left+'%',
+                                top:item.titleDetail.top+'%',
+                                width:item.titleDetail.width+'%',
+                                height:item.titleDetail.height+'%',
+                            }:{
+                                left:'10%',top:'6.6%',width:'68%',height:'5%',
+                            }">
+                            <!-- <div class="title" v-html="item.title"></div> -->
+                            <!-- <el-input type="textarea" placeholder="单击输入标题" v-model="item.title" 
+                                autosize resize="none"
+                                spellcheck="false"
+                                :style="item.titleDetail?{
+                                    color:item.titleDetail.color,
+                                    fontSize:item.titleDetail.fontSize+'px',
+                                    fontFamily:item.titleDetail.fontFamily,
+                                    '--titleColor':item.titleDetail.color,
+                                    '--fontSize':item.titleDetail.fontSize,
+                                    '--fontFamily':item.titleDetail.fontFamily,
+                                }:{ color:'#333',fontSize:'22px',fontFamily:'helvetica' }"
+                                @focus="handleEditTitle(item)"
+                                v-click-title-outside="exitEditTitle"></el-input>  -->
+                                <div contenteditable="true" spellcheck="false" 
+                                :id="`page_title__${index}`"
+                                class="title-editor"
+                                :style="item.titleDetail?{
+                                    color:item.titleDetail.color||'#333',
+                                    fontSize:(item.titleDetail.fontSize||22)+'px',
+                                    fontFamily:(item.titleDetail.fontFamily||'helvetica'),
+                                    outline:0,
+                                }:{ color:'#333',fontSize:'22px',fontFamily:'helvetica',outline:0}"
+                                    v-click-title-outside="exitEditTitle"
+                                    @click.stop="handleEditTitle(item)"
+                                    @input="(e)=>testInput(e,item)"></div>
                         </div>
                         <!-- 内容 -->
                         <component  :is="getComponentName(item.modelId)"
@@ -68,6 +110,7 @@
                                     :isCopy="true"
                                     :isAdd="true"
                                     :isEditLayer="isEditLayer"
+                                    :isEditTitle="isEditTitle"
                                     :choosedId="currentItem.id"
                                     :activeLayerEl="activeLayerEl"
                                     :amendatoryPositionInfo="item.positionInfo"
@@ -121,7 +164,7 @@
             </div>
             <div class="richtext-tool"></div>
             <!-- 防止el-tabs未渲染时触发scrollToActiveTab 报错,v-if改为v-show-->
-            <div class="addppt-right-box" v-show="!isEditLayer">
+            <div class="addppt-right-box" v-show="!isEditLayer&&!isEditTitle">
               <el-tabs v-model="tabsactive">
                 <el-tab-pane :label="tab.label" :name="tab.val" v-for="tab in panelTabs" :key="tab.val"></el-tab-pane>
               </el-tabs>
@@ -187,7 +230,7 @@
               </div>
             </div>
             <!-- 图层编辑 -->
-            <div class="layer-edit-box" v-show="isEditLayer">
+            <div class="layer-edit-box" v-if="isEditLayer">
               	<el-collapse v-model="activeNames" class="tool-list">
                   <el-collapse-item :title="$t('Slides.layer_element')" name="el">
                     <div class="el-wrap">
@@ -226,6 +269,20 @@
                   </el-collapse-item>
                 </el-collapse>
             </div>
+            <!-- 标题编辑 -->
+            <div class="title-edit-box" v-if="isEditTitle">
+                <p>
+                    {{$t('Slides.page_title_style_setting')}}
+                </p>
+                <TitleEditorTool 
+                    ref="titleEditor"
+                    :currentItem="currentItem"
+                    @changeSizeAll="changeSizeAll"
+                    @changePositionAll="changePositionAll"
+                    @styleChange="handleTitelStyleChange"
+                    @textChange="handleTextChange"
+                    @applyToAll="changeSettingAll"/>
+            </div>
           </div>
     </div>
 
@@ -280,7 +337,7 @@
 </template>
 
 <script>
-import {countComponentName,checkClipboardItems,createRandomCode,checkPPTpageElemant,getChartInfo} from './utils/untils';
+import {countComponentName,checkClipboardItems,createRandomCode,checkPPTpageElemant,getChartInfo,getPlainText} from './utils/untils';
 import {modelInfo,defaultPosition} from './utils/config'
 import http from '@/api/http.js';
 import { dataBaseInterface ,sandInterface } from "@/api/api.js";
@@ -310,6 +367,7 @@ import InsertCharts from './components/editor/InsertCharts.vue';
 import ContextMenu from './components/ContextMenu.vue';
 import InsertSemantics from './components/editor/InsertSemantics.vue';
 import ChooseCoverNew from './components/editor/ChooseCoverNew.vue';
+import TitleEditorTool from './components/editor/TitleEditorTool';
 export default {
   mixins:[pptmixin,//ppt页面共同逻辑
           mixins,//图表加载逻辑
@@ -319,7 +377,7 @@ export default {
   components: {
     IndexItem, ChooseCover, AddFormat, ShapePreview,
     LayerEditTool, DeletePageDialog, ChangeFormatDialog, InsertPageDialog, addMyClassifyDia, InsertCharts, ContextMenu, InsertSemantics,
-    ChooseCoverNew
+    ChooseCoverNew,TitleEditorTool
 },
   data() {
     return {
@@ -464,7 +522,7 @@ export default {
       //防止自动保存时,有某一页处于更新图表的状态,其isUpdating为true
       this.pageList.forEach(i=>{
         i.isUpdating = false
-      })     
+      })
       this.dataLoading.close();
       $('.ppt-item').css('background-image',`url(${this.pptBgImage})`);
       //开启自动保存
@@ -476,13 +534,14 @@ export default {
         await this.getpptDataById(id)
         const {status} = this.result
         if(status===200){
-          const {content,FirstPage,ReportId} = this.result
+          const {content,FirstPage,ReportId,TitleSetting} = this.result
           this.pageList = content
           this.firstPage = FirstPage
           this.firstPage.BackIndex = FirstPage.TemplateType-1
           this.currentItem = this.pageList[0]
           this.ReportId=ReportId
           this.CoverContent = this.result.CoverContent
+          this.titleSetting = TitleSetting||null
           /* //开启自动保存
           this.autoSave() */
         }else{
@@ -519,6 +578,7 @@ export default {
             modelId: modelId,
             title:'',
             elements: [],
+            titleDetail:this.titleSetting?this.titleSetting:null
         }
         //限制取消
         /* if(this.pageList.length>=this.maxPageNum){
@@ -742,6 +802,13 @@ export default {
         if(this.currentItem&&this.currentItem.id!==id){
           this.isEditLayer = false
           this.activeLayerEl = {}
+          
+          this.isEditTitle = false
+        }
+        //点击当前页时,退出标题编辑模式
+        if(this.currentItem&&this.currentItem.id===id){
+            this.isEditTitle = false
+            return 
         }
         this.pageList.map((item,index)=>{
           if(item.id===id){
@@ -751,9 +818,16 @@ export default {
         })
         this.$nextTick(()=>{
           let height = $('.ppt-editor-item')[0].offsetHeight
+          const index = this.currentIndex
           //pptEditor的滚动条动画
-          this.$refs.pptEditor.scrollTo({
-              top:height*this.currentIndex,
+          /* this.$refs.pptEditor.scrollTo({
+              top:height*index,
+              left:0,
+              behavior: 'smooth'
+          }) */
+          const pptEditorDom = document.getElementById('pptEditor')
+          pptEditorDom.scrollTo({
+            top:height*index,
               left:0,
               behavior: 'smooth'
           })
@@ -1049,7 +1123,8 @@ export default {
         FirstPage:FirstPage,
         Content:Content,
         GroupId:this.catalogId,
-        CoverContent:this.CoverContent
+        CoverContent:this.CoverContent,
+        TitleSetting:JSON.stringify(this.titleSetting)
       }).then(res=>{
         this.isSaved = false
         if(res.Ret===200){
@@ -1070,7 +1145,8 @@ export default {
         PptId:parseInt(ppt_id),
         FirstPage:FirstPage,
         Content:Content,
-        CoverContent:this.CoverContent
+        CoverContent:this.CoverContent,
+        TitleSetting:JSON.stringify(this.titleSetting)
       }).then(res=>{
         this.isSaved = false
         if(res.Ret===200){
@@ -1108,11 +1184,13 @@ export default {
           return i
         })
         let Content = JSON.stringify(pageList) 
+        let TitleSetting = JSON.stringify(this.titleSetting)
         pptInterface.saveLog({
           PptId:parseInt(ppt_id),
           FirstPage:FirstPage,
           Content:Content,
-          CoverContent:this.CoverContent
+          CoverContent:this.CoverContent,
+          TitleSetting,
         }).then((res)=>{
             if(res.Ret!==200) return 
             this.showLastSaveTime = true
@@ -1323,23 +1401,6 @@ export default {
 <style lang="scss">
 @import './css/common.scss';
 @import './css/format.scss';
-.page-wrap{
-  .ppt-editor-wrap{
-    .ppt-tool{
-      .layer-edit-box{
-        .tool-list{
-          .el-collapse-item__header{
-            margin-bottom: 0;
-          }
-          .el-collapse-item__wrap{
-            overflow: visible;
-          }
-        }
-      }
-    }
-  }
-}
-
 </style>
 <style scoped lang="scss">
 $titleColor:#333333;
@@ -1493,17 +1554,19 @@ $titleColor:#333333;
            min-width:320px;
            width: 320px;
            height:100%;
-           .tool-btn{
-               margin-bottom: 12px;
+           overflow-y: hidden;
+           .richtext-tool{
+            margin:10px 0;
            }
             .addppt-right-box{
               flex: 1;
-              height: calc(100% - 182px);
+             /* height: calc(100% - 182px); */
               padding: 0 10px;
-              margin-top: 12px;
               box-sizing: border-box;
-              border:1px solid #B2B9C3;
+              border: 2px solid #EBEBEB;
+              border-radius: 4px;
               min-width: 320px;
+              overflow-y: auto;
               #tabs {
                 padding: 0px 40px;
                 box-sizing: border-box;
@@ -1579,20 +1642,20 @@ $titleColor:#333333;
               }
 
 		        }
-            .layer-edit-box{
+            .layer-edit-box,.title-edit-box{
               flex: 1;
-              height: calc(100% - 182px);
+              /* height: calc(100% - 182px); */
               padding: 0 20px;
-              margin-top: 12px;
               box-sizing: border-box;
               border: 2px solid #EBEBEB;
               border-radius: 4px;
               min-width: 320px;
-              overflow-y: scroll;
+              overflow-y: auto;
               .tool-list{
                 .el-wrap{
                   display: flex;
-                  justify-content: space-between;
+                  /* justify-content: space-between; */
+                  gap: 0 15px;
                   flex-wrap: wrap;
                   .el-item{
                     border: 1px solid #DCDFE6;
@@ -1614,24 +1677,16 @@ $titleColor:#333333;
                 }
               }
             }
+            .title-edit-box{
+                display:flex;
+                flex-direction: column;
+                padding:20px;
+                p{
+                    font-size: 16px;
+                    font-weight: bold;
+                }
+            }
        }
     }
 }
 </style>
-<style lang="scss">
-.page-wrap {
-	.el-tabs__nav-wrap::after {
-		height: 0;
-	}
-	.el-tabs__item { font-size: 16px; }
-	.layer-edit-box{
-		.tool-list{
-			.el-collapse-item:first-child{
-				.el-collapse-item__content{
-					padding-bottom: 5px;
-				}
-			}
-		}
-	}
-}	
-</style>

+ 5 - 4
src/views/ppt_manage/newVersion/pptEnCatalog.vue

@@ -267,7 +267,7 @@
           <div class="ppt-info">
             <div>{{$t('Slides.author_info')}}:{{pptItem.AdminRealName}}</div>
             <div>
-              {{pptItem.PptxUrl? $t('Slides.publish_info') : $t('Slides.publish_info') }}
+              {{pptItem.PptxUrl? $t('Slides.publish_ab') : $t('Slides.save_info') }}
               {{$t('Slides.time_info')}}:{{$moment(pptItem.PptxUrl?pptItem.PublishTime || undefined:pptItem.PptModifyTime || undefined).format('YYYY-MM-DD')}}
             </div>
           </div>
@@ -545,9 +545,10 @@ export default {
         this.$nextTick(()=>{
            //选中节点
           this.$refs[`${this.treeName}Tree`].setCurrentKey(item.nodeKeyId)
-          //展开该节点的父节点
+          //找到该节点的父节点,展开,获取父节点id
           const node = this.$refs[`${this.treeName}Tree`].getCurrentNode()
           !this[`${this.treeName}ExpandKeys`].includes(node.catalogId)&&this[`${this.treeName}ExpandKeys`].push(node.catalogId)
+          this.pptItem.catalogId = node.catalogId||''
           this.selectNode = item
         })
       }else{
@@ -740,13 +741,13 @@ export default {
             this.$refs[`${this.treeName}Tree`].setCurrentKey(data.catalogId)
             //删除的是公共目录下,某目录的最后一个PPT时,该公共目录会消失
             if(this.treeName==='public'&&catalog.PptList.length>1){
-              this.changeModel('list',catalog)
+              this.changeModel('list',catalog||{})
             }else if(this.treeName==='public'&&catalog.PptList.length===1){
               this.changeModel('list',{})
             }
             //但是私有目录不会
             if(this.treeName==='private'){
-              this.changeModel('list',catalog)
+              this.changeModel('list',catalog||{})
             }
           }
         })

+ 88 - 52
src/views/ppt_manage/newVersion/pptEnEditor.vue

@@ -52,11 +52,41 @@
                 <AddFormat @addPage="addPage($event,index)" :chooseModalId="chooseModalId"/>
                 <div class="ppt-item" :class="{'choose':currentItem.id===item.id}" 
                   v-loading="item.isUpdating" :element-loading-text="$t('Slides.updating_chart_loading')"
-                  @click="changeCurrentItem(item)">
+                  @click.stop="changeCurrentItem(item)">
                     <!-- 标题 -->
-                    <div class="title-wrap" style="left:8%;width:62%;">
+                    <!-- <div class="title-wrap" style="left:8%;width:62%;">
                         <input type="text" :placeholder="$t('Slides.click_to_input_title')" v-model="item.title"/> 
-                    </div>
+                    </div> -->
+                    <!-- 自定义标题 -->
+                    <div @click.stop="handleEditTitle(item)"
+                            :class="[
+                                'ppt-editor-title',
+                                'custom-title-wrap',
+                                currentItem.id===item.id&&isEditTitle?'editor-model':''
+                                ]" 
+                            :style="item.titleDetail?{
+                                left:item.titleDetail.left+'%',
+                                top:item.titleDetail.top+'%',
+                                width:item.titleDetail.width+'%',
+                                height:item.titleDetail.height+'%',
+                            }:{
+                                left:'10%',top:'6.6%',width:'68%',height:'5%'
+                            }">
+                            <!-- <div class="title" v-html="item.title"></div> -->
+                            <!-- <div v-else class="normal-title">{{item.title}}</div> -->
+                            <div contenteditable="true" spellcheck="false" 
+                                :id="`page_title__${index}`"
+                                class="title-editor"
+                                :style="item.titleDetail?{
+                                    color:item.titleDetail.color||'#333',
+                                    fontSize:(item.titleDetail.fontSize||22)+'px',
+                                    fontFamily:(item.titleDetail.fontFamily||'helvetica'),
+                                    outline:0,
+                                }:{ color:'#333',fontSize:'22px',fontFamily:'helvetica',outline:0}"
+                                    v-click-title-outside="exitEditTitle"
+                                    @click.stop="handleEditTitle(item)"
+                                    @input="(e)=>testInput(e,item)"></div>
+                        </div>
                     <!-- 内容 -->
                     <component  :is="getComponentName(item.modelId)"
                                 :ref="`pptPage_${index}`"
@@ -64,6 +94,7 @@
                                 :pageItem="item"
                                 :key="item.key"
                                 :isEditLayer="isEditLayer"
+                                :isEditTitle="isEditTitle"
                                 :choosedId="currentItem.id"
                                 :activeLayerEl="activeLayerEl"
                                 :isCopy="true"
@@ -117,7 +148,7 @@
                 <el-button type="text" @click="handleChangeEditModal"><i class="el-icon-sort" style="transform: rotate(90deg);margin-right:5px;"></i>{{isEditLayer? $t('Slides.ppt_edit_btn'):$t('Slides.layer_editing')}}</el-button>
             </div>
             <div class="richtext-tool"></div>
-            <div class="addppt-right-box" v-show="!isEditLayer">
+            <div class="addppt-right-box" v-show="!isEditLayer&&!isEditTitle">
 
               <el-tabs v-model="tabsactive">
                 <el-tab-pane :label="tab.label" :name="tab.val" v-for="tab in panelTabs" :key="tab"></el-tab-pane>
@@ -226,6 +257,18 @@
                   </el-collapse-item>
                 </el-collapse>
             </div>
+            <!-- 标题编辑 -->
+            <div class="title-edit-box" v-if="isEditTitle">
+                <p>{{$t('Slides.page_title_style_setting')}}</p>
+                <TitleEditorTool 
+                    ref="titleEditor"
+                    :currentItem="currentItem"
+                    @changeSizeAll="changeSizeAll"
+                    @changePositionAll="changePositionAll"
+                    @styleChange="handleTitelStyleChange"
+                    @textChange="handleTextChange"
+                    @applyToAll="changeSettingAll"/>
+            </div>
           </div>
     </div>
 
@@ -322,6 +365,7 @@ import setEnNameDia from '@/views/dataEntry_manage/components/setEnNameDia.vue';
 import ContextMenu from './components/ContextMenu.vue';
 import InsertSemantics from './components/editor/InsertSemantics.vue';
 import ChooseCoverNew from './components/editor/ChooseCoverNew.vue';
+import TitleEditorTool from './components/editor/TitleEditorTool';
 export default {
   mixins:[pptmixin,//ppt页面共同逻辑
           mixins,//图表加载逻辑
@@ -342,7 +386,8 @@ export default {
     InsertCharts,
     ContextMenu,
     InsertSemantics,
-    ChooseCoverNew
+    ChooseCoverNew,
+    TitleEditorTool
   },
   data() {
     return {
@@ -495,13 +540,14 @@ export default {
         await this.getpptDataById(id)
         const {status} = this.result
         if(status===200){
-          const {content,FirstPage,ReportId} = this.result
+          const {content,FirstPage,ReportId,TitleSetting} = this.result
           this.pageList = content
           this.firstPage = FirstPage
           this.firstPage.BackIndex = FirstPage.TemplateType-1
           this.currentItem = this.pageList[0]
           this.ReportId=ReportId
           this.CoverContent = this.result.CoverContent
+          this.titleSetting = TitleSetting||null
           /* //开启自动保存
           this.autoSave() */
         }else{
@@ -538,6 +584,7 @@ export default {
             modelId: modelId,
             title:'',
             elements: [],
+            titleDetail:this.titleSetting?this.titleSetting:null
         }
         this.pageList.splice(index,0,page)
         this.changeCurrentItem(page)
@@ -745,6 +792,13 @@ export default {
         if(this.currentItem&&this.currentItem.id!==id){
           this.isEditLayer = false
           this.activeLayerEl = {}
+
+          this.isEditTitle = false
+        }
+        //点击当前页时,退出标题编辑模式
+        if(this.currentItem&&this.currentItem.id===id){
+            this.isEditTitle = false
+            return 
         }
         this.pageList.map((item,index)=>{
           if(item.id===id){
@@ -1043,7 +1097,8 @@ export default {
         FirstPage:FirstPage,
         Content:Content,
         GroupId:this.catalogId,
-        CoverContent:this.CoverContent
+        CoverContent:this.CoverContent,
+        TitleSetting:JSON.stringify(this.titleSetting)
       }).then(res=>{
         this.isSaved = false
         if(res.Ret===200){
@@ -1062,7 +1117,8 @@ export default {
         PptId:parseInt(ppt_id),
         FirstPage:FirstPage,
         Content:Content,
-        CoverContent:this.CoverContent
+        CoverContent:this.CoverContent,
+        TitleSetting:JSON.stringify(this.titleSetting)
       }).then(res=>{
         this.isSaved = false
         if(res.Ret===200){
@@ -1094,11 +1150,13 @@ export default {
           return i
         })
         let Content = JSON.stringify(pageList) 
+        let TitleSetting = JSON.stringify(this.titleSetting)
         pptEnInterface.saveLog({
           PptId:parseInt(ppt_id),
           FirstPage:FirstPage,
           Content:Content,
-          CoverContent:this.CoverContent
+          CoverContent:this.CoverContent,
+          TitleSetting,
         }).then((res)=>{
             if(res.Ret!==200) return 
             this.showLastSaveTime = true
@@ -1309,23 +1367,6 @@ export default {
 <style lang="scss">
 @import './css/common.scss';
 @import './css/format.scss';
-.page-wrap{
-  .ppt-editor-wrap{
-    .ppt-tool{
-      .layer-edit-box{
-        .tool-list{
-          .el-collapse-item__header{
-            margin-bottom: 0;
-          }
-          .el-collapse-item__wrap{
-            overflow: visible;
-          }
-        }
-      }
-    }
-  }
-}
-
 </style>
 <style scoped lang="scss">
 $titleColor:#333333;
@@ -1480,17 +1521,19 @@ $titleColor:#333333;
            min-width:320px;
            width: 320px;
            height:100%;
-           .tool-btn{
-               margin-bottom: 12px;
+           overflow-y: hidden;
+           .richtext-tool{
+            margin:10px 0;
            }
             .addppt-right-box{
               flex: 1;
-              height: calc(100% - 182px);
+              /* height: calc(100% - 182px); */
               padding: 0 10px;
-              margin-top: 12px;
               box-sizing: border-box;
-              border:1px solid #B2B9C3;
+              border:2px solid #EBEBEB;
+              border-radius: 4px;
               min-width: 320px;
+              overflow-y: auto;
               #tabs {
                 padding: 0px 40px;
                 box-sizing: border-box;
@@ -1578,20 +1621,21 @@ $titleColor:#333333;
               }
 
 		        }
-            .layer-edit-box{
+            .layer-edit-box,.title-edit-box{
               flex: 1;
-              height: calc(100% - 182px);
+              /* height: calc(100% - 182px); */
               padding: 0 20px;
               margin-top: 12px;
               box-sizing: border-box;
               border: 2px solid #EBEBEB;
               border-radius: 4px;
               min-width: 320px;
-              overflow-y: scroll;
+              overflow-y: auto;
               .tool-list{
                 .el-wrap{
                   display: flex;
-                  justify-content: space-between;
+                  /* justify-content: space-between; */
+                  gap:0 15px;
                   flex-wrap: wrap;
                   .el-item{
                     border: 1px solid #DCDFE6;
@@ -1613,24 +1657,16 @@ $titleColor:#333333;
                 }
               }
             }
+            .title-edit-box{
+                display:flex;
+                flex-direction: column;
+                padding:20px;
+                p{
+                    font-size: 16px;
+                    font-weight: bold;
+                }
+            }
        }
     }
 }
 </style>
-<style lang="scss">
-.page-wrap {
-	.el-tabs__nav-wrap::after {
-		height: 0;
-	}
-	.el-tabs__item { font-size: 16px; }
-	.layer-edit-box{
-		.tool-list{
-			.el-collapse-item:first-child{
-				.el-collapse-item__content{
-					padding-bottom: 5px;
-				}
-			}
-		}
-	}
-}	
-</style>

+ 42 - 2
src/views/ppt_manage/newVersion/pptEnPresent.vue

@@ -49,7 +49,7 @@
             </div>
             <!-- PPT内容 -->
               <div class="ppt-item" v-else>
-                <div class="title-wrap" 
+                <!-- <div class="title-wrap" 
                     :title="currentItem.title" 
                     :style="`
                         top:${lineClamp===2?'2%':getStrCount(currentItem.title)<52?'4.5%':'0'};
@@ -57,6 +57,23 @@
                         -webkit-line-clamp:${lineClamp===2?2:3};`" 
                     :class="{'title-ellipsis':getStrCount(currentItem.title)>lineClamp*50}">
                   {{currentItem.title}}
+                </div> -->
+                 <!-- 自定义标题 -->
+                 <div class="custom-title-wrap editor-content" 
+                    :style="currentItem.titleDetail?{
+                        left:(currentItem.titleDetail.baseLeft||90)*contentScale+'px',
+                        top:(currentItem.titleDetail.baseTop||40.9)*contentScale+'px',
+                        width:(currentItem.titleDetail.baseWidth||612)+'px',
+                        height:(currentItem.titleDetail.baseHeight||30.9)+'px',
+                    }:{
+                        left:90*contentScale+'px',top:40.9*contentScale+'px',width:'612px',height:'30.9px'
+                    }">
+                        <div class="title" v-html="currentItem.title"
+                        :style="currentItem.titleDetail?{
+                            color:currentItem.titleDetail.color||'#333',
+                            fontSize:(currentItem.titleDetail.fontSize||22)+'px',
+                            fontFamily:currentItem.titleDetail.fontFamily||'helvetica'
+                        }:{ color:'#333',fontSize:'22px',fontFamily:'helvetica' }"></div>
                 </div>
                 <component
                   :ref="`pptPage_${currentIndex-1}`" 
@@ -108,7 +125,7 @@
             </div>
             <!-- PPT内容 -->
               <div class="ppt-item" v-else>
-                <div class="title-wrap" 
+                <!-- <div class="title-wrap" 
                     :title="currentItem.title" 
                     :style="`
                         top:${lineClamp===2?'2%':'0'};
@@ -116,6 +133,23 @@
                         -webkit-line-clamp:${lineClamp===2?2:3};`" 
                     :class="{'title-ellipsis':getStrCount(currentItem.title)>lineClamp*57}">
                   {{currentItem.title}}
+                </div> -->
+                <!-- 自定义标题 -->
+                <div class="custom-title-wrap editor-content" 
+                    :style="currentItem.titleDetail?{
+                        left:(currentItem.titleDetail.baseLeft||90)*contentScale+'px',
+                        top:(currentItem.titleDetail.baseTop||43.39)*contentScale+'px',
+                        width:(currentItem.titleDetail.baseWidth||612)+'px',
+                        height:(currentItem.titleDetail.baseHeight||30.9)+'px',
+                    }:{
+                        left:90*contentScale+'px',top:43.39*contentScale+'px',width:'612px',height:'30.9px'
+                    }">
+                        <div class="title" v-html="currentItem.title"
+                        :style="currentItem.titleDetail?{
+                            color:currentItem.titleDetail.color||'#333',
+                            fontSize:(currentItem.titleDetail.fontSize||22)+'px',
+                            fontFamily:currentItem.titleDetail.fontFamily||'helvetica'
+                        }:{ color:'#333',fontSize:'22px',fontFamily:'helvetica' }"></div>
                 </div>
                 <component
                   :ref="`pptPage_${currentIndex-1}`" 
@@ -307,6 +341,12 @@ export default {
         const sheetElements = this.pageList[i].elements.filter((item)=>{
           return item.type === 'sheet'
         })
+        if(this.pageList[i].titleDetail){
+            this.pageList[i].titleDetail = {
+                ...this.pageList[i].titleDetail,
+                ...this.getBasePosition(this.pageList[i].titleDetail)
+            }
+        }
         this.listHandle(chartElements,'present');
         this.sheetListHandle(sheetElements);
       }

+ 37 - 10
src/views/ppt_manage/newVersion/pptEnPublish.vue

@@ -35,8 +35,25 @@
           </div>
           <!-- 内容 -->
           <div class="ppt-item" v-for="(item,index) in pageList" :key="item.id">
-            <div class="title-wrap">
+            <!-- <div class="title-wrap">
               {{item.title}} 
+            </div> -->
+            <!-- 自定义标题 -->
+            <div class="custom-title-wrap content" 
+                :style="item.titleDetail?{
+                    left:(item.titleDetail.baseLeft||90)*contentScale+'px',
+                    top:(item.titleDetail.baseTop||40.9)*contentScale+'px',
+                    width:(item.titleDetail.baseWidth||612)+'px',
+                    height:(item.titleDetail.baseHeight||30.9)+'px',
+                }:{
+                    left:90*contentScale+'px',top:40.9*contentScale+'px',width:'612px',height:'30.9px'
+                }">
+                <div class="title" v-html="item.title"
+                :style="item.titleDetail?{
+                    color:item.titleDetail.color||'#333',
+                    fontSize:(item.titleDetail.fontSize||22)+'px',
+                    fontFamily:item.titleDetail.fontFamily||'helvetica'
+                }:{ color:'#333',fontSize:'22px',fontFamily:'helvetica' }"></div>
             </div>
             <component
               :is="getComponentName(item.modelId)"
@@ -182,6 +199,12 @@ export default {
         //获取已加载图表的信息
         let chartInfoMap = {}
         for(let i=0;i<this.pageList.length;i++){
+            if(this.pageList[i].titleDetail){
+                this.pageList[i].titleDetail = {
+                    ...this.pageList[i].titleDetail,
+                    ...this.getBasePosition(this.pageList[i].titleDetail)
+                }
+            }
           this.pageList[i].elements.forEach(item=>{
             if(item.type==='chart'){
               let temp = getChartInfo(this.optionMap[item.chartId])
@@ -263,7 +286,7 @@ export default {
       let pptx = pptConfigInit(new pptxgen(),this.LayoutType,'en',SlideMaster,this.pptBgImage)
       //添加封面
       let cover = pptx.addSlide()
-      let coverId = this.loadingAll?'cover':'changecover'
+      let coverId = 'cover'
       //let coverImg = await this.htmlToCanvans(coverId)
       let coverImg = $(`#${coverId} .cover img`)[0].src
       cover.addImage({
@@ -279,18 +302,19 @@ export default {
       const length = this.pageList.length;
       for (let i = 0; i < length; i++) {
         let slide = pptx.addSlide({ masterName: pptSlideMaster.title });
-        slide.addText(this.pageList[i].title, {
+        /* slide.addText(this.pageList[i].title, {
           placeholder:"slideTitle",
           x:'8%',
           y:'5.5%',
           w:'62%',
           h:'7%',
           color:'333333'
-        });
+        }); */
+        slide = this.setPPTTitle(slide,this.pageList[i])
         const elements = this.pageList[i].elements;
         const elLength = elements.length;
         for (let j = 0; j < elLength; j++) {
-          let imgData = null,textData = null,imgData2 = null,imgData2Obj=null,sheetData=null
+          let imgData = null,textData = null,imgData2 = null,imgData2Obj=null,sheetData={list:null,otherParams:null}
           if (elements[j].type === "chart") {
             console.log("img/chart...");
             let svgData = this.optionMap[this.pageList[i].elements[j].chartId] instanceof Object
@@ -315,7 +339,8 @@ export default {
           }else if (elements[j].type==='sheet'){
             console.log('table...')
             const sheetId = elements[j].sheetId
-            sheetData = getTableData(this.sheetDataMap[sheetId])
+            sheetData.list = getTableData(this.sheetDataMap[sheetId].list)
+            sheetData.otherParams = this.sheetDataMap[sheetId].otherParams
           }
           const { x, y, width, height } = this.getPosition(
             this.pageList[i].modelId,
@@ -332,7 +357,7 @@ export default {
               });
 
             //追加生成图表底部文字
-            this.transChartBottomInfo(slide,{x,y,width,height},this.optionMap[this.pageList[i].elements[j].chartId])
+            this.transBottomInfo(slide,{x,y,width,height},this.optionMap[this.pageList[i].elements[j].chartId])
             
           }else if (textData){
             slide.addText(textData,{
@@ -360,10 +385,12 @@ export default {
               h:offsetY===0?height:(realSize.height/imgData2Obj.imgHeight*percentHeight)+'%',
               size:{type:"contain"}
             })
-          }else if(sheetData){
-            slide.addTable(sheetData,{
+          }else if(sheetData.list){
+            slide.addTable(sheetData.list,{
               x:x,y:y,w:width,h:height,border:{type:'solid',pt:1}
             })
+            //追加生成表格底部文字
+            this.transBottomInfo(slide,{x,y,width,height},sheetData.otherParams)
           } 
         }
         //在添加完版式后,添加图层元素
@@ -401,7 +428,7 @@ export default {
       //添加封底 如果有
       if(this.pptBackImage.length){
         let back = pptx.addSlide()
-        let backId = this.loadingAll?'back':'changeback'
+        let backId = 'back'
         let backImg = $(`#${backId} img`)[0].src
         back.addImage({
             path: backImg,

+ 42 - 2
src/views/ppt_manage/newVersion/pptPresent.vue

@@ -49,7 +49,7 @@
             </div>
             <!-- PPT内容 -->
               <div class="ppt-item" v-else>
-                <div class="title-wrap" 
+                <!-- <div class="title-wrap" 
                     :title="currentItem.title" 
                     :style="`
                         top:${lineClamp===2?'2%':getStrCount(currentItem.title)<58?'5.5%':'0'};
@@ -57,6 +57,23 @@
                         -webkit-line-clamp:${lineClamp===2?2:3};`" 
                     :class="{'title-ellipsis':getStrCount(currentItem.title)>lineClamp*57}">
                   {{currentItem.title}}
+                </div> -->
+                <!-- 自定义标题 -->
+                <div class="custom-title-wrap editor-content" 
+                    :style="currentItem.titleDetail?{
+                        left:(currentItem.titleDetail.baseLeft||90)*contentScale+'px',
+                        top:(currentItem.titleDetail.baseTop||40.9)*contentScale+'px',
+                        width:(currentItem.titleDetail.baseWidth||612)+'px',
+                        height:(currentItem.titleDetail.baseHeight||30.9)+'px',
+                    }:{
+                        left:90*contentScale+'px',top:40.9*contentScale+'px',width:'612px',height:'30.9px'
+                    }">
+                        <div class="title" v-html="currentItem.title"
+                        :style="currentItem.titleDetail?{
+                            color:currentItem.titleDetail.color||'#333',
+                            fontSize:(currentItem.titleDetail.fontSize||22)+'px',
+                            fontFamily:currentItem.titleDetail.fontFamily||'helvetica'
+                        }:{ color:'#333',fontSize:'22px',fontFamily:'helvetica' }"></div>
                 </div>
                 <component
                   :ref="`pptPage_${currentIndex-1}`" 
@@ -108,7 +125,7 @@
             </div>
             <!-- PPT内容 -->
               <div class="ppt-item" v-else>
-                <div class="title-wrap" 
+                <!-- <div class="title-wrap" 
                     :title="currentItem.title" 
                     :style="`
                         top:${lineClamp===2?'2%':getStrCount(currentItem.title)<58?'5.5%':'0'};
@@ -116,6 +133,23 @@
                         -webkit-line-clamp:${lineClamp===2?2:3};`" 
                     :class="{'title-ellipsis':getStrCount(currentItem.title)>lineClamp*57}">
                   {{currentItem.title}}
+                </div> -->
+                <!-- 自定义标题 -->
+                <div class="custom-title-wrap editor-content" 
+                    :style="currentItem.titleDetail?{
+                        left:(currentItem.titleDetail.baseLeft||90)*contentScale+'px',
+                        top:(currentItem.titleDetail.baseTop||40.9)*contentScale+'px',
+                        width:(currentItem.titleDetail.baseWidth||612)+'px',
+                        height:(currentItem.titleDetail.baseHeight||30.9)+'px',
+                    }:{
+                        left:90*contentScale+'px',top:40.9*contentScale+'px',width:'612px',height:'30.9px'
+                    }">
+                        <div class="title" v-html="currentItem.title"
+                        :style="currentItem.titleDetail?{
+                            color:currentItem.titleDetail.color||'#333',
+                            fontSize:(currentItem.titleDetail.fontSize||22)+'px',
+                            fontFamily:currentItem.titleDetail.fontFamily||'helvetica'
+                        }:{ color:'#333',fontSize:'22px',fontFamily:'helvetica' }"></div>
                 </div>
                 <component
                   :ref="`pptPage_${currentIndex-1}`" 
@@ -307,6 +341,12 @@ export default {
         const sheetElements = this.pageList[i].elements.filter((item)=>{
           return item.type === 'sheet'
         })
+        if(this.pageList[i].titleDetail){
+            this.pageList[i].titleDetail = {
+                ...this.pageList[i].titleDetail,
+                ...this.getBasePosition(this.pageList[i].titleDetail)
+            }
+        }
         this.listHandle(chartElements,'present');
         this.sheetListHandle(sheetElements);
       }

+ 37 - 15
src/views/ppt_manage/newVersion/pptPublish.vue

@@ -36,13 +36,30 @@
           </div>
           <!-- 内容 -->
           <div class="ppt-item" v-for="(item,index) in pageList" :key="item.id">
-            <div class="title-wrap"
+            <!-- <div class="title-wrap"
             :style="`
                 top:${lineClamp===2?'2%':getStrCount(item.title)<58?'5.5%':'0'};
                 height:${lineClamp===2?'12%':getStrCount(item.title)<58?'7%':'14%'};
                 -webkit-line-clamp:${lineClamp===2?2:3};`" 
             :class="{'title-ellipsis':getStrCount(item.title)>lineClamp*57}">
               {{item.title}} 
+            </div> -->
+            <!-- 自定义标题 -->
+            <div class="custom-title-wrap content" 
+                :style="item.titleDetail?{
+                    left:(item.titleDetail.baseLeft||90)*contentScale+'px',
+                    top:(item.titleDetail.baseTop||40.9)*contentScale+'px',
+                    width:(item.titleDetail.baseWidth||612)+'px',
+                    height:(item.titleDetail.baseHeight||30.9)+'px',
+                }:{
+                    left:90*contentScale+'px',top:40.9*contentScale+'px',width:'612px',height:'30.9px'
+                }">
+                <div class="title" v-html="item.title"
+                :style="item.titleDetail?{
+                    color:item.titleDetail.color||'#333',
+                    fontSize:(item.titleDetail.fontSize||22)+'px',
+                    fontFamily:item.titleDetail.fontFamily||'helvetica'
+                }:{ color:'#333',fontSize:'22px',fontFamily:'helvetica' }"></div>
             </div>
             <component
               :is="getComponentName(item.modelId)"
@@ -78,7 +95,6 @@ import {countComponentName,pptConfigInit,toTextProps,toJson,svg2Base64,svgData2B
 import {marginTop,modelConfig,pptSlideMaster} from './utils/config';
 import pptmixin from '../mixins/pptMixins';
 import mixins from '../mixins/mixins';
-import virtualScroll from '../mixins/virtualScrollMixins'
 import html2canvas from 'html2canvas';
 import pptxgen from "pptxgenjs";
 import moment from 'moment';
@@ -92,7 +108,7 @@ HightchartsExport(Highcharts)
 HighchartszhCN(Highcharts)
 export default {
   components: {Cover,TransReport,CustomCover},
-  mixins:[pptmixin,mixins,virtualScroll],
+  mixins:[pptmixin,mixins],
   data() {
     return {
         coverInfo:{
@@ -204,6 +220,12 @@ export default {
          //获取已加载图表的信息
         let chartInfoMap = {}
         for(let i=0;i<this.pageList.length;i++){
+            if(this.pageList[i].titleDetail){
+                this.pageList[i].titleDetail = {
+                    ...this.pageList[i].titleDetail,
+                    ...this.getBasePosition(this.pageList[i].titleDetail)
+                }
+            }
           this.pageList[i].elements.forEach(item=>{
             if(item.type==='chart'){
               let temp = getChartInfo(this.optionMap[item.chartId])
@@ -215,11 +237,7 @@ export default {
 
         this.dataLoading.close();
         $('.ppt-item').css('background-image',`url(${this.pptBgImage})`);
-      }else{
-        await this.getpptData();
-        this.initVirtualScroll()
       }
-      //console.log($('#back img')[0].src)
     },
     async getpptData(){
       const {id} = this.$route.query
@@ -289,7 +307,7 @@ export default {
       let pptx = pptConfigInit(new pptxgen(),this.LayoutType,'ch',SlideMaster,this.pptBgImage)
       //添加封面
       let cover = pptx.addSlide()
-      let coverId = this.loadingAll?'cover':'changecover'
+      let coverId = 'cover'
       let coverImg = $(`#${coverId} .cover img`)[0].src
       cover.addImage({
         path: coverImg,
@@ -304,18 +322,19 @@ export default {
       const length = this.pageList.length;
       for (let i = 0; i < length; i++) {
         let slide = pptx.addSlide({ masterName: pptSlideMaster.title });
-        slide.addText(this.pageList[i].title, {
+        /* slide.addText(this.pageList[i].title, {
           placeholder:"slideTitle",
           x:'10%',
           y:'5.5%',
           w:'68%',
           h:'7%',
           color:'333333'
-        });
+        }); */
+        slide = this.setPPTTitle(slide,this.pageList[i])
         const elements = this.pageList[i].elements;
         const elLength = elements.length;
         for (let j = 0; j < elLength; j++) {
-          let imgData = null,textData = null,imgData2 = null,imgData2Obj=null,sheetData=null
+          let imgData = null,textData = null,imgData2 = null,imgData2Obj=null,sheetData={list:null,otherParams:null}
           if (elements[j].type === "chart") {
             console.log("img/chart...");
             let svgData = this.optionMap[this.pageList[i].elements[j].chartId] instanceof Object
@@ -345,7 +364,8 @@ export default {
           }else if (elements[j].type==='sheet'){
             console.log('table...')
             const sheetId = elements[j].sheetId
-            sheetData = getTableData(this.sheetDataMap[sheetId])
+            sheetData.list = getTableData(this.sheetDataMap[sheetId].list)
+            sheetData.otherParams = this.sheetDataMap[sheetId].otherParams
           }
           const { x, y, width, height } = this.getPosition(
             this.pageList[i].modelId,
@@ -362,7 +382,7 @@ export default {
               });
 
             //追加生成图表底部文字
-            this.transChartBottomInfo(slide,{x,y,width,height},this.optionMap[this.pageList[i].elements[j].chartId])
+            this.transBottomInfo(slide,{x,y,width,height},this.optionMap[this.pageList[i].elements[j].chartId])
           }else if (textData){
             slide.addText(textData,{
               x:x,
@@ -391,9 +411,11 @@ export default {
               size:{type:"contain"}
             })
           }else if(sheetData){
-            slide.addTable(sheetData,{
+            slide.addTable(sheetData.list,{
               x:x,y:y,w:width,h:height,border:{type:'solid',pt:1}
             })
+            //追加生成表格底部文字
+            this.transBottomInfo(slide,{x,y,width,height},sheetData.otherParams)
           } 
         }
         //在添加完版式后,添加图层元素
@@ -432,7 +454,7 @@ export default {
       //添加封底 如果有
       if(this.pptBackImage.length){
         let back = pptx.addSlide()
-        let backId = this.loadingAll?'back':'changeback'
+        let backId = 'back'
         let backImg = $(`#${backId} img`)[0].src
         back.addImage({
             path: backImg,

+ 36 - 5
src/views/ppt_manage/newVersion/utils/config.js

@@ -93,6 +93,9 @@ export const formatPre = [{
     },{
         modelId:12,
         text:'上6图'
+    },{
+        modelId:13,
+        text:'xxx'
     }
 ]
 //版式id对应组件名
@@ -108,7 +111,8 @@ export const modelMap = {
     9: 'Nine',
     10:'Ten',
     11:'Ele',
-    12:'Twelve'
+    12:'Twelve',
+    13:'Thirteen'
 }
 //版式信息,用于判断图表/文字插入哪个位置
 export const modelInfo = {
@@ -205,6 +209,13 @@ export const modelInfo = {
         elTextNum:1,
         elTextPosition: 7
     },
+    13:{
+        elNum:2,
+        elType:['chart','chart'],
+        positions:[1,2],
+        elChartNum:2,
+        elTextNum:0
+    }
 }
 
 //给标题预留的位置,单位%
@@ -512,6 +523,22 @@ export const modelConfig = [{
             x:0,
             y:74
         }]
+    },{
+        modelId:13,
+        elements:[{
+            position:1,
+            width:100,
+            height:(restHeight)*0.5*0.9,
+            x:0,
+            y:(restHeight*0.5-restHeight*0.5*0.9)/2
+        },
+        {
+            position:2,
+            width:100,
+            height:(restHeight)*0.5*0.9,
+            x:0,
+            y:(restHeight)*0.5
+        }]
     }
 ]
 //ppt母版
@@ -519,7 +546,7 @@ export const pptSlideMaster = {
 	title: "幻灯片母版",
 	objects: [
 		{
-			placeholder: {
+			/* placeholder: {
 				options: {
 					name: "slideTitle",
 					type: "title",
@@ -532,7 +559,7 @@ export const pptSlideMaster = {
                     valign:'middle',
 					fontSize:24*0.75,
 				},
-			},
+			}, */
 		},
 		{
 			image: {
@@ -551,7 +578,7 @@ export const pptSlideMasterEn = {
   title: "幻灯片母版",
 	objects: [
 		{
-			placeholder: {
+			/* placeholder: {
 				options: {
 					name: "slideTitle",
 					type: "title",
@@ -564,7 +591,7 @@ export const pptSlideMasterEn = {
                     valign:'middle',
 					fontSize:24*0.75,
 				},
-			},
+			}, */
 		},
 		{
 			image: {
@@ -809,6 +836,10 @@ export const defaultPosition = {
     6:{type:'chart'},
     7:{type:'text'}
   },
+  13:{
+    1:{type:'chart'},
+    2:{type:'chart'}
+  }
 }
 //画笔工具栏
 export const boardTool = [

+ 146 - 0
src/views/ppt_manage/newVersion/utils/tinymceSetting.js

@@ -0,0 +1,146 @@
+export const setting = {
+    menubar: false,
+    toolbar: [
+        "indent outdent alignleft aligncenter alignright alignjustify forecolor",
+        "bold italic underline strikethrough numlist bullist backcolor",
+        "fontselect fontsizeselect",
+    ],
+    quickbars_selection_toolbar:false,  
+    quickbars_insert_toolbar: false,
+    plugins: "lists quickbars paste",
+    paste_as_text: true,
+    fontsize_formats:'6px 8px 10px 12px 14px 16px 18px 20px 22px 24px 36px 48px',
+    font_formats:`微软雅黑='微软雅黑';宋体='宋体';黑体='黑体';仿宋='仿宋';
+            楷体='楷体';隶书='隶书';幼圆='幼圆';Andale Mono=andale mono,times;
+            Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;
+            Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;
+            Courier New=courier new,courier;Georgia=georgia,palatino;
+            Helvetica=helvetica;Impact=impact,chicago;
+            Webdings=webdings;Wingdings=wingdings`,
+    skin_url: "/static/css",
+    content_url: "/static/css",
+    inline: true,//启动内联模式,否则会以iframe的形式渲染
+    setup:function(editor){
+        editor.on('ExecCommand',function(evt) {
+            let cmd = evt.command; 
+            //设置ul/ol li的字体大小,颜色
+            if (cmd === 'FontSize' || cmd === 'FontName' /* || cmd === 'mceApplyTextcolor' */) {
+                let val = evt.value; 
+                let node = evt.target.selection.getNode(); 
+                let nodeParent = node.parentNode; 
+                if (node.nodeName === 'SPAN' && nodeParent.nodeName === 'LI') {
+                    if (cmd === 'FontSize') { 
+                        editor.dom.setStyle(nodeParent, 'font-size', val); 
+                    } 
+                    if (cmd === 'FontName') { 
+                        editor.dom.setStyle(nodeParent, 'font-family', val); 
+                    } 
+                    /* if (cmd === 'mceApplyTextcolor') {
+                        editor.dom.setStyle(nodeParent,'color',val)
+                    } */
+                } else if (node.nodeName === 'UL' || node.nodeName === 'OL') { 
+                    let li = editor.dom.select('li', node); 
+                    if (cmd === 'FontSize') { 
+                        editor.dom.setStyle(li, 'font-size', val); 
+                    } 
+                    if (cmd === 'FontName') { 
+                        editor.dom.setStyle(li, 'font-family', val); 
+                    }
+                    /* if (cmd === 'mceApplyTextcolor') {
+                        editor.dom.setStyle(li,'color',val)
+                    } */
+                } 
+            }
+        });
+        //中文输入法和placeholder并存的问题
+        editor.on('input',function(){
+            let content = editor.getContent()
+            if(content){
+                editor.getBody().classList.add('placeholder-hidden')
+            }else{
+                editor.getBody().classList.remove('placeholder-hidden')
+            }
+        })
+    }
+}
+
+export const fontSizeList = [
+    {
+        label:'14px',
+        value:14,
+    },{
+        label:'16px',
+        value:16,
+    },
+    {
+        label:'18px',
+        value:18,
+    },
+    {
+        label:'20px',
+        value:20,
+    },{
+        label:'22px',
+        value:22,
+    },{
+        label:'24px',
+        value:24,
+    },
+    {
+        label:'26px',
+        value:26,
+    },{
+        label:'28px',
+        value:28,
+    },
+    {
+        label:'36px',
+        value:36,
+    },
+    {
+        label:'48px',
+        value:48,
+    },
+]
+export const fontFamily = [
+    {
+        label:'Helvetica',
+        value:'helvetica',
+    },
+    {
+        label:'Arial',
+        value:'arial,helvetica,sans-serif',
+    },
+    {
+        label:'Georgia',
+        value:'Georgia,serif',
+    },
+    {
+        label:'Impact',
+        value:'impact,chicago',
+    },
+    {
+        label:'Tahoma',
+        value:'Tahoma,Geneva,sans-serif',
+    },
+    {
+        label:'Times New Roman',
+        value:"Times New Roman',Times,serif",
+    },
+    {
+        label:'Verdana',
+        value:'Verdana,Geneva,sans-serif',
+    },
+    {
+        label:'思源宋体',
+        value:'思源宋体'
+    },
+    {
+        label:'思源黑体',
+        value:'思源黑体'
+    }
+]
+export const titleDefault = {
+    top:6.6,left:10,width:68,height:5,
+    color:'#333',fontFamily:'helvetica',fontSize:22,
+}

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

@@ -355,6 +355,9 @@ export const getTextContentSize = (model,position)=>{
             6:[1,1,0.33,1,0.9],
             7:[1,1,0.9],
         },
+        13:{
+            1:[],2:[]
+        }
     }
     const modelMapHeight = {
         1:{
@@ -409,6 +412,9 @@ export const getTextContentSize = (model,position)=>{
             6:[0.86,0.4,1,0.9],
             7:[0.86,0.18,0.8],
         },
+        13:{
+            1:[],2:[]
+        }
     }
     const baseWidth=900,baseHeight=630
     const width = modelMapWidth[model][position].reduce((pre,curr)=>{
@@ -727,3 +733,11 @@ export const isShowPPTTitle = (Source,MyChartType)=>{
     const sense_2 = [2,5,6,7,8,9].includes(Source)
     return sense_1||sense_2
 }
+
+//获取富文本字符串的纯文本
+export const getPlainText = (richText='')=>{
+    let tempDiv = document.createElement("div");
+    tempDiv.innerHTML = richText;
+    let plainText = tempDiv.textContent || tempDiv.innerText || "";
+    return plainText.trim(); // 使用trim()移除可能的前后空格
+}

+ 24 - 9
src/views/predictEdb_manage/predictEdb.vue

@@ -115,12 +115,12 @@
 								style="display: flex; align-items: center"
 								v-if="select_node===data.UniqueCode&&data.HaveOperaAuth"
 							>
-								<img
+								<!-- <img
 									src="~@/assets/img/data_m/move_ico.png"
 									alt=""
 									style="width: 14px; height: 14px; margin-right: 8px"
 									v-if="data.Button.MoveButton"
-								/>
+								/> -->
 								<!-- 添加子项 -->
 								<img
 									src="~@/assets/img/set_m/add.png"
@@ -147,23 +147,23 @@
 									v-if="data.Button.DeleteButton&&!data.EdbInfoId&&isEdbBtnShow('edbPreData_classifyOpt_delete')"
 								/>
 								<!-- 查看预测规则 -->
-								<i class="el-icon-view" v-if="data.EdbInfoId&&isEdbBtnShow('edbPreData_checkPreRule')" @click.stop="viewNode(node,data)"></i>
+								<!-- <i class="el-icon-view" v-if="data.EdbInfoId&&isEdbBtnShow('edbPreData_checkPreRule')" @click.stop="viewNode(node,data)"></i> -->
 								<!-- 查看关联图表 -->
-								<img 
+								<!-- <img 
 									v-if="data.Button.ShowChartRelation&&isEdbBtnShow('edbPreData_checkRelatedChart')" 
 									@click.stop="showAssociateChart=true,showAssociateComputeData=false"
 									src="~@/assets/img/icons/associate_chart.png" 
 									style="width: 14px; height: 14px;margin-left: 8px"
 									alt=""
-								/>
+								/> -->
 								<!-- 查看关联指标 -->
-								<img 
+								<!-- <img 
 									v-if="data.Button.ShowEdbRelation&&isEdbBtnShow('edbPreData_checkRelatedEdb')" 
 									@click.stop="showAssociateComputeData=true,showAssociateChart=false"
 									src="~@/assets/img/icons/associate_data.png" 
 									style="width: 14px; height: 14px;margin-left: 8px"
 									alt=""
-								/>
+								/> -->
 							</span>
 						</span>
 					</el-tree>
@@ -248,6 +248,21 @@
 										type="text" 
 										@click="updateEdbHandle"
 									>{{$t('Edb.detail_recalculate_btn')}}<!-- 重新计算 --></el-button>
+									<el-button 
+										v-if="isEdbBtnShow('edbPreData_checkPreRule')"
+										type="text" 
+										@click.stop="viewNode"
+									>{{$t('Edb.detail_formula_btn')}}<!-- 查看公式 --></el-button>
+									<el-button 
+										v-if="edbButton.ShowChartRelation&&isEdbBtnShow('edbPreData_checkRelatedChart')"
+										type="text" 
+										@click="showAssociateChart=true,showAssociateComputeData=false" 
+									>{{$t('Edb.detail_related_charts_btn')}}<!-- 关联图 --></el-button>
+									<el-button 
+										v-if="edbButton.ShowEdbRelation&&isEdbBtnShow('edbPreData_checkRelatedEdb')"
+										type="text"
+										@click="showAssociateComputeData=true,showAssociateChart=false"
+									>{{$t('Edb.detail_related_metrics_btn')}}<!-- 关联指标 --></el-button>
 									<el-button 
 										class="deletesty" 
 										@click="delEdbHandle" 
@@ -318,10 +333,10 @@
 
 				<!-- 指标关联图模块 -->
 				<div class="edb-detail-wrapper" style="padding: 30px 20px;" v-if="showAssociateChart&&select_id">
-					<dataAssociateChart :edbInfoId="select_id"></dataAssociateChart>
+					<dataAssociateChart :edbInfoId="select_id" @returnHandle="showAssociateChart=false,showAssociateComputeData=false"></dataAssociateChart>
 				</div>
 				<div class="edb-detail-wrapper" style="padding: 30px 20px;" v-if="showAssociateComputeData&&select_id">
-					<dataAssociateComputeData :edbInfoId="select_id"></dataAssociateComputeData>
+					<dataAssociateComputeData :edbInfoId="select_id" @returnHandle="showAssociateChart=false,showAssociateComputeData=false"></dataAssociateComputeData>
 				</div>
 			</div>
 		</div>

+ 1 - 1
src/views/report_manage/mixins/editor.js

@@ -42,7 +42,7 @@ export default {
           "redo",
         ],
         height: 800,
-        fontSize: ["12", "13","14","15", "16", "18", "20", "24", "28", "32", "36", "40"],
+        fontSize: ["6","8","10","12", "13","14","15", "16", "18", "20", "24", "28", "32", "36", "40"],
         fontSizeDefaultSelection: "16",
         theme: "dark", //主题
         placeholderText: localStorage.getItem('i18n') == 'en' ? 'Please input content' : "请输入内容",

+ 1 - 1
src/views/report_manage/mixins/reportMixin.js

@@ -97,7 +97,7 @@ export default {
           "redo",
         ],
         height: 800,
-        fontSize: ["12", "13","14","15", "16", "18", "20", "24", "28", "32", "36", "40"],
+        fontSize: ["6","8","10","12", "13","14","15", "16", "18", "20", "24", "28", "32", "36", "40"],
         fontSizeDefaultSelection: "16",
         theme: "dark", //主题
         placeholderText: localStorage.getItem('i18n') == 'en' ? 'Please input content' : "请输入内容",

+ 1 - 1
src/views/report_manage/reportEn/reportEditor.vue

@@ -493,7 +493,7 @@ export default {
 					'undo',
 					'redo',
         ],
-        fontSize: ["12", "13","14","15", "16", "18", "20", "24", "28", "32", "36", "40"],
+        fontSize: ["6","8","10","12", "13","14","15", "16", "18", "20", "24", "28", "32", "36", "40"],
         height:300,
         fontSizeDefaultSelection: "16",
         quickInsertEnabled: false,

+ 21 - 2
src/views/sandbox_manage/index_new_version.vue

@@ -1143,9 +1143,28 @@ import {reportVarietyInterence} from '@/api/modules/reportVariety'
                 let EdbInfoIdList = res.Data.EdbInfoIdList || []
                 let ChartInfoIdList = res.Data.ChartInfoIdList || []
                 let ReportIdList = res.Data.ReportIdList || []
-                this.checkedLinkList = currentLinks.filter(link =>{
-                  return EdbInfoIdList.includes(link.Id) || ChartInfoIdList.includes(link.Id) || ReportIdList.includes(link.Id)
+                this.checkedLinkList=[]
+                // detailParams的参数改从后端取 
+                EdbInfoIdList.map(edbIt=>{
+                  let item = currentLinks.find(it=>it.Id == edbIt.Id)
+                  if(item){
+                    this.checkedLinkList.push({...item,detailParams:{classifyId:edbIt.ClassifyId,code:edbIt.UniqueCode,id:edbIt.Id}})
+                  }
+                })
+                ChartInfoIdList.map(chartIt=>{
+                  let item = currentLinks.find(it=>it.Id == chartIt.Id)
+                  if(item){
+                    this.checkedLinkList.push({...item,detailParams:{classifyId:chartIt.ClassifyId,code:chartIt.UniqueCode,id:chartIt.Id}})
+                  }
+                })
+                ReportIdList.map(reportIt=>{
+                  let item = currentLinks.find(it=>it.Id == reportIt.Id)
+                  if(item){
+                    this.checkedLinkList.push({...item,detailParams:{code:reportIt.UniqueCode,id:reportIt.Id}})
+                  }
                 })
+                // 绑定的链接是否 被删除光了
+                if(!(this.checkedLinkList && this.checkedLinkList.length>0)) return 
                 let clinetPositon=graph.localToClient(node.position())
                 let size=node.size()
                 this.popoverTriggerDom.style.left = clinetPositon.x+size.width/2 + 'px';

+ 33 - 16
src/views/sandbox_manage/sandFlowNew/index.vue

@@ -657,6 +657,7 @@ import addLInkDia from './components/addLInkDia.vue';
           this.linkNode = node
           let isMindmap = node.shape.indexOf('mindmap')!=-1
           this.contextMenuOption.map(item =>{
+            // 思维导图里面的节点不得复制
             if(item.key=='copy'){
               item.show=!isMindmap
             }
@@ -678,29 +679,45 @@ import addLInkDia from './components/addLInkDia.vue';
                 let EdbInfoIdList = res.Data.EdbInfoIdList || []
                 let ChartInfoIdList = res.Data.ChartInfoIdList || []
                 let ReportIdList = res.Data.ReportIdList || []
-                this.linkList = currentLinks.filter(link =>{
-                  return EdbInfoIdList.includes(link.Id) || ChartInfoIdList.includes(link.Id) || ReportIdList.includes(link.Id)
+                this.linkList=[]
+                // detailParams的参数改从后端取更新 
+                EdbInfoIdList.map(edbIt=>{
+                  let item = currentLinks.find(it=>it.Id == edbIt.Id)
+                  if(item){
+                    this.linkList.push({...item,detailParams:{classifyId:edbIt.ClassifyId,code:edbIt.UniqueCode,id:edbIt.Id}})
+                  }
+                })
+                ChartInfoIdList.map(chartIt=>{
+                  let item = currentLinks.find(it=>it.Id == chartIt.Id)
+                  if(item){
+                    this.linkList.push({...item,detailParams:{classifyId:chartIt.ClassifyId,code:chartIt.UniqueCode,id:chartIt.Id}})
+                  }
+                })
+                ReportIdList.map(reportIt=>{
+                  let item = currentLinks.find(it=>it.Id == reportIt.Id)
+                  if(item){
+                    this.linkList.push({...item,detailParams:{code:reportIt.UniqueCode,id:reportIt.Id}})
+                  }
+                })
+
+                // check过滤后的,回传
+                data.linkData=this.linkList
+
+                this.contextMenuOption.map(item =>{
+                  if(item.key=='addLink'){
+                    item.label=(this.linkList && this.linkList.length>0)?this.$t('SandboxManage.SandFlow.edit_link'):this.$t('SandboxManage.SandFlow.add_link')
+                  }else if(item.key=='deleteLink'){
+                    item.show=(this.linkList && this.linkList.length>0)
+                  }
                 })
+                // 绑定的链接是否 被删除光了
+                if(!(this.linkList && this.linkList.length>0)) return 
                 let clinetPositon=this.graph.localToClient(node.position())
                 let size=node.size()
                 this.popoverTriggerDom.style.left = clinetPositon.x+size.width/2 + 'px';
                 this.popoverTriggerDom.style.top = clinetPositon.y + 'px';
                 this.popoverVisible=true
-                if(!(this.linkList.length>0)){
-                  if(item.key=='addLink'){
-                    item.label=this.$t('SandboxManage.SandFlow.add_link')
-                  }else if(item.key=='deleteLink'){
-                    item.show=false
-                  }
-                }
               }
-              this.contextMenuOption.map(item =>{
-                if(item.key=='addLink'){
-                  item.label=this.$t('SandboxManage.SandFlow.edit_link')
-                }else if(item.key=='deleteLink'){
-                  item.show=true
-                }
-              })
             })
           }else{
             this.contextMenuOption.map(item =>{

+ 0 - 84
src/views/sandbox_manage/sandFlowNew/popover.vue

@@ -1,84 +0,0 @@
-<!-- "@antv/x6-vue-shape": "1.5.4", "@vue/composition-api": "^1.5.0", -->
-<template>
-  <el-popover
-    placement="top"
-    trigger="manual"
-    v-model="popoverVisible">
-    <div id="link-popover" :style="{height:popoverFlod?'20px':'unset'}">
-      <div class="link-box">
-        <div v-for="item in checkedLinkList" :key="item.RId" class="link-item">
-          {{ item.Name }}
-        </div>
-      </div>
-      <img src="~@/assets/img/sand_new/arrow_black_down.png" class="link-fold" 
-      :style="{transform:popoverFlod?'':'rotate(180deg)'}" v-show="checkedLinkList.length>1"
-      @click="foldLink"/>
-    </div>
-    <div id="link-reference" slot="reference">不可拖拽</div>
-  </el-popover>
-</template>
-
-<script>
-  export default {
-    name:'linkPopover',
-    inject: ["getGraph", "getNode"],
-    data() {
-      return {
-        checkedLinkList:[],
-        popoverFlod:true,
-        node:null,
-        popoverVisible:false
-      }
-    },
-    mounted(){
-      const self = this;
-      this.node = this.getNode();
-      const graph = this.getGraph()
-      console.log(this.node,'this.node');
-      graph.on("node:mouseenter", ({ node, e }) => {
-        console.log(node, e);
-        this.popoverVisible=true
-        if(node.data){
-          this.checkedLinkList = node.data.linkData || []
-        }
-        console.log(this.checkedLinkList);
-      });
-    },
-    methods:{
-      foldLink(){
-        this.popoverFlod=!this.popoverFlod 
-        if(this.node.data){
-          this.node.data.linkFold = this.popoverFlod
-        }
-        this.popoverVisible=false
-        this.$nextTick(()=>{
-          this.popoverVisible=true
-        })
-      },
-    }
-  }
-</script>
-
-<style lang="scss" scoped>
-  #link-popover{
-    display: flex;
-    justify-content: space-between;
-    transition: all 0.3s ease;
-    overflow: hidden;
-    .link-box{
-      .link-item{
-        &:hover{
-          text-decoration: underline;
-          color: #0052D9;
-          cursor: pointer;
-        }
-      }
-    }
-    .link-fold{
-      transition: all 0.3s ease;
-      height: 16px;
-      width: 16px;
-      cursor: pointer;
-    }
-  }
-</style>

+ 1 - 1
src/views/smartReport/components/TextEdit.vue

@@ -59,7 +59,7 @@ export default {
                     "redo",
                 ],
                 height: 800,
-                fontSize: ["12", "13","14","15", "16", "18", "20", "24", "28", "32", "36", "40"],
+                fontSize: ["6","8","10","12", "13","14","15", "16", "18", "20", "24", "28", "32", "36", "40"],
                 fontSizeDefaultSelection: "16",
                 theme: "dark", //主题
                 placeholderText: localStorage.getItem('i18n') == 'en' ? 'Please input content' : "请输入内容",

+ 26 - 0
src/views/system_manage/chartTheme/common/config.js

@@ -82,15 +82,41 @@ export const alignPositions = [
   { value: 'right',svg:`<path d="M96 128h832v96H96zM96 576h832v96H96zM352 352h576v96H352zM352 800h576v96H352z" p-id="5963"></path>` },
 ]
 
+//可选数据标识样式
+export const markTypesOpts = [
+  { value: 'square',svg:`<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+    <rect width="20" height="20" fill="#D9D9D9"/>
+    </svg>` },
+  { value: 'circle',svg:`<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+    <circle cx="10" cy="10" r="10" fill="#D9D9D9"/>
+    </svg>` },
+  { value: 'diamond',svg:`<svg width="20" height="21" viewBox="0 0 20 21" fill="none" xmlns="http://www.w3.org/2000/svg">
+    <rect y="10.1421" width="14" height="14" transform="rotate(-45 0 10.1421)" fill="#D9D9D9"/>
+    </svg>` },
+  { value: 'triangle',svg:`<svg width="20" height="17" viewBox="0 0 20 17" fill="none" xmlns="http://www.w3.org/2000/svg">
+    <path d="M10 0L19.5263 16.5H0.473721L10 0Z" fill="#D9D9D9"/>
+    </svg>` },
+  { value: 'triangle-down',svg:`<svg width="20" height="17" viewBox="0 0 20 17" fill="none" xmlns="http://www.w3.org/2000/svg">
+    <path d="M10 17L0.473721 0.5L19.5263 0.5L10 17Z" fill="#D9D9D9"/>
+    </svg>` },
+]
+
 /* 当做标准化结构  eta默认值 几种类型图样式还区分开...*/
 export const defaultETAOptions = {
   colorsOptions: defaultOpts.colors.slice(0,10),
+  // 需要将 lineOptions 里面的属性变成 10条线条的独立属性,即长度为10的数组传给后端
   lineOptions: { 
     dashStyle: 'Solid',
+    // color:'#ff0000', //线条颜色
     lineWidth: 1,
     lineType: 'spline',
     radius: 5,
+    dataMark:'none',// none:无 built-in:内置
+    markType:"square",
+    markSize:5,
+    // markColor:'#ff0000' //默认同 线条颜色一致
   },
+  // lineOptionList:[{}],
   legendOptions: {
     verticalAlign: 'top',
     itemStyle: {

+ 112 - 62
src/views/system_manage/chartTheme/components/optionsSection.vue

@@ -2,29 +2,20 @@
   <div class="charTheme-setting-option">
     <ul class="options-wrapper">
       <li v-for="key in Object.keys(themeOptions)" :key="key">
-        <label class="option-title">{{ key ==='lineOptions'?typeLabelMap[chartType].label:labelMap.get(key)}}</label>
+        <label class="option-title">{{ key ==='lineOptionList'?typeLabelMap[chartType].label:labelMap.get(key)}}</label>
         
           <ul class="option-list">
              <!-- 线条设置 -->
-            <template v-if="key==='lineOptions'">
-                <li class="option-item">
-                  <label class="el-form-item__label">{{$t('SystemManage.ChartSet.config_opt01')}}</label>
-                  <el-color-picker
-                    v-model="themeOptions[key].colors[themeOptions[key].colorIndex]"
-                    show-alpha
-                    :predefine="predefineColors"
-                    style="width: 90px"
-                    @change="changeLineColor"
-                  />
-                </li>
+            <template v-if="key==='lineOptionList'">
+              <!-- 顺序 -->
                 <li class="option-item">
                   <label class="el-form-item__label">{{$t('SystemManage.ChartSet.config_opt02')}}</label>
                   <el-select 
-                    v-model="themeOptions[key].colorIndex"
+                    v-model="lineIndex"
                     style="width: 90px"
                   >
                     <el-option 
-                      v-for="(item,index) in themeOptions[key].colors" 
+                      v-for="(item,index) in themeOptions[key]" 
                       :key="index"
                       :label="`${$i18n.locale == 'zh'?'第':''}${index+1}${typeLabelMap[chartType].lineLabel}`"
                       :value="index"
@@ -32,12 +23,22 @@
                   </el-select>
                 </li>
 
+                <li class="option-item">
+                  <label class="el-form-item__label">{{$t('SystemManage.ChartSet.config_opt01')}}</label>
+                  <el-color-picker
+                    v-model="themeOptions[key][lineIndex].color"
+                    show-alpha
+                    :predefine="predefineColors"
+                    style="width: 90px"
+                  />
+                </li>
+
                 <!-- 曲线额外配置 雷达 -->
                 <template v-if="[1,2,11].includes(chartType)">
                   <li class="option-item">
                     <label class="el-form-item__label">{{$t('SystemManage.ChartSet.config_opt03')}}</label>
                     <el-select 
-                      v-model="themeOptions[key].dashStyle"
+                      v-model="themeOptions[key][lineIndex].dashStyle"
                       style="width: 90px"
                     >
                       <el-option 
@@ -54,17 +55,17 @@
                   <li class="option-item">
                     <label class="el-form-item__label">{{$t('SystemManage.ChartSet.config_opt04')}}</label>
                     <el-input
-                      v-model="themeOptions[key].lineWidth"
+                      v-model="themeOptions[key][lineIndex].lineWidth"
                       style="width: 90px"
                       type="number"
                       :min="1"
-                      @change="val => { themeOptions[key].lineWidth=Number(val)}"
+                      @change="val => { themeOptions[key][lineIndex].lineWidth=Number(val)}"
                     />
                   </li>
                   <li class="option-item">
                     <label class="el-form-item__label">{{$t('SystemManage.ChartSet.config_opt05')}}</label>
                     <el-select 
-                      v-model="themeOptions[key].lineType"
+                      v-model="themeOptions[key][lineIndex].lineType"
                       style="width: 90px"
                     >
                       <el-option :label="$t('SystemManage.ChartSet.config_opt05_yes')" value="spline"/>
@@ -72,17 +73,68 @@
                     </el-select>
                   </li>
                 </template>
-                
+                <!-- 曲线、季节性图额外配置- 数据标志-->
+                <template v-if="[1,2].includes(chartType)">
+                  <li class="option-item">
+                    <label class="el-form-item__label">{{$t('SystemManage.ChartSet.config_opt11')}}</label>
+                    <el-select 
+                      v-model="themeOptions[key][lineIndex].dataMark"
+                      style="width: 90px"
+                    >
+                      <el-option :label="$t('SystemManage.ChartSet.config_opt11_none')" value="none"/>
+                      <el-option :label="$t('SystemManage.ChartSet.config_opt11_inside')" value="built-in"/>
+                    </el-select>
+                  </li>
+                  <template v-if="themeOptions[key][lineIndex].dataMark =='built-in'">
+                    <li class="option-item">
+                      <label class="el-form-item__label">{{$t('SystemManage.ChartSet.config_opt12')}}</label>
+                      <el-select 
+                        v-model="themeOptions[key][lineIndex].markType"
+                        style="width: 90px"
+                      >
+                        <el-option 
+                          v-for="item in markTypesOpts" 
+                          :key="item.value"
+                          :value="item.value"
+                          :label="$t('SystemManage.ChartSet.'+(item.value.replace('-','_')))" 
+                        >
+                          <div style="display: flex;align-items: center;justify-content: center;height: 100%;" v-html="item.svg">
+                          </div>
+
+                        </el-option>
+                      </el-select>
+                    </li>
+                    <li class="option-item">
+                      <label class="el-form-item__label">{{$t('SystemManage.ChartSet.config_opt13')}}</label>
+                      <el-input
+                        v-model="themeOptions[key][lineIndex].markSize"
+                        style="width: 90px"
+                        type="number"
+                        :min="1"
+                        @change="val => { themeOptions[key][lineIndex].markSize=Number(val)}"
+                      />
+                    </li>
+                    <li class="option-item">
+                      <label class="el-form-item__label">{{$t('SystemManage.ChartSet.config_opt14')}}</label>
+                      <el-color-picker
+                        v-model="themeOptions[key][lineIndex].markColor"
+                        show-alpha
+                        :predefine="predefineColors"
+                        style="width: 90px"
+                      />
+                    </li>
+                  </template>
+                </template>
                 <!-- 散点额外配置 -->
                 <template v-else-if="[5,10].includes(chartType)">
                   <li class="option-item">
                     <label class="el-form-item__label">{{$t('SystemManage.ChartSet.config_opt06')}}</label>
                     <el-input
-                      v-model="themeOptions[key].radius"
+                      v-model="themeOptions[key][lineIndex].radius"
                       style="width: 90px"
                       type="number"
                       :min="3"
-                      @change="val => { themeOptions[key].radius=Number(val)}"
+                      @change="val => { themeOptions[key][lineIndex].radius=Number(val)}"
                     />
                   </li>
                 </template>
@@ -202,7 +254,9 @@
   </div>
 </template>
 <script>
-import { defaultETAOptions,verticalPositions,predefineColors,lineStylesOpts,alignPositions } from '../common/config'
+import { defaultETAOptions,verticalPositions,predefineColors,lineStylesOpts,alignPositions,
+  markTypesOpts
+ } from '../common/config'
 import { seasonOptions } from '@/utils/defaultOptions';
 export default {
   props: {
@@ -217,7 +271,7 @@ export default {
   computed:{
     labelMap(){
       return new Map([
-        ['lineOptions',this.$t('SystemManage.ChartSet.opt_label01')],
+        ['lineOptionList',this.$t('SystemManage.ChartSet.opt_label01')],
         ['scatterOptions',this.$t('SystemManage.ChartSet.opt_label02')],
         ['legendOptions',this.$t('SystemManage.ChartSet.opt_label03')],
         ['titleOptions',this.$t('SystemManage.ChartSet.opt_label04')],
@@ -245,17 +299,31 @@ export default {
       predefineColors,
       lineStylesOpts,
       alignPositions,
+      markTypesOpts,
      /* 可配置options*/
       themeOptions: {
-        lineOptions: {
-          dashStyle: defaultETAOptions.lineOptions.dashStyle,
-          colors: this.chartType===2?seasonOptions.colors:defaultETAOptions.colorsOptions,
-          color: defaultETAOptions.colorsOptions[0],
-          colorIndex:0,
-          lineWidth: defaultETAOptions.lineOptions.lineWidth,
-          lineType: defaultETAOptions.lineOptions.lineType,
-          radius: defaultETAOptions.lineOptions.radius,
-        },
+        // lineOptions: {
+        //   dashStyle: defaultETAOptions.lineOptions.dashStyle,
+        //   colors: this.chartType===2?seasonOptions.colors:defaultETAOptions.colorsOptions,
+        //   color: defaultETAOptions.colorsOptions[0],
+        //   colorIndex:0,
+        //   lineWidth: defaultETAOptions.lineOptions.lineWidth,
+        //   lineType: defaultETAOptions.lineOptions.lineType,
+        //   radius: defaultETAOptions.lineOptions.radius,
+        // },
+        lineOptionList: new Array(10).fill(1).map((item,index)=>{
+          return {
+            dashStyle: defaultETAOptions.lineOptions.dashStyle,
+            color: this.chartType===2?seasonOptions.colors[index]:defaultETAOptions.colorsOptions[index],
+            lineWidth: defaultETAOptions.lineOptions.lineWidth,
+            lineType: defaultETAOptions.lineOptions.lineType,
+            radius: defaultETAOptions.lineOptions.radius,
+            dataMark: defaultETAOptions.lineOptions.dataMark,
+            markType: defaultETAOptions.lineOptions.markType,
+            markSize: defaultETAOptions.lineOptions.markSize,
+            markColor: this.chartType===2?seasonOptions.colors[index]:defaultETAOptions.colorsOptions[index],
+          }
+        }),
         legendOptions: defaultETAOptions.legendOptions,
         titleOptions: defaultETAOptions.titleOptions,
         markerOptions: defaultETAOptions.markerOptions,
@@ -263,27 +331,9 @@ export default {
         yAxisOptions: defaultETAOptions.yAxisOptions,
         drawOption: defaultETAOptions.drawOption
       },
+      colorsOptions:this.chartType===2?seasonOptions.colors:defaultETAOptions.colorsOptions,
+      lineIndex:0,
       lengendPositions: verticalPositions.filter(_ => _.value!=='middle'),
-      // typeLabelMap: {
-      //   1: {label:'线条设置',lineLabel: '条'},
-      //   2: {label:'线条设置',lineLabel: '条'},
-      //   4: {label:'柱形设置',lineLabel: '根'},
-      //   5: {label:'散点设置',lineLabel: '系列'},
-      //   6: {label:'线条、柱形设置',lineLabel: '系列'},
-      //   7: {label:'柱形设置',lineLabel: '根'},
-      //   10: {label:'散点设置',lineLabel: '系列'},
-      //   11: {label:'线条设置',lineLabel: '条'},
-      // },
-      // labelMap: new Map([
-      //   ['lineOptions','线条设置'],
-      //   ['scatterOptions','散点设置'],
-      //   ['legendOptions','图例设置'],
-      //   ['titleOptions','标题设置'],
-      //   ['markerOptions','标记文字设置(来源,标识)'],
-      //   ['xAxisOptions','横轴设置'],
-      //   ['yAxisOptions','纵轴设置'],
-      //   ['drawOption','绘图区设置'],
-      // ]),
       configOptions: []
     }
   },
@@ -300,17 +350,17 @@ export default {
           spinner: 'el-icon-loading',
           background: 'rgba(255, 255, 255, 0.8)'
       });
-
       this.themeOptions = {
-        lineOptions: {
-          dashStyle: options.lineOptions.dashStyle,
-          colors: options.colorsOptions,
-          color: options.colorsOptions[0],
-          colorIndex:0,
-          lineWidth: options.lineOptions.lineWidth,
-          lineType: options.lineOptions.lineType,
-          radius: options.lineOptions.radius,
-        },
+        // lineOptions: {
+        //   dashStyle: options.lineOptions.dashStyle,
+        //   colors: options.colorsOptions,
+        //   color: options.colorsOptions[0],
+        //   colorIndex:0,
+        //   lineWidth: options.lineOptions.lineWidth,
+        //   lineType: options.lineOptions.lineType,
+        //   radius: options.lineOptions.radius,
+        // },
+        lineOptionList: options.lineOptionList,
         legendOptions: options.legendOptions,
         titleOptions: options.titleOptions,
         markerOptions: options.markerOptions,

+ 2 - 1
src/views/system_manage/chartTheme/index.vue

@@ -5,7 +5,8 @@
         <div class="setting-item">
             <span>
                 {{$t('SystemManage.ChartSet.label00')}}
-                <el-tooltip class="item" effect="dark" :content="$t('SystemManage.ChartSet.label00_hint')" placement="top">
+                <el-tooltip class="item" effect="dark" placement="top">
+                  <div slot="content" v-html="$t('SystemManage.ChartSet.label00_hint')"></div>
                     <i class="el-icon-warning"></i>
                 </el-tooltip>
             </span>

+ 78 - 21
src/views/system_manage/chartTheme/themeSetting.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="themeSet-page">
     <div class="header">
-      <div>
+      <div class="header-option">
         <el-select v-model="formData.chartType" @change="getThemeList('init');">
             <el-option
               v-for="item in chartTypeOpts"
@@ -19,10 +19,14 @@
             :value="item.ChartThemeId"
           />
         </el-select>
+        <span class="rename-item" @click="renameThemeOpen">
+          <img src="~@/assets/img/icons/edit_blue_new.png"/>
+          <span>重命名</span>
+        </span>
       </div>
       <div>
         <el-button type="primary" plain @click="$router.go(-1)">{{$t('Dialog.cancel_btn')}}</el-button>
-        <el-button type="primary" @click="setThemeOptions">{{$t('Dialog.confirm_save_btn')}}</el-button>
+        <el-button type="primary" @click="setThemeOptions(null)">{{$t('Dialog.confirm_save_btn')}}</el-button>
       </div>
     </div> 
 
@@ -48,7 +52,33 @@
         <Chart :options="options" :chartInfo="chartInfo" ref="chartRef" height="400px" minHeight="350px"/>
       </div>
     </div>
-    
+    <!-- 重命名弹窗 -->
+    <m-dialog 
+      :title="$t('SystemManage.ChartSet.rename')" 
+      :show.sync="isOpenThemeDia" 
+      width="650px"
+    >
+      <div style="padding:30px 60px">
+        <div>
+          <label class="el-form-item__label">{{$t('SystemManage.ChartSet.theme_name')}}</label>
+          <el-input 
+            v-model="formData.themeName" 
+            :placeholder="$t('SystemManage.ChartSet.theme_name_placeholder')"
+          />
+        </div>
+      </div>
+      <div slot="footer" style="margin: 20px 0;">
+        <el-button
+          @click="saveThemeName"
+          type="primary"
+          style="width: 132px; height: 40px"
+          >{{$t('Dialog.confirm_save_btn')}}</el-button>
+        <el-button
+        @click="isOpenThemeDia=false"
+        style="width: 132px; height: 40px"
+        >{{$t('Dialog.cancel_btn')}}</el-button>
+      </div>
+    </m-dialog>
   </div>
 </template>
 <script>
@@ -56,19 +86,22 @@ import * as chartThemeInterface from '@/api/modules/chartThemeApi';
 import { dataBaseInterface } from '@/api/api.js';
 import { chartSetMixin } from '@/views/dataEntry_manage/mixins/chartPublic';
 import Chart from '@/views/dataEntry_manage/components/chart.vue';
-import optionsSection from './components/optionsSection.vue'
+import optionsSection from './components/optionsSection.vue';
+import mDialog from '@/components/mDialog.vue';
 export default {
-  components: { optionsSection,Chart },
+  components: { optionsSection,Chart,mDialog },
   mixins: [ chartSetMixin ],
   data() {
     return {
       formData: {
         chartType: Number(this.$route.query.type),
-        theme: Number(this.$route.query.themeId)
+        theme: Number(this.$route.query.themeId),
+        themeName:''
       },
       chartTypeOpts: [],
       themeOpts: [],
-      chartInfo: {}
+      chartInfo: {},
+      isOpenThemeDia:false
     }
   },
   mounted(){
@@ -128,17 +161,12 @@ export default {
     },
 
     /* 保存配置 处理成标准化结构 */
-    async setThemeOptions() {
-      const { lineOptions,legendOptions,titleOptions,markerOptions,xAxisOptions,yAxisOptions,drawOption } = this.$refs.optionsSectionRef.themeOptions;
+    async setThemeOptions(themeName) {
+      const { legendOptions,titleOptions,markerOptions,xAxisOptions,yAxisOptions,drawOption,lineOptionList } = this.$refs.optionsSectionRef.themeOptions;
       
       let options = {
-        colorsOptions: lineOptions.colors,
-        lineOptions: { 
-          dashStyle: lineOptions.dashStyle,
-          lineWidth: lineOptions.lineWidth,
-          lineType: lineOptions.lineType,
-          radius: lineOptions.radius,
-        },
+        colorsOptions: lineOptionList.map(it => it.color),
+        lineOptionList,
         legendOptions,
         titleOptions,
         markerOptions,
@@ -146,20 +174,20 @@ export default {
         yAxisOptions,
         drawOption
       }
-
       const { theme } = this.formData;
-
       let ChartImage = await this.setChartImage();
-
       let res= await chartThemeInterface.saveTheme({
-        ChartThemeName: this.themeOpts.find(_ => _.ChartThemeId===this.formData.theme).ChartThemeName,
+        ChartThemeName: themeName || this.themeOpts.find(_ => _.ChartThemeId===this.formData.theme).ChartThemeName,
         ChartThemeId: theme,
         ChartImage,
         Config: JSON.stringify(options)
       })
 
       if(res.Ret !==200) return
+
       this.getThemeList()
+      // 重命名弹窗
+      this.isOpenThemeDia=false
       this.$message.success(this.$t('MsgPrompt.saved_msg'))
     },
 
@@ -177,6 +205,17 @@ export default {
       let { Data } = await dataBaseInterface.uploadImgSvg(form);
       return Data.ResourceUrl;
     },
+    // 重命名
+    renameThemeOpen(){
+      let themeItem = this.themeOpts.find(_ => _.ChartThemeId===this.formData.theme)
+      this.formData.themeName = themeItem && themeItem.ChartThemeName;
+      this.isOpenThemeDia=true
+    },
+    async saveThemeName(){
+      if(!this.formData.themeName) return this.$message.warning(this.$t('SystemManage.ChartSet.theme_name_placeholder'))
+      // 重命名 用保存的接口,走一遍保存的逻辑
+      this.setThemeOptions(this.formData.themeName)
+    }
   },
 }
 </script>
@@ -197,6 +236,24 @@ export default {
     display: flex;
     justify-content: space-between;
     margin-bottom: 30px;
+    .header-option{
+      display: flex;
+      align-items: center;
+      .rename-item{
+        font-size: 14px;
+        color: #0052D9;
+        font-weight: 400;
+        cursor: pointer;
+        display: flex;
+        align-items: center;
+        margin-left: 10px;
+        img{
+          width: 16px;
+          height: 16px;
+          margin-right: 4px;
+        }
+      }
+    }
   }
   .main {
     min-height: calc(100vh - 230px);
@@ -205,7 +262,7 @@ export default {
       padding: 10px;
       border: 1px solid #C8CDD9;
       border-radius: 6px;
-      margin-left: auto;
+      margin: 0 auto;
       .title {
         margin-bottom: 10px;
       }