refactor(login): 重构登录页面,适配国际化并简化功能
1. 将页面文本替换为国际化翻译 2. 移除验证码、快速登录等冗余功能 3. 更新logo资源路径与表单校验逻辑 4. 优化页面样式与代码结构
This commit is contained in:
@@ -8,7 +8,7 @@
|
|||||||
<div
|
<div
|
||||||
class="page-login--layer page-login--layer-time"
|
class="page-login--layer page-login--layer-time"
|
||||||
flex="main:center cross:center">
|
flex="main:center cross:center">
|
||||||
{{time}}
|
{{ time }}
|
||||||
</div>
|
</div>
|
||||||
<div class="page-login--layer">
|
<div class="page-login--layer">
|
||||||
<div
|
<div
|
||||||
@@ -16,15 +16,13 @@
|
|||||||
flex="dir:top main:justify cross:stretch box:justify">
|
flex="dir:top main:justify cross:stretch box:justify">
|
||||||
<div class="page-login--content-header">
|
<div class="page-login--content-header">
|
||||||
<p class="page-login--content-header-motto">
|
<p class="page-login--content-header-motto">
|
||||||
时间是一切财富中最宝贵的财富
|
{{ $t(key('time_is_most_precious')) }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="page-login--content-main"
|
class="page-login--content-main"
|
||||||
flex="dir:top main:center cross:center">
|
flex="dir:top main:center cross:center">
|
||||||
<!-- logo -->
|
<img class="page-login--logo" :src="`${$baseUrl}image/logo/sc_logo.png`">
|
||||||
<img class="page-login--logo" src="./image/logo@2x.png">
|
|
||||||
<!-- form -->
|
|
||||||
<div class="page-login--form">
|
<div class="page-login--form">
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<el-form
|
<el-form
|
||||||
@@ -37,7 +35,8 @@
|
|||||||
<el-input
|
<el-input
|
||||||
type="text"
|
type="text"
|
||||||
v-model="formLogin.username"
|
v-model="formLogin.username"
|
||||||
placeholder="用户名">
|
@keyup.enter.native="submit"
|
||||||
|
:placeholder="$t(key('username'))">
|
||||||
<i slot="prepend" class="fa fa-user-circle-o"></i>
|
<i slot="prepend" class="fa fa-user-circle-o"></i>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -45,139 +44,65 @@
|
|||||||
<el-input
|
<el-input
|
||||||
type="password"
|
type="password"
|
||||||
v-model="formLogin.password"
|
v-model="formLogin.password"
|
||||||
placeholder="密码">
|
@keyup.enter.native="submit"
|
||||||
|
:placeholder="$t(key('password'))">
|
||||||
<i slot="prepend" class="fa fa-keyboard-o"></i>
|
<i slot="prepend" class="fa fa-keyboard-o"></i>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="code">
|
|
||||||
<el-input
|
|
||||||
type="text"
|
|
||||||
v-model="formLogin.code"
|
|
||||||
placeholder="验证码">
|
|
||||||
<template slot="append">
|
|
||||||
<img class="login-code" src="./image/login-code.png">
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-button
|
<el-button
|
||||||
size="default"
|
size="default"
|
||||||
@click="submit"
|
@click="submit"
|
||||||
type="primary"
|
type="primary"
|
||||||
class="button-login">
|
class="button-login">
|
||||||
登录
|
{{ $t(key('login')) }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
<p
|
|
||||||
class="page-login--options"
|
|
||||||
flex="main:justify cross:center">
|
|
||||||
<span><d2-icon name="question-circle"/> 忘记密码</span>
|
|
||||||
<span>注册用户</span>
|
|
||||||
</p>
|
|
||||||
<!-- quick login -->
|
|
||||||
<el-button class="page-login--quick" size="default" type="info" @click="dialogVisible = true">
|
|
||||||
快速选择用户(测试功能)
|
|
||||||
</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="page-login--content-footer">
|
<div class="page-login--content-footer" />
|
||||||
<p class="page-login--content-footer-locales">
|
|
||||||
<a
|
|
||||||
v-for="language in $languages"
|
|
||||||
:key="language.value"
|
|
||||||
@click="onChangeLocale(language.value)">
|
|
||||||
{{ language.label }}
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
<p class="page-login--content-footer-copyright">
|
|
||||||
Copyright
|
|
||||||
<d2-icon name="copyright"/>
|
|
||||||
2018 D2 Projects 开源组织出品
|
|
||||||
<a href="https://github.com/FairyEver">
|
|
||||||
@FairyEver
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
<p class="page-login--content-footer-options">
|
|
||||||
<a href="#">帮助</a>
|
|
||||||
<a href="#">隐私</a>
|
|
||||||
<a href="#">条款</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-dialog
|
|
||||||
title="快速选择用户"
|
|
||||||
:visible.sync="dialogVisible"
|
|
||||||
width="400px">
|
|
||||||
<el-row :gutter="10" style="margin: -20px 0px -10px 0px;">
|
|
||||||
<el-col v-for="(user, index) in users" :key="index" :span="8">
|
|
||||||
<div class="page-login--quick-user" @click="handleUserBtnClick(user)">
|
|
||||||
<d2-icon name="user-circle-o"/>
|
|
||||||
<span>{{user.name}}</span>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { mapActions } from 'vuex'
|
import { mapActions } from 'vuex'
|
||||||
|
import util from '@/libs/util'
|
||||||
import localeMixin from '@/locales/mixin.js'
|
import localeMixin from '@/locales/mixin.js'
|
||||||
|
import { i18nMixin } from '@/composables/useI18n'
|
||||||
|
import '@/components/d2-icon/font-awesome-4.7.0/css/font-awesome.min.css'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [
|
mixins: [
|
||||||
localeMixin
|
localeMixin,
|
||||||
|
i18nMixin('page.system.login')
|
||||||
],
|
],
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
// 实时时钟定时器
|
||||||
timeInterval: null,
|
timeInterval: null,
|
||||||
|
// 当前时间显示
|
||||||
time: dayjs().format('HH:mm:ss'),
|
time: dayjs().format('HH:mm:ss'),
|
||||||
// 快速选择用户
|
// 登录表单数据
|
||||||
dialogVisible: false,
|
|
||||||
users: [
|
|
||||||
{
|
|
||||||
name: 'Admin',
|
|
||||||
username: 'admin',
|
|
||||||
password: 'admin'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Editor',
|
|
||||||
username: 'editor',
|
|
||||||
password: 'editor'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'User1',
|
|
||||||
username: 'user1',
|
|
||||||
password: 'user1'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
// 表单
|
|
||||||
formLogin: {
|
formLogin: {
|
||||||
username: 'admin',
|
username: '',
|
||||||
password: 'admin',
|
password: ''
|
||||||
code: 'v9am'
|
|
||||||
},
|
},
|
||||||
// 表单校验
|
// 表单校验规则
|
||||||
rules: {
|
rules: {
|
||||||
username: [
|
username: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: '请输入用户名',
|
message: this.$t(this.key('please_enter_username')),
|
||||||
trigger: 'blur'
|
trigger: 'blur'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
password: [
|
password: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: '请输入密码',
|
message: this.$t(this.key('please_enter_password')),
|
||||||
trigger: 'blur'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
code: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入验证码',
|
|
||||||
trigger: 'blur'
|
trigger: 'blur'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -185,50 +110,45 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
util.cookies.set('block', 'false')
|
||||||
|
// 启动实时时钟
|
||||||
this.timeInterval = setInterval(() => {
|
this.timeInterval = setInterval(() => {
|
||||||
this.refreshTime()
|
this.refreshTime()
|
||||||
}, 1000)
|
}, 1000)
|
||||||
},
|
},
|
||||||
beforeDestroy () {
|
beforeDestroy () {
|
||||||
|
// 销毁时清除时钟定时器
|
||||||
clearInterval(this.timeInterval)
|
clearInterval(this.timeInterval)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions('d2admin/account', [
|
...mapActions('d2admin/account', [
|
||||||
'login'
|
'login'
|
||||||
]),
|
]),
|
||||||
|
// 刷新时间显示
|
||||||
refreshTime () {
|
refreshTime () {
|
||||||
this.time = dayjs().format('HH:mm:ss')
|
this.time = dayjs().format('HH:mm:ss')
|
||||||
},
|
},
|
||||||
/**
|
// 提交登录表单
|
||||||
* @description 接收选择一个用户快速登录的事件
|
|
||||||
* @param {Object} user 用户信息
|
|
||||||
*/
|
|
||||||
handleUserBtnClick (user) {
|
|
||||||
this.formLogin.username = user.username
|
|
||||||
this.formLogin.password = user.password
|
|
||||||
this.submit()
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* @description 提交表单
|
|
||||||
*/
|
|
||||||
// 提交登录信息
|
|
||||||
submit () {
|
submit () {
|
||||||
this.$refs.loginForm.validate((valid) => {
|
this.$refs.loginForm.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
// 登录
|
// 调用 Vuex login action 进行登录
|
||||||
// 注意 这里的演示没有传验证码
|
|
||||||
// 具体需要传递的数据请自行修改代码
|
|
||||||
this.login({
|
this.login({
|
||||||
username: this.formLogin.username,
|
username: this.formLogin.username,
|
||||||
password: this.formLogin.password
|
password: this.formLogin.password
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// 重定向对象不存在则返回顶层路径
|
// 登录成功后跳转到目标页或首页
|
||||||
this.$router.replace(this.$route.query.redirect || '/')
|
this.$router.replace(this.$route.query.redirect || '/')
|
||||||
})
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
// 登录失败时清除残留的 cookie 并提示错误信息
|
||||||
|
util.cookies.remove('token')
|
||||||
|
util.cookies.remove('uuid')
|
||||||
|
this.$message.error(error.message || this.$t(this.key('form_validation_failed')))
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
// 登录表单校验失败
|
this.$message.error(this.$t(this.key('form_validation_failed')))
|
||||||
this.$message.error('表单校验失败,请检查')
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -240,33 +160,34 @@ export default {
|
|||||||
.page-login {
|
.page-login {
|
||||||
@extend %unable-select;
|
@extend %unable-select;
|
||||||
$backgroundColor: #F0F2F5;
|
$backgroundColor: #F0F2F5;
|
||||||
// ---
|
|
||||||
background-color: $backgroundColor;
|
background-color: $backgroundColor;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
// 层
|
|
||||||
.page-login--layer {
|
.page-login--layer {
|
||||||
@extend %full;
|
@extend %full;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-login--layer-area {
|
.page-login--layer-area {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
// 时间
|
|
||||||
.page-login--layer-time {
|
.page-login--layer-time {
|
||||||
font-size: 24em;
|
font-size: 24em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: rgba(0, 0, 0, 0.03);
|
color: rgba(0, 0, 0, 0.03);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
// 登陆页面控件的容器
|
|
||||||
.page-login--content {
|
.page-login--content {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
min-height: 500px;
|
min-height: 500px;
|
||||||
}
|
}
|
||||||
// header
|
|
||||||
.page-login--content-header {
|
.page-login--content-header {
|
||||||
padding: 1em 0;
|
padding: 1em 0;
|
||||||
|
|
||||||
.page-login--content-header-motto {
|
.page-login--content-header-motto {
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
@@ -275,115 +196,33 @@ export default {
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// main
|
|
||||||
.page-login--logo {
|
.page-login--logo {
|
||||||
width: 240px;
|
width: 240px;
|
||||||
margin-bottom: 2em;
|
margin-bottom: 2em;
|
||||||
margin-top: -2em;
|
margin-top: -2em;
|
||||||
}
|
}
|
||||||
// 登录表单
|
|
||||||
.page-login--form {
|
.page-login--form {
|
||||||
width: 280px;
|
width: 280px;
|
||||||
// 卡片
|
|
||||||
.el-card {
|
.el-card {
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
// 登录按钮
|
|
||||||
.button-login {
|
.button-login {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
// 输入框左边的图表区域缩窄
|
|
||||||
.el-input-group__prepend {
|
.el-input-group__prepend {
|
||||||
padding: 0px 14px;
|
padding: 0px 14px;
|
||||||
}
|
}
|
||||||
.login-code {
|
|
||||||
height: 40px - 2px;
|
|
||||||
display: block;
|
|
||||||
margin: 0px -20px;
|
|
||||||
border-top-right-radius: 2px;
|
|
||||||
border-bottom-right-radius: 2px;
|
|
||||||
}
|
|
||||||
// 登陆选项
|
|
||||||
.page-login--options {
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
font-size: 14px;
|
|
||||||
color: $color-primary;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.page-login--quick {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// 快速选择用户面板
|
|
||||||
.page-login--quick-user {
|
|
||||||
@extend %flex-center-col;
|
|
||||||
padding: 10px 0px;
|
|
||||||
border-radius: 4px;
|
|
||||||
&:hover {
|
|
||||||
background-color: $color-bg;
|
|
||||||
i {
|
|
||||||
color: $color-text-normal;
|
|
||||||
}
|
|
||||||
span {
|
|
||||||
color: $color-text-normal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i {
|
|
||||||
font-size: 36px;
|
|
||||||
color: $color-text-sub;
|
|
||||||
}
|
|
||||||
span {
|
|
||||||
font-size: 12px;
|
|
||||||
margin-top: 10px;
|
|
||||||
color: $color-text-sub;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// footer
|
|
||||||
.page-login--content-footer {
|
.page-login--content-footer {
|
||||||
padding: 1em 0;
|
padding: 1em 0;
|
||||||
.page-login--content-footer-locales {
|
|
||||||
padding: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 12px;
|
|
||||||
text-align: center;
|
|
||||||
color: $color-text-normal;
|
|
||||||
a {
|
|
||||||
color: $color-text-normal;
|
|
||||||
margin: 0 .5em;
|
|
||||||
&:hover {
|
|
||||||
color: $color-text-main;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.page-login--content-footer-copyright {
|
|
||||||
padding: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 12px;
|
|
||||||
text-align: center;
|
|
||||||
color: $color-text-normal;
|
|
||||||
a {
|
|
||||||
color: $color-text-normal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.page-login--content-footer-options {
|
|
||||||
padding: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 12px;
|
|
||||||
text-align: center;
|
|
||||||
a {
|
|
||||||
color: $color-text-normal;
|
|
||||||
margin: 0 1em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// 背景
|
|
||||||
.circles {
|
.circles {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
@@ -393,6 +232,7 @@ export default {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: block;
|
display: block;
|
||||||
@@ -402,24 +242,27 @@ export default {
|
|||||||
background: #FFF;
|
background: #FFF;
|
||||||
animation: animate 25s linear infinite;
|
animation: animate 25s linear infinite;
|
||||||
bottom: -200px;
|
bottom: -200px;
|
||||||
|
|
||||||
@keyframes animate {
|
@keyframes animate {
|
||||||
0%{
|
0% {
|
||||||
transform: translateY(0) rotate(0deg);
|
transform: translateY(0) rotate(0deg);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
100%{
|
100% {
|
||||||
transform: translateY(-1000px) rotate(720deg);
|
transform: translateY(-1000px) rotate(720deg);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:nth-child(1) {
|
&:nth-child(1) {
|
||||||
left: 15%;
|
left: 15%;
|
||||||
width: 80px;
|
width: 80px;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
animation-delay: 0s;
|
animation-delay: 0s;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:nth-child(2) {
|
&:nth-child(2) {
|
||||||
left: 5%;
|
left: 5%;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
@@ -427,12 +270,14 @@ export default {
|
|||||||
animation-delay: 2s;
|
animation-delay: 2s;
|
||||||
animation-duration: 12s;
|
animation-duration: 12s;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:nth-child(3) {
|
&:nth-child(3) {
|
||||||
left: 70%;
|
left: 70%;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
animation-delay: 4s;
|
animation-delay: 4s;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:nth-child(4) {
|
&:nth-child(4) {
|
||||||
left: 40%;
|
left: 40%;
|
||||||
width: 60px;
|
width: 60px;
|
||||||
@@ -440,24 +285,28 @@ export default {
|
|||||||
animation-delay: 0s;
|
animation-delay: 0s;
|
||||||
animation-duration: 18s;
|
animation-duration: 18s;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:nth-child(5) {
|
&:nth-child(5) {
|
||||||
left: 65%;
|
left: 65%;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
animation-delay: 0s;
|
animation-delay: 0s;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:nth-child(6) {
|
&:nth-child(6) {
|
||||||
left: 75%;
|
left: 75%;
|
||||||
width: 150px;
|
width: 150px;
|
||||||
height: 150px;
|
height: 150px;
|
||||||
animation-delay: 3s;
|
animation-delay: 3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:nth-child(7) {
|
&:nth-child(7) {
|
||||||
left: 35%;
|
left: 35%;
|
||||||
width: 200px;
|
width: 200px;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
animation-delay: 7s;
|
animation-delay: 7s;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:nth-child(8) {
|
&:nth-child(8) {
|
||||||
left: 50%;
|
left: 50%;
|
||||||
width: 25px;
|
width: 25px;
|
||||||
@@ -465,6 +314,7 @@ export default {
|
|||||||
animation-delay: 15s;
|
animation-delay: 15s;
|
||||||
animation-duration: 45s;
|
animation-duration: 45s;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:nth-child(9) {
|
&:nth-child(9) {
|
||||||
left: 20%;
|
left: 20%;
|
||||||
width: 15px;
|
width: 15px;
|
||||||
@@ -472,6 +322,7 @@ export default {
|
|||||||
animation-delay: 2s;
|
animation-delay: 2s;
|
||||||
animation-duration: 35s;
|
animation-duration: 35s;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:nth-child(10) {
|
&:nth-child(10) {
|
||||||
left: 85%;
|
left: 85%;
|
||||||
width: 150px;
|
width: 150px;
|
||||||
|
|||||||
Reference in New Issue
Block a user