一、实验目标
1、学习使用快速启动模板创建小程序的方法;2、学习不使用模板手动创建小程序的方法。
二、实验步骤
1、创建小程序并实现页面排版
首先,在微信开发者工具选择微信云开发创建新的微信小程序。
此次项目的编写在分类页面的页面布局、搜索页面的功能实现耗费功夫,因此着重分析以下两部分代码。
/*main.wxml 分类页面的页面布局*/ <!--miniprogram/pages/main/main.wxml--> <view class="view_main"> <image src="../../images/4.jpg" class="swiper_head" mode="widthFix"/> <view class="view_kindList"> <view class="view_kind" wx:for="{{kindList}}" wx:key="{{item.text}}"> <button class="button_kind" style="background:{{item.color}};" data-item="{{item}}" bindtap="doClick"> <image class="image_kind" src="{{item.imgPath}}" mode="aspectFit" /> {{item.text}} </button> </view> </view> <view class="view_info"> <view class="view_info_title"> ✤垃圾分类简易口诀: </view> <view class="view_info_txt"> • 能卖钱的蓝桶桶, 易腐烂的绿桶桶 </view> <view class="view_info_txt" style="margin-top:12rpx;"> • 有毒有害红桶桶, 没人要的灰桶桶 </view> </view> </view>
// search.js 搜索页面的逻辑实现 Page({ /** * 页面的初始数据 */ data: { //输入的内容 inputTxt: null, //热门搜索 hotSearchItems: [], //常用的分类 kindList: [], //搜索到的所有项目 searchItmes: [], //选择搜索到的项目 selectItem: {}, //扫描到的物品 scanItems: [], //百度Token baiduToken: null, //是否隐藏详细信息弹框 isHiddenInfoModal: true, isHiddenEditModal: true, //是否隐藏扫描物品的弹窗 isHiddenScanModal: true, //你的apisecret 你的apiKey apisecret : "qqUBXjBJzd6oGFMi8olYnGrUlNI7Hxok", apikey : "2TSelCPHfUJFoXnFSnbGNYS8" }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { this.setData({ kindList: getApp().globalData.kindList, }); this.onPullDownRefresh(); }, /** * 生命周期函数--监听页面显示 */ onShow: function () { this.setData({ inputTxt: null }); }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { var that = this; if (that.data.inputTxt) { wx.stopPullDownRefresh(); return; } that.setData({ hotSearchItems: [] }) //显示加载界面 wx.showLoading({ title: '加载中', }); this.getHotItems().then(res => { console.log("【热搜项目】", res) that.setData({ hotSearchItems: res.result.data }) wx.stopPullDownRefresh() //隐藏加载界面 wx.hideLoading(); }) }, //获取热门搜索 getHotItems: function () { var that = this; return new Promise(function (resolve, reject) { wx.cloud.callFunction({ name: 'getHotItems', success: resolve, fail: reject }) }) }, //获取输入的搜索内容 getInput: function (e) { if (e.detail.value == "") { this.setData({ inputTxt: null }) } else { this.setData({ inputTxt: e.detail.value }) } }, //点击搜索按钮 doClick: function (event) { var that = this; //判断输入的内容是否有效 if (that.data.inputTxt == null) { wx.showToast({ title: '请输入有效内容!!', icon: 'none', duration: 2000, mask: true }) return; } //清空历史搜索项 that.setData({ searchItmes: [] }) //显示加载界面 wx.showLoading({ title: '加载中', }); this.searchFunction().then((res) => { that.gettype().then((ress) =>{ console.log('[辣鸡类型]' , ress.result.data) let trash_type = {} for(let k in ress.result.data){ let v = ress.result.data[k]; trash_type[v.id] = v.name } for(let k in res.result.data){ let v = res.result.data[k]; res.result.data[k].type = trash_type[v.category] } console.log("【搜索数据】", res); that.setData({ searchItmes: res.result.data }) //隐藏加载界面 wx: wx.hideLoading(); console.log(res.result.data) if (res.result.data.length == 0) { wx.showToast({ title: '暂时搜索不到该选项, 我们会再接再厉的!!', icon: 'none', duration: 2000, mask: true }) } }) }) }, gettype:function(){ console.log("[获取类型]") var that = this; return new Promise(function(resolve, reject){ wx.cloud.callFunction({ name: 'type', data: { }, success: resolve, fail: reject }) }) }, //搜索动作 searchFunction: function () { console.log("【开始搜索】", this.data.inputTxt) var that = this; return new Promise(function (resolve, reject) { wx.cloud.callFunction({ name: 'search', data: { _txt: that.data.inputTxt }, success: resolve, fail: reject }) }) }, //选择项目 doClickItem: function (event) { console.log("【选择的项目】", event) var _type = event.currentTarget.dataset.type; var _name = event.currentTarget.dataset.name; var _id = event.currentTarget.id; console.log("【选择的ID】", _id) let text; for (var i = 0; i < this.data.kindList.length; i++) { if(_type == '可回收垃圾') { _type = '可回收物' } if(_type == '厨余垃圾') { _type = '湿垃圾' } if (this.data.kindList[i].text == _type) { //显示详细信息 var itemInfo = { _txt: _name, _type: this.data.kindList[i] } this.setData({ selectItem: itemInfo, isHiddenInfoModal: false }) console.log("【详细】", this.data.selectItem) return; } } }, //点击热门搜索 doClickHotItem: function (event) { console.log("【点击热门搜索】", event) this.setData({ inputTxt: event.currentTarget.dataset.name }) //开始搜索 this.doClick(null); }, //点击扫描按钮 doClickCamera: function () { var that = this; //复位扫描的项目 that.setData({ scanItems: null }) // //首先授权相机的使用 that.checkAuth().then(res => { console.log(res); }) //获取BaiduTaken if (!that.baiduToken) { that.getBaiduTaken(); } that.getImage().then(res => { console.log(res) var filePaht = res.tempFilePaths[0]; console.log("【获取图片地址】", filePaht) wx.getFileSystemManager().readFile({ filePath: filePaht, encoding: "base64", success: res => { console.log("【读取图片数据pass】", res.data) //扫描图片物品 that.scanImageInfo(res.data).then(res => { console.log("扫描图片物品", res) that.setData({ scanItems: res.data.result }) if (that.data.scanItems) { that.setData({ isHiddenScanModal: false }) } else { wx.showToast({ title: '很遗憾没有识别到物品哦!!', icon: 'none', duration: 2000, mask: true }) } }) }, fail: res => { console.log("【读取图片数据fail】", res) wx.showToast({ title: '读取图片数据fail', icon: 'none', duration: 2000, mask: true }) } }) }) }, //获取百度taken getBaiduTaken: function () { var that = this; const tokenUrl = `https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=${that.data.apikey}&client_secret=${that.data.apisecret}`; wx.request({ url: tokenUrl, method: 'POST', dataType: "json", header: { 'content-type': 'application/json; charset=UTF-8' }, success: function (res) { console.log("【getBaiduTaken提示pass】", res); that.setData({ baiduToken: res.data.access_token }) }, fail: function (res) { console.log("【getBaiduTaken提示fail】", res); } }) }, //获取本地图片 getImage: function () { var that = this; // 选择图片 return new Promise(function (resolve, reject) { wx.chooseImage({ count: 1, sizeType: ['compressed'], sourceType: ['album', 'camera'], success: resolve, fail: reject }) }) }, //拍照暂无使用 takeImage: function () { const ctx = wx.createCameraContext() return new Promise(function (resolve, reject) { ctx.takePhoto({ quality: 'high', success: (res) => { console.log("【拍照成功】", res) resolve(res) }, fail: res => { console.log("【拍照失败】", res) reject(res) } }) }) }, //判断是否已经授权 checkAuth: function () { return new Promise(function (resolve, reject) { wx.getSetting({ success: res => { if (!res.authSetting['scope.camera']) { wx.authorize({ scope: 'scope.camera', success: res => { console.log("用户同意授权") resolve(res) }, fail: res => { console.log("用户拒绝授权") wx.showToast({ title: '需要右上角设置中授权', icon: 'none', duration: 3000, mask: true }) reject(res) } }) } else { resolve(res) console.log("用户已经授权") } }, fail: reject }) }) }, //扫描图片中的数据 scanImageInfo: function (imageData) { var that = this; const detectUrl = `https://aip.baidubce.com/rest/2.0/image-classify/v2/advanced_general?access_token=${that.data.baiduToken}`; //显示加载界面 wx.showLoading({ title: '加载中', }); return new Promise(function (resolve, reject) { wx.request({ url: detectUrl, data: { image: imageData }, method: 'POST', dataType: "json", header: { 'content-type': 'application/x-www-form-urlencoded' }, success: resolve, fail: reject, complete: res => { //隐藏加载界面 wx.hideLoading() } }) }) }, //点击关闭弹窗详细信息 modal_hidden: function () { this.setData({ isHiddenInfoModal: true, isHiddenScanModal: true }) }, //点击扫描识别的项目 doClickScanItem: function (event) { this.setData({ isHiddenScanModal: true }) console.log("【选择的物品】", event.currentTarget.dataset.name) this.setData({ inputTxt: event.currentTarget.dataset.name }) //开始搜索 this.doClick(null); }, //点击扫描弹窗确定 scanModal_confirm: function (event) { this.setData({ isHiddenInfoModal: true, isHiddenScanModal: true }) } })
2、配置云开发环境
创建云开发环境。
显示以下页面则证明云开发环境创建成功,后续将用到环境ID:miniprogram-1gjqonrs88908a18填写到"miniprogram--app.js--line65env处"。
之后在百度云申请服务器并记录apikey与secretkey,用于接口api。
将API Key和Secret KEY分别填写到"miniprigram--pages--search--search.js--line30"和"miniprigram--pages--search--search.js--line29"。
3、云端部署
将cloudfunctions下的文件右击选择上传并部署:云端安装依赖(不上传node_modules),直到图标显示为如下绿色文件样式。
在云开发的数据库中新建trash和type两个集合,分别传入垃圾识别训练集的trash.json和type.json两个文件。完成后显示结果如下。
以上部署完毕。
三、程序运行结果
分类页:
用于垃圾分类宣传。
搜索页:
用于垃圾识别与搜索。
以保温杯为例,搜索后显示结果如下:
点击搜索结果,可见详细说明。
同时可利用扫描进行图片识别,但是由于图片识别接口调用问题,无法实现图片的识别。
我的页面:
可绑定我的微信。
四、问题总结与体会
首先遇到的问题是调用图片识别接口存在问题。由于使用免费的图片识别接口,对于我们所希望的识别功能无法实现,所以此处对于图片识别接口的实现存在问题。
由于是首次尝试云开发,导致很多步骤都不熟练,所以在操作的过程中存在很多疏忽,比如百度云api接口的实现、环境ID的引用都是通过教程一步步学习。但是现在已经基本了解开发过程,希望下次能够更加熟练地运用技能。
此次实验,是我对于云开发的首次尝试,从搭建云服务器到部署等一步一步获益匪浅,同时也对于js等语言进行了更深一步的练习,对于个人技能有了更进一步的长进。