Add EF Core persistence for charge machine plugin

Introduce ChargeMachineDbContext (SQLite) with ArticleContent and
ChargeHistory entities, plus migrations, and wire it up via
ConfigurePluginServices/OnAppInitialize with startup migration and
article-content seeding.

- ChargeEaChargeHandler now records each charge to ChargeHistory
- GetConfigEaChargeHandler serves article config from the DB instead
  of hardcoded values, and adds multibills/readagreement fields
- GetLastLogEaChargeHandler returns real daily totals and recent
  charge items from history, keyed by session card
- Add GetRecentChargeEaChargeHandler (paginated charge history) and
  OpChPassEaChargeHandler (PIN change)
- Update handlers to the new HandleAsync/primary-constructor style,
  file-scoped namespaces
- Bump EF Core/Identity packages and Abstractions reference to
  net10.0/10.0.10
This commit is contained in:
Kayori
2026-08-09 17:28:14 +02:00
parent c4bcba3b66
commit fa610a9bc6
21 changed files with 641 additions and 154 deletions
@@ -0,0 +1,10 @@
using MedusaPluginChargeMachine.Entities;
using Microsoft.EntityFrameworkCore;
namespace MedusaPluginChargeMachine;
public class ChargeMachineDbContext(DbContextOptions<ChargeMachineDbContext> options) : DbContext(options)
{
public DbSet<ChargeHistory> ChargeHistories { get; set; }
public DbSet<ArticleContent> ArticleContents { get; set; }
}
@@ -0,0 +1,14 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
namespace MedusaPluginChargeMachine;
public class ChargeMachineDbContextFactory : IDesignTimeDbContextFactory<ChargeMachineDbContext>
{
public ChargeMachineDbContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<ChargeMachineDbContext>();
optionsBuilder.UseSqlite("Data Source=database/ChargeMachine.db;");
return new ChargeMachineDbContext(optionsBuilder.Options);
}
}
@@ -1,14 +1,15 @@
using Abstractions;
using Abstractions;
using MedusaPluginChargeMachine.Entities;
using MedusaPluginChargeMachine.Services;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System.Text;
namespace MedusaPluginChargeMachine;
public class ChargeMachinePlugin: IMedusaPlugin
public class ChargeMachinePlugin : IMedusaPlugin
{
public string Name => "Charge Machine";
public string Version => "1.0.0";
public string Description => "Plugin for the paseli charge machine";
@@ -18,15 +19,46 @@ public class ChargeMachinePlugin: IMedusaPlugin
public Encoding? ForcedEncoding => null;
public Delegate DoesProfileExist => () => false;
public Task OnBuilderInitialize(WebApplicationBuilder builder)
public Task OnBuilderInitialize(WebApplicationBuilder builder) => Task.CompletedTask;
public void ConfigurePluginServices(IServiceCollection services)
{
builder.Services.AddSingleton<ISessionService, SessionService>();
return Task.CompletedTask;
services.AddSingleton<ISessionService, SessionService>();
services.AddDbContext<ChargeMachineDbContext>(o =>
o.UseSqlite("Data Source=database/ChargeMachine.db;"));
}
public Task OnAppInitialize(WebApplication app)
public async Task OnAppInitialize(WebApplication app, IServiceProvider pluginServices)
{
return Task.CompletedTask;
await using var scope = pluginServices.CreateAsyncScope();
var db = scope.ServiceProvider.GetRequiredService<ChargeMachineDbContext>();
await db.Database.MigrateAsync();
await SeedArticleContentsAsync(db);
}
}
private static async Task SeedArticleContentsAsync(ChargeMachineDbContext db)
{
if (await db.ArticleContents.AnyAsync())
return;
var defaults = new List<ArticleContent>
{
new() { ArticleType = "DOCMT_0000", ArticleDoc = "" },
new() { ArticleType = "DOCMT_0001", ArticleDoc = "PASELI Charge Machine" },
new() { ArticleType = "DOCMT_0002", ArticleDoc = "" },
new() { ArticleType = "DOCMT_0003", ArticleDoc = "" },
new() { ArticleType = "URL_0001_A", ArticleDoc = "https://localhost:5173/" },
new() { ArticleType = "URL_0001_B", ArticleDoc = "https://localhost:5173/" },
new() { ArticleType = "URL_0002_A", ArticleDoc = "https://localhost:5173/" },
new() { ArticleType = "URL_0002_B", ArticleDoc = "https://localhost:5173/" },
new() { ArticleType = "URL_0003_A", ArticleDoc = "https://localhost:5173/" },
new() { ArticleType = "URL_0003_B", ArticleDoc = "https://localhost:5173/" },
new() { ArticleType = "URL_0004_A", ArticleDoc = "https://localhost:5173/" },
new() { ArticleType = "URL_0041_B", ArticleDoc = "https://localhost:5173/" },
new() { ArticleType = "PASELIUNIT", ArticleDoc = "P" },
};
db.ArticleContents.AddRange(defaults);
await db.SaveChangesAsync();
}
}
@@ -0,0 +1,10 @@
using System.ComponentModel.DataAnnotations;
namespace MedusaPluginChargeMachine.Entities;
public class ArticleContent
{
[Key]
public required string ArticleType { get; set; }
public required string ArticleDoc { get; set; }
}
@@ -0,0 +1,10 @@
namespace MedusaPluginChargeMachine.Entities;
public class ChargeHistory
{
public int Id { get; set; }
public required string CardId { get; set; }
public int ChargeNum { get; set; }
public int ChargeAmount { get; set; }
public DateTime OrderDate { get; set; }
}
@@ -1,44 +1,55 @@
using System.Xml.Linq;
using Abstractions.Entities;
using Abstractions.Entities;
using Abstractions.Handlers;
using Abstractions.SerializationTypes;
using Abstractions.Services;
using MedusaPluginChargeMachine.Entities;
using MedusaPluginChargeMachine.Models.Request;
using MedusaPluginChargeMachine.Models.Response;
using Microsoft.AspNetCore.Identity;
using ISessionService = MedusaPluginChargeMachine.Services.ISessionService;
namespace MedusaPluginChargeMachine.Handlers.LA9
namespace MedusaPluginChargeMachine.Handlers.LA9;
public class ChargeEaChargeHandler(
ICardService cardService,
ISessionService sessionService,
UserManager<User> userManager,
ChargeMachineDbContext db) : Handler<ChargeRequest, ChargeResponse>
{
public class ChargeEaChargeHandler(ICardService cardService, ISessionService sessionService, UserManager<User> userManager): Handler<ChargeRequest, ChargeResponse>
public override void Configure()
{
public override void Configure()
Module("eacharge");
Method("charge");
}
public override async Task<ChargeResponse> HandleAsync(ChargeRequest req, string model)
{
var amount = int.Parse(req.ChargeNumber) * 1000;
var foundSession = sessionService.GetSession(req.SessionId);
var card = await cardService.FindByCardId(foundSession.refId)!;
card!.User.PaseliAmount += amount;
await userManager.UpdateAsync(card.User);
db.ChargeHistories.Add(new ChargeHistory
{
Module("eacharge");
Method("charge");
}
public override async Task<ChargeResponse> HandleAsync(ChargeRequest req, string model)
CardId = foundSession.refId,
ChargeNum = int.Parse(req.ChargeNumber),
ChargeAmount = amount,
OrderDate = DateTime.UtcNow
});
await db.SaveChangesAsync();
return new ChargeResponse
{
var amount = int.Parse(req.ChargeNumber) * 1000;
var foundSession = sessionService.GetSession(req.SessionId);
var card = await cardService.FindByCardId(foundSession.refId)!;
card!.User.PaseliAmount += amount;
await userManager.UpdateAsync(card.User);
var chargeResponse = new ChargeResponse()
{
Status = 0,
Balance = new XrpcInt(card.User.PaseliAmount),
ChargeDailyLimit = new XrpcInt(100000),
ChargeDaily = new XrpcInt(0),
ChargePoint = new XrpcInt(amount)
};
return chargeResponse;
}
Status = 0,
Balance = new XrpcInt(card.User.PaseliAmount),
ChargeDailyLimit = new XrpcInt(100000),
ChargeDaily = new XrpcInt(0),
ChargePoint = new XrpcInt(amount)
};
}
}
@@ -1,108 +1,52 @@
using System.Xml.Linq;
using Abstractions.Handlers;
using Abstractions.SerializationTypes;
using MedusaPluginChargeMachine.Models.Request;
using MedusaPluginChargeMachine.Models.Response;
using Microsoft.EntityFrameworkCore;
namespace MedusaPluginChargeMachine.Handlers.LA9
namespace MedusaPluginChargeMachine.Handlers.LA9;
public class GetConfigEaChargeHandler(ChargeMachineDbContext db) : Handler<EmptyRequest, EaChargeConfigResponse>
{
public class GetConfigEaChargeHandler: HandlerWithoutRequest<EaChargeConfigResponse>
public override void Configure()
{
public override void Configure()
{
Module("eacharge");
Method("getconf");
}
Module("eacharge");
Method("getconf");
}
public override EaChargeConfigResponse Handle(string model)
{
var eaChargeConfig = new EaChargeConfigResponse()
public override async Task<EaChargeConfigResponse> HandleAsync(EmptyRequest _, string model)
{
var articles = await db.ArticleContents.ToListAsync();
var articleList = articles
.Select(a => new EaChargeConfigChargeArticleItem
{
Status = 0,
Expire = 1200,
ChargeArticle = new EaChargeConfigChargeArticle()
{
ArticleRevision = new XrpcString("1"),
ArticleList = [
new EaChargeConfigChargeArticleItem()
{
ArticleType = new XrpcString("DOCMT_0000"),
ArticleDoc = new XrpcString("")
},
new EaChargeConfigChargeArticleItem()
{
ArticleType = new XrpcString("DOCMT_0001"),
ArticleDoc = new XrpcString("")
},
new EaChargeConfigChargeArticleItem()
{
ArticleType = new XrpcString("DOCMT_0002"),
ArticleDoc = new XrpcString("")
},
new EaChargeConfigChargeArticleItem()
{
ArticleType = new XrpcString("DOCMT_0003"),
ArticleDoc = new XrpcString("")
},
new EaChargeConfigChargeArticleItem()
{
ArticleType = new XrpcString("URL_0001_A"),
ArticleDoc = new XrpcString("http://eagate.573.jp")
},
new EaChargeConfigChargeArticleItem()
{
ArticleType = new XrpcString("URL_0001_B"),
ArticleDoc = new XrpcString("http://eagate.573.jp")
},
new EaChargeConfigChargeArticleItem()
{
ArticleType = new XrpcString("URL_0002_A"),
ArticleDoc = new XrpcString("http://eagate.573.jp")
},
new EaChargeConfigChargeArticleItem()
{
ArticleType = new XrpcString("URL_0002_B"),
ArticleDoc = new XrpcString("http://eagate.573.jp")
},
new EaChargeConfigChargeArticleItem()
{
ArticleType = new XrpcString("URL_0003_A"),
ArticleDoc = new XrpcString("http://eagate.573.jp")
},
new EaChargeConfigChargeArticleItem()
{
ArticleType = new XrpcString("URL_0003_B"),
ArticleDoc = new XrpcString("http://eagate.573.jp")
},
new EaChargeConfigChargeArticleItem()
{
ArticleType = new XrpcString("URL_0004_A"),
ArticleDoc = new XrpcString("http://eagate.573.jp")
},
new EaChargeConfigChargeArticleItem()
{
ArticleType = new XrpcString("URL_0041_B"),
ArticleDoc = new XrpcString("http://eagate.573.jp")
},
new EaChargeConfigChargeArticleItem()
{
ArticleType = new XrpcString("PASELIUNIT"),
ArticleDoc = new XrpcString("P")
},
]
},
ChargeDetail = new EaChargeConfigChargeDetail()
{
ChargeDaily = new XrpcInt(0),
ChargeDailyLimit = new XrpcInt(100000)
},
ChargeStatus = new EaChargeConfigChargeStatus()
{
CurrentCode = new XrpcInt(0),
LastChargeStatus = new XrpcInt(1)
}
};
ArticleType = new XrpcString(a.ArticleType),
ArticleDoc = new XrpcString(a.ArticleDoc)
})
.ToList();
return eaChargeConfig;
}
return new EaChargeConfigResponse
{
Status = 0,
Expire = 1200,
MultiBills = new XrpcInt(1),
ReadAgreement = new XrpcInt(0),
ChargeArticle = new EaChargeConfigChargeArticle
{
ArticleRevision = new XrpcString("1"),
ArticleList = articleList
},
ChargeDetail = new EaChargeConfigChargeDetail
{
ChargeDaily = new XrpcInt(0),
ChargeDailyLimit = new XrpcInt(100000)
},
ChargeStatus = new EaChargeConfigChargeStatus
{
CurrentCode = new XrpcInt(0),
LastChargeStatus = new XrpcInt(1)
}
};
}
}
@@ -1,11 +1,14 @@
using System.Xml.Linq;
using Abstractions.Handlers;
using Abstractions.SerializationTypes;
using MedusaPluginChargeMachine.Models.Request;
using MedusaPluginChargeMachine.Models.Response;
using MedusaPluginChargeMachine.Services;
using Microsoft.EntityFrameworkCore;
namespace MedusaPluginChargeMachine.Handlers.LA9;
public class GetLastLogEaChargeHandler : HandlerWithoutRequest<GetLastLogEaChargeResponse>
public class GetLastLogEaChargeHandler(ISessionService sessionService, ChargeMachineDbContext db)
: Handler<GetLastLogRequest, GetLastLogEaChargeResponse>
{
public override void Configure()
{
@@ -13,17 +16,43 @@ public class GetLastLogEaChargeHandler : HandlerWithoutRequest<GetLastLogEaCharg
Method("getlastlog");
}
public override GetLastLogEaChargeResponse Handle(string model)
public override async Task<GetLastLogEaChargeResponse> HandleAsync(GetLastLogRequest req, string model)
{
var getLastLog = new GetLastLogEaChargeResponse()
var today = DateTime.UtcNow.Date;
var cardId = (string?)null;
if (req.SessionId is not null)
{
var session = sessionService.GetSession(req.SessionId);
cardId = session.refId;
}
var query = db.ChargeHistories.AsQueryable();
if (cardId is not null)
query = query.Where(h => h.CardId == cardId);
var todayTotal = await query
.Where(h => h.OrderDate.Date == today)
.SumAsync(h => (int?)h.ChargeAmount) ?? 0;
var recentItems = await query
.OrderByDescending(h => h.OrderDate)
.Take(10)
.ToListAsync();
return new GetLastLogEaChargeResponse
{
Status = 0,
Header = new GetLastLogEaChargeHeader()
Header = new GetLastLogEaChargeHeader
{
Chargedaily = new XrpcInt(0)
Chargedaily = new XrpcInt(todayTotal),
Items = recentItems.Select((h, i) => new GetLastLogChargeItem
{
ChargeId = new XrpcString(h.Id.ToString()),
ChargeNum = new XrpcInt(h.ChargeNum),
ChargeAmount = new XrpcInt(h.ChargeAmount)
}).ToList()
}
};
return getLastLog;
}
}
}
@@ -0,0 +1,74 @@
using Abstractions.Handlers;
using Abstractions.SerializationTypes;
using MedusaPluginChargeMachine.Models.Request;
using MedusaPluginChargeMachine.Models.Response;
using MedusaPluginChargeMachine.Services;
using Microsoft.EntityFrameworkCore;
namespace MedusaPluginChargeMachine.Handlers.LA9;
public class GetRecentChargeEaChargeHandler(ISessionService sessionService, ChargeMachineDbContext db)
: Handler<GetRecentChargeRequest, GetRecentChargeResponse>
{
public override void Configure()
{
Module("eacharge");
Method("getrecentcharge");
}
public override async Task<GetRecentChargeResponse> HandleAsync(GetRecentChargeRequest req, string model)
{
var cardId = ResolveCardId(req);
var page = int.TryParse(req.Page, out var p) ? Math.Max(1, p) : 1;
var perPage = int.TryParse(req.PerPage, out var pp) ? Math.Max(1, pp) : 10;
var query = db.ChargeHistories.AsQueryable();
if (cardId is not null)
query = query.Where(h => h.CardId == cardId);
if (req.TargetDate is not null && DateTime.TryParse(req.TargetDate, out var targetDate))
query = query.Where(h => h.OrderDate.Date == targetDate.Date);
var total = await query.CountAsync();
var rows = await query
.OrderByDescending(h => h.OrderDate)
.Skip((page - 1) * perPage)
.Take(perPage)
.ToListAsync();
var items = rows.Select(h => new GetRecentChargeItem
{
RcvTime = new XrpcString(h.OrderDate.ToString("yyyyMMddHHmmss")),
ChrgPrice = new XrpcInt(h.ChargeAmount),
CardNo = new XrpcString(MaskCardId(h.CardId)),
AccCode = new XrpcString(""),
RcvStatus = new XrpcInt(0),
FontColor = new XrpcString("#FFFFFF")
}).ToList();
return new GetRecentChargeResponse
{
Status = 0,
Num = new XrpcInt(total),
Items = items
};
}
private string? ResolveCardId(GetRecentChargeRequest req)
{
if (req.SessionId is not null)
{
try { return sessionService.GetSession(req.SessionId).refId; }
catch { /* fall through to cardid */ }
}
return req.CardId;
}
private static string MaskCardId(string cardId) =>
cardId.Length <= 4
? new string('*', cardId.Length)
: new string('*', cardId.Length - 4) + cardId[^4..];
}
@@ -0,0 +1,40 @@
using Abstractions.Entities;
using Abstractions.Handlers;
using Abstractions.Services;
using MedusaPluginChargeMachine.Models.Request;
using MedusaPluginChargeMachine.Models.Response;
using MedusaPluginChargeMachine.Services;
using Microsoft.AspNetCore.Identity;
using Abstractions.SerializationTypes;
namespace MedusaPluginChargeMachine.Handlers.LA9;
public class OpChPassEaChargeHandler(
ISessionService sessionService,
ICardService cardService,
UserManager<User> userManager) : Handler<OpChPassRequest, OpChPassResponse>
{
public override void Configure()
{
Module("eacharge");
Method("opchpass");
}
public override async Task<OpChPassResponse> HandleAsync(OpChPassRequest req, string model)
{
var session = sessionService.GetSession(req.SessionId);
var card = await cardService.FindByCardId(session.refId);
if (card is null)
return new OpChPassResponse { Status = 1, Result = new XrpcInt(1) };
var valid = await cardService.ValidatePinAsync(card.KonamiId, req.Passwd);
if (!valid)
return new OpChPassResponse { Status = 1, Result = new XrpcInt(1) };
card.User.Pin = req.NewPasswd;
await userManager.UpdateAsync(card.User);
return new OpChPassResponse { Status = 0, Result = new XrpcInt(0) };
}
}
@@ -4,19 +4,27 @@
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<OutputPath>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName)\</OutputPath>
</PropertyGroup>
<ItemGroup>
<Reference Include="Abstractions">
<HintPath>..\..\Medusa.net\Abstractions\bin\Debug\net9.0\Abstractions.dll</HintPath>
<HintPath>..\..\Medusa.net\Abstractions\bin\Debug\net10.0\Abstractions.dll</HintPath>
<Private>false</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="9.0.6" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.6" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="10.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="10.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.10">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.10" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.10" />
</ItemGroup>
<ItemGroup>
@@ -0,0 +1,63 @@
// <auto-generated />
using System;
using MedusaPluginChargeMachine;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace MedusaPluginChargeMachine.Migrations
{
[DbContext(typeof(ChargeMachineDbContext))]
[Migration("20260809152017_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "10.0.10");
modelBuilder.Entity("MedusaPluginChargeMachine.Entities.ArticleContent", b =>
{
b.Property<string>("ArticleType")
.HasColumnType("TEXT");
b.Property<string>("ArticleDoc")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("ArticleType");
b.ToTable("ArticleContents");
});
modelBuilder.Entity("MedusaPluginChargeMachine.Entities.ChargeHistory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("CardId")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("ChargeAmount")
.HasColumnType("INTEGER");
b.Property<int>("ChargeNum")
.HasColumnType("INTEGER");
b.Property<DateTime>("OrderDate")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("ChargeHistories");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,53 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MedusaPluginChargeMachine.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "ArticleContents",
columns: table => new
{
ArticleType = table.Column<string>(type: "TEXT", nullable: false),
ArticleDoc = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ArticleContents", x => x.ArticleType);
});
migrationBuilder.CreateTable(
name: "ChargeHistories",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
CardId = table.Column<string>(type: "TEXT", nullable: false),
ChargeNum = table.Column<int>(type: "INTEGER", nullable: false),
ChargeAmount = table.Column<int>(type: "INTEGER", nullable: false),
OrderDate = table.Column<DateTime>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ChargeHistories", x => x.Id);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "ArticleContents");
migrationBuilder.DropTable(
name: "ChargeHistories");
}
}
}
@@ -0,0 +1,60 @@
// <auto-generated />
using System;
using MedusaPluginChargeMachine;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace MedusaPluginChargeMachine.Migrations
{
[DbContext(typeof(ChargeMachineDbContext))]
partial class ChargeMachineDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "10.0.10");
modelBuilder.Entity("MedusaPluginChargeMachine.Entities.ArticleContent", b =>
{
b.Property<string>("ArticleType")
.HasColumnType("TEXT");
b.Property<string>("ArticleDoc")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("ArticleType");
b.ToTable("ArticleContents");
});
modelBuilder.Entity("MedusaPluginChargeMachine.Entities.ChargeHistory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("CardId")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("ChargeAmount")
.HasColumnType("INTEGER");
b.Property<int>("ChargeNum")
.HasColumnType("INTEGER");
b.Property<DateTime>("OrderDate")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("ChargeHistories");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,10 @@
using System.Xml.Serialization;
namespace MedusaPluginChargeMachine.Models.Request;
[XmlRoot("eacharge")]
public class GetLastLogRequest
{
[XmlElement("sessid")]
public string? SessionId { get; set; }
}
@@ -0,0 +1,28 @@
using System.Xml.Serialization;
namespace MedusaPluginChargeMachine.Models.Request;
[XmlRoot("eacharge")]
public class GetRecentChargeRequest
{
[XmlElement("sessid")]
public string? SessionId { get; set; }
[XmlElement("cardid")]
public string? CardId { get; set; }
[XmlElement("cardtype")]
public string? CardType { get; set; }
[XmlElement("ectype")]
public string? EcType { get; set; }
[XmlElement("targetdate")]
public string? TargetDate { get; set; }
[XmlElement("perpage")]
public string? PerPage { get; set; }
[XmlElement("page")]
public string? Page { get; set; }
}
@@ -0,0 +1,16 @@
using System.Xml.Serialization;
namespace MedusaPluginChargeMachine.Models.Request;
[XmlRoot("eacharge")]
public class OpChPassRequest
{
[XmlElement("sessid")]
public required string SessionId { get; set; }
[XmlElement("passwd")]
public required string Passwd { get; set; }
[XmlElement("newpasswd")]
public required string NewPasswd { get; set; }
}
@@ -12,7 +12,13 @@ public class EaChargeConfigResponse
[XmlAttribute("expire")]
public required int Expire { get; set; }
[XmlElement("multibills")]
public XrpcInt MultiBills { get; set; }
[XmlElement("readagreement")]
public XrpcInt ReadAgreement { get; set; }
[XmlElement("chargearticle")]
public required EaChargeConfigChargeArticle ChargeArticle { get; set; }
@@ -3,13 +3,13 @@ using Abstractions.SerializationTypes;
namespace MedusaPluginChargeMachine.Models.Response;
[XmlRoot("getlastlog")]
[XmlRoot("eacharge")]
[Serializable]
public class GetLastLogEaChargeResponse
{
[XmlAttribute("status")]
public int Status { get; set; }
[XmlElement("header")]
public required GetLastLogEaChargeHeader Header { get; set; }
}
@@ -18,4 +18,19 @@ public record GetLastLogEaChargeHeader
{
[XmlElement("chargedaily")]
public XrpcInt Chargedaily { get; set; }
[XmlElement("item")]
public List<GetLastLogChargeItem> Items { get; set; } = [];
}
public record GetLastLogChargeItem
{
[XmlElement("chargeid")]
public XrpcString ChargeId { get; set; }
[XmlElement("chargenum")]
public XrpcInt ChargeNum { get; set; }
[XmlElement("chargeamount")]
public XrpcInt ChargeAmount { get; set; }
}
@@ -0,0 +1,39 @@
using System.Xml.Serialization;
using Abstractions.SerializationTypes;
namespace MedusaPluginChargeMachine.Models.Response;
[XmlRoot("eacharge")]
[Serializable]
public class GetRecentChargeResponse
{
[XmlAttribute("status")]
public int Status { get; set; }
[XmlElement("num")]
public XrpcInt Num { get; set; }
[XmlElement("item")]
public List<GetRecentChargeItem> Items { get; set; } = [];
}
public record GetRecentChargeItem
{
[XmlElement("rcvtime")]
public XrpcString RcvTime { get; set; }
[XmlElement("chrgprice")]
public XrpcInt ChrgPrice { get; set; }
[XmlElement("cardno")]
public XrpcString CardNo { get; set; }
[XmlElement("acccode")]
public XrpcString AccCode { get; set; }
[XmlElement("rcvstatus")]
public XrpcInt RcvStatus { get; set; }
[XmlElement("fontcolor")]
public XrpcString FontColor { get; set; }
}
@@ -0,0 +1,15 @@
using System.Xml.Serialization;
using Abstractions.SerializationTypes;
namespace MedusaPluginChargeMachine.Models.Response;
[XmlRoot("eacharge")]
[Serializable]
public class OpChPassResponse
{
[XmlAttribute("status")]
public int Status { get; set; }
[XmlElement("result")]
public XrpcInt Result { get; set; }
}