书接上回,建好了数据库,能正常使用php后,这一章我们来讲一讲小程序端的操作
php的查询openid和返回数据功能应该在下一期(吧!
预计目标:用户点击登录后,判断该用户【未提交数据/已经提交数据/有多条数据(这种情况应该是不被允许的!)】,在填充完数据后,点击“提交”按钮,完成数据库的增改。
若该用户在数据库中已有数据,则应自动将数据库中保存信息更新至小程序端
.js文件(部分)
submit_to_php: function(e){
var that = this;
//读取数据库
wx.request({
// url: 'http://localhost/test/write.php?open_id=aa&nick_name=d&university=3&hobby=dd&gender=1',
url: 'http://localhost/test/write.php',
data: {
open_id: that.data.myOpenid,
nick_name: that.data.nick_name,
university: that.data.schoolindex,
hobby: that.data.hobby,
gender: that.data.gender
},
method: 'GET',
header: { 'content-type': 'application/json' },
success(res) {
console.log("读取数据库结果为 " + res.data);
if(res.data==0)
{
wx.showToast({
title: '出问题兄弟',
icon: 'error',
duration: 1500
});
}
if(res.data==1) // 需要先echo状态码 与write.php对应
{
wx.showToast({
title: '提交成功了',
icon: 'success',
duration: 1500
});
}
},
fail(err) {
console.info("获取用户openId失败");
console.log("读取数据库结果为:");
console.log(err)
}
})
},
若能连接到数据库,小程序端应该可以返回’1’,并且数据库应该会增加一条数据
不过如果不调整编码格式的话,数据会是一串乱码
如何调整编码格式?教程太多了自己翻翻吧但是记得调整完重启mysql服务!
数据库编码中 utf8 格式一个中文字占3个varchar❗
理论上这个时候就能实现本地数据库增删查改等功能了
我们查openid是紧跟在获取openid的那个wx.login后面的,js文件request请求需要时间,当进行到"查询openid"步骤时,**openid信息还没保存好!**此时的openid为空,再去访问会出问题!
这时候年薪百万的程序员会说 :
我说:
wx.showToast({
title: '请稍等',
icon: 'loading',
duration: 2000
});
这招没能打败js的同步机制
于是乎花了大半天的时间找关于js同步异步机制的教程
promise、async、await
直接说结果吧(我也不懂)
需要等待完成
对需要异步的函数操作
e.g
原函数
fun1(){
wx.request({
url: 'http://www.baidu.com',
success(res){
setTimeout(() => {
console.log('执行了fun1')
}, 3000);
}
})
}
修改后
fun1(){
return new Promise((resolve,reject)=>{
wx.request({
url: 'http://www.baidu.com',
success(res){
setTimeout(() => {
console.log('执行了fun1')
resolve(res) // 似乎一定要添加这个返回值
}, 3000);
}
})
})
}
修改部分:
await this.func1();
或者
let result = await this.func1();
获取这一步信息,并在该语句上级函数中加上async
如:
async fun(){
await this.func1();
}
或者
success:async function () {
await this.func1();
},
没什么解释的 上代码!
<view class="container" style="--customBar--:{{customBar}}">
<view class='login'>
<view>
<image src='{{profile_img}}' class='pic' mode="aspectFit">image>
view>
<view class="info">
<view wx:if="{{hasUserInfo == false}}">
<button bindtap='getMyProfile'>获取头像和昵称button>
view>
<view wx:else>
<text class="nickname">{{wx_name}}text>
view>
view>
view>
view>
<view>
<view>请在下方修改昵称({{nick_name}})
view>
<input class="input_class" maxlength="15" type="number" bindinput="input_nick" placeholder="{{nick_name}}"/>
view>
<view class="section">
<view class="section__title">请选择你的学校view>
<picker bindchange="bindchangeSchool" value="{{schoolindex}}" range="{{schoolarray}}">
<view class="picker">
当前选择:{{schoolarray[schoolindex]}}
view>
picker>
view>
<view wx:if="{{user_mysql_status==0}}">
<button disabled='true' type='default' class='btn'>提交前请登录button>
view>
<view wx:elif="{{user_mysql_status==1}}">
<button type='primary' class='btn' bindtap="submit_to_php">提交到数据库button>
view>
<view wx:elif="{{user_mysql_status==2}}">
<button type='primary' class='btn1' bindtap="update_to_php">更新数据库button>
<button type='warn' class='btn1' bindtap="delete_to_php">删除已有信息button>
view>
<view wx:else>
<button disabled='true' type='primary' class='btn'>出问题辣!!button>
view>
<button type='default' class='btn' bindtap="goto_common">回到正常界面button>
不想挑选 可能有漏的 可能有缺的 flex学的不好不献丑了
.login{
height: 100%;
width: 750rpx;
display: flex; /*flex布局方法*/
flex-direction: column;
justify-content: space-between;/*垂直方向分散布局*/
align-items: center;
border: 6rpx solid grey;
background-color: white;
}
.info{
/* width: 256rpx; */
height: 90%;
}
.nickname{
padding-top: 200rpx;
}
.pic {
width: 180rpx;
height: 180rpx;
margin: 20rpx;
border-radius: 50%;
}
.pic_btn {
width: 80rpx;
height: 80rpx;
}
.input_class{
border: 6rpx solid goldenrod;
}
.btn1{
/* border: 20rpx; */
margin: 12rpx;
}
.section{
width: 80%;
border: 6rpx solid blueviolet;
}
// pages/my/my.js
const app = getApp()
Page({
/**
* 页面的初始数据
*/
data: {
myOpenid: "",
have_changed_school:0,
wx_name:'一开始都叫张三',
nick_name:'一开始都叫张三',
profile_img:'/images/default/nick.png',
schoolindex: 0,
schoolarray: ['清华', '北大', '复交', '其他'],
gender: 0,
hobby: "sleep",
user_mysql_status: 0
//0:未登录 1:未提交 2:已提交 3:异常(openid过多)
},
// 跳转至好友列表页
goto_common: function(e){
// wx.navigateTo({
// url: "./my/my"
// })
wx.switchTab({
url: './my/my',
})
},
// 用于函数内部的函数,不应该被直接调用
// 用于已经有数据时,将数据更新到小程序端
update_info(){
var that = this;
wx.request({//通常获取openid需要从后端获取,因为appid 和 secret最好不要在前端展示
url: 'http://localhost/test/read.php',//如果未勾选 不校验合法域名会报错 请在小程序开发工具,右上角点击详情,的本地设置
data: {
open_id: that.data.myOpenid,
},
method: 'GET',
header: { 'content-type': 'application/json' },
success: function (res) {
console.log("读取用户数据库, 读取到" + res.data.length + "条消息")
console.log(res.data[0])
that.setData({
nick_name: res.data[0].nick_name,
schoolindex: res.data[0].university,
myOpenid: res.data[0].open_id,
gender: res.data[0].gender,
hobby: res.data[0].hobby
})
},
fail: function (error) {
console.info("获取用户mysql状态失败");
console.info(error);
}
})
},
// 用于函数内部的函数,不应该被直接调用
// 用于已经有数据时,将数据从数据库中删除
delete_info(){
var that = this;
return new Promise((resolve,reject)=>{
// console.log("进入check_mysql, 用户openid为" + that.data.myOpenid);
// 查询该用户是否已经填充数据
wx.request({//通常获取openid需要从后端获取,因为appid 和 secret最好不要在前端展示
url: 'http://localhost/test/delete.php',//如果未勾选 不校验合法域名会报错 请在小程序开发工具,右上角点击详情,的本地设置
data: {
open_id: that.data.myOpenid,
},
method: 'GET',
header: { 'content-type': 'application/json' },
success: function (res) {
wx.showToast({
title: '删除成功了',
icon: 'success',
duration: 1500
});
that.setData({
nick_name: '一开始都叫张三',
schoolindex: 0,
})
resolve({msg:'请求成功',data:'200'})
},
fail: function (error) {
wx.showToast({
title: '出问题兄弟',
icon: 'error',
duration: 1500
});
reject('check_mysql请求失败')
}
})
})
},
// 用于函数内部的函数,不应该被直接调用
// 用于检测当前openid在数据库内的数据数,并更新状态码
check_mysql(){
var that = this;
return new Promise((resolve,reject)=>{
// console.log("进入check_mysql, 用户openid为" + that.data.myOpenid);
// 查询该用户是否已经填充数据
wx.request({//通常获取openid需要从后端获取,因为appid 和 secret最好不要在前端展示
url: 'http://localhost/test/find.php',//如果未勾选 不校验合法域名会报错 请在小程序开发工具,右上角点击详情,的本地设置
data: {
open_id: that.data.myOpenid,
},
method: 'GET',
header: { 'content-type': 'application/json' },
success: function (res) {
console.log('当前数据库查询结果状态为:' + res.data.info + "状态码:" + res.data.status);
that.setData({
user_mysql_status: res.data.status
})
resolve({msg:'请求成功',data:'200'})
},
fail: function (error) {
console.info("获取用户mysql状态失败");
console.info(error);
reject('check_mysql请求失败')
}
})
})
},
// 用于函数内部的函数,不应该被直接调用
get_openid(){
var that = this;
return new Promise((resolve,reject)=>{
wx.login({
success: function (res) {
// console.log('code为————' + res.code)
if (res.code) {
//通过code 换取openid--开始
wx.request({//通常获取openid需要从后端获取,因为appid 和 secret最好不要在前端展示
url: '此处马赛克',//如果未勾选 不校验合法域名会报错 请在小程序开发工具,右上角点击详情,的本地设置
data: {
js_code: res.code
},
method: 'GET',
header: { 'content-type': 'application/json' },
success: function (openIdRes) {
that.setData({
myOpenid: openIdRes.data.openid
})
resolve({msg:'请求成功',data:'200'})
},
fail: function (error) {
console.info("获取用户openId失败");
console.info(error);
reject('check_mysql请求失败')
}
})
//通过code 换取openid--结束
}
}
})
})
},
getMyProfile(e) {
var that=this;
// 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认
// 开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
wx.getUserProfile({
desc: '用于完善成员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
success:async function (res){
// "美化界面(反正是同步操作 不影响)"
wx.showToast({
title: '请稍等',
icon: 'loading',
duration: 500
});
// 进行异步操作
await that.get_openid();
// 为了下面的if 这里也要进行异步
await that.check_mysql();
if(that.data.user_mysql_status == 2){
that.update_info()
}
let info = res.userInfo
console.log(res.userInfo);
that.setData({
wx_name: info.nickName,
hasUserInfo: true,
profile_img: info.avatarUrl,
gender: info.gender
})
}
})
},
input_nick: function(e){
this.setData({
nick_name: e.detail.value
})
},
bindchangeSchool: function(e){
this.setData({
schoolindex: e.detail.value
})
},
delete_to_php:async function(e){
// 异步处理 删除信息
await this.delete_info();
this.check_mysql(); // 每次提交无论成功失败都要更新状态
},
update_to_php: function(e){
var that = this;
//读取数据库
wx.request({
// url: 'http://localhost/test/write.php?open_id=aa&nick_name=d&university=3&hobby=dd&gender=1',
url: 'http://localhost/test/update.php',
data: {
open_id: that.data.myOpenid,
nick_name: that.data.nick_name,
university: that.data.schoolindex,
hobby: that.data.hobby,
gender: that.data.gender
},
method: 'GET',
header: { 'content-type': 'application/json' },
success(res) {
if(res.data == 0){
wx.showToast({
title: '出问题兄弟',
icon: 'error',
duration: 1500
});
}
if(res.data == 1){
wx.showToast({
title: '更新成功了',
icon: 'success',
duration: 1500
});
}
that.check_mysql(); // 每次提交无论成功失败都要更新状态
},
fail(err) {
console.info("获取用户openId失败");
console.log("读取数据库结果为:");
console.log(err)
}
})
},
submit_to_php: function(e){
var that = this;
//读取数据库
wx.request({
// url: 'http://localhost/test/write.php?open_id=aa&nick_name=d&university=3&hobby=dd&gender=1',
url: 'http://localhost/test/write.php',
data: {
open_id: that.data.myOpenid,
nick_name: that.data.nick_name,
university: that.data.schoolindex,
hobby: that.data.hobby,
gender: that.data.gender
},
method: 'GET',
header: { 'content-type': 'application/json' },
success(res) {
// console.log("读取数据库结果为: " + res.data);
if(res.data == 0){
wx.showToast({
title: '出问题兄弟',
icon: 'error',
duration: 1500
});
}
if(res.data == 1){
wx.showToast({
title: '提交成功了',
icon: 'success',
duration: 1500
});
}
that.check_mysql(); // 每次提交无论成功失败都要更新状态
},
fail(err) {
console.info("获取用户openId失败");
console.info("读取数据库结果为:");
console.log(err)
}
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.setData({
hasUserInfo: false
})
console.log('this.data.hasUserInfo = ' + this.data.hasUserInfo)
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
})