【uniapp云开发】一套代码带你封装云开发中的增删改查云函数

1,572 阅读5分钟

开篇

这篇文章是带着一种悲伤的心情写出来的,由于前段时间去申请掘金小册被拒了,导致uniapp云开发的小册还没开始就结束了,那么就拆分出来直接写成文章吧!

image.png

当然,拆分出来之后就不会有系列文了,只会有零零散散的单篇技术文。

不过,既然要写嘛,那就得好好写对不对!!!

前言

在我做的好几个uniapp云开发项目中,我都会按照数据库表来新建云函数,比如user表对应了一个user云函数。但其实很多增删改查的业务,都是可以封装起来的。

比如:列表、详情页、配置项等等,都只是过滤的参数不一样而已,所以为了减少代码量,完全可以封装成几个、甚至封装成一个。

查询的云函数

我做的一个情侣类小程序中,需要分别获取当前用户信息当前用户的对象信息,但是他们都在一张表中,可能查询的字段不太一样,在设计的时候,就写了两个云函数逻辑。

  • 请求云函数方法(通过action参数去判断请求的哪一个云函数)
const res_reg_val = await uniCloud.callFunction({
    name: 'a_user',
    data: {
        action: 'getUserInfo',
        user_id: '用户ID'
    }
})
  • 云函数查询方法
'use strict';
/*
 * 获取用户信息逻辑:
 * 1、通过 微信code 拿到用户openid
 * 2、通过 用户openid 判断库里是否存在当前用户
 * 	2.1、不存在:走注册逻辑,需要同时注册进入两个表:a-user、a-lovers
 * 	2.2、存在:获取用户信息(情侣ID会在注册时存入用户表)
 */

exports.main = async (event, context) => {
    //event为客户端上传的参数
    // console.log('event : ', event)

    const db = uniCloud.database();
    // 获取 `a-user` 集合的引用(用户表)
    const a_user = db.collection('a-user');
    // 获取 `a-lovers` 集合的引用(情侣表)
    const a_lovers = db.collection('a-lovers');

    // 条件查询必备语法
    const dbCmd = db.command

    // 循环判断客户端传递过来的 action
    // 通过 action 判断请求对象
    let result = {};
    switch (event.action) {
        case 'getUserInfo':
            const res_user_val = await a_user.where({
                    _id: event.user_id
            }).get()

            return res_user_val.data[0]
            break;
        case 'getLoverUserData':
            // 查询另一半的用户信息
            const res_lover_user_val = await a_user.where({
                    lover_id: event.lover_id,
                    _id: dbCmd.neq(event._id)
            }).get()

            return res_lover_user_val.data[0]
            break;
    }
    //返回数据给客户端
    return result
};
  • 根据这两个云函数的写法,其实可以看到除了where中的参数不一样之外,其他的都是一样的
  • 那么我们是不是可以将这两个云函数合并起来呢??

封装查询云函数

  • 请求云函数方法
let config = await uniCloud.callFunction({
    name: 'a_user',
    data: {
        dbName: 'a-user',
        filter: {
            user_id: '用户ID'
        }
    }
})
  • name是云函数名称

  • data中是传给云函数的参数

    • dbName是表名
    • filter是where中的参数
  • 云函数封装

'use strict';
exports.main = async (event, context) => {
    //event为客户端上传的参数
    // console.log('event : ', event)
    // 这里是各种配置表的请求,主要是获取所需的信息
    const db = uniCloud.database();
    // 由于会获取不同表的配置,所以这里就需要直接从前端传递 表名称
    const a_user = db.collection(event.dbName);

    // 这里是获取数据时所需要的查询参数,过滤掉一些不需要的数据
    const filter = event.filter ? event.filter : {}

    let result = {};

    const res_val = await a_user.where(filter).get()
    result = res_val.data

    //返回数据给客户端
    return result
};
  • 根据我写的注释,可以很清楚的看到每一个字段是干啥用的。
  • 我这里配置的所有参数,都是直接去查询某张表的,所有字段都在请求时配置好,这样就不需要在请求和发送的时候都去配置相同的参数了。

根据查询信息的封装方法,我们还可以继续封装其他的,比如删除、分页等等

封装分页云函数

分页其实也是查询的一种,只是里面会多一些额外的分页参数,封装起来和查询也有点区别。

'use strict';
const db = uniCloud.database();
exports.main = async (event, context) => {
    var dbName = event.dbName //集合表名
    var order = event.order ? event.order : {} //排序
    var filter = event.filter ? event.filter : {} //筛选条件
    var pageIndex = event.pageIndex ? event.pageIndex : 1 //当前页数
    var pageSize = event.pageSize ? event.pageSize : 15 //每页数量
};
  • 在获取数据的时候,需要添加两个分页参数pageIndexpageSize
  • 其他的参数都差不多。
  • 分页需要先查询出当前表的总数
let countResult = await db.collection(dbName).where(filter).count()
const total = countResult.total  //得到总记录数 
const totalPage = Math.ceil(total / pageSize)  //计算页数
  • 得到总数之后,就可以判断一下,返回给前端请求时提示它是否还有数据
var hasMore  //提示前端是否还有数据
if (pageIndex > totalPage || pageIndex == totalPage) {  //如果没有数据了,就返回false
    hasMore = false 
} else {
    hasMore = true 
}
  • 最后可以通过上面的参数进行查询分页数据
let result = {}
if(order.name && order.type){
    result = await db.collection(dbName)
    .where(filter)
    .skip((pageIndex - 1) * pageSize)
    .limit(pageSize)
    .orderBy(order.name,order.type)
    .get()
}else{
    result = await db.collection(dbName)
    .where(filter)
    .skip((pageIndex - 1) * pageSize)
    .limit(pageSize)
    .get()
}
result.hasMore = hasMore
return result
  • 我在这里判断一下order参数,主要用于分页后排序操作,如果没有的话,直接用else里面的代码就行了

封装删除云函数

  • 删除的云函数和查询的就一样了,只是最后调用的方法不同而已
'use strict';
const db = uniCloud.database();
exports.main = async (event, context) => {
    var dbName = event.dbName //集合表名
    var filter = event.filter ? event.filter : {}//筛选条件

    let result = await db.collection(dbName).where(filter).remove()
    if(result.deleted === 0){
        return {
            success: false,
            msg: '删除失败'
        }
    }

    return {
        success: true,
        msg: '删除成功'
    }
};

总结一下

封装云函数只是一种思路,会结合实际需求来写,当然大部分时候,都会按照最简单也是最方便的写法去写(一个表对应一个云函数)这样就不会出错,不会一直去修改封装好的云函数里面的逻辑。

如果需求比较简单的话,增删改查 + 分页,一共就五个云函数,看起来会更直观,也不需要修改多处,只需要专注于前端逻辑就好了。

如果有更简单的封装方法,也可以讨论讨论哦~~~