Files
DRS9.Dashboard/src/DRS9.Dashboard.Server/Components/Pages/Applications.razor
2026-01-13 13:50:27 +08:00

250 lines
8.8 KiB
Plaintext

@page "/applications"
@rendermode @(new InteractiveServerRenderMode())
@inject Services.ApiClientService ApiClient
@inject IJSRuntime JSRuntime
<PageTitle>内容管理 - DRS9 信息发布系统</PageTitle>
<h3 class="mb-4">内容管理</h3>
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<span><i class="bi bi-grid"></i> 内容列表</span>
<button class="btn btn-primary btn-sm" @onclick="ShowAddModal">
<i class="bi bi-plus-lg"></i> 添加内容
</button>
</div>
<div class="card-body">
@if (_applications == null)
{
<div class="text-center py-4">
<div class="spinner-border text-primary" role="status"></div>
</div>
}
else if (_applications.Count == 0)
{
<div class="text-center text-muted py-4">
<i class="bi bi-inbox fs-1 d-block mb-3"></i>
<p>暂无内容,点击上方按钮添加</p>
</div>
}
else
{
<div class="row">
@foreach (var app in _applications)
{
<div class="col-md-4 mb-3">
<div class="card h-100">
<div class="card-body">
<div class="d-flex align-items-start">
<div class="content-icon @GetAppTypeClass(app.Type)">
<i class="bi @GetAppIcon(app.Type)"></i>
</div>
<div class="flex-grow-1">
<h6 class="mb-1">@app.Name</h6>
<p class="text-muted mb-2 small">@app.Type</p>
<p class="mb-2 small">@app.Description</p>
</div>
</div>
</div>
<div class="card-footer d-flex justify-content-end gap-2">
<button class="btn btn-sm btn-outline-primary" @onclick="@(() => EditApp(app))">
<i class="bi bi-pencil"></i> 编辑
</button>
<button class="btn btn-sm btn-outline-danger" @onclick="@(() => DeleteApp(app))">
<i class="bi bi-trash"></i> 删除
</button>
</div>
</div>
</div>
}
</div>
}
</div>
</div>
<!-- 添加/编辑 Modal -->
@if (_showModal)
{
<div class="modal fade show d-block" style="background-color: rgba(0,0,0,0.5)" tabindex="-1" @onclick="CloseModal">
<div class="modal-dialog" @onclick:stopPropagation="true">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">@(_editingApp?.Id == null ? "添加内容" : "编辑内容")</h5>
<button type="button" class="btn-close" @onclick="CloseModal"></button>
</div>
<div class="modal-body">
@if (!string.IsNullOrEmpty(_errorMessage))
{
<div class="alert alert-danger" role="alert">
@_errorMessage
</div>
}
<div class="mb-3">
<label class="form-label">内容名称</label>
<input type="text" class="form-control" @bind="_appName" />
</div>
<div class="mb-3">
<label class="form-label">内容类型</label>
<select class="form-select" @bind="_appType" disabled="@(_editingApp != null)">
<option value="">请选择...</option>
<option value="Dashboard">Dashboard</option>
<option value="WebRotator">WebRotator</option>
<option value="Image">Image</option>
<option value="Video">Video</option>
</select>
@if (_editingApp != null)
{
<small class="text-muted">内容类型创建后不可修改</small>
}
</div>
<div class="mb-3">
<label class="form-label">内容 URL</label>
<input type="url" class="form-control" @bind="_appContentUrl" placeholder="https://..." />
</div>
<div class="mb-3">
<label class="form-label">描述</label>
<textarea class="form-control" @bind="_appDescription" rows="3"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" @onclick="CloseModal">取消</button>
<button type="button" class="btn btn-primary" @onclick="SaveApp">保存</button>
</div>
</div>
</div>
</div>
}
@code {
private List<ApplicationDto> _applications = new();
private ApplicationDto? _editingApp;
private string _appName = "";
private string _appType = "";
private string _appContentUrl = "";
private string _appDescription = "";
private bool _showModal = false;
private string _errorMessage = "";
protected override async Task OnInitializedAsync()
{
_applications = await ApiClient.GetApplicationsAsync();
}
private void ShowAddModal()
{
_editingApp = null;
_appName = "";
_appType = "";
_appContentUrl = "";
_appDescription = "";
_errorMessage = "";
_showModal = true;
}
private void EditApp(ApplicationDto app)
{
_editingApp = app;
_appName = app.Name;
_appType = app.Type;
_appContentUrl = app.ContentUrl;
_appDescription = app.Description ?? "";
_errorMessage = "";
_showModal = true;
}
private void CloseModal()
{
_showModal = false;
_editingApp = null;
_errorMessage = "";
}
private async Task SaveApp()
{
// Validate inputs
if (string.IsNullOrWhiteSpace(_appName))
{
_errorMessage = "请输入内容名称";
return;
}
if (string.IsNullOrWhiteSpace(_appType))
{
_errorMessage = "请选择内容类型";
return;
}
if (string.IsNullOrWhiteSpace(_appContentUrl))
{
_errorMessage = "请输入内容 URL";
return;
}
bool success;
if (_editingApp == null)
{
success = await ApiClient.CreateApplicationAsync(new ApplicationCreateRequest
{
Name = _appName,
Type = _appType,
ContentUrl = _appContentUrl,
Description = _appDescription
});
}
else
{
success = await ApiClient.UpdateApplicationAsync(_editingApp.Id, new ApplicationUpdateRequest
{
Name = _appName,
Description = _appDescription,
ContentUrl = _appContentUrl
});
}
if (success)
{
CloseModal();
_applications = await ApiClient.GetApplicationsAsync();
await JSRuntime.InvokeVoidAsync("alert", "保存成功");
}
else
{
_errorMessage = "保存失败,请检查输入数据或稍后重试";
}
}
private async Task DeleteApp(ApplicationDto app)
{
if (await JSRuntime.InvokeAsync<bool>("confirm", $"确定要删除内容 '{app.Name}' 吗?"))
{
var success = await ApiClient.DeleteApplicationAsync(app.Id);
if (success)
{
_applications = await ApiClient.GetApplicationsAsync();
await JSRuntime.InvokeVoidAsync("alert", "删除成功");
}
else
{
await JSRuntime.InvokeVoidAsync("alert", "删除失败");
}
}
}
private string GetAppTypeClass(string type) => type switch
{
"Dashboard" => "dashboard",
"WebRotator" => "web",
"Image" => "image",
"Video" => "video",
_ => ""
};
private string GetAppIcon(string type) => type switch
{
"Dashboard" => "bi-bar-chart",
"WebRotator" => "bi-arrow-repeat",
"Image" => "bi-image",
"Video" => "bi-play-circle",
_ => "bi-file-earmark"
};
}