Ver código fonte

主题增删改 样式预览

Karsa 1 ano atrás
pai
commit
5205945f66

+ 64 - 0
src/api/modules/chartThemeApi.js

@@ -0,0 +1,64 @@
+import http from "@/api/http.js"
+
+/**
+ * 获取图表类型
+ * @param {*} params 
+ * @returns 
+ */
+export const getThemeChartType = params => {
+  return http.get('/datamanage/chart/theme/type/list',params)
+}
+
+/**
+ * 根据类型获取主题
+ * @param {*} params  ChartThemeTypeId
+ * @returns 
+ */
+export const getThemeByType = params => {
+  return http.get('/datamanage/chart/theme/list',params)
+}
+
+/**
+ * 添加主题
+ * @param {*} params ChartThemeName ChartThemeTypeId
+ * @returns 
+ */
+export const addTheme = params => {
+  return http.post('/datamanage/chart/theme/add',params)
+}
+
+/**
+ * 编辑主题
+ * @param {*} params  ChartThemeId ChartThemeName Config
+ * @returns 
+ */
+export const saveTheme = params => {
+  return http.post('/datamanage/chart/theme/edit',params)
+}
+
+/**
+ * 删除主题
+ * @param {*} params ChartThemeId
+ * @returns 
+ */
+export const delTheme = params => {
+  return http.post('/datamanage/chart/theme/delete',params)
+}
+
+/**
+ * 配置默认主题
+ * @param {*} params  ChartThemeId ChartThemeTypeId
+ * @returns 
+ */
+export const setConfigTheme = params => {
+  return http.post('/datamanage/chart/theme/set_default',params)
+}
+
+/**
+ * 预览图数据
+ * @param {*} params 
+ * @returns 
+ */
+export const previewChartData = params => {
+  return http.get('/datamanage/chart/theme/preview_data',params)
+}

+ 1 - 3
src/styles/global.scss

@@ -44,9 +44,7 @@ button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusri
 .clear:after{ display:block; height:0; content:""; clear:both; }
 
 .highcharts-range-selector-group{ display:none; }
-.highcharts-legend-item tspan{ font-size:14px; font-weight:400; color:#960000; }
-
-.highcharts-legend-item tspan{ font-size:14px; font-weight:400; color:#960000; }
+.highcharts-legend-item tspan{ font-weight:400;  }
 
 // 英文图表标识
 .chartEn-mark{

+ 9 - 1
src/utils/buttonConfig.js

@@ -641,6 +641,13 @@ export const outlinkConfigPermission = {
     outlinkListConfig_del:'outlinkListConfig:del',//删除
 }
 
+/* 图表主题配置 */
+export const chartThemePermission = {
+    chartTheme_add:'chartTheme:add',//添加
+    chartTheme_edit:'chartTheme:edit',//编辑
+    chartTheme_del:'chartTheme:del',//删除
+}
+
 
 //创建了新的ManageBtn记得添加到这里
 const btnMap  = {
@@ -655,7 +662,8 @@ const btnMap  = {
     statisticPermission,stockPlantPermission,
     productPricePermission,sysDepartPermission,
     operateAuthPermission,baseConfigPermission,
-    outlinkConfigPermission
+    outlinkConfigPermission,
+    chartThemePermission
 }
 
 /**

+ 6 - 4
src/views/dataEntry_manage/addChart.vue

@@ -46,6 +46,7 @@
 							v-model="chartInfo.Theme"
 							placeholder="请选择图表主题"
 							style="width: 90%"
+							@change="resetChartEdbDefault"
 						>
 							<el-option
 								v-for="item in chartThemeArr"
@@ -183,7 +184,7 @@
 					<!-- 仅用于散点图配置 -->
 					<div class="scatter-setting" v-if="chartInfo.ChartType === 5 && tableData.length">
 						<div style="display: flex;margin-right: 15px;">
-							<span style="margin-right: 3px">线条颜色:</span>
+							<span style="margin-right: 3px">散点颜色:</span>
 							<el-color-picker
 								v-model="tableData[0].ChartColor"
 								size="mini"
@@ -518,7 +519,7 @@
 							</el-radio-group>
 
 							<!-- 图表说明 -->
-							<div class="chart-instruction" v-text="chartInfo.Instructions"></div>
+							<div class="chart-instruction text_twoLine" v-text="chartInfo.Instructions"></div>
 						</div>
 
 
@@ -541,8 +542,8 @@
 							align="center"
 						>
 							<template slot-scope="scope">
-								<div v-if="item.key === 'EdbName' && [1,4,6].includes(chartInfo.ChartType)">
-									<!-- 奇怪柱状图用别名 -->
+								<div v-if="item.key === 'EdbName' && [1,4,6,7].includes(chartInfo.ChartType)">
+									<!-- 柱状图用别名 -->
 									<el-input 
 										v-model="scope.row.EdbAliasName"
 										placeholder="指标别名"
@@ -714,6 +715,7 @@ export default {
 							ChartStyle: item.ChartStyle,
 							ChartWidth: Number(item.ChartWidth),
 							EdbInfoId: item.EdbInfoId,
+							EdbAliasName: item.EdbAliasName,
 							EdbInfoType: item.EdbInfoType,
 							IsAxis: item.IsAxis,
 							IsOrder: item.IsOrder,

+ 23 - 3
src/views/dataEntry_manage/components/addMarkerDialog.vue

@@ -40,11 +40,13 @@
                 <el-date-picker
                   v-if="markerForm.axis===3"
                   v-model="markerForm.value"
+                  :popper-class="{'month-day-picker':chartInfo.ChartType===2}"
                   type="date"
                   style="width: 200px;"
                   placeholder="选择日期"
                   :clearable="false"
-                  value-format="yyyy-MM-dd"
+                  :format="chartInfo.ChartType===2?'MM-dd':'yyyy-MM-dd'"
+                  :value-format="chartInfo.ChartType===2?'MM-dd':'yyyy-MM-dd'"
                 ></el-date-picker>
 
                 <el-input
@@ -79,20 +81,24 @@
                 <div v-if="markerForm.axis===3">
                   <el-date-picker
                     v-model="markerForm.fromValue"
+                    :popper-class="{'month-day-picker':chartInfo.ChartType===2}"
                     type="date"
                     style="width: 150px;"
                     placeholder="选择日期"
                     :clearable="false"
-                    value-format="yyyy-MM-dd"
+                    :format="chartInfo.ChartType===2?'MM-dd':'yyyy-MM-dd'"
+                    :value-format="chartInfo.ChartType===2?'MM-dd':'yyyy-MM-dd'"
                   ></el-date-picker>
                   <el-date-picker
                     v-model="markerForm.toValue"
+                    :popper-class="{'month-day-picker':chartInfo.ChartType===2}"
                     type="date"
                     style="width: 150px;"
                     placeholder="选择日期"
                     :clearable="false"
-                    value-format="yyyy-MM-dd"
+                    :format="chartInfo.ChartType===2?'MM-dd':'yyyy-MM-dd'"
+                    :value-format="chartInfo.ChartType===2?'MM-dd':'yyyy-MM-dd'"
                   ></el-date-picker>
                 </div>
 
@@ -374,5 +380,19 @@ export default {
 .marker-edit-dialog {
   .el-color-picker__trigger { width: 100%;padding: 0;border-radius: 4px; }
   .number-input .el-input__inner { padding: 0 2px 0 10px; }
+
+}
+.month-day-picker {
+  .el-date-picker__header {
+    span:nth-child(3) {
+      display: none;
+    }
+    button:nth-child(1) {
+      display: none;
+    }
+    button:nth-child(5) {
+      display: none;   
+    }
+  }
 }
 </style>

+ 2 - 0
src/views/dataEntry_manage/components/chart.vue

@@ -60,6 +60,8 @@ export default {
 
 			let themeOptions = this.setThemeOptions();
 			const options = {...defaultOpts,...themeOptions,...this.options}
+
+			console.log(themeOptions,this.options)
 			
 			let thatThis = this
 			//stock不支持线形图只支持时间图 部分图用原始chart

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

@@ -58,8 +58,8 @@
       <div class="induction-item" v-if="chartInstruction.text">
         <div v-text="chartInstruction.text" class="text_oneLine text"></div>
          <div>
-            <i class="el-icon-view icon"/>
-            <i class="el-icon-edit icon" style="margin:0 6px"/>
+            <i class="el-icon-view icon" :style="chartInstruction.isShow?'color:#0052D9':'color:#999'" @click="chartInstruction.isShow=!chartInstruction.isShow;"/>
+            <i class="el-icon-edit icon" style="margin:0 6px" @click="addChartInductionHandle"/>
             <i class="el-icon-delete icon" @click="chartInstruction.text=''"/>
           </div>
       </div>
@@ -149,6 +149,7 @@ export default {
       markerAreasArr: [],
       chartInstruction:{
         text: '图表说明的货物带回去无地黄丸酒店',
+        isShow: true,
         color: '#f00',
         fontSize: 12
       } ,
@@ -229,7 +230,7 @@ export default {
     },
 
     initData() {
-
+      
     }
   },
 }

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

@@ -184,7 +184,7 @@
 						<!-- 仅用于散点图配置提出 -->
 					<div class="scatter-setting" v-if="chartInfo.ChartType === 5 && tableData.length">
 						<div style="display: flex;margin-right: 15px;">
-							<span style="margin-right: 3px">线条颜色:</span>
+							<span style="margin-right: 3px">散点颜色:</span>
 							<el-color-picker
 								v-model="tableData[0].ChartColor"
 								size="mini"
@@ -532,13 +532,12 @@
 							align="center"
 						>
 							<template slot-scope="scope">
-								<div v-if="item.key === 'EdbName' && chartInfo.ChartType === 7">
+								<div v-if="item.key === 'EdbName' && [1,4,6,7].includes(chartInfo.ChartType)">
 									<!-- 奇怪柱状图用别名 -->
 									<el-input 
 										v-model="scope.row.EdbAliasName"
 										placeholder="指标别名"
 										class="target-other-name"
-										v-if="chartInfo.ChartType === 7"
 										clearable
 									/>
 								</div>
@@ -798,6 +797,7 @@ export default {
 							ChartStyle: item.ChartStyle,
 							ChartWidth: Number(item.ChartWidth),
 							EdbInfoId: item.EdbInfoId,
+							EdbAliasName: item.EdbAliasName,
 							EdbInfoType: item.EdbInfoType,
 							IsAxis: item.IsAxis,
 							IsOrder: item.IsOrder,

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

@@ -1,5 +1,6 @@
 import { dataBaseInterface } from '@/api/api.js';
 import * as preDictEdbInterface from '@/api/modules/predictEdbApi.js';
+import * as chartThemeInterface from '@/api/modules/chartThemeApi';
 import { defaultOpts } from '@/utils/defaultOptions';
 import { mapState } from 'vuex';
 
@@ -13,7 +14,7 @@ export default {
 				Source:1,
 				Unit: '',
 				ChartName: '',
-				Theme: '',
+				Theme: 0,
 				SourcesFrom: 'wind,ths',
 				SourcesFromVisible: 1,
 				Instructions: '图标说明是的货物以带回去五个一给我倭寇的贫困我的卡我极为强劲的的我吉庆街得我',
@@ -74,7 +75,7 @@ export default {
 			isSpanYearDisable:false,
 			legendEditDiaShow:false,
 
-			chartThemeArr: []
+			chartThemeArr: [],//主题列表
 		}
 	},
 	computed: {
@@ -188,7 +189,9 @@ export default {
 				} 
 				dataBaseInterface.chartInfo(params).then((res) => {
 					if(res.Ret !== 200) return;
-						let [ tableItem ] = res.Data.EdbInfoList;
+						let tableItem = res.Data.EdbInfoList[0];
+						tableItem.EdbAliasName = tableItem.EdbName;
+
 						// 同一指标切换图表类型
 						if(type) {
 							this.tableData = [ tableItem ];
@@ -478,13 +481,16 @@ export default {
 
 		/* 移除表格指标 */
 		delTarget(item) {
-			if(this.tableData.length) {
-				let index = this.tableData.findIndex(obj => obj.EdbInfoId === item.EdbInfoId);
-				this.tableData.splice(index, 1);
-				this.$message.success('删除成功')
-
-				//添加图表时重置默认样式
-				this.$route.path==='/addchart' && this.resetChartEdbDefault();
+			let index = this.tableData.findIndex(obj => obj.EdbInfoId === item.EdbInfoId);
+			this.tableData.splice(index, 1);
+			this.$message.success('删除成功')
+
+			//添加图表时重置默认样式
+			this.$route.path==='/addchart' && this.resetChartEdbDefault();
+			
+			if(!this.tableData.length) {
+				this.chartInfo.MarkersLines = []
+				this.chartInfo.MarkersAreas = []
 			}
 		},
 
@@ -705,8 +711,9 @@ export default {
 			}
 		},
 
-		/* 添加图表页删除指标重置样式 */
+		/* 重置指标相关样式 */
 		resetChartEdbDefault() {
+			if(!this.tableData.length) return
 			this.tableData.forEach((item,index) => {
 				item.ChartColor = defaultOpts.colors[index];
 				item.PredictChartColor = defaultOpts.colors[index];
@@ -717,6 +724,15 @@ export default {
 			})
 		},
 
+		/* 获取主题列表 */
+		async getThemeList() {
+			let res =  await chartThemeInterface.getThemeByType({ChartThemeTypeId: this.formData.chartType})
+
+			if(res.Ret !== 200) return
+      this.chartThemeArr = res.Data || []
+      this.chartInfo.ThemeId = res.Data[0].DefaultChartThemeId
+		},
+
 		/* 更新图表标识区,标识线,图表说明 */
 		setChartMarkerInfo({ markerLinesArr,markerAreasArr,chartInstruction }) {
 			this.chartInfo.MarkersLines = markerLinesArr;

+ 47 - 20
src/views/dataEntry_manage/mixins/chartPublic.js

@@ -610,7 +610,7 @@ export const chartSetMixin = {
             align: 'center',
             x: [0,2].includes(item.IsAxis) ? 5 : -5,
             style: {
-              ...chartTheme&&chartTheme.yAxisOptions.style
+              ...chartTheme&&chartTheme.yAxisOptions.style,
             }
           },
           opposite: [0,2].includes(item.IsAxis),
@@ -644,14 +644,14 @@ export const chartSetMixin = {
           yAxis: sameSideIndex,
           name:
             dynamic_arr.length > 1
-              ? `${item.EdbName}(${item.SourceName})${dynamic_tag}`
-              : `${item.EdbName}${dynamic_tag}`,
+              ? `${item.EdbAliasName||item.EdbName}(${item.SourceName})${dynamic_tag}`
+              : `${item.EdbAliasName||item.EdbName}${dynamic_tag}`,
           nameCh:dynamic_arr.length > 1
-          ? `${item.EdbName}(${item.SourceName})${dynamic_tag}`
-          : `${item.EdbName}${dynamic_tag}`,
-          nameEn:item.EdbNameEn?`${item.EdbNameEn}${dynamic_tag_en}`:`${item.EdbName}${dynamic_tag}`,
+          ? `${item.EdbAliasName||item.EdbName}(${item.SourceName})${dynamic_tag}`
+          : `${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),
+          lineWidth: Number(item.ChartWidth)||(chartTheme&&chartTheme.lineOptions.lineWidth),
           ...predict_params
         };
         item.DataList = item.DataList || [];
@@ -820,14 +820,14 @@ export const chartSetMixin = {
           yAxis: serie_yIndex,
           name:
             dynamic_arr.length > 1
-              ? `${item.EdbName}(${item.SourceName})${dynamic_tag}`
-              : `${item.EdbName}${dynamic_tag}`,
+              ? `${item.EdbAliasName||item.EdbName}(${item.SourceName})${dynamic_tag}`
+              : `${item.EdbAliasName||item.EdbName}${dynamic_tag}`,
           nameCh:dynamic_arr.length > 1
-          ? `${item.EdbName}(${item.SourceName})${dynamic_tag}`
-          : `${item.EdbName}${dynamic_tag}`,
-          nameEn:item.EdbNameEn?`${item.EdbNameEn}${dynamic_tag_en}`:`${item.EdbName}${dynamic_tag}`,
+          ? `${item.EdbAliasName||item.EdbName}(${item.SourceName})${dynamic_tag}`
+          : `${item.EdbAliasName||item.EdbName}${dynamic_tag}`,
+          nameEn:item.EdbNameEn?`${item.EdbNameEn}${dynamic_tag_en}`:`${item.EdbAliasName||item.EdbName}${dynamic_tag}`,
           color: item.ChartColor,
-          lineWidth: (this.chartInfo.ChartType === 6 && item.ChartStyle === 'spline') ? Number(item.ChartWidth) : 0,
+          lineWidth: (this.chartInfo.ChartType === 6 && item.ChartStyle === 'spline') ? Number(item.ChartWidth)||(chartTheme&&chartTheme.lineOptions.lineWidth) : 0,
           fillColor: (this.chartInfo.ChartType === 3 || (this.chartInfo.ChartType === 6 && item.ChartStyle === 'areaspline')) ? item.ChartColor : undefined,
           borderWidth: 1,
           borderColor: item.ChartColor,
@@ -2356,14 +2356,25 @@ export const chartSetMixin = {
       axisType表示x轴类型 处理时间轴的值 datetime/null 
     */
     setAxisPlotLines(axis,axisType=null) {
-      const { MarkersLines } = this.chartInfo;
+      const { MarkersLines,ChartType } = this.chartInfo;
       if(!MarkersLines) return []
       let arr = MarkersLines.filter(_ => _.isShow&&_.axis===axis)
       let plotLines = arr.map(_ => {
         //是否是x时间轴
-        let isXDateAxis = axis===3&&axisType==='datetime'
+        let isXDateAxis = axis===3&&axisType==='datetime';
+        let markerValue='';
+        if(isXDateAxis) {
+          //季节图x轴额外拼个年份
+          let nowYear = new Date().getFullYear();
+          markerValue = ChartType===2 
+            ? new Date(`${nowYear}-${_.value}`).getTime()
+            : new Date(_.value).getTime()
+        }else {
+          markerValue = Number(_.value)
+        }
+
         return { 
-          value: isXDateAxis ? new Date(_.value).getTime() : Number(_.value),
+          value: markerValue,
           dashStyle: _.dashStyle,
           width: Number(_.lineWidth),
           color: _.color,
@@ -2383,16 +2394,32 @@ export const chartSetMixin = {
 
     /* 处理标识区拼接 axisType表示x轴类型处理时间轴的值 datetime/null */
     setAxisPlotAreas(axis,axisType=null) {
-      const { MarkersAreas } = this.chartInfo;
+      const { MarkersAreas,ChartType } = this.chartInfo;
       if(!MarkersAreas) return []
 
       let arr = MarkersAreas.filter(_ => _.isShow&&_.axis===axis)
       let plotBands = arr.map(_ => {
         //是否是x时间轴
-        let isXDateAxis = axis===3&&axisType==='datetime'
+        let isXDateAxis = axis===3&&axisType==='datetime';
+        let fromMarkerValue='',toMarkerValue='';
+        if(isXDateAxis) {
+          //季节图x轴额外拼个年份
+          let nowYear = new Date().getFullYear();
+          fromMarkerValue = ChartType===2 
+            ? new Date(`${nowYear}-${_.fromValue}`).getTime()
+            : new Date(_.fromValue).getTime()
+
+          toMarkerValue = ChartType===2 
+            ? new Date(`${nowYear}-${_.toValue}`).getTime()
+            : new Date(_.toValue).getTime()
+        }else {
+          fromMarkerValue = Number(_.fromValue);
+          toMarkerValue = Number(_.toValue);
+        }
+
         return { 
-          from: isXDateAxis ? new Date(_.fromValue).getTime() : Number(_.fromValue),
-          to: isXDateAxis ? new Date(_.toValue).getTime(): Number(_.toValue),
+          from: fromMarkerValue,
+          to: toMarkerValue,
           color: _.color,
           label: {
             text: _.text||'',

+ 3 - 16
src/views/system_manage/chartTheme/common/config.js

@@ -1,21 +1,8 @@
 // 一些常量
-import { defaultOpts,seasonOptions,scatterColorsOptions } from '@/utils/defaultOptions';
+import { defaultOpts } from '@/utils/defaultOptions';
 
 export const predefineColors = defaultOpts.colors.slice(0, 2); //定义颜色蓝,红 默认颜色
 
-//可选图表类型
-export const chartTypeOpts = [
-  { label: '曲线图', value: 1 },
-  { label: '季节性图', value: 2 },
-  { label: '堆积柱状图', value: 3 },
-  { label: '散点图', value: 4 },
-  { label: '组合图', value: 5 },
-  { label: '柱形图', value: 6 },
-  { label: '截面散点图', value: 7 },
-  // { label: '统计分析', value: 8 },
-  // { label: '商品价格曲线', value: 9 },
-]
-
 //可选线条样式
 export const lineStylesOpts = [
   { value: 'Solid',svg:`<g clip-path="url(#clip0_2634_4692)"><rect x="-14" y="4" width="116" height="2" fill="#333333"/></g>
@@ -98,7 +85,7 @@ export const defaultETAOptions = {
   colorsOptions: defaultOpts.colors.slice(0,10),
   lineOptions: { 
     dashStyle: 'Solid',
-    lineWidth: 2,
+    lineWidth: 1,
     isSpline: 1,
     radius: 5,
   },
@@ -138,6 +125,6 @@ export const defaultETAOptions = {
     }
   },
   drawOption: {
-    plotBackgroundColor: 'transparent'
+    plotBackgroundColor: 'rgba(255, 255, 255, 0)'
   }
 }

+ 41 - 6
src/views/system_manage/chartTheme/components/optionsSection.vue

@@ -58,6 +58,7 @@
                       style="width: 90px"
                       type="number"
                       :min="1"
+                      @change="val => { themeOptions[key].lineWidth=Number(val)}"
                     />
                   </li>
                   <li class="option-item">
@@ -73,7 +74,7 @@
                 </template>
                 
                 <!-- 散点额外配置 -->
-                <template v-else-if="[4,7].includes(chartType)">
+                <template v-else-if="[5,10].includes(chartType)">
                   <li class="option-item">
                     <label class="el-form-item__label">大小</label>
                     <el-input
@@ -81,6 +82,7 @@
                       style="width: 90px"
                       type="number"
                       :min="3"
+                      @change="val => { themeOptions[key].radius=Number(val)}"
                     />
                   </li>
                 </template>
@@ -118,6 +120,7 @@
                     style="width: 90px"
                     type="number"
                     :min="1"
+                    @change="val => { themeOptions[key].itemStyle.fontSize=Number(val)}"
                   />
                 </li>
             </template>
@@ -140,6 +143,7 @@
                     style="width: 90px"
                     type="number"
                     :min="1"
+                    @change="val => { themeOptions[key].style.fontSize=Number(val)}"
                   />
                 </li>
                 <li class="option-item">
@@ -175,6 +179,7 @@
                     style="width: 90px"
                     type="number"
                     :min="1"
+                    @change="val => { themeOptions[key].style.fontSize=Number(val)}"
                   />
                 </li>
             </template>  
@@ -236,11 +241,11 @@ export default {
       typeLabelMap: {
         1: {label:'线条设置',lineLabel: '条'},
         2: {label:'线条设置',lineLabel: '条'},
-        3: {label:'柱形设置',lineLabel: '根'},
-        4: {label:'散点设置',lineLabel: '系列'},
-        5: {label:'线条、柱形设置',lineLabel: '系列'},
-        6: {label:'柱形设置',lineLabel: '根'},
-        7: {label:'散点设置',lineLabel: '系列'},
+        4: {label:'柱形设置',lineLabel: '根'},
+        5: {label:'散点设置',lineLabel: '系列'},
+        6: {label:'线条、柱形设置',lineLabel: '系列'},
+        7: {label:'柱形设置',lineLabel: '根'},
+        10: {label:'散点设置',lineLabel: '系列'},
       },
       labelMap: new Map([
         ['lineOptions','线条设置'],
@@ -258,7 +263,37 @@ export default {
   mounted(){
   },
   methods:{
+    initOptions(options) {
+      console.log(options)
+      //给点页面反馈
+      this.loading = this.$loading({
+          lock: true,
+          text: '切换主题中...',
+          target: '.charTheme-setting-option',
+          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,
+          isSpline: options.lineOptions.isSpline,
+          radius: options.lineOptions.radius,
+        },
+        legendOptions: options.legendOptions,
+        titleOptions: options.titleOptions,
+        markerOptions: options.markerOptions,
+        xAxisOptions: options.xAxisOptions,
+        yAxisOptions: options.yAxisOptions,
+        drawOption: options.drawOption
+      }
+
+      this.loading.close()
+    }
   },
 }
 </script>

+ 108 - 80
src/views/system_manage/chartTheme/index.vue

@@ -1,31 +1,34 @@
 <template>
   <div class="chartTheme-page">
     <div class="header">
-      <div class="select-item">
-        <span style="margin-right: 20px;">主题设置</span>
+      <div style="display: flex;gap:20px;">
         <div class="select-item">
-          <label>图表类型</label>
-          <el-select v-model="formData.chartType" style="margin-left: 15px;">
+          <div class="select-item">
+            <label>图表类型</label>
+            <el-select v-model="formData.chartType" style="margin-left: 15px;" @change="getThemeList();">
+              <el-option
+                v-for="item in chartTypeOpts"
+                :key="item.ChartThemeTypeId"
+                :label="item.ChartTypeName"
+                :value="item.ChartThemeTypeId"
+              />
+            </el-select>
+          </div>
+        </div>
+        <div class="select-item">
+          <label>ETA图库默认主题</label>
+          <el-select v-model="formData.theme" style="margin-left: 10px;">
             <el-option
-              v-for="item in chartTypeOpts"
-              :key="item.value"
-              :label="item.label"
-              :value="item.value"
+              v-for="item in themeOpts"
+              :key="item.ChartThemeId"
+              :label="item.ChartThemeName"
+              :value="item.ChartThemeId"
             />
           </el-select>
         </div>
       </div>
-      <div class="select-item">
-        <label>ETA图库默认主题</label>
-        <el-select v-model="formData.theme" style="margin-left: 10px;">
-          <el-option
-            v-for="item in themeOpts"
-            :key="item.id"
-            :label="item.label"
-            :value="item.id"
-          />
-        </el-select>
-      </div>
+
+      <el-button type="primary" v-permission="permissionBtn.chartThemePermission.chartTheme_edit" @click="setConfigTheme">保存</el-button>
     </div>
 
     <!-- 主题列表 -->
@@ -33,39 +36,28 @@
       <ul class="list-wrap">
         <li 
           v-for="(item,index) in themeOpts" 
-          :key="index" 
+          :key="item.ChartThemeId" 
           class="theme-item"
         >  
-          <header class="item-top">
-            <label>{{item.label}}</label>
-            <div>
-              <el-button type="text" @click="editThemeHandle(item)">编辑</el-button>
-              <span class="deletesty" @click="delThemeHandle(index)" v-if="item.id!==0">删除</span>
-            </div>
-          </header>
           <el-card>
             <div slot="header" class="item-top">
-              <span class="text_oneLine">标题</span>
+              <span class="text_oneLine">{{item.ChartThemeName}}</span>
+              <div>
+                <el-button type="text" @click="editThemeHandle(item)" v-permission="permissionBtn.chartThemePermission.chartTheme_edit">编辑</el-button>
+                <span class="deletesty" @click="delThemeHandle(item,index)" v-permission="permissionBtn.chartThemePermission.chartTheme_del" v-if="!item.IsSystemTheme">删除</span>
+              </div>
             </div>
-            <img
-              :src="item.ChartImage"
-              alt=""
-              class="chart-img"
-            />
+            <div class="chart-img" :style="`backgroundImage:url(${item.ChartImage})`"></div>
           </el-card>
         </li>
-        <li class="add-item" @click="addThemeHandle">
-          <div>
+        <li class="theme-item add-item" @click="addThemeHandle" v-permission="permissionBtn.chartThemePermission.chartTheme_add">
+          <div class="chart-img">
             <i class="el-icon-plus"/>
             <el-button type="text" style="font-size:16px;">添加自定义主题</el-button>
           </div>
         </li>
       </ul>
 
-      <div class="bottom">
-        <el-button type="primary">保存</el-button>
-      </div>
-
     </div>
 
 
@@ -85,60 +77,87 @@
         </div>
       </div>
       <div slot="footer" style="margin: 20px 0;">
-        <el-button
-        @click="isOpenThemeDia=false"
-        style="width: 132px; height: 40px"
-        >取消</el-button>
         <el-button
           @click="saveThemeHandle"
           type="primary"
           style="width: 132px; height: 40px"
           >保存</el-button>
+        <el-button
+        @click="isOpenThemeDia=false"
+        style="width: 132px; height: 40px"
+        >取消</el-button>
       </div>
     </m-dialog>
 
   </div>
 </template>
 <script>
-import { chartTypeOpts } from "./common/config";
+import * as chartThemeInterface from '@/api/modules/chartThemeApi';
 import mDialog from '@/components/mDialog.vue';
 export default {
   components: { mDialog },
   data() {
     return {
-      chartTypeOpts,
+      chartTypeOpts:[],
       formData: {
-        chartType: chartTypeOpts[0].value,
+        chartType: 0,
         theme: 0
       },
 
-      themeOpts: [
-        { label: 'ETA主题',id: 0,ChartImage:'' },
-        { label: 'ETA主题1',id: 1,ChartImage:'' },
-        { label: 'ETA主题2',id: 2,ChartImage:'' },
-        { label: 'ETA主题3',id: 3,ChartImage:'' },
-        { label: 'ETA主题4',id: 4,ChartImage:'' },
-      ],
+      themeOpts: [],
 
       isOpenThemeDia: false,
       addThemeForm: {
-        themeId: 0,
         themeName: '',
       }
     };
   },
-  mounted() {},
+  mounted() {
+    this.getChartType()
+  },
   methods: {
+    /* 获取图表类型 */
+    async getChartType() {
+      let res = await chartThemeInterface.getThemeChartType()
+
+      if(res.Ret !== 200) return
+
+      this.chartTypeOpts = res.Data||[];
+      this.formData.chartType = res.Data[0].ChartThemeTypeId;
+      this.getThemeList()
+    },
+
+    /* 主题列表 */
+    async getThemeList() {
+      let res = await chartThemeInterface.getThemeByType({ChartThemeTypeId: this.formData.chartType})
+
+      if(res.Ret !== 200) return
+      this.themeOpts = res.Data || []
+      this.formData.theme = res.Data[0].DefaultChartThemeId
+    },
+
+    /* 设置默认主题 */
+    async setConfigTheme() {
+      const { chartType,theme } = this.formData
+      let res = await chartThemeInterface.setConfigTheme({
+        ChartThemeId: theme,
+        ChartThemeTypeId: chartType
+      })
+      
+      if(res.Ret !== 200) return
+      this.$message.success('默认主题设置成功')
+
+    },
+
     // 添加主题
     addThemeHandle() {
       this.isOpenThemeDia = true;
       this.addThemeForm= {
-        themeId: 0,
         themeName: '',
       }
     },
 
-    async delThemeHandle(index) {
+    async delThemeHandle(item,index) {
       await this.$confirm('删除后,所有采用该主题的图表,将采用ETA主题,是否确定删除?',
        '提示', {
           confirmButtonText: '确定',
@@ -146,26 +165,37 @@ export default {
           type: 'warning'
       })
 
+      let res = await chartThemeInterface.delTheme({ ChartThemeId: item.ChartThemeId })
+      if(res.Ret!==200) return 
+
       this.themeOpts.splice(index,1)
+      this.$message.success('删除成功')
     },
 
-    editThemeHandle({id}) {
+    editThemeHandle({ChartThemeId}) {
       this.$router.push({
         path: '/chartThemeSet',
         query: {
           type: this.formData.chartType,
-          id
+          themeId: ChartThemeId
         }
       })
     },
 
-    saveThemeHandle() {
+
+    async saveThemeHandle() {
       if(!this.addThemeForm.themeName) return this.$message.warning('主题名称不能为空')
-      
-      this.isOpenThemeDia = false;
-      this.themeOpts.push({
-        label: this.addThemeForm.themeName,id: new Date().getTime(),ChartImage:''
+
+      let res = await chartThemeInterface.addTheme({
+        ChartThemeName: this.addThemeForm.themeName,
+        ChartThemeTypeId: this.formData.chartType
       })
+
+      if(res.Ret !== 200) return
+      this.$message.success('添加成功')
+      this.isOpenThemeDia = false;
+
+      this.getThemeList()
     }
   },
 };
@@ -175,7 +205,6 @@ export default {
   box-sizing: border-box;
 }
 .chartTheme-page {
-  min-height: calc(100vh - 120px);
   .select-item {
     display: flex;
     align-items: center;
@@ -192,6 +221,10 @@ export default {
     display: flex;
     justify-content: space-between;
     margin-bottom: 30px;
+    gap: 20px;
+  }
+  .main {
+     min-height: calc(100vh - 240px);
   }
   .list-wrap {
     display: flex;
@@ -199,31 +232,31 @@ export default {
     margin-bottom: 30px;
     gap: 15px 30px;
     .theme-item {
-      min-width: 280px;
+      width: 20%;
+      min-width: 230px;
       position: relative;
       .item-top {
         display: flex;
+        height: 30px;
         justify-content: space-between;
         align-items: center;
         font-size: 14px;
       }
       .chart-img {
         width: 100%;
-        height: 220px;
-        object-fit: contain !important;
-        cursor: pointer;
+        height: 0;
+        padding-bottom: 75%;
+        object-fit: cover ;
+        background-repeat: no-repeat;
+        background-size: 100%;
       }
     }
     .add-item {
       background: #F8F8F8;
-      display: flex;
-      justify-content: center;
-      align-items: center;
-      width: 280px;
-      height: 302px;
-      margin-top: 40px;
       border: 1px dashed #DCDFE6;
       cursor: pointer;
+      text-align: center;
+      padding-top: 60px;
       .el-icon-plus {
         font-size: 30px;
         display:block;
@@ -233,11 +266,6 @@ export default {
       }
     }
   }
-  .bottom {
-    margin: 40px 0;
-    display: flex;
-    justify-content: flex-end;
-  }
 }
 </style>
 <style lang="scss">

+ 114 - 30
src/views/system_manage/chartTheme/themeSetting.vue

@@ -2,21 +2,21 @@
   <div class="themeSet-page">
     <div class="header">
       <div>
-        <el-select v-model="formData.chartType">
-          <el-option
-            v-for="item in chartTypeOpts"
-            :key="item.value"
-            :label="item.label"
-            :value="item.value"
-          />
-        </el-select>
+        <el-select v-model="formData.chartType" @change="getThemeList('init');">
+            <el-option
+              v-for="item in chartTypeOpts"
+              :key="item.ChartThemeTypeId"
+              :label="item.ChartTypeName"
+              :value="item.ChartThemeTypeId"
+            />
+          </el-select>
 
-        <el-select v-model="formData.theme" style="margin-left: 10px;">
+        <el-select v-model="formData.theme" style="margin-left: 10px;" @change="changeThemeHandle">
           <el-option
             v-for="item in themeOpts"
-            :key="item.id"
-            :label="item.label"
-            :value="item.id"
+            :key="item.ChartThemeId"
+            :label="item.ChartThemeName"
+            :value="item.ChartThemeId"
           />
         </el-select>
       </div>
@@ -34,40 +34,88 @@
       />
 
       <!-- 预览区 -->
-      <!-- <chartRenderSection/> -->
+      <div class="chart-render-wrapper">
+        <Chart :options="options" ref="chartRef" height="400px" minHeight="350px"/>
+      </div>
     </div>
     
   </div>
 </template>
 <script>
-import { chartTypeOpts } from "./common/config";
+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'
 export default {
-  components: { optionsSection },
+  components: { optionsSection,Chart },
+  mixins: [ chartSetMixin ],
   data() {
     return {
       formData: {
         chartType: Number(this.$route.query.type),
-        theme: Number(this.$route.query.id)
+        theme: Number(this.$route.query.themeId)
       },
-      chartTypeOpts,
-      themeOpts: [
-        { label: 'ETA主题',id: 0,ChartImage:'' },
-        { label: 'ETA主题1',id: 1,ChartImage:'' },
-        { label: 'ETA主题2',id: 2,ChartImage:'' },
-        { label: 'ETA主题3',id: 3,ChartImage:'' },
-        { label: 'ETA主题4',id: 4,ChartImage:'' },
-      ],
+      chartTypeOpts: [],
+      themeOpts: [],
+      chartInfo: {}
     }
   },
   mounted(){
-
+    this.getChartType()
   },
   methods:{
+
+    /* 获取图表类型 */
+    async getChartType() {
+      let res = await chartThemeInterface.getThemeChartType()
+
+      if(res.Ret !== 200) return
+
+      this.chartTypeOpts = res.Data||[];
+
+      this.getThemeList()
+    },
+
+     /* 主题列表 */
+    async getThemeList(type=null) {
+      let res = await chartThemeInterface.getThemeByType({ChartThemeTypeId: this.formData.chartType})
+
+      if(res.Ret !== 200) return
+      this.themeOpts = res.Data || []
+      this.formData.theme = type==='init' ? res.Data[0].DefaultChartThemeId : this.formData.theme
+
+      this.changeThemeHandle()
+    },
+
+    /* 预览图数据 */
+    async getPreviewData() {
+      let res = await chartThemeInterface.previewChartData({
+        ChartThemeTypeId: this.formData.chartType,
+      })
+      if(res.Ret !==200) return
+
+      let themeItem = this.themeOpts.find(_ => _.ChartThemeId===this.formData.theme)
+
+      this.chartInfo = {
+        ChartThemeStyle: themeItem.Config,
+        ...res.Data.ChartInfo
+      };
+      this.tableData = res.Data.EdbInfoList;
+      this.chartInfo.ChartType === 7 && this.initBarData(res.Data);
+      this.chartInfo.ChartType === 10 && this.initSectionScatterData(res.Data);
+
+      this.setChartOptionHandle(this.tableData)
+    },
+
+    changeThemeHandle() {
+      let themeItem = this.themeOpts.find(_ => _.ChartThemeId===this.formData.theme)
+      this.$refs.optionsSectionRef.initOptions(JSON.parse(themeItem.Config))
+      this.getPreviewData()
+    },
+
     /* 保存配置 处理成标准化结构 */
-    setThemeOptions() {
-      console.log(this.$refs.optionsSectionRef.themeOptions)
-      //
+    async setThemeOptions() {
       const { lineOptions,legendOptions,titleOptions,markerOptions,xAxisOptions,yAxisOptions,drawOption } = this.$refs.optionsSectionRef.themeOptions;
       
       let options = {
@@ -85,8 +133,37 @@ export default {
         yAxisOptions,
         drawOption
       }
-      console.log(options)
-    }
+
+      const { theme } = this.formData;
+
+      let ChartImage = await this.setChartImage();
+
+      let res= await chartThemeInterface.saveTheme({
+        ChartThemeName: this.themeOpts.find(_ => _.ChartThemeId===this.formData.theme).ChartThemeName,
+        ChartThemeId: theme,
+        ChartImage,
+        Config: JSON.stringify(options)
+      })
+
+      if(res.Ret !==200) return
+      this.getThemeList()
+      this.$message.success('保存成功')
+    },
+
+    /* 设置封面图片 */
+    async setChartImage() {
+      let svg = this.$refs.chartRef.chart.getSVG({
+        chart: {
+          width: 340,
+          height: 230,
+        }
+      });
+      let form = new FormData();
+      form.append('Img', svg);
+
+      let { Data } = await dataBaseInterface.uploadImgSvg(form);
+      return Data.ResourceUrl;
+    },
   },
 }
 </script>
@@ -110,6 +187,13 @@ export default {
   }
   .main {
     min-height: calc(100vh - 230px);
+    .chart-render-wrapper {
+      width: 620px;
+      padding: 10px;
+      border: 1px solid #C8CDD9;
+      border-radius: 6px;
+      margin-left: auto;
+    }
   }
 }
 </style>