diff --git a/package.json b/package.json index d3a448c..7403f62 100755 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "font-awesome": "^4.7.0", "js-cookie": "^2.2.0", "jsencrypt": "^3.2.0", + "lodash": "^4.17.21", "nprogress": "^0.2.0", "script-ext-html-webpack-plugin": "^2.1.5", "vue": "^2.6.11", diff --git a/src/api/apis/device.js b/src/api/apis/device.js new file mode 100644 index 0000000..342a504 --- /dev/null +++ b/src/api/apis/device.js @@ -0,0 +1,39 @@ + +import service from "../axios" +import deviceUrls from "../urls/device" + +export default { + // 下载设备模板 + downDevice(data) { + return service({ + url: deviceUrls.downDevice, + method: 'POST', + data + }) + }, + // 设备列表 + fetchDeviceList(data) { + return service({ + url: deviceUrls.deviceList, + method: 'POST', + data + }) + }, + // autoUpDate + autoUpDate(data) { + return service({ + url: deviceUrls.autoUpDate, + method: 'POST', + data + }) + }, + // 设备列表 + stopUpdate(data) { + return service({ + url: deviceUrls.stopUpdate, + method: 'POST', + data + }) + }, + +} diff --git a/src/api/urls/device.js b/src/api/urls/device.js new file mode 100644 index 0000000..8aebc5d --- /dev/null +++ b/src/api/urls/device.js @@ -0,0 +1,13 @@ + +export default { + // 设备文件上传 + upLoadDevice: "/web/upLoadDevice", + // 设备模板下载 + downDevice: "/web/downDevice", + // 设备列表 + deviceList: "/web/deviceList", + // 自动更新 + autoUpDate: "/web/autoUpDate", + // 关闭自动更新 + stopUpdate: "/web/stopUpdate", +} diff --git a/src/assets/css/index.scss b/src/assets/css/index.scss index 1362381..a5b5f05 100644 --- a/src/assets/css/index.scss +++ b/src/assets/css/index.scss @@ -22,7 +22,7 @@ .el-input__inner { border-radius: 20px; border: 1px solid #e2e2e2; - height: 36px; + height: 36px!important; line-height: 34px; } @@ -116,4 +116,24 @@ .pagination-box{ text-align:center; margin:10px; +} +.down-txt{ + display: flex; + align-items: center; + justify-content: center; +} +.h-title{ + padding-left:12px; + position: relative; + font-size:16px; + &:after{ + content:""; + position:absolute; + left:0; + top:50%; + margin-top:-8px; + width:3px; + height:16px; + background: #2e9afe; + } } \ No newline at end of file diff --git a/src/components/ECharts/lineEcharts.vue b/src/components/ECharts/lineEcharts.vue deleted file mode 100644 index c89f16e..0000000 --- a/src/components/ECharts/lineEcharts.vue +++ /dev/null @@ -1,119 +0,0 @@ - - - - - diff --git a/src/components/charts/pieChart.vue b/src/components/charts/pieChart.vue new file mode 100644 index 0000000..9dd5e84 --- /dev/null +++ b/src/components/charts/pieChart.vue @@ -0,0 +1,114 @@ + + + + + diff --git a/src/components/charts/scatterChart.vue b/src/components/charts/scatterChart.vue new file mode 100644 index 0000000..0e076c9 --- /dev/null +++ b/src/components/charts/scatterChart.vue @@ -0,0 +1,148 @@ + + + + + diff --git a/src/components/upload.vue b/src/components/upload.vue index 665210a..dd18682 100644 --- a/src/components/upload.vue +++ b/src/components/upload.vue @@ -1,19 +1,11 @@ @@ -114,8 +92,22 @@ export default { padding: 10px; } .btn { - margin-top: 20px; border-radius: 8px; font-weight: normal; } +.upload-demo { + display: flex; + flex-direction: column; + align-items: center; +} +.upload-btn { + display: flex; + flex-direction: column; + align-items: center; + .el-icon-upload { + font-size: 48px; + margin-bottom: 6px; + color: #667ffd; + } +} diff --git a/src/router/index.js b/src/router/index.js index f11d9c0..f11346e 100755 --- a/src/router/index.js +++ b/src/router/index.js @@ -21,6 +21,7 @@ const Portrait = () => import("@/views/portrait/index") const Card = () => import("@/views/card/index") const Analysis = () => import("@/views/analysis/index") const Device = () => import("@/views/device/index") +const DeviceLog = () => import("@/views/device/log") const Down = () => import("@/views/down/index") const DownClient = () => import("@/views/down/client") const SetUpAccount = () => import("@/views/setUp/account") @@ -269,6 +270,13 @@ let addrouters = [ //测试用,后续后端获取 name: "", component: Device, children: [] + }, + { + path: "/deviceLog", + iconCls: "fa fa-list-alt", // 图标样式class + name: "", + component: DeviceLog, + children: [] } ] }, diff --git a/src/utils/index.js b/src/utils/index.js index 9d072e1..3dc6d9b 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -1,16 +1,16 @@ - // import CryptoJS from "crypto-js" -import { JSEncrypt } from 'jsencrypt' +import { JSEncrypt } from "jsencrypt"; -const encryptKey = "WfJTKO9S4eLkrPz2JKrAnzdb" -const encryptIV = "D076D35C" +const encryptKey = "WfJTKO9S4eLkrPz2JKrAnzdb"; +const encryptIV = "D076D35C"; /** * 登录密码加密,公钥直接写死在方法里 * @param data: 待加密数据 * @returns 加密结果 */ export function encryptLoginPassword(data) { - const secret = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjh2ei17z5k2r4VzbqoSCE6RmYzWySJTgVQYulgfVM+vqcDoUE4cFB4XCFA2lHWjjpsuJP1EtwKlvUgxo5okr3x/a88o8eERxBynnVQZbEYpKteW5aqSEb/g1yPLWnKV88b/ED445ITYbZZuInRo5lkCvd6QEjL6d2Fch6mEo5awYXC4/S4BJf9YlYRhGzR7wpiXCLvyBHQ4iSIIDNpmrPBPQzGP0rx09aDu54kz/42CR6SX2OqXSi4ZoieqkPFl/iuX4RoD/NKKR+haDn1UzoD3k1WzHSTBFFs27rxRpxfBUZzfXQeskgKyw/Slcl3jUFizczsY4CLgTRrfey48Q6QIDAQAB'; + const secret = + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjh2ei17z5k2r4VzbqoSCE6RmYzWySJTgVQYulgfVM+vqcDoUE4cFB4XCFA2lHWjjpsuJP1EtwKlvUgxo5okr3x/a88o8eERxBynnVQZbEYpKteW5aqSEb/g1yPLWnKV88b/ED445ITYbZZuInRo5lkCvd6QEjL6d2Fch6mEo5awYXC4/S4BJf9YlYRhGzR7wpiXCLvyBHQ4iSIIDNpmrPBPQzGP0rx09aDu54kz/42CR6SX2OqXSi4ZoieqkPFl/iuX4RoD/NKKR+haDn1UzoD3k1WzHSTBFFs27rxRpxfBUZzfXQeskgKyw/Slcl3jUFizczsY4CLgTRrfey48Q6QIDAQAB"; // 新建JSEncrypt对象 let encryptor = new JSEncrypt(); // 设置公钥 @@ -20,11 +20,11 @@ export function encryptLoginPassword(data) { } /** -* 对称加密 -* @param secret:加密公钥 -* @param data: 待加密数据 -* @returns 加密结果 -*/ + * 对称加密 + * @param secret:加密公钥 + * @param data: 待加密数据 + * @returns 加密结果 + */ export function encryptData(secret, data) { // 新建JSEncrypt对象 let encryptor = new JSEncrypt(); @@ -36,17 +36,17 @@ export function encryptData(secret, data) { // 深度复制 export function deepClone(obj) { - let result = Array.isArray(obj) ? [] : {} + let result = Array.isArray(obj) ? [] : {}; for (let key in obj) { if (obj.hasOwnProperty(key)) { if (typeof obj[key] === "object") { - result[key] = deepClone(obj[key]) + result[key] = deepClone(obj[key]); } else { - result[key] = obj[key] + result[key] = obj[key]; } } } - return result + return result; } // // 3DES加密 @@ -78,45 +78,109 @@ export function randomWord(randomFlag, min, max) { // randomFlag: Boolean 是否随机个数 // min 最少个数 // max 最大个数 - var str = "" - var range = min - var arr = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] + var str = ""; + var range = min; + var arr = [ + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + ]; // 随机产生 if (randomFlag) { - range = Math.round(Math.random() * (max - min)) + min + range = Math.round(Math.random() * (max - min)) + min; } - var pos = "" + var pos = ""; for (var i = 0; i < range; i++) { - pos = Math.round(Math.random() * (arr.length - 1)) - str += arr[pos] + pos = Math.round(Math.random() * (arr.length - 1)); + str += arr[pos]; } - return str + return str; } // 判断数组中是否存在相同值 export function hasRepeatValue(arr, key = null) { - if (key) arr = arr.map(d => d[key]) + if (key) arr = arr.map((d) => d[key]); if (arr.length) { let nameNum = arr.reduce((pre, cur) => { if (cur in pre) { - pre[cur]++ + pre[cur]++; } else { - pre[cur] = 1 + pre[cur] = 1; } - return pre - }, {}) - return Object.values(nameNum).findIndex(d => d > 1) < 0 + return pre; + }, {}); + return Object.values(nameNum).findIndex((d) => d > 1) < 0; } - return true + return true; } // 获取cookie值 export function getCookie(name, defaultValue) { - const result = new RegExp("(^| )" + name + "=([^;]*)(;|$)") - return result[0] === document.cookie.match(result[1]) ? unescape(result[0][2]) : defaultValue + const result = new RegExp("(^| )" + name + "=([^;]*)(;|$)"); + return result[0] === document.cookie.match(result[1]) + ? unescape(result[0][2]) + : defaultValue; } - /** * base64转化unicode */ @@ -124,64 +188,69 @@ 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) { } + uni = decodeURIComponent( + atob(str) + .split("") + .map(function (c) { + return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2); + }) + .join("") + ); + } catch (e) {} return uni; } // base64ToFile export function base64ToFile(base64Data, tempfilename, contentType) { - contentType = contentType || "" - var sliceSize = 1024 - var byteCharacters = atob(base64Data) - var bytesLength = byteCharacters.length - var slicesCount = Math.ceil(bytesLength / sliceSize) - var byteArrays = new Array(slicesCount) + contentType = contentType || ""; + var sliceSize = 1024; + var byteCharacters = atob(base64Data); + var bytesLength = byteCharacters.length; + var slicesCount = Math.ceil(bytesLength / sliceSize); + var byteArrays = new Array(slicesCount); for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) { - var begin = sliceIndex * sliceSize - var end = Math.min(begin + sliceSize, bytesLength) + var begin = sliceIndex * sliceSize; + var end = Math.min(begin + sliceSize, bytesLength); - var bytes = new Array(end - begin) + var bytes = new Array(end - begin); for (var offset = begin, i = 0; offset < end; ++i, ++offset) { - bytes[i] = byteCharacters[offset].charCodeAt(0) + bytes[i] = byteCharacters[offset].charCodeAt(0); } - byteArrays[sliceIndex] = new Uint8Array(bytes) + byteArrays[sliceIndex] = new Uint8Array(bytes); } - var file = new File(byteArrays, tempfilename, { type: contentType }) - return file + var file = new File(byteArrays, tempfilename, { type: contentType }); + return file; } // 将base64转换为文件 export function dataURLtoFile(dataurl, filename) { - var arr = dataurl.split(",") - var mime = arr[0].match(/:(.*?);/)[1] - var bstr = atob(arr[1]) - var n = bstr.length - var u8arr = new Uint8Array(n) + var arr = dataurl.split(","); + var mime = arr[0].match(/:(.*?);/)[1]; + var bstr = atob(arr[1]); + var n = bstr.length; + var u8arr = new Uint8Array(n); while (n--) { - u8arr[n] = bstr.charCodeAt(n) + u8arr[n] = bstr.charCodeAt(n); } - return new File([u8arr], filename, { type: mime }) + return new File([u8arr], filename, { type: mime }); } // 将图片转换为Base64 export function getImgToBase64(url, callback, outputFormat) { - var canvas = document.createElement("canvas") - var ctx = canvas.getContext("2d") - var img = new Image() - img.crossOrigin = "Anonymous" + var canvas = document.createElement("canvas"); + var ctx = canvas.getContext("2d"); + var img = new Image(); + img.crossOrigin = "Anonymous"; img.onload = function () { - canvas.height = img.height - canvas.width = img.width - ctx.drawImage(img, 0, 0) - var dataURL = canvas.toDataURL(outputFormat || "image/png") - callback(dataURL) - canvas = null - } - img.src = url + canvas.height = img.height; + canvas.width = img.width; + ctx.drawImage(img, 0, 0); + var dataURL = canvas.toDataURL(outputFormat || "image/png"); + callback(dataURL); + canvas = null; + }; + img.src = url; } // 转换级联下拉数据 @@ -190,47 +259,49 @@ export function loopOptions(list, option = {}) { value: "id", label: "name", children: "children", - ...option - } + ...option, + }; if (list instanceof Array && list.length) { return list.map((d, i) => { - d.value = d[option.value] || i + 1 - d.label = d[option.label] + d.value = d[option.value] || i + 1; + d.label = d[option.label]; if (d[option.children]) { - d[option.children] = loopOptions(d[option.children], option) + d[option.children] = loopOptions(d[option.children], option); } - return d - }) + return d; + }); } - return [] + return []; } // 通过Id获取级联数据id数组 export function getTreeIds(tree, currentId, key = "id") { - let parent = {} - let pid = {} + let parent = {}; + let pid = {}; const loop = (list, level) => { if (list instanceof Array && list.length) { for (let index = 0; index < list.length; index++) { - const d = list[index] - parent[level] = d.id + const d = list[index]; + parent[level] = d.id; if (d[key] === currentId) { for (let idx = 1; idx <= level; idx++) { - pid[idx] = parent[idx] + pid[idx] = parent[idx]; } - break + break; } else if (d.children) { - loop(d.children, level + 1) + loop(d.children, level + 1); } } } - } - loop(tree, 1) - let result = [] - Object.keys(pid).sort((a, b) => a - b).forEach(k => { - result.push(pid[k]) - }) - return result + }; + loop(tree, 1); + let result = []; + Object.keys(pid) + .sort((a, b) => a - b) + .forEach((k) => { + result.push(pid[k]); + }); + return result; } /* @@ -264,38 +335,47 @@ export function formatDate(date, fmt) { return time_str; } - // 获取日期时间戳 export function getTime(dayNum) { - var myDate = new Date() - var lw = new Date(myDate - 1000 * 60 * 60 * 24 * dayNum)// 最后一个数字多少天前的意思 - var lastY = lw.getFullYear() - var lastM = lw.getMonth() + 1 - var lastD = lw.getDate() - var startdate = lastY + "-" + (lastM < 10 ? "0" + lastM : lastM) + "-" + (lastD < 10 ? "0" + lastD : lastD) - var b = startdate.split(/\D/) - var date = new Date(b[0], b[1] - 1, b[2]) - var time = date.getTime() - return time + var myDate = new Date(); + var lw = new Date(myDate - 1000 * 60 * 60 * 24 * dayNum); // 最后一个数字多少天前的意思 + var lastY = lw.getFullYear(); + var lastM = lw.getMonth() + 1; + var lastD = lw.getDate(); + var startdate = + lastY + + "-" + + (lastM < 10 ? "0" + lastM : lastM) + + "-" + + (lastD < 10 ? "0" + lastD : lastD); + var b = startdate.split(/\D/); + var date = new Date(b[0], b[1] - 1, b[2]); + var time = date.getTime(); + return time; } // 获取几天之前日期 export function getData(dayNum) { - var myDate = new Date() - var lw = new Date(myDate - 1000 * 60 * 60 * 24 * dayNum)// 最后一个数字多少天前的意思 - var lastY = lw.getFullYear() - var lastM = lw.getMonth() + 1 - var lastD = lw.getDate() - var startdate = lastY + "-" + (lastM < 10 ? "0" + lastM : lastM) + "-" + (lastD < 10 ? "0" + lastD : lastD) - return startdate + var myDate = new Date(); + var lw = new Date(myDate - 1000 * 60 * 60 * 24 * dayNum); // 最后一个数字多少天前的意思 + var lastY = lw.getFullYear(); + var lastM = lw.getMonth() + 1; + var lastD = lw.getDate(); + var startdate = + lastY + + "-" + + (lastM < 10 ? "0" + lastM : lastM) + + "-" + + (lastD < 10 ? "0" + lastD : lastD); + return startdate; } // 日期转换时间戳 export function getNewTime(dayNum) { - var b = dayNum.split(/\D/) - var date = new Date(b[0], b[1] - 1, b[2]) - var time = date.getTime() - return time + var b = dayNum.split(/\D/); + var date = new Date(b[0], b[1] - 1, b[2]); + var time = date.getTime(); + return time; } /* @@ -310,17 +390,17 @@ export function getURLParams(variable) { let data; for (var i = 0; i < ar.length; i++) { var pair = ar[i].split("="); - pair[1] = decodeURIComponent(pair[1]) + pair[1] = decodeURIComponent(pair[1]); if (pair[0] == variable) { - data = pair[1] - return pair[1] + data = pair[1]; + return pair[1]; } if (pair[0]) { - obj[pair[0]] = pair[1] + obj[pair[0]] = pair[1]; } } - return variable ? data : obj + return variable ? data : obj; } /** @@ -335,13 +415,12 @@ function filtterChar(s, b, optionCount) { let rs = ""; for (let i = 0; i < s.length; i++) { let c = s[i]; - if (c == ',' || c == ' ' || c == ',') { + if (c == "," || c == " " || c == ",") { if (!b) { continue; } - c = ','; - } - else if (c < 'A' || c >= ms[optionCount]) { + c = ","; + } else if (c < "A" || c >= ms[optionCount]) { continue; } rs += c; @@ -359,20 +438,26 @@ function removeDup(s) { } return rs; } -export function checkAnswer(s, questionType, optionCount = 4, questionCount = 1) { +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) {//单选 + if (questionType == 2) { + //单选 console.log(s.length + " " + questionCount); if (s.length > questionCount) { s = s.substring(s.length - questionCount, s.length); } - } - else if (questionType == 3) {//多选 + } else if (questionType == 3) { + //多选 //允许逗号 let ss = s.split(","); let len = questionCount; @@ -383,13 +468,213 @@ export function checkAnswer(s, questionType, optionCount = 4, questionCount = 1) for (let i = 0; i < len; i++) { rs += removeDup(ss[i]); if (i < len - 1) { - rs += ','; + rs += ","; } } s = rs; - } - else { + } else { return null; } return s; } + +export function downloadFile(fileName, files) { + if (typeof window.navigator.msSaveBlob !== "undefined") { + window.navigator.msSaveBlob(files, fileName); + } else { + let URL = window.URL || window.webkitURL; + let objectUrl; + if (files instanceof Blob) { + objectUrl = URL.createObjectURL(files); + } else { + objectUrl = files; + } + const a = document.createElement("a"); + if (typeof a.download === "undefined") { + window.location = objectUrl; + } else { + a.href = objectUrl; + a.download = fileName; + document.body.appendChild(a); + a.click(); + a.remove(); + } + } +} +// 获取网络URL的blob,返回一个promise +export function getBlob(url) { + return new Promise((resolve) => { + resolve( + service({ + url: url, + withCredentials: true, + method: "get", + responseType: "blob", + }) + ); + }); +} +/** + * 打包压缩下载 + */ +export function compressAndDown(arr, fileName) { + const zip = new JSZip(); + const promiseArr = []; + arr.forEach((item) => { + const promise = getBlob(item.reportPath).then((res) => { + const fileName = item.testName; + let sIdx = item.reportPath.lastIndexOf("."); + const fileType = item.reportPath.substring(sIdx); + zip.file(`${fileName}${fileType}`, res, { binary: true }); + }); + promiseArr.push(promise); + }); + Promise.all(promiseArr).then(() => { + zip + .generateAsync({ + type: "blob", + compression: "DEFLATE", + compressionOptions: { + level: 9, + }, + }) + .then((res) => { + FileSave.saveAs(res, fileName ? fileName : "报表.zip"); + }); + }); +} + +/** + * 班级格式化为三级列表 学段-年级-班级 + * @param {*} data + * @returns + */ +function setSectionName(num) { + let txt = ""; + switch (num) { + case 1: + txt = "小学"; + break; + case 2: + txt = "中学"; + break; + case 3: + txt = "高中"; + break; + case 4: + txt = "大学"; + break; + } + return txt; +} +function setGradeName(num) { + let txt = ""; + switch (num) { + case 1: + txt = "一年级"; + break; + case 2: + txt = "二年级"; + break; + case 3: + txt = "三年级"; + break; + case 4: + txt = "四年级"; + break; + case 5: + txt = "五年级"; + break; + case 6: + txt = "六年级"; + break; + case 7: + txt = "初一"; + break; + case 8: + txt = "初二"; + break; + case 9: + txt = "初三"; + break; + case 10: + txt = "高一"; + break; + case 11: + txt = "高二"; + break; + case 12: + txt = "高三"; + break; + case 13: + txt = "大一"; + break; + case 14: + txt = "大二"; + break; + case 15: + txt = "大三"; + break; + case 16: + txt = "大四"; + break; + } + return txt; +} +export function formatClass(data) { + let sectionName = []; + let sectionNameArr = []; + data.map((item) => { + if (!sectionName.includes(item.sectionName)) { + sectionName.push(item.sectionName); + sectionNameArr.push({ + value: item.sectionName, + label: setSectionName(item.sectionName), + children: [ + { + value: item.gradeName, + label: setGradeName(item.gradeName), + children: [ + { + value: item.classId, + label: item.className, + }, + ], + }, + ], + }); + } else { + let hasGrade = false; + let sectionIndex = 0; + let gradeIndex = 0; + sectionNameArr.map((items, index) => { + items.map((grade, gradeInx) => { + if (setGradeName(item.gradeName) == grade.value) { + hasGrade = true; + sectionIndex = index; + gradeIndex = gradeInx; + } + }); + }); + if (hasGrade) { + sectionNameArr[sectionIndex].children[gradeIndex].push({ + value: item.classId, + label: item.className, + }); + } else { + sectionNameArr[sectionIndex].children.push({ + value: setGradeName(item.gradeName), + label: setGradeName(item.gradeName), + children: [ + { + value: item.classId, + label: item.className, + }, + ], + }); + } + } + }); + console.log(sectionNameArr); + return sectionNameArr; +} diff --git a/src/views/device/index.vue b/src/views/device/index.vue index fbef0ae..37c908c 100644 --- a/src/views/device/index.vue +++ b/src/views/device/index.vue @@ -4,7 +4,7 @@ - - \ No newline at end of file diff --git a/src/views/device/log.vue b/src/views/device/log.vue new file mode 100644 index 0000000..7081b7d --- /dev/null +++ b/src/views/device/log.vue @@ -0,0 +1,35 @@ + + + + + \ No newline at end of file diff --git a/src/views/setUp/school.vue b/src/views/setUp/school.vue index b5b28ff..fb94b87 100644 --- a/src/views/setUp/school.vue +++ b/src/views/setUp/school.vue @@ -1,13 +1,190 @@ - \ No newline at end of file