first commit -push

This commit is contained in:
dungtt
2025-10-15 15:15:53 +07:00
parent 674ae395be
commit a9577c5756
885 changed files with 74595 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
using Microsoft.AspNetCore.Mvc;
using RobotNet.ScriptManager.Services;
using RobotNet.Shares;
namespace RobotNet.ScriptManager.Controllers;
[Route("api/[controller]")]
[ApiController]
public class DashboardConfigController(DashboardConfig Config, ILogger<DashboardConfigController> Logger) : ControllerBase
{
[HttpGet]
public Task<MessageResult<string[]>> GetOpenACSSettings()
{
try
{
return Task.FromResult<MessageResult<string[]>>(new(true, "") { Data = Config.MissionNames });
}
catch (Exception ex)
{
Logger.LogWarning($"Lấy cấu hình OpenACS xảy ra lỗi: {ex.Message}");
return Task.FromResult<MessageResult<string[]>>(new(false, "Hệ thống có lỗi xảy ra"));
}
}
[HttpPost]
public async Task<MessageResult> UpdatePublishSetting([FromBody] string[] missionNames)
{
try
{
await Config.UpdateMissionNames(missionNames);
return new(true, "");
}
catch (Exception ex)
{
Logger.LogWarning($"Cập nhật cấu hình publish OpenACS xảy ra lỗi: {ex.Message}");
return new(false, "Hệ thống có lỗi xảy ra");
}
}
}

View File

@@ -0,0 +1,197 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using RobotNet.Script.Shares;
using RobotNet.ScriptManager.Helpers;
using RobotNet.ScriptManager.Services;
using RobotNet.Shares;
namespace RobotNet.ScriptManager.Controllers;
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class ScriptController(ScriptStateManager scriptBuilder) : ControllerBase
{
[HttpGet]
[Route("")]
public ScriptFolder Gets() => new("Scripts", GetScriptFolders(ScriptConfiguration.ScriptStorePath), GetScriptFiles(ScriptConfiguration.ScriptStorePath));
[HttpPost]
[Route("Directory")]
public MessageResult CreateDirectory([FromBody] CreateModel model)
{
if(scriptBuilder.State == ProcessorState.Building
|| scriptBuilder.State == ProcessorState.Starting
|| scriptBuilder.State == ProcessorState.Running
|| scriptBuilder.State == ProcessorState.Stopping)
{
return new(false, $"Hệ thống đang trong trạng thái {scriptBuilder.State}, không thể tạo thư mục");
}
var fullPath = Path.Combine(ScriptConfiguration.ScriptStorePath, model.Path, model.Name);
if (Directory.Exists(fullPath)) return new(false, "Folder đã tồn tại");
try
{
Directory.CreateDirectory(fullPath);
return new(true, "");
}
catch (Exception e)
{
return new(false, e.Message);
}
}
[HttpPost]
[Route("File")]
public MessageResult CreateFile([FromBody] CreateModel model)
{
if (scriptBuilder.State == ProcessorState.Building
|| scriptBuilder.State == ProcessorState.Starting
|| scriptBuilder.State == ProcessorState.Running
|| scriptBuilder.State == ProcessorState.Stopping)
{
return new(false, $"Hệ thống đang trong trạng thái {scriptBuilder.State}, không thể tạo file");
}
var fullPath = Path.Combine(ScriptConfiguration.ScriptStorePath, model.Path, model.Name);
if (System.IO.File.Exists(fullPath)) return new(false, "File đã tồn tại");
try
{
var fs = System.IO.File.Create(fullPath);
fs.Close();
return new(true, "");
}
catch (Exception e)
{
return new(false, e.Message);
}
}
[HttpPatch]
[Route("File")]
public MessageResult UpdateCode([FromBody] UpdateModel model)
{
if (scriptBuilder.State == ProcessorState.Building
|| scriptBuilder.State == ProcessorState.Starting
|| scriptBuilder.State == ProcessorState.Running
|| scriptBuilder.State == ProcessorState.Stopping)
{
return new(false, $"Hệ thống đang trong trạng thái {scriptBuilder.State}, không thể update file");
}
var fullPath = Path.Combine(ScriptConfiguration.ScriptStorePath, model.Path);
System.IO.File.WriteAllText(fullPath, model.Code);
ResetScriptProcessor();
return new(true, "");
}
[HttpPatch]
[Route("FileName")]
public MessageResult RenameFile([FromBody] RenameModel model)
{
if (scriptBuilder.State == ProcessorState.Building
|| scriptBuilder.State == ProcessorState.Starting
|| scriptBuilder.State == ProcessorState.Running
|| scriptBuilder.State == ProcessorState.Stopping)
{
return new(false, $"Hệ thống đang trong trạng thái {scriptBuilder.State}, không thể thay đổi tên file");
}
var fullPath = Path.Combine(ScriptConfiguration.ScriptStorePath, model.Path);
if (!System.IO.File.Exists(fullPath)) return new(false, "Source code không tồn tại");
var folder = Path.GetDirectoryName(fullPath) ?? "";
var fi = new FileInfo(fullPath);
fi.MoveTo(Path.Combine(folder, model.NewName));
return new(true, "");
}
[HttpPatch]
[Route("DirectoryName")]
public MessageResult RenameDirectory([FromBody] RenameModel model)
{
if (scriptBuilder.State == ProcessorState.Building
|| scriptBuilder.State == ProcessorState.Starting
|| scriptBuilder.State == ProcessorState.Running
|| scriptBuilder.State == ProcessorState.Stopping)
{
return new(false, $"Hệ thống đang trong trạng thái {scriptBuilder.State}, không thể thay đổi tên thư mục");
}
var fullPath = Path.Combine(ScriptConfiguration.ScriptStorePath, model.Path);
if (!Directory.Exists(fullPath)) return new(false, "Folder không tồn tại");
var folder = Path.GetDirectoryName(fullPath) ?? "";
var di = new DirectoryInfo(fullPath);
di.MoveTo(Path.Combine(folder, model.NewName));
return new(true, "");
}
[HttpDelete]
[Route("File")]
public MessageResult DeleteFile([FromQuery] string path)
{
if (scriptBuilder.State == ProcessorState.Building
|| scriptBuilder.State == ProcessorState.Starting
|| scriptBuilder.State == ProcessorState.Running
|| scriptBuilder.State == ProcessorState.Stopping)
{
return new(false, $"Hệ thống đang trong trạng thái {scriptBuilder.State}, không thể xóa file");
}
var fullPath = Path.Combine(ScriptConfiguration.ScriptStorePath, path);
if (!System.IO.File.Exists(fullPath)) return new(false, "Source code không tồn tại");
System.IO.File.Delete(fullPath);
ResetScriptProcessor();
return new(true, "");
}
[HttpDelete]
[Route("Directory")]
public MessageResult DeleteDirectory([FromQuery] string path)
{
if (scriptBuilder.State == ProcessorState.Building
|| scriptBuilder.State == ProcessorState.Starting
|| scriptBuilder.State == ProcessorState.Running
|| scriptBuilder.State == ProcessorState.Stopping)
{
return new(false, $"Hệ thống đang trong trạng thái {scriptBuilder.State}, không thể xóa thư mục");
}
var fullPath = Path.Combine(ScriptConfiguration.ScriptStorePath, path);
if (!Directory.Exists(fullPath)) return new(false, "Folder không tồn tại");
var di = new DirectoryInfo(fullPath);
di.Delete(true);
ResetScriptProcessor();
return new(true, "");
}
[HttpGet]
[Route("UsingNamespaces")]
public IEnumerable<string> GetUsingNamespaces() => ScriptConfiguration.UsingNamespaces;
[HttpGet]
[Route("PreCode")]
public string GetPreCode() => ScriptConfiguration.DeveloptGlobalsScript;
private void ResetScriptProcessor()
{
string message = string.Empty;
scriptBuilder.Reset(ref message);
}
private static IEnumerable<ScriptFile> GetScriptFiles(string parentDir)
{
var dirInfo = new DirectoryInfo(parentDir);
foreach (var fileInfo in dirInfo.GetFiles())
{
yield return new ScriptFile(fileInfo.Name, System.IO.File.ReadAllText(fileInfo.FullName));
}
}
private static IEnumerable<ScriptFolder> GetScriptFolders(string parentDir)
{
var dirInfo = new DirectoryInfo(parentDir);
foreach (var dir in dirInfo.GetDirectories())
{
yield return new ScriptFolder(dir.Name, GetScriptFolders(dir.FullName), GetScriptFiles(dir.FullName));
}
}
}

View File

@@ -0,0 +1,47 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace RobotNet.ScriptManager.Controllers;
[Route("api/[controller]")]
[ApiController]
[AllowAnonymous]
public class ScriptManagerLoggerController(ILogger<ScriptManagerLoggerController> Logger) : ControllerBase
{
private readonly string LoggerDirectory = "scriptManagerlogs";
[HttpGet]
public async Task<IEnumerable<string>> GetLogs([FromQuery(Name = "date")] DateTime date)
{
string temp = "";
try
{
string fileName = $"{date:yyyy-MM-dd}.log";
string path = Path.Combine(LoggerDirectory, fileName);
if (!Path.GetFullPath(path).StartsWith(Path.GetFullPath(LoggerDirectory)))
{
Logger.LogWarning($"GetLogs: phát hiện đường dẫn không hợp lệ.");
return [];
}
if (!System.IO.File.Exists(path))
{
Logger.LogWarning($"GetLogs: không tìm thấy file log của ngày {date.ToShortDateString()} - {path}.");
return [];
}
temp = Path.Combine(LoggerDirectory, $"{Guid.NewGuid()}.log");
System.IO.File.Copy(path, temp);
return await System.IO.File.ReadAllLinesAsync(temp);
}
catch (Exception ex)
{
Logger.LogWarning($"GetLogs: Hệ thống có lỗi xảy ra - {ex.Message}");
return [];
}
finally
{
if (System.IO.File.Exists(temp)) System.IO.File.Delete(temp);
}
}
}

View File

@@ -0,0 +1,154 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using RobotNet.Script.Shares;
using RobotNet.ScriptManager.Data;
using RobotNet.ScriptManager.Services;
using RobotNet.Shares;
using System.Security.Claims;
namespace RobotNet.ScriptManager.Controllers;
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class ScriptMissionsController(ScriptMissionManager missionManager, ScriptManagerDbContext scriptManagerDb, ScriptMissionCreator missionCreator) : ControllerBase
{
[HttpGet]
[Route("")]
public IEnumerable<ScriptMissionDto> GetAlls() => missionManager.GetMissionDatas();
[HttpGet]
[Route("Runner")]
public async Task<SearchResult<InstanceMissionDto>> Search(
[FromQuery(Name = "txtSearch")] string? txtSearch,
[FromQuery(Name = "page")] int page,
[FromQuery(Name = "size")] int size)
{
IOrderedQueryable<InstanceMission> query;
if (string.IsNullOrWhiteSpace(txtSearch))
{
query = scriptManagerDb.InstanceMissions.AsQueryable().OrderByDescending(x => x.CreatedAt);
}
else
{
query = scriptManagerDb.InstanceMissions.AsQueryable().Where(x => x.MissionName.Contains(txtSearch)).OrderByDescending(x => x.CreatedAt);
}
var total = await query.CountAsync();
// Đảm bảo size hợp lệ
if (size <= 0) size = 10;
// Tính tổng số trang
var totalPages = (int)Math.Ceiling(total / (double)size);
// Đảm bảo page hợp lệ
if (page <= 0) page = 1;
if (page > totalPages && totalPages > 0) page = totalPages;
// Nếu không có dữ liệu, trả về rỗng
var items = Enumerable.Empty<InstanceMissionDto>();
if (total > 0)
{
items = [.. await query
.OrderByDescending(x => x.CreatedAt)
.Skip((page - 1) * size)
.Take(size)
.Select(x => new InstanceMissionDto
{
Id = x.Id,
MissionName = x.MissionName,
Parameters = x.Parameters,
CreatedAt = x.CreatedAt,
Status = x.Status,
Log = x.Log
})
.ToListAsync()];
}
return new SearchResult<InstanceMissionDto>
{
Total = total,
Page = page,
Size = size,
Items = items
};
}
[HttpPost]
[Route("Runner")]
public async Task<MessageResult<Guid>> Create(InstanceMissionCreateModel model)
{
try
{
var id = await missionCreator.CreateMissionAsync(model.Name, model.Parameters);
return new(true, "Tạo nhiệm vụ thành công") { Data = id };
}
catch (Exception ex)
{
return new MessageResult<Guid>(false, $"Lỗi khi tạo nhiệm vụ: {ex.Message}");
}
}
[HttpDelete]
[Route("Runner/{id:guid}")]
public async Task<MessageResult> Cancel(Guid id, [FromQuery] string? reason)
{
if (missionManager.Cancel(id, $"Cancel by user '{HttpContext.User.FindFirst(ClaimTypes.Name)?.Value??HttpContext.User.Identity?.Name}' with reason '{reason}'"))
{
var mission = await scriptManagerDb.InstanceMissions.FindAsync(id);
if (mission != null)
{
mission.Status = MissionStatus.Canceling;
await scriptManagerDb.SaveChangesAsync();
}
return new MessageResult(true, "Gửi yêu cầu hủy nhiệm vụ thành công");
}
else
{
return new MessageResult(false, "Không thể hủy nhiệm vụ này hoặc nhiệm vụ không tồn tại");
}
}
[HttpPut]
[Route("Runner/{id:guid}/pause")]
public async Task<MessageResult> Pause(Guid id)
{
if (missionManager.Pause(id))
{
var mission = await scriptManagerDb.InstanceMissions.FindAsync(id);
if (mission != null)
{
mission.Status = MissionStatus.Pausing;
await scriptManagerDb.SaveChangesAsync();
}
return new MessageResult(true, "Gửi yêu cầu tạm dừng nhiệm vụ thành công");
}
else
{
return new MessageResult(false, "Không thể tạm dừng nhiệm vụ này hoặc nhiệm vụ không tồn tại");
}
}
[HttpPut]
[Route("Runner/{id:guid}/resume")]
public async Task<MessageResult> Resume(Guid id)
{
if (missionManager.Resume(id))
{
var mission = await scriptManagerDb.InstanceMissions.FindAsync(id);
if (mission != null)
{
mission.Status = MissionStatus.Resuming;
await scriptManagerDb.SaveChangesAsync();
}
return new MessageResult(true, "Gửi yêu cầu tiếp tục nhiệm vụ thành công");
}
else
{
return new MessageResult(false, "Không thể tiếp tục nhiệm vụ này hoặc nhiệm vụ không tồn tại");
}
}
}

View File

@@ -0,0 +1,18 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using RobotNet.Script.Shares;
using RobotNet.ScriptManager.Services;
using RobotNet.Shares;
namespace RobotNet.ScriptManager.Controllers;
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class ScriptTasksController(ScriptTaskManager taskManager) : ControllerBase
{
[HttpGet]
[Route("")]
public IEnumerable<ScriptTaskDto> GetAlls() => taskManager.GetTaskDatas();
}

View File

@@ -0,0 +1,72 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using RobotNet.Script.Shares;
using RobotNet.ScriptManager.Services;
using RobotNet.Shares;
namespace RobotNet.ScriptManager.Controllers;
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class ScriptVariablesController(ScriptGlobalsManager globalManager) : ControllerBase
{
[HttpGet]
[Route("")]
public IEnumerable<ScriptVariableDto> GetAlls() => globalManager.GetVariablesData();
[HttpGet]
[Route("{name}")]
public MessageResult<string> GetVariableValue(string name)
{
if (globalManager.Globals.TryGetValue(name, out var value))
{
return new (true, "") { Data = value?.ToString() ?? "null" };
}
else
{
return new(false, $"Variable \"{name}\" not found.");
}
}
[HttpPut]
[Route("{name}")]
public MessageResult UpdateVariableValue(string name, [FromBody] UpdateVariableModel model)
{
try
{
if(name != model.Name)
{
return new MessageResult(false, "Variable name in the URL does not match the name in the body.");
}
globalManager.SetValue(model.Name, model.Value);
return new MessageResult(true, $"Variable \"{model.Name}\" updated {model.Value} successfully.");
}
catch (Exception ex)
{
return new MessageResult(false, ex.Message);
}
}
[HttpPut]
[Route("{name}/Reset")]
public MessageResult ResetVariableValue(string name, [FromBody] UpdateVariableModel model)
{
try
{
if (name != model.Name)
{
return new MessageResult(false, "Variable name in the URL does not match the name in the body.");
}
globalManager.ResetValue(model.Name);
return new MessageResult(true, $"Variable \"{model.Name}\" reset successfully.");
}
catch (Exception ex)
{
return new MessageResult(false, ex.Message);
}
}
}