如何使用ssm实现基于在线开放课程的Web前端设计与实现+vue

news2024/12/26 2:15:47

@TOC

ssm746基于在线开放课程的Web前端设计与实现+vue

绪论

1.1 选题背景

当人们发现随着生产规模的不断扩大,人为计算方面才是一个巨大的短板,所以发明了各种计算设备,从结绳记事,到算筹,以及算盘,到如今的计算机,都是在无法满足生产的前提下出现的。随着计算机的发展,又出现了互联网技术。到现在为止,互联网已经发展了几十年了,在几十年的时间里就已经风靡世界。各行各业都发现了计算机的好处,计算机刚开始是军用的,后来在民用行业开始使用,到互联网时代,各种行业信息如井喷一般充斥着互联网,信息产生和传播的速度不断的提高。针对互联网的优点,结合互联网,对传统行业信息处理技术进行升级是非常有必要的。本课题对于课程信息的管理方面,开发一个在线开放课程,在信息管理方面不至于混乱,也能降低数据的出错率,数据安全方面也有了保证,该系统还有其他的优点,比如优化信息处理流程,降低信息泄露风险,减少资金投入,产出更高,让管理人员的工作更有效率等。所以说,在线开放课程是目前不可缺的,对使用者相当的重要。

1.2 选题意义

如今的年代,已经是步入信息社会了,不仅信息更新速度频繁,信息量也大,在信息时代必须有相应的处理信息的方法,如果还采用以前的结绳记事或者笔写纸记,不仅是信息录入效率上赶不上节奏,在信息检索的速度上更是让人无法承受。幸而当今社会上计算机技术发展的相当不错,可以通过计算机在信息处理上面实现自动化或者半自动化的作业,采用计算机技术,能有效的提高信息录入以及信息检索的效率,社会上相同行业之间本身就是效率高的淘汰效率低的,既然采用计算机来替代手工记录,必然是效率更高,稳定性更强,成本更低等诸多优点。针对于课程信息管理,开发一个在线开放课程不仅可以实现现代化的信息管理,也更符合现代化信息管理规范。

在实际的使用效果中,在线开放课程的意义如下:

第一点:在线开放课程的出现,就是为了提高工作人员的效率,能够在规定时间完成工作任务。

第二点:操作页面符合人体工程美学,符合日常人为操作习惯,使用友好。

第三点:区别于传统用纸张记录,提高了信息化水平。

第四点:在信息处理方面,极大的降低了人工处理成本。

1.3 研究内容

本文对系统的描述过程将按照绪论,系统开发技术,分析,设计,实现,测试等环节进行展开介绍。

绪论:本节内容主要展示研究该系统的背景和意义。

系统开发技术:本节内容主要展示该系统开发中需要使用的技术和搭建的开发环境。

系统分析:本节内容主要就是分析系统,包括性能,功能上的数据分析,也包括可行性分析等内容。

系统设计:本节内容主要就是根据系统分析的结果进行设计,主要包括功能和数据库的设计。

系统实现:本节内容主要就是通过程序编码对系统的功能进行实现,同时也对需要介绍的功能进行界面运行效果的展示。

系统测试:本节内容主要就是对系统的功能实现部分进行检测,发现系统的错误并及时纠正,让系统能够保证运行无误。

2 系统开发技术

对系统的开发需要做好准备工作,其中安装开发的工具以及学习开发中需要运用的技术都是需要提前进行的,本节内容就对开发中运用的工具还有技术进行阐述。

2.1 MySQL数据库

本设计用到的数据库就是MySQL数据库,之所以用到这个数据库的原因很多。首先,从满足功能需求上面来讲,MySQL是符合的;其次,从学习程度来讲,MySQL相比其他数据库不管是从安装还是使用上面来讲,都比较简单,最重要的是学习起来相当便捷,比较容易入手;再次,MySQL数据库对电脑要求不高,不管是什么样的电脑都可以安装MySQL数据库,并且并不会对电脑性能造成过多的影响。所以,就平常普普通通的电脑就可以作为开发用的电脑,不需要进行额外的电脑升级。虽然自从MySQL数据库被Oracle数据库收购后,有了一些闭源的风险,但是使用者还是很多,MySQL数据库目前的开发人员已经超过五百人了,对数据库开发者来讲已经是一个很大的开发团队了。MySQL在使用上面来讲,普通的增删改查操作已经可以满足大部分业务需求,像一些数据导出导入,以及一些函数,都可以满足一些不同的需求,最重要的是MySQL数据库可以创建索引,可以大大的提高数据的查询效率,当然,物极必反,如果因为索引好用而滥用,索引弄得比数据库表还要多,这样会造成MySQL数据库更新表数据时候的运行效率。总而言之,MySQL数据库在本次设计的使用上,是完全符合使用要求的。

2.2 IDEA简介

IDEA的诞生在Java集成开发工具行业正所谓平地起雷,瞬间震动了整个Java开发行业。真的是每个人用过的都说好。IDEA之所以相比于其他比如MyEclipse或者Eclipse之类的Java开发工具来讲比较好,原因首先在于设计方面。IDEA采用了所谓的人体工程学设计原理,让使用IDEA的人员用了就忘记不了。软件打开首先要设置主题,可以选择常规的白色或者暗色系列,长时间的白色或者长时间的暗色会让开发人员的眼睛疲劳加重,首先从这个细节就让程序开发人员备受青睐,让程序员看着舒服;然后再对一些常用性插件进行归类,让程序的开发注重于提升生产效率,而不是一味的让开发者找各种插件,有时候插件之间的版本还会存在不兼容,IDEA就把兼容的插件双手呈现,如此贴心的IDEA怎么能让人不喜爱。所以选择IDEA用来开发本项目就理所当然的了。

2.3 SSM框架

最近几年流行的SSM框架是之前的SSH框架的一种替代品,取代了原有的SSH框架的那种臃肿的配置,以及各种Bug,并且在开发模式以及运行效率上面来讲,都是有了很大的提高。Spring是控制层,Spring MVC是视图层,MyBatis是持久层。

在原理上面,SSM框架继承了SSH框架的那种框架以及代码分层设计,首先理解起来比较符合人类的正常理解,视图是负责视图的控制和显示,控制层可以接收和传递视图提交过来的信息,也可以接收和传递持久层的数据信息,而持久层只需要对数据对象进行自动化的转换,给控制层的数据是Java对象,到数据库则转换为相应的数据类型。

使用框架可以有效的解决各种代码写作过程中数据类型的转换问题,把数据类型转换让框架自己转换,写作很方便。

2.4 Vue框架

Vue框架的开发者是一个中国人,区别于其他框架的最核心的概念就是渐进式框架,Vue的出现,让网页前端的开发变成了一种纯前端职业,不需要在考虑后台数据类型以及业务逻辑,只需要进行数据绑定即可,大大的减少了前端开发工程师的学习难度。Vue是当前世界上最火的一种前段框架,学习成本比较低,只需要熟悉最基本的网页知识就可以理解相关知识,并且有很好的免费教程进行学习,有各个国家语言的教程,尤其是因为是中国人开发的框架,让中国的高级程序开发人员做了汉语教程。Vue框架发展之初就是高于IE8版本的,所以说只要是当前的主流浏览器都支持Vue框架,如果是很旧的那种电脑是不支持的,必须安装支持HTML5的浏览器才可以访问用Vue发布的站点。

3 系统分析

对于在线开放课程开发设计到的流程有,分析系统的功能,设计系统的结构,设计数据库,编码以及测试,其中,在系统分析中,所做的工作包括功能的确定,性能的分析等。

3.1 可行性研究

在线开放课程开发实现分析需要从不同的角度来进行分析可行性,比如从时间角度,经济角度,甚至操作角度。从不同的角度分析可行性会让在线开放课程开发具体化,进而达到辩证开发的正确性。

3.1.1 经济可行性

从经济方面分析是第一要素,没有经济的支持,任何项目都如水中捞月,无法实现。实现在线开放课程,开发过程不需要额外的经济条件,用本人现有的计算机就可以实现,这方面不需要额外的支出。

3.1.2 时间可行性

在线开放课程设计主要作为毕业设计,在题目确定之后,答辩之前使用的项目,对不同的开发进度上面都有时间的要求,总不至于答辩完成后才能实现功能,这个肯定不行,所以从时间上来分析项目的工作量,发现是可行的,符合正常开发时间。

3.1.3 操作可行性

操作必须符合正常人的思维模式,市面上有很多符合要求的程序正在使用中,可以借鉴其他程序的操作流程,变成符合本设计的操作流程,在操作上面进行无缝衔接,让使用者操作过程中不会感到迷茫。

从上面的角度来分析,后续工作可以继续进展。

3.2 系统性能分析

性能分析是软件开发过程中必不可少的一个环节,主要是为了降低软件在使用的过程中的容错率。通常来讲,分析软件系统的性能一般从以下几个方面进行分析。

3.2.1 系统的安全性

系统开发出来就是让正常使用的,那么在如今的互联网时代,首先考虑的就是安全性的问题。如果系统的安全性不够,那么使用价值就会降低。如果出现使用过程中丢失数据,那么用户就不再信赖,所以系统的安全性是第一要位,只有安全性存在了,才能考虑使用的问题,总不至于今天用户注册,明天用户账号泄露,这些都是不友好的。所以账号一般在数据库里存储会通过MD5进行加密,这样关键数据加密可以保证系统的安全性。

3.2.2 系统的易用性

安全性分析处理完毕,才考虑易用性。一个软件设计得符合操作规范,符合正常人类的理解逻辑,那么在使用上面就会很舒服,如果违背了这条原则,安全性再高的软件也是设计失败的,毕竟软件开发出来就是让人使用的,这一点尤为重要。

3.2.3 系统的健壮性

系统设计易用不代表没有规则,那么系统设计使用方面必须健壮,必须符合软件处理逻辑。比如设计一个价格类的输入框,用户需要输入价格,那么可以设定输入框最多两位小数的纯数字输入,如果用户不小心输入了其他字符,那么就会友好的提示让用户修改正确,只有输入符合规范的数据,才能进行提交,并且存储到数据库里。系统的健壮性就是这样,越是规范,越是健壮,有助于用户理解,还有助于程序使用。

3.3 系统流程分析

系统设计不是胡乱的设计,必须符合软件设计思想,具体的流程参考下图。系统设计的前期就是做各种分析,功能的设计,数据库的设计等,等一切都设计好了,逻辑上没有问题,符合设计流程和设计规范,才可以继续编码环节,编码只是实现设计的一个环节而已。

图3.1系统开发流程图

用户是一切应用的基础,只要牵扯到用户,那么肯定需要用户进行注册,只有这样才能让注册的用户进行使用。如果用户没有注册,只能算是游客,那么只能访问一些大众用户可以浏览的信息,如果需要用户操作的部分是不允许访问的,这样能极大的保证用户的权利。用户注册流程用下面的图来表示,主要是先判断用户名,只有用户名能用了才可以进行后面的信息注册。

图3.2 注册流程图

当需要用户登录的时候,肯定是要验证的,只有验证通过的用户才可以进行下一步操作,用户登录成功代表着用户模块的功能对登录用户进行了开放。流程就是如下面的图所示。

图3.3 登录流程图

3.4 系统功能分析

在对设计的总体要求理解了之后,就要把要求给具体化,也就是功能化,要尽量的把每个功能模块和模块之前的关系理清楚,必须符合正常人的行为逻辑才可以,并且尽量研究同类型的项目,这样能避免走弯路,最终才能得到设计的具体功能。

在线开放课程把操作该系统的用户群分为三类,即管理员,教师,学生。

管理员对于在线开放课程操作的功能包括批改学生的回答信息,管理作业,教师,学生成绩,教学资源,试卷和试题等信息,管理论坛帖子,管理考试信息等。其用例图如图3.4所示:

图3.4 管理员用例图

教师对于在线开放课程操作的功能包括增删改查试卷,试题,作业,学生成绩信息,查看学生信息,管理考试信息等。其用例图如图3.5所示:

图3.5 教师用例图

学生对于在线开放课程操作的功能包括观看教学资源视频,下载教学资源文件,选择试卷进行考试,完成布置的作业,查看学科成绩以及考试试卷的分数等。其用例图如图3.6所示:

图3.6 学生用例图

4 系统设计

系统在设计的过程中,必然要遵循一定的原则才可以,胡乱设计是不可取的。首先用户在使用过程中,能够直观感受到功能操作的便利性,符合正常思维逻辑的操作,这才是系统好用的一个开端,给使用者第一印象就是这个系统设计的相当不错。

4.1 系统设计原则

系统遵循设计原则进行开发,会有很多可以预料到的好处,只要遵循了设计原则,那么开发出来的系统必然是有质量保证的。

首先第一条原则就是安全性原则:程序必须设定角色管理,不同的角色有不同的功能模块,不同的角色登录都需要输入相对应的账号和密码,否则不允许进行操作相对应的权限。每个用户登录只能修改自己的密码,不需要对别的账号进行密码或者其他资料的修改,否则就违背了安全性原则的设定。

其次第二条原则就是易用性原则:符合安全性只是功能的符合,不代表操作就符合,所以要设定易用性原则。易用性原则就是规定程序符合操作流程,正常人的思维定向为基础,在不违背程序运行逻辑定义的情况下,必须使用简单,操作规范,让每个用户使用起来都能看到页面,就能感知功能模块的作用,短时间的就能使用程序,达到易用效果。

再次第三条原则就是实用性原则:实用性代表着花里胡哨的功能必须抛弃,尽量符合数据处理的简洁性,不仅需要这样进行设定,还需要有预知性,系统后期可能会出现的功能模块尽量要解耦,与程序设定要模块化体现,这样才能达到扩展性。

第四条原则就是准确性原则:准确性原则的唯一定义就是准确,包含数据输入格式的准确,数据处理的准确,以及数据存储的准确。程序里面关于数据准确才有存在的意义,如果一堆不相干的数据存在是没有任何用处的,甚至会产生各种问题,所以必须要保证数据的准确性。

第五条原则是易维护原则:易维护代表着程序运行必须是可控的状态,如果不可控出现各种问题,那么所有的工作都是空谈。程序开发中对于各种程序判定异常,必须有统一的处理模式,异常是程序开发中不可避免的,但是可以对出现的异常进行抛出,有助于程序异常处理的复盘,只要每个异常都能定位准确,那么代表程序设计是趋于完美的,维护起来会更加的方便,只要有助于程序维护的都必须给予支持。

4.2 功能模块设计

对管理员具体功能的设计结果将以图4.1所示的管理员功能结构图来进行体现。管理员对于在线开放课程操作的功能包括批改学生的回答信息,管理作业,教师,学生成绩,教学资源,试卷和试题等信息,管理论坛帖子,管理考试信息等。

图4.1 管理员功能结构图

对教师具体功能的设计结果将以图4.2所示的教师功能结构图来进行体现。教师对于在线开放课程操作的功能包括增删改查试卷,试题,作业,学生成绩信息,查看学生信息,管理考试信息等。

图4.2 教师功能结构图

对学生具体功能的设计结果将以图4.3所示的学生功能结构图来进行体现。学生对于在线开放课程操作的功能包括观看教学资源视频,下载教学资源文件,选择试卷进行考试,完成布置的作业,查看学科成绩以及考试试卷的分数等。

图4.3 学生功能结构图

4.3 数据库设计

用户通过系统的功能操作来进行数据交互,包括数据的添加,数据的更新,数据的删除,数据的查询等基本功能操作,表面上虽然是操作系统界面提供的功能,但是实际上系统的这些数据是在数据库当中进行访问与操作的。目前市场上可供选择的存储数据的数据库有很多,除了简单版的Access之外,还有SQL Server,DB2,Informix,MySQL等关系型数据库可供选择,由于关系型数据库具有固定的表结构,以及对数据一致性要求比较强,所以相比没有固定表结构以及具有灵活的数据格式的非关系型数据库而言,在程序配套数据库的选择中,关系型数据库的使用率更高。本系统选择MySQL来存放数据,其相关理论以及技术在经过了很长时间的发展之后,变得非常成熟,各大网络平台都公开分享其开发源码,而且其对计算机的配置要求很低,不需要过多内存进行安装,很符合本系统对于数据库的选择要求。

4.3.1 数据库E-R图

本节需要对系统中存放在数据库中的数据进行充分分析,对数据的实体,实体特征,联系等进行确定,然后通过概念模型的表示方法即E-R图进行表达,在E-R图绘制工具中,选择椭圆,菱形框,矩形等形状表达实体属性,实体间联系,实体这些信息,使用实线段将这些形状进行连接即可。初步完成E-R图之后,需要进行检查,及时进行有误数据的更改,删除实体间存在的冗余联系,删除E-R图中冗余的数据,最终要展示一个内容准确的E-R图。

(1)教学资源包括的属性有资源类型,资源图片,资源视频等。其属性图如下。

图4.4 教学资源实体属性图

(2)学生成绩包括的属性有学科类型,成绩,详情等。其属性图如下。

图4.5 学生成绩实体属性图

(3)作业包括的属性有作业名称,作业文件等。其属性图如下。

图4.6 作业实体属性图

(4)学生包括的属性有学生姓名,性别,联系方式等。其属性图如下。

图4.7 学生实体属性图

(5)教师包括的属性有教师姓名,性别,邮箱等。其属性图如下。

图4.8 教师实体属性图

(6)设计的各实体间关系E-R图如下。

图4.9 实体间关系E-R图

4.3.2 数据库表结构

在指定的数据库里面对数据表进行创建命名,然后设计各个数据表的存储结构,需要对该数据库的操作非常熟悉,并且还需要学习并掌握一定的数据表设计方面的知识,比如数据命名,作为系统的开发人员,为了避免程序运行产生乱码现象以及为了确保系统的正常运行,在对数据表进行命名时,一般都是采用英文名称,同时在对数据表的字段进行编辑时,也是采用英文的方式进行,为了方便今后对数据表的设计内容进行更改或查看,对一些比较重要的字段都会进行中文备注,或者是使用中文进行字段描述。设计期间,也需要对各个字段选择合适的数据类型以及设置匹配的取值范围,当一张数据表设计完成之后,还要对该表的主键进行标注,就是为了确保该数据表的唯一性与独立性。

表4.1 试卷表

字段注释类型
id (主键)主键int(20)
exampaper_name试卷名称varchar(200)
exampaper_date考试时长(分钟)int(11)
exampaper_myscore试卷总分数int(20)
exampaper_types试卷状态int(11)
exampaper_delete逻辑删除(0代表未删除 1代表已删除)int(255)
create_time创建时间timestamp

表4.2 试题表

字段注释类型
id (主键)主键int(20)
exampaper_id所属试卷id(外键)int(20)
examquestion_name试题名称varchar(200)
examquestion_options选项,json字符串longtext
examquestion_score分值int(20)
examquestion_answer正确答案varchar(200)
examquestion_analysis答案解析longtext
examquestion_types试题类型int(20)
examquestion_sequence试题排序,值越大排越前面int(20)
create_time创建时间timestamp

表4.3 考试记录表

字段注释类型
id (主键)主键int(20)
examrecord_uuid_number考试编号varchar(200)
yonghu_id考试用户int(20)
exampaper_id所属试卷id(外键)int(20)
total_score所得总分int(200)
insert_time考试时间timestamp
create_time创建时间timestamp

表4.4 答题详情表

字段注释类型
id (主键)主键int(20)
examredetails_uuid_number试卷编号varchar(200)
yonghu_id用户idint(20)
examquestion_id试题id(外键)int(20)
examredetails_myanswer考生答案varchar(200)
examredetails_myscore试题得分int(20)
create_time创建时间timestamp

表4.5 错题表

字段注释类型
id (主键)主键int(20)
yonghu_id用户idint(20)
exampaper_id试卷(外键)int(20)
examquestion_id试题id(外键)int(20)
examredetails_myanswer考生作答varchar(200)
insert_time记录时间timestamp
create_time创建时间timestamp

表4.6 论坛表

字段注释类型
id (主键)主键int(11)
forum_name帖子标题varchar(200)
yonghu_id学生int(11)
jiaoshi_id老师int(11)
users_id管理员int(11)
forum_content发布内容text
super_ids父idint(11)
forum_state_types帖子状态int(11)
insert_time发帖时间timestamp
update_time修改时间timestamp
create_time创建时间timestamp

表4.7 回答表

字段注释类型
id (主键)主键int(11)
zuoye_id作业int(11)
yonghu_id学生int(11)
huifu_file回答文件varchar(200)
huida_types批改状态int(11)
create_time创建时间timestamp

表4.8 教师表

字段注释类型
id (主键)主键int(11)
username账户varchar(200)
password密码varchar(200)
jiaoshi_name教师姓名varchar(200)
jiaoshi_photo图片varchar(255)
sex_types性别int(11)
jiaoshi_phone联系方式varchar(200)
jiaoshi_email邮箱varchar(200)
jiaoshi_delete假删int(11)
create_time创建时间timestamp

表4.9 教学资源表

字段注释类型
id (主键)主键int(11)
jiaoxueziyuan_name资源标题varchar(200)
jiaoxueziyuan_types资源类型int(11)
jiaoxueziyuan_photo资源图片varchar(200)
jiaoxueziyuan_video资源视频varchar(200)
jiaoxueziyuan_file课件下载varchar(200)
jiaoshi_id资源教师int(11)
jiaoxueziyuan_content资源详情text
insert_time发布时间timestamp
create_time创建时间timestamp

表4.10 公告信息表

字段注释类型
id (主键)主键int(11)
news_name公告标题varchar(200)
news_types公告类型int(11)
news_photo公告图片varchar(200)
insert_time公告时间timestamp
news_content公告详情text
create_time创建时间timestamp

表4.11 管理员表

字段注释类型
id (主键)主键bigint(20)
username用户名varchar(100)
password密码varchar(100)
role角色varchar(100)
addtime新增时间timestamp

表4.12 学生成绩表

字段注释类型
id (主键)主键int(11)
jiaoshi_id教师int(11)
yonghu_id学生int(11)
xueshengchengji_name标题varchar(200)
xueshengchengji_types学科类型int(11)
xueshengchengji_num成绩int(11)
xueshengchengji_text详情varchar(200)
insert_time添加时间timestamp
create_time创建时间timestamp

表4.13 学生表

字段注释类型
id (主键)主键int(11)
username账户varchar(200)
password密码varchar(200)
yonghu_name学生姓名varchar(200)
yonghu_photo头像varchar(255)
sex_types性别int(11)
yonghu_phone联系方式varchar(200)
yonghu_id_number学生身份证号varchar(200)
yonghu_email邮箱varchar(200)
yonghu_delete假删int(11)
create_time创建时间timestamp

表4.14 作业表

字段注释类型
id (主键)主键int(11)
jiaoshi_id教师int(11)
zuoye_uuid_number作业唯一编号varchar(200)
zuoye_name作业名称varchar(200)
zuoye_types作业类型int(11)
insert_time作业发布时间timestamp
zuoye_file作业文件varchar(200)
zuoye_content作业详情text
create_time创建时间timestamp

5 系统实现

下面主要是通过功能实现界面截图的形式,并且运用文字来描述功能实现界面的内容。

5.1 管理员功能实现

5.1.1 教师管理

该功能主要用于实现对教师基本信息的管理,教师管理界面的运行效果见图5.1。在此界面,管理员添加或修改教师的姓名,性别,联系方式等信息,可以对指定教师的账户重置密码。

图5.1 教师管理界面

5.1.2 教学资源管理

该功能主要用于实现对教学资源基本信息的管理,教学资源管理界面的运行效果见图5.2。在此界面,教学资源的课件和教学资源的视频需要管理员上传,同时还需要管理员登记资源标题,资源类型等信息,以及修改教学资源的信息。

图5.2 教学资源管理界面

5.1.3 论坛管理

该功能主要用于实现对论坛帖子基本信息的管理,论坛管理界面的运行效果见图5.3。在此界面,管理员可以查看论坛帖子的标题和论坛帖子的内容,可以删除传播不良信息的论坛帖子,可以通过论坛回复功能及时跟踪论坛回帖信息以及及时删除传播不良信息的回帖数据。

图5.3 论坛管理界面

5.1.4 回答管理

回答管理界面的运行效果见图5.4。在此界面,管理员下载学生的回答文件,并对未批改的回答信息进行批改,已经批改的回答信息可以删除。

图5.4 回答管理界面

5.1.5 作业管理

该功能主要用于实现对作业基本信息的管理,作业管理界面的运行效果见图5.5。在此界面,管理员上传作业文件,登记作业信息,发现有错误数据的作业信息可以及时修改,以及删除早期布置的已经失效的作业信息。

图5.5 作业管理界面

5.2 教师功能实现

5.2.1 试卷管理

该功能主要用于实现对试卷基本信息的管理,试卷管理界面的运行效果见图5.6。在此界面,教师为试卷的总分数以及考试时长数据进行设置,同时可以设置试卷状态为启用状态或者是设置试卷状态为禁用状态,教师删除试卷可以直接通过删除功能执行即可。

图5.6 试卷管理界面

5.2.2 试题管理

试题管理界面的运行效果见图5.7。在此界面,教师对各种类型的试题进行管理,试题信息包括正确答案,答案解析,分值,试题类型等信息,教师对每种试题信息都可以进行修改,查询,删除等。

图5.7 试题管理界面

5.2.3 学生成绩

学生成绩界面的运行效果见图5.8。在此界面,教师对学生的学科成绩进行增加,已经存在的学生成绩信息也能通过修改功能及时更正登记错误的数据。

图5.8 学生成绩界面

5.2.4 考试管理

考试管理界面的运行效果见图5.9。在此界面,教师主要是查看学生对试卷进行答题之后的成绩信息,以及对学生的试卷答题记录信息进行查看。

图5.9 考试管理界面

5.3 学生功能实现

5.3.1 试卷表

试卷表界面的运行效果见图5.10。在此界面,学生查看试卷说明信息,学生对试卷答题需要点击试卷信息右侧的考试按钮,进入考试界面才可以答题。

图5.10 试卷表界面

5.3.2 教学资源

教学资源界面的运行效果见图5.11。在此界面,学生通过查看教学资源视频的方式进行学习,或者是对教学资源界面显示的教学资源文件进行下载。

图5.11 教学资源界面

5.3.3 在线论坛

在线论坛界面的运行效果见图5.12。在此界面,学生主要是针对具体的话题进行讨论,讨论方式主要是发布帖子,以及对查看的帖子进行评论的方式进行。

图5.12 在线论坛界面

5.3.4 错题本

错题本界面的运行效果见图5.13。在此界面,学生主要是查看已完成交卷的试卷的回答错误的题目信息,学生通过错题本可以了解自己回答错误的题目以及查看该题目的正确答案和解析信息。

图5.13 错题本界面

5.3.5 回答管理

回答管理界面的运行效果见图5.14。学生对作业查看之后,学生对作业回答的内容就以文件的形式在回答管理界面进行上传,已经上传的回答信息,会让管理员进行批改。

图5.14 回答管理界面

系统

HuidaController.java

package com.controller;

import java.io.File;
import java.math.BigDecimal;
import java.net.URL;
import java.text.SimpleDateFormat;
import com.alibaba.fastjson.JSONObject;
import java.util.*;
import org.springframework.beans.BeanUtils;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.context.ContextLoader;
import javax.servlet.ServletContext;
import com.service.TokenService;
import com.utils.*;
import java.lang.reflect.InvocationTargetException;

import com.service.DictionaryService;
import org.apache.commons.lang3.StringUtils;
import com.annotation.IgnoreAuth;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.entity.*;
import com.entity.view.*;
import com.service.*;
import com.utils.PageUtils;
import com.utils.R;
import com.alibaba.fastjson.*;

/**
 * 回答
 * 后端接口
 * @author
 * @email
*/
@RestController
@Controller
@RequestMapping("/huida")
public class HuidaController {
    private static final Logger logger = LoggerFactory.getLogger(HuidaController.class);

    @Autowired
    private HuidaService huidaService;


    @Autowired
    private TokenService tokenService;
    @Autowired
    private DictionaryService dictionaryService;

    //级联表service
    @Autowired
    private YonghuService yonghuService;
    @Autowired
    private ZuoyeService zuoyeService;

    @Autowired
    private JiaoshiService jiaoshiService;


    /**
    * 后端列表
    */
    @RequestMapping("/page")
    public R page(@RequestParam Map<String, Object> params, HttpServletRequest request){
        logger.debug("page方法:,,Controller:{},,params:{}",this.getClass().getName(),JSONObject.toJSONString(params));
        String role = String.valueOf(request.getSession().getAttribute("role"));
        if(false)
            return R.error(511,"永不会进入");
        else if("学生".equals(role))
            params.put("yonghuId",request.getSession().getAttribute("userId"));
        else if("教师".equals(role))
            params.put("jiaoshiId",request.getSession().getAttribute("userId"));
        if(params.get("orderBy")==null || params.get("orderBy")==""){
            params.put("orderBy","id");
        }
        PageUtils page = huidaService.queryPage(params);

        //字典表数据转换
        List<HuidaView> list =(List<HuidaView>)page.getList();
        for(HuidaView c:list){
            //修改对应字典表字段
            dictionaryService.dictionaryConvert(c, request);
        }
        return R.ok().put("data", page);
    }

    /**
    * 后端详情
    */
    @RequestMapping("/info/{id}")
    public R info(@PathVariable("id") Long id, HttpServletRequest request){
        logger.debug("info方法:,,Controller:{},,id:{}",this.getClass().getName(),id);
        HuidaEntity huida = huidaService.selectById(id);
        if(huida !=null){
            //entity转view
            HuidaView view = new HuidaView();
            BeanUtils.copyProperties( huida , view );//把实体数据重构到view中

                //级联表
                YonghuEntity yonghu = yonghuService.selectById(huida.getYonghuId());
                if(yonghu != null){
                    BeanUtils.copyProperties( yonghu , view ,new String[]{ "id", "createTime", "insertTime", "updateTime"});//把级联的数据添加到view中,并排除id和创建时间字段
                    view.setYonghuId(yonghu.getId());
                }
                //级联表
                ZuoyeEntity zuoye = zuoyeService.selectById(huida.getZuoyeId());
                if(zuoye != null){
                    BeanUtils.copyProperties( zuoye , view ,new String[]{ "id", "createTime", "insertTime", "updateTime"});//把级联的数据添加到view中,并排除id和创建时间字段
                    view.setZuoyeId(zuoye.getId());
                }
            //修改对应字典表字段
            dictionaryService.dictionaryConvert(view, request);
            return R.ok().put("data", view);
        }else {
            return R.error(511,"查不到数据");
        }

    }

    /**
    * 后端保存
    */
    @RequestMapping("/save")
    public R save(@RequestBody HuidaEntity huida, HttpServletRequest request){
        logger.debug("save方法:,,Controller:{},,huida:{}",this.getClass().getName(),huida.toString());

        String role = String.valueOf(request.getSession().getAttribute("role"));
        if(false)
            return R.error(511,"永远不会进入");
        else if("学生".equals(role))
            huida.setYonghuId(Integer.valueOf(String.valueOf(request.getSession().getAttribute("userId"))));

        Wrapper<HuidaEntity> queryWrapper = new EntityWrapper<HuidaEntity>()
            .eq("zuoye_id", huida.getZuoyeId())
            .eq("yonghu_id", huida.getYonghuId())
            .eq("huida_types", huida.getHuidaTypes())
            ;

        logger.info("sql语句:"+queryWrapper.getSqlSegment());
        HuidaEntity huidaEntity = huidaService.selectOne(queryWrapper);
        if(huidaEntity==null){
            huida.setCreateTime(new Date());
            huidaService.insert(huida);
            return R.ok();
        }else {
            return R.error(511,"表中有相同数据");
        }
    }

    /**
    * 后端修改
    */
    @RequestMapping("/update")
    public R update(@RequestBody HuidaEntity huida, HttpServletRequest request){
        logger.debug("update方法:,,Controller:{},,huida:{}",this.getClass().getName(),huida.toString());

        String role = String.valueOf(request.getSession().getAttribute("role"));
//        if(false)
//            return R.error(511,"永远不会进入");
//        else if("学生".equals(role))
//            huida.setYonghuId(Integer.valueOf(String.valueOf(request.getSession().getAttribute("userId"))));
        //根据字段查询是否有相同数据
        Wrapper<HuidaEntity> queryWrapper = new EntityWrapper<HuidaEntity>()
            .notIn("id",huida.getId())
            .andNew()
            .eq("zuoye_id", huida.getZuoyeId())
            .eq("yonghu_id", huida.getYonghuId())
            .eq("huida_types", huida.getHuidaTypes())
            ;

        logger.info("sql语句:"+queryWrapper.getSqlSegment());
        HuidaEntity huidaEntity = huidaService.selectOne(queryWrapper);
        if("".equals(huida.getHuifuFile()) || "null".equals(huida.getHuifuFile())){
                huida.setHuifuFile(null);
        }
        if(huidaEntity==null){
            huidaService.updateById(huida);//根据id更新
            return R.ok();
        }else {
            return R.error(511,"表中有相同数据");
        }
    }



    /**
    * 删除
    */
    @RequestMapping("/delete")
    public R delete(@RequestBody Integer[] ids){
        logger.debug("delete:,,Controller:{},,ids:{}",this.getClass().getName(),ids.toString());
        huidaService.deleteBatchIds(Arrays.asList(ids));
        return R.ok();
    }


    /**
     * 批量上传
     */
    @RequestMapping("/batchInsert")
    public R save( String fileName, HttpServletRequest request){
        logger.debug("batchInsert方法:,,Controller:{},,fileName:{}",this.getClass().getName(),fileName);
        Integer yonghuId = Integer.valueOf(String.valueOf(request.getSession().getAttribute("userId")));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            List<HuidaEntity> huidaList = new ArrayList<>();//上传的东西
            Map<String, List<String>> seachFields= new HashMap<>();//要查询的字段
            Date date = new Date();
            int lastIndexOf = fileName.lastIndexOf(".");
            if(lastIndexOf == -1){
                return R.error(511,"该文件没有后缀");
            }else{
                String suffix = fileName.substring(lastIndexOf);
                if(!".xls".equals(suffix)){
                    return R.error(511,"只支持后缀为xls的excel文件");
                }else{
                    URL resource = this.getClass().getClassLoader().getResource("../../upload/" + fileName);//获取文件路径
                    File file = new File(resource.getFile());
                    if(!file.exists()){
                        return R.error(511,"找不到上传文件,请联系管理员");
                    }else{
                        List<List<String>> dataList = PoiUtil.poiImport(file.getPath());//读取xls文件
                        dataList.remove(0);//删除第一行,因为第一行是提示
                        for(List<String> data:dataList){
                            //循环
                            HuidaEntity huidaEntity = new HuidaEntity();
//                            huidaEntity.setZuoyeId(Integer.valueOf(data.get(0)));   //作业 要改的
//                            huidaEntity.setYonghuId(Integer.valueOf(data.get(0)));   //学生 要改的
//                            huidaEntity.setHuifuFile(data.get(0));                    //回答文件 要改的
//                            huidaEntity.setHuidaTypes(Integer.valueOf(data.get(0)));   //批改状态 要改的
//                            huidaEntity.setCreateTime(date);//时间
                            huidaList.add(huidaEntity);


                            //把要查询是否重复的字段放入map中
                        }

                        //查询是否重复
                        huidaService.insertBatch(huidaList);
                        return R.ok();
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            return R.error(511,"批量插入数据异常,请联系管理员");
        }
    }





    /**
    * 前端列表
    */
    @IgnoreAuth
    @RequestMapping("/list")
    public R list(@RequestParam Map<String, Object> params, HttpServletRequest request){
        logger.debug("list方法:,,Controller:{},,params:{}",this.getClass().getName(),JSONObject.toJSONString(params));

        // 没有指定排序字段就默认id倒序
        if(StringUtil.isEmpty(String.valueOf(params.get("orderBy")))){
            params.put("orderBy","id");
        }
        PageUtils page = huidaService.queryPage(params);

        //字典表数据转换
        List<HuidaView> list =(List<HuidaView>)page.getList();
        for(HuidaView c:list)
            dictionaryService.dictionaryConvert(c, request); //修改对应字典表字段
        return R.ok().put("data", page);
    }

    /**
    * 前端详情
    */
    @RequestMapping("/detail/{id}")
    public R detail(@PathVariable("id") Long id, HttpServletRequest request){
        logger.debug("detail方法:,,Controller:{},,id:{}",this.getClass().getName(),id);
        HuidaEntity huida = huidaService.selectById(id);
            if(huida !=null){


                //entity转view
                HuidaView view = new HuidaView();
                BeanUtils.copyProperties( huida , view );//把实体数据重构到view中

                //级联表
                    YonghuEntity yonghu = yonghuService.selectById(huida.getYonghuId());
                if(yonghu != null){
                    BeanUtils.copyProperties( yonghu , view ,new String[]{ "id", "createDate"});//把级联的数据添加到view中,并排除id和创建时间字段
                    view.setYonghuId(yonghu.getId());
                }
                //级联表
                    ZuoyeEntity zuoye = zuoyeService.selectById(huida.getZuoyeId());
                if(zuoye != null){
                    BeanUtils.copyProperties( zuoye , view ,new String[]{ "id", "createDate"});//把级联的数据添加到view中,并排除id和创建时间字段
                    view.setZuoyeId(zuoye.getId());
                }
                //修改对应字典表字段
                dictionaryService.dictionaryConvert(view, request);
                return R.ok().put("data", view);
            }else {
                return R.error(511,"查不到数据");
            }
    }


    /**
    * 前端保存
    */
    @RequestMapping("/add")
    public R add(@RequestBody HuidaEntity huida, HttpServletRequest request){
        logger.debug("add方法:,,Controller:{},,huida:{}",this.getClass().getName(),huida.toString());
        Wrapper<HuidaEntity> queryWrapper = new EntityWrapper<HuidaEntity>()
            .eq("zuoye_id", huida.getZuoyeId())
            .eq("yonghu_id", huida.getYonghuId())
            .eq("huida_types", huida.getHuidaTypes())
            ;
        logger.info("sql语句:"+queryWrapper.getSqlSegment());
        HuidaEntity huidaEntity = huidaService.selectOne(queryWrapper);
        if(huidaEntity==null){
            huida.setCreateTime(new Date());
        huidaService.insert(huida);
            return R.ok();
        }else {
            return R.error(511,"表中有相同数据");
        }
    }


}

ZuoyeServiceImpl.java
package com.service.impl;

import com.utils.StringUtil;
import org.springframework.stereotype.Service;
import java.lang.reflect.Field;
import java.util.*;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import com.utils.PageUtils;
import com.utils.Query;
import org.springframework.web.context.ContextLoader;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import com.dao.ZuoyeDao;
import com.entity.ZuoyeEntity;
import com.service.ZuoyeService;
import com.entity.view.ZuoyeView;

/**
 * 作业 服务实现类
 */
@Service("zuoyeService")
@Transactional
public class ZuoyeServiceImpl extends ServiceImpl<ZuoyeDao, ZuoyeEntity> implements ZuoyeService {

    @Override
    public PageUtils queryPage(Map<String,Object> params) {
        if(params != null && (params.get("limit") == null || params.get("page") == null)){
            params.put("page","1");
            params.put("limit","10");
        }
        Page<ZuoyeView> page =new Query<ZuoyeView>(params).getPage();
        page.setRecords(baseMapper.selectListView(page,params));
        return new PageUtils(page);
    }


}

CommonUtil.java
package com.utils;

import java.util.Random;

public class CommonUtil {
	/**
     * 获取随机字符串
     *
     * @param num
     * @return
     */
    public static String getRandomString(Integer num) {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < num; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

}

i18n.js
// translate router.meta.title, be used in breadcrumb sidebar tagsview
export function generateTitle(title) {
  const hasKey = this.$te('route.' + title)

  if (hasKey) {
    // $t :this method from vue-i18n, inject in @/lang/index.js
    const translatedTitle = this.$t('route.' + title)

    return translatedTitle
  }
  return title
}

声明

本博客适用于广泛的学术和教育用途,包括但不限于个人学习、开发设计,产品设计。仅供学习参考,旨在为读者提供深入理解和学术研究的材料。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2180984.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于ssm的宠物领养管理系统的设计与实现 (含源码+sql+视频导入教程)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于ssm的宠物领养管理系统3拥有两种角色 管理员&#xff1a;用户管理、管理员管理、宠物管理、领养管理、评论管理、团队活动管理、志愿者申请管理、领养列表 用户&#xff1a;查看各种…

51单片机应用开发(进阶)---数码管+按键+蜂鸣器(电磁炉显示模拟)

实现目标 1、加强数码管、按键的学习&#xff0c;实现数码显示变量数据&#xff08;四位数的显示&#xff09;&#xff1b; 2、4位数码2个按键无源蜂鸣器实现模拟电磁炉功率调节及显示&#xff1b; 一、内容描述 功能描述&#xff1a;1、开机显示电磁炉功率300&#xff0c;每…

Percona Monitoring and Management

Percona Monitoring and Management (PMM)是一款开源的专用于管理和监控MySQL、MongoDB、PostgreSQL

Java入门3——操作符+String

在入门2中忘了提 String 的事情了&#xff0c;所以这篇就放在开头啦&#xff0c;很有用 话不多说&#xff0c;开始正题~ 一、String 引用数据类型之——String 1.字符串的拼接 在Java中&#xff0c;如果要把两句话合并到一句话的时候&#xff0c;其实是很简单的&#xff0c;…

0109 图解多线程死锁问题

死锁场景 &#x1f92a;举例场景&#xff1a;两个憨憨Tom和Sam去西餐厅吃牛排&#xff0c;桌子上只有一把刀和一把叉&#xff0c;Tom先拿到了叉子&#xff0c;Sam拿到了刀。只有同时拿到刀叉才能吃牛排&#xff0c;于是两个憨憨陷入如下的僵局。 这个场景中&#xff0c;就存在…

信号处理快速傅里叶变换(FFT)的学习

FFT是离散傅立叶变换的快速算法&#xff0c;可以将一个信号变换到频域。有些信号在时域上是很难看出什么特征的&#xff0c;但是如果变换到频域之后&#xff0c;就很容易看出特征了。这就是很多信号分析采用FFT变换的原因。另外&#xff0c;FFT可以将一个信号的频谱提取出来&am…

可以白嫖PPT模板的6个网站,赶紧收藏

推荐6个PPT模板网站&#xff0c;免费下载&#xff0c;绝对的高质量&#xff0c;赶紧收藏&#xff01; 1、菜鸟图库 ppt模板免费下载|ppt背景图片 - 菜鸟图库 菜鸟图库网有非常丰富的免费素材&#xff0c;像设计类、办公类、自媒体类等素材都很丰富。PPT模板种类很多&#xff0…

高中教辅汇总【35GB】

文章目录 一、资源概览二、资源亮点三、获取方式 一、资源概览 这份教辅资源汇总&#xff0c;精心搜集了高中各学科的海量教辅资料&#xff0c;总容量高达35GB&#xff0c;覆盖了语文、数学、英语、物理、化学、生物、历史、地理、政治等所有必修及选修科目。从基础知识点到难…

windos gcc 安装

一、github&#xff1a;https://github.com/skeeto/w64devkit/releases 二、安装 三、打开安装目录 四、当前目录打开命令行&#xff0c;查看版本。如果有说明安装成功 五、将bin路径放入系统环境变量path里

Moki再次拉低睡前视频难度?还能轻松点赞过万!我只能说任重道远(附保姆级制作教程)

大家好&#xff0c;我是凡人。 是一个不黑、不吹、不跟风、有知识、有骨气的五好小号主。 就在昨天&#xff0c;收到了一条短信&#xff0c;内容是&#xff1a;美图Moki电脑端正式上线。 这时我才想到&#xff0c;很早之前就关注了这块自动生成AI短片的工具&#xff0c;宣传是…

CNN中注意力机制综合指南:从理论到Pytorch代码实现

注意力机制已经成为深度学习模型&#xff0c;尤其是卷积神经网络&#xff08;CNN&#xff09;中不可或缺的组成部分。通过使模型能够选择性地关注输入数据中最相关的部分&#xff0c;注意力机制显著提升了CNN在图像分类、目标检测和语义分割等复杂任务中的性能。本文将全面介绍…

redis的数据结构,内存处理,缓存问题

redisObject redis任意数据的key和value都会被封装为一个RedisObject&#xff0c;也叫redis对象&#xff1a; 这就redis的头信息&#xff0c;占有16个字节 redis中有两个热门数据结构 1.SkipList&#xff0c;跳表&#xff0c;首先是链表&#xff0c;和普通链表有以下差异&am…

【c++面试总结】

1. NULL 和 nullptr 区别 int overLoadTest(int x) {cout << __LINE__ << endl;return 0; }int overLoadTest(char* x) {cout << __LINE__ << endl;return 0; }int main() {char x[10] {1,2,3,4,5};overLoadTest(1);overLoadTest(x);overLoadTest(nu…

2024大二上js高级+ES6学习9.23(严格模式,this指向和改变this指向,高阶函数)

9.23.2024 函数进阶 1.函数定义方式 2.函数的调用方式 3.函数的this指向 而普通函数、定时器函数。立即执行函数一般是window调用的 构造函数调用&#xff1a;原型对象中的方法是在实例对象调用这个方法时&#xff0c;才指向实例对象。 4.改变函数的this指向&#xff08;ca…

体育馆智能化系统规划方案

1. 体育馆智能化系统规划概述 本文详细介绍了一个室内体育馆的智能化系统规划方案&#xff0c;旨在通过优化建筑结构、系统、服务和管理&#xff0c;创建一个高效、舒适、便利的环境。该体育馆按照国家三级乙等标准设计&#xff0c;总建筑面积约1.69万平方米&#xff0c;智能化…

基于深度学习的点云处理模型PointNet++学习记录

前面我们已经学习了Open3D&#xff0c;并掌握了其相关应用&#xff0c;但我们也发现对于一些点云分割任务&#xff0c;我们采用聚类等方法的效果似乎并不理想&#xff0c;这时&#xff0c;我们可以想到在深度学习领域是否有相关的算法呢&#xff0c;今天&#xff0c;我们便来学…

在树莓派上部署开源监控系统 ZoneMinder

原文&#xff1a;https://blog.iyatt.com/?p17425 前言 自己搭建&#xff0c;可以用手里已有的设备&#xff0c;不需要额外买。这套系统的源码是公开的&#xff0c;录像数据也掌握在自己手里&#xff0c;不经过不可控的三方。 支持设置访问账号 可以保存录像&#xff0c;启…

ST-GCN模型实现花样滑冰动作分类

加入深度实战社区:www.zzgcz.com&#xff0c;免费学习所有深度学习实战项目。 1. 项目简介 本项目实现了A042-ST-GCN模型&#xff0c;用于对花样滑冰动作进行分类。花样滑冰作为一项融合了舞蹈与竞技的运动&#xff0c;其复杂的动作结构和多变的运动轨迹使得动作识别成为一个具…

redis-数据类型

十大数据类型 学习 redis 操作手册 英文 Commands 中文 Redis命令中心&#xff08;Redis commands&#xff09; – Redis中国用户组&#xff08;CRUG&#xff09; 学习方法 举出一个数据结构的应用场景&#xff08;理解数据结构特点&#xff09;&#xff0c;并操作&…

深度学习模型可视化工具 Netron 使用教程

Netron 介绍 Netron 是一个用于可视化机器学习模型、深度学习模型、神经网络、图模型&#xff08;例如用于计算机视觉的 ONNX、Caffe、TensorFlow Lite、TensorFlow.js、Keras、Darknet、TVM、PyTorch、TorchScript、Core ML、ML.NET、NNEF、PaddlePaddle、OpenVINO、Arm NN等…