From 0cd48936257e8f9297d9617c2a29f7b04b5d72d9 Mon Sep 17 00:00:00 2001 From: RainSun Date: Fri, 17 Apr 2020 10:41:48 +0800 Subject: [PATCH] add account && add auto reflash --- Dockerfile | 3 + nginx/default.conf | 17 + package.json | 3 +- public/index.html | 8 +- src/axios/fetch.js | 4 +- src/components/Drawer.vue | 17 +- src/components/FooterNav.vue | 16 +- src/lib/aes.js | 48 ++ src/router/index.js | 40 +- src/store/index.js | 22 - src/views/Grade/Grade.vue | 136 +++- src/views/Login/Login.vue | 10 +- src/views/MyAccount/MyAccount.vue | 29 +- src/views/Schedule/Schedule.vue | 457 ++++++++----- src/views/lostandfound/LAFAdd.vue | 605 ------------------ src/views/lostandfound/LAFDetail.vue | 487 -------------- src/views/lostandfound/LAFSearch.vue | 309 --------- src/views/lostandfound/LostAndFound.vue | 314 --------- src/views/lostandfound/components/Comment.vue | 121 ---- .../lostandfound/components/InfoCard.vue | 104 --- src/views/lostandfound/components/LAFCard.vue | 82 --- vue.config.js | 4 +- 22 files changed, 515 insertions(+), 2321 deletions(-) create mode 100644 Dockerfile create mode 100644 nginx/default.conf create mode 100644 src/lib/aes.js delete mode 100644 src/views/lostandfound/LAFAdd.vue delete mode 100644 src/views/lostandfound/LAFDetail.vue delete mode 100644 src/views/lostandfound/LAFSearch.vue delete mode 100644 src/views/lostandfound/LostAndFound.vue delete mode 100644 src/views/lostandfound/components/Comment.vue delete mode 100644 src/views/lostandfound/components/InfoCard.vue delete mode 100644 src/views/lostandfound/components/LAFCard.vue diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..76819a8 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,3 @@ +FROM nginx +COPY dist/ /usr/share/nginx/html/ +COPY nginx/default.conf /etc/nginx/conf.d/default.conf \ No newline at end of file diff --git a/nginx/default.conf b/nginx/default.conf new file mode 100644 index 0000000..790cda0 --- /dev/null +++ b/nginx/default.conf @@ -0,0 +1,17 @@ +server { + listen 80; + server_name localhost; + + access_log /var/log/nginx/host.access.log main; + error_log /var/log/nginx/error.log error; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + try_files $uri $uri/ /index.html; + } + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} \ No newline at end of file diff --git a/package.json b/package.json index 729d13b..031415e 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "coc", + "name": "cherry", "version": "0.1.0", "private": true, "scripts": { @@ -12,6 +12,7 @@ "axios": "^0.19.1", "babel-polyfill": "^6.26.0", "core-js": "^3.4.4", + "crc-32": "^1.2.0", "crypto-js": "^4.0.0", "element-ui": "^2.13.0", "es6-promise": "^4.2.8", diff --git a/public/index.html b/public/index.html index 19d4e8b..2a8ea74 100644 --- a/public/index.html +++ b/public/index.html @@ -3,9 +3,9 @@ - Co-Create - - + Cherry + + @@ -13,7 +13,7 @@ - + diff --git a/src/axios/fetch.js b/src/axios/fetch.js index de6f42c..73cbff8 100644 --- a/src/axios/fetch.js +++ b/src/axios/fetch.js @@ -2,8 +2,8 @@ import axios from 'axios' export const api = axios.create({ // baseURL: 'https://beta.powerrain.cn/api/', - // baseURL: 'https://coc.powerrain.cn/api/', - baseURL: window.location.origin + '/api/', + baseURL: 'https://coc.powerrain.cn/api/', + // baseURL: window.location.origin + '/api/', // baseURL: 'http://152.136.99.231:8001' + '/api/', //baseURL: 'http://127.0.0.1:5000/api', headers: { diff --git a/src/components/Drawer.vue b/src/components/Drawer.vue index 4e55a31..d52c334 100644 --- a/src/components/Drawer.vue +++ b/src/components/Drawer.vue @@ -21,7 +21,7 @@

课表小游戏

@@ -325,17 +325,4 @@ export default { opacity: 1; } } - -/* - 这个页面需要进行absolute处理 - 整体用left:width进行隐藏 - drawer为最高显示级别,分配z-index:200~250 - 将挂载在app上,任何页面都能打开 - * 账户页面 - * 账号密码 自动保存 - * 头像 默认 logo - * 昵称 默认 小樱桃001 - * 隐藏周末 - 课表小游戏 - 退出登录 -*/ \ No newline at end of file + \ No newline at end of file diff --git a/src/components/FooterNav.vue b/src/components/FooterNav.vue index 59db218..2372313 100644 --- a/src/components/FooterNav.vue +++ b/src/components/FooterNav.vue @@ -9,10 +9,10 @@

成绩

- +
+ +

我的

+
@@ -92,8 +92,8 @@ footer .content:nth-of-type(2) .select { // color: $footer-laf-color; // } -// footer .content:last-of-type .select { -// color: $footer-mine-color; -// /* color: #efe02d; */ -// } +footer .content:last-of-type .select { + color: $footer-mine-color; + /* color: #efe02d; */ +} \ No newline at end of file diff --git a/src/lib/aes.js b/src/lib/aes.js new file mode 100644 index 0000000..03e766e --- /dev/null +++ b/src/lib/aes.js @@ -0,0 +1,48 @@ +import CryptoJS from 'crypto-js' +import CRC32 from 'crc-32' + +// aes加密 +export function encrypt(code, json_row) { + // 循环冗余校验 + let aesKey = CRC32.str(code) + // 取八位 + aesKey = aesKey.toString().slice(0,8) + // 字符串化 + let json_str = JSON.stringify(json_row) + // 加密 + return CryptoJS.AES.encrypt(json_str, CryptoJS.enc.Utf8.parse(aesKey), { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7 + }).toString(); +} + +// aes解密 +export function decrypt(code, encrypt_str) { + // 循环冗余校验 + let aesKey = CRC32.str(code) + // 取八位 + aesKey = aesKey.toString().slice(0,8) + // 解密 + return CryptoJS.AES.decrypt(encrypt_str, CryptoJS.enc.Utf8.parse(aesKey), { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7 + }).toString(CryptoJS.enc.Utf8); +} + +// aes加密用户密码 +export function encryptMainCode(code) { + let default_key = 'e08b44a351a3' + return CryptoJS.AES.encrypt(code, CryptoJS.enc.Utf8.parse(default_key), { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7 + }).toString(); +} + +// aes解密用户密码 +export function decryptMainCode(row_code) { + let default_key = 'e08b44a351a3' + return CryptoJS.AES.decrypt(row_code, CryptoJS.enc.Utf8.parse(default_key), { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7 + }).toString(CryptoJS.enc.Utf8); +} \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js index 7d4cca5..402569e 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -34,38 +34,6 @@ const routes = [ meta:{ keepAlive:true }, - }, - { - path: '/laf', - name: 'LAF', - component: () => import(/* webpackChunkName: "laf" */ '../views/lostandfound/LostAndFound.vue'), - meta:{ - keepAlive:true - }, - }, - { - path: '/lafdetail', - name: 'LAFDetail', - component: () => import(/* webpackChunkName: "lafdetail" */ '../views/lostandfound/LAFDetail.vue'), - meta:{ - keepAlive:false - }, - }, - { - path: '/lafadd', - name: 'LAFAdd', - component: () => import(/* webpackChunkName: "lafadd" */ '../views/lostandfound/LAFAdd.vue'), - meta:{ - keepAlive:false - }, - }, - { - path: '/lafsearch', - name: 'LAFSearch', - component: () => import(/* webpackChunkName: "lafsearch" */ '../views/lostandfound/LAFSearch.vue'), - meta:{ - keepAlive:true - }, }, { path: '/game', @@ -75,6 +43,14 @@ const routes = [ keepAlive:false }, }, + { + path: '/myaccount', + name: 'MyAccount', + component: () => import(/* webpackChunkName: "account" */ '../views/MyAccount/MyAccount.vue'), + meta:{ + keepAlive:false + }, + }, { path: '*', // 页面不存在的情况下会跳到schedule redirect: '/schedule', diff --git a/src/store/index.js b/src/store/index.js index 25f60c0..5730759 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -11,10 +11,6 @@ export default new Vuex.Store({ grade: null, // 课表 schedule: null, - // LAF - LAF_data: null, - // 失物招领首页刷新 - LAF_reflash: false, // 当前页面 current_page: null, // 游戏 @@ -38,14 +34,6 @@ export default new Vuex.Store({ // 设置课表 SET_SCHEDULE(state, schedule){ state.schedule = schedule; - }, - // 设置LAF - SET_LAFDATA(state, LAF_data) { - state.LAF_data = LAF_data; - }, - // 设置失物招领首页刷新 - SET_LAFREFLASH(state, LAF_reflash) { - state.LAF_reflash = LAF_reflash; }, // 设置游戏 SET_SCHEDULE_GAME(state, schedule_game) { @@ -76,16 +64,6 @@ export default new Vuex.Store({ setSchedule({ commit }, arg){ commit('SET_SCHEDULE', arg[0]); localStorage.setItem("storeState", JSON.stringify(arg[1].$store.state)); - }, - // 设置失物信息 - setLAFData({ commit }, arg) { - commit('SET_LAFDATA', arg[0]); - localStorage.setItem("storeState", JSON.stringify(arg[1].$store.state)); - }, - // 设置失物招领首页刷新 - setLAFReflash({ commit }, arg) { - commit('SET_LAFREFLASH', arg[0]); - localStorage.setItem("storeState", JSON.stringify(arg[1].$store.state)); }, // 设置游戏 setScheduleGame({ commit }, arg) { diff --git a/src/views/Grade/Grade.vue b/src/views/Grade/Grade.vue index 1e771ea..9c5080c 100644 --- a/src/views/Grade/Grade.vue +++ b/src/views/Grade/Grade.vue @@ -68,10 +68,10 @@ 总绩点: {{total.total_GPA.toPrecision(4)}}

-

- 去选修绩点: - {{total.total_bixiu_GPA.toPrecision(4)}} -

+

+ 去选修绩点: + {{total.total_bixiu_GPA.toPrecision(4)}} +

总学分: {{total.total_credit}} @@ -94,7 +94,10 @@ import FooterSpace from "@/components/FooterSpace.vue"; import GradeCard from "./components/GradeCard.vue"; import { mapState, mapActions } from "vuex"; -import { getGradeInitData } from '@/lib/utils.js' +import { getGradeInitData } from "@/lib/utils.js"; +import { decryptMainCode } from "@/lib/aes.js"; +import { Loading } from "element-ui"; +import { login } from "@/axios/api.js"; export default { name: "grade", @@ -108,35 +111,48 @@ export default { }; }, computed: { - ...mapState(["grade", "user_info"]) + ...mapState(["grade", "user_info", "schedule"]) }, methods: { - ...mapActions(["setCurrentPage", 'setGrade']), + ...mapActions(["setUserInfo", "setGrade", "setSchedule", "setCurrentPage"]), // 初始化 init(lock = false) { - // 刷新本页vuex - this.$store.replaceState(Object.assign(this.$store.state,JSON.parse(localStorage.getItem("storeState")))); + // 刷新本页vuex + this.$store.replaceState( + Object.assign( + this.$store.state, + JSON.parse(localStorage.getItem("storeState")) + ) + ); // 互斥锁加锁 - if(this.init_lock) return - console.log('刷新成绩信息') - this.init_lock = lock + if (this.init_lock) return; + console.log("刷新成绩信息"); + this.init_lock = lock; // 设置footerNav this.setCurrentPage(["grade", this]); - // 处理第一次进来没有初始信息的情况 - if(!this.grade || Object.keys(this.grade) == 0 || !this.grade.data.total.total_bixiu_GPA || this.grade.data.total.total_bixiu_GPA == '∞') { - console.log('重置信息') - this.setGrade([getGradeInitData(), this]) - } + // 处理第一次进来没有初始信息的情况 + if ( + !this.grade || + Object.keys(this.grade) == 0 || + !this.grade.data.total.total_bixiu_GPA || + this.grade.data.total.total_bixiu_GPA == "∞" + ) { + console.log("重置信息"); + this.setGrade([getGradeInitData(), this]); + } //将grade的信息存到简单的变量里,由于不涉及更改,所以不需要深拷贝 - this.split = this.grade.data.split - this.total = this.grade.data.total + this.split = this.grade.data.split; + this.total = this.grade.data.total; // 互斥锁解锁 - setTimeout(function(){ - this.init_lock = false - }.bind(this), 100) + setTimeout( + function() { + this.init_lock = false; + }.bind(this), + 100 + ); }, - - // 改变周数 + + // 改变周数 changeWeek(direction, judge) { // 拦截器 if (!judge) return; @@ -144,9 +160,77 @@ export default { if (direction == "left") this.current_term_index++; else this.current_term_index--; }, - // 更新信息 + // 更新信息 reflash() { - this.$router.push("/login"); + // 未登录拦截 + if (!this.user_info || !this.user_info.pwd) { + this.$router.push("/login"); + return; + } + let load = Loading.service({ + background: "rgba(255,245,236,.7)", + target: document.querySelector(".grade") + }); + let cid = this.user_info.cid; + let pwd = decryptMainCode(this.user_info.pwd); + let data = { + cid, + pwd + }; + login(data) + .then(res => { + this.manageRes(res.data, load); + }) + .catch(error => { + console.log(error); + load.close(); + if ( + error.code === "ECONNABORTED" && + error.message.indexOf("timeout") !== -1 + ) { + // 超时 + this.$message.error("教务挂了"); + } else { + // 服务器挂了 + this.$message.error("服务器挂了"); + } + }); + }, + + // 处理服务器返回的数据 + manageRes(data, load) { + if (data.errcode == 200) { + // 登录成功 + // 后端数据,本地数据,初始化数据,有哪个取哪个, + // 成绩保证只存在初始数据和成功返回的数据两种情况 + let grade = + data.grade.errcode == 200 + ? data.grade + : this.grade + ? this.grade + : getGradeInitData(); + let schedule = + data.schedule.errcode == 200 + ? data.schedule + : this.schedule + ? this.schedule + : {}; + // 设置localStorage + this.setGrade([grade, this]); + this.setSchedule([schedule, this]); + // 用户侧处理 + this.split = this.grade.data.split; + this.total = this.grade.data.total; + load.close(); + this.$message({ + message: "信息刷新成功", + type: "success" + }); + } else { + // 教务挂了 + load.close(); + this.$message.error("教务挂了"); + } } }, created() { diff --git a/src/views/Login/Login.vue b/src/views/Login/Login.vue index f770ffd..216256b 100644 --- a/src/views/Login/Login.vue +++ b/src/views/Login/Login.vue @@ -43,6 +43,7 @@ import { login } from '@/axios/api.js'; import { Loading } from 'element-ui'; import FooterSpace from '@/components/FooterSpace.vue'; import { getGradeInitData } from '@/lib/utils.js' +import { encryptMainCode } from '@/lib/aes.js' export default { name: 'login', @@ -67,12 +68,6 @@ export default { this.$store.replaceState(Object.assign(this.$store.state,JSON.parse(localStorage.getItem("storeState")))); // 设置footerNav this.setCurrentPage(["None", this]); - // 只对已经获取到信息的用户显示 - if (this.grade || this.schedule) { - this.$alert('如从教务获取信息失败,将保留原先数据', '提示', { - confirmButtonText: '阅!' - }); - } }, // 用户点击rushB @@ -121,7 +116,8 @@ export default { login_time: new Date().getTime(), id: data.student_id, name: data.student_name, - cid: this.cid + cid: this.cid, + pwd: encryptMainCode(this.pwd) }; // 后端数据,本地数据,初始化数据,有哪个取哪个, // 成绩保证只存在初始数据和成功返回的数据两种情况 diff --git a/src/views/MyAccount/MyAccount.vue b/src/views/MyAccount/MyAccount.vue index 725c56d..598acb0 100644 --- a/src/views/MyAccount/MyAccount.vue +++ b/src/views/MyAccount/MyAccount.vue @@ -1,7 +1,7 @@