uniCloud
是 DCloud 联合阿里云、腾讯云、支付宝小程序云,为开发者提供的基于 serverless 模式和 js 编程的云开发平台。
可以使用极小的成本代价开发具轻松实现前后台整体业务。尤其适用于不太熟悉后端的前端工程师!!!!
一个服务空间对应一整套独立的云开发资源,包括数据库、存储空间、云函数等资源。服务空间之间彼此隔离。
uniCloud
提供了一个 JSON 格式的文档型数据库。顾名思义,数据库中的每条记录都是一个 JSON 格式的文档。
它是 nosql (类似 MongoDB) 非关系型数据库。
可以在web端或者hbuilderX 使用MongoDB语法或jql语法管理数据库
uniapp还提供了独特的 clientDB 能力,可以我们直接在前端页面中读取数据库,极大提高了开发效率
// 获取db引用
const db = uniCloud.database() //代码块为cdb
db.collection('list')
.where({
name: "hello-uni-app" //传统MongoDB写法,不是jql写法。实际开发中推荐使用jql写法
}).get()
.then((res)=>{
// res 为数据库查询结果
}).catch((err)=>{
console.log(err.code); // 打印错误码
console.log(err.message); // 打印错误内容
})
云存储 就是一个云端的静态资源管理工具,也提供了cdn功能。支持直接在客户端就上传资源到云存储。
客户端代码
uniCloud.uploadFile({
filePath: filePath,
cloudPath: 'a.jpg',
success() {},
fail() {},
complete() {}
});
云函数是运行在云端/后端的 JavaScript
代码,是基于 Node.js
的扩展。
在常规的 Node API
基础上,uniCloud的云函数环境内置了uniCloud
对象,这个对象内置了网络、数据库等各种
API。开发者未学习过 Node.js
也没有关系,只需要看uniCloud的文档,掌握这个uniCloud
对象的API即可
// hello云函数index.js入口文件代码
'use strict';
exports.main = async (event, context) => {
//event为客户端上传的参数
let c = event.a + event.b
return {
sum: c
} // 通过return返回结果给客户端
}
我们实现一个产品的功能,往往需要前端+后端共同完成,比如验证码、登录、文件上传等等。uniapp提供了云端一体插件,可以直接通过引入的方式就帮我们做好了前端和后端的所有工作,极大简化了开发者的工作。
一个服务空间对应着一个数据库,我们开通了服务空间自然就会有一个数据库了
DB Schema 数据库范式
新建数据表的渠道有两种
hbuilderX
中新建
建表要遵循 DCloud 的 DB Schema
规范。如数据表的名称 建议是 xxx.schema
。如果是hbuilderX
中创建的 则是 xxx.schema.json
。文件内容如下
{
"bsonType": "object", // 固定节点
"description": "该表的描述",
"required": [], // 必填字段列表
"properties": { // 该表的字段清单
"_id": { // 字段名称,每个表都会带有_id字段
"description": "ID,系统自动生成"
// 这里还有很多字段属性可以设置
},
"field2": { // 字段2,每个表都会带有_id字段
"description": ""
// 这里还有很多字段属性可以设置
}
}
}
DB Schema有很多重要的作用:
参考设计
hm-article.schema.json
// 文档教程: https://uniapp.dcloud.net.cn/uniCloud/schema
{
"bsonType": "object",
"required": [],
"permission": {
"read": true,
"create": true,
"update": true,
"delete": true
},
"properties": {
"_id": {
"description": "ID,系统自动生成"
},
"title":{
"bsonType": "string",
"description": "文章的标题",
"title": "标题",
"minLength": 2,
"maxLength": 20
},
"thumb":{
"bsonType": "string",
"description": "文章封面大图",
"title": "封面图片",
"defaultValue":"https://cdn.slidesharecdn.com/ss_thumbnails/newspaperexamples-stllink-130526034010-phpapp02-thumbnail-4.jpg?cb=1369539652"
},
"category":{
"bsonType": "int",
"enum":[
{
"text":"全部",
"value":0
},
{
"text":"精华",
"value":1
},
{
"text":"分享",
"value":2
}
]
}
}
}
对于前端的小伙伴或者刚入门的后端工程师来说,虽然平时开发也会接触到相关数据,但是这类数据往往都是一些前辈经过实际开发经验提前设计好的。但是现
在要自己独立来设计,并不是一件简单的事情。那么我们可以借助 openDB的帮助。
openDB
,是一套开放的数据表设计规范,包括了表名、字段等schema定义以及初始数据。其中 DCloud根据常用的系统功能,设计出来几十张数据表,可以给
们提供思路或者直接使用。如
openDB
不仅支持定义常用的数据表字段,还可以预置初始化数据。
比如,opendb-city-china是opendb中定义好的中国城市字典表
,它的定义分为两个部分:
你通过uniCloud web控制台创建openDB
表时,uniCloud
会自动校验该opendb表定义中是否包含data.json
,若包含,则在创建表定义后,自动导入
data.json
。
clientDB 客户端操作数据库
先引入 uni-ui
前端页面编写以下代码,利用uniCloud对象的API进行数据库的查询
<template>
<view class="content">
<uni-table stripe emptyText="暂无更多数据">
<uni-tr>
<uni-th align="center">序号</uni-th>
<uni-th align="center">标题</uni-th>
<uni-th align="center">分类</uni-th>
<uni-th align="center">封面图片</uni-th>
<uni-th align="center">操作</uni-th>
</uni-tr>
<uni-tr v-for="(item, index) in list" :key="item._id" >
<uni-td>{{index+1}}</uni-td>
<uni-td>{{item.title}}</uni-td>
<uni-td>{{item.category}}</uni-td>
<uni-td>
<image :src="item.thumb" mode="widthFix"></image>
</uni-td>
<uni-td>
<button type="warn">删除</button>
</uni-td>
</uni-tr>
</uni-table>
</view>
</template>
<script setup>
// 获取云数据库对象引用
const db = uniCloud.database();
import {
ref
} from "vue"
const list = ref([]);
// 查询
const onGet = async () => {
const result = await db.collection("hm-article").get();
list.value = result.result.data
}
// 查询
onGet()
</script>
<style></style>
如果出现以下错误,需要这样解决 提示缺少 uni-id 配置文件
在目录新 新建 config.json
文件,复制配置,修改tokenSecret
然后刷新页面即可
云数据库支持常规的类似MongoDB语法和更加灵活的JQL*( javascript query language)*语法
// MongoDB
const result = await db.collection("hm-article").where({title:/云/}).get()
// JQL
const result = await db.collection("hm-article").where(`/云/.test(title)`).get()
// 新增
const onAdd= async () =>{
await db.collection("hm-article").add({
title:"華為鴻蒙日漸火熱"+list.value.length,
category:2,
thumb:'https://mp-c1674c18-fa0b-4181-90b2-0ffd28dd8786.cdn.bspapp.com/cloudstorage/81fffa58-caf9-4aea-97de-2525ecc51abd.jpeg'
})
}
// 修改
const onUpdate = async (_id) => {
await db.collection('hm-article').doc(_id).update({
title: ""+Date.now(),
category: 0
})
}
// 删除
const onDelete = async (_id) => {
await db.collection("hm-article").doc(_id).remove()
}
unicloud-db 数据库查询组件,可以在组件身上通过属性的方式查询数据库。
支持在在属性中指定要查什么表、哪些字段、以及查询条件
其中 该组件还提供了许多使用的方法
<template>
<view class="content">
<!-- <unicloud-db v-slot:default="{data, loading, error, options}" collection="hm-article" where="/强/.test(title)" field="title" orderby="category desc"> -->
<unicloud-db v-slot:default="{data, loading, error, options}" collection="hm-article" orderby="category desc">
<view v-if="error">{{error.message}}</view>
<view v-else>
<uni-table stripe emptyText="暂无更多数据">
<uni-tr>
<uni-th align="center">序号</uni-th>
<uni-th align="center">标题</uni-th>
<uni-th align="center">分类</uni-th>
<uni-th align="center">封面图片</uni-th>
<uni-th align="center">操作</uni-th>
</uni-tr>
<uni-tr v-for="(item, index) in data" :key="item._id" >
<uni-td>{{index+1}}</uni-td>
<uni-td>{{item.title}}</uni-td>
<uni-td>{{item.category}}</uni-td>
<uni-td>
<image :src="item.thumb" mode="widthFix"></image>
</uni-td>
<uni-td>
<button type="warn" >删除</button>
</uni-td>
</uni-tr>
</uni-table>
</view>
</unicloud-db>
</view>
</template>
<template>
<view class="content">
<!-- <unicloud-db v-slot:default="{data, loading, error, options}" collection="hm-article" where="/强/.test(title)" field="title" orderby="category desc"> -->
<unicloud-db :page-size="2" ref="refCo" v-slot:default="{data, loading, error, options}" collection="hm-article"
orderby="category desc">
<view v-if="error">{{error.message}}</view>
<view v-else>
<uni-table stripe emptyText="暂无更多数据">
<uni-tr>
<uni-th align="center">序号</uni-th>
<uni-th align="center">标题</uni-th>
<uni-th align="center">分类</uni-th>
<uni-th align="center">封面图片</uni-th>
<uni-th align="center">操作</uni-th>
</uni-tr>
<uni-tr v-for="(item, index) in data" :key="item._id">
<uni-td>{{index+1}}</uni-td>
<uni-td>{{item.title}}</uni-td>
<uni-td>{{item.category}}</uni-td>
<uni-td>
<image :src="item.thumb" mode="widthFix"></image>
</uni-td>
<uni-td>
<button type="warn">删除</button>
</uni-td>
</uni-tr>
</uni-table>
</view>
</unicloud-db>
</view>
</template>
<script setup>
import {
ref
} from "vue"
import {
onReachBottom
} from "@dcloudio/uni-app"
const refCo = ref(null)
// 分頁事件
onReachBottom(() => {
refCo.value.loadMore()
})
</script>
<style></style>
<template>
<view class="content">
<!-- <unicloud-db v-slot:default="{data, loading, error, options}" collection="hm-article" where="/强/.test(title)" field="title" orderby="category desc"> -->
<unicloud-db :page-size="2" ref="refCo" v-slot:default="{data, loading, error, options}" collection="hm-article"
orderby="category desc">
<view v-if="error">{{error.message}}</view>
<view v-else>
<uni-table stripe emptyText="暂无更多数据">
<uni-tr>
<uni-th align="center">序号</uni-th>
<uni-th align="center">标题</uni-th>
<uni-th align="center">分类</uni-th>
<uni-th align="center">封面图片</uni-th>
<uni-th align="center">操作</uni-th>
</uni-tr>
<uni-tr v-for="(item, index) in data" :key="item._id">
<uni-td>{{index+1}}</uni-td>
<uni-td>{{item.title}}</uni-td>
<uni-td>{{item.category}}</uni-td>
<uni-td>
<image :src="item.thumb" mode="widthFix"></image>
</uni-td>
<uni-td>
<button type="warn">删除</button>
</uni-td>
</uni-tr>
</uni-table>
</view>
</unicloud-db>
</view>
</template>
<script setup>
import {
ref
} from "vue"
import {
onReachBottom,
onPullDownRefresh
} from "@dcloudio/uni-app"
const refCo = ref(null)
// 下拉 事件
onPullDownRefresh(() => {
refCo.value.loadData({
clear: true //可选参数,是否清空数据
}, () => {
uni.stopPullDownRefresh()
})
})
onReachBottom(() => {
refCo.value.loadMore()
})
</script>
<style>
image {
/* width: 200rpx; */
}
</style>
组件实例.add(value, options)
利用组件示例方法 add 即可实现新增
// 新增
const onAdd = async () => {
await refCo.value.add({
title: "華為鴻蒙日漸火熱" + refCo.value.dataList.length,
category: 2,
thumb: 'https://mp-c1674c18-fa0b-4181-90b2-0ffd28dd8786.cdn.bspapp.com/cloudstorage/81fffa58-caf9-4aea-97de-2525ecc51abd.jpeg'
})
refCo.value.loadData({
clear: true //可选参数,是否清空数据
})
}
组件实例.update(id, value, options)
// 修改
const onUpdate = async (_id) => {
await refCo.value.update(_id, {
title: "" + Date.now(),
category: 2,
thumb: 'https://mp-c1674c18-fa0b-4181-90b2-0ffd28dd8786.cdn.bspapp.com/cloudstorage/81fffa58-caf9-4aea-97de-2525ecc51abd.jpeg'
})
refCo.value.loadData({
clear: true //可选参数,是否清空数据
})
}
组件实例.remove(id, options)
// 刪除
const onDelete = async (_id) => {
const {
confirm
} = await
uni.showModal({
content: '您確定刪除嗎'
});
if (confirm) {
await refCo.value.remove(_id)
refCo.value.loadData({
clear: true //可选参数,是否清空数据
})
}
}
开发者使用uniCloud
的云存储,无需再像传统模式那样单独去购买存储空间、CDN映射、流量采购
云存储的上传方式有3种:
uniCloud.uploadFile
,或者使用uni ui的FilePicker组件,文件选择+上传均封装完毕。uniCloud.uploadFile
const onUpload = async () => {
//前端代码 // 注意小程序和h5端 選擇文件的api
uni.chooseImage({
count: 1,
success:async(res) =>{
if (res.tempFilePaths.length > 0) {
let filePath = res.tempFilePaths[0]
//进行上传操作
const result = await uniCloud.uploadFile({
filePath: filePath,
cloudPath: 'a.jpg'
});
}
}
});
}
文件选择上传组件,可以选择图片、视频等任意文件并上传到当前绑定的服务空间
<uni-file-picker fileMediatype="image"/>
云函数是运行在云端/后端的 JavaScript
代码,是基于 Node.js
的扩展。
在常规的 Node API
基础上,uniCloud的云函数环境内置了uniCloud
对象,这个对象内置了网络、数据库等各种
API。开发者未学习过 Node.js
也没有关系,只需要看uniCloud的文档,掌握这个uniCloud
对象的API即可
新建云函数 在 uniCloud/cloudfunctions
鼠标右键 云函数名称是 hello
修改云函数代码
'use strict';
exports.main = async (event, context) => {
//event为客户端上传的参数
console.log('event : ', event)
//返回数据给客户端
return {event,msg:"来自云函数的问候"}
};
云函数模拟调用
客户端调用云函数
const onCall = async () => {
const result = await uniCloud.callFunction({
name: "hello"// 云函数的名字
})
console.log(result);
}
'use strict';
exports.main = async (event, context) => {
const dbJQL = uniCloud.databaseForJQL({ // 获取JQL database引用,此处需要传入云函数的event和context,必传
event,
context
})
const result = await dbJQL.collection('hm-article').get() // 直接执行数据库操作
return result
};
云函数也可以直接调用其他接口来获取数据的。类似是服务器对服务器进行数据交互
在当前云函数目录下打开终端, 安装 axios
npm i axios
使用 axios
'use strict';
const axios = require("axios") // 注意需要使用 commonjs 規範
exports.main = async (event, context) => {
const result = await axios.get('https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata');
return result.data
};
云对象可以更加方便的帮我们把一个云函数的不同功能独立出来,方便管理。
比如服务端编写一个云对象todo,该对象有add、get、remove、update等方法。客户端的js则可以直接import这个todo云对象,直接调用add等方法。
新建云对象 helloObj
编写代码
module.exports = {
add(title, content) {
return {
errCode: 0,
errMsg: '创建成功'
}
},
remove(id) {
// ....
return {
errCode: 0,
errMsg: '刪除成功'
}
}
}
客户端直接调用
const helloObj = uniCloud.importObject('helloObj') //第一步导入云对象
const onCallCloudObj = async () => {
const result = await helloObj.add('新增',"內容")
console.log(result);
}
根据数据表描述生成前端后端一体代码
DB Schema 在设置字段时,已经包含了大量相关信息,这些信息可以用来生成前端、后端一体代码 (crud) 。如
hm-article.json
// 文档教程: https://uniapp.dcloud.net.cn/uniCloud/schema
{
"bsonType": "object",
"required": ["title"],
"permission": {
"read": true,
"create": true,
"update": true,
"delete": true,
"count": true
},
"properties": {
"_id": {
"description": "ID,系统自动生成"
},
"title": {
"bsonType": "string",
"description": "文章的标题",
"label": "姓名",
"minLength": 2,
"maxLength": 20,
"errorMessage": {
"required": "{label}必填",
"minLength": "{label}不能小于{minLength}个字符"
}
},
"thumb": {
"bsonType": "file",
"description": "文章封面大图",
"title": "封面图片"
},
"category": {
"bsonType": "int",
"enum": [{
"text": "全部",
"value": 0
},
{
"text": "精华",
"value": 1
},
{
"text": "分享",
"value": 2
}
]
}
}
}
鼠标选中要生成 增删改查的数据表 ,点击生成代码即可
此时如果没有数据,需要先自己在数据表中插入一些数据。可以在web控制台直接插入数据。
uni实人认证依赖 HBuilderX 3.7.6+,目前仅支持App平台。
人脸识别是一种比普通的手机验证码、账号密码更加安全的登录方式,适用在更加敏感的场合。人脸识别主要是识别 摄像头前活动的人脸,与姓名和身份证号是
否匹配
新建云对象 faceVerifyObj
添加公共 uniCloud 拓展库
编辑代码
module.exports = {
_before() { // _before是云对象中每个方法运行前都会执行的方法
this.frvManager = uniCloud.getFacialRecognitionVerifyManager({
requestId: this.getUniCloudRequestId() // 获取当前请求id
})
},
// 获取CertifyId
// metaInfo 设备信息
// realName 用户真实姓名
// idCard 身份证号码
async getCertifyId(metaInfo, realName, idCard ) {
const result = await this.frvManager.getCertifyId({
realName,
idCard,
metaInfo: JSON.stringify(metaInfo)
})
return result
},
// 验证当前Certify是否有效 验证人脸是否通过
async getAuthResult(certifyId) {
const result = await this.frvManager.getAuthResult({
certifyId
})
return result
}
}
const onCheckface = async () => {
try {
// 获取实人认证设备信息
const metaInfo = uni.getFacialRecognitionMetaInfo();
// 调用云函数 获取人脸设备信息
const result = await faceVerifyObj.getCertifyId(JSON.parse(metaInfo),"用户名","身份证")
// 调起人脸识别
await uni.startFacialRecognitionVerify({
certifyId: result.certifyId,
progressBarColor: "#CC0000", //刷脸圈的颜色
screenOrientation: "port", //认证界面UI朝向
})
// 验证人脸识别是否通过
const res = await faceVerifyObj.getAuthResult(result.certifyId)
// {
// "errCode": 0,
// "errMsg": "",
// "authState": "SUCCESS",
// "qualityScore": 92.20459747314453, // 活体检测结果分数
// "verifyScore": 99.53412829108788 // 人脸图片质量分
// }
console.log(res);
} catch (e) {
//TODO handle the exception
console.log(e);
}
}
注意
certifyId
后,仅在24
小时内可正常调用getAuthResult
接口获取认证结果,超过24
小时后请求该接口将返回56001 请求记录已过期
错误。certifyId
成功调用后,无论认证结果是否匹配,都仅可再调用5
次getAuthResult
接口获取认证结果,超过5
次后请求该接口将返回56002 请求次数已超限
错误。pictureUrl
照片地址有效期为15
分钟,从查询时开始计时,如有存储需求请尽快处理。