mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-05-27 11:19:45 +08:00
fix: 账号设置warning问题
This commit is contained in:
@@ -252,362 +252,364 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow>
|
||||
<VCol cols="12">
|
||||
<VCard title="个人信息">
|
||||
<VCardText class="d-flex">
|
||||
<!-- 👉 Avatar -->
|
||||
<VAvatar
|
||||
rounded="lg"
|
||||
size="100"
|
||||
class="me-6"
|
||||
:image="accountInfo.avatar"
|
||||
/>
|
||||
<div>
|
||||
<VRow>
|
||||
<VCol cols="12">
|
||||
<VCard title="个人信息">
|
||||
<VCardText class="d-flex">
|
||||
<!-- 👉 Avatar -->
|
||||
<VAvatar
|
||||
rounded="lg"
|
||||
size="100"
|
||||
class="me-6"
|
||||
:image="accountInfo.avatar"
|
||||
/>
|
||||
|
||||
<!-- 👉 Upload Photo -->
|
||||
<form class="d-flex flex-column justify-center gap-5">
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<VBtn
|
||||
color="primary"
|
||||
@click="refInputEl?.click()"
|
||||
>
|
||||
<VIcon
|
||||
icon="mdi-cloud-upload-outline"
|
||||
/>
|
||||
<span class="d-none d-sm-block ms-2">上传头像</span>
|
||||
</VBtn>
|
||||
|
||||
<input
|
||||
ref="refInputEl"
|
||||
type="file"
|
||||
name="file"
|
||||
accept=".jpeg,.png,.jpg,GIF"
|
||||
hidden
|
||||
@input="changeAvatar"
|
||||
>
|
||||
|
||||
<VBtn
|
||||
type="reset"
|
||||
color="error"
|
||||
variant="tonal"
|
||||
@click="resetAvatar"
|
||||
>
|
||||
<VIcon
|
||||
icon="mdi-refresh"
|
||||
/>
|
||||
<span class="d-none d-sm-block ms-2">重置</span>
|
||||
</VBtn>
|
||||
|
||||
<VBtn
|
||||
:color="accountInfo.is_otp ? 'error' : 'info'"
|
||||
variant="tonal"
|
||||
@click.stop="accountInfo.is_otp ? disableOtp() : getOtpUri()"
|
||||
>
|
||||
<VIcon
|
||||
icon="mdi-account-key"
|
||||
/>
|
||||
<span class="d-none d-sm-block ms-2">{{ accountInfo.is_otp ? "关闭验证" : "双重验证" }}</span>
|
||||
</VBtn>
|
||||
</div>
|
||||
|
||||
<p class="text-body-1 mb-0">
|
||||
允许 JPG、GIF 或 PNG 格式, 最大尺寸 800K。
|
||||
</p>
|
||||
</form>
|
||||
</VCardText>
|
||||
|
||||
<VDivider />
|
||||
|
||||
<VCardText>
|
||||
<!-- 👉 Form -->
|
||||
<VForm class="mt-6">
|
||||
<VRow>
|
||||
<!-- 👉 Name -->
|
||||
<VCol
|
||||
md="6"
|
||||
cols="12"
|
||||
>
|
||||
<VTextField
|
||||
v-model="accountInfo.name"
|
||||
readonly
|
||||
label="用户名"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Email -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VTextField
|
||||
v-model="accountInfo.email"
|
||||
label="邮箱"
|
||||
type="email"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<!-- 👉 new password -->
|
||||
<VTextField
|
||||
v-model="newPassword"
|
||||
:type="isNewPasswordVisible ? 'text' : 'password'"
|
||||
:append-inner-icon="isNewPasswordVisible ? 'mdi-eye-off-outline' : 'mdi-eye-outline'"
|
||||
label="新密码"
|
||||
autocomplete=""
|
||||
@click:append-inner="isNewPasswordVisible = !isNewPasswordVisible"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<!-- 👉 confirm password -->
|
||||
<VTextField
|
||||
v-model="confirmPassword"
|
||||
:type="isConfirmPasswordVisible ? 'text' : 'password'"
|
||||
:append-inner-icon="
|
||||
isConfirmPasswordVisible ? 'mdi-eye-off-outline' : 'mdi-eye-outline'
|
||||
"
|
||||
label="确认新密码"
|
||||
@click:append-inner="
|
||||
isConfirmPasswordVisible = !isConfirmPasswordVisible
|
||||
"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Form Actions -->
|
||||
<VCol
|
||||
cols="12"
|
||||
class="d-flex flex-wrap gap-4"
|
||||
>
|
||||
<VBtn @click="saveAccountInfo">
|
||||
保存
|
||||
<!-- 👉 Upload Photo -->
|
||||
<form class="d-flex flex-column justify-center gap-5">
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<VBtn
|
||||
color="primary"
|
||||
@click="refInputEl?.click()"
|
||||
>
|
||||
<VIcon
|
||||
icon="mdi-cloud-upload-outline"
|
||||
/>
|
||||
<span class="d-none d-sm-block ms-2">上传头像</span>
|
||||
</VBtn>
|
||||
|
||||
<input
|
||||
ref="refInputEl"
|
||||
type="file"
|
||||
name="file"
|
||||
accept=".jpeg,.png,.jpg,GIF"
|
||||
hidden
|
||||
@input="changeAvatar"
|
||||
>
|
||||
|
||||
<VBtn
|
||||
type="reset"
|
||||
color="error"
|
||||
variant="tonal"
|
||||
@click="resetAvatar"
|
||||
>
|
||||
<VIcon
|
||||
icon="mdi-refresh"
|
||||
/>
|
||||
<span class="d-none d-sm-block ms-2">重置</span>
|
||||
</VBtn>
|
||||
|
||||
<VBtn
|
||||
:color="accountInfo.is_otp ? 'error' : 'info'"
|
||||
variant="tonal"
|
||||
@click.stop="accountInfo.is_otp ? disableOtp() : getOtpUri()"
|
||||
>
|
||||
<VIcon
|
||||
icon="mdi-account-key"
|
||||
/>
|
||||
<span class="d-none d-sm-block ms-2">{{ accountInfo.is_otp ? "关闭验证" : "双重验证" }}</span>
|
||||
</VBtn>
|
||||
</div>
|
||||
|
||||
<p class="text-body-1 mb-0">
|
||||
允许 JPG、GIF 或 PNG 格式, 最大尺寸 800K。
|
||||
</p>
|
||||
</form>
|
||||
</VCardText>
|
||||
|
||||
<VDivider />
|
||||
|
||||
<VCardText>
|
||||
<!-- 👉 Form -->
|
||||
<VForm class="mt-6">
|
||||
<VRow>
|
||||
<!-- 👉 Name -->
|
||||
<VCol
|
||||
md="6"
|
||||
cols="12"
|
||||
>
|
||||
<VTextField
|
||||
v-model="accountInfo.name"
|
||||
readonly
|
||||
label="用户名"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Email -->
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VTextField
|
||||
v-model="accountInfo.email"
|
||||
label="邮箱"
|
||||
type="email"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<!-- 👉 new password -->
|
||||
<VTextField
|
||||
v-model="newPassword"
|
||||
:type="isNewPasswordVisible ? 'text' : 'password'"
|
||||
:append-inner-icon="isNewPasswordVisible ? 'mdi-eye-off-outline' : 'mdi-eye-outline'"
|
||||
label="新密码"
|
||||
autocomplete=""
|
||||
@click:append-inner="isNewPasswordVisible = !isNewPasswordVisible"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<!-- 👉 confirm password -->
|
||||
<VTextField
|
||||
v-model="confirmPassword"
|
||||
:type="isConfirmPasswordVisible ? 'text' : 'password'"
|
||||
:append-inner-icon="
|
||||
isConfirmPasswordVisible ? 'mdi-eye-off-outline' : 'mdi-eye-outline'
|
||||
"
|
||||
label="确认新密码"
|
||||
@click:append-inner="
|
||||
isConfirmPasswordVisible = !isConfirmPasswordVisible
|
||||
"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<!-- 👉 Form Actions -->
|
||||
<VCol
|
||||
cols="12"
|
||||
class="d-flex flex-wrap gap-4"
|
||||
>
|
||||
<VBtn @click="saveAccountInfo">
|
||||
保存
|
||||
</VBtn>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
|
||||
<VCol
|
||||
v-if="accountInfo.is_superuser"
|
||||
cols="12"
|
||||
>
|
||||
<!-- 👉 Accounts -->
|
||||
<VCard title="所有用户">
|
||||
<template #append>
|
||||
<IconBtn @click.stop="addUserDialog = true">
|
||||
<VIcon icon="mdi-plus" />
|
||||
</IconBtn>
|
||||
</template>
|
||||
<VTable class="text-no-wrap">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">
|
||||
用户名
|
||||
</th>
|
||||
<th scope="col">
|
||||
邮箱
|
||||
</th>
|
||||
<th scope="col">
|
||||
状态
|
||||
</th>
|
||||
<th scope="col">
|
||||
管理员
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="w-5"
|
||||
/>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="user in allUsers"
|
||||
:key="user.name"
|
||||
>
|
||||
<td>
|
||||
{{ user.name }}
|
||||
</td>
|
||||
<td>{{ user.email }}</td>
|
||||
<td>
|
||||
<VChip
|
||||
v-if="user.is_active"
|
||||
color="success"
|
||||
text-color="white"
|
||||
>
|
||||
激活
|
||||
</VChip>
|
||||
<VChip
|
||||
v-else
|
||||
color="error"
|
||||
text-color="white"
|
||||
>
|
||||
冻结
|
||||
</VChip>
|
||||
</td>
|
||||
<td>{{ user.is_superuser ? "是" : "否" }}</td>
|
||||
<td>
|
||||
<IconBtn v-show="accountInfo.is_superuser && accountInfo.name !== user.name">
|
||||
<VIcon icon="mdi-dots-vertical" />
|
||||
<VMenu
|
||||
activator="parent"
|
||||
close-on-content-click
|
||||
>
|
||||
<VList>
|
||||
<VListItem
|
||||
variant="plain"
|
||||
@click="deactivateUser(user)"
|
||||
>
|
||||
<template #prepend>
|
||||
<VIcon icon="mdi-lock" />
|
||||
</template>
|
||||
<VListItemTitle>
|
||||
{{
|
||||
user.is_active ? "冻结" : "解冻"
|
||||
}}
|
||||
</VListItemTitle>
|
||||
</VListItem>
|
||||
<VListItem
|
||||
variant="plain"
|
||||
base-color="error"
|
||||
@click="deleteUser(user)"
|
||||
>
|
||||
<template #prepend>
|
||||
<VIcon icon="mdi-delete" />
|
||||
</template>
|
||||
<VListItemTitle>删除</VListItemTitle>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VMenu>
|
||||
</IconBtn>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</VTable>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
<!-- =弹窗 -->
|
||||
<VDialog
|
||||
v-model="addUserDialog"
|
||||
max-width="50rem"
|
||||
persistent
|
||||
z-index="1010"
|
||||
>
|
||||
<!-- Dialog Content -->
|
||||
<VCard title="新增用户">
|
||||
<VCardText>
|
||||
<VForm @submit.prevent="() => {}">
|
||||
<VRow>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VTextField
|
||||
v-model="userForm.name"
|
||||
label="用户名"
|
||||
:rules="[requiredValidator]"
|
||||
/>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VTextField
|
||||
v-model="userForm.password"
|
||||
label="密码"
|
||||
:rules="[requiredValidator]"
|
||||
:type="isPasswordVisible ? 'text' : 'password'"
|
||||
:append-inner-icon="
|
||||
isPasswordVisible ? 'mdi-eye-off-outline' : 'mdi-eye-outline'
|
||||
"
|
||||
@click:append-inner="isPasswordVisible = !isPasswordVisible"
|
||||
/>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VTextField
|
||||
v-model="userForm.email"
|
||||
:rules="[requiredValidator]"
|
||||
label="邮箱"
|
||||
/>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
<VCardActions>
|
||||
<VBtn @click="addUserDialog = false">
|
||||
取消
|
||||
</VBtn>
|
||||
<VSpacer />
|
||||
<VBtn @click="addUser">
|
||||
确定
|
||||
</VBtn>
|
||||
</VCardActions>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VDialog>
|
||||
|
||||
<VCol
|
||||
v-if="accountInfo.is_superuser"
|
||||
cols="12"
|
||||
<!-- 双重验证弹窗 -->
|
||||
<VDialog
|
||||
v-model="otpDialog"
|
||||
max-width="45rem"
|
||||
persistent
|
||||
z-index="1010"
|
||||
>
|
||||
<!-- 👉 Accounts -->
|
||||
<VCard title="所有用户">
|
||||
<template #append>
|
||||
<IconBtn @click.stop="addUserDialog = true">
|
||||
<VIcon icon="mdi-plus" />
|
||||
</IconBtn>
|
||||
</template>
|
||||
<VTable class="text-no-wrap">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">
|
||||
用户名
|
||||
</th>
|
||||
<th scope="col">
|
||||
邮箱
|
||||
</th>
|
||||
<th scope="col">
|
||||
状态
|
||||
</th>
|
||||
<th scope="col">
|
||||
管理员
|
||||
</th>
|
||||
<th
|
||||
scope="col"
|
||||
class="w-5"
|
||||
/>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="user in allUsers"
|
||||
:key="user.name"
|
||||
>
|
||||
<td>
|
||||
{{ user.name }}
|
||||
</td>
|
||||
<td>{{ user.email }}</td>
|
||||
<td>
|
||||
<VChip
|
||||
v-if="user.is_active"
|
||||
color="success"
|
||||
text-color="white"
|
||||
>
|
||||
激活
|
||||
</VChip>
|
||||
<VChip
|
||||
v-else
|
||||
color="error"
|
||||
text-color="white"
|
||||
>
|
||||
冻结
|
||||
</VChip>
|
||||
</td>
|
||||
<td>{{ user.is_superuser ? "是" : "否" }}</td>
|
||||
<td>
|
||||
<IconBtn v-show="accountInfo.is_superuser && accountInfo.name !== user.name">
|
||||
<VIcon icon="mdi-dots-vertical" />
|
||||
<VMenu
|
||||
activator="parent"
|
||||
close-on-content-click
|
||||
>
|
||||
<VList>
|
||||
<VListItem
|
||||
variant="plain"
|
||||
@click="deactivateUser(user)"
|
||||
>
|
||||
<template #prepend>
|
||||
<VIcon icon="mdi-lock" />
|
||||
</template>
|
||||
<VListItemTitle>
|
||||
{{
|
||||
user.is_active ? "冻结" : "解冻"
|
||||
}}
|
||||
</VListItemTitle>
|
||||
</VListItem>
|
||||
<VListItem
|
||||
variant="plain"
|
||||
base-color="error"
|
||||
@click="deleteUser(user)"
|
||||
>
|
||||
<template #prepend>
|
||||
<VIcon icon="mdi-delete" />
|
||||
</template>
|
||||
<VListItemTitle>删除</VListItemTitle>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VMenu>
|
||||
</IconBtn>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</VTable>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</VRow>
|
||||
<!-- =弹窗 -->
|
||||
<VDialog
|
||||
v-model="addUserDialog"
|
||||
max-width="50rem"
|
||||
persistent
|
||||
z-index="1010"
|
||||
>
|
||||
<!-- Dialog Content -->
|
||||
<VCard title="新增用户">
|
||||
<VCardText>
|
||||
<VForm @submit.prevent="() => {}">
|
||||
<VRow>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VTextField
|
||||
v-model="userForm.name"
|
||||
label="用户名"
|
||||
:rules="[requiredValidator]"
|
||||
/>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VTextField
|
||||
v-model="userForm.password"
|
||||
label="密码"
|
||||
:rules="[requiredValidator]"
|
||||
:type="isPasswordVisible ? 'text' : 'password'"
|
||||
:append-inner-icon="
|
||||
isPasswordVisible ? 'mdi-eye-off-outline' : 'mdi-eye-outline'
|
||||
"
|
||||
@click:append-inner="isPasswordVisible = !isPasswordVisible"
|
||||
/>
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<VTextField
|
||||
v-model="userForm.email"
|
||||
:rules="[requiredValidator]"
|
||||
label="邮箱"
|
||||
/>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
<VCardActions>
|
||||
<VBtn @click="addUserDialog = false">
|
||||
取消
|
||||
</VBtn>
|
||||
<VSpacer />
|
||||
<VBtn @click="addUser">
|
||||
确定
|
||||
</VBtn>
|
||||
</VCardActions>
|
||||
</VCard>
|
||||
</VDialog>
|
||||
|
||||
<!-- 双重验证弹窗 -->
|
||||
<VDialog
|
||||
v-model="otpDialog"
|
||||
max-width="45rem"
|
||||
persistent
|
||||
z-index="1010"
|
||||
>
|
||||
<!-- 开启双重验证弹窗内容 -->
|
||||
<VCard>
|
||||
<DialogCloseBtn @click="otpDialog = false" />
|
||||
<VCardText>
|
||||
<h4 class="text-h4 text-center mb-6 mt-5">
|
||||
登录双重验证
|
||||
</h4><h5 class="text-h5 font-weight-medium mb-2">
|
||||
身份验证器
|
||||
</h5>
|
||||
<p class="mb-6">
|
||||
使用像Google Authenticator、Microsoft Authenticator、Authy或1Password这样的身份验证器应用程序,扫描二维码。它将为您生成一个6位数的代码,供您在下方输入。
|
||||
</p>
|
||||
<div class="my-6">
|
||||
<QrcodeVue class="mx-auto" :value="qrCode" :size="200" max-width="25rem" />
|
||||
</div>
|
||||
<VAlert
|
||||
:title="secret"
|
||||
variant="tonal"
|
||||
type="warning"
|
||||
class="my-4"
|
||||
text="如果您在使用二维码时遇到困难,请在您的应用程序中选择手动输入以上代码。"
|
||||
>
|
||||
<template #prepend />
|
||||
</VAlert>
|
||||
<VForm>
|
||||
<VTextField
|
||||
v-model="otpPassword"
|
||||
type="text"
|
||||
label="输入验证码以确认开启双重验证"
|
||||
autocomplete=""
|
||||
class="mb-8"
|
||||
variant="outlined"
|
||||
/>
|
||||
<div class="d-flex justify-end flex-wrap gap-4">
|
||||
<VBtn variant="outlined" color="secondary" @click="otpDialog = false">
|
||||
取消
|
||||
</VBtn>
|
||||
<VBtn @click="judgeOtpPassword">
|
||||
确定
|
||||
<template #append>
|
||||
<VIcon icon="mdi-check" />
|
||||
</template>
|
||||
</VBtn>
|
||||
<!-- 开启双重验证弹窗内容 -->
|
||||
<VCard>
|
||||
<DialogCloseBtn @click="otpDialog = false" />
|
||||
<VCardText>
|
||||
<h4 class="text-h4 text-center mb-6 mt-5">
|
||||
登录双重验证
|
||||
</h4><h5 class="text-h5 font-weight-medium mb-2">
|
||||
身份验证器
|
||||
</h5>
|
||||
<p class="mb-6">
|
||||
使用像Google Authenticator、Microsoft Authenticator、Authy或1Password这样的身份验证器应用程序,扫描二维码。它将为您生成一个6位数的代码,供您在下方输入。
|
||||
</p>
|
||||
<div class="my-6">
|
||||
<QrcodeVue class="mx-auto" :value="qrCode" :size="200" max-width="25rem" />
|
||||
</div>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VDialog>
|
||||
<VAlert
|
||||
:title="secret"
|
||||
variant="tonal"
|
||||
type="warning"
|
||||
class="my-4"
|
||||
text="如果您在使用二维码时遇到困难,请在您的应用程序中选择手动输入以上代码。"
|
||||
>
|
||||
<template #prepend />
|
||||
</VAlert>
|
||||
<VForm>
|
||||
<VTextField
|
||||
v-model="otpPassword"
|
||||
type="text"
|
||||
label="输入验证码以确认开启双重验证"
|
||||
autocomplete=""
|
||||
class="mb-8"
|
||||
variant="outlined"
|
||||
/>
|
||||
<div class="d-flex justify-end flex-wrap gap-4">
|
||||
<VBtn variant="outlined" color="secondary" @click="otpDialog = false">
|
||||
取消
|
||||
</VBtn>
|
||||
<VBtn @click="judgeOtpPassword">
|
||||
确定
|
||||
<template #append>
|
||||
<VIcon icon="mdi-check" />
|
||||
</template>
|
||||
</VBtn>
|
||||
</div>
|
||||
</VForm>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VDialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user