修复编译错误,完成.NET 8.0升级

主要修复内容:
1. RealTimeController: 修复IEnumerable<int>转List<int>及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别名属性
main
821644@qq.com 3 weeks ago
parent 8022fafd55
commit ade24d7a9b

@ -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)
{

@ -45,7 +45,7 @@ namespace Haoliang.Api.Controllers
if (result.Success)
{
await _loggingService.LogInformationAsync($"User {request.Username} logged in successfully");
return Ok(ApiResponse<AuthResult>.Success(result));
return Ok(ApiResponse<AuthResult>.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<bool>.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<bool>.Success(true));
return Ok(ApiResponse<bool>.Ok(true));
}
else
{
@ -103,7 +103,7 @@ namespace Haoliang.Api.Controllers
if (result.Success)
{
return Ok(ApiResponse<AuthResult>.Success(result));
return Ok(ApiResponse<AuthResult>.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<UserViewModel>.Success(userViewModel));
return Ok(ApiResponse<UserViewModel>.Ok(userViewModel));
}
catch (Exception ex)
{
@ -185,7 +185,7 @@ namespace Haoliang.Api.Controllers
return NotFound(ApiResponse<UserViewModel>.Error("User not found", 404));
}
return Ok(ApiResponse<UserViewModel>.Success(user));
return Ok(ApiResponse<UserViewModel>.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<UserViewModel>.Success(updatedUser));
return Ok(ApiResponse<UserViewModel>.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<bool>.Success(true));
return Ok(ApiResponse<bool>.Ok(true));
}
else
{
@ -282,7 +282,7 @@ namespace Haoliang.Api.Controllers
}
var permissions = await _permissionService.GetUserPermissionsAsync(userId.Value);
return Ok(ApiResponse<IEnumerable<string>>.Success(permissions));
return Ok(ApiResponse<IEnumerable<string>>.Ok(permissions));
}
catch (Exception ex)
{
@ -354,7 +354,7 @@ namespace Haoliang.Api.Controllers
return NotFound(ApiResponse<UserViewModel>.Error("User not found", 404));
}
return Ok(ApiResponse<UserViewModel>.Success(user));
return Ok(ApiResponse<UserViewModel>.Ok(user));
}
catch (Exception ex)
{
@ -372,7 +372,7 @@ namespace Haoliang.Api.Controllers
if (success)
{
await _loggingService.LogInformationAsync($"User activated: {id}");
return Ok(ApiResponse<bool>.Success(true));
return Ok(ApiResponse<bool>.Ok(true));
}
else
{
@ -395,7 +395,7 @@ namespace Haoliang.Api.Controllers
if (success)
{
await _loggingService.LogInformationAsync($"User deactivated: {id}");
return Ok(ApiResponse<bool>.Success(true));
return Ok(ApiResponse<bool>.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; }

@ -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<SystemConfiguration>.Success(config));
return Ok(ApiResponse<SystemConfiguration>.Ok(config));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<SystemConfiguration>.InternalServerError($"Error getting system configuration: {ex.Message}"));
return StatusCode(500, ApiResponse<SystemConfiguration>.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<bool>.Success(result));
return Ok(ApiResponse<bool>.Ok(result));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error updating system configuration: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.InternalServerErrorResult($"Error updating system configuration: {ex.Message}"));
}
}
@ -74,7 +76,7 @@ namespace Haoliang.Api.Controllers
try
{
var targets = await _systemService.GetProductionTargetsAsync();
return Ok(ApiResponse<List<ProductionTargetConfig>>.Success(targets));
return Ok(ApiResponse<List<ProductionTargetConfig>>.Ok(targets));
}
catch (Exception ex)
{
@ -91,11 +93,11 @@ namespace Haoliang.Api.Controllers
try
{
var result = await _systemService.UpdateProductionTargetsAsync(targets);
return Ok(ApiResponse<bool>.Success(result));
return Ok(ApiResponse<bool>.Ok(result));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error updating production targets: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.InternalServerErrorResult($"Error updating production targets: {ex.Message}"));
}
}
@ -108,11 +110,11 @@ namespace Haoliang.Api.Controllers
try
{
var config = await _systemService.GetWorkingHoursConfigAsync();
return Ok(ApiResponse<WorkingHoursConfig>.Success(config));
return Ok(ApiResponse<WorkingHoursConfig>.Ok(config));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<WorkingHoursConfig>.InternalServerError($"Error getting working hours config: {ex.Message}"));
return StatusCode(500, ApiResponse<WorkingHoursConfig>.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<bool>.Success(result));
return Ok(ApiResponse<bool>.Ok(result));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error updating working hours config: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.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<AlertConfiguration>.Success(config));
return Ok(ApiResponse<AlertConfiguration>.Ok(config));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<AlertConfiguration>.InternalServerError($"Error getting alert configuration: {ex.Message}"));
return StatusCode(500, ApiResponse<AlertConfiguration>.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<bool>.Success(result));
return Ok(ApiResponse<bool>.Ok(result));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error updating alert configuration: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.InternalServerErrorResult($"Error updating alert configuration: {ex.Message}"));
}
}
@ -171,16 +173,27 @@ namespace Haoliang.Api.Controllers
/// Get business rules configuration
/// </summary>
[HttpGet("rules")]
public async Task<ActionResult<ApiResponse<List<BusinessRuleConfig>>>> GetBusinessRules()
public async Task<ActionResult<ApiResponse<List<Haoliang.Models.System.BusinessRuleConfig>>>> GetBusinessRules()
{
try
{
var rules = await _rulesService.GetAllRulesAsync();
return Ok(ApiResponse<List<BusinessRuleConfig>>.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<List<Haoliang.Models.System.BusinessRuleConfig>>.Ok(ruleConfigs));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<List<BusinessRuleConfig>>.InternalServerError($"Error getting business rules: {ex.Message}"));
return StatusCode(500, ApiResponse<List<Haoliang.Models.System.BusinessRuleConfig>>.InternalServerError($"Error getting business rules: {ex.Message}"));
}
}
@ -188,16 +201,38 @@ namespace Haoliang.Api.Controllers
/// Create or update business rule
/// </summary>
[HttpPost("rules")]
public async Task<ActionResult<ApiResponse<BusinessRuleConfig>>> CreateOrUpdateBusinessRule([FromBody] BusinessRuleConfig rule)
public async Task<ActionResult<ApiResponse<Haoliang.Models.System.BusinessRuleConfig>>> CreateOrUpdateBusinessRule([FromBody] Haoliang.Models.System.BusinessRuleConfig rule)
{
try
{
var result = await _rulesService.CreateOrUpdateRuleAsync(rule);
return Ok(ApiResponse<BusinessRuleConfig>.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<Haoliang.Models.System.BusinessRuleConfig>.Ok(resultConfig));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<BusinessRuleConfig>.InternalServerError($"Error creating/updating business rule: {ex.Message}"));
return StatusCode(500, ApiResponse<Haoliang.Models.System.BusinessRuleConfig>.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<bool>.Success(result));
return Ok(ApiResponse<bool>.Ok(result));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error deleting business rule: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.InternalServerErrorResult($"Error deleting business rule: {ex.Message}"));
}
}
@ -222,16 +257,27 @@ namespace Haoliang.Api.Controllers
/// Get statistical analysis rules
/// </summary>
[HttpGet("statistics-rules")]
public async Task<ActionResult<ApiResponse<List<StatisticsRuleConfig>>>> GetStatisticsRules()
public async Task<ActionResult<ApiResponse<List<Haoliang.Models.System.StatisticsRuleConfig>>>> GetStatisticsRules()
{
try
{
var rules = await _rulesService.GetStatisticsRulesAsync();
return Ok(ApiResponse<List<StatisticsRuleConfig>>.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<List<Haoliang.Models.System.StatisticsRuleConfig>>.Ok(ruleConfigs));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<List<StatisticsRuleConfig>>.InternalServerError($"Error getting statistics rules: {ex.Message}"));
return StatusCode(500, ApiResponse<List<Haoliang.Models.System.StatisticsRuleConfig>>.InternalServerError($"Error getting statistics rules: {ex.Message}"));
}
}
@ -239,16 +285,27 @@ namespace Haoliang.Api.Controllers
/// Update statistics rules
/// </summary>
[HttpPut("statistics-rules")]
public async Task<ActionResult<ApiResponse<bool>>> UpdateStatisticsRules([FromBody] List<StatisticsRuleConfig> rules)
public async Task<ActionResult<ApiResponse<bool>>> UpdateStatisticsRules([FromBody] List<Haoliang.Models.System.StatisticsRuleConfig> rules)
{
try
{
var result = await _rulesService.UpdateStatisticsRulesAsync(rules);
return Ok(ApiResponse<bool>.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<bool>.Ok(result));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error updating statistics rules: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.InternalServerErrorResult($"Error updating statistics rules: {ex.Message}"));
}
}
@ -261,11 +318,11 @@ namespace Haoliang.Api.Controllers
try
{
var config = await _systemService.GetDataRetentionConfigAsync();
return Ok(ApiResponse<DataRetentionConfig>.Success(config));
return Ok(ApiResponse<DataRetentionConfig>.Ok(config));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<DataRetentionConfig>.InternalServerError($"Error getting data retention config: {ex.Message}"));
return StatusCode(500, ApiResponse<DataRetentionConfig>.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<bool>.Success(result));
return Ok(ApiResponse<bool>.Ok(result));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error updating data retention config: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.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<DashboardConfig>.Success(config));
return Ok(ApiResponse<DashboardConfig>.Ok(config));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<DashboardConfig>.InternalServerError($"Error getting dashboard config: {ex.Message}"));
return StatusCode(500, ApiResponse<DashboardConfig>.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<bool>.Success(result));
return Ok(ApiResponse<bool>.Ok(result));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error updating dashboard config: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.InternalServerErrorResult($"Error updating dashboard config: {ex.Message}"));
}
}
@ -329,11 +386,11 @@ namespace Haoliang.Api.Controllers
try
{
var config = await _systemService.GetExportConfigAsync();
return Ok(ApiResponse<ExportConfig>.Success(config));
return Ok(ApiResponse<ExportConfig>.Ok(config));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<ExportConfig>.InternalServerError($"Error getting export config: {ex.Message}"));
return StatusCode(500, ApiResponse<ExportConfig>.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<bool>.Success(result));
return Ok(ApiResponse<bool>.Ok(result));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error updating export config: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.InternalServerErrorResult($"Error updating export config: {ex.Message}"));
}
}
@ -363,11 +420,11 @@ namespace Haoliang.Api.Controllers
try
{
var config = await _systemService.GetCollectionConfigAsync();
return Ok(ApiResponse<CollectionConfig>.Success(config));
return Ok(ApiResponse<CollectionConfig>.Ok(config));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<CollectionConfig>.InternalServerError($"Error getting collection config: {ex.Message}"));
return StatusCode(500, ApiResponse<CollectionConfig>.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<bool>.Success(result));
return Ok(ApiResponse<bool>.Ok(result));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error updating collection config: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.InternalServerErrorResult($"Error updating collection config: {ex.Message}"));
}
}
@ -397,11 +454,11 @@ namespace Haoliang.Api.Controllers
try
{
var config = await _systemService.GetNotificationConfigAsync();
return Ok(ApiResponse<NotificationConfig>.Success(config));
return Ok(ApiResponse<NotificationConfig>.Ok(config));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<NotificationConfig>.InternalServerError($"Error getting notification config: {ex.Message}"));
return StatusCode(500, ApiResponse<NotificationConfig>.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<bool>.Success(result));
return Ok(ApiResponse<bool>.Ok(result));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error updating notification config: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.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<ValidationResult>.Success(result));
return Ok(ApiResponse<ValidationResult>.Ok(result));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<ValidationResult>.InternalServerError($"Error validating configuration: {ex.Message}"));
return StatusCode(500, ApiResponse<ValidationResult>.InternalServerErrorResult($"Error validating configuration: {ex.Message}"));
}
}
@ -469,12 +526,13 @@ namespace Haoliang.Api.Controllers
{
try
{
var result = await _systemService.ImportConfigurationAsync(configuration);
return Ok(ApiResponse<bool>.Success(result));
var json = System.Text.Json.JsonSerializer.Serialize(configuration);
var result = await _systemService.ImportConfigurationAsync(json);
return Ok(ApiResponse<bool>.Ok(result));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error importing configuration: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.InternalServerErrorResult($"Error importing configuration: {ex.Message}"));
}
}
@ -487,11 +545,11 @@ namespace Haoliang.Api.Controllers
try
{
var result = await _systemService.ResetToDefaultConfigurationAsync();
return Ok(ApiResponse<bool>.Success(result));
return Ok(ApiResponse<bool>.Ok(result));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error resetting configuration: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.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<List<ConfigurationChange>>.Success(history));
return Ok(ApiResponse<List<ConfigurationChange>>.Ok(history));
}
catch (Exception ex)
{

@ -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)
{

@ -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)
{

@ -27,11 +27,11 @@ namespace Haoliang.Api.Controllers
try
{
var count = await _realTimeService.GetConnectedClientsCountAsync();
return Ok(ApiResponse<int>.Success(count));
return Ok(ApiResponse<int>.Ok(count));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<int>.InternalServerError($"Error getting connected clients count: {ex.Message}"));
return StatusCode(500, ApiResponse<int>.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<List<ClientInfo>>.Success(clients));
return Ok(ApiResponse<List<ClientInfo>>.Ok(clients));
}
catch (Exception ex)
{
@ -61,11 +61,11 @@ namespace Haoliang.Api.Controllers
try
{
var status = await _realTimeService.GetDeviceMonitoringStatusAsync(deviceId);
return Ok(ApiResponse<DeviceMonitoringStatus>.Success(status));
return Ok(ApiResponse<DeviceMonitoringStatus>.Ok(status));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<DeviceMonitoringStatus>.InternalServerError($"Error getting device monitoring status: {ex.Message}"));
return StatusCode(500, ApiResponse<DeviceMonitoringStatus>.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<bool>.Success(true));
return Ok(ApiResponse<bool>.Ok(true));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error starting device streaming: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.InternalServerErrorResult($"Error starting device streaming: {ex.Message}"));
}
}
@ -97,11 +97,11 @@ namespace Haoliang.Api.Controllers
try
{
await _realTimeService.StopDeviceStreamingAsync(deviceId);
return Ok(ApiResponse<bool>.Success(true));
return Ok(ApiResponse<bool>.Ok(true));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error stopping device streaming: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.InternalServerErrorResult($"Error stopping device streaming: {ex.Message}"));
}
}
@ -114,7 +114,7 @@ namespace Haoliang.Api.Controllers
try
{
var devices = await _realTimeService.GetActiveStreamingDevicesAsync();
return Ok(ApiResponse<List<int>>.Success(devices));
return Ok(ApiResponse<List<int>>.Ok(devices));
}
catch (Exception ex)
{
@ -136,11 +136,11 @@ namespace Haoliang.Api.Controllers
statusUpdate.Timestamp = DateTime.UtcNow;
await _realTimeService.BroadcastDeviceStatusAsync(statusUpdate);
return Ok(ApiResponse<bool>.Success(true));
return Ok(ApiResponse<bool>.Ok(true));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error sending device status update: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.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<bool>.Success(true));
return Ok(ApiResponse<bool>.Ok(true));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error sending production update: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.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<bool>.Success(true));
return Ok(ApiResponse<bool>.Ok(true));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error sending alert: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.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<bool>.Success(true));
return Ok(ApiResponse<bool>.Ok(true));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error sending system notification: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.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<bool>.Success(true));
return Ok(ApiResponse<bool>.Ok(true));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error sending dashboard update: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.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<bool>.Success(true));
return Ok(ApiResponse<bool>.Ok(true));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error sending command to client: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.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<bool>.Success(true));
return Ok(ApiResponse<bool>.Ok(true));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error broadcasting command: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.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<string>.Success(connectionUrl));
return Ok(ApiResponse<string>.Ok(connectionUrl));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<string>.InternalServerError($"Error getting connection URL: {ex.Message}"));
return StatusCode(500, ApiResponse<string>.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<TestResult>.Success(testResult));
return Ok(ApiResponse<TestResult>.Ok(testResult));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<TestResult>.InternalServerError($"Error testing WebSocket: {ex.Message}"));
return StatusCode(500, ApiResponse<TestResult>.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<WebSocketStatistics>.Success(stats));
return Ok(ApiResponse<WebSocketStatistics>.Ok(stats));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<WebSocketStatistics>.InternalServerError($"Error getting WebSocket statistics: {ex.Message}"));
return StatusCode(500, ApiResponse<WebSocketStatistics>.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<bool>.Success(true));
return Ok(ApiResponse<bool>.Ok(true));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<bool>.InternalServerError($"Error refreshing dashboard data: {ex.Message}"));
return StatusCode(500, ApiResponse<bool>.InternalServerErrorResult($"Error refreshing dashboard data: {ex.Message}"));
}
}
}

@ -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<ProductionTrendAnalysis>.BadRequest("Invalid device ID"));
return BadRequest(ApiResponse<ProductionTrendAnalysis>.BadRequestResult("Invalid device ID"));
if (startDate >= endDate)
return BadRequest(ApiResponse<ProductionTrendAnalysis>.BadRequest("Start date must be before end date"));
return BadRequest(ApiResponse<ProductionTrendAnalysis>.BadRequestResult("Start date must be before end date"));
var result = await _statisticsService.CalculateProductionTrendsAsync(deviceId, startDate, endDate);
return Ok(ApiResponse<ProductionTrendAnalysis>.Success(result));
return Ok(ApiResponse<ProductionTrendAnalysis>.Ok(result));
}
catch (KeyNotFoundException ex)
{
@ -47,7 +47,7 @@ namespace Haoliang.Api.Controllers
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<ProductionTrendAnalysis>.InternalServerError($"Error calculating production trends: {ex.Message}"));
return StatusCode(500, ApiResponse<ProductionTrendAnalysis>.InternalServerErrorResult($"Error calculating production trends: {ex.Message}"));
}
}
@ -60,15 +60,15 @@ namespace Haoliang.Api.Controllers
try
{
if (filter.StartDate >= filter.EndDate)
return BadRequest(ApiResponse<ProductionReport>.BadRequest("Start date must be before end date"));
return BadRequest(ApiResponse<ProductionReport>.BadRequestResult("Start date must be before end date"));
var result = await _statisticsService.GenerateProductionReportAsync(filter);
return Ok(ApiResponse<ProductionReport>.Success(result));
return Ok(ApiResponse<ProductionReport>.Ok(result));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<ProductionReport>.InternalServerError($"Error generating production report: {ex.Message}"));
return StatusCode(500, ApiResponse<ProductionReport>.InternalServerErrorResult($"Error generating production report: {ex.Message}"));
}
}
@ -81,15 +81,15 @@ namespace Haoliang.Api.Controllers
try
{
if (filter.StartDate >= filter.EndDate)
return BadRequest(ApiResponse<EfficiencyMetrics>.BadRequest("Start date must be before end date"));
return BadRequest(ApiResponse<EfficiencyMetrics>.BadRequestResult("Start date must be before end date"));
var result = await _statisticsService.CalculateEfficiencyMetricsAsync(filter);
return Ok(ApiResponse<EfficiencyMetrics>.Success(result));
return Ok(ApiResponse<EfficiencyMetrics>.Ok(result));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<EfficiencyMetrics>.InternalServerError($"Error calculating efficiency metrics: {ex.Message}"));
return StatusCode(500, ApiResponse<EfficiencyMetrics>.InternalServerErrorResult($"Error calculating efficiency metrics: {ex.Message}"));
}
}
@ -102,15 +102,15 @@ namespace Haoliang.Api.Controllers
try
{
if (filter.StartDate >= filter.EndDate)
return BadRequest(ApiResponse<QualityAnalysis>.BadRequest("Start date must be before end date"));
return BadRequest(ApiResponse<QualityAnalysis>.BadRequestResult("Start date must be before end date"));
var result = await _statisticsService.PerformQualityAnalysisAsync(filter);
return Ok(ApiResponse<QualityAnalysis>.Success(result));
return Ok(ApiResponse<QualityAnalysis>.Ok(result));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<QualityAnalysis>.InternalServerError($"Error performing quality analysis: {ex.Message}"));
return StatusCode(500, ApiResponse<QualityAnalysis>.InternalServerErrorResult($"Error performing quality analysis: {ex.Message}"));
}
}
@ -124,11 +124,11 @@ namespace Haoliang.Api.Controllers
{
var result = await _statisticsService.GetDashboardSummaryAsync(filter);
return Ok(ApiResponse<DashboardSummary>.Success(result));
return Ok(ApiResponse<DashboardSummary>.Ok(result));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<DashboardSummary>.InternalServerError($"Error getting dashboard summary: {ex.Message}"));
return StatusCode(500, ApiResponse<DashboardSummary>.InternalServerErrorResult($"Error getting dashboard summary: {ex.Message}"));
}
}
@ -143,19 +143,19 @@ namespace Haoliang.Api.Controllers
try
{
if (deviceId <= 0)
return BadRequest(ApiResponse<OeeMetrics>.BadRequest("Invalid device ID"));
return BadRequest(ApiResponse<OeeMetrics>.BadRequestResult("Invalid device ID"));
var result = await _statisticsService.CalculateOeeAsync(deviceId, date);
return Ok(ApiResponse<OeeMetrics>.Success(result));
return Ok(ApiResponse<OeeMetrics>.Ok(result));
}
catch (KeyNotFoundException ex)
{
return NotFound(ApiResponse<OeeMetrics>.NotFound(ex.Message));
return NotFound(ApiResponse<OeeMetrics>.NotFoundResult(ex.Message));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<OeeMetrics>.InternalServerError($"Error calculating OEE metrics: {ex.Message}"));
return StatusCode(500, ApiResponse<OeeMetrics>.InternalServerErrorResult($"Error calculating OEE metrics: {ex.Message}"));
}
}
@ -168,22 +168,22 @@ namespace Haoliang.Api.Controllers
try
{
if (filter.DeviceId <= 0)
return BadRequest(ApiResponse<ProductionForecast>.BadRequest("Invalid device ID"));
return BadRequest(ApiResponse<ProductionForecast>.BadRequestResult("Invalid device ID"));
if (filter.DaysToForecast <= 0 || filter.DaysToForecast > 365)
return BadRequest(ApiResponse<ProductionForecast>.BadRequest("Days to forecast must be between 1 and 365"));
return BadRequest(ApiResponse<ProductionForecast>.BadRequestResult("Days to forecast must be between 1 and 365"));
var result = await _statisticsService.GenerateProductionForecastAsync(filter);
return Ok(ApiResponse<ProductionForecast>.Success(result));
return Ok(ApiResponse<ProductionForecast>.Ok(result));
}
catch (KeyNotFoundException ex)
{
return NotFound(ApiResponse<ProductionForecast>.NotFound(ex.Message));
return NotFound(ApiResponse<ProductionForecast>.NotFoundResult(ex.Message));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<ProductionForecast>.InternalServerError($"Error generating production forecast: {ex.Message}"));
return StatusCode(500, ApiResponse<ProductionForecast>.InternalServerErrorResult($"Error generating production forecast: {ex.Message}"));
}
}
@ -196,15 +196,15 @@ namespace Haoliang.Api.Controllers
try
{
if (filter.StartDate >= filter.EndDate)
return BadRequest(ApiResponse<AnomalyAnalysis>.BadRequest("Start date must be before end date"));
return BadRequest(ApiResponse<AnomalyAnalysis>.BadRequestResult("Start date must be before end date"));
var result = await _statisticsService.DetectProductionAnomaliesAsync(filter);
return Ok(ApiResponse<AnomalyAnalysis>.Success(result));
return Ok(ApiResponse<AnomalyAnalysis>.Ok(result));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<AnomalyAnalysis>.InternalServerError($"Error detecting production anomalies: {ex.Message}"));
return StatusCode(500, ApiResponse<AnomalyAnalysis>.InternalServerErrorResult($"Error detecting production anomalies: {ex.Message}"));
}
}
@ -220,11 +220,11 @@ namespace Haoliang.Api.Controllers
// For now, returning empty list
var result = new List<DeviceSummary>();
return Ok(ApiResponse<List<DeviceSummary>>.Success(result));
return Ok(ApiResponse<List<DeviceSummary>>.Ok(result));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<List<DeviceSummary>>.InternalServerError($"Error getting available devices: {ex.Message}"));
return StatusCode(500, ApiResponse<List<DeviceSummary>>.InternalServerErrorResult($"Error getting available devices: {ex.Message}"));
}
}
@ -259,11 +259,11 @@ namespace Haoliang.Api.Controllers
DeviceSummaries = dashboardSummary.DeviceSummaries
};
return Ok(ApiResponse<MultiDeviceSummary>.Success(multiDeviceSummary));
return Ok(ApiResponse<MultiDeviceSummary>.Ok(multiDeviceSummary));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<MultiDeviceSummary>.InternalServerError($"Error getting multi-device summary: {ex.Message}"));
return StatusCode(500, ApiResponse<MultiDeviceSummary>.InternalServerErrorResult($"Error getting multi-device summary: {ex.Message}"));
}
}
@ -280,10 +280,10 @@ namespace Haoliang.Api.Controllers
try
{
if (deviceId <= 0)
return BadRequest(ApiResponse<HistoricalProductionData>.BadRequest("Invalid device ID"));
return BadRequest(ApiResponse<HistoricalProductionData>.BadRequestResult("Invalid device ID"));
if (startDate >= endDate)
return BadRequest(ApiResponse<HistoricalProductionData>.BadRequest("Start date must be before end date"));
return BadRequest(ApiResponse<HistoricalProductionData>.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<HistoricalProductionData>.Success(historicalData));
return Ok(ApiResponse<HistoricalProductionData>.Ok(historicalData));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<HistoricalProductionData>.InternalServerError($"Error getting historical production data: {ex.Message}"));
return StatusCode(500, ApiResponse<HistoricalProductionData>.InternalServerErrorResult($"Error getting historical production data: {ex.Message}"));
}
}
@ -333,10 +333,10 @@ namespace Haoliang.Api.Controllers
try
{
if (deviceId <= 0)
return BadRequest(ApiResponse<EfficiencyTrendData>.BadRequest("Invalid device ID"));
return BadRequest(ApiResponse<EfficiencyTrendData>.BadRequestResult("Invalid device ID"));
if (startDate >= endDate)
return BadRequest(ApiResponse<EfficiencyTrendData>.BadRequest("Start date must be before end date"));
return BadRequest(ApiResponse<EfficiencyTrendData>.BadRequestResult("Start date must be before end date"));
var filter = new EfficiencyFilter
{
@ -364,11 +364,11 @@ namespace Haoliang.Api.Controllers
}).ToList()
};
return Ok(ApiResponse<EfficiencyTrendData>.Success(trendData));
return Ok(ApiResponse<EfficiencyTrendData>.Ok(trendData));
}
catch (Exception ex)
{
return StatusCode(500, ApiResponse<EfficiencyTrendData>.InternalServerError($"Error getting efficiency trends: {ex.Message}"));
return StatusCode(500, ApiResponse<EfficiencyTrendData>.InternalServerErrorResult($"Error getting efficiency trends: {ex.Message}"));
}
}
}

@ -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<IActionResult> 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<IActionResult> 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<IActionResult> CreateScheduledTask([FromBody] ScheduledTask task)
public async Task<IActionResult> 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)
{

@ -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)
{

@ -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<GlobalExceptionFilter> _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");

@ -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();

@ -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<string> Errors) ValidateModel(object model)
{
var validationContext = new ValidationContext(model);
var validationResults = new List<ValidationResult>();
var validationResults = new List<DataAnnotationsValidationResult>();
var isValid = Validator.TryValidateObject(model, validationContext, validationResults, true);
var errors = validationResults.Select(vr => vr.ErrorMessage).ToList();

@ -24,9 +24,9 @@
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="8.0.0" />
<PackageReference Include="StackExchange.Redis" Version="2.7.17" />
<PackageReference Include="Moq" Version="4.20.69" />
<PackageReference Include="xunit" Version="2.6.1" />
<PackageReference Include="Xunit.DependencyInjection" Version="9.0.0" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
</ItemGroup>
<ItemGroup>

@ -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; }

@ -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;

@ -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<LoggingMiddleware>();
app.UseMiddleware<CORSMiddleware>();
app.UseCors("AllowAll");
app.UseMiddleware<ExceptionMiddleware>();
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<CNCBusinessDbContext>(options =>
options.UseMySql(connectionString,
ServerVersion.AutoDetect(connectionString),
mysqlOptions => mysqlOptions.EnableRetryOnFailure(
maxRetryCount: 3,
maxRetryDelay: TimeSpan.FromSeconds(30),
errorNumbersToAdd: null)));
// 配置数据库连接池
services.AddDbContextPool<CNCBusinessDbContext>(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<ICacheService, MemoryCacheService>();
// 注册缓存服务使用Scoped生命周期以支持依赖注入
services.AddScoped<ICacheService, MemoryCacheService>();
// 注册状态机服务
services.AddHostedService<DeviceStateMachine>();
services.AddSingleton<DeviceStateMachine>();
services.AddHostedService(sp => sp.GetRequiredService<DeviceStateMachine>());
// 注册服务
services.AddScoped<IDeviceCollectionService, DeviceCollectionService>();
services.AddScoped<IProductionService, ProductionService>();
services.AddScoped<IProductionCalculator, ProductionCalculator>();
services.AddScoped<IProductionScheduler, ProductionScheduler>();
services.AddScoped<IAlarmService, AlarmManager>();
services.AddScoped<IAlarmService, AlarmService>();
services.AddScoped<IAlarmRuleService, AlarmRuleService>();
services.AddScoped<IAlarmNotificationService, AlarmNotificationService>();
services.AddScoped<ITemplateService, TemplateManager>();
services.AddScoped<ITemplateService, TemplateService>();
services.AddScoped<ITagMappingService, TagMappingService>();
services.AddScoped<ITemplateValidationService, TemplateValidationService>();
services.AddScoped<ITemplateMigrationService, TemplateMigrationService>();
services.AddScoped<ILoggerService, ConsoleLoggerService>();
services.AddScoped<ICacheService, MemoryCacheService>();
services.AddScoped<ILoggingService, LoggingService>();
services.AddScoped<IRealTimeService, RealTimeService>();
services.AddScoped<IProductionStatisticsService, ProductionStatisticsService>();
services.AddScoped<IRulesService, RulesService>();
@ -168,27 +155,18 @@ namespace Haoliang.Api
// 注册后台任务服务
services.AddHostedService<BackgroundTaskService>();
// 注册仓储
// 注册仓储 (仅注册存在的)
services.AddScoped<IDeviceRepository, DeviceRepository>();
services.AddScoped<ITemplateRepository, TemplateRepository>();
services.AddScoped<IProductionRepository, ProductionRepository>();
services.AddScoped<IProgramProductionSummaryRepository, ProgramProductionSummaryRepository>();
services.AddScoped<IProductionSummaryRepository, ProductionSummaryRepository>();
services.AddScoped<IAlarmRepository, AlarmRepository>();
services.AddScoped<IAlarmRuleRepository, AlarmRuleRepository>();
services.AddScoped<IAlarmNotificationRepository, AlarmNotificationRepository>();
services.AddScoped<ISystemRepository, SystemRepository>();
services.AddScoped<ISystemConfigRepository, SystemConfigRepository>();
services.AddScoped<ICollectionTaskRepository, CollectionTaskRepository>();
services.AddScoped<ICollectionResultRepository, CollectionResultRepository>();
services.AddScoped<ICollectionLogRepository, CollectionLogRepository>();
services.AddScoped<ILogRepository, LogRepository>();
services.AddScoped<IUserRepository, UserRepository>();
services.AddScoped<IAlarmNotificationRepository, AlarmNotificationRepository>();
services.AddScoped<ITagMappingRepository, TagMappingRepository>();
// 注册设备状态相关仓储
services.AddScoped<IDeviceStatusRepository, DeviceStatusRepository>();
// 注册Ping服务
services.AddScoped<IPingService, PingService>();
@ -197,6 +175,7 @@ namespace Haoliang.Api
services.AddScoped<IDataParserService, DataParserService>();
services.AddScoped<IDataStorageService, DataStorageService>();
services.AddScoped<IRetryService, RetryService>();
services.AddScoped<IRetryService, RetryService>();
// 注册SignalR Hub
services.AddSingleton<RealTimeHub>();

@ -70,6 +70,13 @@ namespace Haoliang.Core.Services
/// <param name="email">邮箱地址</param>
/// <returns>是否存在</returns>
Task<bool> EmailExistsAsync(string email);
/// <summary>
/// 根据ID获取用户
/// </summary>
/// <param name="userId">用户ID</param>
/// <returns>用户信息</returns>
Task<User> GetUserByIdAsync(int userId);
}
/// <summary>
@ -237,6 +244,12 @@ namespace Haoliang.Core.Services
/// 清除所有日志
/// </summary>
Task ClearLogsAsync();
/// <summary>
/// 记录信息日志 (LogInfoAsync的别名)
/// </summary>
/// <param name="message">日志消息</param>
Task LogInfoAsync(string message);
}
/// <summary>
@ -384,6 +397,13 @@ namespace Haoliang.Core.Services
/// <param name="deviceId">设备ID</param>
/// <returns>健康状态信息</returns>
Task<DeviceHealth> GetDeviceHealthAsync(int deviceId);
/// <summary>
/// 获取设备当前状态
/// </summary>
/// <param name="deviceId">设备ID</param>
/// <returns>设备当前状态信息</returns>
Task<DeviceStatus> GetDeviceCurrentStatusAsync(int deviceId);
}
/// <summary>
@ -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
/// </summary>
/// <param name="daysToKeep">保留天数</param>
Task ArchiveProductionDataAsync(int daysToKeep = 90);
/// <summary>
/// 获取设备指定日期的生产数据
/// </summary>
/// <param name="deviceId">设备ID</param>
/// <param name="date">日期</param>
/// <returns>生产数据</returns>
Task<ProductionRecord> GetDeviceProductionForDateAsync(int deviceId, DateTime date);
}
/// <summary>
@ -1308,6 +1339,116 @@ namespace Haoliang.Core.Services
/// 刷新配置缓存
/// </summary>
Task RefreshConfigCacheAsync();
/// <summary>
/// 获取系统配置
/// </summary>
Task<object> GetSystemConfigurationAsync();
/// <summary>
/// 更新系统配置
/// </summary>
Task<bool> UpdateSystemConfigurationAsync(object configuration);
/// <summary>
/// 验证配置
/// </summary>
Task<bool> ValidateConfigurationAsync(object configuration);
/// <summary>
/// 获取生产目标配置
/// </summary>
Task<IEnumerable<object>> GetProductionTargetsAsync();
/// <summary>
/// 更新生产目标配置
/// </summary>
Task<bool> UpdateProductionTargetsAsync(IEnumerable<object> targets);
/// <summary>
/// 获取工作小时配置
/// </summary>
Task<object> GetWorkingHoursConfigAsync();
/// <summary>
/// 更新工作小时配置
/// </summary>
Task<bool> UpdateWorkingHoursConfigAsync(object config);
/// <summary>
/// 获取告警配置
/// </summary>
Task<object> GetAlertConfigurationAsync();
/// <summary>
/// 更新告警配置
/// </summary>
Task<bool> UpdateAlertConfigurationAsync(object config);
/// <summary>
/// 获取通知配置
/// </summary>
Task<object> GetNotificationConfigAsync();
/// <summary>
/// 更新通知配置
/// </summary>
Task<bool> UpdateNotificationConfigAsync(object config);
/// <summary>
/// 获取导出配置
/// </summary>
Task<object> GetExportConfigAsync();
/// <summary>
/// 更新导出配置
/// </summary>
Task<bool> UpdateExportConfigAsync(object config);
/// <summary>
/// 获取数据保留配置
/// </summary>
Task<object> GetDataRetentionConfigAsync();
/// <summary>
/// 更新数据保留配置
/// </summary>
Task<bool> UpdateDataRetentionConfigAsync(object config);
/// <summary>
/// 获取仪表盘配置
/// </summary>
Task<object> GetDashboardConfigAsync();
/// <summary>
/// 更新仪表盘配置
/// </summary>
Task<bool> UpdateDashboardConfigAsync(object config);
/// <summary>
/// 获取采集配置
/// </summary>
Task<object> GetCollectionConfigAsync();
/// <summary>
/// 更新采集配置
/// </summary>
Task<bool> UpdateCollectionConfigAsync(object config);
/// <summary>
/// 导入配置
/// </summary>
Task<bool> ImportConfigurationAsync(string configuration);
/// <summary>
/// 重置为默认配置
/// </summary>
Task<bool> ResetToDefaultConfigurationAsync();
/// <summary>
/// 获取配置变更历史
/// </summary>
Task<IEnumerable<object>> GetConfigurationChangeHistoryAsync(DateTime? startDate = null, DateTime? endDate = null);
}
/// <summary>
@ -1651,19 +1792,34 @@ namespace Haoliang.Core.Services
/// <param name="toTime">结束时间</param>
/// <returns>执行历史</returns>
Task<IEnumerable<RuleExecutionHistory>> GetRuleExecutionHistoryAsync(int ruleId, DateTime fromTime, DateTime toTime);
/// <summary>
/// 创建或更新规则
/// </summary>
Task<BusinessRule> CreateOrUpdateRuleAsync(BusinessRule rule);
/// <summary>
/// 获取统计规则
/// </summary>
Task<IEnumerable<BusinessRule>> GetStatisticsRulesAsync();
/// <summary>
/// 更新统计规则
/// </summary>
Task<bool> UpdateStatisticsRulesAsync(IEnumerable<BusinessRule> rules);
}
/// <summary>
/// 业务规则
/// 业务规则 (与 Haoliang.Models.System.BusinessRuleConfig 同结构)
/// </summary>
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; }
}

@ -21,6 +21,7 @@ namespace Haoliang.Core.Services
public Task<AuthResult> RefreshTokenAsync(string refreshToken) => Task.FromResult<AuthResult>(null);
public Task<bool> UsernameExistsAsync(string username) => Task.FromResult(false);
public Task<bool> EmailExistsAsync(string email) => Task.FromResult(false);
public Task<User> GetUserByIdAsync(int userId) => Task.FromResult<User>(null);
}
public class UserService : IUserService
@ -54,6 +55,7 @@ namespace Haoliang.Core.Services
public Task<int> 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<DeviceStatus> GetDeviceStatusAsync(int deviceId) => Task.FromResult(new DeviceStatus());
public Task<DeviceHealth> GetDeviceHealthAsync(int deviceId) => Task.FromResult(new DeviceHealth());
public Task<DeviceStatus> 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<int, DeviceStatus, DeviceStatus> callback) { }
public IEnumerable<DeviceStatusChange> GetStateHistory(int deviceId, DateTime fromTime, DateTime toTime) => new List<DeviceStatusChange>();
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<ProgramProductionSummary> GetProgramProductionAsync(string programName, DateTime date) => Task.FromResult<ProgramProductionSummary>(null);
public Task<byte[]> ExportProductionDataAsync(DateTime startDate, DateTime endDate) => Task.FromResult<byte[]>(null);
public Task ArchiveProductionDataAsync(int daysToKeep = 90) => Task.CompletedTask;
public Task<ProductionRecord> GetDeviceProductionForDateAsync(int deviceId, DateTime date) => Task.FromResult<ProductionRecord>(null);
}
public class ProductionCalculator : IProductionCalculator
@ -245,6 +252,28 @@ namespace Haoliang.Core.Services
public Task<bool> ConfigExistsAsync(string key) => Task.FromResult(false);
public Task<IEnumerable<SystemConfig>> GetConfigsByCategoryAsync(string category) => Task.FromResult<IEnumerable<SystemConfig>>(new List<SystemConfig>());
public Task RefreshConfigCacheAsync() => Task.CompletedTask;
public Task<object> GetSystemConfigurationAsync() => Task.FromResult<object>(null);
public Task<bool> UpdateSystemConfigurationAsync(object configuration) => Task.FromResult(false);
public Task<bool> ValidateConfigurationAsync(object configuration) => Task.FromResult(false);
public Task<IEnumerable<object>> GetProductionTargetsAsync() => Task.FromResult<IEnumerable<object>>(new List<object>());
public Task<bool> UpdateProductionTargetsAsync(IEnumerable<object> targets) => Task.FromResult(false);
public Task<object> GetWorkingHoursConfigAsync() => Task.FromResult<object>(null);
public Task<bool> UpdateWorkingHoursConfigAsync(object config) => Task.FromResult(false);
public Task<object> GetAlertConfigurationAsync() => Task.FromResult<object>(null);
public Task<bool> UpdateAlertConfigurationAsync(object config) => Task.FromResult(false);
public Task<object> GetNotificationConfigAsync() => Task.FromResult<object>(null);
public Task<bool> UpdateNotificationConfigAsync(object config) => Task.FromResult(false);
public Task<object> GetExportConfigAsync() => Task.FromResult<object>(null);
public Task<bool> UpdateExportConfigAsync(object config) => Task.FromResult(false);
public Task<object> GetDataRetentionConfigAsync() => Task.FromResult<object>(null);
public Task<bool> UpdateDataRetentionConfigAsync(object config) => Task.FromResult(false);
public Task<object> GetDashboardConfigAsync() => Task.FromResult<object>(null);
public Task<bool> UpdateDashboardConfigAsync(object config) => Task.FromResult(false);
public Task<object> GetCollectionConfigAsync() => Task.FromResult<object>(null);
public Task<bool> UpdateCollectionConfigAsync(object config) => Task.FromResult(false);
public Task<bool> ImportConfigurationAsync(string configuration) => Task.FromResult(false);
public Task<bool> ResetToDefaultConfigurationAsync() => Task.FromResult(false);
public Task<IEnumerable<object>> GetConfigurationChangeHistoryAsync(DateTime? startDate = null, DateTime? endDate = null) => Task.FromResult<IEnumerable<object>>(new List<object>());
}
public class SchedulerService : ISchedulerService
@ -289,6 +318,9 @@ namespace Haoliang.Core.Services
public Task<RuleExecutionResult> ExecuteRuleAsync(int ruleId, Dictionary<string, object> context) => Task.FromResult<RuleExecutionResult>(null);
public Task<RuleTestResult> TestRuleAsync(int ruleId, Dictionary<string, object> testData) => Task.FromResult<RuleTestResult>(null);
public Task<IEnumerable<RuleExecutionHistory>> GetRuleExecutionHistoryAsync(int ruleId, DateTime fromTime, DateTime toTime) => Task.FromResult<IEnumerable<RuleExecutionHistory>>(new List<RuleExecutionHistory>());
public Task<BusinessRule> CreateOrUpdateRuleAsync(BusinessRule rule) => Task.FromResult(rule);
public Task<IEnumerable<BusinessRule>> GetStatisticsRulesAsync() => Task.FromResult<IEnumerable<BusinessRule>>(new List<BusinessRule>());
public Task<bool> UpdateStatisticsRulesAsync(IEnumerable<BusinessRule> rules) => Task.FromResult(false);
}
public class DataParserService : IDataParserService

@ -45,6 +45,21 @@ namespace Haoliang.Models.Common
};
}
/// <summary>
/// 创建错误响应(带错误详情列表)
/// </summary>
public static ApiResponse Error(string? message, IEnumerable<string>? errors, int errorCode = 500)
{
return new ApiResponse
{
Success = false,
Message = message ?? "Error",
ErrorCode = errorCode,
Data = errors?.ToList(),
Timestamp = DateTime.Now
};
}
/// <summary>
/// 创建未找到响应
/// </summary>

@ -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; }

@ -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; }

@ -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; }

@ -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

Loading…
Cancel
Save