我用了九个小时给高中同学写了一款留言板!

2,375 阅读9分钟

我正在参加「创意开发 投稿大赛」详情请看:掘金创意开发大赛来了!

前言

        三月的时候,一位高中同学找到海轰,说可以帮忙写个留言小程序吗?说实话,这个留言板没有接触过,抱着试一试的心态,答应了同学。【其实心里还是没有底 毕竟没有做过 而且网课比较多】 在这里插入图片描述 在这里插入图片描述

        2018年3月后申请的公众号是没有用户留言功能的,但是没有留言功能的公众号号感觉没有了灵魂。

        如果想让之后的公众号拥有留言功能,其实也是有方法的。大体有两种:

  1. 迁移账号
  2. 小程序内嵌留言模块

        想着自己有个小程序:***,反正也不咋用,不如添加一个留言板,这样同学还不用再申请账号,还省钱。【云开发免费版足够了】

成果展示

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

提出需求

  1. 用户可以对文章进行留言,发表观点
  2. 作者对留言进行审核:通过的留言,所有用户才可见
  3. 作者可以对留言进行回复
  4. 作者对所有留言进行管理,可以进行删除、审核等操作

开发过程分析

  • 先做一个基础留言板,实现基本的留言功能即可,主要是验证是否可以上线,是否可以应用在公众号中(一次性做完所有功能,怕审核不过或公众号不支持,就太浪费时间了)
  • 基础功能实现其验证其可以在公众号中使用,继续下一步开发,添加其余功能
  • 功能大体开发完毕后,便可以进行真机测试了,检查bug。

留言板实现思路

        鉴于留言板使用频率较低和同一时刻使用人数较少,基础的 云开发 足以胜任。每一篇文章都有可能产生留言,用一条记录表示;一篇文章产生的留言为0条或者多条,用数组存储。又一篇公众号可能不会产生留言,如果作者创建一篇文章留言板系统就创建一天该文章的记录,那么一定会有很大的资源浪费,毕竟我们还是希望数据库中存储的东西需要存在一定的价值。为此,这里海轰给出的思路是,作者为每一篇文章创建留言板时,只是提供小程序页面启动参数,数据库中并不产生该文章记录。只有当第一个用户在该文章产生留言时,则在数据库中添加该文章的记录,而当第二个用户(之后的所有用户)产生留言时,就只需要在原记录上面更新即可。         对于作者回复功能,这里就需要多考虑一点:每个用户都是使用同一个界面,但是我们只需要作者进行留言回复,而普通用户则不可以进行留言。所有,我们需要判断点击事件的发生者是否为作者?这里解决方法也很简单:利用用户的openid标记每一个用户,而页面的启动参数中,我们只需要添加一项为作者的openid,然后继续比对即可。对于回复,这里可以简单的理解为对原留言记录进行更新即可。同样,这个原理也可以用于留言管理,使得管理员可以进行删除等操作         留言审核,这里海轰的解决方法时,对每一条留言进行flag标记,比如flag=true时,表示审核通过;flag=flase,表示不通过。显示留言时,根据flag进行筛选即可

编程第一小时

  • 探索公众号与小程序如何连接
  • 编写初始版留言板

理清两者如何联系?         微信公众平台中,文章中是可以插入小程序的,读者通过点击我们在文章中设置的文字或图片,就可以进入小程序。而且我们还可以确定小程序页面的启动参数,便于实现不同文章进入小程序显示不同的留言内容 在这里插入图片描述 在这里插入图片描述 基础留言板功能开发         写留言:获取用户输入的值,添加新记录或者更新新记录即可。注意:云开发中对记录的更新只可以允许该记录的上传者进行修改,为此我们必须借用云函数。

// 上传留言
  hideModal_sure: function () {
    var k = this
    var content = k.data.content
    var article_url = k.data.article_url
    var flag = k.data.ishave //判断是否含有该文章留言记录
    var year = new Date().getFullYear()//年
    var month = new Date().getMonth() + 1//月
    var day = new Date().getDate()//日
    var hour = new Date().getHours()//小时
    var minute = new Date().getMinutes()// 分钟
    var user_name = k.data.user_name
    var user_image = k.data.user_image
    var time = year + "年" + month + "月" + day + "日" + hour + "时" + minute + "分"

    wx.showLoading({
      title: '留言中...',
    })
    // 含有记录 只需要添加即可
    if (flag == true) {
      console.log("已有记录,需要添加")
      // 调用云函数 push新留言
      console.log(article_url)
      console.log(content)
      wx.cloud.callFunction({
        // 要调用的云函数名称
        name: 'HHPro_functions',
        // 传递给云函数的event参数
        data: {
          function_name: "push_content",
          id_url: article_url,
          content_1: content,//用户留言
          user_name: user_name,//用户昵称
          user_image: user_image,//用户头像
          time: time// 留言时间
        }
      }).then(res => {
        console.log("push 新记录成功")
        wx.hideLoading()
        k.hideModal_cancel()
        k.onLoad()

      }).catch(err => {
        console.error(err)
      })
    }
    // 没有记录 新建记录
    else {
      db.collection('liuyan').add({
        // data 字段表示需新增的 JSON 数据
        data: {
          id_url: article_url,
          liuyan_content: [
            {
              user_name: user_name,//用户昵称
              user_image: user_image,//用户头像
              time: time,//评论时间
              content_1: content,//用户评论
              content_2: ""//作者评论
            }
          ]
        }
      })
        .then(res => {
          //console.log(res)
          console.log("原本无记录,现已添加成功!")
          wx.hideLoading()
          k.hideModal_cancel()
          k.onLoad()
        })
        .catch(console.error)
    }
    console.log("上传留言内容为:" + content)


  },

云函数

try {
      return await db.collection('liuyan').where({
        id_url: id_url
      })
        .update({
          data: {
            liuyan_content: _.push([
              {
                content_1: content_1,//用户留言
                content_2:"",// 作者留言,
                user_name:user_name,//昵称
                user_image:user_image,//头像
                time:time,//时间
                ispass:ispass//是否审核
              }
             
            ])
          },
        })
    } catch (e) {
      console.error(e)
    }

测试         内嵌了基础留言板的小程序"海轰Pro"通过审核,经过公众号文章测试,原理验证成功。不过bug还是存在:由于ishava变量漏写了一个,导致当第二个用户留言时,系统会产生两条记录;"阅读原文"不可以正确使用 在这里插入图片描述

编程第二~第七小时

  • 添加作者审核功能
  • 添加作者回复功能
  • 添加密令生成功能
  • 添加留言管理功能
  • 修复初始版bug

审核模块

// 审核留言
  check:function(e){
    var k=this
    wx.showModal({
      title: '审核',
      content: '是否审核通过这条留言?',
      success(res) {
        if (res.confirm) {
          console.log('用户点击确定')
          wx.showLoading({
            title: '审核中...',
          })
          console.log(e.currentTarget.dataset.id)// 该篇文章的第几个留言
          var id_url = k.data.id_url// 需要审核记录的id_url
          var replys = k.data.replys//所有文章留言
          setTimeout(function () {
            var index_1 = k.data.index_1// 第几篇文章
            replys[index_1].liuyan_content[e.currentTarget.dataset.id].ispass = true
            wx.cloud.callFunction({
              // 要调用的云函数名称
              name: 'HHPro_functions',
              // 传递给云函数的event参数
              data: {
                function_name: "reply",
                id_url: id_url,// 记录标识
                all_content: replys[index_1].liuyan_content//更新后的留言
              }
            }).then(res => {
              console.log("审核通过")
              wx.showToast({
                title: '审核通过^_^',
                icon: "none"
              })
              k.setData({
                value_x: "",
                isreachbottom:false,
                nums:0
              })
              wx.hideLoading()
              k.onLoad()

            }).catch(err => {
              console.error(err)
              wx.hideLoading()
              wx.showToast({
                title: '审核失败┭┮﹏┭┮',
                icon: "none"
              })
            })
          }, 1000)
        } else if (res.cancel) {
          console.log('用户点击取消')
        }
      }
    })
  }

回复模块

// 提交 作者回复
  formSubmit:function(e){
    var k=this
    this.setData({
      modalname: ""
    })
    wx.showLoading({
      title: '回复中...',
    })
    console.log("确定")
    console.log(e.detail.value.reply)// 作者回复的内容
    // 考虑回复内容为空的情况
    if (e.detail.value.reply=="")
    {
      wx.showToast({
        title: '回复内容不可以为空哦(⊙.⊙)!',
        icon:"none"
      })
    }
    // 回复内容不为空的情况
    else
    {
      var content = e.detail.value.reply // 留言内容
      var index = k.data.liuyan_index// 回复第几个留言
      var article_url = k.data.article_url// 记录标识
      // 作者已经回复
      if (k.data.liuyan_content[index].content_2!="")
      {
        k.setData({
          value_x:""
        })
      console.log("已经回复了哦o(*^@^*)o")
      wx.showToast({
        title: '已经回复了哦o(*^@^*)o',
        icon:"none"
      })
      }
      // 没有回复
      else
      {
        
        k.data.liuyan_content[index].content_2 = content
        wx.cloud.callFunction({
          // 要调用的云函数名称
          name: 'HHPro_functions',
          // 传递给云函数的event参数
          data: {
            function_name: "reply",
            id_url: article_url,// 记录标识
            all_content: k.data.liuyan_content//更新后的留言
          }
        }).then(res => {
          console.log("作者回复成功")
          wx.showToast({
            title: '回复成功^_^',
            icon: "none"
          })
          k.setData({
            value_x: ""
          })
          wx.hideLoading()
          k.onLoad()

        }).catch(err => {
          console.error(err)
          wx.hideLoading()
          wx.showToast({
            title: '回复失败┭┮﹏┭┮',
            icon: "none"
          })
        })
      }            
  },

密令生成

// 获取密令
    db.collection('images').where({
      _id: '1583323590594_0.2267614604186734_33609397' // 填入当前用户 openid
    }).get().then(res => {
      console.log(res.data[0].password)
      k.setData({
        password: res.data[0].password
      })
    })
    // 调用获取用户openid的云函数
    wx.cloud.callFunction({
      name: 'login',
      data: {
      }
    }).then(res => {
      console.log(res.result.openid)
      wx.hideLoading()
      k.setData({
        user_openid: res.result.openid,
      })
    })

管理模块(部分)

//删除
  delete:function(e){
    var k = this
    var replys = k.data.replys// 所有文章留言
    wx.showModal({
      title: '提示',
      content: '是否删除该留言?',
      success(res) {
        if (res.confirm) {
          console.log('用户点击确定')
          wx.showLoading({
            title: '删除中...',
          })
          setTimeout(function () {
            var id_url = k.data.id_url// 需要修改文章的id_url
            replys[k.data.index_1].liuyan_content.splice(e.target.dataset.id, 1)
            console.log(id_url)

            wx.cloud.callFunction({
              // 要调用的云函数名称
              name: 'HHPro_functions',
              // 传递给云函数的event参数
              data: {
                function_name: "reply",
                id_url: id_url,// 记录标识
                all_content: replys[k.data.index_1].liuyan_content//更新后的留言
              }
            }).then(res => {
              wx.hideLoading()
              k.onLoad()
              wx.showToast({
                title: '删除成功O(∩_∩)O',
                icon: "none"
              })
            }).catch(err => {
              console.error(err)
              wx.hideLoading()
              wx.showToast({
                title: '删除失败┭┮﹏┭┮',
                icon: "none"
              })

            })
          }, 1000)
        } else if (res.cancel) {
          console.log('用户点击取消')
        }
      }
    }) 
  },

测试         内嵌第二个版本留言板的小程序一天就通过了审核。可是.... 小程序页面启动参数中的一个 ? 被我写成了 & ,密令生成模块作废。好在可以在公众号中修改一下就行了。之后用来快一个小时,测试了留言板所有功能,全部正确!!

在这里插入图片描述

编程第九小时

        留言板功能基本实现,剩下的一点就是修复bug,对界面进行改进。这点工作很快就完成,上传代码,提交审核!!幸运的是,一次就通过审核了,开心!O(∩_∩)O哈哈~

总结

        通过这次的留言板,自己也是学到了很多,特别是在一些细节处理上,原来做的是真的不行。由于本学期学习任务比较重,时间比较少,所以这次的功能做的就显得有点粗糙。但是经过海轰的测试,基础功能还是可以实现的,O(∩_∩)O哈哈~         目前bug还是比较多,时间比较急,对于同学一个人使用应该是可以的。编程一共写了九小时,不是一天就写完了,哪有那么厉害。还不是一报错,就百度。修修补补,勉强才可以使用。【总的说来,简单功能可以实现,可以一旦用户过多,估计就凉凉了】

疑惑

        开发过程中,我想实现一个点赞评论的功能:用户可以对评论点赞,一个用户只可以点赞一次,点赞后页面那个点赞按钮应该变成已经点赞后的状态。这个功能想了挺久,一直都没有思路。希望有知道的大佬可以指点指点,谢谢♪(・ω・)ノ

我正在参加「创意开发 投稿大赛」详情请看:掘金创意开发大赛来了!