feat: 将配置导出功能从JSON改为TOML格式并添加保存对话框
This commit is contained in:
@@ -452,16 +452,57 @@ const resetParams = () => {
|
|||||||
error.value = null
|
error.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 将参数转换为 TOML 格式
|
||||||
|
const tomlStringify = (obj: any, indent: string = ''): string => {
|
||||||
|
let result = ''
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(obj)) {
|
||||||
|
if (value === null || value === undefined) continue
|
||||||
|
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
result += `${indent}${key} = [${value.join(', ')}]\n`
|
||||||
|
} else if (typeof value === 'object') {
|
||||||
|
result += `\n${indent}[${key}]\n`
|
||||||
|
result += tomlStringify(value, indent)
|
||||||
|
} else if (typeof value === 'string') {
|
||||||
|
result += `${indent}${key} = "${value}"\n`
|
||||||
|
} else if (typeof value === 'boolean') {
|
||||||
|
result += `${indent}${key} = ${value}\n`
|
||||||
|
} else {
|
||||||
|
result += `${indent}${key} = ${value}\n`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
// 导出配置
|
// 导出配置
|
||||||
const exportConfig = () => {
|
const exportConfig = async () => {
|
||||||
const config = JSON.stringify(params, null, 2)
|
try {
|
||||||
const blob = new Blob([config], { type: 'application/json' })
|
if (window.pywebview) {
|
||||||
const url = URL.createObjectURL(blob)
|
const response = await window.pywebview.api.export_config(params)
|
||||||
const a = document.createElement('a')
|
if (response.success) {
|
||||||
a.href = url
|
logRef.value?.addLog('info', response.message)
|
||||||
a.download = 'egm_config.json'
|
} else {
|
||||||
a.click()
|
logRef.value?.addLog('warning', response.message)
|
||||||
URL.revokeObjectURL(url)
|
}
|
||||||
|
} else {
|
||||||
|
// 开发模式下的模拟
|
||||||
|
logRef.value?.addLog('info', '导出配置(开发模式,直接下载)')
|
||||||
|
const config = tomlStringify(params)
|
||||||
|
const blob = new Blob([config], { type: 'text/plain' })
|
||||||
|
const url = URL.createObjectURL(blob)
|
||||||
|
const a = document.createElement('a')
|
||||||
|
a.href = url
|
||||||
|
const timestamp = new Date().toISOString().slice(0, 19).replace(/[:-]/g, '')
|
||||||
|
a.download = `egm_config_${timestamp}.toml`
|
||||||
|
a.click()
|
||||||
|
URL.revokeObjectURL(url)
|
||||||
|
}
|
||||||
|
} catch (e: any) {
|
||||||
|
error.value = e.message || '导出失败'
|
||||||
|
logRef.value?.addLog('error', e.message || '导出失败')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 声明 pywebview API 类型
|
// 声明 pywebview API 类型
|
||||||
@@ -470,6 +511,7 @@ declare global {
|
|||||||
pywebview?: {
|
pywebview?: {
|
||||||
api: {
|
api: {
|
||||||
calculate: (params: AllParameters) => Promise<any>
|
calculate: (params: AllParameters) => Promise<any>
|
||||||
|
export_config: (params: AllParameters) => Promise<any>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -340,17 +340,86 @@ class EGMWebApp:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def export_config(self, params: Dict[str, Any]) -> str:
|
def dict_to_toml(self, obj: Dict[str, Any], indent: str = '') -> str:
|
||||||
"""
|
"""
|
||||||
导出配置为 JSON 字符串
|
将字典转换为 TOML 格式字符串
|
||||||
|
|
||||||
|
Args:
|
||||||
|
obj: 参数字典
|
||||||
|
indent: 缩进字符串
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
TOML 格式字符串
|
||||||
|
"""
|
||||||
|
result = ''
|
||||||
|
|
||||||
|
for key, value in obj.items():
|
||||||
|
if value is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if isinstance(value, list):
|
||||||
|
result += f'{indent}{key} = [{", ".join(str(v) for v in value)}]\n'
|
||||||
|
elif isinstance(value, dict):
|
||||||
|
result += f'\n{indent}[{key}]\n'
|
||||||
|
result += self.dict_to_toml(value, indent)
|
||||||
|
elif isinstance(value, str):
|
||||||
|
result += f'{indent}{key} = "{value}"\n'
|
||||||
|
elif isinstance(value, bool):
|
||||||
|
result += f'{indent}{key} = {str(value).lower()}\n'
|
||||||
|
else:
|
||||||
|
result += f'{indent}{key} = {value}\n'
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def export_config(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
导出配置为 TOML 文件,弹出保存对话框
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
params: 参数字典
|
params: 参数字典
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
JSON 字符串
|
包含保存状态和路径的字典
|
||||||
"""
|
"""
|
||||||
return json.dumps(params, indent=2, ensure_ascii=False)
|
try:
|
||||||
|
# 生成默认文件名
|
||||||
|
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|
||||||
|
default_filename = f'egm_config_{timestamp}.toml'
|
||||||
|
|
||||||
|
# 打开保存文件对话框
|
||||||
|
result = self.window.create_file_dialog(
|
||||||
|
webview.SAVE_DIALOG,
|
||||||
|
directory='',
|
||||||
|
save_filename=default_filename,
|
||||||
|
file_types=('TOML Files (*.toml)', 'All files (*.*)')
|
||||||
|
)
|
||||||
|
|
||||||
|
if result and len(result) > 0:
|
||||||
|
file_path = result[0]
|
||||||
|
|
||||||
|
# 转换为 TOML 格式
|
||||||
|
toml_content = self.dict_to_toml(params)
|
||||||
|
|
||||||
|
# 写入文件
|
||||||
|
with open(file_path, 'w', encoding='utf-8') as f:
|
||||||
|
f.write(toml_content)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"success": True,
|
||||||
|
"message": f"配置已保存到: {file_path}",
|
||||||
|
"file_path": file_path
|
||||||
|
}
|
||||||
|
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]:
|
def get_default_config(self) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
@@ -422,6 +491,9 @@ def start_webview():
|
|||||||
min_size=(800, 600)
|
min_size=(800, 600)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 将窗口对象传递给 API
|
||||||
|
api.window = window
|
||||||
|
|
||||||
# 启动
|
# 启动
|
||||||
logger.info("启动 EGM Web 界面...")
|
logger.info("启动 EGM Web 界面...")
|
||||||
webview.start(debug=dev_mode)
|
webview.start(debug=dev_mode)
|
||||||
|
|||||||
Reference in New Issue
Block a user