using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
using System.ComponentModel.DataAnnotations;
|
using WIDESEAWCS_S7Simulator.Core.Entities;
|
using WIDESEAWCS_S7Simulator.Core.Enums;
|
|
namespace WIDESEAWCS_S7Simulator.Web.Pages;
|
|
/// <summary>
|
/// 编辑实例页
|
/// </summary>
|
public class EditModel : PageModel
|
{
|
private readonly ILogger<EditModel> _logger;
|
private readonly HttpClient _httpClient;
|
|
public EditModel(ILogger<EditModel> logger, IHttpClientFactory httpClientFactory)
|
{
|
_logger = logger;
|
_httpClient = httpClientFactory.CreateClient();
|
_httpClient.BaseAddress = new Uri($"{Request.Scheme}://{Request.Host}");
|
}
|
|
[BindProperty]
|
public EditInstanceInputModel Input { get; set; } = new();
|
|
public InstanceState? CurrentInstance { get; private set; }
|
|
public bool IsRunning { get; private set; }
|
|
public async Task<IActionResult> OnGetAsync(string id)
|
{
|
if (string.IsNullOrWhiteSpace(id))
|
{
|
return BadRequest("实例ID不能为空");
|
}
|
|
try
|
{
|
var response = await _httpClient.GetAsync($"/api/SimulatorInstances/{Uri.EscapeDataString(id)}");
|
|
if (response.IsSuccessStatusCode)
|
{
|
CurrentInstance = await response.Content.ReadFromJsonAsync<InstanceState>();
|
IsRunning = CurrentInstance?.Status == InstanceStatus.Running;
|
|
// Load existing config
|
var configResponse = await _httpClient.GetAsync($"/api/SimulatorInstances");
|
if (configResponse.IsSuccessStatusCode)
|
{
|
var allInstances = await configResponse.Content.ReadFromJsonAsync<List<InstanceState>>();
|
// For now, we'll initialize with defaults. In production, you'd have a separate endpoint to get instance config
|
}
|
|
// Initialize input with current values (default for now)
|
Input.Id = id;
|
Input.Name = CurrentInstance?.InstanceId ?? id;
|
Input.Port = 102; // Default
|
}
|
else if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
|
{
|
return NotFound($"实例 \"{id}\" 不存在");
|
}
|
}
|
catch (HttpRequestException ex)
|
{
|
_logger.LogError(ex, "Failed to load instance {InstanceId}", id);
|
ModelState.AddModelError(string.Empty, "加载实例失败,请稍后重试");
|
}
|
|
return Page();
|
}
|
|
public async Task<IActionResult> OnPostAsync()
|
{
|
if (!ModelState.IsValid)
|
{
|
// Reload instance state
|
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 response = await _httpClient.PutAsJsonAsync($"/api/SimulatorInstances/{Uri.EscapeDataString(Input.Id)}", config);
|
|
if (response.IsSuccessStatusCode)
|
{
|
_logger.LogInformation("Instance {InstanceId} updated successfully", Input.Id);
|
TempData["SuccessMessage"] = $"实例 \"{Input.Id}\" 更新成功!";
|
return RedirectToPage("/Index");
|
}
|
else if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
|
{
|
ModelState.AddModelError(string.Empty, "实例不存在");
|
}
|
else
|
{
|
var error = await response.Content.ReadFromJsonAsync<object>();
|
ModelState.AddModelError(string.Empty, error?.ToString() ?? "更新实例失败");
|
}
|
}
|
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
|
{
|
var response = await _httpClient.GetAsync($"/api/SimulatorInstances/{Uri.EscapeDataString(id)}");
|
if (response.IsSuccessStatusCode)
|
{
|
CurrentInstance = await response.Content.ReadFromJsonAsync<InstanceState>();
|
IsRunning = CurrentInstance?.Status == InstanceStatus.Running;
|
}
|
}
|
catch
|
{
|
// Ignore errors when reloading state
|
}
|
}
|
|
/// <summary>
|
/// 编辑实例输入模型
|
/// </summary>
|
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; }
|
}
|
}
|