Jelajahi Sumber

refactor: 通用-->图片,右侧属性栏 组件替换 线型a-select改为el-select, 部分methods改为使用computed

yunxing 4 tahun lalu
induk
melakukan
11e11cfbe5

+ 171 - 152
src/components/editview/rightPropertyBar/BaseImagePro.vue

@@ -8,26 +8,14 @@
                 <div class="property">
                     <div>
                         <span>W</span>
-                        <el-input
-                            style="width: 74px; margin-left: 6px"
-                            size="mini"
-                            v-model="width"
-                            @input="changeWidth"
-                            placeholder="请输入内容"
-                        ></el-input>
+                        <el-input style="width: 74px; margin-left: 6px" size="mini" type="number" v-model="width" placeholder="输入宽度"></el-input>
                     </div>
                     <div>
                         <span>H</span>
-                        <el-input
-                            style="width: 74px; margin-left: 6px"
-                            size="mini"
-                            v-model="height"
-                            @input="changeHeight"
-                            placeholder="请输入内容"
-                        ></el-input>
+                        <el-input style="width: 74px; margin-left: 6px" size="mini" type="number" v-model="height" placeholder="输入高度"></el-input>
                     </div>
                     <div @click="lockItem" :title="isLock ? '锁定' : '解锁'">
-                        <Icon style="vertical-align: middle" :name="isLock ? 'lock' : 'unlock'" />
+                        <i class="el-icon-link" :style="{ color: isLock ? '#409EFF' : '', cursor: 'pointer' }"></i>
                     </div>
                 </div>
             </li>
@@ -53,30 +41,29 @@
                 <div class="property">
                     <div class="color-box">
                         <div class="cololorSelect">
-                            <el-color-picker show-alpha @change="changeColor" class="fix-box-1" v-model="color"></el-color-picker>
+                            <el-color-picker show-alpha class="fix-box-1" v-model="color"></el-color-picker>
                         </div>
-                        <span>颜色</span>
+                        <span class="text">颜色</span>
                     </div>
                     <div class="line-width">
-                        <el-input-number
-                            style="width: 80px"
-                            v-model="linewidth"
-                            controls-position="right"
-                            @change="changeLineWidth"
-                            size="mini"
-                            :min="1"
-                            :max="20"
-                            :maxlength="100"
-                        ></el-input-number>
-                        <span>线宽</span>
+                        <el-input style="width: 80px" v-model="lineWidth" type="number" size="mini" placeholder="输入线宽"></el-input>
+                        <span class="text">线宽</span>
                     </div>
                     <div class="line-width">
-                        <a-select style="width: 80px" v-model="linestyle" :default-value="borderLineOption[0].id" @change="changeLineStyle">
-                            <a-select-option v-for="item in borderLineOption" :key="item.id" :label="item.src" :value="item.id">
+                        <el-select
+                            v-model="lineStyle"
+                            popper-class="image-select"
+                            :default-value="borderLineOption[0].id"
+                            size="mini"
+                            style="width: 80px"
+                            placeholder="请选择"
+                            :ref="`selectLine`"
+                        >
+                            <el-option v-for="item in borderLineOption" :key="item.id" :label="item.src" :value="item.id">
                                 <img :src="item.src" alt width="60" />
-                            </a-select-option>
-                        </a-select>
-                        <span>线型</span>
+                            </el-option>
+                        </el-select>
+                        <span class="text">线型</span>
                     </div>
                 </div>
             </li>
@@ -85,18 +72,15 @@
 </template>
 <script>
 import bus from "@/bus/bus";
-const baseUrl = "/image-service/common/image_get?systemId=dataPlatform&key=";
-import { uploadGroup, getImageGroup } from "@/api/editer";
 import { imgBaseUrl, imgServeUpload } from "@/api/imageservice";
-
+import { SColor } from "@persagy-web/draw";
+import { rgbaNum } from "@persagy-web/big-edit/lib/until";
+import { findIndex } from "lodash";
+import { dataURLtoBlob } from "@/utils/utils";
 export default {
-    props: ["strokeColor", "lineStyle", "lineWidth", "Width", "Height"],
+    props: ["ImageItem"],
     data() {
         return {
-            width: 0,
-            height: 0,
-            color: "#cccccc", //颜色
-            linewidth: 1,
             borderLineOption: [
                 {
                     id: "Solid",
@@ -111,15 +95,105 @@ export default {
                     src: require("@/assets/images/dotLine.png"),
                 },
             ],
-            linestyle: "solid",
-            url: "",
-            isLock: true,
-            aspectRatio: 1, // 元素宽高比
+            isLock: true, //锁定图片宽高比
+            aspectRatio: 1, // 图片宽高比
         };
     },
-    mounted() {
-        window.vm = this;
+    computed: {
+        /**
+         * 图片宽度
+         */
+        width: {
+            get: function () {
+                return this.ImageItem.width || "";
+            },
+            set: function (newV) {
+                if (!newV) newV = 0;
+                newV = Number(newV);
+                const oldV = this.ImageItem.width;
+                if (this.isLock) {
+                    this.ImageItem.height = newV * this.aspectRatio;
+                }
+                this.ImageItem.width = newV;
+                bus.$emit("undoAttr", this.ImageItem, "width", oldV, newV);
+            },
+        },
+        /**
+         * 图片高度
+         */
+        height: {
+            get: function () {
+                return this.ImageItem.height || "";
+            },
+            set: function (newV) {
+                if (!newV) newV = 0;
+                newV = Number(newV);
+                const oldV = this.ImageItem.height;
+                if (this.isLock) {
+                    this.ImageItem.width = newV / this.aspectRatio;
+                }
+                this.ImageItem.height = newV;
+                console.log(newV, this.ImageItem.height);
+                bus.$emit("undoAttr", this.ImageItem, "height", oldV, newV);
+            },
+        },
+        /**
+         * 边框线宽
+         */
+        lineWidth: {
+            get: function () {
+                return this.ImageItem.lineWidth || "";
+            },
+            set: function (newV) {
+                if (!newV) newV = 0;
+                newV = Number(newV);
+                const oldV = this.ImageItem.lineWidth;
+                if (newV > 20) {
+                    this.ImageItem.lineWidth = 20;
+                } else {
+                    this.ImageItem.lineWidth = newV;
+                }
+                bus.$emit("undoAttr", this.ImageItem, "lineWidth", oldV, newV);
+            },
+        },
+        /**
+         * 边框颜色
+         */
+        color: {
+            get: function () {
+                return this.ImageItem.strokeColor.toRgba();
+            },
+            set: function (val) {
+                const colorList = rgbaNum(val);
+                const oldVal = this.ImageItem.strokeColor;
+                const newVal = new SColor(Number(colorList[0]), Number(colorList[1]), Number(colorList[2]), colorList[3] * 255);
+                this.ImageItem.strokeColor = newVal;
+                bus.$emit("undoAttr", this.ImageItem, "strokeColor", oldVal, newVal);
+            },
+        },
+        /**
+         * 边框线型
+         */
+        lineStyle: {
+            get: function () {
+                const id = this.borderLineOption[this.ImageItem.lineStyle].id;
+                // 修改线型下啦菜单样式
+                this.$nextTick(() => {
+                    this.setLineStyle(id);
+                });
+                return id;
+            },
+            set: function (newV) {
+                newV = findIndex(this.borderLineOption, ["id", newV]);
+                const oldV = this.ImageItem.lineStyle;
+                this.ImageItem.lineStyle = newV;
+                bus.$emit("undoAttr", this.ImageItem, "lineStyle", oldV, newV);
+            },
+        },
     },
+
+    watch: {},
+    mounted() {},
     methods: {
         /**
          * 切换锁状态
@@ -131,53 +205,47 @@ export default {
             }
         },
         /**
-         * 更改宽度
+         * 修改线型下啦菜单样式
+         * @param {String} id 选中的线型id
          */
-        changeWidth(val) {
-            bus.$emit("updateStyle", "width", val);
-            if (this.isLock) {
-                this.height = val * this.aspectRatio;
-                bus.$emit("updateStyle", "height", this.height);
+        setLineStyle(id) {
+            const img = this.borderLineOption.filter((v) => v.id === id)[0]?.src;
+            if (img) {
+                this.$refs.selectLine?.$el?.children[0].children[0].setAttribute(
+                    "style",
+                    `
+                        background: url(${img}) no-repeat;
+                        color: rgba(0,0,0,0);
+                        text-indent: -9999px;
+                        background-position: 15px center;
+                        background-size: 40px 1px;
+                    `
+                );
+            } else {
+                this.$refs.selectLine?.$el?.children[0].children[0].setAttribute(
+                    "style",
+                    `
+                        background: inherit;
+                        color:inherit;
+                        text-indent: 0;
+                    `
+                );
             }
         },
         /**
-         * 更改高度
+         * 图片上传
          */
-        changeHeight(val) {
-            bus.$emit("updateStyle", "height", val);
-            if (this.isLock) {
-                this.width = val / this.aspectRatio;
-                bus.$emit("updateStyle", "width", this.width);
-            }
-        },
-
-        /**
-         * 更改线宽
-         */
-        changeLineWidth(val) {
-            bus.$emit("updateStyle", "lineWidth", val);
-        },
-        // 改变线样式
-        changeLineStyle(val) {
-            bus.$emit("updateStyle", "lineStyle", val);
-        },
-        // 改变颜色
-        changeColor(val) {
-            bus.$emit("updateStyle", "strokeColor", val);
-        },
         beforeAvatarUpload(file) {
-            const that = this;
             const fileReader = new FileReader();
             fileReader.readAsDataURL(file); //读取图片
             const ftype = file.type;
             const fname = file.name;
             const uploadKey = file.uid;
-            const imgType = ftype.split(".")[ftype.length - 1];
-            fileReader.addEventListener("load", function () {
+            fileReader.addEventListener("load", () => {
                 // 读取完成
                 const res = fileReader.result;
                 //将canvas的base64位图片转换成图片png的file
-                const blob = that.dataURLtoBlob(res, ftype);
+                const blob = dataURLtoBlob(res, ftype);
                 //将其转换成file对象
                 const file = new File([blob], fname, {
                     type: ftype,
@@ -188,32 +256,26 @@ export default {
                 const reader = new FileReader();
                 const fileType = file.name.split(".");
                 const imgType = fileType[fileType.length - 1];
-                const CreateTime = that.formatDate(new Date(file.lastModified));
-                reader.onloadend = function () {
+                reader.onloadend = () => {
                     // 这个事件在读取结束后,无论成功或者失败都会触发
                     if (reader.error) {
                         //
                     } else {
                         // 构造 XMLHttpRequest 对象,发送文件 Binary 数据
                         const xhr = new XMLHttpRequest();
-                        // xhr.open(
-                        //     /* method */
-                        //     "POST",
-                        //     /* target url */
-                        //     "/image-service/common/image_upload?systemId=dataPlatform&secret=9e0891a7a8c8e885&overwrite=true" +
-                        //         "&key=" +
-                        //         uploadKey +
-                        //         "." +
-                        //         imgType
-                        // );
                         xhr.open("POST", `${imgServeUpload}${uploadKey}.${imgType}`);
                         xhr.send(reader.result);
-                        xhr.onreadystatechange = function () {
+                        xhr.onreadystatechange = () => {
                             if (xhr.readyState == 4) {
                                 if (xhr.status == 200) {
-                                    that.url = baseUrl + uploadKey + "." + imgType;
-                                    bus.$emit("updateStyle", "defaultUrl", uploadKey + "." + imgType);
-                                    bus.$emit("updateStyle", "url", baseUrl + uploadKey + "." + imgType);
+                                    const olDefaultUrl = this.ImageItem.defaultUrl;
+                                    const oldUrl = this.ImageItem.url;
+                                    const newDefaultUrl = `${uploadKey}.${imgType}`;
+                                    const newUrl = `${imgBaseUrl}${uploadKey}.${imgType}`;
+                                    bus.$emit("undoAttr", this.ImageItem, "defaultUrl", olDefaultUrl, newDefaultUrl);
+                                    bus.$emit("undoAttr", this.ImageItem, "url", oldUrl, newUrl);
+                                    this.ImageItem.defaultUrl = newDefaultUrl;
+                                    this.ImageItem.url = newUrl;
                                 }
                             }
                         };
@@ -222,60 +284,16 @@ export default {
                 reader.readAsArrayBuffer(file);
             });
         },
-        dataURLtoBlob(dataURI, type) {
-            const binary = atob(dataURI.split(",")[1]);
-            const array = [];
-            for (let i = 0; i < binary.length; i++) {
-                array.push(binary.charCodeAt(i));
-            }
-            return new Blob([new Uint8Array(array)], { type: type });
-        },
-        formatDate(now) {
-            const year = now.getFullYear();
-            const month = now.getMonth() + 1;
-            const date = now.getDate();
-            const hour = now.getHours();
-            const minute = now.getMinutes();
-            const second = now.getSeconds();
-            return (
-                year +
-                "-" +
-                month +
-                "-" +
-                (date > 10 ? date : "0" + date) +
-                " " +
-                hour +
-                ":" +
-                (minute > 10 ? minute : "0" + minute) +
-                ":" +
-                (second > 10 ? second : "0" + second)
-            );
-        },
-    },
-
-    watch: {
-        strokeColor(val) {
-            this.color = val;
-        },
-        lineWidth(val) {
-            this.linewidth = val;
-        },
-        lineStyle(val) {
-            this.linestyle = val;
-        },
-        Width(val) {
-            this.width = val;
-        },
-        Height(val) {
-            this.height = val;
-            this.aspectRatio = this.Width / this.Height;
-        },
-        Url(val) {
-            this.url = val;
-        },
     },
 };
 </script>
+<style lang="less">
+.image-select {
+    .el-select-dropdown__item {
+        text-align: center;
+    }
+}
+</style>
 <style lang="less" scoped>
 ul,
 li {
@@ -292,19 +310,18 @@ li {
         font-size: 14px;
         padding-left: 12px;
         box-sizing: border-box;
+        font-weight: 600;
     }
     ul {
-        // width: calc(100% - 24px);
-        // margin: -1px 12px 0 12px;
         width: 100%;
         li {
-            // border-top: 1px solid #979797;
             padding: 0 12px;
             margin-bottom: 16px;
             .small-title {
                 font-size: 14px;
                 color: #8d9399;
                 margin: 12px 0;
+                font-weight: 600;
             }
             .property {
                 display: flex;
@@ -337,9 +354,10 @@ li {
                     margin-left: 8px;
                     position: relative;
                 }
-                span {
+                .text {
                     font-size: 12px;
                     color: #1f2429;
+                    font-weight: 600;
                     margin-top: 4px;
                 }
             }
@@ -352,8 +370,9 @@ li {
                 padding: 0 12px;
                 margin-bottom: 12px;
                 color: #8d9399;
-                font-size: 12px;
+                font-size: 14px;
                 line-height: 16px;
+                font-weight: 600;
             }
 
             .avatar-uploader {

+ 2 - 1
src/components/editview/rightPropertyBar/property.vue

@@ -34,13 +34,14 @@
             "
         ></BaseGraphy>
         <BaseImagePro
+            :ImageItem="itemObj"
             :lineStyle="lineStyle"
             :lineWidth="lineWidth"
             :strokeColor="strokeColor"
             :Url="Url"
             :Width="Width"
             :Height="Height"
-            v-show="itemType == 'BaseImage'"
+            v-if="itemObj && itemType == 'BaseImage'"
         ></BaseImagePro>
         <BaseEquipment :EquipItem="itemObj" v-if="itemObj && itemType == 'BaseEquipment'"></BaseEquipment>
     </div>

+ 41 - 3
src/utils/utils.js

@@ -35,13 +35,13 @@ function array2Tree(arr, parentId, id = "id") {
  */
 function mapTree(tree, ...transfor) {
     //  传入数组
-    let arrayTree = Array.isArray(tree);
+    const arrayTree = Array.isArray(tree);
     if (arrayTree) {
         return tree.map((i) => mapTree(i, ...transfor));
     } else {
         // 传入对象
         const haveChildren = Array.isArray(tree.children) && tree.children.length;
-        let obj = {};
+        const obj = {};
         transfor.map((v) => {
             const key = v.split("->")[0],
                 newKey = v.split("->")[1];
@@ -58,4 +58,42 @@ function mapTree(tree, ...transfor) {
         };
     }
 }
-export { array2Tree, mapTree };
+/**
+ * 
+ * @param {*} dataURI 
+ * @param {*} type 
+ */
+function dataURLtoBlob(dataURI, type) {
+    const binary = atob(dataURI.split(",")[1]);
+    const array = [];
+    for (let i = 0; i < binary.length; i++) {
+        array.push(binary.charCodeAt(i));
+    }
+    return new Blob([new Uint8Array(array)], { type: type });
+}
+/**
+ * 格式化时间
+ * @param {Date} now 需要格式化的时间
+ */
+function formatDate(now) {
+    const year = now.getFullYear();
+    const month = now.getMonth() + 1;
+    const date = now.getDate();
+    const hour = now.getHours();
+    const minute = now.getMinutes();
+    const second = now.getSeconds();
+    return (
+        year +
+        "-" +
+        month +
+        "-" +
+        (date > 10 ? date : "0" + date) +
+        " " +
+        hour +
+        ":" +
+        (minute > 10 ? minute : "0" + minute) +
+        ":" +
+        (second > 10 ? second : "0" + second)
+    );
+}
+export { array2Tree, mapTree, dataURLtoBlob, formatDate };