Commit b769660cd6986ed5d519128a4db3ba2f3445f401

Authored by 梁保满
1 parent 13b58a42

备课组题细节调整,随堂问列表页面开发完成

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 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 3 import answerSheet from "../urls/answerSheet"
4 4  
5 5 export default {
6 6 // 答题卡列表
7 7 fetchAnswerList(data) {
8   - return axios({
  8 + return service({
9 9 url: answerSheet.answerList,
10 10 method: 'POST',
11 11 data
... ... @@ -13,7 +13,7 @@ export default {
13 13 },
14 14 // 测验类型
15 15 fetchTypeNames(data) {
16   - return axios({
  16 + return service({
17 17 url: answerSheet.typeNames,
18 18 method: 'POST',
19 19 data
... ... @@ -21,7 +21,7 @@ export default {
21 21 },
22 22 // 班级列表
23 23 fetchClassList(data) {
24   - return axios({
  24 + return service({
25 25 url: answerSheet.classList,
26 26 method: 'POST',
27 27 data
... ... @@ -29,7 +29,7 @@ export default {
29 29 },
30 30 // 科目列表
31 31 fetchSubjectList(data) {
32   - return axios({
  32 + return service({
33 33 url: answerSheet.subjectList,
34 34 method: 'POST',
35 35 data
... ... @@ -37,7 +37,7 @@ export default {
37 37 },
38 38 // 年级列表
39 39 fetchGradeList(data) {
40   - return axios({
  40 + return service({
41 41 url: answerSheet.gradeList,
42 42 method: 'POST',
43 43 data
... ... @@ -45,7 +45,7 @@ export default {
45 45 },
46 46 // 添加测验类型
47 47 addAnswerTypeName(data) {
48   - return axios({
  48 + return service({
49 49 url: answerSheet.addAnswerTypeName,
50 50 method: 'POST',
51 51 data
... ... @@ -53,7 +53,7 @@ export default {
53 53 },
54 54 // 保存答题卡
55 55 saveAnswerSheet(data) {
56   - return axios({
  56 + return service({
57 57 url: answerSheet.saveAnswerSheet,
58 58 method: 'POST',
59 59 data
... ... @@ -61,7 +61,7 @@ export default {
61 61 },
62 62 // 删除答题卡
63 63 removeAnswerSheet(data) {
64   - return axios({
  64 + return service({
65 65 url: answerSheet.removeAnswerSheet,
66 66 method: 'POST',
67 67 data
... ... @@ -69,7 +69,7 @@ export default {
69 69 },
70 70 // 恢复答题卡
71 71 useAnswerSheet(data) {
72   - return axios({
  72 + return service({
73 73 url: answerSheet.useAnswerSheet,
74 74 method: 'POST',
75 75 data
... ... @@ -77,7 +77,7 @@ export default {
77 77 },
78 78 // 恢复答题卡
79 79 updateAnswerSheet(data) {
80   - return axios({
  80 + return service({
81 81 url: answerSheet.updateAnswerSheet,
82 82 method: 'POST',
83 83 data
... ...
src/api/apis/ask.js 0 → 100644
  1 +
  2 +import service from "../axios"
  3 +import askUrls from "../urls/login"
  4 +
  5 +export default {
  6 + // 账号密码登陆
  7 + fetchQuizList(data) {
  8 + return service({
  9 + url: askUrls.quizList,
  10 + method: 'POST',
  11 + data
  12 + })
  13 + },
  14 +}
... ...
src/api/apis/login.js
1 1  
2   -import axios from "../axios"
  2 +import service from "../axios"
3 3 import loginUrls from "../urls/login"
4 4  
5 5 export default {
6 6 // 账号密码登陆
7 7 fetchLogin(data) {
8   - return axios({
  8 + return service({
9 9 url: loginUrls.login,
10 10 method: 'POST',
11 11 data
... ...
src/api/apis/role.js
1 1  
2   -import axios from "../axios"
  2 +import service from "../axios"
3 3 import roleUrls from "../urls/role"
4 4  
5 5 export default {
6 6 // 获取权限列表
7 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 6 import store from "@/store"
7 7 import conf from "../config/index"; // 路径配置
8 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 14 // http request 拦截器
13   -axios.interceptors.request.use(config => {
  15 +service.interceptors.request.use(config => {
14 16 NProgress.start()
15 17 config.headers["Content-Type"] = "application/json;charset=UTF-8"
16 18  
... ... @@ -27,16 +29,16 @@ axios.interceptors.request.use(config => {
27 29 })
28 30  
29 31 // http response 拦截器
30   -axios.interceptors.response.use(
  32 +service.interceptors.response.use(
31 33 response => {
32   - const res = respones.data;
  34 + const res = response.data;
33 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 40 Cookies.set("access_token", response.data.message, { expires: 1 / 12 })
39   - // console.log(respones.status)
  41 + // console.log(response.status)
40 42 if (res.code == 999) {
41 43 if (!location.href.includes('localhost')) {
42 44 if (res.data) {
... ... @@ -88,4 +90,4 @@ axios.interceptors.response.use(
88 90 }
89 91 return Promise.reject(error.response) // 返回接口返回的错误信息
90 92 })
91   -export default axios
  93 +export default service
... ...
src/api/urls/ask.js 0 → 100644
  1 +
  2 +export default {
  3 + // 账号密码登陆
  4 + quizList: "/web/quizList",
  5 +}
... ...
src/api/urls/login.js
1 1  
2 2 export default {
3 3 // 账号密码登陆
4   - login: "/admin/user/login"
  4 + login: "/web/login",
  5 + ssoLogin: "/sso/login"
5 6 }
... ...
src/assets/css/index.scss
... ... @@ -3,65 +3,113 @@
3 3 display: flex;
4 4 justify-content: space-between;
5 5 align-items: center;
  6 +
6 7 .btn-box {
7 8 display: flex;
8 9 }
  10 +
9 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 22 .el-input__inner {
39 23 border-radius: 20px;
40   - border: none;
41   - height: 34px;
  24 + border: 1px solid #e2e2e2;
  25 + height: 36px;
42 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 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 14  
15 15  
16 16 import "nprogress/nprogress.css"
17   -import "element-ui/lib/theme-chalk/index.css"
18 17 import "font-awesome/css/font-awesome.css"
  18 +import "element-ui/lib/theme-chalk/index.css"
19 19 import "@/router/permission"
20 20 import "@/assets/css/base.css"
21 21 import "@/assets/css/index.scss"
... ...
src/router/index.js
... ... @@ -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 332 export default new Router({
... ...
src/router/permission.js
1 1 import NProgress from "nprogress"
2 2 import router from "./index"
3 3 import store from "../store"
4   -import {addrouters} from "./index"
5 4  
6 5 // 获取角色信息,根据用户权限动态加载路由
7 6 router.beforeEach((to, from, next) => {
8 7 NProgress.start()
9 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 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 86 router.afterEach(() => {
50 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 4 import layoutStore from "./modules/layout/index"
5 5 import { defaultRouter } from "@/router/index"
6 6 import { encryptLoginPassword } from "@/utils";
7   -import { b64DecodeUnicode } from "@/utils";
8 7  
9 8 import request from "@/api/index"
10 9 import router from "@/router/index"
11   -import {addrouters} from "@/router/index"
  10 +import { addrouters } from "@/router/index"
12 11 Vue.use(Vuex)
13 12  
14 13 const store = new Vuex.Store({
15 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 22 mutations: {
23 23 setToken(state, token) {
24 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 30 setInfo(state, data) {
28 31 state.info = {
... ... @@ -33,58 +36,62 @@ const store = new Vuex.Store({
33 36 avatar: data.avatar ? data.avatar : "",
34 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 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 53 state.tokenSources.set(data[0], data[1])
45   - }else{
  54 + } else {
46 55 state.tokenSources = new Map()
47 56 }
48 57 },
49   - delTokenSources(state,data){
  58 + delTokenSources(state, data) {
50 59 state.tokenSources.delete(data)
51 60 },
52 61 },
53 62 actions: {
54   - Login({ state,commit }, params) {
55   - let loginForm={}
  63 + Login({ state, commit }, params) {
  64 + let loginForm = {}
56 65 loginForm.username = params.username;
57 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 95 // request.fetchLogin(that.loginForm).then(res => {
89 96 // if (res.status == 200) {
90 97 commit("setToken", "xxxx")
... ... @@ -98,13 +105,39 @@ const store = new Vuex.Store({
98 105 name: "李老师",
99 106 // avatar: data.avatar ? data.avatar : "",
100 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 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 145 getters: {
113 146 addRouters: state => state.addRouters,
114 147 token: state => state.token,
  148 + code: state => state.csCode,
115 149 info: state => state.info,
116 150 routers: state => state.routers,
117 151 logoShow: state => state.layoutStore.logoShow,
... ...
src/utils/index.js
... ... @@ -9,7 +9,7 @@ const encryptIV = "D076D35C"
9 9 * @param data: 待加密数据
10 10 * @returns 加密结果
11 11 */
12   -export function encryptLoginPassword(data){
  12 +export function encryptLoginPassword(data) {
13 13 const secret = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjh2ei17z5k2r4VzbqoSCE6RmYzWySJTgVQYulgfVM+vqcDoUE4cFB4XCFA2lHWjjpsuJP1EtwKlvUgxo5okr3x/a88o8eERxBynnVQZbEYpKteW5aqSEb/g1yPLWnKV88b/ED445ITYbZZuInRo5lkCvd6QEjL6d2Fch6mEo5awYXC4/S4BJf9YlYRhGzR7wpiXCLvyBHQ4iSIIDNpmrPBPQzGP0rx09aDu54kz/42CR6SX2OqXSi4ZoieqkPFl/iuX4RoD/NKKR+haDn1UzoD3k1WzHSTBFFs27rxRpxfBUZzfXQeskgKyw/Slcl3jUFizczsY4CLgTRrfey48Q6QIDAQAB';
14 14 // 新建JSEncrypt对象
15 15 let encryptor = new JSEncrypt();
... ... @@ -25,7 +25,7 @@ export function encryptLoginPassword(data){
25 25 * @param data: 待加密数据
26 26 * @returns 加密结果
27 27 */
28   -export function encryptData(secret, data){
  28 +export function encryptData(secret, data) {
29 29 // 新建JSEncrypt对象
30 30 let encryptor = new JSEncrypt();
31 31 // 设置公钥
... ... @@ -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 39 let result = Array.isArray(obj) ? [] : {}
40 40 for (let key in obj) {
41 41 if (obj.hasOwnProperty(key)) {
... ... @@ -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 78 // randomFlag: Boolean 是否随机个数
79 79 // min 最少个数
80 80 // 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 98 if (key) arr = arr.map(d => d[key])
99 99 if (arr.length) {
100 100 let nameNum = arr.reduce((pre, cur) => {
... ... @@ -111,7 +111,7 @@ export function hasRepeatValue (arr, key = null) {
111 111 }
112 112  
113 113 // 获取cookie值
114   -export function getCookie (name, defaultValue) {
  114 +export function getCookie(name, defaultValue) {
115 115 const result = new RegExp("(^| )" + name + "=([^;]*)(;|$)")
116 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 120 /**
121 121 * base64转化unicode
122 122 */
123   - export function b64DecodeUnicode(str) {
  123 +export function b64DecodeUnicode(str) {
124 124 let uni;
125 125 try {
126 126 // atob 经过 base-64 编码的字符串进行解码
127 127 uni = decodeURIComponent(atob(str).split('').map(function (c) {
128 128 return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
129 129 }).join(''));
130   - } catch (e) {}
  130 + } catch (e) { }
131 131 return uni;
132 132 }
133 133  
134 134 // base64ToFile
135   -export function base64ToFile (base64Data, tempfilename, contentType) {
  135 +export function base64ToFile(base64Data, tempfilename, contentType) {
136 136 contentType = contentType || ""
137 137 var sliceSize = 1024
138 138 var byteCharacters = atob(base64Data)
... ... @@ -155,7 +155,7 @@ export function base64ToFile (base64Data, tempfilename, contentType) {
155 155 }
156 156  
157 157 // 将base64转换为文件
158   -export function dataURLtoFile (dataurl, filename) {
  158 +export function dataURLtoFile(dataurl, filename) {
159 159 var arr = dataurl.split(",")
160 160 var mime = arr[0].match(/:(.*?);/)[1]
161 161 var bstr = atob(arr[1])
... ... @@ -168,7 +168,7 @@ export function dataURLtoFile (dataurl, filename) {
168 168 }
169 169  
170 170 // 将图片转换为Base64
171   -export function getImgToBase64 (url, callback, outputFormat) {
  171 +export function getImgToBase64(url, callback, outputFormat) {
172 172 var canvas = document.createElement("canvas")
173 173 var ctx = canvas.getContext("2d")
174 174 var img = new Image()
... ... @@ -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 189 option = {
190 190 value: "id",
191 191 label: "name",
... ... @@ -206,7 +206,7 @@ export function loopOptions (list, option = {}) {
206 206 }
207 207  
208 208 // 通过Id获取级联数据id数组
209   -export function getTreeIds (tree, currentId, key = "id") {
  209 +export function getTreeIds(tree, currentId, key = "id") {
210 210 let parent = {}
211 211 let pid = {}
212 212 const loop = (list, level) => {
... ... @@ -233,16 +233,40 @@ export function getTreeIds (tree, currentId, key = "id") {
233 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 270 var myDate = new Date()
247 271 var lw = new Date(myDate - 1000 * 60 * 60 * 24 * dayNum)// 最后一个数字多少天前的意思
248 272 var lastY = lw.getFullYear()
... ... @@ -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 284 var myDate = new Date()
261 285 var lw = new Date(myDate - 1000 * 60 * 60 * 24 * dayNum)// 最后一个数字多少天前的意思
262 286 var lastY = lw.getFullYear()
... ... @@ -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 295 var b = dayNum.split(/\D/)
272 296 var date = new Date(b[0], b[1] - 1, b[2])
273 297 var time = date.getTime()
... ... @@ -297,4 +321,75 @@ export function getURLParams(variable) {
297 321 }
298 322 }
299 323 return variable ? data : obj
300   -}
301 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 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 15 </template>
4 16  
5 17 <script>
6   -export default {
7   -
8   -}
  18 +export default {};
9 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 44 </style>
14 45 \ No newline at end of file
... ...
src/views/ask/index.vue
1 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 448 </div>
6 449 </template>
7 450  
8 451 <script>
  452 +import { formatDate, deepClone,checkAnswer } from "utils";
9 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 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 970 </style>
17 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 191 \ No newline at end of file
... ...
src/views/examinationPaper/edit.vue
... ... @@ -26,6 +26,7 @@
26 26 <ul class="questions-ul">
27 27 <li class="sub-questions">
28 28 <div class="qs-num">题号</div>
  29 + <div class="qs-type">题型</div>
29 30 <div class="qs-score">分数</div>
30 31 <div class="qs-options qs-options2">选项设置</div>
31 32 </li>
... ... @@ -245,7 +246,7 @@ export default {
245 246 font-size: 20px;
246 247 color: #333;
247 248 font-weight: 700;
248   - padding: 20px 0 0 0;
  249 + padding-bottom: 20px;
249 250 .totals {
250 251 font-size: 16px;
251 252 color: #888;
... ... @@ -275,25 +276,7 @@ export default {
275 276 .el-input-number {
276 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 280 .questions-ul {
298 281 border-left: 1px solid #e2e2e2;
299 282 border-top: 1px solid #e2e2e2;
... ...
src/views/examinationPaper/index.vue
... ... @@ -19,20 +19,20 @@
19 19  
20 20 <div class="answer-header">
21 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 36 <el-select
37 37 class="sel"
38 38 v-model="query.subjectId"
... ... @@ -134,10 +134,9 @@
134 134 icon="el-icon-more"
135 135 ></el-button>
136 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 140 </el-dropdown-menu>
142 141 </el-dropdown>
143 142 </div>
... ... @@ -170,9 +169,40 @@ export default {
170 169 name: "examinationPaper",
171 170 data() {
172 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 203 dialogVisible: false,
174 204 query: {
175   - clazzId: "2003",
  205 + gradeClass: [],
176 206 subjectId: "0",
177 207 typeName: "周测",
178 208 title: "",
... ... @@ -202,9 +232,9 @@ export default {
202 232 date: "2022-11-04 18:09:49",
203 233 share: 1,
204 234 score: 100,
205   - gradeName:"二年级",
206   - subjectId:1,
207   - examsDuration:4800,
  235 + gradeName: "二年级",
  236 + subjectId: 1,
  237 + examsDuration: 4800,
208 238 questionList: [
209 239 {
210 240 questionTitle: "f",
... ... @@ -234,9 +264,9 @@ export default {
234 264 date: "2022-11-04 18:09:49",
235 265 share: 1,
236 266 score: 100,
237   - gradeName:"二年级",
238   - subjectId:1,
239   - examsDuration:3000,
  267 + gradeName: "二年级",
  268 + subjectId: 1,
  269 + examsDuration: 3000,
240 270 questionList: [
241 271 {
242 272 questionTitle: "f",
... ... @@ -287,38 +317,22 @@ export default {
287 317 const that = this;
288 318 switch (value) {
289 319 case 1:
290   - //授课端同步
291   - that.syncMeg(item);
292   - break;
293   - case 2:
294 320 //修改分享范围
295 321 that.shareForm.id = item.id;
296 322 that.shareForm.grade = item.grade;
297 323 that.shareForm.share = item.share || 1;
298 324 that.dialogVisible = true;
299 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 329 break;
304   - case 4:
  330 + case 3:
305 331 //归档
306 332 that.recovery(item);
307 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 336 async saveShare() {
323 337 //修改分享范围
324 338 // const { data, code, message } = await this.$request.fetchAnswerList({
... ... @@ -347,12 +361,12 @@ export default {
347 361 // this.$message.error(message);
348 362 // }
349 363 },
350   -
351   - async changClazz() {
  364 + async changeGrade() {
352 365 //切换班级
353 366 await this._QuerySubjectList();
354 367 this._QueryData();
355 368 },
  369 + async changClazz() {},
356 370 // 查找答题卡类型
357 371 async _QueryTypeList() {
358 372 const { data, code, message } = await this.$request.fetchTypeNames();
... ... @@ -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 561 .dialog-footer {
538 562 text-align: center;
539 563 :deep(.el-button) {
... ...
src/views/examinationPaper/recycle.vue
... ... @@ -7,50 +7,51 @@
7 7 </back-box>
8 8 <div class="answer-header">
9 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 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 24 <el-select
25 25 class="sel"
26   - v-model="query.type"
27   - placeholder="选择类型"
  26 + v-model="query.subjectId"
  27 + placeholder="选择科目"
28 28 @change="_QueryData()"
29 29 >
30 30 <el-option label="全部" value=""></el-option>
31 31 <el-option
32   - v-for="item in typeList"
  32 + v-for="item in subjectList"
33 33 :key="item.value"
34 34 :label="item.label"
35 35 :value="item.value"
36   - >{{ item.label }}
  36 + >
37 37 </el-option>
38 38 </el-select>
39 39 <el-select
40 40 class="sel"
41   - v-model="query.subjectId"
42   - placeholder="选择科目"
  41 + v-model="query.type"
  42 + placeholder="选择类型"
43 43 @change="_QueryData()"
44 44 >
45 45 <el-option label="全部" value=""></el-option>
46 46 <el-option
47   - v-for="item in subjectList"
  47 + v-for="item in typeList"
48 48 :key="item.value"
49 49 :label="item.label"
50 50 :value="item.value"
51   - >
  51 + >{{ item.label }}
52 52 </el-option>
53 53 </el-select>
  54 +
54 55 <el-input
55 56 placeholder="输入试卷名称"
56 57 v-model="query.title"
... ... @@ -89,7 +90,7 @@
89 90 </p>
90 91 </div>
91 92 <div class="btn-box">
92   - <el-tooltip effect="dark" content="使用" placement="bottom">
  93 + <el-tooltip effect="dark" content="恢复" placement="bottom">
93 94 <el-button
94 95 class="edit"
95 96 type="info"
... ... @@ -119,16 +120,47 @@
119 120 export default {
120 121 data() {
121 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 154 query: {
123   - gradeName: "二年级",
  155 + gradeClass: [],
124 156 type: "",
125 157 subjectId: "",
126 158 title: "",
127 159 },
128 160 gradeList: ["二年级"],
129 161 typeList: [
130   - { label: "随堂问", value: 1 },
131   - { label: "即使测", value: 2 },
  162 + { label: "周测", value: 1 },
  163 + { label: "月测", value: 2 },
132 164 ],
133 165 subjectList: [],
134 166 tableData: [
... ... @@ -165,9 +197,9 @@ export default {
165 197 //删除答题卡
166 198 // const { data, code, message } = await this.$request.useAnswerSheet();
167 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 203 // } else {
172 204 // this.$message.error(message);
173 205 // }
... ... @@ -176,9 +208,9 @@ export default {
176 208 //删除答题卡
177 209 // const { data, code, message } = await this.$request.removeAnswerSheet();
178 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 214 // } else {
183 215 // this.$message.error(message);
184 216 // }
... ... @@ -211,10 +243,19 @@ export default {
211 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 255 async changeGrade() {
215   - this._QueryData();
216   - this._GradeList();
217   - this._QuerySubjectList();
  256 + // this._QueryData();
  257 + // this._GradeList();
  258 + // this._QuerySubjectList();
218 259 },
219 260 async _GradeList() {
220 261 //查询年级列表
... ... @@ -257,6 +298,9 @@ export default {
257 298 .sel {
258 299 min-width: 160px;
259 300 }
  301 + :deep(.el-cascader__tags) {
  302 + flex-wrap: nowrap;
  303 + }
260 304 }
261 305 }
262 306 .content {
... ...
src/views/index/mainIndex.vue
1 1 <template>
2 2 <div class="container">
3 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 5 <img class="icon" src="../../assets/nav/setUpAccount.png" alt="" />
6 6 <div class="text">
7 7 <p class="p1">账号管理</p>
8 8 <p class="p2">管理32个任课教师,14个班主任,3个备课组长账号信息。</p>
9 9 </div>
10 10 </li>
11   - <li class="nav-item item1" @click="links('setUpSchool')">
  11 + <li class="nav-item item1" @click="links('/setUpSchool')">
12 12 <img class="icon" src="../../assets/nav/setUpSchool.png" alt="" />
13 13 <div class="text">
14 14 <p class="p1">学校管理</p>
15 15 <p class="p2">管理6个年级,3个班级,397名学生信息。</p>
16 16 </div>
17 17 </li>
18   - <li class="nav-item item2" @click="links('device')">
  18 + <li class="nav-item item2" @click="links('/device')">
19 19 <img class="icon" src="../../assets/nav/device.png" alt="" />
20 20 <div class="text">
21 21 <p class="p1">设备状态</p>
... ... @@ -23,66 +23,70 @@
23 23 </div>
24 24 </li>
25 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 27 <img class="icon" src="../../assets/nav/analysis.png" alt="" />
28 28 <div class="text">
29 29 <p class="p1">使用分析</p>
30 30 <p class="p2">按班级、科目等维度分析设备使用频率。</p>
31 31 </div>
32 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 34 <img class="icon" src="../../assets/nav/card.png" alt="" />
35 35 <p class="p1">发卡补卡</p>
36 36 <p class="p2">为学生办理发卡、补卡业务。</p>
37 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 39 <img class="icon" src="../../assets/nav/down.png" alt="" />
40 40 <p class="p1">软件下载</p>
41 41 <p class="p2">设置参数,下载授课端软件。</p>
42 42 </div>
43 43 </li>
44 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 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 50 <p class="p1">学校管理</p>
50 51 <p class="p2">管理3个区域,14个学校。</p>
51 52 </div>
52   - <div class="text" v-else-if="item.path == 'setUpAccount'">
  53 + <div class="text" v-else-if="item.path == '/setUpAccount'">
53 54 <p class="p1">账号管理</p>
54 55 <p class="p2">共35个各层级管理员账号。</p>
55 56 </div>
56   - <div class="text" v-else-if="item.path == 'device'">
  57 + <div class="text" v-else-if="item.path == '/device'">
57 58 <p class="p1">设备状态</p>
58 59 <p class="p2">管理14个基站,396套答题器设备。</p>
59 60 </div>
60   - <div class="text" v-else>
  61 + <div class="text" v-else-if="item.path == '/analysis'">
61 62 <p class="p1">使用分析</p>
62 63 <p class="p2">按软件功能、题型统计使用频率。</p>
63 64 </div>
64 65 </li>
  66 + </template>
65 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 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 73 <p class="p1">备题组卷</p>
71 74 <p class="p2">管理32套答题卡。</p>
72 75 </div>
73   - <div class="text" v-else-if="item.path == 'portrait'">
  76 + <div class="text" v-else-if="item.path == '/portrait'">
74 77 <p class="p1">学生画像</p>
75 78 <p class="p2">共分析532名学生成绩。</p>
76 79 </div>
77   - <div class="text" v-else-if="item.path == 'ask'">
  80 + <div class="text" v-else-if="item.path == '/ask'">
78 81 <p class="p1">随堂问报表</p>
79 82 <p class="p2">对41套随堂问答题记录分析。</p>
80 83 </div>
81   - <div class="text" v-else>
  84 + <div class="text" v-else-if="item.path == '/test'">
82 85 <p class="p1">即时测报表</p>
83 86 <p class="p2">对28套即时测答题记录分析。</p>
84 87 </div>
85 88 </li>
  89 + </template>
86 90 </ul>
87 91 </div>
88 92 </template>
... ... @@ -92,54 +96,26 @@ export default {
92 96 name: "mainIndex",
93 97 data() {
94 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 112 methods: {
137 113 getImgs(path) {
138   - return require(`@/assets/nav/${path}.png`)
  114 + return require(`@/assets/nav${path}.png`)
139 115 },
140 116 links(path) {
141 117 this.$router.push({
142   - path: `/${path}`,
  118 + path: path,
143 119 });
144 120 },
145 121 },
... ...
src/views/layout/aside/aside.vue
1 1 <template>
2   - <div>
  2 + <div class="aside-box">
3 3 <el-aside id="asideNav">
4 4 <div class="logo-name">
5 5 <img
... ... @@ -10,7 +10,7 @@
10 10 />
11 11 <template v-else>
12 12 <img class="logo" src="../../../assets/images/logo.png" alt="" />
13   - <p>中天易教</p>
  13 + <p class="ellipsis">中天易教中天易教中天易教</p>
14 14 </template>
15 15 </div>
16 16 <el-menu
... ... @@ -116,7 +116,9 @@ $right: right;
116 116 #{$side}-#{$prop}: $value;
117 117 }
118 118 }
119   -
  119 +.aside-box{
  120 + max-width:200px;
  121 +}
120 122 #asideNav {
121 123 width: auto !important;
122 124 display: flex;
... ... @@ -135,7 +137,8 @@ $right: right;
135 137 height: 24px;
136 138 margin-right: 10px;
137 139 }
138   - p {
  140 + .ellipsis {
  141 + overflow: hidden;
139 142 line-height: 50px;
140 143 text-align: center;
141 144 font-size: 16px;
... ...
src/views/layout/layout.vue
... ... @@ -38,13 +38,16 @@ export default {
38 38 };
39 39 },
40 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 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 51 async _LoginCheck() {
49 52 let params = {};
50 53 if (this.code) {
... ... @@ -52,17 +55,46 @@ export default {
52 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 90 disableClick: true,
91 91 passwordType: "password",
92 92 loginForm: {
93   - username: "admin",
94   - password: "123456",
  93 + username: "15911715665",
  94 + password: "Csiy88888",
95 95 },
96 96 loginRules: {
97 97 username: [
... ...
vue.config.js
... ... @@ -12,7 +12,7 @@ module.exports = {
12 12 productionSourceMap: false, // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
13 13 devServer: {
14 14 hot:true,
15   - port: 8080, // 端口
  15 + port: 8081, // 端口
16 16 open: false, // 启动后打开浏览器
17 17 compress: true,
18 18 overlay: {
... ... @@ -20,13 +20,13 @@ module.exports = {
20 20 warnings: false,
21 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 30 disableHostCheck: true
31 31 },
32 32 css: {
... ...