Bläddra i källkod

ETA_1.8.6 CCF爬虫数据获取

hbchen 5 månader sedan
förälder
incheckning
a090853410

+ 2 - 1
package.json

@@ -64,7 +64,8 @@
     "vue2-datepicker": "^3.8.0",
     "vuedraggable": "^2.24.3",
     "vuex": "^2.0.0-rc.6",
-    "webpack-parallel-uglify-plugin": "1.0.0"
+    "webpack-parallel-uglify-plugin": "1.0.0",
+    "xlsx": "^0.18.5"
   },
   "devDependencies": {
     "@babel/runtime-corejs2": "^7.9.2",

+ 4 - 2
src/api/api.js

@@ -16,7 +16,8 @@ import {
   guangqiInterface,
   icpiInterface,
   coalWordInterface,
-  bloombergInterface
+  bloombergInterface,
+  ccfDataInterface
 } from './modules/thirdBaseApi';
 
 //手工指标 手工数据 手工数据权限
@@ -124,7 +125,8 @@ export {
   guangqiInterface,
   icpiInterface,
   coalWordInterface,
-  bloombergInterface
+  bloombergInterface,
+  ccfDataInterface
 };
 
 //老接口 研报 ppt等

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

@@ -967,6 +967,32 @@ const bloombergInterface={
 
 }
 
+/* CCF化纤信息 */
+const ccfDataInterface={
+	/**
+	 * 分类列表
+	 * @param {} params 
+	 * @returns 
+	 */
+	classifyList: params => {
+		return http.get('/datamanage/ccf/classify',params);
+	},
+	/**
+	 * 获取指标列表详情
+	 */
+	dataList: params => {
+		return http.get('/datamanage/ccf/index/data',params);
+	},
+	//单个指标数据
+	getTargetDataList:params=>{
+		return http.get('/datamanage/ccf/single_data',params);
+	},
+	// 搜索
+	getTargetListByName:params=>{
+		return http.get('/datamanage/ccf/search_list',params);
+	}
+}
+
 export { 
 	lzDataInterface,
 	glDataInterface,
@@ -983,5 +1009,6 @@ export {
 	guangqiInterface,
 	icpiInterface,
 	coalWordInterface,
-    bloombergInterface
+	bloombergInterface,
+	ccfDataInterface
 }

+ 19 - 0
src/api/modules/toolBoxApi.js

@@ -92,4 +92,23 @@ export const ForexCalendarInterface = {
     searchEdbInfo:(params)=>{
         return http.get("/datamanage/edb_info/filter_by_es/all",params)
     }
+}
+
+//CCF化纤信息装置
+export const CCFStockInterface = {
+    /**
+     * 获取分类列表
+     */
+    classifyList:()=>{
+        return http.get("/datamanage/ccf/stock/classify")
+    },
+    /**
+     * 获取数据详情
+     * @param {*} params 
+     * @param {Number} params.ClassifyId 分类Id
+     * @param {String} params.TableDate 时间
+     */
+    excelDataDetail:(params)=>{
+        return http.get("/datamanage/ccf/stock/table",params)
+    }
 }

+ 3 - 3
src/components/lzTable.vue

@@ -69,7 +69,7 @@ export default {
 		headerArr(){
 			let arr=['QuotaName','LzCode','Frequency','UnitName','ModifyTime']
 
-			let sourceTypeOne = ['smm','coal','baiinfo','yyzx','icpi','coalWord']
+			let sourceTypeOne = ['smm','coal','baiinfo','yyzx','icpi','coalWord','ccf']
 
 			if(this.source==='gl'){
 				arr=['IndexName','IndexCode','FrequencyName','UnitName','UpdateTime']
@@ -87,7 +87,7 @@ export default {
 				['UnitName', /* '单位' */this.$t('Edb.Detail.e_unit')],
 				['ModifyTime', /* '更新时间' */this.$t('Edb.Detail.e_update_time')],
 			])
-			let sourceTypeOne = ['smm','coal','baiinfo','yyzx','icpi','coalWord']
+			let sourceTypeOne = ['smm','coal','baiinfo','yyzx','icpi','coalWord','ccf']
 
 			if(this.source==='gl'){
 				temMap=new Map([
@@ -111,7 +111,7 @@ export default {
 		},
 		dynamic_key(){
 			let key='InputValue'
-			if(['smm','baiinfo','coal','yyzx','icpi'].includes(this.source)){
+			if(['smm','baiinfo','coal','yyzx','icpi','ccf'].includes(this.source)){
 				key='Value'
 			}else if(this.source=='coalWord'){
 				key='DealValue'

+ 4 - 0
src/lang/commonLang.js

@@ -304,6 +304,10 @@ export default {
       zh:'暂无表格权限,如有问题请联系管理员!',
       en:'You currently have no table permissions. If there is an issue, please contact the administrator!'
     },
+    no_file_for_download_btn:{
+      en: 'No files available for download.',
+      zh: '暂无下载文件'
+    },
   },
   Common: {
     category: {

+ 9 - 0
src/routes/modules/chartRoutes.js

@@ -350,6 +350,15 @@ export default [
 				name:"事件日历",
 				component:()=>import('@/views/toolBox_manage/ForexCalendar.vue')
 			},
+			{
+				path:"CCFStock",
+				name:"CCF化纤信息装置",
+				component:()=>import('@/views/toolBox_manage/CcfDevice.vue'),
+				meta:{
+          name_en:'CCF Fiber Device'
+        },
+			},
+			
 		]
 	}
 ]

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

@@ -251,6 +251,14 @@ export default [
         name: "Bloomberg",
         hidden: false
       },
+      {
+        path: "ccfData",
+        component: () => import("@/views/dataEntry_manage/thirdBase/ccfData.vue"),
+        name: "CCF化纤信息",
+        meta:{
+          name_en:'CCF Fiber Info'
+        },
+      },
     ],
   },
 ];

+ 3 - 0
src/utils/buttonConfig.js

@@ -269,6 +269,9 @@ export const dataSourcePermission = {
     coalWordData_export:'coalWord:export', // 导出
     /*--------彭博数据源--- */
     Bloomberg_add2edb:'Bloomberg:add2edb',//添加指标库
+    /*--------CCF化纤信息--- */
+    ccfData_view:'ccfData:view',//查看
+    ccfData_exportExcel:'ccfData:exportExcel',//导出
 }
 
 /*

+ 513 - 0
src/views/dataEntry_manage/thirdBase/ccfData.vue

@@ -0,0 +1,513 @@
+<template>
+  <div class="CCF-container target-container" id="box" v-if="canView">
+    <span
+        v-show="!isLeftWrapShow"
+        class="slide-btn-icon slide-right"
+        @click="isLeftWrapShow = !isLeftWrapShow"
+    >
+        <i :class="{'el-icon-d-arrow-left':isLeftWrapShow,'el-icon-d-arrow-right':!isLeftWrapShow}"></i>
+    </span>
+    <div class="left-cont minHeight" id="left" v-show="isLeftWrapShow">
+        <span
+            v-show="isLeftWrapShow"
+            class="slide-btn-icon slide-left"
+            @click="isLeftWrapShow = !isLeftWrapShow"
+        >
+            <i :class="{'el-icon-d-arrow-left':isLeftWrapShow,'el-icon-d-arrow-right':!isLeftWrapShow}"></i>
+        </span>
+      <div class="left-top">
+        <el-button
+          v-permission="permissionBtn.dataSourcePermission.ccfData_exportExcel"
+          style="width: 100%"
+          type="primary"
+          plain
+          size="medium"
+          @click="exportClick"
+          :loading="btnload"
+          :disabled="!select_classify&&!leftSearchTradeCode"
+          ><!-- 导出Excel -->{{$t('Common.exp_excel')}}</el-button
+        >
+        <el-autocomplete
+          style="margin: 20px 0; width: 100%"
+          prefix-icon="el-icon-search"
+          v-model="leftSearchVal"
+          :fetch-suggestions="handleLeftSearch"
+          :trigger-on-focus="false"
+          :placeholder="$t('Edb.InputHolderAll.input_name_orid')"
+          @select="handleSelectLeftSearchval"
+          popper-class="el-autocomplete-suggestion-data-entry"
+          clearable
+          @clear="clearSearch"
+        >
+          <template slot-scope="scope">
+            <div v-if="scope.item.nodata" style="text-align: center">
+              <!-- 暂无数据 -->{{$t('Table.prompt_slogan')}}
+            </div>
+            <div v-else>
+              {{ scope.item.IndexName }}
+            </div>
+          </template>
+        </el-autocomplete>
+      </div>
+      <div class="scroll-wrap">
+        <el-tree
+          ref="treeRef"
+          class="target_tree word-wrap"
+          :data="classifyList"
+          node-key="ClassifyId"
+          :props="{
+            label: 'ClassifyName',
+            children: 'Child',
+          }"
+          :current-node-key="select_classify"
+          check-strictly
+          highlight-current
+          :default-expanded-keys="defaultShowNodes"
+          @node-expand="handleNodeExpand"
+          @node-collapse="handleNodeCollapse"
+          :empty-text="$t('Common.no_classify_msg')"
+          @current-change="nodeChangeHandle"
+        >
+        </el-tree>
+      </div>
+      <span
+        class="move-btn resize"
+        v-drag
+        id="resize"
+      >
+      </span>
+    </div>
+    <div
+      class="right-cont minHeight"
+      id="right"
+      v-loading="dataloading"
+      :element-loading-text="$t('Table.data_loading')"
+    >
+      <template v-if="rightShow">
+        <div class="right-box" @scroll="scrollHandle">
+          <div class="data-header">
+            <lz-table
+              :tableOption="tableOption"
+              tableType="header"
+              ref="table"
+              source="ccf"
+            />
+          </div>
+          <div class="data-cont" v-if="dateArr.length">
+            <lz-table
+              :tableOption="tableOption"
+              tableType="data"
+              :dateArr="dateArr"
+              source="ccf"
+            />
+          </div>
+        </div>
+      </template>
+      <div v-else class="nodata-cont">
+        <tableNoData :text="$t('Table.prompt_slogan')"/>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import lzTable from "@/components/lzTable.vue";
+import { ccfDataInterface } from "@/api/api.js";
+export default {
+  name: "ccfData",
+  components: { lzTable },
+  directives: {
+    drag(el, bindings) {
+      el.onmousedown = function (e) {
+        var init = e.clientX;
+        // console.log(init);
+        var box = $('#box')[0];
+        // console.log(box.clientWidth)
+        let total_wid = box.offsetWidth;
+        var left = $('#left')[0];
+        var right = $('#right')[0];
+        var initWidth = left.offsetWidth;
+        document.onmousemove = function (e) {
+          var end = e.clientX;
+          var newWidth = end - init + initWidth;
+          left.style.width = newWidth + 'px';
+          right.style.width = newWidth > 320 ? total_wid - newWidth + 'px' : total_wid - 320 + 'px';
+        };
+        document.onmouseup = function () {
+          document.onmousemove = document.onmouseup = null;
+          e.releaseCapture && e.releaseCapture();
+        };
+        e.setCapture && e.setCapture();
+        return false;
+      };
+    }
+  }, 
+  data() {
+    return {
+      isLeftWrapShow:true,
+      exportBase:process.env.VUE_APP_API_ROOT + "/datamanage/ccf/export", //CCF数据导出接口
+      dataloading: false,
+      rightShow: false,
+      select_classify: 0,
+      classifyList: [],
+      tableOption: [],
+      dateArr: [], //最长的日期数组
+      btnload: false,
+      page_no: 1,
+      page_size: 20,
+      havemore: true, //是否还有数据
+
+      leftSearchVal: "", //左侧搜索值
+      leftSearchTradeCode: "", //如果是搜索选择的 则有此code
+      isShowSingleData: false, //右侧是否展示的是单个指标数据
+      defaultShowNodes: [], //展开的节点
+    };
+  },
+  methods: {
+    /* 获取分类 */
+    getClassify() {
+      ccfDataInterface.classifyList().then((res) => {
+        if (res.Ret !== 200) return;
+        this.classifyList = res.Data || [];
+        this.select_classify = this.classifyList[0].Child[0].ClassifyId
+        this.getDataList();
+        this.$nextTick(()=>{
+          this.orientationNode(this.select_classify)
+        })
+      });
+    },
+    /* 获取数据 */
+    getDataList: _.throttle(function () {
+      this.isShowSingleData = false;
+      this.dataloading = true;
+      ccfDataInterface
+        .dataList({
+          ClassifyId: this.select_classify,
+          PageSize: this.page_size,
+          CurrentIndex: this.page_no,
+        })
+        .then((res) => {
+          this.rightShow = true;
+          if (res.Ret !== 200) return;
+
+          // 找出最多的页码 判断是否还有数据
+          let page_arrs = res.Data.map((item) => item.Paging.Pages);
+          let totalPage = Math.max.apply(Math, page_arrs);
+          this.havemore = this.page_no < totalPage ? true : false;
+
+          // 合并数据
+          if (this.page_no === 1) {
+            this.tableOption = res.Data;
+          } else {
+            this.tableOption.forEach((item) => {
+              res.Data.forEach((_item) => {
+                if (item.IndexCode === _item.IndexCode) {
+                  item.DataList = item.DataList.concat(_item.DataList);
+                }
+              });
+            });
+          }
+
+          // 合并所有指标中的日期 作为日期数组
+          let arr = res.Data.map((item) => {
+            return item.DataList;
+          });
+
+          let obj = [];
+          for (let i of arr) {
+            for (let j of i) {
+              obj.push(j.DataTime);
+            }
+          }
+          let arr2 = [...new Set(obj)].sort().reverse();
+          let concatArr = [...new Set([...this.dateArr, ...arr2])]
+            .sort()
+            .reverse();
+          this.dateArr = this.page_no === 1 ? arr2 : concatArr;
+
+          /* 不满6个追加6个空的显示一排 别问 问就是为了美观  */
+          if (this.tableOption.length < 7)
+            for (let i = 0; i < 7; i++) {
+              this.tableOption.push({
+                DataList: [],
+              });
+              if (this.tableOption.length >= 7) break;
+            }
+
+          //数据最大长度小于12个 追加数据满12个 别问 问就是为了美观
+          if (this.dateArr.length < 12)
+            for (let i = 0; i < 12; i++) {
+              this.dateArr.push("");
+              if (this.dateArr.length >= 12) break;
+            }
+
+          this.dataloading = false;
+          this.page_no === 1 &&
+            this.$nextTick(() => {
+              this.rightShow && this.initWidth();
+            });
+        });
+    }, 200),
+    // 获取单个指标数据
+    async getTargetDataList(code) {
+      this.isShowSingleData = true;
+      this.dataloading = true;
+      try {
+        const res = await ccfDataInterface.getTargetDataList({
+          IndexCode: code,
+        });
+        this.rightShow = true;
+        if (res.Ret !== 200) return;
+        const DataList = res.Data.Data || [];
+        // 合并数据
+        this.tableOption = [
+          {
+            DataList: DataList,
+            ...res.Data,
+          },
+        ];
+        this.orientationNode(res.Data ? res.Data.ClassifyId:-1)
+        // 这里是单个指标所以不用合并日期
+        const arr = DataList.map((item) => item.DataTime);
+        this.dateArr = [...new Set(arr)].sort().reverse();
+        /* 不满6个追加6个空的显示一排 别问 问就是为了美观  */
+        for (let i = 0; i < 7; i++) {
+          this.tableOption.push({
+            DataList: [],
+          });
+          if (this.tableOption.length >= 7) break;
+        }
+        //数据最大长度小于12个 追加数据满12个 别问 问就是为了美观
+        if (this.dateArr.length < 12)
+          for (let i = 0; i < 12; i++) {
+            this.dateArr.push("");
+            if (this.dateArr.length >= 12) break;
+          }
+        this.dataloading = false;
+        this.rightShow && this.initWidth();
+      } catch (err) {
+        console.log(err);
+      }
+    },
+    // 左侧目录定位
+    orientationNode(Id){
+      this.select_classify = Id;
+      this.defaultShowNodes.push(Id)
+      this.$refs.treeRef.setCurrentKey(Id);
+      this.$nextTick(() => {
+        setTimeout(()=>{
+          let parent = document.getElementsByClassName('scroll-wrap')[0]
+          let node = parent.querySelector('.is-current')
+          parent.scrollTo({
+            top: node.offsetTop-200
+          })
+        },300)
+      })
+    },
+    // 树节点展开
+    handleNodeExpand(data) {
+      // 保存当前展开的节点
+      let flag = this.defaultShowNodes.some((item) => item === data.ClassifyId);
+
+      if (!flag) {
+        // 不存在则存到数组里
+        this.defaultShowNodes.push(data.ClassifyId);
+      }
+    },
+
+    // 树节点关闭
+    handleNodeCollapse(data) {
+      let shouldCollapseIds=data.Child ? [...data.Child.map(it => it.ClassifyId),data.ClassifyId] : [data.ClassifyId]
+
+      this.defaultShowNodes = this.defaultShowNodes.filter(it =>{
+        return !shouldCollapseIds.includes(it)
+      })
+    },
+    initWidth() {
+      this.$nextTick(() => {
+        $(".right-box")[0].style.width =
+          this.$refs.table.$el.clientWidth + 5 + "px";
+        $(".right-box")[0].scrollTop = 0;
+        $(".right-box")[0].scrollLeft = 0;
+      });
+    },
+    /* 无频度的异常显示处理 7*12*/
+    nodataDeal() {
+      this.tableOption = [];
+      this.dateArr = [];
+      for (let i = 0; i < 7; i++) {
+        this.tableOption.push({
+          DataList: [],
+        });
+        if (this.tableOption.length >= 7) break;
+      }
+      for (let i = 0; i < 12; i++) {
+        this.dateArr.push("");
+        if (this.dateArr.length >= 12) break;
+      }
+    },
+    /* 滚动加载 */
+    scrollHandle(e) {
+      if (this.isShowSingleData) return;
+      const dom = e.target;
+      let total = dom.scrollTop + dom.clientHeight;
+      if (total >= dom.scrollHeight && this.havemore) {
+        this.page_no++;
+        console.log("load下一页");
+        this.getDataList();
+      }
+    },
+    /* 数据导出 */
+    exportClick() {
+      this.btnload = true;
+      const link = document.createElement("a");
+      link.href = this.exportDataUrl;
+      link.download = "";
+      link.click();
+      setTimeout(() => {
+        this.btnload = false;
+      }, 5000);
+    },
+    //左侧搜索
+    async handleLeftSearch(query, cb) {
+      cb([]);
+      if (!query) return;
+      const res = await ccfDataInterface.getTargetListByName({
+        Keyword: query,
+      });
+      if (res.Ret === 200) {
+        let arr = res.Data || [];
+        if (!arr.length) {
+          cb([{ nodata: true }]);
+        } else {
+          cb(arr);
+        }
+      }
+    },
+    // 选中左侧搜索值
+    handleSelectLeftSearchval(e) {
+      if (!e.IndexCode) return;
+      this.leftSearchTradeCode = e.IndexCode;
+      this.leftSearchVal = e.IndexName;
+
+      // 获取单独指标数据
+      this.getTargetDataList(e.IndexCode);
+    },
+    // 对[#,;]转义
+    escapeStr(str) {
+      return str.replace(/#/g, escape("#")).replace(/;/g, escape(";")); 
+    },
+  
+    //改变选中节点
+    nodeChangeHandle(data, node) {
+      if (data.Level==1) return;
+      this.select_classify = data.ClassifyId;
+      this.leftSearchVal=''
+      this.page_no = 1;
+      this.page_size = 20;
+      this.getDataList()
+    },
+    clearSearch(){
+      this.page_no=1
+      this.leftSearchTradeCode=''
+      this.getDataList();
+    }
+  },
+  computed: {
+    exportDataUrl() {
+      // 数据导出接口
+      let urlStr = this.exportBase;
+      // token
+      urlStr += `?${localStorage.getItem("auth") || ""}`;
+      if (this.isShowSingleData) {
+        // 指标id
+        urlStr += `&IndexCode=${
+          this.isShowSingleData ? this.leftSearchTradeCode : ""
+        }`;
+      } else {
+        // 目录id
+        urlStr += `&ClassifyId=${
+          this.isShowSingleData ? "" : this.select_classify
+        }`;
+      }
+      return this.escapeStr(urlStr);
+    },
+    canView(){
+      return this.permissionBtn.isShowBtn('dataSourcePermission','ccfData_view')
+    }
+  },
+  mounted() {
+    this.canView && this.getClassify();
+  },
+};
+</script>
+<style lang="scss" scoped>
+@import "../css/customtree.scss";
+@import "../css/baseTargetPage.scss";
+.CCF-container {
+  display: flex;
+  * {
+    box-sizing: border-box;
+  }
+  .minHeight {
+    height: calc(100vh - 120px);
+    background-color: #fff;
+    box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+    border-radius: 4px;
+  }
+  .left-cont {
+    min-width: 300px;
+    width: 300px;
+    margin-right: 20px;
+    padding: 30px 0;
+    overflow: hidden;
+    position: relative;
+    .left-top {
+      padding: 0 20px;
+    }
+    .scroll-wrap {
+      padding: 0 20px;
+      height: calc(100vh - 280px);
+      overflow-y: auto;
+      margin-right: 20px;
+      .target_tree {
+        color: #333;
+      }
+    }
+    .move-btn {
+      height: 100%;
+      width: 4px;
+      position: absolute;
+      right: 0px;
+      top: 0;
+      &:hover {
+        cursor: col-resize;
+      }
+    }
+  }
+  .right-cont {
+    width: 82%;
+    padding: 30px;
+    .right-box {
+      max-width: 100%;
+      max-height: calc(100vh - 180px);
+      border-left: 1px solid #dcdfe6;
+      border-right: 1px solid #dcdfe6;
+      overflow: auto;
+      .data-header {
+        width: 100%;
+        position: sticky;
+        top: 0;
+        z-index: 2;
+      }
+    }
+    .nodata-cont {
+      width: 200px !important;
+      text-align: center;
+      color: #666;
+      font-size: 16px;
+      margin: 0 auto;
+    }
+  }
+}
+</style>

+ 135 - 0
src/views/toolBox_manage/CcfDevice.vue

@@ -0,0 +1,135 @@
+<template>
+    <!-- CCF化纤信息装置 -->
+    <div class="ccf-reserve-wrap">
+        <div class="tool-top">
+            <div class="tool-top-option">
+                <el-date-picker
+                    v-model="selectDate" :clearable="false"
+                    value-format="yyyy-MM-dd"
+                    type="date" @change="getSheetDetail">
+                </el-date-picker>
+                <el-select v-model="selectedVariety" style="width:186px;margin-right:20px;" @change="getSheetDetail">
+                    <el-option
+                        v-for="item in classifyList"
+                        :key="item.ClassifyId"
+                        :label="item.ClassifyName"
+                        :value="item.ClassifyId">
+                    </el-option>
+                </el-select>
+            </div>
+            <div class="tool-top-button">
+                <el-button type="text" @click="downloadSheet" :loading="isDownload">{{$t('Common.download_btn')}}</el-button>
+            </div>
+        </div>
+        <div class="table-box">
+            <div class="sheet-wrap"  v-if="sheetDetail" v-html="sheetDetail"></div>
+            <tableNoData text="该日期暂无数据" v-else/>
+        </div>
+    </div>
+</template>
+
+<script>
+import {CCFStockInterface} from "@/api/modules/toolBoxApi.js";
+import * as XLSX from 'xlsx'
+export default {
+    data() {
+        return {
+            sheetDetail:'',
+            selectDate:'',
+            tempDate:'',
+            selectedVariety:'',
+            tempVariety:'',
+            classifyList:[]
+        };
+    },
+    methods: {
+        getClassify(){
+            CCFStockInterface.classifyList().then(res=>{
+                if(res.Ret == 200){
+                    this.classifyList=res.Data||[]
+                    this.selectedVariety=this.classifyList[0] && this.classifyList[0].ClassifyId
+                    this.getSheetDetail()
+                }
+            })
+        },
+        getSheetDetail(){
+            CCFStockInterface.excelDataDetail({
+                TableDate: this.selectDate,
+                ClassifyId:this.selectedVariety
+            }).then(res=>{
+                if(res.Ret!==200){
+                    this.selectDate=this.tempDate
+                    this.selectedVariety=this.tempVariety
+                    return
+                } 
+                let tableInfo = res.Data||{};
+                this.selectDate = tableInfo.ExcelDate
+                this.tempDate = tableInfo.ExcelDate
+                this.tempVariety = this.selectedVariety
+                this.sheetDetail = tableInfo.ExcelContent
+            })
+        },
+        // 对[#,;]转义
+        escapeStr(str) {
+            return str.replace(/#/g, encodeURIComponent("#")).replace(/;/g, encodeURIComponent(";"));
+        },
+        downloadSheet(){
+            if(!this.sheetDetail){
+                this.$message.warning(this.$t('MsgPrompt.no_file_for_download_btn'))
+                return 
+            }
+            let table = $('.sheet-wrap table')[0]
+            let ws_name = "Sheet1";
+            let wb = XLSX.utils.book_new(), ws = XLSX.utils.table_to_sheet(table);
+            let variety=this.classifyList.find(cl => cl.ClassifyId == this.selectedVariety)
+            let varietyName = variety?variety.ClassifyName:''
+            let infoTime = this.$moment().format('YY.MM.DD')
+            XLSX.utils.format_cell(ws)
+            XLSX.utils.book_append_sheet(wb, ws, ws_name);
+            XLSX.writeFile(wb, `CCF化纤信息装置${varietyName}${infoTime}.xlsx`);
+        },
+    },
+    mounted(){
+        this.getClassify()
+    }
+};
+</script>
+
+<style scoped lang="scss">
+.ccf-reserve-wrap{
+    height:calc(100vh - 120px);
+    background-color: #fff;
+    display: flex;
+    flex-direction: column;
+    box-sizing: border-box;
+    padding:30px;
+    .tool-top{
+        display: flex;
+        justify-content: space-between;
+    }
+    .table-box{
+        width:100%;
+        height: calc(100% - 70px);
+        box-sizing: border-box;
+        flex: 1;
+        margin-top: 30px;
+        .sheet-wrap{
+            width:100%;
+            height: 100%;
+            overflow: auto;
+        }
+    }
+}
+</style>
+<style lang="scss">
+.sheet-wrap{
+    table{
+        border: 1px solid #dcdfe6;
+        td,th{
+            border: 1px solid #dcdfe6;
+            padding: 5px;
+        }
+    }
+}
+
+</style>