├── .gitignore
├── LICENSE
├── README.md
├── exam-admin
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── senior
│ │ ├── ExamApplication.java
│ │ ├── config
│ │ ├── CorsConfig.java
│ │ ├── DruidConfig.java
│ │ ├── Interceptor
│ │ │ ├── AdminInterceptor.java
│ │ │ ├── StudentInterceptor.java
│ │ │ ├── TeacherInterceptor.java
│ │ │ └── WebAppConfigurer.java
│ │ ├── MybatisPlusConfig.java
│ │ └── RedisConfig.java
│ │ ├── constant
│ │ └── ExamConstant.java
│ │ ├── controller
│ │ ├── AdminController.java
│ │ ├── CommonController.java
│ │ ├── StudentController.java
│ │ ├── TeacherController.java
│ │ └── UtilController.java
│ │ ├── entity
│ │ ├── Answer.java
│ │ ├── Exam.java
│ │ ├── ExamQuestion.java
│ │ ├── ExamRecord.java
│ │ ├── Major.java
│ │ ├── Notice.java
│ │ ├── Question.java
│ │ ├── QuestionBank.java
│ │ ├── User.java
│ │ └── UserRole.java
│ │ ├── mapper
│ │ ├── AnswerMapper.java
│ │ ├── ExamMapper.java
│ │ ├── ExamQuestionMapper.java
│ │ ├── ExamRecordMapper.java
│ │ ├── MajorMapper.java
│ │ ├── NoticeMapper.java
│ │ ├── QuestionBankMapper.java
│ │ ├── QuestionMapper.java
│ │ ├── UserMapper.java
│ │ └── UserRoleMapper.java
│ │ ├── service
│ │ ├── AnswerService.java
│ │ ├── ExamQuestionService.java
│ │ ├── ExamRecordService.java
│ │ ├── ExamService.java
│ │ ├── MajorService.java
│ │ ├── NoticeService.java
│ │ ├── QuestionBankService.java
│ │ ├── QuestionService.java
│ │ ├── UserRoleService.java
│ │ ├── UserService.java
│ │ └── impl
│ │ │ ├── AnswerServiceImpl.java
│ │ │ ├── ExamQuestionServiceImpl.java
│ │ │ ├── ExamRecordServiceImpl.java
│ │ │ ├── ExamServiceImpl.java
│ │ │ ├── MajorServiceImpl.java
│ │ │ ├── NoticeServiceImpl.java
│ │ │ ├── QuestionBankServiceImpl.java
│ │ │ ├── QuestionServiceImpl.java
│ │ │ ├── UserRoleServiceImpl.java
│ │ │ └── UserServiceImpl.java
│ │ ├── util
│ │ ├── CheckToken.java
│ │ ├── CreateVerificationCode.java
│ │ ├── RedisUtil.java
│ │ ├── SaltEncryption.java
│ │ └── TokenUtils.java
│ │ └── vo
│ │ ├── AddExamByBankVo.java
│ │ ├── AddExamByQuestionVo.java
│ │ ├── BankHaveQuestionSum.java
│ │ ├── CommonResult.java
│ │ ├── ExamQueryVo.java
│ │ ├── ExamState.java
│ │ ├── QuestionVo.java
│ │ └── TokenVo.java
│ └── resources
│ ├── application.yml
│ └── mapper
│ ├── MajorMapper.xml
│ ├── NoticeMapper.xml
│ ├── UserMapper.xml
│ └── UserRoleMapper.xml
├── exam-vue
├── .browserslistrc
├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── babel.config.js
├── debug.log
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ └── index.html
├── src
│ ├── App.vue
│ ├── api
│ │ └── api.js
│ ├── assets
│ │ ├── css
│ │ │ └── global.css
│ │ ├── imgs
│ │ │ ├── bg.png
│ │ │ ├── examTitle.png
│ │ │ ├── favicon.png
│ │ │ ├── judge.png
│ │ │ ├── multiple.png
│ │ │ ├── order.png
│ │ │ ├── random.png
│ │ │ ├── single.png
│ │ │ ├── true.png
│ │ │ ├── wellcome.5bb22a17.jpg
│ │ │ ├── wellcome.jpg
│ │ │ └── wellcome.png
│ │ └── logo.png
│ ├── components
│ │ ├── AddExam.vue
│ │ ├── Dashboard.vue
│ │ ├── ExamManage.vue
│ │ ├── ExamOnline.vue
│ │ ├── ExamPage.vue
│ │ ├── ExamResult.vue
│ │ ├── Login.vue
│ │ ├── Main.vue
│ │ ├── Major.vue
│ │ ├── MarkExamPage.vue
│ │ ├── MarkManage.vue
│ │ ├── MyGrade.vue
│ │ ├── MyQuestionBank.vue
│ │ ├── NoticeManage.vue
│ │ ├── QuestionBankManage.vue
│ │ ├── QuestionManage.vue
│ │ ├── QuestionTk.vue
│ │ ├── Register.vue
│ │ ├── RoleManage.vue
│ │ ├── StatisticOverview.vue
│ │ ├── TrainPage.vue
│ │ ├── UpdateExam.vue
│ │ └── UserManage.vue
│ ├── main.js
│ ├── plugins
│ │ └── element.js
│ └── router
│ │ └── index.js
└── vue.config.js
├── sql
└── exam.sql
├── 初始用户1.png
├── 初始用户2.png
├── 在线考试系统设计文档.pdf
├── 说明.txt
└── 项目开发环境手册.pdf
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 | target
5 | *.iml
6 | OSSUtil.java
7 |
8 | # local env files
9 | .env.local
10 | .env.*.local
11 |
12 | # Log files
13 | npm-debug.log*
14 | yarn-debug.log*
15 | yarn-error.log*
16 | pnpm-debug.log*
17 |
18 | # Editor directories and files
19 | .idea
20 | .vscode
21 | *.suo
22 | *.ntvs*
23 | *.njsproj
24 | *.sln
25 | *.sw?
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ExamOnline
2 | ## 基于SpringBoot、Vue、Redis的在线考试系统
3 | ### 主要性能
4 | 1、本项目采用了 Springboot + vue2.0 前后端分离模式设计,后端提供获取和显 示数据库数据的接口,前端采用 Vue 框架 Element-UI 前端组件库布局,使用 http 和 axios 向后端发送数据请求获得数据集,然后在前端的组件内部进行展示,前 后端分离的项目模式程序代码层次分明,便于维护和修改。同时还用到了 Echarts 图表工具对考试结果进行展示。
5 |
6 | 2、因为本项目已经部署到服务器上,为了提升服务器性能,使用了 Redis 保存 已经访问过的信息,使请求的数据信息得以持久化,提升高并发性能和访问速度。
7 |
8 | 3、在用户登录验证方面,采用了自生成 token 令牌,每次用户发送请求时都需 要检验该用户的 token 是否与当前登录用户匹配且是否超时等,提升系统安全性能。
9 |
10 | 4、在用户信息安全方面,采取非明文数据存储数据库的方式,使用的是 MD5 信息摘要算法将密码转成完全不同的 128 位信息摘要。这样即使数据库信息泄露,用户的密码也是安全的。
11 |
12 | 5、接口设计采用 restful 风格,接口文档基于 swagger; 6、基于 slf4j 和 Log4j2 实现系统运行日志采集,基于切面实现系统操作日志采集
13 |
14 |
15 | ### 功能模块
16 | 
17 |
18 | ### 后端项目模块
19 | 
20 |
21 | ### 前端项目模块
22 | 
23 |
24 | ### 整体调用关系
25 | 
26 |
27 | ### 部分界面设计
28 | 
29 | 
30 | 
31 | 
32 | 
33 | 
34 | 
35 | 
36 | 
37 | 在线考试页面:
38 | 
39 | 
40 | 成绩可视化
41 | 
42 |
--------------------------------------------------------------------------------
/exam-admin/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.2.7.RELEASE
9 |
10 |
11 | com.senior
12 | exam-admin
13 | 0.0.1-SNAPSHOT
14 | exam-admin
15 | 在线考试系统
16 |
17 |
18 | 1.8
19 |
20 |
21 |
22 |
23 | org.springframework.boot
24 | spring-boot-starter-web
25 |
26 |
27 |
28 | mysql
29 | mysql-connector-java
30 | runtime
31 |
32 |
33 |
34 |
35 | log4j
36 | log4j
37 | 1.2.17
38 |
39 |
40 |
41 | org.projectlombok
42 | lombok
43 | true
44 |
45 |
46 |
47 |
48 | com.auth0
49 | java-jwt
50 | 3.8.2
51 |
52 |
53 |
54 |
55 | io.springfox
56 | springfox-swagger2
57 | 2.9.2
58 |
59 |
60 | io.springfox
61 | springfox-swagger-ui
62 | 2.9.2
63 |
64 |
65 |
66 | com.alibaba
67 | druid
68 | 1.1.22
69 |
70 |
71 |
72 | org.springframework.boot
73 | spring-boot-starter-data-redis
74 |
75 |
76 |
77 | com.baomidou
78 | mybatis-plus-boot-starter
79 | 3.0.5
80 |
81 |
82 |
83 | org.springframework.boot
84 | spring-boot-starter-test
85 | test
86 |
87 |
88 | org.junit.vintage
89 | junit-vintage-engine
90 |
91 |
92 |
93 |
94 | org.apache.commons
95 | commons-lang3
96 | 3.12.0
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 | org.springframework.boot
105 | spring-boot-maven-plugin
106 |
107 | com.senior.ExamApplication
108 |
109 |
110 |
111 |
112 |
113 |
114 |
--------------------------------------------------------------------------------
/exam-admin/src/main/java/com/senior/ExamApplication.java:
--------------------------------------------------------------------------------
1 | package com.senior;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
7 | import org.springframework.stereotype.Controller;
8 | import springfox.documentation.swagger2.annotations.EnableSwagger2;
9 |
10 | @SpringBootApplication
11 | @EnableSwagger2
12 | @Controller
13 | public class ExamApplication extends SpringBootServletInitializer {
14 |
15 | public static void main(String[] args) {
16 | SpringApplication.run(ExamApplication.class, args);
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/exam-admin/src/main/java/com/senior/config/CorsConfig.java:
--------------------------------------------------------------------------------
1 | package com.senior.config;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.web.cors.CorsConfiguration;
6 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
7 | import org.springframework.web.filter.CorsFilter;
8 | import org.springframework.web.servlet.config.annotation.CorsRegistry;
9 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
10 |
11 | @Configuration
12 | public class CorsConfig implements WebMvcConfigurer {
13 | @Override
14 | public void addCorsMappings(CorsRegistry registry) {
15 | registry.addMapping("/**")
16 | .allowedOrigins("*")
17 | .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
18 | .allowCredentials(true)
19 | .maxAge(3600)
20 | .allowedHeaders("*");
21 | }
22 |
23 | // 让cors高于拦截器的权限
24 | @Bean
25 | public CorsFilter corsFilter() {
26 | CorsConfiguration config = new CorsConfiguration();
27 | config.addAllowedOrigin("*");
28 | config.setAllowCredentials(true);
29 | config.addAllowedMethod("*");
30 | config.addAllowedHeader("*");
31 | UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
32 | configSource.registerCorsConfiguration("/**", config);
33 | return new CorsFilter(configSource);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/exam-admin/src/main/java/com/senior/config/DruidConfig.java:
--------------------------------------------------------------------------------
1 | package com.senior.config;
2 |
3 | import java.util.HashMap;
4 |
5 | import javax.sql.DataSource;
6 |
7 | import org.springframework.boot.context.properties.ConfigurationProperties;
8 | import org.springframework.boot.web.servlet.FilterRegistrationBean;
9 | import org.springframework.boot.web.servlet.ServletRegistrationBean;
10 | import org.springframework.context.annotation.Bean;
11 | import org.springframework.context.annotation.Configuration;
12 |
13 | import com.alibaba.druid.pool.DruidDataSource;
14 | import com.alibaba.druid.support.http.StatViewServlet;
15 | import com.alibaba.druid.support.http.WebStatFilter;
16 |
17 | @Configuration
18 | public class DruidConfig {
19 |
20 | @Bean
21 | @ConfigurationProperties(prefix = "spring.datasource")
22 | public DataSource druidDataSource() {
23 | return new DruidDataSource();
24 | }
25 |
26 | // 监控功能 web.xml ServletRegistrationBean
27 | // 因为springboot内置了servlet容器,所以没有web.xml,替代方法
28 |
29 | @Bean
30 | public ServletRegistrationBean statViewServlet() {
31 | ServletRegistrationBean bean = new ServletRegistrationBean<>(new StatViewServlet(),
32 | "/druid/*");
33 |
34 | // 后台需要有人登陆,账号密码配置
35 |
36 | HashMap initParameters = new HashMap<>();
37 | // 增加配置
38 | initParameters.put("loginUsername", "root");// 登陆key是固定的
39 | initParameters.put("loginPassword", "123456");
40 |
41 | // 允许谁能访问
42 | initParameters.put("allow", "");
43 |
44 | bean.setInitParameters(initParameters);// 设置初始化参数
45 | return bean;
46 | }
47 |
48 | // filter
49 | @Bean
50 | public FilterRegistrationBean webStatFilter() {
51 | FilterRegistrationBean bean = new FilterRegistrationBean();
52 |
53 | bean.setFilter(new WebStatFilter());
54 |
55 | // 可以过滤那些请求
56 |
57 | HashMap initParameters = new HashMap<>();
58 |
59 | // 这些东西不进行统计~
60 | initParameters.put("exclusion", "*.js,*.css,/druid/*");
61 |
62 | bean.setInitParameters(initParameters);
63 | return bean;
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/exam-admin/src/main/java/com/senior/config/Interceptor/AdminInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.senior.config.Interceptor;
2 |
3 | import java.util.Objects;
4 |
5 | import javax.servlet.http.HttpServletRequest;
6 | import javax.servlet.http.HttpServletResponse;
7 |
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.stereotype.Component;
10 | import org.springframework.web.servlet.HandlerInterceptor;
11 |
12 | import com.senior.service.impl.UserServiceImpl;
13 | import com.senior.util.CheckToken;
14 | import com.senior.vo.TokenVo;
15 |
16 | // 管理员的拦截器
17 | @Component
18 | public class AdminInterceptor implements HandlerInterceptor {
19 |
20 | @Autowired
21 | private UserServiceImpl userService;
22 |
23 | // 这个方法是在访问接口之前执行的,我们只需要在这里写验证登陆状态的业务逻辑,就可以在用户调用指定接口之前验证登陆状态了
24 | @Override
25 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
26 | throws Exception {
27 | // 判断用户的token信息是否满足
28 | TokenVo tokenVo = new CheckToken().checkToken(request, userService);
29 | if (tokenVo != null && Objects.equals(tokenVo.getRoleId(), 3 + "")) {
30 | return true;
31 | }
32 | // 当前不满足条件,直接跳转拦截
33 | response.getWriter().print("Access denied");
34 | return false;
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/exam-admin/src/main/java/com/senior/config/Interceptor/StudentInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.senior.config.Interceptor;
2 |
3 | import java.util.Objects;
4 |
5 | import javax.servlet.http.HttpServletRequest;
6 | import javax.servlet.http.HttpServletResponse;
7 |
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.stereotype.Component;
10 | import org.springframework.web.servlet.HandlerInterceptor;
11 |
12 | import com.senior.service.impl.UserServiceImpl;
13 | import com.senior.util.CheckToken;
14 | import com.senior.vo.TokenVo;
15 |
16 | // 学生的拦截器(管理员和学生)
17 | @Component
18 | public class StudentInterceptor implements HandlerInterceptor {
19 |
20 | @Autowired
21 | private UserServiceImpl userService;
22 |
23 | // 这个方法是在访问接口之前执行的,我们只需要在这里写验证登陆状态的业务逻辑,就可以在用户调用指定接口之前验证登陆状态了
24 | @Override
25 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
26 | throws Exception {
27 | // 判断用户的token信息是否满足
28 | TokenVo tokenVo = new CheckToken().checkToken(request, userService);
29 | if (tokenVo != null
30 | && (Objects.equals(tokenVo.getRoleId(), 3 + "") || Objects.equals(tokenVo.getRoleId(), 1 + ""))) {
31 | return true;
32 | }
33 | // 当前不满足条件,直接跳转拦截
34 | response.getWriter().print("Access denied");
35 | return false;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/exam-admin/src/main/java/com/senior/config/Interceptor/TeacherInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.senior.config.Interceptor;
2 |
3 | import java.util.Objects;
4 |
5 | import javax.servlet.http.HttpServletRequest;
6 | import javax.servlet.http.HttpServletResponse;
7 |
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.stereotype.Component;
10 | import org.springframework.web.servlet.HandlerInterceptor;
11 |
12 | import com.senior.service.impl.UserServiceImpl;
13 | import com.senior.util.CheckToken;
14 | import com.senior.vo.TokenVo;
15 |
16 | // 又属于老师又属于超级管理员和学生的拦截器
17 | @Component
18 | public class TeacherInterceptor implements HandlerInterceptor {
19 |
20 | @Autowired
21 | private UserServiceImpl userService;
22 |
23 | // 这个方法是在访问接口之前执行的,我们只需要在这里写验证登陆状态的业务逻辑,就可以在用户调用指定接口之前验证登陆状态了
24 | @Override
25 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
26 | throws Exception {
27 | // 判断用户的token信息是否满足
28 | TokenVo tokenVo = new CheckToken().checkToken(request, userService);
29 | if (tokenVo != null && (Objects.equals(tokenVo.getRoleId(), 3 + "")
30 | || Objects.equals(tokenVo.getRoleId(), 2 + "") || Objects.equals(tokenVo.getRoleId(), 1 + ""))) {
31 | return true;
32 | }
33 | // 当前不满足条件,直接跳转拦截
34 | response.getWriter().print("Access denied");
35 | return false;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/exam-admin/src/main/java/com/senior/config/Interceptor/WebAppConfigurer.java:
--------------------------------------------------------------------------------
1 | package com.senior.config.Interceptor;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
7 |
8 | @Configuration
9 | public class WebAppConfigurer implements WebMvcConfigurer {
10 |
11 | @Bean
12 | public AdminInterceptor getAdminInterceptor() {// 只属于管理员
13 | return new AdminInterceptor();
14 | }
15 |
16 | @Bean
17 | public TeacherInterceptor getTeacherInterceptor() {// 属于老师 但是管理员也可以用
18 | return new TeacherInterceptor();
19 | }
20 |
21 | @Bean
22 | public StudentInterceptor getStudentInterceptor() {// 属于学生 但是管理员也可以用
23 | return new StudentInterceptor();
24 | }
25 |
26 | @Override
27 | public void addInterceptors(InterceptorRegistry registry) {
28 | // 可添加多个
29 | // 拦截未登录进入超级管理员的界面
30 | registry.addInterceptor(getAdminInterceptor()).addPathPatterns("/admin/**");
31 | registry.addInterceptor(getTeacherInterceptor()).addPathPatterns("/teacher/**");
32 | registry.addInterceptor(getStudentInterceptor()).addPathPatterns("/student/**");
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/exam-admin/src/main/java/com/senior/config/MybatisPlusConfig.java:
--------------------------------------------------------------------------------
1 | package com.senior.config;
2 |
3 | import org.mybatis.spring.annotation.MapperScan;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.context.annotation.Profile;
7 |
8 | import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
9 | import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
10 |
11 | // 扫描我们的mapper文件夹
12 | @MapperScan("com.senior.mapper")
13 | @Configuration // 配置类
14 | public class MybatisPlusConfig {
15 |
16 | // 分页插件
17 | @Bean
18 | public PaginationInterceptor paginationInterceptor() {
19 | return new PaginationInterceptor();
20 | }
21 |
22 | /**
23 | * SQL执行效率插件
24 | */
25 | @Bean
26 | @Profile({"dev", "test"}) // 设置 dev test 环境开启
27 | public PerformanceInterceptor performanceInterceptor() {
28 | PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
29 | performanceInterceptor.setMaxTime(1000);// ms 设置sql执行的最大时间,如果超过了则不执行
30 | performanceInterceptor.setFormat(true);
31 | return performanceInterceptor;
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/exam-admin/src/main/java/com/senior/config/RedisConfig.java:
--------------------------------------------------------------------------------
1 | package com.senior.config;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.data.redis.connection.RedisConnectionFactory;
6 | import org.springframework.data.redis.core.RedisTemplate;
7 | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
8 | import org.springframework.data.redis.serializer.StringRedisSerializer;
9 |
10 | import com.fasterxml.jackson.annotation.JsonAutoDetect;
11 | import com.fasterxml.jackson.annotation.PropertyAccessor;
12 | import com.fasterxml.jackson.databind.DeserializationFeature;
13 | import com.fasterxml.jackson.databind.ObjectMapper;
14 |
15 | @Configuration
16 | public class RedisConfig {
17 |
18 | // 这是固定的模板
19 | // 自己定义了一个RedisTemplate
20 | @Bean
21 | @SuppressWarnings("all")
22 | public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
23 | // 我们为了自己开发方便, 一般直接使用
24 | RedisTemplate template = new RedisTemplate();
25 | template.setConnectionFactory(factory);
26 |
27 | // Json序列化配置
28 | Jackson2JsonRedisSerializer