@@ -340,12 +340,12 @@ export default {
|
||||
.config-title {
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
color: var(--v-primary-darken1);
|
||||
color: var(--v-theme-primaryText);
|
||||
}
|
||||
|
||||
.config-hint {
|
||||
font-size: 0.75rem;
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
color: var(--v-theme-secondaryText);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
@@ -400,12 +400,12 @@ export default {
|
||||
.property-name {
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
color: var(--v-theme-primaryText);
|
||||
}
|
||||
|
||||
.property-hint {
|
||||
font-size: 0.75rem;
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
color: var(--v-theme-secondaryText);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, inject } from 'vue';
|
||||
import {useCustomizerStore} from "@/stores/customizer";
|
||||
|
||||
const props = defineProps({
|
||||
extension: {
|
||||
@@ -75,7 +76,9 @@ const viewReadme = () => {
|
||||
|
||||
<template>
|
||||
<v-card class="mx-auto d-flex flex-column" :elevation="highlight ? 0 : 1"
|
||||
:style="{ height: $vuetify.display.xs ? '250px' : '220px', backgroundColor: highlight ? '#FAF0DB' : '#ffffff', color: highlight ? '#000' : '#000000' }">
|
||||
:style="{ height: $vuetify.display.xs ? '250px' : '220px',
|
||||
backgroundColor: useCustomizerStore().uiTheme==='PurpleTheme' ? '#eef2f6' : '#282833',
|
||||
color: useCustomizerStore().uiTheme==='PurpleTheme' ? '#000000dd' : '#ffffff'}">
|
||||
<v-card-text style="padding: 16px; padding-bottom: 0px; display: flex; justify-content: space-between;">
|
||||
|
||||
<div class="flex-grow-1">
|
||||
|
||||
@@ -104,11 +104,11 @@ export default {
|
||||
|
||||
<style scoped>
|
||||
.list-config-item {
|
||||
border: 1px solid #e0e0e0;
|
||||
border: 1px solid var(--v-theme-border);
|
||||
padding: 16px;
|
||||
margin-bottom: 8px;
|
||||
border-radius: 10px;
|
||||
background-color: #ffffff;
|
||||
background-color: var(--v-theme-background);
|
||||
}
|
||||
|
||||
.v-list-item {
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
</div>
|
||||
<div class="logo-text">
|
||||
<h2 class="text-secondary">AstrBot 仪表盘</h2>
|
||||
<h4 class="text-disabled">登录以继续</h4>
|
||||
<!-- 父子组件传递css变量可能会出错,暂时使用十六进制颜色值 -->
|
||||
<h4 :style="{color: useCustomizerStore().uiTheme === 'PurpleTheme' ? '#000000aa' : '#ffffffcc'}"
|
||||
class="hint-text">登录以继续</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -14,6 +16,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
// No props or other logic needed for this simple component
|
||||
import {useCustomizerStore} from "@/stores/customizer";
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -56,7 +59,6 @@
|
||||
margin: 0;
|
||||
font-size: 1.8rem;
|
||||
font-weight: 600;
|
||||
color: #5e35b1;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
@@ -64,7 +66,7 @@
|
||||
margin: 4px 0 0 0;
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
color: #616161;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -3,14 +3,25 @@ export type ConfigProps = {
|
||||
Customizer_drawer: boolean;
|
||||
mini_sidebar: boolean;
|
||||
fontTheme: string;
|
||||
uiTheme: string;
|
||||
inputBg: boolean;
|
||||
};
|
||||
|
||||
function checkUITheme() {
|
||||
const theme = localStorage.getItem("uiTheme");
|
||||
console.log('memorized theme: ', theme);
|
||||
if (!theme || !(['PurpleTheme', 'PurpleThemeDark'].includes(theme))) {
|
||||
localStorage.setItem("uiTheme", "PurpleTheme");
|
||||
return 'PurpleTheme';
|
||||
} else return theme;
|
||||
}
|
||||
|
||||
const config: ConfigProps = {
|
||||
Sidebar_drawer: true,
|
||||
Customizer_drawer: false,
|
||||
mini_sidebar: false,
|
||||
fontTheme: 'Roboto',
|
||||
uiTheme: checkUITheme(),
|
||||
inputBg: false
|
||||
};
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ const customizer = useCustomizerStore();
|
||||
<template>
|
||||
<v-locale-provider>
|
||||
<v-app
|
||||
theme="PurpleTheme"
|
||||
:theme="useCustomizerStore().uiTheme"
|
||||
:class="[customizer.fontTheme, customizer.mini_sidebar ? 'mini-sidebar' : '', customizer.inputBg ? 'inputWithbg' : '']"
|
||||
>
|
||||
<VerticalHeaderVue />
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useCustomizerStore } from '../../../stores/customizer';
|
||||
import {ref} from 'vue';
|
||||
import {useCustomizerStore} from '@/stores/customizer';
|
||||
import axios from 'axios';
|
||||
import { md5 } from 'js-md5';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import { useCommonStore } from '@/stores/common';
|
||||
import { marked } from 'marked';
|
||||
import {md5} from 'js-md5';
|
||||
import {useAuthStore} from '@/stores/auth';
|
||||
import {useCommonStore} from '@/stores/common';
|
||||
import {marked} from 'marked';
|
||||
|
||||
const customizer = useCustomizerStore();
|
||||
let dialog = ref(false);
|
||||
@@ -30,11 +30,11 @@ let installLoading = ref(false);
|
||||
let tab = ref(0);
|
||||
|
||||
let releasesHeader = [
|
||||
{ title: '标签', key: 'tag_name' },
|
||||
{ title: '发布时间', key: 'published_at' },
|
||||
{ title: '内容', key: 'body' },
|
||||
{ title: '源码地址', key: 'zipball_url' },
|
||||
{ title: '操作', key: 'switch' }
|
||||
{title: '标签', key: 'tag_name'},
|
||||
{title: '发布时间', key: 'published_at'},
|
||||
{title: '内容', key: 'body'},
|
||||
{title: '源码地址', key: 'zipball_url'},
|
||||
{title: '操作', key: 'switch'}
|
||||
];
|
||||
|
||||
const open = (link: string) => {
|
||||
@@ -56,78 +56,78 @@ function accountEdit() {
|
||||
new_password: newPassword.value,
|
||||
new_username: newUsername.value
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.data.status == 'error') {
|
||||
.then((res) => {
|
||||
if (res.data.status == 'error') {
|
||||
status.value = res.data.message;
|
||||
password.value = '';
|
||||
newPassword.value = '';
|
||||
return;
|
||||
}
|
||||
dialog.value = !dialog.value;
|
||||
status.value = res.data.message;
|
||||
setTimeout(() => {
|
||||
const authStore = useAuthStore();
|
||||
authStore.logout();
|
||||
}, 1000);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
status.value = err
|
||||
password.value = '';
|
||||
newPassword.value = '';
|
||||
return;
|
||||
}
|
||||
dialog.value = !dialog.value;
|
||||
status.value = res.data.message;
|
||||
setTimeout(() => {
|
||||
const authStore = useAuthStore();
|
||||
authStore.logout();
|
||||
}, 1000);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
status.value = err
|
||||
password.value = '';
|
||||
newPassword.value = '';
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getVersion() {
|
||||
axios.get('/api/stat/version')
|
||||
.then((res) => {
|
||||
botCurrVersion.value = "v" + res.data.data.version;
|
||||
dashboardCurrentVersion.value = res.data.data?.dashboard_version;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
.then((res) => {
|
||||
botCurrVersion.value = "v" + res.data.data.version;
|
||||
dashboardCurrentVersion.value = res.data.data?.dashboard_version;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
|
||||
function checkUpdate() {
|
||||
updateStatus.value = '正在检查更新...';
|
||||
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 = '有新版本!';
|
||||
} else {
|
||||
updateStatus.value = res.data.message;
|
||||
}
|
||||
dashboardHasNewVersion.value = res.data.data.dashboard_has_new_version;
|
||||
})
|
||||
.catch((err) => {
|
||||
if (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 = '有新版本!';
|
||||
} else {
|
||||
updateStatus.value = res.data.message;
|
||||
}
|
||||
dashboardHasNewVersion.value = res.data.data.dashboard_has_new_version;
|
||||
})
|
||||
.catch((err) => {
|
||||
if (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;
|
||||
// 更新 published_at 的时间为本地时间
|
||||
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;
|
||||
// 更新 published_at 的时间为本地时间
|
||||
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() {
|
||||
@@ -137,17 +137,17 @@ function getDevCommits() {
|
||||
'Referer': 'https://api.github.com'
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
devCommits.value = data.map((commit: any) => ({
|
||||
sha: commit.sha,
|
||||
date: new Date(commit.commit.author.date).toLocaleString(),
|
||||
message: commit.commit.message
|
||||
}));
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
});
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
devCommits.value = data.map((commit: any) => ({
|
||||
sha: commit.sha,
|
||||
date: new Date(commit.commit.author.date).toLocaleString(),
|
||||
message: commit.commit.message
|
||||
}));
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
|
||||
function switchVersion(version: string) {
|
||||
@@ -157,37 +157,41 @@ 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() {
|
||||
updateStatus.value = '正在更新...';
|
||||
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
|
||||
});
|
||||
.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
|
||||
});
|
||||
}
|
||||
|
||||
function toggleDarkMode() {
|
||||
customizer.SET_UI_THEME(customizer.uiTheme === 'PurpleThemeDark' ? 'PurpleTheme' : 'PurpleThemeDark');
|
||||
}
|
||||
|
||||
getVersion();
|
||||
@@ -209,22 +213,30 @@ if (localStorage.getItem('change_pwd_hint') != null && localStorage.getItem('cha
|
||||
<template>
|
||||
<v-app-bar elevation="0" height="55">
|
||||
|
||||
<v-btn 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 class="hidden-lg-and-up text-secondary ms-3" color="lightsecondary" icon rounded="sm" variant="flat"
|
||||
@click.stop="customizer.SET_SIDEBAR_DRAWER" 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 text-secondary 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">
|
||||
<v-icon>mdi-menu</v-icon>
|
||||
</v-btn>
|
||||
|
||||
<div style="margin-left: 16px; display: flex; align-items: center; gap: 8px;">
|
||||
<span style=" font-size: 24px; font-weight: 1000;">Astr<span style="font-weight: normal;">Bot</span>
|
||||
</span>
|
||||
<span style="font-size: 12px; color: #333333;">{{ botCurrVersion }}</span>
|
||||
<span style="font-size: 12px; color: var(--v-theme-secondaryText);">{{ botCurrVersion }}</span>
|
||||
</div>
|
||||
|
||||
<v-spacer />
|
||||
<v-spacer/>
|
||||
|
||||
<div class="mr-4">
|
||||
<small v-if="hasNewVersion">
|
||||
@@ -235,11 +247,18 @@ if (localStorage.getItem('change_pwd_hint') != null && localStorage.getItem('cha
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<v-btn size="small" @click="toggleDarkMode();" class="text-primary mr-2" color="var(--v-theme-surface)"
|
||||
variant="flat" rounded="sm">
|
||||
<!-- 明暗主题切换按钮 -->
|
||||
<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="1000">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-btn size="small" @click="checkUpdate(); getReleases(); getDevCommits();" class="text-primary mr-2" color="lightprimary"
|
||||
variant="flat" rounded="sm" v-bind="props">
|
||||
<v-btn size="small" @click="checkUpdate(); getReleases(); getDevCommits();" class="text-primary mr-2"
|
||||
color="var(--v-theme-surface)"
|
||||
variant="flat" rounded="sm" v-bind="props">
|
||||
更新
|
||||
</v-btn>
|
||||
</template>
|
||||
@@ -257,15 +276,16 @@ if (localStorage.getItem('change_pwd_hint') != null && localStorage.getItem('cha
|
||||
</div>
|
||||
|
||||
<div
|
||||
style="background-color: #646cff24; padding: 16px; border-radius: 10px; font-size: 14px; max-height: 400px; overflow-y: auto;"
|
||||
v-html="marked(releaseMessage)" class="markdown-content">
|
||||
style="background-color: #646cff24; padding: 16px; border-radius: 10px; font-size: 14px; max-height: 400px; overflow-y: auto;"
|
||||
v-html="marked(releaseMessage)" class="markdown-content">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="mb-4 mt-4">
|
||||
<small>💡 TIP: 跳到旧版本或者切换到某个版本不会重新下载管理面板文件,这可能会造成部分数据显示错误。您可在 <a
|
||||
href="https://github.com/Soulter/AstrBot/releases">此处</a>
|
||||
找到对应的面板文件 dist.zip,解压后替换 data/dist 文件夹即可。当然,前端源代码在 dashboard 目录下,你也可以自己使用 npm install 和 npm build
|
||||
找到对应的面板文件 dist.zip,解压后替换 data/dist 文件夹即可。当然,前端源代码在 dashboard 目录下,你也可以自己使用
|
||||
npm install 和 npm build
|
||||
构建。</small>
|
||||
</div>
|
||||
|
||||
@@ -278,12 +298,13 @@ if (localStorage.getItem('change_pwd_hint') != null && localStorage.getItem('cha
|
||||
<!-- 发行版 -->
|
||||
<v-tabs-window-item key="0" v-show="tab == 0">
|
||||
<v-btn class="mt-4 mb-4" @click="switchVersion('latest')" color="primary" style="border-radius: 10px;"
|
||||
:disabled="!hasNewVersion">
|
||||
:disabled="!hasNewVersion">
|
||||
更新到最新版本
|
||||
</v-btn>
|
||||
<div class="mb-4">
|
||||
<small>`更新到最新版本` 按钮会同时尝试更新机器人主程序和管理面板。如果您正在使用 Docker 部署,也可以重新拉取镜像或者使用 <a
|
||||
href="https://containrrr.dev/watchtower/usage-overview/">watchtower</a> 来自动监控拉取。</small>
|
||||
<small>`更新到最新版本` 按钮会同时尝试更新机器人主程序和管理面板。如果您正在使用 Docker
|
||||
部署,也可以重新拉取镜像或者使用 <a
|
||||
href="https://containrrr.dev/watchtower/usage-overview/">watchtower</a> 来自动监控拉取。</small>
|
||||
</div>
|
||||
|
||||
<v-data-table :headers="releasesHeader" :items="releases" item-key="name">
|
||||
@@ -306,8 +327,8 @@ if (localStorage.getItem('change_pwd_hint') != null && localStorage.getItem('cha
|
||||
<v-tabs-window-item key="1" v-show="tab == 1">
|
||||
<div style="margin-top: 16px;">
|
||||
<v-data-table
|
||||
:headers="[{ title: 'SHA', key: 'sha' }, { title: '日期', key: 'date' }, { title: '信息', key: 'message' }, { title: '操作', key: 'switch' }]"
|
||||
:items="devCommits" item-key="sha">
|
||||
:headers="[{ title: 'SHA', key: 'sha' }, { title: '日期', key: 'date' }, { title: '信息', key: 'message' }, { title: '操作', 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">
|
||||
切换
|
||||
@@ -322,12 +343,13 @@ if (localStorage.getItem('change_pwd_hint') != null && localStorage.getItem('cha
|
||||
<h3 class="mb-4">手动输入版本号或 Commit SHA</h3>
|
||||
|
||||
<v-text-field label="输入版本号或 master 分支下的 commit hash。" v-model="version" required
|
||||
variant="outlined"></v-text-field>
|
||||
variant="outlined"></v-text-field>
|
||||
<div class="mb-4">
|
||||
<small>如 v3.3.16 (不带 SHA) 或 42e5ec5d80b93b6bfe8b566754d45ffac4c3fe0b</small>
|
||||
<br>
|
||||
<a href="https://github.com/Soulter/AstrBot/commits/master"><small>查看 master 分支提交记录(点击右边的 copy
|
||||
即可复制)</small></a>
|
||||
<a href="https://github.com/Soulter/AstrBot/commits/master"><small>查看 master 分支提交记录(点击右边的
|
||||
copy
|
||||
即可复制)</small></a>
|
||||
</div>
|
||||
<v-btn color="error" style="border-radius: 10px;" @click="switchVersion(version)">
|
||||
确定切换
|
||||
@@ -352,7 +374,7 @@ if (localStorage.getItem('change_pwd_hint') != null && localStorage.getItem('cha
|
||||
</div>
|
||||
|
||||
<v-btn color="primary" style="border-radius: 10px;" @click="updateDashboard()"
|
||||
:disabled="!dashboardHasNewVersion">
|
||||
:disabled="!dashboardHasNewVersion">
|
||||
下载并更新
|
||||
</v-btn>
|
||||
</div>
|
||||
@@ -369,7 +391,7 @@ if (localStorage.getItem('change_pwd_hint') != null && localStorage.getItem('cha
|
||||
|
||||
<v-dialog v-model="dialog" persistent width="700">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-btn size="small" class="text-primary mr-4" color="lightprimary" variant="flat" rounded="sm" v-bind="props">
|
||||
<v-btn size="small" class="text-primary mr-4" color="var(--v-theme-surface)" variant="flat" rounded="sm" v-bind="props">
|
||||
账户
|
||||
</v-btn>
|
||||
</template>
|
||||
@@ -387,12 +409,12 @@ if (localStorage.getItem('change_pwd_hint') != null && localStorage.getItem('cha
|
||||
</v-alert>
|
||||
|
||||
<v-text-field label="原密码*" type="password" v-model="password" required
|
||||
variant="outlined"></v-text-field>
|
||||
variant="outlined"></v-text-field>
|
||||
|
||||
<v-text-field label="新用户名" v-model="newUsername" required variant="outlined"></v-text-field>
|
||||
|
||||
<v-text-field label="新密码" type="password" v-model="newPassword" required
|
||||
variant="outlined"></v-text-field>
|
||||
variant="outlined"></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
|
||||
@@ -3,6 +3,7 @@ import '@mdi/font/css/materialdesignicons.css';
|
||||
import * as components from 'vuetify/components';
|
||||
import * as directives from 'vuetify/directives';
|
||||
import { PurpleTheme } from '@/theme/LightTheme';
|
||||
import { PurpleThemeDark } from "@/theme/DarkTheme";
|
||||
|
||||
export default createVuetify({
|
||||
components,
|
||||
@@ -11,7 +12,8 @@ export default createVuetify({
|
||||
theme: {
|
||||
defaultTheme: 'PurpleTheme',
|
||||
themes: {
|
||||
PurpleTheme
|
||||
PurpleTheme,
|
||||
PurpleThemeDark
|
||||
}
|
||||
},
|
||||
defaults: {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
.listitem {
|
||||
height: calc(100vh - 100px);
|
||||
.v-list {
|
||||
color: rgb(var(--v-theme-lightText));
|
||||
color: rgb(var(--v-theme-secondaryText));
|
||||
}
|
||||
.v-list-group__items .v-list-item,
|
||||
.v-list-item {
|
||||
|
||||
@@ -8,6 +8,7 @@ export const useCustomizerStore = defineStore({
|
||||
Customizer_drawer: config.Customizer_drawer,
|
||||
mini_sidebar: config.mini_sidebar,
|
||||
fontTheme: "Poppins",
|
||||
uiTheme: config.uiTheme,
|
||||
inputBg: config.inputBg
|
||||
}),
|
||||
|
||||
@@ -21,6 +22,10 @@ export const useCustomizerStore = defineStore({
|
||||
},
|
||||
SET_FONT(payload: string) {
|
||||
this.fontTheme = payload;
|
||||
}
|
||||
},
|
||||
SET_UI_THEME(payload: string) {
|
||||
this.uiTheme = payload;
|
||||
localStorage.setItem("uiTheme", payload);
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import type { ThemeTypes } from '@/types/themeTypes/ThemeType';
|
||||
|
||||
const PurpleThemeDark: ThemeTypes = {
|
||||
name: 'PurpleThemeDark',
|
||||
dark: true,
|
||||
variables: {
|
||||
'border-color': '#1677ff',
|
||||
'carousel-control-size': 10
|
||||
},
|
||||
colors: {
|
||||
primary: '#1677ff',
|
||||
secondary: '#722ed1',
|
||||
info: '#03c9d7',
|
||||
success: '#52c41a',
|
||||
accent: '#FFAB91',
|
||||
warning: '#faad14',
|
||||
error: '#ff4d4f',
|
||||
lightprimary: '#eef2f6',
|
||||
lightsecondary: '#ede7f6',
|
||||
lightsuccess: '#b9f6ca',
|
||||
lighterror: '#f9d8d8',
|
||||
lightwarning: '#fff8e1',
|
||||
primaryText: '#ffffff',
|
||||
secondaryText: '#ffffffcc',
|
||||
darkprimary: '#1565c0',
|
||||
darksecondary: '#4527a0',
|
||||
borderLight: '#d0d0d0',
|
||||
border: '#333333ee',
|
||||
inputBorder: '#787878',
|
||||
containerBg: '#1a1a1a',
|
||||
surface: '#1f1f1f',
|
||||
'on-surface-variant': '#000',
|
||||
facebook: '#4267b2',
|
||||
twitter: '#1da1f2',
|
||||
linkedin: '#0e76a8',
|
||||
gray100: '#cccccccc',
|
||||
primary200: '#90caf9',
|
||||
secondary200: '#b39ddb',
|
||||
background: '#111111',
|
||||
overlay: '#111111aa',
|
||||
codeBg: '#282833',
|
||||
code: '#ffffffdd'
|
||||
}
|
||||
};
|
||||
|
||||
export { PurpleThemeDark };
|
||||
@@ -20,11 +20,12 @@ const PurpleTheme: ThemeTypes = {
|
||||
lightsuccess: '#b9f6ca',
|
||||
lighterror: '#f9d8d8',
|
||||
lightwarning: '#fff8e1',
|
||||
darkText: '#212121',
|
||||
lightText: '#616161',
|
||||
primaryText: '#000000dd',
|
||||
secondaryText: '#000000aa',
|
||||
darkprimary: '#1565c0',
|
||||
darksecondary: '#4527a0',
|
||||
borderLight: '#d0d0d0',
|
||||
border: '#d0d0d0',
|
||||
inputBorder: '#787878',
|
||||
containerBg: '#eef2f6',
|
||||
surface: '#fff',
|
||||
@@ -32,9 +33,13 @@ const PurpleTheme: ThemeTypes = {
|
||||
facebook: '#4267b2',
|
||||
twitter: '#1da1f2',
|
||||
linkedin: '#0e76a8',
|
||||
gray100: '#fafafa',
|
||||
gray100: '#fafafacc',
|
||||
primary200: '#90caf9',
|
||||
secondary200: '#b39ddb'
|
||||
secondary200: '#b39ddb',
|
||||
background: '#f9fafcf4',
|
||||
overlay: '#ffffffaa',
|
||||
codeBg: '#f5f0ff',
|
||||
code: '#673ab7'
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -17,13 +17,15 @@ export type ThemeTypes = {
|
||||
lightwarning?: string;
|
||||
darkprimary?: string;
|
||||
darksecondary?: string;
|
||||
darkText?: string;
|
||||
lightText?: string;
|
||||
primaryText?: string;
|
||||
secondaryText?: string;
|
||||
borderLight?: string;
|
||||
border?: string;
|
||||
inputBorder?: string;
|
||||
containerBg?: string;
|
||||
surface?: string;
|
||||
background?: string;
|
||||
overlay?: string;
|
||||
'on-surface-variant'?: string;
|
||||
facebook?: string;
|
||||
twitter?: string;
|
||||
@@ -31,5 +33,7 @@ export type ThemeTypes = {
|
||||
gray100?: string;
|
||||
primary200?: string;
|
||||
secondary200?: string;
|
||||
codeBg?: string;
|
||||
code?: string;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</div>
|
||||
<div class="title-container">
|
||||
<h1 class="text-h2 font-weight-bold">AstrBot</h1>
|
||||
<p class="text-subtitle-1" style="color: #777;">A project out of interests and loves ❤️</p>
|
||||
<p class="text-subtitle-1" style="color: var(--v-theme-secondaryText);">A project out of interests and loves ❤️</p>
|
||||
<div class="action-buttons">
|
||||
<v-btn @click="open('https://github.com/Soulter/AstrBot')"
|
||||
color="primary" variant="elevated" prepend-icon="mdi-star">
|
||||
@@ -32,16 +32,20 @@
|
||||
<v-row justify="center" align="center">
|
||||
<v-col cols="12" md="6" class="pr-md-8 contributors-info">
|
||||
<h2 class="text-h4 font-weight-medium">贡献者</h2>
|
||||
<p class="mb-4 text-body-1" style="color: #777;">
|
||||
<p class="mb-4 text-body-1" style="color: var(--v-theme-secondaryText);">
|
||||
本项目由众多开源社区成员共同维护。感谢每一位贡献者的付出!
|
||||
</p>
|
||||
<p class="text-body-1" style="color: #777;">
|
||||
<p class="text-body-1" style="color: var(--v-theme-secondaryText);">
|
||||
<a href="https://github.com/Soulter/AstrBot/graphs/contributors" class="text-decoration-none custom-link">查看 AstrBot 贡献者</a>
|
||||
</p>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<v-card variant="outlined" class="overflow-hidden" elevation="2">
|
||||
<v-img
|
||||
<v-img v-if="useCustomizerStore().uiTheme==='PurpleThemeDark'"
|
||||
alt="Active Contributors of Soulter/AstrBot"
|
||||
src="https://next.ossinsight.io/widgets/official/compose-recent-active-contributors/thumbnail.png?repo_id=575865240&limit=365&image_size=auto&color_scheme=dark">
|
||||
</v-img>
|
||||
<v-img v-else
|
||||
alt="Active Contributors of Soulter/AstrBot"
|
||||
src="https://next.ossinsight.io/widgets/official/compose-recent-active-contributors/thumbnail.png?repo_id=575865240&limit=365&image_size=auto&color_scheme=light">
|
||||
</v-img>
|
||||
@@ -60,12 +64,16 @@
|
||||
|
||||
<div class="license-container mt-8">
|
||||
<img v-bind="props" src="https://www.gnu.org/graphics/agplv3-with-text-100x42.png" style="cursor: pointer;"/>
|
||||
<p class="text-caption mt-2" style="color: #777;">AstrBot 采用 AGPL v3 协议开源</p>
|
||||
<p class="text-caption mt-2" style="color: var(--v-theme-secondaryText);">AstrBot 采用 AGPL v3 协议开源</p>
|
||||
</div>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<v-card variant="outlined" class="overflow-hidden" elevation="2">
|
||||
<v-img
|
||||
<v-img v-if="useCustomizerStore().uiTheme==='PurpleThemeDark'"
|
||||
alt="Stars Map of Soulter/AstrBot"
|
||||
src="https://next.ossinsight.io/widgets/official/analyze-repo-stars-map/thumbnail.png?activity=stars&repo_id=575865240&image_size=auto&color_scheme=dark">
|
||||
</v-img>
|
||||
<v-img v-else
|
||||
alt="Stars Map of Soulter/AstrBot"
|
||||
src="https://next.ossinsight.io/widgets/official/analyze-repo-stars-map/thumbnail.png?activity=stars&repo_id=575865240&image_size=auto&color_scheme=light">
|
||||
</v-img>
|
||||
@@ -80,6 +88,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {useCustomizerStore} from "@/stores/customizer";
|
||||
|
||||
export default {
|
||||
name: 'AboutPage',
|
||||
data() {
|
||||
@@ -89,6 +99,7 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
useCustomizerStore,
|
||||
open(url) {
|
||||
window.open(url, '_blank');
|
||||
}
|
||||
@@ -137,7 +148,7 @@ export default {
|
||||
}
|
||||
|
||||
.contributors-section {
|
||||
background-color: #f9f9fb;
|
||||
background-color: var(--v-theme-containerBg, #f9f9fb);
|
||||
}
|
||||
|
||||
.contributors-info, .stats-info {
|
||||
|
||||
@@ -33,7 +33,7 @@ marked.setOptions({
|
||||
<v-list density="compact" nav class="conversation-list"
|
||||
@update:selected="getConversationMessages">
|
||||
<v-list-item v-for="(item, i) in conversations" :key="item.cid" :value="item.cid"
|
||||
color="primary" rounded="lg" class="conversation-item" active-color="primary">
|
||||
rounded="lg" class="conversation-item" active-color="primary">
|
||||
<template v-slot:prepend>
|
||||
<v-icon size="small" icon="mdi-message-text-outline"></v-icon>
|
||||
</template>
|
||||
@@ -720,7 +720,7 @@ export default {
|
||||
height: 100%;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05) !important;
|
||||
background-color: #fff;
|
||||
background-color: var(--v-theme-surface);
|
||||
}
|
||||
|
||||
.chat-page-container {
|
||||
@@ -743,7 +743,7 @@ export default {
|
||||
flex-direction: column;
|
||||
padding: 0;
|
||||
border-right: 1px solid rgba(0, 0, 0, 0.05);
|
||||
background-color: #fcfcfc;
|
||||
background-color: var(--v-theme-surface) !important;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
@@ -766,7 +766,7 @@ export default {
|
||||
.sidebar-section-title {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #666;
|
||||
color: var(--v-theme-secondaryText);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
margin-bottom: 12px;
|
||||
@@ -824,7 +824,7 @@ export default {
|
||||
|
||||
.timestamp {
|
||||
font-size: 11px;
|
||||
color: #999;
|
||||
color: var(--v-theme-secondaryText);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
@@ -867,7 +867,7 @@ export default {
|
||||
|
||||
.no-conversations-text {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
color: var(--v-theme-secondaryText);
|
||||
}
|
||||
|
||||
/* 聊天内容区域 */
|
||||
@@ -903,21 +903,21 @@ export default {
|
||||
.bot-name {
|
||||
font-weight: 700;
|
||||
margin-left: 8px;
|
||||
color: #673ab7;
|
||||
color: var(--v-theme-secondary);
|
||||
}
|
||||
|
||||
.welcome-hint {
|
||||
margin-top: 8px;
|
||||
color: #666;
|
||||
color: var(--v-theme-secondaryText);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.welcome-hint code {
|
||||
background-color: #f5f0ff;
|
||||
background-color: var(--v-theme-codeBg);
|
||||
padding: 2px 6px;
|
||||
margin: 0 4px;
|
||||
border-radius: 4px;
|
||||
color: #673ab7;
|
||||
color: var(--v-theme-code);
|
||||
font-family: 'Fira Code', monospace;
|
||||
font-size: 13px;
|
||||
}
|
||||
@@ -956,15 +956,15 @@ export default {
|
||||
}
|
||||
|
||||
.user-bubble {
|
||||
background-color: #f5f0ff;
|
||||
color: #333;
|
||||
background-color: var(--v-theme-background);
|
||||
color: var(--v-theme-primaryText);
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
|
||||
.bot-bubble {
|
||||
background-color: #fff;
|
||||
border: 1px solid #e8e8e8;
|
||||
color: #333;
|
||||
background-color: var(--v-theme-surface);
|
||||
border: 1px solid var(--v-theme-border);
|
||||
color: var(--v-theme-primaryText);
|
||||
border-top-left-radius: 4px;
|
||||
}
|
||||
|
||||
@@ -1011,9 +1011,9 @@ export default {
|
||||
/* 输入区域样式 */
|
||||
.input-area {
|
||||
padding: 16px;
|
||||
background-color: #fff;
|
||||
background-color: var(--v-theme-surface);
|
||||
position: relative;
|
||||
border-top: 1px solid #f5f5f5;
|
||||
border-top: 1px solid var(--v-theme-border);
|
||||
}
|
||||
|
||||
.message-input {
|
||||
@@ -1083,12 +1083,12 @@ export default {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 10px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
color: var(--v-theme-primaryText);
|
||||
}
|
||||
|
||||
.markdown-content h1 {
|
||||
font-size: 1.8em;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-bottom: 1px solid var(--v-theme-border);
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
@@ -1111,7 +1111,7 @@ export default {
|
||||
}
|
||||
|
||||
.markdown-content pre {
|
||||
background-color: #f8f8f8;
|
||||
background-color: var(--v-theme-surface);
|
||||
padding: 12px;
|
||||
border-radius: 6px;
|
||||
overflow-x: auto;
|
||||
@@ -1119,12 +1119,12 @@ export default {
|
||||
}
|
||||
|
||||
.markdown-content code {
|
||||
background-color: #f5f0ff;
|
||||
background-color: var(--v-theme-codeBg);
|
||||
padding: 2px 4px;
|
||||
border-radius: 4px;
|
||||
font-family: 'Fira Code', monospace;
|
||||
font-size: 0.9em;
|
||||
color: #673ab7;
|
||||
color: var(--v-theme-code);
|
||||
}
|
||||
|
||||
.markdown-content img {
|
||||
@@ -1134,9 +1134,9 @@ export default {
|
||||
}
|
||||
|
||||
.markdown-content blockquote {
|
||||
border-left: 4px solid #673ab7;
|
||||
border-left: 4px solid var(--v-theme-secondary);
|
||||
padding-left: 16px;
|
||||
color: #666;
|
||||
color: var(--v-theme-secondaryText);
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
@@ -1148,13 +1148,13 @@ export default {
|
||||
|
||||
.markdown-content th,
|
||||
.markdown-content td {
|
||||
border: 1px solid #eee;
|
||||
border: 1px solid var(--v-theme-background);
|
||||
padding: 8px 12px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.markdown-content th {
|
||||
background-color: #f5f0ff;
|
||||
background-color: var(--v-theme-containerBg);
|
||||
}
|
||||
|
||||
/* 动画类 */
|
||||
|
||||
@@ -42,7 +42,7 @@ import config from '@/config';
|
||||
<div v-for="(val2, key2, index2) in metadata[key]['metadata']">
|
||||
<!-- <h3>{{ metadata[key]['metadata'][key2]['description'] }}</h3> -->
|
||||
<div v-if="metadata[key]['metadata'][key2]?.config_template"
|
||||
v-show="key2 !== 'platform' && key2 !== 'provider'" style="border: 1px solid #e0e0e0; padding: 8px; margin-bottom: 16px; border-radius: 10px">
|
||||
v-show="key2 !== 'platform' && key2 !== 'provider'" style="border: 1px solid var(--v-theme-border); padding: 8px; margin-bottom: 16px; border-radius: 10px">
|
||||
<!-- 带有 config_template 的配置项 -->
|
||||
<v-list-item-title style="font-weight: bold;">
|
||||
{{ metadata[key]['metadata'][key2]['description'] }} ({{ key2 }})
|
||||
@@ -88,7 +88,7 @@ import config from '@/config';
|
||||
|
||||
<div v-else>
|
||||
<!-- 如果配置项是一个 object,那么 iterable 需要取到这个 object 的值,否则取到整个 config_data -->
|
||||
<div v-if="metadata[key]['metadata'][key2]['type'] == 'object'" style="border: 1px solid #e0e0e0; padding: 8px; margin-bottom: 16px; border-radius: 10px">
|
||||
<div v-if="metadata[key]['metadata'][key2]['type'] == 'object'" style="border: 1px solid var(--v-theme-border); padding: 8px; margin-bottom: 16px; border-radius: 10px">
|
||||
<AstrBotConfig
|
||||
:metadata="metadata[key]['metadata']" :iterable="config_data[key2]" :metadataKey="key2">
|
||||
</AstrBotConfig>
|
||||
|
||||
@@ -7,7 +7,7 @@ import axios from 'axios';
|
||||
<template>
|
||||
<div style="height: 100%;">
|
||||
<div
|
||||
style="background-color: white; padding: 8px; padding-left: 16px; border-radius: 8px; margin-bottom: 16px; display: flex; flex-direction: row; align-items: center; justify-content: space-between;">
|
||||
style="background-color: var(--v-theme-surface); padding: 8px; padding-left: 16px; border-radius: 8px; margin-bottom: 16px; display: flex; flex-direction: row; align-items: center; justify-content: space-between;">
|
||||
<h4>控制台</h4>
|
||||
<div class="d-flex align-center">
|
||||
<v-switch
|
||||
|
||||
@@ -52,13 +52,16 @@ import 'highlight.js/styles/github.css';
|
||||
|
||||
<v-card-text>
|
||||
|
||||
<small style="color: #bbb;">每个插件都是作者无偿提供的的劳动成果。如果您喜欢某个插件,请 Star!</small>
|
||||
<small style="color: var(--v-theme-secondaryText);">每个插件都是作者无偿提供的的劳动成果。如果您喜欢某个插件,请 Star!</small>
|
||||
<div v-if="pinnedPlugins.length > 0" class="mt-4">
|
||||
<h2>🥳 推荐</h2>
|
||||
|
||||
<v-row style="margin-top: 8px;">
|
||||
<v-col cols="12" md="6" lg="6" v-for="plugin in pinnedPlugins">
|
||||
<ExtensionCard :extension="plugin" market-mode="true" :highlight="true" @install="extension_url=plugin.repo; newExtension()">
|
||||
<ExtensionCard :extension="plugin" class="h-120 rounded-lg"
|
||||
market-mode="true" :highlight="true"
|
||||
@install="extension_url=plugin.repo;
|
||||
newExtension()">
|
||||
</ExtensionCard>
|
||||
</v-col>
|
||||
</v-row>
|
||||
@@ -77,7 +80,7 @@ import 'highlight.js/styles/github.css';
|
||||
style="height: 80px; width: 80px; margin-right: 8px; border-radius: 8px; margin-top: 8px; margin-bottom: 8px;"
|
||||
alt="logo">
|
||||
<span v-if="item?.repo"><a :href="item?.repo"
|
||||
style="color: #000; text-decoration:none">{{
|
||||
style="color: var(--v-theme-primaryText, #000); text-decoration:none">{{
|
||||
item.name }}</a></span>
|
||||
<span v-else>{{ item.name }}</span>
|
||||
|
||||
@@ -565,7 +568,7 @@ export default {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
padding: 8px 0;
|
||||
color: #24292e;
|
||||
color: var(--v-theme-secondaryText);
|
||||
}
|
||||
|
||||
.markdown-body h1,
|
||||
@@ -582,13 +585,13 @@ export default {
|
||||
|
||||
.markdown-body h1 {
|
||||
font-size: 2em;
|
||||
border-bottom: 1px solid #eaecef;
|
||||
border-bottom: 1px solid var(--v-theme-border);
|
||||
padding-bottom: 0.3em;
|
||||
}
|
||||
|
||||
.markdown-body h2 {
|
||||
font-size: 1.5em;
|
||||
border-bottom: 1px solid #eaecef;
|
||||
border-bottom: 1px solid var(--v-theme-border);
|
||||
padding-bottom: 0.3em;
|
||||
}
|
||||
|
||||
@@ -600,7 +603,7 @@ export default {
|
||||
.markdown-body code {
|
||||
padding: 0.2em 0.4em;
|
||||
margin: 0;
|
||||
background-color: rgba(27, 31, 35, 0.05);
|
||||
background-color: var(--v-theme-codeBg);
|
||||
border-radius: 3px;
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
|
||||
font-size: 85%;
|
||||
@@ -611,7 +614,7 @@ export default {
|
||||
overflow: auto;
|
||||
font-size: 85%;
|
||||
line-height: 1.45;
|
||||
background-color: #f6f8fa;
|
||||
background-color: var(--v-theme-containerBg);
|
||||
border-radius: 3px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
@@ -631,19 +634,19 @@ export default {
|
||||
max-width: 100%;
|
||||
margin: 8px 0;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
background-color: var(--v-theme-background);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.markdown-body blockquote {
|
||||
padding: 0 1em;
|
||||
color: #6a737d;
|
||||
border-left: 0.25em solid #dfe2e5;
|
||||
color: var(--v-theme-secondaryText);
|
||||
border-left: 0.25em solid var(--v-theme-border);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.markdown-body a {
|
||||
color: #0366d6;
|
||||
color: var(--v-theme-primary);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@@ -662,23 +665,23 @@ export default {
|
||||
.markdown-body table th,
|
||||
.markdown-body table td {
|
||||
padding: 6px 13px;
|
||||
border: 1px solid #dfe2e5;
|
||||
border: 1px solid var(--v-theme-background);
|
||||
}
|
||||
|
||||
.markdown-body table tr {
|
||||
background-color: #fff;
|
||||
border-top: 1px solid #c6cbd1;
|
||||
background-color: var(--v-theme-surface);
|
||||
border-top: 1px solid var(--v-theme-border);
|
||||
}
|
||||
|
||||
.markdown-body table tr:nth-child(2n) {
|
||||
background-color: #f6f8fa;
|
||||
background-color: var(--v-theme-background);
|
||||
}
|
||||
|
||||
.markdown-body hr {
|
||||
height: 0.25em;
|
||||
padding: 0;
|
||||
margin: 24px 0;
|
||||
background-color: #e1e4e8;
|
||||
background-color: var(--v-theme-containerBg);
|
||||
border: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
|
||||
<div style="background-color: white; padding: 8px; padding-left: 16px; border-radius: 8px; margin-bottom: 16px;">
|
||||
<div style="background-color: var(--v-theme-surface, #fff); padding: 8px; padding-left: 16px; border-radius: 8px; margin-bottom: 16px;">
|
||||
|
||||
<v-list lines="two">
|
||||
<v-list-subheader>网络</v-list-subheader>
|
||||
|
||||
@@ -597,7 +597,7 @@ export default {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
background-color: #ffffff;
|
||||
background-color: var(--v-theme-background);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
@@ -630,7 +630,7 @@ export default {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #ffffff;
|
||||
background-color: var(--v-theme-background);
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
margin-bottom: 16px;
|
||||
|
||||
@@ -4,6 +4,7 @@ import Logo from '@/components/shared/Logo.vue';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import { useRouter } from 'vue-router';
|
||||
import {useCustomizerStore} from "@/stores/customizer";
|
||||
|
||||
const cardVisible = ref(false);
|
||||
const router = useRouter();
|
||||
@@ -24,7 +25,7 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="login-page-container">
|
||||
<div v-if="useCustomizerStore().uiTheme==='PurpleTheme'" class="login-page-container">
|
||||
<div class="login-background"></div>
|
||||
<v-card
|
||||
variant="outlined"
|
||||
@@ -42,6 +43,24 @@ onMounted(() => {
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</div>
|
||||
<div v-else class="login-page-container-dark">
|
||||
<div class="login-background-dark"></div>
|
||||
<v-card
|
||||
variant="outlined"
|
||||
class="login-card"
|
||||
:class="{ 'card-visible': cardVisible }"
|
||||
>
|
||||
<v-card-text class="pa-10">
|
||||
<div class="logo-wrapper">
|
||||
<Logo />
|
||||
</div>
|
||||
<div class="divider-container">
|
||||
<v-divider class="custom-divider"></v-divider>
|
||||
</div>
|
||||
<AuthLogin />
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@@ -56,6 +75,17 @@ onMounted(() => {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.login-page-container-dark {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
background: linear-gradient(135deg, #1a1b1c 0%, #1d1e21 100%);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.login-background {
|
||||
position: absolute;
|
||||
width: 200%;
|
||||
@@ -67,6 +97,17 @@ onMounted(() => {
|
||||
animation: rotate 60s linear infinite;
|
||||
}
|
||||
|
||||
.login-background-dark {
|
||||
position: absolute;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
top: -50%;
|
||||
left: -50%;
|
||||
background-color: var(--v-theme-surface);
|
||||
z-index: 0;
|
||||
animation: rotate 60s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
@@ -79,9 +120,11 @@ onMounted(() => {
|
||||
.login-card {
|
||||
max-width: 520px;
|
||||
width: 90%;
|
||||
color: var(--v-theme-primaryText) !important;
|
||||
border-radius: 12px !important;
|
||||
border-color: var(--v-theme-border) !important;
|
||||
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.07) !important;
|
||||
background-color: rgba(255, 255, 255, 0.98) !important;
|
||||
background-color: var(--v-theme-surface) !important;
|
||||
transform: translateY(20px);
|
||||
opacity: 0;
|
||||
transition: all 0.5s ease;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import {ref, useCssModule} from 'vue';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import { Form } from 'vee-validate';
|
||||
import md5 from 'js-md5';
|
||||
import {useCustomizerStore} from "@/stores/customizer";
|
||||
|
||||
const valid = ref(false);
|
||||
const show1 = ref(false);
|
||||
@@ -42,8 +43,8 @@ async function validate(values: any, { setErrors }: any) {
|
||||
required
|
||||
density="comfortable"
|
||||
hide-details="auto"
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
variant="outlined"
|
||||
:style="{color: useCustomizerStore().uiTheme === 'PurpleTheme' ? '#000000dd' : '#ffffff'}"
|
||||
prepend-inner-icon="mdi-account"
|
||||
:disabled="loading"
|
||||
></v-text-field>
|
||||
@@ -54,7 +55,7 @@ async function validate(values: any, { setErrors }: any) {
|
||||
required
|
||||
density="comfortable"
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
:style="{color: useCustomizerStore().uiTheme === 'PurpleTheme' ? '#000000dd' : '#ffffff'}"
|
||||
hide-details="auto"
|
||||
:append-icon="show1 ? 'mdi-eye' : 'mdi-eye-off'"
|
||||
:type="show1 ? 'text' : 'password'"
|
||||
@@ -64,9 +65,9 @@ async function validate(values: any, { setErrors }: any) {
|
||||
:disabled="loading"
|
||||
></v-text-field>
|
||||
|
||||
<div class="mt-1 mb-5 hint-text">
|
||||
<v-label :style="{color: useCustomizerStore().uiTheme === 'PurpleTheme' ? '#000000aa' : '#ffffffcc'}" class="mt-1 mb-5">
|
||||
<small>默认用户名和密码为 astrbot</small>
|
||||
</div>
|
||||
</v-label>
|
||||
|
||||
<v-btn
|
||||
color="secondary"
|
||||
@@ -160,7 +161,7 @@ async function validate(values: any, { setErrors }: any) {
|
||||
}
|
||||
|
||||
.hint-text {
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
color: var(--v-theme-secondaryText);
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
@@ -171,7 +172,7 @@ async function validate(values: any, { setErrors }: any) {
|
||||
}
|
||||
}
|
||||
|
||||
.custom-devider {
|
||||
.custom-divider {
|
||||
border-color: rgba(0, 0, 0, 0.08) !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -155,7 +155,7 @@ export default {
|
||||
<style scoped>
|
||||
.dashboard-container {
|
||||
padding: 16px;
|
||||
background-color: #f9fafc;
|
||||
background-color: var(--v-theme-background);
|
||||
min-height: calc(100vh - 64px);
|
||||
border-radius: 10px;
|
||||
|
||||
@@ -170,13 +170,13 @@ export default {
|
||||
.dashboard-title {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
color: var(--v-theme-primaryText);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.dashboard-subtitle {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
color: var(--v-theme-secondaryText);
|
||||
}
|
||||
|
||||
.notice-row {
|
||||
@@ -194,18 +194,18 @@ export default {
|
||||
|
||||
.plugin-card {
|
||||
border-radius: 8px;
|
||||
background-color: white;
|
||||
background-color: var(--v-theme-surface);
|
||||
}
|
||||
|
||||
.plugin-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
color: var(--v-theme-primaryText);
|
||||
}
|
||||
|
||||
.plugin-subtitle {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
color: var(--v-theme-secondaryText);
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ export default {
|
||||
|
||||
.plugin-version {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
color: var(--v-theme-secondaryText, #666);
|
||||
}
|
||||
|
||||
.dashboard-footer {
|
||||
|
||||
@@ -167,7 +167,7 @@ export default {
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
borderColor: '#f1f1f1',
|
||||
borderColor: "gray100",
|
||||
row: {
|
||||
colors: ['transparent', 'transparent'],
|
||||
opacity: 0.2
|
||||
@@ -293,12 +293,12 @@ export default {
|
||||
.chart-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
color: var(--v-theme-primaryText);
|
||||
}
|
||||
|
||||
.chart-subtitle {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
color: var(--v-theme-secondaryText);
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
@@ -315,31 +315,31 @@ export default {
|
||||
|
||||
.stat-box {
|
||||
padding: 12px 16px;
|
||||
background: #f5f5f5;
|
||||
background: var(--v-theme-surface);
|
||||
border-radius: 8px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
color: var(--v-theme-secondaryText);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
color: var(--v-theme-primaryText);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.trend-up .stat-number {
|
||||
color: #4caf50;
|
||||
color: var(--v-theme-success);
|
||||
}
|
||||
|
||||
.trend-down .stat-number {
|
||||
color: #f44336;
|
||||
color: var(--v-theme-error);
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
@@ -354,7 +354,7 @@ export default {
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
background: var(--v-theme-overlay);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
@@ -365,6 +365,6 @@ export default {
|
||||
.loading-text {
|
||||
margin-top: 12px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
color: var(--v-theme-secondaryText);
|
||||
}
|
||||
</style>
|
||||
@@ -132,12 +132,12 @@ export default {
|
||||
.platform-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
color: var(--v-theme-primaryText);
|
||||
}
|
||||
|
||||
.platform-subtitle {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
color: var(--v-theme-secondaryText);
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
@@ -171,16 +171,16 @@ export default {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
background-color: #f0f0f0;
|
||||
color: #333;
|
||||
background-color: var(--v-theme-surface);
|
||||
color: var(--v-theme-primaryText);
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.top-rank {
|
||||
background-color: #5e35b1;
|
||||
color: white;
|
||||
background-color: var(--v-theme-secondary);
|
||||
color: var(--v-theme-surface);
|
||||
}
|
||||
|
||||
.platform-name {
|
||||
@@ -195,19 +195,19 @@ export default {
|
||||
.count-value {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
color: #5e35b1;
|
||||
color: var(--v-theme-secondary);
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.count-label {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
color: var(--v-theme-secondaryText);
|
||||
}
|
||||
|
||||
.platform-stats-summary {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
background-color: #f5f5f5;
|
||||
background-color: var(--v-theme-containerBg);
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
margin-bottom: 16px;
|
||||
@@ -220,13 +220,13 @@ export default {
|
||||
|
||||
.stat-label {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
color: var(--v-theme-secondaryText);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
color: var(--v-theme-primaryText);
|
||||
}
|
||||
|
||||
.platform-chart {
|
||||
@@ -246,7 +246,7 @@ export default {
|
||||
}
|
||||
|
||||
.no-data-text {
|
||||
color: #999;
|
||||
color: var(--v-theme-secondaryText);
|
||||
margin-top: 16px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user