mirror of
https://gitea.tendokyu.moe/Kayori/MedusaPluginChargeMachine.git
synced 2026-09-30 02:57:57 +03:00
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:
@@ -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>
|
||||
|
||||
+63
@@ -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; }
|
||||
}
|
||||
Reference in New Issue
Block a user