| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773 | <template name="share">	<view class="poster_page">		<canvas canvas-id="poster" class="poster_canvas"></canvas>		<swiper class="poster_swiper" previous-margin="110rpx" circular :current="swiperIndex" next-margin="110rpx" @change="onSwiperChange">			<swiper-item v-for="(v, k) of fetch.pic" :key="k">				<view class="goods_info_box" :class="{ active: swiperIndex == k }">					<image class="goods_image" :src="v" mode="aspectFit"></image>					<view class="goods_info">						<view class="goods_name">{{fetch.info.name}}</view>						<view class="price_box">							<view class="price">{{fetch.info.price}}</view>							<view class="store_price">{{fetch.info.s_price}}</view>						</view>						<view class="poster_info">							<view class="info">								<view>长按识别二维码访问</view>								<text>{{fetch.info.platform_name}}</text>							</view>							<image class="poster_code_image" :src="fetch.info.qrcode" mode="aspectFit"></image>						</view>					</view>				</view>			</swiper-item>		</swiper>		<view style="text-align: center;" v-if="fetch.info.reward > 0">			<text class="grace-capsule-icon">佣金</text>			<text class="grace-capsule-text">分享给你的好友,好友购买后你至少获得{{fetch.info.reward}}元</text>		</view>		<view class="share_save_box">			<!-- #ifdef MP -->			<button open-type="share">				<image src="@/static/demo/ic_pic.png" mode="aspectFit"></image>				<text>好友</text>			</button>			<!-- #endif -->			<!-- #ifdef APP-PLUS -->			<button @click="onAppShare">				<image src="@/static/demo/ic_pic.png" mode="aspectFit"></image>				<text>好友</text>			</button>			<!-- #endif -->						<button class="onSave" @click="showText">				<view class="lg text-gray cuIcon-formfill" style="width:70rpx;height:70rpx"></view>				<text>文案</text>			</button>						<button class="onSave" @click="showRes">				<view class="lg text-gray cuIcon-picfill" style="width:70rpx;height:70rpx"></view>				<text>素材</text>			</button>						<button class="onSave" @click="showPoster">				<view class="lg text-gray cuIcon-btn" style="width:70rpx;height:70rpx"></view>				<text>海报</text>			</button>		</view>				<graceDialog :isTitle="false" :title="`长按保存海报`" :isCloseBtn="false" :show="image" closeBtnColor="#FFFFFF" v-on:closeDialog="closeImage">			<view class="grace-img-in" slot="content">				<image class="demo-img" :src="poster" mode="widthFix"></image>			</view>			<view slot="btns" class="grace-space-between">				<text class="grace-dialog-buttons" @tap="closeImage">关闭</text>				<text class="grace-dialog-buttons grace-blue" @tap="closeImage">长按复制</text>			</view>		</graceDialog>				<graceDialog :isTitle="true" :title="`复制文案`" :isCloseBtn="false" :show="text" v-on:closeDialog="closeText">			<scroll-view :scroll-y="true" class="content2" slot="content">				<view v-for="(v, k) in fetch.text" :key="k" @click="textClick(k)">					<graceBorderRadius :background="v.background" :radius="['33rpx','33rpx','33rpx','33rpx']">						<text>{{v.content}}</text>					</graceBorderRadius>				</view>			</scroll-view>			<view slot="btns" class="grace-space-between">				<text class="grace-dialog-buttons" @tap="closeText">关闭</text>				<text class="grace-dialog-buttons grace-blue" @tap="textLinkCopy">复制+链接</text>				<text class="grace-dialog-buttons grace-blue" @tap="textCopy(false)">复制</text>			</view>		</graceDialog>				<graceDialog :isTitle="true" :title="`图片素材`" :isCloseBtn="false" :show="res" v-on:closeDialog="closeRes">			<scroll-view :scroll-y="true" class="content3" slot="content">				<view class="grid flex-sub padding-lr col-3 grid-square">					<view @tap.stop @tap="Dever.viewPic(fetch.pic, child)" class="bg-img" :style="{backgroundImage: 'url('+child+')'}"					 v-for="(child, idx) in fetch.pic" :key="idx">					</view>									</view>			</scroll-view>			<view slot="btns" class="grace-space-between">				<text class="grace-dialog-buttons" @tap="closeRes">关闭</text>				<text class="grace-dialog-buttons grace-blue" @tap="closeRes">长按复制</text>			</view>		</graceDialog>	</view></template><script>import { mapState, mapMutations } from 'vuex';let settingWritePhotosAlbum = false;import copyText from "@/lib/clipboard.thorui.js"; import { pathToBase64, base64ToPath } from "@/lib/dever/components/base64.js"; export default {	props: {		content_id : {			type : String,			value : null		},		width : {			type : String,			default : '100%'		},		param : {},		index : 0,		type : 0,	},	data() {		return {			swiperIndex: 0,			posterImgs: [],			poster: "",			image : false,			text : false,			res : false,			text_index : 0,			text_top : 0,			fetch : {				info : {},				pic : [],				text : [],				share: {},			}		};	},	//第一次加载	mounted() {		this.getData();	},	computed: {			},	//方法	methods: {		getData : function() {			var url = this.Dever.host + '/pages/dream/view';			this.Dever.get(this, 'app/collection/?l=api.getShare', {code:this.Dever.config.code,content_id:this.content_id,type:this.type, url:url, index:this.index});		},		getInfo : function() {					},		showImage : function () {			this.image = true;		},		closeImage : function () {			this.image = false;		},		showRes : function () {			this.res = true;		},		closeRes : function () {			this.res = false;		},		showText : function () {			this.text = true;		},		closeText : function () {			this.text = false;		},		textClick : function(index) {			if (index == this.text_index) {				this.fetch.text[this.text_index].background = '#bababa';				this.text_index = -1;				return;			}			this.fetch.text[index].background = '#ffaa00';			if (this.fetch.text[this.text_index]) {				this.fetch.text[this.text_index].background = '#bababa';			}						this.text_index = index;		},		textCopy : function(link) {			var self = this;			var value = this.fetch.text[this.text_index].content;			if (link) {				value += "\r\n" + link;			}			copyText.getClipboardData(value, function(res) {				if (res) {					self.Dever.alert('复制成功');				} else {					self.Dever.alert('复制失败');				}			});		},		textLinkCopy : function() {			this.textCopy(this.fetch.info.url);		},		// 轮播图变化		onSwiperChange(e) {			this.swiperIndex = e.detail.current;		},		// 创建海报		createPoster() {			return new Promise((resolve, reject) => {				if (!this.fetch.info.qrcode) {					this.Dever.alert('没有二维码');					return;				}				uni.showLoading({					title: '海报生成中'				});				const ctx = uni.createCanvasContext('poster');				ctx.imageSmoothingEnabled = false;				ctx.fillRect(0, 0, 375, 673);				ctx.setFillStyle("#FFF");				ctx.fillRect(0, 0, 375, 673);								this.downPic(ctx, resolve, reject);			});		},				//下载图片		downPic : function(ctx, resolve, reject) {			var self = this;			uni.downloadFile({				url: self.fetch.pic[self.swiperIndex],				success: (res) => {					if (res.statusCode === 200) {						uni.getImageInfo({							src: res.tempFilePath,							success: function (image) {								var img = self.Dever.getImage(image.width, image.height, 375, 375);								var x = (375 - img[0])/2;								var y = 0;								ctx.drawImage(res.tempFilePath, x, y, img[0], img[1]);								self.downQrcode(ctx, resolve, reject);							}						});					} else {						uni.hideLoading();						self.Dever.alert('海报制作失败,图片下载失败');					}				},				fail: (err) => {					uni.hideLoading();					self.Dever.alert('海报制作失败,图片下载失败');				}			});		},				//下载二维码		downQrcode : function(ctx, resolve, reject) {			uni.downloadFile({				url: this.fetch.info.qrcode,				success: (res) => {					if (res.statusCode === 200) {						this.addPosterName(ctx);						this.addPosterPrice(ctx);						this.addPosterQrcode(ctx);						// 二维码						ctx.drawImage(res.tempFilePath, 238, this.text_top + 88, 120, 120);												this.drawPoster(ctx, resolve, reject);					} else {						uni.hideLoading();						this.Dever.alert('海报制作失败,图片下载失败');					}				},				fail: (err) => {					uni.hideLoading();					this.Dever.alert('海报制作失败,图片下载失败');				}			});		},				// 商品标题		addPosterName : function(ctx) {			ctx.setFontSize(21);			ctx.setFillStyle('#333');			let drawtextList = drawtext(this.fetch.info.name, 341);			this.text_top = 0;			drawtextList.forEach((item,index) => {				if(index < 2){					this.text_top = 380 + (index + 1) * 28;					ctx.fillText(item.content, 17, this.text_top);				}			});		},				// 商品价格		addPosterPrice : function(ctx) {			if (this.fetch.info.price) {				ctx.setFontSize(26);				ctx.setFillStyle('#f00');				ctx.fillText(this.fetch.info.price, 17, this.text_top + 47);				// 商品门市价				ctx.setFontSize(18);				ctx.setFillStyle('#999');				let textLeft = 38 + (this.fetch.info.price.length * 13)				ctx.fillText(this.fetch.info.s_price, textLeft, this.text_top + 45);				// 商品门市价横线				ctx.beginPath();				ctx.setLineWidth(1);				ctx.moveTo(textLeft - 1, this.text_top + 38);				ctx.lineTo((textLeft + 5 + this.fetch.info.s_price.length * 9), this.text_top + 38);				ctx.setStrokeStyle('#999');				ctx.stroke();			}						// 商品分割线			ctx.beginPath();			ctx.setLineWidth(1);			ctx.moveTo(17, this.text_top + 70);			ctx.lineTo(358, this.text_top + 70);			ctx.setStrokeStyle('#eee');			ctx.stroke();		},				//二维码		addPosterQrcode : function(ctx) {			// 长按识别二维码访问			ctx.setFontSize(19);			ctx.setFillStyle('#333');			ctx.fillText("长按识别二维码访问", 17, this.text_top + 136);			// 平台名称			ctx.setFontSize(16);			ctx.setFillStyle('#999');			ctx.fillText(this.fetch.info.platform_name, 17, this.text_top + 170);		},				// 绘制海报		drawPoster : function(ctx, resolve, reject) {			ctx.draw(true, () => {				// canvas画布转成图片并返回图片地址				uni.canvasToTempFilePath({					canvasId: 'poster',					width: 375,					height: 673,					quality : 1,					success: (res) => {						if (res.tempFilePath.indexOf('base64')) {							base64ToPath(res.tempFilePath).then(path => {								this.finish(path, resolve);							});						} else {							this.finish(res.tempFilePath, resolve);						}					},					fail: () => {						uni.hideLoading();						reject();					}				})			});		},				// 完成绘制		finish : function(path, resolve) {			if(this.posterImgs[this.swiperIndex]){				this.posterImgs[this.swiperIndex].temporary = path;			}else{				this.posterImgs[this.swiperIndex] = {					temporary: path				};			}			resolve(path);		},				// 保存图片		async showPoster() {			let imgUrl = "";			if(this.posterImgs[this.swiperIndex] && this.posterImgs[this.swiperIndex].temporary){				imgUrl = await this.posterImgs[this.swiperIndex].temporary;			}else{				imgUrl = await this.createPoster();			}			// #ifdef H5			this.poster = imgUrl;			this.showImage();			uni.hideLoading();			// #endif			// #ifdef MP-WEIXIN			uni.showLoading({				title: '海报下载中'			});			if (settingWritePhotosAlbum) {				uni.getSetting({					success: res => {						if (res.authSetting['scope.writePhotosAlbum']) {							uni.saveImageToPhotosAlbum({								filePath: imgUrl,								success: () => {									uni.hideLoading();									uni.showToast({										title: '保存成功'									});								}							});						} else {							uni.showModal({								title: '提示',								content: '请先在设置页面打开“保存相册”使用权限',								confirmText: '去设置',								cancelText: '算了',								success: data => {									if (data.confirm) {										uni.hideLoading();										uni.openSetting();									}								}							});						}					}				});			} else {				settingWritePhotosAlbum = true;				uni.authorize({					scope: 'scope.writePhotosAlbum',					success: () => {						uni.saveImageToPhotosAlbum({							filePath: imgUrl,							success: () => {								uni.hideLoading();								uni.showToast({									title: '保存成功'								});							}						});					}				});			}			// #endif			// #ifdef APP-PLUS			uni.showLoading({				title: '海报下载中'			});			uni.saveImageToPhotosAlbum({				filePath: imgUrl,				success: () => {					uni.hideLoading();					uni.showToast({						title: '保存成功'					});				}			});			// #endif		},		async onAppShare() {			// let imgUrl = "";			// if(this.posterImgs[this.swiperIndex] && this.posterImgs[this.swiperIndex].url){			// 	imgUrl = this.posterImgs[this.swiperIndex].url;			// } else if(this.posterImgs[this.swiperIndex] && this.posterImgs[this.swiperIndex].temporary){			// 	let imgData = await this.$http.qnFileUpload([this.posterImgs[this.swiperIndex].temporary]);			// 	imgUrl = imgData[0];			// }else{			// 	let data = await this.createPoster();			// 	let imgData = await this.$http.qnFileUpload([data]);			// 	imgUrl = imgData[0];			// }			// uni.hideLoading();			this.fetch.share.url = this.Dever.host + '';			uni.share({				provider: 'weixin',				scene: 'WXSceneSession',				type: 0,				title: this.fetch.share.title,				href: this.fetch.share.url,				summary: this.fetch.share.content,				imageUrl: this.fetch.share.pic,				success: function(res) {					console.log('success:' + JSON.stringify(res));				},				fail: function(err) {					console.log('fail:' + JSON.stringify(err));				}			});		}	},	//页面隐藏	onHide() {},	//页面卸载	onUnload() {},	//页面下来刷新	onPullDownRefresh() {},	//页面上拉触底	onReachBottom() {},	//用户点击分享	onShareAppMessage(e) {		let shareInfo = {			path: "/pages/home/shop/goodsDetail?objId="+this.fetch.info.id,			title: this.fetch.share.title,			imageUrl: this.fetch.share.pic		};		if(this.userInfo.token){			shareInfo.path += "&recommendCode=" + this.userInfo.uid;		}		console.log(shareInfo);		return shareInfo;	},	components:{copyText}};// 文字换行function drawtext(text, maxWidth) {	let textArr = text.split("");	let len = textArr.length;	// 上个节点	let previousNode = 0;	// 记录节点宽度	let nodeWidth = 0;	// 文本换行数组	let rowText = [];	// 如果是字母,侧保存长度	let letterWidth = 0;	// 汉字宽度	let chineseWidth = 21;	// otherFont宽度	let otherWidth = 10.5;	for (let i = 0; i < len; i++) {		if (/[\u4e00-\u9fa5]|[\uFE30-\uFFA0]/g.test(textArr[i])) {			if(letterWidth > 0){				if(nodeWidth + chineseWidth + letterWidth * otherWidth > maxWidth){					rowText.push({						type: "text",						content: text.substring(previousNode, i)					});					previousNode = i;					nodeWidth = chineseWidth;					letterWidth = 0;				} else {					nodeWidth += chineseWidth + letterWidth * otherWidth;					letterWidth = 0;				}			} else {				if(nodeWidth + chineseWidth > maxWidth){					rowText.push({						type: "text",						content: text.substring(previousNode, i)					});					previousNode = i;					nodeWidth = chineseWidth;				}else{					nodeWidth += chineseWidth;				}			}		} else {			if(/\n/g.test(textArr[i])){				rowText.push({					type: "break",					content: text.substring(previousNode, i)				});				previousNode = i + 1;				nodeWidth = 0;				letterWidth = 0;			}else if(textArr[i] == "\\" && textArr[i + 1] == "n"){				rowText.push({					type: "break",					content: text.substring(previousNode, i)				});				previousNode = i + 2;				nodeWidth = 0;				letterWidth = 0;			}else if(/[a-zA-Z0-9]/g.test(textArr[i])){				letterWidth += 1;				if(nodeWidth + letterWidth * otherWidth > maxWidth){					rowText.push({						type: "text",						content: text.substring(previousNode, i + 1 - letterWidth)					});					previousNode = i + 1 - letterWidth;					nodeWidth = letterWidth * otherWidth;					letterWidth = 0;				}			} else{				if(nodeWidth + otherWidth > maxWidth){					rowText.push({						type: "text",						content: text.substring(previousNode, i)					});					previousNode = i;					nodeWidth = otherWidth;				}else{					nodeWidth += otherWidth;				}			}		}	}	if (previousNode < len) {		rowText.push({			type: "text",			content: text.substring(previousNode, len)		});	}	return rowText;}</script><style lang="scss" scoped>.content3 {	padding:30rpx;	line-height:50rpx;	font-size:26rpx;	height:675rpx;	color:#000000;}.content2 {	padding:30rpx; 	line-height:50rpx;	font-size:26rpx;	height:675rpx;	color:#000000;}.content2 view{	padding: 15rpx;}.content2 .active {	}.demo-msg {	width:600rpx;}.icon-close{}.poster_page {	}.onSave:after {	border:0px;}.poster_canvas {	width: 750rpx;	height: 1334rpx;	position: fixed;	top: -10000rpx;	left: 0rpx;}.poster_swiper {	height: 950rpx;	width: 100%;	swiper-item {		box-sizing: border-box;		display: flex;		align-items: center;		.goods_info_box {			width: 100%;			height: 100%;			transform: scale(0.88);			transition: all 0.4s;			position: relative;			overflow: hidden;			background-color: #FFFFFF;			&.active {				transform: scale(1);			}			.goods_image {				width: 100%;				height: calc(100vw - 220rpx);			}			.goods_info {				padding: 24rpx;				.goods_name {					color: #333;					font-size: 30rpx;									}				.price_box {					margin-top: 24rpx;					display: flex;					align-items: center;					.price {						font-size: 38rpx;						color: red;					}					.store_price {						margin-left: 30rpx;						font-size: 26rpx;						color: #999;						text-decoration: line-through;					}				}				.poster_info {					border-top: 2rpx solid #f1f1f1;					padding-top: 24rpx;					margin-top: 24rpx;					display: flex;					align-items: center;					justify-content: space-between;					.info {						display: flex;						flex-direction: column;						view {							color: #333;							font-size: 28rpx;						}						text {							color: #999;							font-size: 24rpx;							margin-top: 20rpx;						}					}					.poster_code_image {						width: 170rpx;						height: 170rpx;						flex-shrink: 0;					}				}			}		}	}}.share_save_box {	position: fixed;	bottom: calc((100vh - 950rpx - 240rpx) / 4);	left: 0;	z-index: 6;	width: 100%;	display: flex;	justify-content: space-around;	button {		display: flex;		flex-direction: column;		align-items: center;		background-color: transparent;		image {			width: 60rpx;			height: 60rpx;		}		text {			font-size: 24rpx;			color: #333333;		}	}}.h5_press_save {	background-color: #000;	position: fixed;	top: 0;	left: 0;	width: 100%;	height: 100%;	display: flex;	align-items: center;	z-index: 100;	image {		width: 100%;	}	.download {		font-size: 24rpx;		color: #ffffff;		background-color: rgba(0,0,0,0.5);		display: flex;		align-items: center;		flex-direction: row;		justify-content: center;		position: absolute;		padding: 5rpx 30rpx;		border-radius: 40rpx;		bottom: 30rpx;		left: 50%;		transform: translateX(-50%);		&:before {			content: '';			width: 24rpx;			height: 24rpx;			margin-right: 15rpx;		}	}}</style>
 |