如何使用ssm实现基于BS的管理系统的设计与实现+vue

194 篇文章 0 订阅
140 篇文章 0 订阅

@TOC

ssm395基于BS的论文管理系统的设计与实现+vue

第一章 绪论

1.1 研究背景

时代总是在进步的,自从进入了信息时代,面对大量的不同种类的数据,仅仅依靠有限的人力去处理,显然是不行的,毕竟人工处理大量的数据会耗费较长时间,而且数据的错误率也会提升,另外,在对数据进行检索时,也是一件既耗费体力,又耗费时间的事情。因此,引进当前的信息技术开发的系统去解决传统管理模式带来的各种困扰成为一种趋势。本次打算开发论文管理系统,让论文信息的管理完全依赖于计算机,包括录入信息,维护信息等都在计算机上操作,简单方便,在优化信息管理流程的基础上,进一步实现信息管理的规范化和系统化。也让论文信息的管理人员从之前的繁琐工作中解脱出来,让他们提升自身素质,提高自身管理能力,把论文管理系统的作用发挥到最大,从而产生更大的效益。

1.2 研究意义

论文管理系统的出现,可以解决传统模式带来的问题,比如传统模式不能批量处理数据,处理效率低,耗时长,浪费大量人力和物力,数据易出错等问题。论文管理系统是基于计算机进行数据的处理,则可以短时间内批量完成数据的管理,就连基本的数据录入,更改错误的数据,统计数据等操作要求都可以轻松完成,这样的系统的运用可以减少很多繁琐的工作量,让数据的管理人员提升效率,节省数据处理投入的资金和时间。同时,论文管理系统本身就有配套的数据库,用于保存系统的后台数据,对于数据保存的容量则是传统模式不能相比的,在数据安全性上,也有相应的加密技术提供保护,所以数据泄露和被人窃取都不是易事。另外,论文管理系统对操作人员录入的数据进行实时检验,可以及时反馈错误信息,使录入数据的准确率得到提高,也充分保证了系统数据的可靠性。总之,论文管理系统值得信赖,可以完成数据的高效率处理工作。

1.3 研究内容

本文对论文管理系统的描述,将按照如下章节进行。

第一章:根据前期的调研,和对参考资料的分析总结,明确系统研究背景意义;

第二章:通过对当前开发技术的分析,选定开发本系统的开发语言和工具;

第三章:在用户需求的基础上,结合相似系统的功能,分析并确定本系统的功能,分析本系统开发可行性问题;

第四章:在第三章的基础上,进一步细分系统功能,要设计出系统各个模块的功能,同时,对配套数据库进行设计;

第五章:在第四章基础上,要运用编程技术,全面实现论文管理系统的功能;

第六章:检测制作的论文管理系统功能是否运行正常,性能是否达标;

第二章 开发环境与技术

论文管理系统作为一款应用软件,其开发是需要搭建的一定的编程环境,对使用的工具和技术都有相应要求,接下来就介绍本系统中运用到的工具和技术。

2.1 JSP技术

JSP技术是有一定的规则的,首先JSP里可以用Java语言写在标记内,可以混合HTML语言以及XHTML语言代码进行混合编辑,并且进行书写Java语句或者用其他标签,用标签的话都需要用特殊的符号进行描述,编写Java语言的代码需要用特殊符号标记起来,用<%作为开始,中间书写Java语句,以%>作为结束标签,必须是有开头和结尾的,不然会编译出错的,必须是成对出现也必须有闭合的。JSP可以处理表单数据,因为JSP也算是一种Servlet,也可以把数据提交给Servlet处理也是可以的。其实对用户来讲,实现动态数据的网页就可以了,但是后台也是需要对数据进行一些加工的,JSP技术正好也是可以做到数据加工的。JSP可以直接通过JDBC来操作数据库,对数据进行页面展示,也可以记录用户的访问的信息和选择信息等,并且可以使用JavaBean组件,还可以通过Session在不同的网页上传递信息和共享相关的信息。动态网页有很多规范和标准,比如CGI规范或者ISAPI规范这些。标准是固定的,但是JSP技术是比CGI规范更加强壮。比如JSP性能对比上超过CGI,更优秀,原因是因为可以在一个JSP文件里嵌入很多元素,如果元素一样多的话,用CGI就变成了需要很多文件,而受制于硬盘读写效率的影响,用时少就是优秀,能耗少就是强劲。JSP是完整的应用平台Java EE 中不可缺少的一部分。

2.2 MySQL数据库

自从学习了关系型数据库的语法之后,也逐渐的了解了一些属于关系型数据库范畴的几个常见的数据库。比如Oracle数据库和MySQL数据库,以及Microsoft SQL Server数据库和DB2数据库这几种。在这几个关系型数据库之中,对MySQL数据库印象最好。首先MySQL数据库有各种平台的服务器版本,这样就能实现跨平台运行以及移植。其次,MySQL数据库可以进行网络连接,这样可以对本地账户和应用程序账户进行有效的区分,这样在数据库的安全性上面也有很好的保证。再次,MySQL数据库在中小数据量的运行效率上面比其他数据库占用服务器资源最少,所以很多企业都选择了MySQL数据库作为首选。在开发上面,各种图形界面管理工具也是层出不穷,并且还比较好用,从各个方面综合考虑对比的情况下,选择了MySQL数据库作为应用程序所选的数据库软件。

2.3 Java语言

Java语言发展有25年多了,在互联网行业经过这么多年的发展,还依然在市场的占有率上有半壁江山,依然受到很多程序员的喜爱,好多从业人员进行学习,随着互联网从业人员的增加,并没有降低Java语言的江湖地位,算是一个常青藤。Java语言学习很简单,当然这是针对于前辈C++来讲的,C++语言相当的强悍。Java取消了很多C++特征,比如go to这些语句,还有取消了主文件,让所有的文件都是类,类里都是数组和各种对象,还让Java自己处理各种对象的引用和回收,让开发人员只需要创建对象,使用对象,编辑代码逻辑,不需要关注性能方面,让数据的各种存储交给Java自己处理,可以花更多的时间研究应用程序之间的关系,让开发变得更专注,就像赛车的驾驶员一样,只需要了解各种车辆的性能,并且进行操作,不需要研究轱辘如何制造,这样让程序开发更加的细化。

2.4 SSM框架

SSM框架是三个框架的合称,分别是Spring框架和SpringMVC框架以及MyBatis框架。三个框架随着时间的发展,越来越变成了当今Java语言的开发主流,帮助程序开发人员专注于业务逻辑以及配置相关操作,能自动生成的都支持自动生成,避免了很多耦合性出错,通过控制反转和依赖注入,让程序开发变成配置文件开发,简单明了,让创建的Java对象都能通过自身来进行创建。面向切面的操作让程序开发也变成了部门协同,公共事务都交给了SpringAOP来操作,让程序开发变得更加专注。MyBatis越来越智能,可以用配置文件和SQL语句混合开发,可以像操作Java语言一样操作数据库。

第三章 系统分析

通常,对于系统的开发并不是一朝一夕就可以完成的,它需要经历很多的步骤,其中系统分析就是其中的一个,接下来还会有系统的设计和实现,最后一个步骤是系统测试。

3.1可行性分析

一个系统能不能完成开发,以及该系统是否可以带来收益等,都是需要提前分析的。而可行性研究就是分析这些问题,并得出结论,这个环节对项目是否开展起着重要作用。

3.1.1运行可行性分析

首先本系统的运行环境都是当前使用率比较高的软件,通过网络可以下载安装,其次本系统对于运行设备的要求比较低,满足4个G的内存的电脑都可以使用。而当下硬件设备的升级,几乎大部分电脑都是内存8个G,所以运行设备也符合要求。最后,本系统不用于处理繁多的类似商业软件的信息内容,占用的空间比较小。一般的电脑都可以运行。

3.1.2经济可行性分析

任何一个项目在开发前,其在经济上的可行性问题是值得研究的,本项目论文管理系统,其在数据的处理上要求比较简单,并且其管理的数据量比较小,因此,该项目的开发周期并不会耽误很长时间,项目的开发需要支出的费用也不高。加上该项目需要管理的数据量较少,对于性能条件一般的计算机都可以满足项目的运行要求,从后期管理成本上来看,需要投入该项目的管理费用也不高。但是该项目一旦投入使用,会给使用者带来一定的收益,也能节省信息管理成本,如此,这样一个低成本投入,但能够带来大量收益的项目论文管理系统在经济上是可行的。

3.1.3技术可行性分析

互联网的发展非常迅速,跟互联网挂钩的程序也逐渐被广泛关注,尤其是当下被大众熟知的B/S结构的程序,加上JSP技术的发展与成熟,如今可以很快速的使用模块化的代码开发一个基于B/S结构的项目程序。

通过系统运行,经济和技术上的可行性分析,对论文管理系统的开发确实具有必要性,让管理的信息都计算机化,可以缩短在数据处理上消耗的时间,提高工作效率。

3.2系统流程分析

本系统在完成数据的处理时,其内部都设置了相应的处理流程,比如注册时,数据的最终去向以及对每项数据的判断等,这些都是提前进行了分析的,然后在编码时,把这种判断逻辑写入了系统中。让系统在面对同样的事务处理需求时,执行对应的逻辑处理规则。

目前很多的系统除了管理员的登录信息是编码时提前写入的信息,其他的用户的资料大多都是通过注册把资料写入系统中,让数据库中保存已注册用户的资料。注册功能其对应的流程如下。只有每项必填数据都符合要求,用户的资料才会被数据库保存。

图3.1用户注册流程图

在本系统的数据库中,所有用户的资料都会单独保存在一张数据表里面,也就意味着这张用户数据表里面的用户名和密码都是可以进行本系统的登录功能的,其登录流程如下。用户提交的登录信息都是必填项,不能漏掉,数据格式和内容都要准确才可以进入功能操作区。

图3.2 用户登录流程图

本系统中保存的数据都是具有参考价值的,所以在录入数据时,要确保数据的准确性,其录入数据的流程见下图。这些数据都是经过检验合格之后才会被数据库保存。

图3.3 信息添加流程图

3.3 系统性能分析

在进行系统分析期间,有一个很重要的环节,就是需要对系统的性能进行分析。可以说系统的性能跟系统的质量是成正比关系,也就是说系统性能也好,系统质量越可靠,系统性能不好,就代表着系统的质量不行,也就意味着系统在实际中的使用中,会出现中途崩溃,或者系统的数据容易泄露等风险。所以,提前进行系统性能的分析,就可以在系统设计实现中,避免出现上述风险问题。

描述系统性能的特征有可扩展性,易维护性,安全性等。

3.3.1系统安全性

一个系统是否安全,直接影响用户的使用。系统安全体现在数据上的保密性。通常,很多系统都设置了登录功能,或针对游客设置的注册功能等,无论是登录中需要使用的账号密码,还是用户注册产生的私密数据等都是系统中的宝贵资源,一旦数据泄露,一些非法人员就会从中谋取利益,或通过用户注册留下的电话骚扰用户,给用户带来身心上的伤害。所以一般针对此类关键数据,通常会直接进行加密保存。让数据始终保持安全状态。

3.3.2系统可扩展性

面对当前用户的使用需求设计的系统并不一定适用于未来。所以需要使用前瞻性的眼光来看待系统,提前预留好空间,方便在今后对系统进行升级,或者扩充系统功能。因此,系统需要具备可扩展性的特性。

3.3.3系统易维护性

系统在保持长时间使用中,难免会出现一些问题。所以在处理这些问题时,可能会对系统进行部分改动。而系统改动的难易程度就体现出系统是否具备易维护性,通常一个易于维护的系统,在面对系统改动时,将会很容易,而且也会节省时间和资金。

3.4系统功能分析

本系统的功能不会像市场上的商业程序一样具备复杂的功能,其提供的功能只能满足目标用户的一般的系统内容浏览和简单的信息处理功能。

本系统确定设置管理员权限,教师权限和学生权限。

设置的管理员功能可以见下图用例图。管理员管理教师,学生,论文,课题以及课题选择还有公告信息。

图3.4 管理员用例图

设置的教师功能可以见下图用例图。教师发布论文课题,查看学生选择的论文的课题以及学生上交的论文。

图3.5 教师用例图

设置的学生功能可以见下图用例图。学生选择课题,查看已选课题并上交论文,查看已经上交的论文详情以及管理员发布的公告。

图3.6 学生用例图

第四章 系统设计

设计时,通常把用户需求作为对系统功能和数据库的设计重点,殊不知,系统设计时,注重用户体验也是比较关键的设计内容。比如一个系统已经实现了用户需要的功能,但是其界面布局比较混乱,同时界面中各个元素的搭配也不合理,这样一旦访问者访问系统,在短时间内无法找到需要的信息,就容易产生视觉疲劳,直接影响用户对系统的使用。所以,系统设计时,也需要关注用户的使用体验。由于用户之间的差别,比如教育程度,职业,地区等因素的不同,用户产生的行为也会存在差异,所以设计人员既要考虑用户之间的行为差异,也要考虑他们之间的共性。在尊重用户习惯的基础上,进行页面设计布局。达到用户可以多次访问系统的目的。

4.1布局设计原则

进行页面的布局,就要划分系统的各个模块,然后根据这些模块的重要程度进行布局,也需要关注用户比较在意的关键信息,利用合理的布局方式,传达出系统想要表达的信息内容,也让用户快速高效地获取需要的信息。布局虽然是页面设计的核心,但是也要讲究页面内容的协调性,统一性和均衡性。

布局设计也要考虑基本原则,接下来的内容就对此进行阐述。

第一点:参考系统需求,把系统的内容进行划分,按照重要程度的不同进行布局,并把相似或相近的信息内容集中展示在同一个区域,让访问者可以更流畅的阅读信息;

第二点:页面中比较重要的区域是靠上靠左的位置,所以这部分区域应该放置系统中比较重要的模块,毕竟这部分区域可以吸引用户眼球,让用户进入页面中,就可以发现需要的信息。对于一些次要的模块,则可以放置在页面中靠下和靠右的位置。如此设计安排,才可以发挥出页面设计实用性的特点;

第三点:根据用户习惯设计页面,虽然大部分用户具有操作上的共性特征,但他们之间还是存在区别,常见的影响用户操作习惯的因素有:年龄,学历,职业,性别等。所以设计时在考虑用户的共性特征时,也需要尽量尊重用户的不同习惯。

4.2功能模块设计

下图为管理员的功能设计,管理员管理教师,学生,论文,课题以及课题选择还有公告信息。

图4.1 管理员功能结构图

下图为教师的功能设计,教师发布论文课题,查看学生选择的论文的课题以及学生上交的论文。

图4.2 教师功能结构图

下图为学生的功能设计,学生选择课题,查看已选课题并上交论文,查看已经上交的论文详情以及管理员发布的公告。

图4.3 学生功能结构图

4.3数据库设计

论文管理系统选用关系数据库作为程序的后台支持,之所以选择关系数据库主要还是因为它易于使用,而且也方便进行数据维护,尤其是提供强大的SQL查询语言。还有就是关系数据库采用的二维表模型,跟现实生活中的逻辑非常贴近,与网状模型,层次模型相比较,可以发现还是关系模型更容易被接受。

4.3.1数据库E-R图

这部分内容需要根据用户需求当中的数据信息,进行拆分,并仔细分析,要从这些数据中标识出E-R模型需要使用的数据,其中有实体,有实体具备的属性,有基于实体间的关系。在获取了这些数据之后,就可以使用认可度比较高的Visio工具来完成E-R模型的建模。建模期间,只要注意Visio工具中,绘制E-R模型的各个符号代表的含义,并能够正确把实体,属性还有关系等数据完整表示就可以了。使用这样的方法可以节省数据库设计的时间,而且还可以直观表达设计的内容,以及它们之间存在的联系。

(1)设计的论文实体,其具备的属性如下图。

图4.4 论文实体属性图

(2)设计的学生实体,其具备的属性如下图。

图4.5 学生实体属性图

(3)设计的教师实体,其具备的属性如下图。

图4.6 教师实体属性图

  1. 设计的课题实体,其具备的属性如下图。

图4.7 课题实体属性图

(8)设计的实体间关系如下图。

图4.8 实体间关系E-R图

4.3.2 数据库表结构

程序编码基本都是参照设计的方案进行的,包括设计的数据库也是对后面的编码有着一定的影响。通常来说,数据库就是保存数据,不管其设计得好坏,都不会丧失它本身的数据保存功能。设计数据库的好坏,其区别在于,对数据存取的效率。设计比较好的数据库,在数据查询,存储以及更新上,可以快速做出响应。设计不好的数据库,很多时候不仅会延长数据的处理时间,还会容易出错。因此,设计数据库也是程序开发中很关键的环节。

针对本系统设计的数据库,按照数据库设计的原则,即设计数据库的三大范式进行。各个数据表的结构都是根据E-R模型进行的物理转化,对于一些细节问题,包括表的命名,字段的命名,字段类型和长度的设计等都比较规范化,这样做的目的也是方便后期系统编程。

表4.1 公告信息表

字段类型默认注释
id (主键)bigint(20)主键
addtimetimestampCURRENT_TIMESTAMP创建时间
biaotivarchar(200)NULL标题
neironglongtextNULL内容
fabushijiandatetimeNULL发布时间
tupianvarchar(200)NULL图片

表4.2 教师信息表

字段类型默认注释
id (主键)bigint(20)主键
addtimetimestampCURRENT_TIMESTAMP创建时间
jiaoshizhanghaovarchar(200)NULL教师账号
mimavarchar(200)NULL密码
jiaoshixingmingvarchar(200)NULL教师姓名
xingbievarchar(200)NULL性别
dianhuavarchar(200)NULL电话
shenfenzhengvarchar(200)NULL身份证
youxiangvarchar(200)NULL邮箱
touxiangvarchar(200)NULL头像

表4.3 课题信息表

字段类型默认注释
id (主键)bigint(20)主键
addtimetimestampCURRENT_TIMESTAMP创建时间
jiaoshizhanghaovarchar(200)NULL教师账号
jiaoshixingmingvarchar(200)NULL教师姓名
dianhuavarchar(200)NULL电话
ketimingchengvarchar(200)NULL课题名称
ketijianjielongtextNULL课题简介
ketiwenjianvarchar(200)NULL课题文件

表4.4 课题选择信息表

字段类型默认注释
id (主键)bigint(20)主键
addtimetimestampCURRENT_TIMESTAMP创建时间
jiaoshizhanghaovarchar(200)NULL教师账号
jiaoshixingmingvarchar(200)NULL教师姓名
dianhuavarchar(200)NULL电话
ketimingchengvarchar(200)NULL课题名称
ketijianjievarchar(200)NULL课题简介
ketiwenjianvarchar(200)NULL课题文件
zhanghaovarchar(200)NULL账号
xingmingvarchar(200)NULL姓名
banjivarchar(200)NULL班级
zhuanyevarchar(200)NULL专业
shijiandatetimeNULL时间

表4.5 论文信息表

字段类型默认注释
id (主键)bigint(20)主键
addtimetimestampCURRENT_TIMESTAMP创建时间
jiaoshizhanghaovarchar(200)NULL教师账号
jiaoshixingmingvarchar(200)NULL教师姓名
dianhuavarchar(200)NULL电话
ketimingchengvarchar(200)NULL课题名称
ketijianjievarchar(200)NULL课题简介
ketiwenjianvarchar(200)NULL课题文件
zhanghaovarchar(200)NULL账号
xingmingvarchar(200)NULL姓名
banjivarchar(200)NULL班级
zhuanyevarchar(200)NULL专业
lunwenmingchengvarchar(200)NULL论文名称
lunwenshangchuanvarchar(200)NULL论文上传
shangchuanshijiandatetimeNULL上传时间

表4.6 管理员信息表

字段类型默认注释
id (主键)bigint(20)主键
usernamevarchar(100)用户名
passwordvarchar(100)密码
rolevarchar(100)管理员角色
addtimetimestampCURRENT_TIMESTAMP新增时间

表4.7 学生信息表

字段类型默认注释
id (主键)bigint(20)主键
addtimetimestampCURRENT_TIMESTAMP创建时间
zhanghaovarchar(200)NULL账号
mimavarchar(200)NULL密码
xingmingvarchar(200)NULL姓名
xingbievarchar(200)NULL性别
shoujivarchar(200)NULL手机
banjivarchar(200)NULL班级
zhuanyevarchar(200)NULL专业
youxiangvarchar(200)NULL邮箱
touxiangvarchar(200)NULL头像

第五章 系统实现

这部分工作主要由程序编制人员完成。通常在面对一个大型的系统时,这些程序编制人员就会明确分工,每个人都完成不同的功能模块,在用代码实现功能的基础上,提前预留好接口,最后才将他们已完成的功能模块通过接口进行组合。

5.1 管理员功能实现

5.1.1 教师管理

管理教师是管理员的功能。其运行效果图如下。新增教师,修改教师,查询教师等操作都是在本页面完成。

图5.1 教师管理页面

5.1.2 学生管理

管理学生是管理员的功能。其运行效果图如下。学生的资料需要管理员负责管理,包括修改学生的专业,邮箱,手机,班级等信息,管理员通过查询功能提供学生账号即可获取学生信息。

图5.2 学生管理页面

5.1.3 公告管理

管理公告是管理员的功能。其运行效果图如下。本模块主要让管理员负责发布公告,对公告的资料进行更改,点击删除按钮即可删除对应的公告信息。

图5.3 公告管理页面

5.2 教师功能实现

5.2.1 课题管理

管理论文课题是教师的功能。其运行效果图如下。教师负责发布论文课题信息,在本页面可以随时修改论文课题相关描述信息。

图5.4 课题管理页面

5.2.2 论文查看

查看学生上交的论文是教师的功能。其运行效果图如下。教师需要下载学生上交的论文,查询学生上交的论文,查看学生上交的论文详情。

图5.5 论文查看页面

5.3 学生功能实现

5.3.1 课题管理

学生进人本人后台之后,可以选择课题。其运行效果图如下。学生查看各个课题的描述信息,下载课题文件,点击课题右侧的课题选择按钮即可选择课题。

图5.6 课题管理页面

5.3.2 课题选择管理

学生进人本人后台之后,可以查看课题选择信息。其运行效果图如下。学生查看已经选择的课题,然后完成课题论文,并在本页面上交论文。

图5.7 课题选择管理页面

5.3.3 论文查看

学生进人本人后台之后,可以查看已经上交的论文。其运行效果图如下。学生查询上交的论文,下载上交的论文,查看上交论文的详情信息。

图5.8 论文查看页面

FileController.java
package com.controller;

import java.io.File;
import java.io.IOException;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.annotation.IgnoreAuth;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.entity.ConfigEntity;
import com.entity.EIException;
import com.service.ConfigService;
import com.utils.R;

/**
 * 上传文件映射表
 */
@RestController
@RequestMapping("file")
@SuppressWarnings({"unchecked","rawtypes"})
public class FileController{
	@Autowired
    private ConfigService configService;
	/**
	 * 上传文件
	 */
	@RequestMapping("/upload")
	public R upload(@RequestParam("file") MultipartFile file, String type,HttpServletRequest request) throws Exception {
		if (file.isEmpty()) {
			throw new EIException("上传文件不能为空");
		}
		String fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1);
		String fileName = new Date().getTime()+"."+fileExt;
		File dest = new File(request.getSession().getServletContext().getRealPath("/upload")+"/"+fileName);
		file.transferTo(dest);
		if(StringUtils.isNotBlank(type) && type.equals("1")) {
			ConfigEntity configEntity = configService.selectOne(new EntityWrapper<ConfigEntity>().eq("name", "faceFile"));
			if(configEntity==null) {
				configEntity = new ConfigEntity();
				configEntity.setName("faceFile");
				configEntity.setValue(fileName);
			} else {
				configEntity.setValue(fileName);
			}
			configService.insertOrUpdate(configEntity);
		}
		return R.ok().put("file", fileName);
	}
	
	/**
	 * 下载文件
	 */
	@IgnoreAuth
	@RequestMapping("/download")
	public void download(@RequestParam String fileName, HttpServletRequest request, HttpServletResponse response) {
		try {
			File file = new File(request.getSession().getServletContext().getRealPath("/upload")+"/"+fileName);
			if (file.exists()) {
				response.reset();
				response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName+"\"");
				response.setHeader("Cache-Control", "no-cache");
				response.setHeader("Access-Control-Allow-Credentials", "true");
				response.setContentType("application/octet-stream; charset=UTF-8");
				IOUtils.write(FileUtils.readFileToByteArray(file), response.getOutputStream());
			}

		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
}

FileUtil.java
package com.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
* 类说明 : 
*/

public class FileUtil {
	public static byte[] FileToByte(File file) throws IOException {
		// 将数据转为流
		@SuppressWarnings("resource")
		InputStream content = new FileInputStream(file);
		ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
		byte[] buff = new byte[100];
		int rc = 0;
		while ((rc = content.read(buff, 0, 100)) > 0) {
			swapStream.write(buff, 0, rc);
		}
		// 获得二进制数组
		return swapStream.toByteArray();
	}
}

KetixuanzeServiceImpl.java
package com.service.impl;

import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.List;

import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.utils.PageUtils;
import com.utils.Query;


import com.dao.KetixuanzeDao;
import com.entity.KetixuanzeEntity;
import com.service.KetixuanzeService;
import com.entity.vo.KetixuanzeVO;
import com.entity.view.KetixuanzeView;

@Service("ketixuanzeService")
public class KetixuanzeServiceImpl extends ServiceImpl<KetixuanzeDao, KetixuanzeEntity> implements KetixuanzeService {
	

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Page<KetixuanzeEntity> page = this.selectPage(
                new Query<KetixuanzeEntity>(params).getPage(),
                new EntityWrapper<KetixuanzeEntity>()
        );
        return new PageUtils(page);
    }
    
    @Override
	public PageUtils queryPage(Map<String, Object> params, Wrapper<KetixuanzeEntity> wrapper) {
		  Page<KetixuanzeView> page =new Query<KetixuanzeView>(params).getPage();
	        page.setRecords(baseMapper.selectListView(page,wrapper));
	    	PageUtils pageUtil = new PageUtils(page);
	    	return pageUtil;
 	}
    
    @Override
	public List<KetixuanzeVO> selectListVO(Wrapper<KetixuanzeEntity> wrapper) {
 		return baseMapper.selectListVO(wrapper);
	}
	
	@Override
	public KetixuanzeVO selectVO(Wrapper<KetixuanzeEntity> wrapper) {
 		return baseMapper.selectVO(wrapper);
	}
	
	@Override
	public List<KetixuanzeView> selectListView(Wrapper<KetixuanzeEntity> wrapper) {
		return baseMapper.selectListView(wrapper);
	}

	@Override
	public KetixuanzeView selectView(Wrapper<KetixuanzeEntity> wrapper) {
		return baseMapper.selectView(wrapper);
	}

}

login.vue
<template>
  <div>
    <div class="container loginIn" style="backgroundImage: url(http://codegen.caihongy.cn/20210417/43f65b5dad5b48fa9ea5083ff2f4c164.jpg)">

      <div :class="3 == 1 ? 'left' : 3 == 2 ? 'left center' : 'left right'" style="backgroundColor: rgba(255, 255, 255, 0.08)">
        <el-form class="login-form" label-position="left" :label-width="3 == 3 ? '56px' : '0px'">
          <div class="title-container"><h3 class="title" style="color: rgba(30, 136, 229, 1)">论文管理系统登录</h3></div>
          <el-form-item :label="3 == 3 ? '用户名' : ''" :class="'style'+3">
            <span v-if="3 != 3" class="svg-container" style="color:rgba(0, 30, 255, 1);line-height:44px"><svg-icon icon-class="user" /></span>
            <el-input placeholder="请输入用户名" name="username" type="text" v-model="rulesForm.username" />
          </el-form-item>
          <el-form-item :label="3 == 3 ? '密码' : ''" :class="'style'+3">
            <span v-if="3 != 3" class="svg-container" style="color:rgba(0, 30, 255, 1);line-height:44px"><svg-icon icon-class="password" /></span>
            <el-input placeholder="请输入密码" name="password" type="password" v-model="rulesForm.password" />
          </el-form-item>
          <el-form-item v-if="0 == '1'" class="code" :label="3 == 3 ? '验证码' : ''" :class="'style'+3">
            <span v-if="3 != 3" class="svg-container" style="color:rgba(0, 30, 255, 1);line-height:44px"><svg-icon icon-class="code" /></span>
            <el-input placeholder="请输入验证码" name="code" type="text" v-model="rulesForm.code" />
            <div class="getCodeBt" @click="getRandCode(4)" style="height:44px;line-height:44px">
              <span v-for="(item, index) in codes" :key="index" :style="{color:item.color,transform:item.rotate,fontSize:item.size}">{{ item.num }}</span>
            </div>
          </el-form-item>
          <el-form-item label="角色" prop="loginInRole" class="role">
            <el-radio
              v-for="item in menus"
	      v-if="item.hasBackLogin=='是'"
              v-bind:key="item.roleName"
              v-model="rulesForm.role"
              :label="item.roleName"
            >{{item.roleName}}</el-radio>
          </el-form-item>
          <el-button type="primary" @click="login()" class="loginInBt" style="padding:0;font-size:16px;border-radius:4px;height:44px;line-height:44px;width:100%;backgroundColor:rgba(30, 136, 229, 1); borderColor:rgba(30, 136, 229, 1); color:rgba(255, 255, 255, 1)">{{'1' == '1' ? '登录' : 'login'}}</el-button>
          <el-form-item class="setting">
            <div style="color:rgba(255, 255, 255, 1)" class="register" @click="register('xuesheng')">注册学生</div>
            <div style="color:rgba(255, 255, 255, 1)" class="register" @click="register('jiaoshi')">注册教师</div>
            <!-- <div style="color:rgba(255, 255, 255, 1)" class="reset">修改密码</div> -->
          </el-form-item>
        </el-form>
      </div>

    </div>
  </div>
</template>
<script>
import menu from "@/utils/menu";
export default {
  data() {
    return {
      rulesForm: {
        username: "",
        password: "",
        role: "",
        code: '',
      },
      menus: [],
      tableName: "",
      codes: [{
        num: 1,
        color: '#000',
        rotate: '10deg',
        size: '16px'
      },{
        num: 2,
        color: '#000',
        rotate: '10deg',
        size: '16px'
      },{
        num: 3,
        color: '#000',
        rotate: '10deg',
        size: '16px'
      },{
        num: 4,
        color: '#000',
        rotate: '10deg',
        size: '16px'
      }],
    };
  },
  mounted() {
    let menus = menu.list();
    this.menus = menus;
  },
  created() {
    this.setInputColor()
    this.getRandCode()
  },
  methods: {
    setInputColor(){
      this.$nextTick(()=>{
        document.querySelectorAll('.loginIn .el-input__inner').forEach(el=>{
          el.style.backgroundColor = "rgba(244, 237, 237, 1)"
          el.style.color = "rgba(51, 51, 51, 1)"
          el.style.height = "44px"
          el.style.lineHeight = "44px"
          el.style.borderRadius = "4px"
        })
        document.querySelectorAll('.loginIn .style3 .el-form-item__label').forEach(el=>{
          el.style.height = "44px"
          el.style.lineHeight = "44px"
        })
        document.querySelectorAll('.loginIn .el-form-item__label').forEach(el=>{
          el.style.color = "rgba(0, 30, 255, 1)"
        })
        setTimeout(()=>{
          document.querySelectorAll('.loginIn .role .el-radio__label').forEach(el=>{
            el.style.color = "#fff"
          })
        },350)
      })

    },
    register(tableName){
      this.$storage.set("loginTable", tableName);
      this.$router.push({path:'/register'})
    },
    // 登陆
    login() {
      let code = ''
      for(let i in this.codes) {
        code += this.codes[i].num
      }
	  if ('0' == '1' && !this.rulesForm.code) {
	     this.$message.error("请输入验证码");
	    return;
	  }
      if ('0' == '1' && this.rulesForm.code.toLowerCase() != code.toLowerCase()) {
         this.$message.error("验证码输入有误");
		this.getRandCode()
        return;
      }
      if (!this.rulesForm.username) {
         this.$message.error("请输入用户名");
        return;
      }
      if (!this.rulesForm.password) {
         this.$message.error("请输入密码");
        return;
      }
      if (!this.rulesForm.role) {
         this.$message.error("请选择角色");
        return;
      }
      let menus = this.menus;
      for (let i = 0; i < menus.length; i++) {
        if (menus[i].roleName == this.rulesForm.role) {
          this.tableName = menus[i].tableName;
        }
      }
      this.$http({
        url: `${this.tableName}/login?username=${this.rulesForm.username}&password=${this.rulesForm.password}`,
        method: "post"
      }).then(({ data }) => {
        if (data && data.code === 0) {
          this.$storage.set("Token", data.token);
          this.$storage.set("role", this.rulesForm.role);
          this.$storage.set("sessionTable", this.tableName);
          this.$storage.set("adminName", this.rulesForm.username);
          this.$router.replace({ path: "/index/" });
        } else {
          this.$message.error(data.msg);
        }
      });
    },
    getRandCode(len = 4){
      this.randomString(len)
    },
    randomString(len = 4) {
      let chars = [
          "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
          "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
          "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
          "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
          "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2",
          "3", "4", "5", "6", "7", "8", "9"
      ]
      let colors = ["0", "1", "2","3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"]
      let sizes = ['14', '15', '16', '17', '18']

      let output = [];
      for (let i = 0; i < len; i++) {
        // 随机验证码
        let key = Math.floor(Math.random()*chars.length)
        this.codes[i].num = chars[key]
        // 随机验证码颜色
        let code = '#'
        for (let j = 0; j < 6; j++) {
          let key = Math.floor(Math.random()*colors.length)
          code += colors[key]
        }
        this.codes[i].color = code
        // 随机验证码方向
        let rotate = Math.floor(Math.random()*60)
        let plus = Math.floor(Math.random()*2)
        if(plus == 1) rotate = '-'+rotate
        this.codes[i].rotate = 'rotate('+rotate+'deg)'
        // 随机验证码字体大小
        let size = Math.floor(Math.random()*sizes.length)
        this.codes[i].size = sizes[size]+'px'
      }
    },
  }
};
</script>
<style lang="scss" scoped>
.loginIn {
  min-height: 100vh;
  position: relative;
  background-repeat: no-repeat;
  background-position: center center;
  background-size: cover;

  .left {
    position: absolute;
    left: 0;
    top: 0;
    width: 360px;
    height: 100%;

    .login-form {
      background-color: transparent;
      width: 100%;
      right: inherit;
      padding: 0 12px;
      box-sizing: border-box;
      display: flex;
      justify-content: center;
      flex-direction: column;
    }

    .title-container {
      text-align: center;
      font-size: 24px;

      .title {
        margin: 20px 0;
      }
    }

    .el-form-item {
      position: relative;

      .svg-container {
        padding: 6px 5px 6px 15px;
        color: #889aa4;
        vertical-align: middle;
        display: inline-block;
        position: absolute;
        left: 0;
        top: 0;
        z-index: 1;
        padding: 0;
        line-height: 40px;
        width: 30px;
        text-align: center;
      }

      .el-input {
        display: inline-block;
        height: 40px;
        width: 100%;

        & /deep/ input {
          background: transparent;
          border: 0px;
          -webkit-appearance: none;
          padding: 0 15px 0 30px;
          color: #fff;
          height: 40px;
        }
      }

    }


  }

  .center {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 360px;
    transform: translate3d(-50%,-50%,0);
    height: 446px;
    border-radius: 8px;
  }

  .right {
    position: absolute;
    left: inherit;
    right: 0;
    top: 0;
    width: 360px;
    height: 100%;
  }

  .code {
    .el-form-item__content {
      position: relative;

      .getCodeBt {
        position: absolute;
        right: 0;
        top: 0;
        line-height: 40px;
        width: 100px;
        background-color: rgba(51,51,51,0.4);
        color: #fff;
        text-align: center;
        border-radius: 0 4px 4px 0;
        height: 40px;
        overflow: hidden;

        span {
          padding: 0 5px;
          display: inline-block;
          font-size: 16px;
          font-weight: 600;
        }
      }

      .el-input {
        & /deep/ input {
          padding: 0 130px 0 30px;
        }
      }
    }
  }

  .setting {
    & /deep/ .el-form-item__content {
      padding: 0 15px;
      box-sizing: border-box;
      line-height: 32px;
      height: 32px;
      font-size: 14px;
      color: #999;
      margin: 0 !important;

      .register {
        float: left;
        width: 50%;
      }

      .reset {
        float: right;
        width: 50%;
        text-align: right;
      }
    }
  }

  .style2 {
    padding-left: 30px;

    .svg-container {
      left: -30px !important;
    }

    .el-input {
      & /deep/ input {
        padding: 0 15px !important;
      }
    }
  }

  .code.style2, .code.style3 {
    .el-input {
      & /deep/ input {
        padding: 0 115px 0 15px;
      }
    }
  }

  .style3 {
    & /deep/ .el-form-item__label {
      padding-right: 6px;
    }

    .el-input {
      & /deep/ input {
        padding: 0 15px !important;
      }
    }
  }

  .role {
    & /deep/ .el-form-item__label {
      width: 56px !important;
    }

    & /deep/ .el-radio {
      margin-right: 12px;
    }
  }

}
</style>

声明

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值