style:格式化代码

This commit is contained in:
2025-08-15 14:21:16 +08:00
parent 9f849608db
commit a738f102a6
40 changed files with 1144 additions and 922 deletions

View File

@@ -485,4 +485,4 @@ onMounted(() => {
margin-right: 8px;
}
}
</style>
</style>

View File

@@ -4,14 +4,14 @@
<AdminCheck v-if="!isAdmin" />
<!-- 自动初始化模式 -->
<AutoMode
<AutoMode
v-if="autoMode"
:on-switch-to-manual="switchToManualMode"
:on-auto-complete="enterApp"
/>
<!-- 手动初始化模式 -->
<ManualMode
<ManualMode
v-else
ref="manualModeRef"
:python-installed="pythonInstalled"
@@ -38,7 +38,7 @@ import ManualMode from '@/components/initialization/ManualMode.vue'
import type { DownloadProgress } from '@/types/initialization'
const router = useRouter()
const logger = createComponentLogger('InitializationNew')
const logger = createComponentLogger('Initialization')
// 基础状态
const isAdmin = ref(true)
@@ -81,7 +81,7 @@ async function checkCriticalFiles() {
try {
logger.info('开始检查关键文件存在性')
console.log('🔍 正在调用 window.electronAPI.checkCriticalFiles()...')
// 检查API是否存在
if (!window.electronAPI.checkCriticalFiles) {
console.warn('⚠️ window.electronAPI.checkCriticalFiles 不存在,使用配置文件状态')
@@ -91,33 +91,33 @@ async function checkCriticalFiles() {
pythonExists: config.pythonInstalled || false,
pipExists: config.pipInstalled || false,
gitExists: config.gitInstalled || false,
mainPyExists: config.backendExists || false
mainPyExists: config.backendExists || false,
}
}
// 检查关键文件
const criticalFiles = await window.electronAPI.checkCriticalFiles()
console.log('🔍 electronAPI.checkCriticalFiles() 原始返回结果:', criticalFiles)
console.log('🔍 详细检查结果:')
console.log(' - pythonExists:', criticalFiles.pythonExists, typeof criticalFiles.pythonExists)
console.log(' - pipExists:', criticalFiles.pipExists, typeof criticalFiles.pipExists)
console.log(' - gitExists:', criticalFiles.gitExists, typeof criticalFiles.gitExists)
console.log(' - mainPyExists:', criticalFiles.mainPyExists, typeof criticalFiles.mainPyExists)
const result = {
pythonExists: criticalFiles.pythonExists,
pipExists: criticalFiles.pipExists,
pipExists: criticalFiles.pipExists,
gitExists: criticalFiles.gitExists,
mainPyExists: criticalFiles.mainPyExists
mainPyExists: criticalFiles.mainPyExists,
}
console.log('🔍 最终返回结果:', result)
return result
} catch (error) {
logger.error('检查关键文件失败', error)
console.error('❌ 检查关键文件失败,使用配置文件状态:', error)
// 如果检查失败,从配置文件读取状态
try {
const config = await getConfig()
@@ -125,13 +125,13 @@ async function checkCriticalFiles() {
pythonInstalled: config.pythonInstalled,
pipInstalled: config.pipInstalled,
gitInstalled: config.gitInstalled,
backendExists: config.backendExists
backendExists: config.backendExists,
})
return {
pythonExists: config.pythonInstalled || false,
pipExists: config.pipInstalled || false,
gitExists: config.gitInstalled || false,
mainPyExists: config.backendExists || false
mainPyExists: config.backendExists || false,
}
} catch (configError) {
console.error('❌ 读取配置文件也失败了:', configError)
@@ -139,7 +139,7 @@ async function checkCriticalFiles() {
pythonExists: false,
pipExists: false,
gitExists: false,
mainPyExists: false
mainPyExists: false,
}
}
}
@@ -149,46 +149,47 @@ async function checkCriticalFiles() {
async function checkEnvironment() {
try {
logger.info('开始检查环境状态')
// 只检查关键exe文件是否存在
const criticalFiles = await checkCriticalFiles()
console.log('关键文件检查结果:', criticalFiles)
// 直接根据exe文件存在性设置状态
pythonInstalled.value = criticalFiles.pythonExists
pipInstalled.value = criticalFiles.pipExists
gitInstalled.value = criticalFiles.gitExists
backendExists.value = criticalFiles.mainPyExists
// 检查配置文件中的依赖安装状态
const config = await getConfig()
dependenciesInstalled.value = config.dependenciesInstalled || false
console.log('📊 最终状态设置:')
console.log(' - pythonInstalled:', pythonInstalled.value)
console.log(' - pipInstalled:', pipInstalled.value)
console.log(' - gitInstalled:', gitInstalled.value)
console.log(' - backendExists:', backendExists.value)
console.log(' - dependenciesInstalled:', dependenciesInstalled.value)
// 检查是否第一次启动
const isFirst = config.isFirstLaunch
console.log('是否第一次启动:', isFirst)
// 检查所有关键exe文件是否都存在
const allExeFilesExist = criticalFiles.pythonExists &&
criticalFiles.pipExists &&
criticalFiles.gitExists &&
criticalFiles.mainPyExists
const allExeFilesExist =
criticalFiles.pythonExists &&
criticalFiles.pipExists &&
criticalFiles.gitExists &&
criticalFiles.mainPyExists
console.log('关键exe文件状态检查:')
console.log('- python.exe存在:', criticalFiles.pythonExists)
console.log('- pip.exe存在:', criticalFiles.pipExists)
console.log('- git.exe存在:', criticalFiles.gitExists)
console.log('- main.py存在:', criticalFiles.mainPyExists)
console.log('- 所有关键文件存在:', allExeFilesExist)
// 检查是否应该进入自动模式
console.log('自动模式判断条件:')
console.log('- 不是第一次启动:', !isFirst)
@@ -203,8 +204,15 @@ async function checkEnvironment() {
} else {
logger.info('需要进入手动模式进行配置')
console.log('进入手动模式')
console.log('原因: isFirst =', isFirst, ', config.init =', config.init, ', allExeFilesExist =', allExeFilesExist)
console.log(
'原因: isFirst =',
isFirst,
', config.init =',
config.init,
', allExeFilesExist =',
allExeFilesExist
)
// 如果关键文件缺失,重置初始化状态
if (!allExeFilesExist && config.init) {
console.log('检测到关键exe文件缺失重置初始化状态')
@@ -215,7 +223,7 @@ async function checkEnvironment() {
const errorMsg = `环境检查失败: ${error instanceof Error ? error.message : String(error)}`
logger.error('环境检查失败', error)
console.error('环境检查失败:', error)
// 检查失败时强制进入手动模式
autoMode.value = false
}
@@ -241,27 +249,27 @@ function handleProgressUpdate(progress: DownloadProgress) {
onMounted(async () => {
console.log('初始化页面 onMounted 开始')
// 测试配置系统
try {
console.log('测试配置系统...')
const testConfig = await getConfig()
console.log('当前配置:', testConfig)
// 测试保存配置
await saveConfig({ isFirstLaunch: false })
console.log('测试配置保存成功')
// 重新读取配置验证
const updatedConfig = await getConfig()
console.log('更新后的配置:', updatedConfig)
} catch (error) {
console.error('配置系统测试失败:', error)
}
// 检查管理员权限
await checkAdminPermission()
if (isAdmin.value) {
// 延迟检查环境,确保页面完全加载
setTimeout(async () => {
@@ -269,7 +277,7 @@ onMounted(async () => {
await checkEnvironment()
}, 100)
}
window.electronAPI.onDownloadProgress(handleProgressUpdate)
console.log('初始化页面 onMounted 完成')
})

View File

@@ -4,7 +4,7 @@
<h2>系统日志</h2>
<p>查看应用运行日志支持搜索过滤和导出功能</p>
</div>
<div class="logs-content">
<LogViewer />
</div>
@@ -52,4 +52,4 @@ onMounted(() => {
flex: 1;
min-height: 0;
}
</style>
</style>

View File

@@ -2,7 +2,7 @@
<div v-if="loading" class="loading-box">
<a-spin tip="加载中,请稍候..." size="large" />
</div>
<div v-else class="queue-content">
<!-- 队列头部 -->
<div class="queue-header">
@@ -27,7 +27,11 @@
<!-- 空状态 -->
<div v-if="!queueList.length || !currentQueueData" class="empty-state">
<div class="empty-content empty-content-fancy" @click="handleAddQueue" style="cursor: pointer">
<div
class="empty-content empty-content-fancy"
@click="handleAddQueue"
style="cursor: pointer"
>
<div class="empty-icon">
<PlusOutlined />
</div>
@@ -71,21 +75,21 @@
/>
</div>
</div>
<!-- <div class="section-controls">-->
<!-- <a-space>-->
<!-- <span class="status-label">状态</span>-->
<!-- <a-switch -->
<!-- v-model:checked="currentQueueEnabled" -->
<!-- @change="onQueueStatusChange"-->
<!-- checked-children="启用"-->
<!-- un-checked-children="禁用"-->
<!-- />-->
<!-- </a-space>-->
<!-- </div>-->
<!-- <div class="section-controls">-->
<!-- <a-space>-->
<!-- <span class="status-label">状态</span>-->
<!-- <a-switch -->
<!-- v-model:checked="currentQueueEnabled" -->
<!-- @change="onQueueStatusChange"-->
<!-- checked-children="启用"-->
<!-- un-checked-children="禁用"-->
<!-- />-->
<!-- </a-space>-->
<!-- </div>-->
</div>
<!-- 定时项组件 -->
<TimeSetManager
<TimeSetManager
v-if="activeQueueId && currentQueueData"
:queue-id="activeQueueId"
:time-sets="currentTimeSets"
@@ -93,7 +97,7 @@
/>
<!-- 队列项组件 -->
<QueueItemManager
<QueueItemManager
v-if="activeQueueId && currentQueueData"
:queue-id="activeQueueId"
:queue-items="currentQueueItems"
@@ -147,7 +151,7 @@ const fetchQueues = async () => {
if (response.code === 200) {
// 处理队列数据
console.log('API Response:', response) // 调试日志
if (response.index && response.index.length > 0) {
queueList.value = response.index.map((item: any, index: number) => {
try {
@@ -155,19 +159,19 @@ const fetchQueues = async () => {
const queueId = item.uid
const queueName = response.data[queueId]?.Info?.Name || `队列 ${index + 1}`
console.log('Queue ID:', queueId, 'Name:', queueName, 'Type:', typeof queueId) // 调试日志
return {
id: queueId,
name: queueName
return {
id: queueId,
name: queueName,
}
} catch (itemError) {
console.warn('解析队列项失败:', itemError, item)
return {
id: `queue_${index}`,
name: `队列 ${index + 1}`
name: `队列 ${index + 1}`,
}
}
})
// 如果有队列且没有选中的队列,默认选中第一个
if (queueList.value.length > 0 && !activeQueueId.value) {
activeQueueId.value = queueList.value[0].id
@@ -201,7 +205,7 @@ const fetchQueues = async () => {
// 加载队列数据
const loadQueueData = async (queueId: string) => {
if (!queueId) return
try {
const response = await Service.getQueuesApiQueueGetPost({})
currentQueueData.value = response.data
@@ -209,7 +213,7 @@ const loadQueueData = async (queueId: string) => {
// 根据API响应数据更新队列信息
if (response.data && response.data[queueId]) {
const queueData = response.data[queueId]
// 更新队列名称和状态
const currentQueue = queueList.value.find(queue => queue.id === queueId)
if (currentQueue) {
@@ -220,14 +224,14 @@ const loadQueueData = async (queueId: string) => {
// 使用nextTick确保DOM更新后再加载数据
await nextTick()
await new Promise(resolve => setTimeout(resolve, 50))
// 加载定时项和队列项数据 - 添加错误处理
try {
await refreshTimeSets()
} catch (timeError) {
console.error('刷新定时项失败:', timeError)
}
try {
await refreshQueueItems()
} catch (itemError) {
@@ -246,7 +250,7 @@ const refreshTimeSets = async () => {
currentTimeSets.value = []
return
}
try {
// 重新从API获取最新的队列数据
const response = await Service.getQueuesApiQueueGetPost({})
@@ -255,42 +259,42 @@ const refreshTimeSets = async () => {
currentTimeSets.value = []
return
}
// 更新缓存的队列数据
currentQueueData.value = response.data
// 从最新的队列数据中获取定时项信息
if (response.data && response.data[activeQueueId.value]) {
const queueData = response.data[activeQueueId.value]
const timeSets: any[] = []
// 检查是否有TimeSet配置
if (queueData?.SubConfigsInfo?.TimeSet) {
const timeSetConfig = queueData.SubConfigsInfo.TimeSet
// 遍历instances数组获取所有定时项ID
if (Array.isArray(timeSetConfig.instances)) {
timeSetConfig.instances.forEach((instance: any) => {
try {
const timeSetId = instance?.uid
if (!timeSetId) return
const timeSetData = timeSetConfig[timeSetId]
if (timeSetData?.Info) {
// 解析时间字符串 "HH:mm" - 修复字段名
const originalTimeString = timeSetData.Info.Set || timeSetData.Info.Time || '00:00'
const [hours = 0, minutes = 0] = originalTimeString.split(':').map(Number)
// 创建标准化的时间字符串
const validHours = Math.max(0, Math.min(23, hours))
const validMinutes = Math.max(0, Math.min(59, minutes))
const timeString = `${validHours.toString().padStart(2, '0')}:${validMinutes.toString().padStart(2, '0')}`
timeSets.push({
id: timeSetId,
time: timeString,
enabled: Boolean(timeSetData.Info.Enabled),
description: timeSetData.Info.Description || ''
description: timeSetData.Info.Description || '',
})
}
} catch (itemError) {
@@ -299,7 +303,7 @@ const refreshTimeSets = async () => {
})
}
}
// 使用nextTick确保数据更新不会导致渲染问题
await nextTick()
currentTimeSets.value = [...timeSets]
@@ -320,7 +324,7 @@ const refreshQueueItems = async () => {
currentQueueItems.value = []
return
}
try {
// 重新从API获取最新的队列数据
const response = await Service.getQueuesApiQueueGetPost({})
@@ -329,31 +333,31 @@ const refreshQueueItems = async () => {
currentQueueItems.value = []
return
}
// 更新缓存的队列数据
currentQueueData.value = response.data
// 从最新的队列数据中获取队列项信息
if (response.data && response.data[activeQueueId.value]) {
const queueData = response.data[activeQueueId.value]
const queueItems: any[] = []
// 检查是否有QueueItem配置
if (queueData?.SubConfigsInfo?.QueueItem) {
const queueItemConfig = queueData.SubConfigsInfo.QueueItem
// 遍历instances数组获取所有队列项ID
if (Array.isArray(queueItemConfig.instances)) {
queueItemConfig.instances.forEach((instance: any) => {
try {
const queueItemId = instance?.uid
if (!queueItemId) return
const queueItemData = queueItemConfig[queueItemId]
if (queueItemData?.Info) {
queueItems.push({
id: queueItemId,
script: queueItemData.Info.ScriptId || ''
script: queueItemData.Info.ScriptId || '',
})
}
} catch (itemError) {
@@ -362,7 +366,7 @@ const refreshQueueItems = async () => {
})
}
}
// 使用nextTick确保数据更新不会导致渲染问题
await nextTick()
currentQueueItems.value = [...queueItems]
@@ -382,7 +386,8 @@ const onQueueNameBlur = () => {
if (activeQueueId.value) {
const currentQueue = queueList.value.find(queue => queue.id === activeQueueId.value)
if (currentQueue) {
currentQueue.name = currentQueueName.value || `队列 ${queueList.value.indexOf(currentQueue) + 1}`
currentQueue.name =
currentQueueName.value || `队列 ${queueList.value.indexOf(currentQueue) + 1}`
}
}
}
@@ -409,7 +414,7 @@ const onTabEdit = async (targetKey: string | MouseEvent, action: 'add' | 'remove
const handleAddQueue = async () => {
try {
const response = await Service.addQueueApiQueueAddPost()
if (response.code === 200 && response.queueId) {
const defaultName = `队列 ${queueList.value.length + 1}`
const newQueue = {
@@ -438,7 +443,7 @@ const handleAddQueue = async () => {
const handleRemoveQueue = async (queueId: string) => {
try {
const response = await Service.deleteQueueApiQueueDeletePost({ queueId })
if (response.code === 200) {
const index = queueList.value.findIndex(queue => queue.id === queueId)
if (index > -1) {
@@ -465,12 +470,12 @@ const handleRemoveQueue = async (queueId: string) => {
// 队列切换
const onQueueChange = async (queueId: string) => {
if (!queueId) return
try {
// 清空当前数据,避免渲染问题
currentTimeSets.value = []
currentQueueItems.value = []
await loadQueueData(queueId)
} catch (error) {
console.error('队列切换失败:', error)
@@ -505,9 +510,9 @@ const saveQueueData = async () => {
const response = await Service.updateQueueApiQueueUpdatePost({
queueId: activeQueueId.value,
data: queueData
data: queueData,
})
if (response.code !== 200) {
throw new Error(response.message || '保存失败')
}
@@ -701,7 +706,9 @@ onMounted(async () => {
}
.empty-content-fancy {
transition: box-shadow 0.3s, transform 0.2s;
transition:
box-shadow 0.3s,
transform 0.2s;
border: none;
border-radius: 24px;
}

View File

@@ -154,28 +154,27 @@
<!-- 实时日志 (60%) -->
<a-col :span="14">
<a-card size="small" style="height: 100%" title="实时日志">
<div class="realtime-logs-panel">
<!-- <a-row justify="space-between" align="middle" style="margin-bottom: 8px">-->
<!-- &lt;!&ndash; 左侧标题 &ndash;&gt;-->
<!-- <a-col :span="12">-->
<!-- <div class="log-title">实时日志</div>-->
<!-- </a-col>-->
<!-- <a-row justify="space-between" align="middle" style="margin-bottom: 8px">-->
<!-- &lt;!&ndash; 左侧标题 &ndash;&gt;-->
<!-- <a-col :span="12">-->
<!-- <div class="log-title">实时日志</div>-->
<!-- </a-col>-->
<!-- &lt;!&ndash; 右侧清空按钮 &ndash;&gt;-->
<!-- <a-col :span="12" style="text-align: right">-->
<!-- <div class="clear-button">-->
<!-- <a-button-->
<!-- type="default"-->
<!-- size="small"-->
<!-- @click="clearTaskOutput(task.websocketId)"-->
<!-- :icon="h(ClearOutlined)"-->
<!-- >-->
<!-- 清空-->
<!-- </a-button>-->
<!-- </div>-->
<!-- </a-col>-->
<!-- </a-row>-->
<!-- &lt;!&ndash; 右侧清空按钮 &ndash;&gt;-->
<!-- <a-col :span="12" style="text-align: right">-->
<!-- <div class="clear-button">-->
<!-- <a-button-->
<!-- type="default"-->
<!-- size="small"-->
<!-- @click="clearTaskOutput(task.websocketId)"-->
<!-- :icon="h(ClearOutlined)"-->
<!-- >-->
<!-- 清空-->
<!-- </a-button>-->
<!-- </div>-->
<!-- </a-col>-->
<!-- </a-row>-->
<div
class="panel-content log-content"
:ref="el => setOutputRef(el as HTMLElement, task.websocketId)"
@@ -624,17 +623,17 @@ const handleWebSocketMessage = (task: RunningTask, data: any) => {
case 'Info':
// 通知信息
let level = 'info';
let content = '未知通知';
let level = 'info'
let content = '未知通知'
// 检查数据中是否有 Error 字段
if (data.data?.Error) {
// 如果是错误信息,设置为 error 级别
level = 'error';
content = data.data.Error; // 错误信息内容
level = 'error'
content = data.data.Error // 错误信息内容
} else {
// 如果没有 Error 字段,继续处理 val 或 message 字段
content = data.data?.val || data.data?.message || '未知通知';
content = data.data?.val || data.data?.message || '未知通知'
}
addTaskLog(task, content, level as any)
@@ -1023,4 +1022,4 @@ onUnmounted(() => {
.log-error .log-message {
color: var(--ant-color-error);
}
</style>
</style>

View File

@@ -184,7 +184,7 @@ const handleThemeColorChange = (value: SelectValue) => {
const openDevTools = () => {
if ((window as any).electronAPI) {
; (window as any).electronAPI.openDevTools()
;(window as any).electronAPI.openDevTools()
}
}
@@ -204,21 +204,31 @@ onMounted(() => {
<div class="setting-item">
<h4>主题模式</h4>
<p class="setting-description">选择应用程序的外观主题</p>
<Radio.Group :value="themeMode" @change="handleThemeModeChange" :options="themeModeOptions" />
<Radio.Group
:value="themeMode"
@change="handleThemeModeChange"
:options="themeModeOptions"
/>
</div>
<Divider />
<div class="setting-item">
<h4>主题色</h4>
<p class="setting-description">选择应用程序的主色调</p>
<Select :value="themeColor" @change="handleThemeColorChange" style="width: 200px">
<Select.Option v-for="option in themeColorOptions" :key="option.value" :value="option.value">
<Select.Option
v-for="option in themeColorOptions"
:key="option.value"
:value="option.value"
>
<div style="display: flex; align-items: center; gap: 8px">
<div :style="{
width: '16px',
height: '16px',
borderRadius: '50%',
backgroundColor: option.color,
}" />
<div
:style="{
width: '16px',
height: '16px',
borderRadius: '50%',
backgroundColor: option.color,
}"
/>
{{ option.label }}
</div>
</Select.Option>
@@ -235,9 +245,12 @@ onMounted(() => {
<div class="setting-item">
<h4>Boss键</h4>
<p class="setting-description">设置快速隐藏窗口的快捷键</p>
<Input v-model:value="settings.Function.BossKey"
@blur="handleSettingChange('Function', 'BossKey', settings.Function.BossKey)" placeholder="例如: Ctrl+H"
style="width: 300px" />
<Input
v-model:value="settings.Function.BossKey"
@blur="handleSettingChange('Function', 'BossKey', settings.Function.BossKey)"
placeholder="例如: Ctrl+H"
style="width: 300px"
/>
</div>
<Divider />
@@ -245,9 +258,12 @@ onMounted(() => {
<div class="setting-item">
<h4>历史记录保留时间</h4>
<p class="setting-description">设置历史记录的保留时间</p>
<Select v-model:value="settings.Function.HistoryRetentionTime"
@change="(value) => handleSettingChange('Function', 'HistoryRetentionTime', value)"
:options="historyRetentionOptions" style="width: 200px" />
<Select
v-model:value="settings.Function.HistoryRetentionTime"
@change="value => handleSettingChange('Function', 'HistoryRetentionTime', value)"
:options="historyRetentionOptions"
style="width: 200px"
/>
</div>
<Divider />
@@ -255,9 +271,12 @@ onMounted(() => {
<div class="setting-item">
<h4>主页图像模式</h4>
<p class="setting-description">选择主页显示的图像模式</p>
<Select v-model:value="settings.Function.HomeImageMode"
@change="(value) => handleSettingChange('Function', 'HomeImageMode', value)"
:options="homeImageModeOptions" style="width: 200px" />
<Select
v-model:value="settings.Function.HomeImageMode"
@change="value => handleSettingChange('Function', 'HomeImageMode', value)"
:options="homeImageModeOptions"
style="width: 200px"
/>
</div>
<Divider />
@@ -266,28 +285,40 @@ onMounted(() => {
<h4>功能开关</h4>
<Space direction="vertical" size="middle">
<div class="switch-item">
<Switch v-model:checked="settings.Function.IfAllowSleep"
@change="(checked) => handleSettingChange('Function', 'IfAllowSleep', checked)" />
<Switch
v-model:checked="settings.Function.IfAllowSleep"
@change="checked => handleSettingChange('Function', 'IfAllowSleep', checked)"
/>
<span class="switch-label">启动时阻止系统休眠</span>
</div>
<div class="switch-item">
<Switch v-model:checked="settings.Function.IfSilence"
@change="(checked) => handleSettingChange('Function', 'IfSilence', checked)" />
<Switch
v-model:checked="settings.Function.IfSilence"
@change="checked => handleSettingChange('Function', 'IfSilence', checked)"
/>
<span class="switch-label">静默模式</span>
</div>
<div class="switch-item">
<Switch v-model:checked="settings.Function.UnattendedMode"
@change="(checked) => handleSettingChange('Function', 'UnattendedMode', checked)" />
<Switch
v-model:checked="settings.Function.UnattendedMode"
@change="checked => handleSettingChange('Function', 'UnattendedMode', checked)"
/>
<span class="switch-label">无人值守模式</span>
</div>
<div class="switch-item">
<Switch v-model:checked="settings.Function.IfAgreeBilibili"
@change="(checked) => handleSettingChange('Function', 'IfAgreeBilibili', checked)" />
<Switch
v-model:checked="settings.Function.IfAgreeBilibili"
@change="checked => handleSettingChange('Function', 'IfAgreeBilibili', checked)"
/>
<span class="switch-label">托管Bilibili游戏隐私政策</span>
</div>
<div class="switch-item">
<Switch v-model:checked="settings.Function.IfSkipMumuSplashAds"
@change="(checked) => handleSettingChange('Function', 'IfSkipMumuSplashAds', checked)" />
<Switch
v-model:checked="settings.Function.IfSkipMumuSplashAds"
@change="
checked => handleSettingChange('Function', 'IfSkipMumuSplashAds', checked)
"
/>
<span class="switch-label">跳过MuMu模拟器启动广告</span>
</div>
</Space>
@@ -303,9 +334,12 @@ onMounted(() => {
<div class="setting-item">
<h4>任务结果推送时间</h4>
<p class="setting-description">设置何时推送任务执行结果</p>
<Select v-model:value="settings.Notify.SendTaskResultTime"
@change="(value) => handleSettingChange('Notify', 'SendTaskResultTime', value)"
:options="sendTaskResultTimeOptions" style="width: 200px" />
<Select
v-model:value="settings.Notify.SendTaskResultTime"
@change="value => handleSettingChange('Notify', 'SendTaskResultTime', value)"
:options="sendTaskResultTimeOptions"
style="width: 200px"
/>
</div>
<Divider />
@@ -314,18 +348,24 @@ onMounted(() => {
<h4>通知开关</h4>
<Space direction="vertical" size="middle">
<div class="switch-item">
<Switch v-model:checked="settings.Notify.IfSendStatistic"
@change="(checked) => handleSettingChange('Notify', 'IfSendStatistic', checked)" />
<Switch
v-model:checked="settings.Notify.IfSendStatistic"
@change="checked => handleSettingChange('Notify', 'IfSendStatistic', checked)"
/>
<span class="switch-label">发送统计信息</span>
</div>
<div class="switch-item">
<Switch v-model:checked="settings.Notify.IfSendSixStar"
@change="(checked) => handleSettingChange('Notify', 'IfSendSixStar', checked)" />
<Switch
v-model:checked="settings.Notify.IfSendSixStar"
@change="checked => handleSettingChange('Notify', 'IfSendSixStar', checked)"
/>
<span class="switch-label">发送六星通知</span>
</div>
<div class="switch-item">
<Switch v-model:checked="settings.Notify.IfPushPlyer"
@change="(checked) => handleSettingChange('Notify', 'IfPushPlyer', checked)" />
<Switch
v-model:checked="settings.Notify.IfPushPlyer"
@change="checked => handleSettingChange('Notify', 'IfPushPlyer', checked)"
/>
<span class="switch-label">启用PushPlus推送</span>
</div>
</Space>
@@ -337,33 +377,61 @@ onMounted(() => {
<h4>邮件通知</h4>
<Space direction="vertical" size="middle" style="width: 100%">
<div class="switch-item">
<Switch v-model:checked="settings.Notify.IfSendMail"
@change="(checked) => handleSettingChange('Notify', 'IfSendMail', checked)" />
<Switch
v-model:checked="settings.Notify.IfSendMail"
@change="checked => handleSettingChange('Notify', 'IfSendMail', checked)"
/>
<span class="switch-label">启用邮件通知</span>
</div>
<div class="input-group">
<label>SMTP服务器地址</label>
<Input v-model:value="settings.Notify.SMTPServerAddress"
@blur="handleSettingChange('Notify', 'SMTPServerAddress', settings.Notify.SMTPServerAddress)"
placeholder="例如: smtp.gmail.com" style="width: 300px" />
<Input
v-model:value="settings.Notify.SMTPServerAddress"
@blur="
handleSettingChange(
'Notify',
'SMTPServerAddress',
settings.Notify.SMTPServerAddress
)
"
placeholder="例如: smtp.gmail.com"
style="width: 300px"
/>
</div>
<div class="input-group">
<label>授权码</label>
<Input.Password v-model:value="settings.Notify.AuthorizationCode"
@blur="handleSettingChange('Notify', 'AuthorizationCode', settings.Notify.AuthorizationCode)"
placeholder="邮箱授权码" style="width: 300px" />
<Input.Password
v-model:value="settings.Notify.AuthorizationCode"
@blur="
handleSettingChange(
'Notify',
'AuthorizationCode',
settings.Notify.AuthorizationCode
)
"
placeholder="邮箱授权码"
style="width: 300px"
/>
</div>
<div class="input-group">
<label>发件人地址</label>
<Input v-model:value="settings.Notify.FromAddress"
@blur="handleSettingChange('Notify', 'FromAddress', settings.Notify.FromAddress)"
placeholder="发件人邮箱地址" style="width: 300px" />
<Input
v-model:value="settings.Notify.FromAddress"
@blur="
handleSettingChange('Notify', 'FromAddress', settings.Notify.FromAddress)
"
placeholder="发件人邮箱地址"
style="width: 300px"
/>
</div>
<div class="input-group">
<label>收件人地址</label>
<Input v-model:value="settings.Notify.ToAddress"
@blur="handleSettingChange('Notify', 'ToAddress', settings.Notify.ToAddress)" placeholder="收件人邮箱地址"
style="width: 300px" />
<Input
v-model:value="settings.Notify.ToAddress"
@blur="handleSettingChange('Notify', 'ToAddress', settings.Notify.ToAddress)"
placeholder="收件人邮箱地址"
style="width: 300px"
/>
</div>
</Space>
</div>
@@ -374,15 +442,22 @@ onMounted(() => {
<h4>Server酱通知</h4>
<Space direction="vertical" size="middle" style="width: 100%">
<div class="switch-item">
<Switch v-model:checked="settings.Notify.IfServerChan"
@change="(checked) => handleSettingChange('Notify', 'IfServerChan', checked)" />
<Switch
v-model:checked="settings.Notify.IfServerChan"
@change="checked => handleSettingChange('Notify', 'IfServerChan', checked)"
/>
<span class="switch-label">启用Server酱通知</span>
</div>
<div class="input-group">
<label>Server酱Key</label>
<Input v-model:value="settings.Notify.ServerChanKey"
@blur="handleSettingChange('Notify', 'ServerChanKey', settings.Notify.ServerChanKey)"
placeholder="Server酱推送Key" style="width: 300px" />
<Input
v-model:value="settings.Notify.ServerChanKey"
@blur="
handleSettingChange('Notify', 'ServerChanKey', settings.Notify.ServerChanKey)
"
placeholder="Server酱推送Key"
style="width: 300px"
/>
</div>
</Space>
</div>
@@ -393,15 +468,28 @@ onMounted(() => {
<h4>企业微信机器人</h4>
<Space direction="vertical" size="middle" style="width: 100%">
<div class="switch-item">
<Switch v-model:checked="settings.Notify.IfCompanyWebHookBot"
@change="(checked) => handleSettingChange('Notify', 'IfCompanyWebHookBot', checked)" />
<Switch
v-model:checked="settings.Notify.IfCompanyWebHookBot"
@change="
checked => handleSettingChange('Notify', 'IfCompanyWebHookBot', checked)
"
/>
<span class="switch-label">启用企业微信机器人</span>
</div>
<div class="input-group">
<label>Webhook URL</label>
<Input v-model:value="settings.Notify.CompanyWebHookBotUrl"
@blur="handleSettingChange('Notify', 'CompanyWebHookBotUrl', settings.Notify.CompanyWebHookBotUrl)"
placeholder="企业微信机器人Webhook地址" style="width: 400px" />
<Input
v-model:value="settings.Notify.CompanyWebHookBotUrl"
@blur="
handleSettingChange(
'Notify',
'CompanyWebHookBotUrl',
settings.Notify.CompanyWebHookBotUrl
)
"
placeholder="企业微信机器人Webhook地址"
style="width: 400px"
/>
</div>
</Space>
</div>
@@ -416,8 +504,10 @@ onMounted(() => {
<div class="setting-item">
<h4>自动更新</h4>
<p class="setting-description">是否启用自动更新功能</p>
<Switch v-model:checked="settings.Update.IfAutoUpdate"
@change="(checked) => handleSettingChange('Update', 'IfAutoUpdate', checked)" />
<Switch
v-model:checked="settings.Update.IfAutoUpdate"
@change="checked => handleSettingChange('Update', 'IfAutoUpdate', checked)"
/>
</div>
<Divider />
@@ -425,9 +515,12 @@ onMounted(() => {
<div class="setting-item">
<h4>更新类型</h4>
<p class="setting-description">选择更新版本类型</p>
<Select v-model:value="settings.Update.UpdateType"
@change="(value) => handleSettingChange('Update', 'UpdateType', value)" :options="updateTypeOptions"
style="width: 200px" />
<Select
v-model:value="settings.Update.UpdateType"
@change="value => handleSettingChange('Update', 'UpdateType', value)"
:options="updateTypeOptions"
style="width: 200px"
/>
</div>
<Divider />
@@ -435,9 +528,13 @@ onMounted(() => {
<div class="setting-item">
<h4>下载线程数</h4>
<p class="setting-description">设置下载时使用的线程数量 (1-32)</p>
<InputNumber v-model:value="settings.Update.ThreadNumb"
@change="(value) => handleSettingChange('Update', 'ThreadNumb', value)" :min="1" :max="32"
style="width: 120px" />
<InputNumber
v-model:value="settings.Update.ThreadNumb"
@change="value => handleSettingChange('Update', 'ThreadNumb', value)"
:min="1"
:max="32"
style="width: 120px"
/>
</div>
<Divider />
@@ -447,9 +544,14 @@ onMounted(() => {
<Space direction="vertical" size="middle" style="width: 100%">
<div class="input-group">
<label>代理地址</label>
<Input v-model:value="settings.Update.ProxyAddress"
@blur="handleSettingChange('Update', 'ProxyAddress', settings.Update.ProxyAddress)"
placeholder="例如: http://127.0.0.1:7890" style="width: 300px" />
<Input
v-model:value="settings.Update.ProxyAddress"
@blur="
handleSettingChange('Update', 'ProxyAddress', settings.Update.ProxyAddress)
"
placeholder="例如: http://127.0.0.1:7890"
style="width: 300px"
/>
</div>
</Space>
</div>
@@ -459,9 +561,14 @@ onMounted(() => {
<div class="setting-item">
<h4>Mirror酱 CDK</h4>
<p class="setting-description">设置Mirror酱CDK</p>
<Input v-model:value="settings.Update.MirrorChyanCDK"
@blur="handleSettingChange('Update', 'MirrorChyanCDK', settings.Update.MirrorChyanCDK)"
placeholder="镜像CDK" style="width: 300px" />
<Input
v-model:value="settings.Update.MirrorChyanCDK"
@blur="
handleSettingChange('Update', 'MirrorChyanCDK', settings.Update.MirrorChyanCDK)
"
placeholder="镜像CDK"
style="width: 300px"
/>
</div>
</Space>
</Card>
@@ -474,8 +581,10 @@ onMounted(() => {
<div class="setting-item">
<h4>开机自启</h4>
<p class="setting-description">是否在系统启动时自动启动应用</p>
<Switch v-model:checked="settings.Start.IfSelfStart"
@change="(checked) => handleSettingChange('Start', 'IfSelfStart', checked)" />
<Switch
v-model:checked="settings.Start.IfSelfStart"
@change="checked => handleSettingChange('Start', 'IfSelfStart', checked)"
/>
</div>
<Divider />
@@ -483,8 +592,10 @@ onMounted(() => {
<div class="setting-item">
<h4>启动后直接最小化</h4>
<p class="setting-description">启动后是否直接最小化到系统托盘</p>
<Switch v-model:checked="settings.Start.IfMinimizeDirectly"
@change="(checked) => handleSettingChange('Start', 'IfMinimizeDirectly', checked)" />
<Switch
v-model:checked="settings.Start.IfMinimizeDirectly"
@change="checked => handleSettingChange('Start', 'IfMinimizeDirectly', checked)"
/>
</div>
</Space>
</Card>
@@ -498,13 +609,17 @@ onMounted(() => {
<h4>系统托盘</h4>
<Space direction="vertical" size="middle">
<div class="switch-item">
<Switch v-model:checked="settings.UI.IfShowTray"
@change="(checked) => handleSettingChange('UI', 'IfShowTray', checked)" />
<Switch
v-model:checked="settings.UI.IfShowTray"
@change="checked => handleSettingChange('UI', 'IfShowTray', checked)"
/>
<span class="switch-label">显示系统托盘图标</span>
</div>
<div class="switch-item">
<Switch v-model:checked="settings.UI.IfToTray"
@change="(checked) => handleSettingChange('UI', 'IfToTray', checked)" />
<Switch
v-model:checked="settings.UI.IfToTray"
@change="checked => handleSettingChange('UI', 'IfToTray', checked)"
/>
<span class="switch-label">关闭时最小化到托盘</span>
</div>
</Space>
@@ -512,27 +627,27 @@ onMounted(() => {
<Divider />
<!-- <div class="setting-item">-->
<!-- <h4>窗口设置</h4>-->
<!-- <Space direction="vertical" size="middle" style="width: 100%">-->
<!-- <div class="input-group">-->
<!-- <label>窗口大小</label>-->
<!-- <Input v-model:value="settings.UI.size" @blur="handleSettingChange('UI', 'size', settings.UI.size)"-->
<!-- placeholder="例如: 1200x700" style="width: 200px" />-->
<!-- </div>-->
<!-- <div class="input-group">-->
<!-- <label>窗口位置</label>-->
<!-- <Input v-model:value="settings.UI.location"-->
<!-- @blur="handleSettingChange('UI', 'location', settings.UI.location)" placeholder="例如: 100x100"-->
<!-- style="width: 200px" />-->
<!-- </div>-->
<!-- <div class="switch-item">-->
<!-- <Switch v-model:checked="settings.UI.maximized"-->
<!-- @change="(checked) => handleSettingChange('UI', 'maximized', checked)" />-->
<!-- <span class="switch-label">启动时最大化窗口</span>-->
<!-- </div>-->
<!-- </Space>-->
<!-- </div>-->
<!-- <div class="setting-item">-->
<!-- <h4>窗口设置</h4>-->
<!-- <Space direction="vertical" size="middle" style="width: 100%">-->
<!-- <div class="input-group">-->
<!-- <label>窗口大小</label>-->
<!-- <Input v-model:value="settings.UI.size" @blur="handleSettingChange('UI', 'size', settings.UI.size)"-->
<!-- placeholder="例如: 1200x700" style="width: 200px" />-->
<!-- </div>-->
<!-- <div class="input-group">-->
<!-- <label>窗口位置</label>-->
<!-- <Input v-model:value="settings.UI.location"-->
<!-- @blur="handleSettingChange('UI', 'location', settings.UI.location)" placeholder="例如: 100x100"-->
<!-- style="width: 200px" />-->
<!-- </div>-->
<!-- <div class="switch-item">-->
<!-- <Switch v-model:checked="settings.UI.maximized"-->
<!-- @change="(checked) => handleSettingChange('UI', 'maximized', checked)" />-->
<!-- <span class="switch-label">启动时最大化窗口</span>-->
<!-- </div>-->
<!-- </Space>-->
<!-- </div>-->
</Space>
</Card>
</Tabs.TabPane>
@@ -544,8 +659,10 @@ onMounted(() => {
<div class="setting-item">
<h4>语音提示</h4>
<p class="setting-description">是否启用语音提示功能</p>
<Switch v-model:checked="settings.Voice.Enabled"
@change="(checked) => handleSettingChange('Voice', 'Enabled', checked)" />
<Switch
v-model:checked="settings.Voice.Enabled"
@change="checked => handleSettingChange('Voice', 'Enabled', checked)"
/>
</div>
<Divider />
@@ -553,9 +670,13 @@ onMounted(() => {
<div class="setting-item">
<h4>语音类型</h4>
<p class="setting-description">选择语音提示的详细程度</p>
<Select v-model:value="settings.Voice.Type"
@change="(value) => handleSettingChange('Voice', 'Type', value)" :options="voiceTypeOptions"
style="width: 200px" :disabled="!settings.Voice.Enabled" />
<Select
v-model:value="settings.Voice.Type"
@change="value => handleSettingChange('Voice', 'Type', value)"
:options="voiceTypeOptions"
style="width: 200px"
:disabled="!settings.Voice.Enabled"
/>
</div>
</Space>
</Card>
@@ -570,9 +691,9 @@ onMounted(() => {
<p class="setting-description">打开浏览器开发者工具进行调试</p>
<Button type="primary" @click="openDevTools">打开 F12 开发者工具</Button>
</div>
<Divider />
<div class="setting-item">
<h4>系统日志</h4>
<p class="setting-description">查看应用运行日志用于问题排查和调试</p>
@@ -646,5 +767,4 @@ onMounted(() => {
:deep(.ant-tabs-tab) {
color: v-bind(textSecondaryColor);
}
</style>