refactor: 移除logger。全部改为console输出
This commit is contained in:
@@ -516,7 +516,7 @@ export async function startBackend(appRoot: string): Promise<{ success: boolean;
|
|||||||
// ✅ 重要:也要监听 stderr
|
// ✅ 重要:也要监听 stderr
|
||||||
backendProcess.stderr?.on('data', data => {
|
backendProcess.stderr?.on('data', data => {
|
||||||
const output = data.toString()
|
const output = data.toString()
|
||||||
console.error('Backend error:', output) // 保留原有日志
|
console.log('Backend output:', output) // 保留原有日志
|
||||||
|
|
||||||
// ✅ 在 stderr 中也检查启动标志
|
// ✅ 在 stderr 中也检查启动标志
|
||||||
if (output.includes('Uvicorn running') || output.includes('36163')) {
|
if (output.includes('Uvicorn running') || output.includes('36163')) {
|
||||||
@@ -526,7 +526,7 @@ export async function startBackend(appRoot: string): Promise<{ success: boolean;
|
|||||||
})
|
})
|
||||||
|
|
||||||
backendProcess.stderr?.on('data', data => {
|
backendProcess.stderr?.on('data', data => {
|
||||||
console.error('Backend error:', data.toString())
|
console.log('Backend output:', data.toString())
|
||||||
})
|
})
|
||||||
|
|
||||||
backendProcess.on('error', error => {
|
backendProcess.on('error', error => {
|
||||||
|
|||||||
@@ -3,57 +3,56 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
export type GeneralConfig_Script = {
|
export type GeneralConfig_Script = {
|
||||||
/**
|
/**
|
||||||
* 脚本可执行文件路径
|
* 脚本可执行文件路径
|
||||||
*/
|
*/
|
||||||
ScriptPath?: (string | null);
|
ScriptPath?: string | null
|
||||||
/**
|
/**
|
||||||
* 脚本启动附加命令参数
|
* 脚本启动附加命令参数
|
||||||
*/
|
*/
|
||||||
Arguments?: (string | null);
|
Arguments?: string | null
|
||||||
/**
|
/**
|
||||||
* 是否追踪脚本子进程
|
* 是否追踪脚本子进程
|
||||||
*/
|
*/
|
||||||
IfTrackProcess?: (boolean | null);
|
IfTrackProcess?: boolean | null
|
||||||
/**
|
/**
|
||||||
* 配置文件路径
|
* 配置文件路径
|
||||||
*/
|
*/
|
||||||
ConfigPath?: (string | null);
|
ConfigPath?: string | null
|
||||||
/**
|
/**
|
||||||
* 配置文件类型: 单个文件, 文件夹
|
* 配置文件类型: 单个文件, 文件夹
|
||||||
*/
|
*/
|
||||||
ConfigPathMode?: ('File' | 'Folder' | null);
|
ConfigPathMode?: 'File' | 'Folder' | null
|
||||||
/**
|
/**
|
||||||
* 更新配置时机, 从不, 仅成功时, 仅失败时, 任务结束时
|
* 更新配置时机, 从不, 仅成功时, 仅失败时, 任务结束时
|
||||||
*/
|
*/
|
||||||
UpdateConfigMode?: ('Never' | 'Success' | 'Failure' | 'Always' | null);
|
UpdateConfigMode?: 'Never' | 'Success' | 'Failure' | 'Always' | null
|
||||||
/**
|
/**
|
||||||
* 日志文件路径
|
* 日志文件路径
|
||||||
*/
|
*/
|
||||||
LogPath?: (string | null);
|
LogPath?: string | null
|
||||||
/**
|
/**
|
||||||
* 日志文件名格式
|
* 日志文件名格式
|
||||||
*/
|
*/
|
||||||
LogPathFormat?: (string | null);
|
LogPathFormat?: string | null
|
||||||
/**
|
/**
|
||||||
* 日志时间戳开始位置
|
* 日志时间戳开始位置
|
||||||
*/
|
*/
|
||||||
LogTimeStart?: (number | null);
|
LogTimeStart?: number | null
|
||||||
/**
|
/**
|
||||||
* 日志时间戳结束位置
|
* 日志时间戳结束位置
|
||||||
*/
|
*/
|
||||||
LogTimeEnd?: (number | null);
|
LogTimeEnd?: number | null
|
||||||
/**
|
/**
|
||||||
* 日志时间戳格式
|
* 日志时间戳格式
|
||||||
*/
|
*/
|
||||||
LogTimeFormat?: (string | null);
|
LogTimeFormat?: string | null
|
||||||
/**
|
/**
|
||||||
* 成功时日志
|
* 成功时日志
|
||||||
*/
|
*/
|
||||||
SuccessLog?: (string | null);
|
SuccessLog?: string | null
|
||||||
/**
|
/**
|
||||||
* 错误时日志
|
* 错误时日志
|
||||||
*/
|
*/
|
||||||
ErrorLog?: (string | null);
|
ErrorLog?: string | null
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,344 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="log-viewer">
|
|
||||||
<div class="log-header">
|
|
||||||
<div class="log-controls">
|
|
||||||
<a-select v-model:value="selectedLevel" style="width: 120px" @change="filterLogs">
|
|
||||||
<a-select-option value="all">所有级别</a-select-option>
|
|
||||||
<a-select-option value="debug">Debug</a-select-option>
|
|
||||||
<a-select-option value="info">Info</a-select-option>
|
|
||||||
<a-select-option value="warn">Warn</a-select-option>
|
|
||||||
<a-select-option value="error">Error</a-select-option>
|
|
||||||
</a-select>
|
|
||||||
|
|
||||||
<a-input-search
|
|
||||||
v-model:value="searchText"
|
|
||||||
placeholder="搜索日志..."
|
|
||||||
style="width: 200px"
|
|
||||||
@search="filterLogs"
|
|
||||||
@change="filterLogs"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<a-button @click="clearLogs" danger>
|
|
||||||
<template #icon>
|
|
||||||
<DeleteOutlined />
|
|
||||||
</template>
|
|
||||||
清空日志
|
|
||||||
</a-button>
|
|
||||||
|
|
||||||
<a-button @click="downloadLogs" type="primary">
|
|
||||||
<template #icon>
|
|
||||||
<DownloadOutlined />
|
|
||||||
</template>
|
|
||||||
导出日志
|
|
||||||
</a-button>
|
|
||||||
|
|
||||||
<a-button @click="toggleAutoScroll" :type="autoScroll ? 'primary' : 'default'">
|
|
||||||
<template #icon>
|
|
||||||
<VerticalAlignBottomOutlined />
|
|
||||||
</template>
|
|
||||||
自动滚动
|
|
||||||
</a-button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="log-stats">总计: {{ filteredLogs.length }} 条日志</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div ref="logContainer" class="log-container" @scroll="handleScroll">
|
|
||||||
<div
|
|
||||||
v-for="(log, index) in filteredLogs"
|
|
||||||
:key="index"
|
|
||||||
class="log-entry"
|
|
||||||
:class="[`log-${log.level}`, { 'log-highlight': highlightedIndex === index }]"
|
|
||||||
>
|
|
||||||
<div class="log-timestamp">{{ log.timestamp }}</div>
|
|
||||||
<div class="log-level">{{ log.level.toUpperCase() }}</div>
|
|
||||||
<div v-if="log.component" class="log-component">[{{ log.component }}]</div>
|
|
||||||
<div class="log-message">{{ log.message }}</div>
|
|
||||||
<div v-if="log.data" class="log-data">
|
|
||||||
<a-button size="small" type="link" @click="toggleDataVisibility(index)">
|
|
||||||
{{ expandedData.has(index) ? '隐藏数据' : '显示数据' }}
|
|
||||||
</a-button>
|
|
||||||
<pre v-if="expandedData.has(index)" class="log-data-content">{{
|
|
||||||
JSON.stringify(log.data, null, 2)
|
|
||||||
}}</pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { ref, computed, nextTick, onMounted, onUnmounted } from 'vue'
|
|
||||||
import {
|
|
||||||
DeleteOutlined,
|
|
||||||
DownloadOutlined,
|
|
||||||
VerticalAlignBottomOutlined,
|
|
||||||
} from '@ant-design/icons-vue'
|
|
||||||
import { logger, type LogEntry, type LogLevel } from '@/utils/logger'
|
|
||||||
|
|
||||||
const logContainer = ref<HTMLElement>()
|
|
||||||
const selectedLevel = ref<LogLevel | 'all'>('all')
|
|
||||||
const searchText = ref('')
|
|
||||||
const autoScroll = ref(true)
|
|
||||||
const expandedData = ref(new Set<number>())
|
|
||||||
const highlightedIndex = ref(-1)
|
|
||||||
|
|
||||||
const logs = logger.getLogs()
|
|
||||||
|
|
||||||
const filteredLogs = computed(() => {
|
|
||||||
let filtered = logs.value
|
|
||||||
|
|
||||||
// 按级别过滤
|
|
||||||
if (selectedLevel.value !== 'all') {
|
|
||||||
filtered = filtered.filter(log => log.level === selectedLevel.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 按搜索文本过滤
|
|
||||||
if (searchText.value) {
|
|
||||||
const search = searchText.value.toLowerCase()
|
|
||||||
filtered = filtered.filter(
|
|
||||||
log =>
|
|
||||||
log.message.toLowerCase().includes(search) ||
|
|
||||||
log.component?.toLowerCase().includes(search) ||
|
|
||||||
(log.data && JSON.stringify(log.data).toLowerCase().includes(search))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return filtered
|
|
||||||
})
|
|
||||||
|
|
||||||
function filterLogs() {
|
|
||||||
// 过滤逻辑已在computed中处理
|
|
||||||
nextTick(() => {
|
|
||||||
if (autoScroll.value) {
|
|
||||||
scrollToBottom()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearLogs() {
|
|
||||||
logger.clearLogs()
|
|
||||||
expandedData.value.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
function downloadLogs() {
|
|
||||||
logger.downloadLogs()
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleAutoScroll() {
|
|
||||||
autoScroll.value = !autoScroll.value
|
|
||||||
if (autoScroll.value) {
|
|
||||||
scrollToBottom()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleDataVisibility(index: number) {
|
|
||||||
if (expandedData.value.has(index)) {
|
|
||||||
expandedData.value.delete(index)
|
|
||||||
} else {
|
|
||||||
expandedData.value.add(index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function scrollToBottom() {
|
|
||||||
if (logContainer.value) {
|
|
||||||
logContainer.value.scrollTop = logContainer.value.scrollHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleScroll() {
|
|
||||||
if (!logContainer.value) return
|
|
||||||
|
|
||||||
const { scrollTop, scrollHeight, clientHeight } = logContainer.value
|
|
||||||
const isAtBottom = scrollTop + clientHeight >= scrollHeight - 10
|
|
||||||
|
|
||||||
if (!isAtBottom) {
|
|
||||||
autoScroll.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 监听新日志添加
|
|
||||||
let unwatchLogs: (() => void) | null = null
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
// 初始滚动到底部
|
|
||||||
nextTick(() => {
|
|
||||||
scrollToBottom()
|
|
||||||
})
|
|
||||||
|
|
||||||
// 监听日志变化
|
|
||||||
unwatchLogs =
|
|
||||||
logs.value && typeof logs.value === 'object' && 'length' in logs.value
|
|
||||||
? () => {} // 如果logs是响应式的,Vue会自动处理
|
|
||||||
: null
|
|
||||||
})
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
if (unwatchLogs) {
|
|
||||||
unwatchLogs()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 监听日志变化,自动滚动
|
|
||||||
const prevLogsLength = ref(logs.value.length)
|
|
||||||
const checkForNewLogs = () => {
|
|
||||||
if (logs.value.length > prevLogsLength.value) {
|
|
||||||
prevLogsLength.value = logs.value.length
|
|
||||||
if (autoScroll.value) {
|
|
||||||
nextTick(() => {
|
|
||||||
scrollToBottom()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 定期检查新日志
|
|
||||||
const logCheckInterval = setInterval(checkForNewLogs, 100)
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
clearInterval(logCheckInterval)
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.log-viewer {
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
background: var(--ant-color-bg-container);
|
|
||||||
border-radius: 8px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-header {
|
|
||||||
padding: 16px;
|
|
||||||
border-bottom: 1px solid var(--ant-color-border);
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-controls {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 12px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-stats {
|
|
||||||
font-size: 14px;
|
|
||||||
color: var(--ant-color-text-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-container {
|
|
||||||
flex: 1;
|
|
||||||
overflow-y: auto;
|
|
||||||
padding: 8px;
|
|
||||||
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1.4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-entry {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 4px 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin-bottom: 2px;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-entry:hover {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-highlight {
|
|
||||||
background: var(--ant-color-primary-bg) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-timestamp {
|
|
||||||
color: var(--ant-color-text-tertiary);
|
|
||||||
white-space: nowrap;
|
|
||||||
min-width: 140px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-level {
|
|
||||||
font-weight: bold;
|
|
||||||
min-width: 50px;
|
|
||||||
text-align: center;
|
|
||||||
padding: 2px 6px;
|
|
||||||
border-radius: 3px;
|
|
||||||
font-size: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-debug .log-level {
|
|
||||||
background: var(--ant-color-fill-secondary);
|
|
||||||
color: var(--ant-color-text-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-info .log-level {
|
|
||||||
background: var(--ant-color-info-bg);
|
|
||||||
color: var(--ant-color-info);
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-warn .log-level {
|
|
||||||
background: var(--ant-color-warning-bg);
|
|
||||||
color: var(--ant-color-warning);
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-error .log-level {
|
|
||||||
background: var(--ant-color-error-bg);
|
|
||||||
color: var(--ant-color-error);
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-component {
|
|
||||||
color: var(--ant-color-primary);
|
|
||||||
font-weight: 500;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-message {
|
|
||||||
flex: 1;
|
|
||||||
color: var(--ant-color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-data {
|
|
||||||
margin-top: 4px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-data-content {
|
|
||||||
|
|
||||||
padding: 8px;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin-top: 4px;
|
|
||||||
font-size: 11px;
|
|
||||||
overflow-x: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
.log-header {
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: stretch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-controls {
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-entry {
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: stretch;
|
|
||||||
gap: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log-timestamp,
|
|
||||||
.log-level,
|
|
||||||
.log-component {
|
|
||||||
min-width: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -13,15 +13,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { createComponentLogger } from '@/utils/logger'
|
|
||||||
|
|
||||||
const logger = createComponentLogger('AdminCheck')
|
|
||||||
|
|
||||||
async function handleRestartAsAdmin() {
|
async function handleRestartAsAdmin() {
|
||||||
try {
|
try {
|
||||||
await window.electronAPI.restartAsAdmin()
|
await window.electronAPI.restartAsAdmin()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('重启为管理员失败', error)
|
console.error('重启为管理员失败', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -39,12 +39,11 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import { createComponentLogger } from '@/utils/logger'
|
|
||||||
import { getConfig } from '@/utils/config'
|
import { getConfig } from '@/utils/config'
|
||||||
import { getMirrorUrl } from '@/config/mirrors'
|
import { getMirrorUrl } from '@/config/mirrors'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
|
|
||||||
const logger = createComponentLogger('AutoMode')
|
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -120,7 +119,7 @@ async function startAutoProcess() {
|
|||||||
|
|
||||||
// 如果初始化时的镜像源不通,让用户重新选择
|
// 如果初始化时的镜像源不通,让用户重新选择
|
||||||
if (!pipResult.success) {
|
if (!pipResult.success) {
|
||||||
logger.warn(`使用镜像源 ${pipMirror} 安装依赖失败,需要重新选择镜像源`)
|
console.warn(`使用镜像源 ${pipMirror} 安装依赖失败,需要重新选择镜像源`)
|
||||||
|
|
||||||
// 切换到手动模式让用户重新选择镜像源
|
// 切换到手动模式让用户重新选择镜像源
|
||||||
progressText.value = '依赖安装失败,需要重新配置镜像源'
|
progressText.value = '依赖安装失败,需要重新配置镜像源'
|
||||||
@@ -142,14 +141,14 @@ async function startAutoProcess() {
|
|||||||
progress.value = 100
|
progress.value = 100
|
||||||
progressStatus.value = 'success'
|
progressStatus.value = 'success'
|
||||||
|
|
||||||
logger.info('自动启动流程完成,即将进入应用')
|
console.log('自动启动流程完成,即将进入应用')
|
||||||
|
|
||||||
// 延迟0.5秒后自动进入应用
|
// 延迟0.5秒后自动进入应用
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
props.onAutoComplete()
|
props.onAutoComplete()
|
||||||
}, 500)
|
}, 500)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('自动启动流程失败', error)
|
console.error('自动启动流程失败', error)
|
||||||
progressText.value = `自动启动失败: ${error instanceof Error ? error.message : String(error)}`
|
progressText.value = `自动启动失败: ${error instanceof Error ? error.message : String(error)}`
|
||||||
progressStatus.value = 'exception'
|
progressStatus.value = 'exception'
|
||||||
|
|
||||||
@@ -169,7 +168,7 @@ async function checkGitUpdate(): Promise<boolean> {
|
|||||||
const result = await window.electronAPI.checkGitUpdate()
|
const result = await window.electronAPI.checkGitUpdate()
|
||||||
return result.hasUpdate || false
|
return result.hasUpdate || false
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.warn('检查Git更新失败:', error)
|
console.warn('检查Git更新失败:', error)
|
||||||
// 如果检查失败,假设有更新,这样会触发代码拉取和依赖安装
|
// 如果检查失败,假设有更新,这样会触发代码拉取和依赖安装
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,7 +111,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch } from 'vue'
|
import { ref, watch } from 'vue'
|
||||||
import { notification } from 'ant-design-vue'
|
import { notification } from 'ant-design-vue'
|
||||||
import { createComponentLogger } from '@/utils/logger'
|
|
||||||
import { saveConfig } from '@/utils/config'
|
import { saveConfig } from '@/utils/config'
|
||||||
import ThemeStep from './ThemeStep.vue'
|
import ThemeStep from './ThemeStep.vue'
|
||||||
import PythonStep from './PythonStep.vue'
|
import PythonStep from './PythonStep.vue'
|
||||||
@@ -121,7 +120,7 @@ import BackendStep from './BackendStep.vue'
|
|||||||
import DependenciesStep from './DependenciesStep.vue'
|
import DependenciesStep from './DependenciesStep.vue'
|
||||||
import ServiceStep from './ServiceStep.vue'
|
import ServiceStep from './ServiceStep.vue'
|
||||||
|
|
||||||
const logger = createComponentLogger('ManualMode')
|
|
||||||
|
|
||||||
// Props
|
// Props
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -284,26 +283,26 @@ async function autoStartSpeedTest() {
|
|||||||
|
|
||||||
// 安装函数
|
// 安装函数
|
||||||
async function installPython() {
|
async function installPython() {
|
||||||
logger.info('开始安装Python')
|
console.log('开始安装Python')
|
||||||
const mirror = pythonStepRef.value?.selectedPythonMirror || 'tsinghua'
|
const mirror = pythonStepRef.value?.selectedPythonMirror || 'tsinghua'
|
||||||
const result = await window.electronAPI.downloadPython(mirror)
|
const result = await window.electronAPI.downloadPython(mirror)
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
logger.info('Python安装成功')
|
console.log('Python安装成功')
|
||||||
await saveConfig({ pythonInstalled: true })
|
await saveConfig({ pythonInstalled: true })
|
||||||
} else {
|
} else {
|
||||||
logger.error('Python安装失败', result.error)
|
console.error('Python安装失败', result.error)
|
||||||
throw new Error(result.error)
|
throw new Error(result.error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function installGit() {
|
async function installGit() {
|
||||||
logger.info('开始安装Git工具')
|
console.log('开始安装Git工具')
|
||||||
const result = await window.electronAPI.downloadGit()
|
const result = await window.electronAPI.downloadGit()
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
logger.info('Git工具安装成功')
|
console.log('Git工具安装成功')
|
||||||
await saveConfig({ gitInstalled: true })
|
await saveConfig({ gitInstalled: true })
|
||||||
} else {
|
} else {
|
||||||
logger.error('Git工具安装失败', result.error)
|
console.error('Git工具安装失败', result.error)
|
||||||
throw new Error(result.error)
|
throw new Error(result.error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -311,13 +310,13 @@ async function installGit() {
|
|||||||
async function cloneBackend() {
|
async function cloneBackend() {
|
||||||
const selectedMirror = backendStepRef.value?.selectedGitMirror || 'github'
|
const selectedMirror = backendStepRef.value?.selectedGitMirror || 'github'
|
||||||
const mirror = backendStepRef.value?.gitMirrors?.find((m: any) => m.key === selectedMirror)
|
const mirror = backendStepRef.value?.gitMirrors?.find((m: any) => m.key === selectedMirror)
|
||||||
logger.info('开始克隆后端代码', { mirror: mirror?.name, url: mirror?.url })
|
console.log('开始克隆后端代码', { mirror: mirror?.name, url: mirror?.url })
|
||||||
const result = await window.electronAPI.cloneBackend(mirror?.url)
|
const result = await window.electronAPI.cloneBackend(mirror?.url)
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
logger.info('后端代码克隆成功')
|
console.log('后端代码克隆成功')
|
||||||
await saveConfig({ backendExists: true })
|
await saveConfig({ backendExists: true })
|
||||||
} else {
|
} else {
|
||||||
logger.error('后端代码克隆失败', result.error)
|
console.error('后端代码克隆失败', result.error)
|
||||||
throw new Error(result.error)
|
throw new Error(result.error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -325,31 +324,31 @@ async function cloneBackend() {
|
|||||||
async function updateBackend() {
|
async function updateBackend() {
|
||||||
const selectedMirror = backendStepRef.value?.selectedGitMirror || 'github'
|
const selectedMirror = backendStepRef.value?.selectedGitMirror || 'github'
|
||||||
const mirror = backendStepRef.value?.gitMirrors?.find((m: any) => m.key === selectedMirror)
|
const mirror = backendStepRef.value?.gitMirrors?.find((m: any) => m.key === selectedMirror)
|
||||||
logger.info('开始更新后端代码', { mirror: mirror?.name, url: mirror?.url })
|
console.log('开始更新后端代码', { mirror: mirror?.name, url: mirror?.url })
|
||||||
const result = await window.electronAPI.updateBackend(mirror?.url)
|
const result = await window.electronAPI.updateBackend(mirror?.url)
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
logger.error('后端代码更新失败', result.error)
|
console.error('后端代码更新失败', result.error)
|
||||||
throw new Error(result.error)
|
throw new Error(result.error)
|
||||||
}
|
}
|
||||||
logger.info('后端代码更新成功')
|
console.log('后端代码更新成功')
|
||||||
}
|
}
|
||||||
|
|
||||||
async function installDependencies() {
|
async function installDependencies() {
|
||||||
logger.info('开始安装Python依赖')
|
console.log('开始安装Python依赖')
|
||||||
const mirror = dependenciesStepRef.value?.selectedPipMirror || 'tsinghua'
|
const mirror = dependenciesStepRef.value?.selectedPipMirror || 'tsinghua'
|
||||||
const result = await window.electronAPI.installDependencies(mirror)
|
const result = await window.electronAPI.installDependencies(mirror)
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
logger.info('Python依赖安装成功')
|
console.log('Python依赖安装成功')
|
||||||
await saveConfig({ dependenciesInstalled: true })
|
await saveConfig({ dependenciesInstalled: true })
|
||||||
} else {
|
} else {
|
||||||
logger.error('Python依赖安装失败', result.error)
|
console.error('Python依赖安装失败', result.error)
|
||||||
throw new Error(result.error)
|
throw new Error(result.error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 自动启动后端服务(进入第七步时调用)
|
// 自动启动后端服务(进入第七步时调用)
|
||||||
async function autoStartBackendService() {
|
async function autoStartBackendService() {
|
||||||
logger.info('自动启动后端服务')
|
console.log('自动启动后端服务')
|
||||||
isProcessing.value = true
|
isProcessing.value = true
|
||||||
errorMessage.value = ''
|
errorMessage.value = ''
|
||||||
|
|
||||||
@@ -367,14 +366,14 @@ async function autoStartBackendService() {
|
|||||||
serviceStepRef.value.serviceStatus = '后端服务启动成功,即将进入主页...'
|
serviceStepRef.value.serviceStatus = '后端服务启动成功,即将进入主页...'
|
||||||
}
|
}
|
||||||
stepStatus.value = 'finish'
|
stepStatus.value = 'finish'
|
||||||
logger.info('后端服务自动启动成功,延迟1秒后自动进入主页')
|
console.log('后端服务自动启动成功,延迟1秒后自动进入主页')
|
||||||
|
|
||||||
// 延迟1秒后自动进入主页
|
// 延迟1秒后自动进入主页
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
handleEnterApp()
|
handleEnterApp()
|
||||||
}, 1000)
|
}, 1000)
|
||||||
} else {
|
} else {
|
||||||
logger.error('后端服务自动启动失败', result.error)
|
console.error('后端服务自动启动失败', result.error)
|
||||||
if (serviceStepRef.value) {
|
if (serviceStepRef.value) {
|
||||||
serviceStepRef.value.serviceStatus = '后端服务启动失败,请点击重新启动'
|
serviceStepRef.value.serviceStatus = '后端服务启动失败,请点击重新启动'
|
||||||
}
|
}
|
||||||
@@ -384,7 +383,7 @@ async function autoStartBackendService() {
|
|||||||
if (serviceStepRef.value) {
|
if (serviceStepRef.value) {
|
||||||
serviceStepRef.value.serviceStatus = '后端服务启动失败,请点击重新启动'
|
serviceStepRef.value.serviceStatus = '后端服务启动失败,请点击重新启动'
|
||||||
}
|
}
|
||||||
logger.error('后端服务自动启动异常', error)
|
console.error('后端服务自动启动异常', error)
|
||||||
errorMessage.value = error instanceof Error ? error.message : String(error)
|
errorMessage.value = error instanceof Error ? error.message : String(error)
|
||||||
} finally {
|
} finally {
|
||||||
if (serviceStepRef.value) {
|
if (serviceStepRef.value) {
|
||||||
@@ -396,7 +395,7 @@ async function autoStartBackendService() {
|
|||||||
|
|
||||||
// 手动启动后端服务(用户点击按钮时调用)
|
// 手动启动后端服务(用户点击按钮时调用)
|
||||||
async function startBackendService() {
|
async function startBackendService() {
|
||||||
logger.info('手动重新启动后端服务')
|
console.log('手动重新启动后端服务')
|
||||||
|
|
||||||
if (serviceStepRef.value) {
|
if (serviceStepRef.value) {
|
||||||
serviceStepRef.value.startingService = true
|
serviceStepRef.value.startingService = true
|
||||||
@@ -412,21 +411,21 @@ async function startBackendService() {
|
|||||||
serviceStepRef.value.serviceStatus = '后端服务启动成功,即将进入主页...'
|
serviceStepRef.value.serviceStatus = '后端服务启动成功,即将进入主页...'
|
||||||
}
|
}
|
||||||
stepStatus.value = 'finish'
|
stepStatus.value = 'finish'
|
||||||
logger.info('后端服务手动启动成功,延迟1秒后自动进入主页')
|
console.log('后端服务手动启动成功,延迟1秒后自动进入主页')
|
||||||
|
|
||||||
// 延迟1秒后自动进入主页
|
// 延迟1秒后自动进入主页
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
handleEnterApp()
|
handleEnterApp()
|
||||||
}, 1000)
|
}, 1000)
|
||||||
} else {
|
} else {
|
||||||
logger.error('后端服务手动启动失败', result.error)
|
console.error('后端服务手动启动失败', result.error)
|
||||||
throw new Error(result.error)
|
throw new Error(result.error)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (serviceStepRef.value) {
|
if (serviceStepRef.value) {
|
||||||
serviceStepRef.value.serviceStatus = '后端服务启动失败'
|
serviceStepRef.value.serviceStatus = '后端服务启动失败'
|
||||||
}
|
}
|
||||||
logger.error('后端服务手动启动异常', error)
|
console.error('后端服务手动启动异常', error)
|
||||||
throw error
|
throw error
|
||||||
} finally {
|
} finally {
|
||||||
if (serviceStepRef.value) {
|
if (serviceStepRef.value) {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { createApp } from 'vue'
|
|||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import router from './router/index.ts'
|
import router from './router/index.ts'
|
||||||
import { OpenAPI } from '@/api'
|
import { OpenAPI } from '@/api'
|
||||||
import LoggerPlugin, { logger } from '@/utils/logger'
|
|
||||||
|
|
||||||
import Antd from 'ant-design-vue'
|
import Antd from 'ant-design-vue'
|
||||||
import 'ant-design-vue/dist/reset.css'
|
import 'ant-design-vue/dist/reset.css'
|
||||||
@@ -24,10 +23,6 @@ const app = createApp(App)
|
|||||||
// 注册插件
|
// 注册插件
|
||||||
app.use(Antd)
|
app.use(Antd)
|
||||||
app.use(router)
|
app.use(router)
|
||||||
app.use(LoggerPlugin)
|
|
||||||
|
|
||||||
// 挂载应用
|
// 挂载应用
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
|
|
||||||
// 记录应用启动日志
|
|
||||||
logger.info('应用启动', { version: '1.0.0', environment: process.env.NODE_ENV })
|
|
||||||
|
|||||||
@@ -76,12 +76,6 @@ const routes: RouteRecordRaw[] = [
|
|||||||
component: () => import('../views/Settings.vue'),
|
component: () => import('../views/Settings.vue'),
|
||||||
meta: { title: '设置' },
|
meta: { title: '设置' },
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: '/logs',
|
|
||||||
name: 'Logs',
|
|
||||||
component: () => import('../views/Logs.vue'),
|
|
||||||
meta: { title: '系统日志' },
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
import { createComponentLogger } from './logger'
|
|
||||||
import type { ThemeMode, ThemeColor } from '@/composables/useTheme'
|
import type { ThemeMode, ThemeColor } from '@/composables/useTheme'
|
||||||
|
|
||||||
const logger = createComponentLogger('Config')
|
|
||||||
|
|
||||||
export interface FrontendConfig {
|
export interface FrontendConfig {
|
||||||
// 基础配置
|
// 基础配置
|
||||||
isFirstLaunch: boolean
|
isFirstLaunch: boolean
|
||||||
@@ -71,7 +68,6 @@ async function getConfigInternal(): Promise<FrontendConfig> {
|
|||||||
return config
|
return config
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('读取配置失败:', error)
|
console.error('读取配置失败:', error)
|
||||||
logger.error('读取配置失败', error)
|
|
||||||
return { ...DEFAULT_CONFIG }
|
return { ...DEFAULT_CONFIG }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,10 +103,8 @@ export async function saveConfig(config: Partial<FrontendConfig>): Promise<void>
|
|||||||
console.log('合并后的配置:', newConfig)
|
console.log('合并后的配置:', newConfig)
|
||||||
await window.electronAPI.saveConfig(newConfig)
|
await window.electronAPI.saveConfig(newConfig)
|
||||||
console.log('配置保存成功')
|
console.log('配置保存成功')
|
||||||
logger.info('配置已保存', newConfig)
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('保存配置失败:', error)
|
console.error('保存配置失败:', error)
|
||||||
logger.error('保存配置失败', error)
|
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,9 +116,8 @@ export async function resetConfig(): Promise<void> {
|
|||||||
localStorage.removeItem('app-config')
|
localStorage.removeItem('app-config')
|
||||||
localStorage.removeItem('theme-settings')
|
localStorage.removeItem('theme-settings')
|
||||||
localStorage.removeItem('app-initialized')
|
localStorage.removeItem('app-initialized')
|
||||||
logger.info('配置已重置')
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('重置配置失败', error)
|
console.error('重置配置失败:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,192 +0,0 @@
|
|||||||
import { ref } from 'vue'
|
|
||||||
|
|
||||||
export type LogLevel = 'debug' | 'info' | 'warn' | 'error'
|
|
||||||
|
|
||||||
export interface LogEntry {
|
|
||||||
timestamp: string
|
|
||||||
level: LogLevel
|
|
||||||
message: string
|
|
||||||
data?: any
|
|
||||||
component?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
class Logger {
|
|
||||||
private logs = ref<LogEntry[]>([])
|
|
||||||
private maxLogs = 1000 // 最大日志条数
|
|
||||||
private logToConsole = true
|
|
||||||
private logToStorage = true
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
// 延迟加载日志,等待electron API准备就绪
|
|
||||||
setTimeout(() => {
|
|
||||||
this.loadLogsFromStorage()
|
|
||||||
}, 100)
|
|
||||||
}
|
|
||||||
|
|
||||||
private formatTimestamp(): string {
|
|
||||||
const now = new Date()
|
|
||||||
return now.toISOString().replace('T', ' ').substring(0, 19)
|
|
||||||
}
|
|
||||||
|
|
||||||
private addLog(level: LogLevel, message: string, data?: any, component?: string) {
|
|
||||||
const logEntry: LogEntry = {
|
|
||||||
timestamp: this.formatTimestamp(),
|
|
||||||
level,
|
|
||||||
message,
|
|
||||||
data,
|
|
||||||
component,
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加到内存日志
|
|
||||||
this.logs.value.push(logEntry)
|
|
||||||
|
|
||||||
// 限制日志数量
|
|
||||||
if (this.logs.value.length > this.maxLogs) {
|
|
||||||
this.logs.value.shift()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 输出到控制台
|
|
||||||
if (this.logToConsole) {
|
|
||||||
const consoleMessage = `[${logEntry.timestamp}] [${level.toUpperCase()}] ${component ? `[${component}] ` : ''}${message}`
|
|
||||||
|
|
||||||
switch (level) {
|
|
||||||
case 'debug':
|
|
||||||
console.debug(consoleMessage, data)
|
|
||||||
break
|
|
||||||
case 'info':
|
|
||||||
console.info(consoleMessage, data)
|
|
||||||
break
|
|
||||||
case 'warn':
|
|
||||||
console.warn(consoleMessage, data)
|
|
||||||
break
|
|
||||||
case 'error':
|
|
||||||
console.error(consoleMessage, data)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 保存到本地存储
|
|
||||||
if (this.logToStorage) {
|
|
||||||
this.saveLogsToStorage()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async saveLogsToStorage() {
|
|
||||||
try {
|
|
||||||
if (window.electronAPI && window.electronAPI.saveLogsToFile) {
|
|
||||||
const logsToSave = this.logs.value.slice(-500) // 只保存最近500条日志
|
|
||||||
await window.electronAPI.saveLogsToFile(JSON.stringify(logsToSave, null, 2))
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('保存日志到本地文件失败:', error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async loadLogsFromStorage() {
|
|
||||||
try {
|
|
||||||
if (window.electronAPI && window.electronAPI.loadLogsFromFile) {
|
|
||||||
const savedLogs = await window.electronAPI.loadLogsFromFile()
|
|
||||||
if (savedLogs) {
|
|
||||||
const parsedLogs = JSON.parse(savedLogs) as LogEntry[]
|
|
||||||
this.logs.value = parsedLogs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('从本地文件加载日志失败:', error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 公共方法
|
|
||||||
debug(message: string, data?: any, component?: string) {
|
|
||||||
this.addLog('debug', message, data, component)
|
|
||||||
}
|
|
||||||
|
|
||||||
info(message: string, data?: any, component?: string) {
|
|
||||||
this.addLog('info', message, data, component)
|
|
||||||
}
|
|
||||||
|
|
||||||
warn(message: string, data?: any, component?: string) {
|
|
||||||
this.addLog('warn', message, data, component)
|
|
||||||
}
|
|
||||||
|
|
||||||
error(message: string, data?: any, component?: string) {
|
|
||||||
this.addLog('error', message, data, component)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取日志
|
|
||||||
getLogs() {
|
|
||||||
return this.logs
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清空日志
|
|
||||||
clearLogs() {
|
|
||||||
this.logs.value = []
|
|
||||||
localStorage.removeItem('app-logs')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 导出日志到文件
|
|
||||||
exportLogs(): string {
|
|
||||||
const logText = this.logs.value
|
|
||||||
.map(log => {
|
|
||||||
const dataStr = log.data ? ` | Data: ${JSON.stringify(log.data)}` : ''
|
|
||||||
const componentStr = log.component ? ` | Component: ${log.component}` : ''
|
|
||||||
return `[${log.timestamp}] [${log.level.toUpperCase()}]${componentStr} ${log.message}${dataStr}`
|
|
||||||
})
|
|
||||||
.join('\n')
|
|
||||||
|
|
||||||
return logText
|
|
||||||
}
|
|
||||||
|
|
||||||
// 下载日志文件
|
|
||||||
downloadLogs() {
|
|
||||||
const logText = this.exportLogs()
|
|
||||||
const blob = new Blob([logText], { type: 'text/plain;charset=utf-8' })
|
|
||||||
const url = URL.createObjectURL(blob)
|
|
||||||
|
|
||||||
const link = document.createElement('a')
|
|
||||||
link.href = url
|
|
||||||
link.download = `auto-maa-logs-${new Date().toISOString().split('T')[0]}.txt`
|
|
||||||
document.body.appendChild(link)
|
|
||||||
link.click()
|
|
||||||
document.body.removeChild(link)
|
|
||||||
|
|
||||||
URL.revokeObjectURL(url)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 配置选项
|
|
||||||
setLogToConsole(enabled: boolean) {
|
|
||||||
this.logToConsole = enabled
|
|
||||||
}
|
|
||||||
|
|
||||||
setLogToStorage(enabled: boolean) {
|
|
||||||
this.logToStorage = enabled
|
|
||||||
}
|
|
||||||
|
|
||||||
setMaxLogs(max: number) {
|
|
||||||
this.maxLogs = max
|
|
||||||
if (this.logs.value.length > max) {
|
|
||||||
this.logs.value = this.logs.value.slice(-max)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建全局日志实例
|
|
||||||
export const logger = new Logger()
|
|
||||||
|
|
||||||
// 创建组件专用的日志器
|
|
||||||
export function createComponentLogger(componentName: string) {
|
|
||||||
return {
|
|
||||||
debug: (message: string, data?: any) => logger.debug(message, data, componentName),
|
|
||||||
info: (message: string, data?: any) => logger.info(message, data, componentName),
|
|
||||||
warn: (message: string, data?: any) => logger.warn(message, data, componentName),
|
|
||||||
error: (message: string, data?: any) => logger.error(message, data, componentName),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vue插件
|
|
||||||
export default {
|
|
||||||
install(app: any) {
|
|
||||||
app.config.globalProperties.$logger = logger
|
|
||||||
app.provide('logger', logger)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@@ -29,7 +29,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, onUnmounted } from 'vue'
|
import { ref, onMounted, onUnmounted } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { createComponentLogger } from '@/utils/logger'
|
|
||||||
import { getConfig, saveConfig, setInitialized } from '@/utils/config'
|
import { getConfig, saveConfig, setInitialized } from '@/utils/config'
|
||||||
import AdminCheck from '@/components/initialization/AdminCheck.vue'
|
import AdminCheck from '@/components/initialization/AdminCheck.vue'
|
||||||
import AutoMode from '@/components/initialization/AutoMode.vue'
|
import AutoMode from '@/components/initialization/AutoMode.vue'
|
||||||
@@ -37,7 +36,6 @@ import ManualMode from '@/components/initialization/ManualMode.vue'
|
|||||||
import type { DownloadProgress } from '@/types/initialization'
|
import type { DownloadProgress } from '@/types/initialization'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const logger = createComponentLogger('Initialization')
|
|
||||||
|
|
||||||
// 基础状态
|
// 基础状态
|
||||||
const isAdmin = ref(true)
|
const isAdmin = ref(true)
|
||||||
@@ -77,7 +75,6 @@ async function enterApp() {
|
|||||||
// 检查关键文件是否存在
|
// 检查关键文件是否存在
|
||||||
async function checkCriticalFiles() {
|
async function checkCriticalFiles() {
|
||||||
try {
|
try {
|
||||||
logger.info('开始检查关键文件存在性')
|
|
||||||
console.log('🔍 正在调用 window.electronAPI.checkCriticalFiles()...')
|
console.log('🔍 正在调用 window.electronAPI.checkCriticalFiles()...')
|
||||||
|
|
||||||
// 检查API是否存在
|
// 检查API是否存在
|
||||||
@@ -110,7 +107,6 @@ async function checkCriticalFiles() {
|
|||||||
console.log('🔍 最终返回结果:', result)
|
console.log('🔍 最终返回结果:', result)
|
||||||
return result
|
return result
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('检查关键文件失败', error)
|
|
||||||
console.error('❌ 检查关键文件失败,使用配置文件状态:', error)
|
console.error('❌ 检查关键文件失败,使用配置文件状态:', error)
|
||||||
|
|
||||||
// 如果检查失败,从配置文件读取状态
|
// 如果检查失败,从配置文件读取状态
|
||||||
@@ -140,7 +136,6 @@ async function checkCriticalFiles() {
|
|||||||
// 检查环境状态
|
// 检查环境状态
|
||||||
async function checkEnvironment() {
|
async function checkEnvironment() {
|
||||||
try {
|
try {
|
||||||
logger.info('开始检查环境状态')
|
|
||||||
|
|
||||||
// 只检查关键exe文件是否存在
|
// 只检查关键exe文件是否存在
|
||||||
const criticalFiles = await checkCriticalFiles()
|
const criticalFiles = await checkCriticalFiles()
|
||||||
@@ -186,11 +181,9 @@ async function checkEnvironment() {
|
|||||||
|
|
||||||
// 只有在非首次启动、配置显示已初始化、且所有关键exe文件都存在时才进入自动模式
|
// 只有在非首次启动、配置显示已初始化、且所有关键exe文件都存在时才进入自动模式
|
||||||
if (!isFirst && config.init && allExeFilesExist) {
|
if (!isFirst && config.init && allExeFilesExist) {
|
||||||
logger.info('非首次启动、配置显示已初始化且所有关键文件存在,进入自动模式')
|
|
||||||
console.log('进入自动模式,开始自动启动流程')
|
console.log('进入自动模式,开始自动启动流程')
|
||||||
autoMode.value = true
|
autoMode.value = true
|
||||||
} else {
|
} else {
|
||||||
logger.info('需要进入手动模式进行配置')
|
|
||||||
console.log('进入手动模式')
|
console.log('进入手动模式')
|
||||||
console.log(
|
console.log(
|
||||||
'原因: isFirst =',
|
'原因: isFirst =',
|
||||||
@@ -209,7 +202,6 @@ async function checkEnvironment() {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMsg = `环境检查失败: ${error instanceof Error ? error.message : String(error)}`
|
const errorMsg = `环境检查失败: ${error instanceof Error ? error.message : String(error)}`
|
||||||
logger.error('环境检查失败', error)
|
|
||||||
console.error('环境检查失败:', error)
|
console.error('环境检查失败:', error)
|
||||||
|
|
||||||
// 检查失败时强制进入手动模式
|
// 检查失败时强制进入手动模式
|
||||||
@@ -224,7 +216,7 @@ async function checkAdminPermission() {
|
|||||||
isAdmin.value = adminStatus
|
isAdmin.value = adminStatus
|
||||||
console.log('管理员权限检查结果:', adminStatus)
|
console.log('管理员权限检查结果:', adminStatus)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('检查管理员权限失败', error)
|
console.error('检查管理员权限失败:', error)
|
||||||
isAdmin.value = false
|
isAdmin.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="logs-page">
|
|
||||||
<div class="page-header">
|
|
||||||
<h2>系统日志</h2>
|
|
||||||
<p>查看应用运行日志,支持搜索、过滤和导出功能</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="logs-content">
|
|
||||||
<LogViewer />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { onMounted } from 'vue'
|
|
||||||
import LogViewer from '@/components/LogViewer.vue'
|
|
||||||
import { createComponentLogger } from '@/utils/logger'
|
|
||||||
|
|
||||||
const logger = createComponentLogger('LogsPage')
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
logger.info('进入日志查看页面')
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.logs-page {
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-header {
|
|
||||||
margin-bottom: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-header h2 {
|
|
||||||
margin: 0 0 8px 0;
|
|
||||||
color: var(--ant-color-text);
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-header p {
|
|
||||||
margin: 0;
|
|
||||||
color: var(--ant-color-text-secondary);
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logs-content {
|
|
||||||
flex: 1;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -687,11 +687,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
<div class="setting-item">
|
|
||||||
<h4>系统日志</h4>
|
|
||||||
<p class="setting-description">查看应用运行日志,用于问题排查和调试</p>
|
|
||||||
<Button type="default" @click="$router.push('/logs')">查看系统日志</Button>
|
|
||||||
</div>
|
|
||||||
</Space>
|
</Space>
|
||||||
</Card>
|
</Card>
|
||||||
</Tabs.TabPane>
|
</Tabs.TabPane>
|
||||||
|
|||||||
Reference in New Issue
Block a user