Эх сурвалжийг харах

1.增加撤销和恢复功能
2.优化从工具栏拖拽组件到画布时组件初始位置

tclqwl 3 жил өмнө
parent
commit
482c865f92

+ 102 - 0
report-ui/src/utils/revoke.js

@@ -0,0 +1,102 @@
+/**
+  撤销重做功能
+ * @Author: eyas66
+ * @Mail: 33955341@qq.com
+ * @Date: 2021-12-13 10:09:23
+ * @Last Modified by:   eyas66
+ * @Last Modified time: 2021-12-13 10:09:23
+ */
+export class Revoke {
+    // 历史记录
+    recordList = [];
+
+    // 撤销记录,用于重做
+    redoList = [];
+
+    // 当前记录用currentRecord变量暂时存储,当用户修改时,再存放到recordList
+    currentRecord = null;
+
+    // 上次插入数据时间
+    time = 0;
+
+    /**
+     * @description: 插入历史记录
+     * @param {object}record
+     * @return {boolean}
+     */
+    push(record) {
+        const nowTime = Date.now();
+        // 防止添加重复的时间,当添加间隔小于100ms时,则替换当前记录并取消执行添加
+        if (this.time + 100 > nowTime) {
+            this.currentRecord = JSON.stringify(record);
+            return false;
+        }
+
+        this.time = nowTime;
+
+        // 判断之前是否已经存在currentRecord记录,有则存储到recordList
+        if (this.currentRecord) {
+            this.recordList.push(this.currentRecord);
+            //(清空记录)增加记录后则应该清空重做记录
+            //splice() 方法向/从数组添加/删除项目,并返回删除的项目。
+            this.redoList.splice(0, this.redoList.length);
+        }
+
+        // 将json转成字符串存储
+        this.currentRecord = JSON.stringify(record);
+
+        // 最多存储2000条记录,超过2000条记录则删除之前的记录
+        if (this.length > 2000) {
+            //unshift() 方法将新项添加到数组的开头,并返回新的长度。
+            this.recordList.unshift();
+        }
+
+        return true;
+    }
+
+    /**
+     * @description: 撤销操作
+     * @param {*}
+     * @return {object}
+     */
+    undo() {
+        // 没有记录时,返回false
+        // 新建的recordList里面,不知为什么会存在一条记录,未找到原因,所以就判断长度为1时就不能撤销了。
+        if (this.recordList.length === 1 ) {
+            return false;
+        }
+        //pop(): 方法用于删除并返回数组的最后一个元素。
+        const record = this.recordList.pop();
+
+        // 将当前记录添加到重做记录里面
+        if (this.currentRecord) {
+            this.redoList.push(this.currentRecord);
+        }
+        // 丢弃当前记录,防止重复添加
+        this.currentRecord = null;
+        //返回撤销的记录
+        return JSON.parse(record);
+    }
+
+    /**
+     * @description: 重做操作
+     * @param {*}
+     * @return {*}
+     */
+    redo() {
+        // 没有重做记录时,返回false
+        if (this.redoList.length === 0) {
+            return false;
+        }
+        //pop(): 方法用于删除并返回数组的最后一个元素。
+        const record = this.redoList.pop();
+        // 添加到重做记录里面
+        if (this.currentRecord) {
+            this.recordList.push(this.currentRecord);
+        }
+        // 丢弃当前记录,防止重复添加
+        this.currentRecord = null;
+
+        return JSON.parse(record);
+    }
+}

+ 64 - 0
report-ui/src/views/bigscreenDesigner/designer/index.vue

@@ -88,6 +88,29 @@
             <i class="iconfont iconyulan" @click="viewScreen"></i>
           </el-tooltip>
         </span>
+
+        <span class="btn">
+          <el-tooltip
+            class="item"
+            effect="dark"
+            content="撤销"
+            placement="bottom"
+          >
+            <i class="iconfont" @click="handleUndo">撤销</i>
+          </el-tooltip>
+        </span>
+
+        <span class="btn">
+          <el-tooltip
+            class="item"
+            effect="dark"
+            content="恢复"
+            placement="bottom"
+          >
+            <i class="iconfont" @click="handleRedo">恢复</i>
+          </el-tooltip>
+        </span>
+
         <span class="btn" v-permission="'bigScreenManage:export'">
           <el-tooltip
             class="item"
@@ -263,6 +286,7 @@ import draggable from "vuedraggable";
 import VueRulerTool from "vue-ruler-tool"; // 大屏设计页面的标尺插件
 import contentMenu from "./components/contentMenu";
 import { getToken } from "@/utils/auth";
+import { Revoke } from '@/utils/revoke'    //处理历史记录 2022-02-22
 
 export default {
   name: "Login",
@@ -290,6 +314,7 @@ export default {
 
       bigscreenWidth: 1920, // 大屏设计的大小
       bigscreenHeight: 1080,
+      revoke: null, //处理历史记录 2022-02-22
 
       // 工作台大屏画布,保存到表gaea_report_dashboard中
       dashboard: {
@@ -395,10 +420,18 @@ export default {
     widgets: {
       handler(val) {
         this.handlerLayerWidget(val);
+        //以下部分是记录历史
+        this.$nextTick(() => {
+          this.revoke.push(this.widgets)
+        })
       },
       deep: true
     }
   },
+  created() {
+    /* 以下是记录历史的 */
+    this.revoke = new Revoke()
+  },
   mounted() {
     // 如果是新的设计工作台
     this.initEchartData();
@@ -408,6 +441,30 @@ export default {
     });
   },
   methods: {
+          /**
+     * @description: 恢复
+     * @param {*}
+     * @return {*}
+     */
+    handleUndo() {
+      const record = this.revoke.undo()
+      if (!record) {
+        return false
+      }
+      this.widgets = record
+    },
+    /**
+     * @description: 重做
+     * @param {*}
+     * @return {*}
+     */
+    handleRedo() {
+      const record = this.revoke.redo()
+      if (!record) {
+        return false
+      }
+      this.widgets = record
+    },
     handlerLayerWidget(val) {
       const layerWidgetArr = [];
       for (let i = 0; i < val.length; i++) {
@@ -639,6 +696,13 @@ export default {
       };
       // 处理默认值
       const widgetJsonValue = this.handleDefaultValue(widgetJson);
+
+      //2022年02月22日 修复:可以拖拽放到鼠标的位置
+      widgetJsonValue.value.position.left =
+        x - widgetJsonValue.value.position.width / 2
+      widgetJsonValue.value.position.top =
+        y - widgetJsonValue.value.position.height / 2
+
       // 将选中的复制组件,放到工作区中去
       this.widgets.push(this.deepClone(widgetJsonValue));
       // 激活新组件的配置属性