mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-08-28 19:47:49 +08:00
Merge pull request #434 from PKC278/v2
This commit is contained in:
@@ -5,6 +5,7 @@ import { useDisplay } from 'vuetify'
|
|||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import type { ApiResponse, PassKey } from '@/api/types'
|
import type { ApiResponse, PassKey } from '@/api/types'
|
||||||
|
import { useGlobalSettingsStore } from '@/stores'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
modelValue: boolean
|
modelValue: boolean
|
||||||
@@ -21,6 +22,7 @@ const emit = defineEmits(['update:modelValue', 'update:isOtp', 'verifyPassword']
|
|||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const display = useDisplay()
|
const display = useDisplay()
|
||||||
const $toast = useToast()
|
const $toast = useToast()
|
||||||
|
const globalSettingsStore = useGlobalSettingsStore()
|
||||||
|
|
||||||
// 内部状态
|
// 内部状态
|
||||||
const show = computed({
|
const show = computed({
|
||||||
@@ -37,6 +39,8 @@ const secret = ref('')
|
|||||||
// 确认双重验证密码
|
// 确认双重验证密码
|
||||||
const otpPassword = ref('')
|
const otpPassword = ref('')
|
||||||
|
|
||||||
|
const allowPasskeyWithoutOtp = computed(() => globalSettingsStore.get('PASSKEY_ALLOW_REGISTER_WITHOUT_OTP') === true)
|
||||||
|
|
||||||
// 二维码图片 base64
|
// 二维码图片 base64
|
||||||
const qrCodeImage = ref('')
|
const qrCodeImage = ref('')
|
||||||
|
|
||||||
@@ -104,7 +108,7 @@ async function judgeOtpPassword() {
|
|||||||
// 关闭当前用户的双重验证
|
// 关闭当前用户的双重验证
|
||||||
function disableOtp() {
|
function disableOtp() {
|
||||||
// 如果已绑定PassKey,不允许关闭OTP
|
// 如果已绑定PassKey,不允许关闭OTP
|
||||||
if (props.passkeyList && props.passkeyList.length > 0) {
|
if (props.passkeyList && props.passkeyList.length > 0 && !allowPasskeyWithoutOtp.value) {
|
||||||
$toast.error(t('profile.disableOtpWithPasskeyError'))
|
$toast.error(t('profile.disableOtpWithPasskeyError'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { useI18n } from 'vue-i18n'
|
|||||||
import { formatDateDifference } from '@core/utils/formatters'
|
import { formatDateDifference } from '@core/utils/formatters'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import type { ApiResponse, PassKey } from '@/api/types'
|
import type { ApiResponse, PassKey } from '@/api/types'
|
||||||
|
import { useGlobalSettingsStore } from '@/stores'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
modelValue: boolean
|
modelValue: boolean
|
||||||
@@ -26,6 +27,7 @@ const emit = defineEmits(['update:modelValue', 'update:passkeyList', 'verifyPass
|
|||||||
const { t, locale } = useI18n()
|
const { t, locale } = useI18n()
|
||||||
const display = useDisplay()
|
const display = useDisplay()
|
||||||
const $toast = useToast()
|
const $toast = useToast()
|
||||||
|
const globalSettingsStore = useGlobalSettingsStore()
|
||||||
|
|
||||||
// 内部状态
|
// 内部状态
|
||||||
const show = computed({
|
const show = computed({
|
||||||
@@ -45,6 +47,9 @@ const passkeyName = ref('')
|
|||||||
// PassKey challenge
|
// PassKey challenge
|
||||||
const passkeyChallenge = ref('')
|
const passkeyChallenge = ref('')
|
||||||
|
|
||||||
|
const allowPasskeyWithoutOtp = computed(() => globalSettingsStore.get('PASSKEY_ALLOW_REGISTER_WITHOUT_OTP') === true)
|
||||||
|
const canRegisterPasskey = computed(() => props.isOtp || allowPasskeyWithoutOtp.value)
|
||||||
|
|
||||||
// 格式化日期
|
// 格式化日期
|
||||||
function formatDate(dateStr: string) {
|
function formatDate(dateStr: string) {
|
||||||
return new Date(dateStr).toLocaleDateString(locale.value)
|
return new Date(dateStr).toLocaleDateString(locale.value)
|
||||||
@@ -230,7 +235,7 @@ watch(
|
|||||||
</VAlert>
|
</VAlert>
|
||||||
|
|
||||||
<!-- 注册新通行密钥 -->
|
<!-- 注册新通行密钥 -->
|
||||||
<VCard v-if="props.isOtp" variant="tonal" class="mb-6">
|
<VCard v-if="canRegisterPasskey" variant="tonal" class="mb-6">
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<h5 class="text-h5 font-weight-medium mb-2">{{ t('profile.registerNewPasskey') }}</h5>
|
<h5 class="text-h5 font-weight-medium mb-2">{{ t('profile.registerNewPasskey') }}</h5>
|
||||||
<p class="mb-4">{{ t('profile.passkeyDescription') }}</p>
|
<p class="mb-4">{{ t('profile.passkeyDescription') }}</p>
|
||||||
|
|||||||
+22
-1
@@ -1670,6 +1670,7 @@ export default {
|
|||||||
storage: 'Storage',
|
storage: 'Storage',
|
||||||
storageDesc: 'Set up local or cloud storage.',
|
storageDesc: 'Set up local or cloud storage.',
|
||||||
directory: 'Directory',
|
directory: 'Directory',
|
||||||
|
mediaType: 'Media Type',
|
||||||
directoryDesc: 'Set up media file organization directory structure, matching in sequence.',
|
directoryDesc: 'Set up media file organization directory structure, matching in sequence.',
|
||||||
organizeAndScrap: 'Organization & Scraping',
|
organizeAndScrap: 'Organization & Scraping',
|
||||||
organizeAndScrapDesc: 'Set rename format, scraping options, etc.',
|
organizeAndScrapDesc: 'Set rename format, scraping options, etc.',
|
||||||
@@ -1786,7 +1787,7 @@ export default {
|
|||||||
},
|
},
|
||||||
cache: {
|
cache: {
|
||||||
title: 'Cache Management',
|
title: 'Cache Management',
|
||||||
subtitle: 'Manage torrent cache data',
|
subtitle: 'Manage cached site resources',
|
||||||
totalCount: 'Total Count',
|
totalCount: 'Total Count',
|
||||||
siteCount: 'Site Count',
|
siteCount: 'Site Count',
|
||||||
filterByTitle: 'Filter by Title',
|
filterByTitle: 'Filter by Title',
|
||||||
@@ -3048,6 +3049,26 @@ export default {
|
|||||||
unsupportedDownloaderType: 'Unsupported downloader type: {type}',
|
unsupportedDownloaderType: 'Unsupported downloader type: {type}',
|
||||||
unsupportedMediaServerType: 'Unsupported media server type: {type}',
|
unsupportedMediaServerType: 'Unsupported media server type: {type}',
|
||||||
unsupportedNotificationType: 'Unsupported notification type: {type}',
|
unsupportedNotificationType: 'Unsupported notification type: {type}',
|
||||||
|
storageTestFailed: 'Storage test failed',
|
||||||
|
downloaderTestFailed: 'Downloader test failed',
|
||||||
|
downloaderNotSelected: 'No downloader selected',
|
||||||
|
mediaServerTestFailed: 'Media server test failed',
|
||||||
|
mediaServerNotSelected: 'No media server selected',
|
||||||
|
notificationTestFailed: 'Notification test failed',
|
||||||
|
notificationNotSelected: 'No notification type selected',
|
||||||
|
saveStepFailed: 'Failed to save step settings',
|
||||||
|
basicSettingsSaved: 'Basic settings saved successfully',
|
||||||
|
saveBasicSettingsFailed: 'Failed to save basic settings',
|
||||||
|
storageSettingsSaved: 'Storage settings saved successfully',
|
||||||
|
saveStorageSettingsFailed: 'Failed to save storage settings',
|
||||||
|
downloaderSettingsSaved: 'Downloader settings saved successfully',
|
||||||
|
saveDownloaderSettingsFailed: 'Failed to save downloader settings',
|
||||||
|
mediaServerSettingsSaved: 'Media server settings saved successfully',
|
||||||
|
saveMediaServerSettingsFailed: 'Failed to save media server settings',
|
||||||
|
notificationSettingsSaved: 'Notification settings saved successfully',
|
||||||
|
saveNotificationSettingsFailed: 'Failed to save notification settings',
|
||||||
|
preferenceSettingsSaved: 'Preference settings saved successfully',
|
||||||
|
savePreferenceSettingsFailed: 'Failed to save preference settings',
|
||||||
passwordUpdateSuccess: 'Password updated successfully',
|
passwordUpdateSuccess: 'Password updated successfully',
|
||||||
userCreateSuccess: 'User created successfully',
|
userCreateSuccess: 'User created successfully',
|
||||||
passwordUpdateFailed: 'Failed to update password',
|
passwordUpdateFailed: 'Failed to update password',
|
||||||
|
|||||||
+40
-5
@@ -159,7 +159,6 @@ export default {
|
|||||||
subscribeMovie: '電影訂閱',
|
subscribeMovie: '電影訂閱',
|
||||||
subscribeTv: '電視劇訂閱',
|
subscribeTv: '電視劇訂閱',
|
||||||
settings: '設置',
|
settings: '設置',
|
||||||
language: '語言設置',
|
|
||||||
selectLanguage: '選擇語言',
|
selectLanguage: '選擇語言',
|
||||||
logout: '退出登錄',
|
logout: '退出登錄',
|
||||||
restarting: '正在重啟...',
|
restarting: '正在重啟...',
|
||||||
@@ -435,10 +434,13 @@ export default {
|
|||||||
name: '企業微信',
|
name: '企業微信',
|
||||||
corpId: '企業ID',
|
corpId: '企業ID',
|
||||||
corpIdHint: '企業微信後台企業信息中的企業ID',
|
corpIdHint: '企業微信後台企業信息中的企業ID',
|
||||||
|
corpIdRequired: '企業ID不能為空',
|
||||||
appId: '應用 AgentId',
|
appId: '應用 AgentId',
|
||||||
appIdHint: '企業微信自建應用的AgentId',
|
appIdHint: '企業微信自建應用的AgentId',
|
||||||
|
appIdRequired: '應用AgentId不能為空',
|
||||||
appSecret: '應用 Secret',
|
appSecret: '應用 Secret',
|
||||||
appSecretHint: '企業微信自建應用的Secret',
|
appSecretHint: '企業微信自建應用的Secret',
|
||||||
|
appSecretRequired: '應用Secret不能為空',
|
||||||
proxy: '代理地址',
|
proxy: '代理地址',
|
||||||
proxyHint: '微信消息的轉發代理地址,2022年6月20日後創建的自建應用才需要,不使用代理時需要保留默認值',
|
proxyHint: '微信消息的轉發代理地址,2022年6月20日後創建的自建應用才需要,不使用代理時需要保留默認值',
|
||||||
token: 'Token',
|
token: 'Token',
|
||||||
@@ -453,23 +455,30 @@ export default {
|
|||||||
name: 'Telegram',
|
name: 'Telegram',
|
||||||
token: 'Bot Token',
|
token: 'Bot Token',
|
||||||
tokenHint: 'Telegram機器人token,格式:123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11',
|
tokenHint: 'Telegram機器人token,格式:123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11',
|
||||||
|
tokenRequired: 'Bot Token不能為空',
|
||||||
chatId: 'Chat ID',
|
chatId: 'Chat ID',
|
||||||
chatIdHint: '接受消息通知的用戶、群組或頻道Chat ID',
|
chatIdHint: '接受消息通知的用戶、群組或頻道Chat ID',
|
||||||
|
chatIdRequired: 'Chat ID不能為空',
|
||||||
users: '用戶白名單',
|
users: '用戶白名單',
|
||||||
usersHint: '可使用Telegram機器人的用戶ID清單,多個用戶用,分隔,不填寫則所有用戶都能使用',
|
usersHint: '可使用Telegram機器人的用戶ID清單,多個用戶用,分隔,不填寫則所有用戶都能使用',
|
||||||
admins: '管理員白名單',
|
admins: '管理員白名單',
|
||||||
adminsHint: '可使用管理菜單及命令的用戶ID列表,多個ID使用,分隔',
|
adminsHint: '可使用管理菜單及命令的用戶ID列表,多個ID使用,分隔',
|
||||||
adminsPlaceholder: '用戶ID列表,多個ID使用,分隔',
|
adminsPlaceholder: '用戶ID列表,多個ID使用,分隔',
|
||||||
usersPlaceholder: '用戶ID列表,多個ID使用,分隔',
|
usersPlaceholder: '用戶ID列表,多個ID使用,分隔',
|
||||||
|
apiUrl: '代理API地址',
|
||||||
|
apiUrlHint: '自定義代理API地址,格式:https://api.telegram.org',
|
||||||
|
apiUrlPlaceholder: 'https://api.telegram.org',
|
||||||
},
|
},
|
||||||
slack: {
|
slack: {
|
||||||
name: 'Slack',
|
name: 'Slack',
|
||||||
oauthToken: 'Slack Bot User OAuth Token',
|
oauthToken: 'Slack Bot User OAuth Token',
|
||||||
oauthTokenHint: 'Slack應用`OAuth & Permissions`頁面中的`Bot User OAuth Token`',
|
oauthTokenHint: 'Slack應用`OAuth & Permissions`頁面中的`Bot User OAuth Token`',
|
||||||
|
oauthTokenRequired: 'OAuth Token不能為空',
|
||||||
appToken: 'Slack App-Level Token',
|
appToken: 'Slack App-Level Token',
|
||||||
appTokenHint: 'Slack應用`OAuth & Permissions`頁面中的`App-Level Token`',
|
appTokenHint: 'Slack應用`OAuth & Permissions`頁面中的`App-Level Token`',
|
||||||
channel: '頻道名稱',
|
channel: '頻道名稱',
|
||||||
channelHint: '消息發送頻道,默認`全體`',
|
channelHint: '消息發送頻道,默認`全體`',
|
||||||
|
channelRequired: '頻道名稱不能為空',
|
||||||
},
|
},
|
||||||
discord: {
|
discord: {
|
||||||
name: 'Discord',
|
name: 'Discord',
|
||||||
@@ -487,6 +496,7 @@ export default {
|
|||||||
name: 'Synology Chat',
|
name: 'Synology Chat',
|
||||||
webhook: '機器人傳入URL',
|
webhook: '機器人傳入URL',
|
||||||
webhookHint: 'Synology Chat機器人傳入URL',
|
webhookHint: 'Synology Chat機器人傳入URL',
|
||||||
|
webhookRequired: 'Webhook URL不能為空',
|
||||||
token: '令牌',
|
token: '令牌',
|
||||||
tokenHint: 'Synology Chat機器人令牌',
|
tokenHint: 'Synology Chat機器人令牌',
|
||||||
},
|
},
|
||||||
@@ -494,8 +504,10 @@ export default {
|
|||||||
name: 'VoceChat',
|
name: 'VoceChat',
|
||||||
host: '地址',
|
host: '地址',
|
||||||
hostHint: 'VoceChat服務端地址,格式:http(s)://ip:port',
|
hostHint: 'VoceChat服務端地址,格式:http(s)://ip:port',
|
||||||
|
hostRequired: '地址不能為空',
|
||||||
apiKey: '機器人密鑰',
|
apiKey: '機器人密鑰',
|
||||||
apiKeyHint: 'VoceChat機器人密鑰',
|
apiKeyHint: 'VoceChat機器人密鑰',
|
||||||
|
apiKeyRequired: 'API密鑰不能為空',
|
||||||
channelId: '頻道ID',
|
channelId: '頻道ID',
|
||||||
channelIdHint: 'VoceChat的頻道ID,不包含#號',
|
channelIdHint: 'VoceChat的頻道ID,不包含#號',
|
||||||
},
|
},
|
||||||
@@ -503,6 +515,7 @@ export default {
|
|||||||
name: 'WebPush',
|
name: 'WebPush',
|
||||||
username: '登錄用戶名',
|
username: '登錄用戶名',
|
||||||
usernameHint: '只有對應的用戶登錄後才會推送消息',
|
usernameHint: '只有對應的用戶登錄後才會推送消息',
|
||||||
|
usernameRequired: '用戶名不能為空',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
shortcut: {
|
shortcut: {
|
||||||
@@ -1637,6 +1650,7 @@ export default {
|
|||||||
storage: '存儲',
|
storage: '存儲',
|
||||||
storageDesc: '設置本地或網盤存儲',
|
storageDesc: '設置本地或網盤存儲',
|
||||||
directory: '目錄',
|
directory: '目錄',
|
||||||
|
mediaType: '媒體類型',
|
||||||
directoryDesc: '設置媒體文件整理目錄結構,按先後順序依次匹配。',
|
directoryDesc: '設置媒體文件整理目錄結構,按先後順序依次匹配。',
|
||||||
organizeAndScrap: '整理 & 刮削',
|
organizeAndScrap: '整理 & 刮削',
|
||||||
organizeAndScrapDesc: '設置重命名格式、刮削選項等。',
|
organizeAndScrapDesc: '設置重命名格式、刮削選項等。',
|
||||||
@@ -1695,8 +1709,8 @@ export default {
|
|||||||
importHasId: '導入失敗!發現有規則存在相同ID,可能屬於自定義規則!',
|
importHasId: '導入失敗!發現有規則存在相同ID,可能屬於自定義規則!',
|
||||||
},
|
},
|
||||||
scheduler: {
|
scheduler: {
|
||||||
scheduledTasks: '定時作業',
|
title: '定時作業',
|
||||||
scheduledTasksDesc: '包含系統內置服務以及插件提供的服務',
|
subtitle: '包含系統內置服務以及插件提供的服務',
|
||||||
provider: '提供者',
|
provider: '提供者',
|
||||||
taskName: '任務名稱',
|
taskName: '任務名稱',
|
||||||
taskStatus: '任務狀態',
|
taskStatus: '任務狀態',
|
||||||
@@ -1748,9 +1762,10 @@ export default {
|
|||||||
settingsSaveFailed: '訂閱基礎設置保存失敗!',
|
settingsSaveFailed: '訂閱基礎設置保存失敗!',
|
||||||
},
|
},
|
||||||
cache: {
|
cache: {
|
||||||
title: '緩存',
|
title: '緩存管理',
|
||||||
description: '種子緩存、圖片文件緩存管理',
|
|
||||||
subtitle: '管理緩存的站點資源',
|
subtitle: '管理緩存的站點資源',
|
||||||
|
totalCount: '總條數',
|
||||||
|
siteCount: '站點數',
|
||||||
filterByTitle: '按標題篩選',
|
filterByTitle: '按標題篩選',
|
||||||
filterBySite: '按站點篩選',
|
filterBySite: '按站點篩選',
|
||||||
selectSite: '選擇站點',
|
selectSite: '選擇站點',
|
||||||
@@ -3001,6 +3016,26 @@ export default {
|
|||||||
unsupportedDownloaderType: '不支援的下載器類型: {type}',
|
unsupportedDownloaderType: '不支援的下載器類型: {type}',
|
||||||
unsupportedMediaServerType: '不支援的媒體服務器類型: {type}',
|
unsupportedMediaServerType: '不支援的媒體服務器類型: {type}',
|
||||||
unsupportedNotificationType: '不支援的通知類型: {type}',
|
unsupportedNotificationType: '不支援的通知類型: {type}',
|
||||||
|
storageTestFailed: '存儲目錄測試失敗',
|
||||||
|
downloaderTestFailed: '下載器測試失敗',
|
||||||
|
downloaderNotSelected: '未選擇下載器',
|
||||||
|
mediaServerTestFailed: '媒體服務器測試失敗',
|
||||||
|
mediaServerNotSelected: '未選擇媒體服務器',
|
||||||
|
notificationTestFailed: '消息通知測試失敗',
|
||||||
|
notificationNotSelected: '未選擇通知類型',
|
||||||
|
saveStepFailed: '保存步驟設置失敗',
|
||||||
|
basicSettingsSaved: '基礎設置保存成功',
|
||||||
|
saveBasicSettingsFailed: '保存基礎設置失敗',
|
||||||
|
storageSettingsSaved: '存儲設置保存成功',
|
||||||
|
saveStorageSettingsFailed: '保存存儲設置失敗',
|
||||||
|
downloaderSettingsSaved: '下載器設置保存成功',
|
||||||
|
saveDownloaderSettingsFailed: '保存下載器設置失敗',
|
||||||
|
mediaServerSettingsSaved: '媒體服務器設置保存成功',
|
||||||
|
saveMediaServerSettingsFailed: '保存媒體服務器設置失敗',
|
||||||
|
notificationSettingsSaved: '通知設置保存成功',
|
||||||
|
saveNotificationSettingsFailed: '保存通知設置失敗',
|
||||||
|
preferenceSettingsSaved: '偏好設置保存成功',
|
||||||
|
savePreferenceSettingsFailed: '保存偏好設置失敗',
|
||||||
passwordUpdateSuccess: '密碼更新成功',
|
passwordUpdateSuccess: '密碼更新成功',
|
||||||
userCreateSuccess: '使用者建立成功',
|
userCreateSuccess: '使用者建立成功',
|
||||||
passwordUpdateFailed: '密碼更新失敗',
|
passwordUpdateFailed: '密碼更新失敗',
|
||||||
|
|||||||
Reference in New Issue
Block a user