school_website/ruoyi-ui/src/views/officialWebsite/Components/header.vue
2025-02-24 17:10:49 +08:00

586 lines
20 KiB
Vue

<template>
<div class="tab-boxs" style="justify-content: space-between">
<!-- left -->
<div class="d-s" style="width: 20%" @click="toHome">
<div class="logo-box">
<img :src="baseInfo.webImg"/>
</div>
<div class="logo-size">
{{ this.baseInfo.webName }}
</div>
</div>
<!-- tab -->
<div class="d-s" style="width: 68%;justify-content: space-between">
<div class="x-x" :class="{'active' :tabindex == index }" v-for="(item, index) in tablist " :key="index"
@click="tabClick(item.jumpUrl, item.id,index)"
>
<div>
<img v-if="item.iconUrl" :src=" imgurl +item.iconUrl " alt="" style="width: 20px;height: 20px">
</div>
<div class="bsize">{{ item.label }}</div>
</div>
</div>
<!-- right -->
<!-- <div class="d-s" style="font-size: 20px; color: #fff;cursor: pointer;width: 170px;justify-content: flex-end">-->
<!-- <i class="el-icon-search" v-if="show_search"></i>-->
<!-- <div style="font-size: 18px; margin-left: 15px; " v-if="show_search" @click="show_search = !show_search">搜索-->
<!-- </div>-->
<!-- <el-input placeholder="输入关键词" v-model="input" style="width: 150px;height: 35px" v-if="!show_search">-->
<!-- <i slot="prefix" class="el-input__icon el-icon-search"></i>-->
<!-- </el-input>-->
<!-- <i class="el-icon-circle-close" v-if="!show_search" style="margin-left: 10px;"-->
<!-- @click="show_search = true"></i>-->
<!-- </div>-->
<div class="right-box" v-if="!isLoggedIn">
<el-button class="login-button" @click="showLoginDialog = true">登录</el-button>
<el-button class="register-button" @click="registerDialog = true">注册</el-button>
</div>
<div class="right-box" v-if="isLoggedIn">
<el-dropdown @command="handleCommand">
<span class="right-box">
{{ currentUser }} <i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="logout" divided @click.native="goBack">进入后台</el-dropdown-item>
<el-dropdown-item command="logout" divided @click.native="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<el-dialog title="登录" :visible.sync="showLoginDialog" width="30%" :modal="false">
<div>
<el-form :model="loginForm" ref="loginForm">
<el-form-item prop="username">
<el-input placeholder="手机号" v-model="loginForm.username"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input placeholder="密码" v-model="loginForm.password" type="password"></el-input>
</el-form-item>
<el-form-item prop="code">
<el-input v-model="loginForm.code"
auto-complete="off"
placeholder="验证码"
style="width: 63%"
@keyup.enter.native="handleLogin"
>
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon"/>
</el-input>
<div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img"/>
</div>
</el-form-item>
<el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
</el-form>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="showLoginDialog = false">取 消</el-button>
<el-button type="primary" @click="submitLogin">登 录</el-button>
</span>
</el-dialog>
<el-dialog title="注册" :close-on-click-modal="false" :visible.sync="registerDialog" width="30%" :modal="false">
<div>
<el-form :model="registerForm" :rules="registerRules" ref="registerForm">
<el-form-item prop="userType">
<el-radio-group v-model="registerForm.userType">
<el-radio label="01">学生</el-radio>
<el-radio label="02">指导老师</el-radio>
<el-radio label="03">领队老师</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item prop="nickName">
<el-input placeholder="姓名" v-model="registerForm.nickName" type="text"></el-input>
</el-form-item>
<el-form-item prop="username">
<el-input placeholder="手机号(登录账号)" v-model="registerForm.username" type="text"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input placeholder="密码" v-model="registerForm.password" type="password"></el-input>
</el-form-item>
<el-form-item prop="confirmPassword">
<el-input placeholder="确认密码" v-model="registerForm.confirmPassword" type="password"></el-input>
</el-form-item>
<el-form-item prop="hitRegistrationTeachInfo.teacherEmail"
v-if="registerForm.userType=='03'||registerForm.userType=='02'"
>
<el-input placeholder="邮箱" v-model="registerForm.hitRegistrationTeachInfo.teacherEmail" type="text"
></el-input>
</el-form-item>
<!-- <el-form-item prop="hitRegistrationTeachInfo.teacherNumber" v-if="registerForm.userType=='03'||registerForm.userType=='02'">-->
<!-- <el-input placeholder="手机号" v-model="registerForm.hitRegistrationTeachInfo.teacherNumber" type="text"></el-input>-->
<!-- </el-form-item>-->
<el-form-item prop="hitRegistrationTeachInfo.division"
v-if="registerForm.userType=='03'||registerForm.userType=='02'"
>
<el-select v-model="registerForm.hitRegistrationTeachInfo.division" filterable allow-create
default-first-option
placeholder="请选择赛区"
>
<el-option v-for="item in dict.type.com_region" :key="item.value" :label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item prop="hitRegistrationTeachInfo.schoolName"
v-if="registerForm.userType=='03'||registerForm.userType=='02'"
>
<el-select v-model="registerForm.hitRegistrationTeachInfo.schoolName" filterable allow-create
default-first-option
placeholder="请选择学校名称"
>
<el-option v-for="item in dict.type.school_name" :key="item.value" :label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item prop="hitRegistrationTeachInfo.teacherSchool"
v-if="registerForm.userType=='03'||registerForm.userType=='02'"
>
<el-input placeholder="所在系及专业" v-model="registerForm.hitRegistrationTeachInfo.teacherSchool"
type="text"
></el-input>
</el-form-item>
<el-form-item prop="hitRegistrationTeachInfo.teacherJob"
v-if="registerForm.userType=='03'||registerForm.userType=='02'"
>
<el-input placeholder="职务" v-model="registerForm.hitRegistrationTeachInfo.teacherJob" type="text"
></el-input>
</el-form-item>
<el-form-item label="批准盖章文件" prop="hitRegistrationTeachInfo.file" label-width="130px" v-if="registerForm.userType === '03'">
<image-upload :limit="1" v-model="registerForm.hitRegistrationTeachInfo.file"></image-upload>
</el-form-item>
<el-form-item prop="code">
<el-input v-model="registerForm.code"
auto-complete="off"
placeholder="验证码"
style="width: 63%"
@keyup.enter.native="handleLogin"
>
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon"/>
</el-input>
<div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img"/>
</div>
</el-form-item>
<el-form-item></el-form-item>
</el-form>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="showRegisterDialog = false">取 消</el-button>
<el-button type="primary" @click="submitRegister">注 册</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { getHomeUserInfo, getTeacherAndStudentInfo } from '@/api/system/user'
import { getBaseInfo, getTab } from '@/api/gw/home'
import { getCodeImg, register } from '@/api/login'
import Cookies from 'js-cookie'
import { encrypt, decrypt } from '@/utils/jsencrypt'
import { getToken } from '@/utils/auth'
export default {
dicts: ['sys_user_sex', 'school_name', 'com_region'],
data() {
const equalToPassword = (rule, value, callback) => {
if (this.registerForm.password !== value) {
callback(new Error('两次输入的密码不一致'))
} else {
callback()
}
}
return {
isLoggedIn: false, // 是否登录
value: false,
currentUser: '', //当前用户
codeUrl: '', //验证码地址
showLoginDialog: false, // 是否显示登录对话框
registerDialog: false, // 是否显示注册对话框
baseInfo: '',
imgurl: process.env.VUE_APP_BASE_API,
input: '',
show_search: true,
categoryQuery: {},
tabindex: 0,
tablist: [
{ name: '首页' },
{ name: '中心概括' },
{ name: '教学资源' },
{ name: '教学平台' },
{ name: '教学团队' },
{ name: '专业委员会' },
{ name: '教学研讨活动' },
{ name: '虚仿专业频道' },
{ name: '大赛风采' },
{ name: '实践平台' },
{ name: '合作企业' },
{ name: '联系我们' }
],
loginForm: {
username: '',
password: '',
code: '',
uuid: '',
rememberMe: false
},
registerForm: {
username: '',
password: '',
code: '',
confirmPassword: '',
uuid: '',
userType: '01',
hitRegistrationTeachInfo: {
teacherName: '',
teacherJob: '',
teacherEmail: '',
teacherNumber: '',
teacherSchool: '',
schoolName: '',
division: '',
SampleAddress: '',
file:''
}
},
registerRules: {
username: [
{ required: true, trigger: 'blur', message: '请输入您的账号' },
{ message: '学号不能为空', trigger: 'blur' }
],
nickName: [
{ required: true, trigger: 'blur', message: '请输入您的姓名' },
{ message: '姓名不能为空', trigger: 'blur' }
],
password: [
{ required: true, trigger: 'blur', message: '请输入您的密码' },
{ min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' },
{ pattern: /^[^<>"'|\\]+$/, message: '不能包含非法字符:< > " \' \\\ |', trigger: 'blur' }
],
confirmPassword: [
{ required: true, trigger: 'blur', message: '请再次输入您的密码' },
{ required: true, validator: equalToPassword, trigger: 'blur' }
],
code: [{ required: true, trigger: 'change', message: '请输入验证码' }],
'hitRegistrationTeachInfo.teacherEmail': [
{ required: true, trigger: 'blur', message: '请输入您的邮箱' }
],
'hitRegistrationTeachInfo.teacherNumber': [
{ required: true, trigger: 'blur', message: '请输入您的手机号' }
],
'hitRegistrationTeachInfo.division': [
{ required: true, trigger: 'blur', message: '请选择赛区' }
],
'hitRegistrationTeachInfo.schoolName': [
{ required: true, trigger: 'blur', message: '请选择学校名称' }
],
'hitRegistrationTeachInfo.teacherSchool': [
{ required: true, trigger: 'blur', message: '请输入所在系及专业' }
],
'hitRegistrationTeachInfo.teacherJob': [
{ required: true, trigger: 'blur', message: '请输入您的职务' }
],
'hitRegistrationTeachInfo.file': [
//验证文件
{ required: true, trigger: 'blur', message: '请上传您的批准盖章文件' }
]
}
}
},
props: {
msg: String
},
created() {
this.tabindex = this.msg
this.getCode()
this.getCookie() // 页面加载完毕调用
this.isLoggedIn = getToken() ? true : false // 检查 localStorage 中的登录状态
if (this.isLoggedIn) {
this.loadUserInfo()
}
},
mounted() {
this.tabindex = this.msg
// console.log(this.msg)
// 页面加载完毕调用
this.tabLsit()
this.getWebBaseInfo()
// 监听窗口关闭事件
window.addEventListener('beforeunload', this.handleBeforeUnload)
},
beforeDestroy() {
// 组件销毁前移除事件监听
window.removeEventListener('beforeunload', this.handleBeforeUnload)
},
methods: {
//用户信息
loadUserInfo() {
getHomeUserInfo().then(response => {
this.currentUser = response.data.userName
console.log('当前用户名:', this.currentUser)
if (this.userInfo.avatar && this.userInfo.avatar != '') {
this.userInfo.avatar = process.env.VUE_APP_BASE_API + this.userInfo.avatar
}
})
},
//验证码
getCode() {
getCodeImg().then(res => {
this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled
if (this.captchaEnabled) {
this.codeUrl = 'data:image/gif;base64,' + res.img
this.loginForm.uuid = res.uuid
this.registerForm.uuid = res.uuid
}
})
},
getCookie() {
const username = Cookies.get('username')
const password = Cookies.get('password')
const rememberMe = Cookies.get('rememberMe')
this.loginForm = {
username: username === undefined ? this.loginForm.username : username,
password: password === undefined ? this.loginForm.password : decrypt(password),
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
}
},
// 登录
submitLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true
if (this.loginForm.rememberMe) {
Cookies.set('username', this.loginForm.username, { expires: 30 })
Cookies.set('password', encrypt(this.loginForm.password), { expires: 30 })
Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 })
} else {
Cookies.remove('username')
Cookies.remove('password')
Cookies.remove('rememberMe')
}
this.$store.dispatch('Login', this.loginForm).then(() => {
this.isLoggedIn = true // 登录成功后设置标志
this.showLoginDialog = false
this.$router.push('/virtually').catch(() => {
})
this.loadUserInfo()
localStorage.setItem('isLoggedIn', 'true') // 将登录状态存储在 localStorage
console.log('当前用户名:', this.currentUser)
}).catch(() => {
this.loading = false
if (this.captchaEnabled) {
this.getCode()
}
})
}
}
)
},
//注册
submitRegister() {
this.$refs.registerForm.validate(valid => {
if (valid) {
// 验证用户名是否为手机号
const phoneRegex = /^1[3-9]\d{9}$/
if (!phoneRegex.test(this.registerForm.username)) {
this.$alert('<font color=\'red\'>请输入有效的手机号。</font>', '系统提示', {
dangerouslyUseHTMLString: true,
type: 'error'
})
return
}
if (this.registerForm.hitRegistrationTeachInfo) {
this.registerForm.hitRegistrationTeachInfo.teacherNumber = this.registerForm.username
}
this.loading = true
register(this.registerForm).then(res => {
const username = this.registerForm.username
this.registerDialog = false
this.$alert('<font color=\'red\'>恭喜你,您的账号 ' + username + ' 注册成功!</font>', '系统提示', {
dangerouslyUseHTMLString: true,
type: 'success'
}).then(() => {
this.$router.push('/virtually')
}).catch(() => {
})
}).catch(() => {
this.loading = false
if (this.captchaEnabled) {
this.getCode()
}
})
}
})
},
//退出登录
async logout() {
this.$confirm('确定注销并退出系统吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$store.dispatch('LogOut').then(() => {
localStorage.removeItem('isLoggedIn') // 清空 localStorage 中的登录状态
location.href = '/index'
})
}).catch(() => {
})
},
goBack() {
this.$router.push('/index')
},
// 定义处理窗口关闭前的事件
handleBeforeUnload() {
// 清空localStorage中的isLoggedIn
localStorage.removeItem('isLoggedIn')
},
tabClick(url, id, index) {
this.tabindex = index
if (url === 'home') url = 'gw'
this.$router.push({
name: url,
query: { id: id }
})
},
tabLsit() {
getTab().then(response => {
if (response.code == 200) {
this.tablist = response.data
this.categoryQuery.categoryId = this.tablist[0].id
}
})
},
getWebBaseInfo() {
getBaseInfo().then(res => {
this.baseInfo = res.data
this.baseInfo.webImg = process.env.VUE_APP_BASE_API + this.baseInfo.webImg
})
},
toHome() {
this.$router.push('/virtually')
}
}
}
</script>
<style scoped lang="scss">
.right-box {
display: flex;
justify-content: center;
align-items: center;
width: 170px;
font-size: 20px;
color: #fff;
cursor: pointer;
}
.login-button {
background-color: #fff; /* 白色背景 */
color: #005375; /* 蓝色文字 */
}
.register-button {
background: none; /* 透明背景 */
color: #fff; /* 白色文字 */
}
.tab-boxs {
width: 100%;
box-sizing: border-box;
//padding: 0px 50px;
padding-left: 40px;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);;
font-weight: bold;
font-size: 18px;
color: #FFFFFF;
position: absolute;
z-index: 3;
}
.d-s {
display: flex;
align-items: center;
cursor: pointer;
}
.logo-box {
width: 50px;
height: 50px;
//background: #fff;
}
.logo-box img {
width: 47px;
height: 47px;
}
.logo-size {
font-weight: 600;
font-size: 16px;
color: #FFFFFF;
margin-left: 10px;
}
.x-x {
cursor: pointer;
height: 90px;
text-align: center;
box-sizing: border-box;
padding-top: 25px;
}
.x-x:hover {
background: linear-gradient(360deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0) 100%);
//border-bottom: 2px solid #fff;
}
.active {
background: linear-gradient(360deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0) 100%);
border-bottom: 2px solid #fff !important;
}
.bsize {
font-weight: 500;
font-size: 15px;
color: #FFFFFF;
}
.login-code {
width: 33%;
height: 38px;
float: right;
img {
cursor: pointer;
vertical-align: middle;
}
}
.login-code-img {
height: 38px;
}
.el-dialog__title {
text-align: center;
}
</style>