mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-19 17:24:26 +08:00
support changing language in login page, add local verification in login page, modify text in login page, add tips when requesting backend api too slow
This commit is contained in:
+97
-6
@@ -1,11 +1,102 @@
|
|||||||
import en from './langs/en.js'
|
import en from './langs/en.js'
|
||||||
import zhHans from './langs/zh_Hans.js'
|
import zhHans from './langs/zh_Hans.js'
|
||||||
|
|
||||||
export default {
|
const defaultLanguage = 'en';
|
||||||
locale: 'en',
|
|
||||||
fallbackLocale: 'en',
|
const allLanguages = {
|
||||||
messages: {
|
'en': {
|
||||||
'en': en,
|
name: 'English',
|
||||||
'zh_Hans': zhHans
|
displayName: 'English',
|
||||||
|
content: en
|
||||||
|
},
|
||||||
|
'zh-Hans': {
|
||||||
|
name: 'Simplified Chinese',
|
||||||
|
displayName: '简体中文',
|
||||||
|
aliases: ['zh-CHS', 'zh-CN', 'zh-SG'],
|
||||||
|
content: zhHans
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const i18nOptions = {
|
||||||
|
locale: defaultLanguage,
|
||||||
|
fallbackLocale: defaultLanguage,
|
||||||
|
formatFallbackMessages: true,
|
||||||
|
messages: (function () {
|
||||||
|
const messages = {};
|
||||||
|
|
||||||
|
for (let locale in allLanguages) {
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(allLanguages, locale)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const lang = allLanguages[locale];
|
||||||
|
messages[locale] = lang.content;
|
||||||
|
}
|
||||||
|
|
||||||
|
return messages;
|
||||||
|
})()
|
||||||
|
};
|
||||||
|
|
||||||
|
function getAllLanguages() {
|
||||||
|
return allLanguages;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLanguage(locale) {
|
||||||
|
return allLanguages[locale];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLocaleFromLanguageAlias(alias) {
|
||||||
|
for (let locale in allLanguages) {
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(allLanguages, locale)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const lang = allLanguages[locale];
|
||||||
|
const aliases = lang.aliases;
|
||||||
|
|
||||||
|
if (!aliases || aliases.length < 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < aliases.length; i++) {
|
||||||
|
if (aliases[i] === alias) {
|
||||||
|
return locale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDefaultLanguage() {
|
||||||
|
if (!window || !window.navigator) {
|
||||||
|
return defaultLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
let browserLocale = window.navigator.browserLanguage || window.navigator.language;
|
||||||
|
|
||||||
|
if (!browserLocale) {
|
||||||
|
return defaultLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!allLanguages[browserLocale]) {
|
||||||
|
const locale = getLocaleFromLanguageAlias(browserLocale);
|
||||||
|
|
||||||
|
if (locale) {
|
||||||
|
browserLocale = locale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!allLanguages[browserLocale]) {
|
||||||
|
return defaultLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
return browserLocale;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
i18nOptions,
|
||||||
|
getAllLanguages,
|
||||||
|
getLanguage,
|
||||||
|
getDefaultLanguage
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
'global': {
|
'global': {
|
||||||
'app': {
|
'app': {
|
||||||
'title': 'lightweight account book'
|
'title': 'lab app'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'error': {
|
'error': {
|
||||||
@@ -28,9 +28,10 @@ export default {
|
|||||||
'Password': 'Password',
|
'Password': 'Password',
|
||||||
'Log In': 'Log In',
|
'Log In': 'Log In',
|
||||||
'Don\'t have an account?': 'Don\'t have an account?',
|
'Don\'t have an account?': 'Don\'t have an account?',
|
||||||
'Sign up': 'Sign up',
|
'Create an account': 'Create an account',
|
||||||
'Have problem with login?': 'Have problem with login?',
|
'Forget Password?': 'Forget Password?',
|
||||||
'Forget Password': 'Forget Password',
|
'Please input username': 'Please input username',
|
||||||
|
'Please input password': 'Please input password',
|
||||||
'Unable to login': 'Unable to login',
|
'Unable to login': 'Unable to login',
|
||||||
'Logout': 'Logout'
|
'Logout': 'Logout'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,9 +28,10 @@ export default {
|
|||||||
'Password': '密码',
|
'Password': '密码',
|
||||||
'Log In': '登录',
|
'Log In': '登录',
|
||||||
'Don\'t have an account?': '还没有账号?',
|
'Don\'t have an account?': '还没有账号?',
|
||||||
'Sign up': '注册',
|
'Create an account': '创建新账号',
|
||||||
'Have problem with login?': '登录遇到问题?',
|
'Forget Password?': '找回密码?',
|
||||||
'Forget Password': '找回密码',
|
'Please input username': '请输入用户名',
|
||||||
|
'Please input password': '请输入密码',
|
||||||
'Unable to login': '无法登录',
|
'Unable to login': '无法登录',
|
||||||
'Logout': '退出登录'
|
'Logout': '退出登录'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
const settingsLocalStorageKey = 'lab_user_settings';
|
||||||
|
const defaultSettings = {
|
||||||
|
lang: 'en'
|
||||||
|
};
|
||||||
|
|
||||||
|
function getOriginalSettings() {
|
||||||
|
try {
|
||||||
|
const storageData = localStorage.getItem(settingsLocalStorageKey) || '{}';
|
||||||
|
return JSON.parse(storageData);
|
||||||
|
} catch (ex) {
|
||||||
|
console.warn('settings in local storage is invalid', ex);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFinalSettings() {
|
||||||
|
return Object.assign({}, defaultSettings, getOriginalSettings());
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSettings(settings) {
|
||||||
|
const storageData = JSON.stringify(settings);
|
||||||
|
return localStorage.setItem(settingsLocalStorageKey, storageData);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOriginalOption(key) {
|
||||||
|
return getOriginalSettings()[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
function setOption(key, value) {
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(defaultSettings, key)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const settings = getFinalSettings();
|
||||||
|
settings[key] = value;
|
||||||
|
|
||||||
|
return setSettings(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
getLanguage: () => getOriginalOption('lang'),
|
||||||
|
setLanguage: value => setOption('lang', value)
|
||||||
|
};
|
||||||
@@ -27,51 +27,103 @@
|
|||||||
<f7-list-button @click="login">{{ $t('Log In') }}</f7-list-button>
|
<f7-list-button @click="login">{{ $t('Log In') }}</f7-list-button>
|
||||||
<f7-block-footer>
|
<f7-block-footer>
|
||||||
<span v-t="'Don\'t have an account?'"></span>
|
<span v-t="'Don\'t have an account?'"></span>
|
||||||
<f7-link href="/signup">{{ $t('Sign up') }}</f7-link>
|
<f7-link href="/signup">{{ $t('Create an account') }}</f7-link>
|
||||||
<br/>
|
<br/>
|
||||||
<span v-t="'Have problem with login?'"></span>
|
<f7-link href="/forget-pwd">{{ $t('Forget Password?') }}</f7-link>
|
||||||
<f7-link href="/forget-pwd">{{ $t('Forget Password') }}</f7-link>
|
</f7-block-footer>
|
||||||
|
<f7-block-footer>
|
||||||
</f7-block-footer>
|
</f7-block-footer>
|
||||||
</f7-list>
|
</f7-list>
|
||||||
|
<f7-button small popover-open=".popover-menu">{{ currentLanguageName }}</f7-button>
|
||||||
|
<f7-popover class="popover-menu">
|
||||||
|
<f7-list>
|
||||||
|
<f7-list-item
|
||||||
|
link="#" popover-close
|
||||||
|
v-for="(lang, locale) in allLanguages" :key="locale"
|
||||||
|
:title="lang.displayName"
|
||||||
|
@click="changeLanguage(locale)"
|
||||||
|
></f7-list-item>
|
||||||
|
</f7-list>
|
||||||
|
</f7-popover>
|
||||||
</f7-page>
|
</f7-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import services from '../../common/services.js'
|
import services from '../../common/services.js'
|
||||||
import userState from '../../common/userstate.js'
|
import userState from '../../common/userstate.js'
|
||||||
|
import i18n from '../../common/i18n.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
username: '',
|
username: '',
|
||||||
password: ''
|
password: '',
|
||||||
|
allLanguages: i18n.getAllLanguages()
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
currentLanguageName() {
|
||||||
|
const currentLocale = this.$i18n.locale;
|
||||||
|
let lang = i18n.getLanguage(currentLocale);
|
||||||
|
|
||||||
|
if (!lang) {
|
||||||
|
lang = i18n.getLanguage(i18n.getDefaultLanguage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return lang.displayName;
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
login() {
|
login() {
|
||||||
const self = this
|
const self = this;
|
||||||
const app = self.$f7
|
const app = self.$f7;
|
||||||
const router = self.$f7router
|
const router = self.$f7router;
|
||||||
|
|
||||||
|
if (!this.username) {
|
||||||
|
app.dialog.alert(self.$i18n.t('Please input username'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.password) {
|
||||||
|
app.dialog.alert(self.$i18n.t('Please input password'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let hasResponse = false;
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!hasResponse) {
|
||||||
|
self.$f7.preloader.show();
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
|
|
||||||
services.authorize({
|
services.authorize({
|
||||||
loginName: self.username,
|
loginName: self.username,
|
||||||
password: self.password
|
password: self.password
|
||||||
}).then(response => {
|
}).then(response => {
|
||||||
const data = response.data
|
hasResponse = true;
|
||||||
|
self.$f7.preloader.hide();
|
||||||
|
const data = response.data;
|
||||||
|
|
||||||
if (data && data.success && data.result && typeof(data.result) === 'string') {
|
if (data && data.success && data.result && typeof(data.result) === 'string') {
|
||||||
userState.updateToken(data.result)
|
userState.updateToken(data.result);
|
||||||
router.navigate('/')
|
router.navigate('/');
|
||||||
} else {
|
} else {
|
||||||
app.dialog.alert(self.$i18n.t('Unable to login'))
|
app.dialog.alert(self.$i18n.t('Unable to login'));
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
|
hasResponse = true;
|
||||||
|
self.$f7.preloader.hide();
|
||||||
|
|
||||||
if (error.response && error.response.data && error.response.data.errorMessage) {
|
if (error.response && error.response.data && error.response.data.errorMessage) {
|
||||||
app.dialog.alert(self.$i18n.t(`error.${error.response.data.errorMessage}`))
|
app.dialog.alert(self.$i18n.t(`error.${error.response.data.errorMessage}`));
|
||||||
} else {
|
} else {
|
||||||
app.dialog.alert(self.$i18n.t('Unable to login'))
|
app.dialog.alert(self.$i18n.t('Unable to login'));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
changeLanguage(locale) {
|
||||||
|
this.$setLanguage(locale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+14
-9
@@ -9,25 +9,30 @@ import 'framework7-icons';
|
|||||||
|
|
||||||
import './assets/css/custom.css';
|
import './assets/css/custom.css';
|
||||||
|
|
||||||
import i18nOptions from '../common/i18n.js';
|
import i18n from '../common/i18n.js';
|
||||||
|
import settings from '../common/settings.js';
|
||||||
import App from './App.vue';
|
import App from './App.vue';
|
||||||
|
|
||||||
Vue.use(VueI18n);
|
Vue.use(VueI18n);
|
||||||
Framework7.use(Framework7Vue);
|
Framework7.use(Framework7Vue);
|
||||||
|
|
||||||
const i18n = new VueI18n(i18nOptions);
|
const i18nInstance = new VueI18n(i18n.i18nOptions);
|
||||||
|
|
||||||
Vue.prototype.languages = {
|
Vue.prototype.$setLanguage = function (locale) {
|
||||||
setI18nLanguage: lang => {
|
if (settings.getLanguage() !== locale) {
|
||||||
i18n.locale = lang;
|
settings.setLanguage(locale);
|
||||||
axios.defaults.headers.common['Accept-Language'] = lang;
|
|
||||||
document.querySelector('html').setAttribute('lang', lang);
|
|
||||||
return lang;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i18nInstance.locale = locale;
|
||||||
|
axios.defaults.headers.common['Accept-Language'] = locale;
|
||||||
|
document.querySelector('html').setAttribute('lang', locale);
|
||||||
|
return locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vue.prototype.$setLanguage(settings.getLanguage() || i18n.getDefaultLanguage());
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#app',
|
el: '#app',
|
||||||
i18n: i18n,
|
i18n: i18nInstance,
|
||||||
render: h => h(App),
|
render: h => h(App),
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user