├── .gitignore
├── README.md
├── babel.config.js
├── package-lock.json
├── package.json
├── public
├── favicon.ico
└── index.html
├── src
├── App.vue
├── assets
│ ├── bg.jpg
│ ├── exam.png
│ ├── jige.jpg
│ └── logo.png
├── components
│ ├── HelloWorld.vue
│ ├── Pagination.vue
│ ├── SlideVerification.vue
│ └── TimeCountDown.vue
├── layout
│ └── index.vue
├── main.js
├── plugins
│ ├── axios.js
│ └── element.js
├── router
│ └── index.js
├── store
│ └── index.js
└── views
│ ├── Answer.vue
│ ├── Center.vue
│ ├── Error.vue
│ ├── Exam.vue
│ ├── Grade.vue
│ ├── Login.vue
│ ├── Paper.vue
│ ├── Password.vue
│ ├── Practice.vue
│ ├── Record.vue
│ ├── Register.vue
│ └── Score.vue
└── vue.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw?
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # exam-online
2 |
3 | 后端代码:https://github.com/520118202/ExamOnline
4 |
5 | ## Project setup
6 | ```
7 | npm install
8 | ```
9 |
10 | ### Compiles and hot-reloads for development
11 | ```
12 | npm run serve
13 | ```
14 |
15 | ### Compiles and minifies for production
16 | ```
17 | npm run build
18 | ```
19 |
20 | ### Customize configuration
21 | See [Configuration Reference](https://cli.vuejs.org/config/).
22 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exam-online",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build"
8 | },
9 | "dependencies": {
10 | "@babel/core": "^7.10.2",
11 | "@babel/preset-env": "^7.10.2",
12 | "core-js": "^3.6.4",
13 | "element-ui": "^2.4.5",
14 | "vue": "^2.6.11",
15 | "vue-router": "^3.1.5",
16 | "vuex": "^3.1.2"
17 | },
18 | "devDependencies": {
19 | "@vue/cli-plugin-babel": "^4.2.0",
20 | "@vue/cli-plugin-router": "^4.2.0",
21 | "@vue/cli-plugin-vuex": "^4.2.0",
22 | "@vue/cli-service": "^4.2.0",
23 | "axios": "^0.18.0",
24 | "node-sass": "^4.12.0",
25 | "sass-loader": "^8.0.2",
26 | "vue-cli-plugin-axios": "0.0.4",
27 | "vue-cli-plugin-element": "^1.0.1",
28 | "vue-template-compiler": "^2.6.11"
29 | },
30 | "browserslist": [
31 | "> 1%",
32 | "last 2 versions"
33 | ]
34 | }
35 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/520118202/exam-online/e8bcf8ff64f99dd34bc3d96bdef03b8c552a83ed/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
14 |
15 |
24 |
--------------------------------------------------------------------------------
/src/assets/bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/520118202/exam-online/e8bcf8ff64f99dd34bc3d96bdef03b8c552a83ed/src/assets/bg.jpg
--------------------------------------------------------------------------------
/src/assets/exam.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/520118202/exam-online/e8bcf8ff64f99dd34bc3d96bdef03b8c552a83ed/src/assets/exam.png
--------------------------------------------------------------------------------
/src/assets/jige.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/520118202/exam-online/e8bcf8ff64f99dd34bc3d96bdef03b8c552a83ed/src/assets/jige.jpg
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/520118202/exam-online/e8bcf8ff64f99dd34bc3d96bdef03b8c552a83ed/src/assets/logo.png
--------------------------------------------------------------------------------
/src/components/HelloWorld.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{ msg }}
4 |
5 | For a guide and recipes on how to configure / customize this project,
6 | check out the
7 | vue-cli documentation.
8 |
9 |
Installed CLI Plugins
10 |
15 |
Essential Links
16 |
23 |
Ecosystem
24 |
31 |
32 |
33 |
34 |
42 |
43 |
44 |
60 |
--------------------------------------------------------------------------------
/src/components/Pagination.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
37 |
38 |
43 |
--------------------------------------------------------------------------------
/src/components/SlideVerification.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{confirmWords}}
5 |
7 |
8 |
9 |
10 |
75 |
76 |
119 |
--------------------------------------------------------------------------------
/src/components/TimeCountDown.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{showTimeLeft}}
5 |
6 |
7 |
8 |
78 |
--------------------------------------------------------------------------------
/src/layout/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | {{getStudent.name}}
21 |
22 |
23 |
24 |
25 |
26 |
27 | 个人中心
28 |
29 |
30 | 修改密码
31 |
32 |
33 | 退出登录
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | @Copyright 2019-2020. ALL Rights Reserved
44 |
45 |
46 |
47 |
48 |
49 |
92 |
93 |
133 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import router from './router'
4 | import store from './store'
5 | import './plugins/axios.js'
6 | import './plugins/element.js'
7 |
8 | Vue.config.productionTip = false
9 |
10 | new Vue({
11 | router,
12 | store,
13 | render: h => h(App)
14 | }).$mount('#app')
15 |
--------------------------------------------------------------------------------
/src/plugins/axios.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | import Vue from 'vue';
4 | import axios from "axios";
5 |
6 | // Full config: https://github.com/axios/axios#request-config
7 | // axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
8 | // axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
9 | // axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
10 |
11 | let config = {
12 | // baseURL: process.env.baseURL || process.env.apiUrl || ""
13 | // timeout: 60 * 1000, // Timeout
14 | // withCredentials: true, // Check cross-site Access-Control
15 | };
16 |
17 | const _axios = axios.create(config);
18 |
19 | _axios.interceptors.request.use(
20 | function(config) {
21 | // Do something before request is sent
22 | // 添加请求拦截器,在请求头中加token
23 | if (localStorage.getItem('Authorization')) {
24 | config.headers.Authorization = localStorage.getItem('Authorization');
25 | }
26 | return config;
27 | },
28 | function(error) {
29 | // Do something with request error
30 | return Promise.reject(error);
31 | }
32 | );
33 |
34 | // Add a response interceptor
35 | _axios.interceptors.response.use(
36 | function(response) {
37 | // Do something with response data
38 | return response;
39 | },
40 | function(error) {
41 | // Do something with response error
42 | return Promise.reject(error);
43 | }
44 | );
45 |
46 | Plugin.install = function(Vue, options) {
47 | Vue.axios = _axios;
48 | window.axios = _axios;
49 | Object.defineProperties(Vue.prototype, {
50 | axios: {
51 | get() {
52 | return _axios;
53 | }
54 | },
55 | $axios: {
56 | get() {
57 | return _axios;
58 | }
59 | },
60 | });
61 | };
62 |
63 | Vue.use(Plugin)
64 |
65 | export default Plugin;
66 |
--------------------------------------------------------------------------------
/src/plugins/element.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Element from 'element-ui'
3 | import 'element-ui/lib/theme-chalk/index.css'
4 |
5 | Vue.use(Element)
6 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueRouter from 'vue-router'
3 | import Layout from '@/layout/index.vue'
4 |
5 | Vue.use(VueRouter)
6 |
7 | const routes = [{
8 | path: '/',
9 | component: Layout,
10 | redirect: '/exam',
11 | children: [{
12 | path: 'exam',
13 | component: () => import('../views/Exam.vue'),
14 | name: 'exam',
15 | meta: {
16 | title: '考试中心'
17 | }
18 | },
19 | {
20 | path: 'practice',
21 | name: 'Practice',
22 | component: () => import('../views/Practice.vue'),
23 | meta: {
24 | title: '模拟练习'
25 | }
26 | },
27 | {
28 | path: 'grade',
29 | name: 'Grade',
30 | component: () => import('../views/Grade.vue'),
31 | meta: {
32 | title: '查询成绩'
33 | }
34 | },
35 | {
36 | path: 'center',
37 | name: 'Center',
38 | component: () => import('../views/Center.vue'),
39 | meta: {
40 | title: '个人中心'
41 | }
42 | },
43 | {
44 | path: 'password',
45 | name: 'Password',
46 | component: () => import('../views/Password.vue'),
47 | meta: {
48 | title: '修改密码'
49 | }
50 | },
51 | {
52 | path: 'paper',
53 | name: 'Paper',
54 | component: () => import('../views/Paper.vue'),
55 | meta: {
56 | title: '试卷详情'
57 | }
58 | },
59 | {
60 | path: 'score',
61 | name: 'Score',
62 | component: () => import('../views/Score.vue'),
63 | meta: {
64 | title: '考试得分'
65 | }
66 | }
67 | ]
68 | },
69 | {
70 | path: '/answer',
71 | name: 'Answer',
72 | component: () => import('../views/Answer.vue'),
73 | meta: {
74 | title: '答题界面'
75 | }
76 | },
77 | {
78 | path: '/record',
79 | name: 'Record',
80 | component: () => import('../views/Record.vue'),
81 | meta: {
82 | title: '练习记录'
83 | }
84 | },
85 | {
86 | path: '/login',
87 | name: 'Login',
88 | component: () => import('../views/Login.vue'),
89 | meta: {
90 | title: '登录界面'
91 | }
92 | },
93 | {
94 | path: '/register',
95 | name: 'Register',
96 | component: () => import('../views/Register.vue'),
97 | meta: {
98 | title: '注册界面'
99 | }
100 | },
101 | {
102 | path: '*',
103 | name: 'Error',
104 | component: () => import('../views/Error.vue'),
105 | meta: {
106 | title: '404错误界面'
107 | }
108 | }
109 | ]
110 |
111 | const router = new VueRouter({
112 | mode: 'history',
113 | base: process.env.BASE_URL,
114 | routes
115 | })
116 |
117 | // 导航守卫
118 | // 使用 router.beforeEach 注册一个全局前置守卫,判断用户是否登陆
119 | router.beforeEach((to, from, next) => {
120 | // 设置标题
121 | if (to.meta.title) {
122 | document.title = to.meta.title
123 | }
124 |
125 | if (to.path === '/login' || to.path === '/register') {
126 | next();
127 | } else {
128 | let token = sessionStorage.getItem('Authorization');
129 | if (token === null || token === '') {
130 | next('/login');
131 | } else {
132 | next();
133 | }
134 | }
135 | });
136 | export default router
137 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 |
4 | Vue.use(Vuex)
5 |
6 | export default new Vuex.Store({
7 | state: {
8 | user: sessionStorage.getItem('user') ? JSON.parse(sessionStorage.getItem('user')) : {},
9 | student: sessionStorage.getItem('student') ? JSON.parse(sessionStorage.getItem('student')) : {},
10 | Authorization: sessionStorage.getItem('Authorization') ? sessionStorage.getItem('Authorization') : '',
11 | isPractice: sessionStorage.getItem('isPractice') ? sessionStorage.getItem('isPractice') : false
12 | },
13 | mutations: {
14 | setUser(state, value) {
15 | state.user = value;
16 | sessionStorage.setItem("user", JSON.stringify(value));
17 | },
18 | setStudent(state, value) {
19 | state.student = value;
20 | sessionStorage.setItem("student", JSON.stringify(value));
21 | },
22 | setAuthorization(state, value) {
23 | state.Authorization = value;
24 | sessionStorage.setItem("Authorization", value);
25 | },
26 | setIsPractice(state, value) {
27 | state.isPractice = value;
28 | sessionStorage.setItem("isPractice", value)
29 | }
30 | },
31 | actions: {
32 | },
33 | modules: {
34 | }
35 | })
36 |
--------------------------------------------------------------------------------
/src/views/Answer.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 选择题
8 |
9 |
10 |
12 | {{ index + 1 }}
13 |
14 |
15 |
16 | 填空题
17 |
18 |
19 |
21 | {{ index + fillPos }}
22 |
23 |
24 |
25 | 判断题
26 |
27 |
28 |
30 | {{ index + judgePos }}
31 |
32 |
33 |
34 |
35 | 编程题
36 |
37 |
38 |
40 | {{ index + programPos }}
41 |
42 |
43 |
44 |
45 |
46 | 已答
47 | 未答
48 | 当前
49 |
50 |
51 | 交卷
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | 学号:{{getUser.username}}
62 |
63 |
64 | 姓名:{{getStudent.name}}
65 |
66 |
67 | 性别:{{getStudent.gender = 'M' ? '男' : '女'}}
68 |
69 |
70 | 专业:{{clazz.major}}
71 |
72 |
73 | 年级:{{clazz.year}}
74 |
75 |
76 | 班级:{{clazz.clazz}}
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
{{index + 1}}. {{item.question}} [{{item.score}}分]
86 |
87 | A. {{item.answer_A}}
88 | B. {{item.answer_B}}
89 | C. {{item.answer_C}}
90 | D. {{item.answer_D}}
91 |
92 |
93 |
94 |
{{index + fillPos}}. {{item.question}} [{{item.score}}分]
95 |
96 |
97 |
98 |
{{index + judgePos}}. {{item.question}} [{{item.socre}}分]
99 |
100 | 正确
101 | 错误
102 |
103 |
104 |
105 |
{{index + programPos}}. {{item.question}} [{{item.score}}分]
106 |
107 |
108 | 编程区
109 |
110 |
111 |
112 |
113 | 测试
114 |
115 |
116 |
118 | 输出信息
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 | 上一题
131 |
132 |
133 | 下一题
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
484 |
485 |
570 |
--------------------------------------------------------------------------------
/src/views/Center.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 个人中心
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | 确认修改
33 | 取消
34 |
35 |
36 |
37 |
38 |
39 |
150 |
151 |
165 |
--------------------------------------------------------------------------------
/src/views/Error.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
404错误界面
4 |
访问的路径不存在
5 |
6 |
7 |
8 |
10 |
11 |
13 |
--------------------------------------------------------------------------------
/src/views/Exam.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | 搜索试卷
9 |
10 |
11 |
12 |
13 | 考试列表
14 |
15 |
16 |
17 |
18 |
19 |
{{item.name}}
20 |
21 | 考试时间:{{item.exam_date}}
22 |
23 | 考试时长:{{item.total_time}}分钟
24 |
25 |
26 |
29 | 开始做题
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
129 |
157 |
--------------------------------------------------------------------------------
/src/views/Grade.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | {{ scope.row.create_time.replace('T', ' ').substring(0, 19) }}
10 |
11 |
12 |
13 |
14 |
15 | 考试名称: {{ scope.row.exam.name }}
16 | 考试日期: {{ scope.row.exam.exam_date }}
17 | 考试时长: {{ scope.row.exam.total_time }}
18 | 所属专业: {{ scope.row.exam.major }}
19 | 考试须知: {{ scope.row.exam.tips }}
20 |
21 | {{ scope.row.exam.name }}
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | {{ scope.row.score }}
30 |
31 |
32 |
33 |
34 |
35 | {{ scope.row.exam.exam_date }}
36 |
37 |
38 |
40 |
41 | 及格
42 | 不及格
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
115 |
116 |
119 |
--------------------------------------------------------------------------------
/src/views/Login.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Python在线考试系统
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | 登录
21 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
104 |
105 |
144 |
--------------------------------------------------------------------------------
/src/views/Paper.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
9 |
--------------------------------------------------------------------------------
/src/views/Password.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 修改密码
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | 确认更改
18 | 取消
19 |
20 |
21 |
22 |
23 |
135 |
136 |
150 |
--------------------------------------------------------------------------------
/src/views/Practice.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 组卷模块
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | 生成试卷并开始答题
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | {{ scope.row.create_time.replace('T', ' ').substring(0, 19) }}
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | 查看记录
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
140 |
141 |
174 |
--------------------------------------------------------------------------------
/src/views/Record.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
选择题
5 |
6 |
{{index + 1}}. {{item.choice.question}}
7 |
8 | A. {{item.choice.answer_A}}
9 | B. {{item.choice.answer_B}}
10 | C. {{item.choice.answer_C}}
11 | D. {{item.choice.answer_D}}
12 |
13 | 结果:
14 |
15 | {{item.choice.right_answer === item.your_answer ? "正确" : "错误"}}
16 |
17 |
18 | 正确答案:{{item.choice.right_answer}}
19 | 分数:{{item.choice.score}}
20 | 难度:
21 |
22 | 解析:{{item.choice.analysis}}
23 |
24 |
25 |
26 |
填空题
27 |
28 |
{{index + 1}}. {{item.fill.question}}
29 |
30 | 结果:
31 |
32 | {{item.fill.right_answer === item.your_answer ? "正确" : "错误"}}
33 |
34 |
35 | 正确答案:{{item.fill.right_answer}}
36 | 分数:{{item.fill.score}}
37 | 难度:
38 |
39 | 解析:{{item.fill.analysis}}
40 |
41 |
42 |
43 |
判断题
44 |
45 |
{{index + 1}}. {{item.judge.question}}
46 |
47 | 正确
48 | 错误
49 |
50 | 结果:
51 |
52 | {{item.judge.right_answer === item.your_answer ? "正确" : "错误"}}
53 |
54 |
55 | 正确答案:{{item.judge.right_answer}}
56 | 分数:{{item.judge.score}}
57 | 难度:
58 |
59 | 解析:{{item.judge.analysis}}
60 |
61 |
62 |
63 |
编程题
64 |
65 |
{{index + 1}}. {{item.program.question}}
66 |
67 |
68 | 编程区
69 |
70 |
71 |
72 |
73 | 输出信息
74 |
75 |
76 |
77 |
78 | 结果:
79 |
80 | {{item.cmd_msg === 'pass' ? "正确" : "错误"}}
81 |
82 |
83 |
84 | 分数:{{item.program.score}}
85 | 难度:
86 |
87 | 解析:{{item.program.analysis}}
88 |
89 |
90 |
91 |
92 |
93 |
173 |
174 |
193 |
--------------------------------------------------------------------------------
/src/views/Register.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Python在线考试系统
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | 注册
29 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
177 |
178 |
212 |
--------------------------------------------------------------------------------
/src/views/Score.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
9 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | devServer: {
3 | proxy: {
4 | '/api': {
5 | target: 'http://127.0.0.1:8000',
6 | changeOrigin: true,
7 | pathRewrite: {
8 | '^/api': '/'
9 | }
10 | }
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------