瀏覽代碼

Merge branch 'master' into need_pool45

Karsa 1 年之前
父節點
當前提交
38fb6f2e83

+ 5 - 1
src/api/api.js

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

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

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

+ 8 - 41
src/components/lzTable.vue

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

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

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

+ 4 - 1
src/utils/buttonConfig.js

@@ -241,7 +241,10 @@ export const dataSourcePermission = {
     dataSource_account_edit:'dataSourceAccount:edit',//编辑
     dataSource_account_enable:'dataSourceAccount:enable',//禁用/启用
     /*--------涌益咨询---- */
-    yyzxData_export:'yyzx:exportData'
+    yyzxData_export:'yyzx:exportData',
+    /*--------煤炭江湖---- */
+    coalWordData_view:'coalWord:view', // 查看
+    coalWordData_export:'coalWord:export', // 导出
 }
 
 /*

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

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

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

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

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

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

+ 4 - 1
src/views/ppt_manage/mixins/pptMixins.js

@@ -22,9 +22,12 @@ import FormatSix from '../newVersion/components/formatPage/FormatSix.vue';
 import FormatSeven from '../newVersion/components/formatPage/FormatSeven.vue';
 import FormatEight from '../newVersion/components/formatPage/FormatEight.vue';
 import FormatNine from '../newVersion/components/formatPage/FormatNine.vue';
+import FormatTen from '../newVersion/components/formatPage/FormatTen.vue';
+import FormatEle from '../newVersion/components/formatPage/FormatEle.vue';
+import FormatTwelve from '../newVersion/components/formatPage/FormatTwelve.vue';
 export default {
   components:{ FormatOne,FormatTwo,FormatThree,
-    FormatFour,FormatFive,FormatSix,FormatSeven,FormatEight,FormatNine},
+    FormatFour,FormatFive,FormatSix,FormatSeven,FormatEight,FormatNine,FormatTen,FormatEle,FormatTwelve},
   data(){
     return{
       chartInfo:null,

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

+ 16 - 2
src/views/ppt_manage/newVersion/pptPublish.vue

@@ -26,7 +26,12 @@
           </div>
           <!-- 内容 -->
           <div class="ppt-item" v-for="(item,index) in pageList" :key="item.id">
-            <div class="title-wrap">
+            <div class="title-wrap"
+            :style="`
+                top:${lineClamp===2?'2%':getStrCount(item.title)<58?'5.5%':'0'};
+                height:${lineClamp===2?'12%':getStrCount(item.title)<58?'7%':'14%'};
+                -webkit-line-clamp:${lineClamp===2?2:3};`" 
+            :class="{'title-ellipsis':getStrCount(item.title)>lineClamp*57}">
               {{item.title}} 
             </div>
             <component
@@ -59,7 +64,7 @@ import Cover from './components/Cover.vue';
 import CustomCover from './components/CustomCover.vue';
 import TransReport from './components/catalog/transReport.vue';
 //import {pageList} from './utils/mock';
-import {countComponentName,pptConfigInit,toTextProps,toJson,svg2Base64,getImgRealSize,calcScale,getShapeOptions,createRandomCode,getTableData,getChartInfo,pptInit,rgbaToHex } from './utils/untils';
+import {countComponentName,pptConfigInit,toTextProps,toJson,svg2Base64,getImgRealSize,calcScale,countStrSize,getShapeOptions,createRandomCode,getTableData,getChartInfo,pptInit,rgbaToHex } from './utils/untils';
 import {marginTop,modelConfig,pptSlideMaster} from './utils/config';
 import pptmixin from '../mixins/pptMixins';
 import mixins from '../mixins/mixins';
@@ -120,7 +125,16 @@ export default {
       this.coefficient = coefficient
     }
   },
+  computed:{
+    lineClamp(){
+        return this.LayoutType===2?2:3
+    },
+  },
   methods: {
+    //计算title的字节数
+    getStrCount(title){
+        return countStrSize(title)
+    },
     async transHandle(){
       //需要校验PPT
       const {result,hintText} = this.checkPPT()

+ 192 - 3
src/views/ppt_manage/newVersion/utils/config.js

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

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

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