(>>>>在公众号中输入彩蛋号,即可获取测试源码与视频讲解的下载地址)
一、实验目的
以Wafer Quick Start为例,掌握微信小程序的入门,特别是服务器端与小程序端之间的交互,实现登录、请求登录状态、上传图片、建立信道与CGI的功能。
二、实验内容
1、界面
2、实现登录、请求登录状态、上传图片、建立信道与CGI的功能。
三、小程序端与服务器端源代码分析
1、登录功能实现
1)小程序端代码
在client\pages\index\index.js中,代码示例如下:
//用户登录示例
login:function() {
if(this.data.logged)return
util.showBusy('正在登录')
varthat =this
//调用登录接口
qcloud.login({
success(result) {
if(result) {
util.showSuccess('登录成功')
that.setData({
userInfo: result,
logged:true
})
}else{
//如果不是首次登录,不会返回用户信息,请求用户信息接口获取
qcloud.request({
url:config.service.requestUrl,
login:true,
success(result) {
util.showSuccess('登录成功')
that.setData({
userInfo:result.data.data,
logged:true
})
},
fail(error) {
util.showModel('请求失败', error)
console.log('request fail', error)
}
})
}
},
fail(error) {
util.showModel('登录失败', error)
console.log('登录失败', error)
}
})
},
2)服务器端代码
在server\application\controllers\Login.php中,代码示例如下:
classLoginextendsCI_Controller {
publicfunctionindex() {
$result= LoginService::login();
if($result['loginState'] === Constants::S_AUTH) {
$this->json([
'code'=>0,
'data'=>$result['userinfo']
]);
}else{
$this->json([
'code'=> -1,
'error'=>$result['error']
]);
}
}
}
2、请求登录状态
1)小程序端代码
在client\pages\index\index.js中,代码示例如下:
//切换是否带有登录态
switchRequestMode:function(e) {
this.setData({
takeSession: e.detail.value
})
this.doRequest()
},
doRequest:function() {
util.showBusy('请求中...')
varthat =this
varoptions = {
url: config.service.requestUrl,
login:true,
success (result) {
util.showSuccess('请求成功完成')
console.log('request success', result)
that.setData({
requestResult:JSON.stringify(result.data)
})
},
fail (error) {
util.showModel('请求失败', error);
console.log('request fail', error);
}
}
if(this.data.takeSession) {//使用qcloud.request带登录态登录
qcloud.request(options)
}else{//使用wx.request则不带登录态
wx.request(options)
}
},
2)服务器端代码
在server\application\controllers\User.php中,代码示例如下:
classUserextendsCI_Controller {
publicfunctionindex() {
$result= LoginService::check();
if($result['loginState'] === Constants::S_AUTH) {
$this->json([
'code'=>0,
'data'=>$result['userinfo']
]);
}else{
$this->json([
'code'=> -1,
'data'=> []
]);
}
}
}
3、上传图片
1)小程序端代码
在client\pages\index\index.js中,代码示例如下:
//上传图片接口
doUpload:function() {
varthat =this
//选择图片
wx.chooseImage({
count:1,
sizeType: ['compressed'],
sourceType: ['album','camera'],
success:function(res){
util.showBusy('正在上传')
varfilePath = res.tempFilePaths[0]
//上传图片
wx.uploadFile({
url: config.service.uploadUrl,
filePath: filePath,
name:'file',
success:function(res){
util.showSuccess('上传图片成功')
res =JSON.parse(res.data)
that.setData({
imgUrl:res.data.imgUrl
})
},
fail:function(e) {
util.showModel('上传图片失败')
}
})
},
fail:function(e) {
console.error(e)
}
})
},
//预览图片
previewImg:function() {
wx.previewImage({
current:this.data.imgUrl,
urls: [this.data.imgUrl]
})
},
2)服务器端代码
在server\application\controllers\Upload.php中,代码示例如下:
classUploadextendsCI_Controller {
publicfunctionindex() {
//处理文件上传
$file=$_FILES['file'];//去除field值为file的文件
ini_set('upload_max_filesize','10M');
ini_set('post_max_size','10M');
//限制文件格式,支持图片上传
if($file['type'] !=='image/jpeg'&&$file['type'] !=='image/png') {
$this->json([
'code'=>1,
'data'=>'不支持的上传图片类型:'.$file['type']
]);
return;
}
//限制文件大小:5M以内
if($file['size'] >5*1024*1024) {
$this->json([
'code'=>1,
'data'=>'上传图片过大,仅支持5M以内的图片上传'
]);
return;
}
$cosClient= Cos::getInstance();
$cosConfig= Conf::getCos();
$bucketName=$cosConfig['fileBucket'];
$folderName=$cosConfig['uploadFolder'];
try{
/**
*列出bucket列表
*检查要上传的bucket有没有创建
*若没有则创建
*/
$bucketsDetail=$cosClient->listBuckets()->toArray()['Buckets'];
$bucketNames= [];
foreach($bucketsDetailas$bucket) {
array_push($bucketNames, explode('-',$bucket['Name'])[0]);
}
//若不存在bucket就创建bucket
if(count($bucketNames) ===0|| !in_array($bucketName,$bucketNames)) {
$cosClient->createBucket([
'Bucket'=>$bucketName,
'ACL'=>'public-read'
])->toArray();
}
//上传文件
$fileFolder=$folderName?$folderName.'/':'';
$fileKey=$fileFolder. md5(mt_rand()) .'-'.$file['name'];
$uploadStatus=$cosClient->upload(
$bucketName,
$fileKey,
file_get_contents($file['tmp_name'])
)->toArray();
$this->json([
'code'=>0,
'data'=> [
'imgUrl'=>$uploadStatus['ObjectURL'],
'size'=>$file['size'],
'mimeType'=>$file['type'],
'name'=>$fileKey
]
]);
}catch(Exception$e) {
$this->json([
'code'=>1,
'error'=>$e->__toString()
]);
}
}
}
4、建立信道
1)小程序端代码
在client\pages\index\index.js中,代码示例如下:
//切换信道的按钮
switchChange:function(e) {
varchecked = e.detail.value
if(checked) {
this.openTunnel()
}else{
this.closeTunnel()
}
},
openTunnel:function() {
util.showBusy('信道连接中...')
//创建信道,需要给定后台服务地址
vartunnel =this.tunnel =newqcloud.Tunnel(config.service.tunnelUrl)
//监听信道内置消息,包括connect/close/reconnecting/reconnect/error
tunnel.on('connect', () => {
util.showSuccess('信道已连接')
console.log('WebSocket信道已连接')
this.setData({ tunnelStatus:'connected'})
})
tunnel.on('close', () => {
util.showSuccess('信道已断开')
console.log('WebSocket信道已断开')
this.setData({ tunnelStatus:'closed'})
})
tunnel.on('reconnecting', () => {
console.log('WebSocket信道正在重连...')
util.showBusy('正在重连')
})
tunnel.on('reconnect', () => {
console.log('WebSocket信道重连成功')
util.showSuccess('重连成功')
})
tunnel.on('error', error => {
util.showModel('信道发生错误', error)
console.error('信道发生错误:', error)
})
//监听自定义消息(服务器进行推送)
tunnel.on('speak', speak => {
util.showModel('信道消息', speak)
console.log('收到说话消息:', speak)
})
//打开信道
tunnel.open()
this.setData({ tunnelStatus:'connecting'})
},
/**
*点击「关闭信道」按钮,关闭已经打开的信道
*/
closeTunnel() {
if(this.tunnel) {
this.tunnel.close();
}
util.showBusy('信道连接中...')
this.setData({ tunnelStatus:'closed'})
}
2)服务器端代码
在server\application\controllers\Tunnel.php中,代码示例如下:
classTunnelextendsCI_Controller {
publicfunctionindex() {
if($_SERVER['REQUEST_METHOD'] ==='GET') {
$result= LoginService::check();
if($result['loginState'] === Constants::S_AUTH) {
$handler=newChatTunnelHandler($result['userinfo']);
TunnelService::handle($handler,array('checkLogin'=> TRUE));
}else{
$this->json([
'code'=> -1,
'data'=> []
]);
}
}else{
$handler=newChatTunnelHandler([]);
TunnelService::handle($handler,array('checkLogin'=> FALSE));
}
}
}
5、建立CGI的功能
1)小程序端代码
在client\pages\addCgi\addCgi.js中,代码示例如下:
Page({
data: {
requestResult:'',
canIUseClipboard: wx.canIUse('setClipboardData')
},
testCgi:function() {
util.showBusy('请求中...')
varthat =this
qcloud.request({
url:`${config.service.host}/weapp/demo`,
login:false,
success (result) {
util.showSuccess('请求成功完成')
that.setData({
requestResult:JSON.stringify(result.data)
})
},
fail (error) {
util.showModel('请求失败', error);
console.log('request fail', error);
}
})
},
copyCode:function(e) {
varcodeId = e.target.dataset.codeId
wx.setClipboardData({
data: code[codeId -1],
success:function() {
util.showSuccess('复制成功')
}
})
}
})
varcode = [
]
2)服务器端代码
在server\application\controllers\Demo.php中,代码示例如下:
classDemoextendsCI_Controller {
publicfunctionindex() {
$this->json([
'code'=>0,
'data'=> [
'msg'=>'Hello World'
]
]);
}
publicfunctionhello(){
echo'My first Php Framework!';
}
publicfunctionsaysomething() {
//echo
'saysomething!';
$this->load->database('cAuth');
//$this->load->model('fans');
echo'saysomething!';
//$info = $this->test_model->get_test_data();
//echo $info;
}
}
四、源代码下载及视频解析
在“豆豆咨询”公众号里,输入彩蛋号即可获得下载地址:
[if !supportLists]1、[endif]源代码下载的彩蛋号(免费):6000;
[if !supportLists]2、[endif]视频讲解下载的彩蛋号(免费):60001;
五、技术服务
如果有疑问或者需要帮助,请加入QQ群(群名称:豆豆咨询,群号:625686304);或者公众号douAsk,公众号名称为“豆豆咨询”。扫描以下二维码,关注“豆豆咨询”。
技术QQ群名称:豆豆咨询,群号:625686304
微信公众号名称:豆豆咨询,微信公众号:douAsk
如果觉得有用,请动动手指,分享该文章!