Merge branch 'v3' into 'master'

V3

See merge request lacus/cherryfrontend!1
This commit is contained in:
RainSun 2021-03-03 08:27:49 +00:00
commit 9c04ef09ef
43 changed files with 3899 additions and 2837 deletions

3
Dockerfile Normal file
View File

@ -0,0 +1,3 @@
FROM nginx
COPY dist/ /usr/share/nginx/html/
COPY nginx/default.conf /etc/nginx/conf.d/default.conf

View File

@ -34,5 +34,7 @@ See [Configuration Reference](https://cli.vuejs.org/config/).
```
## 本地缓存
* `localStorage.setItem("storeState",JSON.stringify(this.$store.state))`
* `this.$store.replaceState(Object.assign(this.$store.state,JSON.parse(localStorage.getItem("storeState"))));`
* `localStorage.setItem("cherry",JSON.stringify(this.$store.state))`
* `this.$store.replaceState(Object.assign(this.$store.state,JSON.parse(localStorage.getItem("cherry"))));`
* 旋转色值filter: hue-rotate(290deg);

17
nginx/default.conf Normal file
View File

@ -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;
}
}

View File

@ -1,6 +1,6 @@
{
"name": "coc",
"version": "0.1.0",
"name": "cherry",
"version": "3.3.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
@ -12,10 +12,11 @@
"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",
"lrz": "^4.9.40",
"lrz": "^4.9.41",
"register-service-worker": "^1.6.2",
"url-search-params-polyfill": "^8.0.0",
"vue": "^2.6.10",

View File

@ -3,9 +3,9 @@
<head>
<meta charset="utf-8">
<title>Co-Create</title>
<meta name="description" content="Co-Create!为长理同学提供课表,成绩代理查询服务" />
<meta name="keywords" content="Co-Create,coc,长春理工大学,长理,coc app,教务系统,查课表,查成绩" />
<title>Cherry</title>
<meta name="description" content="Cherry!为长理同学提供课表,成绩代理查询服务" />
<meta name="keywords" content="Cherry,长春理工大学,长理app,教务系统,查课表,查成绩" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes">
@ -13,10 +13,11 @@
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<link rel="apple-touch-icon-precomposed" href="<%= BASE_URL %>favicon.ico">
<!-- 标题 -->
<meta itemprop="name" content="Co-Create" />
<meta itemprop="name" content="Cherry" />
<!-- 描述 -->
<meta itemprop="description" content="为长理同学提供课表代理查询服务" />
<meta name="referrer" content="no-referrer">
<script>
var _hmt = _hmt || [];
(function () {
@ -26,6 +27,7 @@
s.parentNode.insertBefore(hm, s);
})();
</script>
<script>
try {
console.log('%cInspire Studio Copyright \xa9 2019-%s',

View File

@ -1,6 +1,5 @@
<template>
<div id="app">
<div class="bg"></div>
<Drawer></Drawer>
<!-- 缓存 -->
<keep-alive>
@ -9,17 +8,20 @@
<!-- 非缓存 -->
<router-view v-if="!this.$route.meta.keepAlive"></router-view>
<FooterNav></FooterNav>
<DrawerAct></DrawerAct>
</div>
</template>
<script>
import FooterNav from "@/components/FooterNav.vue";
import Drawer from "@/components/Drawer.vue";
import DrawerAct from "@/components/DrawerAct.vue";
export default {
name: "grade",
name: "App",
components: {
FooterNav,
Drawer
Drawer,
DrawerAct
}
};
</script>
@ -141,18 +143,6 @@ button {
-khtml-user-select: none;
user-select: none;
}
.bg {
position: fixed;
top: 0;
left: 0;
z-index: -100;
height: 100%;
width: 100%;
object-fit: cover;
background-image: linear-gradient(to bottom, #eaeaea, #ababab);
background-repeat: no-repeat;
background-size: 100% 100%;
}
.icon {
fill: currentColor;
overflow: hidden;

View File

@ -3,13 +3,13 @@ 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: 'http://152.136.99.231:8001' + '/api/',
// baseURL: window.location.origin + '/api/',
baseURL: 'https://cherry.lacus.site' + '/api/',
//baseURL: 'http://127.0.0.1:5000/api',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json',
// 'Access-Control-Allow-Origin': '*'
'Access-Control-Allow-Origin': '*'
},
timeout: 30 * 1000
})

View File

@ -1,44 +1,83 @@
<template>
<div class="drawer">
<div class="mask" :class="mask_class" @click="closeDrawer()" v-if="drawer_state">
<div
class="mask"
:class="mask_class"
@click="closeDrawer()"
v-if="drawer_state"
>
<div class="w">
<!-- 抽屉主体 -->
<div class="main" :class="main_class" @click.stop>
<div
class="main"
:class="main_class"
@click.stop
>
<div class="title">
<div class="logo-box">
<img src="../assets/logo.png" alt />
<img
src="../assets/logo.png"
alt
/>
</div>
<p class="app-name">Co-Create</p>
<p class="version">Version 2.0.1</p>
<p class="app-name">Cherry</p>
<p class="version">Version 3.7</p>
</div>
<div class="list">
<!-- <div class="list-item">
<icon class="info" name="info"></icon>
<p>账户设置</p>
</div> -->
<div class="list-item" @click="goToGame()">
<icon class="game" name="game"></icon>
<div
class="list-item"
@click="goToGame()"
>
<icon
class="game"
name="game"
></icon>
<p>课表小游戏</p>
</div>
<div class="list-item"
v-clipboard:copy="'https://ccb.canary.moe'"
v-clipboard:success="onCopyUrl"
v-clipboard:error="onErrorUrl">
<icon class="game" name="canary"></icon>
<div
class="list-item"
@click="goToCanary()"
>
<icon
class="game"
name="canary"
></icon>
<p>Canary密码本</p>
</div>
</div>
<div class="bottom-box" v-if="user_info">
<div class="logout-dialog to-show" v-if="dialog_state">
<div
class="bottom-box"
v-if="user_info"
>
<div
class="logout-dialog to-show"
v-if="dialog_state"
>
<p class="label">警告</p>
<p class="content">该操作将清除您所有的个人信息是否继续</p>
<div class="confirm-box">
<p class="cancel" @click="dialog_state = false">取消</p>
<p class="confirm" @click="logout">继续</p>
<p
class="cancel"
@click="dialog_state = false"
>取消</p>
<p
class="confirm"
@click="logout"
>继续</p>
</div>
</div>
<div class="bottom-button" @click="dialog_state = true">
<icon class="logout" name="logout"></icon>
<div
class="bottom-button"
@click="dialog_state = true"
>
<icon
class="logout"
name="logout"
></icon>
<p>退出登录</p>
</div>
</div>
@ -51,10 +90,10 @@
<script>
import { mapState, mapActions } from "vuex";
import { getGradeInitData } from '@/lib/utils.js'
import { replaceState } from '@/lib/getStore.js'
export default {
name: "footerNav",
data() {
name: "Drawer",
data () {
return {
mask_class: '',
main_class: '',
@ -62,60 +101,44 @@ export default {
}
},
computed: {
...mapState(["drawer_state","user_info"])
...mapState(["drawer_state", "user_info"])
},
methods: {
...mapActions(["setDrawerState","setUserInfo",'setGrade','setSchedule']),
//
init() {
// vuex
this.$store.replaceState(Object.assign(this.$store.state,JSON.parse(localStorage.getItem("storeState"))));
},
closeDrawer() {
...mapActions(["setDrawerState", "setUserInfo", 'setGrade', 'setSchedule']),
//
closeDrawer () {
this.dialog_state = false
this.mask_class = 'to-shallow'
this.main_class = 'to-left'
setTimeout(()=>{
setTimeout(() => {
this.setDrawerState([false, this])
}, 300)
},
//
reflash() {
this.setDrawerState([false, this])
this.$router.push({ name: "login" });
goToCanary () {
window.open('https://canary.lacus.icu')
},
//
goToGame() {
goToGame () {
this.setDrawerState([false, this])
this.$router.push('/game')
this.$router.push('/game')
},
// 退
logout() {
this.setUserInfo([null, this])
this.setGrade([getGradeInitData(), this])
this.setSchedule([null, this])
this.closeDrawer()
logout () {
localStorage.clear();
replaceState.call(this);
this.$router.replace('/login')
},
onCopyUrl(e) {
this.$message.success("网址复制成功!");
},
onErrorUrl(e) {
this.$message.success("网址复制失败!");
}
},
created() {
this.init()
created () {
},
watch: {
drawer_state: function() {
if(this.drawer_state) {
drawer_state: function () {
if (this.drawer_state) {
//
this.init()
this.mask_class = 'to-deep'
this.main_class = 'to-right'
}
},
},
}
};
</script>
@ -206,28 +229,30 @@ export default {
bottom: 0;
left: 0;
.logout-dialog {
margin: .5rem;
-moz-box-shadow:3px 4px 11px $home-card-boxshadow-color; -webkit-box-shadow:3px 4px 11px $home-card-boxshadow-color; box-shadow:3px 4px 11px $home-card-boxshadow-color;
border-radius: .1rem;
padding: .3rem;
margin: 0.5rem;
-moz-box-shadow: 3px 4px 11px $home-card-boxshadow-color;
-webkit-box-shadow: 3px 4px 11px $home-card-boxshadow-color;
box-shadow: 3px 4px 11px $home-card-boxshadow-color;
border-radius: 0.1rem;
padding: 0.3rem;
box-sizing: border-box;
border: 1px solid $home-card-border-color;
.label {
font-size: .4rem;
font-size: 0.4rem;
}
.content {
font-size: .3rem;
margin-top: .3rem;
font-size: 0.3rem;
margin-top: 0.3rem;
}
.confirm-box {
display: flex;
align-items: center;
justify-content: flex-end;
font-size: .3rem;
margin-top: .3rem;
font-size: 0.3rem;
margin-top: 0.3rem;
.cancel {
color: #989898;
margin-right: .3rem;
margin-right: 0.3rem;
}
.confirm {
color: $red;
@ -319,23 +344,10 @@ export default {
@keyframes toShow {
0% {
opacity: .3;
opacity: 0.3;
}
100% {
opacity: 1;
}
}
</style>
/*
这个页面需要进行absolute处理
整体用leftwidth进行隐藏
drawer为最高显示级别分配z-index200~250
将挂载在app上任何页面都能打开
* 账户页面
* 账号密码 自动保存
* 头像 默认 logo
* 昵称 默认 小樱桃001
* 隐藏周末
课表小游戏
退出登录
*/

View File

@ -0,0 +1,48 @@
<template>
<div class="drawer-act">
<div class="drawer-warp">
<v-touch :swipe-options="{direction: 'horizontal'}" @swiperight="openDrawer">
<div class="act"></div>
</v-touch>
</div>
</div>
</template>
<script>
import { mapState, mapActions } from "vuex";
export default {
name: "DrawerAct",
methods: {
...mapActions(["setDrawerState"]),
openDrawer() {
this.setDrawerState([true, this])
},
},
created() {
},
};
</script>
<style scoped lang="scss" type="text/scss">
@import "../style/main";
.drawer-act {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 50;
.drawer-warp {
max-width: 500px;
margin: 0 auto;
.act {
position: absolute;
width: 0.7rem;
height: calc(100vh);
}
}
}
</style>

View File

@ -3,25 +3,25 @@
<div class="w">
<div class="content" @click="goToAddress('/schedule')">
<i :class="current_page == 'schedule'? 'select' : ''" class="el-icon-message-solid"></i>
<p :class="current_page == 'schedule'? 'select' : ''">课表</p>
<p v-if="!settings.hide_tab_text" :class="current_page == 'schedule'? 'select' : ''">课表</p>
</div>
<div class="content" @click="goToAddress('/grade')">
<i :class="current_page == 'grade'? 'select' : ''" class="el-icon-s-claim"></i>
<p :class="current_page == 'grade'? 'select' : ''">成绩</p>
<p v-if="!settings.hide_tab_text" :class="current_page == 'grade'? 'select' : ''">成绩</p>
</div>
<div class="content" @click="goToAddress('/myaccount')">
<i :class="current_page == 'myaccount'? 'select' : ''" class="el-icon-s-custom"></i>
<p v-if="!settings.hide_tab_text" :class="current_page == 'myaccount'? 'select' : ''">我的</p>
</div>
<!-- <div class="content" @click="goToAddress('/laf')">
<i :class="current_page == 'laf'? 'select' : ''" class="el-icon-s-flag"></i>
<p :class="current_page == 'laf'? 'select' : ''">失物招领</p>
</div> -->
</div>
</footer>
</template>
<script>
import { mapState, mapActions } from "vuex";
import { mapState } from "vuex";
export default {
name: "footerNav",
name: "FooterNav",
computed: {
...mapState(["current_page"])
...mapState(["current_page", "settings"])
},
methods: {
goToAddress(url) {
@ -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; */
}
</style>

View File

@ -3,7 +3,7 @@
</template>
<script>
export default {
name: "footerspace",
name: "FooterSpace",
data() {
return {};
}

92
src/components/Input.vue Normal file
View File

@ -0,0 +1,92 @@
<template>
<div class="input">
<label :class="{'placeholder': input_focus ? false : value ? false : true}" for="input">{{label}}</label>
<input type="text" :value="value" @change="$emit('change', $event.target.value)" @focus="input_focus = true" @blur="input_focus = false" id="input"/>
<div class="line"></div>
</div>
</template>
<script>
export default {
name: "Input",
data: () => {
return {
input_focus: false,
}
},
model: {
prop: "value",
event: "change",
},
props: {
value: {
type: String,
default: "",
},
label: {
type: String,
default: "标题",
},
},
};
</script>
<style scoped lang="scss" type="text/scss">
@import "../style/main";
.input {
display: flex;
align-items: center;
flex: 1;
height: 1.8rem;
position: relative;
label {
position: absolute;
top: 0;
left: 0;
font-size: 0.35rem;
height: 0.5rem;
line-height: 0.5rem;
color: #989898;
transition: all 0.25s;
}
.placeholder {
top: .8rem;
font-size: 0.45rem;
height: 1rem;
line-height: 1rem;
line-height: 0.5rem;
}
input {
border: none;
border-bottom: 1px #333 solid;
outline: none;
flex: 1;
font-size: 0.45rem;
height: 1rem;
line-height: 1rem;
margin-top: 0.15rem;
appearance: none;
-moz-appearance: none; /* Firefox */
-webkit-appearance: none; /* Safari 和 Chrome */
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}
input:focus {
& + .line {
width: 100%;
}
border: none;
}
.line {
position: absolute;
width: 0;
top: 1.45rem;
height: 2px;
background: $gradualGreen;
transition: width 0.25s;
}
.spread {
width: 100%;
}
}
</style>

162
src/components/Select.vue Normal file
View File

@ -0,0 +1,162 @@
<template>
<div class="select">
<label>{{label}}</label>
<input type="text" readonly :value="input_value" :class="{'border': !open_options}"
@click="openOptions"
@keydown.down="openOptions"
@keydown.enter="openOptions"
@keydown.space="openOptions"/>
<div class="line" :class="{'spread': open_options}"></div>
<i class="el-icon-caret-bottom icon"></i>
<div class="options-table" v-if="open_options" :style="`top: ${top}rem;`">
<div class="options" v-for="(item, index) in options" @click="choseContent(item.value)" :key="index">{{item.text}}</div>
</div>
<div class="mask" v-if="open_options" @click="closeTable"></div>
</div>
</template>
<script>
export default {
name: "Select",
data: () => {
return {
open_options: false,
top: 0.2
}
},
model: {
prop: 'value',
event: 'change'
},
props: {
options: {
type: Array,
default: []
},
value: {
type: Number,
default: ''
},
label: {
type: String,
default: '标题'
}
},
computed: {
input_value: function() {
for(let item of this.options) {
if(item.value == this.value) return item.text
}
}
},
methods:{
openOptions() {
let i = -1
for(let item of this.options) {
i++
if(item.value == this.value) break
}
this.top = 0.2 - i * 1.3
this.open_options = true
},
choseContent(value) {
this.open_options = false
this.$emit('change', value)
},
closeTable() {
this.open_options = false
}
}
}
</script>
<style scoped lang="scss" type="text/scss">
@import "../style/main";
.select {
display: flex;
align-items: center;
flex: 1;
height: 1.8rem;
position: relative;
label {
position: absolute;
top: 0;
left: 0;
font-size: .35rem;
height: .5rem;
line-height: .5rem;
color: #989898;
}
input {
border: none;
cursor: pointer;
outline: none;
flex: 1;
font-size: .45rem;
height: 1rem;
line-height: 1rem;
margin-top: .15rem;
appearance:none;
-moz-appearance:none; /* Firefox */
-webkit-appearance:none; /* Safari 和 Chrome */
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-webkit-user-select: none;
}
.border {
border-bottom: 1px #333 solid;
}
.line {
position: absolute;
width: 0;
top: 1.45rem;
height: 2px;
background: $gradualGreen;
transition: width .25s;
}
.spread {
width: 100%;
}
.icon {
position: absolute;
font-size: .4rem;
right: .2rem;
color: #989898;
}
.options-table {
position: absolute;
top: .2rem;
left: -.3rem;
background-color: #fff;
min-width: 7rem;
box-shadow: 1px 1px 15px #ababab;
padding-left: .3rem;
padding-top: .3rem;
z-index: 151;
opacity: 0;
.options {
font-size: .45rem;
height: 1rem;
line-height: 1rem;
margin-bottom: .3rem;
}
animation: toShow 0.25s ease .1s;
animation-fill-mode: forwards;
}
.mask {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: 150;
}
}
@keyframes toShow {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
</style>

62
src/components/Slider.vue Normal file
View File

@ -0,0 +1,62 @@
<template>
<div class="slider">
<input
:value="value"
type="range"
@change="$emit('change', $event.target.value)"
max="1"
min="0"
step="0.1"
/>
</div>
</template>
<script>
export default {
name: "Slider",
model: {
prop: "value",
event: "change",
},
props: {
value: {
type: Number,
default: 1,
},
},
};
</script>
<style scoped lang="scss" type="text/scss">
@import "../style/main";
.slider {
display: flex;
align-items: center;
justify-content: center;
input {
width: 4rem;
background-size: 98% 3px;
background: $gradualGreen;
outline: none;
appearance: none;
-moz-appearance: none; /* Firefox */
-webkit-appearance: none; /* Safari 和 Chrome */
height: 3px; /*横条的高度*/
}
input[type="range"]::-webkit-slider-thumb {
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #fff;
box-shadow: 0 0 4px $olive;
cursor: pointer;
appearance: none;
-moz-appearance: none; /* Firefox */
-webkit-appearance: none; /* Safari 和 Chrome */
border: 0;
}
input[type="range"]:focus {
outline: none;
}
}
</style>

View File

@ -0,0 +1,86 @@
<template>
<div class="snake-bar" :class="snack_bar_class">
<div class="warp">
<div class="content">{{msg}}</div>
</div>
</div>
</template>
<script>
export default {
name: "SnakeBar",
props: ["msg"],
data() {
return {
snack_bar_class: ""
};
},
computed: {},
methods: {
openSnackBar(content) {
this.snack_bar_class = "higher-snake-bar";
setTimeout(() => {
this.snack_bar_class = "lower-snake-bar";
}, 1000);
},
},
created() {
this.openSnackBar();
},
mounted() {},
watch: {},
beforeDestroy() {},
components: {},
activated() {}
};
</script>
<style scoped lang="scss" type="text/scss">
@import "../../style/main";
.snake-bar {
position: fixed;
left: 0;
bottom: -1.2rem;
width: 100%;
.warp {
width: 100%;
max-width: 500px;
margin: 0 auto;
height: 1.2rem;
background: $gradualGreen;
.content {
margin-left: 0.3rem;
padding-left: 0.3rem;
font-size: 0.35rem;
line-height: 1.2rem;
letter-spacing: 2px;
color: #fff;
}
}
}
.higher-snake-bar {
animation: snakeToHigh 0.5s ease;
animation-fill-mode: forwards;
}
.lower-snake-bar {
animation: snakeToLow 0.5s ease;
animation-fill-mode: forwards;
}
@keyframes snakeToHigh {
0% {
bottom: -1.2rem;
}
100% {
bottom: 0rem;
}
}
@keyframes snakeToLow {
0% {
bottom: 0rem;
}
100% {
bottom: -1.2rem;
}
}
</style>

View File

@ -0,0 +1,31 @@
import SnakeBar from './SnakeBar.vue'
import Vue from 'vue'
let SnakeBarConstructor = Vue.extend(SnakeBar)
let instance
let seed = 1
let index = 2000
let eleList = []
const install = () => {
Object.defineProperty(Vue.prototype, '$snakebar', {
get () {
let id = 'snakebar_' + seed++
const alertMsg = options => {
instance = new SnakeBarConstructor({
propsData: {msg:options}
})
index++
instance.id = id
instance.vm = instance.$mount()
document.body.appendChild(instance.vm.$el)
eleList.push(instance.vm.$el)
setTimeout(()=> {
document.body.removeChild(eleList.shift())
},1500)
instance.vm.$el.style.zIndex = index
return instance.vm
}
return alertMsg
}
})
}
export default install

48
src/lib/aes.js Normal file
View File

@ -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);
}

35
src/lib/getStore.js Normal file
View File

@ -0,0 +1,35 @@
// 刷新本页vuex
export function replaceState () {
let state = {}
for (let key of Object.keys(this.$store.state)) {
let content = JSON.parse(localStorage.getItem("cherry_" + key))
if (key == 'user_info' && content == null) content = {}
if (key == 'personal_class' && content == null) content = {}
if (key == 'drawer_state' && content == null) content = false
if (key == 'settings' && content == null) content = {
// 隐藏周末
hide_weekend: false,
// 课表背景链接
user_bg_url: 'https://neko.lacus.site/v1/images/2020101722030968.jpg',
// 是否开启了背景
user_bg_switch: false,
// 课程透明度
lesson_opacity: 0.8,
// 背景主题
user_bg_is_dark: true,
// 课程以及节数的显示方式 无 衬底 阴影 => 0 1 2
bar_show_style: 0,
// 黑暗模式
dark_mode: false,
// 隐藏tab文字
hide_tab_text: false,
}
state[key] = content
}
this.$store.replaceState(
Object.assign(
this.$store.state,
state
)
);
}

36
src/lib/schedule.js Normal file
View File

@ -0,0 +1,36 @@
// 处理课表
export function manageSchedule(all_lesson) {
// 处理完的课表
let after_process = []
// 遍历
for(let week = 0; week < 22; week++) {
// 周
after_process.push([])
for(let day = 0; day < 7; day++) {
// 日
after_process[week].push([])
for(let lesson = 0; lesson < 6; lesson++) {
// 节
let after_process_lesson = undefined
let cache = []
if(all_lesson[day][lesson]) {
// 这节课有内容
for(let cur_lesson of all_lesson[day][lesson]) {
if(cur_lesson.Time_split[week+1]){
cache.push(cur_lesson)
}
}
}
cache = JSON.parse(JSON.stringify(cache))
if(cache.length !== 0) {
// 里边有课程
after_process_lesson = cache[0]
cache.shift()
after_process_lesson['hide'] = cache
}
after_process[week][day].push(after_process_lesson)
}
}
}
return after_process
}

646
src/lib/testInfo.js Normal file
View File

@ -0,0 +1,646 @@
export var test_info = {
"grade": {
"split": [{
"term_GPA": 5.0,
"term_credit": 25.5,
"term_dead": 0,
"term_grade": [{
"class": "正常",
"credit": 1,
"grade": 100,
"kill": "yes",
"title": "大学生就业指导"
}, {
"class": "正常",
"credit": 2,
"grade": 100,
"kill": "yes",
"title": "形势与政策"
}, {
"class": "正常",
"credit": 2.5,
"grade": 100,
"kill": "yes",
"title": "Web程序设计"
}, {
"class": "正常",
"credit": 2.5,
"grade": 100,
"kill": "yes",
"title": "海量信息处理与云计算"
}, {
"class": "正常",
"credit": 2.5,
"grade": 100,
"kill": "yes",
"title": "嵌入式操作系统"
}, {
"class": "正常",
"credit": 2.5,
"grade": 100,
"kill": "yes",
"title": "嵌入式系统设计"
}, {
"class": "正常",
"credit": 2.5,
"grade": 100,
"kill": "yes",
"title": "数据挖掘技术"
}, {
"class": "正常",
"credit": 2.5,
"grade": 100,
"kill": "yes",
"title": "算法分析与设计"
}, {
"class": "正常",
"credit": 2.5,
"grade": 100,
"kill": "yes",
"title": "云计算与分布式系统"
}, {
"class": "正常",
"credit": 2,
"grade": 100,
"kill": "yes",
"title": "第二外语(日语)"
}, {
"class": "正常",
"credit": 3,
"grade": 100,
"kill": "yes",
"title": "专业方向应用实训科研训练"
}],
"term_kill": 11,
"term_time": "20192"
}, {
"term_GPA": 5.0,
"term_credit": 27.5,
"term_dead": 0,
"term_grade": [{
"class": "正常",
"credit": 6,
"grade": 100,
"kill": "yes",
"title": "毛泽东思想和中国特色社会主义理论体系概论"
}, {
"class": "正常",
"credit": 2.5,
"grade": 100,
"kill": "yes",
"title": "Internet技术与应用"
}, {
"class": "正常",
"credit": 2,
"grade": 100,
"kill": "yes",
"title": "并行计算"
}, {
"class": "正常",
"credit": 2,
"grade": 100,
"kill": "yes",
"title": "嵌入式系统原理"
}, {
"class": "正常",
"credit": 3.5,
"grade": 100,
"kill": "yes",
"title": "操作系统"
}, {
"class": "正常",
"credit": 3.5,
"grade": 100,
"kill": "yes",
"title": "计算机网络"
}, {
"class": "正常",
"credit": 3.5,
"grade": 100,
"kill": "yes",
"title": "计算机组成原理"
}, {
"class": "正常",
"credit": 2.5,
"grade": 100,
"kill": "yes",
"title": "计算科学与数值方法"
}, {
"class": "正常",
"credit": 2,
"grade": 100,
"kill": "yes",
"title": "操作系统综合实践课程设计"
}],
"term_kill": 9,
"term_time": "20191"
}, {
"term_GPA": 5.0,
"term_credit": 31.5,
"term_dead": 0,
"term_grade": [{
"class": "正常",
"credit": 4,
"grade": 100,
"kill": "yes",
"title": "大学外语"
}, {
"class": "正常",
"credit": 1,
"grade": 100,
"kill": "yes",
"title": "电工电子实习Ⅱ"
}, {
"class": "正常",
"credit": 3,
"grade": 100,
"kill": "yes",
"title": "概率论与数理统计Ⅰ"
}, {
"class": "正常",
"credit": 3,
"grade": 100,
"kill": "yes",
"title": "马克思主义基本原理"
}, {
"class": "正常",
"credit": 1,
"grade": 100,
"kill": "yes",
"title": "乒乓球"
}, {
"class": "正常",
"credit": 0.5,
"grade": 100,
"kill": "yes",
"title": "数学实验"
}, {
"class": "正常",
"credit": 1,
"grade": 100,
"kill": "yes",
"title": "中国古典诗歌的意境之美"
}, {
"class": "正常",
"credit": 2,
"grade": 100,
"kill": "yes",
"title": "信息系统开发实践课程设计"
}, {
"class": "正常",
"credit": 1,
"grade": 100,
"kill": "yes",
"title": "工程训练"
}, {
"class": "正常",
"credit": 3.5,
"grade": 100,
"kill": "yes",
"title": "工程制图与CAD"
}, {
"class": "正常",
"credit": 2,
"grade": 100,
"kill": "yes",
"title": "软件工程"
}, {
"class": "正常",
"credit": 2.5,
"grade": 100,
"kill": "yes",
"title": "数字逻辑"
}, {
"class": "正常",
"credit": 2.5,
"grade": 100,
"kill": "yes",
"title": "数据库原理与应用"
}, {
"class": "正常",
"credit": 2.5,
"grade": 100,
"kill": "yes",
"title": "汇编语言"
}, {
"class": "正常",
"credit": 2,
"grade": 100,
"kill": "yes",
"title": "数学建模"
}],
"term_kill": 15,
"term_time": "20182"
}, {
"term_GPA": 5.0,
"term_credit": 31.8,
"term_dead": 0,
"term_grade": [{
"class": "正常",
"credit": 4,
"grade": 100,
"kill": "yes",
"title": "大学外语"
}, {
"class": "正常",
"credit": 4,
"grade": 100,
"kill": "yes",
"title": "大学物理Ⅱ"
}, {
"class": "正常",
"credit": 1,
"grade": 100,
"kill": "yes",
"title": "电工电子技术实验"
}, {
"class": "正常",
"credit": 1,
"grade": 100,
"kill": "yes",
"title": "乒乓球"
}, {
"class": "正常",
"credit": 3,
"grade": 100,
"kill": "yes",
"title": "线性代数"
}, {
"class": "正常",
"credit": 1,
"grade": 100,
"kill": "yes",
"title": "知识产权法"
}, {
"class": "正常",
"credit": 3,
"grade": 100,
"kill": "yes",
"title": "中国近现代史纲要"
}, {
"class": "正常",
"credit": 0.8,
"grade": 100,
"kill": "yes",
"title": "大学物理实验Ⅱ"
}, {
"class": "正常",
"credit": 4,
"grade": 100,
"kill": "yes",
"title": "电工电子技术"
}, {
"class": "正常",
"credit": 2,
"grade": 100,
"kill": "yes",
"title": "离散数学"
}, {
"class": "正常",
"credit": 3.5,
"grade": 100,
"kill": "yes",
"title": "数据结构与算法"
}, {
"class": "正常",
"credit": 2,
"grade": 100,
"kill": "yes",
"title": "软件基础算法设计课程设计"
}, {
"class": "正常",
"credit": 2.5,
"grade": 100,
"kill": "yes",
"title": "C# 程序设计"
}],
"term_kill": 13,
"term_time": "20181"
}, {
"term_GPA": 5.0,
"term_credit": 36.3,
"term_dead": 0,
"term_grade": [{
"class": "正常",
"credit": 1,
"grade": 100,
"kill": "yes",
"title": "大学体育"
}, {
"class": "正常",
"credit": 4,
"grade": 100,
"kill": "yes",
"title": "大学外语"
}, {
"class": "正常",
"credit": 4,
"grade": 100,
"kill": "yes",
"title": "大学物理Ⅱ"
}, {
"class": "正常",
"credit": 0.8,
"grade": 100,
"kill": "yes",
"title": "大学物理实验Ⅱ"
}, {
"class": "正常",
"credit": 1,
"grade": 100,
"kill": "yes",
"title": "大学语文"
}, {
"class": "正常",
"credit": 7,
"grade": 100,
"kill": "yes",
"title": "高等数学Ⅱ"
}, {
"class": "正常",
"credit": 1,
"grade": 100,
"kill": "yes",
"title": "军事理论"
}, {
"class": "正常",
"credit": 2,
"grade": 100,
"kill": "yes",
"title": "面向对象程序设计课程设计"
}, {
"class": "正常",
"credit": 1,
"grade": 100,
"kill": "yes",
"title": "软件工程认识实习"
}, {
"class": "正常",
"credit": 2,
"grade": 100,
"kill": "yes",
"title": "大学生心理健康教育"
}, {
"class": "正常",
"credit": 2,
"grade": 100,
"kill": "yes",
"title": "宋崇导演教你拍摄微电影"
}, {
"class": "正常",
"credit": 3,
"grade": 100,
"kill": "yes",
"title": "微观经济学"
}, {
"class": "正常",
"credit": 4,
"grade": 100,
"kill": "yes",
"title": "离散数学"
}, {
"class": "正常",
"credit": 3.5,
"grade": 100,
"kill": "yes",
"title": "面向对象程序设计"
}],
"term_kill": 14,
"term_time": "20172"
}, {
"term_GPA": 5.0,
"term_credit": 22.5,
"term_dead": 0,
"term_grade": [{
"class": "正常",
"credit": 1,
"grade": 100,
"kill": "yes",
"title": "大学生就业指导"
}, {
"class": "正常",
"credit": 1,
"grade": 100,
"kill": "yes",
"title": "大学体育"
}, {
"class": "正常",
"credit": 3,
"grade": 100,
"kill": "yes",
"title": "大学外语"
}, {
"class": "正常",
"credit": 5,
"grade": 100,
"kill": "yes",
"title": "高等数学Ⅱ"
}, {
"class": "正常",
"credit": 1,
"grade": 100,
"kill": "yes",
"title": "军事理论"
}, {
"class": "正常",
"credit": 3,
"grade": 100,
"kill": "yes",
"title": "军训"
}, {
"class": "正常",
"credit": 3,
"grade": 100,
"kill": "yes",
"title": "思想道德修养与法律基础"
}, {
"class": "正常",
"credit": 2,
"grade": 100,
"kill": "yes",
"title": "计算机导论"
}, {
"class": "正常",
"credit": 3.5,
"grade": 100,
"kill": "yes",
"title": "面向对象程序设计"
}],
"term_kill": 9,
"term_time": "20171"
}],
"total": {
"total_GPA": 5.0,
"total_bixiu_GPA": 5.0,
"total_credit": 175.1,
"total_dead": 0,
"total_kill": 71
}
},
"schedule": {
"cur_week": 22,
"days_per_week": [0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 0, 0, 0],
"lesson": [
[0, [{
"Lesson": "嵌入式操作系统",
"Room": "研608[理论]",
"Teacher": "崔广才",
"Time": "1-4周",
"Time_split": [0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"color": 4
}, {
"Lesson": "嵌入式操作系统",
"Room": "研608[理论]",
"Teacher": "祝勇",
"Time": "5-16周",
"Time_split": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
"color": 4
}],
[{
"Lesson": "算法分析与设计",
"Room": "研201阶[理论]",
"Teacher": "何巍",
"Time": "1-16周",
"Time_split": [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
"color": 3
}], 0, [{
"Lesson": "Web程序设计",
"Room": "研1201阶[理论]",
"Teacher": "从立钢",
"Time": "1-16周",
"Time_split": [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
"color": 7
}], 0
],
[
[{
"Lesson": "嵌入式系统设计",
"Room": "研411[理论]",
"Teacher": "祝勇",
"Time": "1-16周",
"Time_split": [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
"color": 8
}],
[{
"Lesson": "数据挖掘技术",
"Room": "研213[理论]",
"Teacher": "田野",
"Time": "1-16周",
"Time_split": [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
"color": 0
}],
[{
"Lesson": "云计算与分布式系统",
"Room": "研401[理论]",
"Teacher": "李松江",
"Time": "1-16周",
"Time_split": [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
"color": 6
}],
[{
"Lesson": "专业方向应用实训科研训练",
"Room": "研501[实践]",
"Teacher": "祝勇",
"Time": "14-19周",
"Time_split": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
"color": 5
}],
[{
"Lesson": "嵌入式系统设计",
"Room": "南实训344[实验]",
"Teacher": "祝勇",
"Time": "9-16周",
"Time_split": [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
"color": 8
}], 0
],
[
[{
"Lesson": "海量信息处理与云计算",
"Room": "研602[理论]",
"Teacher": "王玲",
"Time": "1-16周",
"Time_split": [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
"color": 2
}],
[{
"Lesson": "算法分析与设计",
"Room": "研1213[实验]",
"Teacher": "何巍,刘葳",
"Time": "9-16周",
"Time_split": [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
"color": 3
}], 0, 0, [{
"Lesson": "形势与政策",
"Room": "研201阶[理论]",
"Teacher": "刘俊峰",
"Time": "4-7周",
"Time_split": [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"color": 1
}], 0
],
[0, [{
"Lesson": "数据挖掘技术",
"Room": "研1213[实验]",
"Teacher": "田野,梁子刚",
"Time": "9-16周",
"Time_split": [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
"color": 7
}],
[{
"Lesson": "Web程序设计",
"Room": "研1213[实验]",
"Teacher": "从立钢,梁子刚",
"Time": "9-16周",
"Time_split": [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
"color": 7
}], 0, [{
"Lesson": "嵌入式操作系统",
"Room": "南实训344[实验]",
"Teacher": "祝勇",
"Time": "9-16周",
"Time_split": [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
"color": 4
}], 0
],
[
[{
"Lesson": "第二外语(日语)",
"Room": "研213[理论]",
"Teacher": "任丽",
"Time": "1-16周",
"Time_split": [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
"color": 5
}],
[{
"Lesson": "云计算与分布式系统",
"Room": "南实训413[实验]",
"Teacher": "李松江,梁子刚",
"Time": "9-16周",
"Time_split": [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
"color": 6
}],
[{
"Lesson": "海量信息处理与云计算",
"Room": "南实训413[实验]",
"Teacher": "王玲,梁子刚",
"Time": "9-16周",
"Time_split": [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
"color": 2
}],
[{
"Lesson": "大学生就业指导",
"Room": "研701阶[理论]",
"Teacher": "孙吉",
"Time": "1-8周",
"Time_split": [0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
"color": 7
}], 0, 0
],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0]
]
},
"student_id": "200523366",
"student_name": "Cherry"
}

View File

@ -27,66 +27,6 @@ export function isIOS() {
}
}
// 初始化数据
export function getGradeInitData() {
return {
errcode: 103,
data: {
total: {
total_GPA: 5.0,
total_credit: "∞",
total_kill: "∞",
total_dead: "∞",
total_bixiu_GPA: 5.0,
},
split: [{
term_GPA: 5.0,
term_credit: "∞",
term_dead: "∞",
term_grade: [{
title: "如果你看到这些,先左上角试试获取数据",
credit: 0,
grade: 0,
class: 0
},
{
title: "如果还看到这些",
credit: 0,
grade: 0,
class: 0
},
{
title: "说明教务可能也没有数据",
credit: 0,
grade: 0,
class: 0
},
{
title: "如果教务有数据还看到这些",
credit: 0,
grade: 0,
class: 0
},
{
title: "加群告诉我好吗1030523678",
credit: 0,
grade: 0,
class: 0
},
{
title: "拜托了!!!!",
credit: 0,
grade: 0,
class: 0
}
],
term_kill: "∞",
term_time: "20451"
}]
}
}
}
export function getGameInitData() {
return [{
name: '高等数学',
@ -144,3 +84,5 @@ export function getGameInitData() {
color: 9
}]
}
export var interceptTime = 1590914481754

View File

@ -33,6 +33,10 @@ Vue.use(VueTouch, {name: 'v-touch'})
import VueClipboard from "vue-clipboard2";
Vue.use(VueClipboard);
// 自己写的snakebar组件
import SnakeBar from '@/components/SnakeBar/index'
Vue.use(SnakeBar)
Vue.component('icon', Icon);
new Vue({
router,

View File

@ -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,30 @@ const routes = [
keepAlive:false
},
},
{
path: '/myaccount',
name: 'MyAccount',
component: () => import(/* webpackChunkName: "account" */ '../views/MyAccount/MyAccount.vue'),
meta:{
keepAlive:false
},
},
{
path: '/addclass',
name: 'AddClass',
component: () => import(/* webpackChunkName: "addclass" */ '../views/AddClass/AddClass.vue'),
meta:{
keepAlive:false
},
},
{
path: '/personal',
name: 'Personal',
component: () => import(/* webpackChunkName: "personal" */ '../views/Personal/Personal.vue'),
meta:{
keepAlive:false
},
},
{
path: '*', // 页面不存在的情况下会跳到schedule
redirect: '/schedule',

View File

@ -6,21 +6,40 @@ Vue.use(Vuex)
export default new Vuex.Store({
state: {
// 用户信息
user_info: null,
user_info: {},
// 成绩
grade: null,
// 课表
schedule: null,
// LAF
LAF_data: null,
// 失物招领首页刷新
LAF_reflash: false,
// 当前页面
current_page: null,
// 游戏
schedule_game: null,
// 展开抽屉
drawer_state: false,
// 自定义课程
personal_class: {},
// 源课表信息
row_lesson_info: null,
// 用户设置
settings: {
// 隐藏周末
hide_weekend: false,
// 课表背景链接
user_bg_url: '',
// 是否开启了背景
user_bg_switch: false,
// 课程透明度
lesson_opacity: 1,
// 背景主题
user_bg_is_dark: false,
// 课程以及节数的显示方式 无 衬底 阴影 => 0 1 2
bar_show_style: 0,
// 黑暗模式
dark_mode: false,
// 隐藏tab文字
hide_tab_text: false,
}
},
mutations: {
// 设置用户信息
@ -38,14 +57,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) {
@ -54,50 +65,74 @@ export default new Vuex.Store({
// 设置抽屉状态
SET_DRAWER_STATE(state, drawer_state) {
state.drawer_state = drawer_state
}
},
// 设置自定义课程
SET_PERSONAL_CLASS(state, personal_class) {
state.personal_class = personal_class
},
// 设置源课表信息
SET_ROW_LESSON_INFO(state, row_lesson_info) {
state.row_lesson_info = row_lesson_info
},
// 设置源课表信息
SET_SETTINGS(state, settings) {
state.settings = settings
}
},
actions: {
// 设置用户信息
setUserInfo({ commit }, arg) {
commit('SET_USERINFO', arg[0]);
localStorage.setItem("storeState", JSON.stringify(arg[1].$store.state));
setItem.call(arg[1])
},
// 设置当前页面
setCurrentPage({ commit }, arg){
commit('SET_CURRENTPAGE', arg[0]);
localStorage.setItem("storeState", JSON.stringify(arg[1].$store.state));
setItem.call(arg[1])
},
// 设置成绩
setGrade({ commit }, arg){
commit('SET_GRADE',arg[0]);
localStorage.setItem("storeState", JSON.stringify(arg[1].$store.state));
setItem.call(arg[1])
},
// 设置课表
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));
setItem.call(arg[1])
},
// 设置游戏
setScheduleGame({ commit }, arg) {
commit('SET_SCHEDULE_GAME', arg[0]);
localStorage.setItem("storeState", JSON.stringify(arg[1].$store.state));
setItem.call(arg[1])
},
// 设置抽屉状态
setDrawerState({ commit }, arg) {
commit('SET_DRAWER_STATE', arg[0]);
localStorage.setItem("storeState", JSON.stringify(arg[1].$store.state));
setItem.call(arg[1])
},
// 设置自定义课表
setPersonalClass({ commit }, arg) {
commit('SET_PERSONAL_CLASS', arg[0]);
setItem.call(arg[1])
},
// 设置课表源数据
setRowLessonInfo({ commit }, arg) {
commit('SET_ROW_LESSON_INFO', arg[0]);
setItem.call(arg[1])
},
// 设置课表源数据
setSettings({ commit }, arg) {
commit('SET_SETTINGS', arg[0]);
setItem.call(arg[1])
},
},
modules: {
}
})
function setItem() {
let state = this.$store.state
for(let key of Object.keys(state)) {
localStorage.setItem("cherry_" + key , JSON.stringify(state[key]));
}
}

View File

@ -1 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1574137011982" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3828" data-spm-anchor-id="a313x.7781069.0.i45" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M792.4736 293.888H568.6272a108.032 108.032 0 0 1-69.9392-25.7024l-9.1136-7.7824a148.48 148.48 0 0 0-96.256-35.1232H266.24a108.032 108.032 0 0 0-108.3392 107.6224v258.2528a238.08 238.08 0 0 1 298.9056 229.888h335.6672a108.032 108.032 0 0 0 108.032-108.032V401.92A108.032 108.032 0 0 0 792.4736 293.888z m9.4208 392.192a162.5088 162.5088 0 0 1-39.8336 11.264 538.7264 538.7264 0 0 1-169.7792 0 162.6112 162.6112 0 0 1-39.936-11.264 34.816 34.816 0 0 1-23.4496-29.696A93.0816 93.0816 0 0 1 552.96 601.8048 128.1024 128.1024 0 0 1 612.1472 563.2a7.2704 7.2704 0 0 0 2.56-12.288 92.16 92.16 0 1 1 124.7232 0 7.2704 7.2704 0 0 0 2.4576 12.288 130.56 130.56 0 0 1 59.6992 38.6048 109.4656 109.4656 0 0 1 18.1248 29.5936 70.9632 70.9632 0 0 1 5.632 25.2928A34.816 34.816 0 0 1 801.8944 686.08z" fill="#40a9ff" p-id="3829" data-spm-anchor-id="a313x.7781069.0.i44" class=""></path><path d="M686.08 595.1488a7.5776 7.5776 0 0 1 0.9216-6.2464l3.072-4.7104a7.5776 7.5776 0 0 0 1.2288-4.5056v-0.6144a7.5776 7.5776 0 0 0-7.2704-7.168h-14.2336a7.5776 7.5776 0 0 0-7.2704 7.168v0.6144a7.5776 7.5776 0 0 0 1.2288 4.5056l3.1744 4.8128a7.5776 7.5776 0 0 1 1.024 6.0416l-14.7456 57.1392a7.5776 7.5776 0 0 0 2.9696 8.0896l17.6128 12.1856a7.5776 7.5776 0 0 0 8.6016 0l17.408-12.0832a7.5776 7.5776 0 0 0 2.9696-8.2944z" fill="#40a9ff" p-id="3830" data-spm-anchor-id="a313x.7781069.0.i46" class=""></path><path d="M218.8288 583.0656a238.1824 238.1824 0 0 0-61.44 7.9872v121.856a108.032 108.032 0 0 0 108.032 108.1344h191.3856a237.9776 237.9776 0 0 0-237.9776-237.9776z" fill="#1082FF" p-id="3831"></path><path d="M218.8288 583.0656a238.1824 238.1824 0 0 0-61.44 7.9872v121.856a108.032 108.032 0 0 0 108.032 108.1344h191.3856a237.9776 237.9776 0 0 0-237.9776-237.9776z" fill="#91d5ff" p-id="3832" data-spm-anchor-id="a313x.7781069.0.i47" class=""></path></svg>
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1574137011982" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3828" data-spm-anchor-id="a313x.7781069.0.i45" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M792.4736 293.888H568.6272a108.032 108.032 0 0 1-69.9392-25.7024l-9.1136-7.7824a148.48 148.48 0 0 0-96.256-35.1232H266.24a108.032 108.032 0 0 0-108.3392 107.6224v258.2528a238.08 238.08 0 0 1 298.9056 229.888h335.6672a108.032 108.032 0 0 0 108.032-108.032V401.92A108.032 108.032 0 0 0 792.4736 293.888z m9.4208 392.192a162.5088 162.5088 0 0 1-39.8336 11.264 538.7264 538.7264 0 0 1-169.7792 0 162.6112 162.6112 0 0 1-39.936-11.264 34.816 34.816 0 0 1-23.4496-29.696A93.0816 93.0816 0 0 1 552.96 601.8048 128.1024 128.1024 0 0 1 612.1472 563.2a7.2704 7.2704 0 0 0 2.56-12.288 92.16 92.16 0 1 1 124.7232 0 7.2704 7.2704 0 0 0 2.4576 12.288 130.56 130.56 0 0 1 59.6992 38.6048 109.4656 109.4656 0 0 1 18.1248 29.5936 70.9632 70.9632 0 0 1 5.632 25.2928A34.816 34.816 0 0 1 801.8944 686.08z" fill="#ff776d" p-id="3829" data-spm-anchor-id="a313x.7781069.0.i44" class=""></path><path d="M686.08 595.1488a7.5776 7.5776 0 0 1 0.9216-6.2464l3.072-4.7104a7.5776 7.5776 0 0 0 1.2288-4.5056v-0.6144a7.5776 7.5776 0 0 0-7.2704-7.168h-14.2336a7.5776 7.5776 0 0 0-7.2704 7.168v0.6144a7.5776 7.5776 0 0 0 1.2288 4.5056l3.1744 4.8128a7.5776 7.5776 0 0 1 1.024 6.0416l-14.7456 57.1392a7.5776 7.5776 0 0 0 2.9696 8.0896l17.6128 12.1856a7.5776 7.5776 0 0 0 8.6016 0l17.408-12.0832a7.5776 7.5776 0 0 0 2.9696-8.2944z" fill="#ff776d" p-id="3830" data-spm-anchor-id="a313x.7781069.0.i46" class=""></path><path d="M218.8288 583.0656a238.1824 238.1824 0 0 0-61.44 7.9872v121.856a108.032 108.032 0 0 0 108.032 108.1344h191.3856a237.9776 237.9776 0 0 0-237.9776-237.9776z" fill="#ff4c2b" p-id="3831"></path><path d="M218.8288 583.0656a238.1824 238.1824 0 0 0-61.44 7.9872v121.856a108.032 108.032 0 0 0 108.032 108.1344h191.3856a237.9776 237.9776 0 0 0-237.9776-237.9776z" fill="#ffb5b8" p-id="3832" data-spm-anchor-id="a313x.7781069.0.i47" class=""></path></svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1574136962224" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3272" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M530.1248 534.7328v241.152a48.8448 48.8448 0 0 0 48.64 48.64c26.624-9.216 79.0528-27.8528 129.6384-50.176 13.1072-5.8368 26.0096-13.0048 51.2-27.3408a117.4528 117.4528 0 0 0 40.96-31.4368 89.6 89.6 0 0 0 13.2096-24.8832v-430.08a48.8448 48.8448 0 0 0-48.64-48.64c-10.24 1.7408-24.9856 4.608-42.5984 9.4208a230.5024 230.5024 0 0 1-192.4096 313.344zM252.928 747.008c25.7024 14.336 38.6048 21.6064 51.2 27.3408 50.5856 22.3232 103.0144 40.96 129.6384 50.176a48.8448 48.8448 0 0 0 48.64-48.64V534.3232a230.6048 230.6048 0 0 1-189.44-312.2176 454.9632 454.9632 0 0 0-46.2848-10.24 48.8448 48.8448 0 0 0-48.64 48.64v430.08a89.6 89.6 0 0 0 13.2096 24.8832 117.4528 117.4528 0 0 0 41.6768 31.5392z" fill="#40a9ff" p-id="3273" data-spm-anchor-id="a313x.7781069.0.i34" class=""></path><path d="M839.68 269.2096a47.9232 47.9232 0 0 1 0.9216 8.6016v430.08a89.7024 89.7024 0 0 1-13.2096 24.8832 117.3504 117.3504 0 0 1-40.96 31.4368c-24.7808 13.824-37.5808 20.992-50.2784 26.7264 13.5168 0 53.6576 0.8192 92.9792-1.8432a61.44 61.44 0 0 0 35.5328-12.1856A58.2656 58.2656 0 0 0 883.4048 747.52V317.44A48.64 48.64 0 0 0 839.68 269.2096zM152.3712 777.1136a61.44 61.44 0 0 0 35.5328 12.1856c39.3216 2.6624 79.4624 2.1504 92.9792 1.8432-12.6976-5.7344-25.4976-12.9024-50.2784-26.7264a117.3504 117.3504 0 0 1-40.96-31.4368 89.6 89.6 0 0 1-13.2096-24.8832v-430.08a47.9232 47.9232 0 0 1 0.9216-8.6016A48.64 48.64 0 0 0 133.632 317.44v430.08a58.2656 58.2656 0 0 0 18.7392 29.5936z" fill="#40a9ff" p-id="3274" data-spm-anchor-id="a313x.7781069.0.i35" class=""></path><path d="M544.3584 347.648a204.8 204.8 0 0 0-14.336 34.4064v152.6784a230.5024 230.5024 0 0 0 193.2288-313.6512c-55.6032 15.0528-138.0352 49.152-178.8928 126.5664z" fill="#FFBA00" p-id="3275"></path><path d="M544.3584 347.648a204.8 204.8 0 0 0-14.336 34.4064v152.6784a230.5024 230.5024 0 0 0 193.2288-313.6512c-55.6032 15.0528-138.0352 49.152-178.8928 126.5664z" fill="#91d5ff" p-id="3276" data-spm-anchor-id="a313x.7781069.0.i37" class="selected"></path><path d="M482.9184 534.3232V382.0544a204.8 204.8 0 0 0-14.336-34.4064c-39.936-75.6736-119.7056-109.9776-175.2064-125.5424a230.6048 230.6048 0 0 0 189.44 312.2176z" fill="#FFBA00" p-id="3277"></path><path d="M482.9184 534.3232V382.0544a204.8 204.8 0 0 0-14.336-34.4064c-39.936-75.6736-119.7056-109.9776-175.2064-125.5424a230.6048 230.6048 0 0 0 189.44 312.2176z" fill="#91d5ff" p-id="3278" data-spm-anchor-id="a313x.7781069.0.i36" class="selected"></path></svg>
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1574136962224" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3272" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M530.1248 534.7328v241.152a48.8448 48.8448 0 0 0 48.64 48.64c26.624-9.216 79.0528-27.8528 129.6384-50.176 13.1072-5.8368 26.0096-13.0048 51.2-27.3408a117.4528 117.4528 0 0 0 40.96-31.4368 89.6 89.6 0 0 0 13.2096-24.8832v-430.08a48.8448 48.8448 0 0 0-48.64-48.64c-10.24 1.7408-24.9856 4.608-42.5984 9.4208a230.5024 230.5024 0 0 1-192.4096 313.344zM252.928 747.008c25.7024 14.336 38.6048 21.6064 51.2 27.3408 50.5856 22.3232 103.0144 40.96 129.6384 50.176a48.8448 48.8448 0 0 0 48.64-48.64V534.3232a230.6048 230.6048 0 0 1-189.44-312.2176 454.9632 454.9632 0 0 0-46.2848-10.24 48.8448 48.8448 0 0 0-48.64 48.64v430.08a89.6 89.6 0 0 0 13.2096 24.8832 117.4528 117.4528 0 0 0 41.6768 31.5392z" fill="#ff776d" p-id="3273" data-spm-anchor-id="a313x.7781069.0.i34" class=""></path><path d="M839.68 269.2096a47.9232 47.9232 0 0 1 0.9216 8.6016v430.08a89.7024 89.7024 0 0 1-13.2096 24.8832 117.3504 117.3504 0 0 1-40.96 31.4368c-24.7808 13.824-37.5808 20.992-50.2784 26.7264 13.5168 0 53.6576 0.8192 92.9792-1.8432a61.44 61.44 0 0 0 35.5328-12.1856A58.2656 58.2656 0 0 0 883.4048 747.52V317.44A48.64 48.64 0 0 0 839.68 269.2096zM152.3712 777.1136a61.44 61.44 0 0 0 35.5328 12.1856c39.3216 2.6624 79.4624 2.1504 92.9792 1.8432-12.6976-5.7344-25.4976-12.9024-50.2784-26.7264a117.3504 117.3504 0 0 1-40.96-31.4368 89.6 89.6 0 0 1-13.2096-24.8832v-430.08a47.9232 47.9232 0 0 1 0.9216-8.6016A48.64 48.64 0 0 0 133.632 317.44v430.08a58.2656 58.2656 0 0 0 18.7392 29.5936z" fill="#ff776d" p-id="3274" data-spm-anchor-id="a313x.7781069.0.i35" class=""></path><path d="M544.3584 347.648a204.8 204.8 0 0 0-14.336 34.4064v152.6784a230.5024 230.5024 0 0 0 193.2288-313.6512c-55.6032 15.0528-138.0352 49.152-178.8928 126.5664z" fill="#FFBA00" p-id="3275"></path><path d="M544.3584 347.648a204.8 204.8 0 0 0-14.336 34.4064v152.6784a230.5024 230.5024 0 0 0 193.2288-313.6512c-55.6032 15.0528-138.0352 49.152-178.8928 126.5664z" fill="#ffb5b8" p-id="3276" data-spm-anchor-id="a313x.7781069.0.i37" class="selected"></path><path d="M482.9184 534.3232V382.0544a204.8 204.8 0 0 0-14.336-34.4064c-39.936-75.6736-119.7056-109.9776-175.2064-125.5424a230.6048 230.6048 0 0 0 189.44 312.2176z" fill="#FFBA00" p-id="3277"></path><path d="M482.9184 534.3232V382.0544a204.8 204.8 0 0 0-14.336-34.4064c-39.936-75.6736-119.7056-109.9776-175.2064-125.5424a230.6048 230.6048 0 0 0 189.44 312.2176z" fill="#ffb5b8" p-id="3278" data-spm-anchor-id="a313x.7781069.0.i36" class="selected"></path></svg>

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

1
src/svg/empty.svg Normal file
View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1590879429400" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9080" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M576 928c-6 0-11.9-1.7-17.1-5-9.3-5.9-14.9-16.1-14.9-27V554.3c0-12.4 7.1-23.6 18.3-28.9l288-136.1c9.9-4.7 21.5-4 30.8 1.9s14.9 16.1 14.9 27v341.7c0 12.4-7.1 23.6-18.3 28.9l-288 136.1c-4.4 2.1-9 3.1-13.7 3.1z m32-353.5v271l224-105.8v-271L608 574.5zM448 928c-4.7 0-9.3-1-13.7-3.1l-288-136.1c-11.2-5.3-18.3-16.6-18.3-28.9V418.2c0-11 5.6-21.2 14.9-27 9.3-5.9 20.9-6.6 30.8-1.9l288 136.1c11.2 5.3 18.3 16.6 18.3 28.9V896c0 11-5.6 21.2-14.9 27-5.2 3.3-11.1 5-17.1 5zM192 739.7l224 105.8v-271L192 468.7v271zM512 501.1c-4.7 0-9.4-1-13.8-3.1l-352-168.1c-11.2-5.4-18.3-16.7-18.2-29.2 0.1-12.4 7.4-23.7 18.8-28.8l352-159.9c8.4-3.8 18.1-3.8 26.5 0l352 159.9c11.3 5.1 18.6 16.4 18.8 28.8 0.1 12.4-7 23.8-18.2 29.2L525.8 498c-4.4 2-9.1 3.1-13.8 3.1zM235.8 301.7L512 433.6l276.2-131.9L512 176.2 235.8 301.7z" p-id="9081" fill="#ff776d"></path></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1574136861318" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2251" data-spm-anchor-id="a313x.7781069.0.i18" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M850.7392 541.4912H741.376a18.5344 18.5344 0 0 1-18.5344-18.5344V419.84a55.7056 55.7056 0 0 0-20.48-43.3152l-74.9568-60.416A176.0256 176.0256 0 0 1 357.376 512v11.3664a18.5344 18.5344 0 0 1-18.5344 18.5344H229.4784a55.7056 55.7056 0 0 0-55.3984 55.296v223.8464a55.7056 55.7056 0 0 0 55.7056 55.7056h200.9088A37.0688 37.0688 0 0 0 467.8656 839.68v-58.6752a70.144 70.144 0 0 1 70.144-70.144 74.24 74.24 0 0 1 74.24 74.24V839.68a37.0688 37.0688 0 0 0 37.0688 37.0688h201.4208a55.7056 55.7056 0 0 0 55.7056-55.7056V597.1968a55.7056 55.7056 0 0 0-55.7056-55.7056zM545.5872 204.0832a9.216 9.216 0 0 1-5.5296-8.3968v-53.5552a9.216 9.216 0 0 1 3.4816-7.168 5.4272 5.4272 0 0 0-3.4816-1.3312 5.5296 5.5296 0 0 0-5.5296 5.4272v69.7344c3.6864 1.7408 7.3728 3.6864 10.9568 5.7344z" fill="#40a9ff" p-id="2252" data-spm-anchor-id="a313x.7781069.0.i15" class=""></path><path d="M545.5872 139.0592v65.024c14.2336 5.7344 51.2 18.944 65.3312 7.3728 12.0832-9.6256 39.424-6.4512 56.5248-3.2768a9.216 9.216 0 0 0 10.24-10.24 280.3712 280.3712 0 0 1 3.072-61.44 9.216 9.216 0 0 0-5.2224-9.728c-20.48-9.5232-61.952-4.9152-77.312 3.8912-11.5712 6.656-34.6112 4.3008-48.128 2.048a9.1136 9.1136 0 0 0-7.2704 1.9456 5.4272 5.4272 0 0 1 2.7648 4.4032z" fill="#40a9ff" p-id="2253" data-spm-anchor-id="a313x.7781069.0.i16" class=""></path><path d="M540.0576 142.1312v53.5552a9.216 9.216 0 0 0 5.5296 8.3968v-65.024a5.4272 5.4272 0 0 0-2.048-4.1984 9.216 9.216 0 0 0-3.4816 7.2704z" fill="#1082FF" p-id="2254"></path><path d="M540.0576 142.1312v53.5552a9.216 9.216 0 0 0 5.5296 8.3968v-65.024a5.4272 5.4272 0 0 0-2.048-4.1984 9.216 9.216 0 0 0-3.4816 7.2704z" fill="#1082FF" p-id="2255"></path><path d="M540.0576 430.4896m-50.9952 0a50.9952 50.9952 0 1 0 101.9904 0 50.9952 50.9952 0 1 0-101.9904 0Z" fill="#FFFFFF" p-id="2256"></path><path d="M627.0976 316.2112a176.4352 176.4352 0 0 0-81.92-101.6832v35.9424z" fill="#FFFFFF" p-id="2257"></path><path d="M634.88 367.616a175.9232 175.9232 0 0 0-7.68-51.2l-81.92-65.7408V215.04c-3.584-2.048-7.2704-3.9936-10.9568-5.7344v40.1408L377.856 376.6272a55.7056 55.7056 0 0 0-20.48 43.1104v92.16A176.0256 176.0256 0 0 0 634.88 367.616z m-94.6176 11.8784a51.2 51.2 0 1 1-51.2 51.2 51.2 51.2 0 0 1 50.9952-51.2z" fill="#1082FF" p-id="2258"></path><path d="M634.88 367.616a175.9232 175.9232 0 0 0-7.68-51.2l-81.92-65.7408V215.04c-3.584-2.048-7.2704-3.9936-10.9568-5.7344v40.1408L377.856 376.6272a55.7056 55.7056 0 0 0-20.48 43.1104v92.16A176.0256 176.0256 0 0 0 634.88 367.616z m-94.6176 11.8784a51.2 51.2 0 1 1-51.2 51.2 51.2 51.2 0 0 1 50.9952-51.2z" fill="#91d5ff" p-id="2259" data-spm-anchor-id="a313x.7781069.0.i17" class=""></path></svg>
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1574136861318" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2251" data-spm-anchor-id="a313x.7781069.0.i18" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M850.7392 541.4912H741.376a18.5344 18.5344 0 0 1-18.5344-18.5344V419.84a55.7056 55.7056 0 0 0-20.48-43.3152l-74.9568-60.416A176.0256 176.0256 0 0 1 357.376 512v11.3664a18.5344 18.5344 0 0 1-18.5344 18.5344H229.4784a55.7056 55.7056 0 0 0-55.3984 55.296v223.8464a55.7056 55.7056 0 0 0 55.7056 55.7056h200.9088A37.0688 37.0688 0 0 0 467.8656 839.68v-58.6752a70.144 70.144 0 0 1 70.144-70.144 74.24 74.24 0 0 1 74.24 74.24V839.68a37.0688 37.0688 0 0 0 37.0688 37.0688h201.4208a55.7056 55.7056 0 0 0 55.7056-55.7056V597.1968a55.7056 55.7056 0 0 0-55.7056-55.7056zM545.5872 204.0832a9.216 9.216 0 0 1-5.5296-8.3968v-53.5552a9.216 9.216 0 0 1 3.4816-7.168 5.4272 5.4272 0 0 0-3.4816-1.3312 5.5296 5.5296 0 0 0-5.5296 5.4272v69.7344c3.6864 1.7408 7.3728 3.6864 10.9568 5.7344z" fill="#ff776d" p-id="2252" data-spm-anchor-id="a313x.7781069.0.i15" class=""></path><path d="M545.5872 139.0592v65.024c14.2336 5.7344 51.2 18.944 65.3312 7.3728 12.0832-9.6256 39.424-6.4512 56.5248-3.2768a9.216 9.216 0 0 0 10.24-10.24 280.3712 280.3712 0 0 1 3.072-61.44 9.216 9.216 0 0 0-5.2224-9.728c-20.48-9.5232-61.952-4.9152-77.312 3.8912-11.5712 6.656-34.6112 4.3008-48.128 2.048a9.1136 9.1136 0 0 0-7.2704 1.9456 5.4272 5.4272 0 0 1 2.7648 4.4032z" fill="#ff776d" p-id="2253" data-spm-anchor-id="a313x.7781069.0.i16" class=""></path><path d="M540.0576 142.1312v53.5552a9.216 9.216 0 0 0 5.5296 8.3968v-65.024a5.4272 5.4272 0 0 0-2.048-4.1984 9.216 9.216 0 0 0-3.4816 7.2704z" fill="#ff4c2b" p-id="2254"></path><path d="M540.0576 142.1312v53.5552a9.216 9.216 0 0 0 5.5296 8.3968v-65.024a5.4272 5.4272 0 0 0-2.048-4.1984 9.216 9.216 0 0 0-3.4816 7.2704z" fill="#ff4c2b" p-id="2255"></path><path d="M540.0576 430.4896m-50.9952 0a50.9952 50.9952 0 1 0 101.9904 0 50.9952 50.9952 0 1 0-101.9904 0Z" fill="#FFFFFF" p-id="2256"></path><path d="M627.0976 316.2112a176.4352 176.4352 0 0 0-81.92-101.6832v35.9424z" fill="#FFFFFF" p-id="2257"></path><path d="M634.88 367.616a175.9232 175.9232 0 0 0-7.68-51.2l-81.92-65.7408V215.04c-3.584-2.048-7.2704-3.9936-10.9568-5.7344v40.1408L377.856 376.6272a55.7056 55.7056 0 0 0-20.48 43.1104v92.16A176.0256 176.0256 0 0 0 634.88 367.616z m-94.6176 11.8784a51.2 51.2 0 1 1-51.2 51.2 51.2 51.2 0 0 1 50.9952-51.2z" fill="#ff4c2b" p-id="2258"></path><path d="M634.88 367.616a175.9232 175.9232 0 0 0-7.68-51.2l-81.92-65.7408V215.04c-3.584-2.048-7.2704-3.9936-10.9568-5.7344v40.1408L377.856 376.6272a55.7056 55.7056 0 0 0-20.48 43.1104v92.16A176.0256 176.0256 0 0 0 634.88 367.616z m-94.6176 11.8784a51.2 51.2 0 1 1-51.2 51.2 51.2 51.2 0 0 1 50.9952-51.2z" fill="#ffb5b8" p-id="2259" data-spm-anchor-id="a313x.7781069.0.i17" class=""></path></svg>

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1,789 @@
<template>
<div class="schedule">
<header>
<div class="w">
<i class="el-icon-arrow-left back" @click="back"></i>
<p>自定义课程</p>
<i class="el-icon-plus plus" @click="openAddDialog"></i>
</div>
</header>
<div style="height: 1.2rem;"></div>
<div class="lesson" v-for="(lesson, index) in personal_class" :key="index">
<div class="left">
<p>课程名{{lesson.Lesson}}</p>
<p>上课地点{{lesson.Room}}</p>
<p>任课教师{{lesson.Teacher}}</p>
<p>上课周数{{lesson.Time}}</p>
<p>星期{{week_day_list[lesson.day_position]}}</p>
<p>时间{{lesson_list[lesson.lesson_position]}}</p>
</div>
<i class="el-icon-delete delete" @click="openConfirmDialog(lesson.id)"></i>
</div>
<div class="empty-box" v-if="Object.keys(personal_class).length == 0">
<icon name="empty" class="empty"></icon>
<p>空空如也呢~</p>
</div>
<div
class="dialog"
@click="closeConfirmDialog"
v-if="confirm_dialog_switch"
:class="confirm_dialog_opacity_class"
>
<div class="mask" @touchmove.prevent></div>
<div class="bottom-fixed" @click.stop>
<div class="confirm-dialog" :class="confirm_dialog_height_class">
<div class="dialog-header">删除课程</div>
<div class="dialog-detail">删除后将无法恢复是否确认删除</div>
<div class="dialog-active">
<div class="dialog-cancel" @click="closeConfirmDialog">取消</div>
<div class="dialog-confirm" @click="manageDelete">删除</div>
</div>
</div>
</div>
</div>
<div
class="dialog"
@click="closeAddDialog"
v-if="add_dialog_switch"
:class="add_dialog_opacity_class"
>
<div class="mask" @touchmove.prevent></div>
<div class="bottom-fixed" @click.stop>
<div class="add-dialog" :class="add_dialog_height_class">
<div class="dialog-header">课程详情</div>
<div class="input-box">
<icon name="collage" class="input-icon">课程名</icon>
<input type="text" placeholder="课程名*" v-model="name" />
</div>
<div class="input-box">
<icon name="school" class="input-icon">上课地点</icon>
<input type="text" placeholder="上课地点*" v-model="addr" />
</div>
<div class="input-box">
<icon name="cid" class="input-icon">任课教师</icon>
<input type="text" placeholder="任课教师*" v-model="tea" />
</div>
<div class="tip">小贴士课程名十个字以内为宜上课地点七个字以内为宜由于提交后不能修改只能删除请谨慎填写</div>
<div class="sub-title">日期选择</div>
<div class="list-box">
<div
class="list-item"
:class="select_day == index ? 'select' : ''"
v-for="(day, index) in week_day_list"
:key="index"
@click="dateSelect(index)"
>{{day}}</div>
</div>
<div class="sub-title">时间选择</div>
<div class="list-box">
<div
class="list-item"
:class="select_time == index ? 'select' : ''"
v-for="(lesson, index) in lesson_list"
:key="index"
@click="timeSelect(index)"
>{{lesson}}</div>
</div>
<div class="sub-title">星期选择<span @click="clearWeek">全不选</span><span @click="allWeek">全选</span><span @click="oddWeek">单周</span><span @click="evenWeek">双周</span></div>
<div class="list-box week-box">
<div
class="list-item"
:class="select_week[index+1] ? 'select' : ''"
v-for="(week, index) in 22"
:key="index"
@click="weekSelect(index)"
>{{week}}</div>
</div>
<div class="submit" :class="can_submit? 'select' : ''" @click="submit">确认提交</div>
</div>
</div>
</div>
<FooterSpace></FooterSpace>
</div>
</template>
<script>
// @ is an alias to /src
import FooterSpace from "@/components/FooterSpace.vue";
import { mapState, mapActions } from "vuex";
import { interceptTime } from "@/lib/utils.js";
import { manageSchedule } from "@/lib/schedule.js";
import { Loading } from "element-ui";
import { replaceState } from "@/lib/getStore.js";
export default {
name: "schedule",
data() {
return {
//
week_day_list: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
//
lesson_list: ["1-2节", "3-4节", "5-6节", "7-8节", "9-10节", "11-12节"],
//
select_day: null,
//
select_time: null,
//
select_week: null,
//
name: "",
//
tea: "",
//
addr: "",
//
can_submit: false,
// dialog
add_dialog_height_class: "",
// dialog
add_dialog_switch: false,
// dialog
add_dialog_opacity_class: "",
// dialog
confirm_dialog_height_class: "",
// dialog
confirm_dialog_switch: false,
// dialog
confirm_dialog_opacity_class: "",
// id
delete_id_cache: null
};
},
computed: {
...mapState([
"user_info",
"current_page",
"schedule",
"grade",
"personal_class",
"row_lesson_info"
])
},
methods: {
...mapActions([
"setUserInfo",
"setGrade",
"setSchedule",
"setCurrentPage",
"setDrawerState",
"setPersonalClass",
"setRowLessonInfo"
]),
//
init() {
// vuex
replaceState.call(this);
// footerNav
this.setCurrentPage(["None", this]);
console.log(this.$store.state);
//
if (Object.keys(this.user_info).length != 0) {
let now = new Date().getTime(); //
if (
now - this.user_info.login_time < 1000 * 60 * 60 * 24 * 7 &&
this.user_info.login_time > interceptTime
) {
// 7
//
let user_info = this.user_info;
user_info.login_time = new Date().getTime();
this.setUserInfo([user_info, this]);
console.log("用户登录时间刷新完成");
this.initData();
return;
}
}
localStorage.clear();
replaceState.call(this);
console.log("未登录拦截");
this.$router.replace("/login");
},
//
initData() {
this.select_day = null;
this.select_time = null;
this.select_week = new Array(23).fill(0);
this.name = "";
this.tea = "";
this.addr = "";
},
//
open(url) {
window.open(url);
},
//
dateSelect(index) {
this.select_day = index;
this.judge();
},
//
timeSelect(index) {
this.select_time = index;
this.judge();
},
//
weekSelect(index) {
this.select_week[index + 1] = this.select_week[index + 1] == 1 ? 0 : 1;
this.$forceUpdate();
this.judge();
},
//
judge() {
let flag = true;
if (!(this.name = this.name.trim())) {
flag = false;
}
if (!(this.tea = this.tea.trim())) {
flag = false;
}
if (!(this.addr = this.addr.trim())) {
flag = false;
}
if (!this.select_day && this.select_day !== 0) {
flag = false;
}
if (!this.select_time && this.select_time !== 0) {
flag = false;
}
if (this.select_week.indexOf(1) == -1) {
flag = false;
}
this.can_submit = flag;
},
openAddDialog() {
this.add_dialog_switch = true;
this.add_dialog_height_class = "higher-add-dialog";
this.add_dialog_opacity_class = "show-dialog";
this.initData();
},
closeAddDialog() {
this.add_dialog_height_class = "lower-add-dialog";
this.add_dialog_opacity_class = "hide-dialog";
setTimeout(() => {
this.add_dialog_switch = false;
this.initData();
}, 350);
},
openConfirmDialog(id) {
this.confirm_dialog_switch = true;
this.confirm_dialog_height_class = "higher-confirm-dialog";
this.confirm_dialog_opacity_class = "show-dialog";
this.delete_id_cache = id;
this.initData();
},
closeConfirmDialog() {
this.confirm_dialog_height_class = "lower-confirm-dialog";
this.confirm_dialog_opacity_class = "hide-dialog";
this.delete_id_cache = null;
setTimeout(() => {
this.confirm_dialog_switch = false;
this.initData();
}, 200);
},
//
manageDelete() {
let personal_class = this.personal_class
delete personal_class[this.delete_id_cache]
this.setPersonalClass([personal_class, this]);
console.log("自定义课程覆写完成");
//
this.refreshSchedule();
this.closeConfirmDialog();
this.$message.success("删除成功");
this.$forceUpdate();
},
//
submit() {
if(!this.can_submit) return
//
let cache = [];
for (let i in this.select_week) {
if (this.select_week[i]) {
cache.push(i);
}
}
let random =
new Date()
.getTime()
.toString()
.substring(7) + Math.floor(Math.random() * 10).toString();
let data = {
//
Lesson: this.name,
//
Room: this.addr,
//
Teacher: this.tea,
// 123
Time: cache.join(","),
//
color: 9,
//
id: random,
//
Time_split: this.select_week,
//
day_position: this.select_day,
//
lesson_position: this.select_time
};
//
let personal_class = this.personal_class;
if (!personal_class) personal_class = {};
personal_class[random] = data;
this.setPersonalClass([personal_class, this]);
console.log("自定义课程覆写完成");
//
this.refreshSchedule();
this.closeAddDialog();
this.$message.success("添加成功");
this.$forceUpdate();
},
//
refreshSchedule() {
//
let row_lesson_info = JSON.parse(JSON.stringify(this.row_lesson_info));
if (!row_lesson_info) {
//
row_lesson_info = [];
for (let i = 0; i < 7; i++) {
row_lesson_info.push([0, 0, 0, 0, 0, 0]);
}
}
//
for (let key in this.personal_class) {
let lesson = this.personal_class[key];
if (row_lesson_info[lesson.day_position][lesson.lesson_position] != 0) {
row_lesson_info[lesson.day_position][lesson.lesson_position].push(
lesson
);
} else {
row_lesson_info[lesson.day_position][lesson.lesson_position] = [
lesson
];
}
}
//
let schedule = this.schedule;
if (!schedule) {
//
schedule = {
cur_week: 0,
days_per_week: new Array(23).fill(0),
schedule_game: null
};
}
schedule.lesson = manageSchedule(row_lesson_info);
this.setSchedule([schedule, this]);
console.log("显示用课表覆写完成");
},
back() {
this.$router.go(-1);
},
//
oddWeek() {
this.select_week = new Array(23).fill(0)
this.select_week.forEach((item, index, arr)=> {
arr[index] = index % 2
})
this.judge();
},
//
evenWeek() {
this.select_week = new Array(23).fill(0)
this.select_week.forEach((item, index, arr)=> {
arr[index] = index % 2 == 0 ? 1 : 0
})
this.judge();
},
//
clearWeek() {
this.select_week = new Array(23).fill(0)
this.judge();
},
//
allWeek() {
this.select_week = new Array(23).fill(1)
this.judge();
}
},
created() {
this.init();
},
mounted() {},
activated() {},
watch: {
name: function() {
// console.log(this.name);
this.judge();
},
addr: function() {
// console.log(this.addr);
this.judge();
},
tea: function() {
// console.log(this.tea);
this.judge();
}
},
components: {
FooterSpace
}
};
</script>
<style scoped lang="scss" type="text/scss">
@import "../../style/main";
.schedule {
width: 100%;
max-width: 500px;
margin: 0 auto;
background-color: #fbfbfb;
min-height: 100%;
position: relative;
overflow: hidden;
header {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 1.2rem;
z-index: 100;
.w {
height: 1.2rem;
width: 100%;
max-width: 500px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;
// background-image: linear-gradient(to right, #f0da4b, #ff005e);
background-image: $gradualLoginSubmit;
// background: #ffca9f;
color: #fff;
position: relative;
p {
font-size: 0.5rem;
}
.back {
font-size: 0.6rem;
position: absolute;
left: 0.3rem;
}
.plus {
font-size: 0.6rem;
position: absolute;
right: 0.3rem;
}
}
}
}
.lesson {
margin: 0.3rem 0.4rem;
font-size: 0.3rem;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.4rem;
box-sizing: border-box;
background: #fff;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
line-height: 0.6rem;
.delete {
font-size: 0.5rem;
color: $red;
}
}
.empty-box {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-top: 3rem;
.empty {
height: 2rem;
width: 2rem;
}
p {
font-size: .5rem;
margin-top: .3rem;
color: #ff382a;
letter-spacing:3px;
}
}
.add-dialog {
width: 100%;
max-width: 500px;
margin: 0 auto;
height: 14rem;
background: #fff;
border-top-right-radius: 0.4rem;
border-top-left-radius: 0.4rem;
overflow-y: scroll;
padding: 0.4rem;
box-sizing: border-box;
.dialog-header {
text-align: center;
font-size: 0.5rem;
margin-bottom: 0.5rem;
}
.input-box {
display: flex;
align-items: center;
justify-content: flex-start;
margin-bottom: 0.5rem;
input {
padding: 0 0.1rem;
height: 0.7rem;
border: none;
border-bottom: 1px solid #f2f2f2;
color: #202124;
font-size: 0.4rem;
line-height: 0.7rem;
margin-left: 0.3rem;
width: 100%;
}
input:focus {
outline: none;
}
.input-icon {
height: 0.7rem;
width: 0.7rem;
}
}
.tip {
font-size: 0.3rem;
color: #999;
}
.sub-title {
// color: #ff776d;
color: #ff382a;
font-size: 0.35rem;
margin-top: 0.3rem;
span {
float: right;
margin-left: .3rem;
}
}
.list-box {
width: 100%;
margin-top: 0.3rem;
display: flex;
align-items: center;
justify-content: space-between;
.list-item {
font-size: 0.3rem;
height: 0.6rem;
line-height: 0.6rem;
border-radius: 0.2rem;
// background: #ff776d;
// background: #ffb5b8;
// color: #ff776d;
background: #f5f5f5;
color: #bfbfbf;
padding: 0 0.3rem;
}
.select {
// background: #ff776d;
background: #ffe1e2;
color: #ff382a;
}
}
.week-box {
flex-wrap: wrap;
justify-content: flex-start;
.list-item {
margin-right: 0.24rem;
margin-bottom: 0.2rem;
width: 1rem;
text-align: center;
}
}
.submit {
height: 1rem;
line-height: 1rem;
width: 100%;
background: #f5f5f5;
color: #bfbfbf;
margin: 0.2rem auto;
font-size: 0.5rem;
text-align: center;
border-radius: 0.3rem;
}
.select {
background: #ffe1e2;
color: #ff382a;
}
}
.confirm-dialog {
width: 100%;
max-width: 500px;
margin: 0 auto;
height: 5rem;
background: #fff;
border-top-right-radius: 0.4rem;
border-top-left-radius: 0.4rem;
overflow-y: scroll;
padding: 0.4rem;
box-sizing: border-box;
.dialog-header {
text-align: center;
font-size: 0.5rem;
margin-bottom: 0.5rem;
}
.dialog-detail {
text-align: center;
font-size: 0.4rem;
color: #999;
}
.dialog-active {
display: flex;
align-items: center;
justify-content: space-between;
width: 75%;
margin: 0 auto;
margin-top: 1rem;
div {
height: 1rem;
width: 3rem;
font-size: 0.4rem;
text-align: center;
line-height: 1rem;
border-radius: 0.3rem;
}
.dialog-cancel {
background: #f5f5f5;
color: #bfbfbf;
}
.dialog-confirm {
background: #ffe1e2;
color: #ff382a;
}
}
}
.dialog {
position: fixed;
top: 0;
left: 0;
z-index: 101;
height: 100%;
width: 100%;
.mask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.4);
z-index: 102;
}
.bottom-fixed {
position: absolute;
bottom: 0;
width: 100%;
z-index: 103;
}
}
.higher-add-dialog {
animation: addToHigh 0.5s ease;
animation-fill-mode: forwards;
}
.lower-add-dialog {
animation: addToLow 0.5s ease;
animation-fill-mode: forwards;
}
.higher-confirm-dialog {
animation: confirmToHigh 0.35s ease;
animation-fill-mode: forwards;
}
.lower-confirm-dialog {
animation: confirmToLow 0.35s ease;
animation-fill-mode: forwards;
}
.hide-dialog {
animation: toHide 0.5s ease;
animation-fill-mode: forwards;
}
.show-dialog {
animation: toShow 0.5s ease;
animation-fill-mode: forwards;
}
@keyframes addToHigh {
0% {
height: 0rem;
}
100% {
height: 14rem;
}
}
@keyframes addToLow {
0% {
height: 14rem;
}
100% {
height: 0rem;
}
}
@keyframes confirmToHigh {
0% {
height: 0rem;
}
100% {
height: 5rem;
}
}
@keyframes confirmToLow {
0% {
height: 5rem;
}
100% {
height: 0rem;
}
}
@keyframes toHide {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes toShow {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
</style>

View File

@ -50,9 +50,8 @@
您的总点击数
<span>{{click_count}}</span>
</p>
<input type="text" placeholder="上传的话请在此输入昵称" v-model="nick" />
<div class="btn-box">
<p @click="closeUploadDialog()"></p>
<p @click="closeUploadDialog()">取消</p>
<p @click="uploadGrade()">上传</p>
</div>
</div>
@ -149,8 +148,9 @@
import FooterSpace from "@/components/FooterSpace.vue";
import { mapState, mapActions } from "vuex";
import { rankGet, rankUpload } from "@/axios/api.js";
import { getGameInitData } from "@/lib/utils.js";
import { getGameInitData, interceptTime } from "@/lib/utils.js";
import { Loading } from "element-ui";
import { replaceState } from '@/lib/getStore.js'
export default {
name: "schedule",
@ -216,7 +216,7 @@ export default {
...mapState(["user_info", "current_page", "schedule", "schedule_game"])
},
methods: {
...mapActions(["setCurrentPage", "setScheduleGame"]),
...mapActions(["setUserInfo", "setCurrentPage", "setScheduleGame"]),
//
lessonStyle(item) {
return `background:#${this.bg_color[item.color]};color:#${
@ -224,18 +224,34 @@ export default {
}`;
},
//
initGame() {
init() {
// vuex
this.$store.replaceState(
Object.assign(
this.$store.state,
JSON.parse(localStorage.getItem("storeState"))
)
);
replaceState.call(this)
// footerNav
this.setCurrentPage(["None", this]);
this.getGrade();
//
if (Object.keys(this.user_info).length != 0) {
let now = new Date().getTime(); //
if (
now - this.user_info.login_time < 1000 * 60 * 60 * 24 * 7 &&
this.user_info.login_time > interceptTime
) {
// 7
//
// activated使keepalive
this.initGame()
return;
}
}
localStorage.clear();
replaceState.call(this);
console.log("未登录拦截");
this.$router.replace("/login");
},
//
initGame() {
//
this.nick = "";
this.click_count = 0;
@ -374,7 +390,7 @@ export default {
target: document.querySelector(".dialog-w")
});
let data = {
nick: this.nick,
nick: this.user_info.name,
count: this.click_count,
time: this.time_finish
};
@ -441,7 +457,7 @@ export default {
},
created() {},
mounted() {
this.initGame();
this.init();
},
activated() {},
components: {

View File

@ -8,27 +8,35 @@
<header>
<div class="w">
<div class="title-bar">
<div class="icon-box">
<i class="el-icon-refresh reflash" @click="reflash()"></i>
</div>
<div class="center">
<!-- 判断逻辑默认当前学期是0那么最大学期index为split.length-1因为到达最小学期就不能显示左符号所以为< -->
<div
class="left-box"
@click="changeWeek('left', current_term_index < split.length-1)"
>
<i class="el-icon-arrow-left icon" v-show="current_term_index < split.length-1"></i>
<template v-if="grade">
<div class="icon-box">
<i class="el-icon-refresh reflash" @click="reflash()"></i>
</div>
<div
class="title-box"
>{{split[current_term_index].term_time.slice(0,4)+'-'+'0'+split[current_term_index].term_time[4]}}</div>
<div class="right-box" @click="changeWeek('right', current_term_index > 0)">
<i class="el-icon-arrow-right icon" v-show="current_term_index > 0"></i>
<div class="center">
<!-- 判断逻辑默认当前学期是0那么最大学期index为split.length-1因为到达最小学期就不能显示左符号所以为< -->
<div
class="left-box"
@click="changeWeek('left', current_term_index < split.length-1)"
>
<i class="el-icon-arrow-left icon" v-show="current_term_index < split.length-1"></i>
</div>
<div
class="title-box"
>{{split[current_term_index].term_time.slice(0,4)+'-'+'0'+split[current_term_index].term_time[4]}}</div>
<div class="right-box" @click="changeWeek('right', current_term_index > 0)">
<i class="el-icon-arrow-right icon" v-show="current_term_index > 0"></i>
</div>
</div>
</div>
<div class="total-button" @click="detail = true">总成绩</div>
<div class="total-button" @click="detail = true">总成绩</div>
</template>
<template v-else>
<div class="center">
<div class="title-box">成绩</div>
</div>
</template>
</div>
<div class="grade-bar">
<div class="grade-bar" v-if="grade">
<p>
本学期绩点
<span>{{split[current_term_index].term_GPA.toPrecision(4)}}</span>
@ -46,16 +54,32 @@
</div>
</div>
</header>
<div :style="'height: 2.9rem;'"></div>
<!-- 以下的数据全部基于current_term_index所以不用做特殊处理 -->
<GradeCard
v-for="(content, index) in split[current_term_index].term_grade"
:content="content"
:key="index+current_term_index*30"
></GradeCard>
<template v-if="grade">
<!-- 以下的数据全部基于current_term_index所以不用做特殊处理 -->
<div style="height: 2.9rem;"></div>
<GradeCard
v-for="(content, index) in split[current_term_index].term_grade"
:content="content"
:key="index+current_term_index*30"
></GradeCard>
</template>
<template v-else>
<div style="height: 1.2rem;"></div>
<div class="errMsg">
<p class="title">抱歉暂无数据</p>
<p class="content">请访问教务系统</p>
<p @click="open('https://webvpn.cust.edu.cn')" class="link">webvpn.cust.edu.cn</p>
<p class="content">如在教务能成功查看到成绩信息请</p>
<p @click="reflash()" class="link">刷新数据</p>
<p class="content">如果教务上都看不到那就与我无瓜了,</p>
<p class="content">若刷新后仍无数据请加群</p>
<p @click="open('https://jq.qq.com/?_wv=1027&k=5Jeoz9R')" class="link">1030523678</p>
</div>
</template>
<div style="height:.3rem;"></div>
<!-- 总成绩点击弹窗 -->
<div class="dialog" v-show="detail" @touchmove.prevent>
<div class="dialog" v-if="grade && detail" @touchmove.prevent>
<div class="w">
<div class="title">
总成绩
@ -68,10 +92,10 @@
总绩点
<span>{{total.total_GPA.toPrecision(4)}}</span>
</p>
<p>
去选修绩点
<span>{{total.total_bixiu_GPA.toPrecision(4)}}</span>
</p>
<p>
去选修绩点
<span>{{total.total_bixiu_GPA.toPrecision(4)}}</span>
</p>
<p>
总学分
<span>{{total.total_credit}}</span>
@ -94,49 +118,86 @@
import FooterSpace from "@/components/FooterSpace.vue";
import GradeCard from "./components/GradeCard.vue";
import { mapState, mapActions } from "vuex";
import { getGradeInitData } from '@/lib/utils.js'
import { decryptMainCode } from "@/lib/aes.js";
import { interceptTime } from "@/lib/utils.js";
import { manageSchedule } from "@/lib/schedule.js";
import { Loading } from "element-ui";
import { login } from "@/axios/api.js";
import { replaceState } from "@/lib/getStore.js";
export default {
name: "grade",
data() {
return {
current_term_index: 0,
split: null,
split: [],
total: null,
detail: false,
init_lock: false
};
},
computed: {
...mapState(["grade", "user_info"])
...mapState([
"grade",
"user_info",
"schedule",
"personal_class",
"row_lesson_info"
])
},
methods: {
...mapActions(["setCurrentPage", 'setGrade']),
...mapActions([
"setUserInfo",
"setGrade",
"setSchedule",
"setCurrentPage",
"setRowLessonInfo",
"setPersonalClass"
]),
//
init(lock = false) {
// 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;
this.init_lock = lock;
// vuex
replaceState.call(this);
// 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])
}
//grade
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
);
//
if (Object.keys(this.user_info).length != 0) {
let now = new Date().getTime(); //
if (
now - this.user_info.login_time < 1000 * 60 * 60 * 24 * 7 &&
this.user_info.login_time > interceptTime
) {
// 7
//
let user_info = this.user_info;
user_info.login_time = new Date().getTime();
this.setUserInfo([user_info, this]);
console.log("用户登录时间刷新完成");
if (this.grade) {
//grade
this.split = this.grade.split;
this.total = this.grade.total;
}
return;
}
}
localStorage.clear();
replaceState.call(this);
console.log("未登录拦截");
this.$router.replace("/login");
},
//
//
changeWeek(direction, judge) {
//
if (!judge) return;
@ -144,9 +205,111 @@ 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.cid == '2020') {
this.$message({
message: "信息刷新成功",
type: "success"
});
return
}
//
if (!this.user_info || !this.user_info.pwd) {
this.$router.push("/login");
return;
}
let load = Loading.service({
background: "rgba(236,245,255,.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.response && error.response.status != 500) {
this.$message.error(
`${error.response.status}: ${error.response.data}`
);
} else {
this.$message.error("网络错误,请稍候重试");
}
});
},
//
//
manageRes(data, load) {
//
let user_info = this.user_info;
user_info.login_time = new Date().getTime();
let grade = data.grade ? data.grade : this.grade;
let schedule = data.schedule ? data.schedule : this.schedule;
if (schedule) {
this.setRowLessonInfo([schedule.lesson, this]);
this.setSchedule([schedule, this]);
}
this.refreshSchedule();
// localStorage
this.setUserInfo([user_info, this]);
this.setGrade([grade, this]);
//
load.close();
this.$message({
message: "信息刷新成功",
type: "success"
});
},
//
refreshSchedule() {
//
let row_lesson_info = JSON.parse(JSON.stringify(this.row_lesson_info));
if (!row_lesson_info) {
//
row_lesson_info = [];
for (let i = 0; i < 7; i++) {
row_lesson_info.push([0, 0, 0, 0, 0, 0]);
}
}
//
for (let key in this.personal_class) {
let lesson = this.personal_class[key];
if (row_lesson_info[lesson.day_position][lesson.lesson_position] != 0) {
row_lesson_info[lesson.day_position][lesson.lesson_position].push(
lesson
);
} else {
row_lesson_info[lesson.day_position][lesson.lesson_position] = [
lesson
];
}
}
//
let schedule = this.schedule;
if (!schedule) {
//
schedule = {
cur_week: 0,
days_per_week: new Array(23).fill(0),
schedule_game: null
};
}
schedule.lesson = manageSchedule(row_lesson_info);
this.setSchedule([schedule, this]);
console.log("显示用课表覆写完成");
},
//
open(url) {
window.open(url);
}
},
created() {
@ -174,6 +337,25 @@ export default {
position: relative;
overflow: hidden;
touch-action: pan-y !important;
.errMsg {
width: 80%;
margin: 1rem auto;
box-sizing: border-box;
padding: 0.5rem;
font-size: 0.4rem;
background: #fff;
box-shadow: 0 0 0.3rem 0.1rem rgba(0, 0, 0, 0.1);
border-radius: 0.1rem;
.title {
font-size: 0.6rem;
font-weight: 600;
margin-bottom: 0.5rem;
}
.link {
margin-bottom: 0.5rem;
color: $blue;
}
}
header {
position: fixed;
top: 0;

View File

@ -1,328 +1,411 @@
<template>
<div class="login">
<div class="title-bg-box">
<div class="title-bg1 title-bg"></div>
<div class="title-bg2 title-bg"></div>
<div class="title-bg3 title-bg"></div>
</div>
<header><i class="el-icon-back" @click="turnToHome()"></i></header>
<div class="logo-box"><img src="../../assets/logo.png" alt class="logo" /></div>
<div class="login-box">
<div class="title">获取信息</div>
<div class="label">教务账号</div>
<input type="text" name="cid" v-model.trim="cid" />
<div class="label">教务密码</div>
<input type="password" name="pwd" v-model.trim="pwd" />
<div class="label">手机号码(非必填仅在rush失败时用于更新教务)</div>
<input type="password" name="phone" v-model.trim="phone" />
</div>
<div class="submit-box"><div class="submit" @click="submit()">rushBBBB</div></div>
<div class="copyRight">
<p>Version&nbsp;2.0</p>
<p>Inspire Studio</p>
<p>&copy;2020 All Rights Reserved.</p>
</div>
<FooterSpace></FooterSpace>
<el-dialog
title="服务器开小差了"
:visible.sync="net_error_dialog"
width="90%">
<span>{{net_error_dialog_content}}</span>
<span slot="footer" class="dialog-footer">
<el-button @click="net_error_dialog = false">狠心拒绝</el-button>
<el-button type="primary" @click="openQQ()">欣然接受</el-button>
</span>
</el-dialog>
</div>
<div class="login">
<div class="title-bg-box">
<div class="title-bg1 title-bg"></div>
<div class="title-bg2 title-bg"></div>
<div class="title-bg3 title-bg"></div>
</div>
<!-- <header><i class="el-icon-back" @click="turnToHome()"></i></header> -->
<div class="logo-box">
<img
src="../../assets/logo.png"
alt
class="logo"
/>
</div>
<div class="login-box">
<div class="title">登录</div>
<div class="label">教务账号*</div>
<input
type="text"
name="cid"
v-model.trim="cid"
/>
<!-- <div class="tips">由于教务问题20级同学还无法使用请在此直接输入2020点击登录即可体验</div> -->
<div class="label">教务密码*</div>
<input
type="password"
name="pwd"
v-model.trim="pwd"
/>
<div class="label">手机号码(非必填仅在登录失败时更新教务)</div>
<input
type="password"
name="phone"
v-model.trim="phone"
/>
</div>
<div class="submit-box">
<div
class="submit"
@click="submit()"
>登录</div>
</div>
<div class="copyRight">
<p>Version&nbsp;3.7</p>
<p>RainSun & Accepted</p>
<p>&copy;2020 All Rights Reserved.</p>
</div>
<FooterSpace></FooterSpace>
<el-dialog
title="服务器开小差了"
:visible.sync="net_error_dialog"
width="90%"
>
<span>{{net_error_dialog_content}}</span>
<span
slot="footer"
class="dialog-footer"
>
<el-button @click="net_error_dialog = false">狠心拒绝</el-button>
<el-button
type="primary"
@click="openQQ()"
>欣然接受</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
// @ is an alias to /src
import { mapState, mapActions } from 'vuex';
import { login } from '@/axios/api.js';
import { Loading } from 'element-ui';
import FooterSpace from '@/components/FooterSpace.vue';
import { getGradeInitData } from '@/lib/utils.js'
import { mapState, mapActions } from "vuex";
import { login } from "@/axios/api.js";
import { Loading } from "element-ui";
import FooterSpace from "@/components/FooterSpace.vue";
import { encryptMainCode } from "@/lib/aes.js";
import { manageSchedule } from "@/lib/schedule.js";
import { replaceState } from "@/lib/getStore.js";
import { test_info } from "@/lib/testInfo.js";
export default {
name: 'login',
data() {
return {
cid: '',
pwd: '',
phone: '',
errmsg: '',
net_error_dialog: false,
net_error_dialog_content: ''
};
},
computed: {
...mapState(['grade', 'schedule'])
},
methods: {
...mapActions(['setUserInfo', 'setGrade', 'setSchedule', 'setCurrentPage']),
//
init() {
// vuex
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: '阅!'
});
}
},
name: "login",
data () {
return {
cid: "",
pwd: "",
phone: "",
errmsg: "",
net_error_dialog: false,
net_error_dialog_content: ""
};
},
computed: {
...mapState(["grade", "schedule", "personal_class", "row_lesson_info"])
},
methods: {
...mapActions([
"setUserInfo",
"setGrade",
"setSchedule",
"setCurrentPage",
"setRowLessonInfo",
"setPersonalClass"
]),
//
init () {
// vuex
replaceState.call(this);
// footerNav
this.setCurrentPage(["None", this]);
},
// rushB
submit() {
if (this.cid && this.pwd) {
//
let load = Loading.service({
background: 'rgba(236,245,255,.7)',
target: document.querySelector('.login')
});
let data = {
cid: this.cid,
pwd: this.pwd,
phone: this.phone
};
login(data)
.then(res => {
// console.log(res)
this.manageRes(res.data, load);
})
.catch(error => {
console.log(error);
load.close();
if (error.code === 'ECONNABORTED' && error.message.indexOf('timeout') !== -1) {
//
this.net_error_dialog_content = '可能登陆人数过多,再试试吧,实在不行再加群问问。肥肠感谢!!!'
} else {
//
this.net_error_dialog_content = '服务器出问题了!快加群告诉群主!!肥肠感谢!!!'
}
// dialog
this.net_error_dialog = true
});
} else {
//
this.$message.error('请输入完整的账号密码');
}
},
// rushB
submit () {
if (this.cid == '2020') {
let load = Loading.service({
background: "rgba(236,245,255,.7)",
target: document.querySelector(".login")
});
this.manageRes(JSON.parse(JSON.stringify(test_info)), load);
}
else if (this.cid && this.pwd) {
//
let load = Loading.service({
background: "rgba(236,245,255,.7)",
target: document.querySelector(".login")
});
let data = {
cid: this.cid,
pwd: this.pwd,
phone: this.phone
};
login(data)
.then(res => {
// console.log(res)
this.manageRes(res.data, load);
})
.catch(error => {
console.log(error);
load.close();
if (
error.code === "ECONNABORTED" &&
error.message.indexOf("timeout") !== -1
) {
//
this.net_error_dialog_content =
"可能登陆人数过多,再试试吧,实在不行再加群问问。肥肠感谢!!!";
// dialog
this.net_error_dialog = true;
return;
}
if (error.response && error.response.status != 500) {
this.$message.error(
`${error.response.status}: ${error.response.data}`
);
} else {
this.$message.error("网络错误,请稍候重试");
}
});
} else {
//
this.$message.error("请输入完整的账号密码");
}
},
//
manageRes(data, load) {
if (data.errcode == 200) {
//
let user_info = {
login_time: new Date().getTime(),
id: data.student_id,
name: data.student_name,
cid: this.cid
};
// ,
//
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.setUserInfo([user_info, this]);
this.setGrade([grade, this]);
this.setSchedule([schedule, this]);
//
load.close();
this.$message({
message: '信息获取成功',
type: 'success'
});
//
this.turnToHome();
} else if (data.errcode == 101) {
//
load.close();
this.$alert('账号或密码错了,笨', '与我无瓜', {
confirmButtonText: '阅!'
});
} else {
//
load.close();
this.$alert('教务挂了,等通知吧', '与我无瓜', {
confirmButtonText: '阅!'
});
}
},
//
turnToHome() {
this.$router.replace('/');
},
//
manageRes (data, load) {
//
let user_info = {
login_time: new Date().getTime(),
id: data.student_id,
name: data.student_name,
cid: this.cid,
pwd: encryptMainCode(this.pwd)
};
let grade = data.grade ? data.grade : this.grade;
let schedule = data.schedule ? data.schedule : this.schedule;
if (schedule) {
this.setRowLessonInfo([schedule.lesson, this]);
this.setSchedule([schedule, this]);
}
this.refreshSchedule();
// localStorage
this.setUserInfo([user_info, this]);
this.setGrade([grade, this]);
//
load.close();
this.$message({
message: "信息获取成功",
type: "success"
});
//
this.turnToHome();
},
// qq
openQQ() {
window.open('https://jq.qq.com/?_wv=1027&k=5Jeoz9R');
}
},
created() {
this.init();
},
mounted() {},
activated() {},
components: {
FooterSpace
}
//
refreshSchedule () {
//
let row_lesson_info = JSON.parse(JSON.stringify(this.row_lesson_info));
if (!row_lesson_info) {
//
row_lesson_info = [];
for (let i = 0; i < 7; i++) {
row_lesson_info.push([0, 0, 0, 0, 0, 0]);
}
}
//
for (let key in this.personal_class) {
let lesson = this.personal_class[key];
if (row_lesson_info[lesson.day_position][lesson.lesson_position] != 0) {
row_lesson_info[lesson.day_position][lesson.lesson_position].push(
lesson
);
} else {
row_lesson_info[lesson.day_position][lesson.lesson_position] = [
lesson
];
}
}
//
let schedule = this.schedule;
if (!schedule) {
//
schedule = {
cur_week: 0,
days_per_week: new Array(23).fill(0),
schedule_game: null
};
}
schedule.lesson = manageSchedule(row_lesson_info);
this.setSchedule([schedule, this]);
console.log("显示用课表覆写完成");
},
//
turnToHome () {
this.$router.replace({ path: "/", query: { from_login: true } });
},
// qq
openQQ () {
window.open("https://jq.qq.com/?_wv=1027&k=5Jeoz9R");
}
},
created () {
this.init();
},
mounted () { },
activated () { },
components: {
FooterSpace
}
};
</script>
<style scoped lang="scss" type="text/scss">
@import '../../style/main';
@import "../../style/main";
.login {
width: 100%;
max-width: 500px;
margin: 0 auto;
background-color: #f8f8f8;
min-height: 100%;
position: relative;
overflow: hidden;
.title-bg-box {
position: absolute;
width: 120%;
transform: rotate(-30deg);
top: -2rem;
left: -3.2rem;
.title-bg {
width: 90%;
height: 6rem;
// background-image: linear-gradient(to bottom right, #17e7d7, #5d73e2);
background-image: $gradualLoginTitle;
border-radius: 1rem;
position: absolute;
}
.title-bg1 {
top: 0;
left: 0;
}
.title-bg2 {
top: 2rem;
left: 0rem;
// box-shadow: -.2rem 0 5px #a1dbe4;
box-shadow: -0.2rem 0 5px #dde3a1;
}
.title-bg3 {
top: 3rem;
left: 1rem;
}
}
header {
width: 85%;
margin: 0 auto;
height: 1rem;
margin-top: 0.5rem;
color: #fff;
font-size: 0.8rem;
display: flex;
align-items: center;
position: relative;
z-index: 3;
}
.logo-box {
width: 2.5rem;
height: 2.5rem;
overflow: hidden;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background: rgba(0, 0, 0, 0.1);
margin: 0 auto;
margin-top: 1rem;
position: relative;
z-index: 1;
img {
width: 2.3rem;
height: 2.3rem;
border-radius: 50%;
}
}
.login-box {
width: 85%;
height: 9rem;
background: #fff;
margin: 0 auto;
margin-top: -1rem;
border-radius: 0.2rem;
padding: 0.6rem;
box-sizing: border-box;
display: flex;
flex-direction: column;
box-shadow: 0 5px 15px #e5e5e5;
position: relative;
.title {
color: #333;
font-size: 0.6rem;
font-weight: 600;
margin-top: 0.6rem;
}
.label {
font-size: 0.3rem;
margin: 0.5rem 0 0.3rem 0rem;
color: #909399;
}
input {
font-size: 0.4rem;
padding: 0.1rem;
border: none;
border-bottom: 2px #eee solid;
width: 100%;
box-sizing: border-box;
}
}
.submit-box {
height: 1.2rem;
width: 85%;
margin: 0.5rem auto;
position: relative;
.submit {
float: right;
height: 1.2rem;
width: 4rem;
// background-image: linear-gradient(to right, #1be5d2, #5e75e5);
background-image: $gradualLoginSubmit;
border-radius: 0.1rem;
font-size: 0.4rem;
color: #fff;
line-height: 1.2rem;
text-align: center;
position: relative;
z-index: 1;
}
.submit::before {
content: '';
display: block;
background: inherit;
filter: blur(0.1rem);
position: absolute;
width: 100%;
height: 100%;
top: 0.1rem;
left: 0.1rem;
opacity: 0.4;
transform-origin: 0 0;
border-radius: inherit;
transform: scale(1, 1);
z-index: -1;
}
}
.copyRight {
width: 100%;
display: flex;
align-items: center;
flex-direction: column;
margin-top: 1.5rem;
p {
font-size: 0.3rem;
color: #909399;
}
}
width: 100%;
max-width: 500px;
margin: 0 auto;
background-color: #fefefe;
min-height: 100%;
position: relative;
overflow: hidden;
.title-bg-box {
position: absolute;
width: 120%;
transform: rotate(-30deg);
top: -2rem;
left: -3.2rem;
.title-bg {
width: 90%;
height: 6rem;
// background-image: linear-gradient(to bottom right, #17e7d7, #5d73e2);
background-image: $gradualLoginTitle;
border-radius: 1rem;
position: absolute;
}
.title-bg1 {
top: 0;
left: 0;
}
.title-bg2 {
top: 2rem;
left: 0rem;
// box-shadow: -.2rem 0 5px #a1dbe4;
// box-shadow: -0.2rem 0 5px #dde3a1;
}
.title-bg3 {
top: 3rem;
left: 1rem;
}
}
header {
width: 85%;
margin: 0 auto;
height: 1rem;
margin-top: 0.5rem;
color: #fff;
font-size: 0.8rem;
display: flex;
align-items: center;
position: relative;
z-index: 3;
}
.logo-box {
width: 2.7rem;
height: 2.7rem;
overflow: hidden;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background: rgba(0, 0, 0, 0.1);
margin: 0 auto;
margin-top: 2rem;
position: relative;
z-index: 1;
img {
width: 2.5rem;
height: 2.5rem;
border-radius: 50%;
}
}
.login-box {
width: 85%;
height: 8.5rem;
background: #fff;
margin: 0 auto;
margin-top: -1rem;
border-radius: 0.2rem;
padding: 0.6rem;
box-sizing: border-box;
display: flex;
flex-direction: column;
box-shadow: 0 5px 15px #e5e5e5;
position: relative;
.title {
color: #333;
font-size: 0.6rem;
font-weight: 600;
margin-top: 0.6rem;
}
.label {
font-size: 0.3rem;
margin: 0.5rem 0 0.3rem 0rem;
color: #909399;
}
.tips {
font-size: 0.3rem;
margin: 0.2rem 0;
color: #f86b55;
}
input {
font-size: 0.4rem;
padding: 0.1rem;
border: none;
border-bottom: 2px #eee solid;
width: 100%;
box-sizing: border-box;
}
}
.submit-box {
height: 1.2rem;
width: 85%;
margin: 0.5rem auto;
position: relative;
.submit {
float: right;
height: 1.2rem;
width: 4rem;
// background-image: linear-gradient(to right, #1be5d2, #5e75e5);
background-image: $gradualLoginSubmit;
border-radius: 0.1rem;
font-size: 0.4rem;
color: #fff;
line-height: 1.2rem;
text-align: center;
position: relative;
z-index: 1;
}
.submit::before {
content: "";
display: block;
background: inherit;
filter: blur(0.1rem);
position: absolute;
width: 100%;
height: 100%;
top: 0.1rem;
left: 0.1rem;
opacity: 0.4;
transform-origin: 0 0;
border-radius: inherit;
transform: scale(1, 1);
z-index: -1;
}
}
.copyRight {
width: 100%;
display: flex;
align-items: center;
flex-direction: column;
margin-top: 1.5rem;
p {
font-size: 0.3rem;
color: #909399;
}
}
}
</style>

View File

@ -1,16 +1,25 @@
<template>
<div class="myaccount">
<header>
<img src="../assets/logo_nobg.png" alt="logo" />
<img
src="../../assets/logo_nobg.png"
alt="logo"
/>
<p>
Co-Create
<span>v1.0</span>
Cherry
<span>v3.7</span>
</p>
<div class="auth">By:Inspire Studio</div>
<!-- <img src="../assets/wave.gif" mode="scaleToFill" class="gif-wave"/> -->
<!-- <image src="https://raw.githubusercontent.com/weilanwl/ColorUI/master/demo/images/wave.gif" mode="scaleToFill" class="gif-wave"></image> -->
<img
src="../../assets/wave.gif"
mode="scaleToFill"
class="gif-wave"
/>
</header>
<div class="user-box shadow-warp">
<div
class="user-box shadow-warp"
v-if="Object.keys(this.user_info).length != 0"
>
<div class="cid-box">
<div class="cid">{{user_info.id}}</div>
<div class="label">
@ -25,21 +34,40 @@
</div>
</div>
</div>
<div class="logout" @click="logout()">消除数据</div>
<div class="qq">
使用安卓的同学请注意不要用安装包那不是官方的正式版本我们极力推荐使用浏览器将网页保存到桌面的方法,请转告身边的同学,拜托了(不会保存网页可以来群里问我哈)
<div class="functions-box">
<div
class="item"
@click="goTo('/personal')"
>
<i class="el-icon-s-operation first-function-icon"></i>
<p>个性化</p>
<i class="el-icon-arrow-right arrow-right"></i>
</div>
</div>
<div
class="logout"
@click="logout()"
v-if="Object.keys(this.user_info).length != 0"
>退出登录</div>
<div
class="logout"
@click="goTo('/login')"
v-else
>立即登录</div>
<div class="qq">
反馈及获取最新功能=>
<span @click="openQQ()">1030523678</span>
</div>
<div class="web-addr"
v-clipboard:copy="web_addr"
v-clipboard:success="onCopyUrl"
v-clipboard:error="onErrorUrl">
<div
class="web-addr"
v-clipboard:copy="web_addr"
v-clipboard:success="onCopyUrl"
v-clipboard:error="onErrorUrl"
>
coc主站地址=>
<span>coc.powerrain.cn</span>
<span>cherry.lacus.site</span>
</div>
<div style="height: 1.5rem;"></div>
<FooterSpace></FooterSpace>
</div>
</template>
@ -50,56 +78,54 @@
import FooterSpace from "@/components/FooterSpace.vue";
import { mapState, mapActions } from "vuex";
import { loginInterceptor } from "@/lib/utils.js";
import { replaceState } from '@/lib/getStore.js'
export default {
name: "myaccount",
data() {
data () {
return {
web_addr: 'https://coc.powerrain.cn'
web_addr: "https://cherry.lacus.site"
};
},
computed: {
...mapState(["user_info", "current_week", "current_schedule"])
...mapState(["user_info"])
},
methods: {
...mapActions([
"setCurrentPage",
"setGrade",
"setSchedule",
"setUserInfo"
]),
...mapActions(["setCurrentPage"]),
init () {
// vuex
replaceState.call(this)
this.setCurrentPage(["myaccount", this]);
},
//
logout() {
this.setUserInfo([null, this]);
this.setGrade([null, this]);
this.setSchedule([null, this]);
localStorage.setItem("storeState", JSON.stringify(this.$store.state));
logout () {
localStorage.clear();
replaceState.call(this);
this.$message({
message: "本地数据清除完成",
type: "success"
});
this.$router.replace("/login");
},
// qq
openQQ() {
openQQ () {
window.open("https://jq.qq.com/?_wv=1027&k=5Jeoz9R");
},
goTo(url) {
goTo (url) {
this.$router.push(url);
},
onCopyUrl(e) {
onCopyUrl (e) {
this.$message.success("复制成功!");
},
onErrorUrl(e) {
onErrorUrl (e) {
this.$message.success("复制失败!");
}
},
created() {
created () { },
mounted () {
this.init();
},
mounted(){
this.setCurrentPage(["myaccount", this]);
},
activated (){
this.setCurrentPage(["myaccount", this]);
activated () {
this.init();
},
components: {
FooterSpace
@ -108,17 +134,17 @@ export default {
</script>
<style scoped lang="scss" type="text/scss">
@import "../style/main";
@import "../../style/main";
.myaccount {
width: 100%;
max-width: 500px;
margin: 0 auto;
background-color: #f1f1f1;
background-color: #f5f5f5;
min-height: 100%;
position: relative;
overflow: hidden;
header {
background-image: url(../assets/mine_bg.jpg);
background-image: url(../../assets/mine_bg.jpg);
background-size: cover;
height: 7rem;
display: flex;
@ -135,17 +161,27 @@ export default {
}
p {
font-size: 0.5rem;
font-weight: 300;
span {
font-size: 0.4rem;
font-weight: 100;
font-weight: 700;
}
}
.auth {
font-size: 0.5rem;
margin-top: 0.3rem;
font-weight: 100;
font-weight: 300;
margin-bottom: 1rem;
}
.gif-wave {
position: absolute;
bottom: 0;
mix-blend-mode: screen;
height: 2rem;
width: 100%;
}
}
.user-box {
height: 2rem;
color: $grey;
@ -189,6 +225,32 @@ export default {
border-left: 1px #eee solid;
}
}
.functions-box {
width: 80%;
margin: 0.5rem auto;
background: #fff;
border-radius: 0.2rem;
color: #999;
.item {
display: flex;
position: relative;
align-items: center;
height: 1rem;
.first-function-icon {
font-size: 0.5rem;
margin-left: 0.3rem;
}
p {
font-size: 0.35rem;
margin-left: 0.3rem;
}
.arrow-right {
position: absolute;
right: 0.3rem;
font-size: 0.5rem;
}
}
}
.logout {
background-image: $gradualGreen;
color: #fff;
@ -218,7 +280,8 @@ export default {
border-radius: inherit;
transform: scale(1, 1);
}
.qq ,.web-addr{
.qq,
.web-addr {
font-size: 0.35rem;
color: $gray;
text-align: center;
@ -227,7 +290,7 @@ export default {
}
}
.web-addr {
margin-top: .3rem;
margin-top: 0.3rem;
}
}
</style>

View File

@ -0,0 +1,370 @@
<template>
<div class="personal">
<header>
<div class="w">
<div class="icon-box">
<i
class="el-icon-back title-icon"
@click="back()"
></i>
</div>
<div class="title-box">个性化</div>
</div>
</header>
<div style="height: 1.2rem;"></div>
<div class="main">
<div class="topic">课表设置</div>
<div class="option">
<!-- <icon name="firstPrize" class="option-icon"></icon> -->
<div class="label">隐藏周末</div>
<div class="handle-space">
<el-switch
v-model="hide_weekend"
active-color="#39b54a"
@change="modifyConfig()"
></el-switch>
</div>
</div>
<div class="option">
<!-- <icon name="firstPrize" class="option-icon"></icon> -->
<div class="label">开启背景图</div>
<div class="handle-space">
<el-switch
v-model="user_bg_switch"
active-color="#39b54a"
@change="modifyConfig()"
></el-switch>
</div>
</div>
<div class="option">
<!-- <icon name="firstPrize" class="option-icon"></icon> -->
<div class="label">深色背景适配</div>
<div class="handle-space">
<el-switch
v-model="user_bg_is_dark"
active-color="#39b54a"
@change="modifyConfig()"
></el-switch>
</div>
</div>
<div class="option">
<!-- <icon name="firstPrize" class="option-icon"></icon> -->
<div class="label">课表透明度</div>
<div class="handle-space">
<Slider
:value="settings.lesson_opacity"
@change="modifyOpacity"
></Slider>
</div>
</div>
<div class="option">
<!-- <icon name="firstPrize" class="option-icon"></icon> -->
<Select
label="时间显示类型"
:options="bar_show_style_list"
:value="settings.bar_show_style"
@change="modifyBarShowStyle"
></Select>
</div>
<div class="option">
<!-- <icon name="firstPrize" class="option-icon"></icon> -->
<Input
label="图片网络地址"
:value="settings.user_bg_url"
@change="modifyUserBgUrl"
/>
</div>
<!-- <div
class="option"
@click="clickFile"
>
<div class="img-box">
<icon
name='camera_green'
class="img-box-icon"
/>
</div>
<input
type="file"
style="display: none;"
accept="image/*"
@change="processFile"
id="file"
>
</div> -->
<div class="topic">应用设置</div>
<div class="option">
<!-- <icon name="firstPrize" class="option-icon"></icon> -->
<div class="label">关闭TAB文字</div>
<div class="handle-space">
<el-switch
v-model="hide_tab_text"
active-color="#39b54a"
@change="modifyConfig()"
></el-switch>
</div>
</div>
</div>
<FooterSpace></FooterSpace>
</div>
</template>
<script>
// @ is an alias to /src
import FooterSpace from "@/components/FooterSpace.vue";
import Slider from "@/components/Slider.vue";
import Select from "@/components/Select.vue";
import Input from "@/components/Input.vue";
import { mapState, mapActions } from "vuex";
import { replaceState } from "@/lib/getStore.js";
import { Loading } from "element-ui";
import { interceptTime } from "@/lib/utils.js";
import lrz from "lrz";
export default {
name: "personal",
data () {
return {
//
hide_weekend: false,
//
user_bg_switch: false,
//
user_bg_is_dark: false,
// tab
hide_tab_text: false,
// => 0 1 2
bar_show_style: 0,
bar_show_style_list: [
{
value: 0,
text: "正常",
},
{
value: 1,
text: "衬底",
},
{
value: 2,
text: "阴影",
},
],
//
dark_mode: false,
lrz_file: null,
};
},
computed: {
...mapState(["user_info", "settings"]),
},
methods: {
...mapActions(["setUserInfo", "setCurrentPage", "setSettings"]),
//
init () {
// vuex
replaceState.call(this);
// footerNav
this.setCurrentPage(["None", this]);
//
if (Object.keys(this.user_info).length != 0) {
let now = new Date().getTime(); //
if (
now - this.user_info.login_time < 1000 * 60 * 60 * 24 * 7 &&
this.user_info.login_time > interceptTime
) {
// 7
//
let user_info = this.user_info;
user_info.login_time = new Date().getTime();
this.setUserInfo([user_info, this]);
console.log("用户登录时间刷新完成");
this.initData();
return;
}
}
localStorage.clear();
replaceState.call(this);
console.log("未登录拦截");
this.$router.replace("/login");
},
initData () {
this.hide_weekend = this.settings.hide_weekend;
this.user_bg_switch = this.settings.user_bg_switch;
this.user_bg_is_dark = this.settings.user_bg_is_dark;
this.bar_show_style = this.settings.bar_show_style;
this.hide_tab_text = this.settings.hide_tab_text;
},
back () {
this.$router.go(-1);
},
modifyConfig () {
let new_settings = {
...this.settings,
hide_weekend: this.hide_weekend,
user_bg_switch: this.user_bg_switch,
user_bg_is_dark: this.user_bg_is_dark,
hide_tab_text: this.hide_tab_text,
};
this.setSettings([new_settings, this]);
console.log("设置信息写入完成");
this.$snakebar('个性化设置成功')
},
modifyOpacity (e) {
let new_settings = {
...this.settings,
lesson_opacity: Number(e),
};
this.setSettings([new_settings, this]);
console.log("设置信息写入完成");
this.$snakebar('个性化设置成功')
},
modifyBarShowStyle (e) {
let new_settings = {
...this.settings,
bar_show_style: Number(e),
};
this.setSettings([new_settings, this]);
console.log("设置信息写入完成");
this.$snakebar('个性化设置成功')
},
modifyUserBgUrl (e) {
let new_settings = {
...this.settings,
user_bg_url: e,
};
this.setSettings([new_settings, this]);
console.log("设置信息写入完成");
this.$snakebar('个性化设置成功')
},
clickFile () {
document.getElementById("file").click();
},
//
processFile: async function (e) {
let file = e.target.files[0];
if (!file) return;
let name = file.name;
console.log("文件压缩开始");
file = await lrz(file);
file = file.file;
file = new File([file], name);
this.lrz_file = file
console.log("文件压缩完成", file);
},
},
created () {
this.init();
},
components: {
FooterSpace,
Slider,
Select,
Input,
},
watch: {},
};
</script>
<style scoped lang="scss" type="text/scss">
@import "../../style/main";
.personal {
width: 100%;
max-width: 500px;
margin: 0 auto;
background-color: #fff;
min-height: 100%;
position: relative;
overflow: hidden;
header {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 1.2rem;
z-index: 100;
.w {
height: 1.2rem;
width: 100%;
max-width: 500px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;
background-image: $gradualGreen;
color: #fff;
position: relative;
.title-box {
font-size: 0.5rem;
}
.icon-box {
height: 1.2rem;
width: 1.2rem;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
.title-icon {
font-size: 0.6rem;
}
}
}
}
.main {
max-width: 425px;
margin: 0 0.7rem;
.topic {
margin-top: 0.5rem;
font-size: 0.35rem;
color: $green;
margin-bottom: 0.5rem;
}
.option {
display: flex;
align-items: center;
justify-content: flex-start;
min-height: 1.5rem;
.option-icon {
height: 0.6rem;
width: 0.6rem;
margin-right: 0.7rem;
}
.label {
font-size: 0.45rem;
}
.handle-space {
flex: 1;
min-height: 1.5rem;
display: flex;
align-items: center;
justify-content: flex-end;
}
.img-box {
margin-top: 0.5rem;
height: 1.5rem;
width: 1.5rem;
border: 2px #67c23a solid;
display: flex;
align-items: center;
justify-content: center;
.img-box-icon {
height: 0.7rem;
width: 0.7rem;
}
}
}
}
}
</style>

View File

@ -2,44 +2,70 @@
<div class="schedule">
<header>
<div class="w">
<i class="el-icon-s-operation more" @click="openDrawer()"></i>
<div class="left-box" @click="changeWeek('left')">
<i class="el-icon-arrow-left icon" v-show="show_week!==1"></i>
</div>
<div class="week-box">{{show_week}}</div>
<div class="right-box" @click="changeWeek('right')">
<i class="el-icon-arrow-right icon" v-show="show_week!==max_week"></i>
</div>
<i class="el-icon-refresh refresh" @click="reflash"></i>
<template v-if="schedule">
<i class="el-icon-plus plus" @click="goTo('/addclass')"></i>
<div class="left-box" @click="changeWeek('left')">
<i class="el-icon-arrow-left icon" v-show="show_week!==1"></i>
</div>
<div class="week-box">{{show_week}}</div>
<div class="right-box" @click="changeWeek('right')">
<i class="el-icon-arrow-right icon" v-show="show_week!==max_week"></i>
</div>
<i class="el-icon-refresh refresh" @click="reflash"></i>
</template>
<template v-else>
<div class="week-box">课表</div>
</template>
</div>
</header>
<div style="height: 1.2rem;"></div>
<body>
<nav>
<div class="week-title" v-for="i in hide_weekend? 5:7" :class="highlightWeek == i%7? 'highlight':''" :key="i">
<div class="user-bg">
<div class="bg-content" :style="userBgUrl"></div>
</div>
<template v-if="schedule">
<nav :class="textClass">
<div
class="week-title"
v-for="i in settings.hide_weekend? 5:7"
:class="highlightWeek == i%7? 'highlight':''"
:key="i"
>
<p>{{week_day[i-1]}}</p>
<p>{{date_arr[i-1]}}</p>
</div>
</nav>
<div class="main">
<v-touch @swiperight="openDrawer()">
<aside>
<div class="lesson-title" v-for="i in 12" :key="i">{{i}}</div>
<aside :class="textClass">
<div class="lesson-title" v-for="i in 12" :key="i">{{i}}</div>
</aside>
</v-touch>
<v-touch class="lesson-warp" :swipe-options="{direction: 'horizontal'}" @swipeleft="swipeRight" @swiperight="swipeLeft">
<div class="lesson-warp">
<div class="day-box" v-for="d in hide_weekend ? 5:7" :key="d">
<v-touch
class="lesson-warp"
:swipe-options="{direction: 'horizontal'}"
@swipeleft="swipeRight"
@swiperight="swipeLeft"
>
<div class="lesson-warp" :style="`opacity: ${settings.user_bg_switch ? settings.lesson_opacity : 1};`">
<!-- 周一至周日的列 -->
<div class="day-box" v-for="d in settings.hide_weekend ? 5:7" :key="d">
<!-- 一天六节课 -->
<div class="lesson-box" v-for="i in 6" :key="i">
<template v-if="schedule && schedule.errcode === 200 && schedule.data.lesson[d-1][i-1] !== 0">
<template v-for="item in schedule.data.lesson[d-1][i-1]">
<template v-if="item.Time_split[show_week]">
<div class="lesson" :style="lessonStyle(item)" @click="openDialog(item)">
<p class="info">{{item.Lesson}}<br/>{{item.Room.replace(/\[.+\]/, "")}}</p>
</div>
</template>
</template>
</template>
<!-- 如果所有周的这一节都没有课就是0 -->
<div
class="lesson"
:style="lessonStyle(schedule.lesson[show_week-1][d-1][i-1])"
@click="openDialog(schedule.lesson[show_week-1][d-1][i-1])"
v-if="schedule.lesson[show_week-1][d-1][i-1]"
>
<p class="info">
<span :class="{'long': settings.hide_weekend}">{{schedule.lesson[show_week-1][d-1][i-1].Lesson}}</span>
<br />
<span v-if="settings.hide_weekend">{{schedule.lesson[show_week-1][d-1][i-1].Room}}</span>
<span v-else>{{schedule.lesson[show_week-1][d-1][i-1].Room.replace(/\[.+\]/, "")}}</span>
<br />
<span v-if="settings.hide_weekend">{{schedule.lesson[show_week-1][d-1][i-1].Teacher}}</span>
</p>
</div>
</div>
</div>
</div>
@ -71,10 +97,49 @@
任课教师
<span>{{detail.Teacher}}</span>
</p>
<p>
自定义课程
<span>{{detail.color == 9 ? '是' : '否'}}</span>
</p>
<div class="more-box" v-for="(lesson, index) in detail.hide" :key="index">
<div class="line"></div>
<p>
课程名
<span>{{lesson.Lesson}}</span>
</p>
<p>
周数
<span>{{lesson.Time}}</span>
</p>
<p>
上课地点
<span>{{lesson.Room}}</span>
</p>
<p>
任课教师
<span>{{lesson.Teacher}}</span>
</p>
<p>
自定义课程
<span>{{lesson.color == 9 ? '是' : '否'}}</span>
</p>
</div>
</div>
</div>
</div>
</body>
</template>
<template v-else>
<div class="errMsg">
<p class="title">抱歉暂无数据</p>
<p class="content">请访问教务系统</p>
<p @click="open('https://webvpn.cust.edu.cn')" class="link">webvpn.cust.edu.cn</p>
<p class="content">如在教务能成功查看到成绩信息请</p>
<p @click="reflash()" class="link">刷新数据</p>
<p class="content">如果教务上都看不到那就与我无瓜了,</p>
<p class="content">若刷新后仍无数据请加群</p>
<p @click="open('https://jq.qq.com/?_wv=1027&k=5Jeoz9R')" class="link">1030523678</p>
</div>
</template>
<FooterSpace></FooterSpace>
</div>
</template>
@ -83,38 +148,76 @@
// @ is an alias to /src
import FooterSpace from "@/components/FooterSpace.vue";
import { mapState, mapActions } from "vuex";
import { gameUpload } from '@/axios/api.js'
import { decryptMainCode } from "@/lib/aes.js";
import { interceptTime } from "@/lib/utils.js";
import { manageSchedule } from "@/lib/schedule.js";
import { Loading, TimeSelect } from "element-ui";
import { login } from "@/axios/api.js";
import { replaceState } from "@/lib/getStore.js";
export default {
name: "schedule",
data() {
return {
//
current_week: 1,
//
//
current_week: 1,
//
show_week: 1,
//
//
max_week: 22,
// dialog
// dialog
detail: false,
//
hide_weekend: false,
//
week_day: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
//
bg_color: ["e4f5ff", "defbf7", "e7e5fa", "fcebcf", "feeeef", "d7f0db", "ebd4ef", "f9d7ea", "ede1d9", '48f350'],
//
font_color: ["58a2d9", "2bbbbc", "8379d8", "e89812", "d36e88", "39b54a", "9c26b0", "e03997", "a5673f", '48f350'],
//
//
week_day: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
//
bg_color: [
"E5F4FF",
"defbf7",
"e7e5fa",
"fcebcf",
"feeeef",
"d7f0db",
"ebd4ef",
"f9d7ea",
"ede1d9",
"fadbd9",
"e7ebee"
],
//
font_color: [
"00A6F2",
"2bbbbc",
"8379d8",
"e89812",
"d36e88",
"39b54a",
"9c26b0",
"e03997",
"a5673f",
"e54d42",
"8799a3"
],
//
init_lock: false,
//
date_arr: []
};
},
computed: {
...mapState(["user_info", "current_page", "schedule"]),
//
...mapState([
"user_info",
"current_page",
"schedule",
"grade",
"personal_class",
"row_lesson_info",
"settings"
]),
//
highlightWeek: function() {
let now = new Date().getTime()
if (now < 1598803200000) {
return -1;
}
if (this.show_week == this.current_week) {
//
return new Date().getDay();
@ -122,124 +225,276 @@ export default {
return -1;
}
},
//
userBgUrl: function() {
if (!this.settings.user_bg_switch) return ''
return `background-image: url('${this.settings.user_bg_url}')`
},
//
textClass: function() {
if (!this.settings.user_bg_switch) return 'dark-word'
let res = ''
res += this.settings.user_bg_is_dark ? 'light-word' : 'dark-word'
switch (this.settings.bar_show_style) {
case 0:
break;
case 1:
res += this.settings.user_bg_is_dark ? ' light-word-matting' : ' dark-word-matting'
break;
case 2:
res += this.settings.user_bg_is_dark ? ' light-word-shadow' : ' dark-word-shadow'
break;
}
return res
}
},
methods: {
...mapActions(["setCurrentPage", "setDrawerState"]),
...mapActions([
"setUserInfo",
"setGrade",
"setSchedule",
"setCurrentPage",
"setDrawerState",
"setRowLessonInfo",
"setPersonalClass",
"setSettings"
]),
//
init(lock = false) {
// 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
// footerNav
this.setCurrentPage(["schedule", this]);
//
setTimeout(function(){
this.init_lock = false
}.bind(this), 100)
//
if(!this.schedule) return
//
// activated使keepalive
// this.current_week = this.schedule.data.cur_week > 0 ? this.schedule.data.cur_week : 1;
this.getCurrentWeek()
this.show_week = lock ? this.current_week : this.show_week;
this.getDays()
//
if (this.init_lock) return;
this.init_lock = lock;
if (this.$route.query.from_login) {
lock = true;
}
// vuex
replaceState.call(this);
// footerNav
this.setCurrentPage(["schedule", this]);
//
setTimeout(
function() {
this.init_lock = false;
}.bind(this),
100
);
//
if (Object.keys(this.user_info).length != 0) {
let now = new Date().getTime(); //
if (
now - this.user_info.login_time < 1000 * 60 * 60 * 24 * 7 &&
this.user_info.login_time > interceptTime
) {
// 7
//
let user_info = this.user_info;
user_info.login_time = new Date().getTime();
this.setUserInfo([user_info, this]);
console.log("用户登录时间刷新完成");
//
this.getCurrentWeek();
// activated使keepalive
this.show_week = lock ? this.current_week : this.show_week;
if(this.user_info.cid == '2020') this.show_week = lock ? 1 : this.show_week;
this.getDays();
return;
}
}
localStorage.clear();
replaceState.call(this);
console.log("未登录拦截");
this.$router.replace("/login");
},
//
changeWeek(dirction) {
if (dirction == "left")
if (this.show_week > 1) this.show_week--;
else return;
else if (this.show_week < this.max_week) this.show_week++;
else return;
this.getDays()
if (dirction == "left") this.swipeLeft();
else this.swipeRight();
},
//
reflash() {
this.$router.push({ name: "login" });
},
// dialog
// dialog
openDialog(data) {
this.detail = data;
},
// dialog
// dialog
closeDialog() {
this.detail = false;
},
//
swipeLeft(){
if (this.show_week > 1)
this.show_week--;
this.getDays()
swipeLeft() {
if (this.show_week > 1) this.show_week--;
this.getDays();
},
swipeRight(){
if (this.show_week < this.max_week)
this.show_week++;
this.getDays()
swipeRight() {
if (this.show_week < this.max_week) this.show_week++;
this.getDays();
},
//
lessonStyle(item) {
return `background:#${this.bg_color[item.color]};color:#${this.font_color[item.color]}`
//
lessonStyle(item) {
return `background:#${this.bg_color[item.color]};color:#${
this.font_color[item.color]
};`;
},
//
goToGame() {
this.$router.push('/game')
},
//
getCurrentWeek() {
//
goToGame() {
this.$router.push("/game");
},
//
goTo(url) {
this.$router.push(url);
},
//
getCurrentWeek() {
// let start = new Date("2020-02-24 00:00").getTime();
let start = 1582473600000
let now = new Date().getTime();
//
let days = Math.abs(Math.floor((now - start) / (1000 * 60 * 60 * 24)));
let current_week;
if (start >= now) {
//
this.current_week = 1;
} else {
//
this.current_week = Math.floor(days / 7) + 1;
}
let start = 1598803200000;
let now = new Date().getTime();
//
let days = Math.abs(Math.floor((now - start) / (1000 * 60 * 60 * 24)));
let current_week;
if (start >= now) {
//
this.current_week = 1;
} else {
//
this.current_week = Math.floor(days / 7) + 1;
}
},
//
getDays() {
const day_time = 1000 * 60 * 60 * 24,
start = 1582473600000;
let week_start_time = (this.show_week - 1) * 7 * day_time + start
this.date_arr = []
for(let i = 1; i <= 7; i++) {
let current_day = new Date(week_start_time).getDate()
if( current_day < 10) {
current_day = '0' + current_day
start = 1598803200000;
let week_start_time = (this.show_week - 1) * 7 * day_time + start;
this.date_arr = [];
for (let i = 1; i <= 7; i++) {
let current_day = new Date(week_start_time).getDate();
if (current_day < 10) {
current_day = "0" + current_day;
}
if (i == 1 || current_day == '01') {
current_day = (new Date(week_start_time).getMonth() + 1) + '/' + current_day
if (i == 1 || current_day == "01") {
current_day =
new Date(week_start_time).getMonth() + 1 + "/" + current_day;
}
this.date_arr.push(current_day)
week_start_time += day_time
this.date_arr.push(current_day);
week_start_time += day_time;
}
},
//
openDrawer() {
this.setDrawerState([true, this])
}
//
reflash() {
if(this.user_info && this.user_info.cid == '2020') {
this.$message({
message: "信息刷新成功",
type: "success"
});
return
}
//
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.response && error.response.status != 500) {
this.$message.error(
`${error.response.status}: ${error.response.data}`
);
} else {
this.$message.error("网络错误,请稍候重试");
}
});
},
//
manageRes(data, load) {
//
let user_info = this.user_info;
user_info.login_time = new Date().getTime();
let grade = data.grade ? data.grade : this.grade;
let schedule = data.schedule ? data.schedule : this.schedule;
if (schedule) {
this.setRowLessonInfo([schedule.lesson, this]);
this.setSchedule([schedule, this]);
}
this.refreshSchedule();
// localStorage
this.setUserInfo([user_info, this]);
this.setGrade([grade, this]);
//
load.close();
this.$message({
message: "信息刷新成功",
type: "success"
});
},
//
refreshSchedule() {
//
let row_lesson_info = JSON.parse(JSON.stringify(this.row_lesson_info));
if (!row_lesson_info) {
//
row_lesson_info = [];
for (let i = 0; i < 7; i++) {
row_lesson_info.push([0, 0, 0, 0, 0, 0]);
}
}
//
for (let key in this.personal_class) {
let lesson = this.personal_class[key];
if (row_lesson_info[lesson.day_position][lesson.lesson_position] != 0) {
row_lesson_info[lesson.day_position][lesson.lesson_position].push(
lesson
);
} else {
row_lesson_info[lesson.day_position][lesson.lesson_position] = [
lesson
];
}
}
//
let schedule = this.schedule;
if (!schedule) {
//
schedule = {
cur_week: 0,
days_per_week: new Array(23).fill(0),
schedule_game: null
};
}
schedule.lesson = manageSchedule(row_lesson_info);
this.setSchedule([schedule, this]);
console.log("显示用课表覆写完成");
},
//
open(url) {
window.open(url);
},
},
created() {
this.init(true);
this.init(true);
},
mounted() {},
activated() {
@ -257,10 +512,29 @@ export default {
width: 100%;
max-width: 500px;
margin: 0 auto;
background-color: #f8f8f8;
// background-color: #f8f8f8;
min-height: 100%;
position: relative;
overflow: hidden;
.errMsg {
width: 80%;
margin: 1rem auto;
box-sizing: border-box;
padding: 0.5rem;
font-size: 0.4rem;
background: #fff;
box-shadow: 0 0 0.3rem 0.1rem rgba(0, 0, 0, 0.1);
border-radius: 0.1rem;
.title {
font-size: 0.6rem;
font-weight: 600;
margin-bottom: 0.5rem;
}
.link {
margin-bottom: 0.5rem;
color: $red;
}
}
header {
position: fixed;
top: 0;
@ -295,7 +569,7 @@ export default {
.week-box {
font-size: 0.5rem;
}
.more {
.plus {
font-size: 0.6rem;
position: absolute;
left: 0.3rem;
@ -312,6 +586,43 @@ export default {
}
}
}
.user-bg {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
padding-top: 1.2rem;
padding-bottom: 1.3rem;
box-sizing: border-box;
z-index: -50;
.bg-content {
height: 100%;
max-width: 500px;
margin: 0 auto;
background-size: cover;
background-repeat: no-repeat;
background-position: center top;
}
}
.dark-word {
color: #333;
}
.light-word {
color: #fff;
}
.dark-word-shadow {
text-shadow:1px 1px 1px #fff;
}
.light-word-shadow {
text-shadow:1px 1px 1px #000;
}
.dark-word-matting {
background: rgba($color: #fff, $alpha: .3);
}
.light-word-matting {
background: rgba($color: #000, $alpha: .3);
}
nav {
height: 1rem;
padding-left: 0.7rem;
@ -341,7 +652,7 @@ export default {
.lesson-warp {
flex: 1;
display: flex;
touch-action: pan-y!important;
touch-action: pan-y !important;
// max-width: 94%;
.day-box {
width: 14%;
@ -351,7 +662,6 @@ export default {
flex-direction: column;
.lesson-box {
height: 2.8rem;
border: 1px #eee solid;
display: flex;
align-items: center;
justify-content: center;
@ -366,10 +676,23 @@ export default {
align-items: center;
justify-content: center;
overflow: hidden;
padding: 0.05rem;
box-sizing: border-box;
.info {
font-size: 0.3rem;
font-size: 0.25rem;
margin-bottom: 0.1rem;
text-align: center;
span:first-of-type {
font-size: 0.3rem;
line-height: .4rem;
display: inline-block;
max-height: 1.2rem;
text-overflow: ellipsis;
overflow: hidden;
}
.long {
max-height: 1.6rem !important;
}
}
}
}
@ -390,7 +713,6 @@ export default {
.w {
width: 70%;
max-width: 350px;
height: 5rem;
background: #fff;
border-radius: 0.1rem;
overflow: hidden;
@ -417,11 +739,12 @@ export default {
}
}
.dialog-main {
height: 4rem;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding-top: 0.3rem;
padding-bottom: 0.6rem;
p {
margin-bottom: 0.2rem;
text-align: center;
@ -431,6 +754,17 @@ export default {
color: $red;
}
}
p:first-of-type {
margin-top: 0.3rem;
}
.line {
height: 1px;
background: #eee;
width: 100%;
}
.more-box {
width: 100%;
}
}
}
}

View File

@ -1,605 +0,0 @@
<template>
<div class="LAFAdd">
<header>
<div class="w">
<div class="icon-box">
<i class="el-icon-back title-icon" @click="back()"></i>
</div>
<div class="title-box">新建</div>
</div>
</header>
<div style="height: 1.2rem;"></div>
<div class="main">
<!-- 物品名 物品描述 | 物品图片 区域 详细地址 联系方式 -->
<!-- 主体信息 -->
<div class="card">
<div class="icon-box">
<i class="el-icon-receiving icon"></i>
</div>
<p>主体信息</p>
<input type="text" placeholder="物品名(必填)" v-model="title"/>
<textarea placeholder="物品描述或者想说的话(必填)" v-model="content"/>
</div>
<!-- 链接小竖条 -->
<div class="link">
<div class="link-item">
<div class="link-dote-top"></div>
<div class="link-line"></div>
<div class="link-dote-bottom"></div>
</div>
<div class="link-item">
<div class="link-dote-top"></div>
<div class="link-line"></div>
<div class="link-dote-bottom"></div>
</div>
</div>
<!-- 详细信息 -->
<div class="card detail-card">
<div class="icon-box">
<i class="el-icon-search icon"></i>
</div>
<p>详细信息</p>
<div class="label">类型(单选)</div>
<div class="type-box">
<div class="option" :class="type == 'lost' ? 'select' : ''" @click="changeType('lost')">丢失</div>
<div class="option" :class="type == 'found' ? 'select' : ''" @click="changeType('found')">拾到</div>
<!-- 占位 -->
<div class="option" style="background: #fff; border:none;"></div>
</div>
<div class="label">区域(单选)</div>
<div class="addr-box">
<div class="option" :class="total_addr == '长理东区' ? 'select': ''" @click="changeTotalAddr('长理东区')">长理东区</div>
<div class="option" :class="total_addr == '长理南区' ? 'select': ''" @click="changeTotalAddr('长理南区')">长理南区</div>
<div class="option" :class="total_addr == '长理西区' ? 'select': ''" @click="changeTotalAddr('长理西区')">长理西区</div>
</div>
<input type="text" placeholder="详细地址(必填)" v-model="detail_addr"/>
<div class="label">联系方式(选填)</div>
<div class="contact-box">
<div class="option" :class="contact_way.type == 'none' ? 'select': ''" @click="changeContactWay('none')">不填</div>
<div class="option" :class="contact_way.type == 'QQ' ? 'select': ''" @click="changeContactWay('QQ')">QQ</div>
<div class="option" :class="contact_way.type == '微信' ? 'select': ''" @click="changeContactWay('微信')">微信</div>
<div class="option" :class="contact_way.type == '电话' ? 'select': ''" @click="changeContactWay('电话')">电话</div>
<div class="option" :class="contact_way.type == '邮件' ? 'select': ''" @click="changeContactWay('邮件')">邮件</div>
</div>
<input type="text" placeholder="联系方式(选填)" v-model="contact_way.content" :disabled="contact_way.type == 'none'"/>
<div class="label">图片上传(选填)</div>
<div class="img-box">
<div class="img-border" @click="uploadTrigger" v-if="!upload_file">
<input
id="upload_img"
type="file"
value
@change="uploadFile($event)"
style="display: none;"
/>
<icon class="camera" name="camera"></icon>
</div>
<div class="img-preview" v-show="upload_file">
<div class="img-delete" @click="deleteFile()">
<icon class="close-white" name="close-white"></icon>
</div>
<img id="imgPreview" src alt />
</div>
<div class="tips">
<p>图片最大为1M</p>
<p>当前{{upload_file?parseInt(upload_file.size/1024):'0'}}kb</p>
</div>
</div>
<div class="submit" @click="openSubmitDialog()">确认上传</div>
</div>
</div>
<FooterSpace></FooterSpace>
</div>
</template>
<script>
// @ is an alias to /src
import FooterSpace from "@/components/FooterSpace.vue";
import { mapState, mapActions } from "vuex";
import { addLAF, uploadPhoto } from "@/axios/api.js";
import { Loading } from "element-ui";
import { loginInterceptor } from "@/lib/utils.js";
import "lrz";
export default {
name: "LAFAdd",
data() {
return {
title: '',
content: '',
total_addr:'',
detail_addr:'',
contact_way:{
type: 'none',
content: ''
},
type:'',
upload_file: null
};
},
computed: {
...mapState([
"user_info",
"current_week",
"current_schedule",
"personalized",
"LAF_data"
])
},
methods: {
...mapActions([
"setLAFReflash"
]),
//
init() {
},
back() {
this.$router.go(-1);
},
//
uploadTrigger() {
let file = document.getElementById("upload_img");
file.click();
},
//
async uploadFile(e) {
let file = e.target.files[0]; //
if (!/\.(gif|jpg|jpeg|png|GIF|JPG|PNG)$/.test(e.target.value)) {
this.$message.error("图片类型必须是.gif,jpeg,jpg,png中的一种");
return false;
}
if (file) {
file = await lrz(file);
file = file.file;
let filename = e.target.files[0].name;
// filename = filename.length > 5 ? filename.slice(0, 5) : filename;
file = new File([file], filename);
}
if (file.size > 1024 * 1024 * 1) {
this.$message.error("图片大小不能超过 1MB!");
return false;
}
this.upload_file = file;
let img = document.getElementById("imgPreview");
img.src = URL.createObjectURL(file);
},
//
deleteFile() {
this.upload_file = null;
},
//
changeType(arg){
this.type = arg
},
//
changeTotalAddr(arg) {
this.total_addr = arg
},
//
changeContactWay(arg){
if(arg == 'none') {
this.contact_way.content = ''
}
this.contact_way.type = arg
},
//
judge() {
if((this.title = this.manageInput(this.title.trim())).length == 0) return '请填写物品名'
if((this.content = this.manageInput(this.content.trim())).length == 0) return '请填写物品描述'
if((this.detail_addr = this.manageInput(this.detail_addr.trim())).length == 0) return '请填写详细地址'
switch(this.contact_way.type) {
case 'none':
this.contact_way.content = ''
break;
case 'QQ':
if(!/[1-9][0-9]{4,10}/.test(this.contact_way.content)) return '请填写正确的QQ号';
break;
case '微信':
if((this.contact_way.content = this.manageInput(this.contact_way.content.trim())).length == 0) return "请填写正确的微信号";
break;
case '电话':
if(!/^1[3456789]\d{9}$/.test(this.contact_way.content)) return "请填写正确的电话号";
break;
case '邮件':
if(!/^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/.test(this.contact_way.content)) return "请填写正确的邮件地址";
break;
}
if(this.type == '') return '请选择类型'
if(this.total_addr == '') return '请选择区域'
return false
},
//
manageInput(value) {
//
value = value.replace(/\$/g, "");
value = value.replace(/\^/g, "");
return value;
},
//
openSubmitDialog(){
let judge
if(judge = this.judge()) {
this.$alert(judge, "警告", {
confirmButtonText: "阅!"
});
return
}
this.$prompt(
`您将上传失物招领信息,此操作实名制,请输入你的学号`,
"警告",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
inputPattern: /\d{7}W?\d{2}/,
inputErrorMessage: "请输入正确的学号"
}
)
.then(({ value }) => {
if(value == this.user_info.id) {
//
this.submit()
}else {
this.$message.error('输入学号有误请核对');
}
})
.catch(() => {
this.$message({
type: "info",
message: "取消输入"
});
});
},
async submit() {
let load = Loading.service({
background: "rgba(236,245,255,.7)",
target: document.querySelector(".LAFAdd")
});
let file_name = 'no_img.png'
let stop = false
if(this.upload_file) {
await uploadPhoto(this.upload_file).then(res => {
if(res.data.errcode !== 200) {
this.$message.error("图片上传失败,请重试");
console.log(res.data)
stop = true
}
else {
file_name = res.data.filename
}
}).catch(err => {
this.$message.error("图片上传失败,请重试");
console.log(err);
stop = true
})
}
//
if(stop) {
load.close();
return
}
let data = {
title: this.title,
content: this.content,
total_addr: this.total_addr,
detail_addr: this.detail_addr,
contact_way: this.contact_way,
type: this.type,
img_url: file_name,
create_time: new Date().getTime(),
user_info: {
user_cid: this.user_info.cid,
user_name: this.user_info.name,
user_id: this.user_info.id
},
close: 'false'
}
await addLAF(data).then(res=> {
if(res.data.errcode == 200) {
load.close()
this.$message({
message: "提交成功",
type: "success"
});
this.setLAFReflash([true, this])
this.back()
}
}).catch(err => {
load.close()
this.$message.error("提交失败,请重试");
console.log(err)
})
}
},
created() {
//
// loginInterceptor.call(this,"None",this.init)
},
mounted(){
//
},
components: {
FooterSpace
}
};
</script>
<style scoped lang="scss" type="text/scss">
@import "../../style/main";
.LAFAdd {
width: 100%;
max-width: 500px;
margin: 0 auto;
background-color: #f8f8f8;
min-height: 100%;
position: relative;
overflow: hidden;
header {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 1.2rem;
z-index: 100;
.w {
height: 1.2rem;
width: 100%;
max-width: 500px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;
background-image: $gradualLAF;
color: #fff;
position: relative;
.title-box {
font-size: 0.5rem;
}
.icon-box {
height: 1.2rem;
width: 1.2rem;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
.title-icon {
font-size: 0.6rem;
}
}
}
}
.main {
.card {
height: auto;
padding: 0.3rem 0.3rem 1rem 0.3rem;
box-sizing: border-box;
// padding-bottom:1rem;
width: 90%;
margin: 0 auto;
margin-top: 0.5rem;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
border: 1px solid #eee;
border: 1px solid #eee;
background: #fff;
border-radius: 0.15rem;
.icon-box {
text-align: center;
color: $main-color;
height: 1rem;
}
p {
text-align: center;
font-size: 0.4rem;
// font-weight: 600;
color: $main-color;
letter-spacing: 2px;
margin: .2rem 0;
}
input {
width: 100%;
height: 1rem;
font-size: 0.3rem;
outline-style: none;
background: #f4f9ff;
border: 1px #e1effd solid;
color: $main-color;
padding: 0 .3rem;
box-sizing: border-box;
border-radius: .15rem;
margin-bottom: .3rem;
}
::-webkit-input-placeholder {
/* Chrome/Opera/Safari */
color: #a4c5ed;
}
::-moz-placeholder {
/* Firefox 19+ */
color: #a4c5ed;
}
:-ms-input-placeholder {
/* IE 10+ */
color: #a4c5ed;
}
:-moz-placeholder {
/* Firefox 18- */
color: #a4c5ed;
}
textarea {
width: 100%;
background: #f4f9ff;
border: 1px #e1effd solid;
font-size: 0.3rem;
border-radius: .15rem;
padding: .3rem;
box-sizing: border-box;
color: $main-color;
height: 2.5rem;
}
.label {
color: $main-color;
font-size: .4rem;
margin-bottom: .3rem;
}
.addr-box, .contact-box, .type-box {
display: flex;
align-items: center;
justify-content: space-between;
.option {
height: .6rem;
width: 2rem;
line-height: .6rem;
font-size: .3rem;
text-align: center;
border: 1px #e1effd solid;
color:#a4c5ed;
background: #f4f9ff;
}
.select {
background: #cce6ff !important;
color: #0081ff;
border: 1px #cce6ff solid;
}
}
.type-box {
margin-bottom: .3rem;
}
.contact-box .option {
width: auto!important;
flex :1;
}
.img-box {
display: flex;
align-items: center;
justify-content: space-between;
.img-border {
box-sizing: border-box;
height: 2rem;
width: 2rem;
border: 2px $create-cramera-border-color solid;
border-radius: 0.1rem;
display: flex;
align-items: center;
justify-content: center;
.camera {
height: 0.8rem;
width: 0.8rem;
display: block;
margin: auto;
}
}
.img-preview {
height: 2rem;
width: 2rem;
border-radius: 0.1rem;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
position: relative;
img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.img-delete {
position: absolute;
top: 0;
right: 0;
height: 0.5rem;
width: 0.5rem;
background: #000;
opacity: 0.6;
display: flex;
align-items: center;
justify-content: center;
border-bottom-left-radius: 0.1rem;
.close-white {
height: 0.3rem;
width: 0.3rem;
}
}
}
.tips {
p {
font-size: .3rem;
}
}
}
.submit {
width: 5rem;
height: 1rem;
text-align: center;
line-height: 1rem;
margin: 1rem auto;
margin-bottom: 0;
font-size: .4rem;
letter-spacing: 2px;
color: #fff;
background: $main-color;
border-radius: .1rem;
}
}
.detail-card {
margin-top: 0;
padding-top: 1rem;
}
.link {
height:1.5rem;
width:75%;
// background: red;
margin: 0 auto;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
margin-top:-.5rem;
margin-bottom:-.5rem;
.link-item {
height:1.5rem;
width:.25rem;
position: relative;
.link-dote-top {
height:.25rem;
width:.25rem;
background: #b9d4f7;
/* background: #f7bdba; */
border-radius: 50%;
position: absolute;
top:0;
z-index:10;
}
.link-dote-bottom {
height:.25rem;
width: .25rem;
background: #b9d4f7;
/* background: #f7bdba; */
border-radius: 50%;
position: absolute;
bottom:0;
// left:10rpx;
z-index:10;
}
.link-line {
height:1.3rem;
width:.1rem;
position: absolute;
top:.1rem;
left:.075rem;
background: #e5eef9;
/* background: #fae7e6; */
z-index:11;
border-radius: .2rem;
}
}
}
}
}
</style>

View File

@ -1,487 +0,0 @@
<template>
<div class="LAFDetail">
<header>
<div class="w">
<div class="icon-box">
<i class="el-icon-back title-icon" @click="back()"></i>
</div>
<div class="title-box">详情</div>
<div class="icon-box del-box">
<i class="el-icon-delete title-icon" v-if="user_info.id == '180511307' ||user_info.id == '190521119'||user_info.id == '190511710'" @click="openDelLAF()"></i>
</div>
</div>
</header>
<div style="height: 1.2rem;"></div>
<div class="main">
<InfoCard :data="content"></InfoCard>
<Comment :content="content" :openInput="openInput"></Comment>
</div>
<div style="height: 1.3rem;"></div>
<footer v-if="show_footer">
<div class="footer-w">
<div class="comment" @click="openInput(-1, -1)">我要留言</div>
<div class="finish" v-if="content.contact_way.type!='none'" @click="openDialog()">联系发布者</div>
</div>
</footer>
<!-- 联系发布者弹窗 -->
<div class="dialog" v-if="show_contact" @touchmove.prevent>
<div class="w">
<div class="title">
联系方式
<div class="icon-box" @click="closeDialog()">
<i class="el-icon-close icon"></i>
</div>
</div>
<div class="dialog-main">
<p>
{{content.contact_way.type}}
<span>{{content.contact_way.content}}</span>
</p>
<div
class="copy-buttom"
v-clipboard:copy="content.contact_way.content"
v-clipboard:success="onCopyUrl"
v-clipboard:error="onErrorUrl"
>复制</div>
</div>
</div>
</div>
</div>
</template>
<script>
// @ is an alias to /src
import FooterSpace from "@/components/FooterSpace.vue";
import InfoCard from "./components/InfoCard.vue";
import Comment from "./components/Comment.vue";
import { mapState, mapActions } from "vuex";
import { getLAFDetail, comment, delLAF } from "@/axios/api.js";
import { Loading } from "element-ui";
import { formatDateTime, loginInterceptor } from "@/lib/utils.js";
export default {
name: "LAFDetail",
data() {
return {
content: {
contact_way: {
type: "none"
},
content: "XXXXXXXXXX",
img_url: "no_img.png",
title: "XXXXXXXX",
total_addr: "XXXXXX",
detail_addr: "XXXXXX",
type: "lost",
create_time: 1581515035078
},
show_footer: true,
show_contact: false
};
},
computed: {
...mapState([
"user_info"
])
},
methods: {
...mapActions([
"setLAFReflash"
]),
formatDateTime,
//
init() {
// let id = this.$route.params.item._id["$oid"];
// params
if (Object.keys(this.$route.params).length == 0) {
this.$router.go(-1);
return;
}
let id = this.$route.params.item._id["$oid"];
let type = this.$route.params.item.type;
this.getPageData(id, type);
},
//
getPageData(id, type) {
let load = Loading.service({
background: "rgba(236,245,255,.7)",
target: document.querySelector(".loading-box")
});
let data = {
id,
type
};
getLAFDetail(data)
.then(res => {
// console.log(res)
if (res.data.errcode == 200) {
//
this.content = JSON.parse(res.data.detail);
// console.log(this.content)
load.close();
} else {
//
load.close();
this.$message.error("服务器开小差了,请过段时间重试");
console.log(res.data);
this.back();
}
})
.catch(err => {
load.close();
this.$message.error("服务器开小差了,请过段时间重试");
console.log(err);
this.back();
});
},
back() {
this.$router.go(-1);
},
//
openInput(comment_index, reply_index) {
console.log(comment_index, reply_index);
this.show_footer = false;
this.$prompt(`请输入内容,为保证信息质量,该操作将实名制`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
inputPattern: /^[^\^\$\/\<\(\)]{3,}$/,
inputErrorMessage: "请勿输入特殊符号至少3个字,"
})
.then(({ value }) => {
this.show_footer = true;
this.submit(comment_index, reply_index, value);
})
.catch(() => {
this.show_footer = true;
this.$message({
type: "info",
message: "取消输入"
});
});
},
//
submit(comment_index, reply_index, value) {
let load = Loading.service({
background: "rgba(236,245,255,.7)",
target: document.querySelector(".loading-box")
});
//
// cid
//
var data = {
user_info: {
user_id: this.user_info.id,
user_name: this.user_info.name
},
time: new Date().getTime()
};
// id
var position = {
id: this.content._id["$oid"],
type: this.content.type
};
if (comment_index == -1) {
//
data.msg = value;
position.comment_type = 1;
} else {
//
if (reply_index == -1) {
//
data.msg = `@${this.content.comment[comment_index].user_info.user_name}${value}`;
position.comment_index = comment_index;
position.comment_type = 2;
} else {
//
data.msg = `@${this.content.comment[comment_index].reply[reply_index].user_info.user_name}${value}`;
position.comment_index = comment_index;
position.comment_type = 2;
}
}
comment(data, position)
.then(res => {
console.log(res);
if (res.data.errcode == 200) {
// ,
load.close();
this.$message({
type: "success",
message: `${position.comment_type == 1 ? "留言" : "回复"}成功`
});
this.getPageData(this.content._id["$oid"], this.content.type);
} else {
//
load.close();
this.$message.error(
`${position.comment_type == 1 ? "留言" : "回复"}失败,请重试`
);
}
})
.catch(err => {
load.close();
console.log(err);
this.$message.error(
`${position.comment_type == 1 ? "留言" : "回复"}失败,请重试`
);
});
},
//
openDelLAF() {
this.show_footer = false;
this.$prompt(`此操作将删除该记录,此操作实名制,请输入你的学号`, "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
inputPattern: /\d{7}W?\d{2}/,
inputErrorMessage: "请输入正确的学号"
})
.then(({ value }) => {
this.show_footer = true;
if (value == this.user_info.id) {
//
this.closeLAF();
} else {
this.$message.error("输入学号有误请核对");
}
})
.catch(() => {
this.show_footer = true;
this.$message({
type: "info",
message: "取消输入"
});
});
},
//
closeLAF() {
let load = Loading.service({
background: "rgba(236,245,255,.7)",
target: document.querySelector(".loading-box")
});
let data = {
id: this.content._id["$oid"],
type: this.content.type,
user_info: {
user_id: this.user_info.id,
user_name: this.user_info.name
}
};
delLAF(data)
.then(res => {
if (res.data.errcode == 200) {
//
load.close();
this.$message({
type: "success",
message: "恭喜,操作成功"
});
this.setLAFReflash([true, this]);
this.back();
} else {
//
load.close();
console.log(res.data);
this.$message.error("抱歉,操作失败");
this.setLAFReflash([true, this]);
}
})
.catch(err => {
//
load.close();
console.log(err);
this.$message.error("抱歉,操作失败");
this.setLAFReflash([true, this]);
});
},
//
openDialog() {
this.show_contact = true;
},
//
closeDialog() {
this.show_contact = false;
},
onCopyUrl(e) {
this.$message.success("复制成功!");
},
onErrorUrl(e) {
this.$message.success("复制失败!");
}
},
created() {
//
loginInterceptor.call(this,"None",this.init)
},
mounted(){
//
},
components: {
FooterSpace,
InfoCard,
Comment
}
};
</script>
<style scoped lang="scss" type="text/scss">
@import "../../style/main";
.LAFDetail {
width: 100%;
max-width: 500px;
margin: 0 auto;
background-color: #f8f8f8;
min-height: 100%;
position: relative;
overflow: hidden;
header {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 1.2rem;
z-index: 100;
.w {
height: 1.2rem;
width: 100%;
max-width: 500px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;
background-image: $gradualLAF;
color: #fff;
position: relative;
.title-box {
font-size: 0.5rem;
}
.icon-box {
height: 1.2rem;
width: 1.2rem;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
.title-icon {
font-size: 0.6rem;
}
}
.del-box {
right: 0;
left: auto;
.title-icon {
font-size: 0.5rem;
}
}
}
}
footer {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
z-index: 100;
.footer-w {
border-top: 1px #eee solid;
display: flex;
flex-direction: row;
height: 1.3rem;
width: 100%;
max-width: 500px;
margin: 0 auto;
font-size: 0.4rem;
line-height: 1.3rem;
.comment {
flex: 1;
text-align: center;
background: #fff;
color: $main-color;
}
.finish {
flex: 1;
text-align: center;
background: $main-color;
color: #fff;
}
}
}
.dialog {
position: fixed;
top: 0;
left: 0;
z-index: 101;
height: 100%;
width: 100%;
background: rgba(0, 0, 0, 0.4);
display: flex;
align-items: center;
justify-content: center;
.w {
width: 70%;
max-width: 350px;
height: 5rem;
background: #fff;
border-radius: 0.1rem;
overflow: hidden;
.title {
height: 1rem;
background-image: $gradualLAF;
font-size: 0.4rem;
text-align: center;
line-height: 1rem;
color: #fff;
position: relative;
.icon-box {
position: absolute;
top: 0;
right: 0;
width: 1rem;
height: 1rem;
display: flex;
align-items: center;
justify-content: center;
.icon {
font-size: 0.5rem;
}
}
}
.dialog-main {
height: 4rem;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
p {
margin-bottom: 0.2rem;
text-align: center;
font-size: 0.4rem;
span {
font-size: 0.4rem;
color: $main-color;
-moz-user-select: all;
-webkit-user-select: all;
-ms-user-select: all;
-khtml-user-select: all;
user-select: all;
}
}
.copy-buttom {
width: 40%;
margin: 0 auto;
margin-top: 0.5rem;
// background-image: $gradualLAF;
background: $main-color;
color: #fff;
font-size: 0.3rem;
text-align: center;
height: 0.7rem;
line-height: 0.7rem;
border-radius: 0.1rem;
}
}
}
}
}
</style>

View File

@ -1,309 +0,0 @@
<template>
<div class="LAFAdd">
<header>
<div class="w">
<div class="icon-box">
<i class="el-icon-back title-icon" @click="back()"></i>
</div>
<div class="title-box">检索</div>
</div>
</header>
<div style="height: 1.2rem;"></div>
<div class="search-warp">
<div class="search-box">
<i class="el-icon-search icon"></i>
<input type="text" placeholder="输入物品名" v-model="search_msg"/>
</div>
<div class="submit" @click='matchSearchContent()'>搜索</div>
</div>
<nav>
<div class="lost" :class="search_type == 'lost' ? 'select': ''" @click="changeNav('lost')">失物</div>
<div class="found" :class="search_type == 'found' ? 'select': ''" @click="changeNav('found')">招领</div>
</nav>
<div class="addr-box">
<div class="option" :class="search_addr == '长理东区' ? 'select': ''" @click="changeSearchAddr('长理东区')">长理东区</div>
<div class="option" :class="search_addr == '长理南区' ? 'select': ''" @click="changeSearchAddr('长理南区')">长理南区</div>
<div class="option" :class="search_addr == '长理西区' ? 'select': ''" @click="changeSearchAddr('长理西区')">长理西区</div>
</div>
<div class="main">
<p v-if="search_res[search_type][search_addr].length == 0">空空如也呢~{{has_search?'没有符合您要求的信息呢~':'快搜索一个试试看~'}}</p>
<div class="found-page" v-else>
<LAFCard :content="item" v-for="(item, i) in search_res[search_type][search_addr]" :key="i"></LAFCard>
</div>
</div>
<FooterSpace></FooterSpace>
</div>
</template>
<script>
// @ is an alias to /src
import FooterSpace from "@/components/FooterSpace.vue";
import { mapState, mapActions } from "vuex";
import { Loading } from "element-ui";
import { loginInterceptor } from "@/lib/utils.js";
import LAFCard from "./components/LAFCard.vue";
export default {
name: "LAFSearch",
data() {
return {
search_addr:'未选',
search_res:{'lost' : {'长理西区': [], '长理东区': [], '长理南区': [], '未选': []}, 'found': {'长理西区': [], '长理东区': [], '长理南区': [], '未选': []}},
search_type:'lost',
has_search: false,
current_res: [],
search_msg: ''
};
},
computed: {
...mapState([
"user_info",
"current_week",
"current_schedule",
"personalized",
"LAF_data"
])
},
methods: {
//
init() {
},
back() {
this.$router.go(-1);
},
changeSearchAddr(addr) {
if(this.search_addr == addr) this.search_addr = '未选'
else this.search_addr = addr
},
changeNav(type){
this.search_type = type
},
matchSearchContent(){
//
if(!this.search_msg.trim()) {
this.$message.error("请输入搜索内容");
return
}
this.has_search = true
let lost = this.LAF_data['lost']
let found = this.LAF_data['found']
this.search_res['lost'] = this.matchReg(lost)
this.search_res['found'] = this.matchReg(found)
this.$message.success("搜索完成");
},
//
generReg(val) {
let head = '(.*)('
let tail = ')(.*)'
let body = val.split('').join(')(.*)(')
return new RegExp(head + body + tail, 'i')
},
//
matchReg(data){
let west = []
let east = []
let south = []
let total = []
for (var i in data) {
if(this.generReg(this.search_msg).test(data[i].title) || this.generReg(this.search_msg).test(data[i].content)) {
switch(data[i].total_addr){
case '长理东区':
east.push(data[i]);
break
case '长理西区':
west.push(data[i]);
break
case '长理南区':
south.push(data[i]);
break
}
total.push(data[i])
}
}
return {'长理西区': west, '长理东区': east, '长理南区': south, '未选': total}
},
},
created() {
//
// loginInterceptor.call(this,"None",this.init)
},
mounted(){
//
},
components: {
FooterSpace,
LAFCard
}
};
</script>
<style scoped lang="scss" type="text/scss">
@import "../../style/main";
.LAFAdd {
width: 100%;
max-width: 500px;
margin: 0 auto;
background-color: #f8f8f8;
min-height: 100%;
position: relative;
overflow: hidden;
header {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 1.2rem;
z-index: 100;
.w {
height: 1.2rem;
width: 100%;
max-width: 500px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;
background-image: $gradualLAF;
color: #fff;
position: relative;
.title-box {
font-size: 0.5rem;
}
.icon-box {
height: 1.2rem;
width: 1.2rem;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
.title-icon {
font-size: 0.6rem;
}
}
}
}
.search-warp {
height: 1rem;
// background: red;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 0.3rem;
margin: 0.2rem 0;
.submit {
height: 0.7rem;
width: 1.5rem;
// background-image: linear-gradient(to right, #1be5d2, #5e75e5);
background-image: $gradualLAF;
border-radius: 0.5rem;
font-size: 0.3rem;
color: #fff;
line-height: 0.7rem;
text-align: center;
position: relative;
z-index: 1;
margin-left: 0.3rem;
}
.submit::before {
content: "";
display: block;
background: inherit;
filter: blur(0.1rem);
position: absolute;
width: 100%;
height: 100%;
top: 0.1rem;
left: 0.1rem;
opacity: 0.4;
transform-origin: 0 0;
border-radius: inherit;
transform: scale(1, 1);
z-index: -1;
}
.search-box {
width: 100%;
height: 0.7rem;
border-radius: 0.5rem;
background: rgb(241, 239, 239);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 0.3rem;
box-sizing: border-box;
.icon {
color: #989898;
font-size: 0.3rem;
}
input, p{
width: 100%;
height: 0.7rem;
line-height: .7rem;
border: none;
padding-left: 0.3rem;
font-size: 0.3rem;
background: rgb(241, 239, 239);
outline: none;
}
}
}
.addr-box, .contact-box, .type-box {
padding: 0 .3rem;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
margin-top: .3rem;
margin-bottom: .3rem;
.option {
height: .6rem;
width: 2rem;
line-height: .6rem;
font-size: .3rem;
text-align: center;
border: 1px #dec0ff solid;
color:#bc8eed;
background: #f6edff;
}
.select {
background: #e5ccff !important;
color: #ab64f6;
border: 1px #e5ccff solid;
}
}
nav {
height: 1rem;
display: flex;
align-items: center;
padding: 0 0.3rem;
div {
font-size: 0.4rem;
height: 0.7rem;
line-height: 0.7rem;
}
.lost {
margin-right: 1rem;
}
.select {
font-size: 0.5rem;
font-weight: 600;
border-bottom: 2px #ab64f6 solid;
}
}
.main > p {
font-size: .3rem;
margin-left: .3rem;
margin-top: .3rem;
color: #989898;
}
.main > div{
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 0.3rem;
box-sizing: border-box;
}
}
</style>

View File

@ -1,314 +0,0 @@
<template>
<div class="laf">
<header>
<div class="w">
<div class="icon-box" @click="reflash()">
<i class="el-icon-refresh icon"></i>
</div>
<div class="title-box">失物招领</div>
<div class="icon-box" @click="goToAdd()">
<i class="el-icon-plus icon"></i>
</div>
</div>
</header>
<div style="height: 1.2rem;"></div>
<div class="search-warp" @click='goToSearch()'>
<div class="search-box">
<i class="el-icon-search icon"></i>
<!-- <p>该功能开发中</p> -->
<!-- <input type="text" placeholder="输入物品名" /> -->
</div>
<div class="submit">搜索</div>
</div>
<nav>
<div class="lost" :class="page_type == 'lost' ? 'select': ''" @click="changeNav('lost')">失物</div>
<div class="found" :class="page_type == 'found' ? 'select': ''" @click="changeNav('found')">招领</div>
</nav>
<div class="main">
<p v-if="page_type == 'lost'? LAF_data.lost.length == 0 : LAF_data.found.length == 0">空空如也呢快点击右上角添加一个吧~</p>
<div class="lost-page" v-if="page_type == 'lost'">
<LAFCard :content="item" v-for="(item, i) in LAF_data.lost" :key="i"></LAFCard>
</div>
<div class="found-page" v-else>
<LAFCard :content="item" v-for="(item, i) in LAF_data.found" :key="i"></LAFCard>
</div>
</div>
<FooterSpace></FooterSpace>
</div>
</template>
<script>
// @ is an alias to /src
import FooterSpace from "@/components/FooterSpace.vue";
import LAFCard from "./components/LAFCard.vue";
import { mapState, mapActions } from "vuex";
import { getLAF } from "@/axios/api.js";
import { Loading } from "element-ui";
import { loginInterceptor } from "@/lib/utils.js";
export default {
name: "lost_and_found",
data() {
return {
page_type: "lost",
need_reflash: false
};
},
computed: {
...mapState([
"user_info",
"LAF_data",
'LAF_reflash'
]),
},
methods: {
...mapActions([
"setCurrentPage",
"setLAFData",
"setLAFReflash"
]),
//
init() {
this.getLAFData();
},
getLAFData() {
//
if (Object.keys(this.LAF_data).length != 0) {
let now = new Date().getTime(); //
if (
now - this.LAF_data.get_time < 1000 * 60 * 3 &&
!this.need_reflash && !this.LAF_reflash
) {
// 3
return;
}
}
let load = Loading.service({
background: "rgba(236,245,255,.7)",
target: document.querySelector(".laf")
});
getLAF().then(res => {
// console.log(res.data);
let data = res.data
let laf
if(data.lost.errcode == 200 && data.found.errcode == 200) {
//
laf = {
lost: JSON.parse(data.lost.arr),
found: JSON.parse(data.found.arr),
get_time: new Date().getTime()
}
// console.log(laf)
if(this.need_reflash) {
this.$message({
message: "数据更新成功",
type: "success"
});
}
} else {
//
laf = {
lost: [],
found: [],
get_time: new Date().getTime()
}
this.$message.error("数据更新失败,请联系管理员");
console.log(res.data)
}
this.setLAFData([laf, this]);
this.setLAFReflash([false, this]);
this.need_reflash = false;
load.close()
}).catch(err => {
console.log(err)
laf = {
lost: [],
found: [],
get_time: new Date().getTime()
}
this.$message.error("网络连接失败,请联系管理员");
this.setLAFData([laf, this]);
this.need_reflash = true;
load.close()
});
},
// nav
changeNav(type) {
this.page_type = type
},
reflash(){
//
if(this.need_reflash) return
this.need_reflash = true
this.getLAFData()
},
//
goToAdd(){
this.$router.push('/lafadd')
},
//
goToSearch(){
this.$router.push('/lafsearch')
}
},
created() {
},
mounted() {
this.init();
this.setCurrentPage(["laf", this]);
},
activated() {
this.setCurrentPage(["laf", this]);
},
components: {
FooterSpace,
LAFCard
}
};
</script>
<style scoped lang="scss" type="text/scss">
@import "../../style/main";
.laf {
width: 100%;
max-width: 500px;
margin: 0 auto;
background-color: #f8f8f8;
min-height: 100%;
position: relative;
overflow: hidden;
header {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 1.2rem;
z-index: 100;
.w {
height: 1.2rem;
width: 100%;
max-width: 500px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: space-between;
background-image: $gradualLAF;
color: #fff;
.title-box {
font-size: 0.5rem;
}
.icon-box {
height: 1.2rem;
width: 1.2rem;
display: flex;
align-items: center;
justify-content: center;
.icon {
font-size: .6rem;
}
}
}
}
.search-warp {
height: 1rem;
// background: red;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 0.3rem;
margin: 0.2rem 0;
.submit {
height: 0.7rem;
width: 1.5rem;
// background-image: linear-gradient(to right, #1be5d2, #5e75e5);
background-image: $gradualLAF;
border-radius: 0.5rem;
font-size: 0.3rem;
color: #fff;
line-height: 0.7rem;
text-align: center;
position: relative;
z-index: 1;
margin-left: 0.3rem;
}
.submit::before {
content: "";
display: block;
background: inherit;
filter: blur(0.1rem);
position: absolute;
width: 100%;
height: 100%;
top: 0.1rem;
left: 0.1rem;
opacity: 0.4;
transform-origin: 0 0;
border-radius: inherit;
transform: scale(1, 1);
z-index: -1;
}
.search-box {
width: 100%;
height: 0.7rem;
border-radius: 0.5rem;
background: rgb(241, 239, 239);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 0.3rem;
box-sizing: border-box;
.icon {
color: #989898;
font-size: 0.3rem;
}
input, p{
width: 100%;
height: 0.7rem;
line-height: .7rem;
border: none;
padding-left: 0.3rem;
font-size: 0.3rem;
background: rgb(241, 239, 239);
outline: none;
}
}
}
nav {
height: 1rem;
display: flex;
align-items: center;
padding: 0 0.3rem;
div {
font-size: 0.4rem;
height: 0.7rem;
line-height: 0.7rem;
}
.lost {
margin-right: 1rem;
}
.select {
font-size: 0.5rem;
font-weight: 600;
border-bottom: 2px #ab64f6 solid;
}
}
.main > p {
font-size: .3rem;
margin-left: .3rem;
margin-top: .3rem;
color: #989898;
}
.main > div{
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 0.3rem;
box-sizing: border-box;
}
}
</style>

View File

@ -1,121 +0,0 @@
<template>
<div class="comment-warp" v-if="content.comment && content.comment.length!=0">
<div class="comment-title"># 留言</div>
<div class="comment-item" v-for="(comment, c) in content.comment" :key="c">
<div class="comment-box">
<i class="el-icon-chat-dot-round label-icon-big"></i>
<div class="reply-btn">
<span @click="openInput(c, -1)">回复</span>
</div>
<div class="comment-detail-box">
<div class="comment-user-nick">{{comment.user_info.user_name}}</div>
<div class="comment-time">{{formatDateTime(comment.time)}}</div>
<div class="comment-msg">{{comment.msg}}</div>
</div>
</div>
<div class="reply-item" v-for="(reply, r) in comment.reply" :key="r">
<i class="el-icon-chat-line-round label-icon-small"></i>
<div class="reply-btn">
<span @click="openInput(c, r)">回复</span>
</div>
<div class="reply-detail-box">
<div class="reply-user-nick">{{reply.user_info.user_name}}</div>
<div class="reply-time">{{formatDateTime(reply.time)}}</div>
<div class="reply-msg">{{reply.msg}}</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapState, mapActions } from "vuex";
import { formatDateTime } from "@/lib/utils.js";
export default {
name: "comment",
props: ["content","openInput"],
data() {
return {};
},
computed: {},
methods: {
formatDateTime,
},
created() {}
};
</script>
<style scoped lang="scss" type="text/scss">
@import "../../../style/main";
.comment-warp {
padding: 0.5rem 0.4rem;
.comment-title {
font-size: 0.4rem;
}
.comment-item {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
border-bottom: 1px #eee solid;
.reply-btn {
position: absolute;
top: 0.1rem;
right: 0rem;
font-size: 0.3rem;
color: $main-color;
}
.comment-box {
display: flex;
align-items: flex-start;
justify-content: flex-start;
position: relative;
.label-icon-big {
font-size: .7rem;
color: $main-color;
}
.comment-detail-box {
margin-left: 0.2rem;
.comment-user-nick {
font-size: 0.4rem;
margin-bottom: 0.1rem;
}
.comment-time {
font-size: 0.3rem;
margin-bottom: 0.3rem;
color: $secondary-text;
}
.comment-msg {
font-size: 0.4rem;
}
}
}
.reply-item {
display: flex;
align-items: flex-start;
justify-content: flex-start;
position: relative;
margin-top: 0.3rem;
margin-left: 0.5rem;
.label-icon-small {
font-size: .5rem;
color: $main-color;
}
.reply-detail-box {
margin-left: 0.2rem;
.reply-user-nick {
font-size: 0.3rem;
margin-bottom: 0.1rem;
}
.reply-time {
font-size: 0.2rem;
margin-bottom: 0.1rem;
color: $secondary-text;
}
.reply-msg {
font-size: 0.3rem;
}
}
}
}
}
</style>

View File

@ -1,104 +0,0 @@
<template>
<div class="infocard-page">
<!-- 题头 -->
<div class="title">{{data.title}}</div>
<div class="time">{{show_time}}</div>
<!-- 内容 -->
<div class="content-text">{{data.content}}</div>
<div class="content-imgs-box" v-if="data.img_url != 'no_img.png'">
<div class="img-warp">
<img :src="imgaddr" alt/>
</div>
</div>
<div class="addr-box">
<div class="addr" style="color: #409EFF;background: #d9ecff;">{{data.total_addr}}</div>
<div class="addr" style="color: #67C23A;background: #e1f3d8;">{{data.detail_addr}}</div>
</div>
</div>
</template>
<script>
import { formatDateTime } from "@/lib/utils.js";
export default {
name: "infocard",
props: ["data"],
data: () => {
return {
};
},
computed: {
imgaddr: function() {
return "https://coc.powerrain.cn/api/" + "photo/show/" + this.data.img_url
},
show_time:function() {
return formatDateTime(new Date(parseInt(this.data.create_time)));
},
},
methods: {
},
created() {
}
};
</script>
<style scoped lang="scss" type="text/scss">
@import "../../../style/main";
.infocard-page {
/* border-bottom: 0.3rem #eee solid;
padding: 0.5rem 0.4rem; */
margin: .5rem .4rem;
border: 1px solid #eee;
padding: .3rem .3rem 0 .3rem;
border-radius: .1rem;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
background: #fff;
}
.title {
font-size: .5rem;
font-weight: 600;
margin: 0.3rem 0;
text-align: left;
}
.time {
font-size: 0.3rem;
text-align: left;
color: #909399;
height: 0.3rem;
line-height: 0.3rem;
}
.content-text {
font-size: 0.4rem;
text-align: left;
// text-indent: 1rem;
margin: 0.3rem 0;
}
.content-imgs-box {
display: flex;
align-items: center;
justify-content: space-between;
}
.content-imgs-box img {
display: block;
width: 100%;
object-fit: cover;
}
.addr-box {
height: 1rem;
margin: 0.1rem 0;
display: flex;
align-items: center;
justify-content: flex-start;
}
.addr-box .addr {
font-size: 0.3rem;
padding: 0.1rem 0.2rem;
background: red;
margin-right: 0.1rem;
}
</style>

View File

@ -1,82 +0,0 @@
<template>
<div class="content-box" @click="goToDetail()">
<img :src="imgaddr" alt />
<div class="text-box">
<div class="title">{{content.title.length >= 7? content.title.slice(0,7) + '...' :content.title}}</div>
<div class="time">{{show_time}}</div>
<div class="addr">
<i class="el-icon-location-information icon"></i>
<span>{{content.total_addr}}</span>
</div>
</div>
</div>
</template>
<script>
import { mapState, mapActions } from "vuex";
import { formatDateTime } from "@/lib/utils.js";
export default {
name: "LAFCard",
props: ["content"],
data() {
return {
}
},
computed: {
imgaddr: function() {
return (
"https://coc.powerrain.cn/api/" + "photo/show/" + this.content.img_url
);
},
show_time:function() {
return formatDateTime(new Date(parseInt(this.content.create_time)));
},
},
methods: {
//
goToDetail(){
this.$router.push({name: 'LAFDetail', params: {item: this.content}})
}
},
created() {}
};
</script>
<style scoped lang="scss" type="text/scss">
@import "../../../style/main";
.content-box {
width: 48%;
background: #fff;
border-radius: 0.2em;
overflow: hidden;
box-sizing: border-box;
margin-bottom: 0.3rem;
img {
height: 2rem;
width: 100%;
object-fit: cover;
}
.text-box {
padding: 0 0.3rem;
.title {
font-size: 0.4rem;
}
.time {
font-size: 0.3rem;
margin-top: 0.1rem;
color: #989898;
}
.addr {
font-size: 0.3rem;
display: flex;
align-items: center;
margin-top: 0.1rem;
margin-bottom: 0.3rem;
span {
margin-left: 0.1rem;
}
}
}
}
</style>

View File

@ -1,8 +1,8 @@
module.exports = {
productionSourceMap: false,
pwa: {
name: 'Co-Create',
// themeColor: '#e54d42',
name: 'Cherry',
themeColor: '#e54d42',
workboxOptions: {
skipWaiting: true
},