2021SC@SDUSC
目录
本次分析主要分析page部分,小程序的每个页面都是独立的,每个页面都必须有page.js和page.wxhl文件,对于page.json和page.wxss来说则是非必须文件。
一.导航界面
index.wxml
对于该界面而言,index.wxml编写了页面的布局内容。
居于上方的图片使用了弹性居中布局,利用image添加图片,并且规定了图片的尺寸;下方与之相似,对于文字使用文本对齐等属性定义以使页面更美观,对于不同的文字利用text style定义了不同的尺寸和颜色;同时利用radio对单选框进行定义。
<view style="width: 86%; margin-left: 7%; margin-top: 40rpx; font-size: 30rpx;">
<radio value="agree" bindtap="radiotap"/>
阅读并同意特别提醒及<text style="color: #637f97;" bindtap="viewAgreement">《山东大学校园文件中转系统使用协议(暂行)》</text>
</view>
<button bindtap="useThisSystem" disabled="{{!agree}}" style="width:86%; margin-top: 40rpx; margin-bottom: 40rpx; background-color: #329cd8; color: snow;">进入文件中转系统</button>
</view>
该页面的index.wxss主要进行了背景图的定义。
button[disabled] {
background-color: #92ACD1 !important;
color: snow !important;
}
index.js
index.js用于管理页面的逻辑事件。
Page({
data: {
agree: false,
},
onLoad: function () {
},
useThisSystem: function() {
wx.setStorageSync('guided', true);
wx.redirectTo({
url: '../../index/index',
})
},
viewAgreement: function () {
console.log("attached guide show agreement.")
},
radiotap: function(e) {
if (!this.data.agree) {
this.setData({
agree: true,
})
}
},
})
data用于初始化数据,data将会以json的形式由逻辑层传至渲染层,所以其数据必须是可以转换成json的格式:字符串、数字、布尔值、对象、数组;onload是生命周期函数用于监听页面加载,一个页面只会调用一次;wx.setStorageSync用于进行缓存;wx.redirectTo用于关闭当前页面然后跳转到应用内的界面,即url所指的页面;radiotap用于点击单选框后点击button进入登陆界面。
二、登陆界面
index.wxml
index.wxml用于编写界面,与上部分的wxml相似,在两个<view>中间编写每一部分的界面,利用image引用图片;调用getUserInfo获取用户信息,用getPhoneNumber获取用户手机号,如果微信版本较低将不能获得用户信息以及手机号则会弹出提示窗口;利用bindtap对使用协议进行监听,利用CheckBox设置为agree默认单选框为选中状态,点击可查看详细内容。
<view class="section_space">
<button wx:if="{{canIGetPhoneNumber && phoneNum === null}}" open-type="getPhoneNumber" bindgetphonenumber="bindGetPhoneNumber" disabled="{{agree == false || userInfo === null}}" type="primary">登陆</button>
<view wx:elif="{{!canIGetPhoneNumber}}">当前微信版本无法获取个人信息,请升级微信版本</view>
<!-- <view wx:else>欢迎手机用户 {{phoneNum}}</view> -->
</view>
上方代码即为获取用户手机号。
<view class="section_space">
<checkbox value="cb" checked="{{agree}}" bindtap="changeAgree"/>
<text bindtap="showUseAgreement" style="text-decoration-line: underline; color: blue;">山大格子柜用户使用协议</text>
</view>
<view class="section_space" style="font-size: 24rpx; color: gray;">本程序会收集用户的昵称、手机号信息仅用于权限验证</view>
<view style="font-size: 24rpx; color: gray;">用户成功登陆后,方可使用山东大学校园格子柜。</view>
</view>
</view>
上方即为对单选框的默认确定以及登陆。
index.js
对于index.js首先获取应用实例,并且import了三个公共方法,将在后续进行分析。
const app = getApp()
import constUtil from '../../utils/constUtil'
import util from '../../utils/util'
import request from '../../utils/request'
然后同样在data进行初始化数据,Boolean wx.canIUser用于判断小程序的API,回调,参数,组件等是否在当前版本可用,初始化时用户信息以及用户电话都为null。
data: {
hasUserInfo: false,
userInfo: null,
canIGetUserInfo: wx.canIUse('button.open-type.getUserInfo'),
phoneNum: null,
canIGetPhoneNumber: wx.canIUse('button.open-type.getPhoneNumber'),
role: 0, // 用户角色
agree: true,
},
接下来是事件处理函数,分别定义了三个转到不同页面的函数,利用wx.navigateTo保留当前页面并跳转到url指定界面。例如地图位置界面。
goMapPage: function() {
wx.navigateTo({
url: '../map/index'
})
},
onload中定义加载页面时触发的功能函数,首先初始化userInfo,并且获取用户电话信息,并且调用一个自定义的函数judgeRoleAndRedrict用于向后台发送请求判断用户角色。
let that = this;
let userInfo = wx.getStorageSync('userInfo');
if (userInfo !== undefined && userInfo !== null && userInfo !== '') {
that.setData({
userInfo: userInfo,
})
}
let phone = wx.getStorageSync('phone');
console.log("phone number: " + phone);
if (phone !== undefined && phone !== '') {
that.setData({
phoneNum: phone,
})
this.judgeRoleAndRedrict(phone);
}
judgeRoleAndRedrict函数中进行拼接请求url,然后进行请求数据,调用wx.request请求https,如果成功则会显示成功的log,在进行数据缓冲之后跳转到首页。该部分是登录界面关键代码。
judgeRoleAndRedrict(phone) {
const url = constUtil.url + '/wechat/getRoleByPhoneNum?phone=' + phone;
var that = this;
util.showLoading('');
wx.request({
url: url,
data: {},
header: {
'content-type': 'json' // 默认值
},
success:function(res) {
console.log("-------获取个人信息成功--------")
console.log(res)
if (res.data.success) {
let roleInfo = res.data.result;
let userInfo = wx.getStorageSync('userInfo');
if (roleInfo.avatarurl !== userInfo.avatarurl) {
let param = {
phone: wx.getStorageSync('phone'),
name: userInfo.nickName,
avatarUrl: userInfo.avatarUrl,
}
request.request("/wechat/updateTeacherInfo", "GET", param, (data) => {
// on success
console.log("update userInfo success", param);
}, (data) => {
// on fail
console.log("update userInfo fail")
});
}
// 跳转至首页
wx.setStorageSync('role', roleInfo.type)
that.redrictByRole()
}
},
fail:function(res) {
console.log(res);
},
complete:function(res) {
util.hideLoading('');
},
})
},
自定义函数changeAgree用于根据复选框状态改变登录button的状态;同时自定义函数showUseAgreement用于展示用户使用协议,调用wx.showModal函数。
changeAgree() {
if (this.data.agree) {
this.setData({
agree: false,
})
} else {
this.setData({
agree: true,
})
}
},
bindGetPhoneNumber用于实现登录和获取手机号将jscode、encryptedData、iv发送到后台进行解密,利用wx.login调用接口获取登录凭证(code)。通过凭证进而换取用户登录态信息,包括用户在当前小程序的唯一标识(openid)、微信开放平台帐号下的唯一标识(unionid,若当前小程序已绑定到微信开放平台帐号)及本次登录的会话密钥(session_key)等。用户数据的加解密通讯需要依赖会话密钥完成;wx.request获得https请求。该部分同样是登功能的核心代码。
bindGetPhoneNumber: function(e) {
console.log("bindGetPhoneNumber");
console.log(e);
if (e.detail.encryptedData === undefined) {
wx.showToast({
title: '获取失败',
icon: 'none',
duration: 1000
})
return;
}
let that = this;
wx.login({
success (res) {
console.log("login success", res);
// that.setData({
// jscode: res.code,
// })
let jscode = res.code;
let encryptedData = e.detail.encryptedData;
let iv = e.detail.iv;
let param = {
jscode: jscode,
encryptedData: encryptedData,
iv: iv,
}
const url = constUtil.url + '/wechat/getPhone' // ?jscode=' + jscode + '&encryptedData=' + encryptedData + '&iv=' + iv;
console.log("url: " + url)
console.log("jscode: " + jscode)
console.log("encryptedData: " + encryptedData)
console.log("iv: " + iv)
wx.request({
url: url,
data: {
...param,
},
method: 'post',
header: {
'content-type': 'application/json' // 默认值
},
success:function(res) {
console.log("---------------")
console.log(res)
if (res.data.success) {
that.setData({
phoneNum: res.data.result.phone,
userId: res.data.result.id,
})
wx.setStorageSync('phone', res.data.result.phone);
wx.setStorageSync('userId', res.data.result.id);
that.redrictByRole(res.data.result.type);
} else {
wx.showToast({
title: '获取失败',
icon: 'none',
duration: 1000
})
}
},
fail:function(res) {
console.log(res);
},
})
}
})
},
总结
以上就是本篇博客主要分析内容,其中登录界面中index.js中的bindGetPhoneNumber以及judgeRoleAndRedrict是本篇分析中的核心代码。