using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Web.Http; using System.Configuration; /// /// pivot01Controller - 法會報名統計分析 API /// 設計理念:直接查詢 SQL VIEW,保持彈性與簡潔 /// [ezAuthorize] public class pivot01Controller : ApiController { // 連線字串 private readonly string _connectionString; public pivot01Controller() { // 優先使用 shopConn 連線字串(純 SQL Server 連線字串) var shopConnectionString = ConfigurationManager.ConnectionStrings["shopConn"]?.ConnectionString; if (!string.IsNullOrEmpty(shopConnectionString)) { // 移除不相容的 Provider 參數 _connectionString = shopConnectionString.Replace("Provider=SQLOLEDB;", ""); } else { // 備用方案:從 Entity Framework 連線字串中提取 SQL Server 連線字串 var efConnectionString = ConfigurationManager.ConnectionStrings["ezEntities"]?.ConnectionString; if (!string.IsNullOrEmpty(efConnectionString)) { // 解析 EF 連線字串,提取 provider connection string 部分 var startIndex = efConnectionString.IndexOf("provider connection string="") + "provider connection string="".Length; var endIndex = efConnectionString.LastIndexOf("""); if (startIndex > 0 && endIndex > startIndex) { _connectionString = efConnectionString.Substring(startIndex, endIndex - startIndex); } else { throw new InvalidOperationException("無法解析 Entity Framework 連線字串"); } } else { throw new InvalidOperationException("找不到可用的資料庫連線字串"); } } } #region 通用 VIEW 查詢方法 /// /// 執行 SQL 查詢並回傳 DataTable /// /// SQL 查詢語句 /// 參數陣列 /// 查詢結果 DataTable private DataTable ExecuteSqlQuery(string sql, SqlParameter[] parameters = null) { var dataTable = new DataTable(); try { using (var connection = new SqlConnection(_connectionString)) using (var command = new SqlCommand(sql, connection)) { // 設定逾時時間為 60 秒 command.CommandTimeout = 60; // 加入參數 if (parameters != null && parameters.Length > 0) { command.Parameters.AddRange(parameters); } // 開啟連線並執行查詢 connection.Open(); using (var adapter = new SqlDataAdapter(command)) { adapter.Fill(dataTable); } } } catch (SqlException ex) { throw new Exception($"SQL 查詢錯誤: {ex.Message}", ex); } catch (Exception ex) { throw new Exception($"執行查詢時發生錯誤: {ex.Message}", ex); } return dataTable; } /// /// DataTable 轉換為動態物件列表(保留中文欄位名) /// /// DataTable /// Dictionary 列表 private List> DataTableToDictionary(DataTable dt) { var list = new List>(); foreach (DataRow row in dt.Rows) { var dict = new Dictionary(); foreach (DataColumn col in dt.Columns) { // 保留原始欄位名稱(包含中文) dict[col.ColumnName] = row[col] == DBNull.Value ? null : row[col]; } list.Add(dict); } return list; } #endregion #region API 端點 /// /// GET /api/pivot01/activity_stats /// 查詢法會統計(對應「法會統計」VIEW) /// /// 查詢年份 /// 法會統計資料 [HttpGet] [Route("api/pivot01/activity_stats")] public IHttpActionResult GetActivityStats(int year) { try { // 驗證年份參數 if (year < 1900 || year > 2100) { return BadRequest("年份參數不正確,請輸入 1900 ~ 2100 之間的年份"); } // 建立 SQL 查詢(包含當年度及無日期的法會) string sql = @" SELECT * FROM [法會統計] WHERE (YEAR(開始日期) = @year OR 開始日期 IS NULL) ORDER BY CASE WHEN 開始日期 IS NULL THEN 1 ELSE 0 END, 開始日期 DESC, 結束日期 DESC "; // 建立參數 var parameters = new[] { new SqlParameter("@year", SqlDbType.Int) { Value = year } }; // 執行查詢 var dataTable = ExecuteSqlQuery(sql, parameters); var data = DataTableToDictionary(dataTable); // 回應結果 var result = new { success = true, data = data, message = "查詢成功", rowCount = data.Count }; return Ok(result); } catch (Exception ex) { var errorResponse = new { success = false, message = $"查詢失敗:{ex.Message}", error = ex.ToString() }; return Content(System.Net.HttpStatusCode.BadRequest, errorResponse); } } /// /// GET /api/pivot01/registration_details /// 查詢報名明細(對應「報名明細查詢」VIEW) /// /// 法會編號(必填) /// 報名明細資料 [HttpGet] [Route("api/pivot01/registration_details")] public IHttpActionResult GetRegistrationDetails(int? activityNum = null) { try { // 驗證參數 if (!activityNum.HasValue || activityNum.Value <= 0) { return BadRequest("請提供有效的法會編號(activityNum)"); } // 建立查詢 SQL string sql = @" SELECT * FROM [報名明細查詢] WHERE 法會ID = @activityNum ORDER BY 報名日期 DESC, 報名編號 DESC "; // 建立參數 var parameters = new[] { new SqlParameter("@activityNum", SqlDbType.Int) { Value = activityNum.Value } }; // 執行查詢 var dataTable = ExecuteSqlQuery(sql, parameters); var data = DataTableToDictionary(dataTable); // 回應結果 var result = new { success = true, data = data, message = "查詢成功", rowCount = data.Count }; return Ok(result); } catch (Exception ex) { var errorResponse = new { success = false, message = $"查詢失敗:{ex.Message}", error = ex.ToString() }; return Content(System.Net.HttpStatusCode.BadRequest, errorResponse); } } #endregion }