diff --git a/package-lock.json b/package-lock.json index b6b53d066596b7a75b1c9034e62e34d71111ce30..78895cacc8ea6a2172630eb0f7d4fa6dd803492e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "zvms-electron", - "version": "0.1.0", + "version": "1.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -2028,6 +2028,52 @@ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "optional": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "optional": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "optional": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "optional": true + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "optional": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -2042,6 +2088,41 @@ "requires": { "minipass": "^3.1.1" } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "optional": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "vue-loader-v16": { + "version": "npm:vue-loader@16.8.1", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.8.1.tgz", + "integrity": "sha512-V53TJbHmzjBhCG5OYI2JWy/aYDspz4oVHKxS43Iy212GjGIG1T3EsB3+GWXFm/1z5VwjdjLmdZUFYM70y77vtQ==", + "dev": true, + "optional": true, + "requires": { + "chalk": "^4.1.0", + "hash-sum": "^2.0.0", + "loader-utils": "^2.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "optional": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } } } }, @@ -8609,7 +8690,8 @@ "dev": true, "optional": true, "requires": { - "cli-truncate": "^1.1.0" + "cli-truncate": "^1.1.0", + "node-addon-api": "^1.6.3" } }, "iconv-lite": { @@ -10067,6 +10149,24 @@ "minipass": "^3.0.0" } }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, "mississippi": { "version": "3.0.0", "resolved": "https://registry.npm.taobao.org/mississippi/download/mississippi-3.0.0.tgz", @@ -10227,6 +10327,13 @@ "lower-case": "^1.1.1" } }, + "node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", + "dev": true, + "optional": true + }, "node-forge": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", @@ -13725,12 +13832,14 @@ }, "tar": { "version": "6.0.5", - "resolved": "", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.5.tgz", + "integrity": "sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg==", "dev": true, "requires": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^3.0.0", + "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" }, @@ -15047,7 +15156,8 @@ }, "ssri": { "version": "8.0.0", - "resolved": "", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.0.tgz", + "integrity": "sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA==", "dev": true, "requires": { "minipass": "^3.1.1" @@ -15174,87 +15284,6 @@ } } }, - "vue-loader-v16": { - "version": "npm:vue-loader@16.5.0", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.5.0.tgz", - "integrity": "sha512-WXh+7AgFxGTgb5QAkQtFeUcHNIEq3PGVQ8WskY5ZiFbWBkOwcCPRs4w/2tVyTbh2q6TVRlO3xfvIukUtjsu62A==", - "dev": true, - "optional": true, - "requires": { - "chalk": "^4.1.0", - "hash-sum": "^2.0.0", - "loader-utils": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "optional": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "optional": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "optional": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "optional": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "optional": true - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "optional": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "optional": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "vue-router": { "version": "3.4.3", "resolved": "https://registry.npm.taobao.org/vue-router/download/vue-router-3.4.3.tgz", diff --git a/package.json b/package.json index 483bd4dcf699fda10fab8fe695b218b023349065..d6204bc85cee6e021e798a6d10206d818a688921 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zvms-electron", - "version": "1.2.2", + "version": "1.2.1", "private": true, "scripts": { "serve": "vue-cli-service serve", diff --git a/src/App.vue b/src/App.vue index a098165f7a412d06797fbbe8c2f11ab41651af6d..879145555108638bc078508d7d650f19703039a3 100644 --- a/src/App.vue +++ b/src/App.vue @@ -52,7 +52,7 @@ 义工管理系统 - 内测 + v1.2.1 @@ -102,7 +102,7 @@ color="rgba(255,255,255,0.3)" > {{ new Date().getFullYear() }} - © mo_yi & Zecyel & fpc7519{{ new Date().getFullYear() }} - © mo_yi & Zecyel & fpc5719 @@ -131,22 +131,33 @@ export default { activeBtn: 1, drawer: true, phone: false, + vol: undefined }), mounted: async function () { - let vol; - await zutils.fetchAllVolunter((volworks) => { vol = volworks; }); - this.listen(vol) + await zutils.fetchAllVolunter((volworks) => { this.vol = volworks; }); + setInterval(this.listen, 30000, this); + console.log("mounted"); }, methods: { changeColorTheme() { this.$vuetify.theme.dark = !this.$vuetify.theme.dark; }, - async listen(last) { - if (!last) return; + async listen(t) { + console.log("listen"); + zutils.checkToken(t); let vol; await zutils.fetchAllVolunter((volworks) => { vol = volworks; }); - ipcRenderer.send(vol == last ? 'flash' : 'endflash'); - setInterval(this.listen, 300000, vol); + let flag = false; + let last = t.vol; + if (last && vol) { + if (vol.length != last.length) flag = true; + else { + for (var i = 0; i < vol.length; i++) + if (vol[i]["id"] != last[i]["id"]) + flag = true; + } + if (flag) ipcRenderer.send('flash'); + } }, minwindow() { ipcRenderer.send('minwindow') diff --git a/src/background.js b/src/background.js index 96da82f48687fd34a4e77b76ec68afb035d495cd..3e6d9afac767880b493d2b9be9af09fdf4fcf422 100644 --- a/src/background.js +++ b/src/background.js @@ -105,6 +105,7 @@ function createWindow() { }) let timericon; ipcMain.on('flash', () => { + if (timericon) return; win.flashFrame(true); let type = 0; timericon = setInterval(() => { @@ -115,7 +116,9 @@ function createWindow() { ); }) ipcMain.on('endflash', () => { + if (!timericon) return; clearInterval(timericon); + timericon = undefined; tray.setImage(path.join(__static,'logo.ico')); }) } diff --git a/src/components/signerlist.vue b/src/components/signerlist.vue index d78c1d0a635ac4fe28f444088e01e00b7a7bd7e1..f4d2bdf0d68a01834320d8444c4a2468578237e3 100644 --- a/src/components/signerlist.vue +++ b/src/components/signerlist.vue @@ -18,16 +18,16 @@ {{ vol.time }} - 校内时长(单位:分钟) - {{ vol.inside }} + 校内时长 + {{ timeToHint(vol.inside) }} - 校外时长(单位:分钟) - {{ vol.outside }} + 校外时长 + {{ timeToHint(vol.outside) }} - 大型时长(单位:分钟) - {{ vol.large }} + 大型时长 + {{ timeToHint(vol.large) }} 人数 @@ -73,6 +73,14 @@ export default { this.init(); }, methods: { + timeToHint: function (a){ + let hr = parseInt(a / 60); + let mi = a % 60; + if (hr != 0) + return hr + " 小时 " + mi + " 分钟"; + else + return mi + "分钟"; + }, init: function () { if (this.volid != 0 && this.volid != undefined) { this.$store.commit("loading", true); diff --git a/src/components/stuvolist.vue b/src/components/stuvolist.vue index 1912fd82e3d52fec28c732535813046d4a2f04b5..c719953b36bd5a3462301200930432721b083a4f 100644 --- a/src/components/stuvolist.vue +++ b/src/components/stuvolist.vue @@ -66,6 +66,14 @@ export default { this.init(); }, methods: { + timeToHint: function (a){ + let hr = parseInt(a / 60); + let mi = a % 60; + if (hr != 0) + return hr + " 小时 " + mi + " 分钟"; + else + return mi + "分钟"; + }, init: function () { this.volworks = undefined; if (this.userid != 0 && this.userid != undefined) { @@ -77,6 +85,11 @@ export default { dialogs.toasts.error(response.data.message); else if (response.data.type == "SUCCESS") { this.volworks = response.data.rec; + for (let i in this.volworks){ + this.volworks[i].inside = this.timeToHint(this.volworks[i].inside); + this.volworks[i].outside = this.timeToHint(this.volworks[i].outside); + this.volworks[i].large = this.timeToHint(this.volworks[i].large); + } } else dialogs.toasts.error("未知错误"); }) .catch((error) => { diff --git a/src/components/volinfo.vue b/src/components/volinfo.vue index 7b79ee559b1f8738cc36e10bf0f606b50724d74c..0d86fb76510d238f87a001ae690488c99cc22bd0 100644 --- a/src/components/volinfo.vue +++ b/src/components/volinfo.vue @@ -18,16 +18,16 @@ {{ vol.time }} - 校内时长(单位:分钟) - {{ vol.inside }} + 校内时长 + {{ timeToHint(vol.inside) }} - 校外时长(单位:分钟) - {{ vol.outside }} + 校外时长 + {{ timeToHint(vol.outside) }} - 大型时长(单位:分钟) - {{ vol.large }} + 大型时长 + {{ timeToHint(vol.large) }} 人数 @@ -73,6 +73,14 @@ export default { this.init(); }, methods: { + timeToHint: function (a){ + let hr = parseInt(a / 60); + let mi = a % 60; + if (hr != 0) + return hr + " 小时 " + mi + " 分钟"; + else + return mi + "分钟"; + }, init: function () { if (this.volid != 0 && this.volid != undefined) { this.$store.commit("loading", true); diff --git a/src/main.js b/src/main.js index e3953599d5a16b90b9fab12ae54bd9854f0d4559..9a041b3fe5c9e65a53600f3b252382e068fd49d3 100644 --- a/src/main.js +++ b/src/main.js @@ -35,7 +35,8 @@ axios.interceptors.request.use( router.beforeEach((to, from, next) => { NProgress.start(); - if (to.path != '/login') { + if (to.path == '/report') next(); + else if (to.path != '/login') { if (store.state.token) { next(); } else { diff --git a/src/utils/router.js b/src/utils/router.js index 1fa67a618f28999bb7804c1ad172a8d3d0d69c60..44ded66edd0714e792672bc651c1379dc527d064 100644 --- a/src/utils/router.js +++ b/src/utils/router.js @@ -30,6 +30,11 @@ export default new Router({ name: 'logout', component: () => import('../views/logout.vue') }, + { + path: '/report', + name: 'report', + component: () => import('../views/report.vue') + }, { path: '/class/list', name: 'classList', diff --git a/src/utils/store.js b/src/utils/store.js index cfb4e67c7776c1787ec6914313d278f45895748f..9820abc9008155a44d3f2866070e0f74433af359 100644 --- a/src/utils/store.js +++ b/src/utils/store.js @@ -17,7 +17,8 @@ export default new Vuex.Store({ classname: undefined }, draweritems: [ - { title: '登录', to: '/login', icon: 'mdi-account-circle' } + { title: '登录', to: '/login', icon: 'mdi-account-circle' }, + { title: "反馈错误", to: "/report", icon: "mdi-alert" } ] }, diff --git a/src/utils/zutils.js b/src/utils/zutils.js index 8c168630a563b4de6f9928071ff1859d5654b58f..9050465322ffbf324b3a216d0c3e934ee0243bd3 100644 --- a/src/utils/zutils.js +++ b/src/utils/zutils.js @@ -1,6 +1,26 @@ import Axios from "axios" +let { ipcRenderer } = window.require('electron'); + export default { + checkToken: async (con) => { + await Axios + .post("/user/info").then((msg) => { + if (msg["data"]["type"] != "SUCCESS") { + Axios.post("/user/logout").finally(() => { + con.$store.commit("draweritems", [ + { title: '登录', to: '/login', icon: 'mdi-account-circle' }, + { title: "反馈错误", to: "/report", icon: "mdi-alert" } + ]); + con.$store.state.token = undefined; + ipcRenderer.send('flash'); + con.$store.commit("loading", false); + con.$router.push("/login").catch(()=>{}); + }) + } + }) + }, + fetchClassList: async (callback) => { await Axios .get("/class/list") @@ -20,15 +40,19 @@ export default { let stus = response.data.student if (stus) for (var i = 0; i < stus.length; i++) { + // 义工时间上限;2021届以后有变动 + var vim=24,vom=20,vlm=16; + if(stus[i]["id"]>20210000){ vim=30;vom=16;vlm=18; } + var inside = stus[i]["inside"]/60.0; var outside = stus[i]["outside"]/60.0; var large = stus[i]["large"]/60.0; var result = true; - if (outside < 20) { - inside = inside - (20 - outside) * 2; - outside = 20; + if (outside < vom) { // 溢出判满机制:校内除二当校外 + inside = inside - (vom - outside) * 2; + outside = vom; } - if (large < 16 || inside < 20 || outside < 20 || inside + outside < 44) { + if (large < vlm || inside < vim || outside < vom || inside + outside < vim+vom) { result = false; } result ? stus[i].finished = "是" : stus[i].finished = "否" diff --git a/src/views/class/list.vue b/src/views/class/list.vue index b8582d7e21c90bcfcf076b9bf39ae48612f8bd8c..cda9aabee5e7c7784d33fe5684fe6f895cea13b3 100644 --- a/src/views/class/list.vue +++ b/src/views/class/list.vue @@ -32,6 +32,7 @@ import dialogs from "../../utils/dialogs"; import zutils from "../../utils/zutils"; import permissions from "../../utils/permissions"; +// import axios from "axios"; export default { data: () => ({ @@ -48,6 +49,7 @@ export default { methods: { async pageload() { this.$store.commit("loading", true); + await zutils.checkToken(this); await zutils.fetchClassList((classes) => { classes ? (this.classes = classes) diff --git a/src/views/class/stulist.vue b/src/views/class/stulist.vue index 2b7f22df25499bf3df0105c7b99dfa683ed45a2d..c8dfdfaeb59c5b7e0e5cdd3a142257519a66a866 100644 --- a/src/views/class/stulist.vue +++ b/src/views/class/stulist.vue @@ -80,11 +80,11 @@ export default { rowUserName: undefined, tipText: "班级", headers: [ - { text: "学号", value: "id", align: "start", sortable: true }, + { text: "学号", value: "id", align: "start"}, { text: "姓名", value: "name" }, - { text: "校内(分钟)", value: "inside" }, - { text: "校外(分钟)", value: "outside" }, - { text: "大型(分钟)", value: "large" }, + { text: "校内", value: "inside", sortable: false}, + { text: "校外", value: "outside", sortable: false }, + { text: "大型", value: "large", sortable: false }, { text: "完成", value: "finished" }, ], }), @@ -95,8 +95,17 @@ export default { this.pageload(); }, methods: { + timeToHint: function (a){ + let hr = parseInt(a / 60); + let mi = a % 60; + if (hr != 0) + return hr + " 小时 " + mi + " 分钟"; + else + return mi + "分钟"; + }, async pageload() { this.$store.commit("loading", true); + await zutils.checkToken(this); axios .get("/class/list") .then((response) => { @@ -138,6 +147,11 @@ export default { await zutils.fetchStudentList(this.nowclass, (stus) => { stus ? (this.students = stus) : (this.students = undefined); }); + for (let i in this.students){ + this.students[i].inside = this.timeToHint(this.students[i].inside); + this.students[i].outside = this.timeToHint(this.students[i].outside); + this.students[i].large = this.timeToHint(this.students[i].large); + } this.$store.commit("loading", false); }, diff --git a/src/views/home.vue b/src/views/home.vue index 310162eff73dd60ad6efab296d09021049bf23fa..d6b86a5d6d5dc6c91b9adb1d94bef8c5910a3a8b 100644 --- a/src/views/home.vue +++ b/src/views/home.vue @@ -8,13 +8,15 @@