From 5771b1663f8fa3c300b2f60575bd3f03ff71f055 Mon Sep 17 00:00:00 2001 From: "GukSang.Jin" Date: Wed, 22 Apr 2026 08:55:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/PasswordAccessService.cs | 192 ++++++++++-------- 1 file changed, 112 insertions(+), 80 deletions(-) diff --git a/Cardiopulmonarybypasssystems/Services/PasswordAccessService.cs b/Cardiopulmonarybypasssystems/Services/PasswordAccessService.cs index 228a274..f8b91ed 100644 --- a/Cardiopulmonarybypasssystems/Services/PasswordAccessService.cs +++ b/Cardiopulmonarybypasssystems/Services/PasswordAccessService.cs @@ -9,10 +9,10 @@ public sealed class PasswordAccessService : IPasswordAccessService private const int ExpirationReminderDays = 3; private const string SettingsDirectoryName = "Cardiopulmonarybypasssystems"; private const string StatusFileName = "password-access.json"; - public const string FirstStagePassword = "152026"; - public const string SecondStagePassword = "302026"; - private const int FirstStageDays = 15; - private const int SecondStageDays = 30; + public const string FirstStagePassword = "152026001"; + public const string SecondStagePassword = "302026002"; + private const int InitialAccessDays = 20; + private const int ExtendedAccessDays = 30; private static readonly string StatusFilePath = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @@ -21,14 +21,14 @@ public sealed class PasswordAccessService : IPasswordAccessService public PasswordAccessStatus GetStatus() { - var state = LoadState(); + var state = LoadOrCreateState(); return BuildStatus(state, persistState: true); } public bool TryUnlock(string password, out PasswordAccessStatus status, out string message) { var normalizedPassword = password?.Trim() ?? string.Empty; - var state = LoadState(); + var state = LoadOrCreateState(); var currentStatus = BuildStatus(state, persistState: true); if (currentStatus.IsPermanent) @@ -38,82 +38,81 @@ public sealed class PasswordAccessService : IPasswordAccessService return true; } - if (currentStatus.Stage == 1 && currentStatus.CanLaunch) + if (currentStatus.CanLaunch) { status = currentStatus; - message = "第 1 阶段仍在有效期内,无需再次输入密码。"; - return true; + message = currentStatus.ShouldPromptAtStartup + ? $"当前仍在有效期内,可直接进入系统;满 {GetStageDays(currentStatus.Stage)} 天后再输入密码。" + : $"{GetStageName(currentStatus.Stage)}仍在有效期内,无需再次输入密码。"; + return false; } - if (currentStatus.Stage == 2 && currentStatus.CanLaunch) + var expectedPassword = currentStatus.Stage switch { - status = currentStatus; - message = "第 2 阶段仍在有效期内,无需再次输入密码。"; - return true; - } - - var nextStage = currentStatus.Stage switch - { - <= 0 => 1, - 1 => 2, - _ => 0 + 0 => FirstStagePassword, + 1 => SecondStagePassword, + _ => string.Empty }; - if (nextStage == 0) - { - status = BuildStatus(state, persistState: true); - message = "当前版本已转为永久有效,不再需要密码。"; - return true; - } - - var expectedPassword = nextStage == 1 ? FirstStagePassword : SecondStagePassword; if (!string.Equals(normalizedPassword, expectedPassword, StringComparison.Ordinal)) { status = currentStatus; - message = $"密码错误,请输入第 {nextStage} 次时效密码。"; + message = currentStatus.Stage switch + { + 0 => "密码错误,请输入第 1 次时效密码。", + 1 => "密码错误,请输入第 2 次时效密码。", + _ => "密码错误。" + }; return false; } var now = DateTime.Now; - var expiresAt = now.AddDays(nextStage == 1 ? FirstStageDays : SecondStageDays); + + if (currentStatus.Stage == 1) + { + var permanentState = new PasswordAccessState + { + Stage = 2, + ActivatedAt = state?.ActivatedAt ?? now, + ExpiresAt = null + }; + + SaveState(permanentState); + status = BuildStatus(permanentState, persistState: false); + message = "第 2 次密码验证通过,系统已永久有效。"; + return true; + } + + var expiresAt = now.AddDays(ExtendedAccessDays); var nextState = new PasswordAccessState { - Stage = nextStage, + Stage = 1, ActivatedAt = now, ExpiresAt = expiresAt }; SaveState(nextState); status = BuildStatus(nextState, persistState: false); - message = nextStage == 1 - ? $"第 1 次时效已生效,有效期至 {expiresAt:yyyy-MM-dd HH:mm}。" - : $"第 2 次时效已生效,有效期至 {expiresAt:yyyy-MM-dd HH:mm};到期后自动转为永久有效。"; + message = $"第 1 次密码验证通过,已继续开放 {ExtendedAccessDays} 天,有效期至 {expiresAt:yyyy-MM-dd HH:mm}。"; return true; } private static PasswordAccessStatus BuildStatus(PasswordAccessState? state, bool persistState) { - if (state is null || state.Stage <= 0) + if (state is null) { - return new PasswordAccessStatus + state = CreateInitialState(); + if (persistState) { - Stage = 0, - CanLaunch = false, - IsPermanent = false, - ShouldPromptAtStartup = true, - CanSubmitPassword = true, - StageText = "当前阶段:未开始", - StatusTitle = "需要输入第 1 次时效密码", - StatusDetail = $"输入 15 天密码后进入系统。", - RemainingDays = 0 - }; + SaveState(state); + } } - if (state.Stage >= 3) + if (state.Stage >= 2) { return new PasswordAccessStatus { - Stage = 3, + Stage = 2, CanLaunch = true, IsPermanent = true, ShouldPromptAtStartup = false, @@ -129,63 +128,96 @@ public sealed class PasswordAccessService : IPasswordAccessService if (state.ExpiresAt > now) { var remainingDays = Math.Max(1, (int)Math.Ceiling((state.ExpiresAt.Value - now).TotalDays)); + var isReminderWindow = remainingDays <= ExpirationReminderDays; + var isInitialStage = state.Stage == 0; return new PasswordAccessStatus { Stage = state.Stage, CanLaunch = true, IsPermanent = false, - ShouldPromptAtStartup = state.Stage == 1 && remainingDays <= ExpirationReminderDays, - CanSubmitPassword = state.Stage == 1 && remainingDays <= ExpirationReminderDays, - StageText = state.Stage == 1 ? "当前阶段:第 1 次时效(15 天)" : "当前阶段:第 2 次时效(30 天)", - StatusTitle = state.Stage == 1 && remainingDays <= ExpirationReminderDays ? "第 1 次时效即将到期" : "时效有效", - StatusDetail = state.Stage == 1 && remainingDays <= ExpirationReminderDays - ? $"剩余 {remainingDays} 天,可提前输入 30 天密码。" + ShouldPromptAtStartup = isReminderWindow, + CanSubmitPassword = false, + StageText = isInitialStage ? $"当前阶段:首次使用({InitialAccessDays} 天)" : $"当前阶段:第 1 次续期({ExtendedAccessDays} 天)", + StatusTitle = isReminderWindow + ? isInitialStage ? "首次使用即将到期" : "第 1 次续期即将到期" + : "时效有效", + StatusDetail = isReminderWindow + ? isInitialStage + ? $"剩余 {remainingDays} 天,到期后需输入第 1 次时效密码。" + : $"剩余 {remainingDays} 天,到期后需输入第 2 次时效密码。" : $"当前可直接进入系统。", RemainingDays = remainingDays, ExpiresAt = state.ExpiresAt }; } - if (state.Stage == 1) + if (state.Stage == 0) { return new PasswordAccessStatus { - Stage = 1, + Stage = 0, CanLaunch = false, IsPermanent = false, ShouldPromptAtStartup = true, CanSubmitPassword = true, - StageText = "当前阶段:第 1 次时效已到期", - StatusTitle = "需要输入第 2 次时效密码", - StatusDetail = $"输入 30 天密码后继续使用。", + StageText = "当前阶段:首次使用已到期", + StatusTitle = "需要输入第 1 次时效密码", + StatusDetail = $"输入密码后继续使用 {ExtendedAccessDays} 天。", RemainingDays = 0, ExpiresAt = state.ExpiresAt }; } - var permanentState = new PasswordAccessState - { - Stage = 3, - ActivatedAt = state.ActivatedAt, - ExpiresAt = null - }; - - if (persistState) - { - SaveState(permanentState); - } - return new PasswordAccessStatus { - Stage = 3, - CanLaunch = true, - IsPermanent = true, - ShouldPromptAtStartup = false, - CanSubmitPassword = false, - StageText = "当前阶段:永久有效", - StatusTitle = "系统已永久有效", - StatusDetail = "当前可直接进入系统。", - RemainingDays = int.MaxValue + Stage = 1, + CanLaunch = false, + IsPermanent = false, + ShouldPromptAtStartup = true, + CanSubmitPassword = true, + StageText = "当前阶段:第 1 次续期已到期", + StatusTitle = "需要输入第 2 次时效密码", + StatusDetail = "输入密码后系统转为永久有效。", + RemainingDays = 0, + ExpiresAt = state.ExpiresAt + }; + } + + private static int GetStageDays(int stage) => stage switch + { + 0 => InitialAccessDays, + 1 => ExtendedAccessDays, + _ => 0 + }; + + private static string GetStageName(int stage) => stage switch + { + 0 => "首次使用阶段", + 1 => "第 1 次续期阶段", + _ => "当前阶段" + }; + + private static PasswordAccessState LoadOrCreateState() + { + var state = LoadState(); + if (state is not null) + { + return state; + } + + var initialState = CreateInitialState(); + SaveState(initialState); + return initialState; + } + + private static PasswordAccessState CreateInitialState() + { + var now = DateTime.Now; + return new PasswordAccessState + { + Stage = 0, + ActivatedAt = now, + ExpiresAt = now.AddDays(InitialAccessDays) }; }