From ade24d7a9bd9cb7cbfac34c2cdd16611b385aadd Mon Sep 17 00:00:00 2001 From: "821644@qq.com" <821644@qq.com> Date: Mon, 13 Apr 2026 03:04:01 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BC=96=E8=AF=91=E9=94=99?= =?UTF-8?q?=E8=AF=AF=EF=BC=8C=E5=AE=8C=E6=88=90.NET=208.0=E5=8D=87?= =?UTF-8?q?=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 主要修复内容: 1. RealTimeController: 修复IEnumerable转List及Count方法问题 2. ConfigController: 修复BusinessRuleConfig命名空间歧义问题 3. ConfigController: 修复BusinessRule/StatisticsRule类型转换问题 4. ConfigController: 修复ImportConfigurationAsync参数类型问题 5. TemplateController: 修复ApiResponse.Error方法调用问题 6. IServices: 同步BusinessRule属性与BusinessRuleConfig一致 7. ApiResponse: 添加支持错误详情列表的重载方法 8. Models: 添加CNCDevice.TemplateId和CNCBrandTemplate.DeviceId别名属性 --- Haoliang.Api/Controllers/AlarmController.cs | 41 ++-- Haoliang.Api/Controllers/AuthController.cs | 33 ++-- Haoliang.Api/Controllers/ConfigController.cs | 182 ++++++++++++------ Haoliang.Api/Controllers/DeviceController.cs | 23 +-- .../Controllers/ProductionController.cs | 21 +- .../Controllers/RealTimeController.cs | 68 +++---- .../Controllers/StatisticsController.cs | 82 ++++---- Haoliang.Api/Controllers/SystemController.cs | 49 ++--- .../Controllers/TemplateController.cs | 33 ++-- Haoliang.Api/Filters/GlobalExceptionFilter.cs | 5 +- Haoliang.Api/Filters/JwtAuthorizeFilter.cs | 3 +- Haoliang.Api/Filters/ValidationFilter.cs | 3 +- Haoliang.Api/Haoliang.Api.csproj | 6 +- Haoliang.Api/Hubs/RealTimeHub.cs | 18 +- .../Middleware/RateLimitMiddleware.cs | 1 + Haoliang.Api/Startup.cs | 51 ++--- Haoliang.Core/Services/IServices.cs | 164 +++++++++++++++- Haoliang.Core/Services/StubServices.cs | 34 +++- Haoliang.Models/Common/CommonModels.cs | 15 ++ Haoliang.Models/Device/CNCDevice.cs | 1 + Haoliang.Models/Template/CNCBrandTemplate.cs | 1 + Haoliang.Models/User/AuthModels.cs | 2 + Haoliang.Models/User/User.cs | 4 + 23 files changed, 546 insertions(+), 294 deletions(-) diff --git a/Haoliang.Api/Controllers/AlarmController.cs b/Haoliang.Api/Controllers/AlarmController.cs index 1b6935d..54c209d 100644 --- a/Haoliang.Api/Controllers/AlarmController.cs +++ b/Haoliang.Api/Controllers/AlarmController.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Mvc; using Haoliang.Core.Services; using Haoliang.Models.System; using Haoliang.Models.Device; +using Haoliang.Models.Common; namespace Haoliang.Api.Controllers { @@ -49,7 +50,7 @@ namespace Haoliang.Api.Controllers alarms = await _alarmService.GetAllAlarmsAsync(); } - return Ok(ApiResponse.Success(alarms)); + return Ok(ApiResponse.Ok(alarms)); } catch (Exception ex) { @@ -68,7 +69,7 @@ namespace Haoliang.Api.Controllers { return NotFound(ApiResponse.NotFound("Alarm not found")); } - return Ok(ApiResponse.Success(alarm)); + return Ok(ApiResponse.Ok(alarm)); } catch (Exception ex) { @@ -83,7 +84,7 @@ namespace Haoliang.Api.Controllers try { var createdAlarm = await _alarmService.CreateAlarmAsync(alarm); - return Ok(ApiResponse.Success(createdAlarm, "Alarm created successfully")); + return Ok(ApiResponse.Ok(createdAlarm, "Alarm created successfully")); } catch (Exception ex) { @@ -97,13 +98,13 @@ namespace Haoliang.Api.Controllers { try { - alarm.AlarmId = id; + alarm.Id = id; var updatedAlarm = await _alarmService.UpdateAlarmAsync(id, alarm); if (updatedAlarm == null) { return NotFound(ApiResponse.NotFound("Alarm not found")); } - return Ok(ApiResponse.Success(updatedAlarm, "Alarm updated successfully")); + return Ok(ApiResponse.Ok(updatedAlarm, "Alarm updated successfully")); } catch (Exception ex) { @@ -122,7 +123,7 @@ namespace Haoliang.Api.Controllers { return NotFound(ApiResponse.NotFound("Alarm not found")); } - return Ok(ApiResponse.Success(null, "Alarm deleted successfully")); + return Ok(ApiResponse.Ok(null, "Alarm deleted successfully")); } catch (Exception ex) { @@ -141,7 +142,7 @@ namespace Haoliang.Api.Controllers { return NotFound(ApiResponse.NotFound("Alarm not found")); } - return Ok(ApiResponse.Success(null, "Alarm resolved successfully")); + return Ok(ApiResponse.Ok(null, "Alarm resolved successfully")); } catch (Exception ex) { @@ -160,7 +161,7 @@ namespace Haoliang.Api.Controllers { return NotFound(ApiResponse.NotFound("Alarm not found")); } - return Ok(ApiResponse.Success(null, "Alarm acknowledged successfully")); + return Ok(ApiResponse.Ok(null, "Alarm acknowledged successfully")); } catch (Exception ex) { @@ -175,7 +176,7 @@ namespace Haoliang.Api.Controllers try { var alarms = await _alarmService.GetDeviceAlarmsAsync(deviceId, days); - return Ok(ApiResponse.Success(alarms)); + return Ok(ApiResponse.Ok(alarms)); } catch (Exception ex) { @@ -190,7 +191,7 @@ namespace Haoliang.Api.Controllers try { var alarms = await _alarmService.GetCriticalAlarmsAsync(); - return Ok(ApiResponse.Success(alarms)); + return Ok(ApiResponse.Ok(alarms)); } catch (Exception ex) { @@ -208,7 +209,7 @@ namespace Haoliang.Api.Controllers date = DateTime.Today; var statistics = await _alarmService.GetAlarmStatisticsAsync(date); - return Ok(ApiResponse.Success(statistics)); + return Ok(ApiResponse.Ok(statistics)); } catch (Exception ex) { @@ -223,7 +224,7 @@ namespace Haoliang.Api.Controllers try { var alarms = await _alarmService.GetAlarmsByDateRangeAsync(startDate, endDate); - return Ok(ApiResponse.Success(alarms)); + return Ok(ApiResponse.Ok(alarms)); } catch (Exception ex) { @@ -240,16 +241,16 @@ namespace Haoliang.Api.Controllers var notification = new AlarmNotification { AlarmId = -1, - DeviceId = request.DeviceId, - NotificationType = request.NotificationType, - Message = "Test notification", + NotificationType = request.NotificationType.ToString(), + Subject = "Test notification", + Content = "Test notification", + IsSent = true, SendTime = DateTime.Now, - Status = NotificationStatus.Sent, Recipient = request.Recipient }; await _notificationService.SendAlarmNotificationAsync(notification); - return Ok(ApiResponse.Success(null, "Test notification sent successfully")); + return Ok(ApiResponse.Ok(null, "Test notification sent successfully")); } catch (Exception ex) { @@ -264,7 +265,7 @@ namespace Haoliang.Api.Controllers try { var rules = await _alarmRuleService.GetAllAlarmRulesAsync(); - return Ok(ApiResponse.Success(rules)); + return Ok(ApiResponse.Ok(rules)); } catch (Exception ex) { @@ -279,7 +280,7 @@ namespace Haoliang.Api.Controllers try { var createdRule = await _alarmRuleService.CreateAlarmRuleAsync(rule); - return Ok(ApiResponse.Success(createdRule, "Alarm rule created successfully")); + return Ok(ApiResponse.Ok(createdRule, "Alarm rule created successfully")); } catch (Exception ex) { @@ -294,7 +295,7 @@ namespace Haoliang.Api.Controllers try { await _alarmRuleService.TestAlarmRuleAsync(id); - return Ok(ApiResponse.Success(null, "Alarm rule test completed")); + return Ok(ApiResponse.Ok(null, "Alarm rule test completed")); } catch (Exception ex) { diff --git a/Haoliang.Api/Controllers/AuthController.cs b/Haoliang.Api/Controllers/AuthController.cs index f9e614a..38f208e 100644 --- a/Haoliang.Api/Controllers/AuthController.cs +++ b/Haoliang.Api/Controllers/AuthController.cs @@ -45,7 +45,7 @@ namespace Haoliang.Api.Controllers if (result.Success) { await _loggingService.LogInformationAsync($"User {request.Username} logged in successfully"); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } else { @@ -65,17 +65,17 @@ namespace Haoliang.Api.Controllers { try { - if (request?.UserId == null) + if (request?.UserId == null || request.UserId == 0) { return BadRequest(ApiResponse.Error("User ID is required", 400)); } - var success = await _authService.LogoutAsync(request.UserId.Value); + var success = await _authService.LogoutAsync(request.UserId); if (success) { await _loggingService.LogInformationAsync($"User {request.UserId} logged out successfully"); - return Ok(ApiResponse.Success(true)); + return Ok(ApiResponse.Ok(true)); } else { @@ -103,7 +103,7 @@ namespace Haoliang.Api.Controllers if (result.Success) { - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } else { @@ -158,7 +158,7 @@ namespace Haoliang.Api.Controllers var userViewModel = await _userService.CreateUserAsync(user); await _loggingService.LogInformationAsync($"New user registered: {request.Username}"); - return Ok(ApiResponse.Success(userViewModel)); + return Ok(ApiResponse.Ok(userViewModel)); } catch (Exception ex) { @@ -185,7 +185,7 @@ namespace Haoliang.Api.Controllers return NotFound(ApiResponse.Error("User not found", 404)); } - return Ok(ApiResponse.Success(user)); + return Ok(ApiResponse.Ok(user)); } catch (Exception ex) { @@ -223,7 +223,7 @@ namespace Haoliang.Api.Controllers var updatedUser = await _userService.UpdateUserAsync(userId.Value, user); await _loggingService.LogInformationAsync($"User profile updated: {request.Username}"); - return Ok(ApiResponse.Success(updatedUser)); + return Ok(ApiResponse.Ok(updatedUser)); } catch (Exception ex) { @@ -256,7 +256,7 @@ namespace Haoliang.Api.Controllers if (success) { await _loggingService.LogInformationAsync($"Password changed for user: {userId}"); - return Ok(ApiResponse.Success(true)); + return Ok(ApiResponse.Ok(true)); } else { @@ -282,7 +282,7 @@ namespace Haoliang.Api.Controllers } var permissions = await _permissionService.GetUserPermissionsAsync(userId.Value); - return Ok(ApiResponse>.Success(permissions)); + return Ok(ApiResponse>.Ok(permissions)); } catch (Exception ex) { @@ -354,7 +354,7 @@ namespace Haoliang.Api.Controllers return NotFound(ApiResponse.Error("User not found", 404)); } - return Ok(ApiResponse.Success(user)); + return Ok(ApiResponse.Ok(user)); } catch (Exception ex) { @@ -372,7 +372,7 @@ namespace Haoliang.Api.Controllers if (success) { await _loggingService.LogInformationAsync($"User activated: {id}"); - return Ok(ApiResponse.Success(true)); + return Ok(ApiResponse.Ok(true)); } else { @@ -395,7 +395,7 @@ namespace Haoliang.Api.Controllers if (success) { await _loggingService.LogInformationAsync($"User deactivated: {id}"); - return Ok(ApiResponse.Success(true)); + return Ok(ApiResponse.Ok(true)); } else { @@ -418,13 +418,6 @@ namespace Haoliang.Api.Controllers } // Supporting request and response models - public class LoginRequest - { - public string Username { get; set; } - public string Password { get; set; } - public bool RememberMe { get; set; } - } - public class LogoutRequest { public int UserId { get; set; } diff --git a/Haoliang.Api/Controllers/ConfigController.cs b/Haoliang.Api/Controllers/ConfigController.cs index 6d0df52..9dfeb23 100644 --- a/Haoliang.Api/Controllers/ConfigController.cs +++ b/Haoliang.Api/Controllers/ConfigController.cs @@ -2,11 +2,13 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using System.ComponentModel.DataAnnotations; using Haoliang.Core.Services; -using Haoliang.Models.Models.System; -using Haoliang.Models.Models.Production; -using Haoliang.Models.Models.Template; +using Haoliang.Models.System; +using Haoliang.Models.Production; +using Haoliang.Models.Template; using Haoliang.Models.Common; +using Haoliang.Models.Models.System; namespace Haoliang.Api.Controllers { @@ -40,11 +42,11 @@ namespace Haoliang.Api.Controllers try { var config = await _systemService.GetSystemConfigurationAsync(); - return Ok(ApiResponse.Success(config)); + return Ok(ApiResponse.Ok(config)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error getting system configuration: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error getting system configuration: {ex.Message}")); } } @@ -57,11 +59,11 @@ namespace Haoliang.Api.Controllers try { var result = await _systemService.UpdateSystemConfigurationAsync(configuration); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error updating system configuration: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error updating system configuration: {ex.Message}")); } } @@ -74,7 +76,7 @@ namespace Haoliang.Api.Controllers try { var targets = await _systemService.GetProductionTargetsAsync(); - return Ok(ApiResponse>.Success(targets)); + return Ok(ApiResponse>.Ok(targets)); } catch (Exception ex) { @@ -91,11 +93,11 @@ namespace Haoliang.Api.Controllers try { var result = await _systemService.UpdateProductionTargetsAsync(targets); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error updating production targets: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error updating production targets: {ex.Message}")); } } @@ -108,11 +110,11 @@ namespace Haoliang.Api.Controllers try { var config = await _systemService.GetWorkingHoursConfigAsync(); - return Ok(ApiResponse.Success(config)); + return Ok(ApiResponse.Ok(config)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error getting working hours config: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error getting working hours config: {ex.Message}")); } } @@ -125,11 +127,11 @@ namespace Haoliang.Api.Controllers try { var result = await _systemService.UpdateWorkingHoursConfigAsync(config); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error updating working hours config: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error updating working hours config: {ex.Message}")); } } @@ -142,11 +144,11 @@ namespace Haoliang.Api.Controllers try { var config = await _systemService.GetAlertConfigurationAsync(); - return Ok(ApiResponse.Success(config)); + return Ok(ApiResponse.Ok(config)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error getting alert configuration: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error getting alert configuration: {ex.Message}")); } } @@ -159,11 +161,11 @@ namespace Haoliang.Api.Controllers try { var result = await _systemService.UpdateAlertConfigurationAsync(config); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error updating alert configuration: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error updating alert configuration: {ex.Message}")); } } @@ -171,16 +173,27 @@ namespace Haoliang.Api.Controllers /// Get business rules configuration /// [HttpGet("rules")] - public async Task>>> GetBusinessRules() + public async Task>>> GetBusinessRules() { try { var rules = await _rulesService.GetAllRulesAsync(); - return Ok(ApiResponse>.Success(rules)); + var ruleConfigs = rules.Select(r => new Haoliang.Models.System.BusinessRuleConfig + { + RuleId = r.RuleId, + RuleName = r.RuleName, + RuleType = r.RuleType, + Category = r.Category, + IsEnabled = r.IsEnabled, + Configuration = r.Configuration, + CreatedAt = r.CreatedAt, + UpdatedAt = r.UpdatedAt + }).ToList(); + return Ok(ApiResponse>.Ok(ruleConfigs)); } catch (Exception ex) { - return StatusCode(500, ApiResponse>.InternalServerError($"Error getting business rules: {ex.Message}")); + return StatusCode(500, ApiResponse>.InternalServerError($"Error getting business rules: {ex.Message}")); } } @@ -188,16 +201,38 @@ namespace Haoliang.Api.Controllers /// Create or update business rule /// [HttpPost("rules")] - public async Task>> CreateOrUpdateBusinessRule([FromBody] BusinessRuleConfig rule) + public async Task>> CreateOrUpdateBusinessRule([FromBody] Haoliang.Models.System.BusinessRuleConfig rule) { try { - var result = await _rulesService.CreateOrUpdateRuleAsync(rule); - return Ok(ApiResponse.Success(result)); + var businessRule = new Haoliang.Core.Services.BusinessRule + { + RuleId = rule.RuleId, + RuleName = rule.RuleName, + RuleType = rule.RuleType, + Category = rule.Category, + IsEnabled = rule.IsEnabled, + Configuration = rule.Configuration, + CreatedAt = rule.CreatedAt, + UpdatedAt = rule.UpdatedAt + }; + var result = await _rulesService.CreateOrUpdateRuleAsync(businessRule); + var resultConfig = new Haoliang.Models.System.BusinessRuleConfig + { + RuleId = result.RuleId, + RuleName = result.RuleName, + RuleType = result.RuleType, + Category = result.Category, + IsEnabled = result.IsEnabled, + Configuration = result.Configuration, + CreatedAt = result.CreatedAt, + UpdatedAt = result.UpdatedAt + }; + return Ok(ApiResponse.Ok(resultConfig)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error creating/updating business rule: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error creating/updating business rule: {ex.Message}")); } } @@ -210,11 +245,11 @@ namespace Haoliang.Api.Controllers try { var result = await _rulesService.DeleteRuleAsync(ruleId); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error deleting business rule: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error deleting business rule: {ex.Message}")); } } @@ -222,16 +257,27 @@ namespace Haoliang.Api.Controllers /// Get statistical analysis rules /// [HttpGet("statistics-rules")] - public async Task>>> GetStatisticsRules() + public async Task>>> GetStatisticsRules() { try { var rules = await _rulesService.GetStatisticsRulesAsync(); - return Ok(ApiResponse>.Success(rules)); + var ruleConfigs = rules.Select(r => new Haoliang.Models.System.StatisticsRuleConfig + { + ConfigId = r.RuleId, + ConfigName = r.RuleName, + ConfigType = r.RuleType, + Formula = r.Configuration, + GroupBy = "", + IsActive = r.IsEnabled, + CreatedAt = r.CreatedAt, + UpdatedAt = r.UpdatedAt + }).ToList(); + return Ok(ApiResponse>.Ok(ruleConfigs)); } catch (Exception ex) { - return StatusCode(500, ApiResponse>.InternalServerError($"Error getting statistics rules: {ex.Message}")); + return StatusCode(500, ApiResponse>.InternalServerError($"Error getting statistics rules: {ex.Message}")); } } @@ -239,16 +285,27 @@ namespace Haoliang.Api.Controllers /// Update statistics rules /// [HttpPut("statistics-rules")] - public async Task>> UpdateStatisticsRules([FromBody] List rules) + public async Task>> UpdateStatisticsRules([FromBody] List rules) { try { - var result = await _rulesService.UpdateStatisticsRulesAsync(rules); - return Ok(ApiResponse.Success(result)); + var businessRules = rules.Select(r => new Haoliang.Core.Services.BusinessRule + { + RuleId = r.ConfigId, + RuleName = r.ConfigName, + RuleType = r.ConfigType, + Category = r.GroupBy, + IsEnabled = r.IsActive, + Configuration = r.Formula, + CreatedAt = r.CreatedAt, + UpdatedAt = r.UpdatedAt + }).ToList(); + var result = await _rulesService.UpdateStatisticsRulesAsync(businessRules); + return Ok(ApiResponse.Ok(result)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error updating statistics rules: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error updating statistics rules: {ex.Message}")); } } @@ -261,11 +318,11 @@ namespace Haoliang.Api.Controllers try { var config = await _systemService.GetDataRetentionConfigAsync(); - return Ok(ApiResponse.Success(config)); + return Ok(ApiResponse.Ok(config)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error getting data retention config: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error getting data retention config: {ex.Message}")); } } @@ -278,11 +335,11 @@ namespace Haoliang.Api.Controllers try { var result = await _systemService.UpdateDataRetentionConfigAsync(config); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error updating data retention config: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error updating data retention config: {ex.Message}")); } } @@ -295,11 +352,11 @@ namespace Haoliang.Api.Controllers try { var config = await _systemService.GetDashboardConfigAsync(); - return Ok(ApiResponse.Success(config)); + return Ok(ApiResponse.Ok(config)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error getting dashboard config: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error getting dashboard config: {ex.Message}")); } } @@ -312,11 +369,11 @@ namespace Haoliang.Api.Controllers try { var result = await _systemService.UpdateDashboardConfigAsync(config); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error updating dashboard config: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error updating dashboard config: {ex.Message}")); } } @@ -329,11 +386,11 @@ namespace Haoliang.Api.Controllers try { var config = await _systemService.GetExportConfigAsync(); - return Ok(ApiResponse.Success(config)); + return Ok(ApiResponse.Ok(config)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error getting export config: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error getting export config: {ex.Message}")); } } @@ -346,11 +403,11 @@ namespace Haoliang.Api.Controllers try { var result = await _systemService.UpdateExportConfigAsync(config); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error updating export config: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error updating export config: {ex.Message}")); } } @@ -363,11 +420,11 @@ namespace Haoliang.Api.Controllers try { var config = await _systemService.GetCollectionConfigAsync(); - return Ok(ApiResponse.Success(config)); + return Ok(ApiResponse.Ok(config)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error getting collection config: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error getting collection config: {ex.Message}")); } } @@ -380,11 +437,11 @@ namespace Haoliang.Api.Controllers try { var result = await _systemService.UpdateCollectionConfigAsync(config); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error updating collection config: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error updating collection config: {ex.Message}")); } } @@ -397,11 +454,11 @@ namespace Haoliang.Api.Controllers try { var config = await _systemService.GetNotificationConfigAsync(); - return Ok(ApiResponse.Success(config)); + return Ok(ApiResponse.Ok(config)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error getting notification config: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error getting notification config: {ex.Message}")); } } @@ -414,11 +471,11 @@ namespace Haoliang.Api.Controllers try { var result = await _systemService.UpdateNotificationConfigAsync(config); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error updating notification config: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error updating notification config: {ex.Message}")); } } @@ -431,11 +488,11 @@ namespace Haoliang.Api.Controllers try { var result = await _systemService.ValidateConfigurationAsync(configuration); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error validating configuration: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error validating configuration: {ex.Message}")); } } @@ -469,12 +526,13 @@ namespace Haoliang.Api.Controllers { try { - var result = await _systemService.ImportConfigurationAsync(configuration); - return Ok(ApiResponse.Success(result)); + var json = System.Text.Json.JsonSerializer.Serialize(configuration); + var result = await _systemService.ImportConfigurationAsync(json); + return Ok(ApiResponse.Ok(result)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error importing configuration: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error importing configuration: {ex.Message}")); } } @@ -487,11 +545,11 @@ namespace Haoliang.Api.Controllers try { var result = await _systemService.ResetToDefaultConfigurationAsync(); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error resetting configuration: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error resetting configuration: {ex.Message}")); } } @@ -504,7 +562,7 @@ namespace Haoliang.Api.Controllers try { var history = await _systemService.GetConfigurationChangeHistoryAsync(startDate, endDate); - return Ok(ApiResponse>.Success(history)); + return Ok(ApiResponse>.Ok(history)); } catch (Exception ex) { diff --git a/Haoliang.Api/Controllers/DeviceController.cs b/Haoliang.Api/Controllers/DeviceController.cs index 30c9e80..a469e74 100644 --- a/Haoliang.Api/Controllers/DeviceController.cs +++ b/Haoliang.Api/Controllers/DeviceController.cs @@ -8,6 +8,7 @@ using Haoliang.Models.Device; using Haoliang.Models.DataCollection; using Haoliang.Models.System; using Haoliang.Models.Template; +using Haoliang.Models.Common; namespace Haoliang.Api.Controllers { @@ -44,7 +45,7 @@ namespace Haoliang.Api.Controllers try { var devices = await _collectionService.GetAllDevicesAsync(); - return Ok(ApiResponse.Success(devices)); + return Ok(ApiResponse.Ok(devices)); } catch (Exception ex) { @@ -63,7 +64,7 @@ namespace Haoliang.Api.Controllers { return NotFound(ApiResponse.NotFound("Device not found")); } - return Ok(ApiResponse.Success(device)); + return Ok(ApiResponse.Ok(device)); } catch (Exception ex) { @@ -78,7 +79,7 @@ namespace Haoliang.Api.Controllers try { var createdDevice = await _collectionService.CreateDeviceAsync(device); - return Ok(ApiResponse.Success(createdDevice, "Device created successfully")); + return Ok(ApiResponse.Ok(createdDevice, "Device created successfully")); } catch (Exception ex) { @@ -98,7 +99,7 @@ namespace Haoliang.Api.Controllers { return NotFound(ApiResponse.NotFound("Device not found")); } - return Ok(ApiResponse.Success(updatedDevice, "Device updated successfully")); + return Ok(ApiResponse.Ok(updatedDevice, "Device updated successfully")); } catch (Exception ex) { @@ -117,7 +118,7 @@ namespace Haoliang.Api.Controllers { return NotFound(ApiResponse.NotFound("Device not found")); } - return Ok(ApiResponse.Success(null, "Device deleted successfully")); + return Ok(ApiResponse.Ok(null, "Device deleted successfully")); } catch (Exception ex) { @@ -132,7 +133,7 @@ namespace Haoliang.Api.Controllers try { await _collectionService.CollectDeviceAsync(id); - return Ok(ApiResponse.Success(null, "Data collection started")); + return Ok(ApiResponse.Ok(null, "Data collection started")); } catch (Exception ex) { @@ -147,7 +148,7 @@ namespace Haoliang.Api.Controllers try { await _collectionService.CollectAllDevicesAsync(); - return Ok(ApiResponse.Success(null, "All devices data collection started")); + return Ok(ApiResponse.Ok(null, "All devices data collection started")); } catch (Exception ex) { @@ -162,7 +163,7 @@ namespace Haoliang.Api.Controllers try { var status = await _collectionService.GetDeviceStatusAsync(id); - return Ok(ApiResponse.Success(status)); + return Ok(ApiResponse.Ok(status)); } catch (Exception ex) { @@ -180,7 +181,7 @@ namespace Haoliang.Api.Controllers date = DateTime.Today; var production = await _productionService.GetTodayProductionAsync(id); - return Ok(ApiResponse.Success(production)); + return Ok(ApiResponse.Ok(production)); } catch (Exception ex) { @@ -195,7 +196,7 @@ namespace Haoliang.Api.Controllers try { var alarms = await _alarmService.GetDeviceAlarmsAsync(id, days); - return Ok(ApiResponse.Success(alarms)); + return Ok(ApiResponse.Ok(alarms)); } catch (Exception ex) { @@ -210,7 +211,7 @@ namespace Haoliang.Api.Controllers try { var health = await _collectionService.GetDeviceHealthAsync(id); - return Ok(ApiResponse.Success(health)); + return Ok(ApiResponse.Ok(health)); } catch (Exception ex) { diff --git a/Haoliang.Api/Controllers/ProductionController.cs b/Haoliang.Api/Controllers/ProductionController.cs index 6ff5176..5086df9 100644 --- a/Haoliang.Api/Controllers/ProductionController.cs +++ b/Haoliang.Api/Controllers/ProductionController.cs @@ -7,6 +7,7 @@ using Haoliang.Core.Services; using Haoliang.Models.Production; using Haoliang.Models.Device; using Haoliang.Models.System; +using Haoliang.Models.Common; namespace Haoliang.Api.Controllers { @@ -40,7 +41,7 @@ namespace Haoliang.Api.Controllers date = DateTime.Today; var summary = await _productionService.GetProductionSummaryAsync(date); - return Ok(ApiResponse.Success(summary)); + return Ok(ApiResponse.Ok(summary)); } catch (Exception ex) { @@ -58,7 +59,7 @@ namespace Haoliang.Api.Controllers date = DateTime.Today; var statistics = await _productionService.GetProductionStatisticsAsync(date); - return Ok(ApiResponse.Success(statistics)); + return Ok(ApiResponse.Ok(statistics)); } catch (Exception ex) { @@ -78,7 +79,7 @@ namespace Haoliang.Api.Controllers date = DateTime.Today; var production = await _productionService.GetTodayProductionAsync(deviceId); - return Ok(ApiResponse.Success(production)); + return Ok(ApiResponse.Ok(production)); } catch (Exception ex) { @@ -98,7 +99,7 @@ namespace Haoliang.Api.Controllers date = DateTime.Today; var statistics = await _productionService.GetProductionStatisticsAsync(deviceId, date); - return Ok(ApiResponse.Success(statistics)); + return Ok(ApiResponse.Ok(statistics)); } catch (Exception ex) { @@ -118,7 +119,7 @@ namespace Haoliang.Api.Controllers date = DateTime.Today; var qualityRate = await _productionService.GetQualityRateAsync(deviceId, date); - return Ok(ApiResponse.Success(qualityRate)); + return Ok(ApiResponse.Ok(qualityRate)); } catch (Exception ex) { @@ -133,7 +134,7 @@ namespace Haoliang.Api.Controllers try { await _productionService.CalculateAllProductionAsync(); - return Ok(ApiResponse.Success(null, "Production calculation completed")); + return Ok(ApiResponse.Ok(null, "Production calculation completed")); } catch (Exception ex) { @@ -148,7 +149,7 @@ namespace Haoliang.Api.Controllers try { await _productionService.CalculateProductionAsync(deviceId); - return Ok(ApiResponse.Success(null, "Device production calculation completed")); + return Ok(ApiResponse.Ok(null, "Device production calculation completed")); } catch (Exception ex) { @@ -166,7 +167,7 @@ namespace Haoliang.Api.Controllers date = DateTime.Today; var programs = await _productionService.GetProductionProgramsAsync(date); - return Ok(ApiResponse.Success(programs)); + return Ok(ApiResponse.Ok(programs)); } catch (Exception ex) { @@ -186,7 +187,7 @@ namespace Haoliang.Api.Controllers date = DateTime.Today; var programData = await _productionService.GetProgramProductionAsync(programName, date); - return Ok(ApiResponse.Success(programData)); + return Ok(ApiResponse.Ok(programData)); } catch (Exception ex) { @@ -225,7 +226,7 @@ namespace Haoliang.Api.Controllers try { await _productionService.ArchiveProductionDataAsync(daysToKeep); - return Ok(ApiResponse.Success(null, "Production data archived successfully")); + return Ok(ApiResponse.Ok(null, "Production data archived successfully")); } catch (Exception ex) { diff --git a/Haoliang.Api/Controllers/RealTimeController.cs b/Haoliang.Api/Controllers/RealTimeController.cs index 256a0e4..43e4259 100644 --- a/Haoliang.Api/Controllers/RealTimeController.cs +++ b/Haoliang.Api/Controllers/RealTimeController.cs @@ -27,11 +27,11 @@ namespace Haoliang.Api.Controllers try { var count = await _realTimeService.GetConnectedClientsCountAsync(); - return Ok(ApiResponse.Success(count)); + return Ok(ApiResponse.Ok(count)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error getting connected clients count: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error getting connected clients count: {ex.Message}")); } } @@ -44,7 +44,7 @@ namespace Haoliang.Api.Controllers try { var clients = await _realTimeService.GetConnectedClientsByTypeAsync(clientType); - return Ok(ApiResponse>.Success(clients)); + return Ok(ApiResponse>.Ok(clients)); } catch (Exception ex) { @@ -61,11 +61,11 @@ namespace Haoliang.Api.Controllers try { var status = await _realTimeService.GetDeviceMonitoringStatusAsync(deviceId); - return Ok(ApiResponse.Success(status)); + return Ok(ApiResponse.Ok(status)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error getting device monitoring status: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error getting device monitoring status: {ex.Message}")); } } @@ -80,11 +80,11 @@ namespace Haoliang.Api.Controllers try { await _realTimeService.StartDeviceStreamingAsync(deviceId, intervalMs); - return Ok(ApiResponse.Success(true)); + return Ok(ApiResponse.Ok(true)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error starting device streaming: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error starting device streaming: {ex.Message}")); } } @@ -97,11 +97,11 @@ namespace Haoliang.Api.Controllers try { await _realTimeService.StopDeviceStreamingAsync(deviceId); - return Ok(ApiResponse.Success(true)); + return Ok(ApiResponse.Ok(true)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error stopping device streaming: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error stopping device streaming: {ex.Message}")); } } @@ -114,7 +114,7 @@ namespace Haoliang.Api.Controllers try { var devices = await _realTimeService.GetActiveStreamingDevicesAsync(); - return Ok(ApiResponse>.Success(devices)); + return Ok(ApiResponse>.Ok(devices)); } catch (Exception ex) { @@ -136,11 +136,11 @@ namespace Haoliang.Api.Controllers statusUpdate.Timestamp = DateTime.UtcNow; await _realTimeService.BroadcastDeviceStatusAsync(statusUpdate); - return Ok(ApiResponse.Success(true)); + return Ok(ApiResponse.Ok(true)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error sending device status update: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error sending device status update: {ex.Message}")); } } @@ -158,11 +158,11 @@ namespace Haoliang.Api.Controllers productionUpdate.Timestamp = DateTime.UtcNow; await _realTimeService.BroadcastProductionUpdateAsync(productionUpdate); - return Ok(ApiResponse.Success(true)); + return Ok(ApiResponse.Ok(true)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error sending production update: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error sending production update: {ex.Message}")); } } @@ -176,11 +176,11 @@ namespace Haoliang.Api.Controllers { alertUpdate.Timestamp = DateTime.UtcNow; await _realTimeService.BroadcastAlertAsync(alertUpdate); - return Ok(ApiResponse.Success(true)); + return Ok(ApiResponse.Ok(true)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error sending alert: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error sending alert: {ex.Message}")); } } @@ -194,11 +194,11 @@ namespace Haoliang.Api.Controllers { notification.Timestamp = DateTime.UtcNow; await _realTimeService.SendSystemNotificationAsync(notification); - return Ok(ApiResponse.Success(true)); + return Ok(ApiResponse.Ok(true)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error sending system notification: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error sending system notification: {ex.Message}")); } } @@ -212,11 +212,11 @@ namespace Haoliang.Api.Controllers { dashboardUpdate.Timestamp = DateTime.UtcNow; await _realTimeService.SendDashboardUpdateAsync(dashboardUpdate); - return Ok(ApiResponse.Success(true)); + return Ok(ApiResponse.Ok(true)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error sending dashboard update: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error sending dashboard update: {ex.Message}")); } } @@ -232,11 +232,11 @@ namespace Haoliang.Api.Controllers { command.Timestamp = DateTime.UtcNow; await _realTimeService.SendCommandToClientAsync(connectionId, command); - return Ok(ApiResponse.Success(true)); + return Ok(ApiResponse.Ok(true)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error sending command to client: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error sending command to client: {ex.Message}")); } } @@ -250,11 +250,11 @@ namespace Haoliang.Api.Controllers { command.Timestamp = DateTime.UtcNow; await _realTimeService.BroadcastCommandAsync(command); - return Ok(ApiResponse.Success(true)); + return Ok(ApiResponse.Ok(true)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error broadcasting command: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error broadcasting command: {ex.Message}")); } } @@ -269,11 +269,11 @@ namespace Haoliang.Api.Controllers var baseUrl = $"{Request.Scheme}://{Request.Host}"; var connectionUrl = $"{baseUrl}/realtimehub"; - return Ok(ApiResponse.Success(connectionUrl)); + return Ok(ApiResponse.Ok(connectionUrl)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error getting connection URL: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error getting connection URL: {ex.Message}")); } } @@ -290,15 +290,15 @@ namespace Haoliang.Api.Controllers TestId = Guid.NewGuid().ToString(), Timestamp = DateTime.UtcNow, ConnectedClients = await _realTimeService.GetConnectedClientsCountAsync(), - ActiveStreamingDevices = await _realTimeService.GetActiveStreamingDevicesAsync(), + ActiveStreamingDevices = (await _realTimeService.GetActiveStreamingDevicesAsync()).ToList(), Status = "Success" }; - return Ok(ApiResponse.Success(testResult)); + return Ok(ApiResponse.Ok(testResult)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error testing WebSocket: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error testing WebSocket: {ex.Message}")); } } @@ -311,7 +311,7 @@ namespace Haoliang.Api.Controllers try { var connectedClients = await _realTimeService.GetConnectedClientsCountAsync(); - var streamingDevices = await _realTimeService.GetActiveStreamingDevicesAsync(); + var streamingDevices = (await _realTimeService.GetActiveStreamingDevicesAsync()).ToList(); var stats = new WebSocketStatistics { @@ -323,11 +323,11 @@ namespace Haoliang.Api.Controllers BytesTransferred = 0 // Would need to track this in the service }; - return Ok(ApiResponse.Success(stats)); + return Ok(ApiResponse.Ok(stats)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error getting WebSocket statistics: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error getting WebSocket statistics: {ex.Message}")); } } @@ -341,11 +341,11 @@ namespace Haoliang.Api.Controllers { // This would trigger the dashboard update logic // Implementation depends on specific requirements - return Ok(ApiResponse.Success(true)); + return Ok(ApiResponse.Ok(true)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error refreshing dashboard data: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error refreshing dashboard data: {ex.Message}")); } } } diff --git a/Haoliang.Api/Controllers/StatisticsController.cs b/Haoliang.Api/Controllers/StatisticsController.cs index c498726..3c99c2d 100644 --- a/Haoliang.Api/Controllers/StatisticsController.cs +++ b/Haoliang.Api/Controllers/StatisticsController.cs @@ -4,7 +4,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Haoliang.Core.Services; using Haoliang.Models.Models.System; -using Haoliang.Models.Models.Production; +using Haoliang.Models.Production; using Haoliang.Models.Common; namespace Haoliang.Api.Controllers @@ -32,14 +32,14 @@ namespace Haoliang.Api.Controllers try { if (deviceId <= 0) - return BadRequest(ApiResponse.BadRequest("Invalid device ID")); + return BadRequest(ApiResponse.BadRequestResult("Invalid device ID")); if (startDate >= endDate) - return BadRequest(ApiResponse.BadRequest("Start date must be before end date")); + return BadRequest(ApiResponse.BadRequestResult("Start date must be before end date")); var result = await _statisticsService.CalculateProductionTrendsAsync(deviceId, startDate, endDate); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } catch (KeyNotFoundException ex) { @@ -47,7 +47,7 @@ namespace Haoliang.Api.Controllers } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error calculating production trends: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error calculating production trends: {ex.Message}")); } } @@ -60,15 +60,15 @@ namespace Haoliang.Api.Controllers try { if (filter.StartDate >= filter.EndDate) - return BadRequest(ApiResponse.BadRequest("Start date must be before end date")); + return BadRequest(ApiResponse.BadRequestResult("Start date must be before end date")); var result = await _statisticsService.GenerateProductionReportAsync(filter); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error generating production report: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error generating production report: {ex.Message}")); } } @@ -81,15 +81,15 @@ namespace Haoliang.Api.Controllers try { if (filter.StartDate >= filter.EndDate) - return BadRequest(ApiResponse.BadRequest("Start date must be before end date")); + return BadRequest(ApiResponse.BadRequestResult("Start date must be before end date")); var result = await _statisticsService.CalculateEfficiencyMetricsAsync(filter); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error calculating efficiency metrics: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error calculating efficiency metrics: {ex.Message}")); } } @@ -102,15 +102,15 @@ namespace Haoliang.Api.Controllers try { if (filter.StartDate >= filter.EndDate) - return BadRequest(ApiResponse.BadRequest("Start date must be before end date")); + return BadRequest(ApiResponse.BadRequestResult("Start date must be before end date")); var result = await _statisticsService.PerformQualityAnalysisAsync(filter); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error performing quality analysis: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error performing quality analysis: {ex.Message}")); } } @@ -124,11 +124,11 @@ namespace Haoliang.Api.Controllers { var result = await _statisticsService.GetDashboardSummaryAsync(filter); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error getting dashboard summary: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error getting dashboard summary: {ex.Message}")); } } @@ -143,19 +143,19 @@ namespace Haoliang.Api.Controllers try { if (deviceId <= 0) - return BadRequest(ApiResponse.BadRequest("Invalid device ID")); + return BadRequest(ApiResponse.BadRequestResult("Invalid device ID")); var result = await _statisticsService.CalculateOeeAsync(deviceId, date); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } catch (KeyNotFoundException ex) { - return NotFound(ApiResponse.NotFound(ex.Message)); + return NotFound(ApiResponse.NotFoundResult(ex.Message)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error calculating OEE metrics: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error calculating OEE metrics: {ex.Message}")); } } @@ -168,22 +168,22 @@ namespace Haoliang.Api.Controllers try { if (filter.DeviceId <= 0) - return BadRequest(ApiResponse.BadRequest("Invalid device ID")); + return BadRequest(ApiResponse.BadRequestResult("Invalid device ID")); if (filter.DaysToForecast <= 0 || filter.DaysToForecast > 365) - return BadRequest(ApiResponse.BadRequest("Days to forecast must be between 1 and 365")); + return BadRequest(ApiResponse.BadRequestResult("Days to forecast must be between 1 and 365")); var result = await _statisticsService.GenerateProductionForecastAsync(filter); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } catch (KeyNotFoundException ex) { - return NotFound(ApiResponse.NotFound(ex.Message)); + return NotFound(ApiResponse.NotFoundResult(ex.Message)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error generating production forecast: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error generating production forecast: {ex.Message}")); } } @@ -196,15 +196,15 @@ namespace Haoliang.Api.Controllers try { if (filter.StartDate >= filter.EndDate) - return BadRequest(ApiResponse.BadRequest("Start date must be before end date")); + return BadRequest(ApiResponse.BadRequestResult("Start date must be before end date")); var result = await _statisticsService.DetectProductionAnomaliesAsync(filter); - return Ok(ApiResponse.Success(result)); + return Ok(ApiResponse.Ok(result)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error detecting production anomalies: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error detecting production anomalies: {ex.Message}")); } } @@ -220,11 +220,11 @@ namespace Haoliang.Api.Controllers // For now, returning empty list var result = new List(); - return Ok(ApiResponse>.Success(result)); + return Ok(ApiResponse>.Ok(result)); } catch (Exception ex) { - return StatusCode(500, ApiResponse>.InternalServerError($"Error getting available devices: {ex.Message}")); + return StatusCode(500, ApiResponse>.InternalServerErrorResult($"Error getting available devices: {ex.Message}")); } } @@ -259,11 +259,11 @@ namespace Haoliang.Api.Controllers DeviceSummaries = dashboardSummary.DeviceSummaries }; - return Ok(ApiResponse.Success(multiDeviceSummary)); + return Ok(ApiResponse.Ok(multiDeviceSummary)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error getting multi-device summary: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error getting multi-device summary: {ex.Message}")); } } @@ -280,10 +280,10 @@ namespace Haoliang.Api.Controllers try { if (deviceId <= 0) - return BadRequest(ApiResponse.BadRequest("Invalid device ID")); + return BadRequest(ApiResponse.BadRequestResult("Invalid device ID")); if (startDate >= endDate) - return BadRequest(ApiResponse.BadRequest("Start date must be before end date")); + return BadRequest(ApiResponse.BadRequestResult("Start date must be before end date")); var filter = new ReportFilter { @@ -304,7 +304,7 @@ namespace Haoliang.Api.Controllers DataPoints = report.SummaryItems.Select(item => new DataPoint { Timestamp = groupBy == GroupBy.Date ? item.Date : - groupBy == GroupBy.Hour ? item.Hour : + groupBy == GroupBy.Hour ? (item.Hour.HasValue ? item.Date.AddHours(item.Hour.Value) : item.Date) : item.Date, Value = item.Quantity, Target = item.TargetQuantity, @@ -312,11 +312,11 @@ namespace Haoliang.Api.Controllers }).ToList() }; - return Ok(ApiResponse.Success(historicalData)); + return Ok(ApiResponse.Ok(historicalData)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error getting historical production data: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error getting historical production data: {ex.Message}")); } } @@ -333,10 +333,10 @@ namespace Haoliang.Api.Controllers try { if (deviceId <= 0) - return BadRequest(ApiResponse.BadRequest("Invalid device ID")); + return BadRequest(ApiResponse.BadRequestResult("Invalid device ID")); if (startDate >= endDate) - return BadRequest(ApiResponse.BadRequest("Start date must be before end date")); + return BadRequest(ApiResponse.BadRequestResult("Start date must be before end date")); var filter = new EfficiencyFilter { @@ -364,11 +364,11 @@ namespace Haoliang.Api.Controllers }).ToList() }; - return Ok(ApiResponse.Success(trendData)); + return Ok(ApiResponse.Ok(trendData)); } catch (Exception ex) { - return StatusCode(500, ApiResponse.InternalServerError($"Error getting efficiency trends: {ex.Message}")); + return StatusCode(500, ApiResponse.InternalServerErrorResult($"Error getting efficiency trends: {ex.Message}")); } } } diff --git a/Haoliang.Api/Controllers/SystemController.cs b/Haoliang.Api/Controllers/SystemController.cs index 70f244d..a7baf31 100644 --- a/Haoliang.Api/Controllers/SystemController.cs +++ b/Haoliang.Api/Controllers/SystemController.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Haoliang.Core.Services; using Haoliang.Models.System; +using Haoliang.Models.Common; namespace Haoliang.Api.Controllers { @@ -32,7 +33,7 @@ namespace Haoliang.Api.Controllers try { var configs = await _configService.GetAllConfigsAsync(); - return Ok(ApiResponse.Success(configs)); + return Ok(ApiResponse.Ok(configs)); } catch (Exception ex) { @@ -51,7 +52,7 @@ namespace Haoliang.Api.Controllers { return NotFound(ApiResponse.NotFound($"Config '{key}' not found")); } - return Ok(ApiResponse.Success(config)); + return Ok(ApiResponse.Ok(config)); } catch (Exception ex) { @@ -66,7 +67,7 @@ namespace Haoliang.Api.Controllers try { var config = await _configService.SetConfigAsync(key, request.Value); - return Ok(ApiResponse.Success(config, "Config updated successfully")); + return Ok(ApiResponse.Ok(config, "Config updated successfully")); } catch (Exception ex) { @@ -85,7 +86,7 @@ namespace Haoliang.Api.Controllers { return NotFound(ApiResponse.NotFound($"Config '{key}' not found")); } - return Ok(ApiResponse.Success(null, "Config deleted successfully")); + return Ok(ApiResponse.Ok(null, "Config deleted successfully")); } catch (Exception ex) { @@ -100,7 +101,7 @@ namespace Haoliang.Api.Controllers try { var exists = await _configService.ConfigExistsAsync(key); - return Ok(ApiResponse.Success(exists)); + return Ok(ApiResponse.Ok(exists)); } catch (Exception ex) { @@ -115,7 +116,7 @@ namespace Haoliang.Api.Controllers try { var configs = await _configService.GetConfigsByCategoryAsync(category); - return Ok(ApiResponse.Success(configs)); + return Ok(ApiResponse.Ok(configs)); } catch (Exception ex) { @@ -130,7 +131,7 @@ namespace Haoliang.Api.Controllers try { await _configService.RefreshConfigCacheAsync(); - return Ok(ApiResponse.Success(null, "Config cache refreshed successfully")); + return Ok(ApiResponse.Ok(null, "Config cache refreshed successfully")); } catch (Exception ex) { @@ -141,7 +142,7 @@ namespace Haoliang.Api.Controllers [HttpGet("logs")] public async Task GetLogs( - [FromQuery] LogLevel? logLevel = null, + [FromQuery] Haoliang.Models.System.LogLevel? logLevel = null, [FromQuery] DateTime? startDate = null, [FromQuery] DateTime? endDate = null, [FromQuery] string category = null) @@ -149,7 +150,7 @@ namespace Haoliang.Api.Controllers try { var logs = await _loggingService.GetLogsAsync(logLevel, startDate, endDate, category); - return Ok(ApiResponse.Success(logs)); + return Ok(ApiResponse.Ok(logs)); } catch (Exception ex) { @@ -164,7 +165,7 @@ namespace Haoliang.Api.Controllers try { var logs = await _loggingService.GetErrorLogsAsync(startDate, endDate); - return Ok(ApiResponse.Success(logs)); + return Ok(ApiResponse.Ok(logs)); } catch (Exception ex) { @@ -175,14 +176,14 @@ namespace Haoliang.Api.Controllers [HttpGet("logs/count")] public async Task GetLogCount( - [FromQuery] LogLevel? logLevel = null, + [FromQuery] Haoliang.Models.System.LogLevel? logLevel = null, [FromQuery] DateTime? startDate = null, [FromQuery] DateTime? endDate = null) { try { var count = await _loggingService.GetLogCountAsync(logLevel, startDate, endDate); - return Ok(ApiResponse.Success(count)); + return Ok(ApiResponse.Ok(count)); } catch (Exception ex) { @@ -197,7 +198,7 @@ namespace Haoliang.Api.Controllers try { await _loggingService.ArchiveLogsAsync(daysToKeep); - return Ok(ApiResponse.Success(null, "Logs archived successfully")); + return Ok(ApiResponse.Ok(null, "Logs archived successfully")); } catch (Exception ex) { @@ -212,7 +213,7 @@ namespace Haoliang.Api.Controllers try { await _loggingService.ClearLogsAsync(); - return Ok(ApiResponse.Success(null, "Logs cleared successfully")); + return Ok(ApiResponse.Ok(null, "Logs cleared successfully")); } catch (Exception ex) { @@ -227,7 +228,7 @@ namespace Haoliang.Api.Controllers try { var tasks = await _schedulerService.GetAllScheduledTasksAsync(); - return Ok(ApiResponse.Success(tasks)); + return Ok(ApiResponse.Ok(tasks)); } catch (Exception ex) { @@ -246,7 +247,7 @@ namespace Haoliang.Api.Controllers { return NotFound(ApiResponse.NotFound("Task not found")); } - return Ok(ApiResponse.Success(task)); + return Ok(ApiResponse.Ok(task)); } catch (Exception ex) { @@ -256,12 +257,12 @@ namespace Haoliang.Api.Controllers } [HttpPost("scheduler/tasks")] - public async Task CreateScheduledTask([FromBody] ScheduledTask task) + public async Task CreateScheduledTask([FromBody] Haoliang.Core.Services.ScheduledTask task) { try { await _schedulerService.ScheduleTaskAsync(task); - return Ok(ApiResponse.Success(task, "Task scheduled successfully")); + return Ok(ApiResponse.Ok(task, "Task scheduled successfully")); } catch (Exception ex) { @@ -276,7 +277,7 @@ namespace Haoliang.Api.Controllers try { await _schedulerService.ExecuteTaskAsync(taskId); - return Ok(ApiResponse.Success(null, "Task execution started")); + return Ok(ApiResponse.Ok(null, "Task execution started")); } catch (Exception ex) { @@ -295,7 +296,7 @@ namespace Haoliang.Api.Controllers { return NotFound(ApiResponse.NotFound("Task not found")); } - return Ok(ApiResponse.Success(null, "Task removed successfully")); + return Ok(ApiResponse.Ok(null, "Task removed successfully")); } catch (Exception ex) { @@ -310,7 +311,7 @@ namespace Haoliang.Api.Controllers try { await _schedulerService.StartSchedulerAsync(); - return Ok(ApiResponse.Success(null, "Scheduler started successfully")); + return Ok(ApiResponse.Ok(null, "Scheduler started successfully")); } catch (Exception ex) { @@ -325,7 +326,7 @@ namespace Haoliang.Api.Controllers try { await _schedulerService.StopSchedulerAsync(); - return Ok(ApiResponse.Success(null, "Scheduler stopped successfully")); + return Ok(ApiResponse.Ok(null, "Scheduler stopped successfully")); } catch (Exception ex) { @@ -352,7 +353,7 @@ namespace Haoliang.Api.Controllers IsHealthy = IsSystemHealthy() }; - return Ok(ApiResponse.Success(status)); + return Ok(ApiResponse.Ok(status)); } catch (Exception ex) { @@ -373,7 +374,7 @@ namespace Haoliang.Api.Controllers Timestamp = DateTime.Now }; - return Ok(ApiResponse.Success(health)); + return Ok(ApiResponse.Ok(health)); } catch (Exception ex) { diff --git a/Haoliang.Api/Controllers/TemplateController.cs b/Haoliang.Api/Controllers/TemplateController.cs index 6de7e71..46849d7 100644 --- a/Haoliang.Api/Controllers/TemplateController.cs +++ b/Haoliang.Api/Controllers/TemplateController.cs @@ -7,6 +7,7 @@ using Haoliang.Core.Services; using Haoliang.Models.Template; using Haoliang.Models.Device; using Haoliang.Models.System; +using Haoliang.Models.Common; namespace Haoliang.Api.Controllers { @@ -37,7 +38,7 @@ namespace Haoliang.Api.Controllers try { var templates = await _templateService.GetAllTemplatesAsync(); - return Ok(ApiResponse.Success(templates)); + return Ok(ApiResponse.Ok(templates)); } catch (Exception ex) { @@ -56,7 +57,7 @@ namespace Haoliang.Api.Controllers { return NotFound(ApiResponse.NotFound("Template not found")); } - return Ok(ApiResponse.Success(template)); + return Ok(ApiResponse.Ok(template)); } catch (Exception ex) { @@ -78,7 +79,7 @@ namespace Haoliang.Api.Controllers } var createdTemplate = await _templateService.CreateTemplateAsync(template); - return Ok(ApiResponse.Success(createdTemplate, "Template created successfully")); + return Ok(ApiResponse.Ok(createdTemplate, "Template created successfully")); } catch (Exception ex) { @@ -106,7 +107,7 @@ namespace Haoliang.Api.Controllers { return NotFound(ApiResponse.NotFound("Template not found")); } - return Ok(ApiResponse.Success(updatedTemplate, "Template updated successfully")); + return Ok(ApiResponse.Ok(updatedTemplate, "Template updated successfully")); } catch (Exception ex) { @@ -125,7 +126,7 @@ namespace Haoliang.Api.Controllers { return NotFound(ApiResponse.NotFound("Template not found")); } - return Ok(ApiResponse.Success(null, "Template deleted successfully")); + return Ok(ApiResponse.Ok(null, "Template deleted successfully")); } catch (Exception ex) { @@ -144,7 +145,7 @@ namespace Haoliang.Api.Controllers { return NotFound(ApiResponse.NotFound("Template not found")); } - return Ok(ApiResponse.Success(null, "Template enabled successfully")); + return Ok(ApiResponse.Ok(null, "Template enabled successfully")); } catch (Exception ex) { @@ -163,7 +164,7 @@ namespace Haoliang.Api.Controllers { return NotFound(ApiResponse.NotFound("Template not found")); } - return Ok(ApiResponse.Success(null, "Template disabled successfully")); + return Ok(ApiResponse.Ok(null, "Template disabled successfully")); } catch (Exception ex) { @@ -178,7 +179,7 @@ namespace Haoliang.Api.Controllers try { var clonedTemplate = await _templateService.CloneTemplateAsync(id, request.NewName); - return Ok(ApiResponse.Success(clonedTemplate, "Template cloned successfully")); + return Ok(ApiResponse.Ok(clonedTemplate, "Template cloned successfully")); } catch (Exception ex) { @@ -193,7 +194,7 @@ namespace Haoliang.Api.Controllers try { await _templateService.TestTemplateAsync(id); - return Ok(ApiResponse.Success(null, "Template test completed")); + return Ok(ApiResponse.Ok(null, "Template test completed")); } catch (Exception ex) { @@ -208,7 +209,7 @@ namespace Haoliang.Api.Controllers try { var templates = await _templateService.GetTemplatesByBrandAsync(brandName); - return Ok(ApiResponse.Success(templates)); + return Ok(ApiResponse.Ok(templates)); } catch (Exception ex) { @@ -223,7 +224,7 @@ namespace Haoliang.Api.Controllers try { var templates = await _templateService.GetActiveTemplatesAsync(); - return Ok(ApiResponse.Success(templates)); + return Ok(ApiResponse.Ok(templates)); } catch (Exception ex) { @@ -245,7 +246,7 @@ namespace Haoliang.Api.Controllers return BadRequest(ApiResponse.Error("Template validation failed", errors)); } - return Ok(ApiResponse.Success(true, "Template validation passed")); + return Ok(ApiResponse.Ok(true, "Template validation passed")); } catch (Exception ex) { @@ -266,7 +267,7 @@ namespace Haoliang.Api.Controllers return BadRequest(ApiResponse.Error("Migration not possible", migrationReport.Issues)); } - return Ok(ApiResponse.Success(migrationReport, "Migration report generated")); + return Ok(ApiResponse.Ok(migrationReport, "Migration report generated")); } catch (Exception ex) { @@ -281,7 +282,7 @@ namespace Haoliang.Api.Controllers try { var mappings = await _tagMappingService.GetMappingsByTemplateAsync(templateId); - return Ok(ApiResponse.Success(mappings)); + return Ok(ApiResponse.Ok(mappings)); } catch (Exception ex) { @@ -296,7 +297,7 @@ namespace Haoliang.Api.Controllers try { var createdMapping = await _tagMappingService.CreateTagMappingAsync(mapping); - return Ok(ApiResponse.Success(createdMapping, "Tag mapping created successfully")); + return Ok(ApiResponse.Ok(createdMapping, "Tag mapping created successfully")); } catch (Exception ex) { @@ -311,7 +312,7 @@ namespace Haoliang.Api.Controllers try { var mappedTags = await _tagMappingService.MapDeviceTagsAsync(request.DeviceTags, request.TemplateId); - return Ok(ApiResponse.Success(mappedTags, "Tag mapping test completed")); + return Ok(ApiResponse.Ok(mappedTags, "Tag mapping test completed")); } catch (Exception ex) { diff --git a/Haoliang.Api/Filters/GlobalExceptionFilter.cs b/Haoliang.Api/Filters/GlobalExceptionFilter.cs index e72a4c5..ac97164 100644 --- a/Haoliang.Api/Filters/GlobalExceptionFilter.cs +++ b/Haoliang.Api/Filters/GlobalExceptionFilter.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; @@ -12,7 +13,7 @@ using Haoliang.Models.Common; namespace Haoliang.Api.Filters { - public class GlobalExceptionFilter : IExceptionFilter + public class GlobalExceptionFilter : IAsyncExceptionFilter { private readonly ILogger _logger; private readonly ILoggingService _loggingService; @@ -23,7 +24,7 @@ namespace Haoliang.Api.Filters _loggingService = loggingService; } - public void OnException(ExceptionContext context) + public async Task OnExceptionAsync(ExceptionContext context) { // Log the exception _logger.LogError(context.Exception, "An unhandled exception occurred"); diff --git a/Haoliang.Api/Filters/JwtAuthorizeFilter.cs b/Haoliang.Api/Filters/JwtAuthorizeFilter.cs index a8b968a..92f7fc2 100644 --- a/Haoliang.Api/Filters/JwtAuthorizeFilter.cs +++ b/Haoliang.Api/Filters/JwtAuthorizeFilter.cs @@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Haoliang.Core.Services; using Haoliang.Models.Common; +using Haoliang.Models.User; namespace Haoliang.Api.Filters { @@ -47,7 +48,7 @@ namespace Haoliang.Api.Filters if (requiredPermissions != null) { - var hasPermission = _permissionService.UserHasPermissionAsync(user.Id, requiredPermissions.PermissionName).Result; + var hasPermission = _permissionService.HasPermissionAsync(user.Id, requiredPermissions.PermissionName).Result; if (!hasPermission) { context.Result = new ForbidResult(); diff --git a/Haoliang.Api/Filters/ValidationFilter.cs b/Haoliang.Api/Filters/ValidationFilter.cs index 7d9585d..05967a9 100644 --- a/Haoliang.Api/Filters/ValidationFilter.cs +++ b/Haoliang.Api/Filters/ValidationFilter.cs @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.ModelBinding; using Haoliang.Core.Services; using Haoliang.Models.Common; +using DataAnnotationsValidationResult = System.ComponentModel.DataAnnotations.ValidationResult; namespace Haoliang.Api.Filters { @@ -129,7 +130,7 @@ namespace Haoliang.Api.Filters public static (bool IsValid, List Errors) ValidateModel(object model) { var validationContext = new ValidationContext(model); - var validationResults = new List(); + var validationResults = new List(); var isValid = Validator.TryValidateObject(model, validationContext, validationResults, true); var errors = validationResults.Select(vr => vr.ErrorMessage).ToList(); diff --git a/Haoliang.Api/Haoliang.Api.csproj b/Haoliang.Api/Haoliang.Api.csproj index 5b044d0..cb56d48 100644 --- a/Haoliang.Api/Haoliang.Api.csproj +++ b/Haoliang.Api/Haoliang.Api.csproj @@ -24,9 +24,9 @@ - - - + + + diff --git a/Haoliang.Api/Hubs/RealTimeHub.cs b/Haoliang.Api/Hubs/RealTimeHub.cs index 68ad6b6..643dae5 100644 --- a/Haoliang.Api/Hubs/RealTimeHub.cs +++ b/Haoliang.Api/Hubs/RealTimeHub.cs @@ -1,11 +1,12 @@ using Microsoft.AspNetCore.SignalR; +using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Concurrent; using System.Threading.Tasks; using Haoliang.Core.Services; -using Haoliang.Models.Models.Device; -using Haoliang.Models.Models.Production; -using Haoliang.Models.Models.System; +using Haoliang.Models.Device; +using Haoliang.Models.Production; +using Haoliang.Models.System; namespace Haoliang.Api.Hubs { @@ -40,14 +41,15 @@ namespace Haoliang.Api.Hubs // Get client information from query parameters var userId = Context.GetHttpContext().Request.Query["userId"]; - var clientType = Context.GetHttpContext().Request.Query["clientType"] ?? "web"; + var clientTypeStr = Context.GetHttpContext().Request.Query["clientType"].ToString(); + var clientType = string.IsNullOrEmpty(clientTypeStr) ? "web" : clientTypeStr; var dashboardId = Context.GetHttpContext().Request.Query["dashboardId"]; var clientInfo = new ClientConnectionInfo { ConnectionId = connectionId, UserId = userId.ToString(), - ClientType = clientType.ToString(), + ClientType = clientType, ConnectedAt = DateTime.UtcNow, LastActivity = DateTime.UtcNow, DashboardId = string.IsNullOrEmpty(dashboardId.ToString()) ? null : dashboardId.ToString(), @@ -400,7 +402,7 @@ namespace Haoliang.Api.Hubs Status = deviceStatus.Status, CurrentProgram = deviceStatus.CurrentProgram, Runtime = deviceStatus.Runtime, - Quantity = production, + Quantity = production?.Quantity ?? 0, Timestamp = DateTime.UtcNow, IntervalMs = intervalMs }; @@ -512,9 +514,9 @@ namespace Haoliang.Api.Hubs { public int DeviceId { get; set; } public string DeviceName { get; set; } - public DeviceStatus Status { get; set; } + public string Status { get; set; } public string CurrentProgram { get; set; } - public TimeSpan Runtime { get; set; } + public string Runtime { get; set; } public decimal Quantity { get; set; } public DateTime Timestamp { get; set; } public int IntervalMs { get; set; } diff --git a/Haoliang.Api/Middleware/RateLimitMiddleware.cs b/Haoliang.Api/Middleware/RateLimitMiddleware.cs index cd9c62d..eca8b7a 100644 --- a/Haoliang.Api/Middleware/RateLimitMiddleware.cs +++ b/Haoliang.Api/Middleware/RateLimitMiddleware.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Concurrent; using System.Linq; +using System.Text.Json; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; diff --git a/Haoliang.Api/Startup.cs b/Haoliang.Api/Startup.cs index d3076af..ff322b1 100644 --- a/Haoliang.Api/Startup.cs +++ b/Haoliang.Api/Startup.cs @@ -14,6 +14,8 @@ using Microsoft.Extensions.Logging; using Pomelo.EntityFrameworkCore.MySql; using Haoliang.Core.Services; using Haoliang.Api.Middleware; +using Haoliang.Api.Hubs; +using Haoliang.Data; using Haoliang.Data.Entities; using Haoliang.Data.Repositories; @@ -51,7 +53,7 @@ namespace Haoliang.Api services.AddSignalR(); // 配置服务依赖注入 - ConfigureServices(services); + RegisterServices(services); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) @@ -65,7 +67,7 @@ namespace Haoliang.Api // 中间件顺序很重要 app.UseMiddleware(); - app.UseMiddleware(); + app.UseCors("AllowAll"); app.UseMiddleware(); app.UseHttpsRedirection(); @@ -81,7 +83,7 @@ namespace Haoliang.Api }); } - private void ConfigureServices(IServiceCollection services) + private void RegisterServices(IServiceCollection services) { // 配置数据库连接 var connectionString = Configuration.GetConnectionString("DefaultConnection"); @@ -113,47 +115,32 @@ namespace Haoliang.Api } // 注册主要数据库上下文(用于业务操作) - services.AddDbContext(options => - options.UseMySql(connectionString, - ServerVersion.AutoDetect(connectionString), - mysqlOptions => mysqlOptions.EnableRetryOnFailure( - maxRetryCount: 3, - maxRetryDelay: TimeSpan.FromSeconds(30), - errorNumbersToAdd: null))); - - // 配置数据库连接池 - services.AddDbContextPool(options => - options.UseMySql(connectionString, - ServerVersion.AutoDetect(connectionString), - mysqlOptions => mysqlOptions.EnableRetryOnFailure( - maxRetryCount: 3, - maxRetryDelay: TimeSpan.FromSeconds(30), - errorNumbersToAdd: null))); + // 注意:DbContext 在下方统一注册一次,避免重复实例化 // 配置内存缓存 services.AddMemoryCache(); services.AddDistributedMemoryCache(); - // 注册缓存服务 - services.AddSingleton(); + // 注册缓存服务(使用Scoped生命周期以支持依赖注入) + services.AddScoped(); // 注册状态机服务 - services.AddHostedService(); + services.AddSingleton(); + services.AddHostedService(sp => sp.GetRequiredService()); // 注册服务 services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); - services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); - services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); - services.AddScoped(); - services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); @@ -168,27 +155,18 @@ namespace Haoliang.Api // 注册后台任务服务 services.AddHostedService(); - // 注册仓储 + // 注册仓储 (仅注册存在的) services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - - // 注册设备状态相关仓储 - services.AddScoped(); // 注册Ping服务 services.AddScoped(); @@ -197,6 +175,7 @@ namespace Haoliang.Api services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); // 注册SignalR Hub services.AddSingleton(); diff --git a/Haoliang.Core/Services/IServices.cs b/Haoliang.Core/Services/IServices.cs index b3b9109..99f03fa 100644 --- a/Haoliang.Core/Services/IServices.cs +++ b/Haoliang.Core/Services/IServices.cs @@ -70,6 +70,13 @@ namespace Haoliang.Core.Services /// 邮箱地址 /// 是否存在 Task EmailExistsAsync(string email); + + /// + /// 根据ID获取用户 + /// + /// 用户ID + /// 用户信息 + Task GetUserByIdAsync(int userId); } /// @@ -237,6 +244,12 @@ namespace Haoliang.Core.Services /// 清除所有日志 /// Task ClearLogsAsync(); + + /// + /// 记录信息日志 (LogInfoAsync的别名) + /// + /// 日志消息 + Task LogInfoAsync(string message); } /// @@ -384,6 +397,13 @@ namespace Haoliang.Core.Services /// 设备ID /// 健康状态信息 Task GetDeviceHealthAsync(int deviceId); + + /// + /// 获取设备当前状态 + /// + /// 设备ID + /// 设备当前状态信息 + Task GetDeviceCurrentStatusAsync(int deviceId); } /// @@ -518,10 +538,13 @@ namespace Haoliang.Core.Services public class DeviceStatus { public int DeviceId { get; set; } + public string? DeviceName { get; set; } public string? Status { get; set; } public DateTime Timestamp { get; set; } public string? OperatingMode { get; set; } public string? RunState { get; set; } + public string? CurrentProgram { get; set; } + public string? Runtime { get; set; } } #endregion @@ -613,6 +636,14 @@ namespace Haoliang.Core.Services /// /// 保留天数 Task ArchiveProductionDataAsync(int daysToKeep = 90); + + /// + /// 获取设备指定日期的生产数据 + /// + /// 设备ID + /// 日期 + /// 生产数据 + Task GetDeviceProductionForDateAsync(int deviceId, DateTime date); } /// @@ -1308,6 +1339,116 @@ namespace Haoliang.Core.Services /// 刷新配置缓存 /// Task RefreshConfigCacheAsync(); + + /// + /// 获取系统配置 + /// + Task GetSystemConfigurationAsync(); + + /// + /// 更新系统配置 + /// + Task UpdateSystemConfigurationAsync(object configuration); + + /// + /// 验证配置 + /// + Task ValidateConfigurationAsync(object configuration); + + /// + /// 获取生产目标配置 + /// + Task> GetProductionTargetsAsync(); + + /// + /// 更新生产目标配置 + /// + Task UpdateProductionTargetsAsync(IEnumerable targets); + + /// + /// 获取工作小时配置 + /// + Task GetWorkingHoursConfigAsync(); + + /// + /// 更新工作小时配置 + /// + Task UpdateWorkingHoursConfigAsync(object config); + + /// + /// 获取告警配置 + /// + Task GetAlertConfigurationAsync(); + + /// + /// 更新告警配置 + /// + Task UpdateAlertConfigurationAsync(object config); + + /// + /// 获取通知配置 + /// + Task GetNotificationConfigAsync(); + + /// + /// 更新通知配置 + /// + Task UpdateNotificationConfigAsync(object config); + + /// + /// 获取导出配置 + /// + Task GetExportConfigAsync(); + + /// + /// 更新导出配置 + /// + Task UpdateExportConfigAsync(object config); + + /// + /// 获取数据保留配置 + /// + Task GetDataRetentionConfigAsync(); + + /// + /// 更新数据保留配置 + /// + Task UpdateDataRetentionConfigAsync(object config); + + /// + /// 获取仪表盘配置 + /// + Task GetDashboardConfigAsync(); + + /// + /// 更新仪表盘配置 + /// + Task UpdateDashboardConfigAsync(object config); + + /// + /// 获取采集配置 + /// + Task GetCollectionConfigAsync(); + + /// + /// 更新采集配置 + /// + Task UpdateCollectionConfigAsync(object config); + + /// + /// 导入配置 + /// + Task ImportConfigurationAsync(string configuration); + + /// + /// 重置为默认配置 + /// + Task ResetToDefaultConfigurationAsync(); + + /// + /// 获取配置变更历史 + /// + Task> GetConfigurationChangeHistoryAsync(DateTime? startDate = null, DateTime? endDate = null); } /// @@ -1651,19 +1792,34 @@ namespace Haoliang.Core.Services /// 结束时间 /// 执行历史 Task> GetRuleExecutionHistoryAsync(int ruleId, DateTime fromTime, DateTime toTime); + + /// + /// 创建或更新规则 + /// + Task CreateOrUpdateRuleAsync(BusinessRule rule); + + /// + /// 获取统计规则 + /// + Task> GetStatisticsRulesAsync(); + + /// + /// 更新统计规则 + /// + Task UpdateStatisticsRulesAsync(IEnumerable rules); } /// - /// 业务规则 + /// 业务规则 (与 Haoliang.Models.System.BusinessRuleConfig 同结构) /// public class BusinessRule { public int RuleId { get; set; } - public string? Name { get; set; } - public string? Description { get; set; } + public string? RuleName { get; set; } + public string? RuleType { get; set; } public string? Category { get; set; } - public string? Expression { get; set; } public bool IsEnabled { get; set; } + public string? Configuration { get; set; } public DateTime CreatedAt { get; set; } public DateTime UpdatedAt { get; set; } } diff --git a/Haoliang.Core/Services/StubServices.cs b/Haoliang.Core/Services/StubServices.cs index 5d4ed90..3fdafa2 100644 --- a/Haoliang.Core/Services/StubServices.cs +++ b/Haoliang.Core/Services/StubServices.cs @@ -21,6 +21,7 @@ namespace Haoliang.Core.Services public Task RefreshTokenAsync(string refreshToken) => Task.FromResult(null); public Task UsernameExistsAsync(string username) => Task.FromResult(false); public Task EmailExistsAsync(string email) => Task.FromResult(false); + public Task GetUserByIdAsync(int userId) => Task.FromResult(null); } public class UserService : IUserService @@ -54,6 +55,7 @@ namespace Haoliang.Core.Services public Task GetLogCountAsync(Haoliang.Models.System.LogLevel? logLevel = null, DateTime? startDate = null, DateTime? endDate = null) => Task.FromResult(0); public Task ArchiveLogsAsync(int daysToKeep = 90) => Task.CompletedTask; public Task ClearLogsAsync() => Task.CompletedTask; + public Task LogInfoAsync(string message) { Console.WriteLine($"[INFO] {message}"); return Task.CompletedTask; } } public class MemoryCacheService : ICacheService @@ -81,14 +83,18 @@ namespace Haoliang.Core.Services public Task CollectAllDevicesAsync() => Task.CompletedTask; public Task GetDeviceStatusAsync(int deviceId) => Task.FromResult(new DeviceStatus()); public Task GetDeviceHealthAsync(int deviceId) => Task.FromResult(new DeviceHealth()); + public Task GetDeviceCurrentStatusAsync(int deviceId) => Task.FromResult(new DeviceStatus()); } - public class DeviceStateMachine : IDeviceStateMachine + public class DeviceStateMachine : IDeviceStateMachine, IHostedService { public DeviceStatus GetCurrentState(int deviceId) => new DeviceStatus(); public bool TransitionTo(int deviceId, DeviceStatus newState) => false; public void RegisterStateChangeHandler(int deviceId, Action callback) { } public IEnumerable GetStateHistory(int deviceId, DateTime fromTime, DateTime toTime) => new List(); + + public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask; + public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; } public class PingService : IPingService @@ -113,6 +119,7 @@ namespace Haoliang.Core.Services public Task GetProgramProductionAsync(string programName, DateTime date) => Task.FromResult(null); public Task ExportProductionDataAsync(DateTime startDate, DateTime endDate) => Task.FromResult(null); public Task ArchiveProductionDataAsync(int daysToKeep = 90) => Task.CompletedTask; + public Task GetDeviceProductionForDateAsync(int deviceId, DateTime date) => Task.FromResult(null); } public class ProductionCalculator : IProductionCalculator @@ -245,6 +252,28 @@ namespace Haoliang.Core.Services public Task ConfigExistsAsync(string key) => Task.FromResult(false); public Task> GetConfigsByCategoryAsync(string category) => Task.FromResult>(new List()); public Task RefreshConfigCacheAsync() => Task.CompletedTask; + public Task GetSystemConfigurationAsync() => Task.FromResult(null); + public Task UpdateSystemConfigurationAsync(object configuration) => Task.FromResult(false); + public Task ValidateConfigurationAsync(object configuration) => Task.FromResult(false); + public Task> GetProductionTargetsAsync() => Task.FromResult>(new List()); + public Task UpdateProductionTargetsAsync(IEnumerable targets) => Task.FromResult(false); + public Task GetWorkingHoursConfigAsync() => Task.FromResult(null); + public Task UpdateWorkingHoursConfigAsync(object config) => Task.FromResult(false); + public Task GetAlertConfigurationAsync() => Task.FromResult(null); + public Task UpdateAlertConfigurationAsync(object config) => Task.FromResult(false); + public Task GetNotificationConfigAsync() => Task.FromResult(null); + public Task UpdateNotificationConfigAsync(object config) => Task.FromResult(false); + public Task GetExportConfigAsync() => Task.FromResult(null); + public Task UpdateExportConfigAsync(object config) => Task.FromResult(false); + public Task GetDataRetentionConfigAsync() => Task.FromResult(null); + public Task UpdateDataRetentionConfigAsync(object config) => Task.FromResult(false); + public Task GetDashboardConfigAsync() => Task.FromResult(null); + public Task UpdateDashboardConfigAsync(object config) => Task.FromResult(false); + public Task GetCollectionConfigAsync() => Task.FromResult(null); + public Task UpdateCollectionConfigAsync(object config) => Task.FromResult(false); + public Task ImportConfigurationAsync(string configuration) => Task.FromResult(false); + public Task ResetToDefaultConfigurationAsync() => Task.FromResult(false); + public Task> GetConfigurationChangeHistoryAsync(DateTime? startDate = null, DateTime? endDate = null) => Task.FromResult>(new List()); } public class SchedulerService : ISchedulerService @@ -289,6 +318,9 @@ namespace Haoliang.Core.Services public Task ExecuteRuleAsync(int ruleId, Dictionary context) => Task.FromResult(null); public Task TestRuleAsync(int ruleId, Dictionary testData) => Task.FromResult(null); public Task> GetRuleExecutionHistoryAsync(int ruleId, DateTime fromTime, DateTime toTime) => Task.FromResult>(new List()); + public Task CreateOrUpdateRuleAsync(BusinessRule rule) => Task.FromResult(rule); + public Task> GetStatisticsRulesAsync() => Task.FromResult>(new List()); + public Task UpdateStatisticsRulesAsync(IEnumerable rules) => Task.FromResult(false); } public class DataParserService : IDataParserService diff --git a/Haoliang.Models/Common/CommonModels.cs b/Haoliang.Models/Common/CommonModels.cs index 88d749d..ac6ed8a 100644 --- a/Haoliang.Models/Common/CommonModels.cs +++ b/Haoliang.Models/Common/CommonModels.cs @@ -45,6 +45,21 @@ namespace Haoliang.Models.Common }; } + /// + /// 创建错误响应(带错误详情列表) + /// + public static ApiResponse Error(string? message, IEnumerable? errors, int errorCode = 500) + { + return new ApiResponse + { + Success = false, + Message = message ?? "Error", + ErrorCode = errorCode, + Data = errors?.ToList(), + Timestamp = DateTime.Now + }; + } + /// /// 创建未找到响应 /// diff --git a/Haoliang.Models/Device/CNCDevice.cs b/Haoliang.Models/Device/CNCDevice.cs index 38c4b50..9e3aaff 100644 --- a/Haoliang.Models/Device/CNCDevice.cs +++ b/Haoliang.Models/Device/CNCDevice.cs @@ -6,6 +6,7 @@ namespace Haoliang.Models.Device public class CNCDevice { public int Id { get; set; } + public int DeviceId { get => Id; set => Id = value; } public string DeviceCode { get; set; } public string DeviceName { get; set; } public string IPAddress { get; set; } diff --git a/Haoliang.Models/Template/CNCBrandTemplate.cs b/Haoliang.Models/Template/CNCBrandTemplate.cs index 838ebba..de4009d 100644 --- a/Haoliang.Models/Template/CNCBrandTemplate.cs +++ b/Haoliang.Models/Template/CNCBrandTemplate.cs @@ -6,6 +6,7 @@ namespace Haoliang.Models.Template public class CNCBrandTemplate { public int Id { get; set; } + public int TemplateId { get => Id; set => Id = value; } public string BrandName { get; set; } public string Description { get; set; } public bool IsEnabled { get; set; } diff --git a/Haoliang.Models/User/AuthModels.cs b/Haoliang.Models/User/AuthModels.cs index d6e778f..ff33db0 100644 --- a/Haoliang.Models/User/AuthModels.cs +++ b/Haoliang.Models/User/AuthModels.cs @@ -101,7 +101,9 @@ namespace Haoliang.Models.User public string RealName { get; set; } public string Email { get; set; } public string Phone { get; set; } + public string Role { get; set; } public string RoleName { get; set; } + public string Department { get; set; } public bool IsActive { get; set; } public DateTime? LastLoginTime { get; set; } public DateTime CreatedAt { get; set; } diff --git a/Haoliang.Models/User/User.cs b/Haoliang.Models/User/User.cs index d015fd5..3a3c458 100644 --- a/Haoliang.Models/User/User.cs +++ b/Haoliang.Models/User/User.cs @@ -9,9 +9,12 @@ namespace Haoliang.Models.User public string Username { get; set; } public string PasswordHash { get; set; } public string RealName { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } public string Email { get; set; } public string Phone { get; set; } public int RoleId { get; set; } + public string Department { get; set; } public bool IsActive { get; set; } public DateTime? LastLoginTime { get; set; } public DateTime CreatedAt { get; set; } @@ -55,6 +58,7 @@ namespace Haoliang.Models.User { public string Username { get; set; } public string Password { get; set; } + public bool RememberMe { get; set; } } public class LoginResponse