这是基于vue-vben-admin 模板适用于abp Vnext的前端管理项目
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.
 
 
 
 
 
 

340 lines
8.7 KiB

<template>
<div class="login-container">
<el-form
ref="formResetPassword"
:model="resetPasswordForm"
:rules="resetPasswordFormRules"
label-position="left"
label-width="0px"
class="demo-ruleForm login-page"
>
<div class="title-container">
<h3 class="title">
{{ $t('login.resetpassword') }}
</h3>
<lang-select class="set-language" />
</div>
<el-form-item label-width="0px">
<tenant-box
v-if="isMultiEnabled"
v-model="resetPasswordForm.tenantName"
/>
</el-form-item>
<el-form-item
prop="phoneNumber"
>
<el-input
v-model="resetPasswordForm.phoneNumber"
prefix-icon="el-icon-mobile-phone"
type="text"
maxlength="11"
auto-complete="off"
:placeholder="$t('global.pleaseInputBy', {key: $t('login.phoneNumber')})"
/>
</el-form-item>
<el-form-item
prop="verifyCode"
>
<el-row>
<el-col :span="16">
<el-input
v-model="resetPasswordForm.verifyCode"
auto-complete="off"
:placeholder="$t('global.pleaseInputBy', {key: $t('login.phoneVerifyCode')})"
prefix-icon="el-icon-key"
style="margin:-right: 10px;"
/>
</el-col>
<el-col :span="8">
<el-button
ref="sendButton"
style="margin-left: 10px;width: 132px;"
:disabled="sending"
@click="handleSendPhoneVerifyCode"
>
{{ sendButtonName }}
</el-button>
</el-col>
</el-row>
</el-form-item>
<el-form-item
prop="newPassword"
>
<el-input
:key="passwordType"
ref="newPassword"
v-model="resetPasswordForm.newPassword"
prefix-icon="el-icon-lock"
:type="passwordType"
:placeholder="$t('global.pleaseInputBy', {key: $t('login.password')})"
name="newPassword"
tabindex="2"
@keyup.enter.native="handleResetPassword"
/>
<span
class="show-pwd"
@click="showPwd"
>
<svg-icon :name="passwordType === 'password' ? 'eye-off' : 'eye-on'" />
</span>
</el-form-item>
<el-form-item
label-width="100px"
:label="$t('login.existsAccount')"
>
<el-link
type="success"
@click="handleRedirectLogin"
>
{{ $t('login.logIn') }}
</el-link>
</el-form-item>
<el-form-item style="width:100%;">
<el-button
type="primary"
style="width:100%;"
:loading="reseting"
@click="handleResetPassword"
>
{{ $t('login.resetpassword') }}
</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script lang="ts">
import { Input } from 'element-ui'
import { Route } from 'vue-router'
import { Dictionary } from 'vue-router/types/router'
import TenantBox from '@/components/TenantBox/index.vue'
import LangSelect from '@/components/LangSelect/index.vue'
import { Component, Vue, Watch } from 'vue-property-decorator'
import UserService, { PhoneVerify, VerifyType, UserResetPasswordData } from '@/api/users'
import { AbpConfigurationModule } from '@/store/modules/abp'
@Component({
name: 'Register',
components: {
LangSelect,
TenantBox
}
})
export default class extends Vue {
private passwordType = 'password'
private redirect?: string
private sendTimer: any
private sending = false
private sendButtonName = this.l('login.sendVerifyCode')
private reseting = false
private resetPasswordForm = {
tenantName: '',
newPassword: '',
phoneNumber: '',
verifyCode: ''
}
get isMultiEnabled() {
return AbpConfigurationModule.configuration?.multiTenancy?.isEnabled
}
private validatePhoneNumberValue = (rule: any, value: string, callback: any) => {
const phoneReg = /^1[34578]\d{9}$/
if (!value || !phoneReg.test(value)) {
callback(new Error(this.l('global.pleaseInputBy', { key: this.l('global.correctPhoneNumber') })))
} else {
callback()
}
}
private resetPasswordFormRules = {
newPassword: [
{
required: true, message: this.l('global.pleaseInputBy', { key: this.l('login.password') }), trigger: 'blur'
}
],
phoneNumber: [
{
required: true, validator: this.validatePhoneNumberValue, trigger: 'blur'
}
],
verifyCode: [
{
required: true, message: this.l('global.pleaseInputBy', { key: this.l('login.phoneVerifyCode') }), trigger: 'blur'
}
]
}
destroyed() {
if (this.sendTimer) {
clearInterval(this.sendTimer)
}
}
@Watch('$route', { immediate: true })
private onRouteChange(route: Route) {
// TODO: remove the "as Dictionary<string>" hack after v4 release for vue-router
// See https://github.com/vuejs/vue-router/pull/2050 for details
const query = route.query as Dictionary<string>
if (query) {
this.redirect = query.redirect
}
}
private showPwd() {
if (this.passwordType === 'password') {
this.passwordType = ''
} else {
this.passwordType = 'password'
}
this.$nextTick(() => {
(this.$refs.newPassword as Input).focus()
})
}
private handleRedirectLogin() {
this.$router.replace('login')
}
private handleResetPassword() {
const frmResetPassword = this.$refs.formResetPassword as any
frmResetPassword.validate(async(valid: boolean) => {
if (valid) {
this.reseting = true
try {
const userReserPassword = new UserResetPasswordData()
userReserPassword.phoneNumber = this.resetPasswordForm.phoneNumber
userReserPassword.verifyCode = this.resetPasswordForm.verifyCode
userReserPassword.newPassword = this.resetPasswordForm.newPassword
UserService.resetPassword(userReserPassword).then(() => {
this.handleRedirectLogin()
}).finally(() => {
this.resetLoginButton()
})
} catch {
this.resetLoginButton()
}
}
})
}
private handleSendPhoneVerifyCode() {
const frmResetPassword = this.$refs.formResetPassword as any
frmResetPassword.validateField('phoneNumber', (errorMsg: string) => {
if (!errorMsg) {
this.sending = true
const phoneVerify = new PhoneVerify()
phoneVerify.phoneNumber = this.resetPasswordForm.phoneNumber
phoneVerify.verifyType = VerifyType.ResetPassword
UserService.sendPhoneVerifyCode(phoneVerify).then(() => {
let interValTime = 60
const sendingName = this.l('login.afterSendVerifyCode')
const sendedName = this.l('login.sendVerifyCode')
this.sendTimer = setInterval(() => {
this.sendButtonName = interValTime + sendingName
--interValTime
if (interValTime < 0) {
this.sendButtonName = sendedName
this.sending = false
clearInterval(this.sendTimer)
}
}, 1000)
}).catch(() => {
this.sending = false
})
}
})
}
private l(name: string, values?: any[] | { [key: string]: any }) {
return this.$t(name, values).toString()
}
private resetLoginButton() {
setTimeout(() => {
this.reseting = false
}, 0.5 * 1000)
}
}
</script>
<style lang="scss" scoped>
.login-container {
width: 100%;
height: 100%;
overflow-x: hidden;
overflow-y: auto;
background-color: $loginBg;
.svg-container {
padding: 6px 5px 6px 15px;
color: $darkGray;
vertical-align: middle;
width: 30px;
display: inline-block;
}
.title-container {
position: relative;
.title {
font-size: 26px;
margin: 0px auto 20px auto;
text-align: center;
font-weight: bold;
}
.tips {
font-size: 14px;
color: #fff;
margin-bottom: 10px;
span {
&:first-of-type {
margin-right: 16px;
}
}
}
.set-language {
position: absolute;
top: 3px;
font-size: 18px;
right: 0px;
cursor: pointer;
}
}
.show-pwd {
position: absolute;
right: 10px;
font-size: 16px;
color: $darkGray;
cursor: pointer;
user-select: none;
}
}
.login-page {
-webkit-border-radius: 5px;
border-radius: 5px;
margin: 130px auto;
width: 500px;
padding: 35px 35px 15px;
border: 1px solid #8c9494;
box-shadow: 0 0 25px #454646;
background-color:rgb(247, 255, 255);
.loginTab.el-tabs__item {
width: 180px;
}
}
label.el-checkbox.rememberme {
margin: 0px 0px 15px;
text-align: left;
}
</style>