@@ -1,22 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
import {ref, computed} from 'vue';
|
||||
import {useCustomizerStore} from '@/stores/customizer';
|
||||
import { ref, computed } from 'vue';
|
||||
import { useCustomizerStore } from '@/stores/customizer';
|
||||
import axios from 'axios';
|
||||
import Logo from '@/components/shared/Logo.vue';
|
||||
import LanguageSwitcher from '@/components/shared/LanguageSwitcher.vue';
|
||||
import {md5} from 'js-md5';
|
||||
import {useAuthStore} from '@/stores/auth';
|
||||
import {useCommonStore} from '@/stores/common';
|
||||
import { md5 } from 'js-md5';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import { useCommonStore } from '@/stores/common';
|
||||
import MarkdownIt from 'markdown-it';
|
||||
import { useI18n } from '@/i18n/composables';
|
||||
import { router } from '@/router';
|
||||
|
||||
// 配置markdown-it,默认安全设置
|
||||
const md = new MarkdownIt({
|
||||
html: true, // 启用HTML标签
|
||||
breaks: true, // 换行转<br>
|
||||
linkify: true, // 自动转链接
|
||||
typographer: false // 禁用智能引号
|
||||
html: true, // 启用HTML标签
|
||||
breaks: true, // 换行转<br>
|
||||
linkify: true, // 自动转链接
|
||||
typographer: false // 禁用智能引号
|
||||
});
|
||||
|
||||
const customizer = useCustomizerStore();
|
||||
@@ -44,11 +44,11 @@ let installLoading = ref(false);
|
||||
let tab = ref(0);
|
||||
|
||||
const releasesHeader = computed(() => [
|
||||
{title: t('core.header.updateDialog.table.tag'), key: 'tag_name'},
|
||||
{title: t('core.header.updateDialog.table.publishDate'), key: 'published_at'},
|
||||
{title: t('core.header.updateDialog.table.content'), key: 'body'},
|
||||
{title: t('core.header.updateDialog.table.sourceUrl'), key: 'zipball_url'},
|
||||
{title: t('core.header.updateDialog.table.actions'), key: 'switch'}
|
||||
{ title: t('core.header.updateDialog.table.tag'), key: 'tag_name' },
|
||||
{ title: t('core.header.updateDialog.table.publishDate'), key: 'published_at' },
|
||||
{ title: t('core.header.updateDialog.table.content'), key: 'body' },
|
||||
{ title: t('core.header.updateDialog.table.sourceUrl'), key: 'zipball_url' },
|
||||
{ title: t('core.header.updateDialog.table.actions'), key: 'switch' }
|
||||
]);
|
||||
|
||||
// Form validation
|
||||
@@ -103,90 +103,90 @@ function accountEdit() {
|
||||
new_password: newPassword.value,
|
||||
new_username: newUsername.value ? newUsername.value : username
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.data.status == 'error') {
|
||||
accountEditStatus.value.error = true;
|
||||
accountEditStatus.value.message = res.data.message;
|
||||
password.value = '';
|
||||
newPassword.value = '';
|
||||
return;
|
||||
}
|
||||
accountEditStatus.value.success = true;
|
||||
accountEditStatus.value.message = res.data.message;
|
||||
setTimeout(() => {
|
||||
dialog.value = !dialog.value;
|
||||
const authStore = useAuthStore();
|
||||
authStore.logout();
|
||||
}, 2000);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
.then((res) => {
|
||||
if (res.data.status == 'error') {
|
||||
accountEditStatus.value.error = true;
|
||||
accountEditStatus.value.message = typeof err === 'string' ? err : t('core.header.accountDialog.messages.updateFailed');
|
||||
accountEditStatus.value.message = res.data.message;
|
||||
password.value = '';
|
||||
newPassword.value = '';
|
||||
})
|
||||
.finally(() => {
|
||||
accountEditStatus.value.loading = false;
|
||||
});
|
||||
return;
|
||||
}
|
||||
accountEditStatus.value.success = true;
|
||||
accountEditStatus.value.message = res.data.message;
|
||||
setTimeout(() => {
|
||||
dialog.value = !dialog.value;
|
||||
const authStore = useAuthStore();
|
||||
authStore.logout();
|
||||
}, 2000);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
accountEditStatus.value.error = true;
|
||||
accountEditStatus.value.message = typeof err === 'string' ? err : t('core.header.accountDialog.messages.updateFailed');
|
||||
password.value = '';
|
||||
newPassword.value = '';
|
||||
})
|
||||
.finally(() => {
|
||||
accountEditStatus.value.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
function getVersion() {
|
||||
axios.get('/api/stat/version')
|
||||
.then((res) => {
|
||||
botCurrVersion.value = "v" + res.data.data.version;
|
||||
dashboardCurrentVersion.value = res.data.data?.dashboard_version;
|
||||
let change_pwd_hint = res.data.data?.change_pwd_hint;
|
||||
if (change_pwd_hint) {
|
||||
dialog.value = true;
|
||||
accountWarning.value = true;
|
||||
localStorage.setItem('change_pwd_hint', 'true');
|
||||
} else {
|
||||
localStorage.removeItem('change_pwd_hint');
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
.then((res) => {
|
||||
botCurrVersion.value = "v" + res.data.data.version;
|
||||
dashboardCurrentVersion.value = res.data.data?.dashboard_version;
|
||||
let change_pwd_hint = res.data.data?.change_pwd_hint;
|
||||
if (change_pwd_hint) {
|
||||
dialog.value = true;
|
||||
accountWarning.value = true;
|
||||
localStorage.setItem('change_pwd_hint', 'true');
|
||||
} else {
|
||||
localStorage.removeItem('change_pwd_hint');
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
|
||||
function checkUpdate() {
|
||||
updateStatus.value = t('core.header.updateDialog.status.checking');
|
||||
axios.get('/api/update/check')
|
||||
.then((res) => {
|
||||
hasNewVersion.value = res.data.data.has_new_version;
|
||||
.then((res) => {
|
||||
hasNewVersion.value = res.data.data.has_new_version;
|
||||
|
||||
if (res.data.data.has_new_version) {
|
||||
releaseMessage.value = res.data.message;
|
||||
updateStatus.value = t('core.header.version.hasNewVersion');
|
||||
} else {
|
||||
updateStatus.value = res.data.message;
|
||||
}
|
||||
dashboardHasNewVersion.value = res.data.data.dashboard_has_new_version;
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err.response && err.response.status == 401) {
|
||||
console.log("401");
|
||||
const authStore = useAuthStore();
|
||||
authStore.logout();
|
||||
return;
|
||||
}
|
||||
console.log(err);
|
||||
updateStatus.value = err
|
||||
});
|
||||
if (res.data.data.has_new_version) {
|
||||
releaseMessage.value = res.data.message;
|
||||
updateStatus.value = t('core.header.version.hasNewVersion');
|
||||
} else {
|
||||
updateStatus.value = res.data.message;
|
||||
}
|
||||
dashboardHasNewVersion.value = res.data.data.dashboard_has_new_version;
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err.response && err.response.status == 401) {
|
||||
console.log("401");
|
||||
const authStore = useAuthStore();
|
||||
authStore.logout();
|
||||
return;
|
||||
}
|
||||
console.log(err);
|
||||
updateStatus.value = err
|
||||
});
|
||||
}
|
||||
|
||||
function getReleases() {
|
||||
axios.get('/api/update/releases')
|
||||
.then((res) => {
|
||||
releases.value = res.data.data.map((item: any) => {
|
||||
item.published_at = new Date(item.published_at).toLocaleString();
|
||||
return item;
|
||||
})
|
||||
.then((res) => {
|
||||
releases.value = res.data.data.map((item: any) => {
|
||||
item.published_at = new Date(item.published_at).toLocaleString();
|
||||
return item;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
|
||||
function getDevCommits() {
|
||||
@@ -209,10 +209,10 @@ function getDevCommits() {
|
||||
.then(data => {
|
||||
devCommits.value = Array.isArray(data)
|
||||
? data.map((commit: any) => ({
|
||||
sha: commit.sha,
|
||||
date: new Date(commit.commit.author.date).toLocaleString(),
|
||||
message: commit.commit.message
|
||||
}))
|
||||
sha: commit.sha,
|
||||
date: new Date(commit.commit.author.date).toLocaleString(),
|
||||
message: commit.commit.message
|
||||
}))
|
||||
: [];
|
||||
})
|
||||
.catch(err => {
|
||||
@@ -239,40 +239,40 @@ function switchVersion(version: string) {
|
||||
version: version,
|
||||
proxy: localStorage.getItem('selectedGitHubProxy') || ''
|
||||
})
|
||||
.then((res) => {
|
||||
updateStatus.value = res.data.message;
|
||||
if (res.data.status == 'ok') {
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
updateStatus.value = err
|
||||
}).finally(() => {
|
||||
installLoading.value = false;
|
||||
});
|
||||
.then((res) => {
|
||||
updateStatus.value = res.data.message;
|
||||
if (res.data.status == 'ok') {
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
updateStatus.value = err
|
||||
}).finally(() => {
|
||||
installLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
function updateDashboard() {
|
||||
updatingDashboardLoading.value = true;
|
||||
updateStatus.value = t('core.header.updateDialog.status.updating');
|
||||
axios.post('/api/update/dashboard')
|
||||
.then((res) => {
|
||||
updateStatus.value = res.data.message;
|
||||
if (res.data.status == 'ok') {
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
updateStatus.value = err
|
||||
}).finally(() => {
|
||||
updatingDashboardLoading.value = false;
|
||||
});
|
||||
.then((res) => {
|
||||
updateStatus.value = res.data.message;
|
||||
if (res.data.status == 'ok') {
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
updateStatus.value = err
|
||||
}).finally(() => {
|
||||
updatingDashboardLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
function toggleDarkMode() {
|
||||
@@ -291,29 +291,32 @@ commonStore.getStartTime();
|
||||
<template>
|
||||
<v-app-bar elevation="0" height="55">
|
||||
|
||||
<v-btn v-if="useCustomizerStore().uiTheme==='PurpleTheme'" style="margin-left: 22px;" class="hidden-md-and-down text-secondary" color="lightsecondary" icon rounded="sm"
|
||||
variant="flat" @click.stop="customizer.SET_MINI_SIDEBAR(!customizer.mini_sidebar)" size="small">
|
||||
<v-btn v-if="useCustomizerStore().uiTheme === 'PurpleTheme'" style="margin-left: 22px;"
|
||||
class="hidden-md-and-down text-secondary" color="lightsecondary" icon rounded="sm" variant="flat"
|
||||
@click.stop="customizer.SET_MINI_SIDEBAR(!customizer.mini_sidebar)" size="small">
|
||||
<v-icon>mdi-menu</v-icon>
|
||||
</v-btn>
|
||||
<v-btn v-else style="margin-left: 22px; color: var(--v-theme-primaryText); background-color: var(--v-theme-secondary)" class="hidden-md-and-down" icon rounded="sm"
|
||||
variant="flat" @click.stop="customizer.SET_MINI_SIDEBAR(!customizer.mini_sidebar)" size="small">
|
||||
<v-btn v-else
|
||||
style="margin-left: 22px; color: var(--v-theme-primaryText); background-color: var(--v-theme-secondary)"
|
||||
class="hidden-md-and-down" icon rounded="sm" variant="flat"
|
||||
@click.stop="customizer.SET_MINI_SIDEBAR(!customizer.mini_sidebar)" size="small">
|
||||
<v-icon>mdi-menu</v-icon>
|
||||
</v-btn>
|
||||
<v-btn v-if="useCustomizerStore().uiTheme==='PurpleTheme'" class="hidden-lg-and-up ms-3" color="lightsecondary" icon rounded="sm" variant="flat"
|
||||
@click.stop="customizer.SET_SIDEBAR_DRAWER" size="small">
|
||||
<v-btn v-if="useCustomizerStore().uiTheme === 'PurpleTheme'" class="hidden-lg-and-up ms-3" color="lightsecondary"
|
||||
icon rounded="sm" variant="flat" @click.stop="customizer.SET_SIDEBAR_DRAWER" size="small">
|
||||
<v-icon>mdi-menu</v-icon>
|
||||
</v-btn>
|
||||
<v-btn v-else class="hidden-lg-and-up ms-3" icon rounded="sm" variant="flat"
|
||||
@click.stop="customizer.SET_SIDEBAR_DRAWER" size="small">
|
||||
@click.stop="customizer.SET_SIDEBAR_DRAWER" size="small">
|
||||
<v-icon>mdi-menu</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<div class="logo-container" :class="{'mobile-logo': $vuetify.display.xs}" @click="$router.push('/about')">
|
||||
<div class="logo-container" :class="{ 'mobile-logo': $vuetify.display.xs }" @click="$router.push('/about')">
|
||||
<span class="logo-text">Astr<span class="logo-text-light">Bot</span></span>
|
||||
<span class="version-text hidden-xs">{{ botCurrVersion }}</span>
|
||||
</div>
|
||||
|
||||
<v-spacer/>
|
||||
<v-spacer />
|
||||
|
||||
<!-- 版本提示信息 - 在手机上隐藏 -->
|
||||
<div class="mr-4 hidden-xs">
|
||||
@@ -329,20 +332,25 @@ commonStore.getStartTime();
|
||||
<LanguageSwitcher variant="header" />
|
||||
|
||||
<!-- 主题切换按钮 -->
|
||||
<v-btn size="small" @click="toggleDarkMode();" class="action-btn"
|
||||
color="var(--v-theme-surface)" variant="flat" rounded="sm">
|
||||
<v-btn size="small" @click="toggleDarkMode();" class="action-btn" color="var(--v-theme-surface)" variant="flat"
|
||||
rounded="sm" icon>
|
||||
<v-icon v-if="useCustomizerStore().uiTheme === 'PurpleThemeDark'">mdi-weather-night</v-icon>
|
||||
<v-icon v-else>mdi-white-balance-sunny</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<!-- 更新对话框 -->
|
||||
<v-dialog v-model="updateStatusDialog" :width="$vuetify.display.smAndDown ? '100%' : '1200'" :fullscreen="$vuetify.display.xs">
|
||||
<v-dialog v-model="updateStatusDialog" :width="$vuetify.display.smAndDown ? '100%' : '1200'"
|
||||
:fullscreen="$vuetify.display.xs">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-btn size="small" @click="checkUpdate(); getReleases(); getDevCommits();" class="action-btn"
|
||||
color="var(--v-theme-surface)" variant="flat" rounded="sm" v-bind="props">
|
||||
<v-icon class="hidden-sm-and-up">mdi-update</v-icon>
|
||||
<span class="hidden-xs">{{ t('core.header.buttons.update') }}</span>
|
||||
</v-btn>
|
||||
<v-tooltip>
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-btn size="small" @click="checkUpdate(); getReleases(); getDevCommits();" class="action-btn"
|
||||
color="var(--v-theme-surface)" variant="flat" rounded="sm" v-bind="props" icon>
|
||||
<v-icon>mdi-arrow-up-circle</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
{{ t('core.header.buttons.update') }}
|
||||
</v-tooltip>
|
||||
</template>
|
||||
<v-card>
|
||||
<v-card-title class="mobile-card-title">
|
||||
@@ -361,8 +369,8 @@ commonStore.getStartTime();
|
||||
</div>
|
||||
|
||||
<div v-if="releaseMessage"
|
||||
style="background-color: #646cff24; padding: 16px; border-radius: 10px; font-size: 14px; max-height: 400px; overflow-y: auto;"
|
||||
v-html="md.render(releaseMessage)" class="markdown-content">
|
||||
style="background-color: #646cff24; padding: 16px; border-radius: 10px; font-size: 14px; max-height: 400px; overflow-y: auto;"
|
||||
v-html="md.render(releaseMessage)" class="markdown-content">
|
||||
</div>
|
||||
|
||||
<div class="mb-4 mt-4">
|
||||
@@ -380,15 +388,13 @@ commonStore.getStartTime();
|
||||
<v-tabs-window-item key="0" v-show="tab == 0">
|
||||
<div class="mb-4">
|
||||
<small>{{ t('core.header.updateDialog.dockerTip') }} <a
|
||||
href="https://containrrr.dev/watchtower/usage-overview/">{{ t('core.header.updateDialog.dockerTipLink') }}</a> {{ t('core.header.updateDialog.dockerTipContinue') }}</small>
|
||||
href="https://containrrr.dev/watchtower/usage-overview/">{{
|
||||
t('core.header.updateDialog.dockerTipLink')
|
||||
}}</a> {{ t('core.header.updateDialog.dockerTipContinue') }}</small>
|
||||
</div>
|
||||
|
||||
<v-alert
|
||||
v-if="releases.some(item => isPreRelease(item['tag_name']))"
|
||||
type="warning"
|
||||
variant="tonal"
|
||||
border="start"
|
||||
>
|
||||
<v-alert v-if="releases.some(item => isPreRelease(item['tag_name']))" type="warning" variant="tonal"
|
||||
border="start">
|
||||
<template v-slot:prepend>
|
||||
<v-icon>mdi-alert-circle-outline</v-icon>
|
||||
</template>
|
||||
@@ -406,13 +412,8 @@ commonStore.getStartTime();
|
||||
<template v-slot:item.tag_name="{ item }: { item: { tag_name: string } }">
|
||||
<div class="d-flex align-center">
|
||||
<span>{{ item.tag_name }}</span>
|
||||
<v-chip
|
||||
v-if="isPreRelease(item.tag_name)"
|
||||
size="x-small"
|
||||
color="warning"
|
||||
variant="tonal"
|
||||
class="ml-2"
|
||||
>
|
||||
<v-chip v-if="isPreRelease(item.tag_name)" size="x-small" color="warning" variant="tonal"
|
||||
class="ml-2">
|
||||
{{ t('core.header.updateDialog.preRelease') }}
|
||||
</v-chip>
|
||||
</div>
|
||||
@@ -420,7 +421,8 @@ commonStore.getStartTime();
|
||||
<template v-slot:item.body="{ item }: { item: { body: string } }">
|
||||
<v-tooltip :text="item.body">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-btn v-bind="props" rounded="xl" variant="tonal" color="primary" size="x-small">{{ t('core.header.updateDialog.table.view') }}</v-btn>
|
||||
<v-btn v-bind="props" rounded="xl" variant="tonal" color="primary" size="x-small">{{
|
||||
t('core.header.updateDialog.table.view') }}</v-btn>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
</template>
|
||||
@@ -435,14 +437,12 @@ commonStore.getStartTime();
|
||||
<!-- 开发版 -->
|
||||
<v-tabs-window-item key="1" v-show="tab == 1">
|
||||
<div style="margin-top: 16px;">
|
||||
<v-data-table
|
||||
:headers="[
|
||||
{ title: t('core.header.updateDialog.table.sha'), key: 'sha' },
|
||||
{ title: t('core.header.updateDialog.table.date'), key: 'date' },
|
||||
{ title: t('core.header.updateDialog.table.message'), key: 'message' },
|
||||
{ title: t('core.header.updateDialog.table.actions'), key: 'switch' }
|
||||
]"
|
||||
:items="devCommits" item-key="sha">
|
||||
<v-data-table :headers="[
|
||||
{ title: t('core.header.updateDialog.table.sha'), key: 'sha' },
|
||||
{ title: t('core.header.updateDialog.table.date'), key: 'date' },
|
||||
{ title: t('core.header.updateDialog.table.message'), key: 'message' },
|
||||
{ title: t('core.header.updateDialog.table.actions'), key: 'switch' }
|
||||
]" :items="devCommits" item-key="sha">
|
||||
<template v-slot:item.switch="{ item }: { item: { sha: string } }">
|
||||
<v-btn @click="switchVersion(item.sha)" rounded="xl" variant="plain" color="primary">
|
||||
{{ t('core.header.updateDialog.table.switch') }}
|
||||
@@ -457,11 +457,12 @@ commonStore.getStartTime();
|
||||
<h3 class="mb-4">{{ t('core.header.updateDialog.manualInput.title') }}</h3>
|
||||
|
||||
<v-text-field :label="t('core.header.updateDialog.manualInput.placeholder')" v-model="version" required
|
||||
variant="outlined"></v-text-field>
|
||||
variant="outlined"></v-text-field>
|
||||
<div class="mb-4">
|
||||
<small>{{ t('core.header.updateDialog.manualInput.hint') }}</small>
|
||||
<br>
|
||||
<a href="https://github.com/Soulter/AstrBot/commits/master"><small>{{ t('core.header.updateDialog.manualInput.linkText') }}</small></a>
|
||||
<a href="https://github.com/Soulter/AstrBot/commits/master"><small>{{
|
||||
t('core.header.updateDialog.manualInput.linkText') }}</small></a>
|
||||
</div>
|
||||
<v-btn color="error" style="border-radius: 10px;" @click="switchVersion(version)">
|
||||
{{ t('core.header.updateDialog.manualInput.confirm') }}
|
||||
@@ -471,7 +472,8 @@ commonStore.getStartTime();
|
||||
<div style="margin-top: 16px;">
|
||||
<h3 class="mb-4">{{ t('core.header.updateDialog.dashboardUpdate.title') }}</h3>
|
||||
<div class="mb-4">
|
||||
<small>{{ t('core.header.updateDialog.dashboardUpdate.currentVersion') }} {{ dashboardCurrentVersion }}</small>
|
||||
<small>{{ t('core.header.updateDialog.dashboardUpdate.currentVersion') }} {{ dashboardCurrentVersion
|
||||
}}</small>
|
||||
<br>
|
||||
|
||||
</div>
|
||||
@@ -486,7 +488,7 @@ commonStore.getStartTime();
|
||||
</div>
|
||||
|
||||
<v-btn color="primary" style="border-radius: 10px;" @click="updateDashboard()"
|
||||
:disabled="!dashboardHasNewVersion" :loading="updatingDashboardLoading">
|
||||
:disabled="!dashboardHasNewVersion" :loading="updatingDashboardLoading">
|
||||
{{ t('core.header.updateDialog.dashboardUpdate.downloadAndUpdate') }}
|
||||
</v-btn>
|
||||
</div>
|
||||
@@ -504,9 +506,9 @@ commonStore.getStartTime();
|
||||
<!-- 账户对话框 -->
|
||||
<v-dialog v-model="dialog" persistent :max-width="$vuetify.display.xs ? '90%' : '500'">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-btn size="small" class="action-btn mr-4" color="var(--v-theme-surface)" variant="flat" rounded="sm" v-bind="props">
|
||||
<v-btn size="small" class="action-btn mr-4" color="var(--v-theme-surface)" variant="flat" rounded="sm"
|
||||
v-bind="props" icon>
|
||||
<v-icon>mdi-account</v-icon>
|
||||
<span class="hidden-xs ml-1">{{ t('core.header.buttons.account') }}</span>
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-card class="account-dialog">
|
||||
@@ -514,105 +516,51 @@ commonStore.getStartTime();
|
||||
<div class="d-flex flex-column align-center mb-6">
|
||||
<logo :title="t('core.header.logoTitle')" :subtitle="t('core.header.accountDialog.title')"></logo>
|
||||
</div>
|
||||
<v-alert
|
||||
v-if="accountWarning"
|
||||
type="warning"
|
||||
variant="tonal"
|
||||
border="start"
|
||||
class="mb-4"
|
||||
>
|
||||
<v-alert v-if="accountWarning" type="warning" variant="tonal" border="start" class="mb-4">
|
||||
<strong>{{ t('core.header.accountDialog.securityWarning') }}</strong>
|
||||
</v-alert>
|
||||
|
||||
<v-alert
|
||||
v-if="accountEditStatus.success"
|
||||
type="success"
|
||||
variant="tonal"
|
||||
border="start"
|
||||
class="mb-4"
|
||||
>
|
||||
<v-alert v-if="accountEditStatus.success" type="success" variant="tonal" border="start" class="mb-4">
|
||||
{{ accountEditStatus.message }}
|
||||
</v-alert>
|
||||
|
||||
<v-alert
|
||||
v-if="accountEditStatus.error"
|
||||
type="error"
|
||||
variant="tonal"
|
||||
border="start"
|
||||
class="mb-4"
|
||||
>
|
||||
<v-alert v-if="accountEditStatus.error" type="error" variant="tonal" border="start" class="mb-4">
|
||||
{{ accountEditStatus.message }}
|
||||
</v-alert>
|
||||
|
||||
<v-form v-model="formValid" @submit.prevent="accountEdit">
|
||||
<v-text-field
|
||||
v-model="password"
|
||||
:append-inner-icon="showPassword ? 'mdi-eye-off' : 'mdi-eye'"
|
||||
:type="showPassword ? 'text' : 'password'"
|
||||
:label="t('core.header.accountDialog.form.currentPassword')"
|
||||
variant="outlined"
|
||||
required
|
||||
clearable
|
||||
@click:append-inner="showPassword = !showPassword"
|
||||
prepend-inner-icon="mdi-lock-outline"
|
||||
hide-details="auto"
|
||||
class="mb-4"
|
||||
></v-text-field>
|
||||
<v-text-field v-model="password" :append-inner-icon="showPassword ? 'mdi-eye-off' : 'mdi-eye'"
|
||||
:type="showPassword ? 'text' : 'password'" :label="t('core.header.accountDialog.form.currentPassword')"
|
||||
variant="outlined" required clearable @click:append-inner="showPassword = !showPassword"
|
||||
prepend-inner-icon="mdi-lock-outline" hide-details="auto" class="mb-4"></v-text-field>
|
||||
|
||||
<v-text-field
|
||||
v-model="newPassword"
|
||||
:append-inner-icon="showNewPassword ? 'mdi-eye-off' : 'mdi-eye'"
|
||||
:type="showNewPassword ? 'text' : 'password'"
|
||||
:rules="passwordRules"
|
||||
:label="t('core.header.accountDialog.form.newPassword')"
|
||||
variant="outlined"
|
||||
required
|
||||
clearable
|
||||
@click:append-inner="showNewPassword = !showNewPassword"
|
||||
prepend-inner-icon="mdi-lock-plus-outline"
|
||||
:hint="t('core.header.accountDialog.form.passwordHint')"
|
||||
persistent-hint
|
||||
class="mb-4"
|
||||
></v-text-field>
|
||||
<v-text-field v-model="newPassword" :append-inner-icon="showNewPassword ? 'mdi-eye-off' : 'mdi-eye'"
|
||||
:type="showNewPassword ? 'text' : 'password'" :rules="passwordRules"
|
||||
:label="t('core.header.accountDialog.form.newPassword')" variant="outlined" required clearable
|
||||
@click:append-inner="showNewPassword = !showNewPassword" prepend-inner-icon="mdi-lock-plus-outline"
|
||||
:hint="t('core.header.accountDialog.form.passwordHint')" persistent-hint class="mb-4"></v-text-field>
|
||||
|
||||
<v-text-field
|
||||
v-model="newUsername"
|
||||
:rules="usernameRules"
|
||||
:label="t('core.header.accountDialog.form.newUsername')"
|
||||
variant="outlined"
|
||||
clearable
|
||||
prepend-inner-icon="mdi-account-edit-outline"
|
||||
:hint="t('core.header.accountDialog.form.usernameHint')"
|
||||
persistent-hint
|
||||
class="mb-3"
|
||||
></v-text-field>
|
||||
<v-text-field v-model="newUsername" :rules="usernameRules"
|
||||
:label="t('core.header.accountDialog.form.newUsername')" variant="outlined" clearable
|
||||
prepend-inner-icon="mdi-account-edit-outline" :hint="t('core.header.accountDialog.form.usernameHint')"
|
||||
persistent-hint class="mb-3"></v-text-field>
|
||||
</v-form>
|
||||
|
||||
|
||||
<div class="text-caption text-medium-emphasis mt-2">
|
||||
{{ t('core.header.accountDialog.form.defaultCredentials') }}
|
||||
</div>
|
||||
</v-card-text>
|
||||
|
||||
|
||||
<v-divider></v-divider>
|
||||
|
||||
|
||||
<v-card-actions class="pa-4">
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn
|
||||
v-if="!accountWarning"
|
||||
variant="tonal"
|
||||
color="secondary"
|
||||
@click="dialog = false"
|
||||
:disabled="accountEditStatus.loading"
|
||||
>
|
||||
<v-btn v-if="!accountWarning" variant="tonal" color="secondary" @click="dialog = false"
|
||||
:disabled="accountEditStatus.loading">
|
||||
{{ t('core.header.accountDialog.actions.cancel') }}
|
||||
</v-btn>
|
||||
<v-btn
|
||||
color="primary"
|
||||
@click="accountEdit"
|
||||
:loading="accountEditStatus.loading"
|
||||
:disabled="!formValid"
|
||||
prepend-icon="mdi-content-save"
|
||||
>
|
||||
<v-btn color="primary" @click="accountEdit" :loading="accountEditStatus.loading" :disabled="!formValid"
|
||||
prepend-icon="mdi-content-save">
|
||||
{{ t('core.header.accountDialog.actions.save') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
@@ -665,9 +613,9 @@ commonStore.getStartTime();
|
||||
|
||||
/* 响应式布局样式 */
|
||||
.logo-container {
|
||||
margin-left: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-left: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -678,7 +626,7 @@ commonStore.getStartTime();
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
font-size: 24px;
|
||||
font-size: 24px;
|
||||
font-weight: 1000;
|
||||
}
|
||||
|
||||
@@ -687,7 +635,7 @@ commonStore.getStartTime();
|
||||
}
|
||||
|
||||
.version-text {
|
||||
font-size: 12px;
|
||||
font-size: 12px;
|
||||
color: var(--v-theme-secondaryText);
|
||||
}
|
||||
|
||||
@@ -707,7 +655,7 @@ commonStore.getStartTime();
|
||||
.logo-text {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
|
||||
.action-btn {
|
||||
margin-right: 4px;
|
||||
min-width: 32px !important;
|
||||
@@ -717,11 +665,11 @@ commonStore.getStartTime();
|
||||
.v-card-title {
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
|
||||
.v-card-text {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
|
||||
.v-tabs .v-tab {
|
||||
padding: 0 10px;
|
||||
font-size: 0.9rem;
|
||||
|
||||
Reference in New Issue
Block a user