Browse Source

日报分享

zhujindu 8 months ago
parent
commit
5c2f063271
4 changed files with 233 additions and 117 deletions
  1. 1 0
      package.json
  2. 164 91
      src/components/share copy.vue
  3. 67 25
      src/components/share.vue
  4. 1 1
      src/views/week/dailyApproval.vue

+ 1 - 0
package.json

@@ -20,6 +20,7 @@
     "core-js": "^3.6.5",
     "element-ui": "^2.15.6",
     "html2canvas": "^1.4.1",
+    "qrcodejs2": "^0.0.2",
     "vant": "^2.12.37",
     "vconsole": "^3.15.1",
     "vue": "^2.6.11",

+ 164 - 91
src/components/share copy.vue

@@ -9,43 +9,45 @@
           <img :src="require('@/assets/shareRight.png')" />
         </div>
       </div>
-      <div class="title">
-        <div class="name">{{ reportTarget.nickName }}的日报</div>
-        <div class="date">
-          {{
-            reportTarget.commitTime ? formatChineseDate(reportTarget.commitTime.split(' ')[0]) : ''
-          }}
-        </div>
-      </div>
       <div class="summaryDay">
-        <template v-for="(item, index) in reportTarget.reportContents"
+        <div class="title-box">
+          <div class="title">
+            <div class="name">{{ reportTarget.nickName }}的日报</div>
+            <div class="date">
+              {{
+                reportTarget.commitTime
+                  ? formatChineseDate(reportTarget.commitTime.split(' ')[0])
+                  : ''
+              }}
+            </div>
+          </div>
+        </div>
+        <template
+          v-for="(item, index) in reportTarget.reportContents"
           v-if="reportTarget.reportContents && reportTarget.reportContents.length > 0">
-          <div class="text">{{ filterText(index) }}</div>
+          <div :class="['text', 'text' + index]">{{ filterText(index) }}</div>
           <div class="content">{{ item.dayContent }}</div>
         </template>
         <div class="text">今日拜访照片</div>
         <div class="content-photos">
           <!-- <template v-for="item in reportTarget.photos">
-            <template v-for="item1 in item.photos">
-              <img :src="item1.baseUrl" crossorigin="anonymous" referrerpolicy="no-referrer" alt=""
-                style="display: block; width: 188px; height: 188px; object-fit: cover" v-if="item1.baseUrl" />
-            </template>photosData
-          </template> -->
+              <template v-for="item1 in item.photos">
+                <img :src="item1.baseUrl" crossorigin="anonymous" referrerpolicy="no-referrer" alt=""
+                  style="display: block; width: 188px; height: 188px; object-fit: cover" v-if="item1.baseUrl" />
+              </template>photosData
+            </template> -->
           <template v-for="item in photosData">
-            <img :src="item" crossorigin="anonymous" referrerpolicy="no-referrer" alt=""
-              style="display: block; width: 188px; height: 188px; object-fit: cover" />
+            <img
+              :src="item"
+              crossorigin="anonymous"
+              referrerpolicy="no-referrer"
+              alt=""
+              style="display: block" />
           </template>
         </div>
       </div>
       <div class="footerShare">
-        <div class="QRcodes">
-          <template v-if="processFlag == 'development'">
-            <img :src="require('@/assets/testQRcode.png')" />
-          </template>
-          <template v-else>
-            <img :src="require('@/assets/QRcode.png')" />
-          </template>
-        </div>
+        <div class="QRcodes" ref="QRcodes"></div>
         <div class="right-text">
           <div>长按识别二维码</div>
           <div>查看详情&点评</div>
@@ -58,7 +60,8 @@
   </div>
 </template>
 <script>
-import html2canvas from 'html2canvas'
+import html2canvas from 'html2canvas';
+import QRCode from 'qrcodejs2';
 export default {
   name: 'share',
   props: {
@@ -68,38 +71,47 @@ export default {
         return {};
       },
     },
+    reportId: {
+      type: [String, Number],
+    },
   },
   data() {
     return {
-      processFlag: '',
-      canvasImageUrl: "",
+      canvasImageUrl: '',
       retryCount: 0,
       photosData: [],
     };
   },
   created() {
-    this.processFlag = process.env.NODE_ENV;
-    let photos = this.reportTarget.photos;
-    let photosArr = [];
-    let num = 0
-    for (let i = 0; i < photos.length; i++) {
-      for (let j = 0; j < photos[i].photos.length; j++) {
-        this.imageUrlToBase64(photos[i].photos[j].fileUrl).then(base64 => {
-          // photos[i].photos[j].baseUrl = base64;
-          photosArr.push(base64)
-          num++
+    // this.toastLoading(0, '生成中...', true);
+    // 使用Promise.all确保所有图片加载完成
+    const photos = this.reportTarget.photos;
+    const photoPromises = [];
+
+    // 收集所有图片转换的Promise
+    photos.forEach((item) => {
+      item.photos.forEach((photo) => {
+        photoPromises.push(this.imageUrlToBase64(photo.fileUrl));
+      });
+    });
+
+    // 等待所有图片加载完成
+    Promise.all(photoPromises)
+      .then((photosArr) => {
+        this.photosData = photosArr;
+        this.$nextTick(async () => {
+          //   await this.htmlToCanvas();
         });
-      }
-      if (num == photosArr.length) {
-        this.photosData = photosArr
-        this.$nextTick(() => {
-          setTimeout(async () => {
-            await this.htmlToCanvas();
-          }, 2000)
-        })
-      }
-    }
-    console.log(photos)
+      })
+      .catch((error) => {
+        console.error('图片加载失败:', error);
+        this.$toast('图片加载失败,请检查网络');
+      });
+    console.log(photos);
+  },
+  mounted() {
+    // 二维码
+    this.creatQrCode();
   },
   methods: {
     //异步执行
@@ -111,11 +123,11 @@ export default {
         //解决跨域问题
         image.setAttribute('crossOrigin', 'anonymous');
 
-        image.src = imageUrl
+        image.src = imageUrl;
 
         //image.onload为异步加载
         image.onload = () => {
-          var canvas = document.createElement("canvas");
+          var canvas = document.createElement('canvas');
           canvas.width = image.width;
           canvas.height = image.height;
           var context = canvas.getContext('2d');
@@ -123,14 +135,14 @@ export default {
 
           var quality = 1;
           //这里的dataurl就是base64类型
-          let dataURL = canvas.toDataURL("image/png", quality);//使用toDataUrl将图片转换成jpeg的格式,不要把图片压缩成png,因为压缩成png后base64的字符串可能比不转换前的长!
-          resolve(dataURL)
-        }
+          let dataURL = canvas.toDataURL('image/png', quality); //使用toDataUrl将图片转换成jpeg的格式,不要把图片压缩成png,因为压缩成png后base64的字符串可能比不转换前的长!
+          resolve(dataURL);
+        };
 
         image.onerror = () => {
-          reject(new Error('图像加载失败'))
-        }
-      })
+          reject(new Error('图像加载失败'));
+        };
+      });
     },
     filterText(index) {
       if (index == 0) {
@@ -147,20 +159,30 @@ export default {
         allowTaint: false,
         backgroundColor: null,
         imageTimeout: 30000,
-        ignoreElements: (element) => element.id === 'html2canvas',
-        onclone: (clonedDoc) => {
-          // clonedDoc.getElementById('html2canvas').style.visibility = 'hidden';
-        }
       })
         .then((canvas) => {
+          this.toastLoading().clear();
           let imageUrl = canvas.toDataURL('image/png');
           this.canvasImageUrl = imageUrl;
         })
-        .catch(error => {
+        .catch((error) => {
+          this.toastLoading().clear();
           console.error('html2canvas error:', error);
           this.$toast('生成分享图失败,请稍后重试');
         });
-    }
+    },
+    creatQrCode() {
+      let devText = 'https://suishenbangtest.nipponpaint.com.cn/homeIndex';
+      let proText = 'https://suishenbang.nipponpaint.com.cn/homeIndex';
+      let text = process.env.NODE_ENV == 'development' ? devText : proText;
+      var qrcode = new QRCode(this.$refs.QRcodes, {
+        text: text + '?reportId=' + this.reportId || '', // 需要转换为二维码的内容
+        colorDark: '#000000',
+        colorLight: '#ffffff',
+        correctLevel: QRCode.CorrectLevel.H,
+      });
+      let logo = '../assets/logo1.png';
+    },
   },
 };
 </script>
@@ -169,8 +191,9 @@ export default {
   width: 100%;
   height: 100%;
   overflow: hidden;
-  // position: fixed;
-  // z-index: -1;
+  position: absolute;
+  top: 0;
+  z-index: 111;
 
   .share-content {
     background: url('../assets/shareBack.png') no-repeat center center;
@@ -178,10 +201,12 @@ export default {
     background-attachment: local;
     width: 100%;
     // height: 100%;
-    padding: vw(45);
-    // position: fixed;
+    padding: vw(30);
+    position: absolute;
     // z-index: -1;
     padding-bottom: vw(190);
+    top: 0;
+    z-index: 111111;
   }
 
   .header {
@@ -203,48 +228,71 @@ export default {
       height: 100%;
     }
   }
-
-  .title {
+  .title-box {
     display: flex;
-    justify-content: space-between;
-    color: #ecd98a;
-    font-size: vw(36);
-    font-weight: bold;
-    margin-top: vw(81);
+    justify-content: center;
+    align-items: center;
+    position: absolute;
+    top: -6px;
+    left: 50%;
+    margin-left: vw(-169);
+    .title {
+      color: #600d0e;
+      font-size: vw(36);
+      font-weight: bold;
+      // margin-top: vw(81);
+      //   width: vw(338);
+      //   height: vw(115);
+      text-align: center;
+      background: url('../assets/titleBack.png') no-repeat;
+      background-size: 100% 100%;
+      padding: vw(20) vw(30);
+    }
   }
 
   .summaryDay {
+    background: url('../assets/summaryDay.png') no-repeat;
+    background-size: 100%;
+    padding: vw(24);
+    position: relative;
+    margin-top: vw(55);
+    border-radius: 0 0 vw(35) vw(35);
     .text {
       background: url('../assets/textBack.png') no-repeat;
-      width: vw(595);
+      width: 100%;
       height: vw(94);
-      background-size: contain;
+      background-size: cover;
       color: #7d0207;
       font-size: vw(36);
       text-align: center;
       line-height: vw(94);
-      margin: vw(45) 0;
+      // margin-top: vw(152);
+      // margin-bottom: vw(45);
+      margin: vw(35) 0;
+      font-weight: bold;
+    }
+    .text0 {
+      margin-top: vw(152);
     }
 
     .content {
       font-size: vw(28);
       font-weight: bold;
-      color: #e6cd78;
+      color: #ffff;
       line-height: vw(63);
+      white-space: pre-wrap;
     }
 
     .content-photos {
       display: flex;
       flex-wrap: wrap;
-      justify-content: space-between;
-      overflow: hidden;
-      width: 100%;
-      height: 300px;
+      //   justify-content: space-between;
 
       img {
-        width: 188px;
-        height: 188px;
+        width: vw(188);
+        height: vw(188);
         margin-bottom: 15px;
+        margin-right: 15px;
         background-color: rgba(255, 255, 255, 0.1);
       }
     }
@@ -256,16 +304,27 @@ export default {
     justify-content: center;
     margin-top: vw(100);
 
-    .QRcodes {
-      width: vw(87);
-      height: vw(87);
-      margin-right: vw(12.5);
+    .right-text {
+      margin-left: vw(12.5);
+      display: flex;
+      flex-direction: column;
+      justify-content: space-between;
 
-      img {
-        width: 100%;
-        height: 100%;
+      div {
+        color: #ffffff;
+        font-size: vw(24);
+        font-weight: bold;
       }
     }
+  }
+
+  #html2canvas {
+    width: 100%;
+    height: 100%;
+    position: fixed;
+    top: 0;
+    z-index: 9;
+    overflow-y: auto;
 
     img {
       width: 100%;
@@ -273,3 +332,17 @@ export default {
   }
 }
 </style>
+<style lang="scss">
+.share {
+  .QRcodes {
+    width: vw(87);
+    height: vw(87);
+    margin-right: vw(12.5);
+
+    img {
+      width: 100%;
+      height: 100%;
+    }
+  }
+}
+</style>

+ 67 - 25
src/components/share.vue

@@ -47,13 +47,10 @@
         </div>
       </div>
       <div class="footerShare">
-        <div class="QRcodes">
-          <template v-if="processFlag == 'development'">
-            <img :src="require('@/assets/testQRcode.png')" />
-          </template>
-          <template v-else>
-            <img :src="require('@/assets/QRcode.png')" />
-          </template>
+        <div class="QRcodes" ref="QRcodes">
+          <div class="logo">
+            <img :src="require('@/assets/logo1.png')" />
+          </div>
         </div>
         <div class="right-text">
           <div>长按识别二维码</div>
@@ -68,6 +65,7 @@
 </template>
 <script>
 import html2canvas from 'html2canvas';
+import QRCode from 'qrcodejs2';
 export default {
   name: 'share',
   props: {
@@ -77,18 +75,22 @@ export default {
         return {};
       },
     },
+    reportId: {
+      type: [String, Number],
+    },
   },
   data() {
     return {
-      processFlag: '',
       canvasImageUrl: '',
       retryCount: 0,
       photosData: [],
     };
   },
-  created() {
-    // this.toastLoading(0, '生成中...', true);
-    this.processFlag = process.env.NODE_ENV;
+  created() {},
+  mounted() {
+    // 二维码
+    this.creatQrCode();
+    this.toastLoading(0, '生成中...', true);
     // 使用Promise.all确保所有图片加载完成
     const photos = this.reportTarget.photos;
     const photoPromises = [];
@@ -105,7 +107,7 @@ export default {
       .then((photosArr) => {
         this.photosData = photosArr;
         this.$nextTick(async () => {
-          //   await this.htmlToCanvas();
+          await this.htmlToCanvas();
         });
       })
       .catch((error) => {
@@ -113,6 +115,19 @@ export default {
         this.$toast('图片加载失败,请检查网络');
       });
     console.log(photos);
+
+    // 上拉边界下拉出现白色空白
+    let node = document.getElementsByClassName('share')[0];
+    node.addEventListener(
+      'touchmove',
+      (e) => {
+        if (e._isScroller) return;
+        e.preventDefault();
+      },
+      {
+        passive: false,
+      }
+    );
   },
   methods: {
     //异步执行
@@ -172,6 +187,18 @@ export default {
           this.$toast('生成分享图失败,请稍后重试');
         });
     },
+    creatQrCode() {
+      let devText = 'https://suishenbangtest.nipponpaint.com.cn/homeIndex';
+      let proText = 'https://suishenbang.nipponpaint.com.cn/homeIndex';
+      let text = process.env.NODE_ENV == 'development' ? devText : proText;
+      var qrcode = new QRCode(this.$refs.QRcodes, {
+        text: text + '?reportId=' + this.reportId || '', // 需要转换为二维码的内容
+        colorDark: '#000000',
+        colorLight: '#ffffff',
+        correctLevel: QRCode.CorrectLevel.H,
+      });
+      let logo = '../assets/logo1.png';
+    },
   },
 };
 </script>
@@ -182,7 +209,7 @@ export default {
   overflow: hidden;
   position: absolute;
   top: 0;
-  z-index: 111;
+  // z-index: -1;
 
   .share-content {
     background: url('../assets/shareBack.png') no-repeat center center;
@@ -195,7 +222,7 @@ export default {
     // z-index: -1;
     padding-bottom: vw(190);
     top: 0;
-    z-index: 111111;
+    z-index: -1;
   }
 
   .header {
@@ -293,17 +320,6 @@ export default {
     justify-content: center;
     margin-top: vw(100);
 
-    .QRcodes {
-      width: vw(87);
-      height: vw(87);
-      margin-right: vw(12.5);
-
-      img {
-        width: 100%;
-        height: 100%;
-      }
-    }
-
     .right-text {
       margin-left: vw(12.5);
       display: flex;
@@ -332,3 +348,29 @@ export default {
   }
 }
 </style>
+<style lang="scss">
+.share {
+  .QRcodes {
+    width: vw(87);
+    height: vw(87);
+    margin-right: vw(12.5);
+    position: relative;
+    .logo {
+      position: absolute;
+      top: vw(43);
+      left: vw(43);
+      margin: vw(-15) 0 0 vw(-15);
+      z-index: 3;
+      img {
+        width: vw(30);
+        height: vw(30);
+      }
+    }
+
+    img {
+      width: 100%;
+      height: 100%;
+    }
+  }
+}
+</style>

+ 1 - 1
src/views/week/dailyApproval.vue

@@ -460,7 +460,7 @@
     </div>
     <br />
     <br />
-    <share v-if="isShare" :reportTarget="reportTarget"></share>
+    <share v-if="isShare" :reportTarget="reportTarget" :reportId="$route.query.reportId"></share>
   </div>
 </template>