mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-05 15:36:49 +08:00
fix #91 otp ui
This commit is contained in:
@@ -428,7 +428,7 @@ watch(() => props.plugin?.has_update, (newHasUpdate, oldHasUpdate) => {
|
|||||||
</div>
|
</div>
|
||||||
<span v-if="props.count" class="absolute bottom-1 right-2 flex items-center">
|
<span v-if="props.count" class="absolute bottom-1 right-2 flex items-center">
|
||||||
<VIcon icon="mdi-fire" />
|
<VIcon icon="mdi-fire" />
|
||||||
<span class="text-sm ms-1">{{ props.count }}</span>
|
<span class="text-sm ms-1">{{ props.count?.toLocaleString() }}</span>
|
||||||
</span>
|
</span>
|
||||||
<VCardItem class="py-2">
|
<VCardItem class="py-2">
|
||||||
<VCardTitle class="flex items-center flex-row">
|
<VCardTitle class="flex items-center flex-row">
|
||||||
|
|||||||
+1
-1
@@ -179,8 +179,8 @@ onMounted(() => {
|
|||||||
</VCol>
|
</VCol>
|
||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
<VTextField
|
<VTextField
|
||||||
hint="非必传,如开启二次验证需填写"
|
|
||||||
v-model="form.otp_password"
|
v-model="form.otp_password"
|
||||||
|
hint="非必须,如开启二次验证需填写"
|
||||||
label="二次验证"
|
label="二次验证"
|
||||||
type="input"
|
type="input"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useToast } from 'vue-toast-notification'
|
import { useToast } from 'vue-toast-notification'
|
||||||
|
import QrcodeVue from 'qrcode.vue'
|
||||||
|
import { VForm } from 'vuetify/lib/components/index.mjs'
|
||||||
import { requiredValidator } from '@/@validators'
|
import { requiredValidator } from '@/@validators'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import type { User } from '@/api/types'
|
import type { User } from '@/api/types'
|
||||||
import avatar1 from '@images/avatars/avatar-1.png'
|
import avatar1 from '@images/avatars/avatar-1.png'
|
||||||
import QrcodeVue from 'qrcode.vue'
|
|
||||||
|
|
||||||
const isNewPasswordVisible = ref(false)
|
const isNewPasswordVisible = ref(false)
|
||||||
const isConfirmPasswordVisible = ref(false)
|
const isConfirmPasswordVisible = ref(false)
|
||||||
@@ -48,7 +49,7 @@ const accountInfo = ref<User>({
|
|||||||
is_active: false,
|
is_active: false,
|
||||||
is_superuser: false,
|
is_superuser: false,
|
||||||
avatar: '',
|
avatar: '',
|
||||||
is_otp: false
|
is_otp: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
// 所有用户信息
|
// 所有用户信息
|
||||||
@@ -193,10 +194,12 @@ async function getOtpUri() {
|
|||||||
secret.value = result.data.secret
|
secret.value = result.data.secret
|
||||||
qrCode.value = result.data.uri
|
qrCode.value = result.data.uri
|
||||||
otpDialog.value = true
|
otpDialog.value = true
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
$toast.error(`获取otp uri失败:${result.message}!`)
|
$toast.error(`获取otp uri失败:${result.message}!`)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
}
|
||||||
|
catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -206,28 +209,29 @@ async function disableOtp() {
|
|||||||
try {
|
try {
|
||||||
const result: { [key: string]: any } = await api.post('user/otp/disable')
|
const result: { [key: string]: any } = await api.post('user/otp/disable')
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
accountInfo.value.is_otp = false;
|
accountInfo.value.is_otp = false
|
||||||
$toast.success('关闭二次验证成功!')
|
$toast.success('关闭登录二次验证成功!')
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$toast.error(`关闭otp失败:${result.message}!`)
|
$toast.error(`关闭otp失败:${result.message}!`)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
}
|
||||||
|
catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 启用Otp
|
// 启用Otp
|
||||||
async function judgeOtpPassword() {
|
async function judgeOtpPassword() {
|
||||||
if (!otpPassword) {
|
if (!otpPassword.value) {
|
||||||
$toast.error('请填写6位验证码')
|
$toast.error('请填写6位验证码')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const result: { [key: string]: any } = await api.post('user/otp/judge', {'uri': otpUri.value, 'otpPassword': otpPassword.value})
|
const result: { [key: string]: any } = await api.post('user/otp/judge', { uri: otpUri.value, otpPassword: otpPassword.value })
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
$toast.success('开启二次验证成功!')
|
$toast.success('开启登录二次验证成功!')
|
||||||
otpDialog.value = false
|
otpDialog.value = false
|
||||||
accountInfo.value.is_otp = true
|
accountInfo.value.is_otp = true
|
||||||
}
|
}
|
||||||
@@ -267,10 +271,11 @@ onMounted(() => {
|
|||||||
color="primary"
|
color="primary"
|
||||||
@click="refInputEl?.click()"
|
@click="refInputEl?.click()"
|
||||||
>
|
>
|
||||||
|
<template #prepend>
|
||||||
<VIcon
|
<VIcon
|
||||||
icon="mdi-cloud-upload-outline"
|
icon="mdi-cloud-upload-outline"
|
||||||
class="d-sm-none"
|
|
||||||
/>
|
/>
|
||||||
|
</template>
|
||||||
<span class="d-none d-sm-block">上传头像</span>
|
<span class="d-none d-sm-block">上传头像</span>
|
||||||
</VBtn>
|
</VBtn>
|
||||||
|
|
||||||
@@ -289,21 +294,25 @@ onMounted(() => {
|
|||||||
variant="tonal"
|
variant="tonal"
|
||||||
@click="resetAvatar"
|
@click="resetAvatar"
|
||||||
>
|
>
|
||||||
<span class="d-none d-sm-block">重置</span>
|
<template #prepend>
|
||||||
<VIcon
|
<VIcon
|
||||||
icon="mdi-refresh"
|
icon="mdi-refresh"
|
||||||
class="d-sm-none"
|
|
||||||
/>
|
/>
|
||||||
|
</template>
|
||||||
|
<span class="d-none d-sm-block">重置</span>
|
||||||
</VBtn>
|
</VBtn>
|
||||||
|
|
||||||
<VBtn
|
<VBtn
|
||||||
:color="accountInfo.is_otp? 'error': 'info'"
|
:color="accountInfo.is_otp ? 'error' : 'info'"
|
||||||
@click.stop="accountInfo.is_otp? disableOtp(): getOtpUri()"
|
variant="tonal"
|
||||||
|
@click.stop="accountInfo.is_otp ? disableOtp() : getOtpUri()"
|
||||||
>
|
>
|
||||||
|
<template #prepend>
|
||||||
<VIcon
|
<VIcon
|
||||||
icon="mdi-account-key"
|
icon="mdi-account-key"
|
||||||
/>
|
/>
|
||||||
<span class="d-none d-sm-block">{{accountInfo.is_otp? "关闭验证": "二次验证"}}</span>
|
</template>
|
||||||
|
<span class="d-none d-sm-block">{{ accountInfo.is_otp ? "关闭验证" : "二次验证" }}</span>
|
||||||
</VBtn>
|
</VBtn>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -351,11 +360,9 @@ onMounted(() => {
|
|||||||
<VTextField
|
<VTextField
|
||||||
v-model="newPassword"
|
v-model="newPassword"
|
||||||
:type="isNewPasswordVisible ? 'text' : 'password'"
|
:type="isNewPasswordVisible ? 'text' : 'password'"
|
||||||
:append-inner-icon="
|
:append-inner-icon="isNewPasswordVisible ? 'mdi-eye-off-outline' : 'mdi-eye-outline'"
|
||||||
isNewPasswordVisible ? 'mdi-eye-off-outline' : 'mdi-eye-outline'
|
|
||||||
"
|
|
||||||
label="新密码"
|
label="新密码"
|
||||||
autocomplete="new-password"
|
autocomplete=""
|
||||||
@click:append-inner="isNewPasswordVisible = !isNewPasswordVisible"
|
@click:append-inner="isNewPasswordVisible = !isNewPasswordVisible"
|
||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
@@ -557,46 +564,56 @@ onMounted(() => {
|
|||||||
<!-- 二次验证弹窗 -->
|
<!-- 二次验证弹窗 -->
|
||||||
<VDialog
|
<VDialog
|
||||||
v-model="otpDialog"
|
v-model="otpDialog"
|
||||||
max-width="40rem"
|
max-width="45rem"
|
||||||
persistent
|
persistent
|
||||||
z-index="1010"
|
z-index="1010"
|
||||||
>
|
>
|
||||||
<!-- 开启二次验证弹窗内容 -->
|
<!-- 开启二次验证弹窗内容 -->
|
||||||
<VCard title="二次验证">
|
<VCard>
|
||||||
|
<DialogCloseBtn @click="otpDialog = false" />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VRow>
|
<h4 class="text-h4 text-center mb-6 mt-5">
|
||||||
<VCol>
|
登录二次验证
|
||||||
<QrcodeVue :value="qrCode" :size="200" max-width="25rem"/>
|
</h4><h5 class="text-h5 font-weight-medium mb-2">
|
||||||
</VCol>
|
身份验证器
|
||||||
<VCol>
|
</h5>
|
||||||
<VRow>
|
<p class="mb-6">
|
||||||
1、你可以使用 Microsoft Authenticator (谷歌或其他支持软件如Keeper等) 软件扫描左侧二维码
|
使用像Google Authenticator、Microsoft Authenticator、Authy或1Password这样的身份验证器应用程序,扫描二维码。它将为您生成一个6位数的代码,供您在下方输入。
|
||||||
或者在 APP 中手动输入以下 Key
|
</p>
|
||||||
<h1>{{secret}}</h1>
|
<div class="my-6">
|
||||||
</VRow>
|
<QrcodeVue class="mx-auto" :value="qrCode" :size="200" max-width="25rem" />
|
||||||
<VRow>
|
</div>
|
||||||
2、在 APP 中获取6位验证码并输入
|
<VAlert
|
||||||
</VRow>
|
:title="secret"
|
||||||
<VRow>
|
variant="tonal"
|
||||||
|
type="warning"
|
||||||
|
class="my-4"
|
||||||
|
text="如果您在使用二维码时遇到困难,请在您的应用程序中选择手动输入以上代码。"
|
||||||
|
>
|
||||||
|
<template #prepend />
|
||||||
|
</VAlert>
|
||||||
|
<VForm>
|
||||||
<VTextField
|
<VTextField
|
||||||
v-model="otpPassword"
|
v-model="otpPassword"
|
||||||
type="text"
|
type="text"
|
||||||
label="输入验证码以确认开启双重验证"
|
label="输入验证码以确认开启双重验证"
|
||||||
autocomplete="otpPassword"
|
autocomplete=""
|
||||||
|
class="mb-8"
|
||||||
|
variant="outlined"
|
||||||
/>
|
/>
|
||||||
</VRow>
|
<div class="d-flex justify-end flex-wrap gap-4">
|
||||||
</VCol>
|
<VBtn variant="outlined" color="secondary" @click="otpDialog = false">
|
||||||
</VRow>
|
|
||||||
</VCardText>
|
|
||||||
<VCardActions>
|
|
||||||
<VBtn @click="otpDialog = false">
|
|
||||||
取消
|
取消
|
||||||
</VBtn>
|
</VBtn>
|
||||||
<VSpacer />
|
|
||||||
<VBtn @click="judgeOtpPassword">
|
<VBtn @click="judgeOtpPassword">
|
||||||
确定
|
确定
|
||||||
|
<template #append>
|
||||||
|
<VIcon icon="mdi-check" />
|
||||||
|
</template>
|
||||||
</VBtn>
|
</VBtn>
|
||||||
</VCardActions>
|
</div>
|
||||||
|
</VForm>
|
||||||
|
</VCardText>
|
||||||
</VCard>
|
</VCard>
|
||||||
</VDialog>
|
</VDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user