You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
353 lines
11 KiB
353 lines
11 KiB
<template>
|
|
<div class="site-wrapper site-page--login">
|
|
<div class="site-content__wrapper">
|
|
<div class="site-content">
|
|
<div class="login-main">
|
|
<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-item prop="userName">
|
|
<el-input v-model="dataForm.userName" :placeholder="$t('login.accountPlaceholder')" @blur="handleUsernameBlur"></el-input>
|
|
</el-form-item>
|
|
<el-form-item prop="password">
|
|
<el-input v-model="dataForm.password" type="password" :placeholder="$t('login.passwordPlaceholder')"></el-input>
|
|
</el-form-item>
|
|
<el-form-item >
|
|
<el-select v-model="selectedSite" :placeholder="$t('login.selectSitePlaceholder')" style="width: 100%;">
|
|
<el-option
|
|
v-for="item in siteList"
|
|
:key="item.siteCode"
|
|
:label="item.siteName"
|
|
:value="item.siteCode">
|
|
</el-option>
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<el-button class="login-btn-submit" type="primary" @click="dataFormSubmit()">{{ $t('button.login') }}</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
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 {
|
|
src: 'http://192.168.1.83/upload/ifs.png',
|
|
dataForm: {
|
|
userName: '',
|
|
password: '',
|
|
uuid: '',
|
|
captcha: ''
|
|
},
|
|
siteList: [],
|
|
selectedSite: '',
|
|
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
|
|
},
|
|
set(val) {
|
|
this.$store.commit('user/updateMultiLanguage', val)
|
|
}
|
|
},
|
|
authControl: {
|
|
get() {
|
|
return this.$store.state.user.authControl
|
|
},
|
|
set(val) {
|
|
this.$store.commit('user/updateAuthControl', val)
|
|
}
|
|
}
|
|
},
|
|
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')
|
|
this.handleUsernameBlur()
|
|
this.dataForm.selectedSite = localStorage.getItem('site')
|
|
},
|
|
// 用户名失焦时获取工厂列表
|
|
handleUsernameBlur() {
|
|
if (this.dataForm.userName && this.dataForm.userName.trim()) {
|
|
this.getUserSiteList(this.dataForm.userName);
|
|
} else {
|
|
this.siteList = [];
|
|
this.selectedSite = '';
|
|
}
|
|
},
|
|
// 根据用户名获取授权的工厂列表
|
|
getUserSiteList(userName) {
|
|
if (!userName || !userName.trim()) {
|
|
this.siteList = [];
|
|
this.selectedSite = '';
|
|
return;
|
|
}
|
|
|
|
getUserAuthorizedSites({ userName: userName.trim() }).then(({data}) => {
|
|
if (data && data.code === 0) {
|
|
this.siteList = data.data || data.list || [];
|
|
// 清空之前选择的工厂
|
|
this.selectedSite = '';
|
|
// 如果只有一个工厂,自动选中
|
|
if (this.siteList.length === 1) {
|
|
this.selectedSite = this.siteList[0].siteCode;
|
|
}
|
|
} else {
|
|
this.siteList = [];
|
|
this.selectedSite = '';
|
|
this.$message.error(data.msg || this.$t('login.getSiteListFailed'));
|
|
}
|
|
}).catch(error => {
|
|
this.siteList = [];
|
|
this.selectedSite = '';
|
|
console.error('获取工厂列表失败:', error);
|
|
this.$message.error(this.$t('login.getSiteListFailed'));
|
|
})
|
|
},
|
|
// 提交表单
|
|
dataFormSubmit () {
|
|
// 如果有工厂列表但未选择工厂,提示用户
|
|
if (this.siteList.length > 0 && !this.selectedSite) {
|
|
this.$message.error(this.$t('login.siteRequired'));
|
|
return;
|
|
}
|
|
|
|
this.$refs['dataForm'].validate((valid) => {
|
|
if (valid) {
|
|
this.$http({
|
|
url: this.$http.adornUrl('/sys/login'),
|
|
method: 'post',
|
|
data: this.$http.adornData({
|
|
'username': this.dataForm.userName,
|
|
'password': this.dataForm.password,
|
|
'uuid': this.dataForm.uuid,
|
|
'site': this.selectedSite
|
|
})
|
|
}).then(({data}) => {
|
|
if (data && data.code === 0) {
|
|
// 设置Cookie过期时间为8小时,与后端token同步 - rqrq
|
|
this.$cookie.set('token_wms', data.token, { expires: '8h' })
|
|
this.$router.replace({ name: 'home' })
|
|
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) // 保存选择的工厂
|
|
|
|
this.getConfigParams()
|
|
} else {
|
|
this.$message.error(data.msg)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
},
|
|
// 获取全局参数变量
|
|
getConfigParams() {
|
|
getConfigParams().then(({data}) => {
|
|
if (data && data.code == 0) {
|
|
localStorage.setItem('configParams', JSON.stringify(data.data))
|
|
// this.multiLanguage = JSON.parse(localStorage.getItem('configParams')).multiLanguage
|
|
// this.authControl = JSON.parse(localStorage.getItem('configParams')).authControl
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.site-wrapper.site-page--login {
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
left: 0;
|
|
background-color: rgba(38, 50, 56, 0);
|
|
overflow: hidden;
|
|
&:before {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
z-index: -1;
|
|
width: 80%;
|
|
height: 100%;
|
|
content: "";
|
|
background-image: url(~@/assets/img/login_bg.jpg);
|
|
background-size: cover;
|
|
}
|
|
.site-content__wrapper {
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
left: 0;
|
|
padding: 0;
|
|
margin: 0;
|
|
overflow-x: hidden;
|
|
overflow-y: auto;
|
|
background-color: transparent;
|
|
}
|
|
.site-content {
|
|
min-height: 100%;
|
|
padding: 15% 500px 30px 30px;
|
|
}
|
|
.brand-info {
|
|
margin: 220px 100px 0 90px;
|
|
color: #fff;
|
|
}
|
|
.brand-info__text {
|
|
margin: 0 0 22px 0;
|
|
font-size: 48px;
|
|
font-weight: 400;
|
|
text-transform : uppercase;
|
|
}
|
|
.brand-info__intro {
|
|
margin: 10px 0;
|
|
font-size: 16px;
|
|
line-height: 1.58;
|
|
opacity: .6;
|
|
}
|
|
.login-main {
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
padding: 15% 60px 180px;
|
|
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;
|
|
> img {
|
|
width: 100%;
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
.login-btn-submit {
|
|
width: 100%;
|
|
|
|
}
|
|
.login-main .el-input__inner{
|
|
margin-top: 10px;
|
|
height: 45px;
|
|
}
|
|
.el-button--medium {
|
|
margin-top: 0px;
|
|
padding: 5px 11px;
|
|
font-size: 16px;
|
|
border-radius: 4px;
|
|
}
|
|
.el-form-item {
|
|
margin-bottom: 5px;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
</style>
|