From b7f0d0b0cc61eda7ecfc0df97a5a4aee4ab2ecea Mon Sep 17 00:00:00 2001 From: purp1e Date: Thu, 6 Nov 2025 16:21:24 +0800 Subject: [PATCH] [fix] csv export codec --- src-tauri/tauri.conf.json | 2 +- src/components/cstb/FpsTest.tsx | 82 ++++++++++++++++++++++++--------- 2 files changed, 61 insertions(+), 23 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 6b41bfd..a1989f4 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -51,7 +51,7 @@ }, "productName": "CS工具箱", "mainBinaryName": "cstb", - "version": "0.0.6-beta.4", + "version": "0.0.6-beta.5", "identifier": "upup.cool", "plugins": { "deep-link": { diff --git a/src/components/cstb/FpsTest.tsx b/src/components/cstb/FpsTest.tsx index 7b5932e..5e67bf1 100644 --- a/src/components/cstb/FpsTest.tsx +++ b/src/components/cstb/FpsTest.tsx @@ -32,7 +32,18 @@ import { DropdownItem, } from "@heroui/react" import { useState, useEffect, useRef, useCallback } from "react" -import { TestTube, Power, List, Delete, Play, Edit, Check, Close, Square, DownloadOne } from "@icon-park/react" +import { + TestTube, + Power, + List, + Delete, + Play, + Edit, + Check, + Close, + Square, + DownloadOne, +} from "@icon-park/react" import { allSysInfo, type AllSystemInfo } from "tauri-plugin-system-info-api" import { ToolButton } from "../window/ToolButton" import { save } from "@tauri-apps/plugin-dialog" @@ -215,7 +226,11 @@ export function FpsTest() { const [resolutionWidth, setResolutionWidth] = useState("") // 分辨率宽度 const [resolutionHeight, setResolutionHeight] = useState("") // 分辨率高度 const [isFullscreen, setIsFullscreen] = useState(true) // 全屏模式(默认全屏) - const { isOpen: isNoteModalOpen, onOpen: onNoteModalOpen, onClose: onNoteModalClose } = useDisclosure() + const { + isOpen: isNoteModalOpen, + onOpen: onNoteModalOpen, + onClose: onNoteModalClose, + } = useDisclosure() const monitoringIntervalRef = useRef(null) const timeoutRef = useRef(null) // 记录测试开始的时间戳(用于过滤旧数据) @@ -357,7 +372,8 @@ export function FpsTest() { const mapConfig = BENCHMARK_MAPS[selectedMapIndex] // 使用测试开始时的视频设置(如果有的话),否则使用当前的 - const currentVideoSetting = testStartVideoSettingRef.current || tool.store.state.videoSetting + const currentVideoSetting = + testStartVideoSettingRef.current || tool.store.state.videoSetting fpsTest.addResult({ id: `${now.getTime()}-${Math.random().toString(36).slice(2, 11)}`, @@ -434,7 +450,14 @@ export function FpsTest() { return false } }, - [steam.state.cs2Dir, selectedMapIndex, fpsTest, tool.store, hardwareInfo, tool.state.autoCloseGame] + [ + steam.state.cs2Dir, + selectedMapIndex, + fpsTest, + tool.store, + hardwareInfo, + tool.state.autoCloseGame, + ] ) // 开始监控文件更新 @@ -550,14 +573,14 @@ export function FpsTest() { try { // 构建启动参数:基础参数 + 分辨率和全屏设置 + 自定义启动项(如果有) let baseLaunchOption = `-allow_third_party_software -condebug -conclearlog +map_workshop ${mapConfig.workshopId} ${mapConfig.map}` - + // 只有在启用分辨率和全屏设置时才添加相关参数 if (isResolutionEnabled) { // 添加分辨率设置(如果有设置) if (resolutionWidth && resolutionHeight) { baseLaunchOption += ` -w ${resolutionWidth} -h ${resolutionHeight}` } - + // 添加全屏/窗口化设置 if (isFullscreen) { baseLaunchOption += ` -fullscreen` @@ -565,7 +588,7 @@ export function FpsTest() { baseLaunchOption += ` -sw` } } - + // 添加自定义启动项(如果有,开头加空格避免粘连) const launchOption = customLaunchOption.trim() ? `${baseLaunchOption} ${customLaunchOption.trim()}` @@ -600,12 +623,15 @@ export function FpsTest() { const canStartTest = !tool.state.autoCloseGame ? !isGameRunning : true // 格式化视频设置摘要 - const formatVideoSettingSummary = (videoSetting: typeof tool.state.videoSetting | null): string => { + const formatVideoSettingSummary = ( + videoSetting: typeof tool.state.videoSetting | null + ): string => { if (!videoSetting) return "N/A" const resolution = `${videoSetting.defaultres}x${videoSetting.defaultresheight}` - const refreshRate = videoSetting.refreshrate_denominator === "1" - ? videoSetting.refreshrate_numerator - : `${videoSetting.refreshrate_numerator}/${videoSetting.refreshrate_denominator}` + const refreshRate = + videoSetting.refreshrate_denominator === "1" + ? videoSetting.refreshrate_numerator + : `${videoSetting.refreshrate_numerator}/${videoSetting.refreshrate_denominator}` const msaa = videoSetting.msaa_samples === "0" ? "无" : `${videoSetting.msaa_samples}x` return `${resolution}@${refreshRate}Hz, MSAA:${msaa}` } @@ -640,7 +666,7 @@ export function FpsTest() { const headers = [ "测试时间", "测试地图", - "AVG平均帧", + "平均帧", "P1低帧", "CPU", "系统版本", @@ -650,9 +676,9 @@ export function FpsTest() { "视频设置", "备注", ] - + const csvRows = [headers.join(",")] - + for (const result of fpsTest.state.results) { const row = [ `"${result.testTime}"`, @@ -671,9 +697,12 @@ export function FpsTest() { ] csvRows.push(row.join(",")) } - + const csvContent = csvRows.join("\n") - + + // 添加UTF-8 BOM以确保Excel等软件正确识别编码 + const csvContentWithBOM = "\uFEFF" + csvContent + // 使用文件保存对话框 const filePath = await save({ filters: [ @@ -684,9 +713,9 @@ export function FpsTest() { ], defaultPath: `fps_test_results_${new Date().toISOString().split("T")[0]}.csv`, }) - + if (filePath) { - await writeTextFile(filePath, csvContent) + await writeTextFile(filePath, csvContentWithBOM) addToast({ title: "导出成功", color: "success" }) } } catch (error) { @@ -796,7 +825,7 @@ export function FpsTest() { 测试时间 测试地图 - AVG平均帧 + 平均帧 P1低帧 CPU 系统版本 @@ -817,17 +846,26 @@ export function FpsTest() { {result.p1 !== null ? `${result.p1.toFixed(1)}` : "N/A"} - +
{result.hardwareInfo?.cpu || "N/A"}
- +
{result.hardwareInfo?.os || "N/A"}
- +
{result.hardwareInfo?.gpu || "N/A"}