Merge branch 'dev' of https://gitea.nxsir.cn/nanxun/ql_apimanager_backend into dev
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user