<template> <div class="abroad_detail_share_box" :class="type == 'order' ? 'type_order' : ''" @click="handleMask"> <div class="content" @click.stop> <img class="share_img" src="@/assets/service/share.png" alt="" /> <p class="share_text" v-if="posterLoaded">{{ posterBody }}</p> <div class="line" v-if="posterLoaded"></div> <div class="share_btn_box"> <button class="btn btn1" v-clipboard:copy="posterBody" v-clipboard:success="copyTextPoster" v-clipboard:error="onError"> 复制文字生成海报 </button> <button class="btn btn2" v-clipboard:copy="posterBody" v-clipboard:success="copyTextFriend" v-clipboard:error="onError"> 复制文字分享至朋友 </button> </div> <div class="line2"></div> </div> <div id="posterBox" v-if="showPoster" @click="showPoster = false"> <div class="poster_content" @click.stop> <img class="poster" :src="posterUrl" alt="" /> <button class="btn">长按图片保存海报</button> </div> </div> <div id="posterCreateBox"> <img class="poster1" v-if="sizeType == 2" alt="" /> <img class="poster1_logo" v-if="sizeType == 2" src="@/assets/service/logo4.png" alt="" /> <div class="poster2" v-else> <img class="logo" src="@/assets/service/logo3.png" alt="" /> <p class="title">{{ detailData.course_name }}</p> <p class="des" v-if="periodArr.length > 0">{{ periodArr[0].productSceneName }}</p> <img class="poster2img" alt="" /> <p class="price" v-if="periodArr.length > 0"> 活动价¥{{ periodArr[0].groupPeriodActivityList.actualPrice }}起/人<del >市场价¥{{ periodArr[0].groupPeriodActivityList.productPrice }}/人</del > </p> </div> <div class="bottom_box"> <p class="text"> <span>{{ nickName }} 邀请你参与本研学活动</span><span class="des">{{ posterLabel }}</span> </p> <div class="qrcodeBox"> <div id="qrcode" ref="imageWrapper" v-if="!codeImgUrl"></div> <div class="imgBox"> <img :src="codeImgUrl" v-if="codeImgUrl" style="width:100%;height:100%" crossorigin="anonymous" /> </div> </div> </div> </div> </div> </template> <script> import html2canvas from 'html2canvas' import QRCode from 'qrcodejs2' // 引入qrcode export default { props: ['type', 'detailData'], data() { return { posterBody: '', posterLabel: '', imageUrl: '', sizeType: 1, showPoster: false, posterUrl: '', nickName: '', periodArr: [], codeImgUrl: '', posterLoaded: false, } }, mounted() { let userInfo = localStorage.getItem('userInfo') if (userInfo) { this.nickName = JSON.parse(userInfo).nickName } this.getCoursePoster() this.getPeriod() this.creatQrCode() }, methods: { // 获取海报信息 getCoursePoster() { this.$toast.loading({ message: '加载中...', duration: 0, forbidClick: true, }) this.yxAxios.get(`${this.yanxueUrl}/api/Product/CoursePoster/ByCourseId?courseId=${this.detailData.id}`).then((res) => { if (res.data.data) { this.sizeType = res.data.data.sizeType this.posterBody = res.data.data.posterBody localStorage.setItem('posterBody', res.data.data.posterBody) this.posterLabel = res.data.data.posterLabel localStorage.setItem('posterLabel', res.data.data.posterLabel) if (this.sizeType == 1 || !res.data.data.imageUrl) { this.getImage(this.detailData.coverList ? this.detailData.coverList[0].cover_url : this.detailData.converUrl) } else { this.getImage(res.data.data.imageUrl) //获取到海报使用海报图片 } } else { this.getImage(this.detailData.coverList ? this.detailData.coverList[0].cover_url : this.detailData.converUrl) //未获取到海报使用课程第一张图片 } this.$toast.clear() this.posterLoaded = true }) }, // 获取可使用行程套餐 getPeriod() { let date = this.Moment().format('YYYY-MM-DD') let weekOfday = this.Moment().format('E') // 计算今天是这周第几天 // 如果为限时团购,就传星期三的日期 if (this.$route.query.ProgramType == 1) { let TGMSTabActive = localStorage.getItem('TGMSTabActive') if (TGMSTabActive == 1) { date = this.Moment() .add(weekOfday == 7 ? 3 : 10 - weekOfday, 'days') .format('YYYY-MM-DD') } else { date = this.Moment() .add(weekOfday == 7 ? -4 : 3 - weekOfday, 'days') .format('YYYY-MM-DD') } } let param = { productId: this.detailData.id, state: '1', pageIndex: 1, pageSize: 999, date: date, } if (this.$route.query.productSceneId) { param.productSceneId = this.$route.query.productSceneId } if (this.$route.query.DateComboType) { param.DateComboType = this.$route.query.DateComboType } if (this.$route.query.ProgramType) { param.ProgramType = this.$route.query.ProgramType } if (this.$route.query.ZZCTCanBuy) { param.ZZCTCanBuy = this.$route.query.ZZCTCanBuy } this.yxAxios.post(`${this.yanxueUrl}/api/Product/ProductScene/List`, param).then((res) => { let data = res.data.data.data let periodArr = [] for (let i in data) { if (data[i].groupPeriodActivityList) { // 如果是直通车产品,不显示常规拼团套餐 if (this.$route.query.ProgramType && data[i].dateBindTypeName == '常规拼团') { } else { periodArr.push(data[i]) } } } this.periodArr = periodArr.sort(this.sortUpDate) // this.periodArr = periodArr console.log('套餐列表:', periodArr) }) }, // 日期排序 sortUpDate(a, b) { return a.groupPeriodActivityList.actualPrice - b.groupPeriodActivityList.actualPrice }, handleMask() { this.$emit('hiddenShare') }, // 复制文字生成海报 copyTextPoster() { this.$toast.fail('复制成功') this.createPoster() }, // 复制文字分享至朋友 copyTextFriend() { this.$toast.fail('复制成功') this.$emit('showShareDes') }, onError() { this.$toast.fail('复制失败') }, // 生成海报 createPoster() { this.$toast.loading({ message: '加载中...', duration: 0, forbidClick: true, }) html2canvas(document.getElementById('posterCreateBox'), { backgroundColor: null, //画出来的图片有白色的边框,不要可设置背景为透明色(null) useCORS: true, //支持图片跨域 scale: 1, //设置放大的倍数 }).then((canvas) => { this.$toast.clear() //截图用img元素承装,显示在页面的上 // let img = new Image() // img.src = canvas.toDataURL('image/jpeg') // toDataURL :图片格式转成 base64 // document.getElementById('posterBox').appendChild(img) this.posterUrl = canvas.toDataURL('image/jpeg') this.showPoster = true }) }, //创建qrcode creatQrCode() { let link = `https://payment.myjxt.com/center/#/abroad_detail?courseId=${this.detailData.id}&publicName=SXYX}` if (this.detailData.bindId || this.detailData.dateComboBindId || this.$route.query.bindId) { link = link + '&bindId=' + (this.detailData.bindId || this.detailData.dateComboBindId || this.$route.query.bindId) } if (localStorage.getItem('talentData')) { const talentData = JSON.parse(localStorage.getItem('talentData')) link = link + '&inviteCode=' + talentData.inviteCode } if (this.$route.query.ProgramType) { link = link + '&ProgramType=' + this.$route.query.ProgramType } if (this.$route.query.ZZCTCanBuy) { link = link + '&ZZCTCanBuy=' + this.$route.query.ZZCTCanBuy } document.getElementById('qrcode').innerHTML = '' this.qrcodePIc = new QRCode('qrcode', { text: link, width: 240, height: 240, colorDark: '#333333', // 二维码颜色 colorLight: '#ffffff', // 二维码背景色 correctLevel: QRCode.CorrectLevel.L, // 容错率,L/M/H }) let canvas = document.getElementById('qrcode').innerHTML // console.log(canvas) this.canvanqrCode() }, canvanqrCode() { html2canvas(this.$refs.imageWrapper, { width: 240, height: 240, }).then((canvas) => { let dataURL = canvas.toDataURL('image/png') this.codeImgUrl = dataURL }) }, getBas64(url, outputFormat = 'image/png') { return new Promise(function(resolve, reject) { let canvas = document.createElement('CANVAS'), ctx = canvas.getContext('2d'), img = new Image() img.crossOrigin = 'Anonymous' // 重点!设置image对象可跨域请求 img.onload = function() { canvas.height = img.height canvas.width = img.width ctx.drawImage(img, 0, 0) let dataURL = canvas.toDataURL(outputFormat) canvas = null resolve(dataURL) } // img.src = url; // 旧的方式 img.src = url + '?t=' + new Date().valueOf() // 防止oss的缓存问题 }) }, getImage(url) { let that = this var xhr = new XMLHttpRequest() xhr.open('get', url, true) // 设置请求头(这一步得设置不然oss图片还是跨域) xhr.setRequestHeader('Cache-Control', 'no-cache') xhr.responseType = 'blob' xhr.onload = function() { if (this.status == 200) { if (that.sizeType == 2) { document.getElementsByClassName('poster1')[0].src = URL.createObjectURL(this.response) } else { document.getElementsByClassName('poster2img')[0].src = URL.createObjectURL(this.response) } } } xhr.send() }, }, } </script> <style lang="scss"> .abroad_detail_share_box { width: 100%; height: calc(100% - 176px); position: fixed; top: 0; left: 0; background: rgba(0, 0, 0, 0.5); z-index: 99; .content { width: 100%; height: 308px; position: absolute; bottom: 0; box-sizing: border-box; background: #fff; border-top-left-radius: 20px; border-top-right-radius: 20px; } .share_img { display: none; } .share_text { font-size: 28px; line-height: 40px; height: 80px; color: #666; margin: 32px 42px; display: -webkit-box; white-space: break-spaces; -webkit-line-clamp: 2; text-overflow: ellipsis; overflow: hidden; -webkit-box-orient: vertical; } .line { width: 708px; border-bottom: 2px dashed #d1d1d1; margin: 0 auto; } .line2 { width: 100%; border-bottom: 2px dashed #d1d1d1; position: absolute; bottom: 0; } .share_btn_box { display: flex; justify-content: space-around; margin-top: 46px; .btn { font-size: 28px; width: 296px; height: 72px; line-height: 72px; border-radius: 18px; border: none; } .btn1 { background: #ecf4ff; color: #4092ff; } .btn2 { background: #e3fff1; color: #05b55b; } } #posterBox { width: 100%; height: 100%; position: fixed; top: 0; left: 0; background: rgba(0, 0, 0, 0.5); z-index: 99; .poster_content { width: 540px; height: 960px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); margin-top: -100px; } .poster { width: 100%; user-select: auto; pointer-events: auto; } .btn { width: 448px; height: 84px; background: #4092ff; border-radius: 58px; text-align: center; font-size: 32px; color: #fff; line-height: 84px; border: none; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); margin-top: 600px; } } #posterCreateBox { // width: 540px; // height: 960px; width: 1500px; height: 2664px; background: #fff; position: absolute; top: 0; left: 100%; .poster1 { width: 100%; height: 2140px; } .poster1_logo { width: 500px; position: absolute; top: 50px; left: 50px; } .poster2 { .logo { width: 344px; display: block; margin: 0 auto; margin-top: 100px; } .title { font-size: 76px; font-weight: bold; color: #4092ff; text-align: center; margin-top: 60px; display: -webkit-box; white-space: break-spaces; -webkit-line-clamp: 2; text-overflow: ellipsis; overflow: hidden; -webkit-box-orient: vertical; padding: 0 50px; box-sizing: border-box; } .des { font-size: 60px; color: #999; text-align: center; margin-top: 24px; } .poster2img { width: 1392px; height: 1044px; display: block; margin: 0 auto; margin-top: 60px; } .price { text-align: center; font-size: 64px; color: #ff5f5f; margin-top: 80px; line-height: 88px; del { color: #999; font-size: 56px; margin-left: 8px; } } } .bottom_box { width: 100%; padding: 52px; display: flex; justify-content: space-between; position: absolute; bottom: 0; box-sizing: border-box; .text { font-size: 64px; color: #999999; white-space: break-spaces; span { color: #0f3853; } .des { display: block; font-size: 56px; color: #999; margin-top: 20px; } } } } .qrcodeBox { .imgBox { width: 380px; height: 380px; } } } .abroad_detail_share_box.type_order { height: 100%; .content { width: 616px; height: 632px; bottom: auto; top: 50%; left: 50%; transform: translate(-50%, -50%); border-radius: 20px; border: none; } .share_img { display: block; width: 518px; margin: 0 auto; margin-top: -90px; } .share_text { // padding: 0 50px; text-align: center; margin-top: 20px; display: -webkit-box; -webkit-line-clamp: 2; text-overflow: ellipsis; overflow: hidden; -webkit-box-orient: vertical; } .line, .line2 { display: none; } .share_btn_box { margin-top: 58px; display: block; .btn { width: 504px; height: 92px; line-height: 88px; box-sizing: border-box; border: 2px solid #3385ff; display: block; margin: 0 auto; border-radius: 46px; } .btn1 { color: #3385ff; background: #fff; } .btn2 { color: #fff; background: #3385ff; margin-top: 24px; } } } </style>