diff --git a/Apimanager_backend/Config/MyAutomapper.cs b/Apimanager_backend/Config/MyAutomapper.cs index e032e04..32c9c54 100644 --- a/Apimanager_backend/Config/MyAutomapper.cs +++ b/Apimanager_backend/Config/MyAutomapper.cs @@ -16,6 +16,7 @@ namespace Apimanager_backend.Config CreateMap(); CreateMap(); CreateMap(); + CreateMap(); CreateMap(); CreateMap() .ForMember(dest => dest.Success, opt => opt.MapFrom(src => src.code == 1)) diff --git a/Apimanager_backend/Config/ServiceCollectionExtensions.cs b/Apimanager_backend/Config/ServiceCollectionExtensions.cs index 5f6c4f3..6dc6db5 100644 --- a/Apimanager_backend/Config/ServiceCollectionExtensions.cs +++ b/Apimanager_backend/Config/ServiceCollectionExtensions.cs @@ -31,6 +31,7 @@ namespace Apimanager_backend.Config services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/Apimanager_backend/Controllers/ApisController.cs b/Apimanager_backend/Controllers/ApisController.cs index 56e26db..230a394 100644 --- a/Apimanager_backend/Controllers/ApisController.cs +++ b/Apimanager_backend/Controllers/ApisController.cs @@ -1,5 +1,6 @@ using Apimanager_backend.Dtos; using Apimanager_backend.Exceptions; +using Apimanager_backend.Models; using Apimanager_backend.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; @@ -47,7 +48,7 @@ namespace Apimanager_backend.Controllers #endregion #region 查询API列表 [HttpGet] - //[Authorize(Roles = "User")] + [Authorize(Roles = "User")] public async Task>>> ApiList(int pageIndex,int pageSize,bool desc) { var list = await apiService.GetApisAsync(pageIndex, pageSize, desc); @@ -175,5 +176,23 @@ namespace Apimanager_backend.Controllers } } #endregion + #region 查询API列表(公开) + [HttpGet] + public async Task GetApisPublic(int pageIndex,int pageSize,bool desc) + { + var list = await apiService.GetUserApisAsync(pageIndex, pageSize, desc); + var res = new ResponseBase>(1000,"查询成功",list); + return Ok(res); + } + #endregion + #region 获取API所属套餐 + [HttpGet] + public async Task GetApiPackages(int[] apiId) + { + var list = await apiService.GetApipackageAsync(apiId); + var res = new ResponseBase>(1000,"查询成功",list); + return Ok(res); + } + #endregion } } diff --git a/Apimanager_backend/Controllers/OrderController.cs b/Apimanager_backend/Controllers/OrderController.cs index 593a0d1..a887e5e 100644 --- a/Apimanager_backend/Controllers/OrderController.cs +++ b/Apimanager_backend/Controllers/OrderController.cs @@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Mvc; namespace Apimanager_backend.Controllers { - [Route("api/[controller][action]")] + [Route("api/[controller]/[action]")] [ApiController] public class OrderController:ControllerBase { @@ -44,5 +44,23 @@ namespace Apimanager_backend.Controllers ); return Ok(responseData); } + //获取订单数量 + [HttpGet] + [Authorize(Roles = "Admin")] + public async Task>> GetOrderNum() + { + var num = await _orderService.GetOrderNumAsync(); + var res = new ResponseBase(1000,"查询成功",num); + return Ok(res); + } + [HttpGet] + [Authorize(Roles = "User")] + public async Task>> GetMyOrderNum() + { + string userId = User.Claims.First(x => x.Type == "userId").Value; + var num = await _orderService.GetOrderNumAsync(int.Parse(userId)); + var res = new ResponseBase(1000, "查询成功", num); + return Ok(res); + } } } diff --git a/Apimanager_backend/Controllers/PackageController.cs b/Apimanager_backend/Controllers/PackageController.cs index b3d9aae..c562f88 100644 --- a/Apimanager_backend/Controllers/PackageController.cs +++ b/Apimanager_backend/Controllers/PackageController.cs @@ -169,5 +169,13 @@ namespace Apimanager_backend.Controllers } } #endregion + [HttpPost] + [Authorize(Roles = "Admin")] + public async Task SetApiPackageItem(ApiPackageItem apiPackageItem) + { + await packageService.SetApiPackageItemAsync(apiPackageItem.ApiId,apiPackageItem.ApiPackageId); + var res = new ResponseBase(1000,"操作成功",null); + return Ok(res); + } } } diff --git a/Apimanager_backend/Controllers/PayController.cs b/Apimanager_backend/Controllers/PayController.cs index 0e3de1d..97e1cff 100644 --- a/Apimanager_backend/Controllers/PayController.cs +++ b/Apimanager_backend/Controllers/PayController.cs @@ -31,13 +31,13 @@ namespace Apimanager_backend.Controllers { var userId = User.Claims.First(x => x.Type == "userId").Value; //获取支付接口信息 - var paymentConfig = await _paymentService.GetPaymentConfigInfoByTypeAsync(dto.PaymentType.ToString()); + var paymentConfig = await _paymentService.GetPaymentConfigInfoByIdAsync(dto.Id); //创建订单 OrderDto order = new OrderDto(); order.Amount = dto.Amount; - order.OrderType = OrderType.Purchase; + order.OrderType = OrderType.Recharge; order.UserId = int.Parse(userId); - order.PaymentType = dto.PaymentType; + order.PaymentType = paymentConfig.Method; Order orderRes = await _orderService.CreateOrderAsync(order); switch (paymentConfig.PayType) { @@ -93,5 +93,6 @@ namespace Apimanager_backend.Controllers return Ok(res); } + } } diff --git a/Apimanager_backend/Controllers/PaymentController.cs b/Apimanager_backend/Controllers/PaymentController.cs new file mode 100644 index 0000000..2e4aded --- /dev/null +++ b/Apimanager_backend/Controllers/PaymentController.cs @@ -0,0 +1,54 @@ +using Apimanager_backend.Dtos; +using Apimanager_backend.Models; +using Apimanager_backend.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace Apimanager_backend.Controllers +{ + [Route("api/[controller]/[action]")] + [ApiController] + public class PaymentController : ControllerBase + { + private IPaymentConfigService _paymentService; + private ILogger _logger; + public PaymentController(IPaymentConfigService paymentConfig, ILogger logger) + { + _paymentService = paymentConfig; + _logger = logger; + } + [HttpPost] + [Authorize(Roles = "Admin")] + public async Task AddPayment(PaymentConfig payment) + { + await _paymentService.AddPaymentAsync(payment); + var res = new ResponseBase(1000,"添加成功",null); + return Ok(res); + } + [HttpPost] + [Authorize(Roles = "Admin")] + public async Task UpdatePayment(PaymentConfig payment) + { + await _paymentService.UpdatePaymentAsync(payment); + var res = new ResponseBase(1000,"修改成功",null); + return Ok(res); + } + [HttpGet] + [Authorize(Roles = "Admin")] + public async Task GetAllPayment() + { + var list = await _paymentService.GetAllPaymentAdminAsync(); + var res = new ResponseBase>(1000,"查询成功",list); + return Ok(res); + } + [HttpGet] + [Authorize(Roles = "User")] + public async Task GetAllPublicPayment() + { + var list = await _paymentService.GetAllPaymentAsync(); + var res = new ResponseBase>(1000, "查询成功", list); + return Ok(res); + } + } +} diff --git a/Apimanager_backend/Controllers/SystemInfoController.cs b/Apimanager_backend/Controllers/SystemInfoController.cs new file mode 100644 index 0000000..38413d7 --- /dev/null +++ b/Apimanager_backend/Controllers/SystemInfoController.cs @@ -0,0 +1,27 @@ +using Apimanager_backend.Dtos; +using Apimanager_backend.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace Apimanager_backend.Controllers +{ + [Route("api/[controller]/[action]")] + [ApiController] + public class SystemInfoController : ControllerBase + { + private readonly ISystemInfoService _systemInfoService; + public SystemInfoController(ISystemInfoService systemInfoService) + { + _systemInfoService = systemInfoService; + } + [HttpGet] + [Authorize(Roles = "Admin")] + public async Task GetInfo() + { + var info = await _systemInfoService.GetSystemInfoAsync(); + var res = new ResponseBase(1000,"查询成功",info); + return Ok(res); + } + } +} diff --git a/Apimanager_backend/Controllers/UploadController.cs b/Apimanager_backend/Controllers/UploadController.cs index b7fc80f..5de068d 100644 --- a/Apimanager_backend/Controllers/UploadController.cs +++ b/Apimanager_backend/Controllers/UploadController.cs @@ -198,7 +198,7 @@ namespace Apimanager_backend.Controllers // 9. 返回成功响应 return Ok(new ResponseBase(1000, "favicon上传成功", null)); } - catch (Exception ex) + catch (Exception ex) when (!(ex is BaseException)) { _logger.LogError(ex, "Favicon上传失败"); throw new BaseException(1004, "Favicon上传失败"); diff --git a/Apimanager_backend/Controllers/UserController.cs b/Apimanager_backend/Controllers/UserController.cs index fd2b5e9..46ea523 100644 --- a/Apimanager_backend/Controllers/UserController.cs +++ b/Apimanager_backend/Controllers/UserController.cs @@ -15,9 +15,11 @@ namespace Apimanager_backend.Controllers public class UserController : ControllerBase { private readonly IUserService userService; - public UserController(IUserService userService) + private readonly IUserPackageService _userPackageService; + public UserController(IUserService userService,IUserPackageService userPackageService) { this.userService = userService; + this._userPackageService = userPackageService; } /// /// 获取用户个人信息 @@ -30,9 +32,9 @@ namespace Apimanager_backend.Controllers var userId = User.Claims.First(x => x.Type == "userId").Value; var userInfo = await userService.GetUserAsync(int.Parse(userId)); var res = new ResponseBase( - code:1000, - message:"Success", - data:userInfo + code: 1000, + message: "Success", + data: userInfo ); return Ok(res); } @@ -42,29 +44,29 @@ namespace Apimanager_backend.Controllers /// /// [HttpPost] - public async Task>> Resetpassword([FromBody]ResetPasswordDto dto) + public async Task>> Resetpassword([FromBody] ResetPasswordDto dto) { try { await userService.ResetPasswordAsync(dto.Email, dto.Code, dto.NewPassword); var res = new ResponseBase( - code:1000, - message:"Success", + code: 1000, + message: "Success", data: null ); return Ok(res); - }catch(BaseException e) + } catch (BaseException e) { var res = new ResponseBase( - code:e.code, - message:e.message, - data:null + code: e.code, + message: e.message, + data: null ); - return StatusCode(400,res); + return StatusCode(400, res); } } [HttpPost] - public async Task>> SendResetEmail([FromQuery]string email) + public async Task>> SendResetEmail([FromQuery] string email) { await userService.SendResetPasswordEmailAsync(email); var res = new ResponseBase( @@ -76,16 +78,37 @@ namespace Apimanager_backend.Controllers } [HttpPost] [Authorize(Roles = "User")] - public async Task>> Update([FromBody]UpdateUserDto dto) + public async Task>> Update([FromBody] UpdateUserDto dto) { var userId = User.Claims.First(x => x.Type == "userId").Value; - var userInfo = await userService.UpdateUserAsync(int.Parse(userId),dto); + var userInfo = await userService.UpdateUserAsync(int.Parse(userId), dto); var res = new ResponseBase( - code:1000, - message:"Success", - data:userInfo + code: 1000, + message: "Success", + data: userInfo ); return Ok(res); } + //设置用户apikey + [HttpPost] + [Authorize(Roles = "User")] + public async Task SetApiKey() + { + var userId = User.Claims.First(x => x.Type == "userId").Value; + var key = await userService.SetUserTokenAsync(int.Parse(userId)); + var res = new ResponseBase(1000, "操作成功", key); + return Ok(res); + } + //获取已订购套餐 + [HttpGet] + [Authorize(Roles = "User")] + public async Task GetUserPackages() + { + var userId = User.Claims.First(x => x.Type == "userId").Value; + var list = await _userPackageService.GetUserPackagesByUserIdAsync(int.Parse(userId)); + var res = new ResponseBase>(1000,"查询成功",list); + return Ok(res); + + } } } diff --git a/Apimanager_backend/Dtos/ApiInfoDto.cs b/Apimanager_backend/Dtos/ApiInfoDto.cs index cd576fd..17ed211 100644 --- a/Apimanager_backend/Dtos/ApiInfoDto.cs +++ b/Apimanager_backend/Dtos/ApiInfoDto.cs @@ -13,5 +13,6 @@ namespace Apimanager_backend.Dtos public bool IsActive { get; set; } public Apipackage? Package { get; set; } public int? PackageId { get; set; } + public List? ApiRequestExamples { get; set; } } } diff --git a/Apimanager_backend/Dtos/CreatePaymentDto.cs b/Apimanager_backend/Dtos/CreatePaymentDto.cs index 6ee7b4d..f574237 100644 --- a/Apimanager_backend/Dtos/CreatePaymentDto.cs +++ b/Apimanager_backend/Dtos/CreatePaymentDto.cs @@ -5,6 +5,7 @@ namespace Apimanager_backend.Dtos { public class CreatePaymentDto { + public int Id { get; set; } public PaymentType PaymentType { get; set; } [Required] public decimal Amount { get; set; } diff --git a/Apimanager_backend/Dtos/OrderDto.cs b/Apimanager_backend/Dtos/OrderDto.cs index 08484fb..5182474 100644 --- a/Apimanager_backend/Dtos/OrderDto.cs +++ b/Apimanager_backend/Dtos/OrderDto.cs @@ -41,5 +41,6 @@ namespace Apimanager_backend.Dtos public string? Description { get; set; } // varchar(255) public OrderStatus Status { get; set; } + public User? User { get; set; } } } diff --git a/Apimanager_backend/Dtos/PackageInfoDto.cs b/Apimanager_backend/Dtos/PackageInfoDto.cs index 2a8795b..a3723f4 100644 --- a/Apimanager_backend/Dtos/PackageInfoDto.cs +++ b/Apimanager_backend/Dtos/PackageInfoDto.cs @@ -1,4 +1,6 @@ -namespace Apimanager_backend.Dtos +using Apimanager_backend.Models; + +namespace Apimanager_backend.Dtos { public class PackageInfoDto { @@ -7,6 +9,7 @@ public int CallLimit { get; set; } public decimal Price { get; set; } public int OneMinuteLimit { get; set; } + public ICollection ApiPackageItems { get; set; } } } diff --git a/Apimanager_backend/Dtos/PaymentDto.cs b/Apimanager_backend/Dtos/PaymentDto.cs new file mode 100644 index 0000000..cb12ca3 --- /dev/null +++ b/Apimanager_backend/Dtos/PaymentDto.cs @@ -0,0 +1,22 @@ +using Apimanager_backend.Models; +using System.ComponentModel.DataAnnotations; + +namespace Apimanager_backend.Dtos +{ + public class PaymentDto + { + public int Id { get; set; } + + /// 支付方式(如 Alipay、WeChat、Stripe...) + [Required] + public PaymentType Method { get; set; } // varchar(50) + + + /// 是否启用此配置 + public bool IsEnabled { get; set; } = true; + + /// 备注 + public string? Description { get; set; } + + } +} diff --git a/Apimanager_backend/Dtos/SystemInfoDto.cs b/Apimanager_backend/Dtos/SystemInfoDto.cs new file mode 100644 index 0000000..7096ab9 --- /dev/null +++ b/Apimanager_backend/Dtos/SystemInfoDto.cs @@ -0,0 +1,12 @@ +namespace Apimanager_backend.Dtos +{ + public class SystemInfoDto + { + public int UserCount { get; set; } + public int OrderCount { get; set; } + public int CallCount { get; set; } + public decimal Money { get; set; } + public List RecentUser { get; set; } + public List RecentOrder { get; set; } + } +} diff --git a/Apimanager_backend/Dtos/UserInfoDto.cs b/Apimanager_backend/Dtos/UserInfoDto.cs index 991f938..b7d0405 100644 --- a/Apimanager_backend/Dtos/UserInfoDto.cs +++ b/Apimanager_backend/Dtos/UserInfoDto.cs @@ -12,6 +12,7 @@ namespace Apimanager_backend.Dtos public decimal Balance { get; set; } public string? Avatar { get; set; } public DateTime Created { get; set; } + public string? ApiKey { get; set; } public List? Packages { get; set; } } } diff --git a/Apimanager_backend/Filters/ExceptionFilter/generalExceptionFilter.cs b/Apimanager_backend/Filters/ExceptionFilter/generalExceptionFilter.cs index 67d376f..1e62a2c 100644 --- a/Apimanager_backend/Filters/ExceptionFilter/generalExceptionFilter.cs +++ b/Apimanager_backend/Filters/ExceptionFilter/generalExceptionFilter.cs @@ -8,6 +8,11 @@ namespace Apimanager_backend.Filters.ExceptionFilter { public class generalExceptionFilter : IExceptionFilter { + private ILogger _logger; + public generalExceptionFilter(ILogger logger) + { + _logger = logger; + } public void OnException(ExceptionContext context) { if(context.Exception is BaseException) @@ -25,6 +30,20 @@ namespace Apimanager_backend.Filters.ExceptionFilter }; context.ExceptionHandled = true; } + if(context.Exception is Exception ex) + { + _logger.LogError(ex, "系统未处理异常:{Message}", ex.Message); + var res = new ResponseBase( + code: 1005, + message: "服务器内部错误,请联系管理员。", + data: null + ); + context.Result = new JsonResult(res) + { + StatusCode = 500 + }; + context.ExceptionHandled = true; + } } } } diff --git a/Apimanager_backend/Models/Api.cs b/Apimanager_backend/Models/Api.cs index 60c633b..caa9e02 100644 --- a/Apimanager_backend/Models/Api.cs +++ b/Apimanager_backend/Models/Api.cs @@ -1,5 +1,6 @@ using Apimanager_backend.Data; using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; namespace Apimanager_backend.Models { @@ -57,9 +58,13 @@ namespace Apimanager_backend.Models public DateTime CreatedAt { get; set; } = DateTime.UtcNow; // timestamp //导航属性 + [JsonIgnore] public Apipackage? Package { get; set; } - public ICollection ApiPackageItems { get; set; } - public ICollection ApiCalls { get; set; } - public ICollection ApiRequestExamples { get; set; } + [JsonIgnore] + public ICollection? ApiPackageItems { get; set; } + [JsonIgnore] + public ICollection? ApiCalls { get; set; } + [JsonIgnore] + public ICollection? ApiRequestExamples { get; set; } } } diff --git a/Apimanager_backend/Models/ApiPackageItem.cs b/Apimanager_backend/Models/ApiPackageItem.cs index 95665c1..0e9e787 100644 --- a/Apimanager_backend/Models/ApiPackageItem.cs +++ b/Apimanager_backend/Models/ApiPackageItem.cs @@ -1,4 +1,5 @@ using System.ComponentModel.DataAnnotations.Schema; +using System.Text.Json.Serialization; namespace Apimanager_backend.Models { @@ -8,9 +9,10 @@ namespace Apimanager_backend.Models public int Id { get; set; } public int ApiPackageId { get; set; } - public Apipackage ApiPackage { get; set; } = null!; + [JsonIgnore] + public Apipackage? ApiPackage { get; set; } = null!; public int ApiId { get; set; } - public Api Api { get; set; } = null!; + public Api? Api { get; set; } = null!; } } diff --git a/Apimanager_backend/Models/Apipackage.cs b/Apimanager_backend/Models/Apipackage.cs index eb15cd7..2e6ad1a 100644 --- a/Apimanager_backend/Models/Apipackage.cs +++ b/Apimanager_backend/Models/Apipackage.cs @@ -1,5 +1,6 @@ using Microsoft.EntityFrameworkCore; using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; namespace Apimanager_backend.Models { @@ -45,6 +46,7 @@ namespace Apimanager_backend.Models //导航属性 public ICollection Apis { get; set; } public ICollection ApiPackageItems { get; set; } + [JsonIgnore] public ICollection Packages { get; set; } } diff --git a/Apimanager_backend/Models/OrderType.cs b/Apimanager_backend/Models/OrderType.cs index d3f8f22..d902709 100644 --- a/Apimanager_backend/Models/OrderType.cs +++ b/Apimanager_backend/Models/OrderType.cs @@ -2,8 +2,8 @@ { public enum OrderType { - Recharge, - Purchase, - Refund + Purchase = 0, + Recharge = 1, + Refund = 2 } } diff --git a/Apimanager_backend/Models/PaymentType.cs b/Apimanager_backend/Models/PaymentType.cs index 3b2c584..6b66551 100644 --- a/Apimanager_backend/Models/PaymentType.cs +++ b/Apimanager_backend/Models/PaymentType.cs @@ -5,6 +5,7 @@ AliPay = 0, WxPay = 1, Bank = 2, - QQPay =3 + QQPay =3, + balance = 4 } } diff --git a/Apimanager_backend/Models/User.cs b/Apimanager_backend/Models/User.cs index 0e7ece9..52e0931 100644 --- a/Apimanager_backend/Models/User.cs +++ b/Apimanager_backend/Models/User.cs @@ -1,4 +1,5 @@ using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; namespace Apimanager_backend.Models { @@ -57,9 +58,12 @@ namespace Apimanager_backend.Models public DateTime CreatedAt { get; set; } = DateTime.UtcNow; // Timestamp //导航属性 + [JsonIgnore] public ICollection Packages { get; set; } + [JsonIgnore] public ICollection operationLogs { get; set; } public ICollection CallLogs { get; set; } + [JsonIgnore] public ICollection Orders { get; set; } public ICollection Roles { get; set; } = new List(); public User(int id,string username,string email,string passHash) diff --git a/Apimanager_backend/Models/UserPackage.cs b/Apimanager_backend/Models/UserPackage.cs index f94b7f5..f0aa3e0 100644 --- a/Apimanager_backend/Models/UserPackage.cs +++ b/Apimanager_backend/Models/UserPackage.cs @@ -1,4 +1,6 @@ -namespace Apimanager_backend.Models +using System.Text.Json.Serialization; + +namespace Apimanager_backend.Models { public class UserPackage {/// diff --git a/Apimanager_backend/Services/ApiService.cs b/Apimanager_backend/Services/ApiService.cs index 6f542f8..1d0d167 100644 --- a/Apimanager_backend/Services/ApiService.cs +++ b/Apimanager_backend/Services/ApiService.cs @@ -127,5 +127,30 @@ namespace Apimanager_backend.Services return mapper.Map(apiInfo); } #endregion + #region 获取用于用户展示的api列表 + public async Task> GetUserApisAsync(int pageIndex, int pageSize, bool desc) + { + IQueryable query = context.Apis.Include(x => x.ApiRequestExamples).AsQueryable(); + //倒序 + if (desc) + { + query.OrderDescending(); + } + //分页 + query = query.Skip((pageIndex - 1) * pageSize).Take(pageSize); + return mapper.Map>(await query.ToListAsync()); + } + #endregion + #region 获取API对应的套餐 + public async Task> GetApipackageAsync(int[] apiId) + { + if(apiId.Count() == 0) + { + throw new BaseException(1004,"id不能为空"); + } + var packageItems = await context.apiPackageItems.Include(x => x.ApiPackage).Where(x => apiId.Contains(x.ApiId)).ToListAsync(); + return packageItems.Select(x => x.ApiPackage).ToList(); + } + #endregion } } diff --git a/Apimanager_backend/Services/IApiPackageItemService.cs b/Apimanager_backend/Services/IApiPackageItemService.cs index e33452f..5c8fc97 100644 --- a/Apimanager_backend/Services/IApiPackageItemService.cs +++ b/Apimanager_backend/Services/IApiPackageItemService.cs @@ -5,6 +5,6 @@ namespace Apimanager_backend.Services { public interface IApiPackageItemService { - Task> GetApiPackageItemsByApiIdAsync(int ApiId); + public Task> GetApiPackageItemsByApiIdAsync(int ApiId); } } diff --git a/Apimanager_backend/Services/IApiService.cs b/Apimanager_backend/Services/IApiService.cs index d9b8810..4b5b76e 100644 --- a/Apimanager_backend/Services/IApiService.cs +++ b/Apimanager_backend/Services/IApiService.cs @@ -1,4 +1,5 @@ using Apimanager_backend.Dtos; +using Apimanager_backend.Models; namespace Apimanager_backend.Services { @@ -61,6 +62,15 @@ namespace Apimanager_backend.Services /// api路径 /// public Task GetApiInfoByEndpointAsync(string endpoint); + /// + /// 获取用于用户展示的api列表 + /// + /// + /// + /// + /// + public Task> GetUserApisAsync(int pageIndex, int pageSize, bool desc); + public Task> GetApipackageAsync(int[] apiId); } } diff --git a/Apimanager_backend/Services/IOrderService.cs b/Apimanager_backend/Services/IOrderService.cs index 0109b4a..ae63c49 100644 --- a/Apimanager_backend/Services/IOrderService.cs +++ b/Apimanager_backend/Services/IOrderService.cs @@ -20,5 +20,6 @@ namespace Apimanager_backend.Services /// Task CreateOrderAsync(OrderDto order); Task UpdateOrderAsync(OrderDto order); + Task GetOrderNumAsync(int? userId = null); } } diff --git a/Apimanager_backend/Services/IPackageService.cs b/Apimanager_backend/Services/IPackageService.cs index f5beb16..6f164ba 100644 --- a/Apimanager_backend/Services/IPackageService.cs +++ b/Apimanager_backend/Services/IPackageService.cs @@ -59,6 +59,7 @@ namespace Apimanager_backend.Services /// /// public Task DecuteUserPackageTimeAsync(int packageId,int userId,TimeSpan time); + Task SetApiPackageItemAsync(int apiId,int packageId); } diff --git a/Apimanager_backend/Services/IPaymentConfigService.cs b/Apimanager_backend/Services/IPaymentConfigService.cs index bff6136..56e4665 100644 --- a/Apimanager_backend/Services/IPaymentConfigService.cs +++ b/Apimanager_backend/Services/IPaymentConfigService.cs @@ -5,6 +5,11 @@ namespace Apimanager_backend.Services public interface IPaymentConfigService { Task GetPaymentConfigInfoByTypeAsync(string payType); + Task GetPaymentConfigInfoByIdAsync(int id); + Task GetPaymentAdminAsync(PayType payType, PaymentType paymentType); Task> GetAllPaymentAsync(); + Task> GetAllPaymentAdminAsync(); + Task AddPaymentAsync(PaymentConfig payment); + Task UpdatePaymentAsync(PaymentConfig payment); } } diff --git a/Apimanager_backend/Services/ISystemInfoService.cs b/Apimanager_backend/Services/ISystemInfoService.cs new file mode 100644 index 0000000..f9f5dbc --- /dev/null +++ b/Apimanager_backend/Services/ISystemInfoService.cs @@ -0,0 +1,9 @@ +using Apimanager_backend.Dtos; + +namespace Apimanager_backend.Services +{ + public interface ISystemInfoService + { + Task GetSystemInfoAsync(); + } +} diff --git a/Apimanager_backend/Services/IUserService.cs b/Apimanager_backend/Services/IUserService.cs index 93b0366..c661726 100644 --- a/Apimanager_backend/Services/IUserService.cs +++ b/Apimanager_backend/Services/IUserService.cs @@ -60,5 +60,11 @@ namespace Apimanager_backend.Services /// /// Task UpdateUserAvatarAsync(int userId,string url); + /// + /// 设置用户调用凭证 + /// + /// + /// + Task SetUserTokenAsync(int userId); } } diff --git a/Apimanager_backend/Services/OrderService.cs b/Apimanager_backend/Services/OrderService.cs index 61281d2..e305e01 100644 --- a/Apimanager_backend/Services/OrderService.cs +++ b/Apimanager_backend/Services/OrderService.cs @@ -49,6 +49,29 @@ namespace Apimanager_backend.Services } } #endregion + + public async Task GetOrderNumAsync(int? userId = null) + { + try + { + int num = 0; + if (userId != null) + { + num = await _apiContext.Orders.CountAsync(x => x.UserId == userId); + } + else + { + num = await _apiContext.Orders.CountAsync(); + } + return num; + }catch(Exception e) + { + logger.LogError(e, "查询订单数量:{Message}", e.Message); + throw new BaseException(1005,"服务器内部错误"); + } + + } + #region 获取订单列表 /// /// 获取订单列表 @@ -60,10 +83,10 @@ namespace Apimanager_backend.Services /// public async Task> GetOrdersAsync(int pageIndex, int pageSize, bool desc, int? userId) { - IQueryable query = _apiContext.Orders.AsQueryable().OrderBy(x => x.Id); + IQueryable query = _apiContext.Orders.Include(x => x.User).AsQueryable().OrderBy(x => x.Id); if(userId != null) { - query.Where(x => x.UserId == userId); + query = query.Where(x => x.UserId == userId); } //倒序 if (desc) @@ -90,12 +113,12 @@ namespace Apimanager_backend.Services data.UpdatedAt = DateTime.Now; data.Status = order.Status; data.PaiAt = order.Status == OrderStatus.Completed ? DateTime.Now : null; - var user = await _apiContext.Users.FirstOrDefaultAsync(x => x.Id == order.UserId); + var user = await _apiContext.Users.FirstOrDefaultAsync(x => x.Id == data.UserId); if (user == null) { throw new BaseException(2004, "用户未找到"); } - user.Balance += order.Amount; + user.Balance += data.Amount; _apiContext.Orders.Update(data); _apiContext.Users.Update(user); await _apiContext.SaveChangesAsync(); diff --git a/Apimanager_backend/Services/PackageService.cs b/Apimanager_backend/Services/PackageService.cs index 06bd810..3136c32 100644 --- a/Apimanager_backend/Services/PackageService.cs +++ b/Apimanager_backend/Services/PackageService.cs @@ -139,7 +139,7 @@ namespace Apimanager_backend.Services #region 获取套餐列表 public async Task> GetAllPackagesAsync(int pageIndex, int pageSize, bool desc) { - IQueryable query = apiContext.Apipackages.Where(x => true).OrderBy(x => x.Id); + IQueryable query = apiContext.Apipackages.Include(x => x.ApiPackageItems).ThenInclude(x => x.Api).Where(x => true).OrderBy(x => x.Id); if(desc) { query = query.OrderDescending(); @@ -160,9 +160,9 @@ namespace Apimanager_backend.Services public async Task PackageInfoByIdAsync(int packageId) { var packageInfo = await apiContext.Apipackages.FirstOrDefaultAsync(x => x.Id == packageId); - if(packageInfo == null) + if (packageInfo == null) { - throw new BaseException(4004,"套餐未找到"); + throw new BaseException(4004, "套餐未找到"); } return mapper.Map(packageInfo); } @@ -197,5 +197,23 @@ namespace Apimanager_backend.Services } } #endregion + #region 设置API关联套餐 + public async Task SetApiPackageItemAsync(int apiId, int packageId) + { + var api = await apiContext.Apis.SingleOrDefaultAsync(x => x.Id == apiId); + if(api == null) + { + throw new BaseException(1004,"API不存在"); + } + var package = await apiContext.Apipackages.SingleOrDefaultAsync(x => x.Id == packageId); + if(package is null) + { + throw new BaseException(1004,"套餐不存在"); + } + apiContext.apiPackageItems.Add(new ApiPackageItem() { ApiPackageId = package.Id,ApiId = api.Id}); + await apiContext.SaveChangesAsync(); + return true; + } + #endregion } } diff --git a/Apimanager_backend/Services/PayService.cs b/Apimanager_backend/Services/PayService.cs index 74c775a..7a75632 100644 --- a/Apimanager_backend/Services/PayService.cs +++ b/Apimanager_backend/Services/PayService.cs @@ -47,10 +47,23 @@ namespace Apimanager_backend.Services else { var baseDate = uPackage.ExpiryDate > DateTime.Now ? uPackage.ExpiryDate : DateTime.Now; + uPackage.ExpiryDate = baseDate.AddMonths(1); + uPackage.RemainingCalls += package.CallLimit; _context.UserPackages.Update(uPackage); } user.Balance -= package.Price; _context.Users.Update(user); + Order order = new Order() + { + UserId = user.Id, + OrderNumber = OrderNumberGenerator.Generate(user.Id), + Amount = package.Price, + OrderType = OrderType.Purchase, + PaymentType = PaymentType.balance, + Status = OrderStatus.Completed, + PaiAt = DateTime.Now + }; + _context.Orders.Add(order); await _context.SaveChangesAsync(); await transaction.CommitAsync(); return true; diff --git a/Apimanager_backend/Services/PaymentConfigService.cs b/Apimanager_backend/Services/PaymentConfigService.cs index 969bf0b..6525c47 100644 --- a/Apimanager_backend/Services/PaymentConfigService.cs +++ b/Apimanager_backend/Services/PaymentConfigService.cs @@ -17,12 +17,45 @@ namespace Apimanager_backend.Services _logger = logger; _mapper = mapper; } + + public async Task AddPaymentAsync(PaymentConfig payment) + { + bool res = await _context.paymentConfigs.AnyAsync(x => x.PayType == payment.PayType && x.Method == payment.Method); + if (res) + { + throw new BaseException(1006,"该支付方式已存在"); + } + _context.paymentConfigs.Add(payment); + await _context.SaveChangesAsync(); + return true; + } + + public async Task> GetAllPaymentAdminAsync() + { + return await _context.paymentConfigs.ToListAsync(); + } + public async Task> GetAllPaymentAsync() { var data = await _context.paymentConfigs.Where(x => x.IsEnabled).ToListAsync(); return _mapper.Map>(data); } + public Task GetPaymentAdminAsync(PayType payType, PaymentType paymentType) + { + throw new NotImplementedException(); + } + + public async Task GetPaymentConfigInfoByIdAsync(int id) + { + var payment = await _context.paymentConfigs.SingleOrDefaultAsync(x => x.Id == id); + if(payment is null) + { + throw new BaseException(1004,"未找到支付接口"); + } + return payment; + } + public async Task GetPaymentConfigInfoByTypeAsync(string payType) { if(!Enum.TryParse(payType, true, out PaymentType parsedPayType)) @@ -36,5 +69,31 @@ namespace Apimanager_backend.Services } return data; } + + public async Task UpdatePaymentAsync(PaymentConfig payment) + { + var paymentConfig = await _context.paymentConfigs.FirstOrDefaultAsync(x => x.Id == payment.Id); + if(paymentConfig == null) + { + _context.paymentConfigs.Add(payment); + } + else + { + paymentConfig.AppId = payment.AppId; + paymentConfig.SecretKey = payment.SecretKey; + paymentConfig.PublicKey = payment.PublicKey; + paymentConfig.IsEnabled = payment.IsEnabled; + paymentConfig.Url = payment.Url; + paymentConfig.Description = payment.Description; + paymentConfig.ExtraSettingsJson = payment.ExtraSettingsJson; + paymentConfig.GatewayUrl = payment.GatewayUrl; + paymentConfig.PayType = payment.PayType; + paymentConfig.Method = payment.Method; + paymentConfig.NotifyUrl = payment.NotifyUrl; + _context.paymentConfigs.Update(paymentConfig); + } + await _context.SaveChangesAsync(); + return true; + } } } diff --git a/Apimanager_backend/Services/SystemInfoService.cs b/Apimanager_backend/Services/SystemInfoService.cs new file mode 100644 index 0000000..02157c4 --- /dev/null +++ b/Apimanager_backend/Services/SystemInfoService.cs @@ -0,0 +1,70 @@ +using Apimanager_backend.Data; +using Apimanager_backend.Dtos; +using AutoMapper; +using Microsoft.EntityFrameworkCore; + +namespace Apimanager_backend.Services +{ + public class SystemInfoService : ISystemInfoService + { + private readonly ApiContext _context; + private readonly IMapper _mapper; + public SystemInfoService(ApiContext apiContext,IMapper mapper) + { + _context = apiContext; + _mapper = mapper; + } + public async Task GetSystemInfoAsync() + { + return new SystemInfoDto() + { + UserCount = await GetUserCount(), + OrderCount = await GetOrderCount(), + CallCount = await GetCallCount(), + Money = await GetMoney(), + RecentOrder = await GetRecentOrder(), + RecentUser = await GetRecentUser() + }; + } + #region 获取用户数量 + private async Task GetUserCount() + { + return await _context.Users.CountAsync(); + } + #endregion + #region 获取订单数量 + private async Task GetOrderCount() + { + return await _context.Orders.CountAsync(); + } + #endregion + #region 获取API调用次数 + private async Task GetCallCount() + { + return await _context.CallLogs.CountAsync(); + } + #endregion + #region 获取最近一周用户 + private async Task> GetRecentUser() + { + DateTime dateTime = DateTime.Now.AddDays(-7); + var users = _context.Users.Where(x => x.CreatedAt >= dateTime); + return _mapper.Map>(await users.ToListAsync()); + } + #endregion + #region 获取最近一周订单 + private async Task> GetRecentOrder() + { + DateTime dateTime = DateTime.Now.AddDays(-7); + var orders = _context.Orders.Include(x => x.User).Where(x => x.CreatedAt >= dateTime); + return _mapper.Map>(await orders.ToListAsync()); + } + #endregion + #region 获取金额数 + public async Task GetMoney() + { + return await _context.Orders.Where(x => x.OrderType == Models.OrderType.Recharge).SumAsync(x => x.Amount); + } + #endregion + } +} diff --git a/Apimanager_backend/Services/UserService.cs b/Apimanager_backend/Services/UserService.cs index cbf843f..b226008 100644 --- a/Apimanager_backend/Services/UserService.cs +++ b/Apimanager_backend/Services/UserService.cs @@ -10,6 +10,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Diagnostics; using StackExchange.Redis; using System.ComponentModel; +using System.Security.Cryptography; namespace Apimanager_backend.Services { @@ -125,5 +126,25 @@ namespace Apimanager_backend.Services await apiContext.SaveChangesAsync(); return true; } + #region 设置用户apikey + public async Task SetUserTokenAsync(int userId) + { + User? user = await apiContext.Users.FirstOrDefaultAsync(x => x.Id == userId); + if (user is null) + { + throw new BaseException(2004,"用户未找到"); + } + var tokenBytes = new byte[32]; + using (var rng = RandomNumberGenerator.Create()) + { + rng.GetBytes(tokenBytes); + } + var tokenStr = Convert.ToBase64String(tokenBytes); + user.ApiKey = tokenStr; + apiContext.Users.Update(user); + await apiContext.SaveChangesAsync(); + return tokenStr; + } + #endregion } } diff --git a/Apimanager_backend/Tools/EpayHelper.cs b/Apimanager_backend/Tools/EpayHelper.cs index 1fd3f6d..b0f58c1 100644 --- a/Apimanager_backend/Tools/EpayHelper.cs +++ b/Apimanager_backend/Tools/EpayHelper.cs @@ -37,7 +37,8 @@ namespace Apimanager_backend.Tools using var client = new HttpClient(); var content = new FormUrlEncodedContent(parameters); var response = await client.PostAsync($"{baseUrl}/mapi.php", content); - return JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()); + var responseJson = await response.Content.ReadAsStringAsync(); + return JsonConvert.DeserializeObject(responseJson); } /// diff --git a/Apimanager_backend/uploads/avatars/-1_20250807165504.jpg b/Apimanager_backend/uploads/avatars/-1_20250807165504.jpg new file mode 100644 index 0000000..696bfe5 Binary files /dev/null and b/Apimanager_backend/uploads/avatars/-1_20250807165504.jpg differ diff --git a/Apimanager_backend/uploads/avatars/104_20250806201615.jpg b/Apimanager_backend/uploads/avatars/104_20250806201615.jpg new file mode 100644 index 0000000..696bfe5 Binary files /dev/null and b/Apimanager_backend/uploads/avatars/104_20250806201615.jpg differ diff --git a/Apimanager_backend/uploads/logo.png b/Apimanager_backend/uploads/logo.png new file mode 100644 index 0000000..0544e7a Binary files /dev/null and b/Apimanager_backend/uploads/logo.png differ