继“今天在北航吃什么”后,隆重推出:“今天在北航做什么”!
| 描述 | 进度 | 备注 |
|---|---|---|
| 完成message的所有接口 | 完成 | |
| 对照前端设计,再核对一遍接口 | 完成 | |
| 对关系的设计模式进行一定的调整 | 完成 | |
| 研究请求携带token的具体机制 | 完成 | |
| 调通登录的接口 | 完成 | |
| 对所有接口进行测试 | 完成 | |
| 对所有接口进行核对 | 完成 | |
| 考虑扩展性功能 | 完成 | |
| 对图床功能进行调试 | 完成 | |
| 上传头像接口 | 完成 | |
| 对代码进行优化:优化import、优化内部逻辑 | 完成 | |
| 连接GaussDB | 完成 | |
| 更新requirements.txt | 完成 | |
| 持续调优 | 未完待续 |
修改Calendar/settings.py中的DEVELOP = False
- develop模式下使用本地的数据库sqlite3
- 生产模式下使用GaussDB
访问GaussDB后台可以访问网址,选择数据库/数据管理服务DRS,登录相应的数据库进行数据管理
所有上传图片的逻辑为:
- 前端将图片附在request的FILE中,直接传到后端
- 后端将文件上传到图床,向前端返回一个图片地址
前端的请求格式为:
<div>
<input type="file" @change="onFileChange" style="display: none;" ref="fileInput">
<button class="upload-button" @click="triggerFileUpload">上传头像</button>
</div>
<script>
triggerFileUpload() {
this.$refs.fileInput.click();
},
onFileChange(event) {
const file = event.target.files[0];
if (file) {
const formData = new FormData();
formData.append('img', file);
// 上传文件到服务器
apiClient.post('.../update-avatar/', formData)
.then(response => {
this.user.avatar = response.data.avatar;
})
.catch(error => {
console.error('Error uploading file:', error);
});
}
},
</script>数据库大作业 BUAA_Calendar 项目的后端
采用 Django 作为项目框架, python版本选用了python3.10
# 安装相关依赖
conda create --name buaa_calendar python=3.10
pip install -r requirements.txt
# 进入项目目录
cd Calendar
# 启动后端
python manage.py runserver账号:root
密码:123456
访问管理网站:http://127.0.0.1:8000/admin
以ER图为例:
共计8个实体:
- 用户User
- 任务Task
- 活动Activity
- 班级Class
- 标签Tag
- 消息Message
- 关系抽象TaskUserRelationship
- 关系抽象ActivityUserRelationship
见:https://apifox.com/apidoc/shared-f18b70f2-bf84-4766-aa28-9a466ddd0c11
| 返回码数字 | 返回码名称 | 返回码描述 |
|---|---|---|
| 0 | 操作成功 | 一切正常,没有发生错误 |
| 101 | 登录错误 | 用户名不存在或密码错误 |
| 102 | 登录错误 | 用户选择了自己不具有的角色权限 |
| 103 | 注册错误 | 用户名被占用 |
| 104 | 注册错误 | 邀请码错误 |
| 201 | 角色错误 | 指定的用户操作不符合用户的角色,用户主动非法访问不属于这个错误 |
| 301 | 活动参加状态错误 | 学生试图参加一个已经参加了的活动 |
| 302 | 活动参加状态错误 | 学生试图退出一个没有参加的活动 |
| 401 | 学生所处班级状态错误 | 学生已经在这个班级中了 |
| 402 | 学生所处班级状态错误 | 学生不在这个班级中 |
| 403 | 老师管理班级状态错误 | 老师已经管理这个班级 |
| 404 | 老师管理班级状态错误 | 老师没有管理这个班级 |
| 501 | 标签操作不合法 | 固定标签不可修改或删除 |
| 502 | 标签绑定状态不合法 | 标签已经绑定了活动/任务 |
| 503 | 标签绑定状态不合法 | 标签还没有绑定了活动/任务 |
| 901 | 杂项 | 当一个接口接收一个 array 并执行多项重复操作时,返回 901 意味着至少有一项出现错误 |
| 902 | 杂项 | 请求指定的用户 ID 不存在 |
| 903 | 杂项 | 请求指定的班级 ID 不存在 |
| 904 | 杂项 | 请求指定的活动 ID 不存在 |
| 905 | 杂项 | 当前用户下指定的消息 ID 找不到 |
| 906 | 杂项 | 当前用户下指定的标签 ID 找不到 |
| 907 | 杂项 | 请求指定的任务 ID 不存在 |
目前为在用户视角的接口
- 登录
- 查看个人信息
- 修改个人信息
- 请求任务、请求活动
-
查询:
{ <class-id>: { <task-id>: {"": ""}}} -
查询公共活动
-
选择参与活动
-
退出某项活动
-
调整任务完成度
-
设置任务提醒
-
接受消息:
{ <message-id>: { "titile": <str>, "from": <str>, "time": <int>, "content": <str>, "unread": <bool> } } -
阅读消息
-
查询所有tag列表
-
修改tag和任务的绑定关系
-
修改tag和活动的绑定关系
- 查询管理的班级,包括任务
- 向班级发放任务
- 修改针对班级发放的任务
- 向学生发放任务
- 向班级广播消息
- 向学生发送消息
- 管理班级(将学生添加至班级)
- 管理班级(将学生从班级删除)
- 创建班级
- 给班级添加老师
- 从班级删除老师
- 给班级添加学生
- 从班级删除学生
- 发放集体任务
- 广播消息
- 创建活动
- 修改活动
- 重置用户密码
在实际的场景,任务往往不能单步完成,需要在一个任务中分为多步,即多个子任务。每一个子任务也会有单独的内容、时间约束等等。
为了实现这一关系,后端采用了父子关系的思路进行建模,为每个任务设计了唯一的父任务,每个任务相应的可以有多个子任务,利用任务这一实体指向自身的外键实现了该效果。
随着任务场景的扩展,用户的信息也会相应扩展,目前User支持的自定义属性包括了头像、邮箱、个性签名、电话等多种属性。
并且,为了缓解对服务器的存储压力,将头像设计为了使用外部云数据库的图床COS存储,设计了自动存储到腾讯云COS图床的相应接口,实现了图片文件上传后自动转为相应的图传链接。
任务的定时提醒机制有两个,一种是前端进行轮询,定时发送请求驱动后端进行检查;另一种则是后端进行定时检查。尽管可以使用Celery和Redis等成熟框架进行设计,但是本项目为了降低开发难度,使用了“操作驱动型”的设计思想:即用户进行操作时会触发对DDL的检查,不触发时自然无法查看,也就不用查询。
当前端有请求时,会触发后端进行一次检查,并将发送相应的Message,当前端进行获取信息集合的请求时,就会收到该请求。
任务支持用户自定义,但是有一些公共的Tag,如学校发布的任务、集体活动等却是公共的Tag,为此,后端将Tag、抽象为了被用户群体所共享。通过额外设计的Model:TagUserRelationship单独建模了用户与Tag之间的关系,这样可以实现用户对公用Tag的别名、自定义颜色修改等功能。
随着功能的复杂,原有的简单无关无法满足设计。即数据库的关系约束进行了限制。
为了达到3NF的设计出发点,对关系进行了高级抽象,是的可以实现如下功能:
- 对于一个共享任务,多个user可以分别设置属性
- 对于用户和实体之间的关系进行了再一层的抽象,包括任务别名、权限管理、完成情况等,能够支持对任务和用户之间关系的更灵活处理。
