update basic sign in / sign out

This commit is contained in:
MaysWind
2020-10-19 01:54:24 +08:00
parent 769eb604bd
commit e92e4e6b2e
11 changed files with 274 additions and 25 deletions
+9 -2
View File
@@ -2483,6 +2483,14 @@
"integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==",
"dev": true
},
"axios": {
"version": "0.20.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz",
"integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==",
"requires": {
"follow-redirects": "^1.10.0"
}
},
"babel-eslint": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz",
@@ -5484,8 +5492,7 @@
"follow-redirects": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz",
"integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==",
"dev": true
"integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA=="
},
"for-in": {
"version": "1.0.2",
+1
View File
@@ -8,6 +8,7 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"axios": "^0.20.0",
"core-js": "^3.6.5",
"framework7": "^5.7.13",
"framework7-icons": "^3.0.1",
+1 -1
View File
@@ -8,4 +8,4 @@ export default {
'en': en,
'zh_Hans': zhHans
}
}
};
+26 -2
View File
@@ -4,9 +4,33 @@ export default {
'title': 'lightweight account book'
}
},
'error': {
'user id is invalid': 'User id is invalid',
'username is empty': 'Username is empty',
'email is empty': 'Email is empty',
'password is empty': 'Password is empty',
'user not found': 'User not found',
'password is wrong': 'Password is wrong',
'username already exists': 'Username already exists',
'email already exists': 'Email already exists',
'login name is invalid': 'Login name is invalid',
'login name or password is invalid': 'Login name or password is invalid',
'login name or password is wrong': 'Login name or password is wrong'
},
'Home': 'Home',
'Journals': 'Journals',
'Accounts': 'Accounts',
'Charts': 'Charts',
'Settings': 'Settings'
}
'Settings': 'Settings',
'Back': 'Back',
'Username': 'Username',
'Username or Email': 'Username or Email',
'Password': 'Password',
'Log In': 'Log In',
'Don\'t have an account?': 'Don\'t have an account?',
'Sign up': 'Sign up',
'Have problem with login?': 'Have problem with login?',
'Forget Password': 'Forget Password',
'Unable to login': 'Unable to login',
'Logout': 'Logout'
};
+26 -2
View File
@@ -4,9 +4,33 @@ export default {
'title': 'lab 轻记账'
}
},
'error': {
'user id is invalid': '用户ID无效',
'username is empty': '用户名为空',
'email is empty': '电子邮箱为空',
'password is empty': '密码为空',
'user not found': '找不到该用户',
'password is wrong': '密码错误',
'username already exists': '用户名已经存在',
'email already exists': '邮箱已经存在',
'login name is invalid': '登录名无效',
'login name or password is invalid': '登录名或密码无效',
'login name or password is wrong': '登录名或密码错误'
},
'Home': '首页',
'Journals': '流水',
'Accounts': '账户',
'Charts': '图表',
'Settings': '设置'
}
'Settings': '设置',
'Back': '返回',
'Username': '用户名',
'Username or Email': '用户名或注册邮箱',
'Password': '密码',
'Log In': '登录',
'Don\'t have an account?': '还没有账号?',
'Sign up': '注册',
'Have problem with login?': '登录遇到问题?',
'Forget Password': '找回密码',
'Unable to login': '无法登录',
'Logout': '退出登录'
};
+27
View File
@@ -0,0 +1,27 @@
import axios from 'axios';
import userState from "./userstate.js";
axios.defaults.baseURL = '/api';
axios.interceptors.request.use(config => {
const token = userState.getToken();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
}, error => {
return Promise.reject(error);
});
axios.interceptors.response.use(response => {
return response;
}, error => {
return Promise.reject(error);
});
export default {
authorize: (params) => {
return axios.post('authorize.json', params);
}
};
+24
View File
@@ -0,0 +1,24 @@
const tokenLocalStorageKey = 'UserToken';
function getToken() {
return localStorage.getItem(tokenLocalStorageKey);
}
function isUserLogined() {
return !!getToken();
}
function updateToken(token) {
return localStorage.setItem(tokenLocalStorageKey, token);
}
function clearToken() {
return localStorage.removeItem(tokenLocalStorageKey);
}
export default {
getToken,
isUserLogined,
updateToken,
clearToken
};
+78
View File
@@ -0,0 +1,78 @@
<template>
<f7-page no-toolbar no-navbar no-swipeback login-screen>
<f7-login-screen-title>{{ $t('global.app.title') }}</f7-login-screen-title>
<f7-list form>
<f7-list-input
type="text"
clear-button
validate
required
:label="$t('Username')"
:placeholder="$t('Username or Email')"
:value="username"
@input="username = $event.target.value"
></f7-list-input>
<f7-list-input
type="password"
clear-button
validate
required
:label="$t('Password')"
:placeholder="$t('Password')"
:value="password"
@input="password = $event.target.value"
></f7-list-input>
</f7-list>
<f7-list>
<f7-list-button @click="login">{{ $t('Log In') }}</f7-list-button>
<f7-block-footer>
<span v-t="'Don\'t have an account?'"></span>&nbsp;
<f7-link href="/signup">{{ $t('Sign up') }}</f7-link>
<br/>
<span v-t="'Have problem with login?'"></span>&nbsp;
<f7-link href="/forget-pwd">{{ $t('Forget Password') }}</f7-link>
</f7-block-footer>
</f7-list>
</f7-page>
</template>
<script>
import services from '../../common/services.js'
import userState from '../../common/userstate.js'
export default {
data() {
return {
username: '',
password: ''
};
},
methods: {
login() {
const self = this
const app = self.$f7
const router = self.$f7router
services.authorize({
loginName: self.username,
password: self.password
}).then(response => {
const data = response.data
if (data && data.success && data.result && typeof(data.result) === 'string') {
userState.updateToken(data.result)
router.navigate('/')
} else {
app.dialog.alert(self.$i18n.t('Unable to login'))
}
}).catch(error => {
if (error.response && error.response.data && error.response.data.errorMessage) {
app.dialog.alert(self.$i18n.t(`error.${error.response.data.errorMessage}`))
} else {
app.dialog.alert(self.$i18n.t('Unable to login'))
}
})
}
}
};
</script>
+24
View File
@@ -0,0 +1,24 @@
<template>
<f7-page name="home">
<f7-navbar :title="$t('Settings')" :back-link="$t('Back')"></f7-navbar>
<f7-list>
<f7-list-button @click="logout">{{ $t('Logout') }}</f7-list-button>
</f7-list>
</f7-page>
</template>
<script>
import userState from '../../common/userstate.js';
export default {
methods: {
logout() {
const self = this;
const router = self.$f7router;
userState.clearToken();
router.navigate('/');
}
}
};
</script>
+24 -12
View File
@@ -1,21 +1,33 @@
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import Framework7 from 'framework7/framework7.esm.bundle.js'
import Framework7Vue from 'framework7-vue/framework7-vue.esm.bundle.js'
import 'framework7/css/framework7.bundle.css'
import 'framework7-icons';
import './assets/css/custom.css'
import Vue from 'vue';
import VueI18n from 'vue-i18n';
import axios from 'axios';
import Framework7 from 'framework7/framework7.esm.bundle.js';
import Framework7Vue from 'framework7-vue/framework7-vue.esm.bundle.js';
Vue.use(VueI18n)
Framework7.use(Framework7Vue);
import 'framework7/css/framework7.bundle.css';
import 'framework7-icons';
import './assets/css/custom.css';
import i18nOptions from '../common/i18n.js';
import App from './App.vue'
import App from './App.vue';
const i18n = new VueI18n(i18nOptions)
Vue.use(VueI18n);
Framework7.use(Framework7Vue);
const i18n = new VueI18n(i18nOptions);
Vue.prototype.languages = {
setI18nLanguage: lang => {
i18n.locale = lang;
axios.defaults.headers.common['Accept-Language'] = lang;
document.querySelector('html').setAttribute('lang', lang);
return lang;
}
}
new Vue({
el: '#app',
i18n: i18n,
render: h => h(App),
})
});
+34 -6
View File
@@ -1,7 +1,24 @@
import MainPage from './components/Main.vue'
import MainPageHomeTab from './components/main/Home.vue'
import userState from "../common/userstate.js";
const router = [
import MainPage from './components/Main.vue';
import MainPageHomeTab from './components/main/Home.vue';
import LoginPage from './components/Login.vue';
import SettingsPage from './components/Settings.vue';
function checkLogin(to, from, resolve, reject) {
const router = this;
if (userState.isUserLogined()) {
resolve();
return;
}
reject();
router.navigate('/login');
}
const routes = [
{
path: '/',
component: MainPage,
@@ -10,13 +27,24 @@ const router = [
path: '/',
id: 'main-tab-home',
component: MainPageHomeTab,
beforeEnter: checkLogin
}
]
],
beforeEnter: checkLogin
},
{
path: '/login',
component: LoginPage
},
{
path: '/settings',
component: SettingsPage,
beforeEnter: checkLogin
},
{
path: '(.*)',
redirect: '/'
}
]
];
export default router
export default routes;