Commit b769660cd6986ed5d519128a4db3ba2f3445f401
1 parent
13b58a42
备课组题细节调整,随堂问列表页面开发完成
Showing
27 changed files
with
1881 additions
and
643 deletions
router
1 | -[ //测试用,后续后端获取 | ||
2 | - { | ||
3 | - path: "/examinationPaper", | ||
4 | - iconCls: "fa fa-file-text", // 图标样式class | ||
5 | - name: "备题组卷", | ||
6 | - component: Layout, | ||
7 | - alone: true, | ||
8 | - children: [ | ||
9 | - { | ||
10 | - path: "/examinationPaper", | ||
11 | - iconCls: "fa fa-file-text", // 图标样式class | ||
12 | - name: "", | ||
13 | - component: ExaminationPaper, | ||
14 | - children: [] | ||
15 | - }, | ||
16 | - { | ||
17 | - path: "/examinationPaperAdd", | ||
18 | - iconCls: "", // 图标样式class | ||
19 | - name: "添加答题卡", | ||
20 | - component: ExaminationPaperAdd, | ||
21 | - children: [] | ||
22 | - }, | ||
23 | - { | ||
24 | - path: "/examinationPaperEdit", | ||
25 | - iconCls: "", // 图标样式class | ||
26 | - name: "修改答题卡", | ||
27 | - component: ExaminationPaperEdit, | ||
28 | - children: [] | ||
29 | - }, | ||
30 | - { | ||
31 | - path: "/examinationPaperRecycle", | ||
32 | - iconCls: "", // 图标样式class | ||
33 | - name: "已归档答题卡", | ||
34 | - component: ExaminationPaperRecycle, | ||
35 | - children: [] | ||
36 | - }, | ||
37 | - ] | ||
38 | - }, | ||
39 | - { | ||
40 | - path: "/ask", | ||
41 | - iconCls: "fa fa-bar-chart", // 图标样式class | ||
42 | - name: "随堂问报表", | ||
43 | - component: Layout, | ||
44 | - alone: true, | ||
45 | - children: [ | ||
46 | - { | ||
47 | - path: "/ask", | ||
48 | - iconCls: "fa fa-bar-chart", // 图标样式class | ||
49 | - name: "", | ||
50 | - component: Ask, | ||
51 | - children: [] | ||
52 | - | ||
53 | - }, | ||
54 | - { | ||
55 | - path: "/askAnalysis", | ||
56 | - iconCls: "", // 图标样式class | ||
57 | - name: "随堂问报表分析", | ||
58 | - component: AskAnalysis, | ||
59 | - children: [] | ||
60 | - } | ||
61 | - ] | ||
62 | - }, | ||
63 | - { | ||
64 | - path: "/test", | ||
65 | - iconCls: "fa fa-pie-chart", // 图标样式class | ||
66 | - name: "即时测报表", | ||
67 | - component: Layout, | ||
68 | - alone: true, | ||
69 | - children: [ | ||
70 | - { | ||
71 | - path: "/test", | ||
72 | - iconCls: "fa fa-pie-chart", // 图标样式class | ||
73 | - name: "", | ||
74 | - component: Test, | ||
75 | - children: [] | ||
76 | - }, | ||
77 | - { | ||
78 | - path: "/testAnalysis", | ||
79 | - iconCls: "", // 图标样式class | ||
80 | - name: "即时测报表分析", | ||
81 | - component: TestAnalysis, | ||
82 | - children: [] | ||
83 | - } | ||
84 | - | ||
85 | - ] | ||
86 | - }, | ||
87 | - { | ||
88 | - path: "/portrait", | ||
89 | - iconCls: "fa fa-users", // 图标样式class | ||
90 | - name: "学生画像", | ||
91 | - component: Layout, | ||
92 | - alone: true, | ||
93 | - children: [ | ||
94 | - { | ||
95 | - path: "/portrait", | ||
96 | - iconCls: "fa fa-users", // 图标样式class | ||
97 | - name: "", | ||
98 | - component: Portrait, | ||
99 | - children: [] | ||
100 | - } | ||
101 | - ] | ||
102 | - }, | ||
103 | - | ||
104 | - { | ||
105 | - path: "/setUpConglomerate", | ||
106 | - iconCls: "fa fa-building", // 图标样式class | ||
107 | - name: "学校管理", | ||
108 | - component: Layout, | ||
109 | - alone: true, | ||
110 | - children: [ | ||
111 | - { | ||
112 | - path: "/setUpConglomerate", | ||
113 | - iconCls: "fa fa-building", | ||
114 | - name: '集团管理', | ||
115 | - component: SetUpConglomerate, | ||
116 | - children: [] | ||
117 | - }, | ||
118 | - ] | ||
119 | - }, | ||
120 | - { | ||
121 | - path: "/setUpAccount", | ||
122 | - iconCls: "fa fa-id-card-o", // 图标样式class | ||
123 | - name: "账号管理", | ||
124 | - component: Layout, | ||
125 | - alone: true, | ||
126 | - children: [ | ||
127 | - { | ||
128 | - path: "/setUpAccount", | ||
129 | - iconCls: "fa fa-id-card-o", | ||
130 | - name: '', | ||
131 | - component: SetUpAccount, | ||
132 | - children: [] | ||
133 | - }, | ||
134 | - ] | ||
135 | - }, | ||
136 | - { | ||
137 | - path: "/", | ||
138 | - iconCls: "fa fa-cog", | ||
139 | - name: '学校设置', | ||
140 | - component: Layout, | ||
141 | - children: [ | ||
142 | - { | ||
143 | - path: "/setUpSchool", | ||
144 | - iconCls: "fa fa-calculator", | ||
145 | - name: '学校设置', | ||
146 | - component: SetUpSchool, | ||
147 | - children: [] | ||
148 | - }, | ||
149 | - { | ||
150 | - path: "/setUpTeacher", | ||
151 | - iconCls: "fa fa-male", | ||
152 | - name: '教师管理', | ||
153 | - component: SetUpTeacher, | ||
154 | - children: [] | ||
155 | - }, | ||
156 | - { | ||
157 | - path: "/setUpStudent", | ||
158 | - iconCls: "fa fa-mortar-board", | ||
159 | - name: '学生管理', | ||
160 | - component: SetUpStudent, | ||
161 | - children: [] | ||
162 | - }, | ||
163 | - ] | ||
164 | - }, | ||
165 | - { | ||
166 | - path: "/card", | ||
167 | - iconCls: "fa fa-id-card", // 图标样式class | ||
168 | - name: "发卡记录", | ||
169 | - component: Layout, | ||
170 | - alone: true, | ||
171 | - children: [ | ||
172 | - { | ||
173 | - path: "/card", | ||
174 | - iconCls: "fa fa-id-card", // 图标样式class | ||
175 | - name: "", | ||
176 | - component: Card, | ||
177 | - children: [] | ||
178 | - } | ||
179 | - ] | ||
180 | - }, | ||
181 | - { | ||
182 | - path: "/device", | ||
183 | - iconCls: "fa fa-dashboard", // 图标样式class | ||
184 | - name: "设备状态", | ||
185 | - component: Layout, | ||
186 | - alone: true, | ||
187 | - children: [ | ||
188 | - { | ||
189 | - path: "/device", | ||
190 | - iconCls: "fa fa-dashboard", // 图标样式class | ||
191 | - name: "", | ||
192 | - component: Device, | ||
193 | - children: [] | ||
194 | - } | ||
195 | - ] | ||
196 | - }, | ||
197 | - { | ||
198 | - path: "/analysis", | ||
199 | - iconCls: "fa fa-area-chart", // 图标样式class | ||
200 | - name: "使用分析", | ||
201 | - component: Layout, | ||
202 | - alone: true, | ||
203 | - children: [ | ||
204 | - { | ||
205 | - path: "/analysis", | ||
206 | - iconCls: "fa fa-area-chart", // 图标样式class | ||
207 | - name: "", | ||
208 | - component: Analysis, | ||
209 | - children: [] | ||
210 | - } | ||
211 | - ] | ||
212 | - }, | ||
213 | - { | ||
214 | - path: "/down", | ||
215 | - iconCls: "fa fa-download", // 图标样式class | ||
216 | - name: "软件下载", | ||
217 | - component: Layout, | ||
218 | - alone: true, | ||
219 | - children: [ | ||
220 | - { | ||
221 | - path: "/down", | ||
222 | - iconCls: "fa fa-download", // 图标样式class | ||
223 | - name: "发卡软件", | ||
224 | - component: Down, | ||
225 | - children: [] | ||
226 | - }, | ||
227 | - { | ||
228 | - path: "/downClient", | ||
229 | - iconCls: "", // 图标样式class | ||
230 | - name: "授课端软件", | ||
231 | - component: DownClient, | ||
232 | - children: [] | ||
233 | - } | ||
234 | - ] | ||
235 | - }, | ||
236 | - { | ||
237 | - path: "/dataSync", | ||
238 | - iconCls: "fa fa-random", // 图标样式class | ||
239 | - name: "数据同步", | ||
240 | - component: Layout, | ||
241 | - alone: true, | ||
242 | - children: [ | ||
243 | - { | ||
244 | - path: "/dataSync", | ||
245 | - iconCls: "fa fa-random", // 图标样式class | ||
246 | - name: "", | ||
247 | - component: DataSync, | ||
248 | - children: [] | ||
249 | - } | ||
250 | - ] | ||
251 | - }, | ||
252 | - { | ||
253 | - path: "*", | ||
254 | - redirect: "/404", | ||
255 | - hidden: true, | ||
256 | - children: [] | ||
257 | - } | 1 | +[ |
2 | + "examinationPaper", | ||
3 | + "examinationPaperAdd", | ||
4 | + "examinationPaperEdit", | ||
5 | + "examinationPaperRecycle", | ||
6 | + "ask", | ||
7 | + "askAnalysis", | ||
8 | + "test", | ||
9 | + "testAnalysis", | ||
10 | + "portrait", | ||
11 | + "setUpConglomerate", | ||
12 | + "setUpAccount", | ||
13 | + "setUpSchool", | ||
14 | + "setUpTeacher", | ||
15 | + "setUpStudent", | ||
16 | + "card", | ||
17 | + "device", | ||
18 | + "analysis", | ||
19 | + "down", | ||
20 | + "downClient", | ||
21 | + "dataSync" | ||
258 | ] | 22 | ] |
259 | \ No newline at end of file | 23 | \ No newline at end of file |
src/api/apis/answerSheet.js
1 | 1 | ||
2 | -import axios from "../axios" | 2 | +import service from "../axios" |
3 | import answerSheet from "../urls/answerSheet" | 3 | import answerSheet from "../urls/answerSheet" |
4 | 4 | ||
5 | export default { | 5 | export default { |
6 | // 答题卡列表 | 6 | // 答题卡列表 |
7 | fetchAnswerList(data) { | 7 | fetchAnswerList(data) { |
8 | - return axios({ | 8 | + return service({ |
9 | url: answerSheet.answerList, | 9 | url: answerSheet.answerList, |
10 | method: 'POST', | 10 | method: 'POST', |
11 | data | 11 | data |
@@ -13,7 +13,7 @@ export default { | @@ -13,7 +13,7 @@ export default { | ||
13 | }, | 13 | }, |
14 | // 测验类型 | 14 | // 测验类型 |
15 | fetchTypeNames(data) { | 15 | fetchTypeNames(data) { |
16 | - return axios({ | 16 | + return service({ |
17 | url: answerSheet.typeNames, | 17 | url: answerSheet.typeNames, |
18 | method: 'POST', | 18 | method: 'POST', |
19 | data | 19 | data |
@@ -21,7 +21,7 @@ export default { | @@ -21,7 +21,7 @@ export default { | ||
21 | }, | 21 | }, |
22 | // 班级列表 | 22 | // 班级列表 |
23 | fetchClassList(data) { | 23 | fetchClassList(data) { |
24 | - return axios({ | 24 | + return service({ |
25 | url: answerSheet.classList, | 25 | url: answerSheet.classList, |
26 | method: 'POST', | 26 | method: 'POST', |
27 | data | 27 | data |
@@ -29,7 +29,7 @@ export default { | @@ -29,7 +29,7 @@ export default { | ||
29 | }, | 29 | }, |
30 | // 科目列表 | 30 | // 科目列表 |
31 | fetchSubjectList(data) { | 31 | fetchSubjectList(data) { |
32 | - return axios({ | 32 | + return service({ |
33 | url: answerSheet.subjectList, | 33 | url: answerSheet.subjectList, |
34 | method: 'POST', | 34 | method: 'POST', |
35 | data | 35 | data |
@@ -37,7 +37,7 @@ export default { | @@ -37,7 +37,7 @@ export default { | ||
37 | }, | 37 | }, |
38 | // 年级列表 | 38 | // 年级列表 |
39 | fetchGradeList(data) { | 39 | fetchGradeList(data) { |
40 | - return axios({ | 40 | + return service({ |
41 | url: answerSheet.gradeList, | 41 | url: answerSheet.gradeList, |
42 | method: 'POST', | 42 | method: 'POST', |
43 | data | 43 | data |
@@ -45,7 +45,7 @@ export default { | @@ -45,7 +45,7 @@ export default { | ||
45 | }, | 45 | }, |
46 | // 添加测验类型 | 46 | // 添加测验类型 |
47 | addAnswerTypeName(data) { | 47 | addAnswerTypeName(data) { |
48 | - return axios({ | 48 | + return service({ |
49 | url: answerSheet.addAnswerTypeName, | 49 | url: answerSheet.addAnswerTypeName, |
50 | method: 'POST', | 50 | method: 'POST', |
51 | data | 51 | data |
@@ -53,7 +53,7 @@ export default { | @@ -53,7 +53,7 @@ export default { | ||
53 | }, | 53 | }, |
54 | // 保存答题卡 | 54 | // 保存答题卡 |
55 | saveAnswerSheet(data) { | 55 | saveAnswerSheet(data) { |
56 | - return axios({ | 56 | + return service({ |
57 | url: answerSheet.saveAnswerSheet, | 57 | url: answerSheet.saveAnswerSheet, |
58 | method: 'POST', | 58 | method: 'POST', |
59 | data | 59 | data |
@@ -61,7 +61,7 @@ export default { | @@ -61,7 +61,7 @@ export default { | ||
61 | }, | 61 | }, |
62 | // 删除答题卡 | 62 | // 删除答题卡 |
63 | removeAnswerSheet(data) { | 63 | removeAnswerSheet(data) { |
64 | - return axios({ | 64 | + return service({ |
65 | url: answerSheet.removeAnswerSheet, | 65 | url: answerSheet.removeAnswerSheet, |
66 | method: 'POST', | 66 | method: 'POST', |
67 | data | 67 | data |
@@ -69,7 +69,7 @@ export default { | @@ -69,7 +69,7 @@ export default { | ||
69 | }, | 69 | }, |
70 | // 恢复答题卡 | 70 | // 恢复答题卡 |
71 | useAnswerSheet(data) { | 71 | useAnswerSheet(data) { |
72 | - return axios({ | 72 | + return service({ |
73 | url: answerSheet.useAnswerSheet, | 73 | url: answerSheet.useAnswerSheet, |
74 | method: 'POST', | 74 | method: 'POST', |
75 | data | 75 | data |
@@ -77,7 +77,7 @@ export default { | @@ -77,7 +77,7 @@ export default { | ||
77 | }, | 77 | }, |
78 | // 恢复答题卡 | 78 | // 恢复答题卡 |
79 | updateAnswerSheet(data) { | 79 | updateAnswerSheet(data) { |
80 | - return axios({ | 80 | + return service({ |
81 | url: answerSheet.updateAnswerSheet, | 81 | url: answerSheet.updateAnswerSheet, |
82 | method: 'POST', | 82 | method: 'POST', |
83 | data | 83 | data |
src/api/apis/ask.js
0 → 100644
src/api/apis/login.js
1 | 1 | ||
2 | -import axios from "../axios" | 2 | +import service from "../axios" |
3 | import loginUrls from "../urls/login" | 3 | import loginUrls from "../urls/login" |
4 | 4 | ||
5 | export default { | 5 | export default { |
6 | // 账号密码登陆 | 6 | // 账号密码登陆 |
7 | fetchLogin(data) { | 7 | fetchLogin(data) { |
8 | - return axios({ | 8 | + return service({ |
9 | url: loginUrls.login, | 9 | url: loginUrls.login, |
10 | method: 'POST', | 10 | method: 'POST', |
11 | data | 11 | data |
src/api/apis/role.js
1 | 1 | ||
2 | -import axios from "../axios" | 2 | +import service from "../axios" |
3 | import roleUrls from "../urls/role" | 3 | import roleUrls from "../urls/role" |
4 | 4 | ||
5 | export default { | 5 | export default { |
6 | // 获取权限列表 | 6 | // 获取权限列表 |
7 | fetchGetRoleList () { | 7 | fetchGetRoleList () { |
8 | - return axios.post(roleUrls.getRoleList) | 8 | + return service.post(roleUrls.getRoleList) |
9 | }, | 9 | }, |
10 | } | 10 | } |
11 | 11 |
src/api/axios.js
@@ -6,11 +6,13 @@ import router from "@/router/index" | @@ -6,11 +6,13 @@ import router from "@/router/index" | ||
6 | import store from "@/store" | 6 | import store from "@/store" |
7 | import conf from "../config/index"; // 路径配置 | 7 | import conf from "../config/index"; // 路径配置 |
8 | // axios默认配置 | 8 | // axios默认配置 |
9 | -axios.defaults.timeout = 1000000000 // 超时时间 | ||
10 | -axios.defaults.baseURL = conf.baseURL | ||
11 | - | 9 | +const service = axios.create({ |
10 | + baseURL: conf.baseURL, // api的base_url | ||
11 | + timeout: 600000000000000, // 请求超时时间 | ||
12 | + withCredentials: true, | ||
13 | +}); | ||
12 | // http request 拦截器 | 14 | // http request 拦截器 |
13 | -axios.interceptors.request.use(config => { | 15 | +service.interceptors.request.use(config => { |
14 | NProgress.start() | 16 | NProgress.start() |
15 | config.headers["Content-Type"] = "application/json;charset=UTF-8" | 17 | config.headers["Content-Type"] = "application/json;charset=UTF-8" |
16 | 18 | ||
@@ -27,16 +29,16 @@ axios.interceptors.request.use(config => { | @@ -27,16 +29,16 @@ axios.interceptors.request.use(config => { | ||
27 | }) | 29 | }) |
28 | 30 | ||
29 | // http response 拦截器 | 31 | // http response 拦截器 |
30 | -axios.interceptors.response.use( | 32 | +service.interceptors.response.use( |
31 | response => { | 33 | response => { |
32 | - const res = respones.data; | 34 | + const res = response.data; |
33 | NProgress.done() | 35 | NProgress.done() |
34 | - if (respones.config.cancelToken) { | ||
35 | - store.commit('delTokenSources', respones.config.cancelToken) | 36 | + if (response.config.cancelToken) { |
37 | + store.commit('delTokenSources', response.config.cancelToken) | ||
36 | } | 38 | } |
37 | - if (respones.status == 200) { | 39 | + if (response.status == 200) { |
38 | Cookies.set("access_token", response.data.message, { expires: 1 / 12 }) | 40 | Cookies.set("access_token", response.data.message, { expires: 1 / 12 }) |
39 | - // console.log(respones.status) | 41 | + // console.log(response.status) |
40 | if (res.code == 999) { | 42 | if (res.code == 999) { |
41 | if (!location.href.includes('localhost')) { | 43 | if (!location.href.includes('localhost')) { |
42 | if (res.data) { | 44 | if (res.data) { |
@@ -88,4 +90,4 @@ axios.interceptors.response.use( | @@ -88,4 +90,4 @@ axios.interceptors.response.use( | ||
88 | } | 90 | } |
89 | return Promise.reject(error.response) // 返回接口返回的错误信息 | 91 | return Promise.reject(error.response) // 返回接口返回的错误信息 |
90 | }) | 92 | }) |
91 | -export default axios | 93 | +export default service |
src/api/urls/ask.js
0 → 100644
src/api/urls/login.js
src/assets/css/index.scss
@@ -3,65 +3,113 @@ | @@ -3,65 +3,113 @@ | ||
3 | display: flex; | 3 | display: flex; |
4 | justify-content: space-between; | 4 | justify-content: space-between; |
5 | align-items: center; | 5 | align-items: center; |
6 | + | ||
6 | .btn-box { | 7 | .btn-box { |
7 | display: flex; | 8 | display: flex; |
8 | } | 9 | } |
10 | + | ||
9 | .sel-box { | 11 | .sel-box { |
10 | - display: flex; | ||
11 | - align-items: center; | ||
12 | - flex-wrap: nowrap; | ||
13 | - .sel { | ||
14 | - width: 8%; | ||
15 | - min-width: 90px; | ||
16 | - margin-right: 20px; | ||
17 | - } | ||
18 | - .el-input__inner{ | ||
19 | - border-radius: 20px; | ||
20 | - border: 1px solid #e2e2e2; | ||
21 | - height: 36px; | ||
22 | - line-height: 34px; | ||
23 | - } | ||
24 | - .el-input__icon { | ||
25 | - line-height: 34px; | ||
26 | - } | ||
27 | - .el-date-editor.el-input, | ||
28 | - .el-date-editor.el-input__inner { | ||
29 | - width: 200px; | ||
30 | - } | ||
31 | - .input-with-select { | ||
32 | - width: 200px; | ||
33 | - height: 36px; | ||
34 | - margin-right: 50px; | ||
35 | - border-radius: 20px; | ||
36 | - border: 1px solid #e2e2e2; | ||
37 | - box-sizing: border-box; | 12 | + display: flex; |
13 | + align-items: center; | ||
14 | + flex-wrap: nowrap; | ||
15 | + | ||
16 | + .sel { | ||
17 | + width: 8%; | ||
18 | + min-width: 160px; | ||
19 | + margin-right: 20px; | ||
20 | + } | ||
21 | + | ||
38 | .el-input__inner { | 22 | .el-input__inner { |
39 | border-radius: 20px; | 23 | border-radius: 20px; |
40 | - border: none; | ||
41 | - height: 34px; | 24 | + border: 1px solid #e2e2e2; |
25 | + height: 36px; | ||
42 | line-height: 34px; | 26 | line-height: 34px; |
43 | } | 27 | } |
44 | - .el-input-group__append, .el-input-group__prepend { | ||
45 | - border: none; | ||
46 | - background: transparent; | 28 | + |
29 | + .el-input__icon { | ||
30 | + line-height: 34px; | ||
47 | } | 31 | } |
48 | - } | ||
49 | - .d1 { | ||
50 | - margin-left: 30px; | ||
51 | - } | ||
52 | - .p1 { | ||
53 | - flex: 1; | ||
54 | - .s1 { | ||
55 | - margin-left: 36px; | ||
56 | - cursor: pointer; | ||
57 | - color: #7f7f7f; | ||
58 | - &:hover { | ||
59 | - color: #409eff; | 32 | + |
33 | + .el-date-editor.el-input, | ||
34 | + .el-date-editor.el-input__inner { | ||
35 | + width: 160px; | ||
36 | + } | ||
37 | + | ||
38 | + .input-with-select { | ||
39 | + width: 200px; | ||
40 | + height: 36px; | ||
41 | + margin-right: 50px; | ||
42 | + border-radius: 20px; | ||
43 | + border: 1px solid #e2e2e2; | ||
44 | + box-sizing: border-box; | ||
45 | + | ||
46 | + .el-input__inner { | ||
47 | + border-radius: 20px; | ||
48 | + border: none; | ||
49 | + height: 34px; | ||
50 | + line-height: 34px; | ||
60 | } | 51 | } |
61 | - &.active { | ||
62 | - color: #667ffd; | 52 | + |
53 | + .el-input-group__append, | ||
54 | + .el-input-group__prepend { | ||
55 | + border: none; | ||
56 | + background: transparent; | ||
63 | } | 57 | } |
64 | } | 58 | } |
59 | + | ||
60 | + .p1 { | ||
61 | + flex: 1; | ||
62 | + | ||
63 | + .s1 { | ||
64 | + margin-left: 36px; | ||
65 | + cursor: pointer; | ||
66 | + color: #7f7f7f; | ||
67 | + | ||
68 | + &:hover { | ||
69 | + color: #409eff; | ||
70 | + } | ||
71 | + | ||
72 | + &.active { | ||
73 | + color: #667ffd; | ||
74 | + } | ||
75 | + } | ||
76 | + } | ||
77 | + } | ||
78 | +} | ||
79 | +.answer-box { | ||
80 | + .answer-s { | ||
81 | + display: inline-block; | ||
82 | + width: 30px; | ||
83 | + height: 30px; | ||
84 | + border: 1px solid #e2e2e2; | ||
85 | + border-radius: 3px; | ||
86 | + margin: 0 6px; | ||
87 | + font-size: 16px; | ||
88 | + color: #333; | ||
89 | + text-align: center; | ||
90 | + line-height: 30px; | ||
91 | + &.active { | ||
92 | + background: #5e78fa; | ||
93 | + border-color: #5e78fa; | ||
94 | + color: #fff; | ||
95 | + } | ||
65 | } | 96 | } |
66 | } | 97 | } |
98 | +.el-menu-item i { | ||
99 | + width: 12px; | ||
100 | + text-align: center; | ||
101 | + margin-right: 8px; | ||
102 | +} | ||
103 | + | ||
104 | +.el-table thead th.el-table__cell { | ||
105 | + background: #f5f7fa; | ||
106 | +} | ||
107 | + | ||
108 | +.el-menu--popup { | ||
109 | + min-width: 160px; | ||
110 | +} | ||
111 | +.ellipsis { | ||
112 | + overflow: hidden; | ||
113 | + text-overflow: ellipsis; | ||
114 | + white-space: nowrap; | ||
67 | } | 115 | } |
68 | \ No newline at end of file | 116 | \ No newline at end of file |
src/assets/images/arrow.png
0 → 100644
470 Bytes
src/assets/nav/dataSync.png
0 → 100644
7.45 KB
src/main.js
@@ -14,8 +14,8 @@ import '@/components/globalComponents.js' | @@ -14,8 +14,8 @@ import '@/components/globalComponents.js' | ||
14 | 14 | ||
15 | 15 | ||
16 | import "nprogress/nprogress.css" | 16 | import "nprogress/nprogress.css" |
17 | -import "element-ui/lib/theme-chalk/index.css" | ||
18 | import "font-awesome/css/font-awesome.css" | 17 | import "font-awesome/css/font-awesome.css" |
18 | +import "element-ui/lib/theme-chalk/index.css" | ||
19 | import "@/router/permission" | 19 | import "@/router/permission" |
20 | import "@/assets/css/base.css" | 20 | import "@/assets/css/base.css" |
21 | import "@/assets/css/index.scss" | 21 | import "@/assets/css/index.scss" |
src/router/index.js
@@ -327,12 +327,6 @@ let addrouters = [ //测试用,后续后端获取 | @@ -327,12 +327,6 @@ let addrouters = [ //测试用,后续后端获取 | ||
327 | } | 327 | } |
328 | ] | 328 | ] |
329 | }, | 329 | }, |
330 | - { | ||
331 | - path: "*", | ||
332 | - redirect: "/404", | ||
333 | - hidden: true, | ||
334 | - children: [] | ||
335 | - } | ||
336 | ] | 330 | ] |
337 | 331 | ||
338 | export default new Router({ | 332 | export default new Router({ |
src/router/permission.js
1 | import NProgress from "nprogress" | 1 | import NProgress from "nprogress" |
2 | import router from "./index" | 2 | import router from "./index" |
3 | import store from "../store" | 3 | import store from "../store" |
4 | -import {addrouters} from "./index" | ||
5 | 4 | ||
6 | // 获取角色信息,根据用户权限动态加载路由 | 5 | // 获取角色信息,根据用户权限动态加载路由 |
7 | router.beforeEach((to, from, next) => { | 6 | router.beforeEach((to, from, next) => { |
8 | NProgress.start() | 7 | NProgress.start() |
9 | if (store.getters.token) { | 8 | if (store.getters.token) { |
10 | - if (to.path === "/login") { | ||
11 | - next() | ||
12 | - } else { | ||
13 | - if (!store.getters.info.permissions) { | ||
14 | - !(async function getAddRouters() { | ||
15 | - // 省略 axios 请求代码 通过 token 向后台请求用户权限等信息,这里用假数据赋值 | ||
16 | - await store.commit("setInfo", { | ||
17 | - permissions: [ | ||
18 | - { | ||
19 | - role: "superAdmin", | ||
20 | - roleName: "超级管理员" | ||
21 | - } | ||
22 | - ], | ||
23 | - name: "李老师", | ||
24 | - // avatar: data.avatar ? data.avatar : "", | ||
25 | - // uid: data.id, | ||
26 | - // authorityRouter:[], | 9 | + // if (to.path === "/login") { |
10 | + next() | ||
11 | + // } else { | ||
12 | + // if (!store.getters.info.permissions) { | ||
13 | + // (async function getAddRouters() { | ||
14 | + // // 省略 axios 请求代码 通过 token 向后台请求用户权限等信息,这里用假数据赋值 | ||
15 | + // const userInfo = { | ||
16 | + // permissions: [ | ||
17 | + // { | ||
18 | + // role: "superAdmin", | ||
19 | + // roleName: "超级管理员" | ||
20 | + // } | ||
21 | + // ], | ||
22 | + // name: "李老师", | ||
23 | + // // avatar: data.avatar ? data.avatar : "", | ||
24 | + // // uid: data.id, | ||
25 | + // authorityRouter: ["examinationPaper", | ||
26 | + // "examinationPaperAdd", | ||
27 | + // "examinationPaperEdit", | ||
28 | + // "examinationPaperRecycle", "ask", | ||
29 | + // "askAnalysis", | ||
30 | + // "test", | ||
31 | + // "testAnalysis", "portrait"], | ||
27 | 32 | ||
28 | - }) | ||
29 | - await store.commit("setRouters", addrouters) | ||
30 | - let newAddRouters = store.getters.addRouters | ||
31 | - newAddRouters.forEach(res => { | ||
32 | - router.addRoute(res) | ||
33 | - }) | ||
34 | - next({path: to.fullPath}) | ||
35 | - }()) | ||
36 | - } else { | 33 | + // } |
34 | + // await store.commit("setInfo", { ...userInfo }) | ||
35 | + // await store.commit("setRouters", userInfo.authorityRouter) | ||
36 | + // let newAddRouters = store.getters.addRouters | ||
37 | + // newAddRouters.forEach(res => { | ||
38 | + // router.addRoute(res) | ||
39 | + // }) | ||
40 | + // router.addRoute({ | ||
41 | + // path: "*", | ||
42 | + // redirect: "/404", | ||
43 | + // hidden: true, | ||
44 | + // children: [] | ||
45 | + // }) | ||
46 | + // next({ path: to.fullPath }) | ||
47 | + // }()) | ||
48 | + // } else { | ||
49 | + // next() | ||
50 | + // } | ||
51 | + // } | ||
52 | + } else { | ||
53 | + if (store.getters.info && store.getters.addRouters) { | ||
54 | + console.log(store.getters.addRouters) | ||
55 | + store.commit("setToken", "isLogin"); | ||
56 | + store.commit( | ||
57 | + "setRouters", | ||
58 | + store.getters.info.authorityRouter | ||
59 | + ); | ||
60 | + | ||
61 | + let newAddRouters = store.getters.addRouters; | ||
62 | + newAddRouters.forEach((res) => { | ||
63 | + router.addRoute(res); | ||
64 | + }); | ||
65 | + router.addRoute({ | ||
66 | + path: "*", | ||
67 | + redirect: "/404", | ||
68 | + hidden: true, | ||
69 | + children: [], | ||
70 | + }); | ||
71 | + next({ path: to.fullPath }) | ||
72 | + } else { | ||
73 | + if (store.getters.code) { | ||
37 | next() | 74 | next() |
75 | + } else { | ||
76 | + if (to.path === "/login") { | ||
77 | + next() | ||
78 | + } else { | ||
79 | + next({ path: "/login" }) | ||
80 | + } | ||
38 | } | 81 | } |
39 | } | 82 | } |
40 | - } else { | ||
41 | - if (to.path === "/login") { | ||
42 | - next() | ||
43 | - } | ||
44 | - next({ path: "/login" }) | ||
45 | - | ||
46 | } | 83 | } |
47 | }) | 84 | }) |
48 | 85 | ||
49 | router.afterEach(() => { | 86 | router.afterEach(() => { |
50 | NProgress.done() | 87 | NProgress.done() |
51 | }) | 88 | }) |
89 | +router.onError((error) => { | ||
90 | + const pattern = /Loading chunk (\d)+ failed/g; | ||
91 | + const isChunkLoadFailed = error.message.match(pattern); | ||
92 | + const targetPath = router.history.pending.fullPath; | ||
93 | + if (isChunkLoadFailed) { router.replace(targetPath); } | ||
94 | +}); | ||
95 | + | ||
52 | 96 | ||
53 | 97 | ||
54 | // // 真实使用 | 98 | // // 真实使用 |
src/store/index.js
@@ -4,25 +4,28 @@ import Cookies from "js-cookie" | @@ -4,25 +4,28 @@ import Cookies from "js-cookie" | ||
4 | import layoutStore from "./modules/layout/index" | 4 | import layoutStore from "./modules/layout/index" |
5 | import { defaultRouter } from "@/router/index" | 5 | import { defaultRouter } from "@/router/index" |
6 | import { encryptLoginPassword } from "@/utils"; | 6 | import { encryptLoginPassword } from "@/utils"; |
7 | -import { b64DecodeUnicode } from "@/utils"; | ||
8 | 7 | ||
9 | import request from "@/api/index" | 8 | import request from "@/api/index" |
10 | import router from "@/router/index" | 9 | import router from "@/router/index" |
11 | -import {addrouters} from "@/router/index" | 10 | +import { addrouters } from "@/router/index" |
12 | Vue.use(Vuex) | 11 | Vue.use(Vuex) |
13 | 12 | ||
14 | const store = new Vuex.Store({ | 13 | const store = new Vuex.Store({ |
15 | state: { | 14 | state: { |
16 | - token: Cookies.get("token"), | ||
17 | - info: "", // 每次刷新都要通过token请求个人信息来筛选动态路由 | ||
18 | - routers: [], | ||
19 | - addRouters: [], | ||
20 | - tokenSources:new Map(), | 15 | + token: "", |
16 | + csCode: localStorage.getItem("csCode") || "", | ||
17 | + info: sessionStorage.getItem("info") ? JSON.parse(sessionStorage.getItem("info")) : "", // 每次刷新都要通过token请求个人信息来筛选动态路由 | ||
18 | + routers: [],//左侧菜单 | ||
19 | + addRouters: sessionStorage.getItem("addRouters") ? JSON.parse(sessionStorage.getItem("addRouters")) : [],//动态路由 | ||
20 | + tokenSources: new Map(),//正在请求接口(切换取消请求) | ||
21 | }, | 21 | }, |
22 | mutations: { | 22 | mutations: { |
23 | setToken(state, token) { | 23 | setToken(state, token) { |
24 | state.token = token | 24 | state.token = token |
25 | - Cookies.set("token", token, { expires: 1 / 24 }) | 25 | + }, |
26 | + setCode(state, code) { | ||
27 | + state.csCode = code; | ||
28 | + localStorage.setItem("csCode", code) | ||
26 | }, | 29 | }, |
27 | setInfo(state, data) { | 30 | setInfo(state, data) { |
28 | state.info = { | 31 | state.info = { |
@@ -33,58 +36,62 @@ const store = new Vuex.Store({ | @@ -33,58 +36,62 @@ const store = new Vuex.Store({ | ||
33 | avatar: data.avatar ? data.avatar : "", | 36 | avatar: data.avatar ? data.avatar : "", |
34 | uid: data.uid | 37 | uid: data.uid |
35 | } | 38 | } |
36 | - localStorage.setItem("info", JSON.stringify(store.getters.info)) | 39 | + sessionStorage.setItem("info", JSON.stringify(state.info)) |
37 | }, | 40 | }, |
38 | setRouters: (state, routers) => { | 41 | setRouters: (state, routers) => { |
39 | - state.addRouters = routers // 保存动态路由用来addRouter | ||
40 | - state.routers = defaultRouter.concat(routers) // 所有有权限的路由表,用来生成菜单列表 | 42 | + let aRouters = addrouters.filter(item => { |
43 | + let path = item.children[0]?.path.replace("/", "") | ||
44 | + return routers?.includes(path) | ||
45 | + }) | ||
46 | + | ||
47 | + state.addRouters = aRouters // 保存动态路由用来addRouter | ||
48 | + state.routers = defaultRouter.concat(aRouters) // 所有有权限的路由表,用来生成菜单列表 | ||
49 | + sessionStorage.setItem("addRouters", JSON.stringify(routers)) | ||
41 | }, | 50 | }, |
42 | - setTokenSources(state,data){ | ||
43 | - if(data instanceof Array){ | 51 | + setTokenSources(state, data) { |
52 | + if (data instanceof Array) { | ||
44 | state.tokenSources.set(data[0], data[1]) | 53 | state.tokenSources.set(data[0], data[1]) |
45 | - }else{ | 54 | + } else { |
46 | state.tokenSources = new Map() | 55 | state.tokenSources = new Map() |
47 | } | 56 | } |
48 | }, | 57 | }, |
49 | - delTokenSources(state,data){ | 58 | + delTokenSources(state, data) { |
50 | state.tokenSources.delete(data) | 59 | state.tokenSources.delete(data) |
51 | }, | 60 | }, |
52 | }, | 61 | }, |
53 | actions: { | 62 | actions: { |
54 | - Login({ state,commit }, params) { | ||
55 | - let loginForm={} | 63 | + Login({ state, commit }, params) { |
64 | + let loginForm = {} | ||
56 | loginForm.username = params.username; | 65 | loginForm.username = params.username; |
57 | loginForm.password = encryptLoginPassword(params.password); | 66 | loginForm.password = encryptLoginPassword(params.password); |
58 | - // request.fetchLogin(loginForm).then(res => { | ||
59 | - // if (res.status == 200) { | ||
60 | - // const dataJSON = JSON.parse(b64DecodeUnicode(res.data)); | ||
61 | - commit("setToken", "xxxx") | ||
62 | - commit("setInfo", { | ||
63 | - permissions: [ | ||
64 | - { | ||
65 | - role: "superAdmin", | ||
66 | - roleName: "超级管理员", | ||
67 | - }, | ||
68 | - ], | ||
69 | - name: "张老师", | ||
70 | - // avatar: data.avatar ? data.avatar : "", | ||
71 | - // uid: data.id, | ||
72 | - // authorityRouter:[], | ||
73 | - }); | ||
74 | - commit("setRouters", addrouters) | ||
75 | - state.addRouters.forEach((res) => { | ||
76 | - router.addRoute(res); | ||
77 | - }); | ||
78 | - console.log() | ||
79 | - if (params.url) { | ||
80 | - window.location.href = params.url; | ||
81 | - } else { | ||
82 | - router.push({ path: "/" }) | ||
83 | - } | ||
84 | - // } | ||
85 | - // }) | 67 | + request.fetchLogin({ ...loginForm }).then(res => { |
68 | + let response = res.data | ||
69 | + if (response.status == 0) { | ||
70 | + const userInfo = { ...response.data } | ||
71 | + commit("setToken", "isLogin"); | ||
72 | + commit("setInfo", { ...userInfo }); | ||
73 | + commit("setRouters", [...userInfo.authorityRouter]) | ||
74 | + state.addRouters.forEach((res) => { | ||
75 | + router.addRoute(res); | ||
76 | + }); | ||
77 | + router.addRoute({ | ||
78 | + path: "*", | ||
79 | + redirect: "/404", | ||
80 | + hidden: true, | ||
81 | + children: [] | ||
82 | + }) | ||
83 | + console.log() | ||
84 | + if (params.url) { | ||
85 | + window.location.href = params.url; | ||
86 | + } else { | ||
87 | + router.push({ path: "/" }) | ||
88 | + } | ||
89 | + } | ||
90 | + }).catch(() => { | ||
91 | + // commit("setToken", Cookies.get("JSESSIONID")); | ||
92 | + }) | ||
86 | }, | 93 | }, |
87 | - permissions({ state,commit }, that) { | 94 | + permissions({ state, commit }, that) { |
88 | // request.fetchLogin(that.loginForm).then(res => { | 95 | // request.fetchLogin(that.loginForm).then(res => { |
89 | // if (res.status == 200) { | 96 | // if (res.status == 200) { |
90 | commit("setToken", "xxxx") | 97 | commit("setToken", "xxxx") |
@@ -98,13 +105,39 @@ const store = new Vuex.Store({ | @@ -98,13 +105,39 @@ const store = new Vuex.Store({ | ||
98 | name: "李老师", | 105 | name: "李老师", |
99 | // avatar: data.avatar ? data.avatar : "", | 106 | // avatar: data.avatar ? data.avatar : "", |
100 | // uid: data.id, | 107 | // uid: data.id, |
101 | - // authorityRouter:[], | 108 | + authorityRouter:[ |
109 | + "examinationPaper", | ||
110 | + "examinationPaperAdd", | ||
111 | + "examinationPaperEdit", | ||
112 | + "examinationPaperRecycle", | ||
113 | + "ask", | ||
114 | + "askAnalysis", | ||
115 | + "test", | ||
116 | + "testAnalysis", | ||
117 | + "portrait", | ||
118 | + "setUpConglomerate", | ||
119 | + "setUpAccount", | ||
120 | + "setUpSchool", | ||
121 | + "setUpTeacher", | ||
122 | + "setUpStudent", | ||
123 | + "card", | ||
124 | + "device", | ||
125 | + "analysis", | ||
126 | + "down", | ||
127 | + "downClient", | ||
128 | + "dataSync" | ||
129 | + ], | ||
102 | }); | 130 | }); |
103 | - commit("setRouters", addrouters) | 131 | + commit("setRouters", authorityRouter) |
104 | state.addRouters.forEach((res) => { | 132 | state.addRouters.forEach((res) => { |
105 | - that.$router.addRoute(res); | 133 | + router.addRoute(res); |
106 | }); | 134 | }); |
107 | - that.$router.push({ path: "/" }) | 135 | + router.addRoute({ |
136 | + path: "*", | ||
137 | + redirect: "/404", | ||
138 | + hidden: true, | ||
139 | + children: [] | ||
140 | + }) | ||
108 | // } | 141 | // } |
109 | // }) | 142 | // }) |
110 | } | 143 | } |
@@ -112,6 +145,7 @@ const store = new Vuex.Store({ | @@ -112,6 +145,7 @@ const store = new Vuex.Store({ | ||
112 | getters: { | 145 | getters: { |
113 | addRouters: state => state.addRouters, | 146 | addRouters: state => state.addRouters, |
114 | token: state => state.token, | 147 | token: state => state.token, |
148 | + code: state => state.csCode, | ||
115 | info: state => state.info, | 149 | info: state => state.info, |
116 | routers: state => state.routers, | 150 | routers: state => state.routers, |
117 | logoShow: state => state.layoutStore.logoShow, | 151 | logoShow: state => state.layoutStore.logoShow, |
src/utils/index.js
@@ -9,7 +9,7 @@ const encryptIV = "D076D35C" | @@ -9,7 +9,7 @@ const encryptIV = "D076D35C" | ||
9 | * @param data: 待加密数据 | 9 | * @param data: 待加密数据 |
10 | * @returns 加密结果 | 10 | * @returns 加密结果 |
11 | */ | 11 | */ |
12 | -export function encryptLoginPassword(data){ | 12 | +export function encryptLoginPassword(data) { |
13 | const secret = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjh2ei17z5k2r4VzbqoSCE6RmYzWySJTgVQYulgfVM+vqcDoUE4cFB4XCFA2lHWjjpsuJP1EtwKlvUgxo5okr3x/a88o8eERxBynnVQZbEYpKteW5aqSEb/g1yPLWnKV88b/ED445ITYbZZuInRo5lkCvd6QEjL6d2Fch6mEo5awYXC4/S4BJf9YlYRhGzR7wpiXCLvyBHQ4iSIIDNpmrPBPQzGP0rx09aDu54kz/42CR6SX2OqXSi4ZoieqkPFl/iuX4RoD/NKKR+haDn1UzoD3k1WzHSTBFFs27rxRpxfBUZzfXQeskgKyw/Slcl3jUFizczsY4CLgTRrfey48Q6QIDAQAB'; | 13 | const secret = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjh2ei17z5k2r4VzbqoSCE6RmYzWySJTgVQYulgfVM+vqcDoUE4cFB4XCFA2lHWjjpsuJP1EtwKlvUgxo5okr3x/a88o8eERxBynnVQZbEYpKteW5aqSEb/g1yPLWnKV88b/ED445ITYbZZuInRo5lkCvd6QEjL6d2Fch6mEo5awYXC4/S4BJf9YlYRhGzR7wpiXCLvyBHQ4iSIIDNpmrPBPQzGP0rx09aDu54kz/42CR6SX2OqXSi4ZoieqkPFl/iuX4RoD/NKKR+haDn1UzoD3k1WzHSTBFFs27rxRpxfBUZzfXQeskgKyw/Slcl3jUFizczsY4CLgTRrfey48Q6QIDAQAB'; |
14 | // 新建JSEncrypt对象 | 14 | // 新建JSEncrypt对象 |
15 | let encryptor = new JSEncrypt(); | 15 | let encryptor = new JSEncrypt(); |
@@ -25,7 +25,7 @@ export function encryptLoginPassword(data){ | @@ -25,7 +25,7 @@ export function encryptLoginPassword(data){ | ||
25 | * @param data: 待加密数据 | 25 | * @param data: 待加密数据 |
26 | * @returns 加密结果 | 26 | * @returns 加密结果 |
27 | */ | 27 | */ |
28 | -export function encryptData(secret, data){ | 28 | +export function encryptData(secret, data) { |
29 | // 新建JSEncrypt对象 | 29 | // 新建JSEncrypt对象 |
30 | let encryptor = new JSEncrypt(); | 30 | let encryptor = new JSEncrypt(); |
31 | // 设置公钥 | 31 | // 设置公钥 |
@@ -35,7 +35,7 @@ export function encryptData(secret, data){ | @@ -35,7 +35,7 @@ export function encryptData(secret, data){ | ||
35 | } | 35 | } |
36 | 36 | ||
37 | // 深度复制 | 37 | // 深度复制 |
38 | -export function deepClone (obj) { | 38 | +export function deepClone(obj) { |
39 | let result = Array.isArray(obj) ? [] : {} | 39 | let result = Array.isArray(obj) ? [] : {} |
40 | for (let key in obj) { | 40 | for (let key in obj) { |
41 | if (obj.hasOwnProperty(key)) { | 41 | if (obj.hasOwnProperty(key)) { |
@@ -74,7 +74,7 @@ export function deepClone (obj) { | @@ -74,7 +74,7 @@ export function deepClone (obj) { | ||
74 | // } | 74 | // } |
75 | 75 | ||
76 | // 随机生成由字母+数字的字符串 | 76 | // 随机生成由字母+数字的字符串 |
77 | -export function randomWord (randomFlag, min, max) { | 77 | +export function randomWord(randomFlag, min, max) { |
78 | // randomFlag: Boolean 是否随机个数 | 78 | // randomFlag: Boolean 是否随机个数 |
79 | // min 最少个数 | 79 | // min 最少个数 |
80 | // max 最大个数 | 80 | // max 最大个数 |
@@ -94,7 +94,7 @@ export function randomWord (randomFlag, min, max) { | @@ -94,7 +94,7 @@ export function randomWord (randomFlag, min, max) { | ||
94 | } | 94 | } |
95 | 95 | ||
96 | // 判断数组中是否存在相同值 | 96 | // 判断数组中是否存在相同值 |
97 | -export function hasRepeatValue (arr, key = null) { | 97 | +export function hasRepeatValue(arr, key = null) { |
98 | if (key) arr = arr.map(d => d[key]) | 98 | if (key) arr = arr.map(d => d[key]) |
99 | if (arr.length) { | 99 | if (arr.length) { |
100 | let nameNum = arr.reduce((pre, cur) => { | 100 | let nameNum = arr.reduce((pre, cur) => { |
@@ -111,7 +111,7 @@ export function hasRepeatValue (arr, key = null) { | @@ -111,7 +111,7 @@ export function hasRepeatValue (arr, key = null) { | ||
111 | } | 111 | } |
112 | 112 | ||
113 | // 获取cookie值 | 113 | // 获取cookie值 |
114 | -export function getCookie (name, defaultValue) { | 114 | +export function getCookie(name, defaultValue) { |
115 | const result = new RegExp("(^| )" + name + "=([^;]*)(;|$)") | 115 | const result = new RegExp("(^| )" + name + "=([^;]*)(;|$)") |
116 | return result[0] === document.cookie.match(result[1]) ? unescape(result[0][2]) : defaultValue | 116 | return result[0] === document.cookie.match(result[1]) ? unescape(result[0][2]) : defaultValue |
117 | } | 117 | } |
@@ -120,19 +120,19 @@ export function getCookie (name, defaultValue) { | @@ -120,19 +120,19 @@ export function getCookie (name, defaultValue) { | ||
120 | /** | 120 | /** |
121 | * base64转化unicode | 121 | * base64转化unicode |
122 | */ | 122 | */ |
123 | - export function b64DecodeUnicode(str) { | 123 | +export function b64DecodeUnicode(str) { |
124 | let uni; | 124 | let uni; |
125 | try { | 125 | try { |
126 | // atob 经过 base-64 编码的字符串进行解码 | 126 | // atob 经过 base-64 编码的字符串进行解码 |
127 | uni = decodeURIComponent(atob(str).split('').map(function (c) { | 127 | uni = decodeURIComponent(atob(str).split('').map(function (c) { |
128 | return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); | 128 | return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); |
129 | }).join('')); | 129 | }).join('')); |
130 | - } catch (e) {} | 130 | + } catch (e) { } |
131 | return uni; | 131 | return uni; |
132 | } | 132 | } |
133 | 133 | ||
134 | // base64ToFile | 134 | // base64ToFile |
135 | -export function base64ToFile (base64Data, tempfilename, contentType) { | 135 | +export function base64ToFile(base64Data, tempfilename, contentType) { |
136 | contentType = contentType || "" | 136 | contentType = contentType || "" |
137 | var sliceSize = 1024 | 137 | var sliceSize = 1024 |
138 | var byteCharacters = atob(base64Data) | 138 | var byteCharacters = atob(base64Data) |
@@ -155,7 +155,7 @@ export function base64ToFile (base64Data, tempfilename, contentType) { | @@ -155,7 +155,7 @@ export function base64ToFile (base64Data, tempfilename, contentType) { | ||
155 | } | 155 | } |
156 | 156 | ||
157 | // 将base64转换为文件 | 157 | // 将base64转换为文件 |
158 | -export function dataURLtoFile (dataurl, filename) { | 158 | +export function dataURLtoFile(dataurl, filename) { |
159 | var arr = dataurl.split(",") | 159 | var arr = dataurl.split(",") |
160 | var mime = arr[0].match(/:(.*?);/)[1] | 160 | var mime = arr[0].match(/:(.*?);/)[1] |
161 | var bstr = atob(arr[1]) | 161 | var bstr = atob(arr[1]) |
@@ -168,7 +168,7 @@ export function dataURLtoFile (dataurl, filename) { | @@ -168,7 +168,7 @@ export function dataURLtoFile (dataurl, filename) { | ||
168 | } | 168 | } |
169 | 169 | ||
170 | // 将图片转换为Base64 | 170 | // 将图片转换为Base64 |
171 | -export function getImgToBase64 (url, callback, outputFormat) { | 171 | +export function getImgToBase64(url, callback, outputFormat) { |
172 | var canvas = document.createElement("canvas") | 172 | var canvas = document.createElement("canvas") |
173 | var ctx = canvas.getContext("2d") | 173 | var ctx = canvas.getContext("2d") |
174 | var img = new Image() | 174 | var img = new Image() |
@@ -185,7 +185,7 @@ export function getImgToBase64 (url, callback, outputFormat) { | @@ -185,7 +185,7 @@ export function getImgToBase64 (url, callback, outputFormat) { | ||
185 | } | 185 | } |
186 | 186 | ||
187 | // 转换级联下拉数据 | 187 | // 转换级联下拉数据 |
188 | -export function loopOptions (list, option = {}) { | 188 | +export function loopOptions(list, option = {}) { |
189 | option = { | 189 | option = { |
190 | value: "id", | 190 | value: "id", |
191 | label: "name", | 191 | label: "name", |
@@ -206,7 +206,7 @@ export function loopOptions (list, option = {}) { | @@ -206,7 +206,7 @@ export function loopOptions (list, option = {}) { | ||
206 | } | 206 | } |
207 | 207 | ||
208 | // 通过Id获取级联数据id数组 | 208 | // 通过Id获取级联数据id数组 |
209 | -export function getTreeIds (tree, currentId, key = "id") { | 209 | +export function getTreeIds(tree, currentId, key = "id") { |
210 | let parent = {} | 210 | let parent = {} |
211 | let pid = {} | 211 | let pid = {} |
212 | const loop = (list, level) => { | 212 | const loop = (list, level) => { |
@@ -233,16 +233,40 @@ export function getTreeIds (tree, currentId, key = "id") { | @@ -233,16 +233,40 @@ export function getTreeIds (tree, currentId, key = "id") { | ||
233 | return result | 233 | return result |
234 | } | 234 | } |
235 | 235 | ||
236 | -// 秒转换时分秒 | ||
237 | -export function transverterMss (result) { | ||
238 | - var h = Math.floor(result / 3600) < 10 ? "0" + Math.floor(result / 3600) : Math.floor(result / 3600) | ||
239 | - var m = Math.floor((result / 60 % 60)) < 10 ? "0" + Math.floor((result / 60 % 60)) : Math.floor((result / 60 % 60)) | ||
240 | - var s = Math.floor((result % 60)) < 10 ? "0" + Math.floor((result % 60)) : Math.floor((result % 60)) | ||
241 | - return h + ":" + m + ":" + s | 236 | +/* |
237 | + * 格式化时间 | ||
238 | + * yyyy-MM-dd hh:mm:ss | ||
239 | + * */ | ||
240 | +export function formatDate(date, fmt) { | ||
241 | + if (!date || date == null) return null; | ||
242 | + if (isNaN(date)) { | ||
243 | + return date; | ||
244 | + } | ||
245 | + let format = fmt || "yyyy-MM-dd hh:mm:ss"; | ||
246 | + | ||
247 | + let dates = new Date(Number(date)); | ||
248 | + | ||
249 | + let formatObj = { | ||
250 | + y: dates.getFullYear(), | ||
251 | + M: dates.getMonth() + 1, | ||
252 | + d: dates.getDate(), | ||
253 | + h: dates.getHours(), | ||
254 | + m: dates.getMinutes(), | ||
255 | + s: dates.getSeconds(), | ||
256 | + }; | ||
257 | + let time_str = format.replace(/(y|M|d|h|m|s)+/g, (result, key) => { | ||
258 | + let value = formatObj[key]; | ||
259 | + if (result.length > 0 && value < 10) { | ||
260 | + value = "0" + value; | ||
261 | + } | ||
262 | + return value || 0; | ||
263 | + }); | ||
264 | + return time_str; | ||
242 | } | 265 | } |
243 | 266 | ||
267 | + | ||
244 | // 获取日期时间戳 | 268 | // 获取日期时间戳 |
245 | -export function getTime (dayNum) { | 269 | +export function getTime(dayNum) { |
246 | var myDate = new Date() | 270 | var myDate = new Date() |
247 | var lw = new Date(myDate - 1000 * 60 * 60 * 24 * dayNum)// 最后一个数字多少天前的意思 | 271 | var lw = new Date(myDate - 1000 * 60 * 60 * 24 * dayNum)// 最后一个数字多少天前的意思 |
248 | var lastY = lw.getFullYear() | 272 | var lastY = lw.getFullYear() |
@@ -256,7 +280,7 @@ export function getTime (dayNum) { | @@ -256,7 +280,7 @@ export function getTime (dayNum) { | ||
256 | } | 280 | } |
257 | 281 | ||
258 | // 获取几天之前日期 | 282 | // 获取几天之前日期 |
259 | -export function getData (dayNum) { | 283 | +export function getData(dayNum) { |
260 | var myDate = new Date() | 284 | var myDate = new Date() |
261 | var lw = new Date(myDate - 1000 * 60 * 60 * 24 * dayNum)// 最后一个数字多少天前的意思 | 285 | var lw = new Date(myDate - 1000 * 60 * 60 * 24 * dayNum)// 最后一个数字多少天前的意思 |
262 | var lastY = lw.getFullYear() | 286 | var lastY = lw.getFullYear() |
@@ -267,7 +291,7 @@ export function getData (dayNum) { | @@ -267,7 +291,7 @@ export function getData (dayNum) { | ||
267 | } | 291 | } |
268 | 292 | ||
269 | // 日期转换时间戳 | 293 | // 日期转换时间戳 |
270 | -export function getNewTime (dayNum) { | 294 | +export function getNewTime(dayNum) { |
271 | var b = dayNum.split(/\D/) | 295 | var b = dayNum.split(/\D/) |
272 | var date = new Date(b[0], b[1] - 1, b[2]) | 296 | var date = new Date(b[0], b[1] - 1, b[2]) |
273 | var time = date.getTime() | 297 | var time = date.getTime() |
@@ -297,4 +321,75 @@ export function getURLParams(variable) { | @@ -297,4 +321,75 @@ export function getURLParams(variable) { | ||
297 | } | 321 | } |
298 | } | 322 | } |
299 | return variable ? data : obj | 323 | return variable ? data : obj |
300 | -} | ||
301 | \ No newline at end of file | 324 | \ No newline at end of file |
325 | +} | ||
326 | + | ||
327 | +/** | ||
328 | + * 校验答案 | ||
329 | + * @param {*} s 源字符串 | ||
330 | + * @param {*} questionType 题型,2单选 3多选 | ||
331 | + * @param {*} optionCount 选项数目 | ||
332 | + * @param {*} questionCount 题目数目 | ||
333 | + */ | ||
334 | +function filtterChar(s, b, optionCount) { | ||
335 | + const ms = "ABCDEFG"; | ||
336 | + let rs = ""; | ||
337 | + for (let i = 0; i < s.length; i++) { | ||
338 | + let c = s[i]; | ||
339 | + if (c == ',' || c == ' ' || c == ',') { | ||
340 | + if (!b) { | ||
341 | + continue; | ||
342 | + } | ||
343 | + c = ','; | ||
344 | + } | ||
345 | + else if (c < 'A' || c >= ms[optionCount]) { | ||
346 | + continue; | ||
347 | + } | ||
348 | + rs += c; | ||
349 | + } | ||
350 | + return rs; | ||
351 | +} | ||
352 | + | ||
353 | +function removeDup(s) { | ||
354 | + const ms = "ABCDEFG"; | ||
355 | + let rs = ""; | ||
356 | + for (let i = 0; i < ms.length; i++) { | ||
357 | + if (s.indexOf(ms[i]) >= 0) { | ||
358 | + rs += ms[i]; | ||
359 | + } | ||
360 | + } | ||
361 | + return rs; | ||
362 | +} | ||
363 | +export function checkAnswer(s, questionType, optionCount = 4, questionCount = 1) { | ||
364 | + if (optionCount > 10 || questionCount < 1) { | ||
365 | + return null; | ||
366 | + } | ||
367 | + let pre = s; | ||
368 | + s = s.toUpperCase(); | ||
369 | + s = filtterChar(s, questionType == 3 && questionCount > 1, optionCount); | ||
370 | + if (questionType == 2) {//单选 | ||
371 | + console.log(s.length + " " + questionCount); | ||
372 | + if (s.length > questionCount) { | ||
373 | + s = s.substring(s.length - questionCount, s.length); | ||
374 | + } | ||
375 | + } | ||
376 | + else if (questionType == 3) {//多选 | ||
377 | + //允许逗号 | ||
378 | + let ss = s.split(","); | ||
379 | + let len = questionCount; | ||
380 | + if (len > ss.length) { | ||
381 | + len = ss.length; | ||
382 | + } | ||
383 | + let rs = ""; | ||
384 | + for (let i = 0; i < len; i++) { | ||
385 | + rs += removeDup(ss[i]); | ||
386 | + if (i < len - 1) { | ||
387 | + rs += ','; | ||
388 | + } | ||
389 | + } | ||
390 | + s = rs; | ||
391 | + } | ||
392 | + else { | ||
393 | + return null; | ||
394 | + } | ||
395 | + return s; | ||
396 | +} |
src/views/ask/analysis.vue
1 | <template> | 1 | <template> |
2 | - <div>报表分析</div> | 2 | + <div> |
3 | + <back-box> | ||
4 | + <template slot="title"> | ||
5 | + <span>单课分析</span> | ||
6 | + </template> | ||
7 | + </back-box> | ||
8 | + <div class="tab-box"> | ||
9 | + <span class="tab-item active">答题表现</span> | ||
10 | + <span class="tab-item">学生问答表现</span> | ||
11 | + <span class="tab-item">学生互动表现</span> | ||
12 | + <span class="tab-item">签到明细</span> | ||
13 | + </div> | ||
14 | + </div> | ||
3 | </template> | 15 | </template> |
4 | 16 | ||
5 | <script> | 17 | <script> |
6 | -export default { | ||
7 | - | ||
8 | -} | 18 | +export default {}; |
9 | </script> | 19 | </script> |
10 | 20 | ||
11 | -<style> | ||
12 | - | 21 | +<style lang="scss" scoped> |
22 | +.tab-box { | ||
23 | + width: 800px; | ||
24 | + margin: 20px auto; | ||
25 | + background: #f8f8f8; | ||
26 | + border-radius: 20px; | ||
27 | + display: flex; | ||
28 | + .tab-item { | ||
29 | + flex: 1; | ||
30 | + height: 40px; | ||
31 | + line-height: 40px; | ||
32 | + text-align: center; | ||
33 | + font-size: 16px; | ||
34 | + color: #666; | ||
35 | + font-weight: 500; | ||
36 | + background: transparent; | ||
37 | + border-radius: 20px; | ||
38 | + &.active { | ||
39 | + background: #667ffd; | ||
40 | + color: #fff; | ||
41 | + } | ||
42 | + } | ||
43 | +} | ||
13 | </style> | 44 | </style> |
14 | \ No newline at end of file | 45 | \ No newline at end of file |
src/views/ask/index.vue
1 | <template> | 1 | <template> |
2 | - <div>随堂问报表 | ||
3 | - <router-link to="/askAnalysis">报表分析</router-link> | ||
4 | - | 2 | + <div> |
3 | + <back-box> | ||
4 | + <template slot="title"> | ||
5 | + <span>问答-数据报表</span> | ||
6 | + </template> | ||
7 | + </back-box> | ||
8 | + <div class="answer-header"> | ||
9 | + <div class="sel-box"> | ||
10 | + <el-select | ||
11 | + class="sel" | ||
12 | + v-model="query.clazzId" | ||
13 | + placeholder="" | ||
14 | + @change="changClazz" | ||
15 | + > | ||
16 | + <el-option | ||
17 | + v-for="item in classList" | ||
18 | + :key="item.value" | ||
19 | + :label="item.label" | ||
20 | + :value="item.value" | ||
21 | + >{{ item.label }} | ||
22 | + </el-option> | ||
23 | + </el-select> | ||
24 | + <el-select | ||
25 | + v-if="role == '班主任'" | ||
26 | + class="sel" | ||
27 | + multiple | ||
28 | + collapse-tags | ||
29 | + v-model="query.subjectId" | ||
30 | + placeholder="" | ||
31 | + @change="_QueryData" | ||
32 | + > | ||
33 | + <el-option | ||
34 | + v-for="item in subjectList" | ||
35 | + :key="item.value" | ||
36 | + :label="item.label" | ||
37 | + :value="item.value" | ||
38 | + > | ||
39 | + </el-option> | ||
40 | + </el-select> | ||
41 | + <el-select | ||
42 | + v-else | ||
43 | + class="sel" | ||
44 | + v-model="query.subjectId" | ||
45 | + placeholder="" | ||
46 | + @change="_QueryData" | ||
47 | + > | ||
48 | + <el-option | ||
49 | + v-for="item in subjectList" | ||
50 | + :key="item.value" | ||
51 | + :label="item.label" | ||
52 | + :value="item.value" | ||
53 | + > | ||
54 | + </el-option> | ||
55 | + </el-select> | ||
56 | + <div class="d1"> | ||
57 | + <el-date-picker | ||
58 | + v-model="query.startDay" | ||
59 | + type="date" | ||
60 | + @change="handleChangeTimeStart" | ||
61 | + placeholder="选择日期时间" | ||
62 | + value-format="yyyy-MM-dd" | ||
63 | + > | ||
64 | + </el-date-picker> | ||
65 | + ~ | ||
66 | + <el-date-picker | ||
67 | + v-model="query.endDay" | ||
68 | + type="date" | ||
69 | + placeholder="选择日期时间" | ||
70 | + @change="handleChangeTimeEnd" | ||
71 | + value-format="yyyy-MM-dd" | ||
72 | + > | ||
73 | + </el-date-picker> | ||
74 | + </div> | ||
75 | + <p class="p1"> | ||
76 | + <span @click="setDate(1)" :class="[date == 1 ? 'active' : '', 's1']" | ||
77 | + >今天</span | ||
78 | + > | ||
79 | + <span @click="setDate(2)" :class="[date == 2 ? 'active' : '', 's1']" | ||
80 | + >昨天</span | ||
81 | + > | ||
82 | + <span @click="setDate(3)" :class="[date == 3 ? 'active' : '', 's1']" | ||
83 | + >本周</span | ||
84 | + > | ||
85 | + </p> | ||
86 | + <el-button type="primary" round @click="_QueryData()">筛选</el-button> | ||
87 | + </div> | ||
88 | + </div> | ||
89 | + <div class="table-box"> | ||
90 | + <el-radio-group v-model="tabIndex" style="margin-bottom: 20px"> | ||
91 | + <el-radio-button :label="1">单课时报表</el-radio-button> | ||
92 | + <el-radio-button :label="2" v-if="this.role != '班主任'" | ||
93 | + >阶段问答报表</el-radio-button | ||
94 | + > | ||
95 | + <el-radio-button :label="3">阶段互动报表</el-radio-button> | ||
96 | + </el-radio-group> | ||
97 | + <p class="table-tit" v-if="tabIndex != 1"> | ||
98 | + <span>总课时数:10</span> | ||
99 | + <span>互动总数:22</span> | ||
100 | + </p> | ||
101 | + <div v-if="tabIndex == 1"> | ||
102 | + <el-table | ||
103 | + :data="tableData" | ||
104 | + border | ||
105 | + style="width: 100%" | ||
106 | + :default-sort="{ prop: 'canyudu', order: 'descending' }" | ||
107 | + > | ||
108 | + <el-table-column | ||
109 | + prop="keshi" | ||
110 | + label="课时" | ||
111 | + align="center" | ||
112 | + ></el-table-column> | ||
113 | + <el-table-column | ||
114 | + prop="zongshu" | ||
115 | + label="题目总数" | ||
116 | + align="center" | ||
117 | + width="100" | ||
118 | + ></el-table-column> | ||
119 | + <el-table-column | ||
120 | + prop="shijian" | ||
121 | + label="上课时间" | ||
122 | + align="center" | ||
123 | + ></el-table-column> | ||
124 | + <el-table-column | ||
125 | + prop="canyudu" | ||
126 | + label="参与度" | ||
127 | + sortable | ||
128 | + align="center" | ||
129 | + > <template slot-scope="scoped">{{scoped.row.canyudu}}%</template></el-table-column> | ||
130 | + <el-table-column | ||
131 | + prop="zhengque" | ||
132 | + label="已答总正确率" | ||
133 | + sortable | ||
134 | + align="center" | ||
135 | + > | ||
136 | + <template slot-scope="scoped">{{scoped.row.zhengque}}%</template> | ||
137 | + </el-table-column> | ||
138 | + <el-table-column | ||
139 | + prop="allzheng" | ||
140 | + label="班级总正确率" | ||
141 | + sortable | ||
142 | + align="center" | ||
143 | + ><template slot-scope="scoped">{{scoped.row.allzheng}}%</template></el-table-column> | ||
144 | + <el-table-column label="操作" align="center"> | ||
145 | + <template slot-scope="scoped"> | ||
146 | + <el-tooltip effect="dark" content="详情" placement="left"> | ||
147 | + <el-button | ||
148 | + type="primary" | ||
149 | + circle | ||
150 | + size="mini" | ||
151 | + icon="fa fa-arrow-right" | ||
152 | + @click="linkTo(scoped.row)" | ||
153 | + ></el-button> | ||
154 | + </el-tooltip> | ||
155 | + <el-tooltip effect="dark" content="修改答案" placement="right"> | ||
156 | + <el-button | ||
157 | + type="primary" | ||
158 | + circle | ||
159 | + size="mini" | ||
160 | + icon="fa fa-file-text" | ||
161 | + @click="edit(scoped.row)" | ||
162 | + ></el-button> | ||
163 | + </el-tooltip> | ||
164 | + </template> | ||
165 | + </el-table-column> | ||
166 | + </el-table> | ||
167 | + </div> | ||
168 | + <div v-if="tabIndex == 2"> | ||
169 | + <el-table | ||
170 | + :data="tableAsk" | ||
171 | + border | ||
172 | + style="width: 100%" | ||
173 | + :default-sort="{ prop: 'cishu', order: 'descending' }" | ||
174 | + > | ||
175 | + <el-table-column | ||
176 | + prop="xuehao" | ||
177 | + label="学号" | ||
178 | + align="center" | ||
179 | + ></el-table-column> | ||
180 | + <el-table-column | ||
181 | + prop="xingming" | ||
182 | + label="姓名" | ||
183 | + align="center" | ||
184 | + width="100" | ||
185 | + ></el-table-column> | ||
186 | + <el-table-column | ||
187 | + prop="cishu" | ||
188 | + label="累计答题次数" | ||
189 | + sortable | ||
190 | + align="center" | ||
191 | + ></el-table-column> | ||
192 | + <el-table-column | ||
193 | + prop="dadui" | ||
194 | + label="累计答对次数" | ||
195 | + sortable | ||
196 | + align="center" | ||
197 | + ></el-table-column> | ||
198 | + <el-table-column | ||
199 | + prop="canyudu" | ||
200 | + label="总参与度" | ||
201 | + sortable | ||
202 | + align="center" | ||
203 | + > <template slot-scope="scoped">{{scoped.row.canyudu}}%</template></el-table-column> | ||
204 | + <el-table-column | ||
205 | + prop="allzheng" | ||
206 | + label="总正确率" | ||
207 | + sortable | ||
208 | + align="center" | ||
209 | + > <template slot-scope="scoped">{{scoped.row.allzheng}}%</template></el-table-column> | ||
210 | + <el-table-column | ||
211 | + prop="yidazheng" | ||
212 | + label="已答总正确率" | ||
213 | + sortable | ||
214 | + align="center" | ||
215 | + > | ||
216 | + <template slot-scope="scoped">{{scoped.row.yidazheng}}%</template> | ||
217 | + </el-table-column> | ||
218 | + <el-table-column | ||
219 | + prop="zongpaiming" | ||
220 | + label="总正确率班排名" | ||
221 | + sortable | ||
222 | + align="center" | ||
223 | + ></el-table-column> | ||
224 | + </el-table> | ||
225 | + </div> | ||
226 | + <div v-if="tabIndex == 3"> | ||
227 | + <el-table | ||
228 | + :data="tableAsk" | ||
229 | + border | ||
230 | + style="width: 100%" | ||
231 | + :default-sort="{ prop: 'cishu', order: 'descending' }" | ||
232 | + > | ||
233 | + <el-table-column | ||
234 | + prop="xuehao" | ||
235 | + label="学号" | ||
236 | + align="center" | ||
237 | + ></el-table-column> | ||
238 | + <el-table-column | ||
239 | + prop="xingming" | ||
240 | + label="姓名" | ||
241 | + align="center" | ||
242 | + width="100" | ||
243 | + ></el-table-column> | ||
244 | + <el-table-column | ||
245 | + prop="cishu" | ||
246 | + label="抢答成功次数" | ||
247 | + sortable | ||
248 | + align="center" | ||
249 | + ></el-table-column> | ||
250 | + <el-table-column | ||
251 | + prop="dadui" | ||
252 | + label="答对次数" | ||
253 | + sortable | ||
254 | + align="center" | ||
255 | + ></el-table-column> | ||
256 | + <el-table-column | ||
257 | + prop="chouda" | ||
258 | + label="抽答次数" | ||
259 | + sortable | ||
260 | + align="center" | ||
261 | + ></el-table-column> | ||
262 | + <el-table-column | ||
263 | + prop="choudadui" | ||
264 | + label="抽答答对次数" | ||
265 | + sortable | ||
266 | + align="center" | ||
267 | + ></el-table-column> | ||
268 | + <el-table-column | ||
269 | + prop="canyu" | ||
270 | + label="参与得分" | ||
271 | + sortable | ||
272 | + align="center" | ||
273 | + ></el-table-column> | ||
274 | + <el-table-column | ||
275 | + prop="duicuo" | ||
276 | + label="对错得分" | ||
277 | + sortable | ||
278 | + align="center" | ||
279 | + ></el-table-column> | ||
280 | + </el-table> | ||
281 | + </div> | ||
282 | + <p class="down" v-if="tabIndex == 3||tabIndex == 2"> | ||
283 | + <el-button type="info" plain round icon="fa fa-cloud-download">导出报表</el-button> | ||
284 | + </p> | ||
285 | + </div> | ||
286 | + <el-dialog :visible.sync="dialogVisible" width="400" center> | ||
287 | + <div slot="title"> | ||
288 | + <p> | ||
289 | + <!-- 设置答案 <i class="fa fa-exchange" @click="editType = !editType"></i> --> | ||
290 | + 设置答案 | ||
291 | + </p> | ||
292 | + </div> | ||
293 | + <div v-show="editType"> | ||
294 | + <div v-for="(item, index) in form.questionList" :key="index"> | ||
295 | + <template v-for="(subQuestions, indexs) in item.subQuestions"> | ||
296 | + <div | ||
297 | + class="sub-questions" | ||
298 | + :key="indexs" | ||
299 | + v-if="subQuestions.correctAnswer" | ||
300 | + > | ||
301 | + <div class="qs-num">题{{ subQuestions.questionIndex }}</div> | ||
302 | + <div class="qs-options qs-options2"> | ||
303 | + <p v-if="subQuestions.questionType == 4" class="answer-box"> | ||
304 | + <span | ||
305 | + class="answer-s" | ||
306 | + :class="subQuestions.correctAnswer == 1 ? 'active' : ''" | ||
307 | + @click="subQuestions.correctAnswer = 1" | ||
308 | + >✓</span | ||
309 | + > | ||
310 | + <span | ||
311 | + class="answer-s" | ||
312 | + :class="subQuestions.correctAnswer == 2 ? 'active' : ''" | ||
313 | + @click="subQuestions.correctAnswer = 2" | ||
314 | + >✗</span | ||
315 | + > | ||
316 | + </p> | ||
317 | + <p v-if="subQuestions.questionType == 3" class="answer-box"> | ||
318 | + <span | ||
319 | + class="answer-s" | ||
320 | + v-for="option in subQuestions.answerOptions" | ||
321 | + :class=" | ||
322 | + subQuestions.correctAnswer.includes(option) | ||
323 | + ? 'active' | ||
324 | + : '' | ||
325 | + " | ||
326 | + :key="option" | ||
327 | + @click="changAnswer(subQuestions, option)" | ||
328 | + >{{ option }}</span | ||
329 | + > | ||
330 | + </p> | ||
331 | + <p v-if="subQuestions.questionType == 2" class="answer-box"> | ||
332 | + <span | ||
333 | + class="answer-s" | ||
334 | + v-for="option in subQuestions.answerOptions" | ||
335 | + :class=" | ||
336 | + subQuestions.correctAnswer == option ? 'active' : '' | ||
337 | + " | ||
338 | + :key="option" | ||
339 | + @click="subQuestions.correctAnswer = option" | ||
340 | + >{{ option }}</span | ||
341 | + > | ||
342 | + </p> | ||
343 | + </div> | ||
344 | + </div> | ||
345 | + </template> | ||
346 | + </div> | ||
347 | + </div> | ||
348 | + <!-- <div v-show="!editType"> | ||
349 | + <p class="dia-tips"> | ||
350 | + 请点击选项按钮设置答案,多选题题目之间用“,”隔开,若添加5道题:“AC,AD,BD,AC,CD” | ||
351 | + </p> | ||
352 | + <div class="dia-question-box"> | ||
353 | + <div v-for="(item, index) in form2.questionList" :key="index"> | ||
354 | + <template v-for="(items, indexs) in item.subQuestions"> | ||
355 | + <div class="set-questions" :key="indexs"> | ||
356 | + <div class="qs-num"> | ||
357 | + <p>{{ items.name }}</p> | ||
358 | + <p>共{{ items.list.length }}题</p> | ||
359 | + </div> | ||
360 | + <div class="qs-options"> | ||
361 | + <p class="ipt"> | ||
362 | + <el-input | ||
363 | + v-model="items.answerList" | ||
364 | + @keydown.native="keydownAnswer($event)" | ||
365 | + ></el-input> | ||
366 | + </p> | ||
367 | + <p class="answer-box"> | ||
368 | + <template v-if="items.list[0].questionType == 4"> | ||
369 | + <span | ||
370 | + class="answer-s active" | ||
371 | + @click=" | ||
372 | + items.answerList.length < items.list.length | ||
373 | + ? (items.answerList += '✓') | ||
374 | + : '' | ||
375 | + " | ||
376 | + >✓</span | ||
377 | + > | ||
378 | + <span | ||
379 | + class="answer-s active" | ||
380 | + @click=" | ||
381 | + items.answerList.length < items.list.length | ||
382 | + ? (items.answerList += '✗') | ||
383 | + : '' | ||
384 | + " | ||
385 | + >✗</span | ||
386 | + > | ||
387 | + </template> | ||
388 | + <template v-if="items.list[0].questionType == 3"> | ||
389 | + <span | ||
390 | + class="answer-s active" | ||
391 | + v-for="option in items.list[0].answerOptions" | ||
392 | + :key="option" | ||
393 | + @click="setAnswer(items,option)" | ||
394 | + >{{ option }}</span | ||
395 | + > | ||
396 | + <span | ||
397 | + class="answer-s active" | ||
398 | + @click=" | ||
399 | + items.answerList.split(',').length < items.list.length | ||
400 | + ? (items.answerList += ',') | ||
401 | + : '' | ||
402 | + " | ||
403 | + >,</span | ||
404 | + > | ||
405 | + </template> | ||
406 | + <template | ||
407 | + v-if="items.list[0].questionType == 2" | ||
408 | + class="answer-box" | ||
409 | + > | ||
410 | + <span | ||
411 | + class="answer-s active" | ||
412 | + v-for="option in items.list[0].answerOptions" | ||
413 | + :key="option" | ||
414 | + @click=" | ||
415 | + items.answerList.length < items.list.length | ||
416 | + ? (items.answerList += option) | ||
417 | + : '' | ||
418 | + " | ||
419 | + >{{ option }}</span | ||
420 | + > | ||
421 | + </template> | ||
422 | + <span | ||
423 | + class="answer-s delButton" | ||
424 | + @click="items.answerList = items.answerList.slice(0, -1)" | ||
425 | + >x</span | ||
426 | + > | ||
427 | + <span | ||
428 | + class="answer-s ac" | ||
429 | + @click="items.answerList = ''" | ||
430 | + >AC</span | ||
431 | + > | ||
432 | + </p> | ||
433 | + </div> | ||
434 | + </div> | ||
435 | + </template> | ||
436 | + </div> | ||
437 | + </div> | ||
438 | + </div> --> | ||
439 | + <div slot="footer"> | ||
440 | + <el-button class="dia-btn" type="primary" @click="saveAnswer" | ||
441 | + >确 定</el-button | ||
442 | + > | ||
443 | + <el-button class="dia-btn" type="danger" @click="dialogVisible = false" | ||
444 | + >取 消</el-button | ||
445 | + > | ||
446 | + </div> | ||
447 | + </el-dialog> | ||
5 | </div> | 448 | </div> |
6 | </template> | 449 | </template> |
7 | 450 | ||
8 | <script> | 451 | <script> |
452 | +import { formatDate, deepClone,checkAnswer } from "utils"; | ||
9 | export default { | 453 | export default { |
10 | - | ||
11 | -} | 454 | + data() { |
455 | + return { | ||
456 | + role: "", | ||
457 | + loading: false, | ||
458 | + dialogVisible: false, //修改答案 | ||
459 | + editType: true, //修改答案模式 | ||
460 | + editId: "", | ||
461 | + form: { questionList: [] }, | ||
462 | + form2: { questionList: [] }, | ||
463 | + date: "", //今天-昨天-本周 | ||
464 | + query: { | ||
465 | + //搜索条件 | ||
466 | + clazzId: "", | ||
467 | + subjectId: "", | ||
468 | + startDay: "", | ||
469 | + endDay: "", | ||
470 | + day: "", | ||
471 | + }, | ||
472 | + classList: [], //班级 | ||
473 | + subjectList: [], //科目 | ||
474 | + tabIndex: 1, //选项卡 | ||
475 | + tableData: [ | ||
476 | + //单课时报表 | ||
477 | + { | ||
478 | + id: 1, | ||
479 | + keshi: "课时一", | ||
480 | + zongshu: 10, | ||
481 | + shijian: "2022-11-9 21:30至22:30", | ||
482 | + canyudu: 60, | ||
483 | + zhengque: 90, | ||
484 | + allzheng: 80, | ||
485 | + questionList: [ | ||
486 | + { | ||
487 | + questionTitle: "f", | ||
488 | + score: 1, | ||
489 | + subQuestions: [ | ||
490 | + { | ||
491 | + questionIndex: 1, | ||
492 | + questionType: 2, | ||
493 | + score: 1, | ||
494 | + partScore: 0, | ||
495 | + selectNum: 4, | ||
496 | + answerOptions: ["A", "B", "C", "D"], | ||
497 | + correctAnswer: "B", | ||
498 | + }, | ||
499 | + { | ||
500 | + questionIndex: 2, | ||
501 | + questionType: 2, | ||
502 | + score: 1, | ||
503 | + partScore: 0, | ||
504 | + selectNum: 4, | ||
505 | + answerOptions: ["A", "B", "C", "D", "E", "F"], | ||
506 | + correctAnswer: "A", | ||
507 | + }, | ||
508 | + { | ||
509 | + questionIndex: 2, | ||
510 | + questionType: 3, | ||
511 | + score: 1, | ||
512 | + partScore: 0, | ||
513 | + selectNum: 4, | ||
514 | + answerOptions: ["A", "B", "C", "D", "E", "F"], | ||
515 | + correctAnswer: "AB", | ||
516 | + }, | ||
517 | + { | ||
518 | + questionIndex: 2, | ||
519 | + questionType: 3, | ||
520 | + score: 1, | ||
521 | + partScore: 0, | ||
522 | + selectNum: 4, | ||
523 | + answerOptions: ["A", "B", "C", "D", "E", "F"], | ||
524 | + correctAnswer: "AB", | ||
525 | + }, | ||
526 | + { | ||
527 | + questionIndex: 3, | ||
528 | + questionType: 4, | ||
529 | + score: 1, | ||
530 | + partScore: 0, | ||
531 | + selectNum: 0, | ||
532 | + answerOptions: [], | ||
533 | + correctAnswer: "1", | ||
534 | + }, | ||
535 | + ], | ||
536 | + }, | ||
537 | + ], | ||
538 | + }, | ||
539 | + { | ||
540 | + id: 2, | ||
541 | + keshi: "课时二", | ||
542 | + zongshu: 8, | ||
543 | + shijian: "2022-11-10 21:30至22:30", | ||
544 | + canyudu: 70, | ||
545 | + zhengque: 80, | ||
546 | + allzheng: 60, | ||
547 | + questionList: [ | ||
548 | + { | ||
549 | + questionTitle: "a", | ||
550 | + score: 1, | ||
551 | + subQuestions: [ | ||
552 | + { | ||
553 | + questionIndex: 2, | ||
554 | + questionType: 3, | ||
555 | + score: 1, | ||
556 | + partScore: 0, | ||
557 | + selectNum: 4, | ||
558 | + answerOptions: ["A", "B", "C", "D"], | ||
559 | + correctAnswer: "A,C", | ||
560 | + }, | ||
561 | + ], | ||
562 | + }, | ||
563 | + ], | ||
564 | + }, | ||
565 | + ], | ||
566 | + tableAsk:[ | ||
567 | + { | ||
568 | + xuehao: 1, | ||
569 | + xingming: "丁芳菲", | ||
570 | + cishu: 5, | ||
571 | + dadui: 60, | ||
572 | + canyudu: 90, | ||
573 | + allzheng: 80, | ||
574 | + yidazheng:50, | ||
575 | + zongpaiming:5 | ||
576 | + }, | ||
577 | + { | ||
578 | + xuehao: 1, | ||
579 | + xingming: "丁芳菲2", | ||
580 | + cishu: 3, | ||
581 | + dadui: 20, | ||
582 | + canyudu: 80, | ||
583 | + allzheng: 60, | ||
584 | + yidazheng:65, | ||
585 | + zongpaiming:4 | ||
586 | + } | ||
587 | + ], | ||
588 | + tableStage:[ | ||
589 | + { | ||
590 | + xuehao: 1, | ||
591 | + xingming: "丁芳菲", | ||
592 | + cishu: 5, | ||
593 | + dadui: 60, | ||
594 | + chouda: 90, | ||
595 | + choudadui: 80, | ||
596 | + canyu:50, | ||
597 | + duicuo:5 | ||
598 | + } | ||
599 | + ] | ||
600 | + }; | ||
601 | + }, | ||
602 | + async created() { | ||
603 | + this.role = this.$store.getters.info.permissions[0]?.roleName; | ||
604 | + if (this.role == "班主任") { | ||
605 | + this.query.subjectId = []; | ||
606 | + } | ||
607 | + // await this._QueryClassList(); | ||
608 | + // await this._QuerySubjectList(); | ||
609 | + // await this.setDate(1); | ||
610 | + let startDay = this.query?.startDay; | ||
611 | + if (!startDay) { | ||
612 | + this.query.startDay = new Date(); | ||
613 | + this.query.endDay = new Date(); | ||
614 | + } | ||
615 | + }, | ||
616 | + methods: { | ||
617 | + linkTo(obj) { | ||
618 | + //去详情 | ||
619 | + this.$router.push({ | ||
620 | + path: "/askAnalysis", | ||
621 | + query: { | ||
622 | + id: obj.id, | ||
623 | + }, | ||
624 | + }); | ||
625 | + }, | ||
626 | + setSubPro(type) { | ||
627 | + let tit; | ||
628 | + switch (type) { | ||
629 | + case 2: | ||
630 | + tit = "单选题"; | ||
631 | + break; | ||
632 | + case 3: | ||
633 | + tit = "多选题"; | ||
634 | + break; | ||
635 | + case 4: | ||
636 | + tit = "判断题"; | ||
637 | + break; | ||
638 | + case 5: | ||
639 | + tit = "主观题"; | ||
640 | + break; | ||
641 | + } | ||
642 | + return tit; | ||
643 | + }, | ||
644 | + edit(item) { | ||
645 | + this.form = deepClone(item); | ||
646 | + // this.form2 = deepClone(item); | ||
647 | + // //组合每道大题中的相同题目 | ||
648 | + // let questionList = deepClone(item.questionList); | ||
649 | + // for (let i = 0; i < questionList.length; i++) { | ||
650 | + // let jsons = {}; | ||
651 | + // let answerOptions = []; | ||
652 | + // questionList[i].subQuestions.map((items) => { | ||
653 | + // let txt = this.setSubPro(items.questionType); | ||
654 | + // if (jsons[txt]) { | ||
655 | + // jsons[txt].push(items); | ||
656 | + // } else { | ||
657 | + // jsons[txt] = [items]; | ||
658 | + // } | ||
659 | + // if (items.questionType == 2 || items.questionType == 3) { | ||
660 | + // if (items.answerOptions.length > answerOptions.length) { | ||
661 | + // answerOptions = items.answerOptions; | ||
662 | + // } | ||
663 | + // jsons[txt][0].answerOptions = answerOptions; | ||
664 | + // } | ||
665 | + // }); | ||
666 | + // this.form2.questionList[i].subQuestions = Object.keys(jsons).map( | ||
667 | + // (item) => { | ||
668 | + // return { | ||
669 | + // name: item, | ||
670 | + // list: jsons[item], | ||
671 | + // answerList: "", | ||
672 | + // }; | ||
673 | + // } | ||
674 | + // ); | ||
675 | + // } | ||
676 | + this.dialogVisible = true; | ||
677 | + }, | ||
678 | + keydownAnswer(event) {//快速答案设置禁止输入 | ||
679 | + if ( | ||
680 | + event.key == "Meta" || | ||
681 | + event.key == "CapsLock" || | ||
682 | + event.key == "Shift" || | ||
683 | + event.key == "Enter" || | ||
684 | + event.key == "Alt" || | ||
685 | + event.key == "Backspace" || | ||
686 | + event.key == "Delete" || | ||
687 | + event.key == "ArrowUp" || | ||
688 | + event.key == "ArrowDown" || | ||
689 | + event.key == "ArrowLeft" || | ||
690 | + event.key == "v" || | ||
691 | + event.key == "V" || | ||
692 | + event.key == "ArrowRight" | ||
693 | + ) { | ||
694 | + return; | ||
695 | + } else { | ||
696 | + event.returnValue = ""; | ||
697 | + } | ||
698 | + }, | ||
699 | + setAnswer(obj,answer){//多选答案设置 | ||
700 | + obj.answerList+=answer | ||
701 | + let str = obj.answerList; | ||
702 | + let str2 = checkAnswer( | ||
703 | + str, | ||
704 | + 3, | ||
705 | + obj.list[0].answerOptions, | ||
706 | + obj.list.length | ||
707 | + ); | ||
708 | + obj.answerList = str2; | ||
709 | + }, | ||
710 | + setDate(index) { | ||
711 | + const that = this; | ||
712 | + this.date = index == this.date ? "" : index; | ||
713 | + that.query.day = ""; | ||
714 | + that.query.startDay = ""; | ||
715 | + that.query.endDay = ""; | ||
716 | + switch (index) { | ||
717 | + case 1: | ||
718 | + that.query.day = formatDate(new Date(), "yyyy-MM-dd"); | ||
719 | + that.query.startDay = that.query.day; | ||
720 | + that.query.endDay = that.query.day; | ||
721 | + break; | ||
722 | + case 2: { | ||
723 | + let times = new Date().getTime() - 24 * 60 * 60 * 1000; | ||
724 | + that.query.day = formatDate(new Date(times), "yyyy-MM-dd"); | ||
725 | + that.query.startDay = that.query.day; | ||
726 | + that.query.endDay = that.query.day; | ||
727 | + break; | ||
728 | + } | ||
729 | + case 3: { | ||
730 | + let day = new Date().getDay(); | ||
731 | + if (day == 0) { | ||
732 | + //中国式星期天是一周的最后一天 | ||
733 | + day = 7; | ||
734 | + } | ||
735 | + let times1 = new Date().getTime() - 24 * 60 * 60 * 1000 * (day - 1); | ||
736 | + let times2 = new Date().getTime() - 24 * 60 * 60 * 1000 * (day - 7); | ||
737 | + that.query.startDay = formatDate(new Date(times1), "yyyy-MM-dd"); | ||
738 | + that.query.endDay = formatDate(new Date(times2), "yyyy-MM-dd"); | ||
739 | + break; | ||
740 | + } | ||
741 | + } | ||
742 | + this.page = 1; | ||
743 | + this._QueryData(); | ||
744 | + }, | ||
745 | + handleChangeTimeStart(val) { | ||
746 | + this.query.day = ""; | ||
747 | + this.date = ""; | ||
748 | + if (this.query.endDay) { | ||
749 | + if (new Date(val).getTime() > new Date(this.query.endDay).getTime()) { | ||
750 | + this.$message.error("任务结束时间不能任务开始时间前面,请重新设置"); | ||
751 | + this.query.startDay = ""; | ||
752 | + } | ||
753 | + } | ||
754 | + }, | ||
755 | + handleChangeTimeEnd(val) { | ||
756 | + this.query.day = ""; | ||
757 | + this.date = ""; | ||
758 | + if (this.query.startDay) { | ||
759 | + if (new Date(val).getTime() < new Date(this.query.startDay).getTime()) { | ||
760 | + this.$message.error("任务结束时间不能任务开始时间前面,请重新设置"); | ||
761 | + this.query.endDay = ""; | ||
762 | + } | ||
763 | + } | ||
764 | + }, | ||
765 | + changAnswer(sub, option) { | ||
766 | + //设置多选答案 | ||
767 | + let str = new RegExp(option, "g"); | ||
768 | + if (sub.correctAnswer?.includes(option)) { | ||
769 | + sub.correctAnswer = sub.correctAnswer.replace(str, ""); | ||
770 | + } else { | ||
771 | + let arrs = (sub.correctAnswer && sub.correctAnswer.split("")) || []; | ||
772 | + arrs.push(option); | ||
773 | + sub.correctAnswer = arrs.sort().join(""); | ||
774 | + } | ||
775 | + }, | ||
776 | + async saveAnswer(){ | ||
777 | + // const { data, code, message } = await this.$request.updateAnswerSheet({...this.form}); | ||
778 | + // if (code == 0) { | ||
779 | + this.dialogVisible = false | ||
780 | + // } else { | ||
781 | + // this.$message.error(message); | ||
782 | + // } | ||
783 | + }, | ||
784 | + async changClazz() { | ||
785 | + await this._QuerySubjectList(); | ||
786 | + await this.setDate(1); | ||
787 | + }, | ||
788 | + async _QueryClassList() { | ||
789 | + const { data, code, message } = await this.$request.fetchClassList(); | ||
790 | + if (code === 0) { | ||
791 | + this.classList = data.list.map((item) => { | ||
792 | + return { | ||
793 | + value: item.clazzId, | ||
794 | + label: item.clazzName, | ||
795 | + }; | ||
796 | + }); | ||
797 | + this.query.clazzId = this.classList[0].value; | ||
798 | + } else { | ||
799 | + this.$message.error(message); | ||
800 | + } | ||
801 | + }, | ||
802 | + async _QuerySubjectList() { | ||
803 | + const datas = this.query.clazzId | ||
804 | + ? { | ||
805 | + clazzId: this.query.clazzId, | ||
806 | + } | ||
807 | + : {}; | ||
808 | + const { data, code, message } = await this.$request.fetchSubjectList( | ||
809 | + datas | ||
810 | + ); | ||
811 | + if (code === 0) { | ||
812 | + this.subjectList = data.list.map((item) => { | ||
813 | + return { | ||
814 | + value: item.subjectId, | ||
815 | + label: item.subjectName, | ||
816 | + }; | ||
817 | + }); | ||
818 | + if (this.role == "班主任") { | ||
819 | + this.subjectList.unshift({ | ||
820 | + value: "", | ||
821 | + label: "全部", | ||
822 | + }); | ||
823 | + } | ||
824 | + this.query.subjectId = this.subjectList[0].value; | ||
825 | + } else { | ||
826 | + this.$message.error(message); | ||
827 | + } | ||
828 | + }, | ||
829 | + async _QueryData() { | ||
830 | + this.loading = true; | ||
831 | + //多课时对比 | ||
832 | + let query = {}; | ||
833 | + for (let key in this.query) { | ||
834 | + if (this.query[key] != "") { | ||
835 | + query[key] = this.query[key]; | ||
836 | + } | ||
837 | + } | ||
838 | + const { data, code, message } = await this.$request.fetchQuizList({ | ||
839 | + ...query, | ||
840 | + }); | ||
841 | + this.loading = false; | ||
842 | + if (code === 0) { | ||
843 | + } else { | ||
844 | + this.$message.error(message); | ||
845 | + } | ||
846 | + }, | ||
847 | + }, | ||
848 | +}; | ||
12 | </script> | 849 | </script> |
13 | 850 | ||
14 | -<style> | 851 | +<style lang="scss" scoped> |
852 | +.table-box { | ||
853 | + margin: 0 20px; | ||
854 | + padding: 16px; | ||
855 | + background: #f8f8f8; | ||
856 | + border-radius: 5px; | ||
857 | + :deep(.fa-arrow-right) { | ||
858 | + padding-left: 2px; | ||
859 | + } | ||
860 | + :deep(.fa-file-text) { | ||
861 | + padding-left: 2px; | ||
862 | + } | ||
863 | +} | ||
15 | 864 | ||
865 | +.sub-questions { | ||
866 | + width: 100%; | ||
867 | + display: flex; | ||
868 | + &:hover { | ||
869 | + background: #f8f8f8; | ||
870 | + } | ||
871 | + & > div { | ||
872 | + min-height: 40px; | ||
873 | + padding: 5px; | ||
874 | + flex-shrink: 0; | ||
875 | + display: flex; | ||
876 | + justify-content: center; | ||
877 | + align-items: center; | ||
878 | + } | ||
879 | + .qs-num { | ||
880 | + width: 80px; | ||
881 | + font-size: 16px; | ||
882 | + color: #333; | ||
883 | + font-weight: 500; | ||
884 | + } | ||
885 | + .qs-options { | ||
886 | + flex: 1; | ||
887 | + } | ||
888 | + .qs-options2 { | ||
889 | + text-align: left; | ||
890 | + justify-content: flex-start; | ||
891 | + padding-left: 20px; | ||
892 | + .answer-s { | ||
893 | + cursor: pointer; | ||
894 | + border-color: #667ffd; | ||
895 | + color: #667ffd; | ||
896 | + margin: 0 15px; | ||
897 | + &.active { | ||
898 | + color: #fff; | ||
899 | + } | ||
900 | + } | ||
901 | + } | ||
902 | + :deep(.el-select) { | ||
903 | + .el-input__inner { | ||
904 | + border-radius: 20px; | ||
905 | + border-color: #667ffd; | ||
906 | + width: 150px; | ||
907 | + height: 32px; | ||
908 | + line-height: 32px; | ||
909 | + background: rgba($color: #667ffd, $alpha: 0.05); | ||
910 | + } | ||
911 | + .el-input__icon { | ||
912 | + line-height: 32px; | ||
913 | + } | ||
914 | + } | ||
915 | +} | ||
916 | +.fa-exchange { | ||
917 | + color: #667ffd; | ||
918 | + cursor: pointer; | ||
919 | + font-size: 16px; | ||
920 | + margin-left: 10px; | ||
921 | +} | ||
922 | +.dia-btn { | ||
923 | + border-radius: 20px; | ||
924 | + margin: 0 20px; | ||
925 | + padding: 10px 20px; | ||
926 | +} | ||
927 | +.dia-tips{ | ||
928 | + padding-bottom:10px; | ||
929 | + } | ||
930 | +.dia-question-box { | ||
931 | + padding: 16px 16px 1px; | ||
932 | + background: #f8f8f8; | ||
933 | + border-radius: 10px; | ||
934 | + | ||
935 | + .answer-s { | ||
936 | + width: 36px; | ||
937 | + height: 28px; | ||
938 | + cursor: pointer; | ||
939 | + } | ||
940 | +} | ||
941 | +.set-questions { | ||
942 | + display: flex; | ||
943 | + margin-bottom: 12px; | ||
944 | + width: 100%; | ||
945 | + .qs-num { | ||
946 | + flex-shrink: 0; | ||
947 | + margin-right: 10px; | ||
948 | + } | ||
949 | + .qs-options { | ||
950 | + flex: 1; | ||
951 | + .ipt { | ||
952 | + margin-bottom: 5px; | ||
953 | + } | ||
954 | + } | ||
955 | + .delButton { | ||
956 | + border-color: #ff6868; | ||
957 | + background: #ff6868 url("../../assets/images/arrow.png") no-repeat center; | ||
958 | + background-size: 19px; | ||
959 | + color: transparent; | ||
960 | + } | ||
961 | + .ac{ | ||
962 | + border-color: #ff6868; | ||
963 | + background: #ff6868; | ||
964 | + color:#fff | ||
965 | + } | ||
966 | +} | ||
967 | +.down{ | ||
968 | +padding-top:16px; | ||
969 | +} | ||
16 | </style> | 970 | </style> |
17 | \ No newline at end of file | 971 | \ No newline at end of file |
src/views/examinationPaper/detail.vue
0 → 100644
1 | +<template> | ||
2 | + <div> | ||
3 | + <back-box> | ||
4 | + <template slot="title"> | ||
5 | + <span>修改答案</span> | ||
6 | + </template> | ||
7 | + </back-box> | ||
8 | + <div class="content"> | ||
9 | + <p class="tips"> | ||
10 | + <i class="fa fa-bell-o"></i> 2022-11-24 14:30张老师修改了答案。 | ||
11 | + </p> | ||
12 | + <div class="answer-title"> | ||
13 | + <p class="name">{{ form.title }}</p> | ||
14 | + <p class="totals">卷面总分:{{ allScore }}分</p> | ||
15 | + </div> | ||
16 | + <div v-for="(question, index) in form.questionList" :key="index"> | ||
17 | + <p class="question-title"> | ||
18 | + <span>{{ setBigNum(index) }}、</span> | ||
19 | + <span class="title-txt">{{ question.questionTitle }}</span> | ||
20 | + <span>共 {{ question.score }} 分</span> | ||
21 | + </p> | ||
22 | + <ul class="questions-ul"> | ||
23 | + <li class="sub-questions"> | ||
24 | + <div class="qs-num">题号</div> | ||
25 | + <div class="qs-type">题型</div> | ||
26 | + <div class="qs-score">分数</div> | ||
27 | + <div class="qs-partScore">部分分值</div> | ||
28 | + <div class="qs-answer">答案</div> | ||
29 | + </li> | ||
30 | + <li | ||
31 | + class="sub-questions" | ||
32 | + v-for="(subQuestions, indexs) in question.subQuestions" | ||
33 | + :key="indexs" | ||
34 | + > | ||
35 | + <div class="qs-num">{{ subQuestions.questionIndex }}</div> | ||
36 | + <div class="qs-type"> | ||
37 | + {{ setSubPro(subQuestions.questionType) }} | ||
38 | + </div> | ||
39 | + <div class="qs-score"> | ||
40 | + {{ subQuestions.score }} | ||
41 | + </div> | ||
42 | + <div class="qs-partScore"> | ||
43 | + {{ subQuestions.partScore }} | ||
44 | + </div> | ||
45 | + <div class="qs-answer"> | ||
46 | + {{ setAns(subQuestions.correctAnswer) }} | ||
47 | + </div> | ||
48 | + </li> | ||
49 | + </ul> | ||
50 | + </div> | ||
51 | + <div class="btn-box"> | ||
52 | + <el-button type="danger" plain round @click="linkBack">取消</el-button> | ||
53 | + <el-button type="primary" round @click="save">保存</el-button> | ||
54 | + </div> | ||
55 | + </div> | ||
56 | + </div> | ||
57 | +</template> | ||
58 | + | ||
59 | +<script> | ||
60 | +export default { | ||
61 | + methods: { | ||
62 | + setSubPro(type) { | ||
63 | + let tit; | ||
64 | + switch (type) { | ||
65 | + case 2: | ||
66 | + tit = "单选题"; | ||
67 | + break; | ||
68 | + case 3: | ||
69 | + tit = "多选题"; | ||
70 | + break; | ||
71 | + case 4: | ||
72 | + tit = "判断题"; | ||
73 | + break; | ||
74 | + case 5: | ||
75 | + tit = "主观题"; | ||
76 | + break; | ||
77 | + } | ||
78 | + return tit; | ||
79 | + }, | ||
80 | + setBigNum(num) { | ||
81 | + let txt = ""; | ||
82 | + let bigNum = [ | ||
83 | + "一", | ||
84 | + "二", | ||
85 | + "三", | ||
86 | + "四", | ||
87 | + "五", | ||
88 | + "六", | ||
89 | + "七", | ||
90 | + "八", | ||
91 | + "九", | ||
92 | + "十", | ||
93 | + "十一", | ||
94 | + "十二", | ||
95 | + "十三", | ||
96 | + "十四", | ||
97 | + "十五", | ||
98 | + "十六", | ||
99 | + "十七", | ||
100 | + "十八", | ||
101 | + "十九", | ||
102 | + "二十", | ||
103 | + ]; | ||
104 | + txt = bigNum[num]; | ||
105 | + | ||
106 | + return txt; | ||
107 | + }, | ||
108 | + setAns(answer) { | ||
109 | + let txt; | ||
110 | + switch (answer) { | ||
111 | + case 1: | ||
112 | + case "1": | ||
113 | + txt = "✓"; | ||
114 | + break; | ||
115 | + case 2: | ||
116 | + case "2": | ||
117 | + txt = "✗"; | ||
118 | + break; | ||
119 | + case "": | ||
120 | + txt = "--"; | ||
121 | + break; | ||
122 | + default: | ||
123 | + txt = answer; | ||
124 | + } | ||
125 | + return txt | ||
126 | + }, | ||
127 | + }, | ||
128 | +}; | ||
129 | +</script> | ||
130 | + | ||
131 | +<style lang="scss" scoped> | ||
132 | +.content { | ||
133 | + width: 100%; | ||
134 | + box-sizing: border-box; | ||
135 | + padding: 0 50px; | ||
136 | + .ml-20 { | ||
137 | + margin-left: 20px; | ||
138 | + } | ||
139 | + .btn-box { | ||
140 | + text-align: right; | ||
141 | + margin-left: 140px; | ||
142 | + } | ||
143 | + .tips { | ||
144 | + height: 48px; | ||
145 | + line-height: 48px; | ||
146 | + padding: 0 16px; | ||
147 | + border: 1px solid #fac7cc; | ||
148 | + background-color: #ffebec; | ||
149 | + font-size: 14px; | ||
150 | + color: #fd9795; | ||
151 | + margin: 10px 0 20px 0; | ||
152 | + .fa-bell-o { | ||
153 | + font-size: 18px; | ||
154 | + margin-right: 5px; | ||
155 | + } | ||
156 | + } | ||
157 | +} | ||
158 | +.answer-title { | ||
159 | + text-align: center; | ||
160 | + font-size: 20px; | ||
161 | + color: #333; | ||
162 | + font-weight: 700; | ||
163 | + padding-bottom: 20px; | ||
164 | + .totals { | ||
165 | + font-size: 16px; | ||
166 | + color: #888; | ||
167 | + font-weight: normal; | ||
168 | + } | ||
169 | +} | ||
170 | +.question-title { | ||
171 | + line-height: 40px; | ||
172 | + .ipt { | ||
173 | + width: 300px; | ||
174 | + margin: 0 16px 0 10px; | ||
175 | + :deep(.el-input__inner) { | ||
176 | + border-radius: 20px; | ||
177 | + border-color: #667ffd; | ||
178 | + background: rgba($color: #667ffd, $alpha: 0.05); | ||
179 | + } | ||
180 | + } | ||
181 | + .delete { | ||
182 | + margin-right: 8px; | ||
183 | + } | ||
184 | + .title-txt { | ||
185 | + margin-right: 20px; | ||
186 | + font-size: 16px; | ||
187 | + font-weight: 700; | ||
188 | + } | ||
189 | +} | ||
190 | +</style> | ||
0 | \ No newline at end of file | 191 | \ No newline at end of file |
src/views/examinationPaper/edit.vue
@@ -26,6 +26,7 @@ | @@ -26,6 +26,7 @@ | ||
26 | <ul class="questions-ul"> | 26 | <ul class="questions-ul"> |
27 | <li class="sub-questions"> | 27 | <li class="sub-questions"> |
28 | <div class="qs-num">题号</div> | 28 | <div class="qs-num">题号</div> |
29 | + <div class="qs-type">题型</div> | ||
29 | <div class="qs-score">分数</div> | 30 | <div class="qs-score">分数</div> |
30 | <div class="qs-options qs-options2">选项设置</div> | 31 | <div class="qs-options qs-options2">选项设置</div> |
31 | </li> | 32 | </li> |
@@ -245,7 +246,7 @@ export default { | @@ -245,7 +246,7 @@ export default { | ||
245 | font-size: 20px; | 246 | font-size: 20px; |
246 | color: #333; | 247 | color: #333; |
247 | font-weight: 700; | 248 | font-weight: 700; |
248 | - padding: 20px 0 0 0; | 249 | + padding-bottom: 20px; |
249 | .totals { | 250 | .totals { |
250 | font-size: 16px; | 251 | font-size: 16px; |
251 | color: #888; | 252 | color: #888; |
@@ -275,25 +276,7 @@ export default { | @@ -275,25 +276,7 @@ export default { | ||
275 | .el-input-number { | 276 | .el-input-number { |
276 | width: 140px; | 277 | width: 140px; |
277 | } | 278 | } |
278 | -.answer-box { | ||
279 | - .answer-s { | ||
280 | - display: inline-block; | ||
281 | - width: 30px; | ||
282 | - height: 30px; | ||
283 | - border: 1px solid #e2e2e2; | ||
284 | - border-radius: 3px; | ||
285 | - margin: 0 6px; | ||
286 | - font-size: 16px; | ||
287 | - color: #333; | ||
288 | - text-align: center; | ||
289 | - line-height: 30px; | ||
290 | - &.active { | ||
291 | - background: #5e78fa; | ||
292 | - border-color: #5e78fa; | ||
293 | - color: #fff; | ||
294 | - } | ||
295 | - } | ||
296 | -} | 279 | + |
297 | .questions-ul { | 280 | .questions-ul { |
298 | border-left: 1px solid #e2e2e2; | 281 | border-left: 1px solid #e2e2e2; |
299 | border-top: 1px solid #e2e2e2; | 282 | border-top: 1px solid #e2e2e2; |
src/views/examinationPaper/index.vue
@@ -19,20 +19,20 @@ | @@ -19,20 +19,20 @@ | ||
19 | 19 | ||
20 | <div class="answer-header"> | 20 | <div class="answer-header"> |
21 | <div class="sel-box"> | 21 | <div class="sel-box"> |
22 | - <el-select | ||
23 | - class="sel" | ||
24 | - v-model="query.clazzId" | ||
25 | - placeholder="选择班级" | ||
26 | - @change="changClazz" | 22 | + <el-cascader |
23 | + class="sel sel2" | ||
24 | + :options="options" | ||
25 | + :props="props" | ||
26 | + collapse-tags | ||
27 | + clearable | ||
28 | + placeholder="选择年级-班级" | ||
29 | + v-model="query.gradeClass" | ||
30 | + @change="changeGrade" | ||
31 | + ><template slot-scope="{ node, data }"> | ||
32 | + <span>{{ data.label }}</span> | ||
33 | + <span v-if="!node.isLeaf"> ({{ data.children.length }}) </span> | ||
34 | + </template></el-cascader | ||
27 | > | 35 | > |
28 | - <el-option | ||
29 | - v-for="item in classList" | ||
30 | - :key="item.value" | ||
31 | - :label="item.label" | ||
32 | - :value="item.value" | ||
33 | - >{{ item.label }} | ||
34 | - </el-option> | ||
35 | - </el-select> | ||
36 | <el-select | 36 | <el-select |
37 | class="sel" | 37 | class="sel" |
38 | v-model="query.subjectId" | 38 | v-model="query.subjectId" |
@@ -134,10 +134,9 @@ | @@ -134,10 +134,9 @@ | ||
134 | icon="el-icon-more" | 134 | icon="el-icon-more" |
135 | ></el-button> | 135 | ></el-button> |
136 | <el-dropdown-menu slot="dropdown"> | 136 | <el-dropdown-menu slot="dropdown"> |
137 | - <el-dropdown-item :command="1">授课端同步</el-dropdown-item> | ||
138 | - <el-dropdown-item :command="2">修改分享范围</el-dropdown-item> | ||
139 | - <el-dropdown-item :command="3">复制</el-dropdown-item> | ||
140 | - <el-dropdown-item :command="4">归档</el-dropdown-item> | 137 | + <el-dropdown-item :command="1" v-if="this.$store.info.id == item.id">修改分享范围</el-dropdown-item> |
138 | + <el-dropdown-item :command="2">复制</el-dropdown-item> | ||
139 | + <el-dropdown-item :command="3">归档</el-dropdown-item> | ||
141 | </el-dropdown-menu> | 140 | </el-dropdown-menu> |
142 | </el-dropdown> | 141 | </el-dropdown> |
143 | </div> | 142 | </div> |
@@ -170,9 +169,40 @@ export default { | @@ -170,9 +169,40 @@ export default { | ||
170 | name: "examinationPaper", | 169 | name: "examinationPaper", |
171 | data() { | 170 | data() { |
172 | return { | 171 | return { |
172 | + props: { multiple: true, checkStrictly: true }, | ||
173 | + options: [ | ||
174 | + { | ||
175 | + value: 1, | ||
176 | + label: "一年级", | ||
177 | + children: [ | ||
178 | + { | ||
179 | + value: 2, | ||
180 | + label: "二班", | ||
181 | + }, | ||
182 | + { | ||
183 | + value: 3, | ||
184 | + label: "三班", | ||
185 | + }, | ||
186 | + ], | ||
187 | + }, | ||
188 | + { | ||
189 | + value: 4, | ||
190 | + label: "二年级", | ||
191 | + children: [ | ||
192 | + { | ||
193 | + value: 5, | ||
194 | + label: "二班", | ||
195 | + }, | ||
196 | + { | ||
197 | + value: 6, | ||
198 | + label: "三班", | ||
199 | + }, | ||
200 | + ], | ||
201 | + }, | ||
202 | + ], | ||
173 | dialogVisible: false, | 203 | dialogVisible: false, |
174 | query: { | 204 | query: { |
175 | - clazzId: "2003", | 205 | + gradeClass: [], |
176 | subjectId: "0", | 206 | subjectId: "0", |
177 | typeName: "周测", | 207 | typeName: "周测", |
178 | title: "", | 208 | title: "", |
@@ -202,9 +232,9 @@ export default { | @@ -202,9 +232,9 @@ export default { | ||
202 | date: "2022-11-04 18:09:49", | 232 | date: "2022-11-04 18:09:49", |
203 | share: 1, | 233 | share: 1, |
204 | score: 100, | 234 | score: 100, |
205 | - gradeName:"二年级", | ||
206 | - subjectId:1, | ||
207 | - examsDuration:4800, | 235 | + gradeName: "二年级", |
236 | + subjectId: 1, | ||
237 | + examsDuration: 4800, | ||
208 | questionList: [ | 238 | questionList: [ |
209 | { | 239 | { |
210 | questionTitle: "f", | 240 | questionTitle: "f", |
@@ -234,9 +264,9 @@ export default { | @@ -234,9 +264,9 @@ export default { | ||
234 | date: "2022-11-04 18:09:49", | 264 | date: "2022-11-04 18:09:49", |
235 | share: 1, | 265 | share: 1, |
236 | score: 100, | 266 | score: 100, |
237 | - gradeName:"二年级", | ||
238 | - subjectId:1, | ||
239 | - examsDuration:3000, | 267 | + gradeName: "二年级", |
268 | + subjectId: 1, | ||
269 | + examsDuration: 3000, | ||
240 | questionList: [ | 270 | questionList: [ |
241 | { | 271 | { |
242 | questionTitle: "f", | 272 | questionTitle: "f", |
@@ -287,38 +317,22 @@ export default { | @@ -287,38 +317,22 @@ export default { | ||
287 | const that = this; | 317 | const that = this; |
288 | switch (value) { | 318 | switch (value) { |
289 | case 1: | 319 | case 1: |
290 | - //授课端同步 | ||
291 | - that.syncMeg(item); | ||
292 | - break; | ||
293 | - case 2: | ||
294 | //修改分享范围 | 320 | //修改分享范围 |
295 | that.shareForm.id = item.id; | 321 | that.shareForm.id = item.id; |
296 | that.shareForm.grade = item.grade; | 322 | that.shareForm.grade = item.grade; |
297 | that.shareForm.share = item.share || 1; | 323 | that.shareForm.share = item.share || 1; |
298 | that.dialogVisible = true; | 324 | that.dialogVisible = true; |
299 | break; | 325 | break; |
300 | - case 3: | 326 | + case 2: |
301 | //复制 | 327 | //复制 |
302 | - that.toAdd({ type: 2, form: JSON.stringify(item), }); | 328 | + that.toAdd({ type: 2, form: JSON.stringify(item) }); |
303 | break; | 329 | break; |
304 | - case 4: | 330 | + case 3: |
305 | //归档 | 331 | //归档 |
306 | that.recovery(item); | 332 | that.recovery(item); |
307 | break; | 333 | break; |
308 | } | 334 | } |
309 | }, | 335 | }, |
310 | - async syncMeg() { | ||
311 | - //同步 | ||
312 | - // const { data, code, message } = await this.$request.fetchAnswerList({ | ||
313 | - // ...this.shareForm, | ||
314 | - // }); | ||
315 | - // this.loading = false; | ||
316 | - // if (code === 0) { | ||
317 | - this.$message.success("已同步"); | ||
318 | - // } else { | ||
319 | - // this.$message.error(message); | ||
320 | - // } | ||
321 | - }, | ||
322 | async saveShare() { | 336 | async saveShare() { |
323 | //修改分享范围 | 337 | //修改分享范围 |
324 | // const { data, code, message } = await this.$request.fetchAnswerList({ | 338 | // const { data, code, message } = await this.$request.fetchAnswerList({ |
@@ -347,12 +361,12 @@ export default { | @@ -347,12 +361,12 @@ export default { | ||
347 | // this.$message.error(message); | 361 | // this.$message.error(message); |
348 | // } | 362 | // } |
349 | }, | 363 | }, |
350 | - | ||
351 | - async changClazz() { | 364 | + async changeGrade() { |
352 | //切换班级 | 365 | //切换班级 |
353 | await this._QuerySubjectList(); | 366 | await this._QuerySubjectList(); |
354 | this._QueryData(); | 367 | this._QueryData(); |
355 | }, | 368 | }, |
369 | + async changClazz() {}, | ||
356 | // 查找答题卡类型 | 370 | // 查找答题卡类型 |
357 | async _QueryTypeList() { | 371 | async _QueryTypeList() { |
358 | const { data, code, message } = await this.$request.fetchTypeNames(); | 372 | const { data, code, message } = await this.$request.fetchTypeNames(); |
@@ -534,6 +548,16 @@ export default { | @@ -534,6 +548,16 @@ export default { | ||
534 | } | 548 | } |
535 | } | 549 | } |
536 | } | 550 | } |
551 | +.answer-header { | ||
552 | + .sel-box { | ||
553 | + .sel { | ||
554 | + min-width: 160px; | ||
555 | + } | ||
556 | + :deep(.el-cascader__tags) { | ||
557 | + flex-wrap: nowrap; | ||
558 | + } | ||
559 | + } | ||
560 | +} | ||
537 | .dialog-footer { | 561 | .dialog-footer { |
538 | text-align: center; | 562 | text-align: center; |
539 | :deep(.el-button) { | 563 | :deep(.el-button) { |
src/views/examinationPaper/recycle.vue
@@ -7,50 +7,51 @@ | @@ -7,50 +7,51 @@ | ||
7 | </back-box> | 7 | </back-box> |
8 | <div class="answer-header"> | 8 | <div class="answer-header"> |
9 | <div class="sel-box"> | 9 | <div class="sel-box"> |
10 | - <el-select | ||
11 | - class="sel" | ||
12 | - v-model="query.gradeName" | ||
13 | - placeholder="" | 10 | + <el-cascader |
11 | + class="sel sel2" | ||
12 | + :options="options" | ||
13 | + :props="props" | ||
14 | + collapse-tags | ||
15 | + clearable | ||
16 | + placeholder="选择年级-班级" | ||
17 | + v-model="query.gradeClass" | ||
14 | @change="changeGrade" | 18 | @change="changeGrade" |
19 | + ><template slot-scope="{ node, data }"> | ||
20 | + <span>{{ data.label }}</span> | ||
21 | + <span v-if="!node.isLeaf"> ({{ data.children.length }}) </span> | ||
22 | + </template></el-cascader | ||
15 | > | 23 | > |
16 | - <el-option | ||
17 | - v-for="item in gradeList" | ||
18 | - :key="item" | ||
19 | - :label="item" | ||
20 | - :value="item" | ||
21 | - > | ||
22 | - </el-option> | ||
23 | - </el-select> | ||
24 | <el-select | 24 | <el-select |
25 | class="sel" | 25 | class="sel" |
26 | - v-model="query.type" | ||
27 | - placeholder="选择类型" | 26 | + v-model="query.subjectId" |
27 | + placeholder="选择科目" | ||
28 | @change="_QueryData()" | 28 | @change="_QueryData()" |
29 | > | 29 | > |
30 | <el-option label="全部" value=""></el-option> | 30 | <el-option label="全部" value=""></el-option> |
31 | <el-option | 31 | <el-option |
32 | - v-for="item in typeList" | 32 | + v-for="item in subjectList" |
33 | :key="item.value" | 33 | :key="item.value" |
34 | :label="item.label" | 34 | :label="item.label" |
35 | :value="item.value" | 35 | :value="item.value" |
36 | - >{{ item.label }} | 36 | + > |
37 | </el-option> | 37 | </el-option> |
38 | </el-select> | 38 | </el-select> |
39 | <el-select | 39 | <el-select |
40 | class="sel" | 40 | class="sel" |
41 | - v-model="query.subjectId" | ||
42 | - placeholder="选择科目" | 41 | + v-model="query.type" |
42 | + placeholder="选择类型" | ||
43 | @change="_QueryData()" | 43 | @change="_QueryData()" |
44 | > | 44 | > |
45 | <el-option label="全部" value=""></el-option> | 45 | <el-option label="全部" value=""></el-option> |
46 | <el-option | 46 | <el-option |
47 | - v-for="item in subjectList" | 47 | + v-for="item in typeList" |
48 | :key="item.value" | 48 | :key="item.value" |
49 | :label="item.label" | 49 | :label="item.label" |
50 | :value="item.value" | 50 | :value="item.value" |
51 | - > | 51 | + >{{ item.label }} |
52 | </el-option> | 52 | </el-option> |
53 | </el-select> | 53 | </el-select> |
54 | + | ||
54 | <el-input | 55 | <el-input |
55 | placeholder="输入试卷名称" | 56 | placeholder="输入试卷名称" |
56 | v-model="query.title" | 57 | v-model="query.title" |
@@ -89,7 +90,7 @@ | @@ -89,7 +90,7 @@ | ||
89 | </p> | 90 | </p> |
90 | </div> | 91 | </div> |
91 | <div class="btn-box"> | 92 | <div class="btn-box"> |
92 | - <el-tooltip effect="dark" content="使用" placement="bottom"> | 93 | + <el-tooltip effect="dark" content="恢复" placement="bottom"> |
93 | <el-button | 94 | <el-button |
94 | class="edit" | 95 | class="edit" |
95 | type="info" | 96 | type="info" |
@@ -119,16 +120,47 @@ | @@ -119,16 +120,47 @@ | ||
119 | export default { | 120 | export default { |
120 | data() { | 121 | data() { |
121 | return { | 122 | return { |
123 | + props: { multiple: true, checkStrictly: true }, | ||
124 | + options: [ | ||
125 | + { | ||
126 | + value: 1, | ||
127 | + label: "一年级", | ||
128 | + children: [ | ||
129 | + { | ||
130 | + value: 2, | ||
131 | + label: "二班", | ||
132 | + }, | ||
133 | + { | ||
134 | + value: 3, | ||
135 | + label: "三班", | ||
136 | + }, | ||
137 | + ], | ||
138 | + }, | ||
139 | + { | ||
140 | + value: 4, | ||
141 | + label: "二年级", | ||
142 | + children: [ | ||
143 | + { | ||
144 | + value: 5, | ||
145 | + label: "二班", | ||
146 | + }, | ||
147 | + { | ||
148 | + value: 6, | ||
149 | + label: "三班", | ||
150 | + }, | ||
151 | + ], | ||
152 | + }, | ||
153 | + ], | ||
122 | query: { | 154 | query: { |
123 | - gradeName: "二年级", | 155 | + gradeClass: [], |
124 | type: "", | 156 | type: "", |
125 | subjectId: "", | 157 | subjectId: "", |
126 | title: "", | 158 | title: "", |
127 | }, | 159 | }, |
128 | gradeList: ["二年级"], | 160 | gradeList: ["二年级"], |
129 | typeList: [ | 161 | typeList: [ |
130 | - { label: "随堂问", value: 1 }, | ||
131 | - { label: "即使测", value: 2 }, | 162 | + { label: "周测", value: 1 }, |
163 | + { label: "月测", value: 2 }, | ||
132 | ], | 164 | ], |
133 | subjectList: [], | 165 | subjectList: [], |
134 | tableData: [ | 166 | tableData: [ |
@@ -165,9 +197,9 @@ export default { | @@ -165,9 +197,9 @@ export default { | ||
165 | //删除答题卡 | 197 | //删除答题卡 |
166 | // const { data, code, message } = await this.$request.useAnswerSheet(); | 198 | // const { data, code, message } = await this.$request.useAnswerSheet(); |
167 | // if (code == 0) { | 199 | // if (code == 0) { |
168 | - this.tableData = this.tableData.filter(item=>{ | ||
169 | - return obj.if != item.id | ||
170 | - }) | 200 | + this.tableData = this.tableData.filter((item) => { |
201 | + return obj.if != item.id; | ||
202 | + }); | ||
171 | // } else { | 203 | // } else { |
172 | // this.$message.error(message); | 204 | // this.$message.error(message); |
173 | // } | 205 | // } |
@@ -176,9 +208,9 @@ export default { | @@ -176,9 +208,9 @@ export default { | ||
176 | //删除答题卡 | 208 | //删除答题卡 |
177 | // const { data, code, message } = await this.$request.removeAnswerSheet(); | 209 | // const { data, code, message } = await this.$request.removeAnswerSheet(); |
178 | // if (code == 0) { | 210 | // if (code == 0) { |
179 | - this.tableData = this.tableData.filter(item=>{ | ||
180 | - return obj.if != item.id | ||
181 | - }) | 211 | + this.tableData = this.tableData.filter((item) => { |
212 | + return obj.if != item.id; | ||
213 | + }); | ||
182 | // } else { | 214 | // } else { |
183 | // this.$message.error(message); | 215 | // this.$message.error(message); |
184 | // } | 216 | // } |
@@ -211,10 +243,19 @@ export default { | @@ -211,10 +243,19 @@ export default { | ||
211 | this.$message.error(message); | 243 | this.$message.error(message); |
212 | } | 244 | } |
213 | }, | 245 | }, |
246 | + // 查找答题卡类型 | ||
247 | + async _QueryTypeList() { | ||
248 | + const { data, code, message } = await this.$request.fetchTypeNames(); | ||
249 | + if (code === 0) { | ||
250 | + this.typeList = [...data.typeNames] || []; | ||
251 | + } else { | ||
252 | + this.$message.error(message); | ||
253 | + } | ||
254 | + }, | ||
214 | async changeGrade() { | 255 | async changeGrade() { |
215 | - this._QueryData(); | ||
216 | - this._GradeList(); | ||
217 | - this._QuerySubjectList(); | 256 | + // this._QueryData(); |
257 | + // this._GradeList(); | ||
258 | + // this._QuerySubjectList(); | ||
218 | }, | 259 | }, |
219 | async _GradeList() { | 260 | async _GradeList() { |
220 | //查询年级列表 | 261 | //查询年级列表 |
@@ -257,6 +298,9 @@ export default { | @@ -257,6 +298,9 @@ export default { | ||
257 | .sel { | 298 | .sel { |
258 | min-width: 160px; | 299 | min-width: 160px; |
259 | } | 300 | } |
301 | + :deep(.el-cascader__tags) { | ||
302 | + flex-wrap: nowrap; | ||
303 | + } | ||
260 | } | 304 | } |
261 | } | 305 | } |
262 | .content { | 306 | .content { |
src/views/index/mainIndex.vue
1 | <template> | 1 | <template> |
2 | <div class="container"> | 2 | <div class="container"> |
3 | <ul class="nav-list" v-if="type == '学校管理员'"> | 3 | <ul class="nav-list" v-if="type == '学校管理员'"> |
4 | - <li class="nav-item item1" @click="links('setUpAccount')"> | 4 | + <li class="nav-item item1" @click="links('/setUpAccount')"> |
5 | <img class="icon" src="../../assets/nav/setUpAccount.png" alt="" /> | 5 | <img class="icon" src="../../assets/nav/setUpAccount.png" alt="" /> |
6 | <div class="text"> | 6 | <div class="text"> |
7 | <p class="p1">账号管理</p> | 7 | <p class="p1">账号管理</p> |
8 | <p class="p2">管理32个任课教师,14个班主任,3个备课组长账号信息。</p> | 8 | <p class="p2">管理32个任课教师,14个班主任,3个备课组长账号信息。</p> |
9 | </div> | 9 | </div> |
10 | </li> | 10 | </li> |
11 | - <li class="nav-item item1" @click="links('setUpSchool')"> | 11 | + <li class="nav-item item1" @click="links('/setUpSchool')"> |
12 | <img class="icon" src="../../assets/nav/setUpSchool.png" alt="" /> | 12 | <img class="icon" src="../../assets/nav/setUpSchool.png" alt="" /> |
13 | <div class="text"> | 13 | <div class="text"> |
14 | <p class="p1">学校管理</p> | 14 | <p class="p1">学校管理</p> |
15 | <p class="p2">管理6个年级,3个班级,397名学生信息。</p> | 15 | <p class="p2">管理6个年级,3个班级,397名学生信息。</p> |
16 | </div> | 16 | </div> |
17 | </li> | 17 | </li> |
18 | - <li class="nav-item item2" @click="links('device')"> | 18 | + <li class="nav-item item2" @click="links('/device')"> |
19 | <img class="icon" src="../../assets/nav/device.png" alt="" /> | 19 | <img class="icon" src="../../assets/nav/device.png" alt="" /> |
20 | <div class="text"> | 20 | <div class="text"> |
21 | <p class="p1">设备状态</p> | 21 | <p class="p1">设备状态</p> |
@@ -23,66 +23,70 @@ | @@ -23,66 +23,70 @@ | ||
23 | </div> | 23 | </div> |
24 | </li> | 24 | </li> |
25 | <li class="item3"> | 25 | <li class="item3"> |
26 | - <div class="nav-item item1 item-child1" @click="links('analysis')"> | 26 | + <div class="nav-item item1 item-child1" @click="links('/analysis')"> |
27 | <img class="icon" src="../../assets/nav/analysis.png" alt="" /> | 27 | <img class="icon" src="../../assets/nav/analysis.png" alt="" /> |
28 | <div class="text"> | 28 | <div class="text"> |
29 | <p class="p1">使用分析</p> | 29 | <p class="p1">使用分析</p> |
30 | <p class="p2">按班级、科目等维度分析设备使用频率。</p> | 30 | <p class="p2">按班级、科目等维度分析设备使用频率。</p> |
31 | </div> | 31 | </div> |
32 | </div> | 32 | </div> |
33 | - <div class="nav-item item1 item-child2" @click="links('card')"> | 33 | + <div class="nav-item item1 item-child2" @click="links('/card')"> |
34 | <img class="icon" src="../../assets/nav/card.png" alt="" /> | 34 | <img class="icon" src="../../assets/nav/card.png" alt="" /> |
35 | <p class="p1">发卡补卡</p> | 35 | <p class="p1">发卡补卡</p> |
36 | <p class="p2">为学生办理发卡、补卡业务。</p> | 36 | <p class="p2">为学生办理发卡、补卡业务。</p> |
37 | </div> | 37 | </div> |
38 | - <div class="nav-item item1 item-child2" @click="links('down')"> | 38 | + <div class="nav-item item1 item-child2" @click="links('/down')"> |
39 | <img class="icon" src="../../assets/nav/down.png" alt="" /> | 39 | <img class="icon" src="../../assets/nav/down.png" alt="" /> |
40 | <p class="p1">软件下载</p> | 40 | <p class="p1">软件下载</p> |
41 | <p class="p2">设置参数,下载授课端软件。</p> | 41 | <p class="p2">设置参数,下载授课端软件。</p> |
42 | </div> | 42 | </div> |
43 | </li> | 43 | </li> |
44 | </ul> | 44 | </ul> |
45 | - <ul class="nav-list" v-if="type == '集团管理员'"> | ||
46 | - <li v-for="item in navList" :key="item.path" class="nav-item item4" @click="links(item.path)"> | 45 | + <ul class="nav-list" v-if="type == 'ROLE_JITUAN'"> |
46 | + <template v-for="item in navList"> | ||
47 | + <li v-if="item.path!='dataSync'" :key="item.path" class="nav-item item4" @click="links(item.path)"> | ||
47 | <img class="icon" :src="getImgs(item.path)" alt="" /> | 48 | <img class="icon" :src="getImgs(item.path)" alt="" /> |
48 | - <div class="text" v-if="item.path == 'setUpConglomerate'"> | 49 | + <div class="text" v-if="item.path == '/setUpConglomerate'"> |
49 | <p class="p1">学校管理</p> | 50 | <p class="p1">学校管理</p> |
50 | <p class="p2">管理3个区域,14个学校。</p> | 51 | <p class="p2">管理3个区域,14个学校。</p> |
51 | </div> | 52 | </div> |
52 | - <div class="text" v-else-if="item.path == 'setUpAccount'"> | 53 | + <div class="text" v-else-if="item.path == '/setUpAccount'"> |
53 | <p class="p1">账号管理</p> | 54 | <p class="p1">账号管理</p> |
54 | <p class="p2">共35个各层级管理员账号。</p> | 55 | <p class="p2">共35个各层级管理员账号。</p> |
55 | </div> | 56 | </div> |
56 | - <div class="text" v-else-if="item.path == 'device'"> | 57 | + <div class="text" v-else-if="item.path == '/device'"> |
57 | <p class="p1">设备状态</p> | 58 | <p class="p1">设备状态</p> |
58 | <p class="p2">管理14个基站,396套答题器设备。</p> | 59 | <p class="p2">管理14个基站,396套答题器设备。</p> |
59 | </div> | 60 | </div> |
60 | - <div class="text" v-else> | 61 | + <div class="text" v-else-if="item.path == '/analysis'"> |
61 | <p class="p1">使用分析</p> | 62 | <p class="p1">使用分析</p> |
62 | <p class="p2">按软件功能、题型统计使用频率。</p> | 63 | <p class="p2">按软件功能、题型统计使用频率。</p> |
63 | </div> | 64 | </div> |
64 | </li> | 65 | </li> |
66 | + </template> | ||
65 | </ul> | 67 | </ul> |
66 | - <ul class="nav-list" v-if="type == '班主任' || type == '任课老师' "> | ||
67 | - <li v-for="item in navList" :key="item.path" class="nav-item item4" @click="links(item.path)"> | 68 | + <ul class="nav-list" v-if="type == 'superAdmin' || type == '任课老师' "> |
69 | + <template v-for="item in navList"> | ||
70 | + <li v-if="item.path!='dataSync'" :key="item.path" class="nav-item item4" @click="links(item.path)"> | ||
68 | <img class="icon" :src="getImgs(item.path)" alt="" /> | 71 | <img class="icon" :src="getImgs(item.path)" alt="" /> |
69 | - <div class="text" v-if="item.path == 'examinationPaper'"> | 72 | + <div class="text" v-if="item.path == '/examinationPaper'"> |
70 | <p class="p1">备题组卷</p> | 73 | <p class="p1">备题组卷</p> |
71 | <p class="p2">管理32套答题卡。</p> | 74 | <p class="p2">管理32套答题卡。</p> |
72 | </div> | 75 | </div> |
73 | - <div class="text" v-else-if="item.path == 'portrait'"> | 76 | + <div class="text" v-else-if="item.path == '/portrait'"> |
74 | <p class="p1">学生画像</p> | 77 | <p class="p1">学生画像</p> |
75 | <p class="p2">共分析532名学生成绩。</p> | 78 | <p class="p2">共分析532名学生成绩。</p> |
76 | </div> | 79 | </div> |
77 | - <div class="text" v-else-if="item.path == 'ask'"> | 80 | + <div class="text" v-else-if="item.path == '/ask'"> |
78 | <p class="p1">随堂问报表</p> | 81 | <p class="p1">随堂问报表</p> |
79 | <p class="p2">对41套随堂问答题记录分析。</p> | 82 | <p class="p2">对41套随堂问答题记录分析。</p> |
80 | </div> | 83 | </div> |
81 | - <div class="text" v-else> | 84 | + <div class="text" v-else-if="item.path == '/test'"> |
82 | <p class="p1">即时测报表</p> | 85 | <p class="p1">即时测报表</p> |
83 | <p class="p2">对28套即时测答题记录分析。</p> | 86 | <p class="p2">对28套即时测答题记录分析。</p> |
84 | </div> | 87 | </div> |
85 | </li> | 88 | </li> |
89 | + </template> | ||
86 | </ul> | 90 | </ul> |
87 | </div> | 91 | </div> |
88 | </template> | 92 | </template> |
@@ -92,54 +96,26 @@ export default { | @@ -92,54 +96,26 @@ export default { | ||
92 | name: "mainIndex", | 96 | name: "mainIndex", |
93 | data() { | 97 | data() { |
94 | return { | 98 | return { |
95 | - // type: "学校管理员", | ||
96 | - // type: "集团管理员", | ||
97 | - // type: "班主任", | ||
98 | - type: "任课老师", | ||
99 | - navList: [ | ||
100 | - // { | ||
101 | - // name: "学校管理", | ||
102 | - // path: "setUpConglomerate", | ||
103 | - // }, | ||
104 | - // { | ||
105 | - // name: "账号管理", | ||
106 | - // path: "setUpAccount", | ||
107 | - // }, | ||
108 | - // { | ||
109 | - // name: "设备状态", | ||
110 | - // path: "device", | ||
111 | - // }, | ||
112 | - // { | ||
113 | - // name: "使用分析", | ||
114 | - // path: "analysis", | ||
115 | - // }, | ||
116 | - { | ||
117 | - name: "备题组卷", | ||
118 | - path: "examinationPaper", | ||
119 | - }, | ||
120 | - { | ||
121 | - name: "学生画像", | ||
122 | - path: "portrait", | ||
123 | - }, | ||
124 | - { | ||
125 | - name: "随堂问报表", | ||
126 | - path: "ask", | ||
127 | - }, | ||
128 | - { | ||
129 | - name: "即时测报表", | ||
130 | - path: "test", | ||
131 | - }, | ||
132 | - ], | 99 | + type: "", |
100 | + navList: [], | ||
133 | }; | 101 | }; |
134 | }, | 102 | }, |
135 | - mounted() {}, | 103 | + created() { |
104 | + this.type = this.$store.getters.info.permissions[0].role | ||
105 | + this.navList = this.$store.getters.addRouters.map(item=>{ | ||
106 | + return { | ||
107 | + name:item.name, | ||
108 | + path:item.children[0].path, | ||
109 | + } | ||
110 | + }) | ||
111 | + }, | ||
136 | methods: { | 112 | methods: { |
137 | getImgs(path) { | 113 | getImgs(path) { |
138 | - return require(`@/assets/nav/${path}.png`) | 114 | + return require(`@/assets/nav${path}.png`) |
139 | }, | 115 | }, |
140 | links(path) { | 116 | links(path) { |
141 | this.$router.push({ | 117 | this.$router.push({ |
142 | - path: `/${path}`, | 118 | + path: path, |
143 | }); | 119 | }); |
144 | }, | 120 | }, |
145 | }, | 121 | }, |
src/views/layout/aside/aside.vue
1 | <template> | 1 | <template> |
2 | - <div> | 2 | + <div class="aside-box"> |
3 | <el-aside id="asideNav"> | 3 | <el-aside id="asideNav"> |
4 | <div class="logo-name"> | 4 | <div class="logo-name"> |
5 | <img | 5 | <img |
@@ -10,7 +10,7 @@ | @@ -10,7 +10,7 @@ | ||
10 | /> | 10 | /> |
11 | <template v-else> | 11 | <template v-else> |
12 | <img class="logo" src="../../../assets/images/logo.png" alt="" /> | 12 | <img class="logo" src="../../../assets/images/logo.png" alt="" /> |
13 | - <p>中天易教</p> | 13 | + <p class="ellipsis">中天易教中天易教中天易教</p> |
14 | </template> | 14 | </template> |
15 | </div> | 15 | </div> |
16 | <el-menu | 16 | <el-menu |
@@ -116,7 +116,9 @@ $right: right; | @@ -116,7 +116,9 @@ $right: right; | ||
116 | #{$side}-#{$prop}: $value; | 116 | #{$side}-#{$prop}: $value; |
117 | } | 117 | } |
118 | } | 118 | } |
119 | - | 119 | +.aside-box{ |
120 | + max-width:200px; | ||
121 | +} | ||
120 | #asideNav { | 122 | #asideNav { |
121 | width: auto !important; | 123 | width: auto !important; |
122 | display: flex; | 124 | display: flex; |
@@ -135,7 +137,8 @@ $right: right; | @@ -135,7 +137,8 @@ $right: right; | ||
135 | height: 24px; | 137 | height: 24px; |
136 | margin-right: 10px; | 138 | margin-right: 10px; |
137 | } | 139 | } |
138 | - p { | 140 | + .ellipsis { |
141 | + overflow: hidden; | ||
139 | line-height: 50px; | 142 | line-height: 50px; |
140 | text-align: center; | 143 | text-align: center; |
141 | font-size: 16px; | 144 | font-size: 16px; |
src/views/layout/layout.vue
@@ -38,13 +38,16 @@ export default { | @@ -38,13 +38,16 @@ export default { | ||
38 | }; | 38 | }; |
39 | }, | 39 | }, |
40 | created() { | 40 | created() { |
41 | - this.code = getURLParams("code") || ""; | ||
42 | - if (this.code) { | ||
43 | - localStorage.setItem("code",this.code) | ||
44 | - this._LoginCheck(); | ||
45 | - } | 41 | + this.initRouter(); |
46 | }, | 42 | }, |
47 | methods: { | 43 | methods: { |
44 | + initRouter() { | ||
45 | + this.code = getURLParams("code") || this.$store.getters.code; | ||
46 | + if (this.code) { | ||
47 | + this.$store.commit("setCode", this.code); | ||
48 | + this._LoginCheck(); | ||
49 | + } | ||
50 | + }, | ||
48 | async _LoginCheck() { | 51 | async _LoginCheck() { |
49 | let params = {}; | 52 | let params = {}; |
50 | if (this.code) { | 53 | if (this.code) { |
@@ -52,17 +55,46 @@ export default { | @@ -52,17 +55,46 @@ export default { | ||
52 | code: this.code, | 55 | code: this.code, |
53 | }; | 56 | }; |
54 | } | 57 | } |
55 | - const { data = {}, message, code } = await loginCheck(params); | ||
56 | - if (code === 0) { | ||
57 | - if (data) { | ||
58 | - this.school = data.schoolName; | ||
59 | - this.user.name = data.realName; | ||
60 | - this.user.id = data.id; | ||
61 | - this.user.tx = data.smallHeaderImgPath; | ||
62 | - } | ||
63 | - } else { | ||
64 | - this.$message.error(message); | ||
65 | - } | 58 | + // const { data = {}, message, code } = await loginCheck(params); |
59 | + // if (code === 0) { | ||
60 | + // if (data) { | ||
61 | + const userInfo = { | ||
62 | + permissions: [ | ||
63 | + { | ||
64 | + role: "superAdmin", | ||
65 | + roleName: "超级管理员", | ||
66 | + }, | ||
67 | + ], | ||
68 | + name: "李老师", | ||
69 | + // avatar: data.avatar ? data.avatar : "", | ||
70 | + // uid: data.id, | ||
71 | + authorityRouter: [ | ||
72 | + "examinationPaper", | ||
73 | + "examinationPaperAdd", | ||
74 | + "examinationPaperEdit", | ||
75 | + "examinationPaperRecycle", | ||
76 | + "ask", | ||
77 | + "askAnalysis", | ||
78 | + "test", | ||
79 | + "testAnalysis", | ||
80 | + ], | ||
81 | + }; | ||
82 | + await this.$store.commit("setInfo", { ...userInfo }); | ||
83 | + await this.$store.commit("setRouters", userInfo.authorityRouter); | ||
84 | + let newAddRouters = this.$store.getters.addRouters; | ||
85 | + newAddRouters.forEach((res) => { | ||
86 | + this.$router.addRoute(res); | ||
87 | + }); | ||
88 | + this.$router.addRoute({ | ||
89 | + path: "*", | ||
90 | + redirect: "/404", | ||
91 | + hidden: true, | ||
92 | + children: [], | ||
93 | + }); | ||
94 | + // } | ||
95 | + // } else { | ||
96 | + // this.$message.error(message); | ||
97 | + // } | ||
66 | }, | 98 | }, |
67 | }, | 99 | }, |
68 | }; | 100 | }; |
src/views/login/index.vue
@@ -90,8 +90,8 @@ export default { | @@ -90,8 +90,8 @@ export default { | ||
90 | disableClick: true, | 90 | disableClick: true, |
91 | passwordType: "password", | 91 | passwordType: "password", |
92 | loginForm: { | 92 | loginForm: { |
93 | - username: "admin", | ||
94 | - password: "123456", | 93 | + username: "15911715665", |
94 | + password: "Csiy88888", | ||
95 | }, | 95 | }, |
96 | loginRules: { | 96 | loginRules: { |
97 | username: [ | 97 | username: [ |
vue.config.js
@@ -12,7 +12,7 @@ module.exports = { | @@ -12,7 +12,7 @@ module.exports = { | ||
12 | productionSourceMap: false, // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。 | 12 | productionSourceMap: false, // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。 |
13 | devServer: { | 13 | devServer: { |
14 | hot:true, | 14 | hot:true, |
15 | - port: 8080, // 端口 | 15 | + port: 8081, // 端口 |
16 | open: false, // 启动后打开浏览器 | 16 | open: false, // 启动后打开浏览器 |
17 | compress: true, | 17 | compress: true, |
18 | overlay: { | 18 | overlay: { |
@@ -20,13 +20,13 @@ module.exports = { | @@ -20,13 +20,13 @@ module.exports = { | ||
20 | warnings: false, | 20 | warnings: false, |
21 | errors: true, | 21 | errors: true, |
22 | }, | 22 | }, |
23 | - proxy: { | ||
24 | - "/": { | ||
25 | - target:"http://lead.xc.com:32269", | ||
26 | - changeOrigin: true, | ||
27 | - ws:true, | ||
28 | - }, | ||
29 | - }, | 23 | + // proxy: { |
24 | + // "/": { | ||
25 | + // target:"http://192.168.3.29:8080", | ||
26 | + // changeOrigin: true, | ||
27 | + // ws:true, | ||
28 | + // }, | ||
29 | + // }, | ||
30 | disableHostCheck: true | 30 | disableHostCheck: true |
31 | }, | 31 | }, |
32 | css: { | 32 | css: { |