feat: 日志页面

This commit is contained in:
Junyan Qin
2024-10-14 18:52:28 +08:00
parent 0dd74c825b
commit 231dca956d
8 changed files with 213 additions and 13 deletions

View File

@@ -2,17 +2,32 @@
<v-app>
<v-layout>
<v-navigation-drawer :width="160" app permanent expand-on-hover>
<v-navigation-drawer id="navigation-drawer" :width="160" app permanent rail>
<v-list-item id="logo-list-item">
<template v-slot:prepend>
<v-img src="@/assets/langbot-logo-block.png" height="32" width="32"></v-img>
</template>
</v-list-item>
<v-divider></v-divider>
<v-list density="compact" nav>
<v-list-item to="/" title="仪表盘" value="dashboard" prepend-icon="mdi-view-dashboard-outline">
<v-list-item to="/" title="仪表盘" value="dashboard" prepend-icon="mdi-speedometer" v-tooltip="仪表盘">
</v-list-item>
<v-list-item to="/settings" title="置" value="settings" prepend-icon="mdi-cog-outline">
<v-list-item to="/settings" title="置" value="settings" prepend-icon="mdi-toggle-switch-outline"
v-tooltip="设置">
</v-list-item>
<v-list-item to="/logs" title="日志" value="logs" prepend-icon="mdi-file-outline">
<v-list-item to="/logs" title="日志" value="logs" prepend-icon="mdi-file-outline" v-tooltip="日志">
</v-list-item>
<v-list-item to="/plugins" title="插件" value="plugins" prepend-icon="mdi-puzzle-outline">
<v-list-item to="/plugins" title="插件" value="plugins" prepend-icon="mdi-puzzle-outline" v-tooltip="插件">
</v-list-item>
</v-list>
<template v-slot:append>
<div>
<v-list density="compact" nav>
<v-list-item id="about-list-item" title="关于" prepend-icon="mdi-cog-outline" v-tooltip="关于">
</v-list-item>
</v-list>
</div>
</template>
</v-navigation-drawer>
<v-main>
@@ -24,3 +39,28 @@
<script setup>
</script>
<style scoped>
#navigation-drawer {
display: flex;
flex-direction: column;
}
#logo-list-item {
margin-left: -0.2rem;
margin-block: 0.5rem;
}
#about-list-item {
justify-self: flex-end;
}
#about-list-item:hover {
cursor: pointer;
background-color: #eee;
}
#about-list-item:active {
background-color: #ddd;
}
</style>

View File

@@ -0,0 +1,51 @@
<template>
<span class="title-container">
<h2 id="page-title">{{ title }}</h2>
<v-icon @click="refresh" id="refresh-icon" icon="mdi-refresh" />
</span>
</template>
<script setup>
defineProps({
title: {
type: String,
required: true
}
})
const emit = defineEmits(['refresh'])
const refresh = () => {
emit('refresh')
}
</script>
<style scoped>
#page-title {
font-weight: 500;
margin-left: 1.4rem;
user-select: none;
}
.title-container {
display: flex;
justify-content: flex-start;
align-items: center;
padding-top: 1rem;
}
#refresh-icon {
padding-top: 0.1rem;
margin-left: 0.5rem;
color: #aaa;
}
#refresh-icon:hover {
cursor: pointer;
}
#refresh-icon:active {
color: #6c6c6c;
}
</style>

View File

@@ -1,9 +1,11 @@
<template>
<h1>Dashboard</h1>
<PageTitle title="仪表盘" @refresh="refresh" />
</template>
<script setup>
import PageTitle from '@/components/PageTitle.vue'
</script>
<style scoped>

View File

@@ -1,9 +1,102 @@
<template>
<h1>Logs</h1>
<PageTitle title="日志" @refresh="refresh" />
<v-card id="toolbar">
<v-card-text>
<v-switch class="toolbar-component" color="primary" :model-value="proxy.$store.state.autoRefreshLog"
@update:model-value="proxy.$store.state.autoRefreshLog = $event" label="自动刷新"></v-switch>
</v-card-text>
</v-card>
<v-card id="log-card">
<v-card-text id="log-card-text">
<textarea id="log-textarea" placeholder="点击标题旁的按钮以刷新日志" v-model="logContent" readonly></textarea>
</v-card-text>
</v-card>
</template>
<script setup>
import PageTitle from '@/components/PageTitle.vue'
import { ref, getCurrentInstance, onMounted, onUnmounted } from 'vue'
const { proxy } = getCurrentInstance()
const logContent = ref('')
const refresh = () => {
refreshLog()
}
let logPointer = {
"start_page_number": 0,
"start_offset": 0
}
const refreshLog = () => {
proxy.$axios.get(`${proxy.$store.state.apiBaseUrl}/logs`, {
params: {
start_page_number: logPointer.start_page_number,
start_offset: logPointer.start_offset
}
}).then(response => {
logContent.value += response.data.data.logs
logPointer.start_page_number = response.data.data.end_page_number
logPointer.start_offset = response.data.data.end_offset
})
}
let refreshLogTask = null
onMounted(() => {
refreshLog()
refreshLogTask = setInterval(() => {
if (proxy.$store.state.autoRefreshLog) {
refreshLog()
}
}, 1000)
})
onUnmounted(() => {
clearInterval(refreshLogTask)
})
</script>
<style scoped>
#toolbar {
display: flex;
justify-content: center;
align-items: center;
margin: 1rem;
margin-top: 1rem;
height: 3rem;
border-radius: 1rem;
}
.toolbar-component {
margin-top: 1.4rem;
}
#log-card {
margin: 1rem;
margin-top: 1rem;
height: calc(100vh - 10rem);
border-radius: 1rem;
}
#log-textarea {
/* height: 100%; */
height: 100%;
width: 100%;
resize: none;
border: none;
outline: none;
appearance: none;
/* background-color: #eee; */
}
#log-card-text {
display: flex;
height: 100%;
}
</style>

View File

@@ -1,9 +1,13 @@
<template>
<h1>Plugins</h1>
<PageTitle title="插件" @refresh="refresh" />
</template>
<script setup>
import PageTitle from '@/components/PageTitle.vue'
</script>
<style scoped>
</style>
</style>

View File

@@ -1,9 +1,13 @@
<template>
<h1>Settings</h1>
<PageTitle title="设置" @refresh="refresh" />
</template>
<script setup>
import PageTitle from '@/components/PageTitle.vue'
</script>
<style scoped>
</style>
</style>

View File

@@ -8,11 +8,13 @@
import vuetify from './vuetify'
import router from '@/router'
import store from '@/store'
import axios from 'axios'
export function registerPlugins (app) {
app
.use(vuetify)
.use(router)
.use(store)
app.config.globalProperties.$axios = axios
}

View File

@@ -3,7 +3,11 @@ import router from '@/router'
import axios from 'axios'
export default createStore({
state: {},
state: {
apiBaseUrl: 'http://localhost:5300/api/v1',
autoRefreshLog: false,
version: '0.0.1'
},
mutations: {},
actions: {},
})