










現(xiàn)在二維碼的使用場景越來越廣泛,如網(wǎng)頁端為了兼容手機(jī)瀏覽,會為PC端網(wǎng)站每個頁生成唯一的二維碼,如在瀏覽我們站點(diǎn)文章時,在這部分是可以查看到生成的手機(jī)端的二維碼的,如下圖:
本文不介紹網(wǎng)頁如何無限生成二維碼的技術(shù),只講微信小程序通過調(diào)用wxacode.getUnlimited生成無限小程序碼的功能實(shí)現(xiàn)。
因?yàn)槲⑿判〕绦蚬俜轿臋n對本人來說可能是寫得比較高深,以至于經(jīng)常還得配合很多文檔才能理解,再一個本文不是針對云開發(fā)的,如果使用云開發(fā)可以另查其他相關(guān)文章。
好,進(jìn)入實(shí)戰(zhàn),先看最后實(shí)現(xiàn)的場景載圖:
在訂單中到店自取時選擇貨到付款時,需要用到核銷碼的功能,如下圖:
有些系統(tǒng)開發(fā)會直接使用一串?dāng)?shù)字實(shí)現(xiàn),如美團(tuán)的就是用數(shù)字和二維碼相結(jié)合,但美團(tuán)只是生成二維碼,并沒有使用小程序碼功能,為什么美團(tuán)不用小程序碼,而使用二維碼呢,因?yàn)槊缊F(tuán)開發(fā)有獨(dú)立的核銷系統(tǒng),所以用二維碼加數(shù)字更符合他們的場景使用,好,還是言歸正題。
點(diǎn)擊核銷碼時,彈出微信小程序的二維碼,如下圖:
開發(fā)SAAS類型的小程序,這樣的優(yōu)勢還是比較明顯,在后臺設(shè)置了有核銷功能權(quán)限的用戶,就可以通過掃小程序碼對此訂單進(jìn)行核銷操作,當(dāng)然微信小程序碼更大的用途還不止如此。
使用場景講完,再進(jìn)行實(shí)現(xiàn)方法講解,所使用的開發(fā)環(huán)境是阿里云ecs服務(wù)器主機(jī)、系統(tǒng)nginx/1.18、搭建寶塔面板、PHP版本7.3、MYSQL5.5。
在申請小程序碼時,首先要使用微信的token令牌,和令牌使用方式和大部分API區(qū)別不大,令牌大概2小時的使用期限,所以不是每次申請小程序調(diào)用都去獲取令牌,像令牌的管理,應(yīng)該不寫在場景里,可以單獨(dú)的開發(fā)個頁,然后通過自動化執(zhí)行命令,如2小時就更新一次,這個實(shí)現(xiàn)起來非常簡單,這里不作詳細(xì)說明,在本文就直接把令牌管理也放在代碼里了。
首先我們要建一個數(shù)據(jù)表來存放令牌,名稱就叫wzjm_wx_token吧,然后三個字段,id(int 4), token_str(text),token_time(varchar 32),數(shù)據(jù)表創(chuàng)建命令如下:
CREATE TABLE `wzjm_wx_token` (
`id` INT( 4 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`token_str` TEXT NULL ,
`token_time` VARCHAR( 32 ) NULL
) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_estonian_ci;
申請令牌的接口是:auth.getAccessToken,調(diào)用參數(shù)與方法介紹微信官方文檔有了,大家就去查官方的資料,但微信官方?jīng)]實(shí)現(xiàn)的案例,我們就寫實(shí)例。
代碼如下:
/*
讀數(shù)據(jù)庫代碼略
*/
//生成小程序碼
$time=time();
$token_time=time();//這里改成取數(shù)據(jù)表的token_time
$appid="XXXX";//微信小程序appid
$secret=""XXXX;//微信小程序secret
if($time>=($token_time+6000))
{
//token過期,這里為什么使用6000秒,而不使用7200秒呢,反正系統(tǒng)給的調(diào)用次數(shù)足夠,但如果使用7200秒是極容易產(chǎn)生BUG的。
$url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$secret;
$curl = curl_init ( ) ;
//設(shè)置抓取的url
curl_setopt ( $curl , CURLOPT_URL , $url) ;
//設(shè)置頭文件的信息作為數(shù)據(jù)流輸出
curl_setopt ( $curl , CURLOPT_HEADER , 0 ) ;
//設(shè)置獲取的信息以文件流的形式返回,而不是直接輸出。
curl_setopt ( $curl , CURLOPT_RETURNTRANSFER , 1 ) ;
//執(zhí)行命令
$data = curl_exec ( $curl ) ;
//關(guān)閉URL請求
curl_close ( $curl ) ;
//顯示獲得的數(shù)據(jù)
$data_info = json_decode($data,true);
if($data_info['access_token']<>"")
{
$up_date=array();
$up_date['ewm_token']=$data_info['access_token'];
$up_date['ewm_time']=time();
/*
更新數(shù)據(jù)庫代碼略,可以自己補(bǔ)充
*/
}
else
{
//提示異常
exit();
}
//token過期
}
通過以上代碼,令牌管理基本可以了,如果要統(tǒng)一更新也更加簡單了,寫好分析加條每隔一段時間自動化執(zhí)行命令即可。
令牌代碼實(shí)現(xiàn)后,就可以申請小程序碼了。
像訂單核銷場景,需要針對每個訂單添加一個小程序碼的字段,如果不做保存,每次使用時都去申請這樣會造成比較占用系統(tǒng)的資源。
繼續(xù)看代碼:
$token="XXXXXX";//這是上段代碼取得的token值
$url="https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=".$token;
$ewm_list=array();
$ewm_list['scene']='id='.$id;//小程序傳參
$ewm_list['page']='pages/index/welcome';//掃碼時進(jìn)入小程序的頁面
$ewm_list['width']=215;//小程序碼的寬度和高度
$ewm_str = json_encode($ewm_list);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $ewm_str);
$data=curl_exec($ch);
curl_close($ch);
$ts=array();//提示信息
$data_str= json_decode($data,true);
if($data_str['errcode'])
{
//這個判斷一定要加,不然返回錯異常的時候,也會生成不可以用的小程序碼
$ts['user_zt']="300";
$ts['user_info']="生成二維碼異常";
echo json_encode($login_info);
exit();
}
else
{
$path = 'userfiles/ewm';//圖片本地保存路徑
if(!file_exists($path))
{
//檢查是否有該文件夾,如果沒有就創(chuàng)建,并給予權(quán)限
mkdir($path, 0700);
}
$path = $path.'/ewm_'.$id.'.jpg';
//保存到服務(wù)器
if(file_put_contents($path, $data))
{
/*
更新訂單中的小程序碼字段,這里略過
*/
}
else
{
$ts['user_zt']="300";
$ts['user_info']="生成二維碼異常";
echo json_encode($ts);
exit();
}
//保存到服務(wù)器
//生成小程序碼,返回給小小程序
$ts['ewmimg']=$system_url."/wx/".$path;
$ts['user_zt']="200";
echo json_encode($ts);
exit();
}
最后到小程序上的邏輯實(shí)現(xiàn),先看wxml關(guān)鍵代碼:
<view class="btn-pay" catchtap="showewm" data-id="{{item.id}}">核銷碼view>
<view class="ewm-box" hidden='{{ewmflag}}'>
<view class="ewm-img-box">
<image src="{{ewmimg}}" class="ewm-img">image>
view>
<view class="btn-list">
<view class="btn-close" bindtap="closeewm">
關(guān)閉
view>
view>
view>
<view class='mask' hidden='{{maskFlag}}'>view>
wxss代碼:
.btn-pay{
width: 160rpx;
border-radius: 30rpx;
height: 60rpx;
line-height: 60rpx;
text-align: center;
border: 1px solid #dadada;
margin-left: 20rpx;
}
.ewm-box{
width: 650rpx;
height: 700rpx;
position: fixed;
left: 50rpx;
top: 50%;
margin-top: -350rpx;
z-index: 9999;
background: #FFFFFF;
border-radius: 30rpx;
}
.ewm-img-box{
width: 430rpx;
height: 430rpx;
margin: 40rpx auto;
}
.ewm-img{
width: 430rpx;
height: 430rpx;
}
.btn-list {
position: absolute;
left: 0;
top: 550rpx;
display: flex;
justify-content: center;
width: 100%;
z-index: 99999;
}
.btn-close {
width: 30%;
height: 60rpx;
line-height: 60rpx;
text-align: center;
border-radius: 30rpx;
border: 1px solid #999;
color: #666;
}.mask {
position: fixed;
width: 100%;
height: 100%;
top: 0px;
background: rgba(0, 0, 0, 0.6);
overflow: hidden;
z-index: 9998;
}
微信JS代碼:
Page({
data: {
ewmflag:true,
maskFlag:true,
ewmimg:'',
},
showewm:function(e){
var id = e.currentTarget.dataset.id;
var that=this;
that.setData({
ewmflag:false,
maskFlag:false,
});
wx.showLoading({
title: '加載中',
});
wx.request({
url: '取小程序碼的服務(wù)器網(wǎng)頁地址',
data: {
id:id,
},
success: function (res) {
if (res.data['user_zt'] == '200') {
that.setData({
ewmimg: res.data['ewmimg'],
});
}
},
complete: function () {
wx.hideLoading();
}
});
},
closeewm:function(){
var that=this;
that.setData({
ewmflag:true,
maskFlag:true,
})
},
})
至止,關(guān)鍵部分的代碼實(shí)例已完成,當(dāng)然在實(shí)際場景中還需要添加各類事件的邏輯需要處理,非主要功能的邏輯代碼都刪除了。
在開發(fā)生成小程序這代碼部分,當(dāng)時出了點(diǎn)BUG,生成的圖片就是一個小方格圖標(biāo),排查了很久沒能找到原因,中途顯示器出現(xiàn)太熱出現(xiàn)少量花點(diǎn),休息了一下,等冷卻后再次重寫才見到小程序碼,所以那個生成小方格的迷到現(xiàn)在還不知道是什么原因造成。
最后開發(fā)時,如果還沒發(fā)布的小程序是不可以生成小程序的