using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.ComponentModel.DataAnnotations;
using WIDESEAWCS_S7Simulator.Core.Entities;
using WIDESEAWCS_S7Simulator.Core.Enums;
using WIDESEAWCS_S7Simulator.Web.Services;
namespace WIDESEAWCS_S7Simulator.Web.Pages;
///
/// 编辑实例页
///
public class EditModel : BasePageModel
{
private readonly ILogger _logger;
private readonly ApiHttpClient _apiClient;
public EditModel(ILogger logger, IConfiguration configuration, ApiHttpClient apiClient)
: base(configuration)
{
_logger = logger;
_apiClient = apiClient;
}
[BindProperty]
public EditInstanceInputModel Input { get; set; } = new();
public InstanceState? CurrentInstance { get; private set; }
public bool IsRunning { get; private set; }
public async Task OnGetAsync(string id)
{
if (string.IsNullOrWhiteSpace(id))
{
return BadRequest("实例ID不能为空");
}
try
{
// 获取实例状态
CurrentInstance = await _apiClient.GetInstanceAsync(id);
if (CurrentInstance != null)
{
IsRunning = CurrentInstance.Status == InstanceStatus.Running;
// 获取实例配置
var config = await _apiClient.GetInstanceConfigAsync(id);
if (config != null)
{
Input.Id = config.Id;
Input.Name = config.Name;
Input.PLCType = config.PLCType;
Input.Port = config.Port;
Input.ActivationKey = config.ActivationKey;
Input.AutoStart = config.AutoStart;
// 内存配置
Input.MRegionSize = config.MemoryConfig.MRegionSize;
Input.DBBlockCount = config.MemoryConfig.DBBlockCount;
Input.DBBlockSize = config.MemoryConfig.DBBlockSize;
Input.IRegionSize = config.MemoryConfig.IRegionSize;
Input.QRegionSize = config.MemoryConfig.QRegionSize;
Input.TRegionCount = config.MemoryConfig.TRegionCount;
Input.CRegionCount = config.MemoryConfig.CRegionCount;
}
}
else
{
return NotFound($"实例 \"{id}\" 不存在");
}
}
catch (HttpRequestException ex)
{
_logger.LogError(ex, "Failed to load instance {InstanceId}", id);
ModelState.AddModelError(string.Empty, "加载实例失败,请稍后重试");
}
return Page();
}
public async Task OnPostAsync()
{
if (!ModelState.IsValid)
{
await LoadInstanceStateAsync(Input.Id);
return Page();
}
try
{
var config = new InstanceConfig
{
Id = Input.Id,
Name = Input.Name,
PLCType = Input.PLCType,
Port = Input.Port,
ActivationKey = Input.ActivationKey ?? string.Empty,
AutoStart = Input.AutoStart,
MemoryConfig = new MemoryRegionConfig
{
MRegionSize = Input.MRegionSize > 0 ? Input.MRegionSize : 1024,
DBBlockCount = Input.DBBlockCount > 0 ? Input.DBBlockCount : 100,
DBBlockSize = Input.DBBlockSize > 0 ? Input.DBBlockSize : 1024,
IRegionSize = Input.IRegionSize > 0 ? Input.IRegionSize : 256,
QRegionSize = Input.QRegionSize > 0 ? Input.QRegionSize : 256,
TRegionCount = Input.TRegionCount > 0 ? Input.TRegionCount : 64,
CRegionCount = Input.CRegionCount > 0 ? Input.CRegionCount : 64
}
};
var result = await _apiClient.UpdateInstanceAsync(Input.Id, config);
if (result != null)
{
_logger.LogInformation("Instance {InstanceId} updated successfully", Input.Id);
TempData["SuccessMessage"] = $"实例 \"{Input.Id}\" 更新成功!";
return RedirectToPage("/Index");
}
else
{
ModelState.AddModelError(string.Empty, "更新实例失败");
}
}
catch (HttpRequestException ex)
{
_logger.LogError(ex, "Failed to update instance");
ModelState.AddModelError(string.Empty, "网络错误,请稍后重试");
}
await LoadInstanceStateAsync(Input.Id);
return Page();
}
private async Task LoadInstanceStateAsync(string id)
{
try
{
CurrentInstance = await _apiClient.GetInstanceAsync(id);
if (CurrentInstance != null)
{
IsRunning = CurrentInstance.Status == InstanceStatus.Running;
}
}
catch
{
// Ignore errors when reloading state
}
}
///
/// 编辑实例输入模型
///
public class EditInstanceInputModel
{
public string Id { get; set; } = string.Empty;
[Required(ErrorMessage = "实例名称不能为空")]
[StringLength(100, ErrorMessage = "实例名称不能超过100个字符")]
public string Name { get; set; } = string.Empty;
[Required(ErrorMessage = "PLC型号不能为空")]
public SiemensPLCType PLCType { get; set; } = SiemensPLCType.S71200;
[Required(ErrorMessage = "端口不能为空")]
[Range(1, 65535, ErrorMessage = "端口必须在1-65535之间")]
public int Port { get; set; } = 102;
[StringLength(200, ErrorMessage = "激活码不能超过200个字符")]
public string? ActivationKey { get; set; }
public bool AutoStart { get; set; } = false;
// 内存配置
public int MRegionSize { get; set; }
public int DBBlockCount { get; set; }
public int DBBlockSize { get; set; }
public int IRegionSize { get; set; }
public int QRegionSize { get; set; }
public int TRegionCount { get; set; }
public int CRegionCount { get; set; }
}
}