图片画廊示例

图片画廊是一个简单的小程序示例,结合小程序客户端和 Basement 后端,完成一个具备前后端功能的完整小程序。


前提条件


创建小程序

  • 登录 蚂蚁金服开放平台,选择 开发者中心 > 小程序 > 创建
  • 填写 基本信息,点击 创建 按钮,创建应用名为 示例应用 小程序。

说明:一个账号最多可以创建 10 个小程序;未提交过审核的小程序可以删除,删除的小程序不在计数范围。


创建 Basement

  • 我的小程序 页面,选择已经创建的小程序,点击 查看,进入 开发管理 页面。
  • 点击左侧导航栏的 云服务(公测),在 云服务列表 页面点击 创建云服务 > 创建 Basement
  • 创建 Basement 页面,填入 应用名称描述 (选填),点击 创建

说明:每个账号可免费创建一个 Basement 服务;当前测试环境该方案免费提供,但若 连续 7 日小程序没有访问量,并且未部署过代码 ,环境资源会被自动回收。

image.png


准备开发环境

  • 打开小程序开发者工具,点击 新建项目
    image.png

  • 在新建项目向导中,选择 小程序,选择 图片画廊示例,点击 下一步
    image.png

  • 输入 项目名称,项目路径会自动填充,选择 Basement 为后端服务,点击 完成
    image.png

  • 在 IDE 的客户端依赖页面,安装 @ant-basement/miniprogram-sdk

说明:如果列表中找不到,可以在依赖框中输入 @ant-basement/miniprogram-sdk 完成添加。

image.png

  • 点击 云服务:请选择 > 选择此前已经创建好的 Basement 服务作为关联的云服务。
    image.png

部署云函数

点击 云服务 唤起菜单,点击 上传部署服务端代码 提交云函数部署。

说明:将 server 目录的代码作为云函数进行上传和部署。部署成功相当于完成云函数的代码发布,部署前请注意区分测试环境和生产环境的区别。

image.png


预览和上传

  • 点击 刷新图标 可以在 IDE 模拟器 中查看预览效果;还可以点击 预览 ,使用 支付宝扫描二维码 在手机上实现真机预览。
    image.png

  • 点击 上传 将小程序上传到开放平台,具体操作请参考 小程序提审、发布流程
    image.png


后端代码介绍

获取用户信息

小程序是运行在支付宝上的,首先需要获取支付宝用户的基础信息,用于完善用户头像、昵称等信息。我们需要创建一个云应用,通过支付宝 OpenAPI,当用户访问小程序的时候将对应信息获取到并显示在页面上。

  • 在 server 目录增加 getUserInfo/index.js 文件,用于编写和存放云函数的代码。
  1. 'use strict';
  2. module.exports = async (ctx) => {
  3. // 从支付宝 OpenAPI 获取用户信息
  4. const user = await ctx.basement.openapi.alipay.exec('alipay.user.info.share');
  5. // 返回用户信息
  6. return user;
  7. };
  • 在 server 目录修改 serverless.yml 文件,将 getUserInfo/index 作为一个 function 服务。在这里相当于定义云函数的访问别名和云函数路径的关系。
  1. functions:
  2. getUserInfo:
  3. handler: getUserInfo/index
  • 重新点击 上传部署服务端代码 提交云函数部署。

image.png

  • 在首页,有当前 用户的头像 。通过调用云函数在支付宝获取用户信息,并显示到页面上。
    image.png

client/pages/index/index.js 文件中,修改 onShow 方法 ,在页面初始化时获取用户信息并更新页面。

javascript // 显示指定当前用户的图片列表 onShow() { basement.function.invoke('getUserInfo').then((res) => { if (res.success) { const user = res.result; this.setData({ user }); this._getImages(user); my.hideLoading(); } }).catch(console.error); }

读取图片列表

在首页,需要从数据库将 图片列表 读取出来。

image.png

client/pages/index/index.js 文件中,在 onShow 方法 获取图片列表并更新页面。(本示例中获取图片列表的处理封装在 _getImage 方法中)

  1. // 获取特定用户的图片列表
  2. _getImages(user) {
  3. basement.db.collection('images')
  4. .find({ userId: user.userId }, { sort: { uploadTime: -1 } })
  5. .then(({ result: images }) => {
  6. images.map((item) => {
  7. item.uploadTime = new Date(item.uploadTime).toDateString();
  8. return item;
  9. })
  10. const noImages = images && images.length === 0 ? true : false;
  11. this.setData({ images, noImages });
  12. })
  13. .catch(console.error);
  14. }

更新图片信息

用户可以在图片列表上点击 重命名 ,在对话框输入新的名称,对图片名称进行更新。

image.png

client/pages/index/index.js 文件中,在 rename 方法 中显示对话框采集新的图片名称,最后刷新列表。

  1. // 变更图片名称的事件处理
  2. rename(e) {
  3. const dataset = e.target.dataset;
  4. my.prompt({
  5. title: '修改名称',
  6. message: '请输入新的图片名称:',
  7. placeholder: '',
  8. okButtonText: '确定',
  9. cancelButtonText: '取消',
  10. success: (result) => {
  11. if (result.ok) {
  12. basement.db.collection('images').updateOne(
  13. { _id: dataset.itemId },
  14. {
  15. $set: {
  16. text: result.inputValue,
  17. }
  18. }
  19. ).then(() => {
  20. this._getImages(this.data.user);
  21. }).catch(console.error);
  22. }
  23. },
  24. });
  25. }

删除图片

用户可以在图片列表上点击 删除 ,销毁一张图片。

image.png

client/pages/index/index.js 文件中,在 delete 方法 中显示确认对话框,确认后删除图片并刷新列表。

  1. // 删除图片的事件处理
  2. delete(e) {
  3. const dataset = e.target.dataset;
  4. // 确认和删除图片
  5. my.confirm({
  6. title: '删除图片',
  7. content: '是否确认删除该图片?',
  8. confirmButtonText: '删除',
  9. cancelButtonText: '取消',
  10. success: (result) => {
  11. if (result.confirm) {
  12. basement.db.collection('images').deleteOne({
  13. '_id': dataset.itemId,
  14. 'userId': this.data.user.userId,
  15. }).then(() => {
  16. // 刷新任务列表
  17. this._getImages(this.data.user);
  18. }).catch(console.error);
  19. }
  20. },
  21. });
  22. }

添加图片

当用户点击 添加图片 新增页面,在这里填写 图片名称 和上传 图片 后,可以增加一个新的图片记录。

image.png

  • 上传图标:client/pages/add-image/add-image.js 文件中,在 uploadImg 方法 完成图片上传和存储。
  1. // 选择并上传图片,获得图片 URL
  2. attach() {
  3. my.chooseImage({
  4. chooseImage: 1,
  5. success: res => {
  6. const path = res.apFilePaths[0];
  7. const options = {
  8. filePath: path,
  9. headers: {
  10. contentDisposition: 'attachment',
  11. },
  12. };
  13. basement.file.uploadFile(options).then((image) => {
  14. this.setData({
  15. imageUrl: image.fileUrl,
  16. });
  17. }).catch(console.error);
  18. },
  19. });
  20. }
  • 新增图片:client/pages/add-image/add-image.js 文件中,在 add 方法 完成新的图片内容新增。
  1. // 将新的图片内容添加到当前用户的图片列表中
  2. add() {
  3. // 如果图片名称没有填,或者没有上传图片,则进行提示
  4. if (this.data.inputValue == '' || !this.data.imageUrl) {
  5. my.alert({
  6. title: '添加失败',
  7. content: '请填写图片名称和上传图片。',
  8. buttonText: '我知道了',
  9. });
  10. // 正常情况,写入数据存储
  11. } else {
  12. basement.function.invoke('getUserInfo').then((res) => {
  13. if (res.success) {
  14. const user = res.result;
  15. basement.db.collection('images').insertOne({
  16. text: this.data.inputValue,
  17. url: this.data.imageUrl ? this.data.imageUrl : false,
  18. userId: user.userId,
  19. uploadTime: new Date(),
  20. }).then(() => {
  21. my.navigateBack();
  22. }).catch(console.error);
  23. }
  24. }).catch(console.error);
  25. }
  26. }

查看图片数量

为了让开发者了解在云函数中如何调用数据存储服务,本示例中我们在云函数对图片数量进行了统计。

  • 在 server 目录增加 imageAnalytics/index.js 文件,用于编写和存放云函数的代码。
  1. 'use strict';
  2. module.exports = async (ctx) => {
  3. const user = await ctx.basement.openapi.alipay.exec('alipay.user.info.share');
  4. const images = await ctx.basement.db.collection('images').find({ userId: user.userId });
  5. // 如果没有任务,返回 null
  6. if (!images.affectedDocs) {
  7. return null;
  8. }
  9. // 获取结果值
  10. const total = images.result.length || 0;
  11. return {
  12. total: total,
  13. };
  14. };
  • 在 server 目录修改 serverless.yml 文件,将 imageAnalytics/index 作为一个 function 服务。
  1. functions:
  2. imageAnalytics:
  3. handler: imageAnalytics/index
  4. getUserInfo:
  5. handler: getUserInfo/index
  • 重新点击 上传部署服务端代码 提交云函数部署。

  • 在首页点击 用户头像 ,前往 我的统计页面 ,在页面上显示统计信息。

image.png

client/pages/me/me.js 文件中,修改 onShow 方法 ,在页面初始化时获取图片统计数量并显示出来。

javascript // 请求云函数获取图片总数 onShow() { basement.function.invoke('getUserInfo').then((res) => { if (res.success) { this.setData({ user: res.result }); basement.function.invoke('imageAnalytics').then((imageRes) => { my.hideLoading(); if (imageRes.success) { this.setData({ analytics: imageRes.result || { total: 0 } }); } }).catch(console.log); } }).catch(console.log); }

原文: https://docs.alipay.com/mini/cloud-service/km54mf