Browse Source

导入导出

Raod 4 years ago
parent
commit
17c2265082

+ 11 - 7
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/ReportDashboardController.java

@@ -11,6 +11,7 @@ import io.swagger.annotations.Api;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -72,21 +73,24 @@ public class ReportDashboardController {
      * @param reportCode
      * @return
      */
-    @GetMapping("/export/{reportCode}")
+    @GetMapping("/export")
     @Permission(code = "view", name = "导出大屏")
-    public ResponseEntity<byte[]> exportDashboard(HttpServletRequest request, HttpServletResponse response, @PathVariable("reportCode") String reportCode) {
-        return reportDashboardService.exportDashboard(request, response, reportCode);
+    public ResponseEntity<byte[]> exportDashboard(HttpServletRequest request, HttpServletResponse response,
+                                                  @RequestParam("reportCode") String reportCode, @RequestParam(value = "showDataSet",required = false, defaultValue = "1") Integer showDataSet) {
+        return reportDashboardService.exportDashboard(request, response, reportCode, showDataSet);
     }
 
     /**
      * 导入大屏
-     * @param dto
+     * @param file  导入的zip文件
+     * @param reportCode
      * @return
      */
-    @PostMapping("/import")
+    @PostMapping("/import/{reportCode}")
     @Permission(code = "design", name = "导入大屏")
-    public ResponseBean importDashboard(@RequestBody ChartDto dto) {
-        return ResponseBean.builder().data(reportDashboardService.getChartData(dto)).build();
+    public ResponseBean importDashboard(@RequestParam("file") MultipartFile file, @PathVariable("reportCode") String reportCode) {
+        reportDashboardService.importDashboard(file, reportCode);
+        return ResponseBean.builder().build();
     }
 
 }

+ 10 - 1
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/ReportDashboardService.java

@@ -7,6 +7,7 @@ import com.anjiplus.template.gaea.business.modules.dashboard.controller.dto.Repo
 import com.anjiplus.template.gaea.business.modules.dashboard.controller.param.ReportDashboardParam;
 import com.anjiplus.template.gaea.business.modules.dashboard.dao.entity.ReportDashboard;
 import org.springframework.http.ResponseEntity;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -48,5 +49,13 @@ public interface ReportDashboardService extends GaeaBaseService<ReportDashboardP
      * @param reportCode
      * @return
      */
-    ResponseEntity<byte[]> exportDashboard(HttpServletRequest request, HttpServletResponse response, String reportCode);
+    ResponseEntity<byte[]> exportDashboard(HttpServletRequest request, HttpServletResponse response, String reportCode, Integer showDataSet);
+
+    /**
+     * 导入大屏zip
+     * @param file
+     * @param reportCode
+     * @return
+     */
+    void importDashboard(MultipartFile file, String reportCode);
 }

+ 103 - 3
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/impl/ReportDashboardServiceImpl.java

@@ -43,6 +43,7 @@ import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -133,7 +134,7 @@ public class ReportDashboardServiceImpl implements ReportDashboardService, Initi
      * @param dto
      */
     @Override
-    @Transactional
+    @Transactional(rollbackFor = Exception.class)
     public void insertDashboard(ReportDashboardObjectDto dto) {
         String reportCode = dto.getReportCode();
         GaeaAssert.notEmpty(reportCode, ResponseCode.PARAM_IS_NULL, "reportCode");
@@ -149,6 +150,7 @@ public class ReportDashboardServiceImpl implements ReportDashboardService, Initi
         } else {
             //更新
             dashboard.setId(reportDashboard.getId());
+            dashboard.setVersion(null);
             this.update(dashboard);
         }
 
@@ -202,7 +204,7 @@ public class ReportDashboardServiceImpl implements ReportDashboardService, Initi
      * @return
      */
     @Override
-    public ResponseEntity<byte[]> exportDashboard(HttpServletRequest request, HttpServletResponse response, String reportCode) {
+    public ResponseEntity<byte[]> exportDashboard(HttpServletRequest request, HttpServletResponse response, String reportCode, Integer showDataSet) {
         String userAgent = request.getHeader("User-Agent");
         boolean isIeBrowser = userAgent.indexOf("MSIE") > 0;
 
@@ -225,6 +227,16 @@ public class ReportDashboardServiceImpl implements ReportDashboardService, Initi
                     zipLoadImage(imageAddress, path);
                 });
 
+        //showDataSet == 0 代表不包含数据集
+        if (0 == showDataSet) {
+            detail.getWidgets().forEach(reportDashboardWidgetDto -> {
+                ReportDashboardWidgetValueDto value = reportDashboardWidgetDto.getValue();
+                JSONObject data = value.getData();
+                if (null != data && data.containsKey("dataType")) {
+                    reportDashboardWidgetDto.getValue().getData().put("dataType", "staticData");
+                }
+            });
+        }
 
 
         //2.将大屏设计到的json文件保存
@@ -248,13 +260,101 @@ public class ReportDashboardServiceImpl implements ReportDashboardService, Initi
             builder.header("Content-Disposition", "attacher; filename*=UTF-8''" + reportCode + ".zip");
         }
 
+        ResponseEntity<byte[]> body = builder.body(FileUtils.readFileToByteArray(file));
+
         //删除zip文件
         file.delete();
         //删除path临时文件夹
         FileUtil.delete(path);
         log.info("删除临时文件:{},{}", zipPath, path);
 
-        return builder.body(FileUtils.readFileToByteArray(file));
+        return body;
+    }
+
+    /**
+     * 导入大屏zip
+     *
+     * @param file
+     * @param reportCode
+     * @return
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void importDashboard(MultipartFile file, String reportCode) {
+        log.info("导入开始,{}", reportCode);
+        //1.组装临时目录,/app/disk/upload/zip/临时文件夹
+        String path = dictPath + ZIP_PATH + UuidUtil.generateShortUuid();
+        //2.解压
+        FileUtil.decompress(file, path);
+        // path/uuid/
+        File parentPath = new File(path);
+        //获取打包的第一层目录
+        File firstFile = parentPath.listFiles()[0];
+
+        File[] files = firstFile.listFiles();
+
+        //定义map
+        Map<String, String> fileMap = new HashMap<>();
+        String content = "";
+
+        for (int i = 0; i < files.length; i++) {
+            File childFile = files[i];
+            if (JSON_PATH.equals(childFile.getName())) {
+                //json文件
+                content = FileUtil.readFile(childFile);
+            } else if ("image".equals(childFile.getName())) {
+                File[] imageFiles = childFile.listFiles();
+                //所有需要上传的图片
+                for (File imageFile : imageFiles) {
+                    //查看是否存在此image
+                    String name = imageFile.getName();
+                    String fileName = imageFile.getName().split("\\.")[0];
+                    //根据fileId,从gaea_file中读出filePath
+                    LambdaQueryWrapper<GaeaFile> queryWrapper = Wrappers.lambdaQuery();
+                    queryWrapper.eq(GaeaFile::getFileId, fileName);
+                    GaeaFile gaeaFile = gaeaFileService.selectOne(queryWrapper);
+                    if (null == gaeaFile) {
+                        GaeaFile upload = gaeaFileService.upload(null, imageFile, fileName);
+                        fileMap.put(fileName, upload.getUrlPath());
+                    }
+                }
+            }
+
+        }
+
+
+
+        //解析cotent
+        ReportDashboardObjectDto detail = JSONObject.parseObject(content, ReportDashboardObjectDto.class);
+        //将涉及到的图片路径替换(1.背景图,2.组件为图片的)
+        String backgroundImage = detail.getDashboard().getBackgroundImage();
+        detail.getDashboard().setBackgroundImage(replaceUrl(backgroundImage, fileMap));
+        detail.getWidgets().stream()
+                .filter(reportDashboardWidgetDto -> "widget-image".equals(reportDashboardWidgetDto.getType()))
+                .forEach(reportDashboardWidgetDto -> {
+                    String imageAddress = reportDashboardWidgetDto.getValue().getSetup().getString("imageAdress");
+                    String address = replaceUrl(imageAddress, fileMap);
+                    reportDashboardWidgetDto.getValue().getSetup().put("imageAdress", address);
+                    reportDashboardWidgetDto.getOptions().getJSONArray("setup").getJSONObject(4).put("value", address);
+                });
+        //将新的大屏编码赋值
+        detail.setReportCode(reportCode);
+
+        //解析结束,删除临时文件夹
+        FileUtil.delete(path);
+
+        log.info("解析成功,开始存入数据库...");
+        insertDashboard(detail);
+    }
+
+
+    private String replaceUrl(String imageAddress, Map<String, String> fileMap) {
+        String fileId = imageAddress.substring(imageAddress.trim().length() - 36);
+        String orDefault = fileMap.getOrDefault(fileId, null);
+        if (StringUtils.isBlank(orDefault)) {
+            return imageAddress;
+        }
+        return orDefault;
     }
 
     /**

+ 1 - 1
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/file/controller/GaeaFileController.java

@@ -33,7 +33,7 @@ public class GaeaFileController extends BaseController<GaeaFileParam, GaeaFile,
     @PostMapping("/upload")
     @Permission(code = "upload", name = "文件上传")
     public ResponseBean upload(@RequestParam("file") MultipartFile file) {
-        return ResponseBean.builder().message("success").data((gaeaFileService.upload(file))).build();
+        return ResponseBean.builder().message("success").data((gaeaFileService.upload(file, null, null))).build();
     }
 
     @GetMapping(value = "/download/{fileId}")

+ 2 - 3
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/file/service/GaeaFileService.java

@@ -8,6 +8,7 @@ import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.io.File;
 
 /**
  * (GaeaFile)Service
@@ -17,15 +18,13 @@ import javax.servlet.http.HttpServletResponse;
  */
 public interface GaeaFileService extends GaeaBaseService<GaeaFileParam, GaeaFile> {
 
-
     /**
      * 文件上传
      *
      * @param file
      * @return 文件访问路径
      */
-    GaeaFile upload(MultipartFile file);
-
+    GaeaFile upload(MultipartFile multipartFile, File file, String customFileName);
     /**
      * 根据fileId显示图片或者下载文件
      *

+ 21 - 4
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/file/service/impl/GaeaFileServiceImpl.java

@@ -10,6 +10,7 @@ import com.anjiplus.template.gaea.business.modules.file.entity.GaeaFile;
 import com.anjiplus.template.gaea.business.modules.file.service.GaeaFileService;
 import com.anjiplus.template.gaea.business.modules.file.util.FileUtils;
 import com.anjiplus.template.gaea.business.modules.file.util.StringPatternUtil;
+import com.anjiplus.template.gaea.business.util.FileUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.extern.slf4j.Slf4j;
@@ -64,11 +65,18 @@ public class GaeaFileServiceImpl implements GaeaFileService {
         return gaeaFileMapper;
     }
 
+
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public GaeaFile upload(MultipartFile file) {
+    public GaeaFile upload(MultipartFile multipartFile, File file, String customFileName) {
         try {
-            String fileName = file.getOriginalFilename();
+            String fileName = "";
+            if (null != multipartFile) {
+                fileName = multipartFile.getOriginalFilename();
+            }else {
+                fileName = file.getName();
+            }
+
             if (StringUtils.isBlank(fileName)) {
                 throw BusinessExceptionBuilder.build(ResponseCode.FILE_EMPTY_FILENAME);
             }
@@ -82,7 +90,12 @@ public class GaeaFileServiceImpl implements GaeaFileService {
                 throw BusinessExceptionBuilder.build(ResponseCode.FILE_SUFFIX_UNSUPPORTED);
             }
             // 生成文件唯一性标识
-            String fileId = UUID.randomUUID().toString();
+            String fileId;
+            if (StringUtils.isBlank(customFileName)) {
+                fileId = UUID.randomUUID().toString();
+            } else {
+                fileId = customFileName;
+            }
             String newFileName = fileId + suffixName;
             // 本地文件保存路径
             String filePath = dictPath + newFileName;
@@ -102,7 +115,11 @@ public class GaeaFileServiceImpl implements GaeaFileService {
             if (!parentFile.exists()) {
                 parentFile.mkdirs();
             }
-            file.transferTo(dest);
+            if (null != multipartFile) {
+                multipartFile.transferTo(dest);
+            }else {
+                FileUtil.copyFileUsingFileChannels(file, dest);
+            }
             // 将完整的http访问路径返回
             return gaeaFile;
         } catch (Exception e) {

+ 55 - 6
report-core/src/main/java/com/anjiplus/template/gaea/business/util/FileUtil.java

@@ -3,6 +3,7 @@ package com.anjiplus.template.gaea.business.util;
 import com.anji.plus.gaea.code.ResponseCode;
 import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.io.*;
 import java.net.URL;
@@ -90,6 +91,11 @@ public class FileUtil {
 
     public static void WriteStringToFile(String filePath, String content) {
         try {
+            //不存在创建文件
+            File file = new File(filePath);
+            if (!file.getParentFile().exists()) {
+                file.getParentFile().mkdirs();
+            }
             FileWriter fw = new FileWriter(filePath);
             BufferedWriter bw = new BufferedWriter(fw);
             bw.write(content);
@@ -241,23 +247,45 @@ public class FileUtil {
         }
     }
 
+    public static void decompress(String zipFile, String dstPath) {
+        try {
+            decompress(new ZipFile(zipFile), dstPath);
+        } catch (IOException e) {
+            log.error("", e);
+            throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
+        }
+    }
+
+    public static void decompress(MultipartFile zipFile, String dstPath) {
+        try {
+            File file = new File(dstPath + File.separator + zipFile.getOriginalFilename());
+            if (!file.getParentFile().exists()) {
+                file.getParentFile().mkdirs();
+            }
+            zipFile.transferTo(file);
+            decompress(new ZipFile(file), dstPath);
+            //解压完删除
+            file.delete();
+        } catch (IOException e) {
+            log.error("", e);
+            throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
+        }
+    }
 
     /**
      * 解压zip
      *
-     * @param zipFile
+     * @param zip
      * @param dstPath
      * @throws IOException
      */
-    public static void decompress(String zipFile, String dstPath) {
-        log.info("解压zip:{},临时目录:{}", zipFile, dstPath);
+    public static void decompress(ZipFile zip, String dstPath) {
+        log.info("解压zip:{},临时目录:{}", zip.getName(), dstPath);
         File pathFile = new File(dstPath);
         if (!pathFile.exists()) {
             pathFile.mkdirs();
         }
-        ZipFile zip = null;
         try {
-            zip = new ZipFile(zipFile);
 
             for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) {
                 ZipEntry entry = (ZipEntry) entries.nextElement();
@@ -314,8 +342,30 @@ public class FileUtil {
         }
     }
 
+    /**
+     * 获取流文件
+     * @param ins
+     * @param file
+     */
+    private static void inputStreamToFile(InputStream ins, File file) {
+        try {
+            OutputStream os = new FileOutputStream(file);
+            int bytesRead = 0;
+            byte[] buffer = new byte[8192];
+            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
+                os.write(buffer, 0, bytesRead);
+            }
+            os.close();
+            ins.close();
+        } catch (Exception e) {
+            log.error("获取流文件失败", e);
+            throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
+        }
+    }
+
     /**
      * 删除文件夹
+     *
      * @param path
      */
     public static void delete(String path) {
@@ -357,7 +407,6 @@ public class FileUtil {
 //        FileUtil.downloadPicture("http://10.108.26.197:9095/file/download/fd20d563-00aa-45e2-b5db-aff951f814ec", "D:\\abc.png");
 
 
-
 //        delete("D:\\aa");
 
     }

+ 1 - 1
report-ui/src/api/bigscreen.js

@@ -52,7 +52,7 @@ export function exportDashboard(data) {
   return new Promise((resolve) =>{
     axios({
       method:'get',
-      url: process.env.BASE_API + '/reportDashboard/export/' + data,
+      url: process.env.BASE_API + '/reportDashboard/export',
       headers: { 'Authorization': getToken() },
       params:data,
       responseType:'blob'

+ 153 - 48
report-ui/src/views/report/bigscreen/designer/index.vue

@@ -59,7 +59,7 @@
       :style="{ width: widthLeftForToolsHideButton + 'px' }"
       @click="toolIsShow = !toolIsShow"
     >
-      <i class="el-icon-arrow-right" />
+      <i class="el-icon-arrow-right"/>
     </div>
 
     <div
@@ -94,49 +94,80 @@
             content="导入"
             placement="bottom"
           >
-            <i class="iconfont iconyulan" @click="importDashboard"></i>
-          </el-tooltip>
-        </span>
-        <span class="btn">
-          <el-tooltip
-            class="item"
-            effect="dark"
-            content="导出"
-            placement="bottom"
-          >
-            <i class="iconfont iconyulan" @click="exportDashboard"></i>
+
+            <el-upload class="el-upload"
+                       ref="upload"
+                       :action="uploadUrl"
+                       :headers="headers"
+                       accept=".zip"
+                       :on-success="handleUpload"
+                       :on-error="handleError"
+                       :show-file-list="false"
+                       :limit="1">
+              <i class="iconfont iconxiazai"></i>
+          </el-upload>
           </el-tooltip>
         </span>
-        <!-- <span class="btn border-left">
+        <span class="btn border-left">
           <ul class="nav">
             <li>
-              <i class="el-icon-brush"></i><i class="el-icon-arrow-down"></i>
+              <i class="iconfont iconfenxiang_2"></i><i class="el-icon-arrow-down"></i>
               <ul>
                 <li>
-                  <div>
-                    <i class="el-icon-full-screen mr10"></i>边框
-                    <i class="el-icon-arrow-right ml20"></i>
-                  </div>
-                  <ul class="three-level">
-                    <li><a href="#">边框1</a></li>
-                    <li><a href="#">边框2</a></li>
-                    <li><a href="#">边框3</a></li>
-                  </ul>
+                  <el-tooltip
+                    class="item"
+                    effect="dark"
+                    content="适合当前系统"
+                    placement="right"
+                  >
+                       <div @click="exportDashboard(1)">导出(包含数据集)</div>
+                  </el-tooltip>
+
                 </li>
                 <li>
-                  <div>
-                    <i class="el-icon-magic-stick mr10"></i>装饰<i
-                      class="el-icon-arrow-right ml20"
-                    ></i>
-                  </div>
-                  <ul class="three-level">
-                    <li><a href="#">装饰1</a></li>
-                  </ul>
+                  <el-tooltip
+                    class="item"
+                    effect="dark"
+                    content="适合跨系统"
+                    placement="right"
+                  >
+                       <div @click="exportDashboard(0)">导出(不包含数据集)</div>
+                  </el-tooltip>
                 </li>
               </ul>
             </li>
           </ul>
-        </span> -->
+        </span>
+        <!--         <span class="btn border-left">
+                  <ul class="nav">
+                    <li>
+                      <i class="el-icon-brush"></i><i class="el-icon-arrow-down"></i>
+                      <ul>
+                        <li>
+                          <div>
+                            <i class="el-icon-full-screen mr10"></i>边框
+                            <i class="el-icon-arrow-right ml20"></i>
+                          </div>
+                          <ul class="three-level">
+                            <li><a href="#">边框1</a></li>
+                            <li><a href="#">边框2</a></li>
+                            <li><a href="#">边框3</a></li>
+                          </ul>
+                        </li>
+                        <li>
+                          <div>
+                            <i class="el-icon-magic-stick mr10"></i>装饰<i
+                              class="el-icon-arrow-right ml20"
+                            ></i>
+                          </div>
+                          <ul class="three-level">
+                            <li><a href="#">装饰1</a></li>
+                          </ul>
+                        </li>
+                      </ul>
+                    </li>
+                  </ul>
+                </span>-->
       </div>
       <div
         class="workbench-container"
@@ -246,13 +277,15 @@
 </template>
 
 <script>
-import { insertDashboard, detailDashboard, importDashboard, exportDashboard } from "@/api/bigscreen";
-import { widgetTools, getToolByCode } from "./tools";
+import {insertDashboard, detailDashboard, importDashboard, exportDashboard} from "@/api/bigscreen";
+import {widgetTools, getToolByCode} from "./tools";
 import widget from "./widget/widget.vue";
 import dynamicForm from "./form/dynamicForm.vue";
 import draggable from "vuedraggable";
 import VueRulerTool from "vue-ruler-tool"; // 大屏设计页面的标尺插件
 import contentMenu from "./form/contentMenu";
+import {getToken} from "@/utils/auth";
+
 export default {
   name: "Login",
   components: {
@@ -264,6 +297,7 @@ export default {
   },
   data() {
     return {
+      uploadUrl: process.env.BASE_API + '/reportDashboard/import/' + this.$route.query.reportCode,
       grade: false,
       layerWidget: [],
       widgetTools: widgetTools, // 左侧工具栏的组件图标,将js变量加入到当前作用域
@@ -330,6 +364,11 @@ export default {
     };
   },
   computed: {
+    headers() {
+      return {
+        Authorization: getToken(), // 直接从本地获取token就行
+      }
+    },
     // 左侧折叠切换时,动态计算中间区的宽度
     middleWidth() {
       var widthLeftAndRight = 0;
@@ -402,7 +441,7 @@ export default {
     },
     async initEchartData() {
       const reportCode = this.$route.query.reportCode;
-      const { code, data } = await detailDashboard(reportCode);
+      const {code, data} = await detailDashboard(reportCode);
       if (code != 200) return;
       const processData = this.handleInitEchartsData(data);
       const screenData = this.handleBigScreen(data.dashboard);
@@ -502,7 +541,7 @@ export default {
         },
         widgets: this.widgets
       };
-      const { code, data } = await insertDashboard(screenData);
+      const {code, data} = await insertDashboard(screenData);
       if (code == "200") {
         this.$message.success("保存成功!");
       }
@@ -511,14 +550,19 @@ export default {
     viewScreen() {
       var routeUrl = this.$router.resolve({
         path: "/bigscreen/viewer",
-        query: { reportCode: this.$route.query.reportCode }
+        query: {reportCode: this.$route.query.reportCode}
       });
       window.open(routeUrl.href, "_blank");
     },
     //  导出
-    async exportDashboard() {
+    async exportDashboard(val) {
       const fileName = this.$route.query.reportCode + ".zip"
-      exportDashboard(this.$route.query.reportCode).then(res=>{
+
+      const param = {
+        reportCode:this.$route.query.reportCode,
+        showDataSet:val
+      }
+      exportDashboard(param).then(res => {
         const blob = new Blob([res], {type: "application/octet-stream"});
         if (window.navigator.msSaveOrOpenBlob) {//msSaveOrOpenBlob方法返回bool值
           navigator.msSaveBlob(blob, fileName);//本地保存
@@ -532,11 +576,24 @@ export default {
       })
 
     },
-
-    // 导入
-    importDashboard() {
-      alert("导入,开发中")
+    // 上传成功的回调
+    handleUpload(response, file, fileList) {
+      //清除el-upload组件中的文件
+      this.$refs.upload.clearFiles();
+      //刷新大屏页面
+      this.initEchartData();
+      this.$message({
+        message: '导入成功!',
+        type: 'success',
+      })
+    },
+    handleError() {
+      this.$message({
+        message: '上传失败!',
+        type: 'error',
+      })
     },
+
     // 在缩放模式下的大小
     getPXUnderScale(px) {
       return this.bigscreenScaleInWorkbench * px;
@@ -792,22 +849,28 @@ export default {
 .mr10 {
   margin-right: 10px;
 }
+
 .ml20 {
   margin-left: 20px;
 }
+
 .border-right {
   border-right: 1px solid #273b4d;
 }
+
 .border-left {
   border-left: 1px solid #273b4d;
 }
+
 .el-icon-arrow-down {
   font-size: 10px;
 }
+
 .is-active {
   background: #31455d !important;
   color: #bfcbd9 !important;
 }
+
 .layout {
   display: -webkit-box;
   display: -ms-flexbox;
@@ -817,6 +880,7 @@ export default {
   -webkit-box-sizing: border-box;
   box-sizing: border-box;
   overflow: hidden;
+
   .layout-left {
     display: inline-block;
     height: 100%;
@@ -849,6 +913,7 @@ export default {
         border: 1px solid #3a4659;
         background: #282a30;
       }
+
       .tools-item-text {
       }
     }
@@ -865,6 +930,7 @@ export default {
     background-color: #242a30;
     cursor: pointer;
     padding-top: 26%;
+
     i {
       font-size: 18px;
       width: 18px;
@@ -886,18 +952,21 @@ export default {
     align-items: center;
     vertical-align: middle;
     text-align: center;
+
     .top-button {
       display: flex;
       flex-direction: row;
       height: 40px;
       line-height: 40px;
       margin-left: 9px;
+
       .btn {
         color: #788994;
         width: 55px;
         text-align: center;
         display: block;
         cursor: pointer;
+
         .el-icon-arrow-down {
           transform: rotate(0deg);
           -ms-transform: rotate(0deg); /* IE 9 */
@@ -906,8 +975,10 @@ export default {
           -o-transform: rotate(0deg); /* Opera */
           transition: all 0.4s ease-in-out;
         }
+
         &:hover {
           background: rgb(25, 29, 34);
+
           .el-icon-arrow-down {
             transform: rotate(180deg);
             -ms-transform: rotate(180deg); /* IE 9 */
@@ -919,6 +990,7 @@ export default {
         }
       }
     }
+
     .workbench-container {
       position: relative;
       -webkit-transform-origin: 0 0;
@@ -927,10 +999,12 @@ export default {
       box-sizing: border-box;
       margin: 0;
       padding: 0;
+
       .vueRuler {
         width: 100%;
         padding: 18px 0px 0px 18px;
       }
+
       .workbench {
         background-color: #1e1e1e;
         position: relative;
@@ -943,6 +1017,7 @@ export default {
         margin: 0;
         padding: 0;
       }
+
       .bg-grid {
         position: absolute;
         top: 0;
@@ -953,11 +1028,12 @@ export default {
         background-image: linear-gradient(
             hsla(0, 0%, 100%, 0.1) 1px,
             transparent 0
-          ),
-          linear-gradient(90deg, hsla(0, 0%, 100%, 0.1) 1px, transparent 0);
+        ),
+        linear-gradient(90deg, hsla(0, 0%, 100%, 0.1) 1px, transparent 0);
         // z-index: 2;
       }
     }
+
     .bottom-text {
       width: 100%;
       color: #a0a0a0;
@@ -972,36 +1048,43 @@ export default {
     height: 100%;
   }
 
-  /deep/.el-tabs--border-card {
+  /deep/ .el-tabs--border-card {
     border: 0;
+
     .el-tabs__header {
       .el-tabs__nav {
         .el-tabs__item {
           background-color: #242f3b;
           border: 0px;
         }
+
         .el-tabs__item.is-active {
           background-color: #31455d;
         }
       }
     }
+
     .el-tabs__content {
       background-color: #242a30;
       height: calc(100vh - 39px);
       overflow-x: hidden;
       overflow-y: auto;
+
       .el-tab-pane {
         color: #bfcbd9;
       }
+
       &::-webkit-scrollbar {
         width: 5px;
         height: 14px;
       }
+
       &::-webkit-scrollbar-track,
       &::-webkit-scrollbar-thumb {
         border-radius: 1px;
         border: 0 solid transparent;
       }
+
       &::-webkit-scrollbar-track-piece {
         /*修改滚动条的背景和圆角*/
         background: #29405c;
@@ -1011,14 +1094,17 @@ export default {
       &::-webkit-scrollbar-track {
         box-shadow: 1px 1px 5px rgba(116, 148, 170, 0.5) inset;
       }
+
       &::-webkit-scrollbar-thumb {
         min-height: 20px;
         background-clip: content-box;
         box-shadow: 0 0 0 5px rgba(116, 148, 170, 0.5) inset;
       }
+
       &::-webkit-scrollbar-corner {
         background: transparent;
       }
+
       /*修改垂直滚动条的样式*/
       &::-webkit-scrollbar-thumb:vertical {
         background-color: #00113a;
@@ -1033,34 +1119,41 @@ export default {
     }
   }
 }
+
 ul,
 li {
   list-style: none;
   margin: 0;
   padding: 0;
 }
+
 .nav {
   width: 40px;
   padding: 0;
   list-style: none;
   /* overflow: hidden; */
 }
+
 .nav {
   zoom: 1;
 }
+
 .nav:before,
 .nav:after {
   content: "";
   display: table;
 }
+
 .nav:after {
   clear: both;
 }
+
 .nav li {
   width: 55px;
   text-align: center;
   position: relative;
 }
+
 .nav li a {
   float: left;
   padding: 12px 30px;
@@ -1068,9 +1161,11 @@ li {
   font: bold 12px;
   text-decoration: none;
 }
+
 .nav li:hover {
   color: #788994;
 }
+
 .nav li ul {
   visibility: hidden;
   position: absolute;
@@ -1085,14 +1180,17 @@ li {
   width: 120px;
   transition: all 0.2s ease-in-out;
 }
+
 .nav li:hover > ul {
   opacity: 1;
   visibility: visible;
   margin: 0;
+
   li:hover {
     background-color: rgb(25, 29, 34);
   }
 }
+
 .nav ul li {
   float: left;
   display: block;
@@ -1100,6 +1198,7 @@ li {
   width: 100%;
   font-size: 12px;
 }
+
 .nav ul a {
   padding: 10px;
   width: 100%;
@@ -1110,12 +1209,15 @@ li {
   background-color: rgb(25, 29, 34);
   transition: all 0.2s ease-in-out;
 }
+
 .nav ul a:hover {
   border: 1px solid #3c5e88;
 }
+
 .nav ul li:first-child > a:hover:before {
   border-bottom-color: #04acec;
 }
+
 .nav ul ul {
   top: 0;
   left: 120px;
@@ -1125,6 +1227,7 @@ li {
   padding: 10px;
   _margin: 0;
 }
+
 .nav ul ul li {
   width: 120px;
   height: 120px;
@@ -1132,10 +1235,12 @@ li {
   display: block;
   float: left;
 }
-/deep/.vue-ruler-h {
+
+/deep/ .vue-ruler-h {
   opacity: 0.3;
 }
-/deep/.vue-ruler-v {
+
+/deep/ .vue-ruler-v {
   opacity: 0.3;
 }
 </style>