标题小程序开发步骤:
1去微信公众平台https://mp.weixin.qq.com/申请账号,密码:
2AppID(小程序ID),
小程序的标识,(个人理解,开发者工具中识别哪个小程序,上传代码)(开发时候有区别作用)
3AppSecret(小程序密钥)
想要生产unionId的前提,后续与后端交互有用到
4小程序的开发需要开发者工具
绿框的部分就是说,如果web-src的地址不是https也可以在开发者工具中启动,但是微信肯定访问不了。
文件结构啥的和vue差不多:
5服务器域名,配置合法的服务器域名(必须https)
wx.request 请求 去拉取数据的域名
6业务域名
业务域名是小程序的webview组件要引入的其他H5地址的URL的域名或者网页里面的iframe的域名
7管理-成员管理,可以添加开发人员及相关权限,体验人员
8管理-版本管理,可以设置体验版本,一般开发者工具上传后,这边就可以设置
9有支付功能要开通支付功能:
小程序这边要关联商户号(收钱方)
商户号的设置:登录商户平台-产品中心-账号关联(AppID绑定),进入授权申请页面;
10普通微信扫码进入小程序
二维码地址(https://x.jx116114.com/FZD/)是个短连接,在后端配置好对应长链接的表,H5这边写个短连接空页面,加载转换的url判断
具体设置:
测试连接:前面是地址的域名,中间/FZD/是区别哪个小程序,绿框的部分是对应长链接的具体地址和分享人的信息和分享的信息(具体传啥后端定义好)
标题Web-view结合H5的小程序开发步骤:
H5正常开发,需要的openId、unionId都从url里面取(小程序转到H5的时候拼接)
Web-view小程序壳子: https://developers.weixin.qq.com/miniprogram/dev/component/web-view.html 开发文档
1.在小程序中
/page/index/
Wxml:
<view >
<view wx:if='{{showOrHidden}}'>
<button wx:if="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo" class="button-img"></button>
</view>
<view wx:if='{{showOrHiddenW}}'>
<web-view src="{{src}}" bindmessage="msgHandler" value="{{}}"></web-view>
</view>
<view controls="{{!officialCanIUse}}" style="width:100%;position:fixed;height:5rem;bottom:0px;">
<official-account style=""></official-account>
</view>
</view>
Index.js:
//index.js
//获取应用实例
// const app = getApp()
var appid = "wx**********************";
var shareUrl;
Page({
data: {
officialCanIUse: wx.canIUse('official-account'),
canIUse: wx.canIUse('button.open-type.getUserInfo'),
fxStr:'',
showOrHidden: false,//判断按钮显示与否的,true表示显示,反之隐藏
showOrHiddenW: false//判断web-view显示与否的,true表示显示,反之隐藏
},
onLoad: function (options) {
console.log(options);
var that = this;
that.data.fxStr = '';
if (options.q) {
let scan_url = decodeURIComponent(options.q);
console.log("scan_url:" + scan_url)
that.data.fxStr = scan_url;
// that.setData({ src: src });
let video_id = scan_url.match(/\d+/) //提取链接中的数字,也就是链接中的参数id,/\d+/ 为正则表达式
}
// 查看是否授权
wx.getSetting({
success: function (res) {
if (res.authSetting['scope.userInfo']) {
wx.showLoading({
title: '加载中',
});
// 已经授权,可以直接调用 getUserInfo 获取头像昵称
wx.getUserInfo({
success: function (res) {
console.log(res.userInfo)
//小程序获取信息
wxLogin(that, res.userInfo);
}
})
}else{
that.setData({
showOrHidden: that.showOrHidden = true,
showOrHiddenW: that.showOrHiddenW = false
})
}
}
})
},
getUserInfo: function (e) {
console.log(e.detail.userInfo)
var that = this;
wx.showLoading({
title: '加载中',
});
//小程序获取信息
wxLogin(that, e.detail.userInfo);
},
msgHandler: function (e) { //转发时候先执行(h5像小程序传递参数)
console.log(e.detail.data) //我是网页,获取到来自也页面的数据
var info = (e.detail.data)[((e.detail.data).length) - 1]
console.log("H5返回:" + JSON.stringify(info) );
wx.setStorage({
"key" : "shareDatas",
"data" : info
})
},
// 网页向小程序传值
onShareAppMessage: function () {
var title = '';
var desc = '';
var imageUrl = '';
var path = 'pages/detail/index';
var shareDatasStr = wx.getStorageSync("shareDatas");
if (shareDatasStr != null && shareDatasStr != ""){
var shareDatas = JSON.parse(shareDatasStr);
title = shareDatas.hTitle == null ? '泛终端!' : shareDatas.hTitle;
imageUrl = shareDatas.hImage == null ? "../image/share_res.png" : shareDatas.hImage;
desc = shareDatas.hDesc == null ? '优惠泛终端' : shareDatas.hDesc;
shareUrl = shareDatas.hUrl;
wx.setStorage({
"key": "shareUrl",
"data": shareUrl
})
}
var phoneNumber = wx.getStorageSync('phoneNumber');
var md5PhoneNumber = wx.getStorageSync('md5PhoneNumber');
var params = { "phoneNumber": phoneNumber, "encryptStr":md5PhoneNumber };
var url = 'https://x.jx116114.com/concent/contactcentre/dreamIntegrate/shareDevAddIntegrate';
console.log('url:' + url + ',params:' + JSON.stringify(params));
// ------ 发送凭证 ------
wx.request({
url: url,
data: params,
method: 'POST',
header: {
'content-type': 'application/json'
},
success: function (res) {
console.log("分享增加梦享值接口返回:" + JSON.stringify(res.data));
if (res.data.code == "0000") {
console.log("data:" + res.data);
}
},
})
return {
title: title,
imageUrl: imageUrl,
desc: desc,
path: path
};
}
})
/**
* 小程序获取信息
*/
function wxLogin(that,userInfo){
that.setData({
showOrHidden: that.showOrHidden = false,
showOrHiddenW: that.showOrHiddenW = true
})
wx.setStorage({
"key": "userInfo",
"data": userInfo
})
wx.login({
success: res => {
// ------ 获取凭证 ------
var code = res.code;
if (code) {
console.log('获取用户登录凭证: ' + code);
getUnionIdByCode(code, appid, that);//code查unionid
} else {
console.log('获取用户登录凭证失败: ' + res.errMsg);
}
}
})
}
/**
* code查unionid
*/
function getUnionIdByCode(code, appid,that){
var params = { "code": code, "appid": appid };
var url = 'https://x.jx116114.com/concent/comprehensiveUtil/GetWechatInfo/appletGetOpenIdByCode';
console.log('code查unionid url: ' + url + ' params: ' + JSON.stringify(params));
// ------ 发送凭证 ------
wx.request({
url: url,
data: params,
method: 'POST',
header: {
'content-type': 'application/json'
},
success: function (res) {
console.log("获取到的用户信息为:" + JSON.stringify(res.data));
if (res.statusCode == 200 && res.data.code != "4444") {
if (res.data.openid != null){
//保存小程序用户信息
// saveMiniProgramInfo(res.data.openid);
}
if (res.data.unionid != null) {
getOpneIdByUnionId(res.data, that);//unionid查openid
}
}
},
})
}
/**
* unionid查openid
*/
function getOpneIdByUnionId(data,that) {
var unionId = data.unionid;
var sOpenId = data.openid;
// 小程序本地存储
wx.setStorageSync('unionId', unionId);
wx.setStorageSync('sOpenId', sOpenId);
var params = { "unionid": unionId};
var url = 'https://x.jx116114.com/concent/comprehensiveUtil/GetWechatInfo/queryPhoneByUnionId';
console.log('unionid查openid url ' + url + 'params: ' + JSON.stringify(params));
// ------ 发送凭证 ------
wx.request({
url: url,
data: params,
method: 'POST',
header: {
'content-type': 'application/json'
},
success: function (res) {
console.log("获取到公众号返回的用户信息为: " + JSON.stringify(res.data));
if (res.statusCode == 200 && res.data.code != "4444" && res.data.code != "500") {
// that.globalData.openid = res.data
if (res.data.md5PhoneNumber != null) {
wx.setStorage({
"key": "phoneNumber",
"data": res.data.phoneNumber
});
//保存小程序用户信息
saveMiniProgramInfo(unionId, res.data.phoneNumber);
// console.log("获取手机: " + res.data.phoneNumber);
wx.setStorage({
"key": "md5PhoneNumber",
"data": res.data.md5PhoneNumber
});
}
var src
if (that.data.fxStr){
src = that.data.fxStr +"&unionId=" + unionId + "&sOpenId=" + sOpenId
}else{
src = "https://x.jx116114.com/concent/pages/contactCentrePhone/cloudShopping/miniAppHome.html?unionId=" + unionId + "&sOpenId=" + sOpenId;
}
// wx.showModal({
// content: "测试正常/分享" + JSON.stringify(src),
// showCancel: false
// });
// 网页向小程序传值url带参数
that.setData({ src: src });
wx.hideLoading();
} else{
var src
if (that.data.fxStr) {
src = that.data.fxStr + "&unionId=" + unionId + "&sOpenId=" + sOpenId
} else {
src = "https://x.jx116114.com/concent/pages/contactCentrePhone/cloudShopping/miniAppHome.html?unionId=" + unionId + "&sOpenId=" + sOpenId;
}
console.log("src: " + src);
// 网页向小程序传值url带参数
that.setData({ src: src });
wx.hideLoading();
}
wx.hideLoading();
},fail:function(res){
console.log("获取到公众号返回的用户信息为: " + JSON.stringify(res.data));
wx.showToast({
title: '接口异常',
icon: 'none',
mask: "true",
duration: 20000
})
wx.hideLoading();
}
})
}
/**
* 保存小程序用户信息
*/
function saveMiniProgramInfo(sOpenId,phoneNumber) {
var sDatas = wx.getStorageSync('userInfo');
sDatas.contactPhone = phoneNumber;
var params = { "sOpenId": sOpenId, "sDatas": JSON.stringify(sDatas)};
var url = 'https://x.jx116114.com/concent/contactcentre/dreamPartner/saveMiniProgramInfo';
console.log('url' + url + 'params:' + JSON.stringify(params));
// ------ 发送凭证 ------
wx.request({
url: url,
data: params,
method: 'POST',
header: {
'content-type': 'application/json'
},
success: function (res) {
if (res.data.code == "0000") {
console.log("保存小程序用户信息返回为: " + JSON.stringify(res.data));
}
},
})
}
/page/pay/
Wxml:
<web-view src="{{url}}"></web-view>
Index.js:
// pages/wxPay/index.js
Page({
onLoad: function (options) {
console.log('支付开始');
console.log(options)
var param= {
"timeStamp": options.timeStamp,
"nonceStr": options.nonceStr,
"package": "prepay_id="+options.package,//组装下参数
"signType": "MD5",
"paySign": options.paySign,
"orderId":options.orderId
}
console.log(param)
//页面加载调取微信支付(原则上应该对options的携带的参数进行签名计算,校验)
this.pay(param,this)//吊起支付
},
pay: function (param,that) {
var unionId = wx.getStorageSync('unionId')
var sOpenId = wx.getStorageSync('sOpenId')
console.log('unionId'+unionId,'sOpenId'+sOpenId)
// 调起支付
wx.requestPayment({
timeStamp: param.timeStamp,//时间搓
nonceStr: param.nonceStr,//随机码
package: param.package,//统一下单接口返回的 prepay_id
signType: param.signType,//签名算法MD5
paySign: param.paySign,//签名字符串
'success': function (res) {
console.log(res)
console.log('=======支付成功返回支付中心==========');
var url = "https://x.jx116114.com/paycent/pages/paycenter/cashDesk/mobileNetWork/cashierDeskResult.html?code=0000&orderId=" + param.orderId + "&appName=FanZhongDuan&unionId="+unionId+"&sOpenId="+sOpenId;
// var url = "https://x.jx116114.com/concent/pages/contactCentrePhone/cloudShopping/miniAppHome.html?unionId=o7m06t5O8wekvuhnsQ8uznl1VknM"
// 网页向小程序传值url带参数
that.setData({ url: url });
// wx.navigateTo({
// url: `/pages/index/index`
// })
},
'fail': function (res) {
console.log(res)
console.log('=======支付失败==========')
var url = "https://x.jx116114.com/paycent/pages/paycenter/cashDesk/mobileNetWork/cashierDeskResult.html?code=9999&appName=FanZhongDuan&unionId="+unionId+"&sOpenId="+sOpenId;
that.setData({ url: url });
// wx.navigateBack({
// delta: 1//返回1个页面
// })
}
})
}
})
从上可以看出只要更换web-src的值就是小程序打开H5的入口。
2开发瓶颈注意
H5正常开发就好,但是支付时有问题,H5不支持小程序的支付,这里采用,支付时由H5跳回小程序方法:
- H5最好单写一个页面只管跳小程序,(不能是Tab页面)
一定要有:
传参保证准确性:
timeStamp=&nonceStr=&package=&signType=&paySign=&orderId=’
由后端生成之后传给小程序
- 小程序的支付
/page/pay/
见上 - 小程序的转发分享
Web-view组件提供:
在H5端
wx.miniProgram.postMessage({
data: LiJiFx
})
其中:
var LiJiFx = {
'shareDesc': '泛终端',
'shareImage': '图片地址',
'shareTitle': 'title信息',
'url':'分享出去的url'
} //后端返回的短连接:https://x.jx116114.com/FZD/U73uIz
//对应长链接:https://x.jx116114.com/concent/pages/contactCentrePhone/cloudShopping/goodsPage.html?goodsId=1912201412123413&shareId=o7m06t5O8wekvuhnsQ8uznl1VknM&recomDepartId=75b38ay&recomPersonId=7509935868
小程序要用:
Bindmessage绑定wxml绑定事件
msgHandler: function (e) { //转发时候先执行(h5像小程序传递参数) }
接收,存到小程序本地
// 用户点击右上角分享
onShareAppMessage: function (options) {
进行转发给别人,取出本地参数传给被分享人
var shareDatasStr = wx.getStorageSync("shareDatas");
var title = shareDatasStr.shareTitle
var desc = shareDatasStr.shareDesc;
var imageUrl = shareDatasStr.shareImage;
var goodsId = shareDatasStr.goodsId;
var shareUrl = shareDatasStr.url;
var path = 'pages/index/index?shareInfo='+shareUrl
return {
title: title,
imageUrl: imageUrl,
desc: desc,
path: path
};
被分享人打开时:
onLoad: function (options) {
console.log(options);
var that = this;
that.data.fxStr = '';
that.data.liJiFx = '';
if (options.q) {
//二维码分享进来
let scan_url = decodeURIComponent(options.q);
console.log("scan_url:" + scan_url)
that.data.fxStr = scan_url;
}else if(options.shareInfo){
//小程序分享转发进来
this.data.liJiFx = options.shareInfo
}
再改变全局web-view的src= this.data.liJiFx
<!--index.wxml-->
<view >
<view wx:if='{{showOrHidden}}'>
<button wx:if="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo" class="button-img"></button>
</view>
<view wx:if='{{showOrHiddenW}}'>
<web-view src="{{src}}" bindmessage="msgHandler" value="{{}}"></web-view>
</view>
<view controls="{{!officialCanIUse}}" style="width:100%;position:fixed;height:5rem;bottom:0px;">
<official-account style=""></official-account>
</view>
</view>
具体见代码
//index.js
//获取应用实例
// const app = getApp()
var appid = "wxf****************";
Page({
data: {
officialCanIUse: wx.canIUse('official-account'),
canIUse: wx.canIUse('button.open-type.getUserInfo'),
fxStr:'',
liJiFx:'',
showOrHidden: false,//判断按钮显示与否的,true表示显示,反之隐藏
showOrHiddenW: false//判断web-view显示与否的,true表示显示,反之隐藏
},
onLoad: function (options) {
console.log(options);
var that = this;
that.data.fxStr = '';
that.data.liJiFx = '';
if (options.q) {
let scan_url = decodeURIComponent(options.q);
console.log("scan_url:" + scan_url)
that.data.fxStr = scan_url;
}else if(options.shareInfo){
this.data.liJiFx = options.shareInfo
}
// 查看是否授权
wx.getSetting({
success: function (res) {
if (res.authSetting['scope.userInfo']) {
wx.showLoading({
title: '加载中',
});
// 已经授权,可以直接调用 getUserInfo 获取头像昵称
wx.getUserInfo({
success: function (res) {
console.log(res.userInfo)
//小程序获取信息
wxLogin(that, res.userInfo);
}
})
}else{
that.setData({
showOrHidden: that.showOrHidden = true,
showOrHiddenW: that.showOrHiddenW = false
})
}
}
})
},
getUserInfo: function (e) {
console.log(e.detail.userInfo)
var that = this;
wx.showLoading({
title: '加载中',
});
//小程序获取信息
wxLogin(that, e.detail.userInfo);
},
//我是网页,获取到来自也页面的数据
msgHandler: function (e) { //转发时候先执行(h5像小程序传递参数)
console.log(e.detail.data) //我是网页,获取到来自也页面的数据
var info = (e.detail.data)[((e.detail.data).length) - 1]
console.log("H5返回:" + JSON.stringify(info) );
wx.setStorage({
"key" : "shareDatas",
"data" : info
})
},
// 用户点击右上角分享
onShareAppMessage: function (options) {
var return_url = options.webViewUrl;
var shareDatasStr = wx.getStorageSync("shareDatas");
var title = shareDatasStr.shareTitle
var desc = shareDatasStr.shareDesc;
var imageUrl = shareDatasStr.shareImage;
var goodsId = shareDatasStr.goodsId;
var shareUrl = shareDatasStr.url;
// wx.getStorageSync('unionId');
// wx.getStorageSync('sOpenId');
var path = 'pages/index/index?shareInfo='+shareUrl
var phoneNumber = wx.getStorageSync('phoneNumber');
var md5PhoneNumber = wx.getStorageSync('md5PhoneNumber');
var params = { "phoneNumber": phoneNumber, "encryptStr":md5PhoneNumber };
var url = 'https://x.jx116114.com/concent/contactcentre/dreamIntegrate/shareDevAddIntegrate';
console.log('url:' + url + ',params:' + JSON.stringify(params));
// ------ 发送凭证 ------
wx.request({
url: url,
data: params,
method: 'POST',
header: {
'content-type': 'application/json'
},
success: function (res) {
console.log("分享增加梦享值接口返回:" + JSON.stringify(res.data));
if (res.data.code == "0000") {
console.log("data:" + res.data);
}
},
})
return {
title: title,
imageUrl: imageUrl,
desc: desc,
path: path
};
}
})
/**
* 小程序获取信息
*/
function wxLogin(that,userInfo){
that.setData({
showOrHidden: that.showOrHidden = false,
showOrHiddenW: that.showOrHiddenW = true
})
wx.setStorage({
"key": "userInfo",
"data": userInfo
})
wx.login({
success: res => {
// ------ 获取凭证 ------
var code = res.code;
if (code) {
console.log('获取用户登录凭证: ' + code);
getUnionIdByCode(code, appid, that);//code查unionid
} else {
console.log('获取用户登录凭证失败: ' + res.errMsg);
}
}
})
}
/**
* code查unionid
*/
function getUnionIdByCode(code, appid,that){
var params = { "code": code, "appid": appid };
var url = 'https://x.jx116114.com/concent/comprehensiveUtil/GetWechatInfo/appletGetOpenIdByCode';
console.log('code查unionid url: ' + url + ' params: ' + JSON.stringify(params));
// ------ 发送凭证 ------
wx.request({
url: url,
data: params,
method: 'POST',
header: {
'content-type': 'application/json'
},
success: function (res) {
console.log("获取到的用户信息为:" + JSON.stringify(res.data));
if (res.statusCode == 200 && res.data.code != "4444") {
if (res.data.openid != null){
//保存小程序用户信息
// saveMiniProgramInfo(res.data.openid);
}
if (res.data.unionid != null) {
getOpneIdByUnionId(res.data, that);//unionid查openid
}
}
},
})
}
/**
* unionid查openid
*/
function getOpneIdByUnionId(data,that) {
var unionId = data.unionid;
var sOpenId = data.openid;
// 小程序本地存储
wx.setStorageSync('unionId', unionId);
wx.setStorageSync('sOpenId', sOpenId);
var params = { "unionid": unionId};
var url = 'https://x.jx116114.com/concent/comprehensiveUtil/GetWechatInfo/queryPhoneByUnionId';
console.log('unionid查openid url ' + url + 'params: ' + JSON.stringify(params));
// ------ 发送凭证 ------
wx.request({
url: url,
data: params,
method: 'POST',
header: {
'content-type': 'application/json'
},
success: function (res) {
console.log("获取到公众号返回的用户信息为: " + JSON.stringify(res.data));
if (res.statusCode == 200 && res.data.code != "4444" && res.data.code != "500") {
// that.globalData.openid = res.data
if (res.data.md5PhoneNumber != null) {
wx.setStorage({
"key": "phoneNumber",
"data": res.data.phoneNumber
});
//保存小程序用户信息
saveMiniProgramInfo(unionId, res.data.phoneNumber);
// console.log("获取手机: " + res.data.phoneNumber);
wx.setStorage({
"key": "md5PhoneNumber",
"data": res.data.md5PhoneNumber
});
}
var src
if (that.data.fxStr){
src = that.data.fxStr +"&unionId=" + unionId + "&sOpenId=" + sOpenId
}else if(that.data.liJiFx){
// src = "https://x.jx116114.com/concent/pages/contactCentrePhone/cloudShopping/miniAppHome.html?unionId=" + unionId + "&sOpenId=" + sOpenId;
src = that.data.liJiFx +"&unionId=" + unionId + "&sOpenId=" + sOpenId
}else{
src = "https://x.jx116114.com/concent/pages/contactCentrePhone/cloudShopping/miniAppHome.html?unionId=" + unionId + "&sOpenId=" + sOpenId;
}
// wx.showModal({
// content: "测试正常/分享" + JSON.stringify(src),
// showCancel: false
// });
// 网页向小程序传值url带参数
that.setData({ src: src });
wx.hideLoading();
} else{
var src
if (that.data.fxStr) {
src = that.data.fxStr + "&unionId=" + unionId + "&sOpenId=" + sOpenId
} else if(that.data.liJiFx){
// src = "https://x.jx116114.com/concent/pages/contactCentrePhone/cloudShopping/miniAppHome.html?unionId=" + unionId + "&sOpenId=" + sOpenId;
src = that.data.liJiFx +"&unionId=" + unionId + "&sOpenId=" + sOpenId
}else {
src = "https://x.jx116114.com/concent/pages/contactCentrePhone/cloudShopping/miniAppHome.html?unionId=" + unionId + "&sOpenId=" + sOpenId;
}
console.log("src: " + src);
// 网页向小程序传值url带参数
that.setData({ src: src });
wx.hideLoading();
}
wx.hideLoading();
},fail:function(res){
console.log("获取到公众号返回的用户信息为: " + JSON.stringify(res.data));
wx.showToast({
title: '接口异常',
icon: 'none',
mask: "true",
duration: 20000
})
wx.hideLoading();
}
})
}
/**
* 保存小程序用户信息
*/
function saveMiniProgramInfo(sOpenId,phoneNumber) {
var sDatas = wx.getStorageSync('userInfo');
sDatas.contactPhone = phoneNumber;
var params = { "sOpenId": sOpenId, "sDatas": JSON.stringify(sDatas)};
var url = 'https://x.jx116114.com/concent/contactcentre/dreamPartner/saveMiniProgramInfo';
console.log('url' + url + 'params:' + JSON.stringify(params));
// ------ 发送凭证 ------
wx.request({
url: url,
data: params,
method: 'POST',
header: {
'content-type': 'application/json'
},
success: function (res) {
if (res.data.code == "0000") {
console.log("保存小程序用户信息返回为: " + JSON.stringify(res.data));
}
},
})
}