|
|
@@ -0,0 +1,519 @@
|
|
|
+<template>
|
|
|
+ <div ref="share">
|
|
|
+ <van-overlay :show="show" @click="show = false" z-index="99">
|
|
|
+ <div class="wrapper">
|
|
|
+ <div class="img" ref="wrap" v-if="img" @click.stop="save">
|
|
|
+ <img :src="img" />
|
|
|
+ </div>
|
|
|
+ <template v-if="!img">
|
|
|
+ <div class="assignmentPost" v-if="assignment && pageUrl === 'productDetail'" ref="post">
|
|
|
+ <!-- <van-image class="assignmentPostBg" fit="cover" width="300" height="500" :src="shareBg" /> -->
|
|
|
+ <img class="assignmentPostBg" :src="shareBg" alt="" />
|
|
|
+ <div class="qrcode-text" :style="{ bottom: qrcodeBottom + 'px' }">
|
|
|
+ <div class="qrcode">
|
|
|
+ <vue-qrcode :value="url" :options="{ width: qrcodeImg, margin: 0 }"></vue-qrcode>
|
|
|
+ </div>
|
|
|
+ <div class="text-tips">
|
|
|
+ {{ supportNativeShare ? '点击图片保存到本地' : '长按图片保存' }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <div class="close-btn" @click.stop="show = false">
|
|
|
+ <img src="@assets/icon_cha_close.png" alt="" />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- <div class="share-wrapper" v-if="supportNativeShare === 2">
|
|
|
+ <div class="share-btns">
|
|
|
+ <div class="share-item" @click.stop="shareNative('WEIXIN')">
|
|
|
+ <img src="@/assets/share_weixin.png" class="share-icon" />
|
|
|
+ <div class="share-desc">微信</div>
|
|
|
+ </div>
|
|
|
+ <div class="share-item" @click.stop="shareNative('WEIXIN_CIRCLE')">
|
|
|
+ <img src="@/assets/share_timeline.png" class="share-icon" />
|
|
|
+ <div class="share-desc">朋友圈</div>
|
|
|
+ </div>
|
|
|
+ <div class="share-item" @click.stop="save">
|
|
|
+ <img src="@/assets/share_download.png" class="share-icon" />
|
|
|
+ <div class="share-desc">保存</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="btn" @click.stop="" v-else-if="supportNativeShare === 1">
|
|
|
+ <van-button type="primary" round @click="save">点击保存到本地</van-button>
|
|
|
+ </div>
|
|
|
+ <div class="tips" v-else>长按图片保存</div> -->
|
|
|
+ </div>
|
|
|
+ </van-overlay>
|
|
|
+ <div class="share" v-if="!noButton" @click="init">
|
|
|
+ <img src="@assets/svgs/icon-share.svg" alt="" />
|
|
|
+ <span>分享</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+import vueQrcode from '@chenfengyuan/vue-qrcode';
|
|
|
+import html2canvas from 'html2canvas';
|
|
|
+import product from '../mixins/product';
|
|
|
+import resolveUrl from 'resolve-url';
|
|
|
+import axios from 'axios';
|
|
|
+import { isBefore, format } from 'date-fns';
|
|
|
+import { abs } from 'mathjs';
|
|
|
+import { ImagePreview } from 'vant';
|
|
|
+export default {
|
|
|
+ mixins: [product],
|
|
|
+ props: {
|
|
|
+ info: {
|
|
|
+ type: Object,
|
|
|
+ default: () => {
|
|
|
+ return {
|
|
|
+ pic: []
|
|
|
+ };
|
|
|
+ }
|
|
|
+ },
|
|
|
+ pageUrl: {
|
|
|
+ type: String,
|
|
|
+ default: 'productDetail'
|
|
|
+ },
|
|
|
+ noButton: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ inject: ['appHeight'],
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ show: false,
|
|
|
+ share: null,
|
|
|
+ img: '',
|
|
|
+ detailImg: '',
|
|
|
+ userImg: '',
|
|
|
+ shareBg: ''
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ url() {
|
|
|
+ let pageUrl = this.pageUrl;
|
|
|
+ let id = this.info.id;
|
|
|
+ if (pageUrl === 'assetDetail') {
|
|
|
+ id = this.info.publicCollectionId;
|
|
|
+ pageUrl = 'productDetail';
|
|
|
+ }
|
|
|
+
|
|
|
+ if (pageUrl === 'productDetail' && !this.assignment) {
|
|
|
+ pageUrl = 'productDetail/' + id;
|
|
|
+ }
|
|
|
+ if (this.isLogin && this.assignment && pageUrl === 'productDetail') {
|
|
|
+ return resolveUrl(
|
|
|
+ this.$baseUrl,
|
|
|
+ '9th/productTasks?id=' + id + '&invitor=' + this.$store.state.userInfo.id
|
|
|
+ );
|
|
|
+ } else if (this.isLogin) {
|
|
|
+ return resolveUrl(
|
|
|
+ this.$baseUrl,
|
|
|
+ '9th/' + pageUrl + '?id=' + id + '&invitor=' + this.$store.state.userInfo.id
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ return resolveUrl(this.$baseUrl, '9th/' + pageUrl + '?id=' + id);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ banners() {
|
|
|
+ return this.getImg(this.changeImgs(this.info.pic || []), '', 900);
|
|
|
+ },
|
|
|
+ isBuy() {
|
|
|
+ return this.info.stock && this.info.onShelf && this.info.salable;
|
|
|
+ },
|
|
|
+ time() {
|
|
|
+ if (this.info.startTime) {
|
|
|
+ if (isBefore(new Date(this.info.startTime), new Date())) {
|
|
|
+ return format(new Date(this.info.startTime), 'mm月dd日');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return '';
|
|
|
+ },
|
|
|
+ supportNativeShare() {
|
|
|
+ // if (window.UmengPlugin) {
|
|
|
+ // return 2;
|
|
|
+ // }
|
|
|
+ if (window.cordova) {
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ },
|
|
|
+ qrcodeImg() {
|
|
|
+ let appHeight = this.appHeight.replace(/px/, '');
|
|
|
+
|
|
|
+ return this.accMul(Number(appHeight), 0.12);
|
|
|
+ },
|
|
|
+ qrcodeBottom() {
|
|
|
+ let appHeight = this.appHeight.replace(/px/, '');
|
|
|
+
|
|
|
+ return this.accMul(Number(appHeight), 0.18);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ components: {
|
|
|
+ vueQrcode
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ init() {
|
|
|
+ this.show = true;
|
|
|
+ // this.getImgBase64(this.info.shareBg, 'shareBg');
|
|
|
+ if (!this.img) {
|
|
|
+ this.$toast.loading({
|
|
|
+ message: '加载中...',
|
|
|
+ forbidClick: true
|
|
|
+ });
|
|
|
+ this.$nextTick(() => {
|
|
|
+ if (this.assignment && this.pageUrl === 'productDetail') {
|
|
|
+ this.getImgBase64(this.info.shareBg, 'shareBg');
|
|
|
+ } else {
|
|
|
+ this.getImgBase64(this.banners, 'detailImg');
|
|
|
+ this.getImgBase64(this.info.minterAvatar, 'userImg');
|
|
|
+ }
|
|
|
+ setTimeout(() => {
|
|
|
+ this.loadImg();
|
|
|
+ }, 1000);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ loadImg() {
|
|
|
+ html2canvas(this.$refs.post, {
|
|
|
+ useCORS: true,
|
|
|
+ allowTaint: true,
|
|
|
+ backgroundColor: null,
|
|
|
+ scale: 4
|
|
|
+ }).then(canvas => {
|
|
|
+ this.$toast.clear();
|
|
|
+ this.img = canvas.toDataURL('image/png');
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getImgBase64(img2, key) {
|
|
|
+ let img = new Image();
|
|
|
+ img.crossOrigin = 'anonymous';
|
|
|
+ let _this = this;
|
|
|
+ img.onload = function () {
|
|
|
+ let src = _this.image2Base64(img);
|
|
|
+ _this[key] = src;
|
|
|
+ };
|
|
|
+ img.src = img2;
|
|
|
+ },
|
|
|
+ image2Base64(img) {
|
|
|
+ let canvas = document.createElement('canvas');
|
|
|
+ canvas.width = img.width;
|
|
|
+ canvas.height = img.height;
|
|
|
+ let ctx = canvas.getContext('2d');
|
|
|
+ ctx.drawImage(img, 0, 0, img.width, img.height);
|
|
|
+ let dataURL = canvas.toDataURL('image/png');
|
|
|
+ return dataURL;
|
|
|
+ },
|
|
|
+ preview(index = 0, list = []) {
|
|
|
+ ImagePreview({
|
|
|
+ images: [...list],
|
|
|
+ startPosition: index
|
|
|
+ });
|
|
|
+ },
|
|
|
+ save() {
|
|
|
+ if (window.cordova) {
|
|
|
+ let _this = this;
|
|
|
+ imageSaver.saveBase64Image(
|
|
|
+ { data: this.img },
|
|
|
+ function (filePath) {
|
|
|
+ _this.$toast('图片已保存至文件夹');
|
|
|
+ _this.show = false;
|
|
|
+ console.log('File saved on ' + filePath);
|
|
|
+ },
|
|
|
+ function (msg) {
|
|
|
+ _this.$dialog.alert({
|
|
|
+ title: '提示',
|
|
|
+ message: msg + ',请尝试截图保存分享'
|
|
|
+ });
|
|
|
+ (1).then(() => {
|
|
|
+ _this.preview(0, [_this.img]);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ },
|
|
|
+ shareNative(platform = 'WEIXIN') {
|
|
|
+ window.UmengPlugin.shareImg({ imgUrl: this.img, platform });
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
+<style lang="less" scoped>
|
|
|
+.wrapper {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ flex-direction: column;
|
|
|
+ height: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.content {
|
|
|
+ width: 80vw;
|
|
|
+ background: @bg;
|
|
|
+ border-radius: 30px;
|
|
|
+ overflow: hidden;
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+
|
|
|
+.img {
|
|
|
+ img {
|
|
|
+ width: 100vw;
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.info {
|
|
|
+ padding: 12px 10px 7px;
|
|
|
+ .name {
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: @text0;
|
|
|
+ line-height: 24px;
|
|
|
+ }
|
|
|
+ .text {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: flex-end;
|
|
|
+ margin-top: 6px;
|
|
|
+
|
|
|
+ .price {
|
|
|
+ img {
|
|
|
+ width: 10px;
|
|
|
+ height: 11px;
|
|
|
+ }
|
|
|
+ span {
|
|
|
+ font-size: 24px;
|
|
|
+ font-family: OSP-DIN, OSP;
|
|
|
+ color: @prim;
|
|
|
+ line-height: 36px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .text1 {
|
|
|
+ font-size: 14px;
|
|
|
+ color: @text3;
|
|
|
+ line-height: 24px;
|
|
|
+ span + span {
|
|
|
+ margin-left: 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.code {
|
|
|
+ border-radius: 6px;
|
|
|
+}
|
|
|
+
|
|
|
+.minter {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ padding: 10px 16px 12px 10px;
|
|
|
+ border-top: 2px solid @bg3;
|
|
|
+
|
|
|
+ .minter-content {
|
|
|
+ /deep/.van-image {
|
|
|
+ img {
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .text1 {
|
|
|
+ font-size: @font1;
|
|
|
+ color: @text0;
|
|
|
+ line-height: 17px;
|
|
|
+ margin-top: 1px;
|
|
|
+ }
|
|
|
+ .text2 {
|
|
|
+ font-size: @font1;
|
|
|
+ color: @text3;
|
|
|
+ line-height: 17px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.tips {
|
|
|
+ font-size: 13px;
|
|
|
+ color: @text3;
|
|
|
+ line-height: 22px;
|
|
|
+ margin-top: 30px;
|
|
|
+}
|
|
|
+
|
|
|
+.share {
|
|
|
+ position: fixed;
|
|
|
+ right: 16px;
|
|
|
+ bottom: 20vh;
|
|
|
+ width: 48px;
|
|
|
+ height: 48px;
|
|
|
+ background: linear-gradient(135deg, @prim 0%, @warn 100%);
|
|
|
+ z-index: 20;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ border-radius: 100px;
|
|
|
+ justify-content: center;
|
|
|
+ span {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #333230;
|
|
|
+ line-height: 17px;
|
|
|
+ }
|
|
|
+ img {
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.detailImg {
|
|
|
+ width: 80vw;
|
|
|
+ height: 80vw;
|
|
|
+ display: block;
|
|
|
+}
|
|
|
+.tabs {
|
|
|
+ .flex();
|
|
|
+ margin-top: 6px;
|
|
|
+ span {
|
|
|
+ font-size: 12px;
|
|
|
+ color: @text3;
|
|
|
+ line-height: 22px;
|
|
|
+ padding: 0 10px;
|
|
|
+ background: @bg3;
|
|
|
+ border-radius: 4px;
|
|
|
+ margin-right: 6px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.status {
|
|
|
+ font-size: 14px;
|
|
|
+ color: @text3;
|
|
|
+ line-height: 24px;
|
|
|
+ padding-top: 11px;
|
|
|
+}
|
|
|
+
|
|
|
+.sold {
|
|
|
+ background-color: #1c1e25;
|
|
|
+ font-size: @font1;
|
|
|
+ color: @text3;
|
|
|
+ padding: 0 17px;
|
|
|
+ border-radius: 13px;
|
|
|
+ line-height: 24px;
|
|
|
+ position: absolute;
|
|
|
+ top: 16px;
|
|
|
+ left: 16px;
|
|
|
+ z-index: 3;
|
|
|
+
|
|
|
+ &.xianliang {
|
|
|
+ position: absolute;
|
|
|
+ top: 16px;
|
|
|
+ left: 16px;
|
|
|
+ font-size: @font1;
|
|
|
+ color: @prim;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ // border-radius: 13px !important;
|
|
|
+ z-index: 4;
|
|
|
+ padding: 0 10px !important;
|
|
|
+
|
|
|
+ img {
|
|
|
+ width: 18px;
|
|
|
+ height: 18px;
|
|
|
+ margin-right: 3px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+.btn {
|
|
|
+ padding: 30px;
|
|
|
+}
|
|
|
+.share-wrapper {
|
|
|
+ margin-top: 20px;
|
|
|
+ .share-title {
|
|
|
+ font-size: 12px;
|
|
|
+ color: white;
|
|
|
+ margin: 10px 0 10px 0;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+ .share-btns {
|
|
|
+ .flex();
|
|
|
+ justify-content: center;
|
|
|
+ .share-item {
|
|
|
+ margin: 0 15px;
|
|
|
+ .share-icon {
|
|
|
+ width: 44px;
|
|
|
+ height: 44px;
|
|
|
+ }
|
|
|
+ .share-desc {
|
|
|
+ margin-top: 2px;
|
|
|
+ font-size: 10px;
|
|
|
+ color: @text3;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.assignmentPost {
|
|
|
+ width: 100vw;
|
|
|
+ height: var(--app-height);
|
|
|
+ position: relative;
|
|
|
+ background-position: center center;
|
|
|
+ background-size: cover;
|
|
|
+ overflow: hidden;
|
|
|
+ .qrcode-text {
|
|
|
+ background: #f5f7fa;
|
|
|
+ border-radius: 6px;
|
|
|
+ padding: 5px 5px 4px;
|
|
|
+ position: absolute;
|
|
|
+ left: 50%;
|
|
|
+ transform: translateX(-50%);
|
|
|
+ bottom: 18vh;
|
|
|
+ z-index: 20;
|
|
|
+ /deep/canvas {
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+
|
|
|
+ .qrcode {
|
|
|
+ background-color: #fff;
|
|
|
+ padding: 5px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .text-tips {
|
|
|
+ font-size: 10px;
|
|
|
+ color: #939599;
|
|
|
+ line-height: 12px;
|
|
|
+ text-align: center;
|
|
|
+ margin-top: 4px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .assignmentPostBg {
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ width: auto;
|
|
|
+ height: var(--app-height);
|
|
|
+ left: 50%;
|
|
|
+ top: 50%;
|
|
|
+ transform: translate(-50%, -50%);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.tips {
|
|
|
+ position: absolute;
|
|
|
+}
|
|
|
+
|
|
|
+.close-btn {
|
|
|
+ position: absolute;
|
|
|
+ right: 20px;
|
|
|
+ top: 20px;
|
|
|
+ background: rgba(0, 0, 0, 0.2);
|
|
|
+ backdrop-filter: blur(1px);
|
|
|
+ width: 34px;
|
|
|
+ height: 34px;
|
|
|
+ border-radius: 100%;
|
|
|
+ .flex();
|
|
|
+ justify-content: center;
|
|
|
+ z-index: 90;
|
|
|
+ img {
|
|
|
+ width: 18px;
|
|
|
+ height: 18px;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|