diff --git a/src/i18n/locales/cn.js b/src/i18n/locales/cn.js index 0998b17..487fde5 100644 --- a/src/i18n/locales/cn.js +++ b/src/i18n/locales/cn.js @@ -13,6 +13,19 @@ export default { welcome: "欢迎", greeting: "{name}!" }, + login: { + title: "用户登陆", + accountPlaceholder: "帐号", + passwordPlaceholder: "密码", + selectSitePlaceholder: "请选择工厂", + selectLanguagePlaceholder: "请选择语言", + accountRequired: "帐号不能为空", + passwordRequired: "密码不能为空", + siteRequired: "请选择工厂", + getSiteListFailed: "获取工厂列表失败", + languageOptionCn: "中文", + languageOptionEn: "英文" + }, button: { login: "登录" }, diff --git a/src/i18n/locales/en.js b/src/i18n/locales/en.js index e98dd1b..6c50376 100644 --- a/src/i18n/locales/en.js +++ b/src/i18n/locales/en.js @@ -13,6 +13,19 @@ export default { welcome: "Welcome", 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: { login: "Login" }, diff --git a/src/views/common/login.vue b/src/views/common/login.vue index 8a6781e..f6ccd29 100644 --- a/src/views/common/login.vue +++ b/src/views/common/login.vue @@ -3,17 +3,31 @@
@@ -36,6 +50,7 @@ import { getUUID } from '@/utils' import {getConfigParams} from '@/api/sysConfig.js' import {getUserAuthorizedSites} from '@/api/factory/accessSite.js' + import {searchSysLanguage} from '@/api/sysLanguage.js' export default { data () { return { @@ -48,18 +63,22 @@ }, siteList: [], selectedSite: '', - dataRule: { - userName: [ - { required: true, message: '帐号不能为空', trigger: 'blur' } - ], - password: [ - { required: true, message: '密码不能为空', trigger: 'blur' } - ] - }, + selectedLanguage: 'cn', + languageList: [], captchaPath: '' } }, computed: { + dataRule() { + return { + userName: [ + { required: true, message: this.$t('login.accountRequired'), trigger: 'blur' } + ], + password: [ + { required: true, message: this.$t('login.passwordRequired'), trigger: 'blur' } + ] + } + }, multiLanguage: { get() { return this.$store.state.user.multiLanguage @@ -78,9 +97,53 @@ } }, created () { + this.initLoginLanguage() + this.getLanguageList() this.userName(); }, 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(){ this.dataForm.userName = localStorage.getItem('userName') @@ -116,20 +179,20 @@ } else { this.siteList = []; this.selectedSite = ''; - this.$message.error(data.msg || '获取工厂列表失败'); + this.$message.error(data.msg || this.$t('login.getSiteListFailed')); } }).catch(error => { this.siteList = []; this.selectedSite = ''; console.error('获取工厂列表失败:', error); - this.$message.error('获取工厂列表失败'); + this.$message.error(this.$t('login.getSiteListFailed')); }) }, // 提交表单 dataFormSubmit () { // 如果有工厂列表但未选择工厂,提示用户 if (this.siteList.length > 0 && !this.selectedSite) { - this.$message.error('请选择工厂'); + this.$message.error(this.$t('login.siteRequired')); return; } @@ -149,9 +212,8 @@ // 设置Cookie过期时间为8小时,与后端token同步 - rqrq this.$cookie.set('token_wms', data.token, { expires: '8h' }) 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('userName', this.dataForm.userName) localStorage.setItem('site', this.selectedSite) // 保存选择的工厂 @@ -238,9 +300,27 @@ width: 350px; min-height: 100%; background-color: #fff; + box-sizing: border-box; } .login-title { 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 { overflow: hidden; diff --git a/src/views/modules/labelSetting/components/DataSourceDialog.vue b/src/views/modules/labelSetting/components/DataSourceDialog.vue index 5fabcc8..98d9854 100644 --- a/src/views/modules/labelSetting/components/DataSourceDialog.vue +++ b/src/views/modules/labelSetting/components/DataSourceDialog.vue @@ -19,9 +19,6 @@ :key="group.viewSource" class="view-group" > -
- {{ group.viewSource + ' (' + $t('labelSetting.dataSource.fieldCount', { count: group.fields.length }) + ')' }} -