diff --git a/router b/router index 24f40e7..d0b6f85 100644 --- a/router +++ b/router @@ -1,258 +1,22 @@ -[ //测试用,后续后端获取 - { - path: "/examinationPaper", - iconCls: "fa fa-file-text", // 图标样式class - name: "备题组卷", - component: Layout, - alone: true, - children: [ - { - path: "/examinationPaper", - iconCls: "fa fa-file-text", // 图标样式class - name: "", - component: ExaminationPaper, - children: [] - }, - { - path: "/examinationPaperAdd", - iconCls: "", // 图标样式class - name: "添加答题卡", - component: ExaminationPaperAdd, - children: [] - }, - { - path: "/examinationPaperEdit", - iconCls: "", // 图标样式class - name: "修改答题卡", - component: ExaminationPaperEdit, - children: [] - }, - { - path: "/examinationPaperRecycle", - iconCls: "", // 图标样式class - name: "已归档答题卡", - component: ExaminationPaperRecycle, - children: [] - }, - ] - }, - { - path: "/ask", - iconCls: "fa fa-bar-chart", // 图标样式class - name: "随堂问报表", - component: Layout, - alone: true, - children: [ - { - path: "/ask", - iconCls: "fa fa-bar-chart", // 图标样式class - name: "", - component: Ask, - children: [] - - }, - { - path: "/askAnalysis", - iconCls: "", // 图标样式class - name: "随堂问报表分析", - component: AskAnalysis, - children: [] - } - ] - }, - { - path: "/test", - iconCls: "fa fa-pie-chart", // 图标样式class - name: "即时测报表", - component: Layout, - alone: true, - children: [ - { - path: "/test", - iconCls: "fa fa-pie-chart", // 图标样式class - name: "", - component: Test, - children: [] - }, - { - path: "/testAnalysis", - iconCls: "", // 图标样式class - name: "即时测报表分析", - component: TestAnalysis, - children: [] - } - - ] - }, - { - path: "/portrait", - iconCls: "fa fa-users", // 图标样式class - name: "学生画像", - component: Layout, - alone: true, - children: [ - { - path: "/portrait", - iconCls: "fa fa-users", // 图标样式class - name: "", - component: Portrait, - children: [] - } - ] - }, - - { - path: "/setUpConglomerate", - iconCls: "fa fa-building", // 图标样式class - name: "学校管理", - component: Layout, - alone: true, - children: [ - { - path: "/setUpConglomerate", - iconCls: "fa fa-building", - name: '集团管理', - component: SetUpConglomerate, - children: [] - }, - ] - }, - { - path: "/setUpAccount", - iconCls: "fa fa-id-card-o", // 图标样式class - name: "账号管理", - component: Layout, - alone: true, - children: [ - { - path: "/setUpAccount", - iconCls: "fa fa-id-card-o", - name: '', - component: SetUpAccount, - children: [] - }, - ] - }, - { - path: "/", - iconCls: "fa fa-cog", - name: '学校设置', - component: Layout, - children: [ - { - path: "/setUpSchool", - iconCls: "fa fa-calculator", - name: '学校设置', - component: SetUpSchool, - children: [] - }, - { - path: "/setUpTeacher", - iconCls: "fa fa-male", - name: '教师管理', - component: SetUpTeacher, - children: [] - }, - { - path: "/setUpStudent", - iconCls: "fa fa-mortar-board", - name: '学生管理', - component: SetUpStudent, - children: [] - }, - ] - }, - { - path: "/card", - iconCls: "fa fa-id-card", // 图标样式class - name: "发卡记录", - component: Layout, - alone: true, - children: [ - { - path: "/card", - iconCls: "fa fa-id-card", // 图标样式class - name: "", - component: Card, - children: [] - } - ] - }, - { - path: "/device", - iconCls: "fa fa-dashboard", // 图标样式class - name: "设备状态", - component: Layout, - alone: true, - children: [ - { - path: "/device", - iconCls: "fa fa-dashboard", // 图标样式class - name: "", - component: Device, - children: [] - } - ] - }, - { - path: "/analysis", - iconCls: "fa fa-area-chart", // 图标样式class - name: "使用分析", - component: Layout, - alone: true, - children: [ - { - path: "/analysis", - iconCls: "fa fa-area-chart", // 图标样式class - name: "", - component: Analysis, - children: [] - } - ] - }, - { - path: "/down", - iconCls: "fa fa-download", // 图标样式class - name: "软件下载", - component: Layout, - alone: true, - children: [ - { - path: "/down", - iconCls: "fa fa-download", // 图标样式class - name: "发卡软件", - component: Down, - children: [] - }, - { - path: "/downClient", - iconCls: "", // 图标样式class - name: "授课端软件", - component: DownClient, - children: [] - } - ] - }, - { - path: "/dataSync", - iconCls: "fa fa-random", // 图标样式class - name: "数据同步", - component: Layout, - alone: true, - children: [ - { - path: "/dataSync", - iconCls: "fa fa-random", // 图标样式class - name: "", - component: DataSync, - children: [] - } - ] - }, - { - path: "*", - redirect: "/404", - hidden: true, - children: [] - } +[ + "examinationPaper", + "examinationPaperAdd", + "examinationPaperEdit", + "examinationPaperRecycle", + "ask", + "askAnalysis", + "test", + "testAnalysis", + "portrait", + "setUpConglomerate", + "setUpAccount", + "setUpSchool", + "setUpTeacher", + "setUpStudent", + "card", + "device", + "analysis", + "down", + "downClient", + "dataSync" ] \ No newline at end of file diff --git a/src/api/apis/answerSheet.js b/src/api/apis/answerSheet.js index 698f09b..d25ecd6 100644 --- a/src/api/apis/answerSheet.js +++ b/src/api/apis/answerSheet.js @@ -1,11 +1,11 @@ -import axios from "../axios" +import service from "../axios" import answerSheet from "../urls/answerSheet" export default { // 答题卡列表 fetchAnswerList(data) { - return axios({ + return service({ url: answerSheet.answerList, method: 'POST', data @@ -13,7 +13,7 @@ export default { }, // 测验类型 fetchTypeNames(data) { - return axios({ + return service({ url: answerSheet.typeNames, method: 'POST', data @@ -21,7 +21,7 @@ export default { }, // 班级列表 fetchClassList(data) { - return axios({ + return service({ url: answerSheet.classList, method: 'POST', data @@ -29,7 +29,7 @@ export default { }, // 科目列表 fetchSubjectList(data) { - return axios({ + return service({ url: answerSheet.subjectList, method: 'POST', data @@ -37,7 +37,7 @@ export default { }, // 年级列表 fetchGradeList(data) { - return axios({ + return service({ url: answerSheet.gradeList, method: 'POST', data @@ -45,7 +45,7 @@ export default { }, // 添加测验类型 addAnswerTypeName(data) { - return axios({ + return service({ url: answerSheet.addAnswerTypeName, method: 'POST', data @@ -53,7 +53,7 @@ export default { }, // 保存答题卡 saveAnswerSheet(data) { - return axios({ + return service({ url: answerSheet.saveAnswerSheet, method: 'POST', data @@ -61,7 +61,7 @@ export default { }, // 删除答题卡 removeAnswerSheet(data) { - return axios({ + return service({ url: answerSheet.removeAnswerSheet, method: 'POST', data @@ -69,7 +69,7 @@ export default { }, // 恢复答题卡 useAnswerSheet(data) { - return axios({ + return service({ url: answerSheet.useAnswerSheet, method: 'POST', data @@ -77,7 +77,7 @@ export default { }, // 恢复答题卡 updateAnswerSheet(data) { - return axios({ + return service({ url: answerSheet.updateAnswerSheet, method: 'POST', data diff --git a/src/api/apis/ask.js b/src/api/apis/ask.js new file mode 100644 index 0000000..445bfd1 --- /dev/null +++ b/src/api/apis/ask.js @@ -0,0 +1,14 @@ + +import service from "../axios" +import askUrls from "../urls/login" + +export default { + // 账号密码登陆 + fetchQuizList(data) { + return service({ + url: askUrls.quizList, + method: 'POST', + data + }) + }, +} diff --git a/src/api/apis/login.js b/src/api/apis/login.js index 5d3eb16..32add82 100644 --- a/src/api/apis/login.js +++ b/src/api/apis/login.js @@ -1,11 +1,11 @@ -import axios from "../axios" +import service from "../axios" import loginUrls from "../urls/login" export default { // 账号密码登陆 fetchLogin(data) { - return axios({ + return service({ url: loginUrls.login, method: 'POST', data diff --git a/src/api/apis/role.js b/src/api/apis/role.js index 4c9ba1e..c7422b3 100644 --- a/src/api/apis/role.js +++ b/src/api/apis/role.js @@ -1,11 +1,11 @@ -import axios from "../axios" +import service from "../axios" import roleUrls from "../urls/role" export default { // 获取权限列表 fetchGetRoleList () { - return axios.post(roleUrls.getRoleList) + return service.post(roleUrls.getRoleList) }, } diff --git a/src/api/axios.js b/src/api/axios.js index c322633..5b714b9 100644 --- a/src/api/axios.js +++ b/src/api/axios.js @@ -6,11 +6,13 @@ import router from "@/router/index" import store from "@/store" import conf from "../config/index"; // 路径配置 // axios默认配置 -axios.defaults.timeout = 1000000000 // 超时时间 -axios.defaults.baseURL = conf.baseURL - +const service = axios.create({ + baseURL: conf.baseURL, // api的base_url + timeout: 600000000000000, // 请求超时时间 + withCredentials: true, +}); // http request 拦截器 -axios.interceptors.request.use(config => { +service.interceptors.request.use(config => { NProgress.start() config.headers["Content-Type"] = "application/json;charset=UTF-8" @@ -27,16 +29,16 @@ axios.interceptors.request.use(config => { }) // http response 拦截器 -axios.interceptors.response.use( +service.interceptors.response.use( response => { - const res = respones.data; + const res = response.data; NProgress.done() - if (respones.config.cancelToken) { - store.commit('delTokenSources', respones.config.cancelToken) + if (response.config.cancelToken) { + store.commit('delTokenSources', response.config.cancelToken) } - if (respones.status == 200) { + if (response.status == 200) { Cookies.set("access_token", response.data.message, { expires: 1 / 12 }) - // console.log(respones.status) + // console.log(response.status) if (res.code == 999) { if (!location.href.includes('localhost')) { if (res.data) { @@ -88,4 +90,4 @@ axios.interceptors.response.use( } return Promise.reject(error.response) // 返回接口返回的错误信息 }) -export default axios +export default service diff --git a/src/api/urls/ask.js b/src/api/urls/ask.js new file mode 100644 index 0000000..2b54532 --- /dev/null +++ b/src/api/urls/ask.js @@ -0,0 +1,5 @@ + +export default { + // 账号密码登陆 + quizList: "/web/quizList", +} diff --git a/src/api/urls/login.js b/src/api/urls/login.js index 1b687d9..27b3e13 100644 --- a/src/api/urls/login.js +++ b/src/api/urls/login.js @@ -1,5 +1,6 @@ export default { // 账号密码登陆 - login: "/admin/user/login" + login: "/web/login", + ssoLogin: "/sso/login" } diff --git a/src/assets/css/index.scss b/src/assets/css/index.scss index 39663b3..e5a25ee 100644 --- a/src/assets/css/index.scss +++ b/src/assets/css/index.scss @@ -3,65 +3,113 @@ display: flex; justify-content: space-between; align-items: center; + .btn-box { display: flex; } + .sel-box { - display: flex; - align-items: center; - flex-wrap: nowrap; - .sel { - width: 8%; - min-width: 90px; - margin-right: 20px; - } - .el-input__inner{ - border-radius: 20px; - border: 1px solid #e2e2e2; - height: 36px; - line-height: 34px; - } - .el-input__icon { - line-height: 34px; - } - .el-date-editor.el-input, - .el-date-editor.el-input__inner { - width: 200px; - } - .input-with-select { - width: 200px; - height: 36px; - margin-right: 50px; - border-radius: 20px; - border: 1px solid #e2e2e2; - box-sizing: border-box; + display: flex; + align-items: center; + flex-wrap: nowrap; + + .sel { + width: 8%; + min-width: 160px; + margin-right: 20px; + } + .el-input__inner { border-radius: 20px; - border: none; - height: 34px; + border: 1px solid #e2e2e2; + height: 36px; line-height: 34px; } - .el-input-group__append, .el-input-group__prepend { - border: none; - background: transparent; + + .el-input__icon { + line-height: 34px; } - } - .d1 { - margin-left: 30px; - } - .p1 { - flex: 1; - .s1 { - margin-left: 36px; - cursor: pointer; - color: #7f7f7f; - &:hover { - color: #409eff; + + .el-date-editor.el-input, + .el-date-editor.el-input__inner { + width: 160px; + } + + .input-with-select { + width: 200px; + height: 36px; + margin-right: 50px; + border-radius: 20px; + border: 1px solid #e2e2e2; + box-sizing: border-box; + + .el-input__inner { + border-radius: 20px; + border: none; + height: 34px; + line-height: 34px; } - &.active { - color: #667ffd; + + .el-input-group__append, + .el-input-group__prepend { + border: none; + background: transparent; } } + + .p1 { + flex: 1; + + .s1 { + margin-left: 36px; + cursor: pointer; + color: #7f7f7f; + + &:hover { + color: #409eff; + } + + &.active { + color: #667ffd; + } + } + } + } +} +.answer-box { + .answer-s { + display: inline-block; + width: 30px; + height: 30px; + border: 1px solid #e2e2e2; + border-radius: 3px; + margin: 0 6px; + font-size: 16px; + color: #333; + text-align: center; + line-height: 30px; + &.active { + background: #5e78fa; + border-color: #5e78fa; + color: #fff; + } } } +.el-menu-item i { + width: 12px; + text-align: center; + margin-right: 8px; +} + +.el-table thead th.el-table__cell { + background: #f5f7fa; +} + +.el-menu--popup { + min-width: 160px; +} +.ellipsis { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } \ No newline at end of file diff --git a/src/assets/images/arrow.png b/src/assets/images/arrow.png new file mode 100644 index 0000000..1302220 --- /dev/null +++ b/src/assets/images/arrow.png diff --git a/src/assets/nav/dataSync.png b/src/assets/nav/dataSync.png new file mode 100644 index 0000000..5fd7b09 --- /dev/null +++ b/src/assets/nav/dataSync.png diff --git a/src/main.js b/src/main.js index fc8e568..7d2d5f4 100755 --- a/src/main.js +++ b/src/main.js @@ -14,8 +14,8 @@ import '@/components/globalComponents.js' import "nprogress/nprogress.css" -import "element-ui/lib/theme-chalk/index.css" import "font-awesome/css/font-awesome.css" +import "element-ui/lib/theme-chalk/index.css" import "@/router/permission" import "@/assets/css/base.css" import "@/assets/css/index.scss" diff --git a/src/router/index.js b/src/router/index.js index 5386c20..f11d9c0 100755 --- a/src/router/index.js +++ b/src/router/index.js @@ -327,12 +327,6 @@ let addrouters = [ //测试用,后续后端获取 } ] }, - { - path: "*", - redirect: "/404", - hidden: true, - children: [] - } ] export default new Router({ diff --git a/src/router/permission.js b/src/router/permission.js index 9c6b56e..ffe662f 100644 --- a/src/router/permission.js +++ b/src/router/permission.js @@ -1,54 +1,98 @@ import NProgress from "nprogress" import router from "./index" import store from "../store" -import {addrouters} from "./index" // 获取角色信息,根据用户权限动态加载路由 router.beforeEach((to, from, next) => { NProgress.start() if (store.getters.token) { - if (to.path === "/login") { - next() - } else { - if (!store.getters.info.permissions) { - !(async function getAddRouters() { - // 省略 axios 请求代码 通过 token 向后台请求用户权限等信息,这里用假数据赋值 - await store.commit("setInfo", { - permissions: [ - { - role: "superAdmin", - roleName: "超级管理员" - } - ], - name: "李老师", - // avatar: data.avatar ? data.avatar : "", - // uid: data.id, - // authorityRouter:[], + // if (to.path === "/login") { + next() + // } else { + // if (!store.getters.info.permissions) { + // (async function getAddRouters() { + // // 省略 axios 请求代码 通过 token 向后台请求用户权限等信息,这里用假数据赋值 + // const userInfo = { + // permissions: [ + // { + // role: "superAdmin", + // roleName: "超级管理员" + // } + // ], + // name: "李老师", + // // avatar: data.avatar ? data.avatar : "", + // // uid: data.id, + // authorityRouter: ["examinationPaper", + // "examinationPaperAdd", + // "examinationPaperEdit", + // "examinationPaperRecycle", "ask", + // "askAnalysis", + // "test", + // "testAnalysis", "portrait"], - }) - await store.commit("setRouters", addrouters) - let newAddRouters = store.getters.addRouters - newAddRouters.forEach(res => { - router.addRoute(res) - }) - next({path: to.fullPath}) - }()) - } else { + // } + // await store.commit("setInfo", { ...userInfo }) + // await store.commit("setRouters", userInfo.authorityRouter) + // let newAddRouters = store.getters.addRouters + // newAddRouters.forEach(res => { + // router.addRoute(res) + // }) + // router.addRoute({ + // path: "*", + // redirect: "/404", + // hidden: true, + // children: [] + // }) + // next({ path: to.fullPath }) + // }()) + // } else { + // next() + // } + // } + } else { + if (store.getters.info && store.getters.addRouters) { + console.log(store.getters.addRouters) + store.commit("setToken", "isLogin"); + store.commit( + "setRouters", + store.getters.info.authorityRouter + ); + + let newAddRouters = store.getters.addRouters; + newAddRouters.forEach((res) => { + router.addRoute(res); + }); + router.addRoute({ + path: "*", + redirect: "/404", + hidden: true, + children: [], + }); + next({ path: to.fullPath }) + } else { + if (store.getters.code) { next() + } else { + if (to.path === "/login") { + next() + } else { + next({ path: "/login" }) + } } } - } else { - if (to.path === "/login") { - next() - } - next({ path: "/login" }) - } }) router.afterEach(() => { NProgress.done() }) +router.onError((error) => { + const pattern = /Loading chunk (\d)+ failed/g; + const isChunkLoadFailed = error.message.match(pattern); + const targetPath = router.history.pending.fullPath; + if (isChunkLoadFailed) { router.replace(targetPath); } +}); + // // 真实使用 diff --git a/src/store/index.js b/src/store/index.js index cdea525..3ec6c73 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -4,25 +4,28 @@ import Cookies from "js-cookie" import layoutStore from "./modules/layout/index" import { defaultRouter } from "@/router/index" import { encryptLoginPassword } from "@/utils"; -import { b64DecodeUnicode } from "@/utils"; import request from "@/api/index" import router from "@/router/index" -import {addrouters} from "@/router/index" +import { addrouters } from "@/router/index" Vue.use(Vuex) const store = new Vuex.Store({ state: { - token: Cookies.get("token"), - info: "", // 每次刷新都要通过token请求个人信息来筛选动态路由 - routers: [], - addRouters: [], - tokenSources:new Map(), + token: "", + csCode: localStorage.getItem("csCode") || "", + info: sessionStorage.getItem("info") ? JSON.parse(sessionStorage.getItem("info")) : "", // 每次刷新都要通过token请求个人信息来筛选动态路由 + routers: [],//左侧菜单 + addRouters: sessionStorage.getItem("addRouters") ? JSON.parse(sessionStorage.getItem("addRouters")) : [],//动态路由 + tokenSources: new Map(),//正在请求接口(切换取消请求) }, mutations: { setToken(state, token) { state.token = token - Cookies.set("token", token, { expires: 1 / 24 }) + }, + setCode(state, code) { + state.csCode = code; + localStorage.setItem("csCode", code) }, setInfo(state, data) { state.info = { @@ -33,58 +36,62 @@ const store = new Vuex.Store({ avatar: data.avatar ? data.avatar : "", uid: data.uid } - localStorage.setItem("info", JSON.stringify(store.getters.info)) + sessionStorage.setItem("info", JSON.stringify(state.info)) }, setRouters: (state, routers) => { - state.addRouters = routers // 保存动态路由用来addRouter - state.routers = defaultRouter.concat(routers) // 所有有权限的路由表,用来生成菜单列表 + let aRouters = addrouters.filter(item => { + let path = item.children[0]?.path.replace("/", "") + return routers?.includes(path) + }) + + state.addRouters = aRouters // 保存动态路由用来addRouter + state.routers = defaultRouter.concat(aRouters) // 所有有权限的路由表,用来生成菜单列表 + sessionStorage.setItem("addRouters", JSON.stringify(routers)) }, - setTokenSources(state,data){ - if(data instanceof Array){ + setTokenSources(state, data) { + if (data instanceof Array) { state.tokenSources.set(data[0], data[1]) - }else{ + } else { state.tokenSources = new Map() } }, - delTokenSources(state,data){ + delTokenSources(state, data) { state.tokenSources.delete(data) }, }, actions: { - Login({ state,commit }, params) { - let loginForm={} + Login({ state, commit }, params) { + let loginForm = {} loginForm.username = params.username; loginForm.password = encryptLoginPassword(params.password); - // request.fetchLogin(loginForm).then(res => { - // if (res.status == 200) { - // const dataJSON = JSON.parse(b64DecodeUnicode(res.data)); - commit("setToken", "xxxx") - commit("setInfo", { - permissions: [ - { - role: "superAdmin", - roleName: "超级管理员", - }, - ], - name: "张老师", - // avatar: data.avatar ? data.avatar : "", - // uid: data.id, - // authorityRouter:[], - }); - commit("setRouters", addrouters) - state.addRouters.forEach((res) => { - router.addRoute(res); - }); - console.log() - if (params.url) { - window.location.href = params.url; - } else { - router.push({ path: "/" }) - } - // } - // }) + request.fetchLogin({ ...loginForm }).then(res => { + let response = res.data + if (response.status == 0) { + const userInfo = { ...response.data } + commit("setToken", "isLogin"); + commit("setInfo", { ...userInfo }); + commit("setRouters", [...userInfo.authorityRouter]) + state.addRouters.forEach((res) => { + router.addRoute(res); + }); + router.addRoute({ + path: "*", + redirect: "/404", + hidden: true, + children: [] + }) + console.log() + if (params.url) { + window.location.href = params.url; + } else { + router.push({ path: "/" }) + } + } + }).catch(() => { + // commit("setToken", Cookies.get("JSESSIONID")); + }) }, - permissions({ state,commit }, that) { + permissions({ state, commit }, that) { // request.fetchLogin(that.loginForm).then(res => { // if (res.status == 200) { commit("setToken", "xxxx") @@ -98,13 +105,39 @@ const store = new Vuex.Store({ name: "李老师", // avatar: data.avatar ? data.avatar : "", // uid: data.id, - // authorityRouter:[], + authorityRouter:[ + "examinationPaper", + "examinationPaperAdd", + "examinationPaperEdit", + "examinationPaperRecycle", + "ask", + "askAnalysis", + "test", + "testAnalysis", + "portrait", + "setUpConglomerate", + "setUpAccount", + "setUpSchool", + "setUpTeacher", + "setUpStudent", + "card", + "device", + "analysis", + "down", + "downClient", + "dataSync" + ], }); - commit("setRouters", addrouters) + commit("setRouters", authorityRouter) state.addRouters.forEach((res) => { - that.$router.addRoute(res); + router.addRoute(res); }); - that.$router.push({ path: "/" }) + router.addRoute({ + path: "*", + redirect: "/404", + hidden: true, + children: [] + }) // } // }) } @@ -112,6 +145,7 @@ const store = new Vuex.Store({ getters: { addRouters: state => state.addRouters, token: state => state.token, + code: state => state.csCode, info: state => state.info, routers: state => state.routers, logoShow: state => state.layoutStore.logoShow, diff --git a/src/utils/index.js b/src/utils/index.js index 20688b9..9d072e1 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -9,7 +9,7 @@ const encryptIV = "D076D35C" * @param data: 待加密数据 * @returns 加密结果 */ -export function encryptLoginPassword(data){ +export function encryptLoginPassword(data) { const secret = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjh2ei17z5k2r4VzbqoSCE6RmYzWySJTgVQYulgfVM+vqcDoUE4cFB4XCFA2lHWjjpsuJP1EtwKlvUgxo5okr3x/a88o8eERxBynnVQZbEYpKteW5aqSEb/g1yPLWnKV88b/ED445ITYbZZuInRo5lkCvd6QEjL6d2Fch6mEo5awYXC4/S4BJf9YlYRhGzR7wpiXCLvyBHQ4iSIIDNpmrPBPQzGP0rx09aDu54kz/42CR6SX2OqXSi4ZoieqkPFl/iuX4RoD/NKKR+haDn1UzoD3k1WzHSTBFFs27rxRpxfBUZzfXQeskgKyw/Slcl3jUFizczsY4CLgTRrfey48Q6QIDAQAB'; // 新建JSEncrypt对象 let encryptor = new JSEncrypt(); @@ -25,7 +25,7 @@ export function encryptLoginPassword(data){ * @param data: 待加密数据 * @returns 加密结果 */ -export function encryptData(secret, data){ +export function encryptData(secret, data) { // 新建JSEncrypt对象 let encryptor = new JSEncrypt(); // 设置公钥 @@ -35,7 +35,7 @@ export function encryptData(secret, data){ } // 深度复制 -export function deepClone (obj) { +export function deepClone(obj) { let result = Array.isArray(obj) ? [] : {} for (let key in obj) { if (obj.hasOwnProperty(key)) { @@ -74,7 +74,7 @@ export function deepClone (obj) { // } // 随机生成由字母+数字的字符串 -export function randomWord (randomFlag, min, max) { +export function randomWord(randomFlag, min, max) { // randomFlag: Boolean 是否随机个数 // min 最少个数 // max 最大个数 @@ -94,7 +94,7 @@ export function randomWord (randomFlag, min, max) { } // 判断数组中是否存在相同值 -export function hasRepeatValue (arr, key = null) { +export function hasRepeatValue(arr, key = null) { if (key) arr = arr.map(d => d[key]) if (arr.length) { let nameNum = arr.reduce((pre, cur) => { @@ -111,7 +111,7 @@ export function hasRepeatValue (arr, key = null) { } // 获取cookie值 -export function getCookie (name, defaultValue) { +export function getCookie(name, defaultValue) { const result = new RegExp("(^| )" + name + "=([^;]*)(;|$)") return result[0] === document.cookie.match(result[1]) ? unescape(result[0][2]) : defaultValue } @@ -120,19 +120,19 @@ export function getCookie (name, defaultValue) { /** * base64转化unicode */ - export function b64DecodeUnicode(str) { +export function b64DecodeUnicode(str) { let uni; try { // atob 经过 base-64 编码的字符串进行解码 uni = decodeURIComponent(atob(str).split('').map(function (c) { return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); }).join('')); - } catch (e) {} + } catch (e) { } return uni; } // base64ToFile -export function base64ToFile (base64Data, tempfilename, contentType) { +export function base64ToFile(base64Data, tempfilename, contentType) { contentType = contentType || "" var sliceSize = 1024 var byteCharacters = atob(base64Data) @@ -155,7 +155,7 @@ export function base64ToFile (base64Data, tempfilename, contentType) { } // 将base64转换为文件 -export function dataURLtoFile (dataurl, filename) { +export function dataURLtoFile(dataurl, filename) { var arr = dataurl.split(",") var mime = arr[0].match(/:(.*?);/)[1] var bstr = atob(arr[1]) @@ -168,7 +168,7 @@ export function dataURLtoFile (dataurl, filename) { } // 将图片转换为Base64 -export function getImgToBase64 (url, callback, outputFormat) { +export function getImgToBase64(url, callback, outputFormat) { var canvas = document.createElement("canvas") var ctx = canvas.getContext("2d") var img = new Image() @@ -185,7 +185,7 @@ export function getImgToBase64 (url, callback, outputFormat) { } // 转换级联下拉数据 -export function loopOptions (list, option = {}) { +export function loopOptions(list, option = {}) { option = { value: "id", label: "name", @@ -206,7 +206,7 @@ export function loopOptions (list, option = {}) { } // 通过Id获取级联数据id数组 -export function getTreeIds (tree, currentId, key = "id") { +export function getTreeIds(tree, currentId, key = "id") { let parent = {} let pid = {} const loop = (list, level) => { @@ -233,16 +233,40 @@ export function getTreeIds (tree, currentId, key = "id") { return result } -// 秒转换时分秒 -export function transverterMss (result) { - var h = Math.floor(result / 3600) < 10 ? "0" + Math.floor(result / 3600) : Math.floor(result / 3600) - var m = Math.floor((result / 60 % 60)) < 10 ? "0" + Math.floor((result / 60 % 60)) : Math.floor((result / 60 % 60)) - var s = Math.floor((result % 60)) < 10 ? "0" + Math.floor((result % 60)) : Math.floor((result % 60)) - return h + ":" + m + ":" + s +/* + * 格式化时间 + * yyyy-MM-dd hh:mm:ss + * */ +export function formatDate(date, fmt) { + if (!date || date == null) return null; + if (isNaN(date)) { + return date; + } + let format = fmt || "yyyy-MM-dd hh:mm:ss"; + + let dates = new Date(Number(date)); + + let formatObj = { + y: dates.getFullYear(), + M: dates.getMonth() + 1, + d: dates.getDate(), + h: dates.getHours(), + m: dates.getMinutes(), + s: dates.getSeconds(), + }; + let time_str = format.replace(/(y|M|d|h|m|s)+/g, (result, key) => { + let value = formatObj[key]; + if (result.length > 0 && value < 10) { + value = "0" + value; + } + return value || 0; + }); + return time_str; } + // 获取日期时间戳 -export function getTime (dayNum) { +export function getTime(dayNum) { var myDate = new Date() var lw = new Date(myDate - 1000 * 60 * 60 * 24 * dayNum)// 最后一个数字多少天前的意思 var lastY = lw.getFullYear() @@ -256,7 +280,7 @@ export function getTime (dayNum) { } // 获取几天之前日期 -export function getData (dayNum) { +export function getData(dayNum) { var myDate = new Date() var lw = new Date(myDate - 1000 * 60 * 60 * 24 * dayNum)// 最后一个数字多少天前的意思 var lastY = lw.getFullYear() @@ -267,7 +291,7 @@ export function getData (dayNum) { } // 日期转换时间戳 -export function getNewTime (dayNum) { +export function getNewTime(dayNum) { var b = dayNum.split(/\D/) var date = new Date(b[0], b[1] - 1, b[2]) var time = date.getTime() @@ -297,4 +321,75 @@ export function getURLParams(variable) { } } return variable ? data : obj -} \ No newline at end of file +} + +/** + * 校验答案 + * @param {*} s 源字符串 + * @param {*} questionType 题型,2单选 3多选 + * @param {*} optionCount 选项数目 + * @param {*} questionCount 题目数目 + */ +function filtterChar(s, b, optionCount) { + const ms = "ABCDEFG"; + let rs = ""; + for (let i = 0; i < s.length; i++) { + let c = s[i]; + if (c == ',' || c == ' ' || c == ',') { + if (!b) { + continue; + } + c = ','; + } + else if (c < 'A' || c >= ms[optionCount]) { + continue; + } + rs += c; + } + return rs; +} + +function removeDup(s) { + const ms = "ABCDEFG"; + let rs = ""; + for (let i = 0; i < ms.length; i++) { + if (s.indexOf(ms[i]) >= 0) { + rs += ms[i]; + } + } + return rs; +} +export function checkAnswer(s, questionType, optionCount = 4, questionCount = 1) { + if (optionCount > 10 || questionCount < 1) { + return null; + } + let pre = s; + s = s.toUpperCase(); + s = filtterChar(s, questionType == 3 && questionCount > 1, optionCount); + if (questionType == 2) {//单选 + console.log(s.length + " " + questionCount); + if (s.length > questionCount) { + s = s.substring(s.length - questionCount, s.length); + } + } + else if (questionType == 3) {//多选 + //允许逗号 + let ss = s.split(","); + let len = questionCount; + if (len > ss.length) { + len = ss.length; + } + let rs = ""; + for (let i = 0; i < len; i++) { + rs += removeDup(ss[i]); + if (i < len - 1) { + rs += ','; + } + } + s = rs; + } + else { + return null; + } + return s; +} diff --git a/src/views/ask/analysis.vue b/src/views/ask/analysis.vue index 89c9741..83e3776 100644 --- a/src/views/ask/analysis.vue +++ b/src/views/ask/analysis.vue @@ -1,13 +1,44 @@ - \ No newline at end of file diff --git a/src/views/ask/index.vue b/src/views/ask/index.vue index aa7cb81..abc3f30 100644 --- a/src/views/ask/index.vue +++ b/src/views/ask/index.vue @@ -1,16 +1,970 @@ - \ No newline at end of file diff --git a/src/views/examinationPaper/detail.vue b/src/views/examinationPaper/detail.vue new file mode 100644 index 0000000..4611414 --- /dev/null +++ b/src/views/examinationPaper/detail.vue @@ -0,0 +1,190 @@ + + + + + \ No newline at end of file diff --git a/src/views/examinationPaper/edit.vue b/src/views/examinationPaper/edit.vue index a01cebf..cf564d1 100644 --- a/src/views/examinationPaper/edit.vue +++ b/src/views/examinationPaper/edit.vue @@ -26,6 +26,7 @@