DCS/ruiyiweiUX/Assets/Scripts/Services/DataPersistenceService.cs

765 lines
28 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.IO;
using System.Globalization;
using System.Text;
using UnityEngine;
using LitJson;
using GeneralTools;
/// <summary>
/// 数据持久化服务实现
/// 使用JSON格式存储应用数据INI格式存储系统配置
/// </summary>
public class DataPersistenceService : IDataPersistenceService
{
private readonly string _settingsPath;
private readonly string _userPrefsPath;
private readonly string _appConfigPath;
private readonly string _configIniPath;
private readonly string _streamingConfigIniPath;
public DataPersistenceService()
{
// 设置存储路径
var dataPath = Application.persistentDataPath;
_settingsPath = Path.Combine(dataPath, "settings.json");
_userPrefsPath = Path.Combine(dataPath, "UserPrefs");
_appConfigPath = Path.Combine(dataPath, "appconfig.json");
_configIniPath = Path.Combine(dataPath, "config.ini");
_streamingConfigIniPath = Path.Combine(Application.streamingAssetsPath, "config.ini");
// 确保目录存在
EnsureDirectoryExists(_userPrefsPath);
TryCopyIniToPersistent();
}
public bool SaveSettings(SystemSettings settings)
{
bool jsonSaved = false;
bool iniSaved = false;
try
{
var json = JsonMapper.ToJson(settings);
jsonSaved = WriteTextAtomically(_settingsPath, json);
}
catch (Exception ex)
{
Debug.LogError($"保存JSON设置失败: {ex.Message}");
}
iniSaved = SaveToIniFile(settings);
if (jsonSaved || iniSaved)
{
Debug.Log($"设置已保存 - JSON: {jsonSaved}, INI: {iniSaved}");
return true;
}
Debug.LogError("保存设置失败JSON和INI都未成功写入");
return false;
}
public SystemSettings LoadSettings()
{
if (TryLoadJsonSettings(out var settings, out var jsonSourcePath))
{
ApplyNewestIniOverrides(settings, jsonSourcePath);
return settings;
}
if (TryLoadIniSettings(_configIniPath, "持久化INI配置", out settings))
{
return settings;
}
if (TryLoadIniSettings(_configIniPath + ".bak", "持久化INI备份配置", out settings))
{
return settings;
}
if (File.Exists(_streamingConfigIniPath))
{
settings = LoadFromIniFile(_streamingConfigIniPath);
Debug.Log($"从默认INI配置加载设置成功: {_streamingConfigIniPath}");
return settings;
}
Debug.Log("使用默认设置");
return new SystemSettings();
}
public bool SaveUserPreferences(string userId, UserPreferences preferences)
{
try
{
var filePath = Path.Combine(_userPrefsPath, $"{userId}_prefs.json");
var json = JsonMapper.ToJson(preferences);
File.WriteAllText(filePath, json);
Debug.Log($"用户偏好已保存: {userId}");
return true;
}
catch (Exception ex)
{
Debug.LogError($"保存用户偏好失败: {ex.Message}");
return false;
}
}
public UserPreferences LoadUserPreferences(string userId)
{
try
{
var filePath = Path.Combine(_userPrefsPath, $"{userId}_prefs.json");
if (File.Exists(filePath))
{
var json = File.ReadAllText(filePath);
return JsonMapper.ToObject<UserPreferences>(json);
}
}
catch (Exception ex)
{
Debug.LogError($"加载用户偏好失败: {ex.Message}");
}
return new UserPreferences { userId = userId };
}
public bool SaveAppConfig(AppConfig config)
{
try
{
var json = JsonMapper.ToJson(config);
File.WriteAllText(_appConfigPath, json);
return true;
}
catch (Exception ex)
{
Debug.LogError($"保存应用配置失败: {ex.Message}");
return false;
}
}
public AppConfig LoadAppConfig()
{
try
{
if (File.Exists(_appConfigPath))
{
var json = File.ReadAllText(_appConfigPath);
return JsonMapper.ToObject<AppConfig>(json);
}
}
catch (Exception ex)
{
Debug.LogError($"加载应用配置失败: {ex.Message}");
}
return new AppConfig();
}
public bool ExportData(string filePath, ExportDataType dataType)
{
try
{
var exportData = new
{
ExportTime = DateTime.Now,
DataType = dataType.ToString(),
Data = GetExportData(dataType)
};
var json = JsonMapper.ToJson(exportData);
File.WriteAllText(filePath, json);
Debug.Log($"数据导出成功: {filePath}");
return true;
}
catch (Exception ex)
{
Debug.LogError($"导出数据失败: {ex.Message}");
return false;
}
}
public void ClearAllData()
{
try
{
if (File.Exists(_settingsPath))
File.Delete(_settingsPath);
if (File.Exists(_appConfigPath))
File.Delete(_appConfigPath);
if (Directory.Exists(_userPrefsPath))
Directory.Delete(_userPrefsPath, true);
Debug.Log("所有持久化数据已清除");
}
catch (Exception ex)
{
Debug.LogError($"清除数据失败: {ex.Message}");
}
}
private bool SaveToIniFile(SystemSettings settings)
{
try
{
var sb = new StringBuilder();
AppendIniSection(sb, "Display",
("brightness", settings.brightness.ToString("F1", CultureInfo.InvariantCulture)));
AppendIniSection(sb, "Audio",
("volume", settings.volume.ToString(CultureInfo.InvariantCulture)),
("muteDurationMinutes", settings.muteDurationMinutes.ToString(CultureInfo.InvariantCulture)));
AppendIniSection(sb, "SerialPort",
("serialPortName", settings.serialPortName ?? string.Empty),
("serialBaudRate", settings.serialBaudRate.ToString(CultureInfo.InvariantCulture)),
("enableSerialCommunication", settings.enableSerialCommunication.ToString()));
AppendIniSection(sb, "BFI",
("bfiLowThreshold", settings.bfiLowThreshold.ToString("F1", CultureInfo.InvariantCulture)),
("bfiHighThreshold", settings.bfiHighThreshold.ToString("F1", CultureInfo.InvariantCulture)),
("bfiAlarmPriority", settings.bfiAlarmPriority.ToString(CultureInfo.InvariantCulture)),
("enableBFIAlarm", settings.enableBFIAlarm.ToString()));
AppendIniSection(sb, "Time",
("useCustomSystemTime", settings.useCustomSystemTime.ToString()),
("customTimeOffsetTicks", settings.customTimeOffsetTicks.ToString(CultureInfo.InvariantCulture)),
("systemTime", settings.systemTime == DateTime.MinValue ? string.Empty : settings.systemTime.ToString("o", CultureInfo.InvariantCulture)));
AppendIniSection(sb, "Network",
("mode", settings.network.Mode.ToString()),
("ipv4", settings.network.IPv4 ?? string.Empty),
("mask", settings.network.Mask ?? string.Empty),
("gateway", settings.network.Gateway ?? string.Empty),
("dns1", settings.network.Dns1 ?? string.Empty),
("dns2", settings.network.Dns2 ?? string.Empty));
AppendIniSection(sb, "System",
("autoBackup", settings.autoBackup.ToString()),
("dataRetentionDays", settings.dataRetentionDays.ToString(CultureInfo.InvariantCulture)));
bool saved = WriteTextAtomically(_configIniPath, sb.ToString());
if (saved)
{
IniFile.ClearCache(_configIniPath);
}
return saved;
}
catch (Exception ex)
{
Debug.LogError($"保存到INI文件失败: {ex.Message}");
return false;
}
}
private SystemSettings LoadFromIniFile(string iniPath)
{
var settings = new SystemSettings();
try
{
IniFile.ClearCache(iniPath);
// 显示设置,使用公开的方法
var brightness = IniFile.ReadIniData("Display", "brightness", "50", iniPath);
if (float.TryParse(brightness, NumberStyles.Float, CultureInfo.InvariantCulture, out float b))
settings.brightness = b;
// 音频设置
var volume = IniFile.ReadIniData("Audio", "volume", "50", iniPath);
if (int.TryParse(volume, NumberStyles.Integer, CultureInfo.InvariantCulture, out int v))
settings.volume = v;
var muteDuration = IniFile.ReadIniData("Audio", "muteDurationMinutes", "3", iniPath);
if (int.TryParse(muteDuration, NumberStyles.Integer, CultureInfo.InvariantCulture, out int md))
settings.muteDurationMinutes = md;
var serialPortName = IniFile.ReadIniData("SerialPort", "serialPortName", settings.serialPortName, iniPath);
if (!string.IsNullOrWhiteSpace(serialPortName))
settings.serialPortName = serialPortName;
var serialBaudRate = IniFile.ReadIniData("SerialPort", "serialBaudRate", settings.serialBaudRate.ToString(), iniPath);
if (int.TryParse(serialBaudRate, NumberStyles.Integer, CultureInfo.InvariantCulture, out int sbr))
settings.serialBaudRate = sbr;
var enableSerial = IniFile.ReadIniData("SerialPort", "enableSerialCommunication", settings.enableSerialCommunication.ToString(), iniPath);
if (bool.TryParse(enableSerial, out bool esc))
settings.enableSerialCommunication = esc;
var bfiLowThreshold = IniFile.ReadIniData("BFI", "bfiLowThreshold", settings.bfiLowThreshold.ToString(CultureInfo.InvariantCulture), iniPath);
if (float.TryParse(bfiLowThreshold, NumberStyles.Float, CultureInfo.InvariantCulture, out float bfiLow))
settings.bfiLowThreshold = bfiLow;
var bfiHighThreshold = IniFile.ReadIniData("BFI", "bfiHighThreshold", settings.bfiHighThreshold.ToString(CultureInfo.InvariantCulture), iniPath);
if (float.TryParse(bfiHighThreshold, NumberStyles.Float, CultureInfo.InvariantCulture, out float bfiHigh))
settings.bfiHighThreshold = bfiHigh;
var bfiAlarmPriority = IniFile.ReadIniData("BFI", "bfiAlarmPriority", settings.bfiAlarmPriority.ToString(), iniPath);
if (int.TryParse(bfiAlarmPriority, NumberStyles.Integer, CultureInfo.InvariantCulture, out int priority))
settings.bfiAlarmPriority = priority;
var enableBfiAlarm = IniFile.ReadIniData("BFI", "enableBFIAlarm", settings.enableBFIAlarm.ToString(), iniPath);
if (bool.TryParse(enableBfiAlarm, out bool enableAlarm))
settings.enableBFIAlarm = enableAlarm;
var useCustomSystemTime = IniFile.ReadIniData("Time", "useCustomSystemTime", settings.useCustomSystemTime.ToString(), iniPath);
if (bool.TryParse(useCustomSystemTime, out bool customTime))
settings.useCustomSystemTime = customTime;
var customTimeOffsetTicks = IniFile.ReadIniData("Time", "customTimeOffsetTicks", settings.customTimeOffsetTicks.ToString(), iniPath);
if (long.TryParse(customTimeOffsetTicks, NumberStyles.Integer, CultureInfo.InvariantCulture, out long offsetTicks))
settings.customTimeOffsetTicks = offsetTicks;
var systemTime = IniFile.ReadIniData("Time", "systemTime", "", iniPath);
if (!string.IsNullOrWhiteSpace(systemTime) &&
DateTime.TryParse(systemTime, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out DateTime parsedTime))
{
settings.systemTime = parsedTime;
}
// 网络设置
var networkMode = IniFile.ReadIniData("Network", "mode", "Dhcp", iniPath);
if (Enum.TryParse<NetworkMode>(networkMode, out NetworkMode nm))
settings.network.Mode = nm;
settings.network.IPv4 = IniFile.ReadIniData("Network", "ipv4", "", iniPath);
settings.network.Mask = IniFile.ReadIniData("Network", "mask", "", iniPath);
settings.network.Gateway = IniFile.ReadIniData("Network", "gateway", "", iniPath);
settings.network.Dns1 = IniFile.ReadIniData("Network", "dns1", "", iniPath);
settings.network.Dns2 = IniFile.ReadIniData("Network", "dns2", "", iniPath);
// 系统设置
var autoBackup = IniFile.ReadIniData("System", "autoBackup", "true", iniPath);
if (bool.TryParse(autoBackup, out bool ab))
settings.autoBackup = ab;
var dataRetention = IniFile.ReadIniData("System", "dataRetentionDays", "30", iniPath);
if (int.TryParse(dataRetention, NumberStyles.Integer, CultureInfo.InvariantCulture, out int dr))
settings.dataRetentionDays = dr;
}
catch (Exception ex)
{
Debug.LogError($"从INI文件加载设置失败 ({iniPath}): {ex.Message}");
}
return settings;
}
private static void AppendIniSection(StringBuilder builder, string sectionName, params (string Key, string Value)[] values)
{
builder.Append('[').Append(sectionName).AppendLine("]");
foreach (var pair in values)
{
builder.Append(pair.Key).Append('=').AppendLine(pair.Value ?? string.Empty);
}
builder.AppendLine();
}
private void ApplyIniOverrides(SystemSettings settings, string iniPath)
{
if (settings == null || string.IsNullOrWhiteSpace(iniPath) || !File.Exists(iniPath))
{
return;
}
IniFile.ClearCache(iniPath);
const string missing = "__DCX_SETTING_MISSING__";
string brightness = IniFile.ReadIniData("Display", "brightness", missing, iniPath);
if (brightness != missing && float.TryParse(brightness, NumberStyles.Float, CultureInfo.InvariantCulture, out float b))
settings.brightness = b;
string volume = IniFile.ReadIniData("Audio", "volume", missing, iniPath);
if (volume != missing && int.TryParse(volume, out int v))
settings.volume = v;
string muteDuration = IniFile.ReadIniData("Audio", "muteDurationMinutes", missing, iniPath);
if (muteDuration != missing && int.TryParse(muteDuration, out int md))
settings.muteDurationMinutes = md;
string serialPortName = IniFile.ReadIniData("SerialPort", "serialPortName", missing, iniPath);
if (serialPortName != missing && !string.IsNullOrWhiteSpace(serialPortName))
settings.serialPortName = serialPortName;
string serialBaudRate = IniFile.ReadIniData("SerialPort", "serialBaudRate", missing, iniPath);
if (serialBaudRate != missing && int.TryParse(serialBaudRate, out int sbr))
settings.serialBaudRate = sbr;
string enableSerial = IniFile.ReadIniData("SerialPort", "enableSerialCommunication", missing, iniPath);
if (enableSerial != missing && bool.TryParse(enableSerial, out bool esc))
settings.enableSerialCommunication = esc;
string bfiLowThreshold = IniFile.ReadIniData("BFI", "bfiLowThreshold", missing, iniPath);
if (bfiLowThreshold != missing && float.TryParse(bfiLowThreshold, NumberStyles.Float, CultureInfo.InvariantCulture, out float bfiLow))
settings.bfiLowThreshold = bfiLow;
string bfiHighThreshold = IniFile.ReadIniData("BFI", "bfiHighThreshold", missing, iniPath);
if (bfiHighThreshold != missing && float.TryParse(bfiHighThreshold, NumberStyles.Float, CultureInfo.InvariantCulture, out float bfiHigh))
settings.bfiHighThreshold = bfiHigh;
string bfiAlarmPriority = IniFile.ReadIniData("BFI", "bfiAlarmPriority", missing, iniPath);
if (bfiAlarmPriority != missing && int.TryParse(bfiAlarmPriority, out int priority))
settings.bfiAlarmPriority = priority;
string enableBfiAlarm = IniFile.ReadIniData("BFI", "enableBFIAlarm", missing, iniPath);
if (enableBfiAlarm != missing && bool.TryParse(enableBfiAlarm, out bool enableAlarm))
settings.enableBFIAlarm = enableAlarm;
string useCustomSystemTime = IniFile.ReadIniData("Time", "useCustomSystemTime", missing, iniPath);
if (useCustomSystemTime != missing && bool.TryParse(useCustomSystemTime, out bool customTime))
settings.useCustomSystemTime = customTime;
string customTimeOffsetTicks = IniFile.ReadIniData("Time", "customTimeOffsetTicks", missing, iniPath);
if (customTimeOffsetTicks != missing && long.TryParse(customTimeOffsetTicks, out long offsetTicks))
settings.customTimeOffsetTicks = offsetTicks;
string systemTime = IniFile.ReadIniData("Time", "systemTime", missing, iniPath);
if (systemTime != missing && !string.IsNullOrWhiteSpace(systemTime) &&
DateTime.TryParse(systemTime, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out DateTime parsedTime))
{
settings.systemTime = parsedTime;
}
string networkMode = IniFile.ReadIniData("Network", "mode", missing, iniPath);
if (networkMode != missing && Enum.TryParse<NetworkMode>(networkMode, out NetworkMode nm))
settings.network.Mode = nm;
string ipv4 = IniFile.ReadIniData("Network", "ipv4", missing, iniPath);
if (ipv4 != missing)
settings.network.IPv4 = ipv4;
string mask = IniFile.ReadIniData("Network", "mask", missing, iniPath);
if (mask != missing)
settings.network.Mask = mask;
string gateway = IniFile.ReadIniData("Network", "gateway", missing, iniPath);
if (gateway != missing)
settings.network.Gateway = gateway;
string dns1 = IniFile.ReadIniData("Network", "dns1", missing, iniPath);
if (dns1 != missing)
settings.network.Dns1 = dns1;
string dns2 = IniFile.ReadIniData("Network", "dns2", missing, iniPath);
if (dns2 != missing)
settings.network.Dns2 = dns2;
string autoBackup = IniFile.ReadIniData("System", "autoBackup", missing, iniPath);
if (autoBackup != missing && bool.TryParse(autoBackup, out bool ab))
settings.autoBackup = ab;
string dataRetention = IniFile.ReadIniData("System", "dataRetentionDays", missing, iniPath);
if (dataRetention != missing && int.TryParse(dataRetention, out int dr))
settings.dataRetentionDays = dr;
}
private bool WriteTextAtomically(string filePath, string content)
{
var tempPath = string.IsNullOrWhiteSpace(filePath) ? null : filePath + ".tmp";
try
{
var directory = Path.GetDirectoryName(filePath);
if (!string.IsNullOrWhiteSpace(directory))
{
Directory.CreateDirectory(directory);
}
var backupPath = filePath + ".bak";
byte[] bytes = new UTF8Encoding(false).GetBytes(content ?? string.Empty);
DeleteFileIfExists(tempPath);
WriteBytesAndFlush(tempPath, bytes);
if (File.Exists(filePath))
{
try
{
CopyFileSynced(filePath, backupPath);
}
catch (Exception ex)
{
Debug.LogWarning($"备份旧配置文件失败,将继续写入新配置: {filePath}, {ex.Message}");
}
DeleteFileIfExists(filePath);
}
File.Move(tempPath, filePath);
var fileInfo = new FileInfo(filePath);
if (!fileInfo.Exists || fileInfo.Length != bytes.Length)
{
throw new IOException($"写入校验失败,期望 {bytes.Length} 字节,实际 {(fileInfo.Exists ? fileInfo.Length : 0)} 字节");
}
return true;
}
catch (Exception ex)
{
Debug.LogError($"原子写入失败: {filePath}, {ex.Message}");
return false;
}
finally
{
if (!string.IsNullOrWhiteSpace(tempPath))
{
DeleteFileIfExists(tempPath);
}
}
}
private void TryCopyIniToPersistent()
{
try
{
if (File.Exists(_configIniPath) || File.Exists(_settingsPath))
{
return;
}
if (File.Exists(_streamingConfigIniPath))
{
File.Copy(_streamingConfigIniPath, _configIniPath, true);
}
}
catch (Exception ex)
{
Debug.LogWarning($"复制默认INI到持久化目录失败: {ex.Message}");
}
}
private bool TryLoadJsonSettings(out SystemSettings settings, out string sourcePath)
{
settings = null;
sourcePath = null;
string[] candidates =
{
_settingsPath,
_settingsPath + ".bak",
_settingsPath + ".tmp"
};
foreach (string candidate in GetExistingPathsNewestFirst(candidates))
{
if (TryLoadJsonSettings(candidate, out settings))
{
sourcePath = candidate;
return true;
}
}
return false;
}
private IEnumerable<string> GetExistingPathsNewestFirst(IEnumerable<string> paths)
{
var existingPaths = new List<string>();
foreach (string path in paths)
{
if (!string.IsNullOrWhiteSpace(path) && File.Exists(path))
{
existingPaths.Add(path);
}
}
existingPaths.Sort((left, right) => GetLastWriteTimeUtcSafe(right).CompareTo(GetLastWriteTimeUtcSafe(left)));
return existingPaths;
}
private bool TryLoadJsonSettings(string path, out SystemSettings settings)
{
settings = null;
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
{
return false;
}
try
{
var json = File.ReadAllText(path, Encoding.UTF8);
if (string.IsNullOrWhiteSpace(json))
{
throw new InvalidDataException("文件为空");
}
settings = JsonMapper.ToObject<SystemSettings>(json);
if (settings == null)
{
throw new InvalidDataException("反序列化结果为空");
}
Debug.Log($"从JSON配置加载设置成功: {path}");
return true;
}
catch (Exception ex)
{
Debug.LogWarning($"从JSON配置加载设置失败: {path}, {ex.Message}");
settings = null;
return false;
}
}
private void ApplyNewestIniOverrides(SystemSettings settings, string jsonSourcePath)
{
string iniPath = GetNewestExistingPath(_configIniPath, _configIniPath + ".bak");
if (iniPath == null)
{
return;
}
if (GetLastWriteTimeUtcSafe(iniPath) >= GetLastWriteTimeUtcSafe(jsonSourcePath))
{
ApplyIniOverrides(settings, iniPath);
Debug.Log($"已合并INI覆盖项: {iniPath}");
}
}
private bool TryLoadIniSettings(string path, string sourceName, out SystemSettings settings)
{
settings = null;
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
{
return false;
}
settings = LoadFromIniFile(path);
Debug.Log($"从{sourceName}加载设置成功: {path}");
return settings != null;
}
private string GetNewestExistingPath(string firstPath, string secondPath)
{
bool firstExists = !string.IsNullOrWhiteSpace(firstPath) && File.Exists(firstPath);
bool secondExists = !string.IsNullOrWhiteSpace(secondPath) && File.Exists(secondPath);
if (firstExists && secondExists)
{
return GetLastWriteTimeUtcSafe(secondPath) > GetLastWriteTimeUtcSafe(firstPath) ? secondPath : firstPath;
}
if (firstExists)
{
return firstPath;
}
return secondExists ? secondPath : null;
}
private DateTime GetLastWriteTimeUtcSafe(string path)
{
try
{
return !string.IsNullOrWhiteSpace(path) && File.Exists(path)
? File.GetLastWriteTimeUtc(path)
: DateTime.MinValue;
}
catch
{
return DateTime.MinValue;
}
}
private void WriteBytesAndFlush(string filePath, byte[] bytes)
{
using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read, 4096))
{
stream.Write(bytes, 0, bytes.Length);
FlushFileStream(stream);
}
}
private void CopyFileSynced(string sourcePath, string targetPath)
{
if (string.IsNullOrWhiteSpace(sourcePath) || !File.Exists(sourcePath))
{
return;
}
byte[] bytes = File.ReadAllBytes(sourcePath);
WriteBytesAndFlush(targetPath, bytes);
}
private void FlushFileStream(FileStream stream)
{
try
{
stream.Flush(true);
}
catch
{
stream.Flush();
}
}
private void DeleteFileIfExists(string path)
{
try
{
if (!string.IsNullOrWhiteSpace(path) && File.Exists(path))
{
File.Delete(path);
}
}
catch (Exception ex)
{
Debug.LogWarning($"删除文件失败: {path}, {ex.Message}");
}
}
private object GetExportData(ExportDataType dataType)
{
switch (dataType)
{
case ExportDataType.Settings:
return LoadSettings();
case ExportDataType.UserData:
// 导出所有用户数据
return "用户数据导出功能待实现";
case ExportDataType.AlarmRecords:
// 导出报警记录
var records = DCSAlarmManager.Instance?.GetAlarmRecords(1000);
return records != null ? records : "无报警记录";
case ExportDataType.PatientInfo:
// 导出病人信息
var patient = ServiceLocator.Get<IPatientInfoService>()?.GetCurrentPatient();
return patient != null ? patient : "无病人信息";
case ExportDataType.SystemLogs:
return "系统日志导出功能待实现";
case ExportDataType.All:
return new
{
Settings = LoadSettings(),
AppConfig = LoadAppConfig(),
SystemInfo = new
{
UnityVersion = Application.unityVersion,
Platform = Application.platform.ToString(),
SystemTime = DateTime.Now
}
};
default:
return null;
}
}
private void EnsureDirectoryExists(string path)
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
}
}