|
|
@@ -0,0 +1,388 @@
|
|
|
+<template>
|
|
|
+ <van-overlay :show="show" :lock-scroll="false" @click="show = false" z-index="99">
|
|
|
+ <div class="box">
|
|
|
+ <img v-if="img" @click.stop="" :src="img" alt="" class="post-img" />
|
|
|
+ <div v-else class="post" ref="post" @click.stop="">
|
|
|
+ <div class="post-content">
|
|
|
+ <div class="title">
|
|
|
+ <div class="text1">{{ info.name }}</div>
|
|
|
+ <div class="text2">铸造时间(GMT+8): {{ info.createdAt }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="post-box">
|
|
|
+ <div class="show-box">
|
|
|
+ <img class="show-bg" ref="showBg" src="@assets/png-bg-shangping2.png" alt="" />
|
|
|
+ <div class="banner">
|
|
|
+ <van-image width="53vw" height="53vw" :src="detailImg" fit="cover" />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <img src="@assets/png-xiushi.png" class="icon1" alt="" />
|
|
|
+ <img src="@assets/png-xiushi1.png" class="icon2" alt="" />
|
|
|
+ </div>
|
|
|
+ <div class="info-box">
|
|
|
+ <img src="@assets/png-renzheng.png" alt="" class="renzhen" />
|
|
|
+ <div class="info">
|
|
|
+ <div class="text1">持有者昵称</div>
|
|
|
+ <div class="text2">
|
|
|
+ <span>{{ info.owner }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="info">
|
|
|
+ <div class="text1">铸造者昵称</div>
|
|
|
+ <div class="text2">
|
|
|
+ <span>{{ info.minter }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="info" v-if="info.hcTokenId">
|
|
|
+ <div class="text1">CRC华储链令牌ID</div>
|
|
|
+ <div class="text2" ref="hcTokenId">
|
|
|
+ <span>{{ getShort(info.hcTokenId, 30) }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="info" v-if="info.hcTxHash">
|
|
|
+ <div class="text1">HASH地址</div>
|
|
|
+ <div class="text2" ref="hcTxHash">
|
|
|
+ <span>{{ getShort(info.hcTxHash, 30) }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="info" v-if="info.hcBlockNumber">
|
|
|
+ <div class="text1">区块高度</div>
|
|
|
+ <div class="text2">
|
|
|
+ <span>{{ info.hcBlockNumber }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="info" v-if="info.ipfsUrl">
|
|
|
+ <div class="text1">IPFS分布式存储地址</div>
|
|
|
+ <div class="text2" ref="ipfsUrl">
|
|
|
+ <span>{{ getShort(info.ipfsUrl, 30) }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="info">
|
|
|
+ <div class="text1">确权平台</div>
|
|
|
+ <div class="text2">RAEX绿洲宇宙</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="info">
|
|
|
+ <div class="text1">确权查询</div>
|
|
|
+ <div class="text2">www.raex.co</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <img src="@assets/png-zhengshu-diwen.png" alt="" class="box-bg" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <img src="@assets/icon_dialog_close.png" class="close" alt="" />
|
|
|
+ <img
|
|
|
+ src="@assets/copy_icon.png"
|
|
|
+ v-for="(item, index) in copys"
|
|
|
+ :key="index"
|
|
|
+ :style="this[item]"
|
|
|
+ alt=""
|
|
|
+ class="copy"
|
|
|
+ @click.stop="copy(item)"
|
|
|
+ />
|
|
|
+
|
|
|
+ <div class="btn" @click.stop="save" v-if="inApp">
|
|
|
+ <van-button block round type="primary">保存图片</van-button>
|
|
|
+ </div>
|
|
|
+ <div class="tips" v-else>长按图片保存</div>
|
|
|
+ </div>
|
|
|
+ </van-overlay>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import product from '../../mixins/product';
|
|
|
+import html2canvas from 'html2canvas';
|
|
|
+let inApp = /#cordova#/i.test(navigator.userAgent);
|
|
|
+import { ImagePreview } from 'vant';
|
|
|
+export default {
|
|
|
+ mixins: [product],
|
|
|
+ props: {
|
|
|
+ info: {
|
|
|
+ type: Object,
|
|
|
+ default: () => {
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ show: false,
|
|
|
+ img: '',
|
|
|
+ detailImg: '',
|
|
|
+ txHash: {},
|
|
|
+ tokenId: {},
|
|
|
+ ipfsUrl: {},
|
|
|
+ hcTxHash: {},
|
|
|
+ hcTokenId: {},
|
|
|
+ inApp,
|
|
|
+ copys: ['txHash', 'tokenId', 'ipfsUrl', 'hcTxHash', 'hcTokenId']
|
|
|
+ };
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ // setTimeout(() => {
|
|
|
+ // this.init();
|
|
|
+ // }, 1000);
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ init() {
|
|
|
+ this.show = true;
|
|
|
+ if (!this.img) {
|
|
|
+ this.$toast.loading({
|
|
|
+ message: '加载中...',
|
|
|
+ forbidClick: true
|
|
|
+ });
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.getImgBase64(this.getImg(this.changeImgs(this.info.pic, 600)), 'detailImg');
|
|
|
+ setTimeout(() => {
|
|
|
+ [...this.copys].forEach(item => {
|
|
|
+ this.getCopy(item);
|
|
|
+ });
|
|
|
+ }, 500);
|
|
|
+ setTimeout(() => {
|
|
|
+ this.loadImg();
|
|
|
+ }, 1000);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ getCopy(refName = 'txHash') {
|
|
|
+ if (this.$refs[refName]) {
|
|
|
+ let top = this.$refs[refName].parentNode.offsetTop + 167 + this.$refs.showBg.offsetHeight;
|
|
|
+ let left = this.$refs[refName].childNodes[0].offsetWidth + 53;
|
|
|
+ this[refName] = {
|
|
|
+ top: top + 'px',
|
|
|
+ left: left + 'px'
|
|
|
+ };
|
|
|
+ } else {
|
|
|
+ this[refName] = {
|
|
|
+ display: 'none'
|
|
|
+ };
|
|
|
+ }
|
|
|
+ },
|
|
|
+ loadImg() {
|
|
|
+ html2canvas(this.$refs.post, {
|
|
|
+ useCORS: true,
|
|
|
+ allowTaint: true,
|
|
|
+ backgroundColor: null,
|
|
|
+ scale: 3
|
|
|
+ }).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;
|
|
|
+ },
|
|
|
+ copy(key) {
|
|
|
+ this.$copyText(this.info[key]).then(
|
|
|
+ e => {
|
|
|
+ this.$toast.success('复制成功');
|
|
|
+ console.log(e);
|
|
|
+ },
|
|
|
+ e => {
|
|
|
+ this.$toast('复制失败');
|
|
|
+ console.log(e);
|
|
|
+ }
|
|
|
+ );
|
|
|
+ },
|
|
|
+ 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]);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" scoped>
|
|
|
+.box {
|
|
|
+ .flex-col();
|
|
|
+ align-items: center;
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ overflow: auto;
|
|
|
+ box-sizing: border-box;
|
|
|
+ padding: 50px 0;
|
|
|
+}
|
|
|
+
|
|
|
+.post-img {
|
|
|
+ width: calc(100vw - 32px);
|
|
|
+ display: block;
|
|
|
+}
|
|
|
+
|
|
|
+.post {
|
|
|
+ width: calc(100vw - 32px);
|
|
|
+ border-radius: 12px;
|
|
|
+ border: 1px solid rgba(243, 224, 184, 0.5);
|
|
|
+ padding: 12px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ background-color: #0f0f0f;
|
|
|
+ .post-content {
|
|
|
+ background: linear-gradient(180deg, #ffd694 0%, #f3e0b8 17%, #9f875e 100%);
|
|
|
+ border-radius: 12px;
|
|
|
+ padding: 1px;
|
|
|
+ .title {
|
|
|
+ padding: 16px;
|
|
|
+ .text1 {
|
|
|
+ font-size: 20px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #0d090b;
|
|
|
+ line-height: 24px;
|
|
|
+ }
|
|
|
+ .text2 {
|
|
|
+ font-size: 12px;
|
|
|
+ color: rgba(13, 9, 11, 0.5);
|
|
|
+ line-height: 17px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.post-box {
|
|
|
+ background: linear-gradient(180deg, #0f0f0f 0%, #0a0a0a 100%);
|
|
|
+ border-radius: 12px;
|
|
|
+ padding-bottom: 20px;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .info {
|
|
|
+ padding: 6px 16px;
|
|
|
+ .text1 {
|
|
|
+ font-size: 12px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #939599;
|
|
|
+ line-height: 17px;
|
|
|
+ }
|
|
|
+ .text2 {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #ffffff;
|
|
|
+ line-height: 24px;
|
|
|
+ margin-top: 4px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .box-bg {
|
|
|
+ width: 100%;
|
|
|
+ position: absolute;
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ z-index: 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+.info-box {
|
|
|
+ position: relative;
|
|
|
+ z-index: 1;
|
|
|
+ .renzhen {
|
|
|
+ width: 108px;
|
|
|
+ height: 108px;
|
|
|
+ position: absolute;
|
|
|
+ top: 12px;
|
|
|
+ right: 24px;
|
|
|
+ }
|
|
|
+}
|
|
|
+.show-box {
|
|
|
+ position: relative;
|
|
|
+ .show-bg {
|
|
|
+ width: 100%;
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+ .banner {
|
|
|
+ position: absolute;
|
|
|
+ box-shadow: 0px 0px 5px 0px #ffffff;
|
|
|
+ border-radius: 16px;
|
|
|
+ padding: 8px;
|
|
|
+ border: 1px solid rgba(255, 255, 255, 0.2);
|
|
|
+ left: 50%;
|
|
|
+ transform: translateX(-50%);
|
|
|
+ top: 9.3vw;
|
|
|
+ .van-image {
|
|
|
+ border: 2px solid #2f2f2f;
|
|
|
+ border-radius: 16px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.btn {
|
|
|
+ width: calc(100vw - 102px);
|
|
|
+ margin: 20px 0 0;
|
|
|
+ --van-button-primary-background-color: #303133;
|
|
|
+}
|
|
|
+.copy {
|
|
|
+ position: absolute;
|
|
|
+ width: 18px;
|
|
|
+ height: 18px;
|
|
|
+ z-index: 20;
|
|
|
+}
|
|
|
+.tips {
|
|
|
+ font-size: 13px;
|
|
|
+ color: @text3;
|
|
|
+ line-height: 22px;
|
|
|
+ margin-top: 30px;
|
|
|
+}
|
|
|
+
|
|
|
+.icon1 {
|
|
|
+ width: 9px;
|
|
|
+ height: 18px;
|
|
|
+ position: absolute;
|
|
|
+ bottom: 30px;
|
|
|
+ left: 0;
|
|
|
+}
|
|
|
+.icon2 {
|
|
|
+ width: 9px;
|
|
|
+ height: 18px;
|
|
|
+ position: absolute;
|
|
|
+ bottom: 30px;
|
|
|
+ right: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.close {
|
|
|
+ position: absolute;
|
|
|
+ right: 5px;
|
|
|
+ top: 40px;
|
|
|
+ width: 30px;
|
|
|
+ height: 30px;
|
|
|
+ z-index: 99;
|
|
|
+}
|
|
|
+</style>
|