Files
thinkyu/報到系統客戶端/ClientSession.cs
T
sryang 577060bc78 chore: 首次簽入 Thinkyu ASP.NET 專案
- 加入 Visual Studio / ASP.NET .gitignore
- 排除建置輸出、IDE 設定、NuGet packages、大型 MSI 安裝檔
2026-09-10 09:42:37 +08:00

301 lines
8.8 KiB
C#

using System;
using System.Windows.Forms;
using 報到系統客戶端.Data.Repositories;
using 報到系統客戶端.Models;
using 報到系統客戶端.Services;
namespace 報到系統客戶端
{
/// <summary>
/// Session 狀態改變事件委派
/// </summary>
public delegate void OnModeChangeEventHandler(object sender, ModeChangeEventArgs e);
/// <summary>
/// Session 狀態改變事件參數
/// </summary>
public class ModeChangeEventArgs : EventArgs
{
public bool OnlineMode { get; set; }
public string UserID { get; set; }
public string UserName { get; set; }
public DateTime ChangeTime { get; set; }
}
/// <summary>
/// 客戶端 Session 管理
/// 使用新的 ApiService 進行 API 呼叫
/// </summary>
public class ClientSession
{
private static ClientSession instance = null;
private static readonly object lockObject = new object();
private string userID = string.Empty;
private string userName = string.Empty;
private bool onlineMode = false;
private DateTime loginTime = DateTime.MinValue;
/// <summary>
/// Session 狀態改變事件
/// </summary>
public static event OnModeChangeEventHandler OnModeChange;
private ClientSession()
{
}
private static void InitInstance()
{
if (instance == null)
{
lock (lockObject)
{
if (instance == null)
instance = new ClientSession();
}
}
}
/// <summary>
/// 觸發 Session 狀態改變事件
/// </summary>
private static void RaiseModeChangeEvent()
{
OnModeChange?.Invoke(null, new ModeChangeEventArgs
{
OnlineMode = instance.onlineMode,
UserID = instance.userID,
UserName = instance.userName,
ChangeTime = DateTime.Now
});
}
/// <summary>
/// 程式版本號
/// </summary>
public static string Version
{
get
{
var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
return string.Format("版本 {0}.{1}.{2}", version.Major, version.Minor, version.Build);
// Build: 8
// Major: 2026
// MajorRevision: 0
// Minor: 2
// MinorRevision: 0
// Revision: 0
}
}
/// <summary>
/// 取得目前登入的使用者ID
/// </summary>
public static string UserID
{
get
{
InitInstance();
return instance.userID;
}
}
/// <summary>
/// 取得目前登入的使用者名稱
/// </summary>
public static string UserName
{
get
{
InitInstance();
return instance.userName;
}
}
/// <summary>
/// 取得是否為連線模式
/// </summary>
public static bool OnlineMode
{
get
{
InitInstance();
return instance.onlineMode;
}
}
/// <summary>
/// 取得登入時間
/// </summary>
public static DateTime LoginTime
{
get
{
InitInstance();
return instance.loginTime;
}
}
/// <summary>
/// 設定登入資訊
/// </summary>
internal static void SetLoginInfo(string userID, string userName, bool onLineMode)
{
InitInstance();
instance.userID = userID;
instance.userName = userName;
instance.onlineMode = onLineMode;
instance.loginTime = DateTime.Now;
RaiseModeChangeEvent();
}
/// <summary>
/// 檢查是否已登入,若未登入則導向登入畫面
/// </summary>
public static void CheckLogin()
{
InitInstance();
BaseResponse response = LoginService.CheckSession();
if (!response.Success)
{
ShowLoginForm();
}
}
/// <summary>
/// 進行心跳檢測
/// </summary>
public static void HeartBeat()
{
InitInstance();
LoginService.CheckSession();
}
/// <summary>
/// 進行通訊測試
/// </summary>
public static bool Ping()
{
InitInstance();
return LoginService.Ping();
}
/// <summary>
/// 執行登入(非同步版本)
/// </summary>
public static async System.Threading.Tasks.Task<(bool, string)> LoginAsync(string username, string password)
{
BaseResponse response = await LoginService.LoginAsync(username, password);
if (response.Success)
{
try
{
// 解析登入回應資料
dynamic data = response.Data;
string returnedUserID = data?.UserID ?? username;
string returnedUsername = data?.UserName ?? username;
SetLoginInfo(returnedUserID, returnedUsername, true);
return (true, string.Empty);
}
catch (Exception ex)
{
SetLoginInfo(string.Empty, string.Empty, false);
return (false, string.Format("登入錯誤:{0}", ex.Message));
}
}
return (false, response.Message);
}
/// <summary>
/// 執行登入(同步版本)
/// </summary>
public static bool Login(string username, string password, out string message)
{
message = string.Empty;
BaseResponse response = LoginService.Login(username, password);
if (response.Success)
{
try
{
// 解析登入回應資料
dynamic data = response.Data;
string returnedUserID = data?.UserID ?? username;
string returnedUsername = data?.UserName ?? username;
SetLoginInfo(returnedUserID, returnedUsername, true);
return true;
}
catch (Exception ex)
{
SetLoginInfo(string.Empty, string.Empty, false);
message = string.Format("登入錯誤:{0}", ex.Message);
return false;
}
}
message = response.Message;
return false;
}
/// <summary>
/// 執行登出
/// </summary>
public static void Logout()
{
InitInstance();
LoginService.Logout();
LoginService.ClearSession();
instance.userID = string.Empty;
instance.userName = string.Empty;
instance.onlineMode = false;
instance.loginTime = DateTime.MinValue;
RaiseModeChangeEvent();
}
/// <summary>
/// 顯示登入表單
/// </summary>
public static void ShowLoginForm()
{
var loginForm = new LoginForm();
if (loginForm.ShowDialog() == DialogResult.Cancel)
{
Application.Exit();
}
}
public static (bool, string) LoginOffline(string bpeno)
{
try
{
BPSNRepository bpsnRepo = new BPSNRepository();
var bpsn = bpsnRepo.GetByBPENO(bpeno);
if (bpsn == null)
{
return (false, "登入帳號錯誤");
}
SetLoginInfo(bpsn.BPENO, bpsn.BPNME, false);
// 離線模式不驗證密碼
// string combined = bpsn.BPENO + password;
// using (SHA1 sha1 = SHA1.Create())
// {
// byte[] hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(combined));
// if (string.Compare(bpsn.BPAWD, Convert.ToBase64String(hash)) != 0)
// {
// return (false, "帳號或密碼錯誤");
// }
// }
return (true, string.Empty);
}
catch (Exception ex)
{
SetLoginInfo(string.Empty, string.Empty, false);
return (false, string.Format("登入錯誤:{0}", ex.Message));
}
}
}
}