项目 | 内容 |
---|---|
这个作业属于哪个课程 | 2020春季计算机学院软件工程(罗杰 任建) |
这个作业的要求在哪里 | 团队博客作业-技术规格说明书 |
产品描述:“妈妈再也不用担心我忘交作业了!”
产品功能介绍:功能规格说明书
概述
我们的学生资源整合与作业提醒平台将通过Web搭建服务,前端框架采用Vue.js,后端框架采用Django。由于是从零开始开发,所以我们将采用增量式开发的思路,先实现基本的需求,然后再通过增加新功能的方式进行迭代。
前端框架:Vue.js
目前网络上的前端框架有非常多的可选项,主流的前端框架有Angular,React,Vue等,相对于前两者,Vue更加年轻,同时也有许多支持我们选择的优点,如简单易学、轻量高效、文档丰富等等。Vue作为渐进式JS框架,可以很好地支持自底向上的增量开发,符合我们“敏捷”的原则。此外Vue的两大核心——数据驱动与视图组件化也是支持我们选择的重要原因,数据驱动大大简化视图更新的过程,减少工作量的同时也能够为用户提供更高效的交互,视图组件化使得页面能够划分为区块进行拼接或嵌套,也使我们的开发更加高效和规整。
后端框架:Django
市面上的后端框架也琳琅满目,如基于Java的Spring Boot,基于Ruby的Ruby on Rails,基于Python的Django、Flask等等。相比于Ruby和Java,python更容易上手,开发过程更敏捷高效。Django框架拥有健全的功能模块和文档教程,可以为我们提供比较完善的开发环境和开发过程中的疑难解答。
数据库:Sqlite3/MySql
MySql是市场上较为成熟的数据库,被许多网页和程序都使用,使用上来说无论是连接还是兼容性都表现出色。至于Sqlite3是Python(Django)原生支持的数据库,所以我们设想是否需要在前期先使用简单的方式进行实现,即使用Sqlite3,后期正式发布的时候进行数据库迁移,迁移到数据库服务器上,使用MySql。
产品设计
产品数据库存储设计
- User 用户表
- user_id
- student_id
- user_name
- password_digest
- Course 课程表
- course_id
- bh_id
- course_name
- course_grade
- task 包括作业和自定义事项
- task_id
- content
- course_id: foreign key (optional)
- ddl 截止日期
- ddl_id
- time
- notification_email
- notification_time (optional)
- notification_content
- task_id (optional)
- user_course 用户选择的课程表
- user_id, course_id: primary key
抽象和模块化
Django 实现
Django是我们采用的后端框架。Django框架提供了对象关系映射器(ORM),使用它即可通过Python代码来实现数据库中对数据模型的各种操作,这些操作是面向对象的。具体来讲,Django将每一个数据库的每一个实体都封装成了一个类,类的属性即是实体的属性,还提供了不同的属性数据类型,如日期,字符等。此外,类的主码、外码等关系也可以在Django框架中定义。以Django的document中给出的demo为例:
from django.db import models
class Reporter(models.Model):
full_name = models.CharField(max_length=70)
def __str__(self):
return self.full_name
class Article(models.Model):
pub_date = models.DateField()
headline = models.CharField(max_length=200)
content = models.TextField()
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE)
def __str__(self):
return self.headline
这段代码建立了两个数据库实体:Reporter和Article。分别以一个类实现,Reporter的属性有full_name,Article的属性有pub_date,headline,content,reporter。其中reporter是外码。注意到两个类中都实现了一个__str__方法,这个方法可以在查看类中的实体是设置显示的内容(而非"object")。
经过这样的抽象封装,可以直接通过调用类中的方法来实现数据的插删改查,并且如果数据库的结构之后有改动,可以直接通过Django的migration命令来更新,方便了数据库的维护。
信息封装和隐藏
Vue.js 实现
Vue是我们采用的前端框架,它的特点在于它可以像Python的包一样,去import其他的.vue文件。因此如果将核心的方法封装在一个.vue文件中,其他项目需要用到这些方法时直接通过import包的方式去调用这些方法,而不必知道这些方法的实现具体过程,这样就实现了方法内部的信息封装和隐藏。
前后端分离
RESTful API 实现
我们的项目还使用了RESTful框架,REST指的是一组架构约束条件和原则,它规定了一组资源的接口和URI规则。规定的接口包括GET、POST、PUT和DELETE这几个HTTP请求方法,并遵循这些方法的语义。
规定了这些方法之后,前端和后端就可以利用这些方法来实现请求和返回数据。后端在开发时,需要实现RESTful API的一些接口,以从后端数据库中按要求获取数据;而前端在向后端请求数据时,只需调用后端实现好的接口,即可获得返回结果,不需要也不关心后端的数据是如何存储、如何查询的。这种框架保证了前后端的分离,并且如果前端需要增加功能时,后端只需修改或增加相应的RESTful接口供前端调用即可,也保持了良好的可扩展性。
API一览 (维护中)
# | Action | url | meaning | others |
---|---|---|---|---|
1 | post | /api/users/student_id/verify | 验证学号 | |
2 | post | /api/users/email/verify | 给绑定邮箱发送验证码 | |
3 | post | /api/users/email/verify/:uid/:verification_code | 验证邮箱验证码 | |
4 | get | /api/course/:course_id/ddls | 获取当前课程下的所有DDL | 需要验证当前用户是否有访问该课程的权限 |
5 | get | /api/user/:uid/ddls | 获取当前用户的所有DDL | |
6 | get | /api/ddls | 获取当前系统所有的DDL | 管理员权限 |
7 | get | /api/user/:uid/task/:tid | 获取指定任务的内容 | |
8 | get | /api/user/:uid/courses | 获取用户的所有课程 | |
9 | get | /api/user/:uid/tasks | 获取当前系统的所有DDL | 管理员权限 |
10 | post | /api/course/quit | 退出该课程 | |
11 | post | /api/course/apply | 申请加入课程 | |
12 | post | /api/task/:tid/alert | 对指定的任务设置提醒 | |
13 | post | /api/course/:cid/appoint | 任命某用户成为指定课程负责人 | 管理员权限 |
14 | post | /api/user/apply | 注册新用户 | |
15 | get | /api/user/:uid/info | 获取当前用户的个人信息 | |
16 | post | /api/user/:uid/modify | 修改个人信息 |
错误处理
可能的错误包括:
-
输入的信息不合法(如邮箱格式错误、学号重复等)
-
请求的后端数据不存在(如查询了一门不存在的课程id)
-
操作对象不存在(如访问了不存在的url)
其中,第1种错误属于前端的错误,在前端的vue.js框架中就提供了正则表达式的检验,可以直接检查并提示这种错误;
第2种错误属于需要前后端协同处理的,前端将用户的请求数据内容发送给后端,后端可以实现相应的接口检验数据的合法性,如果合法才能继续查询,否则返回错误代码;
第3种错误主要出现在后端,因为不存在的url需要到后端才能检查出,对于这种错误,可以返回一个错误代码或错误信息。
[End]