微信小程序+nginx+php+mysql实现数据库管理【第二期】小程序端的操作

书接上回,建好了数据库,能正常使用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服务!

⚠️⚠️tips

数据库编码中 utf8 格式一个中文字占3个varchar


理论上这个时候就能实现本地数据库增删查改等功能了

燃🔥鹅🦢

我们查openid是紧跟在获取openid的那个wx.login后面的,js文件request请求需要时间,当进行到"查询openid"步骤时,**openid信息还没保存好!**此时的openid为空,再去访问会出问题!
这时候年薪百万的程序员会说 :

“我让他sleep几秒不就好了?”

我说:

“要不我用一种巧妙而不失美观的方法装饰一下?”

wx.showToast({  
                title: '请稍等',  
                icon: 'loading',  
                duration: 2000  
                });  

在这里插入图片描述

没用(废话,,,

这招没能打败js的同步机制🤨
于是乎花了大半天的时间找关于js同步异步机制的教程
https://www.runoob.com/wp-content/uploads/2020/07/async-sync.png

解决方案:

promise、async、await
直接说结果吧(我也不懂)
需要等待完成

Promise部分

对需要异步的函数操作
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);
       }
     })
   })
 }

修改部分:

  • return new Promise…(resolve,reject可以自定义,但常为这两个值)
  • resolve(res)相当于"return res",resolve表示成功,reject表示失败

async和await部分

  • await
    在需要异步的函数前加上await
await this.func1();

或者

let result = await this.func1();

获取这一步信息,并在该语句上级函数中加上async
如:

async fun(){
    await this.func1();
}

或者

success:async function () {
 	await this.func1();
                       },
  • 至于我是怎么找到这个问题的?
    – 我在每次查询openid前,打印了openid,然后发现,登陆后的查询时,openid无输出,而登录后才有的openid的输出
    在这里插入图片描述
    修改后
    在这里插入图片描述

小程序部分代码

没什么解释的 上代码!

部分效果展示

在这里插入图片描述

wxml代码(绝大部分)

<!-- 最上方头像显示 -->
    <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>  

wxss代码(应该全了把)

不想挑选 可能有漏的 可能有缺的 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;
}

js代码

// 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 () {

    },
})

整体功能如下

在这里插入图片描述

在这里插入图片描述

祝大🔥都成功!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值