8分钟

任务 4 新建评论详情展示

任务目的

经过这一步的操作,可以实现新建评论后,自动跳转到评论详情页,展示评论的情感分析结果。评论详情需要单独的页面展示,所以这一步需要先在小程序中创建一个新的详情页面,然后在新的页面中调用云开发数据库的API,通过传入新评论的ID获取到对应的情感分析数据,并将获取到的结果在页面中以图表的形式展现。完成上述操作后,用户还可以通过页面中的返回按钮,跳转回项目的主页。

任务步骤

1.功能预期效果展示

经过这一步的操作,我们希望能够完成如下功能:

  • 填写评论内容,新建评论后,页面跳转到评论详情页;
  • 评论详情页中可以展示评论的情感分析新结果;
  • 点击底部的 “返回评论列表” 按钮,可以返回主页。

具体展示效果如下:

4-4-1 情感分析详情效果展示

接下来会介绍评论详情页的制作流程。

2.index.js页面引入跳转

接下来需要构建一个新的页面,用于展示评论的详情信息,新的页面命名为detail。在构建新的页面前,先要在主页的js逻辑文件中,引入页面的跳转功能。

打开index页面中的index.js文件,在其中addComment函数的.then({})部分进行如下修改:

【修改文件:index.js,所在页面:index】

Page({
  ......
  addComment(event) {
    ......
    }).then(res => {
    //上方内容无需修改

      // ++++++++++新增内容++++++++++
      // 获取数据id,执行页面跳转
      let id = res.result._id
      wx.navigateTo({
        url: '/pages/detail/detail?add=true&id=' + id,
      })
      // ++++++++++新增内容++++++++++

    // 下方内容无需修改
    }).catch(res => {
    ......
    }),
  },
})

此处的修改移除了原来打印在控制台上的内容(打印内容主要用于调试,现程序已经运行成功,可以移除),添加了页面跳转的功能。

在跳转到详情页的同时,额外添加了addid两个参数,前者用于标记执行新增数据操作,后者用于在详情页获取数据库集合中的评论信息。

接下来将要构建具体的评论详情页代码。

3.添加评论详情(detail)页本地代码

(1)新建detail页面。

这一步将会创建一个名为detail的新页面,操作示意图如下:

4-4-2 新建小程序页面

具体的操作步骤说明如下:

  • 右键点击pages,选择 “新建 目录” ,创建一个名为detail的目录。
  • 右键点击detail目录,选择 “新建 Page” ,detail页面将会自动生成。

想要新建页面生效,还需要在app.json文件中注册新的页面,新版本的微信开发者工具已经自动完成了这一步操作,所以无需用户手动注册新页面。学员可以打开app.json文件,确认pages中是否包含新注册的detail页面:

{
  "pages": [
    "pages/index/index",
    "pages/detail/detail"
  ],
  ......
}

如果学员的pages中不包含页面pages/detail/detail,可以手动将其添加到主页页面列表中。

(2)引入Vant相关组件。

新的页面上也需要引入Vant中的单元格cellcell-group和按钮button组件,在detail页面的detail.json中添加如下内容,引入新组件:

【修改文件:detail.json,所在页面:detail】

{
  "usingComponents": {
    "van-cell": "@vant/weapp/cell",
    "van-cell-group": "@vant/weapp/cell-group",
    "van-button": "@vant/weapp/button"
  }
}

(3)编写wxml页面代码。

在detail页面的detail.wxml文件中编辑页面结构代码。清空原来的内容,添加如下代码

【修改文件:detail.wxml,所在页面:detail】

<view class="subtitle">评论内容:</view>

<van-cell-group>
  <van-cell title="{{comment}}" />
</van-cell-group>

<view class="subtitle">文本情感分析:</view>
<view>
  <view class="sentiment" wx:if="{{Sentiment !== ''}}">
    <canvas class="sentimentCanvas" canvas-id="sentimentCanvas">
      <cover-view class="text">
      <cover-view class="center-text {{ Sentiment == 'negative' ? 'negative' : 'positive' }}">{{Sentiment == 'negative' ? '消极' : '积极'}}</cover-view>
      </cover-view>
    </canvas>
    <view class="sentiment-number">
      <view class="sentiment-view">
        <block>
        <view class="groud positive-groud"></view>
        <text class="sentiment-text">正面情感 <text class="number">{{positiveNumber}}</text></text>
        </block>
      </view>
      <view>
        <block>
        <view class="groud negative-groud"></view>
        <text class="sentiment-text">负面情感 <text class="number">{{negativeNumber}}</text></text>
        </block>
      </view>
    </view>
  </view>
</view>

<van-button type="primary" block size="default" bind:click="toIndex">返回评论列表</van-button>

这些代码分别用于展示评论内容、情感分析图表,以及返回评论列表的按钮。接收到不同的数据时,页面上的图表以及相关文字也会动态变化。

(4)编写js逻辑代码。

在detail页面的detail.js中添加页面的逻辑代码。清空原来的内容,添加如下代码

【修改文件:detail.js,所在页面:detail】

Page({
  // 页面的初始数据
  data: {
    comment: "",
    Sentiment: '',
    Negative: 0,
    positiveNumber: '',
    negativeNumber: '',
    width: 375
  },

  // 生命周期函数--监听页面加载
  onLoad: function (options) {
    // 更新页面的宽度信息,用于绘制图表
    this.setData({
      width: wx.getSystemInfoSync().windowWidth
    })
    // 接收请求参数
    this._id = options.id
    this.add = options.add
  },

  toIndex(event) {
    // 根据详情页进入方式决定返回主页的跳转方式
    if (this.add == undefined) {
      wx.navigateBack({
        url: '/pages/index/index',
      })
    } else {
      wx.reLaunch({
        url: '/pages/index/index',
      })
    }
  },

  // 生命周期函数--监听页面初次渲染完成
  onReady: function () {
    // 通过id获取集合中的评论数据
    const db = wx.cloud.database()
    db.collection('userComments').doc(this._id).get().then(
      res => {
        // 更新绑定数据
        this.setData({
          "comment": res.data.comment,
          "Sentiment": res.data.sentiment,
          "Negative": Math.round(res.data.negative * 10000) / 10000,
          "positiveNumber": Math.round(res.data.positive * 10000) / 100 + "%",
          "negativeNumber": Math.round(res.data.negative * 10000) / 100 + "%",
        })
        // 调用函数,绘制情感分析圆环
        drawRing()
      })

    // 绘制情感分析圆环的函数
    const that = this
    function drawRing() {
      const ctx = wx.createCanvasContext("sentimentCanvas", this)
      const width = 260;
      const lineWidth = 16;
      ctx.lineWidth = lineWidth;
      const rpx2px = (rpx) => (rpx * that.data.width / 750);
      const value = (that.data.Negative) * 2 * Math.PI;
      ctx.beginPath();
      ctx.arc(rpx2px(width) / 2, rpx2px(width) / 2, rpx2px(width - 4 * lineWidth) / 2, 0, 2 * Math.PI);
      ctx.setStrokeStyle('#29cc85');
      ctx.stroke();
      ctx.beginPath();
      ctx.arc(rpx2px(width) / 2, rpx2px(width) / 2, rpx2px(width - 4 * lineWidth) / 2, 3 * Math.PI / 2 - value, 3 * Math.PI / 2);
      ctx.setStrokeStyle('#ff584e');
      ctx.stroke();
      ctx.draw();
    }
  },
})

对应的代码逻辑说明如下:

  • data:{}:对应页面的初始数据
  • onLoad:页面加载时的执行函数。用于获取页面宽度信息,接收页面跳转时的请求参数
  • toIndex:点击 “返回评论列表” 按钮时执行的函数,会根据进入页面的方式判断跳转方式。如果是新增数据,则重新加载页面,如果没有新增数据,直接返回上一个页面。
  • onReady:页面渲染完成时的执行函数。用于调用数据库API,获取评论的分析数据,更新页面的绑定数据,同时执行drawRing函数绘制情感分析图表。
  • function drawRing():绘制情感分析图表的函数,此函数会接收情感分析中的关键参数,结合分析结果绘制图表。

4.更新集合权限

保存上面每一步操作的页面,即完成情感分析详情页代码编写。

尝试编写评论内容并点击新建评论,发现结果展示页没有展示评论内容和分析结果,且控制台报错:

4-4-3 运行程序控制台报错

这是由于数据库中没有设置所有用户的读取权限,需要在云开发控制台中进行如下操作:

4-4-4 修改数据库读写权限

操作步骤说明如下:

  • 进入云开发控制台,选择 “数据库”
  • 选择集合userComments
  • 点击上方的 “权限设置” 按钮
  • 将权限修改为 “所有用户可读,仅创建者可读写”,并在弹出的对话框中点击 “确认” 按钮

5.结果验证

完成上一步的权限设置后,再次尝试进行新增评论的操作。

点击 “新建评论” 后,页面可以顺利跳转到评论详情页,且评论的分析结果可以正常展示,点击下方的 “返回评论列表” 按钮,页面也可顺利跳转回首页。说明评论详情页已经成功实现。