diff --git a/Apimanager_backend/Apimanager_backend.csproj b/Apimanager_backend/Apimanager_backend.csproj
index 9daa180..ce65827 100644
--- a/Apimanager_backend/Apimanager_backend.csproj
+++ b/Apimanager_backend/Apimanager_backend.csproj
@@ -7,7 +7,19 @@
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
diff --git a/Apimanager_backend/Controllers/WeatherForecastController.cs b/Apimanager_backend/Controllers/WeatherForecastController.cs
deleted file mode 100644
index 028579e..0000000
--- a/Apimanager_backend/Controllers/WeatherForecastController.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using Microsoft.AspNetCore.Mvc;
-
-namespace Apimanager_backend.Controllers
-{
- [ApiController]
- [Route("[controller]")]
- public class WeatherForecastController : ControllerBase
- {
- private static readonly string[] Summaries = new[]
- {
- "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
- };
-
- private readonly ILogger _logger;
-
- public WeatherForecastController(ILogger logger)
- {
- _logger = logger;
- }
-
- [HttpGet(Name = "GetWeatherForecast")]
- public IEnumerable Get()
- {
- return Enumerable.Range(1, 5).Select(index => new WeatherForecast
- {
- Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
- TemperatureC = Random.Shared.Next(-20, 55),
- Summary = Summaries[Random.Shared.Next(Summaries.Length)]
- })
- .ToArray();
- }
- }
-}
diff --git a/Apimanager_backend/Data/ApiCallLogConfig.cs b/Apimanager_backend/Data/ApiCallLogConfig.cs
new file mode 100644
index 0000000..b4484b0
--- /dev/null
+++ b/Apimanager_backend/Data/ApiCallLogConfig.cs
@@ -0,0 +1,26 @@
+using Apimanager_backend.Models;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace Apimanager_backend.Data
+{
+ public class ApiCallLogConfig : IEntityTypeConfiguration
+ {
+ public void Configure(EntityTypeBuilder builder)
+ {
+ //主键
+ builder.HasKey(x => x.Id);
+ //自增
+ builder.Property(x => x.Id)
+ .ValueGeneratedOnAdd();
+ //外键:API
+ builder.HasOne(x => x.Api)
+ .WithMany(u => u.ApiCalls)
+ .HasForeignKey(x => x.ApiId);
+ //外键:User
+ builder.HasOne(x => x.User)
+ .WithMany(u => u.CallLogs)
+ .HasForeignKey(x => x.UserId);
+ }
+ }
+}
diff --git a/Apimanager_backend/Data/ApiConfig.cs b/Apimanager_backend/Data/ApiConfig.cs
new file mode 100644
index 0000000..cf36445
--- /dev/null
+++ b/Apimanager_backend/Data/ApiConfig.cs
@@ -0,0 +1,23 @@
+using Apimanager_backend.Models;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace Apimanager_backend.Data
+{
+ public class ApiConfig : IEntityTypeConfiguration
+ {
+ public void Configure(EntityTypeBuilder builder)
+ {
+ //主键
+ builder.HasKey(x => x.Id);
+ //自增
+ builder.Property(x => x.Id)
+ .ValueGeneratedOnAdd();
+ //外键
+ builder.HasOne(x => x.Package)
+ .WithMany(u => u.Apis)
+ .HasForeignKey(x => x.PackageId);
+
+ }
+ }
+}
diff --git a/Apimanager_backend/Data/ApiContext.cs b/Apimanager_backend/Data/ApiContext.cs
new file mode 100644
index 0000000..1be7614
--- /dev/null
+++ b/Apimanager_backend/Data/ApiContext.cs
@@ -0,0 +1,30 @@
+using Apimanager_backend.Models;
+using Microsoft.EntityFrameworkCore;
+using System.Reflection;
+
+namespace Apimanager_backend.Data
+{
+ public class ApiContext:DbContext
+ {
+ //API表
+ public DbSet Apis { get; set; }
+ //用户表
+ public DbSet Users { get; set; }
+ //API调用日志
+ public DbSet CallLogs { get; set; }
+ //套餐表
+ public DbSet Apipackages { get; set; }
+ //操作日志表
+ public DbSet OperationLogs { get; set; }
+ //订单表
+ public DbSet Orders { get; set; }
+ //用户已订购套餐表
+ public DbSet UserPackages { get; set; }
+ public ApiContext(DbContextOptions options) : base(options) { }
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+ modelBuilder.ApplyConfigurationsFromAssembly(typeof(ApiContext).Assembly);
+ }
+
+ }
+}
diff --git a/Apimanager_backend/Data/OperationLogConfig.cs b/Apimanager_backend/Data/OperationLogConfig.cs
new file mode 100644
index 0000000..01d83ae
--- /dev/null
+++ b/Apimanager_backend/Data/OperationLogConfig.cs
@@ -0,0 +1,22 @@
+using Apimanager_backend.Models;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace Apimanager_backend.Data
+{
+ public class OperationLogConfig : IEntityTypeConfiguration
+ {
+ public void Configure(EntityTypeBuilder builder)
+ {
+ //主键
+ builder.HasKey(x => x.Id);
+ //自增
+ builder.Property(x => x.Id)
+ .ValueGeneratedOnAdd();
+ //外键
+ builder.HasOne(x => x.User)
+ .WithMany(u => u.operationLogs)
+ .HasForeignKey(x => x.UserId);
+ }
+ }
+}
diff --git a/Apimanager_backend/Data/OrderConfig.cs b/Apimanager_backend/Data/OrderConfig.cs
new file mode 100644
index 0000000..50d6452
--- /dev/null
+++ b/Apimanager_backend/Data/OrderConfig.cs
@@ -0,0 +1,28 @@
+using Apimanager_backend.Models;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace Apimanager_backend.Data
+{
+ public class OrderConfig : IEntityTypeConfiguration
+ {
+ public void Configure(EntityTypeBuilder builder)
+ {
+ //主键
+ builder.HasKey(x => x.Id);
+ //自增
+ builder.Property(x => x.Id)
+ .ValueGeneratedOnAdd();
+ //唯一索引
+ builder.HasIndex(x => x.OrderNumber)
+ .IsUnique();
+ //唯一索引
+ builder.HasIndex(x => x.ThirdPartyOrderId)
+ .IsUnique();
+ //外键
+ builder.HasOne(x => x.User)
+ .WithMany(u => u.Orders)
+ .HasForeignKey(x => x.UserId);
+ }
+ }
+}
diff --git a/Apimanager_backend/Data/UserConfig.cs b/Apimanager_backend/Data/UserConfig.cs
new file mode 100644
index 0000000..7b5058a
--- /dev/null
+++ b/Apimanager_backend/Data/UserConfig.cs
@@ -0,0 +1,23 @@
+using Apimanager_backend.Models;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace Apimanager_backend.Data
+{
+ public class UserConfig : IEntityTypeConfiguration
+ {
+ public void Configure(EntityTypeBuilder builder)
+ {
+ //主键
+ builder.HasKey(x => x.Id);
+ //自增
+ builder.Property(x => x.Id)
+ .ValueGeneratedOnAdd();
+ //唯一索引
+ builder.HasIndex(x => x.Username)
+ .IsUnique();
+ builder.HasIndex(x => x.Email)
+ .IsUnique();
+ }
+ }
+}
diff --git a/Apimanager_backend/Data/UserPackageConfig.cs b/Apimanager_backend/Data/UserPackageConfig.cs
new file mode 100644
index 0000000..032d923
--- /dev/null
+++ b/Apimanager_backend/Data/UserPackageConfig.cs
@@ -0,0 +1,25 @@
+using Apimanager_backend.Models;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace Apimanager_backend.Data
+{
+ public class UserPackageConfig : IEntityTypeConfiguration
+ {
+ public void Configure(EntityTypeBuilder builder)
+ {
+ //主键
+ builder.HasKey(x => x.Id);
+ //自增
+ builder.Property(x => x.Id)
+ .ValueGeneratedOnAdd();
+ //外键
+ builder.HasOne(x => x.User)
+ .WithMany(u => u.Packages)
+ .HasForeignKey(x => x.UserId);
+ builder.HasOne(x => x.Package)
+ .WithMany(u => u.Packages)
+ .HasForeignKey(x => x.PackageId);
+ }
+ }
+}
diff --git a/Apimanager_backend/Migrations/20241024162342_Init-Database.Designer.cs b/Apimanager_backend/Migrations/20241024162342_Init-Database.Designer.cs
new file mode 100644
index 0000000..d3bb34c
--- /dev/null
+++ b/Apimanager_backend/Migrations/20241024162342_Init-Database.Designer.cs
@@ -0,0 +1,378 @@
+//
+using System;
+using Apimanager_backend.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace Apimanager_backend.Migrations
+{
+ [DbContext(typeof(ApiContext))]
+ [Migration("20241024162342_Init-Database")]
+ partial class InitDatabase
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "8.0.0")
+ .HasAnnotation("Relational:MaxIdentifierLength", 64);
+
+ modelBuilder.Entity("Apimanager_backend.Models.Api", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Endpoint")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("IsActive")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("IsDelete")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("IsThirdParty")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Method")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("varchar(200)");
+
+ b.Property("PackageId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PackageId");
+
+ b.ToTable("Apis");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.ApiCallLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("ApiId")
+ .HasColumnType("int");
+
+ b.Property("CallResult")
+ .HasColumnType("int");
+
+ b.Property("CallTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ApiId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("CallLogs");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.Apipackage", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("CallLimit")
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("ExpiryDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("varchar(20)");
+
+ b.Property("Price")
+ .HasColumnType("decimal(65,30)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Apipackages");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.OperationLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("IpAddress")
+ .IsRequired()
+ .HasMaxLength(45)
+ .HasColumnType("varchar(45)");
+
+ b.Property("Operation")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("varchar(20)");
+
+ b.Property("TargetId")
+ .HasColumnType("int");
+
+ b.Property("TargetType")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)");
+
+ b.Property("UserAgent")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("OperationLogs");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.Order", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Amount")
+ .HasColumnType("decimal(65,30)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Description")
+ .HasColumnType("longtext");
+
+ b.Property("OrderNumber")
+ .IsRequired()
+ .HasColumnType("varchar(255)");
+
+ b.Property("OrderType")
+ .HasColumnType("int");
+
+ b.Property("Status")
+ .HasColumnType("int");
+
+ b.Property("ThirdPartyOrderId")
+ .HasColumnType("varchar(255)");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrderNumber")
+ .IsUnique();
+
+ b.HasIndex("ThirdPartyOrderId")
+ .IsUnique();
+
+ b.HasIndex("UserId");
+
+ b.ToTable("Orders");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.User", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Balance")
+ .HasColumnType("decimal(65,30)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Email")
+ .IsRequired()
+ .HasColumnType("varchar(255)");
+
+ b.Property("IsBan")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("IsDelete")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("PassHash")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("varchar(255)");
+
+ b.Property("Role")
+ .HasColumnType("int");
+
+ b.Property("Username")
+ .IsRequired()
+ .HasColumnType("varchar(255)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Email")
+ .IsUnique();
+
+ b.HasIndex("Username")
+ .IsUnique();
+
+ b.ToTable("Users");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.UserPackage", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("PackageId")
+ .HasColumnType("int");
+
+ b.Property("PurchasedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("RemainingCalls")
+ .HasColumnType("int");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PackageId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("UserPackages");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.Api", b =>
+ {
+ b.HasOne("Apimanager_backend.Models.Apipackage", "Package")
+ .WithMany("Apis")
+ .HasForeignKey("PackageId");
+
+ b.Navigation("Package");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.ApiCallLog", b =>
+ {
+ b.HasOne("Apimanager_backend.Models.Api", "Api")
+ .WithMany("ApiCalls")
+ .HasForeignKey("ApiId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Apimanager_backend.Models.User", "User")
+ .WithMany("CallLogs")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Api");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.OperationLog", b =>
+ {
+ b.HasOne("Apimanager_backend.Models.User", "User")
+ .WithMany("operationLogs")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.Order", b =>
+ {
+ b.HasOne("Apimanager_backend.Models.User", "User")
+ .WithMany("Orders")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.UserPackage", b =>
+ {
+ b.HasOne("Apimanager_backend.Models.Apipackage", "Package")
+ .WithMany("Packages")
+ .HasForeignKey("PackageId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Apimanager_backend.Models.User", "User")
+ .WithMany("Packages")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Package");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.Api", b =>
+ {
+ b.Navigation("ApiCalls");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.Apipackage", b =>
+ {
+ b.Navigation("Apis");
+
+ b.Navigation("Packages");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.User", b =>
+ {
+ b.Navigation("CallLogs");
+
+ b.Navigation("Orders");
+
+ b.Navigation("Packages");
+
+ b.Navigation("operationLogs");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Apimanager_backend/Migrations/20241024162342_Init-Database.cs b/Apimanager_backend/Migrations/20241024162342_Init-Database.cs
new file mode 100644
index 0000000..3de7b1b
--- /dev/null
+++ b/Apimanager_backend/Migrations/20241024162342_Init-Database.cs
@@ -0,0 +1,295 @@
+using System;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace Apimanager_backend.Migrations
+{
+ ///
+ public partial class InitDatabase : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AlterDatabase()
+ .Annotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.CreateTable(
+ name: "Apipackages",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
+ Name = table.Column(type: "varchar(20)", maxLength: 20, nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ CallLimit = table.Column(type: "int", nullable: false),
+ Price = table.Column(type: "decimal(65,30)", nullable: false),
+ ExpiryDate = table.Column(type: "datetime(6)", nullable: false),
+ CreatedAt = table.Column(type: "datetime(6)", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Apipackages", x => x.Id);
+ })
+ .Annotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.CreateTable(
+ name: "Users",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
+ Username = table.Column(type: "varchar(255)", nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ Email = table.Column(type: "varchar(255)", nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ PassHash = table.Column(type: "varchar(255)", maxLength: 255, nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ Role = table.Column(type: "int", nullable: false),
+ IsBan = table.Column(type: "tinyint(1)", nullable: false),
+ IsDelete = table.Column(type: "tinyint(1)", nullable: false),
+ Balance = table.Column(type: "decimal(65,30)", nullable: false),
+ CreatedAt = table.Column(type: "datetime(6)", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Users", x => x.Id);
+ })
+ .Annotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.CreateTable(
+ name: "Apis",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
+ Name = table.Column(type: "varchar(200)", maxLength: 200, nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ Endpoint = table.Column(type: "longtext", nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ Method = table.Column(type: "int", nullable: false),
+ PackageId = table.Column(type: "int", nullable: true),
+ IsThirdParty = table.Column(type: "tinyint(1)", nullable: false),
+ IsActive = table.Column(type: "tinyint(1)", nullable: false),
+ IsDelete = table.Column(type: "tinyint(1)", nullable: false),
+ CreatedAt = table.Column(type: "datetime(6)", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Apis", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Apis_Apipackages_PackageId",
+ column: x => x.PackageId,
+ principalTable: "Apipackages",
+ principalColumn: "Id");
+ })
+ .Annotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.CreateTable(
+ name: "OperationLogs",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
+ UserId = table.Column(type: "int", nullable: false),
+ Operation = table.Column(type: "varchar(20)", maxLength: 20, nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ TargetType = table.Column(type: "varchar(50)", maxLength: 50, nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ TargetId = table.Column(type: "int", nullable: false),
+ CreatedAt = table.Column(type: "datetime(6)", nullable: false),
+ IpAddress = table.Column(type: "varchar(45)", maxLength: 45, nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ UserAgent = table.Column(type: "longtext", nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ Description = table.Column(type: "longtext", nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4")
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_OperationLogs", x => x.Id);
+ table.ForeignKey(
+ name: "FK_OperationLogs_Users_UserId",
+ column: x => x.UserId,
+ principalTable: "Users",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ })
+ .Annotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.CreateTable(
+ name: "Orders",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
+ UserId = table.Column(type: "int", nullable: false),
+ OrderNumber = table.Column(type: "varchar(255)", nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ ThirdPartyOrderId = table.Column(type: "varchar(255)", nullable: true)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ Amount = table.Column(type: "decimal(65,30)", nullable: false),
+ OrderType = table.Column(type: "int", nullable: false),
+ Status = table.Column(type: "int", nullable: false),
+ CreatedAt = table.Column(type: "datetime(6)", nullable: false),
+ UpdatedAt = table.Column(type: "datetime(6)", nullable: false),
+ Description = table.Column(type: "longtext", nullable: true)
+ .Annotation("MySql:CharSet", "utf8mb4")
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Orders", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Orders_Users_UserId",
+ column: x => x.UserId,
+ principalTable: "Users",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ })
+ .Annotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.CreateTable(
+ name: "UserPackages",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
+ UserId = table.Column(type: "int", nullable: false),
+ PackageId = table.Column(type: "int", nullable: false),
+ RemainingCalls = table.Column(type: "int", nullable: false),
+ PurchasedAt = table.Column(type: "datetime(6)", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_UserPackages", x => x.Id);
+ table.ForeignKey(
+ name: "FK_UserPackages_Apipackages_PackageId",
+ column: x => x.PackageId,
+ principalTable: "Apipackages",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_UserPackages_Users_UserId",
+ column: x => x.UserId,
+ principalTable: "Users",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ })
+ .Annotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.CreateTable(
+ name: "CallLogs",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
+ UserId = table.Column(type: "int", nullable: false),
+ ApiId = table.Column(type: "int", nullable: false),
+ CallTime = table.Column(type: "datetime(6)", nullable: false),
+ CallResult = table.Column(type: "int", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_CallLogs", x => x.Id);
+ table.ForeignKey(
+ name: "FK_CallLogs_Apis_ApiId",
+ column: x => x.ApiId,
+ principalTable: "Apis",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_CallLogs_Users_UserId",
+ column: x => x.UserId,
+ principalTable: "Users",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ })
+ .Annotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Apis_PackageId",
+ table: "Apis",
+ column: "PackageId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_CallLogs_ApiId",
+ table: "CallLogs",
+ column: "ApiId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_CallLogs_UserId",
+ table: "CallLogs",
+ column: "UserId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_OperationLogs_UserId",
+ table: "OperationLogs",
+ column: "UserId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Orders_OrderNumber",
+ table: "Orders",
+ column: "OrderNumber",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Orders_ThirdPartyOrderId",
+ table: "Orders",
+ column: "ThirdPartyOrderId",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Orders_UserId",
+ table: "Orders",
+ column: "UserId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_UserPackages_PackageId",
+ table: "UserPackages",
+ column: "PackageId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_UserPackages_UserId",
+ table: "UserPackages",
+ column: "UserId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Users_Email",
+ table: "Users",
+ column: "Email",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Users_Username",
+ table: "Users",
+ column: "Username",
+ unique: true);
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "CallLogs");
+
+ migrationBuilder.DropTable(
+ name: "OperationLogs");
+
+ migrationBuilder.DropTable(
+ name: "Orders");
+
+ migrationBuilder.DropTable(
+ name: "UserPackages");
+
+ migrationBuilder.DropTable(
+ name: "Apis");
+
+ migrationBuilder.DropTable(
+ name: "Users");
+
+ migrationBuilder.DropTable(
+ name: "Apipackages");
+ }
+ }
+}
diff --git a/Apimanager_backend/Migrations/ApiContextModelSnapshot.cs b/Apimanager_backend/Migrations/ApiContextModelSnapshot.cs
new file mode 100644
index 0000000..83d8249
--- /dev/null
+++ b/Apimanager_backend/Migrations/ApiContextModelSnapshot.cs
@@ -0,0 +1,375 @@
+//
+using System;
+using Apimanager_backend.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace Apimanager_backend.Migrations
+{
+ [DbContext(typeof(ApiContext))]
+ partial class ApiContextModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "8.0.0")
+ .HasAnnotation("Relational:MaxIdentifierLength", 64);
+
+ modelBuilder.Entity("Apimanager_backend.Models.Api", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Endpoint")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("IsActive")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("IsDelete")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("IsThirdParty")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Method")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("varchar(200)");
+
+ b.Property("PackageId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PackageId");
+
+ b.ToTable("Apis");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.ApiCallLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("ApiId")
+ .HasColumnType("int");
+
+ b.Property("CallResult")
+ .HasColumnType("int");
+
+ b.Property("CallTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ApiId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("CallLogs");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.Apipackage", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("CallLimit")
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("ExpiryDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("varchar(20)");
+
+ b.Property("Price")
+ .HasColumnType("decimal(65,30)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Apipackages");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.OperationLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("IpAddress")
+ .IsRequired()
+ .HasMaxLength(45)
+ .HasColumnType("varchar(45)");
+
+ b.Property("Operation")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("varchar(20)");
+
+ b.Property("TargetId")
+ .HasColumnType("int");
+
+ b.Property("TargetType")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)");
+
+ b.Property("UserAgent")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("OperationLogs");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.Order", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Amount")
+ .HasColumnType("decimal(65,30)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Description")
+ .HasColumnType("longtext");
+
+ b.Property("OrderNumber")
+ .IsRequired()
+ .HasColumnType("varchar(255)");
+
+ b.Property("OrderType")
+ .HasColumnType("int");
+
+ b.Property("Status")
+ .HasColumnType("int");
+
+ b.Property("ThirdPartyOrderId")
+ .HasColumnType("varchar(255)");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrderNumber")
+ .IsUnique();
+
+ b.HasIndex("ThirdPartyOrderId")
+ .IsUnique();
+
+ b.HasIndex("UserId");
+
+ b.ToTable("Orders");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.User", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Balance")
+ .HasColumnType("decimal(65,30)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Email")
+ .IsRequired()
+ .HasColumnType("varchar(255)");
+
+ b.Property("IsBan")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("IsDelete")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("PassHash")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("varchar(255)");
+
+ b.Property("Role")
+ .HasColumnType("int");
+
+ b.Property("Username")
+ .IsRequired()
+ .HasColumnType("varchar(255)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Email")
+ .IsUnique();
+
+ b.HasIndex("Username")
+ .IsUnique();
+
+ b.ToTable("Users");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.UserPackage", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("PackageId")
+ .HasColumnType("int");
+
+ b.Property("PurchasedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("RemainingCalls")
+ .HasColumnType("int");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PackageId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("UserPackages");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.Api", b =>
+ {
+ b.HasOne("Apimanager_backend.Models.Apipackage", "Package")
+ .WithMany("Apis")
+ .HasForeignKey("PackageId");
+
+ b.Navigation("Package");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.ApiCallLog", b =>
+ {
+ b.HasOne("Apimanager_backend.Models.Api", "Api")
+ .WithMany("ApiCalls")
+ .HasForeignKey("ApiId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Apimanager_backend.Models.User", "User")
+ .WithMany("CallLogs")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Api");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.OperationLog", b =>
+ {
+ b.HasOne("Apimanager_backend.Models.User", "User")
+ .WithMany("operationLogs")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.Order", b =>
+ {
+ b.HasOne("Apimanager_backend.Models.User", "User")
+ .WithMany("Orders")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.UserPackage", b =>
+ {
+ b.HasOne("Apimanager_backend.Models.Apipackage", "Package")
+ .WithMany("Packages")
+ .HasForeignKey("PackageId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Apimanager_backend.Models.User", "User")
+ .WithMany("Packages")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Package");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.Api", b =>
+ {
+ b.Navigation("ApiCalls");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.Apipackage", b =>
+ {
+ b.Navigation("Apis");
+
+ b.Navigation("Packages");
+ });
+
+ modelBuilder.Entity("Apimanager_backend.Models.User", b =>
+ {
+ b.Navigation("CallLogs");
+
+ b.Navigation("Orders");
+
+ b.Navigation("Packages");
+
+ b.Navigation("operationLogs");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Apimanager_backend/Models/Api.cs b/Apimanager_backend/Models/Api.cs
new file mode 100644
index 0000000..85b8d23
--- /dev/null
+++ b/Apimanager_backend/Models/Api.cs
@@ -0,0 +1,59 @@
+using Apimanager_backend.Data;
+using System.ComponentModel.DataAnnotations;
+
+namespace Apimanager_backend.Models
+{
+ public class Api
+ {
+ ///
+ /// 主键,自增
+ ///
+ public int Id { get; set; }
+
+ ///
+ /// API名称
+ ///
+ [MaxLength(200)]
+ [Required]
+ public string Name { get; set; } // varchar(20)
+
+ ///
+ /// API地址
+ ///
+ [Required]
+ public string Endpoint { get; set; } // varchar(255)
+
+ ///
+ /// 调用方法
+ ///
+ public ApiMethod Method { get; set; } // enum('GET','POST','PUT', 'DELETE')
+
+ ///
+ /// 套餐Id,默认为空(免费无限制)
+ ///
+ public int? PackageId { get; set; } // int? 使其可为null
+
+ ///
+ /// 是否第三方API
+ ///
+ public bool IsThirdParty { get; set; } // boolean
+
+ ///
+ /// 是否启用
+ ///
+ public bool IsActive { get; set; } // boolean
+ ///
+ /// 是否删除
+ ///
+ public bool IsDelete { get; set; } // boolean
+
+ ///
+ /// 创建时间,默认当前时间
+ ///
+ public DateTime CreatedAt { get; set; } = DateTime.UtcNow; // timestamp
+
+ //导航属性
+ public Apipackage? Package { get; set; }
+ public ICollection ApiCalls { get; set; }
+ }
+}
diff --git a/Apimanager_backend/Models/ApiCallLog.cs b/Apimanager_backend/Models/ApiCallLog.cs
new file mode 100644
index 0000000..234b42d
--- /dev/null
+++ b/Apimanager_backend/Models/ApiCallLog.cs
@@ -0,0 +1,35 @@
+namespace Apimanager_backend.Models
+{
+ public class ApiCallLog
+ {
+ ///
+ /// 主键,自增
+ ///
+ public int Id { get; set; }
+
+ ///
+ /// 外键,用户ID
+ ///
+ public int UserId { get; set; }
+
+ ///
+ /// 外键,API ID
+ ///
+ public int ApiId { get; set; }
+
+ ///
+ /// 调用时间,默认当前时间
+ ///
+ public DateTime CallTime { get; set; } = DateTime.UtcNow; // Timestamp
+
+ ///
+ /// 调用结果状态码
+ ///
+ public int CallResult { get; set; } // 调用结果状态码
+
+
+ //导航属性
+ public User? User { get; set; }
+ public Api? Api { get; set; }
+ }
+}
diff --git a/Apimanager_backend/Models/ApiMethod.cs b/Apimanager_backend/Models/ApiMethod.cs
new file mode 100644
index 0000000..2d736c9
--- /dev/null
+++ b/Apimanager_backend/Models/ApiMethod.cs
@@ -0,0 +1,10 @@
+namespace Apimanager_backend.Models
+{
+ public enum ApiMethod
+ {
+ GET,
+ POST,
+ PUT,
+ DELETE
+ }
+}
diff --git a/Apimanager_backend/Models/Apipackage.cs b/Apimanager_backend/Models/Apipackage.cs
new file mode 100644
index 0000000..fc031ba
--- /dev/null
+++ b/Apimanager_backend/Models/Apipackage.cs
@@ -0,0 +1,44 @@
+using Microsoft.EntityFrameworkCore;
+using System.ComponentModel.DataAnnotations;
+
+namespace Apimanager_backend.Models
+{
+ public class Apipackage
+ {
+ ///
+ /// 主键,自增
+ ///
+ [Key]
+ public int Id { get; set; }
+
+ ///
+ /// 套餐名称
+ ///
+ [MaxLength(20)]
+ public string Name { get; set; } // varchar(20)
+
+ ///
+ /// 最大调用次数
+ ///
+ public int CallLimit { get; set; } // int
+
+ ///
+ /// 价格
+ ///
+ public decimal Price { get; set; } // decimal(10,2)
+
+ ///
+ /// 套餐过期时间,可用于控制套餐是否过期
+ ///
+ public DateTime ExpiryDate { get; set; } // timestamp
+
+ ///
+ /// 创建时间
+ ///
+ public DateTime CreatedAt { get; set; } = DateTime.UtcNow; // timestamp
+
+ //导航属性
+ public ICollection Apis { get; set; }
+ public ICollection Packages { get; set; }
+ }
+}
diff --git a/Apimanager_backend/Models/OperationLog.cs b/Apimanager_backend/Models/OperationLog.cs
new file mode 100644
index 0000000..1cebed2
--- /dev/null
+++ b/Apimanager_backend/Models/OperationLog.cs
@@ -0,0 +1,61 @@
+using Microsoft.AspNetCore.Antiforgery;
+using System.ComponentModel.DataAnnotations;
+
+namespace Apimanager_backend.Models
+{
+ public class OperationLog
+ {
+ ///
+ /// 主键,自增
+ ///
+ public int Id { get; set; }
+
+ ///
+ /// 操作人ID,操作者的用户ID(通常是管理员)
+ ///
+ public int UserId { get; set; }
+
+ ///
+ /// 操作类型,描述操作的具体内容
+ ///
+ [Required]
+ [MaxLength(20)]
+ public string Operation { get; set; } // varchar(20)
+
+ ///
+ /// 目标类型,操作的对象类型
+ ///
+ [Required]
+ [MaxLength(50)]
+ public string TargetType { get; set; } // varchar(50)
+
+ ///
+ /// 目标对象ID,操作对象的具体ID
+ ///
+ public int TargetId { get; set; }
+
+ ///
+ /// 操作时间,操作发生时间
+ ///
+ public DateTime CreatedAt { get; set; } = DateTime.UtcNow; // timestamp
+
+ ///
+ /// 操作来源IP
+ ///
+ [MaxLength(45)]
+ public string IpAddress { get; set; } // varchar(45)
+
+ ///
+ /// 操作设备信息
+ ///
+ public string UserAgent { get; set; } // varchar(255)
+
+ ///
+ /// 操作描述,可选的详细说明,解释操作原因等
+ ///
+ public string Description { get; set; } // varchar(255)
+
+ //导航属性
+ public User? User { get; set; }
+ }
+}
diff --git a/Apimanager_backend/Models/Order.cs b/Apimanager_backend/Models/Order.cs
new file mode 100644
index 0000000..804b846
--- /dev/null
+++ b/Apimanager_backend/Models/Order.cs
@@ -0,0 +1,62 @@
+using Microsoft.EntityFrameworkCore;
+using System.ComponentModel.DataAnnotations;
+
+namespace Apimanager_backend.Models
+{
+ public class Order
+ {
+ ///
+ /// 主键,自增
+ ///
+ public int Id { get; set; }
+
+ ///
+ /// 外键,用户ID
+ ///
+ public int UserId { get; set; }
+
+ ///
+ /// 订单号,唯一
+ ///
+ [Required]
+ public string OrderNumber { get; set; } // varchar(50)
+
+ ///
+ /// 第三方系统订单编号
+ ///
+ public string? ThirdPartyOrderId { get; set; } // varchar(100)
+
+ ///
+ /// 订单金额
+ ///
+ public decimal Amount { get; set; } // decimal(10, 2)
+
+ ///
+ /// 订单类型
+ ///
+ public OrderType OrderType { get; set; } // enum('Recharge','Purchase','Refund')
+
+ ///
+ /// 订单状态
+ ///
+ public OrderStatus Status { get; set; } // enum('Pending','Completed','Cancelled','Failed')
+
+ ///
+ /// 创建时间,订单创建时间
+ ///
+ public DateTime CreatedAt { get; set; } = DateTime.UtcNow; // timestamp
+
+ ///
+ /// 更新时间,订单状态更新时间
+ ///
+ public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; // timestamp
+
+ ///
+ /// 订单描述,可选的详细信息
+ ///
+ public string? Description { get; set; } // varchar(255)
+
+ //导航属性
+ public User? User { get; set; }
+ }
+}
diff --git a/Apimanager_backend/Models/OrderStatus.cs b/Apimanager_backend/Models/OrderStatus.cs
new file mode 100644
index 0000000..9477196
--- /dev/null
+++ b/Apimanager_backend/Models/OrderStatus.cs
@@ -0,0 +1,10 @@
+namespace Apimanager_backend.Models
+{
+ public enum OrderStatus
+ {
+ Pending,
+ Completed,
+ Cancelled,
+ Failed
+ }
+}
diff --git a/Apimanager_backend/Models/OrderType.cs b/Apimanager_backend/Models/OrderType.cs
new file mode 100644
index 0000000..d3f8f22
--- /dev/null
+++ b/Apimanager_backend/Models/OrderType.cs
@@ -0,0 +1,9 @@
+namespace Apimanager_backend.Models
+{
+ public enum OrderType
+ {
+ Recharge,
+ Purchase,
+ Refund
+ }
+}
diff --git a/Apimanager_backend/Models/User.cs b/Apimanager_backend/Models/User.cs
new file mode 100644
index 0000000..07c11fc
--- /dev/null
+++ b/Apimanager_backend/Models/User.cs
@@ -0,0 +1,60 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace Apimanager_backend.Models
+{
+ public class User
+ {
+ ///
+ /// 用户ID,主键,自增
+ ///
+ public int Id { get; set; }
+
+ ///
+ /// 用户名,唯一
+ ///
+ [Required]
+ public string Username { get; set; } // varchar(20)
+
+ ///
+ /// 邮箱,唯一
+ ///
+ public string Email { get; set; } // varchar(20)
+
+ ///
+ /// 密码哈希
+ ///
+ [Required]
+ [MaxLength(255)]
+ public string PassHash { get; set; } // varchar(255)
+
+ ///
+ /// 用户角色
+ ///
+ public UserRole Role { get; set; } // Enum('Admin','User')
+
+ ///
+ /// 是否禁用
+ ///
+ public bool IsBan { get; set; } // boolean
+ ///
+ /// 是否删除
+ ///
+ public bool IsDelete { get; set; } // boolean
+
+ ///
+ /// 余额
+ ///
+ public decimal Balance { get; set; } // Decimal(10)
+
+ ///
+ /// 创建时间,默认当前时间
+ ///
+ public DateTime CreatedAt { get; set; } = DateTime.UtcNow; // Timestamp
+
+ //导航属性
+ public ICollection Packages { get; set; }
+ public ICollection operationLogs { get; set; }
+ public ICollection CallLogs { get; set; }
+ public ICollection Orders { get; set; }
+ }
+}
diff --git a/Apimanager_backend/Models/UserPackage.cs b/Apimanager_backend/Models/UserPackage.cs
new file mode 100644
index 0000000..bee6120
--- /dev/null
+++ b/Apimanager_backend/Models/UserPackage.cs
@@ -0,0 +1,33 @@
+namespace Apimanager_backend.Models
+{
+ public class UserPackage
+ {///
+ /// 主键,自增
+ ///
+ public int Id { get; set; }
+
+ ///
+ /// 外键,用户ID
+ ///
+ public int UserId { get; set; }
+
+ ///
+ /// 外键,套餐ID
+ ///
+ public int PackageId { get; set; }
+
+ ///
+ /// 剩余调用次数
+ ///
+ public int RemainingCalls { get; set; }
+
+ ///
+ /// 购买时间
+ ///
+ public DateTime PurchasedAt { get; set; } = DateTime.UtcNow; // timestamp
+
+ //导航属性
+ public User? User { get; set; }
+ public Apipackage? Package { get; set; }
+ }
+}
diff --git a/Apimanager_backend/Models/UserRole.cs b/Apimanager_backend/Models/UserRole.cs
new file mode 100644
index 0000000..cbd29ff
--- /dev/null
+++ b/Apimanager_backend/Models/UserRole.cs
@@ -0,0 +1,8 @@
+namespace Apimanager_backend.Models
+{
+ public enum UserRole
+ {
+ Admin = 0,
+ User = 1
+ }
+}
diff --git a/Apimanager_backend/Program.cs b/Apimanager_backend/Program.cs
index 48863a6..8661d8a 100644
--- a/Apimanager_backend/Program.cs
+++ b/Apimanager_backend/Program.cs
@@ -1,7 +1,21 @@
+using Apimanager_backend.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.DependencyInjection;
+
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
+IConfiguration configuration = new ConfigurationBuilder()
+ .SetBasePath(Directory.GetCurrentDirectory())
+ .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
+ .Build();
+
+string? constr = configuration.GetConnectionString("DefaultConnection");
+builder.Services.AddDbContext(option =>
+option.UseMySql(constr, MySqlServerVersion.AutoDetect(constr))
+);
+
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
diff --git a/Apimanager_backend/WeatherForecast.cs b/Apimanager_backend/WeatherForecast.cs
deleted file mode 100644
index d21615d..0000000
--- a/Apimanager_backend/WeatherForecast.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Apimanager_backend
-{
- public class WeatherForecast
- {
- public DateOnly Date { get; set; }
-
- public int TemperatureC { get; set; }
-
- public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
-
- public string? Summary { get; set; }
- }
-}
diff --git a/Apimanager_backend/appsettings.json b/Apimanager_backend/appsettings.json
index 10f68b8..8fbdf86 100644
--- a/Apimanager_backend/appsettings.json
+++ b/Apimanager_backend/appsettings.json
@@ -5,5 +5,8 @@
"Microsoft.AspNetCore": "Warning"
}
},
- "AllowedHosts": "*"
+ "AllowedHosts": "*",
+ "ConnectionStrings": {
+ "DefaultConnection": "server=192.168.5.200;username=root;password=768788Dyw@;port=3306;database=api_billing_system;SslMode=Preferred;"
+ }
}