feat: 添加配置文件的导入功能及文件路径显示

新增通过系统对话框导入配置文件的功能
在界面上显示当前打开的配置文件路径
添加对50%击穿电压的验证
优化开发模式下的文件导入备用方案
This commit is contained in:
dmy
2026-03-03 18:58:19 +08:00
parent 7dd466a28a
commit 86b294baf9
2 changed files with 98 additions and 6 deletions

View File

@@ -2,16 +2,20 @@
<q-layout view="lHh lpr lFf">
<q-header elevated class="bg-indigo-600 text-white">
<q-toolbar>
<q-toolbar-title>
<q-toolbar-title class="q-py-sm">
<div class="flex items-center gap-2">
<q-icon name="flash_on" size="md" />
<span class="text-xl font-bold">EGM 输电线路绕击跳闸率计算</span>
</div>
<div v-if="currentFilePath" class="text-sm truncate max-w-2xl bg-white text-green-700 px-2 py-0.5 rounded mt-1" :title="currentFilePath">
{{ currentFilePath }}
</div>
</q-toolbar-title>
</q-toolbar>
</q-header>
<q-page-container>
<q-page class="q-pa-md">
<div class="max-w-4xl mx-auto">
<!-- 基本参数 -->
@@ -342,7 +346,7 @@
/>
</div>
<!-- 隐藏的文件输入 -->
<!-- 隐藏的文件输入开发模式备用 -->
<input
ref="fileInput"
type="file"
@@ -441,6 +445,8 @@ const error = ref<string | null>(null)
const logRef = ref<InstanceType<typeof LogComponent> | null>(null)
const animationRef = ref<InstanceType<typeof Animation> | null>(null)
const fileInput = ref<HTMLInputElement | null>(null)
// 当前打开的文件路径
const currentFilePath = ref<string>('')
// 雷电流概率密度系数设置开关
const showIpCoefficients = ref(false)
// 50%击穿电压设置开关
@@ -582,6 +588,16 @@ const calculate = async () => {
}
}
// 验证50%击穿电压
if (showU50.value) {
const u50 = Number(params.advance.u_50)
if (u50 < 1000) {
error.value = '请检查参数:"50%击穿电压 U_50"的值应该大于等于 1000 kV'
logRef.value?.addLog('error', '请检查参数:"50%击穿电压 U_50"的值应该大于等于 1000 kV')
return
}
}
calculating.value = true
result.value = null
error.value = null
@@ -771,12 +787,44 @@ const exportConfig = async () => {
}
}
// 导入配置 - 触发文件选择
const importConfig = () => {
fileInput.value?.click()
// 导入配置 - 调用后端文件对话框
const importConfig = async () => {
try {
if (window.pywebview) {
const response = await window.pywebview.api.import_config()
if (response.success && response.params) {
// 合并导入的参数到当前参数
if (response.params.parameter) {
Object.assign(params.parameter, response.params.parameter)
}
if (response.params.advance) {
Object.assign(params.advance, response.params.advance)
}
if (response.params.optional) {
Object.assign(params.optional, response.params.optional)
}
// 处理文件选择
// 显示完整文件路径
currentFilePath.value = response.file_path || ''
logRef.value?.addLog('info', `成功导入配置: ${response.file_path}`)
result.value = null
error.value = null
} else if (!response.success && response.message !== '用户取消了选择') {
error.value = response.message || '导入失败'
logRef.value?.addLog('error', response.message || '导入失败')
}
} else {
// 开发模式下使用 HTML 文件输入
fileInput.value?.click()
}
} catch (e: any) {
error.value = e.message || '导入失败'
logRef.value?.addLog('error', e.message || '导入失败')
}
}
// 处理文件选择(开发模式备用)
const handleFileSelect = async (event: Event) => {
const input = event.target as HTMLInputElement
const file = input.files?.[0]
@@ -797,6 +845,8 @@ const handleFileSelect = async (event: Event) => {
Object.assign(params.optional, importedParams.optional)
}
currentFilePath.value = file.name
logRef.value?.addLog('info', `成功导入配置: ${file.name}`)
result.value = null
error.value = null
@@ -815,6 +865,7 @@ declare global {
pywebview?: {
api: {
calculate: (params: AllParameters) => Promise<any>
import_config: () => Promise<any>
export_config: (params: AllParameters) => Promise<any>
export_log: (logText: string) => Promise<any>
}

View File

@@ -9,6 +9,7 @@ import json
import math
import threading
import queue
import tomllib
from pathlib import Path
from typing import Dict, Any, List
from datetime import datetime
@@ -524,6 +525,46 @@ class EGMWebApp:
"message": f"保存失败: {str(e)}"
}
def import_config(self) -> Dict[str, Any]:
"""
导入配置从 TOML 文件,弹出打开对话框
Returns:
包含解析后的参数和文件路径的字典
"""
try:
# 打开文件选择对话框
result = self.window.create_file_dialog(
webview.OPEN_DIALOG,
directory='',
file_types=('TOML Files (*.toml)', 'All files (*.*)')
)
if result and len(result) > 0:
file_path = result[0]
# 读取并解析 TOML 文件
with open(file_path, 'rb') as f:
toml_data = tomllib.load(f)
return {
"success": True,
"message": f"成功导入配置",
"file_path": file_path,
"params": toml_data
}
else:
return {
"success": False,
"message": "用户取消了选择"
}
except Exception as e:
logger.error(f"导入配置失败: {str(e)}")
return {
"success": False,
"message": f"导入失败: {str(e)}"
}
def get_default_config(self) -> Dict[str, Any]:
"""
获取默认配置