chore: 首次簽入 Thinkyu ASP.NET 專案

- 加入 Visual Studio / ASP.NET .gitignore
- 排除建置輸出、IDE 設定、NuGet packages、大型 MSI 安裝檔
This commit is contained in:
2026-09-10 09:42:37 +08:00
commit 577060bc78
2496 changed files with 501389 additions and 0 deletions
@@ -0,0 +1,328 @@
using Newtonsoft.Json;
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using .Models;
namespace .Services
{
/// <summary>
/// API 服務基礎類別
/// 處理 HTTP 請求、Session cookie、錯誤處理
/// </summary>
public class ApiService
{
private static ApiService _instance;
private static readonly object _lockObject = new object();
private string _baseUrl;
private CookieContainer _cookieContainer;
// 用於儲存 cookie 的檔案路徑
private string _cookiePath;
public static JsonSerializerSettings jsonConvertSettings = new JsonSerializerSettings { DateTimeZoneHandling = DateTimeZoneHandling.Local };
public static object DeserializeObject(string value)
{
return JsonConvert.DeserializeObject(value, jsonConvertSettings);
}
public static T DeserializeObject<T>(string value)
{
return (T)JsonConvert.DeserializeObject(value, typeof(T), jsonConvertSettings);
}
/// <summary>
/// 取得單例實例
/// </summary>
public static ApiService Instance
{
get
{
if (_instance == null)
{
lock (_lockObject)
{
if (_instance == null)
{
_instance = new ApiService();
}
}
}
return _instance;
}
}
private ApiService()
{
// 從設定檔讀取基底 URL
_baseUrl = ConfigService.Instance.GetApiBaseUrl();
if (string.IsNullOrWhiteSpace(_baseUrl))
{
_baseUrl = "http://localhost:58792";
}
// 初始化 Cookie 容器
_cookieContainer = new CookieContainer();
_cookiePath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"報到系統客戶端",
"cookies.txt"
);
// 嘗試載入已儲存的 Cookie
LoadCookies();
}
/// <summary>
/// 設定基底 URL
/// </summary>
public string BaseUrl
{
set
{
_baseUrl = value;
}
get
{
return _baseUrl;
}
}
/// <summary>
/// 執行 POST 請求
/// </summary>
public async Task<BaseResponse> PostAsync(string servicePath, string methodName, object parameters)
{
try
{
string url = $"{_baseUrl}{servicePath}/{methodName}";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/json; charset=utf-8";
request.CookieContainer = _cookieContainer;
request.KeepAlive = true;
// 序列化參數
string jsonData = JsonConvert.SerializeObject(parameters ?? new { });
// 寫入請求體
byte[] data = Encoding.UTF8.GetBytes(jsonData);
request.ContentLength = data.Length;
using (Stream requestStream = request.GetRequestStream())
{
await requestStream.WriteAsync(data, 0, data.Length);
}
// 取得回應
using (HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync())
{
// 更新 Cookie(用於 Session 管理)
_cookieContainer.Add(response.ResponseUri, response.Cookies);
SaveCookies();
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
string responseJson = await reader.ReadToEndAsync();
// 解析回應
dynamic result = DeserializeObject(responseJson);
// ASP.NET Web Service 會將結果包在 "d" 屬性中
if (result.d != null)
{
string dataJson = JsonConvert.SerializeObject(result.d);
return DeserializeObject<BaseResponse>(dataJson);
}
else
{
return DeserializeObject<BaseResponse>(responseJson);
}
}
}
}
catch (WebException ex)
{
return new BaseResponse
{
Success = false,
Message = $"網路錯誤: {ex.Message}"
};
}
catch (Exception ex)
{
return new BaseResponse
{
Success = false,
Message = $"錯誤: {ex.Message}"
};
}
}
/// <summary>
/// 同步版本的 POST 請求(用於向後相容)
/// </summary>
public BaseResponse Post(string servicePath, string methodName, object parameters)
{
try
{
string url = $"{_baseUrl}{servicePath}/{methodName}";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/json; charset=utf-8";
request.CookieContainer = _cookieContainer;
request.KeepAlive = true;
// 序列化參數
string jsonData = JsonConvert.SerializeObject(parameters ?? new { });
// 寫入請求體
byte[] data = Encoding.UTF8.GetBytes(jsonData);
request.ContentLength = data.Length;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(data, 0, data.Length);
}
// 取得回應
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
// 更新 Cookie(用於 Session 管理)
_cookieContainer.Add(response.ResponseUri, response.Cookies);
SaveCookies();
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
string responseJson = reader.ReadToEnd();
// 解析回應
dynamic result = DeserializeObject(responseJson);
// ASP.NET Web Service 會將結果包在 "d" 屬性中
if (result.d != null)
{
string dataJson = JsonConvert.SerializeObject(result.d);
return DeserializeObject<BaseResponse>(dataJson);
}
else
{
return DeserializeObject<BaseResponse>(responseJson);
}
}
}
}
catch (WebException ex)
{
return new BaseResponse
{
Success = false,
Message = $"網路錯誤: {ex.Message}"
};
}
catch (Exception ex)
{
return new BaseResponse
{
Success = false,
Message = $"錯誤: {ex.Message}"
};
}
}
/// <summary>
/// 清除所有 Session cookie
/// </summary>
public void ClearSession()
{
_cookieContainer = new CookieContainer();
DeleteCookies();
}
/// <summary>
/// 儲存 Cookie 到檔案
/// </summary>
private void SaveCookies()
{
try
{
string directory = Path.GetDirectoryName(_cookiePath);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
using (StreamWriter sw = new StreamWriter(_cookiePath, false, Encoding.UTF8))
{
foreach (Cookie cookie in _cookieContainer.GetCookies(new Uri(_baseUrl)))
{
sw.WriteLine($"{cookie.Name}={cookie.Value}");
}
}
}
catch
{
// 忽略儲存錯誤
}
}
/// <summary>
/// 從檔案載入 Cookie
/// </summary>
private void LoadCookies()
{
try
{
if (File.Exists(_cookiePath))
{
using (StreamReader sr = new StreamReader(_cookiePath, Encoding.UTF8))
{
string line;
while ((line = sr.ReadLine()) != null)
{
if (string.IsNullOrWhiteSpace(line)) continue;
string[] parts = line.Split(new[] { '=' }, 2);
if (parts.Length == 2)
{
Cookie cookie = new Cookie(parts[0], parts[1])
{
Path = "/",
HttpOnly = true
};
_cookieContainer.Add(new Uri(_baseUrl), cookie);
}
}
}
}
}
catch
{
// 忽略載入錯誤
}
}
/// <summary>
/// 刪除儲存的 Cookie 檔案
/// </summary>
private void DeleteCookies()
{
try
{
if (File.Exists(_cookiePath))
{
File.Delete(_cookiePath);
}
}
catch
{
// 忽略刪除錯誤
}
}
}
}
@@ -0,0 +1,32 @@
using System;
using System.Threading.Tasks;
using .Models;
namespace .Services
{
/// <summary>
/// 員工資料服務客戶端
/// 呼叫後端 Services/BPSNService.asmx
/// </summary>
public class BPSNService
{
private const string SERVICE_PATH = "/Services/BPSNService.asmx";
/// <summary>
/// 下載員工資料
/// </summary>
/// <returns>下載結果,包含員工資料清單</returns>
public static BaseResponse Download()
{
return ApiService.Instance.Post(SERVICE_PATH, "Download", null);
}
/// <summary>
/// 下載員工資料(非同步版本)
/// </summary>
//public static async Task<BaseResponse> DownloadAsync()
//{
// return await ApiService.Instance.PostAsync(SERVICE_PATH, "Download", null);
//}
}
}
@@ -0,0 +1,66 @@
using System;
using System.Threading.Tasks;
using .Models;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ToolTip;
namespace .Services
{
/// <summary>
/// 活動服務客戶端
/// 呼叫後端 Services/ClassesService.asmx
/// </summary>
public class ClassesService
{
private const string SERVICE_PATH = "/Services/ClassesService.asmx";
/// <summary>
/// 搜尋活動清單
/// </summary>
/// <param name="pageIndex">頁碼(從 1 開始)</param>
/// <param name="pageSize">每頁筆數</param>
/// <param name="courseCode">活動代碼</param>
/// <param name="courseName">活動名稱</param>
/// <param name="courseDate1">活動開始日期</param>
/// <param name="courseDate2">活動結束日期</param>
/// <param name="courseLocation">活動地點</param>
/// <returns>搜尋結果</returns>
public static BaseResponse SearchClasses()
{
var parameters = new
{
pageIndex = 1,
pageSize = Int32.MaxValue,
courseCode = string.Empty,
courseName = string.Empty,
courseDate1 = new DateTime?(),
courseDate2 = new DateTime?(),
courseLocation = string.Empty,
projectID = string.Empty,
closed = false
};
return ApiService.Instance.Post(SERVICE_PATH, "SearchClasses", parameters);
}
/// <summary>
/// 搜尋活動清單(非同步版本)
/// </summary>
//public static async Task<BaseResponse> SearchClassesAsync()
//{
// var parameters = new
// {
// pageIndex = 1,
// pageSize = Int32.MaxValue,
// courseCode = string.Empty,
// courseName = string.Empty,
// courseDate1 = new DateTime?(),
// courseDate2 = new DateTime?(),
// courseLocation = string.Empty,
// projectID = string.Empty,
// closed = false
// };
// return await ApiService.Instance.PostAsync(SERVICE_PATH, "SearchClasses", parameters);
//}
}
}
@@ -0,0 +1,254 @@
using System;
using System.Configuration;
using System.IO;
using System.Xml;
namespace .Services
{
/// <summary>
/// 系統設定管理服務
/// 提供讀取和寫入應用程式設定的功能
/// 設定檔存儲在用戶的 AppData 資料夾中,以避免 Program Files 權限問題
/// </summary>
public class ConfigService
{
private static ConfigService _instance;
private static readonly object _lockObject = new object();
private string _userConfigPath;
private string _defaultConfigPath;
/// <summary>
/// 取得 ConfigService 的單一實例
/// </summary>
public static ConfigService Instance
{
get
{
if (_instance == null)
{
lock (_lockObject)
{
if (_instance == null)
{
_instance = new ConfigService();
}
}
}
return _instance;
}
}
private ConfigService()
{
_defaultConfigPath = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
// 用戶設定檔存儲在 AppData\Roaming\報到系統客戶端 資料夾
string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string configDirectory = Path.Combine(appDataPath, "報到系統客戶端");
// 確保目錄存在
if (!Directory.Exists(configDirectory))
{
Directory.CreateDirectory(configDirectory);
}
_userConfigPath = Path.Combine(configDirectory, "AppSettings.config");
// 如果用戶設定檔不存在,從預設設定檔複製
if (!File.Exists(_userConfigPath))
{
InitializeUserConfig();
}
}
/// <summary>
/// 初始化用戶設定檔
/// 從預設設定檔複製所需的設定項目
/// </summary>
private void InitializeUserConfig()
{
try
{
XmlDocument defaultDoc = new XmlDocument();
defaultDoc.Load(_defaultConfigPath);
XmlDocument userDoc = new XmlDocument();
// 建立新的設定檔結構
XmlDeclaration declaration = userDoc.CreateXmlDeclaration("1.0", "utf-8", null);
userDoc.AppendChild(declaration);
XmlElement configElement = userDoc.CreateElement("configuration");
userDoc.AppendChild(configElement);
// 建立 applicationSettings 節點
XmlElement appSettingsNode = userDoc.CreateElement("applicationSettings");
configElement.AppendChild(appSettingsNode);
// 建立報到系統客戶端.Properties.Settings 節點
XmlElement settingsNode = userDoc.CreateElement("報到系統客戶端.Properties.Settings");
appSettingsNode.AppendChild(settingsNode);
// 建立 ApiBaseUrl 設定項目
XmlElement settingElement = userDoc.CreateElement("setting");
settingElement.SetAttribute("name", "ApiBaseUrl");
settingElement.SetAttribute("serializeAs", "String");
XmlElement valueElement = userDoc.CreateElement("value");
valueElement.InnerText = "https://thinkyustaff.com/event";
settingElement.AppendChild(valueElement);
settingsNode.AppendChild(settingElement);
userDoc.Save(_userConfigPath);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"初始化用戶設定檔失敗: {ex.Message}");
}
}
/// <summary>
/// 讀取 API 基礎 URL
/// </summary>
/// <returns>API 基礎 URL</returns>
public string GetApiBaseUrl()
{
try
{
if (File.Exists(_userConfigPath))
{
XmlDocument doc = new XmlDocument();
doc.Load(_userConfigPath);
XmlNode valueNode = doc.SelectSingleNode(
"/configuration/applicationSettings/報到系統客戶端.Properties.Settings/setting[@name='ApiBaseUrl']/value"
);
if (valueNode != null && !string.IsNullOrWhiteSpace(valueNode.InnerText))
{
return valueNode.InnerText;
}
}
// 回退到預設值或 App.config
return Properties.Settings.Default.ApiBaseUrl ?? "https://thinkyustaff.com/event";
}
catch
{
return "https://thinkyustaff.com/event";
}
}
/// <summary>
/// 設定 API 基礎 URL
/// </summary>
/// <param name="baseUrl">新的 API 基礎 URL</param>
/// <returns>是否設定成功</returns>
public bool SetApiBaseUrl(string baseUrl)
{
if (string.IsNullOrWhiteSpace(baseUrl))
{
return false;
}
try
{
// 確保用戶設定檔存在
if (!File.Exists(_userConfigPath))
{
InitializeUserConfig();
}
XmlDocument doc = new XmlDocument();
doc.Load(_userConfigPath);
// 找到或建立 applicationSettings 節點
XmlNode appSettingsNode = doc.SelectSingleNode("//applicationSettings");
if (appSettingsNode == null)
{
XmlNode configNode = doc.SelectSingleNode("//configuration");
if (configNode == null)
{
return false;
}
appSettingsNode = doc.CreateElement("applicationSettings");
configNode.AppendChild(appSettingsNode);
}
// 找到或建立 報到系統客戶端.Properties.Settings 節點
XmlNode settingsNode = appSettingsNode.SelectSingleNode("報到系統客戶端.Properties.Settings");
if (settingsNode == null)
{
settingsNode = doc.CreateElement("報到系統客戶端.Properties.Settings");
appSettingsNode.AppendChild(settingsNode);
}
// 找到 ApiBaseUrl 設定項目
XmlNode apiBaseUrlNode = settingsNode.SelectSingleNode("setting[@name='ApiBaseUrl']");
if (apiBaseUrlNode == null)
{
apiBaseUrlNode = doc.CreateElement("setting");
apiBaseUrlNode.Attributes.Append(doc.CreateAttribute("name"));
apiBaseUrlNode.Attributes["name"].Value = "ApiBaseUrl";
apiBaseUrlNode.Attributes.Append(doc.CreateAttribute("serializeAs"));
apiBaseUrlNode.Attributes["serializeAs"].Value = "String";
settingsNode.AppendChild(apiBaseUrlNode);
}
// 更新值
XmlNode valueNode = apiBaseUrlNode.SelectSingleNode("value");
if (valueNode != null)
{
valueNode.InnerText = baseUrl;
}
else
{
// 如果沒有 value 節點,則建立一個
valueNode = doc.CreateElement("value");
valueNode.InnerText = baseUrl;
apiBaseUrlNode.AppendChild(valueNode);
}
// 保存設定檔到用戶的 AppData 資料夾
doc.Save(_userConfigPath);
// 刷新設定以更新記憶體中的值
RefreshSettings();
return true;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"設定 ApiBaseUrl 失敗: {ex.Message}");
return false;
}
}
/// <summary>
/// 刷新設定值
/// </summary>
private void RefreshSettings()
{
try
{
Properties.Settings.Default.Reload();
}
catch
{
// 刷新失敗時不執行任何操作
}
}
/// <summary>
/// 取得應用程式設定檔路徑
/// 返回用戶設定檔的路徑(位於 AppData 中)
/// </summary>
/// <returns>設定檔路徑</returns>
//public string GetConfigFilePath()
//{
// return _userConfigPath;
//}
}
}
@@ -0,0 +1,101 @@
using System;
using System.Threading.Tasks;
using .Models;
namespace .Services
{
/// <summary>
/// 登入服務客戶端
/// 呼叫後端 Services/LoginService.asmx
/// </summary>
public class LoginService
{
private const string SERVICE_PATH = "/Services/LoginService.asmx";
/// <summary>
/// 登入
/// </summary>
/// <param name="username">使用者名稱</param>
/// <param name="password">密碼</param>
/// <param name="rememberMe">是否記住密碼</param>
/// <returns>登入結果</returns>
public static BaseResponse Login(string username, string password, bool rememberMe = false)
{
var parameters = new
{
username = username,
password = password,
rememberMe = rememberMe
};
return ApiService.Instance.Post(SERVICE_PATH, "Login", parameters);
}
/// <summary>
/// 登入(非同步版本)
/// </summary>
public static async Task<BaseResponse> LoginAsync(string username, string password, bool rememberMe = false)
{
var parameters = new
{
username = username,
password = password,
rememberMe = rememberMe
};
return await ApiService.Instance.PostAsync(SERVICE_PATH, "Login", parameters);
}
/// <summary>
/// 登出
/// </summary>
/// <returns>登出結果</returns>
public static BaseResponse Logout()
{
return ApiService.Instance.Post(SERVICE_PATH, "Logout", null);
}
/// <summary>
/// 登出(非同步版本)
/// </summary>
//public static async Task<BaseResponse> LogoutAsync()
//{
// return await ApiService.Instance.PostAsync(SERVICE_PATH, "Logout", null);
//}
/// <summary>
/// 檢查 Session(當作心跳使用)
/// </summary>
/// <returns>檢查結果</returns>
public static BaseResponse CheckSession()
{
return ApiService.Instance.Post(SERVICE_PATH, "CheckSession", null);
}
/// <summary>
/// 檢查 Session(非同步版本)
/// </summary>
//public static async Task<BaseResponse> CheckSessionAsync()
//{
// return await ApiService.Instance.PostAsync(SERVICE_PATH, "CheckSession", null);
//}
/// <summary>
/// 清除 Session
/// </summary>
public static void ClearSession()
{
ApiService.Instance.ClearSession();
}
/// <summary>
/// 測試是否能連線
/// </summary>
/// <returns></returns>
public static bool Ping()
{
var pingResult = ApiService.Instance.Post(SERVICE_PATH, "Ping", null);
return pingResult != null;
}
}
}
@@ -0,0 +1,57 @@
using System;
using System.IO;
using System.Media;
namespace .Services
{
/// <summary>
/// 通知音效服務,密集呼叫時會中斷先前的播放再重新播放。
/// </summary>
public static class NotificationSoundService
{
private static readonly string _dingWavePath =
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Sound\\ding.wav");
private static readonly string _checkinWavePath =
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Sound\\CheckinOK.wav");
private static readonly string _checkoutWavePath =
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Sound\\CheckoutOK.wav");
private static SoundPlayer _dingPlayer;
private static SoundPlayer _checkinPlayer;
private static SoundPlayer _checkoutPlayer;
private static void StopAll()
{
_dingPlayer?.Stop();
_checkinPlayer?.Stop();
_checkoutPlayer?.Stop();
}
private static void PlaySound(string path, ref SoundPlayer player)
{
if (!File.Exists(path))
return;
if (player == null)
player = new SoundPlayer(path);
StopAll();
player.Play();
}
/// <summary>
/// 播放 ding.wav;若有其他音效正在播放,先全部停止再播放。
/// </summary>
public static void Ding() => PlaySound(_dingWavePath, ref _dingPlayer);
/// <summary>
/// 播放 CheckinOK.wav;若有其他音效正在播放,先全部停止再播放。
/// </summary>
public static void CheckinOK() => PlaySound(_checkinWavePath, ref _checkinPlayer);
/// <summary>
/// 播放 CheckoutOK.wav;若有其他音效正在播放,先全部停止再播放。
/// </summary>
public static void CheckoutOK() => PlaySound(_checkoutWavePath, ref _checkoutPlayer);
}
}
@@ -0,0 +1,298 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using .Models;
namespace .Services
{
/// <summary>
/// 報名服務客戶端
/// 呼叫後端 Services/SignUpService.asmx
/// </summary>
public class SignUpService
{
private const string SERVICE_PATH = "/Services/SignUpService.asmx";
/// <summary>
/// 搜尋活動參加人員清單
/// </summary>
/// <param name="pageIndex">頁碼(從 1 開始)</param>
/// <param name="pageSize">每頁筆數</param>
/// <param name="courseID">活動編號</param>
/// <param name="name">學員姓名</param>
/// <param name="mobile">手機號</param>
/// <returns>搜尋結果</returns>
public static BaseResponse SearchSignUps(
int pageIndex,
int pageSize,
int courseID,
string name = "",
string mobile = "")
{
var parameters = new
{
pageIndex = pageIndex,
pageSize = pageSize,
courseID = courseID,
name = name,
mobile = mobile
};
return ApiService.Instance.Post(SERVICE_PATH, "SearchSignUps", parameters);
}
///// <summary>
///// 搜尋活動參加人員清單(非同步版本)
///// </summary>
//public static async Task<BaseResponse> SearchSignUpsAsync(
// int pageIndex,
// int pageSize,
// int courseID,
// string name = "",
// string mobile = "")
//{
// var parameters = new
// {
// pageIndex = pageIndex,
// pageSize = pageSize,
// courseID = courseID,
// name = name,
// mobile = mobile
// };
// return await ApiService.Instance.PostAsync(SERVICE_PATH, "SearchSignUps", parameters);
//}
/// <summary>
/// 上傳活動參加人員簽到簽退資料
/// 由 WinForm 客戶端上傳簽到簽退資料
/// </summary>
/// <param name="courseID">活動編號</param>
/// <param name="items">報名人員列表</param>
/// <returns>上傳結果</returns>
//public static BaseResponse UploadSignUps(int courseID, List<SignUpItem> items)
//{
// var parameters = new
// {
// courseID = courseID,
// items = items
// };
// return ApiService.Instance.Post(SERVICE_PATH, "UploadSignUps", parameters);
//}
/// <summary>
/// 上傳活動參加人員簽到簽退資料(非同步版本)
/// </summary>
//public static async Task<BaseResponse> UploadSignUpsAsync(int courseID, List<SignUpItem> items)
//{
// var parameters = new
// {
// courseID = courseID,
// items = items
// };
// return await ApiService.Instance.PostAsync(SERVICE_PATH, "UploadSignUps", parameters);
//}
/// <summary>
/// 掃碼簽到
/// </summary>
/// <param name="checkType">簽到類型</param>
/// <param name="qrCode">QR Code</param>
/// <param name="checkInTime">簽到時間</param>
/// <returns>簽到結果</returns>
//public static BaseResponse CheckIn(string checkType, string qrCode, DateTime checkInTime)
//{
// var parameters = new
// {
// checkType = checkType,
// qrCode = qrCode,
// checkInTime = checkInTime
// };
// return ApiService.Instance.Post(SERVICE_PATH, "CheckIn", parameters);
//}
/// <summary>
/// 掃碼簽到(非同步版本)
/// </summary>
//public static async Task<BaseResponse> CheckInAsync(string checkType, string qrCode, DateTime checkInTime)
//{
// var parameters = new
// {
// checkType = checkType,
// qrCode = qrCode,
// checkInTime = checkInTime
// };
// return await ApiService.Instance.PostAsync(SERVICE_PATH, "CheckIn", parameters);
//}
/// <summary>
/// 掃碼簽退
/// </summary>
/// <param name="checkType">簽退類型</param>
/// <param name="qrCode">QR Code</param>
/// <param name="checkOutTime">簽退時間</param>
/// <returns>簽退結果</returns>
//public static BaseResponse CheckOut(string checkType, string qrCode, DateTime checkOutTime)
//{
// var parameters = new
// {
// checkType = checkType,
// qrCode = qrCode,
// checkOutTime = checkOutTime
// };
// return ApiService.Instance.Post(SERVICE_PATH, "CheckOut", parameters);
//}
/// <summary>
/// 掃碼簽退(非同步版本)
/// </summary>
//public static async Task<BaseResponse> CheckOutAsync(string checkType, string qrCode, DateTime checkOutTime)
//{
// var parameters = new
// {
// checkType = checkType,
// qrCode = qrCode,
// checkOutTime = checkOutTime
// };
// return await ApiService.Instance.PostAsync(SERVICE_PATH, "CheckOut", parameters);
//}
/// <summary>
/// 現場簽到(未預先登記的參加人員)
/// </summary>
/// <param name="checkType">簽到類型</param>
/// <param name="courseID">活動編號</param>
/// <param name="name">姓名</param>
/// <param name="mobile">手機號</param>
/// <param name="checkInTime">簽到時間</param>
/// <returns>簽到結果</returns>
//public static BaseResponse OnSiteCheckIn(
// string checkType,
// int courseID,
// string name,
// string mobile,
// DateTime checkInTime)
//{
// var parameters = new
// {
// checkType = checkType,
// courseID = courseID,
// name = name,
// mobile = mobile,
// checkInTime = checkInTime
// };
// return ApiService.Instance.Post(SERVICE_PATH, "OnSiteCheckIn", parameters);
//}
/// <summary>
/// 現場簽到(非同步版本)
/// </summary>
//public static async Task<BaseResponse> OnSiteCheckInAsync(
// string checkType,
// int courseID,
// string name,
// string mobile,
// DateTime checkInTime)
//{
// var parameters = new
// {
// checkType = checkType,
// courseID = courseID,
// name = name,
// mobile = mobile,
// checkInTime = checkInTime
// };
// return await ApiService.Instance.PostAsync(SERVICE_PATH, "OnSiteCheckIn", parameters);
//}
/// <summary>
/// 現場簽退(未預先登記的參加人員)
/// </summary>
/// <param name="checkType">簽退類型</param>
/// <param name="courseID">活動編號</param>
/// <param name="name">姓名</param>
/// <param name="mobile">手機號</param>
/// <param name="checkOutTime">簽退時間</param>
/// <returns>簽退結果</returns>
//public static BaseResponse OnSiteCheckOut(
// string checkType,
// int courseID,
// string name,
// string mobile,
// DateTime checkOutTime)
//{
// var parameters = new
// {
// checkType = checkType,
// courseID = courseID,
// name = name,
// mobile = mobile,
// checkOutTime = checkOutTime
// };
// return ApiService.Instance.Post(SERVICE_PATH, "OnSiteCheckOut", parameters);
//}
/// <summary>
/// 現場簽退(非同步版本)
/// </summary>
//public static async Task<BaseResponse> OnSiteCheckOutAsync(
// string checkType,
// int courseID,
// string name,
// string mobile,
// DateTime checkOutTime)
//{
// var parameters = new
// {
// checkType = checkType,
// courseID = courseID,
// name = name,
// mobile = mobile,
// checkOutTime = checkOutTime
// };
// return await ApiService.Instance.PostAsync(SERVICE_PATH, "OnSiteCheckOut", parameters);
//}
/// <summary>
/// 批量上傳簽到簽退資料
/// 由 WinForm 客戶端上傳簽到簽退資料
/// </summary>
/// <param name="courseID">活動編號</param>
/// <param name="items">簽到簽退資料列表</param>
/// <returns>上傳結果</returns>
public static BaseResponse UploadCheckIns(int courseID, List<CheckInItem> items)
{
var parameters = new
{
courseID = courseID,
items = items
};
return ApiService.Instance.Post(SERVICE_PATH, "UploadCheckIns", parameters);
}
/// <summary>
/// 批量上傳簽到簽退資料(非同步版本)
/// </summary>
//public static async Task<BaseResponse> UploadCheckInsAsync(int courseID, List<CheckInItem> items)
//{
// var parameters = new
// {
// courseID = courseID,
// items = items
// };
// return await ApiService.Instance.PostAsync(SERVICE_PATH, "UploadCheckIns", parameters);
//}
}
}