2025-11-14 11:39:33 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<u-popup v-model="show" mode="bottom" border-radius="16" closeable>
|
|
|
|
|
|
<view class="popup-content">
|
2026-01-15 17:18:24 +08:00
|
|
|
|
<view class="popup-title">{{ title }}</view>
|
2025-11-14 11:39:33 +08:00
|
|
|
|
|
|
|
|
|
|
<u-cell-group>
|
2026-01-15 17:18:24 +08:00
|
|
|
|
<!-- 微信小程序:官方分享 -->
|
|
|
|
|
|
<!-- #ifdef MP-WEIXIN -->
|
|
|
|
|
|
<button open-type="share" class="share-btn" :style="{backgroundColor: btnColor}">
|
|
|
|
|
|
📤 分享给好友
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<!-- #endif -->
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 非小程序:外部链接 -->
|
|
|
|
|
|
<!-- #ifndef MP-WEIXIN -->
|
|
|
|
|
|
<u-cell-item
|
|
|
|
|
|
title="🔗 复制网页分享链接"
|
|
|
|
|
|
@click="copyLink"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<!-- #endif -->
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 全平台 -->
|
|
|
|
|
|
<!-- <u-cell-item
|
|
|
|
|
|
title="📱 生成二维码分享"
|
|
|
|
|
|
@click="generateQrcode"
|
|
|
|
|
|
/> -->
|
2025-11-14 11:39:33 +08:00
|
|
|
|
</u-cell-group>
|
|
|
|
|
|
|
|
|
|
|
|
<view class="cancel-btn" @click="show = false">取消</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 二维码弹窗 -->
|
|
|
|
|
|
<u-popup v-model="showQrcode" mode="center" border-radius="12">
|
|
|
|
|
|
<view class="qrcode-box">
|
2026-01-15 17:18:24 +08:00
|
|
|
|
<image v-if="qrcodeUrl" :src="qrcodeUrl" class="qrcode-img" />
|
|
|
|
|
|
<view class="tips">扫一扫打开</view>
|
2025-11-14 11:39:33 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
</u-popup>
|
|
|
|
|
|
</u-popup>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
|
import QRCode from 'qrcode'
|
|
|
|
|
|
|
|
|
|
|
|
export default {
|
2026-01-15 17:18:24 +08:00
|
|
|
|
name: 'SharePopup',
|
2025-11-14 11:39:33 +08:00
|
|
|
|
props: {
|
2026-01-15 17:18:24 +08:00
|
|
|
|
/** 弹窗标题 */
|
|
|
|
|
|
title: {
|
|
|
|
|
|
type: String,
|
|
|
|
|
|
default: '分享'
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** 微信分享标题 */
|
|
|
|
|
|
shareTitle: {
|
|
|
|
|
|
type: String,
|
|
|
|
|
|
default: ''
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** 小程序页面路径 */
|
|
|
|
|
|
pagePath: {
|
|
|
|
|
|
type: String,
|
|
|
|
|
|
required: true
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** H5 页面路径 */
|
|
|
|
|
|
h5Path: {
|
|
|
|
|
|
type: String,
|
|
|
|
|
|
required: true
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** 分享参数(id / code 等) */
|
|
|
|
|
|
query: {
|
|
|
|
|
|
type: Object,
|
|
|
|
|
|
default: () => ({})
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** 小程序码接口 */
|
|
|
|
|
|
minicodeApi: {
|
|
|
|
|
|
type: String,
|
|
|
|
|
|
default: ''
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/** H5 基础域名(可选) */
|
|
|
|
|
|
baseUrl: {
|
|
|
|
|
|
type: String,
|
|
|
|
|
|
default: ''
|
|
|
|
|
|
},
|
|
|
|
|
|
btnColor: {
|
|
|
|
|
|
type: String,
|
|
|
|
|
|
default: ''
|
|
|
|
|
|
}
|
2025-11-14 11:39:33 +08:00
|
|
|
|
},
|
2026-01-15 17:18:24 +08:00
|
|
|
|
|
2025-11-14 11:39:33 +08:00
|
|
|
|
data() {
|
|
|
|
|
|
return {
|
|
|
|
|
|
show: false,
|
|
|
|
|
|
showQrcode: false,
|
|
|
|
|
|
qrcodeUrl: ''
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
2026-01-15 17:18:24 +08:00
|
|
|
|
|
|
|
|
|
|
computed: {
|
|
|
|
|
|
queryString() {
|
|
|
|
|
|
const query = this.query || {}
|
|
|
|
|
|
return Object.keys(query)
|
|
|
|
|
|
.filter(key => query[key] !== undefined && query[key] !== null)
|
|
|
|
|
|
.map(key => `${key}=${encodeURIComponent(query[key])}`)
|
|
|
|
|
|
.join('&')
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2025-11-14 11:39:33 +08:00
|
|
|
|
methods: {
|
|
|
|
|
|
open() {
|
|
|
|
|
|
this.show = true
|
|
|
|
|
|
},
|
2026-01-15 17:18:24 +08:00
|
|
|
|
|
|
|
|
|
|
/** 复制网页链接 */
|
|
|
|
|
|
copyLink() {
|
2025-11-14 11:39:33 +08:00
|
|
|
|
this.show = false
|
2026-01-15 17:18:24 +08:00
|
|
|
|
|
|
|
|
|
|
let url = ''
|
2025-11-14 11:39:33 +08:00
|
|
|
|
|
|
|
|
|
|
// #ifdef H5
|
2026-01-15 17:18:24 +08:00
|
|
|
|
url = `${window.location.origin}/#/${this.h5Path}?${this.queryString}`
|
2025-11-14 11:39:33 +08:00
|
|
|
|
// #endif
|
2026-01-15 17:18:24 +08:00
|
|
|
|
|
|
|
|
|
|
// #ifndef H5
|
|
|
|
|
|
url = `${this.baseUrl}/#/${this.h5Path}?${this.queryString}`
|
|
|
|
|
|
// #endif
|
|
|
|
|
|
|
2025-11-14 11:39:33 +08:00
|
|
|
|
uni.setClipboardData({
|
2026-01-15 17:18:24 +08:00
|
|
|
|
data: url,
|
2025-11-14 11:39:33 +08:00
|
|
|
|
success: () => {
|
2026-01-15 17:18:24 +08:00
|
|
|
|
uni.showToast({ title: '链接已复制', icon: 'success' })
|
2025-11-14 11:39:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
2026-01-15 17:18:24 +08:00
|
|
|
|
|
|
|
|
|
|
/** 生成二维码 / 小程序码 */
|
2025-11-14 11:39:33 +08:00
|
|
|
|
async generateQrcode() {
|
|
|
|
|
|
this.show = false
|
|
|
|
|
|
this.showQrcode = true
|
2026-01-15 17:18:24 +08:00
|
|
|
|
this.qrcodeUrl = ''
|
|
|
|
|
|
|
|
|
|
|
|
// ========== 小程序 ==========
|
|
|
|
|
|
// #ifdef MP-WEIXIN
|
|
|
|
|
|
if (!this.minicodeApi) {
|
|
|
|
|
|
uni.showToast({ title: '未配置小程序码接口', icon: 'none' })
|
|
|
|
|
|
this.showQrcode = false
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const res = await uni.request({
|
|
|
|
|
|
url: this.minicodeApi,
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
data: {
|
|
|
|
|
|
page: this.pagePath,
|
|
|
|
|
|
scene: this.queryString
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
this.qrcodeUrl = res.data.url
|
|
|
|
|
|
// #endif
|
|
|
|
|
|
|
|
|
|
|
|
// ========== H5 / App ==========
|
|
|
|
|
|
// #ifndef MP-WEIXIN
|
|
|
|
|
|
let url = ''
|
|
|
|
|
|
|
|
|
|
|
|
// #ifdef H5
|
|
|
|
|
|
url = `${window.location.origin}/#/${this.h5Path}?${this.queryString}`
|
|
|
|
|
|
// #endif
|
|
|
|
|
|
|
|
|
|
|
|
// #ifndef H5
|
|
|
|
|
|
url = `${this.baseUrl}/#/${this.h5Path}?${this.queryString}`
|
|
|
|
|
|
// #endif
|
|
|
|
|
|
|
|
|
|
|
|
this.qrcodeUrl = await QRCode.toDataURL(url, {
|
|
|
|
|
|
width: 300,
|
|
|
|
|
|
margin: 2
|
|
|
|
|
|
})
|
|
|
|
|
|
// #endif
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// #ifdef MP-WEIXIN
|
|
|
|
|
|
onShareAppMessage() {
|
|
|
|
|
|
return {
|
|
|
|
|
|
title: this.shareTitle || this.title,
|
|
|
|
|
|
path: `/${this.pagePath}?${this.queryString}`
|
2025-11-14 11:39:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-01-15 17:18:24 +08:00
|
|
|
|
// #endif
|
2025-11-14 11:39:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
|
.popup-content {
|
|
|
|
|
|
padding: 30rpx;
|
2026-01-15 17:18:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
.popup-title {
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
margin-bottom: 20rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.share-btn {
|
|
|
|
|
|
margin: 10rpx 30rpx;
|
|
|
|
|
|
padding: 20rpx;
|
|
|
|
|
|
border-radius: 12rpx;
|
|
|
|
|
|
color: #fff;
|
2025-11-14 11:39:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
.cancel-btn {
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
color: #666;
|
|
|
|
|
|
margin-top: 20rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.qrcode-box {
|
|
|
|
|
|
padding: 40rpx;
|
2026-01-15 17:18:24 +08:00
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
.qrcode-img {
|
|
|
|
|
|
width: 300rpx;
|
2025-11-14 11:39:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
</style>
|