一、业务需求
分享链接,包括:
下载二维码,保存到相册;
复制链接,可以复制链接内容;
分享到微信,可以唤起微信。
二、实现效果
三、核心
唤起微信
// data定义
wexinParam: {
name: '微信',
pname: 'com.tencent.mm',
scheme: 'weixin://'
}
// 调用方法
this.launchApp(this.wexinParam)
// 打开外部应用-微信
launchApp(data) {
if (plus.os.name == 'Android') {
plus.runtime.launchApplication({ pname: e.pname }, function(e) {
console.log('Open system default browser failed: ' + e.name)
})
} else if (plus.os.name == 'iOS') {
plus.runtime.launchApplication({ action: e.scheme }, function(e) {
console.log('Open system default browser failed: ' + e.name)
})
}
}
三、代码实现
1、分享链接弹框
shareLink.vue
<template>
<my-popup
ref="myPopup"
type="bottom"
title="分享链接"
:topCancel="false"
:isShowFooter="false"
height="32vh">
<view class="share-link">
<view class="share-link-item" @click="downloadQRCode">
<image src="../../../static/visitorMgt/download-qr-code.png" mode=""></image>
<view class="share-link-item-title">下载二维码</view>
</view>
<view class="share-link-item" @click="copyLink">
<image src="../../../static/visitorMgt/copy-link.png" mode=""></image>
<view class="share-link-item-title">复制链接</view>
</view>
<view class="share-link-item" @click="shareOnWechat">
<image src="../../../static/visitorMgt/share-on-wechat.png" mode=""></image>
<view class="share-link-item-title">分享到微信</view>
</view>
</view>
<view class="share-link-bottom">
<view class="share-link-cancel" @click="cancel">
取消
</view>
</view>
</my-popup>
</template>
<script>
import {
getLinkVisitorInfo,
getQRVisitorInfo,
} from '@/api/visitorMgt/visitorMgt.js'
import {
getFullUrl,
downLoadImg
} from '@/utils/commonFun.js'
export default {
name: 'shareLink',
props: {
visitFormId: {
type: Number,
default: null
}
},
data() {
return {
wexinParam: {
name: '微信',
pname: 'com.tencent.mm',
scheme: 'weixin://'
}
}
},
methods: {
/**
* 取消按钮
*/
cancel() {
this.$refs.myPopup.popupClose()
this.$emit('shareCancel')
},
/**
* 打开弹框
*/
popupOpen() {
this.$refs.myPopup.popupOpen()
},
/**
* 下载二维码
*/
downloadQRCode(){
getQRVisitorInfo(this.visitFormId).then(res => {
let fileData = JSON.parse(res)
this.imageSrc = getFullUrl(fileData.fileUrl)
this.imageName = fileData.originalName
downLoadImg({
fileUrl: this.imageSrc,
originalName: this.imageName
})
})
},
/**
* 复制链接
*/
copyLink() {
getLinkVisitorInfo(this.visitFormId).then(res => {
uni.setClipboardData({
data: res.shortUrl
})
})
},
/**
* 分享到微信
*/
shareOnWechat() {
getLinkVisitorInfo(this.visitFormId).then(res => {
uni.setClipboardData({
data: res.shortUrl
})
uni.$u.toast('已复制,正在打开微信...')
setTimeout(() => {
// 打开微信
this.launchApp(this.wexinParam)
}, 1000)
})
},
/**
* 打开外部应用-微信
*/
launchApp(e) {
// 判断平台
if (plus.os.name == 'Android') {
plus.runtime.launchApplication({ pname: e.pname }, function(e) {
console.log('Open system default browser failed: ' + e.name)
})
} else if (plus.os.name == 'iOS') {
plus.runtime.launchApplication({ action: e.scheme }, function(e) {
console.log('Open system default browser failed: ' + e.name)
})
}
}
}
}
</script>
<style lang="scss" scoped>
.share-link {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
.share-link-item {
width: 33%;
margin-top: 20rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
image {
width: 100rpx;
height: 100rpx;
}
.share-link-item-title {
margin-top: 16rpx;
color: #8E8E8E;
}
}
}
.share-link-bottom {
padding-top: 32rpx;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
.share-link-cancel {
flex: 1;
height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 32rpx;
font-weight: 500;
color: #000000;
}
}
</style>
2、工具类
export const config = {
baseUrl: "/api",
filePath: "http://115.1.2.3:280",
// #ifdef APP-PLUS
// 开发环境
baseUrl: "http://115.1.2.3:280/stage-api",
filePath: "http://115.1.2.3:280",
// #endif
}
// 文件图片地址
export function getFullUrl(url) {
let fullUrl = ''
if (url) {
fullUrl = /(http|https|blob:):\/\/([\w.]+\/?)\S*/.test(url)
? url
: config.filePath + url
}
return fullUrl
}
export const downLoadImg = (file) => {
// #ifdef APP-PLUS
uni.showLoading({
title: '正在下载'
})
uni.downloadFile({
url: getFullUrl(file.fileUrl),
success: (res) => {
if (res.statusCode === 200) {
// console.log(res.tempFilePath)
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: () => {
uni.$u.toast('已保存到系统相册')
},
fail: () => {
uni.$u.toast('图片保存失败')
},
complete: () => {}
})
}
},
complete: () => {
uni.hideLoading()
}
})
// #endif
// #ifdef H5
window.open(getFullUrl(file.fileUrl))
// #endif
// #ifdef MP
uni.setClipboardData({
data: getFullUrl(file.fileUrl),
success: () => {
uni.$u.toast('链接已复制,请在浏览器打开')
}
})
// #endif
}
3、弹框组件
my-popup.vue
<template>
<uni-popup
ref="popup"
:safe-area="false"
:type="type"
:is-mask-click="isMaskClick"
@change="change"
@maskClick="maskClick">
<view class="popup-content" :style="{ 'height': height }">
<view v-if="topBtn" class="popup-top">
<view class="popup-top-cancel" @click="cancel">{{ topCancelText }}</view>
<view class="popup-title">
<slot name="title" v-if="$slots.title"></slot>
<view v-else>
{{ title }}
</view>
</view>
<view class="popup-top-confirm" @click="confirm">
{{ topConfirmText }}
</view>
</view>
<view v-else class="popup-title">
<slot name="title" v-if="$slots.title"></slot>
<view v-else>
{{ title }}
</view>
<image
v-if="topCancel"
src="../../static/common/close-outlined.png"
mode=""
class="icon-close w-40 h-40"
@click="closed"
></image>
</view>
<view
class="popup-middle"
:class="[isShowFooter ? 'popup-middle-bottom-160' : 'popup-middle-bottom-32']"
>
<slot></slot>
</view>
<view class="popup-bottom" v-if="isShowFooter">
<view
v-if="isShowCancelBtn"
class="popup-bottom-cancel mr-20"
@click="cancel"
>{{ cancelText }}</view>
<view class="popup-bottom-confirm" @click="confirm">{{ confirmText }}</view>
</view>
</view>
</uni-popup>
</template>
<script>
export default {
name: "my-popup",
props: {
// 弹出方式
type: {
type: String,
default: 'bottom'
},
// 内容区高度
height: {
type: String,
default: ''
},
// 表头
title: {
type: String,
default: '筛选'
},
// 取消按钮text
cancelText: {
type: String,
default: '重置'
},
// 确定按钮text
confirmText: {
type: String,
default: '确定'
},
// 顶部,取消按钮text
topCancelText: {
type: String,
default: '取消'
},
// 顶部,确定按钮text
topConfirmText: {
type: String,
default: '确定'
},
// 蒙版点击是否关闭弹窗
isMaskClick: {
type: Boolean,
default: true
},
// 点击确定是否校验内容区域
confirmIsCheck: {
type: Boolean,
default: false
},
// 点击取消是否校验内容区域
cancelIsCheck: {
type: Boolean,
default: false
},
// 是否显示footer
isShowFooter: {
type: Boolean,
default: true
},
// 顶部显示按钮
topBtn: {
type: Boolean,
default: false
},
// 顶部不显示按钮时,是否展示取消图标
topCancel: {
type: Boolean,
default: true
},
// 是否显示取消按钮
isShowCancelBtn: {
type: Boolean,
default: false
}
},
data() {
return {}
},
methods: {
/**
* 打开弹框
*/
popupOpen() {
this.$refs.popup.open()
},
/**
* 关闭弹框
*/
popupClose() {
this.$refs.popup.close()
},
/**
* 右上角按钮关闭
*/
closed() {
this.popupClose()
this.$emit('closed')
},
/**
* 取消按钮点击
*/
cancel() {
if (!this.cancelIsCheck) {
this.popupClose()
}
this.$emit('cancel')
},
/**
* 确定按钮点击
*/
confirm() {
if (!this.confirmIsCheck) {
this.popupClose()
}
this.$emit('confirm')
},
/**
* 组件状态发生变化触发
* @param {Object} e
*/
change(e) {
this.$emit('change', e)
},
/**
* 点击遮罩层触发
*/
maskClick() {
this.$emit('maskClick')
}
}
}
</script>
<style lang="scss" scoped>
.popup-content {
height: 70vh;
border-radius: 40rpx 40rpx 0 0;
background: #fff;
}
.popup-title {
height: 90rpx;
line-height: 90rpx;
display: flex;
justify-content: center;
box-sizing: border-box;
padding: 0 32rpx;
position: relative;
font-size: 32rpx;
font-weight: bold;
overflow: hidden;
color: #000000;
.icon-close {
position: absolute;
right: 32rpx;
top: 24rpx;
}
}
.popup-top {
display: flex;
align-items: center;
font-weight: bold;
padding: 0 32rpx;
box-sizing: border-box;
.popup-title {
flex: 1;
padding: 0 32rpx;
}
.popup-top-cancel {
font-size: 32rpx;
color: #000000;
}
.popup-top-confirm {
font-size: 32rpx;
color: #005AFF;
}
}
.popup-middle {
overflow-y: auto;
padding: 0 32rpx;
box-sizing: border-box;
position: absolute;
right: 0;
left: 0;
top: 90rpx;
background-color: #fff;
}
.popup-middle-bottom-160 {
bottom: 160rpx;
}
.popup-middle-bottom-32 {
bottom: 32rpx;
}
.popup-bottom {
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 160rpx;
padding: 32rpx 32rpx 48rpx;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
.popup-bottom-cancel,
.popup-bottom-confirm {
flex: 1;
height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 32rpx;
color: #FFFFFF;
font-weight: 500;
border-radius: 58rpx;
}
.popup-bottom-cancel {
border: 2rpx solid #005AFF;
color: #005AFF;
}
.popup-bottom-confirm {
background: linear-gradient(180deg, #4D8CFF 0%, #005AFF 100%);
}
}
</style>