forked from zhongyuanhaiju/uniapp
409 lines
12 KiB
Vue
409 lines
12 KiB
Vue
<!-- 省、市 两级地区选择器 -->
|
||
<template>
|
||
<view>
|
||
<!-- 分享弹框 -->
|
||
<van-share-sheet
|
||
v-model="show"
|
||
title="立即分享给好友"
|
||
:close-on-click-overlay="false"
|
||
:options="options"
|
||
:cancel-text="''"
|
||
@click-overlay="cancel"
|
||
@cancel="cancel"
|
||
@select="onShare"
|
||
/>
|
||
<!-- 二维码弹框 -->
|
||
<van-popup ref="qrcodeContent" class="qrcode-content" v-model="share_qrcode_show">
|
||
<canvas ref="qrcode" canvas-id="share-qrcode" class="qrcode-canvas" />
|
||
</van-popup>
|
||
<!-- 海报弹框 -->
|
||
<van-popup class="poster-content" v-model="share_poster_show">
|
||
<canvas ref="posterImage" canvas-id="posterImage" id="posterImage" class="poster-image" />
|
||
<image :src="poster_image" :show-menu-by-longpress="true" class="poster-image poster-show-image"/>
|
||
</van-popup>
|
||
<!--<view v-if="share_poster_show" class="poster-tip">-->
|
||
<!-- <view class="download-button" @click="downloadPoster">下载海报</view>-->
|
||
<!--</view>-->
|
||
|
||
<view v-if="share_poster_show" class="poster-tip">长按图片保存</view>
|
||
<!--同意关闭按钮-->
|
||
<van-button v-if="share_poster_show || share_qrcode_show" type="danger" size="small" class="cancel-btn" @click="cancelAll">
|
||
关闭
|
||
</van-button>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import uQRCode from '@/common/js/uqrcode.js'
|
||
import {Weixin} from "@/common/js/wx-jssdk";
|
||
import Http from "@/common/js/http";
|
||
|
||
export default {
|
||
name: 'share-panel',
|
||
props:{
|
||
// 是否显示
|
||
show:{
|
||
type: Boolean,
|
||
default: function() {
|
||
return false;
|
||
}
|
||
},
|
||
// 分享信息
|
||
share: {
|
||
type: Object,
|
||
default: function() {
|
||
return {};
|
||
}
|
||
},
|
||
// 分享参数
|
||
shareParams: {
|
||
type: Array,
|
||
default: function() {
|
||
return [];
|
||
}
|
||
},
|
||
},
|
||
onLoad() {},
|
||
onShow() {},
|
||
data() {
|
||
return {
|
||
userInfo: {},
|
||
path: '',
|
||
options: [
|
||
// { name: '微信', icon: 'wechat' },
|
||
{ name: '复制链接', icon: 'link' },
|
||
{ name: '分享海报', icon: 'poster' },
|
||
{ name: '二维码', icon: 'qrcode' },
|
||
],
|
||
share_qrcode_show: false,// 二维码分享
|
||
share_poster_show: false,// 海报分享
|
||
share_id: '',
|
||
|
||
poster_image: '',
|
||
};
|
||
},
|
||
watch: {
|
||
share: {
|
||
handler(newValue, oldValue) {
|
||
|
||
this.createSharePath();
|
||
this.setPublicShare();
|
||
},
|
||
immediate: false,
|
||
deep: true
|
||
}
|
||
},
|
||
created() {},
|
||
mounted() {
|
||
// 生成唯一分享id
|
||
this.createShareId();
|
||
// 获取个人信息
|
||
this.getUserInfo();
|
||
},
|
||
methods: {
|
||
//获取个人信息
|
||
getUserInfo() {
|
||
this.$api.sendRequest({
|
||
url: '/api/member/info',
|
||
success: res => {
|
||
if (res.code == 0) {
|
||
this.userInfo = res.data;
|
||
|
||
this.createSharePath();
|
||
this.setPublicShare();
|
||
}
|
||
}
|
||
});
|
||
},
|
||
// 关闭
|
||
cancel(){
|
||
this.$emit('close');
|
||
},
|
||
// 关闭全部
|
||
cancelAll(){
|
||
this.share_qrcode_show = false;
|
||
this.share_poster_show = false;
|
||
|
||
this.cancel();
|
||
},
|
||
// 点击分享
|
||
onShare(option,index){
|
||
this.recordSharing();
|
||
// 根据点击的类型进行对应的分享操作
|
||
let icon = option.icon;
|
||
switch (icon){
|
||
case 'link': this.shareLink();break;
|
||
case 'poster': this.sharePoster();break;
|
||
case 'qrcode': this.shareQrcode();break;
|
||
}
|
||
},
|
||
// 分享 —— 复制链接
|
||
shareLink(){
|
||
this.$util.copy(this.path);
|
||
this.cancel();
|
||
},
|
||
// 分享 —— 二维码
|
||
shareQrcode(is_get = false){
|
||
let _this = this;
|
||
_this.cancel();
|
||
_this.share_qrcode_show = true
|
||
return new Promise((req, rej) => {
|
||
_this.$nextTick(() => {
|
||
if(is_get) _this.$refs.qrcodeContent.$el.style.marginLeft = '50000px';
|
||
else _this.$refs.qrcodeContent.$el.style.marginLeft = '0';
|
||
let size = _this.$refs.qrcode.$el.offsetHeight;
|
||
uQRCode.make({
|
||
canvasId: 'share-qrcode',
|
||
componentInstance: this,
|
||
text: _this.path,
|
||
size: size,
|
||
margin: 10,
|
||
backgroundColor: '#ffffff',
|
||
foregroundColor: '#000000',
|
||
fileType: 'jpg',
|
||
errorCorrectLevel: uQRCode.errorCorrectLevel.H,
|
||
success: res => {
|
||
req(res);
|
||
}
|
||
});
|
||
})
|
||
});
|
||
},
|
||
// 分享 —— 生成海报
|
||
async sharePoster(){
|
||
// 显示内容
|
||
let _this = this;
|
||
_this.share_poster_show = true;
|
||
let backgroundImage = _this.$util.img('public/picture/aijiu/article_bg.jpg');// 背景图片
|
||
let avatar = _this.$util.img( _this.userInfo.headimg );// 用户头像
|
||
let qrcode = '';
|
||
await _this.shareQrcode(true).then((res)=>{
|
||
qrcode = res;
|
||
_this.share_qrcode_show = false
|
||
});
|
||
// 开始绘制
|
||
_this.$nextTick(() => {
|
||
// 获取画布大小
|
||
let width = _this.$refs.posterImage.$el.offsetWidth;// 300
|
||
let height = _this.$refs.posterImage.$el.offsetHeight;// 510
|
||
// 生成基本画布
|
||
let ctx = uni.createCanvasContext('posterImage', this);
|
||
ctx.setFillStyle('#ffffff'); // 默认白色
|
||
ctx.fillRect(0, 0, width, height);// fillRect(x,y,宽度,高度)
|
||
// 绘制背景图
|
||
ctx.drawImage(backgroundImage, 0, 0, width , height) // drawImage(图片路径,x,y,绘制图像的宽度,绘制图像的高度)
|
||
// 绘制头像
|
||
_this.drawAvatar(ctx,avatar,width);
|
||
// 绘制用户昵称
|
||
let nicknameLen = this.userInfo.nickname.length;
|
||
let nicknameX = (width / 2) - (nicknameLen * 20 / 2);
|
||
ctx.setFillStyle('#000000');
|
||
_this.drawText(ctx,"20px Microsoft YaHei",this.userInfo.nickname,nicknameX,230,width)
|
||
// 绘制文字
|
||
ctx.setFillStyle('#a67344');
|
||
_this.drawText(ctx,"20px Microsoft YaHei","欢迎关注",110,45,width)
|
||
_this.drawText(ctx,"20px Microsoft YaHei","全叶真爱",110,70,width)
|
||
// 邀请词
|
||
let invitation = "邀请您一起学养生,懂健康";
|
||
let len = invitation.length;
|
||
let invitationX = (width / 2) - (len * 15 / 2);
|
||
_this.drawText(ctx,"15px Microsoft YaHei",invitation,invitationX,270,width)
|
||
// 二维码
|
||
let qrcodeSize = 100;
|
||
ctx.drawImage(qrcode, (width / 2 - (qrcodeSize / 2)), 290, qrcodeSize , qrcodeSize) // drawImage(图片路径,x,y,绘制图像的宽度,绘制图像的高度)
|
||
// 将内容绘制到画布上面
|
||
ctx.draw(true,function () {
|
||
|
||
|
||
uni.canvasToTempFilePath({
|
||
canvasId: 'posterImage',
|
||
success: (res) => {
|
||
//console.log(res.tempFilePath);
|
||
_this.poster_image = res.tempFilePath
|
||
},
|
||
fail: function(err) {
|
||
console.log("失败")
|
||
console.log(err)
|
||
}
|
||
})
|
||
|
||
|
||
});
|
||
|
||
|
||
|
||
|
||
|
||
})
|
||
},
|
||
// 生成海报 —— 绘制头像
|
||
drawAvatar(ctx,avatar,width){
|
||
let arcX = width / 2;
|
||
let avatarSize = 40;
|
||
ctx.save();
|
||
// 绘制头像背景
|
||
ctx.beginPath();
|
||
ctx.fillStyle = "#d7c08a";
|
||
ctx.arc(arcX,160,45,0,2*Math.PI);
|
||
ctx.fill();
|
||
// 绘制头像
|
||
ctx.beginPath();
|
||
ctx.arc(arcX,160, avatarSize, 0, Math.PI * 2);
|
||
ctx.clip();
|
||
ctx.drawImage(avatar, arcX - avatarSize, 160 - avatarSize , avatarSize * 2 , avatarSize * 2) // drawImage(图片路径,x,y,绘制图像的宽度,绘制图像的高度)
|
||
ctx.closePath();
|
||
ctx.restore();
|
||
},
|
||
// 生成海报 —— 绘制文字
|
||
drawText(ctx,size,text,x,y,maxWidth){
|
||
ctx.save();
|
||
ctx.beginPath();
|
||
ctx.font = size;
|
||
ctx.fillText(text, x, y, maxWidth);
|
||
ctx.closePath();
|
||
ctx.restore();
|
||
},
|
||
// 点击下载海报
|
||
downloadPoster(){
|
||
uni.canvasToTempFilePath({
|
||
canvasId: 'posterImage',
|
||
success: (res) => {
|
||
uni.downloadFile({
|
||
url: res.tempFilePath,
|
||
success: (res) => {
|
||
var link = document.createElement('a') //创建一个a标签
|
||
link.href = res.tempFilePath//把a标签的href属性赋值到生成好了的url
|
||
link.download = '邀请好友.png'//通过a标签的download属性修改下载图片的名字
|
||
link.click()//让a标签的click函数,直接下载图片
|
||
},
|
||
})
|
||
},
|
||
fail: function(err) {
|
||
console.log("失败canvasToTempFilePath")
|
||
console.log(err)
|
||
}
|
||
})
|
||
},
|
||
// 记录分享信息
|
||
recordSharing(){
|
||
let _this = this;
|
||
_this.$api.sendRequest({
|
||
url: '/api/ShareRecord/recordShareInfo',
|
||
data: { share_path: _this.path }
|
||
});
|
||
},
|
||
// 设置公众号分享信息
|
||
setPublicShare(){
|
||
let shareUrl = this.path;
|
||
let _this = this;
|
||
this.$util.setPublicShare({
|
||
title: _this.share.title, // 分享标题
|
||
desc: _this.share.desc, // 分享描述
|
||
link: shareUrl,
|
||
imgUrl: _this.$util.img(_this.share.imgUrl), // 分享图标
|
||
},function (params) {
|
||
Http.sendRequest({
|
||
url: '/api/ShareRecord/recordShareInfo',
|
||
data: { share_path: params.link },
|
||
success: res => {},
|
||
fail:err=>{}
|
||
})
|
||
})
|
||
},
|
||
// 生成唯一的分享id
|
||
createShareId(){
|
||
let timeDate = new Date()
|
||
this.share_id = timeDate.getTime().toString();
|
||
},
|
||
// 生成分享链接
|
||
createSharePath(){
|
||
// 生成唯一id
|
||
this.createShareId();
|
||
let member_id = this.userInfo.member_id;
|
||
this.path = '';
|
||
// 生成分享链接
|
||
if(this.share.link){
|
||
// 如果传递了分享链接 使用分享链接
|
||
this.path = this.share.link + `?source_member=${member_id}&share_id=` + this.share_id.toString();
|
||
}else{
|
||
// 没有分享链接 生成分享链接
|
||
let pages = getCurrentPages();
|
||
let currentPage = pages[pages.length - 1].$page
|
||
let currentPath = currentPage.path + `?source_member=${member_id}&share_id=` + this.share_id.toString();
|
||
let options = currentPage.options;
|
||
// 获取分享的参数
|
||
if(Object.keys(this.shareParams).length > 0){
|
||
this.shareParams.forEach(function (item, index) {
|
||
if(options[item]) currentPath = currentPath + `&${item}=` + options[item];
|
||
});
|
||
}
|
||
|
||
let split = window.location.href.split(currentPage.path)
|
||
this.path = split[0] + currentPath;
|
||
}
|
||
}
|
||
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.qrcode-content{
|
||
width: 60vw;
|
||
height: 60vw;
|
||
.qrcode-canvas{
|
||
width: 60vw;
|
||
height: 60vw;
|
||
}
|
||
}
|
||
.poster-content{
|
||
--poster-size-: 300px; // 海报的大小
|
||
width: var(--poster-size-);
|
||
height: calc(var(--poster-size-) * 1.7);
|
||
|
||
.poster-image{
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.poster-show-image{
|
||
position: absolute;
|
||
z-index: 555555;
|
||
top: 0;
|
||
}
|
||
}
|
||
.poster-tip {
|
||
position: absolute;
|
||
font-size: 50rpx;
|
||
font-weight: bold;
|
||
z-index: 99999;
|
||
bottom: 160rpx;
|
||
width: 100%;
|
||
text-align: center;
|
||
color: #fff;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
.download-button{
|
||
color: #fff;
|
||
background: #ee0a24;
|
||
width: 100px;
|
||
border-radius: 30px;
|
||
font-size: 15px;
|
||
height: 30px;
|
||
line-height: 30px;
|
||
}
|
||
}
|
||
.cancel-btn{
|
||
position: absolute;
|
||
top: 40rpx;
|
||
right: 40rpx;
|
||
z-index: 999999;
|
||
width: 100rpx;
|
||
height: 50rpx;
|
||
font-size: 26rpx;
|
||
border-radius: 50rpx;
|
||
}
|
||
</style>
|
||
|