Files
frontend-app/pages/active/components/share-popup.vue
T
2026-09-23 10:29:41 +08:00

1093 lines
27 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<up-popup :show="show" :round="24" :closeOnClickOverlay="false">
<view class="share-popup-view">
<view class="share-head">
<text class="text-28 text-gray">分享信任桥</text>
</view>
<view class="share-btn-view">
<!-- #ifndef APP-PLUS || H5 -->
<block v-for="(item, index) in filteredBtnList" :key="index">
<button v-if="item.originalIndex === 0" open-type="share" hover-class="none"
class="share-box share-btn-clean" @click="onBtn(item.originalIndex)">
<image :src="`https://static.tbmall.xin/static/new/share_${item.originalIndex}.png`"
class="share-img">
</image>
<text class="text-24 text-gray">{{ item.name }}</text>
</button>
<view v-else class="share-box" @click="onBtn(item.originalIndex)">
<image :src="`https://static.tbmall.xin/static/new/share_${item.originalIndex}.png`"
class="share-img">
</image>
<text class="text-24 text-gray">{{ item.name }}</text>
</view>
</block>
<!-- #endif -->
<!-- #ifdef APP-PLUS || H5 -->
<view class="share-box" @click="onShare(item.originalIndex)" v-for="(item, index) in filteredAppBtnList"
:key="index">
<image
:src="`https://cex-pub.s3.ap-southeast-1.amazonaws.com/static/new/share_${item.originalIndex}.png`"
class="share-img"></image>
<text class="text-24 text-gray">{{ item.name }}</text>
</view>
<!-- #endif -->
</view>
<view class="share-line" style="margin-top:40rpx;"></view>
<view class="qr-view" v-if="qrvalue && !isGroupBuy">
<tki-qrcode ref="qrcode" :val="qrvalue" :size="252" />
</view>
<view class="share-line" style="min-height:16rpx;height:16rpx">
</view>
<view class="share-bottom" @click="onClose">
<text class="text-32 text-fu1">取消</text>
</view>
<!-- 拼团专属卡片 -->
<view class="group-share-card" v-if="isGroupBuy">
<image :src="tu" class="group-card-img" mode="aspectFill"></image>
<view class="group-card-price-row">
<view class="group-card-price-box">
<text class="group-card-price-label">拼团价</text>
<text class="group-card-price-symbol">¥</text>
<text class="group-card-price-num">{{ groupPrice || price }}</text>
</view>
<view class="group-card-tag" v-if="requiredNum">
<text>{{ requiredNum }}人成团</text>
</view>
</view>
<view class="group-card-title">
{{ text }}
</view>
<view class="group-card-divider"></view>
<view class="group-card-bottom">
<view class="group-card-bottom-left">
<view class="group-card-main-title">超值拼团</view>
<view class="group-card-sub-title">人多价更优 拼团更实惠</view>
<view class="group-card-user-row">
<image :src="currentInviterAvatar" class="group-card-avatar" mode="aspectFill"></image>
<text class="group-card-username">{{ currentInviterName }}</text>
</view>
</view>
<view class="group-card-bottom-right">
<view class="group-card-qr-box">
<tki-qrcode
ref="groupQrcode"
cid="tki-group-qrcode-canvas"
:val="qrvalue"
:size="260"
unit="px"
:onval="true"
:lv="2"
:showLoading="false"
@result="onGroupQrResult"
/>
</view>
<text class="group-card-qr-tip">长按识别 参与拼团</text>
</view>
</view>
</view>
<!-- 原普通商品卡片 -->
<view class="share-top-image-view" v-else>
<image :src="tu" class="tu-img"></image>
<view class="image-view-bottom">
<view class="image-view-bottom-left"
:style="{ borderRight: price ? '2rpx solid #EBEBEB' : 'none', flex: price ? 'none' : '1' }">
<text class="text-24 text-gray text-overflow1">{{ text }}</text>
</view>
<view class="image-view-bottom-right" v-if="price">
<text class="text-24 text-zi">¥{{ price }}</text>
</view>
</view>
</view>
<!-- 隐藏 Canvas 用于生成拼团卡片海报 -->
<view class="hideCanvasView">
<canvas
canvas-id="groupCardCanvas"
id="groupCardCanvas"
style="width: 560px; height: 910px;"
></canvas>
</view>
</view>
</up-popup>
</template>
<script>
import Func from '/utils/func'
import tkiQrcode from './tki-qrcode/tki-qrcode.vue'
import { SHARE_URL } from '@/utils/config.js'
import { getStorageFun, USER_DATA } from '@/utils/auth.js'
export default {
data() {
return {
btnList: ['微信', '朋友圈'],
appBtnList: ['微信', '朋友圈', '复制链接', '保存图片', 'QQ'],
qrvalue: '',
defaultAvatar: 'https://static.tbmall.xin/static/new/default_avatar.png',
groupQrPath: '',
isGeneratingPoster: false
}
},
components: { tkiQrcode },
props: {
show: {
type: Boolean,
default: false
},
id: {
type: [String, Number],
default: ''
},
tu: {
type: String,
default: ''
},
price: {
type: String,
default: ''
},
text: {
type: String,
default: ''
},
hideCopyAndQQ: {
type: Boolean,
default: false
},
sharePath: {
type: String,
default: ''
},
isGroupBuy: {
type: Boolean,
default: false
},
groupPrice: {
type: [String, Number],
default: ''
},
requiredNum: {
type: [String, Number],
default: 2
},
inviterName: {
type: String,
default: ''
},
inviterAvatar: {
type: String,
default: ''
}
},
watch: {
show(val) {
if (val) {
this.initQrCode();
}
},
sharePath() {
this.initQrCode();
},
id() {
this.initQrCode();
},
isGroupBuy() {
this.initQrCode();
}
},
mounted() {
this.initQrCode();
},
computed: {
isInvitePage() {
if (this.hideCopyAndQQ) return true;
try {
const pages = getCurrentPages();
const current = pages[pages.length - 1];
const route = current?.route || current?.$page?.fullPath || '';
return route.includes('invite_friends');
} catch (e) {
return false;
}
},
filteredBtnList() {
const items = this.btnList.map((name, originalIndex) => ({ name, originalIndex }));
if (this.isInvitePage) {
return items.filter(item => item.name !== '微信');
}
if (this.isGroupBuy) {
return items.filter(item => item.name !== 'QQ');
}
return items;
},
filteredAppBtnList() {
const items = this.appBtnList.map((name, originalIndex) => ({ name, originalIndex }));
if (this.isInvitePage) {
return items.filter(item => item.name !== '复制链接' && item.name !== 'QQ');
}
if (this.isGroupBuy) {
return items.filter(item => item.name !== 'QQ');
}
return items;
},
currentInviterName() {
if (this.inviterName) return this.inviterName;
try {
const u = getStorageFun(USER_DATA) || {};
return u.name || u.nickName || 'Haonan Mu';
} catch (e) {
return 'Haonan Mu';
}
},
currentInviterAvatar() {
if (this.inviterAvatar) return this.inviterAvatar;
try {
const u = getStorageFun(USER_DATA) || {};
return u.avatar || u.avatarUrl || this.defaultAvatar;
} catch (e) {
return this.defaultAvatar;
}
}
},
methods: {
initQrCode() {
if (!this.isInvitePage) {
this.groupQrPath = '';
if (this.isGroupBuy) {
// 拼团专属卡片二维码:路由后面加 id=${this.id}&activedType=groupBuy&activityId=1
let basePath = 'pages/other_package/productInfo/productInfo';
let targetId = this.id != null ? String(this.id) : '';
if (this.sharePath) {
const cleanPath = this.sharePath.startsWith('/') ? this.sharePath.slice(1) : this.sharePath;
const pathOnly = cleanPath.split('?')[0];
if (pathOnly) {
basePath = pathOnly;
}
if (!targetId) {
const idMatch = cleanPath.match(/[?&]id=([^&]+)/);
if (idMatch) {
targetId = idMatch[1];
}
}
}
// 拼团专属卡片二维码:扫码后直接打开 H5 对应商品详情页,路由后面加 id=${this.id}&activedType=groupBuy&activityId=1
this.qrvalue = `${SHARE_URL}/#/${basePath}?id=${targetId}&activedType=groupBuy&activityId=1`;
} else if (this.sharePath) {
const cleanPath = this.sharePath.startsWith('/') ? this.sharePath.slice(1) : this.sharePath;
this.qrvalue = `${SHARE_URL}/#/${cleanPath}`;
} else if (this.id) {
this.qrvalue = `${SHARE_URL}/#/pages/other_package/productInfo/productInfo?id=${this.id}`;
}
if (this.qrvalue) {
this.$nextTick(() => {
setTimeout(() => {
if (this.$refs.qrcode && this.$refs.qrcode._makeCode) {
this.$refs.qrcode._makeCode();
}
if (this.$refs.groupQrcode && this.$refs.groupQrcode._makeCode) {
this.$refs.groupQrcode._makeCode();
}
}, 50);
});
}
}
},
creatQrcode() {
if (this.$refs.qrcode && this.$refs.qrcode._makeCode) {
this.$refs.qrcode._makeCode();
}
},
onBtn(index) {
if (index == 2) {
let tmp = `【信任桥】消费共享数字化权益 ${this.qrvalue} ${this.text}`;
// #ifdef APP-PLUS
console.log("--11---", tmp)
uni.setClipboardData({
data: tmp,
success: function (res) {
uni.getClipboardData({
success: function (res) {
Func.myToast('复制成功')
}
})
}
})
// #endif
// #ifdef H5
this.$copyText(tmp).then(res => {
console.log('resresresres', res)
Func.myToast('复制成功')
})
// #endif
}
console.log('微信分享', index);
this.$emit('wxShare', index)
},
onShare(index) {
if (index == 2) {
let tmp = `【信任桥】消费共享数字化权益 ${this.qrvalue} ${this.text}`;
// #ifdef APP-PLUS
uni.setClipboardData({
data: tmp,
success: function (res) {
uni.getClipboardData({
success: function (res) {
Func.myToast('复制成功')
}
})
}
})
// #endif
// #ifdef H5
this.$copyText(tmp).then(res => {
console.log('resresresres', res)
Func.myToast('复制成功')
})
// #endif
} else if (index == 3) {
if (this.isGroupBuy) {
this.saveGroupCard();
return;
}
}
this.$emit('share', index)
},
onGroupQrResult(res) {
this.groupQrPath = res;
},
getLocalImage(url) {
return new Promise((resolve) => {
if (!url) {
resolve('');
return;
}
if (
url.startsWith('file://') ||
url.startsWith('_doc') ||
url.startsWith('/storage') ||
url.startsWith('blob:') ||
url.startsWith('data:')
) {
resolve(url);
return;
}
uni.downloadFile({
url: url,
success: (res) => {
if (res.statusCode === 200 && res.tempFilePath) {
resolve(res.tempFilePath);
} else {
uni.getImageInfo({
src: url,
success: (info) => resolve(info.path),
fail: () => resolve('')
});
}
},
fail: () => {
uni.getImageInfo({
src: url,
success: (info) => resolve(info.path),
fail: () => resolve('')
});
}
});
});
},
base64ToTempFile(base64Data) {
return new Promise((resolve) => {
if (!base64Data || !base64Data.startsWith('data:image')) {
resolve(base64Data);
return;
}
// #ifdef APP-PLUS
try {
const bitmap = new plus.nativeObj.Bitmap('qr_' + Date.now());
bitmap.loadBase64Data(
base64Data,
() => {
const tempPath = `_doc/qr_${Date.now()}.png`;
bitmap.save(
tempPath,
{ overwrite: true, format: 'png', quality: 100 },
(e) => {
bitmap.clear();
resolve(e.target);
},
() => {
bitmap.clear();
resolve(base64Data);
}
);
},
() => {
bitmap.clear();
resolve(base64Data);
}
);
} catch (e) {
resolve(base64Data);
}
// #endif
// #ifndef APP-PLUS
resolve(base64Data);
// #endif
});
},
drawRoundedRect(ctx, x, y, width, height, radius, fill, stroke) {
ctx.beginPath();
ctx.moveTo(x + radius, y);
ctx.lineTo(x + width - radius, y);
ctx.arcTo(x + width, y, x + width, y + radius, radius);
ctx.lineTo(x + width, y + height - radius);
ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius);
ctx.lineTo(x + radius, y + height);
ctx.arcTo(x, y + height, x, y + height - radius, radius);
ctx.lineTo(x, y + radius);
ctx.arcTo(x, y, x + radius, y, radius);
ctx.closePath();
if (fill) {
ctx.fill();
}
if (stroke) {
ctx.stroke();
}
},
drawWrapText(ctx, text, x, y, maxWidth, lineHeight, maxLines = 2) {
if (!text) return y;
const chars = String(text).split('');
let line = '';
let currentLine = 1;
let currentY = y;
for (let n = 0; n < chars.length; n++) {
const testLine = line + chars[n];
const metrics = ctx.measureText ? ctx.measureText(testLine) : { width: testLine.length * 14 };
const testWidth = metrics.width;
if (testWidth > maxWidth && n > 0) {
if (currentLine === maxLines) {
let ellipsisLine = line;
while (ellipsisLine.length > 0) {
const lineWithEllipsis = ellipsisLine + '...';
const m = ctx.measureText ? ctx.measureText(lineWithEllipsis) : { width: lineWithEllipsis.length * 14 };
if (m.width <= maxWidth) {
ctx.fillText(lineWithEllipsis, x, currentY);
break;
}
ellipsisLine = ellipsisLine.slice(0, -1);
}
return currentY + lineHeight;
}
ctx.fillText(line, x, currentY);
line = chars[n];
currentY += lineHeight;
currentLine++;
} else {
line = testLine;
}
}
ctx.fillText(line, x, currentY);
return currentY + lineHeight;
},
async saveGroupCard() {
if (this.isGeneratingPoster) return;
this.isGeneratingPoster = true;
uni.showLoading({ title: '海报生成中...', mask: true });
try {
let localTu = '';
if (this.tu) {
localTu = await this.getLocalImage(this.tu);
}
const avatarUrl = this.currentInviterAvatar;
let localAvatar = '';
if (avatarUrl) {
localAvatar = await this.getLocalImage(avatarUrl);
}
let qrImg = this.groupQrPath || (this.$refs.groupQrcode && this.$refs.groupQrcode.result);
if (!qrImg && this.$refs.groupQrcode) {
if (this.$refs.groupQrcode._makeCode) {
this.$refs.groupQrcode._makeCode();
}
await new Promise((r) => setTimeout(r, 450));
qrImg = this.groupQrPath || (this.$refs.groupQrcode && this.$refs.groupQrcode.result);
}
if (!qrImg) {
await new Promise((r) => setTimeout(r, 300));
qrImg = this.groupQrPath || (this.$refs.groupQrcode && this.$refs.groupQrcode.result);
}
if (qrImg && qrImg.startsWith('data:image')) {
qrImg = await this.base64ToTempFile(qrImg);
}
const ctx = uni.createCanvasContext('groupCardCanvas', this);
const W = 560;
const H = 910;
const pad = 24;
const innerW = W - pad * 2; // 512
// 1. 卡片背景
ctx.fillStyle = '#FFFFFF';
this.drawRoundedRect(ctx, 0, 0, W, H, 24, true, false);
// 2. 商品主图
if (localTu) {
ctx.save();
this.drawRoundedRect(ctx, pad, pad, innerW, 500, 16, false, false);
ctx.clip();
ctx.drawImage(localTu, pad, pad, innerW, 500);
ctx.restore();
} else {
ctx.fillStyle = '#F7F7F7';
this.drawRoundedRect(ctx, pad, pad, innerW, 500, 16, true, false);
}
// 3. 价格行
const priceRowY = pad + 500 + 20; // 544
ctx.font = 'normal 500 24px sans-serif';
ctx.fillStyle = '#7F3BF5';
ctx.textBaseline = 'middle';
ctx.fillText('拼团价', pad, priceRowY + 18);
const labelWidth = ctx.measureText ? ctx.measureText('拼团价').width : 72;
ctx.font = 'bold 22px sans-serif';
ctx.fillStyle = '#7F3BF5';
const symbolX = pad + labelWidth + 6;
ctx.fillText('¥', symbolX, priceRowY + 19);
const symbolWidth = ctx.measureText ? ctx.measureText('¥').width : 16;
const displayPrice = String(this.groupPrice || this.price || '0');
ctx.font = 'bold 42px sans-serif';
ctx.fillStyle = '#7F3BF5';
const numX = symbolX + symbolWidth + 4;
ctx.fillText(displayPrice, numX, priceRowY + 16);
if (this.requiredNum) {
const tagText = `${this.requiredNum}人成团`;
ctx.font = 'normal 500 20px sans-serif';
const tagTextWidth = ctx.measureText ? ctx.measureText(tagText).width : 74;
const tagW = tagTextWidth + 24;
const tagH = 34;
const tagX = W - pad - tagW;
const tagY = priceRowY + 2;
ctx.fillStyle = '#F3EBFE';
this.drawRoundedRect(ctx, tagX, tagY, tagW, tagH, 8, true, false);
ctx.fillStyle = '#7F3BF5';
ctx.textBaseline = 'middle';
ctx.fillText(tagText, tagX + 12, tagY + tagH / 2);
}
// 4. 商品名称 (最多2行,溢出显示省略号)
const titleY = priceRowY + 54;
ctx.fillStyle = '#222222';
ctx.font = 'bold 26px sans-serif';
ctx.textBaseline = 'top';
const nextY = this.drawWrapText(ctx, this.text || '', pad, titleY, innerW, 36, 2);
// 5. 分割线
const dividerY = Math.max(nextY + 12, titleY + 76);
ctx.strokeStyle = '#F0F0F0';
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(pad, dividerY);
ctx.lineTo(W - pad, dividerY);
ctx.stroke();
// 6. 底部区域
const bottomY = dividerY + 18;
ctx.fillStyle = '#1E1E1E';
ctx.font = 'bold 30px sans-serif';
ctx.textBaseline = 'top';
ctx.fillText('超值拼团', pad, bottomY);
ctx.fillStyle = '#999999';
ctx.font = 'normal 20px sans-serif';
ctx.fillText('人多价更优 拼团更实惠', pad, bottomY + 38);
const userRowY = bottomY + 74;
const avatarSize = 44;
if (localAvatar) {
ctx.save();
ctx.beginPath();
ctx.arc(pad + avatarSize / 2, userRowY + avatarSize / 2, avatarSize / 2, 0, 2 * Math.PI);
ctx.closePath();
ctx.clip();
ctx.drawImage(localAvatar, pad, userRowY, avatarSize, avatarSize);
ctx.restore();
} else {
ctx.fillStyle = '#EEEEEE';
ctx.beginPath();
ctx.arc(pad + avatarSize / 2, userRowY + avatarSize / 2, avatarSize / 2, 0, 2 * Math.PI);
ctx.fill();
}
ctx.fillStyle = '#333333';
ctx.font = 'normal 500 22px sans-serif';
ctx.textBaseline = 'middle';
const username = this.currentInviterName;
ctx.fillText(username, pad + avatarSize + 12, userRowY + avatarSize / 2);
// 二维码绘制(带纯白底色与四周静区 Padding,确保微信扫码/长按识别成功率)
const qrBoxSize = 144;
const qrInnerPad = 10;
const qrSize = qrBoxSize - qrInnerPad * 2; // 124px
const qrBoxX = W - pad - qrBoxSize;
const qrBoxY = bottomY;
// 绘制白色背景底卡
ctx.fillStyle = '#FFFFFF';
this.drawRoundedRect(ctx, qrBoxX, qrBoxY, qrBoxSize, qrBoxSize, 8, true, false);
if (qrImg) {
ctx.drawImage(qrImg, qrBoxX + qrInnerPad, qrBoxY + qrInnerPad, qrSize, qrSize);
}
ctx.fillStyle = '#999999';
ctx.font = 'normal 17px sans-serif';
ctx.textBaseline = 'top';
const tipText = '长按识别 参与拼团';
const tipWidth = ctx.measureText ? ctx.measureText(tipText).width : 120;
const tipX = qrBoxX + (qrBoxSize - tipWidth) / 2;
ctx.fillText(tipText, tipX, qrBoxY + qrBoxSize + 8);
// 7. 提交绘制
await new Promise((resolve) => {
ctx.draw(false, () => {
setTimeout(resolve, 200);
});
});
// 8. 导出临时图片
const tempFilePath = await new Promise((resolve, reject) => {
uni.canvasToTempFilePath(
{
canvasId: 'groupCardCanvas',
fileType: 'png',
width: W,
height: H,
destWidth: W * 2,
destHeight: H * 2,
quality: 1,
success: (res) => resolve(res.tempFilePath),
fail: (err) => reject(err)
},
this
);
});
uni.hideLoading();
// 9. 保存至相册
// #ifdef APP-PLUS || MP-WEIXIN
uni.saveImageToPhotosAlbum({
filePath: tempFilePath,
success: () => {
uni.showToast({
title: '已保存至手机相册',
icon: 'success',
duration: 2000
});
this.onClose();
},
fail: (err) => {
console.error('保存相册失败:', err);
if (err && err.errMsg && (err.errMsg.includes('auth') || err.errMsg.includes('authorize'))) {
uni.showModal({
title: '提示',
content: '需要保存图片到相册权限,请在系统设置中开启相册权限',
success: (res) => {
if (res.confirm) uni.openSetting();
}
});
} else {
uni.previewImage({ urls: [tempFilePath] });
}
}
});
// #endif
// #ifdef H5
uni.previewImage({ urls: [tempFilePath] });
uni.showToast({ title: '请长按图片保存到手机相册', icon: 'none' });
this.onClose();
// #endif
} catch (err) {
uni.hideLoading();
console.error('生成或保存海报失败:', err);
uni.showToast({
title: '生成海报失败,请重试',
icon: 'none'
});
} finally {
this.isGeneratingPoster = false;
}
},
onClose() {
this.$emit('close');
},
onOk() {
Func.debounce(this.dOk())
},
dOk() {
this.$emit('ok');
}
}
}
</script>
<style lang="scss" scoped>
.group-share-card {
position: absolute;
bottom: 100%;
margin-bottom: 24rpx;
left: 50%;
transform: translateX(-50%);
width: 560rpx;
background-color: #ffffff;
border-radius: 24rpx;
padding: 24rpx;
box-sizing: border-box;
box-shadow: 0 10rpx 36rpx rgba(0, 0, 0, 0.16);
z-index: 10;
.group-card-img {
width: 100%;
height: 500rpx;
border-radius: 16rpx;
background-color: #f7f7f7;
display: block;
}
.group-card-price-row {
margin-top: 20rpx;
display: flex;
flex-direction: row;
align-items: baseline;
justify-content: space-between;
.group-card-price-box {
display: flex;
flex-direction: row;
align-items: baseline;
.group-card-price-label {
font-size: 26rpx;
color: #7f3bf5;
font-weight: 500;
}
.group-card-price-symbol {
font-size: 24rpx;
color: #7f3bf5;
font-weight: bold;
margin-left: 6rpx;
margin-right: 4rpx;
}
.group-card-price-num {
font-size: 42rpx;
color: #7f3bf5;
font-weight: bold;
line-height: 1;
}
}
.group-card-tag {
background-color: #f3ebfe;
color: #7f3bf5;
font-size: 22rpx;
font-weight: 500;
padding: 6rpx 14rpx;
border-radius: 8rpx;
line-height: 1;
}
}
.group-card-title {
margin-top: 14rpx;
font-size: 28rpx;
font-weight: 500;
color: #222222;
line-height: 38rpx;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
}
.group-card-divider {
width: 100%;
height: 1rpx;
background-color: #f0f0f0;
margin: 20rpx 0 16rpx 0;
}
.group-card-bottom {
display: flex;
flex-direction: row;
align-items: flex-end;
justify-content: space-between;
.group-card-bottom-left {
flex: 1;
padding-right: 16rpx;
.group-card-main-title {
font-size: 32rpx;
font-weight: bold;
color: #1e1e1e;
line-height: 1.2;
}
.group-card-sub-title {
font-size: 22rpx;
color: #999999;
margin-top: 6rpx;
line-height: 1.2;
}
.group-card-user-row {
display: flex;
flex-direction: row;
align-items: center;
margin-top: 20rpx;
.group-card-avatar {
width: 44rpx;
height: 44rpx;
border-radius: 50%;
background-color: #f0f0f0;
flex-shrink: 0;
}
.group-card-username {
font-size: 24rpx;
color: #333333;
font-weight: 500;
margin-left: 12rpx;
max-width: 200rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
.group-card-bottom-right {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
flex-shrink: 0;
.group-card-qr-box {
width: 140rpx;
height: 140rpx;
padding: 8rpx;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
background-color: #ffffff;
border-radius: 8rpx;
overflow: hidden;
::v-deep .tki-qrcode,
::v-deep .tki-qrcode image {
width: 124rpx !important;
height: 124rpx !important;
display: block;
}
}
.group-card-qr-tip {
font-size: 18rpx;
color: #999999;
margin-top: 6rpx;
white-space: nowrap;
}
}
}
}
.share-top-image-view {
width: 400rpx;
min-height: 496rpx;
height: 496rpx;
display: flex;
flex-direction: column;
align-items: center;
padding: 32rpx;
box-sizing: border-box;
border-radius: 24rpx;
position: absolute;
background-color: #fff;
top: -638rpx;
.image-view-bottom {
width: 100%;
flex: 1;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
margin-top: 20rpx;
.image-view-bottom-left {
height: 72rpx;
min-height: 72rpx;
border-right: 2rpx solid #EBEBEB;
display: flex;
align-items: center;
padding-right: 10rpx;
}
.image-view-bottom-right {
// min-width:130rpx;
margin-left: 10rpx;
height: 72rpx;
min-height: 72rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-end;
}
}
.tu-img {
width: 100%;
height: 344rpx;
}
}
.share-popup-view {
width: 100%;
// height: 400rpx;
display: flex;
flex-direction: column;
align-items: center;
background-color: #fff;
border-radius: 24rpx 24rpx 0 0;
position: relative;
.share-head {
width: 100%;
height: 88rpx;
display: flex;
align-items: center;
justify-content: center;
}
.share-bottom {
width: 100%;
height: 92rpx;
min-height: 92rpx;
display: flex;
align-items: center;
justify-content: center;
}
.share-line {
display: flex;
width: 100%;
height: 2rpx;
min-height: 2rpx;
background-color: #e7e7e7;
}
.qr-view {
width: 100%;
height: 332rpx;
min-height: 332rpx;
display: flex;
align-items: center;
justify-content: center;
}
.share-btn-view {
width: 100%;
height: 124rpx;
min-height: 124rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
// padding: 0 36rpx;
box-sizing: border-box;
margin-top: 36rpx;
.share-box {
flex: 1;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
.share-img {
width: 80rpx;
height: 80rpx;
}
}
.share-btn-clean {
background: none !important;
background-color: transparent !important;
border: 0 !important;
padding: 0 !important;
margin: 0 !important;
line-height: normal !important;
font-size: inherit !important;
color: inherit !important;
outline: none !important;
border-radius: 0 !important;
box-sizing: border-box !important;
display: flex !important;
flex-direction: column !important;
justify-content: space-between !important;
align-items: center !important;
&::after {
border: none !important;
display: none !important;
}
}
}
}
.hideCanvasView {
position: fixed;
top: 10000px;
left: 10000px;
width: 560px;
height: 910px;
z-index: -9999;
}
</style>