《微信小程序案例11》改进案例5,使用egg服务器连接操作数据库交互前端实现案例5

一、回顾案例5

案例5连接:CSDN

案例5中我前端的数据都是写在js里面的data的,现在通过egg服务器来连接数据库,设计数据库表,来实现动态渲染微信小程序前端页面,为了节省时间精力,前端代码大都不改变,只需要把数据库获取的数据格式改编成js的data里面的数据格式即可。

二、egg服务器代码

 1、配置mysql数据库

egg服务器要下载mysql数据库的模块:npm i --save egg-mysql 

接着在config文件夹里面的config.default.js里面配置:

config.mysql = {
    client:{
      host:'localhost',
      port:"3306",
      user:"root",
      password:"123456",
      database:"sx"
    },
    app:true,
    agent:false
  }

2、创建接口

 3、在控制层中编写每一个接口函数

 4、在服务层中编写具体实现代码

 三、egg服务器具体代码

接口层

'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
// 接口,也就是前端请求的地址,请求的哪一个接口方法,就去调用
module.exports = app => {
  const { router, controller } = app;
  router.post('/',controller.home.index);
  router.post('/chat',controller.home.chat);
  router.post('/setUserInfo',controller.home.setUserInfo);
  router.post('/getUserinfo',controller.home.getUserinfo);
  router.post('/getCategory',controller.home.getCategory);
  router.post('/getProducts',controller.home.getProducts);
};

控制层

'use strict';

const Controller = require('egg').Controller;

class HomeController extends Controller {
  async index() {
    const { ctx } = this;
    ctx.body = 'hi, egg';//  ctx.body返回数据到前端
    
  }

  // 结合腾讯AI开发平台的智能对话,首先前端发送聊天内容后端服务器接收到后再通过InputText把聊天数据发送到腾讯服务器获取智能AI的回复聊天内容,再把该内容返回到前端
  async chat() {
    const { ctx } = this;
    //下面这段代码是腾讯AI开发平台生成的
    console.log(ctx.request.body);
    var myMsg = ctx.request.body.myMsg  //从前端接收到的数据
    // Depends on tencentcloud-sdk-nodejs version 4.0.3 or higher
    const tencentcloud = require("tencentcloud-sdk-nodejs"); 
    //该代码表示需要去下载tencentcloud-sdk-nodejs这个模块

    const TbpClient = tencentcloud.tbp.v20190627.Client;

    // 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密
    // 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
    const clientConfig = {
      credential: {
        secretId: "AKIDSkmY4LM8euue8MK2UgcIismQTHq9CzWn",
        secretKey: "3qMddNr55qMccNs76pIVR7XhaEclfIn2",
      },
      region: "",
      profile: {
        httpProfile: {
          endpoint: "tbp.tencentcloudapi.com",
        },
      },
    };

    // 实例化要请求产品的client对象,clientProfile是可选的
    const client = new TbpClient(clientConfig);
    const params = {
      "BotId": "c472c9ea-8edf-4486-a58d-560c5e14c814",
      "BotEnv": "dev",
      "TerminalId": "1447608208",
      "InputText": myMsg
      // 前端传过来的数据,再传给腾讯服务器,以获取智能AI回复的数据
    };
    // await是等待执行,等返回数据后再执行
    await client.TextProcess(params).then(
      (data) => {
        console.log(data);
        ctx.body = data;  //返回到前端的数据
      },
      (err) => {
        console.error("error", err);
      }
    );
    
  }

// 根据接口的方法来到这里,又去服务层调用index(),该方法里面是获取数据库数据的具体代码
  async getUserinfo() {
    const { ctx } = this;
    ctx.body = await ctx.service.home.index();
  }

  async setUserInfo() {
    const { ctx } = this;
    // console.log(ctx.request.body);
    var data = ctx.request.body
    ctx.body = await ctx.service.home.setUserInfo(data)
    // ctx.body = "hi body"
    // ctx.body = await ctx.service.home.setUserInfo();
  }

// 获取父级类别
  async getCategory() {
    const { ctx } = this;
    ctx.body = await ctx.service.home.getCategory();

  }

// 获取选中菜单产品内容
async getProducts() {
  const { ctx } = this;
  const order_id=ctx.request.body.order_id;//根据前端传来的order_id查询选中菜单的产品内容,
  console.log(order_id+"   前端传来的order_id");
  ctx.body = await ctx.service.home.getProducts(order_id);
}


}
module.exports = HomeController;

服务层

'use strict';

const Service = require('egg').Service;

class HomeService extends Service {
  async index() {
    const { app } = this;
    let res = await app.mysql.get("userinfo",{id:1})
     console.log(res);
    return res
  }

  // 获取父级类别
  async getCategory() {
    const { app } = this;
    // let res = await app.mysql.get("product_category",{parent_id:0})
    let res = await this.app.mysql.select('product_category', { // 搜索 post 表
      where: { parent_id: '0'}, // WHERE 条件
      columns: ['name','select','order_id']})// 要查询的表字段
     console.log(res);
    return res
  }

    // 获取选中菜单的产品内容
    async getProducts(order_id) {
      const { app } = this;

      // 由于数据从两个表获取,所以组合起来自定义返回数据类型
      const res={
        name:'',
        imgUrl:'',
        navigator:'',
        container:[]
      }
      let selectMenu = await this.app.mysql.select('product_category', { // 搜索 post 表
        where: { order_id: order_id}, // WHERE 条件
        columns: ['name','id','imgUrl']})// 要查询的表字段
        res.name=selectMenu[0].name;
        res.imgUrl=selectMenu[0].imgUrl;
      let id=selectMenu[0].id;  //获取选中菜单的id,接着根据这个父id寻找子菜单
      let navigator =  await this.app.mysql.select('product_category', { // 搜索 post 表
        where: { parent_id: id}, // WHERE 条件
        columns: ['name','id','select']})// 要查询的表字段
        for(let i=0;i<navigator.length;i++){
          const container={
            title:'',
            goods:[],
          }
          res.navigator=navigator;//把数据库获取的navigator导航数组赋值给res的navigator数组
          let navigator_item =  await this.app.mysql.select('product', { // 搜索 post 表
            where: { category_id: navigator[i].id}, // WHERE 条件
            columns: ['image','title','price']})// 要查询的表字段
            container.title=navigator[i].name;
            container.goods=navigator_item;
            res.container.push(container);
        }
        console.log(res);
      return res
    }


    async setUserInfo(data) {
      const { app } = this;
      var openid = await app.mysql.get('userinfo',{openid:data.openid});
      if(openid) {
        return {
          code:100
        }
      }else {
       var res =  await app.mysql.insert('userinfo',{name:data.name,hdsrc:data.hdSrc,openid:data.openid});
           if(res.affectedRows) {
            return {
              code:102
            }
           }
      }
      
    } 

}

module.exports = HomeService;

四、前端

wxml代码

<!--
    项目:仿小米Lite小程序的分类板块 
    时间:2022/09/17-18
 -->
<view class="parent">
  <!-- 左侧滚动区域 -->
  <scroll-view style="height:calc(100vh);width:25vw;" scroll-y>
    <view class="fa">
      <view class="son" wx:for="{{itemList}}"  bindtap="selected" data-id="{{item.order_id}}"><span class="{{item.select !=0 ? 'active' : ''}}">{{item.name}}</span></view>
    </view>
  </scroll-view>
  <!-- 右侧滚动区域 -->
  <scroll-view style="height:calc(100vh);width:75vw;" scroll-y scroll-into-view="{{ intoindex }}" bindscroll="scroll" class="right">
    <view class="fa" id="fa">
      <view style="text-align: center;">
        <image src="{{product.imgUrl}}" mode="aspectFit" style="height: 100px;width: 275px;"></image>
      </view>
      <!-- 右侧中间导航栏 -->
      <scroll-view style="height:36px; border-bottom: 1px solid #EBEBEB;" scroll-x class="{{navigator!=0 ? 'navigator':''}}">
        <view class="xiaoMiMeau">
          <view class="{{item.select !=0  ? 'XiaomiSelect' : ''}} " wx:for="{{product.navigator}}" bindtap="jumpToselect" data-id="{{index}}">{{item.name}}</view>
        </view>
      </scroll-view>
      <!-- 小板块 -->
      <view class="item" wx:for="{{product.container}}" id="text{{index}}">
        <view>
          <view class="XiaomiMIXTitle" >{{item.title}}</view>
          <view>
            <view class="xiaomiMixItem" wx:for="{{item.goods}}">
              <view class="xiaomiMixPic">
                <image src="{{item.image}}"></image>
              </view>
              <view class="xiaomiMixText">
                <view class="title">{{item.title}}</view>
                <view class="price">¥{{item.price}}起 </view>
              </view>
            </view>
          </view>
        </view>
      </view>
      <!-- 小板块结束 -->
    </view>   <!-- fa结束 -->
  </scroll-view>    <!-- 右侧滚动区域结束 -->
</view><!-- parent结束 -->

js代码

Page({
  /**
   * 页面的初始数据
   */
  selected:function(e){
    this.setData({
      intoindex: "fa"
    })
     //先把之前选中的变为0,只能循环遍历了
     for(var i=0;i<15;i++){
      var item=this.data.itemList[i]
      var flag=item.select
      if(flag) {
     var select = 'itemList['+i+'].select'
     this.setData({
       [select]:0
      })
      }
    }
     //获取wxml自定义数据data-id的值,点击事件会把当前选中的id传过来
     var id = e.currentTarget.dataset.id 
     var select = 'itemList['+id+'].select'
     this.setData({
       [select]:1
      })
      //获取当前选中的页面产品数据
      wx.request({
        url: 'http://127.0.0.1:7001/getProducts',
        method: 'POST',
        data:{
          order_id:id
        },
        success:(res)=>{
          this.setData({
          product:res.data
          })
          console.log(res.data)
        }
      })
  },

  jumpToselect: function (e) {
    //改变右侧滚动区域的scroll-into-view="{{ intoindex }}"的值
    console.log(e)
    this.setData({
      intoindex: "text" + e.currentTarget.dataset.id
    })
    // 改变导航的select值,当前选中的select由0改为1,而之前选中的由1改为0
    //先把之前选中的变为0,只能循环遍历了
    let navigator=this.data.product.navigator
    console.log(navigator)
    let length=this.data.product.navigator.length
    console.log(length)
    for(var i=0;i<length;i++){
      var item=navigator[i]
      var flag=item.select
      if(flag==1) {
    var select = 'product.navigator['+i+'].select'
    console.log("select:"+select)
    this.setData({
      [select]:0
      })
      console.log(navigator[0].select)
      }
    }
    //获取wxml自定义数据data-id的值,点击事件会把当前选中的id传过来
    var id = e.currentTarget.dataset.id 
    console.log("自定义数据前端传来:"+id)
    var select = 'product.navigator['+id+'].select'
    this.setData({
      [select]:1
      })
  },

  scroll(e) {
    console.log(e.detail.scrollTop)
    let scrollTop=e.detail.scrollTop
    if(scrollTop>100){
      this.setData({
        navigator:1
      })}
      else{
        this.setData({
          navigator:0
        })
      }
    },
  
  data: {
      navigator:0  //表示右侧中间导航栏在未滚动前的状态,滚动100距离后由0变为1
      } ,

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    wx.request({
      url: 'http://127.0.0.1:7001/getProducts',
      method: 'POST',
      data:{
        order_id:1
      },
      success:(res)=>{
        this.setData({
        product:res.data
        })
        console.log(res.data)
      }
    })
  },




  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {
    wx.request({
      url: 'http://127.0.0.1:7001/getCategory',
      method: 'POST',
      success:(res)=>{
        // console.log(res)
        this.setData({
          itemList:res.data
        })
        console.log(this.data.itemList)
      }
    })
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }

})
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值