Commit 13b58a42000676c072cf9711491b5e6230dcb345

Authored by 梁保满
1 parent 65f592b6

备题组卷部分前端页面基本完成

... ... @@ -136,13 +136,13 @@
136 136 {
137 137 path: "/",
138 138 iconCls: "fa fa-cog",
139   - name: '学校管理',
  139 + name: '学校设置',
140 140 component: Layout,
141 141 children: [
142 142 {
143 143 path: "/setUpSchool",
144 144 iconCls: "fa fa-calculator",
145   - name: '学校管理',
  145 + name: '学校设置',
146 146 component: SetUpSchool,
147 147 children: []
148 148 },
... ... @@ -220,14 +220,14 @@
220 220 {
221 221 path: "/down",
222 222 iconCls: "fa fa-download", // 图标样式class
223   - name: "",
  223 + name: "发卡软件",
224 224 component: Down,
225 225 children: []
226 226 },
227 227 {
228 228 path: "/downClient",
229 229 iconCls: "", // 图标样式class
230   - name: "",
  230 + name: "授课端软件",
231 231 component: DownClient,
232 232 children: []
233 233 }
... ...
src/api/apis/answerSheet.js
... ... @@ -11,7 +11,7 @@ export default {
11 11 data
12 12 })
13 13 },
14   - // 答题卡列表
  14 + // 测验类型
15 15 fetchTypeNames(data) {
16 16 return axios({
17 17 url: answerSheet.typeNames,
... ... @@ -19,7 +19,7 @@ export default {
19 19 data
20 20 })
21 21 },
22   - // 答题卡列表
  22 + // 班级列表
23 23 fetchClassList(data) {
24 24 return axios({
25 25 url: answerSheet.classList,
... ... @@ -27,7 +27,7 @@ export default {
27 27 data
28 28 })
29 29 },
30   - // 答题卡列表
  30 + // 科目列表
31 31 fetchSubjectList(data) {
32 32 return axios({
33 33 url: answerSheet.subjectList,
... ... @@ -35,5 +35,53 @@ export default {
35 35 data
36 36 })
37 37 },
  38 + // 年级列表
  39 + fetchGradeList(data) {
  40 + return axios({
  41 + url: answerSheet.gradeList,
  42 + method: 'POST',
  43 + data
  44 + })
  45 + },
  46 + // 添加测验类型
  47 + addAnswerTypeName(data) {
  48 + return axios({
  49 + url: answerSheet.addAnswerTypeName,
  50 + method: 'POST',
  51 + data
  52 + })
  53 + },
  54 + // 保存答题卡
  55 + saveAnswerSheet(data) {
  56 + return axios({
  57 + url: answerSheet.saveAnswerSheet,
  58 + method: 'POST',
  59 + data
  60 + })
  61 + },
  62 + // 删除答题卡
  63 + removeAnswerSheet(data) {
  64 + return axios({
  65 + url: answerSheet.removeAnswerSheet,
  66 + method: 'POST',
  67 + data
  68 + })
  69 + },
  70 + // 恢复答题卡
  71 + useAnswerSheet(data) {
  72 + return axios({
  73 + url: answerSheet.useAnswerSheet,
  74 + method: 'POST',
  75 + data
  76 + })
  77 + },
  78 + // 恢复答题卡
  79 + updateAnswerSheet(data) {
  80 + return axios({
  81 + url: answerSheet.updateAnswerSheet,
  82 + method: 'POST',
  83 + data
  84 + })
  85 + },
38 86 }
39 87  
... ...
src/api/apis/login.js
... ... @@ -4,7 +4,11 @@ import loginUrls from "../urls/login"
4 4  
5 5 export default {
6 6 // 账号密码登陆
7   - fetchLogin (data) {
8   - return axios.post(loginUrls.login, data)
9   - }
  7 + fetchLogin(data) {
  8 + return axios({
  9 + url: loginUrls.login,
  10 + method: 'POST',
  11 + data
  12 + })
  13 + },
10 14 }
... ...
src/api/axios.js
... ... @@ -2,10 +2,12 @@ import axios from "axios"
2 2 import Cookies from "js-cookie"
3 3 import NProgress from "nprogress"
4 4 import { Message } from "element-ui"
5   -import config from "../config/index"; // 路径配置
  5 +import router from "@/router/index"
  6 +import store from "@/store"
  7 +import conf from "../config/index"; // 路径配置
6 8 // axios默认配置
7 9 axios.defaults.timeout = 1000000000 // 超时时间
8   -axios.defaults.baseURL = config.baseURL
  10 +axios.defaults.baseURL = conf.baseURL
9 11  
10 12 // http request 拦截器
11 13 axios.interceptors.request.use(config => {
... ... @@ -27,38 +29,62 @@ axios.interceptors.request.use(config => {
27 29 // http response 拦截器
28 30 axios.interceptors.response.use(
29 31 response => {
  32 + const res = respones.data;
30 33 NProgress.done()
31 34 if (respones.config.cancelToken) {
32 35 store.commit('delTokenSources', respones.config.cancelToken)
33 36 }
34   - if (response.data.code === 11000) {
  37 + if (respones.status == 200) {
35 38 Cookies.set("access_token", response.data.message, { expires: 1 / 12 })
36   - return Promise.resolve()
37   - } else if (response.data.code === 10000) { // 约定报错信息
38   - Message({
39   - message: response.data.message,
40   - type: "warning"
41   - })
42   - return Promise.reject(response)
43   - } else {
44   - return Promise.resolve(response)
  39 + // console.log(respones.status)
  40 + if (res.code == 999) {
  41 + if (!location.href.includes('localhost')) {
  42 + if (res.data) {
  43 + window.location.href = res.data
  44 + } else {
  45 + router.push({ path: '/login' })
  46 + if (res.message.includes('不存在')) {
  47 + Message({
  48 + message: res.message,
  49 + type: 'error',
  50 + duration: 3 * 1000
  51 + })
  52 + }
  53 + }
  54 + }
  55 + return
  56 + } else {
  57 + Cookies.set("access_token", response.data.message, { expires: 1 / 12 })
  58 + }
45 59 }
  60 + return Promise.resolve(response)
46 61 },
47 62 error => {
48   - if (error.response.status === 404) {
  63 + Message({
  64 + message: error.message,
  65 + type: 'error',
  66 + duration: 3 * 1000
  67 + })
  68 + if (error.response == undefined) {
  69 + return Promise.reject(error);
  70 + }
  71 + Message.closeAll()
  72 + const {
  73 + status
  74 + } = error.response
  75 + if (status === 403 || status === 401) {
49 76 Message({
50   - message: "请求地址出错",
51   - type: "warning"
  77 + message: "未登录或登录超时,即将跳转到登录页面",
  78 + type: 'error',
  79 + duration: 3 * 1000
52 80 })
53   - } else if (error.response.status === 401) {
54   - Message({
55   - message: error.response.data.message,
56   - type: "warning"
  81 + router.push({
  82 + path: '/login',
  83 + query: {
  84 + url: window.location.href
  85 + }
57 86 })
58   - Cookies.remove("access_token")
59   - setTimeout(() => {
60   - location.reload()
61   - }, 3000)
  87 + return
62 88 }
63 89 return Promise.reject(error.response) // 返回接口返回的错误信息
64 90 })
... ...
src/api/urls/answerSheet.js
1 1 export default {
2 2 // 答题卡列表
3 3 answerList: "/apis/answerList",
4   - // 答题卡类型
  4 + // 测验类型
5 5 typeNames: "/apis/typeNames",
  6 + // 查找年级
  7 + gradeList: "/apis/gradeList",
6 8 // 查找班级
7 9 classList: "/apis/classList",
8 10 // 查找科目
9 11 subjectList: "/apis/subjectList",
  12 + // 天假答题卡测验类型
  13 + addAnswerTypeName: "/apis/addAnswerTypeName",
  14 + // 保存答题卡
  15 + saveAnswerSheet: "/apis/saveAnswerSheet",
  16 + // 删除答题卡
  17 + removeAnswerSheet: "/apis/removeAnswerSheet",
  18 + // 恢复使用答题卡
  19 + useAnswerSheet: "/apis/useAnswerSheet",
  20 + // 更新答题卡
  21 + updateAnswerSheet: "/apis/updateAnswerSheet",
10 22 }
11 23 \ No newline at end of file
... ...
src/assets/css/base.css
... ... @@ -21,18 +21,25 @@ a {
21 21 }
22 22  
23 23 /* element-style */
24   -.el-button--default{
  24 +.el-button--default {
25 25 color: #667ffd;
26 26 border-color: #667ffd;
27 27 }
  28 +
28 29 .el-button--primary {
29 30 background-color: #667ffd;
30 31 border-color: #667ffd;
31 32 }
32   -.el-radio__input.is-checked+.el-radio__label{
  33 +
  34 +.el-radio__input.is-checked+.el-radio__label {
33 35 color: #667ffd;
34 36 }
35   -.el-radio__input.is-checked .el-radio__inner{
  37 +
  38 +.el-radio__input.is-checked .el-radio__inner {
36 39 border-color: #667ffd;
37   - background: #667ffd;
38   -}
39 40 \ No newline at end of file
  41 + background: #667ffd;
  42 +}
  43 +
  44 +.el-message-box .el-button--default {
  45 + color: #fff
  46 +}
... ...
src/assets/css/index.scss 0 → 100644
  1 +.answer-header {
  2 + padding: 16px 40px 12px 20px;
  3 + display: flex;
  4 + justify-content: space-between;
  5 + align-items: center;
  6 + .btn-box {
  7 + display: flex;
  8 + }
  9 + .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;
  38 + .el-input__inner {
  39 + border-radius: 20px;
  40 + border: none;
  41 + height: 34px;
  42 + line-height: 34px;
  43 + }
  44 + .el-input-group__append, .el-input-group__prepend {
  45 + border: none;
  46 + background: transparent;
  47 + }
  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;
  60 + }
  61 + &.active {
  62 + color: #667ffd;
  63 + }
  64 + }
  65 + }
  66 +}
  67 +}
0 68 \ No newline at end of file
... ...
src/main.js
... ... @@ -18,6 +18,7 @@ import "element-ui/lib/theme-chalk/index.css"
18 18 import "font-awesome/css/font-awesome.css"
19 19 import "@/router/permission"
20 20 import "@/assets/css/base.css"
  21 +import "@/assets/css/index.scss"
21 22  
22 23 Vue.config.productionTip = false
23 24 Vue.use(ElementUI)
... ...
src/router/index.js
... ... @@ -5,8 +5,29 @@ import Login from "@/views/login/index"
5 5 import Layout from "@/views/layout/layout"
6 6 import HomeMain from "@/views/index/mainIndex"
7 7  
  8 +
8 9 // 不是必须加载的组件使用懒加载
9 10 const NotFound = () => import("@/views/page404")
  11 +const ExaminationPaper = () => import("@/views/examinationPaper/index")
  12 +const ExaminationPaperAdd = () => import("@/views/examinationPaper/add")
  13 +const ExaminationPaperEdit = () => import("@/views/examinationPaper/edit")
  14 +const ExaminationPaperRecycle = () => import("@/views/examinationPaper/recycle")
  15 +const Ask = () => import("@/views/ask/index")
  16 +const AskAnalysis = () => import("@/views/ask/analysis")
  17 +const Test = () => import("@/views/test/index")
  18 +const TestAnalysis = () => import("@/views/test/analysis")
  19 +const DataSync = () => import("@/views/dataSync/index")
  20 +const Portrait = () => import("@/views/portrait/index")
  21 +const Card = () => import("@/views/card/index")
  22 +const Analysis = () => import("@/views/analysis/index")
  23 +const Device = () => import("@/views/device/index")
  24 +const Down = () => import("@/views/down/index")
  25 +const DownClient = () => import("@/views/down/client")
  26 +const SetUpAccount = () => import("@/views/setUp/account")
  27 +const SetUpConglomerate = () => import("@/views/setUp/conglomerate")
  28 +const SetUpSchool = () => import("@/views/setUp/school")
  29 +const SetUpStudent = () => import("@/views/setUp/student")
  30 +const SetUpTeacher = () => import("@/views/setUp/teacher")
10 31  
11 32 /**
12 33 * 重写路由的push方法
... ... @@ -55,7 +76,266 @@ let defaultRouter = [
55 76 }
56 77 ]
57 78  
  79 +let addrouters = [ //测试用,后续后端获取
  80 + {
  81 + path: "/examinationPaper",
  82 + iconCls: "fa fa-file-text", // 图标样式class
  83 + name: "备题组卷",
  84 + component: Layout,
  85 + alone: true,
  86 + children: [
  87 + {
  88 + path: "/examinationPaper",
  89 + iconCls: "fa fa-file-text", // 图标样式class
  90 + name: "",
  91 + component: ExaminationPaper,
  92 + children: []
  93 + },
  94 + {
  95 + path: "/examinationPaperAdd",
  96 + iconCls: "", // 图标样式class
  97 + name: "添加答题卡",
  98 + component: ExaminationPaperAdd,
  99 + children: []
  100 + },
  101 + {
  102 + path: "/examinationPaperEdit",
  103 + iconCls: "", // 图标样式class
  104 + name: "修改答题卡",
  105 + component: ExaminationPaperEdit,
  106 + children: []
  107 + },
  108 + {
  109 + path: "/examinationPaperRecycle",
  110 + iconCls: "", // 图标样式class
  111 + name: "已归档答题卡",
  112 + component: ExaminationPaperRecycle,
  113 + children: []
  114 + },
  115 + ]
  116 + },
  117 + {
  118 + path: "/ask",
  119 + iconCls: "fa fa-bar-chart", // 图标样式class
  120 + name: "随堂问报表",
  121 + component: Layout,
  122 + alone: true,
  123 + children: [
  124 + {
  125 + path: "/ask",
  126 + iconCls: "fa fa-bar-chart", // 图标样式class
  127 + name: "",
  128 + component: Ask,
  129 + children: []
  130 +
  131 + },
  132 + {
  133 + path: "/askAnalysis",
  134 + iconCls: "", // 图标样式class
  135 + name: "随堂问报表分析",
  136 + component: AskAnalysis,
  137 + children: []
  138 + }
  139 + ]
  140 + },
  141 + {
  142 + path: "/test",
  143 + iconCls: "fa fa-pie-chart", // 图标样式class
  144 + name: "即时测报表",
  145 + component: Layout,
  146 + alone: true,
  147 + children: [
  148 + {
  149 + path: "/test",
  150 + iconCls: "fa fa-pie-chart", // 图标样式class
  151 + name: "",
  152 + component: Test,
  153 + children: []
  154 + },
  155 + {
  156 + path: "/testAnalysis",
  157 + iconCls: "", // 图标样式class
  158 + name: "即时测报表分析",
  159 + component: TestAnalysis,
  160 + children: []
  161 + }
  162 +
  163 + ]
  164 + },
  165 + {
  166 + path: "/portrait",
  167 + iconCls: "fa fa-users", // 图标样式class
  168 + name: "学生画像",
  169 + component: Layout,
  170 + alone: true,
  171 + children: [
  172 + {
  173 + path: "/portrait",
  174 + iconCls: "fa fa-users", // 图标样式class
  175 + name: "",
  176 + component: Portrait,
  177 + children: []
  178 + }
  179 + ]
  180 + },
  181 +
  182 + {
  183 + path: "/setUpConglomerate",
  184 + iconCls: "fa fa-building", // 图标样式class
  185 + name: "学校管理",
  186 + component: Layout,
  187 + alone: true,
  188 + children: [
  189 + {
  190 + path: "/setUpConglomerate",
  191 + iconCls: "fa fa-building",
  192 + name: '集团管理',
  193 + component: SetUpConglomerate,
  194 + children: []
  195 + },
  196 + ]
  197 + },
  198 + {
  199 + path: "/setUpAccount",
  200 + iconCls: "fa fa-id-card-o", // 图标样式class
  201 + name: "账号管理",
  202 + component: Layout,
  203 + alone: true,
  204 + children: [
  205 + {
  206 + path: "/setUpAccount",
  207 + iconCls: "fa fa-id-card-o",
  208 + name: '',
  209 + component: SetUpAccount,
  210 + children: []
  211 + },
  212 + ]
  213 + },
  214 + {
  215 + path: "/",
  216 + iconCls: "fa fa-cog",
  217 + name: '学校设置',
  218 + component: Layout,
  219 + children: [
  220 + {
  221 + path: "/setUpSchool",
  222 + iconCls: "fa fa-calculator",
  223 + name: '学校设置',
  224 + component: SetUpSchool,
  225 + children: []
  226 + },
  227 + {
  228 + path: "/setUpTeacher",
  229 + iconCls: "fa fa-male",
  230 + name: '教师管理',
  231 + component: SetUpTeacher,
  232 + children: []
  233 + },
  234 + {
  235 + path: "/setUpStudent",
  236 + iconCls: "fa fa-mortar-board",
  237 + name: '学生管理',
  238 + component: SetUpStudent,
  239 + children: []
  240 + },
  241 + ]
  242 + },
  243 + {
  244 + path: "/card",
  245 + iconCls: "fa fa-id-card", // 图标样式class
  246 + name: "发卡记录",
  247 + component: Layout,
  248 + alone: true,
  249 + children: [
  250 + {
  251 + path: "/card",
  252 + iconCls: "fa fa-id-card", // 图标样式class
  253 + name: "",
  254 + component: Card,
  255 + children: []
  256 + }
  257 + ]
  258 + },
  259 + {
  260 + path: "/device",
  261 + iconCls: "fa fa-dashboard", // 图标样式class
  262 + name: "设备状态",
  263 + component: Layout,
  264 + alone: true,
  265 + children: [
  266 + {
  267 + path: "/device",
  268 + iconCls: "fa fa-dashboard", // 图标样式class
  269 + name: "",
  270 + component: Device,
  271 + children: []
  272 + }
  273 + ]
  274 + },
  275 + {
  276 + path: "/analysis",
  277 + iconCls: "fa fa-area-chart", // 图标样式class
  278 + name: "使用分析",
  279 + component: Layout,
  280 + alone: true,
  281 + children: [
  282 + {
  283 + path: "/analysis",
  284 + iconCls: "fa fa-area-chart", // 图标样式class
  285 + name: "",
  286 + component: Analysis,
  287 + children: []
  288 + }
  289 + ]
  290 + },
  291 + {
  292 + path: "/down",
  293 + iconCls: "fa fa-download", // 图标样式class
  294 + name: "软件下载",
  295 + component: Layout,
  296 + alone: true,
  297 + children: [
  298 + {
  299 + path: "/down",
  300 + iconCls: "fa fa-download", // 图标样式class
  301 + name: "发卡软件",
  302 + component: Down,
  303 + children: []
  304 + },
  305 + {
  306 + path: "/downClient",
  307 + iconCls: "", // 图标样式class
  308 + name: "授课端软件",
  309 + component: DownClient,
  310 + children: []
  311 + }
  312 + ]
  313 + },
  314 + {
  315 + path: "/dataSync",
  316 + iconCls: "fa fa-random", // 图标样式class
  317 + name: "数据同步",
  318 + component: Layout,
  319 + alone: true,
  320 + children: [
  321 + {
  322 + path: "/dataSync",
  323 + iconCls: "fa fa-random", // 图标样式class
  324 + name: "",
  325 + component: DataSync,
  326 + children: []
  327 + }
  328 + ]
  329 + },
  330 + {
  331 + path: "*",
  332 + redirect: "/404",
  333 + hidden: true,
  334 + children: []
  335 + }
  336 +]
  337 +
58 338 export default new Router({
59 339 routes: defaultRouter
60 340 })
61   -export {defaultRouter}
  341 +export {defaultRouter,addrouters}
... ...
src/router/permission.js
1 1 import NProgress from "nprogress"
2   -import en from "../i18n/lang/en"
3   -import Layout from "@/views/layout/layout"
4   -import CommerViews from "@/views/commerViews"
5 2 import router from "./index"
6 3 import store from "../store"
7   -// let routeName = en.routeName
8   -
9   -const ExaminationPaper = () => import("@/views/examinationPaper/index")
10   -const ExaminationPaperAdd = () => import("@/views/examinationPaper/add")
11   -const ExaminationPaperEdit = () => import("@/views/examinationPaper/edit")
12   -const ExaminationPaperRecycle = () => import("@/views/examinationPaper/recycle")
13   -const Ask = () => import("@/views/ask/index")
14   -const AskAnalysis = () => import("@/views/ask/analysis")
15   -const Test = () => import("@/views/test/index")
16   -const TestAnalysis = () => import("@/views/test/analysis")
17   -const DataSync = () => import("@/views/dataSync/index")
18   -const Portrait = () => import("@/views/portrait/index")
19   -const Card = () => import("@/views/card/index")
20   -const Analysis = () => import("@/views/analysis/index")
21   -const Device = () => import("@/views/device/index")
22   -const Down = () => import("@/views/down/index")
23   -const DownClient = () => import("@/views/down/client")
24   -const SetUpAccount = () => import("@/views/setUp/account")
25   -const SetUpConglomerate = () => import("@/views/setUp/conglomerate")
26   -const SetUpSchool = () => import("@/views/setUp/school")
27   -const SetUpStudent = () => import("@/views/setUp/student")
28   -const SetUpTeacher = () => import("@/views/setUp/teacher")
29   -let addrouters = [ //测试用,后续后端获取
30   - {
31   - path: "/examinationPaper",
32   - iconCls: "fa fa-file-text", // 图标样式class
33   - name: "备题组卷",
34   - component: Layout,
35   - alone: true,
36   - children: [
37   - {
38   - path: "/examinationPaper",
39   - iconCls: "fa fa-file-text", // 图标样式class
40   - name: "",
41   - component: ExaminationPaper,
42   - children: []
43   - },
44   - {
45   - path: "/examinationPaperAdd",
46   - iconCls: "", // 图标样式class
47   - name: "添加答题卡",
48   - component: ExaminationPaperAdd,
49   - children: []
50   - },
51   - {
52   - path: "/examinationPaperEdit",
53   - iconCls: "", // 图标样式class
54   - name: "修改答题卡",
55   - component: ExaminationPaperEdit,
56   - children: []
57   - },
58   - {
59   - path: "/examinationPaperRecycle",
60   - iconCls: "", // 图标样式class
61   - name: "已归档答题卡",
62   - component: ExaminationPaperRecycle,
63   - children: []
64   - },
65   - ]
66   - },
67   - {
68   - path: "/ask",
69   - iconCls: "fa fa-bar-chart", // 图标样式class
70   - name: "随堂问报表",
71   - component: Layout,
72   - alone: true,
73   - children: [
74   - {
75   - path: "/ask",
76   - iconCls: "fa fa-bar-chart", // 图标样式class
77   - name: "",
78   - component: Ask,
79   - children: []
80   -
81   - },
82   - {
83   - path: "/askAnalysis",
84   - iconCls: "", // 图标样式class
85   - name: "随堂问报表分析",
86   - component: AskAnalysis,
87   - children: []
88   - }
89   - ]
90   - },
91   - {
92   - path: "/test",
93   - iconCls: "fa fa-pie-chart", // 图标样式class
94   - name: "即时测报表",
95   - component: Layout,
96   - alone: true,
97   - children: [
98   - {
99   - path: "/test",
100   - iconCls: "fa fa-pie-chart", // 图标样式class
101   - name: "",
102   - component: Test,
103   - children: []
104   - },
105   - {
106   - path: "/testAnalysis",
107   - iconCls: "", // 图标样式class
108   - name: "即时测报表分析",
109   - component: TestAnalysis,
110   - children: []
111   - }
112   -
113   - ]
114   - },
115   - {
116   - path: "/portrait",
117   - iconCls: "fa fa-users", // 图标样式class
118   - name: "学生画像",
119   - component: Layout,
120   - alone: true,
121   - children: [
122   - {
123   - path: "/portrait",
124   - iconCls: "fa fa-users", // 图标样式class
125   - name: "",
126   - component: Portrait,
127   - children: []
128   - }
129   - ]
130   - },
131   -
132   - {
133   - path: "/setUpConglomerate",
134   - iconCls: "fa fa-building", // 图标样式class
135   - name: "学校管理",
136   - component: Layout,
137   - alone: true,
138   - children: [
139   - {
140   - path: "/setUpConglomerate",
141   - iconCls: "fa fa-building",
142   - name: '集团管理',
143   - component: SetUpConglomerate,
144   - children: []
145   - },
146   - ]
147   - },
148   - {
149   - path: "/setUpAccount",
150   - iconCls: "fa fa-id-card-o", // 图标样式class
151   - name: "账号管理",
152   - component: Layout,
153   - alone: true,
154   - children: [
155   - {
156   - path: "/setUpAccount",
157   - iconCls: "fa fa-id-card-o",
158   - name: '',
159   - component: SetUpAccount,
160   - children: []
161   - },
162   - ]
163   - },
164   - {
165   - path: "/",
166   - iconCls: "fa fa-cog",
167   - name: '学校管理',
168   - component: Layout,
169   - children: [
170   - {
171   - path: "/setUpSchool",
172   - iconCls: "fa fa-calculator",
173   - name: '学校管理',
174   - component: SetUpSchool,
175   - children: []
176   - },
177   - {
178   - path: "/setUpTeacher",
179   - iconCls: "fa fa-male",
180   - name: '教师管理',
181   - component: SetUpTeacher,
182   - children: []
183   - },
184   - {
185   - path: "/setUpStudent",
186   - iconCls: "fa fa-mortar-board",
187   - name: '学生管理',
188   - component: SetUpStudent,
189   - children: []
190   - },
191   - ]
192   - },
193   - {
194   - path: "/card",
195   - iconCls: "fa fa-id-card", // 图标样式class
196   - name: "发卡记录",
197   - component: Layout,
198   - alone: true,
199   - children: [
200   - {
201   - path: "/card",
202   - iconCls: "fa fa-id-card", // 图标样式class
203   - name: "",
204   - component: Card,
205   - children: []
206   - }
207   - ]
208   - },
209   - {
210   - path: "/device",
211   - iconCls: "fa fa-dashboard", // 图标样式class
212   - name: "设备状态",
213   - component: Layout,
214   - alone: true,
215   - children: [
216   - {
217   - path: "/device",
218   - iconCls: "fa fa-dashboard", // 图标样式class
219   - name: "",
220   - component: Device,
221   - children: []
222   - }
223   - ]
224   - },
225   - {
226   - path: "/analysis",
227   - iconCls: "fa fa-area-chart", // 图标样式class
228   - name: "使用分析",
229   - component: Layout,
230   - alone: true,
231   - children: [
232   - {
233   - path: "/analysis",
234   - iconCls: "fa fa-area-chart", // 图标样式class
235   - name: "",
236   - component: Analysis,
237   - children: []
238   - }
239   - ]
240   - },
241   - {
242   - path: "/down",
243   - iconCls: "fa fa-download", // 图标样式class
244   - name: "软件下载",
245   - component: Layout,
246   - alone: true,
247   - children: [
248   - {
249   - path: "/down",
250   - iconCls: "fa fa-download", // 图标样式class
251   - name: "",
252   - component: Down,
253   - children: []
254   - },
255   - {
256   - path: "/downClient",
257   - iconCls: "", // 图标样式class
258   - name: "",
259   - component: DownClient,
260   - children: []
261   - }
262   - ]
263   - },
264   - {
265   - path: "/dataSync",
266   - iconCls: "fa fa-random", // 图标样式class
267   - name: "数据同步",
268   - component: Layout,
269   - alone: true,
270   - children: [
271   - {
272   - path: "/dataSync",
273   - iconCls: "fa fa-random", // 图标样式class
274   - name: "",
275   - component: DataSync,
276   - children: []
277   - }
278   - ]
279   - },
280   - {
281   - path: "*",
282   - redirect: "/404",
283   - hidden: true,
284   - children: []
285   - }
286   -]
287   -
  4 +import {addrouters} from "./index"
288 5  
289 6 // 获取角色信息,根据用户权限动态加载路由
290 7 router.beforeEach((to, from, next) => {
... ... @@ -314,7 +31,7 @@ router.beforeEach((to, from, next) => {
314 31 newAddRouters.forEach(res => {
315 32 router.addRoute(res)
316 33 })
317   - next({ path: to.path })
  34 + next({path: to.fullPath})
318 35 }())
319 36 } else {
320 37 next()
... ...
src/store/index.js
... ... @@ -3,291 +3,12 @@ import Vuex from "vuex"
3 3 import Cookies from "js-cookie"
4 4 import layoutStore from "./modules/layout/index"
5 5 import { defaultRouter } from "@/router/index"
  6 +import { encryptLoginPassword } from "@/utils";
  7 +import { b64DecodeUnicode } from "@/utils";
6 8  
7 9 import request from "@/api/index"
8 10 import router from "@/router/index"
9   -
10   -import Layout from "@/views/layout/layout"
11   -import CommerViews from "@/views/commerViews"
12   -const ExaminationPaper = () => import("@/views/examinationPaper/index")
13   -const ExaminationPaperAdd = () => import("@/views/examinationPaper/add")
14   -const ExaminationPaperEdit = () => import("@/views/examinationPaper/edit")
15   -const ExaminationPaperRecycle = () => import("@/views/examinationPaper/recycle")
16   -const Ask = () => import("@/views/ask/index")
17   -const AskAnalysis = () => import("@/views/ask/analysis")
18   -const Test = () => import("@/views/test/index")
19   -const TestAnalysis = () => import("@/views/test/analysis")
20   -const DataSync = () => import("@/views/dataSync/index")
21   -const Portrait = () => import("@/views/portrait/index")
22   -const Card = () => import("@/views/card/index")
23   -const Analysis = () => import("@/views/analysis/index")
24   -const Device = () => import("@/views/device/index")
25   -const Down = () => import("@/views/down/index")
26   -const DownClient = () => import("@/views/down/client")
27   -const SetUpAccount = () => import("@/views/setUp/account")
28   -const SetUpConglomerate = () => import("@/views/setUp/conglomerate")
29   -const SetUpSchool = () => import("@/views/setUp/school")
30   -const SetUpStudent = () => import("@/views/setUp/student")
31   -const SetUpTeacher = () => import("@/views/setUp/teacher")
32   -let addrouters = [ //测试用,后续后端获取
33   - {
34   - path: "/examinationPaper",
35   - iconCls: "fa fa-file-text", // 图标样式class
36   - name: "备题组卷",
37   - component: Layout,
38   - alone: true,
39   - children: [
40   - {
41   - path: "/examinationPaper",
42   - iconCls: "fa fa-file-text", // 图标样式class
43   - name: "",
44   - component: ExaminationPaper,
45   - children: []
46   - },
47   - {
48   - path: "/examinationPaperAdd",
49   - iconCls: "", // 图标样式class
50   - name: "添加答题卡",
51   - component: ExaminationPaperAdd,
52   - children: []
53   - },
54   - {
55   - path: "/examinationPaperEdit",
56   - iconCls: "", // 图标样式class
57   - name: "修改答题卡",
58   - component: ExaminationPaperEdit,
59   - children: []
60   - },
61   - {
62   - path: "/examinationPaperRecycle",
63   - iconCls: "", // 图标样式class
64   - name: "已归档答题卡",
65   - component: ExaminationPaperRecycle,
66   - children: []
67   - },
68   - ]
69   - },
70   - {
71   - path: "/ask",
72   - iconCls: "fa fa-bar-chart", // 图标样式class
73   - name: "随堂问报表",
74   - component: Layout,
75   - alone: true,
76   - children: [
77   - {
78   - path: "/ask",
79   - iconCls: "fa fa-bar-chart", // 图标样式class
80   - name: "",
81   - component: Ask,
82   - children: []
83   -
84   - },
85   - {
86   - path: "/askAnalysis",
87   - iconCls: "", // 图标样式class
88   - name: "随堂问报表分析",
89   - component: AskAnalysis,
90   - children: []
91   - }
92   - ]
93   - },
94   - {
95   - path: "/test",
96   - iconCls: "fa fa-pie-chart", // 图标样式class
97   - name: "即时测报表",
98   - component: Layout,
99   - alone: true,
100   - children: [
101   - {
102   - path: "/test",
103   - iconCls: "fa fa-pie-chart", // 图标样式class
104   - name: "",
105   - component: Test,
106   - children: []
107   - },
108   - {
109   - path: "/testAnalysis",
110   - iconCls: "", // 图标样式class
111   - name: "即时测报表分析",
112   - component: TestAnalysis,
113   - children: []
114   - }
115   -
116   - ]
117   - },
118   - {
119   - path: "/portrait",
120   - iconCls: "fa fa-users", // 图标样式class
121   - name: "学生画像",
122   - component: Layout,
123   - alone: true,
124   - children: [
125   - {
126   - path: "/portrait",
127   - iconCls: "fa fa-users", // 图标样式class
128   - name: "",
129   - component: Portrait,
130   - children: []
131   - }
132   - ]
133   - },
134   -
135   - {
136   - path: "/setUpConglomerate",
137   - iconCls: "fa fa-building", // 图标样式class
138   - name: "学校管理",
139   - component: Layout,
140   - alone: true,
141   - children: [
142   - {
143   - path: "/setUpConglomerate",
144   - iconCls: "fa fa-building",
145   - name: '集团管理',
146   - component: SetUpConglomerate,
147   - children: []
148   - },
149   - ]
150   - },
151   - {
152   - path: "/setUpAccount",
153   - iconCls: "fa fa-id-card-o", // 图标样式class
154   - name: "账号管理",
155   - component: Layout,
156   - alone: true,
157   - children: [
158   - {
159   - path: "/setUpAccount",
160   - iconCls: "fa fa-id-card-o",
161   - name: '',
162   - component: SetUpAccount,
163   - children: []
164   - },
165   - ]
166   - },
167   - {
168   - path: "/",
169   - iconCls: "fa fa-cog",
170   - name: '学校设置',
171   - component: Layout,
172   - children: [
173   - {
174   - path: "/setUpSchool",
175   - iconCls: "fa fa-calculator",
176   - name: '学校设置',
177   - component: SetUpSchool,
178   - children: []
179   - },
180   - {
181   - path: "/setUpTeacher",
182   - iconCls: "fa fa-male",
183   - name: '教师管理',
184   - component: SetUpTeacher,
185   - children: []
186   - },
187   - {
188   - path: "/setUpStudent",
189   - iconCls: "fa fa-mortar-board",
190   - name: '学生管理',
191   - component: SetUpStudent,
192   - children: []
193   - },
194   - ]
195   - },
196   - {
197   - path: "/card",
198   - iconCls: "fa fa-id-card", // 图标样式class
199   - name: "发卡记录",
200   - component: Layout,
201   - alone: true,
202   - children: [
203   - {
204   - path: "/card",
205   - iconCls: "fa fa-id-card", // 图标样式class
206   - name: "",
207   - component: Card,
208   - children: []
209   - }
210   - ]
211   - },
212   - {
213   - path: "/device",
214   - iconCls: "fa fa-dashboard", // 图标样式class
215   - name: "设备状态",
216   - component: Layout,
217   - alone: true,
218   - children: [
219   - {
220   - path: "/device",
221   - iconCls: "fa fa-dashboard", // 图标样式class
222   - name: "",
223   - component: Device,
224   - children: []
225   - }
226   - ]
227   - },
228   - {
229   - path: "/analysis",
230   - iconCls: "fa fa-area-chart", // 图标样式class
231   - name: "使用分析",
232   - component: Layout,
233   - alone: true,
234   - children: [
235   - {
236   - path: "/analysis",
237   - iconCls: "fa fa-area-chart", // 图标样式class
238   - name: "",
239   - component: Analysis,
240   - children: []
241   - }
242   - ]
243   - },
244   - {
245   - path: "/down",
246   - iconCls: "fa fa-download", // 图标样式class
247   - name: "软件下载",
248   - component: Layout,
249   - alone: true,
250   - children: [
251   - {
252   - path: "/down",
253   - iconCls: "fa fa-download", // 图标样式class
254   - name: "发卡软件",
255   - component: Down,
256   - children: []
257   - },
258   - {
259   - path: "/downClient",
260   - iconCls: "", // 图标样式class
261   - name: "授课端软件",
262   - component: DownClient,
263   - children: []
264   - }
265   - ]
266   - },
267   - {
268   - path: "/dataSync",
269   - iconCls: "fa fa-random", // 图标样式class
270   - name: "数据同步",
271   - component: Layout,
272   - alone: true,
273   - children: [
274   - {
275   - path: "/dataSync",
276   - iconCls: "fa fa-random", // 图标样式class
277   - name: "",
278   - component: DataSync,
279   - children: []
280   - }
281   - ]
282   - },
283   - {
284   - path: "*",
285   - redirect: "/404",
286   - hidden: true,
287   - children: []
288   - }
289   -]
290   -
  11 +import {addrouters} from "@/router/index"
291 12 Vue.use(Vuex)
292 13  
293 14 const store = new Vuex.Store({
... ... @@ -310,7 +31,7 @@ const store = new Vuex.Store({
310 31 name: data.name,
311 32 authorityRouter: data.authorityRouter,
312 33 avatar: data.avatar ? data.avatar : "",
313   - uid: data.id
  34 + uid: data.uid
314 35 }
315 36 localStorage.setItem("info", JSON.stringify(store.getters.info))
316 37 },
... ... @@ -330,9 +51,13 @@ const store = new Vuex.Store({
330 51 },
331 52 },
332 53 actions: {
333   - Login({ commit }, that) {
334   - // request.fetchLogin(that.loginForm).then(res => {
  54 + Login({ state,commit }, params) {
  55 + let loginForm={}
  56 + loginForm.username = params.username;
  57 + loginForm.password = encryptLoginPassword(params.password);
  58 + // request.fetchLogin(loginForm).then(res => {
335 59 // if (res.status == 200) {
  60 + // const dataJSON = JSON.parse(b64DecodeUnicode(res.data));
336 61 commit("setToken", "xxxx")
337 62 commit("setInfo", {
338 63 permissions: [
... ... @@ -347,14 +72,19 @@ const store = new Vuex.Store({
347 72 // authorityRouter:[],
348 73 });
349 74 commit("setRouters", addrouters)
350   - addrouters.forEach((res) => {
351   - that.$router.addRoute(res);
  75 + state.addRouters.forEach((res) => {
  76 + router.addRoute(res);
352 77 });
353   - that.$router.push({ path: "/" })
  78 + console.log()
  79 + if (params.url) {
  80 + window.location.href = params.url;
  81 + } else {
  82 + router.push({ path: "/" })
  83 + }
354 84 // }
355 85 // })
356 86 },
357   - permissions({ commit }, that) {
  87 + permissions({ state,commit }, that) {
358 88 // request.fetchLogin(that.loginForm).then(res => {
359 89 // if (res.status == 200) {
360 90 commit("setToken", "xxxx")
... ... @@ -371,7 +101,7 @@ const store = new Vuex.Store({
371 101 // authorityRouter:[],
372 102 });
373 103 commit("setRouters", addrouters)
374   - addrouters.forEach((res) => {
  104 + state.addRouters.forEach((res) => {
375 105 that.$router.addRoute(res);
376 106 });
377 107 that.$router.push({ path: "/" })
... ...
src/utils/index.js
1 1  
2   -import CryptoJS from "crypto-js"
  2 +// import CryptoJS from "crypto-js"
  3 +import { JSEncrypt } from 'jsencrypt'
3 4  
4 5 const encryptKey = "WfJTKO9S4eLkrPz2JKrAnzdb"
5 6 const encryptIV = "D076D35C"
  7 +/**
  8 + * 登录密码加密,公钥直接写死在方法里
  9 + * @param data: 待加密数据
  10 + * @returns 加密结果
  11 + */
  12 +export function encryptLoginPassword(data){
  13 + const secret = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjh2ei17z5k2r4VzbqoSCE6RmYzWySJTgVQYulgfVM+vqcDoUE4cFB4XCFA2lHWjjpsuJP1EtwKlvUgxo5okr3x/a88o8eERxBynnVQZbEYpKteW5aqSEb/g1yPLWnKV88b/ED445ITYbZZuInRo5lkCvd6QEjL6d2Fch6mEo5awYXC4/S4BJf9YlYRhGzR7wpiXCLvyBHQ4iSIIDNpmrPBPQzGP0rx09aDu54kz/42CR6SX2OqXSi4ZoieqkPFl/iuX4RoD/NKKR+haDn1UzoD3k1WzHSTBFFs27rxRpxfBUZzfXQeskgKyw/Slcl3jUFizczsY4CLgTRrfey48Q6QIDAQAB';
  14 + // 新建JSEncrypt对象
  15 + let encryptor = new JSEncrypt();
  16 + // 设置公钥
  17 + encryptor.setPublicKey(secret);
  18 + // 加密数据
  19 + return encryptor.encrypt(data);
  20 +}
  21 +
  22 +/**
  23 +* 对称加密
  24 +* @param secret:加密公钥
  25 +* @param data: 待加密数据
  26 +* @returns 加密结果
  27 +*/
  28 +export function encryptData(secret, data){
  29 + // 新建JSEncrypt对象
  30 + let encryptor = new JSEncrypt();
  31 + // 设置公钥
  32 + encryptor.setPublicKey(secret);
  33 + // 加密数据
  34 + return encryptor.encrypt(data);
  35 +}
6 36  
7 37 // 深度复制
8 38 export function deepClone (obj) {
... ... @@ -19,29 +49,29 @@ export function deepClone (obj) {
19 49 return result
20 50 }
21 51  
22   -// 3DES加密
23   -export function desEncrypt (str, key = encryptKey, iv = encryptIV) {
24   - var cryptoKey = CryptoJS.enc.Utf8.parse(key)
25   - var cryptoIv = CryptoJS.enc.Utf8.parse(iv.substr(0, 8))
26   - var encodeStr = CryptoJS.TripleDES.encrypt(str, cryptoKey, {
27   - iv: cryptoIv,
28   - mode: CryptoJS.mode.CBC,
29   - padding: CryptoJS.pad.Pkcs7
30   - })
31   - return encodeStr.toString()
32   -}
  52 +// // 3DES加密
  53 +// export function desEncrypt (str, key = encryptKey, iv = encryptIV) {
  54 +// var cryptoKey = CryptoJS.enc.Utf8.parse(key)
  55 +// var cryptoIv = CryptoJS.enc.Utf8.parse(iv.substr(0, 8))
  56 +// var encodeStr = CryptoJS.TripleDES.encrypt(str, cryptoKey, {
  57 +// iv: cryptoIv,
  58 +// mode: CryptoJS.mode.CBC,
  59 +// padding: CryptoJS.pad.Pkcs7
  60 +// })
  61 +// return encodeStr.toString()
  62 +// }
33 63  
34   -// 3DES解密
35   -export function desDecrypt (str, key = encryptKey, iv = encryptIV) {
36   - var cryptoKey = CryptoJS.enc.Utf8.parse(key)
37   - var cryptoIv = CryptoJS.enc.Utf8.parse(iv.substr(0, 8))
38   - var decryptStr = CryptoJS.TripleDES.decrypt(str, cryptoKey, {
39   - iv: cryptoIv,
40   - mode: CryptoJS.mode.CBC,
41   - padding: CryptoJS.pad.Pkcs7
42   - })
43   - return decryptStr.toString(CryptoJS.enc.Utf8)
44   -}
  64 +// // 3DES解密
  65 +// export function desDecrypt (str, key = encryptKey, iv = encryptIV) {
  66 +// var cryptoKey = CryptoJS.enc.Utf8.parse(key)
  67 +// var cryptoIv = CryptoJS.enc.Utf8.parse(iv.substr(0, 8))
  68 +// var decryptStr = CryptoJS.TripleDES.decrypt(str, cryptoKey, {
  69 +// iv: cryptoIv,
  70 +// mode: CryptoJS.mode.CBC,
  71 +// padding: CryptoJS.pad.Pkcs7
  72 +// })
  73 +// return decryptStr.toString(CryptoJS.enc.Utf8)
  74 +// }
45 75  
46 76 // 随机生成由字母+数字的字符串
47 77 export function randomWord (randomFlag, min, max) {
... ... @@ -86,6 +116,21 @@ export function getCookie (name, defaultValue) {
86 116 return result[0] === document.cookie.match(result[1]) ? unescape(result[0][2]) : defaultValue
87 117 }
88 118  
  119 +
  120 +/**
  121 + * base64转化unicode
  122 + */
  123 + export function b64DecodeUnicode(str) {
  124 + let uni;
  125 + try {
  126 + // atob 经过 base-64 编码的字符串进行解码
  127 + uni = decodeURIComponent(atob(str).split('').map(function (c) {
  128 + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
  129 + }).join(''));
  130 + } catch (e) {}
  131 + return uni;
  132 +}
  133 +
89 134 // base64ToFile
90 135 export function base64ToFile (base64Data, tempfilename, contentType) {
91 136 contentType = contentType || ""
... ... @@ -228,3 +273,28 @@ export function getNewTime (dayNum) {
228 273 var time = date.getTime()
229 274 return time
230 275 }
  276 +
  277 +/*
  278 + * 获取URL参数
  279 + *
  280 + * */
  281 +export function getURLParams(variable) {
  282 + let str = window.location.href.split("?")[1];
  283 + if (!str) return null;
  284 + let ar = str.split("&");
  285 + let obj = {};
  286 + let data;
  287 + for (var i = 0; i < ar.length; i++) {
  288 + var pair = ar[i].split("=");
  289 + pair[1] = decodeURIComponent(pair[1])
  290 +
  291 + if (pair[0] == variable) {
  292 + data = pair[1]
  293 + return pair[1]
  294 + }
  295 + if (pair[0]) {
  296 + obj[pair[0]] = pair[1]
  297 + }
  298 + }
  299 + return variable ? data : obj
  300 +}
231 301 \ No newline at end of file
... ...
src/views/examinationPaper/add.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="content">
  9 + <el-steps
  10 + :active="step"
  11 + finish-status="success"
  12 + simple
  13 + style="margin: 20px 0"
  14 + >
  15 + <el-step title="基础信息" icon="el-icon-edit"></el-step>
  16 + <el-step title="题目编辑" icon="el-icon-tickets"></el-step>
  17 + <el-step title="设置答案" icon="el-icon-edit-outline"></el-step>
  18 + </el-steps>
  19 + <div v-show="step == 0">
  20 + <el-form
  21 + ref="forms"
  22 + :model="form"
  23 + :rules="formRules"
  24 + label-width="140px"
  25 + >
  26 + <el-form-item label="答题卡名称:" prop="title">
  27 + <el-col :span="10"
  28 + ><el-input
  29 + type="text"
  30 + placeholder="请输入答题卡名称"
  31 + v-model.trim="form.title"
  32 + maxlength="30"
  33 + size="45"
  34 + show-word-limit
  35 + >
  36 + </el-input
  37 + ></el-col>
  38 + </el-form-item>
  39 + <el-form-item label="测验类型:">
  40 + <el-select v-model="form.tag" placeholder="选择测验类型">
  41 + <el-option
  42 + v-for="item in answerTypeList"
  43 + :key="item.id"
  44 + :label="item.typeName"
  45 + :value="item.id"
  46 + >{{ item.typeName }}</el-option
  47 + >
  48 + </el-select>
  49 + <el-button
  50 + class="ml-20"
  51 + type="primary"
  52 + round
  53 + circle
  54 + icon="el-icon-plus"
  55 + @click="dialogVisible = true"
  56 + ></el-button>
  57 + </el-form-item>
  58 + <el-form-item label="年级:" prop="gradeName">
  59 + <el-select
  60 + class="sel"
  61 + v-model="form.gradeName"
  62 + placeholder=""
  63 + @change="changeGrade"
  64 + >
  65 + <el-option
  66 + v-for="item in gradeList"
  67 + :key="item"
  68 + :label="item"
  69 + :value="item"
  70 + >
  71 + </el-option>
  72 + </el-select>
  73 + </el-form-item>
  74 + <el-form-item label="科目:" prop="subjectId">
  75 + <el-select class="sel" v-model="form.subjectId" placeholder="">
  76 + <el-option
  77 + v-for="item in subjectList"
  78 + :key="item.value"
  79 + :label="item.label"
  80 + :value="item.value"
  81 + >
  82 + </el-option>
  83 + </el-select>
  84 + </el-form-item>
  85 + <el-form-item label="考试时长:" prop="examsDuration">
  86 + <el-input-number
  87 + size="medium"
  88 + :min="1"
  89 + :max="240"
  90 + v-model="form.examsDuration"
  91 + label="考试时长"
  92 + ></el-input-number>
  93 + </el-form-item>
  94 + <el-form-item label="分享范围:" prop="share">
  95 + <el-radio-group v-model="form.share">
  96 + <el-radio :label="1">任课班级分享</el-radio>
  97 + <el-radio :label="2">全年级分享</el-radio>
  98 + </el-radio-group>
  99 + </el-form-item>
  100 + </el-form>
  101 + <div class="btn-box">
  102 + <el-button type="danger" plain round @click="linkBack"
  103 + >取消</el-button
  104 + >
  105 + <el-button type="primary" round @click="setStep1">下一步</el-button>
  106 + </div>
  107 + <el-dialog
  108 + title="天假测验类型"
  109 + :visible.sync="dialogVisible"
  110 + width="500px"
  111 + >
  112 + <div class="dia-content">
  113 + <p class="add-type">
  114 + <el-input
  115 + type="text"
  116 + placeholder="请输入答题卡类型名称"
  117 + v-model.trim="answerTypeName"
  118 + maxlength="10"
  119 + show-word-limit
  120 + >
  121 + </el-input>
  122 + </p>
  123 + </div>
  124 + <div class="" slot="footer">
  125 + <el-button type="primary" @click="addAnswerTypeName"
  126 + >确 定</el-button
  127 + >
  128 + <el-button @click="dialogVisible = false">取 消</el-button>
  129 + </div>
  130 + </el-dialog>
  131 + </div>
  132 + <div v-show="step == 1">
  133 + <div v-for="(question, index) in form.questionList" :key="index">
  134 + <p class="question-title">
  135 + <span>{{ setBigNum(index) }}、</span>
  136 + <el-input
  137 + class="ipt"
  138 + v-model.trim="question.questionTitle"
  139 + placeholder="填写大题名称"
  140 + ></el-input>
  141 + <el-popconfirm
  142 + title="确定删除这道大题吗?"
  143 + @confirm="form.questionList.splice(index, 1)"
  144 + >
  145 + <el-button
  146 + slot="reference"
  147 + class="delete"
  148 + type="danger"
  149 + size="mini"
  150 + circle
  151 + icon="el-icon-delete"
  152 + ></el-button>
  153 + </el-popconfirm>
  154 +
  155 + <span>总分数:{{ setScore(question) }}分</span>
  156 + </p>
  157 + <ul class="questions-ul">
  158 + <li class="sub-questions">
  159 + <div class="qs-num">题号</div>
  160 + <div class="qs-type">题型</div>
  161 + <div class="qs-score">分数</div>
  162 + <div class="qs-partScore">部分分值</div>
  163 + <div class="qs-options">选项设置</div>
  164 + <div class="qs-set">操作</div>
  165 + </li>
  166 + <li
  167 + class="sub-questions"
  168 + v-for="(subQuestions, indexs) in question.subQuestions"
  169 + :key="indexs"
  170 + >
  171 + <div class="qs-num">{{ setNum(index, indexs) }}</div>
  172 + <div class="qs-type">
  173 + <el-select
  174 + v-model="subQuestions.questionType"
  175 + placeholder="选择答题卡类型"
  176 + @change="changeSubQuestions($event, subQuestions)"
  177 + >
  178 + <el-option label="单选题" :value="2"></el-option>
  179 + <el-option label="多选题" :value="3"></el-option>
  180 + <el-option label="判断题" :value="4"></el-option>
  181 + <el-option label="主观题" :value="5"></el-option>
  182 + </el-select>
  183 + </div>
  184 + <div class="qs-score">
  185 + <el-input-number
  186 + class="number-ipt"
  187 + size="medium"
  188 + :min="1"
  189 + :max="200"
  190 + :precision="2"
  191 + v-model="subQuestions.score"
  192 + label="单题分值"
  193 + ></el-input-number>
  194 + </div>
  195 + <div class="qs-partScore">
  196 + <p v-if="subQuestions.questionType != 3">--</p>
  197 + <el-input-number
  198 + class="number-ipt"
  199 + v-else
  200 + size="medium"
  201 + :min="0"
  202 + :precision="2"
  203 + :max="subQuestions.score"
  204 + :step="0.5"
  205 + v-model="subQuestions.partScore"
  206 + label="部分分值"
  207 + ></el-input-number>
  208 + </div>
  209 + <div class="qs-options">
  210 + <p v-if="subQuestions.questionType == 5">--</p>
  211 + <p
  212 + v-else-if="subQuestions.questionType == 4"
  213 + class="answer-box"
  214 + >
  215 + <span class="answer-s">✓</span>
  216 + <span class="answer-s">✗</span>
  217 + </p>
  218 + <p v-else class="answer-box">
  219 + <span
  220 + class="answer-s"
  221 + v-for="option in subQuestions.answerOptions"
  222 + :key="option"
  223 + >{{ option }}</span
  224 + >
  225 + <el-button
  226 + size="mini"
  227 + type="primary"
  228 + icon="el-icon-plus"
  229 + circle
  230 + @click="addOptions(subQuestions)"
  231 + ></el-button>
  232 + <el-button
  233 + size="mini"
  234 + type="primary"
  235 + icon="el-icon-minus"
  236 + round
  237 + circle
  238 + @click="removeOptions(subQuestions)"
  239 + ></el-button>
  240 + </p>
  241 + </div>
  242 + <div class="qs-set">
  243 + <el-popconfirm
  244 + title="确定删除这道题吗?"
  245 + @confirm="delTabData(indexs, index)"
  246 + >
  247 + <el-button
  248 + slot="reference"
  249 + class="delete"
  250 + type="danger"
  251 + size="mini"
  252 + circle
  253 + icon="el-icon-delete"
  254 + ></el-button>
  255 + </el-popconfirm>
  256 + </div>
  257 + </li>
  258 + <li class="sub-questions">
  259 + <div class="qs-num">添加</div>
  260 + <div class="qs-type">
  261 + <el-select
  262 + v-model="addSubQuestionsType"
  263 + placeholder="选择答题卡类型"
  264 + @change="changeAddSubQuestions($event, question)"
  265 + >
  266 + <el-option label="单选题" :value="2"></el-option>
  267 + <el-option label="多选题" :value="3"></el-option>
  268 + <el-option label="判断题" :value="4"></el-option>
  269 + <el-option label="主观题" :value="5"></el-option>
  270 + </el-select>
  271 + </div>
  272 + <div class="qs-score"></div>
  273 + <div class="qs-partScore"></div>
  274 + <div class="qs-options"></div>
  275 + <div class="qs-set"></div>
  276 + </li>
  277 + </ul>
  278 + </div>
  279 + <div class="add-box">
  280 + <p class="add-question" @click="openQuestion">
  281 + <el-button
  282 + size="mini"
  283 + type="primary"
  284 + icon="el-icon-plus"
  285 + circle
  286 + ></el-button>
  287 + <span class="s1">添加大题</span>
  288 + </p>
  289 + </div>
  290 + <div class="btn-box">
  291 + <el-button type="danger" plain round @click="linkBack"
  292 + >取消</el-button
  293 + >
  294 + <el-button round @click="step = 0">上一步</el-button>
  295 + <el-button type="primary" round @click="setStep2">下一步</el-button>
  296 + </div>
  297 + <el-dialog
  298 + title="添加大题"
  299 + :visible.sync="addQuestionVisible"
  300 + width="600px"
  301 + >
  302 + <div class="dia-content">
  303 + <el-form
  304 + ref="form"
  305 + :model="questionForm"
  306 + :rules="questionFormRules"
  307 + label-width="100px"
  308 + >
  309 + <el-form-item label="标题:" prop="questionTitle">
  310 + <el-col :span="12">
  311 + <el-input
  312 + v-model.trim="questionForm.questionTitle"
  313 + maxlength="30"
  314 + placeholder="输入大题名称"
  315 + ></el-input>
  316 + </el-col>
  317 + </el-form-item>
  318 + <el-form-item label="选择题型:">
  319 + <el-select v-model="questionForm.questionType" placeholder="">
  320 + <el-option
  321 + v-for="item in questionOptions"
  322 + :key="item.value"
  323 + :label="item.label"
  324 + :value="item.value"
  325 + >
  326 + </el-option>
  327 + </el-select>
  328 + </el-form-item>
  329 + <el-form-item label="默认题数:">
  330 + <el-input-number
  331 + v-model="questionForm.number"
  332 + :min="1"
  333 + :max="50"
  334 + label="label"
  335 + ></el-input-number>
  336 + </el-form-item>
  337 + </el-form>
  338 + </div>
  339 + <div class="dialog-footer" slot="footer">
  340 + <el-button type="primary" @click="addQuestion">确 定</el-button>
  341 + <el-button @click="addQuestionVisible = false">取 消</el-button>
  342 + </div>
  343 + </el-dialog>
  344 + </div>
  345 + <div v-show="step == 2">
  346 + <div v-for="(question, index) in form.questionList" :key="index">
  347 + <p class="question-title">
  348 + <span>{{ setBigNum(index) }}、</span>
  349 + <span class="title-txt">{{ question.questionTitle }}</span>
  350 + <span>共 {{ setScore(question) }} 分</span>
  351 + </p>
  352 + <ul class="questions-ul">
  353 + <li class="sub-questions">
  354 + <div class="qs-num">题号</div>
  355 + <div class="qs-score">分数</div>
  356 + <div class="qs-options qs-options2">选项设置</div>
  357 + </li>
  358 + <li
  359 + class="sub-questions"
  360 + v-for="(subQuestions, indexs) in question.subQuestions"
  361 + :key="indexs"
  362 + >
  363 + <div class="qs-num">{{ setNum(index, indexs) }}</div>
  364 + <div class="qs-type">
  365 + {{ setSubPro(subQuestions.questionType) }}
  366 + </div>
  367 + <div class="qs-score">
  368 + <el-input-number
  369 + class="number-ipt"
  370 + size="medium"
  371 + :min="1"
  372 + :max="200"
  373 + :precision="2"
  374 + v-model="subQuestions.score"
  375 + label="单题分值"
  376 + ></el-input-number>
  377 + </div>
  378 + <div class="qs-options qs-options2">
  379 + <p v-if="subQuestions.questionType == 5">--</p>
  380 + <p v-if="subQuestions.questionType == 4" class="answer-box">
  381 + <span
  382 + class="answer-s"
  383 + :class="subQuestions.correctAnswer == 1 ? 'active' : ''"
  384 + @click="subQuestions.correctAnswer = 1"
  385 + >✓</span
  386 + >
  387 + <span
  388 + class="answer-s"
  389 + :class="subQuestions.correctAnswer == 2 ? 'active' : ''"
  390 + @click="subQuestions.correctAnswer = 2"
  391 + >✗</span
  392 + >
  393 + </p>
  394 + <p v-if="subQuestions.questionType == 3" class="answer-box">
  395 + <span
  396 + class="answer-s"
  397 + v-for="option in subQuestions.answerOptions"
  398 + :class="
  399 + subQuestions.correctAnswer.includes(option)
  400 + ? 'active'
  401 + : ''
  402 + "
  403 + :key="option"
  404 + @click="changAnswer(subQuestions, option)"
  405 + >{{ option }}</span
  406 + >
  407 + </p>
  408 + <p v-if="subQuestions.questionType == 2" class="answer-box">
  409 + <span
  410 + class="answer-s"
  411 + v-for="option in subQuestions.answerOptions"
  412 + :class="
  413 + subQuestions.correctAnswer == option ? 'active' : ''
  414 + "
  415 + :key="option"
  416 + @click="subQuestions.correctAnswer = option"
  417 + >{{ option }}</span
  418 + >
  419 + </p>
  420 + </div>
  421 + </li>
  422 + </ul>
  423 + </div>
  424 + <div class="btn-box">
  425 + <el-button type="danger" plain round @click="linkBack"
  426 + >取消</el-button
  427 + >
  428 + <el-button round @click="step = 1">上一步</el-button>
  429 + <el-button type="primary" round @click="save">保存</el-button>
  430 + </div>
  431 + </div>
  432 + </div>
  433 + </div>
3 434 </template>
4 435  
5 436 <script>
  437 +const questionForm = {
  438 + questionTitle: "",
  439 + questionType: 2,
  440 + number: 10,
  441 +};
  442 +const subQuesOptions = {
  443 + questionType: 2,
  444 + score: 1,
  445 + partScore: 0,
  446 + selectNum: 4,
  447 + answerOptions: ["A", "B", "C", "D"],
  448 + correctAnswer: "",
  449 +};
6 450 export default {
  451 + data() {
  452 + return {
  453 + type: 1, //1-创建,2-复制答题卡
  454 + dialogVisible: false, //测验类型设置弹窗
  455 + addQuestionVisible: false, //添加大题弹窗
  456 + questionForm: { ...questionForm },
  457 + questionFormRules: {
  458 + questionTitle: [
  459 + { required: true, message: "请输入答题卡名称", trigger: "blur" },
  460 + {
  461 + min: 1,
  462 + max: 30,
  463 + message: "长度在 1 到 30 个字符",
  464 + trigger: "blur",
  465 + },
  466 + ],
  467 + },
  468 + questionOptions: [
  469 + { label: "单选题", value: 2 },
  470 + { label: "多选题", value: 3 },
  471 + { label: "判断题", value: 4 },
  472 + { label: "主观题", value: 5 },
  473 + ],
  474 + rightOptions: ["A", "B", "C", "D", "E", "F", "G"],
  475 + addSubQuestionsType: "",
  476 + step: 0, //步骤
  477 + gradeList: [], //年级
  478 + subjectList: [], //科目
  479 + answerTypeList: [], //测验类型
  480 + answerTypeName: [], //测验类型名称
  481 + form: {
  482 + //答题卡详情
  483 + title: "",
  484 + tag: "",
  485 + subjectId: "",
  486 + examsDuration: 0,
  487 + gradeName: "",
  488 + share: 1,
  489 + questionList: [],
  490 + },
  491 + formRules: {
  492 + //答题卡验证
  493 + title: [
  494 + { required: true, message: "请输入答题卡名称", trigger: "blur" },
  495 + {
  496 + min: 1,
  497 + max: 30,
  498 + message: "长度在 1 到 30 个字符",
  499 + trigger: "blur",
  500 + },
  501 + ],
  502 + gradeName: [{ required: true, message: "请选择年级", trigger: "blur" }],
  503 + subjectId: [{ required: true, message: "请选择科目", trigger: "blur" }],
  504 + examsDuration: [
  505 + { required: true, message: "请设置考试时长", trigger: "blur" },
  506 + ],
  507 + },
  508 + };
  509 + },
  510 + created() {
  511 + this.type = this.$route.query.type ? this.$route.query.type : 1;
  512 + if (this.type == 2) {
  513 + this.form = this.$route.query.form && JSON.parse(this.$route.query.form);
  514 + console.log(this.form.examsDuration)
  515 + this.form.examsDuration = Number(this.form.examsDuration)/60
  516 + }
  517 + },
  518 + methods: {
  519 + linkBack() {
  520 + this.$confirm(
  521 + (this.type == 2 ? "修改复制的" : "组建的") +
  522 + "答题卡未保存,确认退出吗?",
  523 + "提示",
  524 + {
  525 + confirmButtonText: "取消",
  526 + cancelButtonText: "确定",
  527 + confirmButtonClass: "el-button--danger1",
  528 + cancelButtonClass: "el-button--primary",
  529 + showClose: false,
  530 + roundButton: true,
  531 + center: true,
  532 + type: "warning",
  533 + }
  534 + )
  535 + .then(() => {})
  536 + .catch(() => {
  537 + this.$router.push({
  538 + path: "/examinationPaper",
  539 + });
  540 + });
  541 + },
  542 + setSubPro(type) {
  543 + let tit;
  544 + switch (type) {
  545 + case 2:
  546 + tit = "单选题";
  547 + break;
  548 + case 3:
  549 + tit = "多选题";
  550 + break;
  551 + case 4:
  552 + tit = "判断题";
  553 + break;
  554 + case 5:
  555 + tit = "主观题";
  556 + break;
  557 + }
  558 + return tit;
  559 + },
  560 + setNum(index, indexs) {
  561 + let lengths = 0;
  562 + for (let i = 0; i < index; i++) {
  563 + lengths += this.form.questionList[i].subQuestions.length;
  564 + }
  565 + return lengths + indexs + 1;
  566 + },
  567 + setBigNum(num) {
  568 + let txt = "";
  569 + let bigNum = [
  570 + "一",
  571 + "二",
  572 + "三",
  573 + "四",
  574 + "五",
  575 + "六",
  576 + "七",
  577 + "八",
  578 + "九",
  579 + "十",
  580 + "十一",
  581 + "十二",
  582 + "十三",
  583 + "十四",
  584 + "十五",
  585 + "十六",
  586 + "十七",
  587 + "十八",
  588 + "十九",
  589 + "二十",
  590 + ];
  591 + txt = bigNum[num];
7 592  
8   -}
9   -</script>
  593 + return txt;
  594 + },
  595 + setAddIndex(index) {},
  596 + setStep1() {
  597 + this.$refs["forms"].validate((valid) => {
  598 + // 验证通过:保存
  599 + if (valid) {
  600 + this.step = 1;
  601 + } else {
  602 + this.$message.error("数据有误,请检查!");
  603 + return false;
  604 + }
  605 + });
  606 + },
  607 + setStep2() {
  608 + let valid = true;
  609 + this.form.questionList.map((item) => {
  610 + if (!item.questionTitle) {
  611 + valid = false;
  612 + }
  613 + });
  614 + if (valid) {
  615 + this.step = 2;
  616 + } else {
  617 + this.$message.error("大题名称不能为空,请检查!");
  618 + }
  619 + },
  620 + openQuestion() {
  621 + this.questionForm = { ...questionForm };
  622 + this.addQuestionVisible = true;
  623 + },
  624 + addQuestion() {
  625 + let subQuestions = [];
  626 + let questionsOptions = {
  627 + ...subQuesOptions,
  628 + questionType: this.questionForm.questionType,
  629 + };
  630 + switch (questionsOptions.questionType) {
  631 + case 2:
  632 + questionsOptions.answerOptions = this.rightOptions.slice(
  633 + 0,
  634 + questionsOptions.selectNum
  635 + );
  636 + break;
  637 + case 3:
  638 + questionsOptions.answerOptions = this.rightOptions.slice(
  639 + 0,
  640 + questionsOptions.selectNum
  641 + );
  642 + questionsOptions.partScore = 0.5;
  643 + break;
  644 + case 4:
  645 + case 5:
  646 + questionsOptions.selectNum = 0;
  647 + break;
  648 + }
  649 + for (let i = 0; i < this.questionForm.number; i++) {
  650 + subQuestions.push({ ...questionsOptions });
  651 + }
  652 + this.form.questionList.push({
  653 + questionTitle: this.questionForm.questionTitle,
  654 + number: this.questionForm.number,
  655 + source: 10,
  656 + subQuestions: [...subQuestions],
  657 + });
  658 + this.addQuestionVisible = false;
  659 + },
  660 + delTabData(subIndex, index) {
  661 + //删除小题
  662 + console.log(subIndex);
  663 + console.log(index);
  664 + this.form.questionList[index].subQuestions.splice(subIndex, 1);
  665 + },
  666 + setScore(question) {
  667 + let score = question.subQuestions.reduce((a, b) => {
  668 + return a + b.score;
  669 + }, 0);
  670 + return score;
  671 + },
  672 + changeAddSubQuestions(val, question) {
  673 + if (val) {
  674 + let questionsOptions = {
  675 + ...subQuesOptions,
  676 + questionType: val,
  677 + };
  678 + switch (questionsOptions.questionType) {
  679 + case 2:
  680 + questionsOptions.answerOptions = this.rightOptions.slice(
  681 + 0,
  682 + questionsOptions.selectNum
  683 + );
  684 + break;
  685 + case 3:
  686 + questionsOptions.answerOptions = this.rightOptions.slice(
  687 + 0,
  688 + questionsOptions.selectNum
  689 + );
  690 + questionsOptions.partScore = 0.5;
  691 + break;
  692 + case 4:
  693 + case 5:
  694 + questionsOptions.selectNum = 0;
  695 + break;
  696 + }
  697 + question.subQuestions.push(questionsOptions);
  698 + this.addSubQuestionsType = "";
  699 + }
  700 + },
  701 + changeSubQuestions(val, subQuestions) {
  702 + //切换多题型-小题题型
  703 + const that = this;
  704 + subQuestions.score = 1;
  705 + subQuestions.partScore = 0;
  706 + subQuestions.correctAnswer = "";
  707 + subQuestions.selectNum = 4;
  708 + switch (val) {
  709 + case 2:
  710 + subQuestions.answerOptions = that.rightOptions.slice(
  711 + 0,
  712 + subQuestions.selectNum
  713 + );
  714 + break;
  715 + case 3:
  716 + subQuestions.answerOptions = that.rightOptions.slice(
  717 + 0,
  718 + subQuestions.selectNum
  719 + );
  720 + subQuestions.partScore = 0.5;
  721 + break;
  722 + case 4:
  723 + case 5:
  724 + subQuestions.selectNum = 0;
  725 + break;
  726 + }
  727 + },
  728 + addOptions(subQuestions) {
  729 + //添加选项
  730 + let length = subQuestions.answerOptions.length;
  731 + if (length > 6) return;
  732 + subQuestions.selectNum = length + 1;
  733 + subQuestions.answerOptions = this.rightOptions.slice(
  734 + 0,
  735 + subQuestions.selectNum
  736 + );
  737 + },
  738 + removeOptions(subQuestions) {
  739 + //删除选项
  740 + let length = subQuestions.answerOptions.length;
  741 + if (length < 2) return;
  742 + subQuestions.selectNum = length - 1;
  743 + subQuestions.answerOptions = this.rightOptions.slice(
  744 + 0,
  745 + subQuestions.selectNum
  746 + );
  747 + },
  748 + changAnswer(sub, option) {
  749 + //设置多选答案
  750 + let str = new RegExp(option, "g");
  751 + if (sub.correctAnswer?.includes(option)) {
  752 + sub.correctAnswer = sub.correctAnswer.replace(str, "");
  753 + } else {
  754 + let arrs = (sub.correctAnswer && sub.correctAnswer.split("")) || [];
  755 + arrs.push(option);
  756 + sub.correctAnswer = arrs.sort().join("");
  757 + }
  758 + },
  759 + async addAnswerTypeName() {
  760 + //保存测验类型
  761 + if (!this.answerTypeName) {
  762 + this.$message.error("请填写测验名称!");
  763 + return;
  764 + }
  765 + //添加测验类型
  766 + const { data, code, message } = await this.$request.addAnswerTypeName({
  767 + typeName: this.answerTypeName,
  768 + });
  769 + if (code == 0) {
  770 + this._CreatedTypeList();
  771 + this.dialogVisible = false;
  772 + this.answerTypeName = "";
  773 + this.$message.success("添加成功");
  774 + } else {
  775 + this.$message.error(message);
  776 + }
  777 + },
  778 + async save() {
  779 + if (this.saceLoading) return;
  780 + this.saceLoading = true;
  781 + const { data, code, message } = await this.$request.saveAnswerSheet({
  782 + ...this.form,
  783 + });
  784 + this.saceLoading = false;
  785 + if (code == 0) {
  786 + this.$router.push({
  787 + path:"/examinationPaper"
  788 + })
  789 + } else {
  790 + this.$message.error(message);
  791 + }
  792 + },
  793 + async changeGrade() {
  794 + //切换年级查询科目
  795 + this._QuerySubjectList(this.form.gradeName);
  796 + },
  797 + async _CreatedTypeList() {
  798 + //测验类型查询
  799 + const { data, code, message } = await this.$request.fetchTypeNames();
  800 + if (code == 0) {
  801 + this.answerTypeList = [...data.list] || [];
  802 + this.answerTypeList.unshift({
  803 + typeName: "--",
  804 + id: "",
  805 + });
  806 + if (this.type != 2) {
  807 + this.form.tag = this.answerTypeList[0].id || "";
  808 + }
  809 + } else {
  810 + this.$message.error(message);
  811 + }
  812 + },
  813 + async _GradeList() {
  814 + //查询年级列表
  815 + const { data, code, message } = await this.$request.fetchGradeList();
  816 + if (code == 0) {
  817 + this.gradeList = [...data.gradeNames] || [];
  818 + if (this.type != 2) {
  819 + this.form.gradeName = this.gradeList[0];
  820 + }
  821 + this._QuerySubjectList(this.gradeList[0]);
  822 + } else {
  823 + this.$message.error(message);
  824 + }
  825 + },
  826 + async _QuerySubjectList(grade, dont) {
  827 + //查询科目列表
  828 + let param = {};
  829 + if (grade) {
  830 + param.gradeName = grade;
  831 + }
  832 + const { data, code, message } = await this.$request.fetchSubjectList(
  833 + param
  834 + );
  835 + if (code === 0) {
  836 + this.subjectList = data.list.map((item) => {
  837 + return {
  838 + value: item.subjectId,
  839 + label: item.subjectName,
  840 + };
  841 + });
  842 + if (this.subjectList.length > 1) {
  843 + let isTeachingCourse = false;
  844 + this.subjectList.map((item) => {
  845 + if (item.isTeachingCourse) {
  846 + isTeachingCourse = true;
  847 + }
  848 + });
  849 + if (this.type != 2) {
  850 + !isTeachingCourse && !dont
  851 + ? (this.form.subjectId = this.subjectList[0].value)
  852 + : "";
  853 + }
  854 + }
  855 + if (this.subjectList.length > 0 && !dont) {
  856 + this.form.subjectId = this.subjectList[0].value;
  857 + }
  858 + } else {
  859 + this.$message.error(message);
  860 + }
  861 + },
10 862  
11   -<style>
  863 +
  864 + },
  865 +};
  866 +</script>
12 867  
  868 +<style lang="scss" scoped>
  869 +.red {
  870 + color: #f30;
  871 +}
  872 +.content {
  873 + width: 100%;
  874 + box-sizing: border-box;
  875 + padding: 0 50px;
  876 + .ml-20 {
  877 + margin-left: 20px;
  878 + }
  879 + .btn-box {
  880 + text-align: right;
  881 + margin-left: 140px;
  882 + }
  883 +}
  884 +.dia-content {
  885 + .dia-tit {
  886 + font-size: 20px;
  887 + color: #333;
  888 + font-weight: 700;
  889 + text-align: center;
  890 + }
  891 + .add-type {
  892 + display: flex;
  893 + }
  894 + .add-btn {
  895 + margin-left: 20px;
  896 + }
  897 +}
  898 +.el-message-box {
  899 + :deep(.el-button--default) {
  900 + color: #fff;
  901 + }
  902 +}
  903 +.add-box {
  904 + display: flex;
  905 + justify-content: center;
  906 + align-items: center;
  907 + .add-question {
  908 + display: flex;
  909 + justify-content: center;
  910 + align-items: center;
  911 + font-size: 16px;
  912 + font-weight: bolder;
  913 + padding: 2px;
  914 + cursor: pointer;
  915 + .s1 {
  916 + margin-left: 6px;
  917 + }
  918 + :deep(.el-icon-plus) {
  919 + font-size: 24px;
  920 + font-weight: 900;
  921 + }
  922 + :deep(.el-button--mini.is-circle) {
  923 + padding: 3px;
  924 + }
  925 + }
  926 +}
  927 +.dialog-footer {
  928 + text-align: center;
  929 + :deep(.el-button) {
  930 + border-radius: 20px;
  931 + padding: 8px 20px 7px;
  932 + margin: 0 12px;
  933 + }
  934 +}
  935 +.question-title {
  936 + line-height: 40px;
  937 + .ipt {
  938 + width: 300px;
  939 + margin: 0 16px 0 10px;
  940 + :deep(.el-input__inner) {
  941 + border-radius: 20px;
  942 + border-color: #667ffd;
  943 + background: rgba($color: #667ffd, $alpha: 0.05);
  944 + }
  945 + }
  946 + .delete {
  947 + margin-right: 8px;
  948 + }
  949 + .title-txt {
  950 + margin-right: 20px;
  951 + font-size: 16px;
  952 + font-weight: 700;
  953 + }
  954 +}
  955 +.el-input-number {
  956 + width: 140px;
  957 +}
  958 +.answer-box {
  959 + .answer-s {
  960 + display: inline-block;
  961 + width: 30px;
  962 + height: 30px;
  963 + border: 1px solid #e2e2e2;
  964 + border-radius: 3px;
  965 + margin: 0 6px;
  966 + font-size: 16px;
  967 + color: #333;
  968 + text-align: center;
  969 + line-height: 30px;
  970 + &.active {
  971 + background: #5e78fa;
  972 + border-color: #5e78fa;
  973 + color: #fff;
  974 + }
  975 + }
  976 +}
  977 +.questions-ul {
  978 + border-left: 1px solid #e2e2e2;
  979 + border-top: 1px solid #e2e2e2;
  980 + margin: 12px 0;
  981 +}
  982 +.sub-questions {
  983 + width: 100%;
  984 + display: flex;
  985 + border-bottom: 1px solid #e2e2e2;
  986 + & > div {
  987 + min-height: 40px;
  988 + padding: 5px;
  989 + flex-shrink: 0;
  990 + border-right: 1px solid #e2e2e2;
  991 + display: flex;
  992 + justify-content: center;
  993 + align-items: center;
  994 + }
  995 + .qs-num {
  996 + width: 80px;
  997 + }
  998 + .qs-type {
  999 + width: 160px;
  1000 + }
  1001 + .qs-score,
  1002 + .qs-partScore {
  1003 + width: 160px;
  1004 + }
  1005 + .qs-options {
  1006 + flex: 1;
  1007 + }
  1008 + .qs-set {
  1009 + width: 80px;
  1010 + }
  1011 + .qs-options2 {
  1012 + text-align: left;
  1013 + justify-content: flex-start;
  1014 + padding-left: 20px;
  1015 + .answer-s {
  1016 + cursor: pointer;
  1017 + }
  1018 + }
  1019 + :deep(.el-select) {
  1020 + .el-input__inner {
  1021 + border-radius: 20px;
  1022 + border-color: #667ffd;
  1023 + width: 150px;
  1024 + height: 32px;
  1025 + line-height: 32px;
  1026 + background: rgba($color: #667ffd, $alpha: 0.05);
  1027 + }
  1028 + .el-input__icon {
  1029 + line-height: 32px;
  1030 + }
  1031 + }
  1032 +}
13 1033 </style>
14 1034 \ No newline at end of file
... ...
src/views/examinationPaper/edit.vue
... ... @@ -5,12 +5,349 @@
5 5 <span>修改答案</span>
6 6 </template>
7 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 + <el-input
  20 + class="ipt"
  21 + v-model.trim="question.questionTitle"
  22 + placeholder="填写大题名称"
  23 + ></el-input>
  24 + <span>共 {{ setScore(question) }} 分</span>
  25 + </p>
  26 + <ul class="questions-ul">
  27 + <li class="sub-questions">
  28 + <div class="qs-num">题号</div>
  29 + <div class="qs-score">分数</div>
  30 + <div class="qs-options qs-options2">选项设置</div>
  31 + </li>
  32 + <li
  33 + class="sub-questions"
  34 + v-for="(subQuestions, indexs) in question.subQuestions"
  35 + :key="indexs"
  36 + >
  37 + <div class="qs-num">{{ subQuestions.questionIndex }}</div>
  38 + <div class="qs-type">
  39 + {{ setSubPro(subQuestions.questionType) }}
  40 + </div>
  41 + <div class="qs-score">
  42 + <el-input-number
  43 + class="number-ipt"
  44 + size="medium"
  45 + :min="1"
  46 + :max="200"
  47 + :precision="2"
  48 + v-model="subQuestions.score"
  49 + label="单题分值"
  50 + ></el-input-number>
  51 + </div>
  52 + <div class="qs-options qs-options2">
  53 + <p v-if="subQuestions.questionType == 5">--</p>
  54 + <p v-if="subQuestions.questionType == 4" class="answer-box">
  55 + <span
  56 + class="answer-s"
  57 + :class="subQuestions.correctAnswer == 1 ? 'active' : ''"
  58 + @click="subQuestions.correctAnswer = 1"
  59 + >✓</span
  60 + >
  61 + <span
  62 + class="answer-s"
  63 + :class="subQuestions.correctAnswer == 2 ? 'active' : ''"
  64 + @click="subQuestions.correctAnswer = 2"
  65 + >✗</span
  66 + >
  67 + </p>
  68 + <p v-if="subQuestions.questionType == 3" class="answer-box">
  69 + <span
  70 + class="answer-s"
  71 + v-for="option in subQuestions.answerOptions"
  72 + :class="
  73 + subQuestions.correctAnswer.includes(option) ? 'active' : ''
  74 + "
  75 + :key="option"
  76 + @click="changAnswer(subQuestions, option)"
  77 + >{{ option }}</span
  78 + >
  79 + </p>
  80 + <p v-if="subQuestions.questionType == 2" class="answer-box">
  81 + <span
  82 + class="answer-s"
  83 + v-for="option in subQuestions.answerOptions"
  84 + :class="subQuestions.correctAnswer == option ? 'active' : ''"
  85 + :key="option"
  86 + @click="subQuestions.correctAnswer = option"
  87 + >{{ option }}</span
  88 + >
  89 + </p>
  90 + </div>
  91 + </li>
  92 + </ul>
  93 + </div>
  94 + <div class="btn-box">
  95 + <el-button type="danger" plain round @click="linkBack">取消</el-button>
  96 + <el-button type="primary" round @click="save">保存</el-button>
  97 + </div>
  98 + </div>
8 99 </div>
9 100 </template>
10 101  
11 102 <script>
12   -export default {};
  103 +export default {
  104 + data() {
  105 + return {
  106 + form: {
  107 + //答题卡详情
  108 + title: "",
  109 + tag: "",
  110 + subjectId: "",
  111 + examsDuration: 90,
  112 + gradeName: "",
  113 + share: 1,
  114 + questionList: [],
  115 + },
  116 + };
  117 + },
  118 + computed: {
  119 + allScore: function () {
  120 + let score = 0;
  121 + this.form.questionList.map((item) => {
  122 + score += item.subQuestions.reduce((a, b) => {
  123 + return a + Number(b.score);
  124 + }, 0);
  125 + }, 0);
  126 + return Number(score).toFixed(2);
  127 + },
  128 + },
  129 + created() {
  130 + this.form = this.$route.query.form && JSON.parse(this.$route.query.form);
  131 + },
  132 + methods: {
  133 + linkBack() {
  134 + this.$router.push({
  135 + path: "/examinationPaper",
  136 + });
  137 + },
  138 + setSubPro(type) {
  139 + let tit;
  140 + switch (type) {
  141 + case 2:
  142 + tit = "单选题";
  143 + break;
  144 + case 3:
  145 + tit = "多选题";
  146 + break;
  147 + case 4:
  148 + tit = "判断题";
  149 + break;
  150 + case 5:
  151 + tit = "主观题";
  152 + break;
  153 + }
  154 + return tit;
  155 + },
  156 + setBigNum(num) {
  157 + let txt = "";
  158 + let bigNum = [
  159 + "一",
  160 + "二",
  161 + "三",
  162 + "四",
  163 + "五",
  164 + "六",
  165 + "七",
  166 + "八",
  167 + "九",
  168 + "十",
  169 + "十一",
  170 + "十二",
  171 + "十三",
  172 + "十四",
  173 + "十五",
  174 + "十六",
  175 + "十七",
  176 + "十八",
  177 + "十九",
  178 + "二十",
  179 + ];
  180 + txt = bigNum[num];
  181 +
  182 + return txt;
  183 + },
  184 + setScore(question) {
  185 + let score = question.subQuestions.reduce((a, b) => {
  186 + return a + b.score;
  187 + }, 0);
  188 + return score;
  189 + },
  190 + changAnswer(sub, option) {
  191 + //设置多选答案
  192 + let str = new RegExp(option, "g");
  193 + if (sub.correctAnswer?.includes(option)) {
  194 + sub.correctAnswer = sub.correctAnswer.replace(str, "");
  195 + } else {
  196 + let arrs = (sub.correctAnswer && sub.correctAnswer.split("")) || [];
  197 + arrs.push(option);
  198 + sub.correctAnswer = arrs.sort().join("");
  199 + }
  200 + },
  201 + save(){
  202 + //删除答题卡
  203 + // const { data, code, message } = await this.$request.updateAnswerSheet({...this.form});
  204 + // if (code == 0) {
  205 + this.$router.push({
  206 + path:"/examinationPaper"
  207 + })
  208 + // } else {
  209 + // this.$message.error(message);
  210 + // }
  211 + }
  212 + },
  213 +};
13 214 </script>
14 215  
15   -<style>
  216 +<style lang="scss" scoped>
  217 +.content {
  218 + width: 100%;
  219 + box-sizing: border-box;
  220 + padding: 0 50px;
  221 + .ml-20 {
  222 + margin-left: 20px;
  223 + }
  224 + .btn-box {
  225 + text-align: right;
  226 + margin-left: 140px;
  227 + }
  228 + .tips {
  229 + height: 48px;
  230 + line-height: 48px;
  231 + padding: 0 16px;
  232 + border: 1px solid #fac7cc;
  233 + background-color: #ffebec;
  234 + font-size: 14px;
  235 + color: #fd9795;
  236 + margin: 10px 0 20px 0;
  237 + .fa-bell-o {
  238 + font-size: 18px;
  239 + margin-right: 5px;
  240 + }
  241 + }
  242 +}
  243 +.answer-title {
  244 + text-align: center;
  245 + font-size: 20px;
  246 + color: #333;
  247 + font-weight: 700;
  248 + padding: 20px 0 0 0;
  249 + .totals {
  250 + font-size: 16px;
  251 + color: #888;
  252 + font-weight: normal;
  253 + }
  254 +}
  255 +.question-title {
  256 + line-height: 40px;
  257 + .ipt {
  258 + width: 300px;
  259 + margin: 0 16px 0 10px;
  260 + :deep(.el-input__inner) {
  261 + border-radius: 20px;
  262 + border-color: #667ffd;
  263 + background: rgba($color: #667ffd, $alpha: 0.05);
  264 + }
  265 + }
  266 + .delete {
  267 + margin-right: 8px;
  268 + }
  269 + .title-txt {
  270 + margin-right: 20px;
  271 + font-size: 16px;
  272 + font-weight: 700;
  273 + }
  274 +}
  275 +.el-input-number {
  276 + width: 140px;
  277 +}
  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 +}
  297 +.questions-ul {
  298 + border-left: 1px solid #e2e2e2;
  299 + border-top: 1px solid #e2e2e2;
  300 + margin: 12px 0;
  301 +}
  302 +.sub-questions {
  303 + width: 100%;
  304 + display: flex;
  305 + border-bottom: 1px solid #e2e2e2;
  306 + & > div {
  307 + min-height: 40px;
  308 + padding: 5px;
  309 + flex-shrink: 0;
  310 + border-right: 1px solid #e2e2e2;
  311 + display: flex;
  312 + justify-content: center;
  313 + align-items: center;
  314 + }
  315 + .qs-num {
  316 + width: 80px;
  317 + }
  318 + .qs-type {
  319 + width: 160px;
  320 + }
  321 + .qs-score,
  322 + .qs-partScore {
  323 + width: 160px;
  324 + }
  325 + .qs-options {
  326 + flex: 1;
  327 + }
  328 + .qs-set {
  329 + width: 80px;
  330 + }
  331 + .qs-options2 {
  332 + text-align: left;
  333 + justify-content: flex-start;
  334 + padding-left: 20px;
  335 + .answer-s {
  336 + cursor: pointer;
  337 + }
  338 + }
  339 + :deep(.el-select) {
  340 + .el-input__inner {
  341 + border-radius: 20px;
  342 + border-color: #667ffd;
  343 + width: 150px;
  344 + height: 32px;
  345 + line-height: 32px;
  346 + background: rgba($color: #667ffd, $alpha: 0.05);
  347 + }
  348 + .el-input__icon {
  349 + line-height: 32px;
  350 + }
  351 + }
  352 +}
16 353 </style>
17 354 \ No newline at end of file
... ...
src/views/examinationPaper/index.vue
... ... @@ -11,7 +11,7 @@
11 11 icon="el-icon-plus"
12 12 plain
13 13 circle
14   - @click="toAdd"
  14 + @click="toAdd({})"
15 15 ></el-button>
16 16 </el-tooltip>
17 17 </template>
... ... @@ -201,6 +201,27 @@ export default {
201 201 teacher: "张老师",
202 202 date: "2022-11-04 18:09:49",
203 203 share: 1,
  204 + score: 100,
  205 + gradeName:"二年级",
  206 + subjectId:1,
  207 + examsDuration:4800,
  208 + questionList: [
  209 + {
  210 + questionTitle: "f",
  211 + score: 1,
  212 + subQuestions: [
  213 + {
  214 + questionIndex: 1,
  215 + questionType: 2,
  216 + score: 1,
  217 + partScore: 0,
  218 + selectNum: 4,
  219 + answerOptions: ["A", "B", "C", "D"],
  220 + correctAnswer: "B",
  221 + },
  222 + ],
  223 + },
  224 + ],
204 225 },
205 226 {
206 227 title: "数学样例试卷202211-4180949",
... ... @@ -212,6 +233,27 @@ export default {
212 233 teacher: "张老师",
213 234 date: "2022-11-04 18:09:49",
214 235 share: 1,
  236 + score: 100,
  237 + gradeName:"二年级",
  238 + subjectId:1,
  239 + examsDuration:3000,
  240 + questionList: [
  241 + {
  242 + questionTitle: "f",
  243 + score: 1,
  244 + subQuestions: [
  245 + {
  246 + questionIndex: 2,
  247 + questionType: 3,
  248 + score: 1,
  249 + partScore: 0,
  250 + selectNum: 4,
  251 + answerOptions: ["A", "B", "C", "D"],
  252 + correctAnswer: "A,C",
  253 + },
  254 + ],
  255 + },
  256 + ],
215 257 },
216 258 ],
217 259 shareForm: {
... ... @@ -226,25 +268,27 @@ export default {
226 268 },
227 269 methods: {
228 270 toAdd(query) {
229   - this.$router.push({
  271 + let routerItem = {
230 272 path: "/examinationPaperAdd",
231   - query:query&&{...query}
232   - });
  273 + };
  274 + query ? (routerItem["query"] = { ...query }) : "";
  275 + this.$router.push(routerItem);
233 276 },
234 277 toEdit(item) {
235 278 this.$router.push({
236 279 path: "/examinationPaperEdit",
237 280 query: {
238   - id: item.id,
  281 + form: JSON.stringify(item),
239 282 },
240 283 });
241 284 },
242   - handleDropdownClick(value, item) {//更多
  285 + handleDropdownClick(value, item) {
  286 + //更多
243 287 const that = this;
244 288 switch (value) {
245 289 case 1:
246 290 //授课端同步
247   - that.syncMeg(item)
  291 + that.syncMeg(item);
248 292 break;
249 293 case 2:
250 294 //修改分享范围
... ... @@ -255,15 +299,16 @@ export default {
255 299 break;
256 300 case 3:
257 301 //复制
258   - that.toAdd()
  302 + that.toAdd({ type: 2, form: JSON.stringify(item), });
259 303 break;
260 304 case 4:
261 305 //归档
262   - that.recovery(item)
  306 + that.recovery(item);
263 307 break;
264 308 }
265 309 },
266   - async syncMeg() {//同步
  310 + async syncMeg() {
  311 + //同步
267 312 // const { data, code, message } = await this.$request.fetchAnswerList({
268 313 // ...this.shareForm,
269 314 // });
... ... @@ -274,7 +319,8 @@ export default {
274 319 // this.$message.error(message);
275 320 // }
276 321 },
277   - async saveShare() {//修改分享范围
  322 + async saveShare() {
  323 + //修改分享范围
278 324 // const { data, code, message } = await this.$request.fetchAnswerList({
279 325 // ...this.shareForm,
280 326 // });
... ... @@ -288,20 +334,22 @@ export default {
288 334 // this.$message.error(message);
289 335 // }
290 336 },
291   - async recovery(item) {//归档
  337 + async recovery(item) {
  338 + //归档
292 339 // const { data, code, message } = await this.$request.fetchAnswerList({
293 340 // ...this.shareForm,
294 341 // });
295 342 // if (code === 0) {
296   - this.tableData = this.tableData.filter(items=>{
297   - return items.id != item.id
298   - })
  343 + this.tableData = this.tableData.filter((items) => {
  344 + return items.id != item.id;
  345 + });
299 346 // } else {
300 347 // this.$message.error(message);
301 348 // }
302 349 },
303 350  
304   - async changClazz() {//切换班级
  351 + async changClazz() {
  352 + //切换班级
305 353 await this._QuerySubjectList();
306 354 this._QueryData();
307 355 },
... ... @@ -348,7 +396,8 @@ export default {
348 396 this.$message.error(message);
349 397 }
350 398 },
351   - async _QueryData(type) {//获取答题卡列表
  399 + async _QueryData(type) {
  400 + //获取答题卡列表
352 401 let query = {};
353 402 if (!type) {
354 403 this.query.title = "";
... ... @@ -387,73 +436,6 @@ export default {
387 436 </script>
388 437  
389 438 <style scoped lang="scss">
390   -.answer-header {
391   - padding: 16px 40px 12px 20px;
392   - display: flex;
393   - justify-content: space-between;
394   - align-items: center;
395   - .btn-box {
396   - display: flex;
397   - }
398   -}
399   -.sel-box {
400   - display: flex;
401   - align-items: center;
402   - flex-wrap: nowrap;
403   - .sel {
404   - width: 8%;
405   - min-width: 90px;
406   - margin-right: 20px;
407   - }
408   - :deep(.el-input__inner) {
409   - border-radius: 20px;
410   - border: 1px solid #e2e2e2;
411   - height: 36px;
412   - line-height: 34px;
413   - }
414   - :deep(.el-input__icon) {
415   - line-height: 34px;
416   - }
417   - :deep(.el-date-editor.el-input),
418   - :deep(.el-date-editor.el-input__inner) {
419   - width: 200px;
420   - }
421   - .input-with-select {
422   - width: 200px;
423   - height: 36px;
424   - margin-right: 50px;
425   - border-radius: 20px;
426   - border: 1px solid #e2e2e2;
427   - box-sizing: border-box;
428   - :deep(.el-input__inner) {
429   - border-radius: 20px;
430   - border: none;
431   - height: 34px;
432   - line-height: 34px;
433   - }
434   - :deep(.el-input-group__append, .el-input-group__prepend) {
435   - border: none;
436   - background: transparent;
437   - }
438   - }
439   - .d1 {
440   - margin-left: 30px;
441   - }
442   - .p1 {
443   - flex: 1;
444   - .s1 {
445   - margin-left: 36px;
446   - cursor: pointer;
447   - color: #7f7f7f;
448   - &:hover {
449   - color: #409eff;
450   - }
451   - &.active {
452   - color: #667ffd;
453   - }
454   - }
455   - }
456   -}
457 439 .tips {
458 440 display: flex;
459 441 padding-left: 30px;
... ...
src/views/examinationPaper/recycle.vue
1 1 <template>
2 2 <div>
3   - <back-box>
  3 + <back-box>
4 4 <template slot="title">
5   - <span>归档</span>
  5 + <span>已归档答题卡</span>
6 6 </template>
7 7 </back-box>
  8 + <div class="answer-header">
  9 + <div class="sel-box">
  10 + <el-select
  11 + class="sel"
  12 + v-model="query.gradeName"
  13 + placeholder=""
  14 + @change="changeGrade"
  15 + >
  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
  25 + class="sel"
  26 + v-model="query.type"
  27 + placeholder="选择类型"
  28 + @change="_QueryData()"
  29 + >
  30 + <el-option label="全部" value=""></el-option>
  31 + <el-option
  32 + v-for="item in typeList"
  33 + :key="item.value"
  34 + :label="item.label"
  35 + :value="item.value"
  36 + >{{ item.label }}
  37 + </el-option>
  38 + </el-select>
  39 + <el-select
  40 + class="sel"
  41 + v-model="query.subjectId"
  42 + placeholder="选择科目"
  43 + @change="_QueryData()"
  44 + >
  45 + <el-option label="全部" value=""></el-option>
  46 + <el-option
  47 + v-for="item in subjectList"
  48 + :key="item.value"
  49 + :label="item.label"
  50 + :value="item.value"
  51 + >
  52 + </el-option>
  53 + </el-select>
  54 + <el-input
  55 + placeholder="输入试卷名称"
  56 + v-model="query.title"
  57 + class="input-with-select"
  58 + @keyup.enter.native="_QueryData(true)"
  59 + >
  60 + <el-button
  61 + slot="append"
  62 + icon="el-icon-search"
  63 + @click="_QueryData(true)"
  64 + ></el-button>
  65 + </el-input>
  66 + </div>
  67 + </div>
  68 + <ul class="content">
  69 + <li class="item" v-for="item in tableData" :key="item.id">
  70 + <div class="pic-box">
  71 + <p class="i-box"><i class="fa fa-map-o"></i></p>
  72 + <p class="ids">{{ item.id }}</p>
  73 + </div>
  74 + <div class="info">
  75 + <p class="title">
  76 + {{ item.title }} <span class="label">{{ item.typeName }}</span>
  77 + </p>
  78 + <p class="num">
  79 + {{ item.gradeName }}
  80 + <em class="s-line">|</em>
  81 + 总题数:{{ item.answerNum }}
  82 + <em class="s-line">|</em>
  83 + 预计时长:{{ item.time }}
  84 + <em class="s-line">|</em>
  85 + </p>
  86 + <p class="person">
  87 + {{ item.teacher }}<em class="s-line">|</em
  88 + ><span class="date">{{ item.date }}</span>
  89 + </p>
  90 + </div>
  91 + <div class="btn-box">
  92 + <el-tooltip effect="dark" content="使用" placement="bottom">
  93 + <el-button
  94 + class="edit"
  95 + type="info"
  96 + size="mini"
  97 + circle
  98 + icon="fa fa-mail-reply"
  99 + @click="have(item)"
  100 + ></el-button>
  101 + </el-tooltip>
  102 + <el-popconfirm title="确定删除这张答题卡吗?" @confirm="remove(item)">
  103 + <el-button
  104 + slot="reference"
  105 + class="delete"
  106 + type="info"
  107 + size="mini"
  108 + circle
  109 + icon="el-icon-delete"
  110 + ></el-button>
  111 + </el-popconfirm>
  112 + </div>
  113 + </li>
  114 + </ul>
8 115 </div>
9 116 </template>
10 117  
11 118 <script>
12 119 export default {
13   -
14   -}
  120 + data() {
  121 + return {
  122 + query: {
  123 + gradeName: "二年级",
  124 + type: "",
  125 + subjectId: "",
  126 + title: "",
  127 + },
  128 + gradeList: ["二年级"],
  129 + typeList: [
  130 + { label: "随堂问", value: 1 },
  131 + { label: "即使测", value: 2 },
  132 + ],
  133 + subjectList: [],
  134 + tableData: [
  135 + {
  136 + title: "数学样例试卷202211-324654",
  137 + id: "1062837",
  138 + gradeName: "二年级",
  139 + typeName: "周测",
  140 + answerNum: 45,
  141 + time: 90,
  142 + aboutClazz: [203, 204],
  143 + teacher: "张老师",
  144 + date: "2022-11-04 18:09:49",
  145 + share: 1,
  146 + },
  147 + {
  148 + title: "数学样例试卷202211-4180949",
  149 + id: "1062838",
  150 + gradeName: "二年级",
  151 + typeName: "周测",
  152 + answerNum: 45,
  153 + time: 90,
  154 + aboutClazz: [203, 204],
  155 + teacher: "张老师",
  156 + date: "2022-11-04 18:09:49",
  157 + share: 1,
  158 + },
  159 + ],
  160 + total: 0,
  161 + };
  162 + },
  163 + methods: {
  164 + have(obj) {
  165 + //删除答题卡
  166 + // const { data, code, message } = await this.$request.useAnswerSheet();
  167 + // if (code == 0) {
  168 + this.tableData = this.tableData.filter(item=>{
  169 + return obj.if != item.id
  170 + })
  171 + // } else {
  172 + // this.$message.error(message);
  173 + // }
  174 + },
  175 + remove(obj) {
  176 + //删除答题卡
  177 + // const { data, code, message } = await this.$request.removeAnswerSheet();
  178 + // if (code == 0) {
  179 + this.tableData = this.tableData.filter(item=>{
  180 + return obj.if != item.id
  181 + })
  182 + // } else {
  183 + // this.$message.error(message);
  184 + // }
  185 + },
  186 + async _QueryData(type) {
  187 + //获取答题卡列表
  188 + let query = {};
  189 + if (!type) {
  190 + this.query.title = "";
  191 + query = { ...this.query };
  192 + } else {
  193 + query = { title: this.query.title };
  194 + this.query.type = "";
  195 + this.query.subjectId = "";
  196 + }
  197 + for (let key in query) {
  198 + if (!query[key]) {
  199 + query[key] = null;
  200 + }
  201 + }
  202 + this.loading = true;
  203 + const { data, code, message } = await this.$request.fetchAnswerList({
  204 + ...query,
  205 + });
  206 + this.loading = false;
  207 + if (code === 0) {
  208 + this.total = data.total;
  209 + this.tableData = (data.list && [...data.list]) || [];
  210 + } else {
  211 + this.$message.error(message);
  212 + }
  213 + },
  214 + async changeGrade() {
  215 + this._QueryData();
  216 + this._GradeList();
  217 + this._QuerySubjectList();
  218 + },
  219 + async _GradeList() {
  220 + //查询年级列表
  221 + const { data, code, message } = await this.$request.fetchGradeList();
  222 + if (code == 0) {
  223 + this.gradeList = [...data.gradeNames] || [];
  224 + this.query.gradeName = this.gradeList[0];
  225 + this._QuerySubjectList(this.gradeList[0]);
  226 + } else {
  227 + this.$message.error(message);
  228 + }
  229 + },
  230 + async _QuerySubjectList(grade, dont) {
  231 + //查询科目列表
  232 + let param = {};
  233 + if (grade) {
  234 + param.gradeName = grade;
  235 + }
  236 + const { data, code, message } = await this.$request.fetchSubjectList(
  237 + param
  238 + );
  239 + if (code === 0) {
  240 + this.subjectList = data.list.map((item) => {
  241 + return {
  242 + value: item.subjectId,
  243 + label: item.subjectName,
  244 + };
  245 + });
  246 + } else {
  247 + this.$message.error(message);
  248 + }
  249 + },
  250 + },
  251 +};
15 252 </script>
16 253  
17   -<style>
18   -
  254 +<style lang="scss" scoped>
  255 +.answer-header {
  256 + .sel-box {
  257 + .sel {
  258 + min-width: 160px;
  259 + }
  260 + }
  261 +}
  262 +.content {
  263 + margin: 0 20px;
  264 + background: #f8f8f8;
  265 + padding: 12px;
  266 + border-radius: 20px;
  267 + .item {
  268 + display: flex;
  269 + align-items: center;
  270 + width: 100%;
  271 + overflow: hidden;
  272 + box-sizing: border-box;
  273 + padding: 12px;
  274 + border-radius: 20px;
  275 + background: #fff;
  276 + margin-bottom: 12px;
  277 + &:last-of-type {
  278 + margin-bottom: 0;
  279 + }
  280 + .pic-box {
  281 + width: 80px;
  282 + height: 80px;
  283 + border-radius: 10px;
  284 + margin-right: 10px;
  285 + flex-shrink: 0;
  286 + background: #d7d7d7;
  287 + text-align: center;
  288 + color: #fff;
  289 + font-weight: 500;
  290 + .i-box {
  291 + padding-top: 10px;
  292 + font-size: 32px;
  293 + margin-bottom: 3px;
  294 + }
  295 + }
  296 + .info {
  297 + height: 80px;
  298 + flex: 1;
  299 + overflow: hidden;
  300 + display: flex;
  301 + flex-direction: column;
  302 + justify-content: space-between;
  303 + .s-line {
  304 + padding: 0 5px;
  305 + color: #e2e2e2;
  306 + }
  307 + .title {
  308 + font-size: 16px;
  309 + color: #222;
  310 + font-weight: 500;
  311 + .label {
  312 + display: inline-block;
  313 + font-size: 12px;
  314 + color: #2e9afe;
  315 + line-height: 16px;
  316 + padding: 0 10px;
  317 + border: 1px solid #2e9afe;
  318 + border-radius: 10px;
  319 + transform: translateY(-2px);
  320 + }
  321 + }
  322 + .person {
  323 + color: #666;
  324 + }
  325 + }
  326 + .btn-box {
  327 + flex-shrink: 0;
  328 + .edit {
  329 + margin-right: 12px;
  330 + }
  331 + }
  332 + }
  333 +}
19 334 </style>
20 335 \ No newline at end of file
... ...
src/views/layout/header/header.vue
... ... @@ -126,7 +126,6 @@ export default {
126 126 },
127 127 handleCommand(command) {
128 128 //刷新权限跳转首页
129   - this.$message("click on item " + command);
130 129 this.$store.dispatch("permissions", this);
131 130 },
132 131 logOut() {
... ...
src/views/layout/layout.vue
... ... @@ -22,6 +22,7 @@ import layoutAside from &quot;./aside/aside&quot;;
22 22 import layoutHeader from "./header/header";
23 23 import Bottom from "./Footer/bottom";
24 24 import langSelect from "../../components/lang/langSelect";
  25 +import { getURLParams } from "@/utils";
25 26  
26 27 export default {
27 28 name: "layout",
... ... @@ -31,6 +32,39 @@ export default {
31 32 langSelect,
32 33 layoutAside,
33 34 },
  35 + data() {
  36 + return {
  37 + code: "",
  38 + };
  39 + },
  40 + created() {
  41 + this.code = getURLParams("code") || "";
  42 + if (this.code) {
  43 + localStorage.setItem("code",this.code)
  44 + this._LoginCheck();
  45 + }
  46 + },
  47 + methods: {
  48 + async _LoginCheck() {
  49 + let params = {};
  50 + if (this.code) {
  51 + params = {
  52 + code: this.code,
  53 + };
  54 + }
  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 + }
  66 + },
  67 + },
34 68 };
35 69 </script>
36 70  
... ... @@ -81,7 +115,7 @@ ul.el-menu {
81 115  
82 116 #elmain {
83 117 background-color: #fff;
84   - padding:0;
  118 + padding: 0;
85 119 }
86 120  
87 121 .avatar-uploader .el-upload {
... ...
src/views/login/index.vue
... ... @@ -101,8 +101,12 @@ export default {
101 101 { required: true, message: "请输入账号密码",trigger: "blur" }
102 102 ]
103 103 },
  104 + url: "",
104 105 };
105 106 },
  107 + created() {
  108 + this.url = this.$route.query?.url || "";
  109 + },
106 110 methods: {
107 111 showPwd() {
108 112 if (this.passwordType === "password") {
... ... @@ -115,7 +119,6 @@ export default {
115 119 });
116 120 },
117 121 submitForm() {
118   - let that = this;
119 122 if (this.loginForm.username === "" || this.loginForm.password === "") {
120 123 this.$message({
121 124 showClose: true,
... ... @@ -124,7 +127,7 @@ export default {
124 127 });
125 128 return false;
126 129 } else {
127   - this.$store.dispatch("Login",this)
  130 + this.$store.dispatch("Login",{...this.loginForm,url:this.url})
128 131 }
129 132 },
130 133 },
... ...