Browse Source

登录页面可以选择语言

master
han\hanst 1 month ago
parent
commit
5cd4cfd9d8
  1. 13
      src/i18n/locales/cn.js
  2. 13
      src/i18n/locales/en.js
  3. 114
      src/views/common/login.vue
  4. 3
      src/views/modules/labelSetting/components/DataSourceDialog.vue
  5. 12
      src/views/modules/sys/user-add-or-update.vue

13
src/i18n/locales/cn.js

@ -13,6 +13,19 @@ export default {
welcome: "欢迎", welcome: "欢迎",
greeting: "{name}!" greeting: "{name}!"
}, },
login: {
title: "用户登陆",
accountPlaceholder: "帐号",
passwordPlaceholder: "密码",
selectSitePlaceholder: "请选择工厂",
selectLanguagePlaceholder: "请选择语言",
accountRequired: "帐号不能为空",
passwordRequired: "密码不能为空",
siteRequired: "请选择工厂",
getSiteListFailed: "获取工厂列表失败",
languageOptionCn: "中文",
languageOptionEn: "英文"
},
button: { button: {
login: "登录" login: "登录"
}, },

13
src/i18n/locales/en.js

@ -13,6 +13,19 @@ export default {
welcome: "Welcome", welcome: "Welcome",
greeting: "{name}!" // 支持动态插值 greeting: "{name}!" // 支持动态插值
}, },
login: {
title: "User Login",
accountPlaceholder: "Account",
passwordPlaceholder: "Password",
selectSitePlaceholder: "Please select a factory",
selectLanguagePlaceholder: "Please select language",
accountRequired: "Account cannot be empty",
passwordRequired: "Password cannot be empty",
siteRequired: "Please select a factory",
getSiteListFailed: "Failed to get factory list",
languageOptionCn: "Chinese",
languageOptionEn: "English"
},
button: { button: {
login: "Login" login: "Login"
}, },

114
src/views/common/login.vue

@ -3,17 +3,31 @@
<div class="site-content__wrapper"> <div class="site-content__wrapper">
<div class="site-content"> <div class="site-content">
<div class="login-main"> <div class="login-main">
<h3 class="login-title">用户登陆</h3>
<div class="login-language-wrapper">
<el-select
v-model="selectedLanguage"
class="login-language-select"
:placeholder="$t('login.selectLanguagePlaceholder')"
@change="switchLoginLanguage">
<el-option
v-for="(item, index) in languageList"
:key="'login-language-' + index"
:label="item.languageName"
:value="item.languageCode">
</el-option>
</el-select>
</div>
<h3 class="login-title">{{ $t('login.title') }}</h3>
<el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()" status-icon> <el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()" status-icon>
<el-form-item prop="userName"> <el-form-item prop="userName">
<el-input v-model="dataForm.userName" placeholder="帐号" @blur="handleUsernameBlur"></el-input>
<el-input v-model="dataForm.userName" :placeholder="$t('login.accountPlaceholder')" @blur="handleUsernameBlur"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="password"> <el-form-item prop="password">
<el-input v-model="dataForm.password" type="password" placeholder="密码"></el-input>
<el-input v-model="dataForm.password" type="password" :placeholder="$t('login.passwordPlaceholder')"></el-input>
</el-form-item> </el-form-item>
<el-form-item > <el-form-item >
<el-select v-model="selectedSite" placeholder="请选择工厂" style="width: 100%;">
<el-select v-model="selectedSite" :placeholder="$t('login.selectSitePlaceholder')" style="width: 100%;">
<el-option <el-option
v-for="item in siteList" v-for="item in siteList"
:key="item.siteCode" :key="item.siteCode"
@ -23,7 +37,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button class="login-btn-submit" type="primary" @click="dataFormSubmit()">登录</el-button>
<el-button class="login-btn-submit" type="primary" @click="dataFormSubmit()">{{ $t('button.login') }}</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
@ -36,6 +50,7 @@
import { getUUID } from '@/utils' import { getUUID } from '@/utils'
import {getConfigParams} from '@/api/sysConfig.js' import {getConfigParams} from '@/api/sysConfig.js'
import {getUserAuthorizedSites} from '@/api/factory/accessSite.js' import {getUserAuthorizedSites} from '@/api/factory/accessSite.js'
import {searchSysLanguage} from '@/api/sysLanguage.js'
export default { export default {
data () { data () {
return { return {
@ -48,18 +63,22 @@
}, },
siteList: [], siteList: [],
selectedSite: '', selectedSite: '',
dataRule: {
selectedLanguage: 'cn',
languageList: [],
captchaPath: ''
}
},
computed: {
dataRule() {
return {
userName: [ userName: [
{ required: true, message: '帐号不能为空', trigger: 'blur' }
{ required: true, message: this.$t('login.accountRequired'), trigger: 'blur' }
], ],
password: [ password: [
{ required: true, message: '密码不能为空', trigger: 'blur' }
{ required: true, message: this.$t('login.passwordRequired'), trigger: 'blur' }
] ]
},
captchaPath: ''
} }
}, },
computed: {
multiLanguage: { multiLanguage: {
get() { get() {
return this.$store.state.user.multiLanguage return this.$store.state.user.multiLanguage
@ -78,9 +97,53 @@
} }
}, },
created () { created () {
this.initLoginLanguage()
this.getLanguageList()
this.userName(); this.userName();
}, },
methods: { methods: {
normalizeLanguageCode(languageCode) {
const locale = (languageCode || '').toLowerCase()
return (locale === 'en' || locale === 'en-us') ? 'en' : 'cn'
},
//
initLoginLanguage() {
const locale = this.normalizeLanguageCode(localStorage.getItem('locale') || 'cn')
this.applyLoginLanguage(locale)
},
//
buildFallbackLanguageList() {
return [
{ languageCode: 'cn', languageName: this.$t('login.languageOptionCn') },
{ languageCode: 'en', languageName: this.$t('login.languageOptionEn') }
]
},
//
getLanguageList() {
this.languageList = this.buildFallbackLanguageList()
searchSysLanguage({ languageCode: this.$i18n.locale }).then(({data}) => {
const rows = (data && data.rows) ? data.rows : []
if (rows.length > 0) {
this.languageList = rows
if (!this.languageList.find(item => this.normalizeLanguageCode(item.languageCode) === this.selectedLanguage)) {
this.selectedLanguage = this.languageList[0].languageCode
}
this.selectedLanguage = this.normalizeLanguageCode(this.selectedLanguage)
}
}).catch(() => {
})
},
//
applyLoginLanguage(languageCode) {
const locale = this.normalizeLanguageCode(languageCode)
this.selectedLanguage = locale
this.$i18n.locale = locale
localStorage.setItem('locale', locale)
},
switchLoginLanguage(languageCode) {
this.applyLoginLanguage(languageCode)
this.getLanguageList()
},
// //
userName(){ userName(){
this.dataForm.userName = localStorage.getItem('userName') this.dataForm.userName = localStorage.getItem('userName')
@ -116,20 +179,20 @@
} else { } else {
this.siteList = []; this.siteList = [];
this.selectedSite = ''; this.selectedSite = '';
this.$message.error(data.msg || '获取工厂列表失败');
this.$message.error(data.msg || this.$t('login.getSiteListFailed'));
} }
}).catch(error => { }).catch(error => {
this.siteList = []; this.siteList = [];
this.selectedSite = ''; this.selectedSite = '';
console.error('获取工厂列表失败:', error); console.error('获取工厂列表失败:', error);
this.$message.error('获取工厂列表失败');
this.$message.error(this.$t('login.getSiteListFailed'));
}) })
}, },
// //
dataFormSubmit () { dataFormSubmit () {
// //
if (this.siteList.length > 0 && !this.selectedSite) { if (this.siteList.length > 0 && !this.selectedSite) {
this.$message.error('请选择工厂');
this.$message.error(this.$t('login.siteRequired'));
return; return;
} }
@ -149,9 +212,8 @@
// Cookie8token - rqrq // Cookie8token - rqrq
this.$cookie.set('token_wms', data.token, { expires: '8h' }) this.$cookie.set('token_wms', data.token, { expires: '8h' })
this.$router.replace({ name: 'home' }) this.$router.replace({ name: 'home' })
this.$i18n.locale=data.language
localStorage.setItem('locale', data.language)
this.$i18n.locale = data.language; //
const loginLanguage = this.normalizeLanguageCode(this.selectedLanguage || data.language || 'cn')
this.applyLoginLanguage(loginLanguage)
localStorage.setItem('refresh', "0") localStorage.setItem('refresh', "0")
localStorage.setItem('userName', this.dataForm.userName) localStorage.setItem('userName', this.dataForm.userName)
localStorage.setItem('site', this.selectedSite) // localStorage.setItem('site', this.selectedSite) //
@ -238,9 +300,27 @@
width: 350px; width: 350px;
min-height: 100%; min-height: 100%;
background-color: #fff; background-color: #fff;
box-sizing: border-box;
} }
.login-title { .login-title {
font-size: 30px; font-size: 30px;
margin: 0 0 18px 0;
text-align: center;
}
.login-language-wrapper {
position: absolute;
top: 24px;
right: 24px;
z-index: 2;
}
.login-language-select {
width: 140px;
.el-input__inner {
margin-top: 0 !important;
height: 32px;
line-height: 32px;
}
} }
.login-captcha { .login-captcha {
overflow: hidden; overflow: hidden;

3
src/views/modules/labelSetting/components/DataSourceDialog.vue

@ -19,9 +19,6 @@
:key="group.viewSource" :key="group.viewSource"
class="view-group" class="view-group"
> >
<div class="view-title">
{{ group.viewSource + ' (' + $t('labelSetting.dataSource.fieldCount', { count: group.fields.length }) + ')' }}
</div>
<div class="checkbox-grid"> <div class="checkbox-grid">
<label <label
v-for="key in group.fields" v-for="key in group.fields"

12
src/views/modules/sys/user-add-or-update.vue

@ -34,6 +34,12 @@
<el-form-item :label="buttons.mobile||'手机号'" prop="mobile"> <el-form-item :label="buttons.mobile||'手机号'" prop="mobile">
<el-input v-model="dataForm.mobile" style="width: 150px;" placeholder="手机号"></el-input> <el-input v-model="dataForm.mobile" style="width: 150px;" placeholder="手机号"></el-input>
</el-form-item> </el-form-item>
<el-form-item :label="buttons.language||'语言'" prop="languageDefault">
<el-select filterable v-model="dataForm.languageDefault" clearable style="width: 150px;">
<el-option :label="item.languageName" :value="item.languageCode" v-for="(item,index) in languageList "
:key="index"></el-option>
</el-select>
</el-form-item>
</el-form> </el-form>
<el-form> <el-form>
<el-form-item :label="buttons.site||'工厂'" size="mini" prop="siteList"> <el-form-item :label="buttons.site||'工厂'" size="mini" prop="siteList">
@ -44,12 +50,6 @@
</el-checkbox> </el-checkbox>
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
<!-- <el-form-item :label="buttons.language||'语言'" prop="languageDefault">-->
<!-- <el-select filterable v-model="dataForm.languageDefault" clearable style="width: 150px;">-->
<!-- <el-option :label="item.languageName" :value="item.languageCode" v-for="(item,index) in languageList "-->
<!-- :key="index"></el-option>-->
<!-- </el-select>-->
<!-- </el-form-item>-->
</el-form> </el-form>
<el-form> <el-form>
<el-form-item label="角色" size="mini" prop="roleIdList"> <el-form-item label="角色" size="mini" prop="roleIdList">

Loading…
Cancel
Save