V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
LeanCloud
V2EX  ›  推广

教学贴 | 如何用小程序 SDK 实现电商评价模块

  •  
  •   LeanCloud · 2017-12-06 18:57:36 +08:00 · 1762 次点击
    这是一个创建于 2546 天前的主题,其中的信息可能已经有所发展或是发生改变。

    [ 玩转 LeanCloud ] 开发者经验分享: 作者:黄秀杰

    在商城系统中给商品添加评价是一种非常典型的需求,我下面要来演示一下如何借助 LeanCloud 的小程序 SDK 来快速完整地实现这个需求,包括如何处理用户登录和获取用户信息、数据添加和读取、图片上传等功能。

    先列一下基本需求:

    • 写入一条带描述和多张图片的评价记录
    • 保存用户对象,关联商品对象
    • 评价显示在商品详情底部

    添加评价演示:

    评价列表显示:

    前端 UI 要完成:

    • 绘制带「删除」按钮的九宫格
    • 一个文本域,供输入描述文字
    • 一个提交按钮

    技能点:

    • LeanCloud 小程序 SDK 常用的 API
    • Promise.all() 并发处理多个网络请求
    • 小程序表单控件 textarea 访问取值与小程序页面传值

    LeanCloud 存储部分

    新建一张 Evaluate 评价表,该表保存着多图 url 路径数组,同时还维护商品 goods 表与 user 表的关联,以表示哪个用户 user 针对哪个商品作出的评价。数据表在 LeanCloud 用 Class 表示,而外键关联在 LeanCloud 中使用 Pointer 类型表示,建表与建字段如下图所示。

    • 建表

    • 建字段

    建商品字段

    建用户字段

    图组字段

    引入 LeanCloud 小程序 JS 库—— av-weapp.min.js

    js 库下载地址: https://unpkg.com/leancloud-storage@%5E3.0.0-alpha/dist/av-weapp-min.js

    下载将它放在 /utils/目录下,然后在需要的 js 页面按如下方式引入

    const AV = require('../../../utils/av-weapp.js')
    
    

    然后按下面方式初始化,初始化过程只用操作一次,因此可以放到 app.js 执行。

    // 初始化 AV
    const AV = require('./utils/av-weapp.js');
    const appId = "7tm1OFlNlmLFxxxoHsz";
    const appKey = "XxNkFIrxxxal0ttvj";
    
    AV.init({ 
        appId: appId, 
        appKey: appKey
    });
    

    创建评论页面

    /pages/member/evaluate/ 目录下创建 4 个文件:

    • evaluate.js
    • evaluate.json
    • evaluate.wxml
    • evaluate.wxss

    LeanCloud 一键登录与获取当前用户

    取出当前用户后,与描述内容、图片数组、商品关联一并提交到网络:

    AV.User.loginWithWeapp();
    var user = AV.User.current();
    

    小程序端从 wxml 中取出 textarea 的值

    在 wxml 文件个添加一个 textarea 控件,通过 bindblur 事件获取它的值:

    <textarea value="{{content}}" name="content" placeholder="请输入评价内容" maxlength="-1" auto-height bindblur="getContent" />
    

    JS 中实现取值并保于 page 的 data 中,供提交数据到网络之用:

     getContent: function (e) {
        that.setData({
            content: e.detail.value
        });
        },
    

    在评论页接收上个页面传递来的商品 id

        onLoad: function(options) {
        // 取出商品 id
        var objectId = options.objectId;
        // 存在当前页面 data 中,以保存到评价表
        this.setData({
            objectId: objectId
        });
        },
    

    然后通过 LeanCloud SDK 的 AV.Object.createWithoutData 方法来得到被关联的商品对象,最终被提交到 Evaluate 表中。

    浏览与上传图片

    wx.chooseImage 是小程序提供的图集浏览 API,使用方法见 https://mp.weixin.qq.com/debug/wxadoc/dev/api/media-picture.html#wxchooseimageobject,它会返回一个 tempFilePaths 数组,之后用它上传给 LeanCloud 云端。

    chooseImage: function() {
        // 选择图片
        wx.chooseImage({
            sizeType: ['compressed'],
            sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
            success: function(res) {
                // 返回选定照片的本地文件路径列表,tempFilePath 可以作为 img 标签的 src 属性显示图片
                var tempFilePaths = res.tempFilePaths;
                console.log(tempFilePaths);
                that.setData({
                    images: that.data.images.concat(tempFilePaths)
                });
            }
        })
        },
    

    上传图片得到图片 url 数组

    上传通过 LeanCloud SDK 的 AV.FIle#save() 方法完成。由于上传是异步操作的,因此这里用 Promise.all 方法等全部图片上传完成后再把返回的 image url 数组提交到网络。

    // 提交图片,事先遍历图集数组
    var promises = that.data.images.map(function(tempFilePath) {
        return new AV.File('file-name', {
            blob: {
                uri: tempFilePath,
            },
        }).save();
    });
    Promise.all(promises).then(
        function(files) {
            // Promise 返回待上传图片数组
            var uploadedImages = files.map(function(file) {
                return file.url();
            });
            console.log(uploadedImages);
        }
    );
    

    提交数据到 LeanCloud

    先创建对象 evaluate,然后通过 set 方法设置成员变量值,最后调用 save() 方法提交数据到 LeanCloud:

    // 提交数据到网络
    var evaluate = new AV.Object('Evaluate');
    // 设置图组
    evaluate.set('images', uploadedImages);
    // 设置用户提交的描述
    evaluate.set('content', that.data.content);
    // 设置当前用户
    evaluate.set('user', AV.User.current());
    // 关联商品
    evaluate.set('goods', AV.Object.createWithoutData('Goods', that.data.objectId));
    // 保存到 LeanCloud 数据表
    evaluate.save().then(function() {
        // 弹出提示
        wx.showToast({
            title: '评价成功',
            success: function() {
                // wx.navigateBack();
            }
        });
    }, function(err) {
        console.log(err);
    });
    

    如果是 update 操作,那么需要这个对象要有 ObjectId,同样是调用 save() 方法。通常是在编辑页面的时候已经在 data 中保存了读取到的 object,然后再 save() 这样就变成 update 操作了。

    这时就能看到开篇的多图上传 gif 动图里的效果了。

    后台查看存储结果

    登录 LeanCloud 后台,找到 Evaluate 表,看到数据已经插入成功了。其中 goods 与 user 分别指向商品与用户对象,点击链接可以跳转查看到关联的商品与用户的数据。

    图片描述

    表中数据

    在商品详情处列表渲染

    查询操作使用 query#find() 方法,关联表的字段需要使用 include('xx_table') 设定,查询条件全匹配使用 equalTo:

    getEvaluateByGoods: function (goodsId) {
        var query = new AV.Query('Evaluate');   
        // 查询关联表的数据需要调用设置 include 属性,可以多次设定
        query.include('user');
        // 查询条件设定为当前 goods 对象
        query.equalTo('goods', AV.Object.createWithoutData('Goods', goodsId));
        // 查询所有记录
        query.find().then(function (evaluateObjects) {
            // 将返回结果返回到 data 数据中,以在 wxml 渲染
            that.setData({
                evaluateObjects: evaluateObjects
            })
        }, function (err) {
            console.log(err);
        });
    },
    

    相应的 wxml 布局

    通过 wx:for 来遍历,并且指定 wx:for-item 以区分嵌套内层循环的数据。LeanCloud 小程序 SDK 升级到 3.0 后,成员变量可以很方便地使用点语法在 wxml 链接访问,比如 {{ evaluate.user.avatarUrl }}

    <!-- 用户评价 -->
    <view class="evaluate-container">
        <view wx:for="{{evaluateObjects}}" class="evaluate" wx:for-item="evaluate">
            <view class="avatar">
                <image src="{{evaluate.user.avatarUrl}}" />
            </view>
            <view class="main">
                <view class="nickname">{{evaluate.user.nickName}}</view>
                <view class="content">{{evaluate.content}}</view>
                <view class="gallery">
                    <view class="image-container" wx:for="{{evaluate.images}}" wx:for-item="url">
                        <image src="{{url}}" />
                    </view>
                </view>
            </view>
        </view>
    </view>
    

    这时能看到开篇的那张商品详情的截图效果。

    大功告成,超 easy 是不是!源码地址 http://git.oschina.net/dotton/lendoo-wx,文中所涉及的代码保存在 /pages/member/evaluate 文件夹中,欢迎 fork 和讨论。

    3 条回复    2017-12-07 13:23:57 +08:00
    eccstartup
        1
    eccstartup  
       2017-12-07 09:57:01 +08:00 via iPhone
    收藏了
    mokeyjay
        2
    mokeyjay  
       2017-12-07 10:39:27 +08:00
    @Livid 这种算不算推广呢?
    Livid
        3
    Livid  
    MOD
       2017-12-07 13:23:57 +08:00 via iPhone
    @mokeyjay 谢谢举报。已经移动。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1056 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 20:30 · PVG 04:30 · LAX 12:30 · JFK 15:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.