import 'package:http/http.dart' as http; import 'dart:convert'; import '../auth_manager.dart'; // 確保引入 AuthManager // 共用 API 常數 const String BASE_IP = "https://api.gex.com.tw:8033"; const String COMMON_API_ENDPOINT = "xapi/v2/eis_demo/orm_api_v2/3/"; const String COMMON_API_URL = "$BASE_IP/$COMMON_API_ENDPOINT"; class GenericApiService { /// 通用的獲取列表方法 /// [T] : 目標資料模型 (例如 Announcement 或 Todo) /// [tableName] : 資料庫表名 (API 參數) /// [pk] : 主鍵欄位名稱 (API 參數) /// [queryFilter] : 查詢過濾條件 (API 參數) /// [fromJson] : 將 Map 轉換為物件的工廠方法 (例如 Announcement.fromJson) Future> fetchList({ required String tableName, required String pk, required String queryFilter, required T Function(Map) fromJson, Map? additionalParams, // 允許傳入額外參數 (如分頁) }) async { // 1. 讀取 Token String? token = await AuthManager.getToken(); if (token == null) { print("錯誤:未找到登入 Token"); // 根據需求決定是否拋出錯誤或回傳空陣列 throw Exception('未登入'); } // 2. 建立 API 參數 final Map params = { "token": token, "_\$_tableName": tableName, "_\$_pk": pk, "_\$_action": "P", "_\$_query_filter": queryFilter, }; // 如果有額外參數,合併進去 if (additionalParams != null) { params.addAll(additionalParams); } try { final response = await http.post( Uri.parse(COMMON_API_URL), headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: params, ); if (response.statusCode == 200) { final Map responseData = json.decode(response.body); // 檢查 code if (responseData['code'] == 0) { final dynamic dataObject = responseData['data']; // 檢查結構是否正確 (data -> items List) if (dataObject is Map && dataObject['items'] is List) { List listJson = dataObject['items']; // 核心魔法:使用傳入的 fromJson 函數將資料轉換為 T 類型 return listJson.map((json) => fromJson(json as Map)).toList(); } else { return []; // 結構不符或無資料 } } else { throw Exception(responseData['msg'] ?? 'API 邏輯錯誤'); } } else { throw Exception('HTTP 錯誤: ${response.statusCode}'); } } catch (e) { print('API 請求錯誤 ($tableName): $e'); throw Exception('無法載入資料: $e'); } } }