更新
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PetWash.Api.Data;
|
||||
using PetWash.Api.Models;
|
||||
|
||||
namespace PetWash.Api.Controllers;
|
||||
|
||||
@@ -18,7 +19,9 @@ public class PackagesController : ControllerBase
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> GetPackages()
|
||||
{
|
||||
var packages = await _context.Packages.ToListAsync();
|
||||
var packages = await _context.Packages
|
||||
.OrderBy(x => x.Id)
|
||||
.ToListAsync();
|
||||
return Ok(packages);
|
||||
}
|
||||
|
||||
@@ -31,4 +34,71 @@ public class PackagesController : ControllerBase
|
||||
|
||||
return Ok(package);
|
||||
}
|
||||
|
||||
[HttpPut("{id}")]
|
||||
public async Task<IActionResult> UpdatePackage(int id, [FromBody] UpdatePackageRequest request)
|
||||
{
|
||||
var package = await _context.Packages.FindAsync(id);
|
||||
if (package == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if (request.Price <= 0)
|
||||
{
|
||||
return BadRequest("套餐金额必须大于 0。");
|
||||
}
|
||||
|
||||
if (request.FirstSprayWaterTime <= 0 ||
|
||||
request.AfterShampoo1SprayTime <= 0 ||
|
||||
request.AfterShampoo2SprayTime <= 0 ||
|
||||
request.AfterShampoo3SprayTime <= 0 ||
|
||||
request.SprayShampoo1Time <= 0 ||
|
||||
request.SprayShampoo2Time <= 0 ||
|
||||
request.SprayShampoo3Time <= 0 ||
|
||||
request.HotAirTime <= 0 ||
|
||||
request.ColdAirTime <= 0 ||
|
||||
request.UvSterilizationTime <= 0)
|
||||
{
|
||||
return BadRequest("套餐流程时间必须全部大于 0。");
|
||||
}
|
||||
|
||||
package.Price = request.Price;
|
||||
package.FirstSprayWaterTime = request.FirstSprayWaterTime;
|
||||
package.AfterShampoo1SprayTime = request.AfterShampoo1SprayTime;
|
||||
package.AfterShampoo2SprayTime = request.AfterShampoo2SprayTime;
|
||||
package.AfterShampoo3SprayTime = request.AfterShampoo3SprayTime;
|
||||
package.SprayShampoo1Time = request.SprayShampoo1Time;
|
||||
package.SprayShampoo2Time = request.SprayShampoo2Time;
|
||||
package.SprayShampoo3Time = request.SprayShampoo3Time;
|
||||
package.HotAirTime = request.HotAirTime;
|
||||
package.ColdAirTime = request.ColdAirTime;
|
||||
package.UvSterilizationTime = request.UvSterilizationTime;
|
||||
package.DurationMinutes = request.FirstSprayWaterTime
|
||||
+ request.AfterShampoo1SprayTime
|
||||
+ request.AfterShampoo2SprayTime
|
||||
+ request.AfterShampoo3SprayTime
|
||||
+ request.SprayShampoo1Time
|
||||
+ request.SprayShampoo2Time
|
||||
+ request.SprayShampoo3Time
|
||||
+ request.HotAirTime
|
||||
+ request.ColdAirTime
|
||||
+ request.UvSterilizationTime;
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
return Ok(package);
|
||||
}
|
||||
}
|
||||
|
||||
public record UpdatePackageRequest(
|
||||
decimal Price,
|
||||
int FirstSprayWaterTime,
|
||||
int AfterShampoo1SprayTime,
|
||||
int AfterShampoo2SprayTime,
|
||||
int AfterShampoo3SprayTime,
|
||||
int SprayShampoo1Time,
|
||||
int SprayShampoo2Time,
|
||||
int SprayShampoo3Time,
|
||||
int HotAirTime,
|
||||
int ColdAirTime,
|
||||
int UvSterilizationTime);
|
||||
|
||||
@@ -13,12 +13,6 @@ public class PetWashDbContext : DbContext
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
|
||||
// 初始化套餐数据
|
||||
modelBuilder.Entity<Package>().HasData(
|
||||
new Package { Id = 1, Name = "套餐1", Price = 50, DurationMinutes = 38, Description = "适用于小型犬" },
|
||||
new Package { Id = 2, Name = "套餐2", Price = 80, DurationMinutes = 48, Description = "适用于中型犬" },
|
||||
new Package { Id = 3, Name = "套餐3", Price = 120, DurationMinutes = 60, Description = "适用于大型犬" }
|
||||
);
|
||||
modelBuilder.Entity<Package>().HasData(PackageCatalog.DefaultPackages.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,4 +7,14 @@ public class Package
|
||||
public decimal Price { get; set; }
|
||||
public int DurationMinutes { get; set; }
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public int FirstSprayWaterTime { get; set; }
|
||||
public int AfterShampoo1SprayTime { get; set; }
|
||||
public int AfterShampoo2SprayTime { get; set; }
|
||||
public int AfterShampoo3SprayTime { get; set; }
|
||||
public int SprayShampoo1Time { get; set; }
|
||||
public int SprayShampoo2Time { get; set; }
|
||||
public int SprayShampoo3Time { get; set; }
|
||||
public int HotAirTime { get; set; }
|
||||
public int ColdAirTime { get; set; }
|
||||
public int UvSterilizationTime { get; set; }
|
||||
}
|
||||
|
||||
62
PetWash.Api/Models/PackageCatalog.cs
Normal file
62
PetWash.Api/Models/PackageCatalog.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
namespace PetWash.Api.Models;
|
||||
|
||||
public static class PackageCatalog
|
||||
{
|
||||
public static IReadOnlyList<Package> DefaultPackages { get; } =
|
||||
[
|
||||
new Package
|
||||
{
|
||||
Id = 1,
|
||||
Name = "小型犬套餐",
|
||||
Price = 0.01m,
|
||||
DurationMinutes = 20,
|
||||
Description = "适用于小型犬,洗护流程较短",
|
||||
FirstSprayWaterTime = 2,
|
||||
AfterShampoo1SprayTime = 2,
|
||||
AfterShampoo2SprayTime = 2,
|
||||
AfterShampoo3SprayTime = 2,
|
||||
SprayShampoo1Time = 1,
|
||||
SprayShampoo2Time = 1,
|
||||
SprayShampoo3Time = 1,
|
||||
HotAirTime = 5,
|
||||
ColdAirTime = 2,
|
||||
UvSterilizationTime = 2
|
||||
},
|
||||
new Package
|
||||
{
|
||||
Id = 2,
|
||||
Name = "中型犬套餐",
|
||||
Price = 0.02m,
|
||||
DurationMinutes = 26,
|
||||
Description = "适用于中型犬,洗护流程适中",
|
||||
FirstSprayWaterTime = 3,
|
||||
AfterShampoo1SprayTime = 3,
|
||||
AfterShampoo2SprayTime = 3,
|
||||
AfterShampoo3SprayTime = 3,
|
||||
SprayShampoo1Time = 1,
|
||||
SprayShampoo2Time = 1,
|
||||
SprayShampoo3Time = 1,
|
||||
HotAirTime = 6,
|
||||
ColdAirTime = 3,
|
||||
UvSterilizationTime = 2
|
||||
},
|
||||
new Package
|
||||
{
|
||||
Id = 3,
|
||||
Name = "大型犬套餐",
|
||||
Price = 0.03m,
|
||||
DurationMinutes = 37,
|
||||
Description = "适用于大型犬,洗护流程更长",
|
||||
FirstSprayWaterTime = 4,
|
||||
AfterShampoo1SprayTime = 4,
|
||||
AfterShampoo2SprayTime = 4,
|
||||
AfterShampoo3SprayTime = 4,
|
||||
SprayShampoo1Time = 2,
|
||||
SprayShampoo2Time = 2,
|
||||
SprayShampoo3Time = 2,
|
||||
HotAirTime = 8,
|
||||
ColdAirTime = 4,
|
||||
UvSterilizationTime = 3
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PetWash.Api.Data;
|
||||
using PetWash.Api.Models;
|
||||
using PetWash.Api.Services;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// 配置数据库(支持 SQLite 和 MySQL)
|
||||
var dbProvider = builder.Configuration.GetValue<string>("DatabaseProvider") ?? "Sqlite";
|
||||
var connectionString = dbProvider == "MySql"
|
||||
var connectionString = dbProvider == "MySql"
|
||||
? builder.Configuration.GetConnectionString("MySqlConnection")
|
||||
: builder.Configuration.GetConnectionString("DefaultConnection");
|
||||
|
||||
@@ -23,7 +25,6 @@ builder.Services.AddDbContext<PetWashDbContext>(options =>
|
||||
}
|
||||
});
|
||||
|
||||
// 添加服务
|
||||
builder.Services.AddSingleton<MqttService>();
|
||||
builder.Services.AddHostedService(provider => provider.GetRequiredService<MqttService>());
|
||||
builder.Services.AddScoped<OrderService>();
|
||||
@@ -34,7 +35,6 @@ builder.Services.AddHttpClient<WeChatPayService>(client =>
|
||||
client.Timeout = TimeSpan.FromSeconds(15);
|
||||
});
|
||||
|
||||
// 添加CORS
|
||||
builder.Services.AddCors(options =>
|
||||
{
|
||||
options.AddDefaultPolicy(policy =>
|
||||
@@ -51,36 +51,79 @@ builder.Services.AddSwaggerGen();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// 初始化数据库
|
||||
using (var scope = app.Services.CreateScope())
|
||||
{
|
||||
var db = scope.ServiceProvider.GetRequiredService<PetWashDbContext>();
|
||||
var logger = scope.ServiceProvider.GetRequiredService<ILogger<Program>>();
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
logger.LogInformation("开始初始化数据库...");
|
||||
|
||||
// 确保数据库已创建
|
||||
logger.LogInformation("Starting database initialization.");
|
||||
|
||||
var created = db.Database.EnsureCreated();
|
||||
|
||||
if (created)
|
||||
{
|
||||
logger.LogInformation("数据库创建成功,种子数据已插入");
|
||||
logger.LogInformation("Database created and seed data inserted.");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogInformation("数据库已存在");
|
||||
logger.LogInformation("Database already exists.");
|
||||
}
|
||||
|
||||
EnsurePackageTimingColumns(db, logger);
|
||||
|
||||
foreach (var package in PackageCatalog.DefaultPackages)
|
||||
{
|
||||
var existingPackage = db.Packages.FirstOrDefault(x => x.Id == package.Id);
|
||||
if (existingPackage is null)
|
||||
{
|
||||
db.Packages.Add(new Package
|
||||
{
|
||||
Id = package.Id,
|
||||
Name = package.Name,
|
||||
Price = package.Price,
|
||||
DurationMinutes = package.DurationMinutes,
|
||||
Description = package.Description,
|
||||
FirstSprayWaterTime = package.FirstSprayWaterTime,
|
||||
AfterShampoo1SprayTime = package.AfterShampoo1SprayTime,
|
||||
AfterShampoo2SprayTime = package.AfterShampoo2SprayTime,
|
||||
AfterShampoo3SprayTime = package.AfterShampoo3SprayTime,
|
||||
SprayShampoo1Time = package.SprayShampoo1Time,
|
||||
SprayShampoo2Time = package.SprayShampoo2Time,
|
||||
SprayShampoo3Time = package.SprayShampoo3Time,
|
||||
HotAirTime = package.HotAirTime,
|
||||
ColdAirTime = package.ColdAirTime,
|
||||
UvSterilizationTime = package.UvSterilizationTime
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
existingPackage.Name = package.Name;
|
||||
existingPackage.Price = package.Price;
|
||||
existingPackage.DurationMinutes = package.DurationMinutes;
|
||||
existingPackage.Description = package.Description;
|
||||
existingPackage.FirstSprayWaterTime = package.FirstSprayWaterTime;
|
||||
existingPackage.AfterShampoo1SprayTime = package.AfterShampoo1SprayTime;
|
||||
existingPackage.AfterShampoo2SprayTime = package.AfterShampoo2SprayTime;
|
||||
existingPackage.AfterShampoo3SprayTime = package.AfterShampoo3SprayTime;
|
||||
existingPackage.SprayShampoo1Time = package.SprayShampoo1Time;
|
||||
existingPackage.SprayShampoo2Time = package.SprayShampoo2Time;
|
||||
existingPackage.SprayShampoo3Time = package.SprayShampoo3Time;
|
||||
existingPackage.HotAirTime = package.HotAirTime;
|
||||
existingPackage.ColdAirTime = package.ColdAirTime;
|
||||
existingPackage.UvSterilizationTime = package.UvSterilizationTime;
|
||||
}
|
||||
}
|
||||
|
||||
db.SaveChanges();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "数据库初始化失败");
|
||||
logger.LogError(ex, "Database initialization failed.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
// 启用 Swagger(所有环境)
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
|
||||
@@ -90,3 +133,56 @@ app.UseAuthorization();
|
||||
app.MapControllers();
|
||||
|
||||
app.Run();
|
||||
|
||||
static void EnsurePackageTimingColumns(PetWashDbContext db, ILogger logger)
|
||||
{
|
||||
var providerName = db.Database.ProviderName ?? string.Empty;
|
||||
var isSqlite = providerName.Contains("Sqlite", StringComparison.OrdinalIgnoreCase);
|
||||
var missingColumns = GetMissingPackageTimingColumns(db.Database.GetDbConnection(), isSqlite);
|
||||
|
||||
foreach (var column in missingColumns)
|
||||
{
|
||||
var sql = isSqlite
|
||||
? $"ALTER TABLE Packages ADD COLUMN {column.Name} INTEGER NOT NULL DEFAULT {column.DefaultValue};"
|
||||
: $"ALTER TABLE Packages ADD COLUMN {column.Name} INT NOT NULL DEFAULT {column.DefaultValue};";
|
||||
|
||||
db.Database.ExecuteSqlRaw(sql);
|
||||
logger.LogInformation("Added missing package timing column {ColumnName}", column.Name);
|
||||
}
|
||||
}
|
||||
|
||||
static List<(string Name, int DefaultValue)> GetMissingPackageTimingColumns(DbConnection connection, bool isSqlite)
|
||||
{
|
||||
var expectedColumns = new List<(string Name, int DefaultValue)>
|
||||
{
|
||||
("FirstSprayWaterTime", 2),
|
||||
("AfterShampoo1SprayTime", 2),
|
||||
("AfterShampoo2SprayTime", 2),
|
||||
("AfterShampoo3SprayTime", 2),
|
||||
("SprayShampoo1Time", 1),
|
||||
("SprayShampoo2Time", 1),
|
||||
("SprayShampoo3Time", 1),
|
||||
("HotAirTime", 5),
|
||||
("ColdAirTime", 2),
|
||||
("UvSterilizationTime", 2)
|
||||
};
|
||||
|
||||
if (connection.State != ConnectionState.Open)
|
||||
{
|
||||
connection.Open();
|
||||
}
|
||||
|
||||
using var command = connection.CreateCommand();
|
||||
command.CommandText = isSqlite ? "PRAGMA table_info(Packages);" : "SHOW COLUMNS FROM Packages;";
|
||||
|
||||
using var reader = command.ExecuteReader();
|
||||
var existingColumns = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
while (reader.Read())
|
||||
{
|
||||
existingColumns.Add(reader.GetString(isSqlite ? 1 : 0));
|
||||
}
|
||||
|
||||
return expectedColumns
|
||||
.Where(column => !existingColumns.Contains(column.Name))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
},
|
||||
"DatabaseProvider": "Sqlite",
|
||||
"WeChatPay": {
|
||||
"AppId": "",
|
||||
"AppId": "wxa27a3e3cfce7ae19",
|
||||
"MerchantId": "1107066208",
|
||||
"CertificateSerialNumber": "",
|
||||
"CertificateSerialNumber": "3243AE8427384A692FBAA92C5EC5887BEF1988FD",
|
||||
"PrivateKeyPath": "",
|
||||
"PrivateKeyPem": "",
|
||||
"NotifyUrl": "",
|
||||
"ApiV3Key": "",
|
||||
"ApiV3Key": "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDMlj1LkO9Cfg3LWBYpe9GBn7vWgLE6kqEG1ohaxbaPxA6OwuGn0XQZfRBbJmncSXGLYahQ7T0OvFBIp8SyYm6q9kol8c9naxd+KxjMrx/qSWqwEJ76meBNK6LBYBVFTobg47cexpyR1TOZK0EFBGJQU2yQ1nsuQczVvq+WaSn4+kVENWf+o2g2nFS1VXNBIjL0/C8vXbz/0Y8k6ecH5mbmy/t+YR6X4TsiIAzIxIcfMMNhVCwqKLsu3D20N0ViYbKToHWIXi8wS8dyruHqQ1lZVJV/fF7pdI36HFI94enksCZrDb1LVFjL+4ccE04MJLIEZSH73RrOFkLaRzn8pwBbAgMBAAECggEAY7kD7baa+XVKMgkg3F2vVJjQzZDzUpKwjQ27b0uaXl95nRrfNZcCGX59n4CM70SZZRBYJAJP1cP",
|
||||
"PlatformPublicKeyPath": "",
|
||||
"PlatformPublicKeyPem": "",
|
||||
"PlatformPublicKeySerial": "",
|
||||
|
||||
Reference in New Issue
Block a user