feat: 添加配置文件的导入功能及文件路径显示
新增通过系统对话框导入配置文件的功能 在界面上显示当前打开的配置文件路径 添加对50%击穿电压的验证 优化开发模式下的文件导入备用方案
This commit is contained in:
@@ -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>
|
||||
}
|
||||
|
||||
@@ -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]:
|
||||
"""
|
||||
获取默认配置
|
||||
|
||||
Reference in New Issue
Block a user