mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-14 06:57:35 +08:00
update basic sign in / sign out
This commit is contained in:
Generated
+9
-2
@@ -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",
|
||||
|
||||
@@ -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
@@ -8,4 +8,4 @@ export default {
|
||||
'en': en,
|
||||
'zh_Hans': zhHans
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
+26
-2
@@ -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'
|
||||
};
|
||||
|
||||
@@ -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': '退出登录'
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
@@ -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>
|
||||
<f7-link href="/signup">{{ $t('Sign up') }}</f7-link>
|
||||
<br/>
|
||||
<span v-t="'Have problem with login?'"></span>
|
||||
<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>
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user