|
|
using Microsoft.AspNetCore.Mvc; |
|
|
using Microsoft.AspNetCore.Authorization; |
|
|
using ToolHub.Models; |
|
|
using ToolHub.Services; |
|
|
|
|
|
namespace ToolHub.Controllers; |
|
|
|
|
|
[Authorize(Roles = "Admin")] |
|
|
public class ToolController : Controller |
|
|
{ |
|
|
private readonly IToolService _toolService; |
|
|
private readonly IFreeSql _freeSql; |
|
|
|
|
|
public ToolController(IToolService toolService, IFreeSql freeSql) |
|
|
{ |
|
|
_toolService = toolService; |
|
|
_freeSql = freeSql; |
|
|
} |
|
|
|
|
|
|
|
|
public async Task<IActionResult> Index(int page = 1, int categoryId = 0) |
|
|
{ |
|
|
ViewBag.Categories = await _toolService.GetCategoriesAsync(); |
|
|
ViewBag.CurrentCategory = categoryId; |
|
|
ViewBag.CurrentPage = page; |
|
|
|
|
|
var pageSize = 20; |
|
|
var tools = await _toolService.GetToolsByCategoryAsync(categoryId, page, pageSize,true); |
|
|
|
|
|
|
|
|
var totalCount = await GetToolsCountAsync(categoryId); |
|
|
var totalPages = (int)Math.Ceiling((double)totalCount / pageSize); |
|
|
|
|
|
ViewBag.TotalCount = totalCount; |
|
|
ViewBag.TotalPages = totalPages; |
|
|
ViewBag.PageSize = pageSize; |
|
|
|
|
|
return View(tools); |
|
|
} |
|
|
|
|
|
|
|
|
private async Task<int> GetToolsCountAsync(int categoryId = 0) |
|
|
{ |
|
|
var query = _freeSql.Select<Tool>().Where(t => t.IsActive); |
|
|
|
|
|
if (categoryId > 0) |
|
|
{ |
|
|
query = query.Where(t => t.CategoryId == categoryId); |
|
|
} |
|
|
|
|
|
return (int)await query.CountAsync(); |
|
|
} |
|
|
|
|
|
|
|
|
[HttpGet] |
|
|
public async Task<IActionResult> GetTools(int page = 1, int categoryId = 0, string search = "") |
|
|
{ |
|
|
try |
|
|
{ |
|
|
var pageSize = 20; |
|
|
List<Tool> tools; |
|
|
int totalCount; |
|
|
|
|
|
if (!string.IsNullOrEmpty(search)) |
|
|
{ |
|
|
tools = await _toolService.SearchToolsAsync(search, page, pageSize); |
|
|
totalCount = (int)await _freeSql.Select<Tool>() |
|
|
.Where(t => t.IsActive && (t.Name.Contains(search) || t.Description!.Contains(search))) |
|
|
.CountAsync(); |
|
|
} |
|
|
else |
|
|
{ |
|
|
tools = await _toolService.GetToolsByCategoryAsync(categoryId, page, pageSize); |
|
|
totalCount = await GetToolsCountAsync(categoryId); |
|
|
} |
|
|
|
|
|
var totalPages = (int)Math.Ceiling((double)totalCount / pageSize); |
|
|
|
|
|
return Json(new |
|
|
{ |
|
|
tools = tools, |
|
|
pagination = new |
|
|
{ |
|
|
currentPage = page, |
|
|
totalPages = totalPages, |
|
|
totalCount = totalCount, |
|
|
pageSize = pageSize, |
|
|
hasNext = page < totalPages, |
|
|
hasPrev = page > 1 |
|
|
} |
|
|
}); |
|
|
} |
|
|
catch |
|
|
{ |
|
|
return Json(new { success = false, message = "获取工具列表失败" }); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
[HttpGet] |
|
|
public async Task<IActionResult> GetAllTools() |
|
|
{ |
|
|
try |
|
|
{ |
|
|
var tools = await _freeSql.Select<Tool>() |
|
|
.Where(t => t.IsActive) |
|
|
.OrderBy(t => t.Name) |
|
|
.ToListAsync(); |
|
|
|
|
|
return Json(new { success = true, tools = tools }); |
|
|
} |
|
|
catch |
|
|
{ |
|
|
return Json(new { success = false, message = "获取工具列表失败" }); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
[HttpGet] |
|
|
public async Task<IActionResult> Get(int id) |
|
|
{ |
|
|
try |
|
|
{ |
|
|
var tool = await _freeSql.Select<Tool>() |
|
|
.Where(t => t.Id == id) |
|
|
.FirstAsync(); |
|
|
|
|
|
if (tool == null) |
|
|
return NotFound(); |
|
|
|
|
|
return Json(tool); |
|
|
} |
|
|
catch |
|
|
{ |
|
|
return StatusCode(500); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
[HttpPost] |
|
|
public async Task<IActionResult> Save([FromBody] ToolDto toolDto) |
|
|
{ |
|
|
try |
|
|
{ |
|
|
if (toolDto.Id == 0) |
|
|
{ |
|
|
|
|
|
var tool = new Tool |
|
|
{ |
|
|
Name = toolDto.Name, |
|
|
Description = toolDto.Description, |
|
|
Icon = toolDto.Icon, |
|
|
Image = toolDto.Image, |
|
|
Url = toolDto.Url, |
|
|
CategoryId = toolDto.CategoryId, |
|
|
IsHot = toolDto.IsHot, |
|
|
IsNew = toolDto.IsNew, |
|
|
IsRecommended = toolDto.IsRecommended, |
|
|
SortOrder = toolDto.SortOrder, |
|
|
IsActive = true |
|
|
}; |
|
|
await _freeSql.Insert(tool).ExecuteAffrowsAsync(); |
|
|
} |
|
|
else |
|
|
{ |
|
|
|
|
|
await _freeSql.Update<Tool>() |
|
|
.Where(t => t.Id == toolDto.Id) |
|
|
.Set(t => t.Name, toolDto.Name) |
|
|
.Set(t => t.Description, toolDto.Description) |
|
|
.Set(t => t.Icon, toolDto.Icon) |
|
|
.Set(t => t.Image, toolDto.Image) |
|
|
.Set(t => t.Url, toolDto.Url) |
|
|
.Set(t => t.CategoryId, toolDto.CategoryId) |
|
|
.Set(t => t.IsHot, toolDto.IsHot) |
|
|
.Set(t => t.IsNew, toolDto.IsNew) |
|
|
.Set(t => t.IsRecommended, toolDto.IsRecommended) |
|
|
.Set(t => t.SortOrder, toolDto.SortOrder) |
|
|
.Set(t => t.UpdatedAt, DateTime.Now) |
|
|
.ExecuteAffrowsAsync(); |
|
|
} |
|
|
return Json(new { success = true }); |
|
|
} |
|
|
catch |
|
|
{ |
|
|
return Json(new { success = false }); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
[HttpPost] |
|
|
public async Task<IActionResult> Delete([FromBody] DeleteToolRequest request) |
|
|
{ |
|
|
try |
|
|
{ |
|
|
var result = await _toolService.DeleteToolAsync(request.Id); |
|
|
return Json(new { success = result }); |
|
|
} |
|
|
catch |
|
|
{ |
|
|
return Json(new { success = false }); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
[HttpPost] |
|
|
public async Task<IActionResult> ToggleStatus([FromBody] ToggleToolStatusRequest request) |
|
|
{ |
|
|
try |
|
|
{ |
|
|
await _freeSql.Update<Tool>() |
|
|
.Where(t => t.Id == request.Id) |
|
|
.Set(t => t.IsActive, request.IsActive) |
|
|
.Set(t => t.UpdatedAt, DateTime.Now) |
|
|
.ExecuteAffrowsAsync(); |
|
|
return Json(new { success = true }); |
|
|
} |
|
|
catch |
|
|
{ |
|
|
return Json(new { success = false }); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
[HttpPost] |
|
|
public async Task<IActionResult> UpdateFlags([FromBody] UpdateToolFlagsRequest request) |
|
|
{ |
|
|
try |
|
|
{ |
|
|
await _freeSql.Update<Tool>() |
|
|
.Where(t => t.Id == request.Id) |
|
|
.Set(t => t.IsHot, request.IsHot) |
|
|
.Set(t => t.IsNew, request.IsNew) |
|
|
.Set(t => t.IsRecommended, request.IsRecommended) |
|
|
.Set(t => t.UpdatedAt, DateTime.Now) |
|
|
.ExecuteAffrowsAsync(); |
|
|
return Json(new { success = true }); |
|
|
} |
|
|
catch |
|
|
{ |
|
|
return Json(new { success = false }); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
[HttpGet] |
|
|
public async Task<IActionResult> InitImageCompressor() |
|
|
{ |
|
|
try |
|
|
{ |
|
|
|
|
|
var existingTool = await _freeSql.Select<Tool>() |
|
|
.Where(t => t.Name == "图片压缩工具" || t.Url!.Contains("/Tools/ImageCompressor")) |
|
|
.FirstAsync(); |
|
|
|
|
|
if (existingTool != null) |
|
|
{ |
|
|
return Json(new { success = false, message = "图片压缩工具已存在" }); |
|
|
} |
|
|
|
|
|
|
|
|
var category = await _freeSql.Select<Category>() |
|
|
.Where(c => c.Name == "图像处理" || c.Name == "图片工具") |
|
|
.FirstAsync(); |
|
|
|
|
|
if (category == null) |
|
|
{ |
|
|
|
|
|
category = new Category |
|
|
{ |
|
|
Name = "图像处理", |
|
|
Description = "图片处理、编辑、转换等相关工具", |
|
|
Icon = "fas fa-image", |
|
|
Color = "#FF6B35", |
|
|
SortOrder = 3, |
|
|
IsActive = true, |
|
|
CreatedAt = DateTime.Now |
|
|
}; |
|
|
var categoryId = await _freeSql.Insert(category).ExecuteIdentityAsync(); |
|
|
category.Id = (int)categoryId; |
|
|
} |
|
|
|
|
|
|
|
|
var tool = new Tool |
|
|
{ |
|
|
Name = "图片压缩工具", |
|
|
Description = "快速压缩图片文件,支持JPG、PNG、WebP等格式,保持高质量的同时大幅减小文件体积", |
|
|
Icon = "fas fa-compress-alt", |
|
|
Image = "", |
|
|
Url = "/Tools/ImageCompressor", |
|
|
CategoryId = category.Id, |
|
|
IsHot = true, |
|
|
IsNew = true, |
|
|
IsRecommended = true, |
|
|
IsActive = true, |
|
|
SortOrder = 1, |
|
|
ViewCount = 0, |
|
|
CreatedAt = DateTime.Now |
|
|
}; |
|
|
|
|
|
await _freeSql.Insert(tool).ExecuteAffrowsAsync(); |
|
|
|
|
|
return Json(new { success = true, message = "图片压缩工具初始化成功" }); |
|
|
} |
|
|
catch (Exception ex) |
|
|
{ |
|
|
return Json(new { success = false, message = ex.Message }); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public class ToolDto |
|
|
{ |
|
|
public int Id { get; set; } |
|
|
public string Name { get; set; } = string.Empty; |
|
|
public string? Description { get; set; } |
|
|
public string? Icon { get; set; } |
|
|
public string? Image { get; set; } |
|
|
public string? Url { get; set; } |
|
|
public int CategoryId { get; set; } |
|
|
public bool IsHot { get; set; } |
|
|
public bool IsNew { get; set; } |
|
|
public bool IsRecommended { get; set; } |
|
|
public int SortOrder { get; set; } |
|
|
} |
|
|
|
|
|
public class DeleteToolRequest |
|
|
{ |
|
|
public int Id { get; set; } |
|
|
} |
|
|
|
|
|
public class ToggleToolStatusRequest |
|
|
{ |
|
|
public int Id { get; set; } |
|
|
public bool IsActive { get; set; } |
|
|
} |
|
|
|
|
|
public class UpdateToolFlagsRequest |
|
|
{ |
|
|
public int Id { get; set; } |
|
|
public bool IsHot { get; set; } |
|
|
public bool IsNew { get; set; } |
|
|
public bool IsRecommended { get; set; } |
|
|
} |
|
|
|