博客班级 | https://edu.cnblogs.com/campus/zjcsxy/SE2020 |
作业要求 | https://edu.cnblogs.com/campus/zjcsxy/SE2020/homework/11334 |
作业目标 | 完成一个小程序,上传代码,完成一篇博文 |
作业源代码 | https://github.com/blank-hk1/WX-miniapps.git |
学号 | 31801149-何科 |
院系 | 浙大城院计算机系 |
项目描述: 本项目主要完成了一个类似于漂流瓶小程序的简易搭建,采用了微信云开发的数据库后台,实现了扔捡的功能。该项目主要包括了首页展示,漂流瓶扔,捡功能的简易实现,以及个人信息的展示。
项目页面展示
全局配置:
JSON文件(app.json):
{
"pages": [
"pages/index/index",//登录界面
"pages/zy/zy",//首页
"pages/write/write",//扔漂流瓶界面
"pages/mine/mine",//我的漂流瓶
"pages/get/get"//捡漂流瓶界面
],
"window": { //登录界面样式
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#26A5FF",
"navigationBarTitleText": "漂流瓶",
"navigationBarTextStyle": "black"
},
"style": "v2",
"sitemapLocation": "sitemap.json"
}
JS文件(app.js) :
//app.js App({ onLaunch: function () { // 展示本地存储能力 var logs = wx.getStorageSync(\'logs\') || [] logs.unshift(Date.now()) wx.setStorageSync(\'logs\', logs) // 登录 wx.login({ success: res => { // 发送 res.code 到后台换取 openId, sessionKey, unionId } }) // 获取用户信息 wx.getSetting({ success: res => { if (res.authSetting[\'scope.userInfo\']) { // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 wx.getUserInfo({ success: res => { // 可以将 res 发送给后台解码出 unionId this.globalData.userInfo = res.userInfo // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 if (this.userInfoReadyCallback) { this.userInfoReadyCallback(res) } } }) } } }) }, globalData: { //定义全局变量 userInfo: null, throw:0, get:0 } })
各页面代码:
首页
wxml文件:
<!--pages/zy/zy.wxml--> <view> <!--轮播图--> <swiper class=\'lunbo\' indicator-dots=\'true\' autoplay=\'true\' interval=\'4000\'> //利用swiper组件实现轮播动画 <swiper-item> <image src=\'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1602684860769&di=39fce0bf578183478d1a389ab76cea9d&imgtype=0&src=http%3A%2F%2Fdpic.tiankong.com%2Fdn%2F0m%2FQJ8477065702.jpg\'></image> </swiper-item> <swiper-item> <image src=\'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1602682402604&di=90242ef9939b6c7f72119f15485bd34c&imgtype=0&src=http%3A%2F%2Fimg1.juimg.com%2F160409%2F330800-16040911292961.jpg\'></image></swiper-item> <swiper-item> <image src=\'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1602682432669&di=01182e87ae641423b81226a767b6f6b4&imgtype=0&src=http%3A%2F%2Ffile03.16sucai.com%2F2017%2F1100%2F16sucai_P59201F287.JPG\'></image> </swiper-item> </swiper> </view> <view class="sj"> <text>截止目前, \n</text> <text> \n</text> <text>您已经扔了</text> <text>{{throwing}}</text>//全局变量,实时更改扔出数量 <text>个漂流瓶, \n</text> <text> \n</text> <text>您已经捡了{{geting}}个漂流瓶。 \n</text>//全局变量,实时更改捡到数量
</view> <view class="play-style"> <view class="leftstyle"> <image class="img" src="{{throwSrc}}" bindtap="throw"></image> <text>扔一个</text> </view> <view class="playstyle"> <image class="img" src="{{getSrc}}" bindtap="get"></image> <text>捡一个</text> </view> <view class="rightstyle"> <image class="img" src="{{mySrc}}" bindtap="mine"></image> <text>我的瓶子</text> </view> </view>
JS文件
// pages/zy/zy.js var app = getApp() Page({ data: { getSrc: "../../images/a.png",//捡一个 throwSrc: "../../images/b.png",//扔一个 mySrc: "../../images/c.png",//我的 throwing:0, geting:"" }, //捡一个 onShow:function(){ console.log(app.globalData.throw) this.setData({ throwing:app.globalData.throw, geting:app.globalData.get }) }, get: function () { console.log("捡一个") //随机去后台拉取一个录音 wx.navigateTo({ url: \'../get/get\', success: function (res) { // success }, fail: function () { // fail }, complete: function () { // complete } }) }, //扔一个 throw: function () { console.log("扔一个") wx.navigateTo({ url: \'../write/write\', success: function (res) { // success }, fail: function () { // fail }, complete: function () { // complete } }) }, //我的瓶子 mine: function () { console.log("我的瓶子") wx.navigateTo({ url: \'../mine/mine\', success: function (res) { // success }, fail: function () { // fail }, complete: function () { // complete } }) } })
在主页的界面中通过全局变量throw和get来实时更新主页的数据:
要调用全局变量,需要在js文件开头写上调用语句
var app=getApp();
之后再通过按钮的点击来改变全局变量的值,即可在主页显示
onShow:function(){ console.log(app.globalData.throw) this.setData({ throwing:app.globalData.throw, geting:app.globalData.get }) },
扔漂流瓶界面:
可以通过文字和语音输入漂流瓶文本,如果没有输入内容会弹出相关提示。
wxml文件:
<!--write.wxml--> <view class="weui-cells weui-cells_after-title"> <view class="weui-cell"> <view class="weui-cell__bd"> <textarea wx:if="{{!isInput}}" class="weui-textarea" placeholder="请输入文本" style="height: 16em;" bindblur="bindTextAreaBlur" /> </view> </view> </view> <view wx:if="{{isSpeaking}}" class="speak-style"> <image class="sound-style" src="../../images/voice_icon_speech_sound_1.png" ></image> <image wx:if="{{j==2}}" class="sound-style" src="../../images/voice_icon_speech_sound_2.png" ></image> <image wx:if="{{j==3}}" class="sound-style" src="../../images/voice_icon_speech_sound_3.png" ></image> <image wx:if="{{j==4}}" class="sound-style" src="../../images/voice_icon_speech_sound_4.png" ></image> <image wx:if="{{j==5}}"class="sound-style" src="../../images/voice_icon_speech_sound_5.png" ></image> </view> <image wx:if="{{bottle}}" class="bottle-style" animation="{{animationBottle}}" src="../../images/bottle.png" ></image> <view class="play-style"> <image style="margin:20rpx;height:80rpx;width:80rpx;" src="{{isInput?jp:ht}}" bindtap="inputSwitch"></image> <button class="btn-style" bindtouchstart="touchdown" bindtouchend="touchup" bindtap="throwBottle">{{isInput?"按住 说话":"扔出去"}}</button> </view>
JS文件:
//write.js //获取应用实例 var app = getApp() const db = wx.cloud.database({}) const cont = db.collection(\'hkcloud\') Page({ data: { jp: "../../images/jp.png", ht: "../../images/ht.png", isInput: true,//默认键盘输入 j: 1,//帧动画初始图片 isSpeaking: false,//是否正在说话 animationBottle: {},//扔出漂流瓶动画 bottle: false,//漂流瓶 contentInput: \'\',//内容 num:0 }, onLoad: function () { //在leancloud生成目录 // 声明类型 // var TodoFolder = AV.Object.extend(\'TodoFolder\'); // 新建对象 // var todoFolder = new TodoFolder(); // 设置名称 // todoFolder.set(\'name\', "文本漂流瓶"); // 设置优先级 // todoFolder.set(\'priority\', 1); // todoFolder.save().then(function (todo) { // console.log(\'objectId is \' + todo.id); // }, function (error) { // console.error(error); // }); }, onReady: function () { // 标题栏 wx.setNavigationBarTitle({ title: \'扔一个\' }) }, //切换话筒和键盘 inputSwitch: function () { this.setData({ isInput: !this.data.isInput }) }, //手指按下 touchdown: function () { var _this = this; //话筒的时候,点击按钮无效 if (!this.data.isInput) return this.data.contentInput console.log("new date : " + new Date) speaking.call(this); this.setData({ isSpeaking: true }) //开始录音 wx.startRecord({ success: function (res) { //临时路径,下次进入小程序时无法正常使用 var tempFilePath = res.tempFilePath console.log("tempFilePath: " + tempFilePath) //录音完成后直接上传,不再持久保存本地 //持久保存 //wx.saveFile({ // tempFilePath: tempFilePath, // success: function (res) { //持久路径 //本地文件存储的大小限制为 100M //var savedFilePath = res.savedFilePath //console.log("savedFilePath: " + savedFilePath) // } // }) wx.showToast({ title: \'恭喜!录音成功\', icon: \'success\', duration: 1000 }) }, fail: function (res) { //录音失败 wx.showModal({ title: \'提示\', content: \'录音的姿势不对!\', showCancel: false, success: function (res) { if (res.confirm) { console.log(\'用户点击确定\') return } } }) } }) }, //手指抬起 touchup: function () { //话筒的时候,点击按钮无效 if (!this.data.isInput) return console.log("手指抬起了...") clearInterval(this.timer) wx.stopRecord() //开发工具测试有效.真机不执行. throwBottleAnimation.call(this); this.setData({ isSpeaking: false, }) }, //扔出去 //获取多行输入框内容 bindTextAreaBlur: function (e) { //console.log(e.detail.value) this.setData({ contentInput: e.detail.value }); }, throwBottle: function () { let self = this; var _this = this; //键盘的时候,点击按钮无效 if (this.data.isInput) return //button获取焦点后,textarea才失去焦点,contentInput有值 setTimeout(function () { if (_this.data.contentInput == \'\') { wx.showModal({ title: \'提示\', content: \'请输入内容\', showCancel: false, success: function (res) { if (res.confirm) { console.log(\'用户点击确定\') } } }) return } else{ app.globalData.throw=app.globalData.throw+1, wx.showModal({ title: \'提示\', content: \'成功扔出漂流瓶!\', showCancel: false, success: function (res) { if (res.confirm) { console.log(\'用户点击确定\') console.log(self.data.contentInput) } } }) const db = wx.cloud.database({}); const cont = db.collection(\'Floating\'); //数据库集合名称为“Floating” db.collection("Floating").count() .then(async res=>{ let totals = res.total+1; //将totals赋值为数据库集合中记录数加一 cont.add({ //将写入的文本存入到数据库中,数据id+1 data:{ 数据内容: self.data.contentInput, 数据id:totals, } }) }) return } //将文本漂流瓶上传到leancloud // 执行 CQL 语句实现新增一个 TodoFolder 对象 //扔出漂流瓶动画 throwBottleAnimation.call(_this); }, 50) }, }) //麦克风帧动画 function speaking() { var _this = this; //话筒帧动画 var i = 1; this.timer = setInterval(function () { i++; i = i % 5; _this.setData({ j: i }) }, 200); } //扔出漂流瓶动画 function throwBottleAnimation() { this.setData({ bottle: true }) var animation = wx.createAnimation({ duration: 1500,//动画持续时间 }) // 旋转同时缩小 animation.translate(-150, -180).rotateZ(720).scale(0, 0).step() this.setData({ animationBottle: animation.export() }) }
首先通过以下代码获取到输入的文本信息,
bindTextAreaBlur: function (e) { //console.log(e.detail.value) this.setData({ contentInput: e.detail.value }); }
之后通过.add方法将读取到的文本存入到数据库中,为了之后能够随机取出漂流瓶,设置每一条记录的id值,该id值不会重复,递增(获取方法:通过.count读取集合中记录的数据个数,然后使其加一即是要加入的数据的id值)。
捡漂流瓶页面:
首先能否捡到漂流瓶通过随机函数random来决定,当产生的随机数大于5时,无法捡到,反之则可以捡到。
而当捡到漂流瓶时,通过得到一个在1~记录数之间的随机数来判断捡到的是第几个漂流瓶,并将该漂流瓶中的文本内容输出。
var num = Math.round(Math.random() * 9 + 1); var number; var that =this; //console.log(num); const db = wx.cloud.database({}); const cont = db.collection(\'Floating\'); if(num>5){ app.globalData.get=app.globalData.get+1, db.collection("Floating").count() .then(async res=>{ let totals = res.total; //记录总数 number= Math.round(Math.random() * totals + 1); //得到一个在1~totals之间的随机数 //console.log(number) db.collection("Floating").where({ //通过检索数据id得出捡到的是哪个漂流瓶 数据id:number, }).get({ success: function (res) { //console.log(res.data[0].数据内容) that.setData({ content:res.data[0].数据内容 //将漂流瓶的文本内容赋值给content }) } }) }) console.log(that.data.content) this.setData({ bgPng: this.data.getPngThrid, dl:this.data.dl1, content1:"漂流瓶上的内容是" }) }
var num = Math.round(Math.random() * 9 + 1);//利用随机函数得出的变量num,来判断是否能捡到漂流瓶 console.log(num); if(num>5){ /**wx.showModal({ title: \'提示\', content: \'未捡到漂流瓶\', showCancel: false, success: function (res) { if (res.confirm) { console.log(\'用户点击确定\') } } }) return**/ this.setData({ bgPng: this.data.getPngThrid, dl:this.data.dl1 })
wxml文件:
<view > <view> <image src="{{bgPng}}" class="back"></image> <view class="wb"> <text >{{dl}}</text> </view> </view> <button class="bind" style="width:750rpx" bindtap="getAnswer">{{motto}}</button> </view>
JS文件:
//get.js //获取应用实例 var app = getApp() Page({ data: { motto:"打捞漂流瓶", bgPng:"https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1699162582,1738986241&fm=26&gp=0.jpg", getPngSecond: "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1602692242325&di=c3cbad90b6a86eba9f22b3391bc63fdb&imgtype=0&src=http%3A%2F%2Fdpic.tiankong.com%2Fcp%2Fmh%2FQJ6226751079.jpg",//海星 getPngThrid: "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1699162582,1738986241&fm=26&gp=0.jpg",//漂流瓶 dl1:"成功捡到漂流瓶", dl2:"未能成功捡到漂流瓶", content:"请点击下方按钮", content1:"" }, onLoad: function () { var _this = this; //获取屏幕宽高 wx.getSystemInfo({ success: function (res) { } }) }, getAnswer: function (){ var num = Math.round(Math.random() * 9 + 1); var number; var that =this; //console.log(num); const db = wx.cloud.database({}); const cont = db.collection(\'Floating\'); if(num>5){ app.globalData.get=app.globalData.get+1, db.collection("Floating").count() .then(async res=>{ let totals = res.total; //记录总数 number= Math.round(Math.random() * totals + 1); //得到一个在1~totals之间的随机数 //console.log(number) db.collection("Floating").where({ //通过检索数据id得出捡到的是哪个漂流瓶 数据id:number, }).get({ success: function (res) { //console.log(res.data[0].数据内容) that.setData({ content:res.data[0].数据内容 //将漂流瓶的文本内容赋值给content }) } }) }) console.log(that.data.content) this.setData({ bgPng: this.data.getPngThrid, dl:this.data.dl1, content1:"漂流瓶上的内容是" }) } else{ this.setData({ bgPng: this.data.getPngSecond, dl:this.data.dl2, content:"", content1:"" }) } } })
我的漂流瓶界面:
利用wx:if判断是否读取到头像昵称,并显示相应的界面。
wxml文件:
<!--mine.wxml--> <view class="container"> <view class="userinfo"> <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button> <block wx:else> <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image> <text class="userinfo-nickname">{{userInfo.nickName}}</text> </block> </view> </view> <button class=
全部评论
请发表评论