Toolhub / Views /Admin /Index.cshtml
unifare
Initial commit: ToolHub ASP.NET Core app
5fc700d
@{
ViewData["Title"] = "仪表板";
Layout = "_AdminLayout";
}
<!-- 统计卡片 -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 mb-6">
<div class="stats-card">
<div class="stats-number" style="color: var(--primary);">
@(ViewBag.TotalTools ?? 0)
</div>
<div class="stats-label">
<i class="fas fa-tools" style="margin-right: 0.5rem;"></i>
工具总数
</div>
</div>
<div class="stats-card">
<div class="stats-number" style="color: var(--secondary);">
@(ViewBag.TotalCategories ?? 0)
</div>
<div class="stats-label">
<i class="fas fa-tags" style="margin-right: 0.5rem;"></i>
分类总数
</div>
</div>
<div class="stats-card">
<div class="stats-number" style="color: var(--success);">
@(ViewBag.TotalUsers ?? 0)
</div>
<div class="stats-label">
<i class="fas fa-users" style="margin-right: 0.5rem;"></i>
用户总数
</div>
</div>
<div class="stats-card">
<div class="stats-number" style="color: var(--warning);">
@{
var totalViews = ViewBag.TotalViews as long? ?? 0;
var viewsDisplay = totalViews > 1000000 ? $"{totalViews / 1000000:F1}M" :
totalViews > 1000 ? $"{totalViews / 1000:F0}K" :
totalViews.ToString();
}
@viewsDisplay
</div>
<div class="stats-label">
<i class="fas fa-eye" style="margin-right: 0.5rem;"></i>
总访问量
</div>
</div>
</div>
<div class="grid grid-cols-1 lg:grid-cols-2">
<!-- 最新工具 -->
<div class="data-table" style="margin-bottom: 2rem;">
<div style="padding: 1.5rem; border-bottom: 1px solid var(--light-2);">
<h3 style="margin: 0; font-size: 1.1rem; font-weight: 600; color: var(--dark);">
<i class="fas fa-clock" style="margin-right: 0.5rem; color: var(--primary);"></i>
最新工具
</h3>
</div>
@if (ViewBag.RecentTools is List<ToolHub.Models.Tool> recentTools && recentTools.Any())
{
<table>
<thead>
<tr>
<th>工具名称</th>
<th>分类</th>
<th>状态</th>
<th>创建时间</th>
</tr>
</thead>
<tbody>
@foreach (var tool in recentTools)
{
<tr>
<td>
<div style="display: flex; align-items: center;">
@if (!string.IsNullOrEmpty(tool.Icon))
{
<i class="@tool.Icon" style="margin-right: 0.75rem; color: var(--primary);"></i>
}
<div>
<strong>@tool.Name</strong>
@if (!string.IsNullOrEmpty(tool.Description) && tool.Description.Length > 30)
{
<br><small style="color: var(--dark-2);">@(tool.Description.Substring(0, 30))...</small>
}
</div>
</div>
</td>
<td>
<span class="badge badge-primary">@tool.Category?.Name</span>
</td>
<td>
@if (tool.IsHot)
{
<span class="badge badge-danger">热门</span>
}
@if (tool.IsNew)
{
<span class="badge badge-warning">新品</span>
}
@if (tool.IsRecommended)
{
<span class="badge badge-success">推荐</span>
}
@if (!tool.IsHot && !tool.IsNew && !tool.IsRecommended)
{
<span class="badge badge-secondary">普通</span>
}
</td>
<td style="color: var(--dark-2); font-size: 0.875rem;">
@tool.CreatedAt.ToString("MM-dd HH:mm")
</td>
</tr>
}
</tbody>
</table>
}
else
{
<div style="padding: 2rem; text-align: center; color: var(--dark-2);">
<i class="fas fa-inbox" style="font-size: 2rem; margin-bottom: 1rem; display: block;"></i>
暂无工具数据
</div>
}
<div style="padding: 1rem; border-top: 1px solid var(--light-2); text-align: center;">
<a href="@Url.Action("Index", "Tool")" class="btn btn-outline btn-sm">
查看所有工具
</a>
</div>
</div>
<!-- 快速操作 -->
<div class="data-table">
<div style="padding: 1.5rem; border-bottom: 1px solid var(--light-2);">
<h3 style="margin: 0; font-size: 1.1rem; font-weight: 600; color: var(--dark);">
<i class="fas fa-bolt" style="margin-right: 0.5rem; color: var(--warning);"></i>
快速操作
</h3>
</div>
<div style="padding: 1.5rem;">
<div style="display: grid; gap: 1rem;">
<a href="@Url.Action("Index", "Tool")"
style="display: flex; align-items: center; padding: 1rem; background: var(--light-1); border-radius: var(--border-radius); text-decoration: none; color: var(--dark); transition: var(--transition);"
onmouseover="this.style.background='var(--primary)'; this.style.color='white';"
onmouseout="this.style.background='var(--light-1)'; this.style.color='var(--dark)';">
<i class="fas fa-plus-circle" style="font-size: 1.5rem; margin-right: 1rem; color: var(--primary);"></i>
<div>
<strong>工具管理</strong>
<br><small style="opacity: 0.8;">管理平台上的工具</small>
</div>
</a>
<a href="@Url.Action("Index", "Category")"
style="display: flex; align-items: center; padding: 1rem; background: var(--light-1); border-radius: var(--border-radius); text-decoration: none; color: var(--dark); transition: var(--transition);"
onmouseover="this.style.background='var(--secondary)'; this.style.color='white';"
onmouseout="this.style.background='var(--light-1)'; this.style.color='var(--dark)';">
<i class="fas fa-tag" style="font-size: 1.5rem; margin-right: 1rem; color: var(--secondary);"></i>
<div>
<strong>分类管理</strong>
<br><small style="opacity: 0.8;">管理工具分类</small>
</div>
</a>
<a href="@Url.Action("Index", "Tag")"
style="display: flex; align-items: center; padding: 1rem; background: var(--light-1); border-radius: var(--border-radius); text-decoration: none; color: var(--dark); transition: var(--transition);"
onmouseover="this.style.background='var(--accent)'; this.style.color='white';"
onmouseout="this.style.background='var(--light-1)'; this.style.color='var(--dark)';">
<i class="fas fa-tags" style="font-size: 1.5rem; margin-right: 1rem; color: var(--accent);"></i>
<div>
<strong>标签管理</strong>
<br><small style="opacity: 0.8;">管理工具标签</small>
</div>
</a>
<a href="@Url.Action("Users", "Admin")"
style="display: flex; align-items: center; padding: 1rem; background: var(--light-1); border-radius: var(--border-radius); text-decoration: none; color: var(--dark); transition: var(--transition);"
onmouseover="this.style.background='var(--success)'; this.style.color='white';"
onmouseout="this.style.background='var(--light-1)'; this.style.color='var(--dark)';">
<i class="fas fa-user-cog" style="font-size: 1.5rem; margin-right: 1rem; color: var(--success);"></i>
<div>
<strong>用户管理</strong>
<br><small style="opacity: 0.8;">管理注册用户</small>
</div>
</a>
<a href="@Url.Action("Index", "Home")" target="_blank"
style="display: flex; align-items: center; padding: 1rem; background: var(--light-1); border-radius: var(--border-radius); text-decoration: none; color: var(--dark); transition: var(--transition);"
onmouseover="this.style.background='var(--accent)'; this.style.color='white';"
onmouseout="this.style.background='var(--light-1)'; this.style.color='var(--dark)';">
<i class="fas fa-external-link-alt" style="font-size: 1.5rem; margin-right: 1rem; color: var(--accent);"></i>
<div>
<strong>访问网站</strong>
<br><small style="opacity: 0.8;">查看前台网站</small>
</div>
</a>
<button onclick="initImageCompressor()"
style="display: flex; align-items: center; padding: 1rem; background: var(--light-1); border-radius: var(--border-radius); border: none; color: var(--dark); transition: var(--transition); cursor: pointer; width: 100%;"
onmouseover="this.style.background='var(--warning)'; this.style.color='white';"
onmouseout="this.style.background='var(--light-1)'; this.style.color='var(--dark)';">
<i class="fas fa-compress-alt" style="font-size: 1.5rem; margin-right: 1rem; color: var(--warning);"></i>
<div style="text-align: left;">
<strong>初始化图片压缩工具</strong>
<br><small style="opacity: 0.8;">添加图片压缩工具到数据库</small>
</div>
</button>
</div>
</div>
</div>
</div>
<!-- 系统信息 -->
<div class="data-table mt-6">
<div style="padding: 1.5rem; border-bottom: 1px solid var(--light-2);">
<h3 style="margin: 0; font-size: 1.1rem; font-weight: 600; color: var(--dark);">
<i class="fas fa-info-circle" style="margin-right: 0.5rem; color: var(--primary);"></i>
系统信息
</h3>
</div>
<div style="padding: 1.5rem;">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4">
<div>
<strong>系统版本</strong>
<p style="color: var(--dark-2); margin: 0.25rem 0 0;">ToolHub v1.0.0</p>
</div>
<div>
<strong>运行环境</strong>
<p style="color: var(--dark-2); margin: 0.25rem 0 0;">.NET 9.0</p>
</div>
<div>
<strong>数据库</strong>
<p style="color: var(--dark-2); margin: 0.25rem 0 0;">SQLite + FreeSql</p>
</div>
<div>
<strong>服务器时间</strong>
<p style="color: var(--dark-2); margin: 0.25rem 0 0;">@DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")</p>
</div>
</div>
</div>
</div>
<script>
async function initImageCompressor() {
try {
const button = event.target.closest('button');
const originalContent = button.innerHTML;
// 显示加载状态
button.innerHTML = `
<i class="fas fa-spinner fa-spin" style="font-size: 1.5rem; margin-right: 1rem; color: var(--warning);"></i>
<div style="text-align: left;">
<strong>初始化中...</strong>
<br><small style="opacity: 0.8;">请稍候</small>
</div>
`;
button.disabled = true;
const response = await fetch('/Tool/InitImageCompressor');
const result = await response.json();
if (result.success) {
toolHub.showToast('图片压缩工具初始化成功!', 'success');
// 恢复按钮状态
button.innerHTML = `
<i class="fas fa-check-circle" style="font-size: 1.5rem; margin-right: 1rem; color: var(--success);"></i>
<div style="text-align: left;">
<strong>初始化完成</strong>
<br><small style="opacity: 0.8;">图片压缩工具已添加</small>
</div>
`;
// 3秒后恢复原状态
setTimeout(() => {
button.innerHTML = originalContent;
button.disabled = false;
}, 3000);
} else {
toolHub.showToast(result.message || '初始化失败', 'error');
button.innerHTML = originalContent;
button.disabled = false;
}
} catch (error) {
console.error('初始化失败:', error);
toolHub.showToast('初始化失败,请重试', 'error');
// 恢复按钮状态
const button = event.target.closest('button');
button.innerHTML = originalContent;
button.disabled = false;
}
}
</script>