Files
egm/webui/src/components/Log.vue

130 lines
2.7 KiB
Vue
Raw Normal View History

<template>
<q-card class="q-mt-md shadow-2">
<q-card-section class="bg-blue-grey-1 cursor-pointer" @click="expanded = !expanded">
<div class="text-h6 text-blue-grey-9 flex items-center gap-2">
<q-icon name="terminal" />
运行日志
<q-space />
<q-icon :name="expanded ? 'expand_less' : 'expand_more'" />
</div>
</q-card-section>
<div v-show="expanded" class="q-pa-none">
<div ref="logContainer" class="log-container">
<div
v-for="(log, index) in logs"
:key="index"
:class="['log-line', `log-${log.level}`]"
>
<span class="log-time">{{ log.time }}</span>
<span class="log-message">{{ log.message }}</span>
</div>
<div v-if="logs.length === 0" class="log-empty">暂无日志</div>
</div>
</div>
</q-card>
</template>
<script setup lang="ts">
import { ref, nextTick } from 'vue'
defineOptions({
name: 'LogComponent'
})
interface LogEntry {
level: 'info' | 'warning' | 'error' | 'debug'
time: string
message: string
}
const logs = ref<LogEntry[]>([])
const logContainer = ref<HTMLElement | null>(null)
2026-03-03 16:35:28 +08:00
const expanded = ref(false) // 默认折叠
const lastTripRates = ref<number[]>([])
const addLog = (level: LogEntry['level'], message: string) => {
const now = new Date()
const time = now.toLocaleTimeString('zh-CN', { hour12: false })
logs.value.push({ level, time, message })
// 解析跳闸率数值
const match = message.match(/不同相跳闸率是\[([\d.\s]+)\]/)
if (match) {
const values = match[1].trim().split(/\s+/).map(Number)
lastTripRates.value = values
}
// 自动滚动到底部
nextTick(() => {
if (logContainer.value) {
logContainer.value.scrollTop = logContainer.value.scrollHeight
}
})
}
const clearLog = () => {
logs.value = []
}
2026-03-03 14:26:58 +08:00
// 获取日志文本
const getLogsText = (): string => {
return logs.value.map(log => `[${log.time}] [${log.level.toUpperCase()}] ${log.message}`).join('\n')
}
// 暴露方法给父组件
defineExpose({
addLog,
clearLog,
2026-03-03 14:26:58 +08:00
lastTripRates,
getLogsText
})
</script>
<style scoped>
.log-container {
max-height: 300px;
overflow-y: auto;
background-color: #1e1e1e;
color: #d4d4d4;
font-family: 'Consolas', 'Monaco', monospace;
font-size: 12px;
padding: 8px;
user-select: text;
cursor: text;
}
.log-line {
padding: 2px 0;
display: flex;
gap: 8px;
}
.log-time {
color: #6a9955;
flex-shrink: 0;
}
.log-info .log-message {
color: #d4d4d4;
}
.log-warning .log-message {
color: #dcdcaa;
}
.log-error .log-message {
color: #f48771;
}
.log-debug .log-message {
color: #9cdcfe;
}
.log-empty {
color: #666;
font-style: italic;
padding: 8px;
}
</style>