团队项目技术规格说明书

简述

概述

  • 根据网站的需求,我们团队在经过网上调研比较之后,决定使用bootstrap作为前端开发框架,Django作为后端服务器开发框架。选用MySQL作为数据库。在开发阶段使用sqlite作为临时的数据库。

前端技术

  • 我们团队选择了bootstrap作为前端框架。一方面由于其文档教程较为丰富,另一方面在于其社区活跃,使用的人多。遇到困难能够更轻松地解决。我们还选择了pingendo的IDE,帮助我们可视化开发前端,现有模板帮助我们省去不必要的工作。

后端技术

  • 我们团队比较了基于Java的spring,基于python的web.py和Django,以及php的后端开发框架。调研发现spring框架学习周期长,而php这一门语言我们并不了解。Python语言团队成员都较为熟悉。Web.py一方面功能并不强大,且不支持Python3,所以我们最终选择了Django。这一框架学习周期较短,且功能完善,社区活跃,开发文档也很丰富。

前端技术规格

页面之间联系

  • 前端分为主页,搜索结果页面,课程详细信息页面,添加评分评论页面四个部分。关系如下图:

各页面布局

  • 此处只列出简略的页面布局,更加精细的布局原型在功能规格说明书中展示:

后端技术规格

数据库结构规格

  • 数据库中需要存储学校,院系,课程,教师,用户,评价记录,评分记录7个实体,且实体之间存在联系,实体也包含其属性。联系属性如下图所示:

关于一些数据格式的说明

  • 用户的用户名不能出现重复。一旦确定不能修改。邮箱不能重复,邮箱验证在beta阶段实现。用户权限暂分为完全权限和禁言两种。
  • 评价记录呈树状结构生长。标签可以为空,其他的必须完整。
  • 课程中的课程简介和课程编号可以为空。
  • 教师信息中教师姓名,所属院系不能为空。
  • 院系中院系名和所属学校不能为空。
  • 课程信息的获取途径
  • 在教务网站中爬取。经测试,可以使用JavaScript在网页上爬取信息。
  • 在前端提供用户补充课程信息的接口。

前后端接口规格

POST和GET规格

  • GET:
    • 搜索:/search/?school=[schoolName]&keyword=[input words]返回搜索结果页面

    • 课程详细:/course/[course id]返回课程详细页面

    • 主页:/index/返回主页

  • POST:
  1. 登录:/signIn
传入 username string
password string
传出 statCode int 0表示成功,-1表示用户名不存在,-2表示密码错误,-3表示未知错误
username string
neckname string
  1. 注册:/signUp
传入 username string
mail string
password string
传出 statCode int 0表示成功,-1表示用户名重复,-2表示邮箱重复,-3表示未知错误
  1. 发表评论:/course_addComment
传入 username string
content string
parentId int 如果为空表示没有,id就是隐藏起来的。现阶段会一直为空。
courseId int
传出 statCode int 0表示成功,-1表示用户名不存在,-2表示父评论不存在,-3表示未知错误
  1. 发表评分/course_addRate
传入 username string
rate int[] 表示评分数组。
courseId int
传出 statCode int 0表示成功,-1表示用户名不存在,-2表示评分格式不合法,-3表示未知错误

网页模板使用的字典规格

  • 需要填写模板的网页只有主页,搜索结果页面和课程详细信息页面
  1. 主页

    {
    	"schoolNameList": [xxx, xxx, xxx] // a list of school name
    	// 在确定搜索范围时会用到
    }
    
    
  2. 搜索结果页面

    {
    	"courseList": [
    		{
    			"courseName": // string type
    			"courseNumber": // string type
    			"courseIndex": // int type
    			"teachers": [...] // teacher names, string type
    			"departmentName": // string type
    			"description": // string type, can be null
    			"overAllRate": // float type
    			"commentCount": // number of comments, int
    		},
    		...
    	]
    	// 这里xxxIndex是用来填到跳转页面部分的。例如:
    	// 《a href="/course/{{ courseIndex }}"》courseName《/ a》
    }
    
  3. 课程详细页

    {
    	"courseName": // string type
    	"courseNumber": // string type
    	"courseIndex": // int type
    	"description": // string type
    	"credit": // int type
    	"courseType": // string type, 例如专业课,核心通识之类的分类
    	"department": {
    		"departmentName": // string type
    		"departmentIndex": // int type
    	}
    	"teachers": [
    		{
    			"teacherName": // string type
    		},
    		...
    	]
    	"comments": [
    		{
    			"userName": // string type
    			"time": // string type
    			"content": // string type
    			"commentIndex": // int type
    		}
    	]
    	"rates": [
    		{
    			"aspect": // rating aspect, string
    			"value": // value of rate, float
    			"count": // how many peaple rate it, int
    		},
    		...
    	]
    }
    

接口规格更新说明

  • / or /index 得到网站首页

  • /search

    method: get
    data: {
        keywords:
        school:(可选)
        department:(可选)
    }
    response: 搜索结果页面searchResult.html
    
  • /course/<course_number>

    response: 课程详细信息页面CoursePage.html
    templates: {
        'course_name':
        'course_credit':
        'course_profession':
        'course_type':
        'course_scores':
        'detail_names': // name of detail rate subject
        'detail_scores': // list of scores
        'course_website':
        'profession_website':
    }
    
  • course/<course_number>/rate

    response: 课程评分页面ratePage.html
    templates: {
        'course': {
            'name':
            'school':
            'department':
        },
        'detail_names':
    }
    
  • use/<usename>

    method: post
    data: {
        password: (可选)
    }
    response: 用户信息页面userPage.html
    templates: {
        'userName':
        'userimgurl':
        'assessments': [
            {
                'courseName':
                'course_id':
                'content':
                'time':
                'likeCount':
                'commentCount':
            }
            ...
        ]
        'discussions': [
            {
                'userName':
                'userimgurl':
                'course_id':
                'content':
                'time':
                'title':
                'originalContent':
                'newmsg':
            }
            ...
        ]
    }
    
  • /signIn

    method: post
    data: {
        'username':
        'password':
    }
    response: {
        'statCode':
        'username':
    }
    
  • /signUp

    method: post
    data: {
        'username':
        'mail':
        'password':
    }
    response: {
        'statCode':
        'username':
    }
    
  • /active/<active_code>

    response: {
        'statCode':
    }
    
  • /submitComment

    method: post
    data: {
        'username':
        'comment':
        'rate':[]
        'course_number':
        'anonymous':
        'term':
        'thacher':[]
    }
    response: {
        'statCode':
    }
    
  • /submitDiscuss

    method: post
    data: {
        'username':
        'discuss':
        'comment_id':
    }
    response: {
        'statCode':
    }
    
  • /getSchool

    method: get
    response: {
        'school':
    }
    
  • /getDepartment

    method: get
    data: {
        'school':
    }
    response: {
        'department':
    }
    
  • /getComment

    method: get
    data: {
        'username':
        'course_number':
    }
    response: {
        'comments': [
            {
               'userName':
               'text':
               'iTerm':
               'iTotal':
               'iId':
               'isSelf':
               'snum':
               'cnum':
               'support':
            }
            ...
        ]
    }
    
  • /getDiscuss

    method: get
    data: {
        'iId':
    }
    response: {
        'discusses':[
            {
                'userName':
                'text':
                'time':
                'discuss_id':
            }
            ...
        ]
    }
    
  • /getTeachers

    method: get
    data: {
        course_number:
    }
    response: {
        'teachers': 
    }
    
  • /addComment/<comment_id>

    method: get
    response: 追加评论页面addRatePage.html
    templates: {
        'course': {
            'name':
            'school':
            'department':
            'term':
            'teacher':
        }
        'originalRate':
    }
    
  • /changeComment

    method: post
    data: {
        'comment_id':
        'comment_add':
        'password':
    }
    response: {
        'statCode':
        'course_number':
    }
    
  • /delComment

    method: post
    data: {
        'comment_id':
        'passowrd':
    }
    response: {
        'statCode':
    }
    
  • /changeSupport

    method: post
    data: {
        'comment_id':
        'username':
        'passowrd':
    }
    response: {
        'statCode':
    }
    
  • /delDiscuss

    method: post
    data: {
        'discuss_id':
        'password':
    }
    response: {
        'statCode':
    }
    
posted @ 2017-10-26 16:21  弗朗明哥舞步  阅读(335)  评论(0编辑  收藏  举报