This commit is contained in:
南浔
2025-07-31 22:52:41 +08:00
73 changed files with 7108 additions and 16 deletions
@@ -47,7 +47,7 @@ namespace Apimanager_backend.Controllers
#endregion
#region API列表
[HttpGet]
[Authorize(Roles = "User")]
//[Authorize(Roles = "User")]
public async Task<ActionResult<ResponseBase<List<ApiInfoDto>>>> ApiList(int pageIndex,int pageSize,bool desc)
{
var list = await apiService.GetApisAsync(pageIndex, pageSize, desc);
@@ -0,0 +1,48 @@
using Apimanager_backend.Dtos;
using Apimanager_backend.Models;
using Apimanager_backend.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Apimanager_backend.Controllers
{
[Route("api/[controller][action]")]
[ApiController]
public class OrderController:ControllerBase
{
private IOrderService _orderService;
private ILogger<OrderController> _logger;
public OrderController(IOrderService orderService,ILogger<OrderController> logger)
{
_orderService = orderService;
_logger = logger;
}
//获取全部订单列表
[HttpGet]
[Authorize(Roles = "Admin")]
public async Task<ActionResult<ResponseBase<List<Order>>>> GetOrders(int pageIndex,int pageSize,bool desc)
{
var orderList = await _orderService.GetOrdersAsync(pageIndex,pageSize,desc, null);
var responseData = new ResponseBase<List<Order>>(
code:1000,
message:"Success",
data:orderList
);
return Ok(responseData);
}
//获取个人订单列表
[HttpGet]
[Authorize(Roles = "User")]
public async Task<ActionResult<ResponseBase<List<Order>>>> GetMyOrders(int pageIndex,int pageSize,bool desc)
{
string userId = User.Claims.First(x => x.Type == "userId").Value;
var orderList = await _orderService.GetOrdersAsync(pageIndex,pageSize,desc,int.Parse(userId));
var responseData = new ResponseBase<List<Order>>(
code:1000,
data:orderList,
message:"Success"
);
return Ok(responseData);
}
}
}
@@ -95,7 +95,7 @@ namespace Apimanager_backend.Controllers
#endregion
#region
[HttpGet]
//[Authorize(Roles = "User")]
[Authorize(Roles = "User")]
public async Task<ActionResult<ResponseBase<List<PackageInfoDto>>>> GetPackageList(int pageIndex,int pageSize,bool desc)
{
var packageList = await packageService.GetAllPackagesAsync(pageIndex,pageSize,desc);
@@ -0,0 +1,83 @@
using Apimanager_backend.Dtos;
using Apimanager_backend.Exceptions;
using Apimanager_backend.Models;
using Apimanager_backend.Services;
using Apimanager_backend.Tools;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace Apimanager_backend.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class PayController : ControllerBase
{
private ILogger<PayController> _logger;
private IOrderService _orderService;
private IPaymentConfigService _paymentService;
private IPayService _payService;
public PayController(ILogger<PayController> logger,IOrderService order,IPaymentConfigService paymentConfigService,IPayService payService)
{
_logger = logger;
_orderService = order;
_paymentService = paymentConfigService;
_payService = payService;
}
[HttpPost]
[Authorize(Roles = "User")]
public async Task<IActionResult> CreatePayment([FromBody]CreatePaymentDto dto)
{
var userId = User.Claims.First(x => x.Type == "userId").Value;
//获取支付接口信息
var paymentConfig = await _paymentService.GetPaymentConfigInfoByTypeAsync(dto.PaymentType.ToString());
//创建订单
OrderDto order = new OrderDto();
order.Amount = dto.Amount;
order.OrderType = OrderType.Purchase;
order.UserId = int.Parse(userId);
order.PaymentType = dto.PaymentType;
Order orderRes = await _orderService.CreateOrderAsync(order);
switch (paymentConfig.PayType)
{
case PayType.None:
throw new BaseException(4001,"当前支付方式未配置");
case PayType.Epay:
var epayRes = await _payService.CreateEpay(orderRes, paymentConfig,dto.ReturnUrl);
return Ok(epayRes);
default:
throw new BaseException(4001, "不支持的支付方式");
}
}
[HttpGet]
public async Task<IActionResult> Notice(
int pid, string trade_no,string out_trade_no
, string type, string name, decimal money
, string trade_status, string sign, string sign_type
)
{
Dictionary<string, string> param = new Dictionary<string, string>();
param["pid"] = pid.ToString();
param["trade_no"] = trade_no;
param["out_trade_no"] = out_trade_no;
param["type"] = type;
param["name"] = name;
param["money"] = money.ToString();
param["trade_status"] = trade_status;
param["sign"] = sign;
param["sign_type"] = sign_type;
PaymentConfig paymentConfig = await _paymentService.GetPaymentConfigInfoByTypeAsync(type);
bool verifyRes = EpayHelper.VerifySign(param,paymentConfig.SecretKey);
if (!verifyRes)
{
throw new BaseException(4001, "签名校验失败");
}
OrderDto orderDto = new OrderDto();
orderDto.ThirdPartyOrderId = trade_no;
if (trade_status == "TRADE_SUCCESS") orderDto.Status = OrderStatus.Completed;
else orderDto.Status = OrderStatus.Failed;
await _orderService.UpdateOrderAsync(orderDto);
return Ok("Success");
}
}
}
@@ -0,0 +1,66 @@
using Apimanager_backend.Dtos;
using Apimanager_backend.Exceptions;
using Apimanager_backend.Services;
using Apimanager_backend.Tools;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.RateLimiting;
using Public;
using System.Text.Json;
namespace Apimanager_backend.Controllers
{
[Route("api/[controller]/{code}")]
[ApiController]
public class PublicController : ControllerBase
{
private BillableApiDispatcher _dispatcher;
private IApiService _apiService;
private IWebHostEnvironment _webHostEnvironment;
public PublicController(BillableApiDispatcher billableApiDispatcher,IApiService apiService,IWebHostEnvironment webHostEnvironment)
{
_dispatcher = billableApiDispatcher;
_apiService = apiService;
_webHostEnvironment = webHostEnvironment;
}
[HttpGet,HttpDelete,HttpPost,HttpPut]
[EnableRateLimiting("DynamicPerUser")]
public async Task<IActionResult> Invoke(string code)
{
var requestMethod = HttpContext.Request.Method; // GET, POST, etc.
var api = await _apiService.GetApiInfoByEndpointAsync(code);
if (api == null || !api.IsActive)
throw new BaseException(3002,"接口不存在");
if (!string.Equals(api.Method.ToString(),requestMethod, StringComparison.OrdinalIgnoreCase))
throw new BaseException(3002,$"接口不支持{requestMethod}方法");
Dictionary<string, object> parameters = new Dictionary<string, object>();
// 获取参数
if ((requestMethod == "GET" && Request.Query.Count == 0) || (requestMethod == "POST" && Request.ContentLength == 0))
{
parameters = new Dictionary<string, object>();
}
else
{
parameters = requestMethod switch
{
"GET" => HttpContext.Request.Query.ToDictionary(x => x.Key, x => (object)x.Value.ToString()),
_ => await JsonSerializer.DeserializeAsync<Dictionary<string, object>>(Request.Body)
};
}
//var userId = int.Parse(User.Claims.First(x => x.Type == "userId").Value);
var context = new ApiCallContext
{
UserId = -1,
HttpContext = HttpContext,
Parameters = parameters
};
var result = await _dispatcher.DispatchAsync(_webHostEnvironment.ContentRootPath,api.Id,api.Endpoint, context);
return Ok(result);
}
}
}
@@ -0,0 +1,236 @@
using Apimanager_backend.Exceptions;
using Apimanager_backend.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SixLabors.ImageSharp; // 确保添加这个using
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Png;
using Apimanager_backend.Dtos;
namespace Apimanager_backend.Controllers
{
[ApiController]
[Route("api/[controller]/[action]")]
public class UploadController:ControllerBase
{
private ILogger<UploadController> _logger;
private readonly IWebHostEnvironment _environment;
private IUserService _userService;
// 最大文件大小 5MB
private const long MaxFileSize = 5 * 1024 * 1024;
// 允许的文件类型
private static readonly string[] AllowedExtensions = { ".jpg", ".jpeg", ".png", ".gif" };
public UploadController(ILogger<UploadController> logger,IWebHostEnvironment webHostEnvironment,IUserService userService)
{
_logger = logger;
_environment = webHostEnvironment;
_userService = userService;
}
[HttpPost]
[Authorize(Roles = "User")]
public async Task<IActionResult> UploadPic(IFormFile file)
{
try
{
// 1. 验证文件
if (file == null || file.Length == 0)
{
throw new BaseException(1001,"缺少文件");
}
// 2. 验证文件大小
if (file.Length > MaxFileSize)
{
throw new BaseException(1001, $"文件大小不能超过{MaxFileSize}");
}
var basePath = _environment.WebRootPath ?? _environment.ContentRootPath;
// 3. 验证文件类型
var extension = Path.GetExtension(file.FileName).ToLowerInvariant();
if (string.IsNullOrEmpty(extension) || !AllowedExtensions.Contains(extension))
{
throw new BaseException(1001, "只支持 JPG, PNG, GIF 格式的图片");
}
// 5. 创建存储目录
var uploadsFolder = Path.Combine(basePath, "uploads", "avatars");
if (!Directory.Exists(uploadsFolder))
{
Directory.CreateDirectory(uploadsFolder);
}
var userId = User.Claims.First(x => x.Type == "userId").Value;
// 6. 生成唯一文件名
var uniqueFileName = $"{userId}_{DateTime.Now:yyyyMMddHHmmss}{extension}";
var filePath = Path.Combine(uploadsFolder, uniqueFileName);
// 7. 处理并保存图片
using (var image = await Image.LoadAsync(file.OpenReadStream()))
{
// 调整图片大小(最大200x200)
image.Mutate(x => x.Resize(new ResizeOptions
{
Size = new Size(200, 200),
Mode = ResizeMode.Max
}));
// 保存为高质量JPEG
await image.SaveAsync(filePath);
}
// 8. 更新数据库中的头像路径
var avatarUrl = $"/uploads/avatars/{uniqueFileName}";
var result = await _userService.UpdateUserAvatarAsync(int.Parse(userId), avatarUrl);
if (!result)
{
// 如果数据库更新失败,删除已上传的文件
System.IO.File.Delete(filePath);
throw new BaseException(1004,"头像上传失败");
}
// 9. 返回成功响应
return Ok(new ResponseBase<object>(1000,"头像上传成功",null));
}
catch (Exception ex)
{
_logger.LogError(ex, "头像上传失败");
throw new BaseException(1004, "头像上传失败");
}
}
[HttpPost]
[Authorize(Roles = "Admin")]
public async Task<IActionResult> UploadLogo(IFormFile file)
{
try
{
// 1. 验证文件
if (file == null || file.Length == 0)
{
throw new BaseException(1001, "缺少文件");
}
// 2. 验证文件大小
if (file.Length > MaxFileSize)
{
throw new BaseException(1001, $"文件大小不能超过{MaxFileSize}");
}
var basePath = _environment.WebRootPath ?? _environment.ContentRootPath;
// 3. 验证文件类型
var extension = Path.GetExtension(file.FileName).ToLowerInvariant();
if (string.IsNullOrEmpty(extension) || !AllowedExtensions.Contains(extension))
{
throw new BaseException(1001, "只支持 JPG, PNG, GIF 格式的图片");
}
// 5. 创建存储目录
var uploadsFolder = Path.Combine(basePath);
var filePath = Path.Combine(uploadsFolder, "logo.png");
// 7. 处理并保存图片
using (var image = await Image.LoadAsync(file.OpenReadStream()))
{
// 调整图片大小(最大200x200)
/*
image.Mutate(x => x.Resize(new ResizeOptions
{
Size = new Size(200, 200),
Mode = ResizeMode.Max
}));
*/
// 强制保存为PNG(高质量)
await image.SaveAsync(filePath, new PngEncoder
{
CompressionLevel = PngCompressionLevel.BestCompression // 最佳压缩
});
}
// 9. 返回成功响应
return Ok(new ResponseBase<object>(1000, "LOGO上传成功", null));
}
catch (Exception ex)
{
_logger.LogError(ex, "LOGO上传失败");
throw new BaseException(1004, "LOGO上传失败");
}
}
[HttpPost]
[Authorize(Roles = "Admin")]
public async Task<IActionResult> UploadFavicon(IFormFile file)
{
try
{
// 1. 验证文件
if (file == null || file.Length == 0)
{
throw new BaseException(1001, "缺少文件");
}
// 2. 验证文件大小
if (file.Length > MaxFileSize)
{
throw new BaseException(1001, $"文件大小不能超过{MaxFileSize}");
}
var basePath = _environment.WebRootPath ?? _environment.ContentRootPath;
// 3. 验证文件类型
var extension = Path.GetExtension(file.FileName).ToLowerInvariant();
if (string.IsNullOrEmpty(extension) || extension != ".ico")
{
throw new BaseException(1001, "只支持 ICO 格式的图片");
}
// 3. 保存到网站根目录
var icoPath = Path.Combine(_environment.WebRootPath, "favicon.ico");
using (var stream = new FileStream(icoPath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
// 9. 返回成功响应
return Ok(new ResponseBase<object>(1000, "favicon上传成功", null));
}
catch (Exception ex)
{
_logger.LogError(ex, "Favicon上传失败");
throw new BaseException(1004, "Favicon上传失败");
}
}
[HttpPost]
[Authorize(Roles = "Admin")]
public async Task<IActionResult> UploadApi(IFormFile file)
{
if (file == null || file.Length == 0)
throw new BaseException(1001,"请上传文件");
// 检查扩展名
var ext = Path.GetExtension(file.FileName);
if (ext != ".dll")
throw new BaseException(1001, "只允许上传DLL");
// 插件保存路径
var saveDir = Path.Combine(_environment.ContentRootPath, "ApiHandler");
if (!Directory.Exists(saveDir))
Directory.CreateDirectory(saveDir);
var filePath = Path.Combine(saveDir, file.FileName);
// 保存文件
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
return Ok(new ResponseBase<object>(1000,"上传成功",null));
}
}
}
@@ -78,7 +78,7 @@ namespace Apimanager_backend.Controllers
[Authorize(Roles = "User")]
public async Task<ActionResult<ResponseBase<UserInfoDto?>>> Update([FromBody]UpdateUserDto dto)
{
var userId = User.Claims.First(x => x.ValueType == "userId").Value;
var userId = User.Claims.First(x => x.Type == "userId").Value;
var userInfo = await userService.UpdateUserAsync(int.Parse(userId),dto);
var res = new ResponseBase<object?>(
code:1000,