Kaynağa Gözat

海报保存

Tang 2 yıl önce
ebeveyn
işleme
41c1e791de

+ 1 - 0
package.json

@@ -48,6 +48,7 @@
     "fuse.js": "6.4.3",
     "gsap": "^3.11.4",
     "highlight.js": "9.18.5",
+    "html2canvas": "^1.4.1",
     "js-beautify": "1.13.0",
     "js-cookie": "2.2.1",
     "js-md5": "^0.7.3",

+ 228 - 169
src/components/modelView/index.vue

@@ -1,177 +1,236 @@
 <template>
-    <div id="left" class="left">
+  <div
+    id="left"
+    class="left"
+    ref="modelView"
+    :style="IMGSHOW ? '' : 'border:none'"
+  >
+    <img
+      :style="modelData.background.css"
+      v-if="modelData.background.checked"
+      :src="modelData.background.name"
+      alt=""
+      crossorigin="anonymous"
+    />
+    <!-- 标题 -->
+    <vue-draggable-resizable
+      @dragstop="onDragstop1"
+      @resizestop="onResizeStop1"
+      :w="modelData.title.width"
+      :h="modelData.title.height"
+      :x="modelData.title.left"
+      :y="modelData.title.top"
+      :parent="true"
+      v-if="modelData.title.checked"
+    >
+      <p :style="modelData.title.css">{{ modelData.title.name }}</p>
+    </vue-draggable-resizable>
+    <!-- 商品图 -->
+    <vue-draggable-resizable
+      @dragstop="onDragstop2"
+      @resizestop="onResizeStop2"
+      :w="modelData.goods.width"
+      :h="modelData.goods.height"
+      :x="modelData.goods.left"
+      :y="modelData.goods.top"
+      :parent="true"
+      v-if="modelData.goods.checked"
+      :style="
+        modelData.goods.name ? '' : 'border: 1px dotted rgba(225,225,225,.4)'
+      "
+    >
       <img
-        :style="modelData.background.css"
-        v-if="modelData.background.checked"
-        :src="modelData.background.name"
+        crossorigin="anonymous"
+        v-if="modelData.goods.name"
+        :style="modelData.goods.css"
+        :src="$methodsTools.splitImgHost(modelData.goods.name)"
         alt=""
       />
-      <!-- 标题 -->
-      <vue-draggable-resizable
-        @dragstop="onDragstop1"
-        @resizestop="onResizeStop1"
-        :w="modelData.title.width"
-        :h="modelData.title.height"
-        :x="modelData.title.left"
-        :y="modelData.title.top"
-        :parent="true"
-        v-if="modelData.title.checked"
-      >
-        <p :style="modelData.title.css">{{ modelData.title.name }}</p>
-      </vue-draggable-resizable>
-      <!-- 商品图 -->
-      <vue-draggable-resizable
-        @dragstop="onDragstop2"
-        @resizestop="onResizeStop2"
-        :w="modelData.goods.width"
-        :h="modelData.goods.height"
-        :x="modelData.goods.left"
-        :y="modelData.goods.top"
-        :parent="true"
-        v-if="modelData.goods.checked"
-      >
-        <img :style="modelData.goods.css" :src="modelData.goods.name" alt="" />
-      </vue-draggable-resizable>
-      <!-- 分销码 -->
-      <vue-draggable-resizable
-        @dragstop="onDragstop3"
-        @resizestop="onResizeStop3"
-        :w="modelData.distribution.width"
-        :h="modelData.distribution.height"
-        :x="modelData.distribution.left"
-        :y="modelData.distribution.top"
-        :parent="true"
-        v-if="modelData.distribution.checked"
-      >
-        <img
-          :style="modelData.distribution.css"
-          :src="modelData.distribution.name"
-          alt=""
-        />
-      </vue-draggable-resizable>
-      <!-- 电子名片码 -->
-      <vue-draggable-resizable
-        @dragstop="onDragstop4"
-        @resizestop="onResizeStop4"
-        :w="modelData.cardCode.width"
-        :h="modelData.cardCode.height"
-        :x="modelData.cardCode.left"
-        :y="modelData.cardCode.top"
-        :parent="true"
-        v-if="modelData.cardCode.checked"
-      >
-        <img
-          :style="modelData.cardCode.css"
-          :src="modelData.cardCode.name"
-          alt=""
-        />
-      </vue-draggable-resizable>
-      <!-- 广告语 -->
-      <vue-draggable-resizable
-        @dragstop="onDragstop5"
-        @resizestop="onResizeStop5"
-        :w="modelData.advertise.width"
-        :h="modelData.advertise.height"
-        :x="modelData.advertise.left"
-        :y="modelData.advertise.top"
-        :parent="true"
-        v-if="modelData.advertise.checked"
-      >
-        <p :style="modelData.advertise.css">{{ modelData.advertise.name }}</p>
-      </vue-draggable-resizable>
-      <!-- 机构 -->
-      <vue-draggable-resizable
-        @dragstop="onDragstop6"
-        @resizestop="onResizeStop6"
-        :w="modelData.mechanism.width"
-        :h="modelData.mechanism.height"
-        :x="modelData.mechanism.left"
-        :y="modelData.mechanism.top"
-        :parent="true"
-        v-if="modelData.mechanism.checked"
-      >
-        <p :style="modelData.mechanism.css">{{ modelData.mechanism.name }}</p>
-      </vue-draggable-resizable>
-    </div>
-  </template>
-  
-  <script>
-  import VueDraggableResizable from "vue-draggable-resizable";
-  import "vue-draggable-resizable/dist/VueDraggableResizable.css";
-  export default {
-    components: { VueDraggableResizable },
-    props: {
-      modelData: {
-        type: Object,
-        default: () => {
-          return {};
-        },
+    </vue-draggable-resizable>
+    <!-- 分销码 -->
+    <vue-draggable-resizable
+      @dragstop="onDragstop3"
+      @resizestop="onResizeStop3"
+      :w="modelData.distribution.width"
+      :h="modelData.distribution.height"
+      :x="modelData.distribution.left"
+      :y="modelData.distribution.top"
+      :parent="true"
+      v-if="modelData.distribution.checked"
+      v-show="IMGSHOW"
+      style="border: 1px solid skyblue"
+    >
+      <!-- <img
+        :style="modelData.distribution.css"
+        :src="modelData.distribution.name"
+        alt=""
+      /> -->
+    </vue-draggable-resizable>
+    <!-- 电子名片码 -->
+    <vue-draggable-resizable
+      @dragstop="onDragstop4"
+      @resizestop="onResizeStop4"
+      :w="modelData.cardCode.width"
+      :h="modelData.cardCode.height"
+      :x="modelData.cardCode.left"
+      :y="modelData.cardCode.top"
+      :parent="true"
+      v-if="modelData.cardCode.checked"
+      v-show="IMGSHOW"
+      style="border: 1px solid skyblue"
+    >
+      <!-- <img
+        :style="modelData.cardCode.css"
+        :src="modelData.cardCode.name"
+        alt=""
+      /> -->
+    </vue-draggable-resizable>
+    <!-- 广告语 -->
+    <vue-draggable-resizable
+      @dragstop="onDragstop5"
+      @resizestop="onResizeStop5"
+      :w="modelData.advertise.width"
+      :h="modelData.advertise.height"
+      :x="modelData.advertise.left"
+      :y="modelData.advertise.top"
+      :parent="true"
+      v-if="modelData.advertise.checked"
+    >
+      <p :style="modelData.advertise.css">{{ modelData.advertise.name }}</p>
+    </vue-draggable-resizable>
+    <!-- 机构 -->
+    <vue-draggable-resizable
+      @dragstop="onDragstop6"
+      @resizestop="onResizeStop6"
+      :w="modelData.mechanism.width"
+      :h="modelData.mechanism.height"
+      :x="modelData.mechanism.left"
+      :y="modelData.mechanism.top"
+      :parent="true"
+      v-if="modelData.mechanism.checked"
+    >
+      <p :style="modelData.mechanism.css">{{ modelData.mechanism.name }}</p>
+    </vue-draggable-resizable>
+  </div>
+</template>
+
+<script>
+import html2Canvas from "html2canvas";
+import VueDraggableResizable from "vue-draggable-resizable";
+import "vue-draggable-resizable/dist/VueDraggableResizable.css";
+export default {
+  components: { VueDraggableResizable },
+  props: {
+    modelData: {
+      type: Object,
+      default: () => {
+        return {};
       },
     },
-    data() {
-      return {};
+  },
+  data() {
+    return {
+      IMGSHOW: true, //截图过程先隐藏二维码窗口
+    };
+  },
+  methods: {
+    //标签转oss图片路径
+    changeFile() {
+      return new Promise((resolve, reject) => {
+        this.IMGSHOW = false;
+        this.$nextTick(() => {
+          html2Canvas(this.$refs.modelView, { useCORS: true, allowTaint: true })
+            .then((canvas) => {
+              const jpeg = canvas.toDataURL("image/jpeg", 1.0);
+              this.$upload
+                .upload(this.base64ToFile(jpeg), 0)
+                .then((res) => {
+                  resolve(res);
+                })
+                .catch(() => {
+                  reject();
+                });
+            })
+            .catch(() => {
+              reject();
+            })
+            .finally(() => {
+              this.IMGSHOW = true;
+            });
+        });
+      });
     },
-    methods: {
-      onDragstop1(left, top) {
-        this.backData("title", left, top);
-      },
-      onResizeStop1(left, top, width, height) {
-        this.backData("title", left, top, width, height);
-      },
-      onDragstop2(left, top) {
-        this.backData("goods", left, top);
-      },
-      onResizeStop2(left, top, width, height) {
-        this.backData("goods", left, top, width, height);
-      },
-      onDragstop3(left, top) {
-        this.backData("distribution", left, top);
-      },
-      onResizeStop3(left, top, width, height) {
-        this.backData("distribution", left, top, width, height);
-      },
-      onDragstop4(left, top) {
-        this.backData("cardCode", left, top);
-      },
-      onResizeStop4(left, top, width, height) {
-        this.backData("cardCode", left, top, width, height);
-      },
-      onDragstop5(left, top) {
-        this.backData("advertise", left, top);
-      },
-      onResizeStop5(left, top, width, height) {
-        this.backData("advertise", left, top, width, height);
-      },
-      onDragstop6(left, top) {
-        this.backData("mechanism", left, top);
-      },
-      onResizeStop6(left, top, width, height) {
-        this.backData("mechanism", left, top, width, height);
-      },
-  
-      backData(name, left, top, width, height) {
-        this.$emit("changeModelData", { name, left, top, width, height });
-      },
+    //格式转换
+    base64ToFile(urlData) {
+      const arr = urlData.split(",");
+      const mime = arr[0].match(/:(.*?);/)[1];
+      const bytes = atob(arr[1]);
+      let n = bytes.length;
+      const ia = new Uint8Array(n);
+      while (n--) {
+        ia[n] = bytes.charCodeAt(n);
+      }
+      return new File([ia], "jpeg", { type: mime });
+    },
+    onDragstop1(left, top) {
+      this.backData("title", left, top);
+    },
+    onResizeStop1(left, top, width, height) {
+      this.backData("title", left, top, width, height);
+    },
+    onDragstop2(left, top) {
+      this.backData("goods", left, top);
+    },
+    onResizeStop2(left, top, width, height) {
+      this.backData("goods", left, top, width, height);
+    },
+    onDragstop3(left, top) {
+      this.backData("distribution", left, top);
+    },
+    onResizeStop3(left, top, width, height) {
+      this.backData("distribution", left, top, width, height);
+    },
+    onDragstop4(left, top) {
+      this.backData("cardCode", left, top);
+    },
+    onResizeStop4(left, top, width, height) {
+      this.backData("cardCode", left, top, width, height);
+    },
+    onDragstop5(left, top) {
+      this.backData("advertise", left, top);
+    },
+    onResizeStop5(left, top, width, height) {
+      this.backData("advertise", left, top, width, height);
+    },
+    onDragstop6(left, top) {
+      this.backData("mechanism", left, top);
+    },
+    onResizeStop6(left, top, width, height) {
+      this.backData("mechanism", left, top, width, height);
+    },
+
+    backData(name, left, top, width, height) {
+      this.$emit("changeModelData", { name, left, top, width, height });
     },
-  };
-  </script>
-  
-  <style lang="scss" scoped>
-  #left {
-    position: relative;
-    width: 375px;
-    height: 667px;
-    border: 1px solid #333;
-    margin-right: 20px;
-    flex-shrink: 0;
-    box-sizing: content-box;
-    overflow: hidden;
-  }
-  .vdr {
-    border-color: transparent;
-  }
-  .active {
-    border: 1px dashed #000;
-  }
-  </style>
-  
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+#left {
+  position: relative;
+  width: 375px;
+  height: 667px;
+  border: 1px solid #333;
+  margin-right: 20px;
+  flex-shrink: 0;
+  box-sizing: content-box;
+  overflow: hidden;
+}
+.vdr {
+  border-color: transparent;
+}
+.active {
+  border: 1px dashed #000;
+}
+</style>

+ 1 - 0
src/permission.js

@@ -53,6 +53,7 @@ router.beforeEach((to, from, next) => {
           if (!to.path.includes('/user/profile')) {
             checkFunc()
           }
+          console.log("to:",to)
           next()
         }
       }

+ 1 - 0
src/store/modules/permission.js

@@ -63,6 +63,7 @@ const permission = {
           const rdata = JSON.parse(JSON.stringify(res.data))
           const sidebarRoutes = filterAsyncRouter(sdata)
           const rewriteRoutes = filterAsyncRouter(rdata, false, true)
+          console.log("rewriteRoutes:",rewriteRoutes)
           rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
           commit('SET_ROUTES', rewriteRoutes)
           commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))

+ 8 - 0
src/views/2Cport/pageSettings/H5_small.vue

@@ -69,6 +69,14 @@
       <el-form-item label="Pc域名" prop="hostPc">
         <el-input v-model="moveInfo.hostPc" disabled></el-input>
       </el-form-item>
+      <el-form-item label="PC小程序" prop="smallQrCodeShow">
+        <el-switch
+          v-model="moveInfo.smallQrCodeShow"
+          active-color="#13ce66"
+          inactive-color="#ff4949"
+        >
+        </el-switch>
+      </el-form-item>
       <el-form-item>
         <el-button
           size="small"

+ 122 - 84
src/views/Marketing/activitySystem/posterList/model.vue

@@ -13,82 +13,87 @@
         </div>
       </div>
       <div id="content">
-    <modelView
-      ref="modelView"
-      :modelData="modelData"
-      @changeModelData="changeModelData"
-    ></modelView>
-    <div class="right">
-      <div class="lis">
-        <el-checkbox v-model="modelData.title.checked">标题:</el-checkbox
-        ><el-input v-model="modelData.title.name"></el-input
-        ><el-color-picker
-          v-model="modelData.title.css.color"
-          show-alpha
-        ></el-color-picker>
-        <el-input
-          placeholder="请输入字体大小"
-          v-model="modelData.title.css.fontSize"
-        >
-          <template slot="prepend">字体大小</template></el-input
-        >
-      </div>
-      <div class="lis">
-        <el-checkbox v-model="modelData.background.checked"
-          >背景图:</el-checkbox
-        ><el-select v-model="modelData.background.name" placeholder="请选择">
-          <el-option
-            v-for="(item, index) in backImgList"
-            :key="index"
-            :label="item.label"
-            :value="item.name"
-          >
-          </el-option>
-        </el-select>
-      </div>
-      <div class="lis">
-        <el-checkbox v-model="modelData.goods.checked">商品图:</el-checkbox
-        ><input id="goods" type="file" />
-      </div>
-      <div class="lis">
-        <el-checkbox v-model="modelData.distribution.checked"
-          >分销码</el-checkbox
-        >
-        <el-checkbox v-model="modelData.cardCode.checked"
-          >电子名片码</el-checkbox
-        >
-      </div>
-      <div class="lis">
-        <el-checkbox v-model="modelData.advertise.checked">广告语:</el-checkbox
-        ><el-input v-model="modelData.advertise.name"></el-input
-        ><el-color-picker
-          v-model="modelData.advertise.css.color"
-          show-alpha
-        ></el-color-picker>
-        <el-input
-          placeholder="请输入字体大小"
-          v-model="modelData.advertise.css.fontSize"
-        >
-          <template slot="prepend">字体大小</template></el-input
-        >
-      </div>
-      <div class="lis">
-        <el-checkbox v-model="modelData.mechanism.checked">机构:</el-checkbox
-        ><el-input v-model="modelData.mechanism.name"></el-input
-        ><el-color-picker
-          v-model="modelData.mechanism.css.color"
-          show-alpha
-        ></el-color-picker>
-        <el-input
-          placeholder="请输入字体大小"
-          v-model="modelData.mechanism.css.fontSize"
-        >
-          <template slot="prepend">字体大小</template></el-input
-        >
+        <modelView
+          ref="modelView"
+          :modelData="modelData"
+          @changeModelData="changeModelData"
+        ></modelView>
+        <div class="right">
+          <div class="lis">
+            <el-checkbox v-model="modelData.title.checked">标题:</el-checkbox
+            ><el-input v-model="modelData.title.name"></el-input
+            ><el-color-picker
+              v-model="modelData.title.css.color"
+              show-alpha
+            ></el-color-picker>
+            <el-input
+              placeholder="请输入字体大小"
+              v-model="modelData.title.css.fontSize"
+            >
+              <template slot="prepend">字体大小</template></el-input
+            >
+          </div>
+          <div class="lis">
+            <el-checkbox v-model="modelData.background.checked"
+              >背景图:</el-checkbox
+            ><el-select
+              v-model="modelData.background.name"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="(item, index) in backImgList"
+                :key="index"
+                :label="item.label"
+                :value="item.name"
+              >
+              </el-option>
+            </el-select>
+          </div>
+          <div class="lis">
+            <el-checkbox v-model="modelData.goods.checked">商品图:</el-checkbox
+            ><input id="goods" type="file" @change="uploadImg" />
+          </div>
+          <div class="lis">
+            <el-checkbox v-model="modelData.distribution.checked"
+              >分销码</el-checkbox
+            >
+            <el-checkbox v-model="modelData.cardCode.checked"
+              >电子名片码</el-checkbox
+            >
+          </div>
+          <div class="lis">
+            <el-checkbox v-model="modelData.advertise.checked"
+              >广告语:</el-checkbox
+            ><el-input v-model="modelData.advertise.name"></el-input
+            ><el-color-picker
+              v-model="modelData.advertise.css.color"
+              show-alpha
+            ></el-color-picker>
+            <el-input
+              placeholder="请输入字体大小"
+              v-model="modelData.advertise.css.fontSize"
+            >
+              <template slot="prepend">字体大小</template></el-input
+            >
+          </div>
+          <div class="lis">
+            <el-checkbox v-model="modelData.mechanism.checked"
+              >机构:</el-checkbox
+            ><el-input v-model="modelData.mechanism.name"></el-input
+            ><el-color-picker
+              v-model="modelData.mechanism.css.color"
+              show-alpha
+            ></el-color-picker>
+            <el-input
+              placeholder="请输入字体大小"
+              v-model="modelData.mechanism.css.fontSize"
+            >
+              <template slot="prepend">字体大小</template></el-input
+            >
+          </div>
+          <el-button @click="submits">保存</el-button>
+        </div>
       </div>
-      <el-button @click="submits">保存</el-button>
-    </div>
-  </div>
       <span slot="footer" class="dialog-footer">
         <el-button @click="close">取 消</el-button>
         <el-button
@@ -112,7 +117,7 @@ export default {
       disabledBtn: false,
       //   弹窗数据
       listData: {},
-      
+
       backImgList: [
         { label: "模板1", name: require("@/assets/model_images/model1.png") },
         { label: "模板2", name: require("@/assets/model_images/model2.png") },
@@ -138,11 +143,12 @@ export default {
           css: {
             textAlign: "center",
             fontSize: "30px",
-            margin:"0px"
+            margin: "0px",
           },
         },
         goods: {
-          name: require("@/assets/model_images/model1.png"),
+          // name: require("@/assets/model_images/model1.png"),
+          name: "",
           top: 126,
           left: 28,
           width: 330,
@@ -153,7 +159,7 @@ export default {
           },
         },
         distribution: {
-          name: require("@/assets/model_images/model1.png"),
+          name: "",
           top: 476,
           left: 114,
           width: 121,
@@ -164,7 +170,7 @@ export default {
           },
         },
         cardCode: {
-          name: require("@/assets/model_images/model1.png"),
+          name: "",
           top: 476,
           left: 244,
           width: 125,
@@ -182,7 +188,7 @@ export default {
           height: 96,
           css: {
             fontSize: "20px",
-            margin:"0px"
+            margin: "0px",
           },
         },
         mechanism: {
@@ -194,7 +200,7 @@ export default {
           css: {
             fontSize: "16px",
             textAlign: "center",
-            margin:"0px"
+            margin: "0px",
           },
         },
       },
@@ -216,8 +222,9 @@ export default {
     close() {
       this.dialogVisible = false;
     },
-    submits() {
-      console.log(this.modelData);
+    async submits() {
+      const imgUrl = await this.$refs.modelView.changeFile();
+      console.log(imgUrl, this.modelData);
     },
     changeModelData(data) {
       const { name, left, top, width, height } = data;
@@ -234,6 +241,37 @@ export default {
         }
       }
     },
+    uploadImg(e) {
+      var self = this;
+      var file = e.target.files[0];
+      if (file === undefined) {
+        self.$set(self.listData, "coverUrl", "");
+        return;
+      }
+      if (file.size > 0.3 * 1024 * 1024) {
+        self.$message.error("图片不得大于300kb");
+        return;
+      }
+      var type = e.target.value.toLowerCase().split(".").splice(-1);
+      if (
+        type[0] != "jpg" &&
+        type[0] != "png" &&
+        type[0] != "jpeg" &&
+        type[0] != "gif"
+      ) {
+        self.$message.error("上传格式需为:.jpg/.png/.jpeg/gif");
+        e.target.value = "";
+        return;
+      }
+      this.$upload
+        .upload(file, 0)
+        .then((res) => {
+          this.$set(this.modelData.goods, "name", res);
+        })
+        .finally(() => {
+          e.target.value = "";
+        });
+    },
   },
 };
 </script>