From e443805972f55049a0fb6464d3ddb12d5b9208b6 Mon Sep 17 00:00:00 2001 From: zpc Date: Tue, 6 Jan 2026 00:42:25 +0800 Subject: [PATCH] 333 --- client/WorkCameraExport/Forms/LoginForm.cs | 8 +- client/WorkCameraExport/Forms/MainForm.cs | 2 +- .../WorkCameraExport/Forms/MonthReportForm.cs | 61 +++---------- .../WorkCameraExport/Forms/WorkRecordForm.cs | 37 ++------ client/WorkCameraExport/Models/ApiModels.cs | 33 ++++++- client/WorkCameraExport/Models/AppConfig.cs | 9 +- client/WorkCameraExport/Models/AppSettings.cs | 19 ++-- client/WorkCameraExport/Program.cs | 31 +++---- .../WorkCameraExport/Services/ApiService.cs | 30 ++++++- .../Services/ConfigService.cs | 68 +++++---------- .../Services/ExportService.cs | 2 +- .../Services/LoginStateManager.cs | 40 ++++----- .../WorkCameraExport/Services/PathService.cs | 86 +++++++++++++++++++ 13 files changed, 231 insertions(+), 195 deletions(-) create mode 100644 client/WorkCameraExport/Services/PathService.cs diff --git a/client/WorkCameraExport/Forms/LoginForm.cs b/client/WorkCameraExport/Forms/LoginForm.cs index eca585e..7c5b497 100644 --- a/client/WorkCameraExport/Forms/LoginForm.cs +++ b/client/WorkCameraExport/Forms/LoginForm.cs @@ -80,12 +80,8 @@ namespace WorkCameraExport.Forms _apiService.SetBaseUrl(_settings.ServerUrl); _apiService.SetToken(_settings.SavedToken); - // 验证 Token 是否有效(通过调用一个简单的 API) - var (success, _, _) = await _apiService.GetExportCountAsync(new WorkRecordExportQuery - { - PageNum = 1, - PageSize = 1 - }); + // 验证 Token 是否有效(通过获取当前用户信息) + var (success, _, _) = await _apiService.GetCurrentUserAsync(); if (success) { diff --git a/client/WorkCameraExport/Forms/MainForm.cs b/client/WorkCameraExport/Forms/MainForm.cs index 102c937..102452f 100644 --- a/client/WorkCameraExport/Forms/MainForm.cs +++ b/client/WorkCameraExport/Forms/MainForm.cs @@ -42,7 +42,7 @@ namespace WorkCameraExport.Forms } else { - txtExportPath.Text = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); + txtExportPath.Text = PathService.ExportDirectory; } UpdateExportButtonState(); diff --git a/client/WorkCameraExport/Forms/MonthReportForm.cs b/client/WorkCameraExport/Forms/MonthReportForm.cs index 0754e03..45f138f 100644 --- a/client/WorkCameraExport/Forms/MonthReportForm.cs +++ b/client/WorkCameraExport/Forms/MonthReportForm.cs @@ -194,10 +194,11 @@ namespace WorkCameraExport.Forms return; } - var outputPath = GetExcelExportPath(); - if (string.IsNullOrEmpty(outputPath)) return; + // 直接生成导出路径,不使用文件对话框 + var fileName = $"月报表_{dtpMonth.Value:yyyyMM}_{DateTime.Now:yyyyMMdd_HHmmss}.xlsx"; + var outputPath = Path.Combine(PathService.ExportDirectory, fileName); - _logService?.Info($"开始导出月报表 Excel,共 {_currentData.Count} 条记录"); + _logService?.Info($"开始导出月报表 Excel,共 {_currentData.Count} 条记录,路径: {outputPath}"); SetLoadingState(true); lblStatusBar.Text = "正在导出 Excel..."; @@ -221,7 +222,7 @@ namespace WorkCameraExport.Forms _logService?.Info($"导出完成: {outputPath}"); var result = MessageBox.Show( - "导出完成!是否打开文件所在目录?", + $"导出完成!\n文件已保存到:{outputPath}\n\n是否打开文件所在目录?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question); @@ -242,27 +243,6 @@ namespace WorkCameraExport.Forms } } - /// - /// 获取 Excel 导出路径 - /// - private string? GetExcelExportPath() - { - using var dialog = new SaveFileDialog - { - Title = "选择导出位置", - Filter = "Excel 文件 (*.xlsx)|*.xlsx", - FileName = $"月报表_{dtpMonth.Value:yyyyMM}_{DateTime.Now:yyyyMMdd_HHmmss}.xlsx", - InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) - }; - - if (dialog.ShowDialog() == DialogResult.OK) - { - return dialog.FileName; - } - - return null; - } - #endregion #region 下载照片 ZIP 功能 @@ -281,8 +261,10 @@ namespace WorkCameraExport.Forms public async Task DownloadPhotosZipAsync() { var yearMonth = dtpMonth.Value.ToString("yyyy-MM"); - var outputPath = GetZipExportPath(yearMonth); - if (string.IsNullOrEmpty(outputPath)) return; + + // 直接生成导出路径,不使用文件对话框 + var fileName = $"工作照片_{yearMonth.Replace("-", "")}_{DateTime.Now:yyyyMMdd_HHmmss}.zip"; + var outputPath = Path.Combine(PathService.ExportDirectory, fileName); if (_isExporting) { @@ -290,7 +272,7 @@ namespace WorkCameraExport.Forms return; } - _logService?.Info($"开始下载照片 ZIP,月份: {yearMonth}"); + _logService?.Info($"开始下载照片 ZIP,月份: {yearMonth},路径: {outputPath}"); _isExporting = true; _exportCts = new CancellationTokenSource(); @@ -318,7 +300,7 @@ namespace WorkCameraExport.Forms _logService?.Info($"下载完成: {outputPath}"); var result = MessageBox.Show( - "下载完成!是否打开文件所在目录?", + $"下载完成!\n文件已保存到:{outputPath}\n\n是否打开文件所在目录?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question); @@ -349,27 +331,6 @@ namespace WorkCameraExport.Forms } } - /// - /// 获取 ZIP 导出路径 - /// - private string? GetZipExportPath(string yearMonth) - { - using var dialog = new SaveFileDialog - { - Title = "选择保存位置", - Filter = "ZIP 文件 (*.zip)|*.zip", - FileName = $"工作照片_{yearMonth.Replace("-", "")}_{DateTime.Now:yyyyMMdd_HHmmss}.zip", - InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) - }; - - if (dialog.ShowDialog() == DialogResult.OK) - { - return dialog.FileName; - } - - return null; - } - /// /// 更新下载进度 /// diff --git a/client/WorkCameraExport/Forms/WorkRecordForm.cs b/client/WorkCameraExport/Forms/WorkRecordForm.cs index 3186e7f..7d016af 100644 --- a/client/WorkCameraExport/Forms/WorkRecordForm.cs +++ b/client/WorkCameraExport/Forms/WorkRecordForm.cs @@ -687,10 +687,11 @@ namespace WorkCameraExport.Forms return; } - var outputPath = GetExportPath(); - if (string.IsNullOrEmpty(outputPath)) return; + // 直接生成导出路径,不使用文件对话框 + var fileName = $"工作记录导出_{DateTime.Now:yyyyMMdd_HHmmss}.xlsx"; + var outputPath = Path.Combine(PathService.ExportDirectory, fileName); - _logService?.Info($"开始导出全部数据,共 {_totalRecords} 条记录"); + _logService?.Info($"开始导出全部数据,共 {_totalRecords} 条记录,路径: {outputPath}"); await DoExportAsync(outputPath, null); } @@ -701,34 +702,14 @@ namespace WorkCameraExport.Forms { if (ids.Count == 0) return; - var outputPath = GetExportPath(); - if (string.IsNullOrEmpty(outputPath)) return; + // 直接生成导出路径,不使用文件对话框 + var fileName = $"工作记录导出_选中{ids.Count}条_{DateTime.Now:yyyyMMdd_HHmmss}.xlsx"; + var outputPath = Path.Combine(PathService.ExportDirectory, fileName); - _logService?.Info($"开始导出选中数据,共 {ids.Count} 条记录"); + _logService?.Info($"开始导出选中数据,共 {ids.Count} 条记录,路径: {outputPath}"); await DoExportAsync(outputPath, ids); } - /// - /// 获取导出路径 - /// - private string? GetExportPath() - { - using var dialog = new SaveFileDialog - { - Title = "选择导出位置", - Filter = "Excel 文件 (*.xlsx)|*.xlsx", - FileName = $"工作记录导出_{DateTime.Now:yyyyMMdd_HHmmss}.xlsx", - InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) - }; - - if (dialog.ShowDialog() == DialogResult.OK) - { - return dialog.FileName; - } - - return null; - } - /// /// 执行导出 /// @@ -775,7 +756,7 @@ namespace WorkCameraExport.Forms _logService?.Info($"导出完成: {outputPath}"); var result = MessageBox.Show( - "导出完成!是否打开文件所在目录?", + $"导出完成!\n文件已保存到:{outputPath}\n\n是否打开文件所在目录?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question); diff --git a/client/WorkCameraExport/Models/ApiModels.cs b/client/WorkCameraExport/Models/ApiModels.cs index aa2314d..7baddc5 100644 --- a/client/WorkCameraExport/Models/ApiModels.cs +++ b/client/WorkCameraExport/Models/ApiModels.cs @@ -89,6 +89,30 @@ namespace WorkCameraExport.Models public string NickName { get; set; } = ""; } + /// + /// 用户信息响应(/system/user/profile 接口) + /// + public class UserProfileResponse + { + public UserProfileDto? User { get; set; } + public List? Roles { get; set; } + public string? PostGroup { get; set; } + } + + /// + /// 用户详细信息 + /// + public class UserProfileDto + { + public long UserId { get; set; } + public string? UserName { get; set; } + public string? NickName { get; set; } + public string? DeptName { get; set; } + public string? Email { get; set; } + public string? Phonenumber { get; set; } + public string? Avatar { get; set; } + } + /// /// 工作记录导出查询请求 /// @@ -116,14 +140,17 @@ namespace WorkCameraExport.Models public string Address { get; set; } = ""; public string Content { get; set; } = ""; public string StatusName { get; set; } = ""; - public List Workers { get; set; } = new(); + /// + /// 施工人员名称列表(与服务端保持一致,为字符串列表) + /// + public List Workers { get; set; } = new(); public List Images { get; set; } = new(); public DateTime? CreateTime { get; set; } public DateTime? UpdateTime { get; set; } /// - /// 获取工作人员名称列表(便捷属性) + /// 获取工作人员名称列表(便捷属性,保持向后兼容) /// - public List WorkerNames => Workers?.Select(w => w.WorkerName).ToList() ?? new List(); + public List WorkerNames => Workers ?? new List(); } } diff --git a/client/WorkCameraExport/Models/AppConfig.cs b/client/WorkCameraExport/Models/AppConfig.cs index d553146..6efb20a 100644 --- a/client/WorkCameraExport/Models/AppConfig.cs +++ b/client/WorkCameraExport/Models/AppConfig.cs @@ -1,3 +1,5 @@ +using WorkCameraExport.Services; + namespace WorkCameraExport.Models { /// @@ -30,18 +32,15 @@ namespace WorkCameraExport.Models /// public void Validate() { - // 并发数限制在 1-10 if (ImageDownloadConcurrency < 1) ImageDownloadConcurrency = 1; if (ImageDownloadConcurrency > 10) ImageDownloadConcurrency = 10; - // 压缩质量限制在 30-100 if (ImageCompressQuality < 30) ImageCompressQuality = 30; if (ImageCompressQuality > 100) ImageCompressQuality = 100; - // 默认保存路径为空时使用桌面 if (string.IsNullOrWhiteSpace(DefaultSavePath)) { - DefaultSavePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); + DefaultSavePath = PathService.ExportDirectory; } } @@ -52,7 +51,7 @@ namespace WorkCameraExport.Models { return new AppConfig { - DefaultSavePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop), + DefaultSavePath = PathService.ExportDirectory, ImageDownloadConcurrency = 5, ImageCompressQuality = 50, AutoCleanTempFiles = true diff --git a/client/WorkCameraExport/Models/AppSettings.cs b/client/WorkCameraExport/Models/AppSettings.cs index 1a79973..c9a5f40 100644 --- a/client/WorkCameraExport/Models/AppSettings.cs +++ b/client/WorkCameraExport/Models/AppSettings.cs @@ -1,4 +1,5 @@ using System.Text.Json; +using WorkCameraExport.Services; namespace WorkCameraExport.Models { @@ -7,11 +8,6 @@ namespace WorkCameraExport.Models /// public class AppSettings { - private static readonly string SettingsPath = Path.Combine( - Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), - "WorkCameraExport", - "settings.json"); - /// /// 服务器地址 /// @@ -49,9 +45,10 @@ namespace WorkCameraExport.Models { try { - if (File.Exists(SettingsPath)) + var path = PathService.SettingsFile; + if (File.Exists(path)) { - var json = File.ReadAllText(SettingsPath); + var json = File.ReadAllText(path); return JsonSerializer.Deserialize(json) ?? new AppSettings(); } } @@ -69,17 +66,11 @@ namespace WorkCameraExport.Models { try { - var directory = Path.GetDirectoryName(SettingsPath); - if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory)) - { - Directory.CreateDirectory(directory); - } - var json = JsonSerializer.Serialize(this, new JsonSerializerOptions { WriteIndented = true }); - File.WriteAllText(SettingsPath, json); + File.WriteAllText(PathService.SettingsFile, json); } catch { diff --git a/client/WorkCameraExport/Program.cs b/client/WorkCameraExport/Program.cs index a201dcb..c445021 100644 --- a/client/WorkCameraExport/Program.cs +++ b/client/WorkCameraExport/Program.cs @@ -13,7 +13,7 @@ static class Program /// The main entry point for the application. /// [STAThread] - static void Main() + static async Task Main() { // To customize application configuration such as set high DPI settings or default font, // see https://aka.ms/applicationconfiguration. @@ -37,26 +37,23 @@ static class Program // 主循环:处理登录失效后重新登录 while (true) { - // 显示登录窗体 - using var loginForm = new LoginForm(apiService, configService); - if (loginForm.ShowDialog() != DialogResult.OK) + // 先尝试自动登录 + var autoLoginSuccess = await loginStateManager.TryAutoLoginAsync(); + + if (!autoLoginSuccess) { - // 用户取消登录,退出应用 - return; - } - - // 登录成功,保存登录状态(无论是自动登录还是手动登录) - if (loginForm.Token != null) - { - var settings = Models.AppSettings.Load(); - if (loginForm.IsAutoLogin) + // 自动登录失败,显示登录窗体 + using var loginForm = new LoginForm(apiService, configService); + if (loginForm.ShowDialog() != DialogResult.OK) { - // 自动登录成功,启动 Token 检查定时器(不重新保存凭证) - loginStateManager.OnAutoLoginSuccess(settings.Username); + // 用户取消登录,退出应用 + return; } - else + + // 手动登录成功,保存登录状态 + if (loginForm.Token != null) { - // 手动登录成功,保存凭证并启动定时器 + var settings = Models.AppSettings.Load(); loginStateManager.OnLoginSuccess( settings.ServerUrl, settings.Username, diff --git a/client/WorkCameraExport/Services/ApiService.cs b/client/WorkCameraExport/Services/ApiService.cs index 536aa3b..8a72f05 100644 --- a/client/WorkCameraExport/Services/ApiService.cs +++ b/client/WorkCameraExport/Services/ApiService.cs @@ -248,6 +248,34 @@ namespace WorkCameraExport.Services _refreshToken = ""; } + /// + /// 获取当前用户信息(用于验证 Token 有效性) + /// + public async Task<(bool Success, string Message, UserInfo? Data)> GetCurrentUserAsync() + { + try + { + var response = await GetAsync("/system/user/profile"); + + if (response.IsSuccess && response.Data?.User != null) + { + return (true, "获取成功", new UserInfo + { + UserId = response.Data.User.UserId, + UserName = response.Data.User.UserName ?? "", + NickName = response.Data.User.NickName ?? "" + }); + } + + return (false, response.Msg ?? "获取用户信息失败", null); + } + catch (Exception ex) + { + _logService?.Error($"获取用户信息异常: {ex.Message}", ex); + return (false, $"获取用户信息异常: {ex.Message}", null); + } + } + #endregion #region 统计接口 @@ -425,7 +453,7 @@ namespace WorkCameraExport.Services await EnsureTokenValidAsync(); var queryParams = BuildQueryString(query); var response = await ExecuteWithRetryAsync(() => - GetAsync>($"/api/workrecord/monthlyReport?{queryParams}")); + GetAsync>($"/business/CamWorkers/list?{queryParams}")); if (response.IsSuccess && response.Data != null) { diff --git a/client/WorkCameraExport/Services/ConfigService.cs b/client/WorkCameraExport/Services/ConfigService.cs index 95b1909..146f3a8 100644 --- a/client/WorkCameraExport/Services/ConfigService.cs +++ b/client/WorkCameraExport/Services/ConfigService.cs @@ -11,12 +11,6 @@ namespace WorkCameraExport.Services /// public class ConfigService : IConfigService { - private readonly string _appDataPath; - private readonly string _configFilePath; - private readonly string _credentialsFilePath; - private readonly string _tempPath; - private readonly string _logPath; - // 用于加密凭证的密钥(AES-256 需要 32 字节密钥,16 字节 IV) private static readonly byte[] EncryptionKey = Encoding.UTF8.GetBytes("WorkCameraExport2025SecretKey!!!"); // 32 bytes private static readonly byte[] EncryptionIV = Encoding.UTF8.GetBytes("WCE2025InitVect!"); // 16 bytes @@ -29,46 +23,31 @@ namespace WorkCameraExport.Services public ConfigService() { - _appDataPath = Path.Combine( - Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), - "WorkCameraExport"); - _configFilePath = Path.Combine(_appDataPath, "config.json"); - _credentialsFilePath = Path.Combine(_appDataPath, "credentials.dat"); - _tempPath = Path.Combine(_appDataPath, "temp"); - _logPath = Path.Combine(_appDataPath, "logs"); - - EnsureDirectoriesExist(); } /// - /// 用于测试的构造函数,允许指定自定义路径 + /// 用于测试的构造函数 /// - public ConfigService(string appDataPath) + public ConfigService(string _) { - _appDataPath = appDataPath; - _configFilePath = Path.Combine(_appDataPath, "config.json"); - _credentialsFilePath = Path.Combine(_appDataPath, "credentials.dat"); - _tempPath = Path.Combine(_appDataPath, "temp"); - _logPath = Path.Combine(_appDataPath, "logs"); - - EnsureDirectoriesExist(); } #region IConfigService 实现 - public string AppDataPath => _appDataPath; - public string TempPath => _tempPath; - public string LogPath => _logPath; + public string AppDataPath => PathService.BaseDirectory; + public string TempPath => PathService.TempDirectory; + public string LogPath => PathService.LogDirectory; - public bool HasSavedCredentials => File.Exists(_credentialsFilePath); + public bool HasSavedCredentials => File.Exists(PathService.CredentialsFile); public AppConfig LoadConfig() { try { - if (File.Exists(_configFilePath)) + var path = PathService.ConfigFile; + if (File.Exists(path)) { - var json = File.ReadAllText(_configFilePath); + var json = File.ReadAllText(path); var config = JsonSerializer.Deserialize(json, JsonOptions); if (config != null) { @@ -89,7 +68,7 @@ namespace WorkCameraExport.Services { config.Validate(); var json = JsonSerializer.Serialize(config, JsonOptions); - File.WriteAllText(_configFilePath, json); + File.WriteAllText(PathService.ConfigFile, json); } public void SaveCredentials(string serverUrl, string token, string username) @@ -104,17 +83,18 @@ namespace WorkCameraExport.Services var json = JsonSerializer.Serialize(credentials, JsonOptions); var encrypted = Encrypt(json); - File.WriteAllBytes(_credentialsFilePath, encrypted); + File.WriteAllBytes(PathService.CredentialsFile, encrypted); } public (string ServerUrl, string Token, string Username)? LoadCredentials() { try { - if (!File.Exists(_credentialsFilePath)) + var path = PathService.CredentialsFile; + if (!File.Exists(path)) return null; - var encrypted = File.ReadAllBytes(_credentialsFilePath); + var encrypted = File.ReadAllBytes(path); var json = Decrypt(encrypted); var credentials = JsonSerializer.Deserialize(json, JsonOptions); @@ -138,9 +118,10 @@ namespace WorkCameraExport.Services { try { - if (File.Exists(_credentialsFilePath)) + var path = PathService.CredentialsFile; + if (File.Exists(path)) { - File.Delete(_credentialsFilePath); + File.Delete(path); } } catch @@ -153,9 +134,10 @@ namespace WorkCameraExport.Services { try { - if (Directory.Exists(_tempPath)) + var tempPath = PathService.TempDirectory; + if (Directory.Exists(tempPath)) { - var directory = new DirectoryInfo(_tempPath); + var directory = new DirectoryInfo(tempPath); foreach (var file in directory.GetFiles()) { try { file.Delete(); } catch { } @@ -176,16 +158,6 @@ namespace WorkCameraExport.Services #region 私有方法 - private void EnsureDirectoriesExist() - { - if (!Directory.Exists(_appDataPath)) - Directory.CreateDirectory(_appDataPath); - if (!Directory.Exists(_tempPath)) - Directory.CreateDirectory(_tempPath); - if (!Directory.Exists(_logPath)) - Directory.CreateDirectory(_logPath); - } - private static byte[] Encrypt(string plainText) { using var aes = Aes.Create(); diff --git a/client/WorkCameraExport/Services/ExportService.cs b/client/WorkCameraExport/Services/ExportService.cs index 0d9462b..083c953 100644 --- a/client/WorkCameraExport/Services/ExportService.cs +++ b/client/WorkCameraExport/Services/ExportService.cs @@ -312,7 +312,7 @@ namespace WorkCameraExport.Services Address = dto.Address, Content = dto.Content, StatusName = dto.StatusName, - Workers = dto.Workers, // 保持 List 类型 + Workers = dto.Workers?.Select(w => w.WorkerName).ToList() ?? new List(), Images = dto.Images.Select(i => i.Url).ToList(), CreateTime = dto.CreateTime, UpdateTime = dto.UpdateTime diff --git a/client/WorkCameraExport/Services/LoginStateManager.cs b/client/WorkCameraExport/Services/LoginStateManager.cs index 6a3e25c..d7605f2 100644 --- a/client/WorkCameraExport/Services/LoginStateManager.cs +++ b/client/WorkCameraExport/Services/LoginStateManager.cs @@ -57,18 +57,23 @@ namespace WorkCameraExport.Services /// 是否自动登录成功 public async Task TryAutoLoginAsync() { + // 每次尝试自动登录时重新加载设置,确保获取最新的保存信息 + var settings = AppSettings.Load(); + + _logService?.Info($"[自动登录] 检查设置: RememberMe={settings.RememberMe}, ServerUrl={settings.ServerUrl}, SavedToken长度={settings.SavedToken?.Length ?? 0}"); + // 首先检查 AppSettings 中的保存信息 - if (!_settings.RememberMe || - string.IsNullOrEmpty(_settings.ServerUrl) || - string.IsNullOrEmpty(_settings.SavedToken)) + if (!settings.RememberMe || + string.IsNullOrEmpty(settings.ServerUrl) || + string.IsNullOrEmpty(settings.SavedToken)) { _logService?.Info("未找到保存的登录信息,跳过自动登录"); return false; } // 检查 Token 是否已过期 - if (_settings.TokenExpireTime.HasValue && - _settings.TokenExpireTime.Value <= DateTime.Now) + if (settings.TokenExpireTime.HasValue && + settings.TokenExpireTime.Value <= DateTime.Now) { _logService?.Info("保存的 Token 已过期,清除登录信息"); ClearLoginState(); @@ -79,25 +84,21 @@ namespace WorkCameraExport.Services try { - _apiService.SetBaseUrl(_settings.ServerUrl); - _apiService.SetToken(_settings.SavedToken); + _apiService.SetBaseUrl(settings.ServerUrl); + _apiService.SetToken(settings.SavedToken); - // 验证 Token 是否有效 - var (success, _, _) = await _apiService.GetExportCountAsync(new WorkRecordExportQuery - { - PageNum = 1, - PageSize = 1 - }); + // 验证 Token 是否有效(通过获取当前用户信息) + var (success, message, userInfo) = await _apiService.GetCurrentUserAsync(); - if (success) + if (success && userInfo != null) { - CurrentUsername = _settings.Username; + CurrentUsername = userInfo.UserName ?? settings.Username; StartTokenCheckTimer(); _logService?.Info($"自动登录成功,用户: {CurrentUsername}"); return true; } - _logService?.Warn("Token 验证失败,清除登录信息"); + _logService?.Warn($"Token 验证失败: {message},清除登录信息"); ClearLoginState(); return false; } @@ -181,11 +182,8 @@ namespace WorkCameraExport.Services try { - var (success, _, _) = await _apiService.GetExportCountAsync(new WorkRecordExportQuery - { - PageNum = 1, - PageSize = 1 - }); + // 通过获取当前用户信息验证 Token 有效性 + var (success, _, _) = await _apiService.GetCurrentUserAsync(); if (!success) { diff --git a/client/WorkCameraExport/Services/PathService.cs b/client/WorkCameraExport/Services/PathService.cs new file mode 100644 index 0000000..b25c51b --- /dev/null +++ b/client/WorkCameraExport/Services/PathService.cs @@ -0,0 +1,86 @@ +namespace WorkCameraExport.Services +{ + /// + /// 路径服务 - 统一管理所有文件路径,全部基于 exe 所在目录 + /// + public static class PathService + { + private static readonly string _baseDir; + + static PathService() + { + // 使用 AppContext.BaseDirectory,兼容单文件发布 + _baseDir = AppContext.BaseDirectory.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); + } + + /// + /// 获取基础目录(exe 所在目录) + /// + public static string BaseDirectory => _baseDir; + + /// + /// 获取设置文件路径 + /// + public static string SettingsFile => Path.Combine(_baseDir, "settings.json"); + + /// + /// 获取配置文件路径 + /// + public static string ConfigFile => Path.Combine(_baseDir, "config.json"); + + /// + /// 获取凭证文件路径 + /// + public static string CredentialsFile => Path.Combine(_baseDir, "credentials.dat"); + + /// + /// 获取日志目录 + /// + public static string LogDirectory + { + get + { + var dir = Path.Combine(_baseDir, "logs"); + EnsureDirectoryExists(dir); + return dir; + } + } + + /// + /// 获取临时文件目录 + /// + public static string TempDirectory + { + get + { + var dir = Path.Combine(_baseDir, "temp"); + EnsureDirectoryExists(dir); + return dir; + } + } + + /// + /// 获取导出目录 + /// + public static string ExportDirectory + { + get + { + var dir = Path.Combine(_baseDir, "Export"); + EnsureDirectoryExists(dir); + return dir; + } + } + + /// + /// 确保目录存在 + /// + private static void EnsureDirectoryExists(string path) + { + if (!Directory.Exists(path)) + { + Directory.CreateDirectory(path); + } + } + } +}