canary_fe/src/views/Settings/Settings.vue
2020-09-01 23:56:14 +08:00

434 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="account">
<md-app md-waterfall md-mode="fixed">
<md-app-toolbar class="md-primary toolbar">
<div class="md-toolbar-section-start">
<md-button class="md-icon-button" @click="back()"><md-icon>arrow_back</md-icon></md-button>
<h3 class="md-title" style="flex: 1">{{ lang.title }}</h3>
</div>
</md-app-toolbar>
<md-app-content>
<v-touch @swiperight="back()" :swipe-options="{ direction: 'horizontal' }">
<div ref="list_placeholder" style="height: 54px;"></div>
<md-list>
<md-subheader class="md-primary">{{ lang.subheader[0] }}</md-subheader>
<md-list-item @click="openResetDialog('account')">
<md-icon>person</md-icon>
<span class="md-list-item-text">{{ lang.reset_list[0] }}</span>
<md-progress-spinner v-if="account_loading" :md-diameter="22" :md-stroke="3" md-mode="indeterminate"></md-progress-spinner>
</md-list-item>
<md-list-item @click="openResetDialog('codebook')">
<md-icon>format_align_left</md-icon>
<span class="md-list-item-text">{{ lang.reset_list[1] }}</span>
<md-progress-spinner v-if="codebook_loading" :md-diameter="22" :md-stroke="3" md-mode="indeterminate"></md-progress-spinner>
</md-list-item>
<md-list-item @click="openResetDialog('application')">
<md-icon>layers</md-icon>
<span class="md-list-item-text">{{ lang.reset_list[2] }}</span>
<md-progress-spinner v-if="application_loading" :md-diameter="22" :md-stroke="3" md-mode="indeterminate"></md-progress-spinner>
</md-list-item>
<md-list-item @click="open_dialog">
<md-icon>vpn_key</md-icon>
<span class="md-list-item-text">{{ lang.reset_list[3] }}</span>
</md-list-item>
<md-divider></md-divider>
<md-subheader class="md-primary">{{ lang.subheader[1] }}</md-subheader>
<md-list-item>
<md-icon>format_color_text</md-icon>
<span class="md-list-item-text">{{ lang.option_list[0] }}</span>
<md-switch v-model="is_chinese" class="md-primary"></md-switch>
</md-list-item>
<md-list-item>
<md-icon>brightness_6</md-icon>
<span class="md-list-item-text">{{ lang.option_list[1] }}</span>
<md-switch v-model="is_dark_mode" class="md-primary"></md-switch>
</md-list-item>
<md-list-item>
<md-icon>update</md-icon>
<md-field>
<label for="expired_time">{{ lang.option_list[2] }}</label>
<md-select v-model="expired_time" name="expired_time" id="expired_time">
<md-option value="300000">5 min</md-option>
<md-option value="600000">10 min</md-option>
<md-option value="900000">15 min</md-option>
<md-option :value="Number.MAX_SAFE_INTEGER">{{ lang.expired_time }}</md-option>
</md-select>
</md-field>
</md-list-item>
</md-list>
<md-dialog-prompt
:md-active.sync="reset_main_pwd_active"
v-model="new_main_pwd"
:md-title="lang.dialog.title"
md-input-maxlength="30"
:md-input-placeholder="lang.dialog.placeholder"
:md-confirm-text="lang.dialog.confirm"
:md-cancel-text="lang.dialog.cancel"
@md-confirm="resetPwd"
/>
<md-dialog-confirm
:md-active.sync="reset_confirm"
:md-title="lang.reset_dialog.title"
:md-content="lang.reset_dialog.content"
:md-confirm-text="lang.reset_dialog.confirm"
:md-cancel-text="lang.reset_dialog.cancel"
@md-cancel="reset_confirm = false"
@md-confirm="resetStart"
/>
<md-snackbar md-position="center" :md-active.sync="show_snackbar" md-persistent>
<span>{{ snakebar_msg }}</span>
</md-snackbar>
</v-touch>
</md-app-content>
</md-app>
</div>
</template>
<script>
// @ is an alias to /src
import { mapState, mapActions } from 'vuex';
import { encrypt, decrypt, encryptMainCode, decryptMainCode } from '@/utils/aes.js';
import { login, activation, syncLocal, syncCloud } from '@/axios/api.js';
import { lang } from '@/utils/language.js';
import { setHtmlFontSize } from '@/utils/px2rem.js';
export default {
name: 'Add',
data() {
return {
// 重置loading
account_loading: false,
codebook_loading: false,
application_loading: false,
reset_main_pwd_active: false,
new_main_pwd: '',
reset_active: false,
// 设置状态
is_chinese: false,
is_dark_mode: false,
// 过期时间 300000 5分钟
expired_time: 300000,
// snackbar
show_snackbar: false,
snakebar_msg: '',
// 初始化完成状态
has_init: false,
lang: '',
clientHeight: '',
// 重置确认
reset_confirm: false,
reset_type: ''
};
},
computed: {
...mapState(['user_infos', 'row_data', 'row_pwd', 'settings'])
},
methods: {
...mapActions(['setUserInfo', 'setRowData', 'setRowPwd', 'setSettings']),
// 修改md-app的最小高度
changeFixed(clientHeight) {
//动态修改样式
// console.log(clientHeight);
// window.document.getElementsByClassName('md-content')[0].style.minHeight = clientHeight + 'px';
this.$refs.list_placeholder.parentNode.parentNode.style.maxHeight = clientHeight + 'px';
this.$refs.list_placeholder.parentNode.style.minHeight = clientHeight - 32 + 'px';
window.document.documentElement.setAttribute('data-theme', this.settings.is_dark_mode ? 'dark' : 'light');
},
// 初始化
init() {
// 刷新vuex
this.$store.replaceState(Object.assign(this.$store.state, JSON.parse(localStorage.getItem('storeState'))));
// 判断有无用户密码
if (Object.keys(this.row_pwd).length != 0) {
// 有密码,已经输入过了
let now = new Date().getTime();
if (now - this.row_pwd.create_time < this.settings.expired_time) {
// 上次写入时间距离现在在(默认五分钟)之内
// 初始化本页信息
this.is_chinese = this.settings.is_chinese;
this.is_dark_mode = this.settings.is_dark_mode;
this.expired_time = this.settings.expired_time;
this.initLanguage();
// 设置flag
setTimeout(
function() {
this.has_init = true;
console.log('本页信息覆写完成');
}.bind(this),
10
);
} else {
// 密码超时
this.turnToHome('密码超时');
}
} else {
// 没有密码
this.turnToHome('无密码');
}
},
// 配置语言
initLanguage() {
if (this.settings.is_chinese) {
this.lang = lang().settings.CHS;
} else {
this.lang = lang().settings.EN;
}
console.log('语言配置完成');
},
//返回上一页
back() {
// 重置处理拦截器
if (this.reset_active) {
return;
}
this.$router.go(-1);
},
// 强制返回Home
turnToHome(msg) {
console.log(msg);
this.$router.replace('/');
},
// 重置账户
resetAccount(need_loading = true) {
this.reset_active = true;
if (need_loading) {
this.account_loading = true;
setTimeout(
function() {
this.account_loading = false;
this.snakebar_msg = this.lang.snakebar_msg.reset_account;
this.show_snackbar = true;
}.bind(this),
1000
);
}
// 初始化用户信息
let user_infos = {
user_name: 'A Little Canary',
cid: 'Codebook',
row_login_pwd: '',
drivce: this.user_infos.drivce,
cloud_drivce: this.settings.is_chinese ? '暂无' : 'unknown',
update_time: new Date().getTime()
};
this.setUserInfo([user_infos, this]);
console.log('用户信息覆写完成');
this.reset_active = false;
},
// 重置密码本
resetCodebook(need_loading = true) {
this.reset_active = true;
if (need_loading) {
this.codebook_loading = true;
setTimeout(
function() {
this.codebook_loading = false;
this.snakebar_msg = this.lang.snakebar_msg.reset_codebook;
this.show_snackbar = true;
}.bind(this),
1000
);
}
this.setRowData(['', this]);
console.log('密码本覆写完成');
this.reset_active = false;
},
// 重置整个项目
resetApplication() {
this.application_loading = true;
this.reset_active = true;
this.resetAccount(false);
this.resetCodebook(false);
this.setRowPwd(['', this]);
console.log('主密码覆写完成');
let settings = {
is_chinese: true,
is_dark_mode: false,
expired_time: 300000
};
this.setSettings([settings, this]);
console.log('个性化设置覆写完成');
this.reset_active = false;
this.application_loading = false;
this.turnToHome('项目重置完成');
},
//覆写个性化设置
resetSettings() {
let settings = {
is_chinese: this.is_chinese,
is_dark_mode: this.is_dark_mode,
expired_time: this.expired_time
};
this.setSettings([settings, this]);
console.log('个性化设置覆写完成');
if (this.settings.is_chinese) {
this.lang = lang().settings.CHS;
} else {
this.lang = lang().settings.EN;
}
window.document.documentElement.setAttribute('data-theme', this.settings.is_dark_mode ? 'dark' : 'light');
console.log('语言配置完成');
this.snakebar_msg = this.lang.snakebar_msg.reset_settings;
this.show_snackbar = true;
},
open_dialog() {
this.reset_main_pwd_active = true;
},
resetPwd(new_main_pwd) {
// 空内容拦截器
if (!new_main_pwd.trim()) {
this.snakebar_msg = this.lang.snakebar_msg.reset_pwd_failed;
this.show_snackbar = true;
}
// 判断有无密码本
if (this.row_data) {
// 解密主密码
let main_code_decrpt = decryptMainCode(this.row_pwd.main_code);
let data_decrypt;
// 解密密码本
try {
data_decrypt = decrypt(main_code_decrpt, this.row_data);
} catch (e) {
// 不正确
// 跳转到解锁界面
console.log(e);
this.turnToHome('密码错误');
return;
}
let data_list = JSON.parse(data_decrypt);
let data_list_aes = encrypt(new_main_pwd, data_list);
this.setRowData([data_list_aes, this]);
console.log('密码本密码修改成功,覆写完成')
}
let main_code_aes = encryptMainCode(new_main_pwd);
let row_pwd = {
main_code: main_code_aes,
create_time: new Date().getTime()
};
this.setRowPwd([row_pwd, this]);
this.snakebar_msg = this.lang.snakebar_msg.reset_pwd_successful;
this.show_snackbar = true;
},
// 打开重置的警告提醒
openResetDialog(type) {
this.reset_confirm = true;
this.reset_type = type
},
// 提醒完成点击确定
resetStart() {
console.log('用户点击继续,重置开始')
switch(this.reset_type) {
case 'account':
this.resetAccount();
break
case 'codebook':
this.resetCodebook();
break
case 'application':
this.resetApplication();
break
default:
return
}
this.reset_type = ''
}
},
created() {
this.lang = lang().settings.CHS;
console.log('临时语言系统加载完成');
this.init();
},
mounted() {
// 获取浏览器可视区域高度
this.clientHeight = `${document.documentElement.clientHeight}`;
//document.body.clientWidth;
window.onresize = function temp() {
this.clientHeight = `${document.documentElement.clientHeight}`;
setHtmlFontSize();
}.bind(this);
},
watch: {
// 如果 `clientHeight` 发生改变,这个函数就会运行
clientHeight: function() {
this.changeFixed(this.clientHeight);
},
// 如果 `is_chinese` 发生改变,就会执行设置函数
is_chinese: function() {
if (this.has_init) this.resetSettings();
},
// 如果 `is_dark_mode` 发生改变,就会执行设置函数
is_dark_mode: function() {
if (this.has_init) this.resetSettings();
},
// 如果 `expired_time` 发生改变,就会执行设置函数
expired_time: function() {
if (this.has_init) this.resetSettings();
}
},
beforeDestroy() {},
components: {}
};
</script>
<style scoped lang="scss" type="text/scss">
@import '../../style/main';
.account {
width: 100%;
min-height: 100%;
background: #fff;
.expand {
width: 100%;
margin: 0 !important;
min-height: 1.2rem !important;
margin-top: 0.5rem !important;
}
.time-content {
text-align: right !important;
}
.loading-box {
position: absolute;
right: 50%;
top: 50%;
margin-right: -11px;
margin-top: -11px;
}
.toolbar {
position: fixed !important;
}
}
</style>
<!--
本页计划内容
重置账户
重置密码本
重置应用
修改密码本解密密码
-----------
设置语言
设置过期时间
黑暗模式再议
-->