小程序开发经验-二维码分享
先看一下效果图
一:wxml
<view class='page'>
<view class='img'>
<canvas class='shareImg' style='width:{{windowWidth}}px; height:{{windowHeight}}px;'
canvas-id="shareCanvas"
binderror="canvasIdErrorCallback"
></canvas>
</view>
<view class='btn'>
<button class='shareView' open-type='getUserInfo' bindtap="downImg">
<text class='iconfont icon-xiazai xiazai black'></text>保存到本地
</button>
<button class='shareFriend' data-name="shareBtn" open-type="share">
邀请好友为我点赞
</button>
</view>
</view>
二:js
1:页面初始化加载
onReady: function () {
var that = this;
wx.showLoading({
title: '正在生成...',
mask: true,
});
var i = setInterval(function () {
console.log(calDays);
if (share_like_code && share_bg_img && windowWidth && nickName && wxAvatarUrl && stepSize && days && calDays==days){
clearInterval(i);
createShareImg(that);
}
},200);
loadUserData(this);
loadUserInfo(this);
loadShareData(this);
},
2:加载二维码
function loadShareLikeCode(that){
user_info_table.where({
_openid: openid
}).orderBy('createDate', 'desc').limit(1).get().then(res => {
var user = res.data[0];
console.log(' save user select user ', user);
var shareLikeCodeUrl = user.shareLikeCodeUrl;
if (shareLikeCodeUrl){
wx.getImageInfo({
src: shareLikeCodeUrl,
success: function (res) {
console.log('res', res);
share_like_code = res.path;
},
fail: function (e) {
console.log(e);
wx.showToast({
title: '加载失败',
icon: 'none',
mask: false,
duration: 2000
});
}
})
}else{
wx.cloud.callFunction({
name: 'img_upload_handle', // 云函数名称
data: { // 小程序码所需的参数
page: "pages/home/home",
scene: 'f:' + openid,
fileName: 'shareLike/' + openid + '/code/' + openid + '.png',
},
complete: res => {
console.log('callFunction test result: ', res)
console.log('callFunction test url: ', res.result.url);
var url = "https://" + res.result.url;
console.log("url:", url);
wx.getImageInfo({
src: url,
success: function (res) {
console.log('res', res);
share_like_code = res.path;
},
fail: function (e) {
console.log(e);
wx.showToast({
title: '加载失败',
icon: 'none',
mask: false,
duration: 2000
});
}
})
var user_id = user._id;
user_info_table.doc(user_id).update({
data: {
shareLikeCodeUrl: url,
}
})
.then(res => { })
.catch(console.error);
},
});
}
})
}
2:加载背景图片
function loadShareData(that) {
dict_config_table.where({
type: 'share_bg_img',
sub_type: page_type,
}).orderBy('index', 'ASC').get().then(res => {
var content = res.data[0].content;
console.log(content);
wx.getImageInfo({
src: content,
success: function (res) {
console.log('res', res);
share_bg_img = res.path;
},
fail: function (e) {
console.log(e);
}
})
})
3:绘制图片
function createShareImg(that){
const context = wx.createCanvasContext('shareCanvas');
context.drawImage(share_bg_img, 0, 0, windowWidth, windowHeight);
context.fillStyle = "rgba(0,0,0,0.4)";
context.fillRect(20 * rpx, 20 * hrpx, 280 * rpx, 464 * hrpx);
//头像
context.fillStyle = "rgba(255,255,255,1)";
context.fillRect(50 * rpx, 30 * hrpx, 50 * rpx, 50 * rpx);
context.drawImage(wxAvatarUrl, 50 * rpx, 30 * hrpx, 50 * rpx, 50 * rpx);
context.setFillStyle('#FFFFFF');
// context.setFontSize(30);
// context.fillText(avatar, 30, 60);
//昵称
context.setFontSize(15 * rpx);
context.fillText(nickName, 110 * rpx, 50 * hrpx);
//说明
context.setFontSize(11 * rpx);
context.fillText(titContent, 110 * rpx, 75 * hrpx);
// 完成度
context.setFontSize(27 * rpx);
context.fillText(stepSize, 50 * rpx, 120 * hrpx);
context.setFontSize(10 * rpx);
context.fillText(stepUnit, 105 * rpx, 120 * hrpx);
context.setFontSize(18 * rpx);
context.fillText(stepResult, 60 * rpx, 150 * hrpx);
context.setFontSize(27 * rpx);
context.fillText(days, 200 * rpx, 120 * hrpx);
context.setFontSize(10 * rpx);
context.fillText(daysUnit, 240 * rpx, 120 * hrpx);
context.setFontSize(18 * rpx);
context.fillText(daysResult, 210 * rpx, 150 * hrpx);
//中间提示
context.setFontSize(15 * rpx);
context.fillText(encontent1, 70 * rpx, 200 * hrpx);
context.setFontSize(15 * rpx);
context.fillText(encontent2, 30 * rpx, 230 * hrpx);
context.setFontSize(11 * rpx);
context.fillText(content, 75 * rpx, 260 * hrpx);
context.drawImage('/pages/utils/resources/image/dz.png', 140 * rpx, 290 * hrpx, 40 * rpx, 40 * rpx);
context.setFontSize(12 * rpx);
context.fillText(likeTip, 135 * rpx, 355 * hrpx);
// 二维码
context.drawImage(share_like_code, 65 * rpx, 390 * hrpx, 80 * rpx, 80 * rpx);
context.setFontSize(18 * rpx);
context.fillText(codeName, 175 * rpx, 410 * hrpx);
context.setFontSize(12 * rpx);
context.fillText(codeTip1, 175 * rpx, 440 * hrpx);
context.setFontSize(12 * rpx);
context.fillText(codeTip2, 175 * rpx, 460 * hrpx);
context.draw();
wx.hideLoading();
}
4:下载图片
downImg:function(){
wx.showLoading({
title: '正在保存...',
mask: true,
});
wx.getSetting({
success(res) {
console.log(res.authSetting)
console.log();
var isSave = res.authSetting['scope.writePhotosAlbum'];
console.log(isSave);
if (false == isSave) {
wx.openSetting({
success(res) {
console.log(res.authSetting)
}
})
wx.hideLoading();
}
}
})
wx.canvasToTempFilePath({
canvasId: 'shareCanvas',
success(res) {
console.log(res);
wx.authorize({
scope: 'scope.writePhotosAlbum',
success() {
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success() {
wx.showToast({
title: '已下载至相册',
icon: 'success',
mask: false,
duration: 2000
})
},
fail(){
wx.hideLoading();
},
complete(){
}
})
},
fail(e) {
console.log(e);
}
})
}
}, this);
},
三:云函数
1:img_upload_handle
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext();
var dataresult = await cloud.callFunction({
name: 'get_token', // 云函数名称
data: { // 小程序码所需的参数
page: event.page,
friendId: event.friendId,
},
})
var data = dataresult.result.data;
var access_token = dataresult.result.access_token;
var bytes = data;
var upresult = await cloud.callFunction({
name: 'weixin_bytes_uploader', // 云函数名称
data: { // 小程序码所需的参数
bybes: bytes,
fileName: event.fileName,
access_token: access_token,
page: event.page,
scene: event.scene,
},
})
return {
event,
openid: wxContext.OPENID,
appid: wxContext.APPID,
unionid: wxContext.UNIONID,
dataresult: dataresult,
url: upresult.result.url
}
}
2:云函数 get_token
// 云函数入口文件
const cloud = require('wx-server-sdk');
cloud.init()
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext();
const request = require('request');
return new Promise((resolve, reject) => {
request('https://....getToken', function (error, response, body) {
var access_token = JSON.parse(body).data;
var result = {
event,
openid: wxContext.OPENID,
appid: wxContext.APPID,
unionid: wxContext.UNIONID,
access_token: access_token
}
resolve(result);
});
});
}
3: 云函数 weixin_bytes_uploader
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
// 云函数入口函数
exports.main = async (event, context) => {
var fileName = null;
var bybes = null;
if (event.fileName){
fileName = event.fileName;
}
if (event.bybes){
bybes = event.bybes;
}else{
return {
error:"no bybes",
}
}
var access_token = event.access_token;
var key = fileName;
var options = {
scope: 'scope',
expires: 7200,
};
var param = {
page: event.page,
width: 280,
scene: event.scene,
};
const request = require('request');
return new Promise((resolve, reject) => {
var COS = require('cos-nodejs-sdk-v5');
// 使用永久**创建实例
var cos = new COS({
SecretId: 'SecretId',
SecretKey: 'SecretKey'
})
request.post({
url: 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' + access_token, form: JSON.stringify(param),
body: 'buffer',
encoding: null,
headers: [
{
name: 'responseType',
value: 'arraybuffer'
},
{
name: 'content-type',
value: 'application/x-www-form-urlencoded'
}
],
}, function (err, httpResponse, body) {
cos.putObject({
Bucket: 'Bucket', /* 必须 */
Region: 'Region', /* 必须 */
Key: key, /* 必须 */
Body: body, /* 必须 */
onProgress: function (progressData) {
console.log(progressData);
},
}, function (err, data) {
result.err = err;
result.data = data;
result.url = data.Location;
resolve(result);
if (err) {
console.log(err);
} else {
console.log(data);
}
});
});
});
}
四:生成效果图