修复编译错误,完成.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.Core.Services;
using Haoliang.Models.System; using Haoliang.Models.System;
using Haoliang.Models.Device; using Haoliang.Models.Device;
using Haoliang.Models.Common;
namespace Haoliang.Api.Controllers namespace Haoliang.Api.Controllers
{ {
@ -49,7 +50,7 @@ namespace Haoliang.Api.Controllers
alarms = await _alarmService.GetAllAlarmsAsync(); alarms = await _alarmService.GetAllAlarmsAsync();
} }
return Ok(ApiResponse.Success(alarms)); return Ok(ApiResponse.Ok(alarms));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -68,7 +69,7 @@ namespace Haoliang.Api.Controllers
{ {
return NotFound(ApiResponse.NotFound("Alarm not found")); return NotFound(ApiResponse.NotFound("Alarm not found"));
} }
return Ok(ApiResponse.Success(alarm)); return Ok(ApiResponse.Ok(alarm));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -83,7 +84,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var createdAlarm = await _alarmService.CreateAlarmAsync(alarm); 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) catch (Exception ex)
{ {
@ -97,13 +98,13 @@ namespace Haoliang.Api.Controllers
{ {
try try
{ {
alarm.AlarmId = id; alarm.Id = id;
var updatedAlarm = await _alarmService.UpdateAlarmAsync(id, alarm); var updatedAlarm = await _alarmService.UpdateAlarmAsync(id, alarm);
if (updatedAlarm == null) if (updatedAlarm == null)
{ {
return NotFound(ApiResponse.NotFound("Alarm not found")); 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) catch (Exception ex)
{ {
@ -122,7 +123,7 @@ namespace Haoliang.Api.Controllers
{ {
return NotFound(ApiResponse.NotFound("Alarm not found")); 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) catch (Exception ex)
{ {
@ -141,7 +142,7 @@ namespace Haoliang.Api.Controllers
{ {
return NotFound(ApiResponse.NotFound("Alarm not found")); 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) catch (Exception ex)
{ {
@ -160,7 +161,7 @@ namespace Haoliang.Api.Controllers
{ {
return NotFound(ApiResponse.NotFound("Alarm not found")); 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) catch (Exception ex)
{ {
@ -175,7 +176,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var alarms = await _alarmService.GetDeviceAlarmsAsync(deviceId, days); var alarms = await _alarmService.GetDeviceAlarmsAsync(deviceId, days);
return Ok(ApiResponse.Success(alarms)); return Ok(ApiResponse.Ok(alarms));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -190,7 +191,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var alarms = await _alarmService.GetCriticalAlarmsAsync(); var alarms = await _alarmService.GetCriticalAlarmsAsync();
return Ok(ApiResponse.Success(alarms)); return Ok(ApiResponse.Ok(alarms));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -208,7 +209,7 @@ namespace Haoliang.Api.Controllers
date = DateTime.Today; date = DateTime.Today;
var statistics = await _alarmService.GetAlarmStatisticsAsync(date); var statistics = await _alarmService.GetAlarmStatisticsAsync(date);
return Ok(ApiResponse.Success(statistics)); return Ok(ApiResponse.Ok(statistics));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -223,7 +224,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var alarms = await _alarmService.GetAlarmsByDateRangeAsync(startDate, endDate); var alarms = await _alarmService.GetAlarmsByDateRangeAsync(startDate, endDate);
return Ok(ApiResponse.Success(alarms)); return Ok(ApiResponse.Ok(alarms));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -240,16 +241,16 @@ namespace Haoliang.Api.Controllers
var notification = new AlarmNotification var notification = new AlarmNotification
{ {
AlarmId = -1, AlarmId = -1,
DeviceId = request.DeviceId, NotificationType = request.NotificationType.ToString(),
NotificationType = request.NotificationType, Subject = "Test notification",
Message = "Test notification", Content = "Test notification",
IsSent = true,
SendTime = DateTime.Now, SendTime = DateTime.Now,
Status = NotificationStatus.Sent,
Recipient = request.Recipient Recipient = request.Recipient
}; };
await _notificationService.SendAlarmNotificationAsync(notification); 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) catch (Exception ex)
{ {
@ -264,7 +265,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var rules = await _alarmRuleService.GetAllAlarmRulesAsync(); var rules = await _alarmRuleService.GetAllAlarmRulesAsync();
return Ok(ApiResponse.Success(rules)); return Ok(ApiResponse.Ok(rules));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -279,7 +280,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var createdRule = await _alarmRuleService.CreateAlarmRuleAsync(rule); 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) catch (Exception ex)
{ {
@ -294,7 +295,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
await _alarmRuleService.TestAlarmRuleAsync(id); 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) catch (Exception ex)
{ {

@ -45,7 +45,7 @@ namespace Haoliang.Api.Controllers
if (result.Success) if (result.Success)
{ {
await _loggingService.LogInformationAsync($"User {request.Username} logged in successfully"); await _loggingService.LogInformationAsync($"User {request.Username} logged in successfully");
return Ok(ApiResponse<AuthResult>.Success(result)); return Ok(ApiResponse<AuthResult>.Ok(result));
} }
else else
{ {
@ -65,17 +65,17 @@ namespace Haoliang.Api.Controllers
{ {
try try
{ {
if (request?.UserId == null) if (request?.UserId == null || request.UserId == 0)
{ {
return BadRequest(ApiResponse<bool>.Error("User ID is required", 400)); 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) if (success)
{ {
await _loggingService.LogInformationAsync($"User {request.UserId} logged out successfully"); await _loggingService.LogInformationAsync($"User {request.UserId} logged out successfully");
return Ok(ApiResponse<bool>.Success(true)); return Ok(ApiResponse<bool>.Ok(true));
} }
else else
{ {
@ -103,7 +103,7 @@ namespace Haoliang.Api.Controllers
if (result.Success) if (result.Success)
{ {
return Ok(ApiResponse<AuthResult>.Success(result)); return Ok(ApiResponse<AuthResult>.Ok(result));
} }
else else
{ {
@ -158,7 +158,7 @@ namespace Haoliang.Api.Controllers
var userViewModel = await _userService.CreateUserAsync(user); var userViewModel = await _userService.CreateUserAsync(user);
await _loggingService.LogInformationAsync($"New user registered: {request.Username}"); await _loggingService.LogInformationAsync($"New user registered: {request.Username}");
return Ok(ApiResponse<UserViewModel>.Success(userViewModel)); return Ok(ApiResponse<UserViewModel>.Ok(userViewModel));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -185,7 +185,7 @@ namespace Haoliang.Api.Controllers
return NotFound(ApiResponse<UserViewModel>.Error("User not found", 404)); return NotFound(ApiResponse<UserViewModel>.Error("User not found", 404));
} }
return Ok(ApiResponse<UserViewModel>.Success(user)); return Ok(ApiResponse<UserViewModel>.Ok(user));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -223,7 +223,7 @@ namespace Haoliang.Api.Controllers
var updatedUser = await _userService.UpdateUserAsync(userId.Value, user); var updatedUser = await _userService.UpdateUserAsync(userId.Value, user);
await _loggingService.LogInformationAsync($"User profile updated: {request.Username}"); await _loggingService.LogInformationAsync($"User profile updated: {request.Username}");
return Ok(ApiResponse<UserViewModel>.Success(updatedUser)); return Ok(ApiResponse<UserViewModel>.Ok(updatedUser));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -256,7 +256,7 @@ namespace Haoliang.Api.Controllers
if (success) if (success)
{ {
await _loggingService.LogInformationAsync($"Password changed for user: {userId}"); await _loggingService.LogInformationAsync($"Password changed for user: {userId}");
return Ok(ApiResponse<bool>.Success(true)); return Ok(ApiResponse<bool>.Ok(true));
} }
else else
{ {
@ -282,7 +282,7 @@ namespace Haoliang.Api.Controllers
} }
var permissions = await _permissionService.GetUserPermissionsAsync(userId.Value); var permissions = await _permissionService.GetUserPermissionsAsync(userId.Value);
return Ok(ApiResponse<IEnumerable<string>>.Success(permissions)); return Ok(ApiResponse<IEnumerable<string>>.Ok(permissions));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -354,7 +354,7 @@ namespace Haoliang.Api.Controllers
return NotFound(ApiResponse<UserViewModel>.Error("User not found", 404)); return NotFound(ApiResponse<UserViewModel>.Error("User not found", 404));
} }
return Ok(ApiResponse<UserViewModel>.Success(user)); return Ok(ApiResponse<UserViewModel>.Ok(user));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -372,7 +372,7 @@ namespace Haoliang.Api.Controllers
if (success) if (success)
{ {
await _loggingService.LogInformationAsync($"User activated: {id}"); await _loggingService.LogInformationAsync($"User activated: {id}");
return Ok(ApiResponse<bool>.Success(true)); return Ok(ApiResponse<bool>.Ok(true));
} }
else else
{ {
@ -395,7 +395,7 @@ namespace Haoliang.Api.Controllers
if (success) if (success)
{ {
await _loggingService.LogInformationAsync($"User deactivated: {id}"); await _loggingService.LogInformationAsync($"User deactivated: {id}");
return Ok(ApiResponse<bool>.Success(true)); return Ok(ApiResponse<bool>.Ok(true));
} }
else else
{ {
@ -418,13 +418,6 @@ namespace Haoliang.Api.Controllers
} }
// Supporting request and response models // 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 class LogoutRequest
{ {
public int UserId { get; set; } public int UserId { get; set; }

@ -2,11 +2,13 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;
using Haoliang.Core.Services; using Haoliang.Core.Services;
using Haoliang.Models.Models.System; using Haoliang.Models.System;
using Haoliang.Models.Models.Production; using Haoliang.Models.Production;
using Haoliang.Models.Models.Template; using Haoliang.Models.Template;
using Haoliang.Models.Common; using Haoliang.Models.Common;
using Haoliang.Models.Models.System;
namespace Haoliang.Api.Controllers namespace Haoliang.Api.Controllers
{ {
@ -40,11 +42,11 @@ namespace Haoliang.Api.Controllers
try try
{ {
var config = await _systemService.GetSystemConfigurationAsync(); var config = await _systemService.GetSystemConfigurationAsync();
return Ok(ApiResponse<SystemConfiguration>.Success(config)); return Ok(ApiResponse<SystemConfiguration>.Ok(config));
} }
catch (Exception ex) 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 try
{ {
var result = await _systemService.UpdateSystemConfigurationAsync(configuration); var result = await _systemService.UpdateSystemConfigurationAsync(configuration);
return Ok(ApiResponse<bool>.Success(result)); return Ok(ApiResponse<bool>.Ok(result));
} }
catch (Exception ex) 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 try
{ {
var targets = await _systemService.GetProductionTargetsAsync(); var targets = await _systemService.GetProductionTargetsAsync();
return Ok(ApiResponse<List<ProductionTargetConfig>>.Success(targets)); return Ok(ApiResponse<List<ProductionTargetConfig>>.Ok(targets));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -91,11 +93,11 @@ namespace Haoliang.Api.Controllers
try try
{ {
var result = await _systemService.UpdateProductionTargetsAsync(targets); var result = await _systemService.UpdateProductionTargetsAsync(targets);
return Ok(ApiResponse<bool>.Success(result)); return Ok(ApiResponse<bool>.Ok(result));
} }
catch (Exception ex) 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 try
{ {
var config = await _systemService.GetWorkingHoursConfigAsync(); var config = await _systemService.GetWorkingHoursConfigAsync();
return Ok(ApiResponse<WorkingHoursConfig>.Success(config)); return Ok(ApiResponse<WorkingHoursConfig>.Ok(config));
} }
catch (Exception ex) 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 try
{ {
var result = await _systemService.UpdateWorkingHoursConfigAsync(config); var result = await _systemService.UpdateWorkingHoursConfigAsync(config);
return Ok(ApiResponse<bool>.Success(result)); return Ok(ApiResponse<bool>.Ok(result));
} }
catch (Exception ex) 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 try
{ {
var config = await _systemService.GetAlertConfigurationAsync(); var config = await _systemService.GetAlertConfigurationAsync();
return Ok(ApiResponse<AlertConfiguration>.Success(config)); return Ok(ApiResponse<AlertConfiguration>.Ok(config));
} }
catch (Exception ex) 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 try
{ {
var result = await _systemService.UpdateAlertConfigurationAsync(config); var result = await _systemService.UpdateAlertConfigurationAsync(config);
return Ok(ApiResponse<bool>.Success(result)); return Ok(ApiResponse<bool>.Ok(result));
} }
catch (Exception ex) 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 /// Get business rules configuration
/// </summary> /// </summary>
[HttpGet("rules")] [HttpGet("rules")]
public async Task<ActionResult<ApiResponse<List<BusinessRuleConfig>>>> GetBusinessRules() public async Task<ActionResult<ApiResponse<List<Haoliang.Models.System.BusinessRuleConfig>>>> GetBusinessRules()
{ {
try try
{ {
var rules = await _rulesService.GetAllRulesAsync(); 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) 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 /// Create or update business rule
/// </summary> /// </summary>
[HttpPost("rules")] [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 try
{ {
var result = await _rulesService.CreateOrUpdateRuleAsync(rule); var businessRule = new Haoliang.Core.Services.BusinessRule
return Ok(ApiResponse<BusinessRuleConfig>.Success(result)); {
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) 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 try
{ {
var result = await _rulesService.DeleteRuleAsync(ruleId); var result = await _rulesService.DeleteRuleAsync(ruleId);
return Ok(ApiResponse<bool>.Success(result)); return Ok(ApiResponse<bool>.Ok(result));
} }
catch (Exception ex) 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 /// Get statistical analysis rules
/// </summary> /// </summary>
[HttpGet("statistics-rules")] [HttpGet("statistics-rules")]
public async Task<ActionResult<ApiResponse<List<StatisticsRuleConfig>>>> GetStatisticsRules() public async Task<ActionResult<ApiResponse<List<Haoliang.Models.System.StatisticsRuleConfig>>>> GetStatisticsRules()
{ {
try try
{ {
var rules = await _rulesService.GetStatisticsRulesAsync(); 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) 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 /// Update statistics rules
/// </summary> /// </summary>
[HttpPut("statistics-rules")] [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 try
{ {
var result = await _rulesService.UpdateStatisticsRulesAsync(rules); var businessRules = rules.Select(r => new Haoliang.Core.Services.BusinessRule
return Ok(ApiResponse<bool>.Success(result)); {
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) 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 try
{ {
var config = await _systemService.GetDataRetentionConfigAsync(); var config = await _systemService.GetDataRetentionConfigAsync();
return Ok(ApiResponse<DataRetentionConfig>.Success(config)); return Ok(ApiResponse<DataRetentionConfig>.Ok(config));
} }
catch (Exception ex) 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 try
{ {
var result = await _systemService.UpdateDataRetentionConfigAsync(config); var result = await _systemService.UpdateDataRetentionConfigAsync(config);
return Ok(ApiResponse<bool>.Success(result)); return Ok(ApiResponse<bool>.Ok(result));
} }
catch (Exception ex) 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 try
{ {
var config = await _systemService.GetDashboardConfigAsync(); var config = await _systemService.GetDashboardConfigAsync();
return Ok(ApiResponse<DashboardConfig>.Success(config)); return Ok(ApiResponse<DashboardConfig>.Ok(config));
} }
catch (Exception ex) 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 try
{ {
var result = await _systemService.UpdateDashboardConfigAsync(config); var result = await _systemService.UpdateDashboardConfigAsync(config);
return Ok(ApiResponse<bool>.Success(result)); return Ok(ApiResponse<bool>.Ok(result));
} }
catch (Exception ex) 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 try
{ {
var config = await _systemService.GetExportConfigAsync(); var config = await _systemService.GetExportConfigAsync();
return Ok(ApiResponse<ExportConfig>.Success(config)); return Ok(ApiResponse<ExportConfig>.Ok(config));
} }
catch (Exception ex) 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 try
{ {
var result = await _systemService.UpdateExportConfigAsync(config); var result = await _systemService.UpdateExportConfigAsync(config);
return Ok(ApiResponse<bool>.Success(result)); return Ok(ApiResponse<bool>.Ok(result));
} }
catch (Exception ex) 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 try
{ {
var config = await _systemService.GetCollectionConfigAsync(); var config = await _systemService.GetCollectionConfigAsync();
return Ok(ApiResponse<CollectionConfig>.Success(config)); return Ok(ApiResponse<CollectionConfig>.Ok(config));
} }
catch (Exception ex) 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 try
{ {
var result = await _systemService.UpdateCollectionConfigAsync(config); var result = await _systemService.UpdateCollectionConfigAsync(config);
return Ok(ApiResponse<bool>.Success(result)); return Ok(ApiResponse<bool>.Ok(result));
} }
catch (Exception ex) 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 try
{ {
var config = await _systemService.GetNotificationConfigAsync(); var config = await _systemService.GetNotificationConfigAsync();
return Ok(ApiResponse<NotificationConfig>.Success(config)); return Ok(ApiResponse<NotificationConfig>.Ok(config));
} }
catch (Exception ex) 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 try
{ {
var result = await _systemService.UpdateNotificationConfigAsync(config); var result = await _systemService.UpdateNotificationConfigAsync(config);
return Ok(ApiResponse<bool>.Success(result)); return Ok(ApiResponse<bool>.Ok(result));
} }
catch (Exception ex) 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 try
{ {
var result = await _systemService.ValidateConfigurationAsync(configuration); var result = await _systemService.ValidateConfigurationAsync(configuration);
return Ok(ApiResponse<ValidationResult>.Success(result)); return Ok(ApiResponse<ValidationResult>.Ok(result));
} }
catch (Exception ex) 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 try
{ {
var result = await _systemService.ImportConfigurationAsync(configuration); var json = System.Text.Json.JsonSerializer.Serialize(configuration);
return Ok(ApiResponse<bool>.Success(result)); var result = await _systemService.ImportConfigurationAsync(json);
return Ok(ApiResponse<bool>.Ok(result));
} }
catch (Exception ex) 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 try
{ {
var result = await _systemService.ResetToDefaultConfigurationAsync(); var result = await _systemService.ResetToDefaultConfigurationAsync();
return Ok(ApiResponse<bool>.Success(result)); return Ok(ApiResponse<bool>.Ok(result));
} }
catch (Exception ex) 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 try
{ {
var history = await _systemService.GetConfigurationChangeHistoryAsync(startDate, endDate); var history = await _systemService.GetConfigurationChangeHistoryAsync(startDate, endDate);
return Ok(ApiResponse<List<ConfigurationChange>>.Success(history)); return Ok(ApiResponse<List<ConfigurationChange>>.Ok(history));
} }
catch (Exception ex) catch (Exception ex)
{ {

@ -8,6 +8,7 @@ using Haoliang.Models.Device;
using Haoliang.Models.DataCollection; using Haoliang.Models.DataCollection;
using Haoliang.Models.System; using Haoliang.Models.System;
using Haoliang.Models.Template; using Haoliang.Models.Template;
using Haoliang.Models.Common;
namespace Haoliang.Api.Controllers namespace Haoliang.Api.Controllers
{ {
@ -44,7 +45,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var devices = await _collectionService.GetAllDevicesAsync(); var devices = await _collectionService.GetAllDevicesAsync();
return Ok(ApiResponse.Success(devices)); return Ok(ApiResponse.Ok(devices));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -63,7 +64,7 @@ namespace Haoliang.Api.Controllers
{ {
return NotFound(ApiResponse.NotFound("Device not found")); return NotFound(ApiResponse.NotFound("Device not found"));
} }
return Ok(ApiResponse.Success(device)); return Ok(ApiResponse.Ok(device));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -78,7 +79,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var createdDevice = await _collectionService.CreateDeviceAsync(device); 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) catch (Exception ex)
{ {
@ -98,7 +99,7 @@ namespace Haoliang.Api.Controllers
{ {
return NotFound(ApiResponse.NotFound("Device not found")); 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) catch (Exception ex)
{ {
@ -117,7 +118,7 @@ namespace Haoliang.Api.Controllers
{ {
return NotFound(ApiResponse.NotFound("Device not found")); 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) catch (Exception ex)
{ {
@ -132,7 +133,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
await _collectionService.CollectDeviceAsync(id); await _collectionService.CollectDeviceAsync(id);
return Ok(ApiResponse.Success(null, "Data collection started")); return Ok(ApiResponse.Ok(null, "Data collection started"));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -147,7 +148,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
await _collectionService.CollectAllDevicesAsync(); 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) catch (Exception ex)
{ {
@ -162,7 +163,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var status = await _collectionService.GetDeviceStatusAsync(id); var status = await _collectionService.GetDeviceStatusAsync(id);
return Ok(ApiResponse.Success(status)); return Ok(ApiResponse.Ok(status));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -180,7 +181,7 @@ namespace Haoliang.Api.Controllers
date = DateTime.Today; date = DateTime.Today;
var production = await _productionService.GetTodayProductionAsync(id); var production = await _productionService.GetTodayProductionAsync(id);
return Ok(ApiResponse.Success(production)); return Ok(ApiResponse.Ok(production));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -195,7 +196,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var alarms = await _alarmService.GetDeviceAlarmsAsync(id, days); var alarms = await _alarmService.GetDeviceAlarmsAsync(id, days);
return Ok(ApiResponse.Success(alarms)); return Ok(ApiResponse.Ok(alarms));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -210,7 +211,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var health = await _collectionService.GetDeviceHealthAsync(id); var health = await _collectionService.GetDeviceHealthAsync(id);
return Ok(ApiResponse.Success(health)); return Ok(ApiResponse.Ok(health));
} }
catch (Exception ex) catch (Exception ex)
{ {

@ -7,6 +7,7 @@ using Haoliang.Core.Services;
using Haoliang.Models.Production; using Haoliang.Models.Production;
using Haoliang.Models.Device; using Haoliang.Models.Device;
using Haoliang.Models.System; using Haoliang.Models.System;
using Haoliang.Models.Common;
namespace Haoliang.Api.Controllers namespace Haoliang.Api.Controllers
{ {
@ -40,7 +41,7 @@ namespace Haoliang.Api.Controllers
date = DateTime.Today; date = DateTime.Today;
var summary = await _productionService.GetProductionSummaryAsync(date); var summary = await _productionService.GetProductionSummaryAsync(date);
return Ok(ApiResponse.Success(summary)); return Ok(ApiResponse.Ok(summary));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -58,7 +59,7 @@ namespace Haoliang.Api.Controllers
date = DateTime.Today; date = DateTime.Today;
var statistics = await _productionService.GetProductionStatisticsAsync(date); var statistics = await _productionService.GetProductionStatisticsAsync(date);
return Ok(ApiResponse.Success(statistics)); return Ok(ApiResponse.Ok(statistics));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -78,7 +79,7 @@ namespace Haoliang.Api.Controllers
date = DateTime.Today; date = DateTime.Today;
var production = await _productionService.GetTodayProductionAsync(deviceId); var production = await _productionService.GetTodayProductionAsync(deviceId);
return Ok(ApiResponse.Success(production)); return Ok(ApiResponse.Ok(production));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -98,7 +99,7 @@ namespace Haoliang.Api.Controllers
date = DateTime.Today; date = DateTime.Today;
var statistics = await _productionService.GetProductionStatisticsAsync(deviceId, date); var statistics = await _productionService.GetProductionStatisticsAsync(deviceId, date);
return Ok(ApiResponse.Success(statistics)); return Ok(ApiResponse.Ok(statistics));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -118,7 +119,7 @@ namespace Haoliang.Api.Controllers
date = DateTime.Today; date = DateTime.Today;
var qualityRate = await _productionService.GetQualityRateAsync(deviceId, date); var qualityRate = await _productionService.GetQualityRateAsync(deviceId, date);
return Ok(ApiResponse.Success(qualityRate)); return Ok(ApiResponse.Ok(qualityRate));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -133,7 +134,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
await _productionService.CalculateAllProductionAsync(); await _productionService.CalculateAllProductionAsync();
return Ok(ApiResponse.Success(null, "Production calculation completed")); return Ok(ApiResponse.Ok(null, "Production calculation completed"));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -148,7 +149,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
await _productionService.CalculateProductionAsync(deviceId); 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) catch (Exception ex)
{ {
@ -166,7 +167,7 @@ namespace Haoliang.Api.Controllers
date = DateTime.Today; date = DateTime.Today;
var programs = await _productionService.GetProductionProgramsAsync(date); var programs = await _productionService.GetProductionProgramsAsync(date);
return Ok(ApiResponse.Success(programs)); return Ok(ApiResponse.Ok(programs));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -186,7 +187,7 @@ namespace Haoliang.Api.Controllers
date = DateTime.Today; date = DateTime.Today;
var programData = await _productionService.GetProgramProductionAsync(programName, date); var programData = await _productionService.GetProgramProductionAsync(programName, date);
return Ok(ApiResponse.Success(programData)); return Ok(ApiResponse.Ok(programData));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -225,7 +226,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
await _productionService.ArchiveProductionDataAsync(daysToKeep); 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) catch (Exception ex)
{ {

@ -27,11 +27,11 @@ namespace Haoliang.Api.Controllers
try try
{ {
var count = await _realTimeService.GetConnectedClientsCountAsync(); var count = await _realTimeService.GetConnectedClientsCountAsync();
return Ok(ApiResponse<int>.Success(count)); return Ok(ApiResponse<int>.Ok(count));
} }
catch (Exception ex) 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 try
{ {
var clients = await _realTimeService.GetConnectedClientsByTypeAsync(clientType); var clients = await _realTimeService.GetConnectedClientsByTypeAsync(clientType);
return Ok(ApiResponse<List<ClientInfo>>.Success(clients)); return Ok(ApiResponse<List<ClientInfo>>.Ok(clients));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -61,11 +61,11 @@ namespace Haoliang.Api.Controllers
try try
{ {
var status = await _realTimeService.GetDeviceMonitoringStatusAsync(deviceId); var status = await _realTimeService.GetDeviceMonitoringStatusAsync(deviceId);
return Ok(ApiResponse<DeviceMonitoringStatus>.Success(status)); return Ok(ApiResponse<DeviceMonitoringStatus>.Ok(status));
} }
catch (Exception ex) 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 try
{ {
await _realTimeService.StartDeviceStreamingAsync(deviceId, intervalMs); await _realTimeService.StartDeviceStreamingAsync(deviceId, intervalMs);
return Ok(ApiResponse<bool>.Success(true)); return Ok(ApiResponse<bool>.Ok(true));
} }
catch (Exception ex) 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 try
{ {
await _realTimeService.StopDeviceStreamingAsync(deviceId); await _realTimeService.StopDeviceStreamingAsync(deviceId);
return Ok(ApiResponse<bool>.Success(true)); return Ok(ApiResponse<bool>.Ok(true));
} }
catch (Exception ex) 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 try
{ {
var devices = await _realTimeService.GetActiveStreamingDevicesAsync(); var devices = await _realTimeService.GetActiveStreamingDevicesAsync();
return Ok(ApiResponse<List<int>>.Success(devices)); return Ok(ApiResponse<List<int>>.Ok(devices));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -136,11 +136,11 @@ namespace Haoliang.Api.Controllers
statusUpdate.Timestamp = DateTime.UtcNow; statusUpdate.Timestamp = DateTime.UtcNow;
await _realTimeService.BroadcastDeviceStatusAsync(statusUpdate); await _realTimeService.BroadcastDeviceStatusAsync(statusUpdate);
return Ok(ApiResponse<bool>.Success(true)); return Ok(ApiResponse<bool>.Ok(true));
} }
catch (Exception ex) 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; productionUpdate.Timestamp = DateTime.UtcNow;
await _realTimeService.BroadcastProductionUpdateAsync(productionUpdate); await _realTimeService.BroadcastProductionUpdateAsync(productionUpdate);
return Ok(ApiResponse<bool>.Success(true)); return Ok(ApiResponse<bool>.Ok(true));
} }
catch (Exception ex) 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; alertUpdate.Timestamp = DateTime.UtcNow;
await _realTimeService.BroadcastAlertAsync(alertUpdate); await _realTimeService.BroadcastAlertAsync(alertUpdate);
return Ok(ApiResponse<bool>.Success(true)); return Ok(ApiResponse<bool>.Ok(true));
} }
catch (Exception ex) 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; notification.Timestamp = DateTime.UtcNow;
await _realTimeService.SendSystemNotificationAsync(notification); await _realTimeService.SendSystemNotificationAsync(notification);
return Ok(ApiResponse<bool>.Success(true)); return Ok(ApiResponse<bool>.Ok(true));
} }
catch (Exception ex) 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; dashboardUpdate.Timestamp = DateTime.UtcNow;
await _realTimeService.SendDashboardUpdateAsync(dashboardUpdate); await _realTimeService.SendDashboardUpdateAsync(dashboardUpdate);
return Ok(ApiResponse<bool>.Success(true)); return Ok(ApiResponse<bool>.Ok(true));
} }
catch (Exception ex) 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; command.Timestamp = DateTime.UtcNow;
await _realTimeService.SendCommandToClientAsync(connectionId, command); await _realTimeService.SendCommandToClientAsync(connectionId, command);
return Ok(ApiResponse<bool>.Success(true)); return Ok(ApiResponse<bool>.Ok(true));
} }
catch (Exception ex) 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; command.Timestamp = DateTime.UtcNow;
await _realTimeService.BroadcastCommandAsync(command); await _realTimeService.BroadcastCommandAsync(command);
return Ok(ApiResponse<bool>.Success(true)); return Ok(ApiResponse<bool>.Ok(true));
} }
catch (Exception ex) 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 baseUrl = $"{Request.Scheme}://{Request.Host}";
var connectionUrl = $"{baseUrl}/realtimehub"; var connectionUrl = $"{baseUrl}/realtimehub";
return Ok(ApiResponse<string>.Success(connectionUrl)); return Ok(ApiResponse<string>.Ok(connectionUrl));
} }
catch (Exception ex) 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(), TestId = Guid.NewGuid().ToString(),
Timestamp = DateTime.UtcNow, Timestamp = DateTime.UtcNow,
ConnectedClients = await _realTimeService.GetConnectedClientsCountAsync(), ConnectedClients = await _realTimeService.GetConnectedClientsCountAsync(),
ActiveStreamingDevices = await _realTimeService.GetActiveStreamingDevicesAsync(), ActiveStreamingDevices = (await _realTimeService.GetActiveStreamingDevicesAsync()).ToList(),
Status = "Success" Status = "Success"
}; };
return Ok(ApiResponse<TestResult>.Success(testResult)); return Ok(ApiResponse<TestResult>.Ok(testResult));
} }
catch (Exception ex) 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 try
{ {
var connectedClients = await _realTimeService.GetConnectedClientsCountAsync(); var connectedClients = await _realTimeService.GetConnectedClientsCountAsync();
var streamingDevices = await _realTimeService.GetActiveStreamingDevicesAsync(); var streamingDevices = (await _realTimeService.GetActiveStreamingDevicesAsync()).ToList();
var stats = new WebSocketStatistics var stats = new WebSocketStatistics
{ {
@ -323,11 +323,11 @@ namespace Haoliang.Api.Controllers
BytesTransferred = 0 // Would need to track this in the service 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) 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 // This would trigger the dashboard update logic
// Implementation depends on specific requirements // Implementation depends on specific requirements
return Ok(ApiResponse<bool>.Success(true)); return Ok(ApiResponse<bool>.Ok(true));
} }
catch (Exception ex) 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 Microsoft.AspNetCore.Mvc;
using Haoliang.Core.Services; using Haoliang.Core.Services;
using Haoliang.Models.Models.System; using Haoliang.Models.Models.System;
using Haoliang.Models.Models.Production; using Haoliang.Models.Production;
using Haoliang.Models.Common; using Haoliang.Models.Common;
namespace Haoliang.Api.Controllers namespace Haoliang.Api.Controllers
@ -32,14 +32,14 @@ namespace Haoliang.Api.Controllers
try try
{ {
if (deviceId <= 0) if (deviceId <= 0)
return BadRequest(ApiResponse<ProductionTrendAnalysis>.BadRequest("Invalid device ID")); return BadRequest(ApiResponse<ProductionTrendAnalysis>.BadRequestResult("Invalid device ID"));
if (startDate >= endDate) 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); var result = await _statisticsService.CalculateProductionTrendsAsync(deviceId, startDate, endDate);
return Ok(ApiResponse<ProductionTrendAnalysis>.Success(result)); return Ok(ApiResponse<ProductionTrendAnalysis>.Ok(result));
} }
catch (KeyNotFoundException ex) catch (KeyNotFoundException ex)
{ {
@ -47,7 +47,7 @@ namespace Haoliang.Api.Controllers
} }
catch (Exception ex) 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 try
{ {
if (filter.StartDate >= filter.EndDate) 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); var result = await _statisticsService.GenerateProductionReportAsync(filter);
return Ok(ApiResponse<ProductionReport>.Success(result)); return Ok(ApiResponse<ProductionReport>.Ok(result));
} }
catch (Exception ex) 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 try
{ {
if (filter.StartDate >= filter.EndDate) 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); var result = await _statisticsService.CalculateEfficiencyMetricsAsync(filter);
return Ok(ApiResponse<EfficiencyMetrics>.Success(result)); return Ok(ApiResponse<EfficiencyMetrics>.Ok(result));
} }
catch (Exception ex) 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 try
{ {
if (filter.StartDate >= filter.EndDate) 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); var result = await _statisticsService.PerformQualityAnalysisAsync(filter);
return Ok(ApiResponse<QualityAnalysis>.Success(result)); return Ok(ApiResponse<QualityAnalysis>.Ok(result));
} }
catch (Exception ex) 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); var result = await _statisticsService.GetDashboardSummaryAsync(filter);
return Ok(ApiResponse<DashboardSummary>.Success(result)); return Ok(ApiResponse<DashboardSummary>.Ok(result));
} }
catch (Exception ex) 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 try
{ {
if (deviceId <= 0) 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); var result = await _statisticsService.CalculateOeeAsync(deviceId, date);
return Ok(ApiResponse<OeeMetrics>.Success(result)); return Ok(ApiResponse<OeeMetrics>.Ok(result));
} }
catch (KeyNotFoundException ex) catch (KeyNotFoundException ex)
{ {
return NotFound(ApiResponse<OeeMetrics>.NotFound(ex.Message)); return NotFound(ApiResponse<OeeMetrics>.NotFoundResult(ex.Message));
} }
catch (Exception ex) 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 try
{ {
if (filter.DeviceId <= 0) 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) 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); var result = await _statisticsService.GenerateProductionForecastAsync(filter);
return Ok(ApiResponse<ProductionForecast>.Success(result)); return Ok(ApiResponse<ProductionForecast>.Ok(result));
} }
catch (KeyNotFoundException ex) catch (KeyNotFoundException ex)
{ {
return NotFound(ApiResponse<ProductionForecast>.NotFound(ex.Message)); return NotFound(ApiResponse<ProductionForecast>.NotFoundResult(ex.Message));
} }
catch (Exception ex) 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 try
{ {
if (filter.StartDate >= filter.EndDate) 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); var result = await _statisticsService.DetectProductionAnomaliesAsync(filter);
return Ok(ApiResponse<AnomalyAnalysis>.Success(result)); return Ok(ApiResponse<AnomalyAnalysis>.Ok(result));
} }
catch (Exception ex) 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 // For now, returning empty list
var result = new List<DeviceSummary>(); var result = new List<DeviceSummary>();
return Ok(ApiResponse<List<DeviceSummary>>.Success(result)); return Ok(ApiResponse<List<DeviceSummary>>.Ok(result));
} }
catch (Exception ex) 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 DeviceSummaries = dashboardSummary.DeviceSummaries
}; };
return Ok(ApiResponse<MultiDeviceSummary>.Success(multiDeviceSummary)); return Ok(ApiResponse<MultiDeviceSummary>.Ok(multiDeviceSummary));
} }
catch (Exception ex) 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 try
{ {
if (deviceId <= 0) if (deviceId <= 0)
return BadRequest(ApiResponse<HistoricalProductionData>.BadRequest("Invalid device ID")); return BadRequest(ApiResponse<HistoricalProductionData>.BadRequestResult("Invalid device ID"));
if (startDate >= endDate) 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 var filter = new ReportFilter
{ {
@ -304,7 +304,7 @@ namespace Haoliang.Api.Controllers
DataPoints = report.SummaryItems.Select(item => new DataPoint DataPoints = report.SummaryItems.Select(item => new DataPoint
{ {
Timestamp = groupBy == GroupBy.Date ? item.Date : 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, item.Date,
Value = item.Quantity, Value = item.Quantity,
Target = item.TargetQuantity, Target = item.TargetQuantity,
@ -312,11 +312,11 @@ namespace Haoliang.Api.Controllers
}).ToList() }).ToList()
}; };
return Ok(ApiResponse<HistoricalProductionData>.Success(historicalData)); return Ok(ApiResponse<HistoricalProductionData>.Ok(historicalData));
} }
catch (Exception ex) 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 try
{ {
if (deviceId <= 0) if (deviceId <= 0)
return BadRequest(ApiResponse<EfficiencyTrendData>.BadRequest("Invalid device ID")); return BadRequest(ApiResponse<EfficiencyTrendData>.BadRequestResult("Invalid device ID"));
if (startDate >= endDate) 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 var filter = new EfficiencyFilter
{ {
@ -364,11 +364,11 @@ namespace Haoliang.Api.Controllers
}).ToList() }).ToList()
}; };
return Ok(ApiResponse<EfficiencyTrendData>.Success(trendData)); return Ok(ApiResponse<EfficiencyTrendData>.Ok(trendData));
} }
catch (Exception ex) 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 Microsoft.AspNetCore.Mvc;
using Haoliang.Core.Services; using Haoliang.Core.Services;
using Haoliang.Models.System; using Haoliang.Models.System;
using Haoliang.Models.Common;
namespace Haoliang.Api.Controllers namespace Haoliang.Api.Controllers
{ {
@ -32,7 +33,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var configs = await _configService.GetAllConfigsAsync(); var configs = await _configService.GetAllConfigsAsync();
return Ok(ApiResponse.Success(configs)); return Ok(ApiResponse.Ok(configs));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -51,7 +52,7 @@ namespace Haoliang.Api.Controllers
{ {
return NotFound(ApiResponse.NotFound($"Config '{key}' not found")); return NotFound(ApiResponse.NotFound($"Config '{key}' not found"));
} }
return Ok(ApiResponse.Success(config)); return Ok(ApiResponse.Ok(config));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -66,7 +67,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var config = await _configService.SetConfigAsync(key, request.Value); 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) catch (Exception ex)
{ {
@ -85,7 +86,7 @@ namespace Haoliang.Api.Controllers
{ {
return NotFound(ApiResponse.NotFound($"Config '{key}' not found")); 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) catch (Exception ex)
{ {
@ -100,7 +101,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var exists = await _configService.ConfigExistsAsync(key); var exists = await _configService.ConfigExistsAsync(key);
return Ok(ApiResponse.Success(exists)); return Ok(ApiResponse.Ok(exists));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -115,7 +116,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var configs = await _configService.GetConfigsByCategoryAsync(category); var configs = await _configService.GetConfigsByCategoryAsync(category);
return Ok(ApiResponse.Success(configs)); return Ok(ApiResponse.Ok(configs));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -130,7 +131,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
await _configService.RefreshConfigCacheAsync(); await _configService.RefreshConfigCacheAsync();
return Ok(ApiResponse.Success(null, "Config cache refreshed successfully")); return Ok(ApiResponse.Ok(null, "Config cache refreshed successfully"));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -141,7 +142,7 @@ namespace Haoliang.Api.Controllers
[HttpGet("logs")] [HttpGet("logs")]
public async Task<IActionResult> GetLogs( public async Task<IActionResult> GetLogs(
[FromQuery] LogLevel? logLevel = null, [FromQuery] Haoliang.Models.System.LogLevel? logLevel = null,
[FromQuery] DateTime? startDate = null, [FromQuery] DateTime? startDate = null,
[FromQuery] DateTime? endDate = null, [FromQuery] DateTime? endDate = null,
[FromQuery] string category = null) [FromQuery] string category = null)
@ -149,7 +150,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var logs = await _loggingService.GetLogsAsync(logLevel, startDate, endDate, category); var logs = await _loggingService.GetLogsAsync(logLevel, startDate, endDate, category);
return Ok(ApiResponse.Success(logs)); return Ok(ApiResponse.Ok(logs));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -164,7 +165,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var logs = await _loggingService.GetErrorLogsAsync(startDate, endDate); var logs = await _loggingService.GetErrorLogsAsync(startDate, endDate);
return Ok(ApiResponse.Success(logs)); return Ok(ApiResponse.Ok(logs));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -175,14 +176,14 @@ namespace Haoliang.Api.Controllers
[HttpGet("logs/count")] [HttpGet("logs/count")]
public async Task<IActionResult> GetLogCount( public async Task<IActionResult> GetLogCount(
[FromQuery] LogLevel? logLevel = null, [FromQuery] Haoliang.Models.System.LogLevel? logLevel = null,
[FromQuery] DateTime? startDate = null, [FromQuery] DateTime? startDate = null,
[FromQuery] DateTime? endDate = null) [FromQuery] DateTime? endDate = null)
{ {
try try
{ {
var count = await _loggingService.GetLogCountAsync(logLevel, startDate, endDate); var count = await _loggingService.GetLogCountAsync(logLevel, startDate, endDate);
return Ok(ApiResponse.Success(count)); return Ok(ApiResponse.Ok(count));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -197,7 +198,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
await _loggingService.ArchiveLogsAsync(daysToKeep); await _loggingService.ArchiveLogsAsync(daysToKeep);
return Ok(ApiResponse.Success(null, "Logs archived successfully")); return Ok(ApiResponse.Ok(null, "Logs archived successfully"));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -212,7 +213,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
await _loggingService.ClearLogsAsync(); await _loggingService.ClearLogsAsync();
return Ok(ApiResponse.Success(null, "Logs cleared successfully")); return Ok(ApiResponse.Ok(null, "Logs cleared successfully"));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -227,7 +228,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var tasks = await _schedulerService.GetAllScheduledTasksAsync(); var tasks = await _schedulerService.GetAllScheduledTasksAsync();
return Ok(ApiResponse.Success(tasks)); return Ok(ApiResponse.Ok(tasks));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -246,7 +247,7 @@ namespace Haoliang.Api.Controllers
{ {
return NotFound(ApiResponse.NotFound("Task not found")); return NotFound(ApiResponse.NotFound("Task not found"));
} }
return Ok(ApiResponse.Success(task)); return Ok(ApiResponse.Ok(task));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -256,12 +257,12 @@ namespace Haoliang.Api.Controllers
} }
[HttpPost("scheduler/tasks")] [HttpPost("scheduler/tasks")]
public async Task<IActionResult> CreateScheduledTask([FromBody] ScheduledTask task) public async Task<IActionResult> CreateScheduledTask([FromBody] Haoliang.Core.Services.ScheduledTask task)
{ {
try try
{ {
await _schedulerService.ScheduleTaskAsync(task); await _schedulerService.ScheduleTaskAsync(task);
return Ok(ApiResponse.Success(task, "Task scheduled successfully")); return Ok(ApiResponse.Ok(task, "Task scheduled successfully"));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -276,7 +277,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
await _schedulerService.ExecuteTaskAsync(taskId); await _schedulerService.ExecuteTaskAsync(taskId);
return Ok(ApiResponse.Success(null, "Task execution started")); return Ok(ApiResponse.Ok(null, "Task execution started"));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -295,7 +296,7 @@ namespace Haoliang.Api.Controllers
{ {
return NotFound(ApiResponse.NotFound("Task not found")); 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) catch (Exception ex)
{ {
@ -310,7 +311,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
await _schedulerService.StartSchedulerAsync(); await _schedulerService.StartSchedulerAsync();
return Ok(ApiResponse.Success(null, "Scheduler started successfully")); return Ok(ApiResponse.Ok(null, "Scheduler started successfully"));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -325,7 +326,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
await _schedulerService.StopSchedulerAsync(); await _schedulerService.StopSchedulerAsync();
return Ok(ApiResponse.Success(null, "Scheduler stopped successfully")); return Ok(ApiResponse.Ok(null, "Scheduler stopped successfully"));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -352,7 +353,7 @@ namespace Haoliang.Api.Controllers
IsHealthy = IsSystemHealthy() IsHealthy = IsSystemHealthy()
}; };
return Ok(ApiResponse.Success(status)); return Ok(ApiResponse.Ok(status));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -373,7 +374,7 @@ namespace Haoliang.Api.Controllers
Timestamp = DateTime.Now Timestamp = DateTime.Now
}; };
return Ok(ApiResponse.Success(health)); return Ok(ApiResponse.Ok(health));
} }
catch (Exception ex) catch (Exception ex)
{ {

@ -7,6 +7,7 @@ using Haoliang.Core.Services;
using Haoliang.Models.Template; using Haoliang.Models.Template;
using Haoliang.Models.Device; using Haoliang.Models.Device;
using Haoliang.Models.System; using Haoliang.Models.System;
using Haoliang.Models.Common;
namespace Haoliang.Api.Controllers namespace Haoliang.Api.Controllers
{ {
@ -37,7 +38,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var templates = await _templateService.GetAllTemplatesAsync(); var templates = await _templateService.GetAllTemplatesAsync();
return Ok(ApiResponse.Success(templates)); return Ok(ApiResponse.Ok(templates));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -56,7 +57,7 @@ namespace Haoliang.Api.Controllers
{ {
return NotFound(ApiResponse.NotFound("Template not found")); return NotFound(ApiResponse.NotFound("Template not found"));
} }
return Ok(ApiResponse.Success(template)); return Ok(ApiResponse.Ok(template));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -78,7 +79,7 @@ namespace Haoliang.Api.Controllers
} }
var createdTemplate = await _templateService.CreateTemplateAsync(template); 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) catch (Exception ex)
{ {
@ -106,7 +107,7 @@ namespace Haoliang.Api.Controllers
{ {
return NotFound(ApiResponse.NotFound("Template not found")); 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) catch (Exception ex)
{ {
@ -125,7 +126,7 @@ namespace Haoliang.Api.Controllers
{ {
return NotFound(ApiResponse.NotFound("Template not found")); 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) catch (Exception ex)
{ {
@ -144,7 +145,7 @@ namespace Haoliang.Api.Controllers
{ {
return NotFound(ApiResponse.NotFound("Template not found")); 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) catch (Exception ex)
{ {
@ -163,7 +164,7 @@ namespace Haoliang.Api.Controllers
{ {
return NotFound(ApiResponse.NotFound("Template not found")); 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) catch (Exception ex)
{ {
@ -178,7 +179,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var clonedTemplate = await _templateService.CloneTemplateAsync(id, request.NewName); 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) catch (Exception ex)
{ {
@ -193,7 +194,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
await _templateService.TestTemplateAsync(id); await _templateService.TestTemplateAsync(id);
return Ok(ApiResponse.Success(null, "Template test completed")); return Ok(ApiResponse.Ok(null, "Template test completed"));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -208,7 +209,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var templates = await _templateService.GetTemplatesByBrandAsync(brandName); var templates = await _templateService.GetTemplatesByBrandAsync(brandName);
return Ok(ApiResponse.Success(templates)); return Ok(ApiResponse.Ok(templates));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -223,7 +224,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var templates = await _templateService.GetActiveTemplatesAsync(); var templates = await _templateService.GetActiveTemplatesAsync();
return Ok(ApiResponse.Success(templates)); return Ok(ApiResponse.Ok(templates));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -245,7 +246,7 @@ namespace Haoliang.Api.Controllers
return BadRequest(ApiResponse.Error("Template validation failed", errors)); 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) catch (Exception ex)
{ {
@ -266,7 +267,7 @@ namespace Haoliang.Api.Controllers
return BadRequest(ApiResponse.Error("Migration not possible", migrationReport.Issues)); 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) catch (Exception ex)
{ {
@ -281,7 +282,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var mappings = await _tagMappingService.GetMappingsByTemplateAsync(templateId); var mappings = await _tagMappingService.GetMappingsByTemplateAsync(templateId);
return Ok(ApiResponse.Success(mappings)); return Ok(ApiResponse.Ok(mappings));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -296,7 +297,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var createdMapping = await _tagMappingService.CreateTagMappingAsync(mapping); 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) catch (Exception ex)
{ {
@ -311,7 +312,7 @@ namespace Haoliang.Api.Controllers
try try
{ {
var mappedTags = await _tagMappingService.MapDeviceTagsAsync(request.DeviceTags, request.TemplateId); 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) catch (Exception ex)
{ {

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
@ -12,7 +13,7 @@ using Haoliang.Models.Common;
namespace Haoliang.Api.Filters namespace Haoliang.Api.Filters
{ {
public class GlobalExceptionFilter : IExceptionFilter public class GlobalExceptionFilter : IAsyncExceptionFilter
{ {
private readonly ILogger<GlobalExceptionFilter> _logger; private readonly ILogger<GlobalExceptionFilter> _logger;
private readonly ILoggingService _loggingService; private readonly ILoggingService _loggingService;
@ -23,7 +24,7 @@ namespace Haoliang.Api.Filters
_loggingService = loggingService; _loggingService = loggingService;
} }
public void OnException(ExceptionContext context) public async Task OnExceptionAsync(ExceptionContext context)
{ {
// Log the exception // Log the exception
_logger.LogError(context.Exception, "An unhandled exception occurred"); _logger.LogError(context.Exception, "An unhandled exception occurred");

@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using Haoliang.Core.Services; using Haoliang.Core.Services;
using Haoliang.Models.Common; using Haoliang.Models.Common;
using Haoliang.Models.User;
namespace Haoliang.Api.Filters namespace Haoliang.Api.Filters
{ {
@ -47,7 +48,7 @@ namespace Haoliang.Api.Filters
if (requiredPermissions != null) if (requiredPermissions != null)
{ {
var hasPermission = _permissionService.UserHasPermissionAsync(user.Id, requiredPermissions.PermissionName).Result; var hasPermission = _permissionService.HasPermissionAsync(user.Id, requiredPermissions.PermissionName).Result;
if (!hasPermission) if (!hasPermission)
{ {
context.Result = new ForbidResult(); context.Result = new ForbidResult();

@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding;
using Haoliang.Core.Services; using Haoliang.Core.Services;
using Haoliang.Models.Common; using Haoliang.Models.Common;
using DataAnnotationsValidationResult = System.ComponentModel.DataAnnotations.ValidationResult;
namespace Haoliang.Api.Filters namespace Haoliang.Api.Filters
{ {
@ -129,7 +130,7 @@ namespace Haoliang.Api.Filters
public static (bool IsValid, List<string> Errors) ValidateModel(object model) public static (bool IsValid, List<string> Errors) ValidateModel(object model)
{ {
var validationContext = new ValidationContext(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 isValid = Validator.TryValidateObject(model, validationContext, validationResults, true);
var errors = validationResults.Select(vr => vr.ErrorMessage).ToList(); 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.Memory" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="8.0.0" />
<PackageReference Include="StackExchange.Redis" Version="2.7.17" /> <PackageReference Include="StackExchange.Redis" Version="2.7.17" />
<PackageReference Include="Moq" Version="4.20.69" /> <PackageReference Include="Serilog.AspNetCore" Version="8.0.0" />
<PackageReference Include="xunit" Version="2.6.1" /> <PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
<PackageReference Include="Xunit.DependencyInjection" Version="9.0.0" /> <PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

@ -1,11 +1,12 @@
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.Mvc;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Threading.Tasks; using System.Threading.Tasks;
using Haoliang.Core.Services; using Haoliang.Core.Services;
using Haoliang.Models.Models.Device; using Haoliang.Models.Device;
using Haoliang.Models.Models.Production; using Haoliang.Models.Production;
using Haoliang.Models.Models.System; using Haoliang.Models.System;
namespace Haoliang.Api.Hubs namespace Haoliang.Api.Hubs
{ {
@ -40,14 +41,15 @@ namespace Haoliang.Api.Hubs
// Get client information from query parameters // Get client information from query parameters
var userId = Context.GetHttpContext().Request.Query["userId"]; 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 dashboardId = Context.GetHttpContext().Request.Query["dashboardId"];
var clientInfo = new ClientConnectionInfo var clientInfo = new ClientConnectionInfo
{ {
ConnectionId = connectionId, ConnectionId = connectionId,
UserId = userId.ToString(), UserId = userId.ToString(),
ClientType = clientType.ToString(), ClientType = clientType,
ConnectedAt = DateTime.UtcNow, ConnectedAt = DateTime.UtcNow,
LastActivity = DateTime.UtcNow, LastActivity = DateTime.UtcNow,
DashboardId = string.IsNullOrEmpty(dashboardId.ToString()) ? null : dashboardId.ToString(), DashboardId = string.IsNullOrEmpty(dashboardId.ToString()) ? null : dashboardId.ToString(),
@ -400,7 +402,7 @@ namespace Haoliang.Api.Hubs
Status = deviceStatus.Status, Status = deviceStatus.Status,
CurrentProgram = deviceStatus.CurrentProgram, CurrentProgram = deviceStatus.CurrentProgram,
Runtime = deviceStatus.Runtime, Runtime = deviceStatus.Runtime,
Quantity = production, Quantity = production?.Quantity ?? 0,
Timestamp = DateTime.UtcNow, Timestamp = DateTime.UtcNow,
IntervalMs = intervalMs IntervalMs = intervalMs
}; };
@ -512,9 +514,9 @@ namespace Haoliang.Api.Hubs
{ {
public int DeviceId { get; set; } public int DeviceId { get; set; }
public string DeviceName { get; set; } public string DeviceName { get; set; }
public DeviceStatus Status { get; set; } public string Status { get; set; }
public string CurrentProgram { get; set; } public string CurrentProgram { get; set; }
public TimeSpan Runtime { get; set; } public string Runtime { get; set; }
public decimal Quantity { get; set; } public decimal Quantity { get; set; }
public DateTime Timestamp { get; set; } public DateTime Timestamp { get; set; }
public int IntervalMs { get; set; } public int IntervalMs { get; set; }

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Linq; using System.Linq;
using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;

@ -14,6 +14,8 @@ using Microsoft.Extensions.Logging;
using Pomelo.EntityFrameworkCore.MySql; using Pomelo.EntityFrameworkCore.MySql;
using Haoliang.Core.Services; using Haoliang.Core.Services;
using Haoliang.Api.Middleware; using Haoliang.Api.Middleware;
using Haoliang.Api.Hubs;
using Haoliang.Data;
using Haoliang.Data.Entities; using Haoliang.Data.Entities;
using Haoliang.Data.Repositories; using Haoliang.Data.Repositories;
@ -51,7 +53,7 @@ namespace Haoliang.Api
services.AddSignalR(); services.AddSignalR();
// 配置服务依赖注入 // 配置服务依赖注入
ConfigureServices(services); RegisterServices(services);
} }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
@ -65,7 +67,7 @@ namespace Haoliang.Api
// 中间件顺序很重要 // 中间件顺序很重要
app.UseMiddleware<LoggingMiddleware>(); app.UseMiddleware<LoggingMiddleware>();
app.UseMiddleware<CORSMiddleware>(); app.UseCors("AllowAll");
app.UseMiddleware<ExceptionMiddleware>(); app.UseMiddleware<ExceptionMiddleware>();
app.UseHttpsRedirection(); app.UseHttpsRedirection();
@ -81,7 +83,7 @@ namespace Haoliang.Api
}); });
} }
private void ConfigureServices(IServiceCollection services) private void RegisterServices(IServiceCollection services)
{ {
// 配置数据库连接 // 配置数据库连接
var connectionString = Configuration.GetConnectionString("DefaultConnection"); var connectionString = Configuration.GetConnectionString("DefaultConnection");
@ -113,47 +115,32 @@ namespace Haoliang.Api
} }
// 注册主要数据库上下文(用于业务操作) // 注册主要数据库上下文(用于业务操作)
services.AddDbContext<CNCBusinessDbContext>(options => // 注意DbContext 在下方统一注册一次,避免重复实例化
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)));
// 配置内存缓存 // 配置内存缓存
services.AddMemoryCache(); services.AddMemoryCache();
services.AddDistributedMemoryCache(); services.AddDistributedMemoryCache();
// 注册缓存服务 // 注册缓存服务使用Scoped生命周期以支持依赖注入
services.AddSingleton<ICacheService, MemoryCacheService>(); services.AddScoped<ICacheService, MemoryCacheService>();
// 注册状态机服务 // 注册状态机服务
services.AddHostedService<DeviceStateMachine>(); services.AddSingleton<DeviceStateMachine>();
services.AddHostedService(sp => sp.GetRequiredService<DeviceStateMachine>());
// 注册服务 // 注册服务
services.AddScoped<IDeviceCollectionService, DeviceCollectionService>(); services.AddScoped<IDeviceCollectionService, DeviceCollectionService>();
services.AddScoped<IProductionService, ProductionService>(); services.AddScoped<IProductionService, ProductionService>();
services.AddScoped<IProductionCalculator, ProductionCalculator>(); services.AddScoped<IProductionCalculator, ProductionCalculator>();
services.AddScoped<IProductionScheduler, ProductionScheduler>(); services.AddScoped<IProductionScheduler, ProductionScheduler>();
services.AddScoped<IAlarmService, AlarmManager>(); services.AddScoped<IAlarmService, AlarmService>();
services.AddScoped<IAlarmRuleService, AlarmRuleService>(); services.AddScoped<IAlarmRuleService, AlarmRuleService>();
services.AddScoped<IAlarmNotificationService, AlarmNotificationService>(); services.AddScoped<IAlarmNotificationService, AlarmNotificationService>();
services.AddScoped<ITemplateService, TemplateManager>(); services.AddScoped<ITemplateService, TemplateService>();
services.AddScoped<ITagMappingService, TagMappingService>(); services.AddScoped<ITagMappingService, TagMappingService>();
services.AddScoped<ITemplateValidationService, TemplateValidationService>(); services.AddScoped<ITemplateValidationService, TemplateValidationService>();
services.AddScoped<ITemplateMigrationService, TemplateMigrationService>(); services.AddScoped<ITemplateMigrationService, TemplateMigrationService>();
services.AddScoped<ILoggerService, ConsoleLoggerService>(); services.AddScoped<ILoggingService, LoggingService>();
services.AddScoped<ICacheService, MemoryCacheService>();
services.AddScoped<IRealTimeService, RealTimeService>(); services.AddScoped<IRealTimeService, RealTimeService>();
services.AddScoped<IProductionStatisticsService, ProductionStatisticsService>(); services.AddScoped<IProductionStatisticsService, ProductionStatisticsService>();
services.AddScoped<IRulesService, RulesService>(); services.AddScoped<IRulesService, RulesService>();
@ -168,27 +155,18 @@ namespace Haoliang.Api
// 注册后台任务服务 // 注册后台任务服务
services.AddHostedService<BackgroundTaskService>(); services.AddHostedService<BackgroundTaskService>();
// 注册仓储 // 注册仓储 (仅注册存在的)
services.AddScoped<IDeviceRepository, DeviceRepository>(); services.AddScoped<IDeviceRepository, DeviceRepository>();
services.AddScoped<ITemplateRepository, TemplateRepository>(); services.AddScoped<ITemplateRepository, TemplateRepository>();
services.AddScoped<IProductionRepository, ProductionRepository>(); services.AddScoped<IProductionRepository, ProductionRepository>();
services.AddScoped<IProgramProductionSummaryRepository, ProgramProductionSummaryRepository>(); services.AddScoped<IProgramProductionSummaryRepository, ProgramProductionSummaryRepository>();
services.AddScoped<IProductionSummaryRepository, ProductionSummaryRepository>(); services.AddScoped<IProductionSummaryRepository, ProductionSummaryRepository>();
services.AddScoped<IAlarmRepository, AlarmRepository>(); 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<ICollectionTaskRepository, CollectionTaskRepository>();
services.AddScoped<ICollectionResultRepository, CollectionResultRepository>(); services.AddScoped<ICollectionResultRepository, CollectionResultRepository>();
services.AddScoped<ICollectionLogRepository, CollectionLogRepository>(); services.AddScoped<ICollectionLogRepository, CollectionLogRepository>();
services.AddScoped<ILogRepository, LogRepository>(); services.AddScoped<ILogRepository, LogRepository>();
services.AddScoped<IUserRepository, UserRepository>(); services.AddScoped<IUserRepository, UserRepository>();
services.AddScoped<IAlarmNotificationRepository, AlarmNotificationRepository>();
services.AddScoped<ITagMappingRepository, TagMappingRepository>();
// 注册设备状态相关仓储
services.AddScoped<IDeviceStatusRepository, DeviceStatusRepository>();
// 注册Ping服务 // 注册Ping服务
services.AddScoped<IPingService, PingService>(); services.AddScoped<IPingService, PingService>();
@ -197,6 +175,7 @@ namespace Haoliang.Api
services.AddScoped<IDataParserService, DataParserService>(); services.AddScoped<IDataParserService, DataParserService>();
services.AddScoped<IDataStorageService, DataStorageService>(); services.AddScoped<IDataStorageService, DataStorageService>();
services.AddScoped<IRetryService, RetryService>(); services.AddScoped<IRetryService, RetryService>();
services.AddScoped<IRetryService, RetryService>();
// 注册SignalR Hub // 注册SignalR Hub
services.AddSingleton<RealTimeHub>(); services.AddSingleton<RealTimeHub>();

@ -70,6 +70,13 @@ namespace Haoliang.Core.Services
/// <param name="email">邮箱地址</param> /// <param name="email">邮箱地址</param>
/// <returns>是否存在</returns> /// <returns>是否存在</returns>
Task<bool> EmailExistsAsync(string email); Task<bool> EmailExistsAsync(string email);
/// <summary>
/// 根据ID获取用户
/// </summary>
/// <param name="userId">用户ID</param>
/// <returns>用户信息</returns>
Task<User> GetUserByIdAsync(int userId);
} }
/// <summary> /// <summary>
@ -237,6 +244,12 @@ namespace Haoliang.Core.Services
/// 清除所有日志 /// 清除所有日志
/// </summary> /// </summary>
Task ClearLogsAsync(); Task ClearLogsAsync();
/// <summary>
/// 记录信息日志 (LogInfoAsync的别名)
/// </summary>
/// <param name="message">日志消息</param>
Task LogInfoAsync(string message);
} }
/// <summary> /// <summary>
@ -384,6 +397,13 @@ namespace Haoliang.Core.Services
/// <param name="deviceId">设备ID</param> /// <param name="deviceId">设备ID</param>
/// <returns>健康状态信息</returns> /// <returns>健康状态信息</returns>
Task<DeviceHealth> GetDeviceHealthAsync(int deviceId); Task<DeviceHealth> GetDeviceHealthAsync(int deviceId);
/// <summary>
/// 获取设备当前状态
/// </summary>
/// <param name="deviceId">设备ID</param>
/// <returns>设备当前状态信息</returns>
Task<DeviceStatus> GetDeviceCurrentStatusAsync(int deviceId);
} }
/// <summary> /// <summary>
@ -518,10 +538,13 @@ namespace Haoliang.Core.Services
public class DeviceStatus public class DeviceStatus
{ {
public int DeviceId { get; set; } public int DeviceId { get; set; }
public string? DeviceName { get; set; }
public string? Status { get; set; } public string? Status { get; set; }
public DateTime Timestamp { get; set; } public DateTime Timestamp { get; set; }
public string? OperatingMode { get; set; } public string? OperatingMode { get; set; }
public string? RunState { get; set; } public string? RunState { get; set; }
public string? CurrentProgram { get; set; }
public string? Runtime { get; set; }
} }
#endregion #endregion
@ -613,6 +636,14 @@ namespace Haoliang.Core.Services
/// </summary> /// </summary>
/// <param name="daysToKeep">保留天数</param> /// <param name="daysToKeep">保留天数</param>
Task ArchiveProductionDataAsync(int daysToKeep = 90); 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> /// <summary>
@ -1308,6 +1339,116 @@ namespace Haoliang.Core.Services
/// 刷新配置缓存 /// 刷新配置缓存
/// </summary> /// </summary>
Task RefreshConfigCacheAsync(); 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> /// <summary>
@ -1651,19 +1792,34 @@ namespace Haoliang.Core.Services
/// <param name="toTime">结束时间</param> /// <param name="toTime">结束时间</param>
/// <returns>执行历史</returns> /// <returns>执行历史</returns>
Task<IEnumerable<RuleExecutionHistory>> GetRuleExecutionHistoryAsync(int ruleId, DateTime fromTime, DateTime toTime); 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> /// <summary>
/// 业务规则 /// 业务规则 (与 Haoliang.Models.System.BusinessRuleConfig 同结构)
/// </summary> /// </summary>
public class BusinessRule public class BusinessRule
{ {
public int RuleId { get; set; } public int RuleId { get; set; }
public string? Name { get; set; } public string? RuleName { get; set; }
public string? Description { get; set; } public string? RuleType { get; set; }
public string? Category { get; set; } public string? Category { get; set; }
public string? Expression { get; set; }
public bool IsEnabled { get; set; } public bool IsEnabled { get; set; }
public string? Configuration { get; set; }
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { 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<AuthResult> RefreshTokenAsync(string refreshToken) => Task.FromResult<AuthResult>(null);
public Task<bool> UsernameExistsAsync(string username) => Task.FromResult(false); public Task<bool> UsernameExistsAsync(string username) => Task.FromResult(false);
public Task<bool> EmailExistsAsync(string email) => 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 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<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 ArchiveLogsAsync(int daysToKeep = 90) => Task.CompletedTask;
public Task ClearLogsAsync() => Task.CompletedTask; public Task ClearLogsAsync() => Task.CompletedTask;
public Task LogInfoAsync(string message) { Console.WriteLine($"[INFO] {message}"); return Task.CompletedTask; }
} }
public class MemoryCacheService : ICacheService public class MemoryCacheService : ICacheService
@ -81,14 +83,18 @@ namespace Haoliang.Core.Services
public Task CollectAllDevicesAsync() => Task.CompletedTask; public Task CollectAllDevicesAsync() => Task.CompletedTask;
public Task<DeviceStatus> GetDeviceStatusAsync(int deviceId) => Task.FromResult(new DeviceStatus()); public Task<DeviceStatus> GetDeviceStatusAsync(int deviceId) => Task.FromResult(new DeviceStatus());
public Task<DeviceHealth> GetDeviceHealthAsync(int deviceId) => Task.FromResult(new DeviceHealth()); 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 DeviceStatus GetCurrentState(int deviceId) => new DeviceStatus();
public bool TransitionTo(int deviceId, DeviceStatus newState) => false; public bool TransitionTo(int deviceId, DeviceStatus newState) => false;
public void RegisterStateChangeHandler(int deviceId, Action<int, DeviceStatus, DeviceStatus> callback) { } public void RegisterStateChangeHandler(int deviceId, Action<int, DeviceStatus, DeviceStatus> callback) { }
public IEnumerable<DeviceStatusChange> GetStateHistory(int deviceId, DateTime fromTime, DateTime toTime) => new List<DeviceStatusChange>(); 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 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<ProgramProductionSummary> GetProgramProductionAsync(string programName, DateTime date) => Task.FromResult<ProgramProductionSummary>(null);
public Task<byte[]> ExportProductionDataAsync(DateTime startDate, DateTime endDate) => Task.FromResult<byte[]>(null); public Task<byte[]> ExportProductionDataAsync(DateTime startDate, DateTime endDate) => Task.FromResult<byte[]>(null);
public Task ArchiveProductionDataAsync(int daysToKeep = 90) => Task.CompletedTask; public Task ArchiveProductionDataAsync(int daysToKeep = 90) => Task.CompletedTask;
public Task<ProductionRecord> GetDeviceProductionForDateAsync(int deviceId, DateTime date) => Task.FromResult<ProductionRecord>(null);
} }
public class ProductionCalculator : IProductionCalculator public class ProductionCalculator : IProductionCalculator
@ -245,6 +252,28 @@ namespace Haoliang.Core.Services
public Task<bool> ConfigExistsAsync(string key) => Task.FromResult(false); 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<IEnumerable<SystemConfig>> GetConfigsByCategoryAsync(string category) => Task.FromResult<IEnumerable<SystemConfig>>(new List<SystemConfig>());
public Task RefreshConfigCacheAsync() => Task.CompletedTask; 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 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<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<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<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 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>
/// 创建未找到响应 /// 创建未找到响应
/// </summary> /// </summary>

@ -6,6 +6,7 @@ namespace Haoliang.Models.Device
public class CNCDevice public class CNCDevice
{ {
public int Id { get; set; } public int Id { get; set; }
public int DeviceId { get => Id; set => Id = value; }
public string DeviceCode { get; set; } public string DeviceCode { get; set; }
public string DeviceName { get; set; } public string DeviceName { get; set; }
public string IPAddress { get; set; } public string IPAddress { get; set; }

@ -6,6 +6,7 @@ namespace Haoliang.Models.Template
public class CNCBrandTemplate public class CNCBrandTemplate
{ {
public int Id { get; set; } public int Id { get; set; }
public int TemplateId { get => Id; set => Id = value; }
public string BrandName { get; set; } public string BrandName { get; set; }
public string Description { get; set; } public string Description { get; set; }
public bool IsEnabled { get; set; } public bool IsEnabled { get; set; }

@ -101,7 +101,9 @@ namespace Haoliang.Models.User
public string RealName { get; set; } public string RealName { get; set; }
public string Email { get; set; } public string Email { get; set; }
public string Phone { get; set; } public string Phone { get; set; }
public string Role { get; set; }
public string RoleName { get; set; } public string RoleName { get; set; }
public string Department { get; set; }
public bool IsActive { get; set; } public bool IsActive { get; set; }
public DateTime? LastLoginTime { get; set; } public DateTime? LastLoginTime { get; set; }
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }

@ -9,9 +9,12 @@ namespace Haoliang.Models.User
public string Username { get; set; } public string Username { get; set; }
public string PasswordHash { get; set; } public string PasswordHash { get; set; }
public string RealName { get; set; } public string RealName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; } public string Email { get; set; }
public string Phone { get; set; } public string Phone { get; set; }
public int RoleId { get; set; } public int RoleId { get; set; }
public string Department { get; set; }
public bool IsActive { get; set; } public bool IsActive { get; set; }
public DateTime? LastLoginTime { get; set; } public DateTime? LastLoginTime { get; set; }
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
@ -55,6 +58,7 @@ namespace Haoliang.Models.User
{ {
public string Username { get; set; } public string Username { get; set; }
public string Password { get; set; } public string Password { get; set; }
public bool RememberMe { get; set; }
} }
public class LoginResponse public class LoginResponse

Loading…
Cancel
Save