Unit3 使用 uniCloud 制作书籍管理移动端应用项目
-
- [1 构建项目并关联云服务空间](#1 构建项目并关联云服务空间)
- [2 为项目准备数据库表](#2 为项目准备数据库表)
- [3 schema2Code](#3 schema2Code)
- [4 遇到了错误](#4 遇到了错误)
- [5 对 "addtime" 字段对应的前端组件进行修改](#5 对 "addtime" 字段对应的前端组件进行修改)
- [6 美化列表页](#6 美化列表页)
- 操作视频
1 构建项目并关联云服务空间
- uniCloud 为开发人员提供了"阿里云"和"腾讯云"两种云服务空间供应商。其中"阿里云"可以创建一个免费的云服务空间,"腾讯云"不提供免费服务。
- 不管是"阿里云"还是"腾讯云",如果要使用云服务功能,都必须进行实名制认证。
- "阿里云"的免费云服务空间有效期是 1 个月,如果需要延长免费使用时间,需要在临到期之前继续以 0 元支付该空间的费用,否则将失去"免费"资格,只能创建付费的云服务空间。
以下是构建一个新的项目,并与uniCloud云服务空间关联的操作步骤。
1\] 新建一个 uni-ui 项目 uniCloudBooks,并启用 uniCloud。

\[2\] 项目创建后,在项目管理器中"右键单击" uniCloud 目录,在弹出的快捷菜单中选择 "关联云服务空间或项目"。

\[3\] 初次使用 uniCloud 时,由于并没有任何云服务空间,所以在 "关联云服务空间或项目"窗口中看到的列表项应该是空的。需要点击窗口上的"新建"按钮,进入新建云服务空间页面。

\[4\] 进入 uniCloud 控制台页面,点击 "新建服务空间" 按钮。

\[5\] 免费的阿里云服务空间

\[6\] 在 HX 中完成云服务空间与项目之间的关联

### 2 为项目准备数据库表
一本书的信息应该包含(但不限于):书名、作者、出版社、封面照片、单价、内容简介等。
为了让小程序更加适用于一个线下书店对所有图书的管理功能,这里可以考虑增加 "剩余数量" 和 "购置日期"两个信息。
uniCloud 的云数据库是一个基于 JSON 格式的文档型数据库。官网的介绍如下:

以下是在 HX 中创建数据库表文件的操作步骤。
\[1\] 新建DB Schema

\[2\] 选择 default 模板创建 DB Schema 文件

\[3\] 一个基本的数据库表文件结构
```json
{
"bsonType": "object",
"required": [],
"permission": {
"read": true,
"create": true,
"update": true,
"delete": true
},
"properties": {
"_id": {
"description": "ID,系统自动生成"
}
}
}
```
在 uniCloud 的云数据库中,使用 json 格式的数据来描述一个数据库表的表结构。其中:
* `"bsonType"` 表示当前是一个表对象实例。
* `"required"`表示在 "properties" 项里定义的哪些字段是必填项。
* `"permission"` 表示可以在当前的数据库表实例上进行"增、删、改、查"的权限,默认创建时全是"false"
* `"properties"` 表示这里是表字段的描述。默认情况自动创建了"主键"字段 "_id"。该字段不可删除和修改。用户需要添加的其他字段也都写在这里。
\[4\] 该项目的数据库表文件 mybooks.schema.json
```json
{
"bsonType": "object",
"required": ["book_name","authors","publisher","classify","count","price"],
"permission": {
"read": true,
"create": true,
"update": true,
"delete": true
},
"properties": {
"_id": {
"description": "ID,系统自动生成"
},
"book_name": {
"bsonType": "string",
"minLength": 1,
"maxLength": 50,
"title": "书籍名称"
},
"authors": {
"bsonType": "string",
"minLength": 1,
"maxLength": 50,
"title": "作者"
},
"publisher": {
"bsonType": "string",
"minLength": 1,
"maxLength": 50,
"title": "出版社"
},
"classify": {
"bsonType": "string",
"enum": [
{"text": "小说", "value": "novel"},
{"text": "科技", "value": "technology"},
{"text": "生活", "value": "life"},
{"text": "社科", "value": "society"},
{"text": "经济", "value": "economic"},
{"text": "传记", "value": "biography"},
{"text": "历史", "value": "history"},
{"text": "儿童", "value": "children"}
],
"componentForEdit": {
"name": "uni-data-select",
"props": {
"placeholder": "请选择分类"
}
},
"title": "分类"
},
"book_cover": {
"bsonType": "file",
"fileMediaType": "image",
"fileExtName": "jpg,png",
"title": "封面"
},
"count": {
"bsonType": "int",
"minimum": 0,
"title": "余量"
},
"price": {
"bsonType": "int",
"minimum": 0,
"title": "单价(分)"
},
"brief": {
"bsonType": "string",
"minLength": 3,
"maxLength": 200,
"componentForEdit": {
"name": "uni-easyinput",
"props": {
"type": "textarea"
}
},
"title": "简介"
},
"addtime": {
"bsonType": "timestamp",
"forceDefaultValue": {
"$env": "now"
},
"componentForShow": {
"name": "uni-dateformat"
},
"title": "购置时间"
}
}
}
```
【说明】:
* `"properties"` 项中定义了数据表所需要的9个字段。
* `"book_name"` 字段存放的是书籍名称,字符串型,长度在 1 \~ 50 个字符之间。
* `"authors"` 字段存放的是书籍作者,字符串型,长度在 1 \~ 50 个字符之间。
* `"publisher"` 字段存放的是出版社名称,字符串型,长度在 1 \~ 50 个字符之间。
* `"classify"` 字段存放的是书籍的种类,字符串型。
* 这里用到了 `"enum"` 属性,表示这个字段的数据值是在 `"enum"` 中所列内容中的其中一个。
* 搭配的 `"componentForEdit"` 属性,表示在对该数据进行编辑使,使用什么样的前端组件进行展示。这里使用的是数据下拉选择器组件 `"uni-data-select"`。
* `"book_cover"` 字段用于存放书籍封面图片的信息,这里用的是 file 类型,有关使用 file 类型设置图片信息的示例可以参考官网的说明。

* `"count"` 字段用于存储书籍的数量,int 类型,最小值为 0。
* `"price"` 字段用于存储书籍的单价,int 类型,最小值为 0。因为在 JavaScript 中 double 数据类型在计算时容易出现误差,因此建议使用"分"为单位进行价格数据的存储。这个可以看下图中官网的解释。

* `"brief"` 字段用于存储书籍的简介,字符串类型,长度在 3 \~ 200 之间。因为简介内容比较多,用单行文本输入框不合适,因此使用 `"componentForEdit"` 属性指定了前端组件 `"uni-easyinput"` 为多行文本框。
* `"addtime"` 字段用于存储当前这条记录添加到数据库表的时刻,用的是 timestamp 类型(时间戳)。针对这种数据官方的解释说明见下图:

\[5\] 上传 DB Schema

上传成功后,在 HX 的控制台调试窗口中会显示:"上传数据集合Schema(mybooks.schema.json)成功" 的字样。
在 uniCloud 的 Web 控制台中,看到云数据库中已经有了一个与本地的 mybooks 一模一样的表文件。

### 3 schema2Code
关于 schema2code 官网的介绍如下:

以下是对创建好的表文件 mybooks.schema.json 执行 schema2code 的操作步骤。
\[1\] 对表文件执行 schema2code

\[2\] 在数据表文件上右键后,选择"schema2code",注意在下图中一定要全选所有字段后,点击"确定"按钮。

如果弹出来提示说未安装XX插件的话,那就直接点击安装即可。
\[3\] schema2code 的过程会稍微长一些,等待一下,会询问是否需要把页面合并注册的提示。一定要选择"注册"

\[4\] 之后会询问是否将文件进行合并,下图一定要选"合并"。

\[5\] 一切结束后,在 HX 的项目管理器窗口中会看到 schema2code 自动生成的四个页面。

### 4 遇到了错误
以下的问题主要是由 HX 的版本问题引起的,如果开发过程中没有遇到,可以忽略这里。
\[错误1\] 提示 "未安装公共模块"
在 HX 的编辑器打开 list.vue 页面后,点击"预览"按钮,在 HX 的内置浏览器中"第一次"运行时,会报"未找到公共模块\[uni-id-common\]"的错误,见下图:

参考下图的指引,下载所有云函数、公共模块及actions

\[错误2\] Invaild uni-id config file
当执行完"下载所有云函数、公共模块及 action"后,再次运行 list.vue 页面,报错:"Invalid uni-id config file"。

这种情况就需要手动创建 uni-id 目录及 config.json 文件,在 uniCloud/cloudfunctions/common/uni-config-center/ 目录下新建 uni-id 目录,并继续创建 config.json 文件。

上述代码从https://uniapp.dcloud.net.cn/uniCloud/uni-id-summary.html#config 页面上找到文件源码,直接按照官网提示复制文件内容。
【重要提示】:
* json 文件不支持注释语句,一定要把所有的注释代码删掉。
* `"tokenSecret"` 项必须填写,自己拟定一个比较长的字符串即可。
config.json 示例代码如下:
```json
{
"passwordSecret": [
{
"type": "hmac-sha256",
"version": 1
}
],
"passwordStrength": "medium",
"tokenSecret": "sjzceducnuniapp2023mobileapplicationdevelopclass",
"requestAuthSecret": "",
"tokenExpiresIn": 7200,
"tokenExpiresThreshold": 3600,
"maxTokenLength": 10,
"passwordErrorLimit": 6,
"passwordErrorRetryTime": 3600,
"autoSetInviteCode": false,
"forceInviteCode": false,
"idCardCertifyLimit": 1,
"realNameCertifyLimit": 5,
"sensitiveInfoEncryptSecret": "",
"frvNeedAlivePhoto": false,
"userRegisterDefaultRole": [],
"app": {
"tokenExpiresIn": 2592000,
"tokenExpiresThreshold": 864000,
"oauth": {
"weixin": {
"appid": "",
"appsecret": ""
},
"qq": {
"appid": "",
"appsecret": ""
},
"apple": {
"bundleId": ""
}
}
},
"web": {
"tokenExpiresIn": 7200,
"tokenExpiresThreshold": 3600,
"oauth": {
"weixin-h5": {
"appid": "",
"appsecret": ""
},
"weixin-web": {
"appid": "",
"appsecret": ""
}
}
},
"mp-weixin": {
"tokenExpiresIn": 259200,
"tokenExpiresThreshold": 86400,
"oauth": {
"weixin": {
"appid": "",
"appsecret": ""
}
}
},
"mp-qq": {
"tokenExpiresIn": 259200,
"tokenExpiresThreshold": 86400,
"oauth": {
"qq": {
"appid": "",
"appsecret": ""
}
}
},
"mp-alipay": {
"tokenExpiresIn": 259200,
"tokenExpiresThreshold": 86400,
"oauth": {
"alipay": {
"appid": "",
"privateKey": "",
"keyType": "PKCS8"
}
}
},
"service": {
"sms": {
"name": "",
"codeExpiresIn": 180,
"smsKey": "",
"smsSecret": "",
"scene": {
"bind-mobile-by-sms": {
"templateId": "",
"codeExpiresIn": 240
}
}
},
"univerify": {
"appid": "",
"apiKey": "",
"apiSecret": ""
}
}
}
```
故障排除,预览正常

### 5 对 "addtime" 字段对应的前端组件进行修改
schema2code 自动生成的前端页面有些组件的选配不是很智能,需要手动进行一下调整。这里仅仅以 "addtime" 字段对应生成的组件进行调整。其他页面中前端组件的显示效果,可以根据实际需要进行美化或重新布局。
"addtime" 字段在定义时选择的类型是 timestamp 时间戳,且设置了强制默认值为当前的系统时间,而这种数据本身以长整型的形式存储,在查看该数据时需要对其使用专门的组件 uni-dateformat 来实施。
以下就是对涉及到的三个页面的修改步骤。
\[1\] 在 HX 中打开 pages/mybooks/add.vue 页面,在页面源码中找到以下代码,将其删除。
```html