hbchen 1 rok temu
rodzic
commit
cf21879e13
1 zmienionych plików z 228 dodań i 109 usunięć
  1. 228 109
      src/views/dataEntry_manage/onlineExcelCopy.vue

+ 228 - 109
src/views/dataEntry_manage/onlineExcelCopy.vue

@@ -30,9 +30,10 @@
         <el-tooltip :open-delay="400">
           <div slot="content">
             <p class="hint-message">1、新增指标:在预设好的指标列下输入指标名称、单位、数值并保存;</p>
-            <p class="hint-message">2、新增日期:在第一列选择日期或插入日期行(需复制已有日期格式)输入数值并保存;</p>
-            <p class="hint-message">3、除指标:清空该指标下所有数据并保存,请勿直接删除指标列;</p>
+            <p class="hint-message">2、新增日期:在第一列选择日期或插入日期行(需复制已有日期格式)输入数值并保存;</p>
+            <p class="hint-message">3、除指标:清空该指标下所有数据并保存,该操作不会删除指标,仅清除指标数据,请勿直接删除指标列;</p>
             <p class="hint-message">4、删除日期:清空该日期对应所有数据并保存,请勿直接删除日期行;</p>
+            <p class="hint-message">5、指标名称编辑、单位编辑、频度编辑、指标删除等操作请在“手工指标列表”中完成;</p>
           </div>
           <div class="instruction-hint" >
             <span>使用说明</span>
@@ -51,105 +52,101 @@ import EventBus from '@/api/bus.js'
 export default {
   name:'onlineExcelCopy',
   data() {
-    return {
-      // 初始化数据
-      options:{
-        container:'luckysheet',
-        lang: 'zh',
-        gridKey:'handmade-excel',
-        showinfobar:false,
-        row:300,
-        column:60,
-        data:[
-          {
-            "name":"test",
-            "celldata":[
-              {
-                "r":0,
-                "c":0,
-                "v":{
-                  ct: {fa: "General", t: "g"},
-                  m:"一级分类",
-                  v:"一级分类",
-                  bg:'#b4a7d6'
-                },
-              },
-              {
-                "r":1,
-                "c":0,
-                "v":{
-                  ct: {fa: "General", t: "g"},
-                  m:"指标分类",
-                  v:"指标分类",
-                  bg:'#b4a7d6'
-                },
+    // 受保护的数据 维护一个二维数组 用于还原不能被修改或者以错误方式修改的数据
+    this.protectedData=[]
+
+    // 初始化数据
+    this.options={
+      container:'luckysheet',
+      lang: 'zh',
+      gridKey:'handmade-excel',
+      showinfobar:false,
+      row:300,
+      column:60,
+      data:[
+        {
+          "name":"test",
+          "celldata":[
+            {
+              "r":0,
+              "c":0,
+              "v":{
+                ct: {fa: "General", t: "g"},
+                m:"一级分类",
+                v:"一级分类",
+                bg:'#b4a7d6'
               },
-              {
-                "r":2,
-                "c":0,
-                "v":{
-                  ct: {fa: "General", t: "g"},
-                  m:"频度",
-                  v:"频度",
-                  bg:'#b4a7d6'
-                },
+            },
+            {
+              "r":1,
+              "c":0,
+              "v":{
+                ct: {fa: "General", t: "g"},
+                m:"指标分类",
+                v:"指标分类",
+                bg:'#b4a7d6'
               },
-              {
-                "r":3,
-                "c":0,
-                "v":{
-                  ct: {fa: "General", t: "g"},
-                  m:"指标名称",
-                  v:"指标名称",
-                  bg:'#b4a7d6'
-                },
+            },
+            {
+              "r":2,
+              "c":0,
+              "v":{
+                ct: {fa: "General", t: "g"},
+                m:"频度",
+                v:"频度",
+                bg:'#b4a7d6'
               },
-              {
-                "r":4,
-                "c":0,
-                "v":{
-                  ct: {fa: "General", t: "g"},
-                  m:"单位",
-                  v:"单位",
-                  bg:'#b4a7d6'
-                },
+            },
+            {
+              "r":3,
+              "c":0,
+              "v":{
+                ct: {fa: "General", t: "g"},
+                m:"指标名称",
+                v:"指标名称",
+                bg:'#b4a7d6'
               },
-            ],
-            "config":{
-              "borderInfo":[{
-                "rangeType": "range",
-                "borderType": "border-all",
-                "style": "1",
-                "color": "#fff",
-                "range": [{
-                    "row": [0,4],
-                    "column": [0,0]
-                }]
-              }],
             },
-            "frozen":{
-              type: 'rangeBoth',
-              range: {row_focus: 4, column_focus: 0}
+            {
+              "r":4,
+              "c":0,
+              "v":{
+                ct: {fa: "General", t: "g"},
+                m:"单位",
+                v:"单位",
+                bg:'#b4a7d6'
+              },
             },
-            "dataVerification":{}
-          }
-        ],
-        hook:{
-          cellUpdateBefore(r,c){
-            // 禁止更新的单元格
-            if([0,1,2,3,4].includes(r) && c==0){
-              return false
-            }
+          ],
+          "config":{
+            "borderInfo":[{
+              "rangeType": "range",
+              "borderType": "border-all",
+              "style": "1",
+              "color": "#fff",
+              "range": [{
+                  "row": [0,4],
+                  "column": [0,0]
+              }]
+            }],
           },
-          cellMousedownBefore(e,position){
-            // 禁止鼠标选中的单元格
-            if([0,1,2].includes(position.r) || ([3,4].includes(position.r) && position.c==0)){
-              return false
-            }
-          }
-        },
-        showsheetbar:false
-		  },
+          "frozen":{
+            type: 'rangeBoth',
+            range: {row_focus: 4, column_focus: 0}
+          },
+          "dataVerification":{}
+        }
+      ],
+      hook:{},
+      showsheetbar:false,
+      // cellRightClickConfig:{
+      //   insertColumn:false,
+      //   deleteRow:false,
+      //   deleteColumn:false
+      // }
+    }
+
+    return {
       dataForm:{
         firstClassify:'',
         secondClassify:'',
@@ -165,7 +162,9 @@ export default {
       secondClassifyArray:[],
       // 保存时候的加载框
       saveLoading:false,
-      isEdit:"false"
+      isEdit:"false",
+      refreshed:false,
+      haveSaveProtected:false
     }
   },
 created() {
@@ -224,6 +223,102 @@ created() {
           // if(res.Data.FrequencyList) this.dataForm.frequency = res.Data.FrequencyList[0]
         }
       }
+
+      // hook设置
+      // 处理复制粘贴造成的漏洞 - 记录数据
+      this.options.hook.cellAllRenderBefore=(data,sheet)=>{
+        if(this.haveSaveProtected) return 
+        // console.log("全部刷新");
+        if(!this.protectedData.length>0){
+          for (let i = 0; i < 5; i++) {
+            if([0,1,2].includes(i)){
+              for (let j = 0; j < 2; j++) {
+                const element = data[i][j];
+                if(!Array.isArray(this.protectedData[i])) this.protectedData[i]=[]
+                this.protectedData[i][j] = element
+              }
+            }else{
+              for (let k = 0; k <= dataList.length; k++) {
+                const element = data[i][k];
+                if(!Array.isArray(this.protectedData[i])) this.protectedData[i]=[]
+                this.protectedData[i][k] = element
+              }
+            }
+          }
+        }
+        this.haveSaveProtected=true
+      }
+      this.options.hook.cellUpdateBefore=(r,c)=>{
+        // 禁止更新的单元格 已经有的指标名称和单位不允许更新
+        if(([0,1,2].includes(r) && c==0) || ([3,4].includes(r) && c<=dataList.length)){
+          return false
+        }
+      }
+
+      this.options.hook.cellMousedownBefore=(e,position)=>{
+        // console.log(e,position);
+        // 禁止鼠标选中的单元格
+        if([0,1,2].includes(position.r) || ([3,4].includes(position.r) && position.c<=dataList.length)){
+          return false
+        }
+      }
+
+      // 处理复制粘贴造成的漏洞 - 还原数据
+      this.options.hook.cellRenderBefore=(cell,position,sheet,ctx)=>{
+        // console.log('cellRenderBeforecellRenderBefore');
+        // 是否更改了受保护的数据
+        let haveUpdatedProtectedData=false
+        if([3,4].includes(position.r) && position.c>=0 && position.c<=dataList.length){
+          if(!cell) return 
+          Object.keys(this.protectedData[position.r][position.c]).forEach(key => {
+            // console.log(_.isEqual(cell[key], this.protectedData[position.r][position.c][key]),'lodash');
+            if(!_.isEqual(cell[key], this.protectedData[position.r][position.c][key])){
+              haveUpdatedProtectedData=true
+              cell[key] = this.protectedData[position.r][position.c][key]
+            }
+          }); 
+        }else if([0,1,2].includes(position.r)){
+          let cindex = position.c>1?1:position.c
+          // console.log(position.c,position.r,cell);
+          if(!cell){
+            if(cindex<1){
+              return 
+            }
+            luckysheet.getSheet().data[position.r][position.c] = this.protectedData[position.r][cindex]
+          }else{
+            Object.keys(this.protectedData[position.r][cindex]).forEach(key => {
+              if(!_.isEqual(cell[key], this.protectedData[position.r][cindex][key])){
+                haveUpdatedProtectedData=true
+                cell[key] = this.protectedData[position.r][cindex][key]
+              }
+            });
+            if([0,1,2].includes(position.r) && position.c>0){
+              if(position.r==0){
+                if(cell.m !==this.firstClassName || cell.v !== this.firstClassName){
+                  haveUpdatedProtectedData=true
+                  cell.m = cell.v = this.firstClassName
+                }
+              }else if(position.r==1){
+                if(cell.m !==this.secondClassName || cell.v !== this.secondClassName){
+                  haveUpdatedProtectedData=true
+                  cell.m = cell.v = this.secondClassName
+                }
+              }else{
+                if(cell.m !==this.dataForm.frequency || cell.v !== this.dataForm.frequency){
+                  haveUpdatedProtectedData=true
+                  cell.m = cell.v = this.dataForm.frequency
+                }
+              }
+            }
+          }
+          // console.log(cindex,position.r,'cindex,position.r',this.protectedData[position.r][cindex]);
+        }
+        if(haveUpdatedProtectedData){
+          // 还原数据后的手动刷新
+          this.refreshManual()
+        }
+      }
+
       // 拿出所有数组
       let arr = dataList.map((item => item.DataList)).flat()
       // 拿出所有数组的日期并展平排序
@@ -238,7 +333,7 @@ created() {
         return objList
       })
       /**
-       * 当数据的长度大于默认的84时,行数需要设置成数据的长度+15
+       * 当数据的长度大于默认的300时,行数需要设置成数据的长度+15
        */
       this.options.row = dateArr.length>(this.options.row-15) ? (dateArr.length+15):this.options.row
       /**
@@ -257,7 +352,8 @@ created() {
             "v":{
               ct: {fa: "General", t: "g"},
               m:item.SecName,
-              v:item.SecName
+              v:item.SecName,
+              bg:'#cccccc'
             }
           },
           {
@@ -266,7 +362,8 @@ created() {
             "v":{
               ct: {fa: "General", t: "g"},
               m:item.Unit,
-              v:item.Unit
+              v:item.Unit,
+              bg:'#cccccc'
             }
         })
       })
@@ -343,6 +440,15 @@ created() {
             "row": [5,row],
             "column": [0,0]
         }]
+      },{
+        "rangeType": "range",
+        "borderType": "border-all",
+        "style": "1",
+        "color": "#fff",
+        "range": [{
+            "row": [3,4],
+            "column": [1,dataList.length]
+        }]
       })
       // 设置数据验证
       for (let i = 0; i < col; i++) {
@@ -360,6 +466,15 @@ created() {
         luckysheet.create(this.options)
       })
     },
+    refreshManual: _.debounce(function() {
+      if(!this.refreshed) {
+        luckysheet.refresh()
+        this.refreshed=true
+        setTimeout(()=>{
+          this.refreshed=false
+        },1500)
+      }
+		},1000),
     // 获取分类
     async getClassify() {
       let res=await dataInterence.getClassify()
@@ -393,25 +508,29 @@ created() {
         this.dataForm.secondClassify = this.secondClassifyArray[0].ClassifyId
         this.secondClassName = this.secondClassifyArray[0].ClassifyName
       }
-      for (let i= 1;  i< col+1 ; i++) {
-        luckysheet.setCellValue(0,i,this.firstClassName,{isRefresh:false})
-        luckysheet.setCellValue(1,i,this.secondClassName,{isRefresh:i==col?true:false})
-      }
+      luckysheet.refresh()
+      // for (let i= 1;  i< col+1 ; i++) {
+      //   luckysheet.setCellValue(0,i,this.firstClassName,{isRefresh:false})
+      //   luckysheet.setCellValue(1,i,this.secondClassName,{isRefresh:i==col?true:false})
+      // }
     },
     // 切换选择二级分类
     changeSecondClassify(id){
       let col = this.options.column
       let item = this.secondClassifyArray.find(item => item.ClassifyId == id)
-      for (let i= 1;  i< col+1; i++) {
-        luckysheet.setCellValue(1,i,item.ClassifyName,{isRefresh:i==col?true:false})
-      }
+      this.secondClassName=item.ClassifyName
+      // for (let i= 1;  i< col+1; i++) {
+      //   luckysheet.setCellValue(1,i,this.secondClassName,{isRefresh:i==col?true:false})
+      // }
+      luckysheet.refresh()
     },
     // 切换选择频度
     changeFrequency(value){
-      let col = this.options.column
-      for (let i= 1;  i< col+1; i++) {
-        luckysheet.setCellValue(2,i,value,{isRefresh:i==col?true:false})
-      }
+      // let col = this.options.column
+      // for (let i= 1;  i< col+1; i++) {
+      //   luckysheet.setCellValue(2,i,value,{isRefresh:i==col?true:false})
+      // }
+      luckysheet.refresh()
     },
     saveExcel(){
       this.$refs.dataOptions.validate((valid)=>{