需求:小程序内点击分享按钮,将当前页面,已海报形式进行分享,用户可通过海报上的二维码,扫描进入到该界面,实现原理主要是通过lime-painter插件,生产canvas模板,复制即用,废话不多说,直接上代码。
插件地址+教程: ext.dcloud.net.cn/plugin?id=2…
效果图展示:
分享海报功能:
<view class="share-item" @click="shareCanvas" style="margin-top: -7rpx;">
<image src="/static/images/share2.png"></image>
<text style="margin-top: 8rpx;">分享海报</text>
</view>
// 生成分享海报
shareCanvas() {
// this.showCanvas = true;
uni.showLoading({
mask: true,
title: '正在生成海报'
});////
// #ifdef H5
let origin = "h5";
let url = this.$c.shareH5Url + "/subpages/content/buyUserTicket/index?routeId=" + this.postId
// #endif
// #ifdef MP-WEIXIN
let origin = "weixin";
let customerPushCode = uni.getStorageSync("userInfo").pushCode || ''
let url = `/subpages/content/buyUserTicket/index?routeId=${this.postId}&pushCode=${customerPushCode}`
// #endif
console.log(url, 'urlurlurlurl')
this.$H.get('/business/app/tripTourRoute/qrWxCode', {
url: url
}).then(res => {
if (res.code == 0) {
this.configData = {
posterQrcode: res.result,
routeName: this.detailContent.routeName,
posterImg: this.detailContent.miediaList[0].mediaPath
}
this.showCanvas = true;
}
uni.hideLoading();
});
},
海报组件:
<!-- 生成海报组件 -->
<poster v-if="showCanvas" ref="posterRef" :configData="configData" @close="closePopup"/>
import poster from "./poster.vue";
poster.vue页面:
<template>
<view class="main">
<!-- :mask-close-able="false" 点击遮罩关闭 -->
<u-popup class="poster-oppup" ref="popupRef" mode="center" width="90%" height="auto" :custom-style="customStyle"
:safe-area-inset-bottom="true" :closeable="!show" v-model="pop"
:close-icon-size="36" close-icon-color="#d53228">
<view class="content">
<image v-if="!show" class="poster-img" :src="path" mode="widthFix"></image>
<view v-else style="display: flex; align-items: center; justify-content: center; height: 1100rpx;">
<u-loading :show="show" class="loading" size="84" mode="flower"></u-loading>
</view>
<!-- width 越小,越放大 -->
<!-- background-color: #ffffff; 要设置背景位白色,不然保存的图标黑底 -->
<l-painter ref="painter" isCanvasToTempFilePath @success="path = $event;show = false;" custom-style="position: fixed; left: 200%" css="width: 670rpx; padding: 20rpx; background-color: #ffffff;">
<l-painter-view css="border-bottom: 2rpx dashed #817EF7; padding-bottom: 20rpx; display: flex; align-items: center;">
<l-painter-image :src="userInfo.avatar" css="margin-right: 20rpx; width: 100rpx; height: 100rpx; border-radius: 50%;"/>
<l-painter-view css="display: inline-block; ">
<l-painter-text :text="userInfo.username" css="display: block; padding-bottom: 10rpx; color: #000000; font-size: 30rpx;"/>
<l-painter-text text="就等你了,赶快来一起出游吧!" css="color: #817EF7; font-size: 28rpx"/>
</l-painter-view>
</l-painter-view>
<l-painter-view css="margin-top: 20rpx; box-sizing: border-box; border-radius: 10rpx;">
<l-painter-image :src="configData.posterImg" css="object-fit: cover; object-position: 50% 50%; width: 630rpx; height: 560rpx; border-radius: 20rpx;"/>
<l-painter-view css="display: flex; margin-top: 20rpx; border-top: 2rpx dashed #817EF7; padding-top: 30rpx;">
<l-painter-view >
<l-painter-text v-if="configData.routeName.length > 16" :text="configData.routeName" css="line-clamp: 2; display: block; font-size: 30rpx; color: #333333; width: 440rpx; font-weight: bold; margin-bottom: 44rpx" />
<l-painter-text v-else :text="configData.routeName" css="line-clamp: 2; display: block; font-size: 30rpx; color: #333333; width: 440rpx; font-weight: bold; margin-bottom: 90rpx" />
<l-painter-text text="微信扫码获得更多详情" css="font-size: 28rpx; color: #817EF7; display: block;"/>
</l-painter-view>
<l-painter-image :src="configData.posterQrcode" css="width: 168rpx; height: 168rpx; object-fit: cover;"/>
</l-painter-view>
</l-painter-view>
</l-painter>
</view>
<view v-if="!show" class="save-btn" @tap="saveImg">
<text>保存分享</text>
</view>
</u-popup>
</view>
</view>
</template>
<script>
export default {
name: "adv",
props: {
configData: Object,
},
data() {
return {
userInfo: uni.getStorageSync("userInfo"),
customStyle: {
backgroundColor: "transparent",
height: "90vh",
marginTop:"20rpx",
},
path: "",
pop: true,
show: true
};
},
watch: {
pop: {
handler(newval, oldVal) {
if (!newval) {
this.$emit("close");
}
}
},
},
methods: {
// 保存海报到相册
saveImg() {
let filePathData = ''
// #ifdef MP-WEIXIN
// 生成图片
this.$refs.painter.canvasToTempFilePathSync({
fileType: "jpg",
// 如果返回的是base64是无法使用 saveImageToPhotosAlbum,需要设置 pathType为url
pathType: 'url',
quality: 1,
success: (res) => {
console.log(res.tempFilePath);
filePathData = res.tempFilePath
// 非H5 保存到相册
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: function () {
uni.showToast({
title: '图片保存成功'
});
},
fail: function(error) {
uni.showModal({
title: '图片保存失败',
content: '请确认是否已开启授权',
confirmText: '开启授权',
success(res) {
if (res.confirm) {
uni.openSetting({
success(settingdata) {
if (settingdata.authSetting[
"scope.writePhotosAlbum"
])
{
uni.showToast({ title: '授权成功,请重试哦~',
icon: "none"
});
} else { uni.showToast({
title: '请确定已打开保存权限', icon: "none" });
}
}
})
}
}
})
},
});
},
});
// #endif
// #ifdef H5
var oA = document.createElement('a');
oA.download = ''; // 设置下载的文件名,默认是’下载’
oA.href = filePathData;
document.body.appendChild(oA);
oA.click();
oA.remove(); // 下载之后把创建的元素删除
// #endif
return
// #ifdef MP-WEIXIN
// errMsg: "saveImageToPhotosAlbum: fail api scope is not declared in the privacy agreement"
uni.getImageInfo({
src: this.posterUrl,
success: function(image) {
uni.saveImageToPhotosAlbum({
filePath: image.path,
success: function(sucess) {
uni.showToast({
title: '图片保存成功'
});
},
});
},
fail() {}
});
// #endif
// #ifdef H5
var oA = document.createElement('a');
oA.download = ''; // 设置下载的文件名,默认是’下载’
oA.href = this.posterUrl;
document.body.appendChild(oA);
oA.click();
oA.remove(); // 下载之后把创建的元素删除
// #endif
},
},
};
</script>
<style lang="scss" scoped>
.main {
.poster-oppup {
.u-mode-center-box {
border-radius: 20rpx;
}
.poster-img {
width: 900rpx;
border-radius: 20rpx;
}
}
.save-btn {
width: 100%;
display: flex;
justify-content: center;
text {
width: 408rpx;
height: 70rpx;
margin-bottom: 40rpx;
font-size: 30rpx; color: #FFFFFF;
background: linear-gradient( 180deg, #CECDFF 0%, #817EF7 100%);
border-radius: 35rpx 35rpx 35rpx 35rpx;
text-align: center; line-height: 70rpx;
}
}
}
</style>
完整代码:index.vue
<template>
<view class="full-container">
<u-navbar></u-navbar>
<view class="swiper-box hight-swiper-box">
<u-swiper @click="onSwiper" :list="detailContent.miediaList" name="mediaPath" border-radius="0" mode="rect" indicator-pos="bottomRight" img-mode="aspectFill"></u-swiper>
</view>
<view class="main-box">
<view class="scienc-info">
<view class="desc ellipsis">{{ detailContent.routeName }}</view>
<view class="tip two-ellipsis">{{ detailContent.description }}</view>
<view class="extension-vontainer" @click="getExtension">
<view class="flex">
<image class="notice-icon" :src="$IMG + '/images/notice-icon.png'"></image>
<view class="common-tip puoduct">推广计划产品</view>
<view class="common-tip plan">本产品已参与推广计划</view>
</view>
<image class="two-right-icon" :src="$IMG + '/images/two-right-icon.png'"></image>
</view>
<view class="price-box">
<view class="money">
<view class="hot-flex">
<view class="symbol">¥</view>
<view class="money">{{ detailContent.price }}</view>
<view class="text">起/人</view>
</view>
</view>
<view class="person" v-if="detailContent.joinNumber > 0">{{ detailContent.joinNumber }}人参加</view>
</view>
<view class="operate-box">
<view class="flex">
<view class="flex">
<image class="icon-img" src="/static/images/adress-icon.png"></image>
<view class="text">{{ detailContent.destination }}</view>
</view>
<view class="flex">
<image class="icon-img" src="/static/images/time-icon.png"></image>
<view class="text">{{ detailContent.days }}天</view>
</view>
<view class="flex">
<image class="icon-img" src="/static/images/person-icon.png"></image>
<view class="text">{{ detailContent.groupNumber }} 人</view>
</view>
</view>
<view class="flex" @click="getShowShare">
<image class="icon-img share-icon" src="/static/images/share.png"></image>
<view class="text">分享</view>
</view>
</view>
</view>
<!-- <view class="package-info common-box">
<view class="nav-tit">
<text class="tit">套餐信息</text>
<text class="desc">(进入拼团后再选择)</text>
</view>
<view class="flex-container">
<view class="package-list" v-for="(item, index) in detailContent.packageList" :key="index">
<text class="name" v-if="!item.tip">{{ item.name }}:¥{{ item.price }}</text>
<text class="name" v-else>{{ item.name }}({{ item.tip }}):¥{{ item.price }}</text>
</view>
</view>
</view> -->
<view class="set-out-time common-box">
<view class="nav-tit">出发日期</view>
<ticketInfo v-if="showStatus" :dateVoList="dateVoList" :classSyle="classSyle" :pageType="pageType" @getSelectPackage="getSelectPackage"></ticketInfo>
</view>
<view class="aggregate-info common-box">
<view class="nav-tit">集合信息</view>
<view class="list-item" v-for="(item, index) in detailContent.rendezvousList" :key="index">
</block>
<view class="default-icon">
<image class="icon-img" src="/static/images/default-icon.png"></image>
<text class="icon-index">{{ index + 1}}</text>
</view>
<text class="text-desc">{{ item }}</text>
</view>
</view>
<view v-if="detailContent.joinNumber > 0" class="person-info common-box">
<view class="nav-tit flex" @click="getMorePerson">
<view class="left">已参加的人</view>
<view class="flex">
<view class="number">{{ detailContent.joinNumber }}</view>
<view class="person">人</view>
<image class="more-arr-img" src="/static/images/more-right.png"></image>
</view>
</view>
<view class="recommend-scroll">
<scroll-view class="wrap-scroller" scroll-x="true">
<view class="list-item" v-for="(item, index) in detailContent.personVos" :key="index">
<image class="avatar-z" :src="item.avatar" mode="aspectFill"></image>
<view class="name"> {{ item.customerName }} </view>
</view>
</scroll-view>
</view>
</view>
<view class="bottom-operate">
<view class="flex">
<view class="ico-box home-icon" @click.stop="getHome">
<image class="icon-img" src="/static/images/detail-home.png"></image>
<view class="text">首页</view>
</view>
<view class="ico-box">
<button open-type="contact" hover-class='none' class='item tui-skeleton-rect' >
<image class="icon-img" src="/static/images/customer-service.png"></image>
</button>
<view class="text">客服</view>
</view>
</view>
<view class="btn-customer-bg" @click="getJoinGroup">加入该团</view>
</view>
<lf-popup v-model="showPersonPopup" class="customer-popup">
<div class="titile-box" @click="onClose">
<view></view>
<view class="popup-tit">人员名单</view>
<image src="/static/images/login-close.png"></image>
</div>
<view class="sign-up">已报名</view>
<view class="list-box">
<view class="list-item" v-for="(item, index) in detailContent.personVos" :key="index">
<image class="avatar-z" :src="item.avatar" mode="aspectFill"></image>
<view class="name"> {{ item.customerName }} </view>
</view>
</view>
<view class="bottom">只显示部分报名用户信息</view>
</lf-popup>
<!-- 分享选择弹窗 -->
<lf-popup v-model="showShare" height="240rpx">
<view class="share-wrap" @click="closeShare">
<!-- #ifdef MP-WEIXIN -->
<button open-type="share" class="share-item u-reset-button">
<image style="width: 86rpx; height: 86rpx; margin-top: 1rpx;" src="/static/wechat.png"></image>
<text>微信好友</text>
</button>
<!-- #endif -->
<!-- #ifdef H5 -->
<view class="share-item2" @click="copyPageUrl">
<image src="/static/images/share.png"></image>
<text>分享链接</text>
</view>
<!-- #endif -->
<!-- #ifdef H5 || MP-WEIXIN -->
<view class="share-item" @click="shareCanvas" style="margin-top: -7rpx;">
<image src="/static/images/share2.png"></image>
<text style="margin-top: 8rpx;">分享海报</text>
</view>
<!-- #endif -->
</view>
</lf-popup>
<toast v-if="loadingFlag" color="#fff" type="rotate3"></toast>
</view>
<view class="tab-content">
<Anchor
:tabList="tabs"
:barFixed="true"
:transitionShow="true"
barHeight="50"
:barTop="barTop"
barId="0"
@clickTabs="clickTabs"
ref="barTabNav"
>
<!-- id与数据tabs->navTarget对应 -->
<view id="item1">
<view class="box">
<mp-html :content="detailContent.routeExtendList[0].details" selectable="true" />
</view>
</view>
<view id="item2">
<view class="box">
<mp-html :content="detailContent.routeExtendList[1].details" selectable="true" />
</view>
</view>
<view id="item3">
<view class="box">
<mp-html :content="detailContent.routeExtendList[2].details" selectable="true" />
</view>
</view>
<view id="item4">
<view class="box">
<mp-html :content="detailContent.routeExtendList[3].details" selectable="true" />
</view>
<!-- 热门推荐-->
<group-buying ref="groupBuying" :pageType="pageType" :tittle="groupTittle" :classStyle="classStyle"></group-buying>
</view>
</Anchor>
</view>
<lf-back-top :show-tag="showTag"></lf-back-top>
<!-- 生成海报组件 -->
<poster v-if="showCanvas" ref="posterRef" :configData="configData" @close="closePopup"/>
<phone-login ref="phoneLogin"></phone-login>
<extension-popup ref="extensionPopup" @getShare="getShare"></extension-popup>
</view>
</template>
<script>
import poster from "./poster.vue";
import Anchor from './anchor.vue'
import extensionPopup from './components/extension-popup.vue'
import ticketInfo from '@/subpages/content/components/ticketInfo/index.vue'
export default {
components:{
poster,
Anchor,
ticketInfo,
extensionPopup
},
data() {
return {
tabs: [
{
text: "详情亮点",//名称
navTarget: "#item1",//锚点
value: 'one'
},
{
text: "行程准备",
navTarget: "#item2",
value: 'two'
},
{
text: "费用须知",
navTarget: "#item3",
value: 'three'
},
{
text: "注意事项",
navTarget: "#item4",
value: 'four'
}
],
$IMG: this.$IMG,
configData: {},
posterUrl: '',
showTag: false,
current: 'one',
show: false,
show: true,
tabCount: '',
dateVoList: [],
goTimeOpenId: '',
showShare: false,
barTop: 0,
postId: 0,
page: 1,
form: {
pid: 0,
type: 1,
toUid: '',
toCid: 0,
postId: '',
content: ''
},
showCanvas: false,
showStatus: false,
classSyle: 'buy-ticket',
postDetail: {},
commentList: [],
groupTittle: '热门推荐',
postingUser: {},
pageType: 'buyTicket',
loadingFlag: true,
detailContent: {
days: 0,
price: 0,
groupNumber: 0,
routeName: '',
joinNumber: 0,
description: '',
destination: ''
},
classStyle: 'buy-ticket',
tabList: [
{ name: '详情亮点' , id: '0' },
{ name: '行程准备' , id: '1' },
{ name: '费用须知' , id: '2' },
{ name: '注意事项' , id: '3' }
],
clickFlag: false,
myScroll: 0,
currentItem: 0,
currentTabs: 0,
showPersonPopup: false,
shareCover: '',
}
},
onShareAppMessage(res) {
let imgURL = this.shareCover;
if (this.detailContent.miediaList.length > 0) {
imgURL = this.detailContent.miediaList[0].mediaPath
}
let customerPushCode = uni.getStorageSync("userInfo").pushCode || ''
return {
title: this.detailContent.routeName ? this.detailContent.routeName : this.$c.miniappName,
path: `/subpages/content/buyUserTicket/index?routeId=${this.postId}&pushCode=${customerPushCode}`,
imageUrl: imgURL
};
},
onShareTimeline(res) {
let imgURL = this.shareCover;
if (this.detailContent.miediaList.length > 0) {
imgURL = this.detailContent.miediaList[0].mediaPath
}
let customerPushCode = uni.getStorageSync("userInfo").pushCode || ''
return {
title: this.detailContent.routeName ? this.detailContent.routeName : this.$c.miniappName,
query: `routeId=${this.postId}&pushCode=${customerPushCode}`,
imageUrl: imgURL
};
},
onShow() {
uni.removeStorageSync('getDetailFlag')
},
onLoad(options) {
if ('q' in options) {
const q = decodeURIComponent(options.q);
const querys = q
.split('?')[1]
.split('&')
.reduce((acc, it) => {
let r = it.split(/=/);
return Object.assign(acc, {
[r[0]]: r[1]
})
}, {});
if ('routeId' in querys) {
this.postId = querys.routeId.trim();
}
}else{
this.postId = options.routeId.trim();
}
this.form.postId = this.postId;
this.loadingFlag = true
this.$loading(true)
this.getInit()
this.getSysInfo();
// this.getCommentList()
uni.setStorageSync('clickTabFlag', false)
uni.setStorageSync('scrollBtttom', false)
uni.setStorageSync('clickTabIndex', '0')
uni.getSystemInfo({
success: (res) => {
this.barTop = (res.statusBarHeight) + (res.system.indexOf('iOS') > -1 ? 44 : 48)
}
})
this.postingUser = uni.getStorageSync('userInfo')
//#ifdef MP-WEIXIN
wx.showShareMenu({
withShareTicket: true,
menus: ['shareAppMessage', 'shareTimeline']
});
//#endif
},
// 1. 点击并且滚动页面,采用点击切换Tab
onPageScroll(e) {
this.showTag = e.scrollTop > 750
uni.setStorageSync('scrollPageFlag', true)
this.$refs.barTabNav.getSelectedTab(e.scrollTop, 'scrollPage');
},
onReachBottom() {
uni.setStorageSync('scrollBtttom', true)
this.$refs.groupBuying.getReachBottom()
this.$refs.barTabNav.getSelectedTab();
},
onPullDownRefresh() {
setTimeout(() => {
uni.stopPullDownRefresh();
}, 500)
},
methods: {
getSysInfo() {
this.$H.get('system/basic').then(res => {
this.shareCover = res.shareImg;
});
},
// 获取二维码路径参数
GetWxMiniProgramUrlParam(url) {
let theRequest = {};
if (url.indexOf("#") != -1) {
const str = url.split("#")[1];
const strs = str.split("&");
for (let i = 0; i < strs.length; i++) {
theRequest[strs[i].split("=")[0]] = decodeURI(strs[i].split("=")[1]);
}
} else if (url.indexOf("?") != -1) {
const str = url.split("?")[1];
const strs = str.split("&");
for (let i = 0; i < strs.length; i++) {
theRequest[strs[i].split("=")[0]] = decodeURI(strs[i].split("=")[1]);
}
}
return theRequest;
},
onSwiper(index) {
let arr = []
this.detailContent.miediaList.forEach((item) => {
arr.push(item.mediaPath)
})
let currnetImg = this.detailContent.miediaList[index].mediaPath
uni.previewImage({
urls: arr, //预览图片列表
current: currnetImg //图片路径
})
},
clickTabs(row, status) {
// 点击Tab标识
this.clickFlag = status
// 避免重复点击
if(this.current == row.value) return false;
// 操作处理
this.current = row.value
},
itemChange(id) {
this.currentItem = id;
},
getInit() {
this.$H.get('/business/app/tripTourRoute/info/' + this.postId).then(res => {
if (res.code == 0) {
this.detailContent = res.result
if(res.result.personVos !== null) {
if (res.result.personVos.length > 0) {
res.result.personVos.forEach((item) => {
item.customerName = item.nickname.slice(0, 1) + '**'
})
}
}
this.dateVoList = res.result.goDateVoList
this.tabCount = this.detailContent.routeExtendList[0].details
this.showStatus = true
this.loadingFlag = false
}
})
},
tabChange(index) {
this.currentTabs = index;
this.tabCount = this.detailContent.routeExtendList[index].details
},
getMorePerson() {
this.showPersonPopup = true
},
onClose() {
this.showPersonPopup = false
},
getHome() {
uni.reLaunch({
url: '/pages/index/index'
})
},
getSelectPackage(data) {
this.goTimeOpenId = data.openId
// 清除出行人信息
uni.setStorageSync('travelersAddFlag', false)
uni.setStorageSync('finallTravelersUserIds', [])
uni.setStorageSync('defaultArrData', [])
uni.setStorageSync('OriginExistenceIds', [])
},
getJoinGroup() {
if (!uni.getStorageSync('hasLogin')) {
setTimeout(() => {
uni.showModal({
title: '提示',
content: '您还未登录,登录体验更多精彩',
confirmText: '去登录',
cancelText: '随便逛逛',
success: (res) => {
if (res.confirm) {
this.$refs.phoneLogin.getShow()
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
}, 500)
} else {
if (this.goTimeOpenId) {
uni.setStorageSync('currentOpenId', this.goTimeOpenId)
uni.setStorageSync('resortArr', this.detailContent.rendezvousList)
uni.navigateTo({
url: `/subpages/content/joinGroup/index?openId=${this.goTimeOpenId}`
})
} else {
this.$u.toast('请选择出发日期');
}
}
},
getShare() {
this.showShare = true
},
getShowShare() {
if (!uni.getStorageSync('hasLogin')) {
setTimeout(() => {
uni.showModal({
title: '提示',
content: '您还未登录,登录体验更多精彩',
confirmText: '去登录',
cancelText: '随便逛逛',
success: (res) => {
if (res.confirm) {
this.$refs.phoneLogin.getShow()
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
}, 500)
} else {
this.showShare = true
}
},
closeShare() {
this.showShare = false
},
getReplyMore(index) {
this.commentList[index].copyChildren = this.commentList[index].children
this.commentList[index].openReplyStatus = false
},
// 回复评论
onReply(e) {
this.placeholder = '回复:' + e.userInfo.username;
this.focus = true;
// toCid: 如果是一级评论传0,如果是针对某一条评论进行回复,传当前评论的id
this.form.toCid = e.id ? e.id : 0
// pid: 如果是针对帖子评论传0,如果是针对某一条评论进行回复,传当前评论的id
this.form.pid = e.pid ? e.pid : e.id
this.form.toUid = e.userInfo.uid;
this.form.postId = this.postId;
this.focusFlag = true
},
jumpUser(uid) {
uni.navigateTo({
url: '/subpages/childrenPackge/user/home?uid=' + uid
});
},
getCommentList() {
this.$H.get('comment/list', {
postId: '1814259461133684738',
page: this.page
}).then(res => {
if (res.code ==0) {
res.result.data.forEach((item) => {
if (item.children.length > 1) {
// item.openReplyStatus = true
// item.copyChildren = item.children.slice(0, 1)
} else {
// item.openReplyStatus = false
// item.copyChildren = item.children
}
})
this.commentList = this.commentList.concat(res.result.data);
}
})
},
getExtension() {
if (!uni.getStorageSync('hasLogin')) {
setTimeout(() => {
uni.showModal({
title: '提示',
content: '您还未登录,登录体验更多精彩',
confirmText: '去登录',
cancelText: '随便逛逛',
success: (res) => {
if (res.confirm) {
this.$refs.phoneLogin.getShow()
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
}, 500)
} else {
// 1是推广人
const userInfo = uni.getStorageSync('userInfo');
if (userInfo.isPromoter) {
if (userInfo.isPromoter === 0) {
uni.navigateTo({
url: '/subpages/content/promotion/illustrate'
})
} else {
this.$refs.extensionPopup.getShow(this.postId);
}
} else {
uni.navigateTo({
url: '/subpages/content/promotion/illustrate'
})
}
}
},
handleInput() {
if (this.form.content == '') {
this.$u.toast('评论不能为空');
return;
}
if (val.detail.cursor == 50) {
this.$u.toast('内容字数最多为50个字符');
return;
}
uni.showLoading({
mask: true,
title: '发布中'
});
this.$H.post('post/addComment', this.form).then(res => {
uni.hideLoading();
if (res.code == 0) {
if(res.check){
uni.showModal({
title: '提示',
content: '评论审核通过后发布哦,请耐心等待',
showCancel: false,
success: function (res) {
if (res.confirm) {
}
}
});
}else{
this.$u.toast('评论成功');
this.postDetail.commentCount+=1
}
this.form.content = '';
this.page = 1;
this.commentList = [];
this.form.pid = 0;
// this.getCommentList();
}else if(res.code==500){
this.$u.toast(res.msg);
}
});
},
// 长按 删除评论
delComment(e, index, index2) {
let that = this;
let user = uni.getStorageSync('userInfo');
//如果是子评论需要遍历子评论查询是否存在自己回复的评论消息
var flag = false; //这个用来确定父评论下是否存在用户自己的子评论
var i = 0; //这个用来锁定子评论楼层位置
e.children.map((item) => {
if (item.uid == user.uid) {
flag = true;
e.id = item.id;
if (index2) {
index2 = i;
}
}
i++;
});
if (e.uid != user.uid) {
if (!flag) {
return;
}
}
uni.showModal({
title: '提示',
content: '确定删除自己的评论嘛?',
success: function(res) {
if (res.confirm) {
that.$H
.post('comment/del', {
id: e.id
})
.then(res2 => {
if (res2.code == 0) {
// if (index2 || index2 === 0) {
// that.commentList[index].children.splice(index2, 1);
// } else {
// that.commentList.splice(index, 1);
// }
that.postDetail.commentCount --
// that.getCommentList('delete');
}
});
}
}
});
},
// 生成分享海报
shareCanvas() {
// this.showCanvas = true;
uni.showLoading({
mask: true,
title: '正在生成海报'
});////
// #ifdef H5
let origin = "h5";
let url = this.$c.shareH5Url + "/subpages/content/buyUserTicket/index?routeId=" + this.postId
// #endif
// #ifdef MP-WEIXIN
let origin = "weixin";
let customerPushCode = uni.getStorageSync("userInfo").pushCode || ''
let url = `/subpages/content/buyUserTicket/index?routeId=${this.postId}&pushCode=${customerPushCode}`
// #endif
console.log(url, 'urlurlurlurl')
this.$H.get('/business/app/tripTourRoute/qrWxCode', {
// routeId: this.postId,
// pushCode: customerPushCode,
url: url
})
.then(res => {
if (res.code == 0) {
this.configData = {
posterQrcode: res.result,
routeName: this.detailContent.routeName,
posterImg: this.detailContent.miediaList[0].mediaPath
}
this.showCanvas = true;
}
uni.hideLoading();
});
},
// 保存海报到相册
saveImg() {
// #ifdef MP-WEIXIN
// errMsg: "saveImageToPhotosAlbum: fail api scope is not declared in the privacy agreement"
uni.getImageInfo({
src: this.posterUrl,
success: function(image) {
uni.saveImageToPhotosAlbum({
filePath: image.path,
success: function(sucess) {
uni.showToast({
title: '图片保存成功'
});
},
fail: function(error) {
uni.showModal({
title: '图片保存失败',
content: '请确认是否已开启授权',
confirmText: '开启授权',
success(res) {
if (res.confirm) {
uni.openSetting({
success(settingdata) {
if (settingdata.authSetting[
"scope.writePhotosAlbum"
]) {
uni.showToast({
title: '授权成功,请重试哦~',
icon: "none"
});
} else {
uni.showToast({
title: '请确定已打开保存权限',
icon: "none"
});
}
}
})
}
}
})
},
});
},
fail() {}
});
// #endif
// #ifdef H5
var oA = document.createElement('a');
oA.download = ''; // 设置下载的文件名,默认是’下载’
oA.href = this.posterUrl;
document.body.appendChild(oA);
oA.click();
oA.remove(); // 下载之后把创建的元素删除
// #endif
},
// 销毁组件
closePopup() {
this.showCanvas = false;
},
}
}
</script>
<style scoped lang="scss">
.tab-content {
padding-bottom: 125rpx;
}
/* 占位内容 */
.seize {
padding: 40px;
text-align: center;
}
/* END */
/* 选项卡样式 */
.tabs {
background: #fff;
width: 100%;
}
/* END */
.box {
padding: 20px;
background-color: #fff;
border-bottom: 20rpx solid #F6F7F9;
}
.btn-customer-bg {
width: 408rpx;
}
.full-container {
background-color: #F6F7F9;
.common-box {
background: #fff;
margin: 10rpx 0;
padding: 0 40rpx 20rpx 40rpx;
}
.flex {
display: flex;
align-items: center;
}
.list-item {
text-align: center;
display: inline-block;
margin-right: 80rpx;
.avatar-z {
width: 70rpx;
height: 70rpx;
border-radius: 50%;
}
.name {
color: #000000;
margin-top: -6rpx;
font-size: 24rpx;
}
}
.list-item:nth-child(5n) {
margin-right: 0;
}
.banner-img {
width: 750rpx;
height: 560rpx;
display: block;
}
.main-box {
// padding-bottom: 149rpx;
.scienc-info {
padding: 0 40rpx;
background: #fff;
.desc {
font-weight: 600;
color: #333333;
font-size: 30rpx;
padding: 20rpx 0 10rpx 0;
}
.tip {
color: #333333;
font-size: 28rpx;
margin-bottom: 20rpx;
}
.price-box {
display: flex;
align-items: center;
justify-content: space-between;
.person {
color: #666666;
font-size: 24rpx;
}
}
.extension-vontainer {
display: flex;
width: 670rpx;
height: 46rpx;
background: #E4E3FF;
align-items: center;
margin-bottom: 20rpx;
border-radius: 23rpx;
padding: 0 20rpx 0 10rpx;
justify-content: space-between;
.notice-icon {
width: 34rpx;
height: 34rpx;
margin-right: 10rpx;
}
.common-tip {
color: #817EF7;
font-size: 24rpx;
}
.puoduct {
padding-top: 9rpx;
}
.plan {
padding-top: 8rpx;
}
.puoduct::after {
content: '';
height: 38rpx;
width: 2rpx;
display: inline-block;
background-color: #817EF7;
vertical-align: middle;
margin: 0 10rpx 8rpx 10rpx;
}
.two-right-icon {
width: 20rpx;
height: 20rpx;
}
}
.operate-box {
padding: 30rpx 0 20rpx 0;
.flex {
display: flex;
align-items: center;
margin-right: 20rpx;
}
display: flex;
justify-content: space-between;
.icon-img {
width: 40rpx;
height: 40rpx;
}
.text {
color: #666666;
font-size: 24rpx;
margin-left: 8rpx;
}
}
}
.package-info {
.nav-tit {
display: flex;
align-items: center;
padding: 20rpx 0 0 0;
.tit {
font-size: 30rpx;
font-weight: 600;
}
.desc {
font-size: 24rpx;
margin-top: 5rpx;
}
}
.flex-container {
display: flex;
flex-wrap: wrap;
.package-list {
margin-bottom: 10rpx;
.name {
font-size: 26rpx;
color: #000000;
padding: 10rpx 16rpx;
background: #F6F7F9;
margin: 0 20rpx 10rpx 0;
border-radius: 4rpx 4rpx 4rpx 4rpx;
}
.name:last-child {
margin: 0 20rpx 0 0;
}
.desc {
color: #333333;
font-size: 24rpx;
margin: 5prx 0 0 10rpx;
}
}
}
}
// .share-icon{
// animation: name 0.75s ease infinite;
// }
// @keyframes name{
// 0% {transform: scale(1);}
// 50% {transform: scale(1.35);}
// 100% {transform: scale(1)}
// }
.set-out-time {
padding: 0 40rpx 20rpx 40rpx;
.nav-tit {
// padding: 20rpx 0 20rpx 40rpx;
}
}
.aggregate-info {
.list-item {
display: flex;
align-items: center;
margin-bottom: 26rpx;
.text-desc {
font-size: 28rpx;
}
.icon-img {
width: 42rpx;
height: 42rpx;
margin-right: 12rpx;
}
.name {
color: #333333;
font-size: 24rpx;
}
.default-icon {
display: flex;
position: relative;
.icon-index {
top: 50%;
left: 40%;
color: #FFFFFF;
font-size: 20rpx;
transform: translate(-50%, -50%);
position: absolute;
}
}
}
.list-item:last-child {
margin-bottom: 0;
}
}
.person-info {
.nav-tit {
justify-content: space-between;
.number {
color: #817EF7;
font-size: 24rpx;
}
.person {
font-size: 24rpx;
color: #333333;
margin-right: 8rpx;
}
}
}
.tab-info {
.tab-content {
padding-top: 15rpx;
padding-left: 40rpx;
background-color: #fff;
.tabs-item {
margin-right: 60rpx;
.flex {
margin-left: 28rpx;
.line-bottom {
width: 50rpx;
}
}
}
}
.conent {
color: #666666;
font-size: 28rpx;
padding: 40rpx;
background: #fff;
}
}
.comment-box {
padding-bottom: 180rpx;
.avatar {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
margin-right: 10rpx;
}
.comment-tool {
display: flex;
align-items: center;
margin-bottom: 40rpx;
.send-input {
height: 36rpx;
color: #666666;
font-size: 26rpx;
background-color: #F6F6F6;
padding: 27rpx 30rpx 16rpx 30rpx;
border-radius: 34rpx 34rpx 34rpx 34rpx;
}
}
.comment-item {
.flex {
.user {
.user-name {
color: #333333;
font-size: 28rpx;
font-weight: 600;
margin-right: 10rpx;
}
.user-time {
color: #666666;
font-size: 26rpx;
}
}
}
.reply-desc {
color: #666666;
font-size: 26rpx;
margin-left: 90rpx;
}
}
.reply-comment-list {
background: #F6F7F9;
margin: 20rpx 0 0 90rpx;
padding: 20rpx 30rpx;
border-radius: 10rpx 10rpx 10rpx 10rpx;
.sub-comment-item {
margin-bottom: 10rpx;
.flex {
color: #333333;
font-size: 24rpx;
.name {
color: #817EF7;
}
.content {
word-break: break-all;
}
}
.open-more {
color: #6F97CB;
font-size: 24rpx;
margin: 10rpx 0 0 52rpx;
}
}
.sub-comment-item:last-child {
margin-bottom: 0;
}
}
}
}
.bottom-operate {
.flex {
display: flex;
.home-icon {
margin: 0 35rpx 0 20rpx;
}
.ico-box {
text-align: center;
.tui-skeleton-rect {
line-height: 34rpx;
background-color: #fff;
}
.icon-img {
width: 52rpx;
height: 52rpx;
display: block;
}
.text {
color: #666666;
font-size: 18rpx;
}
}
}
.play-group {
width: 408rpx;
}
}
}
</style>
anchor.vue
同上anchor.vue
END...