import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; import 'package:crypto/crypto.dart'; // 引入九宮格主選單,登入成功後跳轉 import 'main.dart'; import './auth_manager.dart'; // 確保路徑正確 // API 相關常數 const String BASE_IP = "https://api.gex.com.tw:8033"; const String API_ENDPOINT = "xapi/v1/eis_demo/checklogin/2/"; const String API_URL = "$BASE_IP/$API_ENDPOINT"; class LoginPage extends StatefulWidget { const LoginPage({super.key}); @override State createState() => _LoginPageState(); } class _LoginPageState extends State { // 用於獲取輸入框內容 final TextEditingController _userController = TextEditingController(text: 'admin'); // 預設帳號 final TextEditingController _pwdController = TextEditingController(text: 'gex123'); // 預設密碼 bool _isLoading = false; String? _errorMessage; // 輔助函數:將字串轉換為 MD5 雜湊值 String _generateMd5(String input) { return md5.convert(utf8.encode(input)).toString(); } // 登入邏輯,模擬您的 JS logon() 函數 Future _logon() async { if (_userController.text.isEmpty || _pwdController.text.isEmpty) { setState(() { _errorMessage = '請輸入帳號和密碼'; }); return; } setState(() { _isLoading = true; _errorMessage = null; }); final String userId = _userController.text; final String password = _pwdController.text; // 對密碼進行 MD5 加密 final String md5Password = _generateMd5(password); // 建立 API 參數,使用您的邏輯 final Map params = { 'token': 'xxx', 'para01': userId, 'para02': md5Password, 'para03': 'web', }; try { // 執行 POST 請求。使用 application/x-www-form-urlencoded 格式 final response = await http.post( Uri.parse(API_URL), headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: params, ); // 解析 API 回應 final Map responseData = json.decode(response.body); // 根據您的 API 邏輯:res.data.code === 0 為成功 if (responseData['code'] == 0) { // 1. 預期 responseData['data'] 是一個 List final List? dataList = responseData['data'] as List?; // 2. 檢查 List 不為空,並從第一個元素中提取 'token' final String? token = (dataList != null && dataList.isNotEmpty) ? (dataList[0] as Map)['token'] as String? : null; if (token != null && token.isNotEmpty) { await AuthManager.saveLoginInfo(token, userId); // 呼叫 AuthManager 儲存 Token } else { print("警告: 登入成功但未收到 Token,將不儲存。"); } // 登入成功:導航至 MainMenu 並替換登入頁面(防止按返回鍵回到登入) if (mounted) { Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => const MainMenu()), ); } } else { // 登入失敗:顯示錯誤訊息 setState(() { _errorMessage = '登入失敗,請重新輸入正確的帳號及密碼!'; }); } } catch (e) { // 網路或伺服器錯誤 setState(() { _errorMessage = '網路錯誤或伺服器無法連線。'; }); } finally { setState(() { _isLoading = false; }); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('用戶登入')), body: Center( child: SingleChildScrollView( padding: const EdgeInsets.all(32.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const Icon(Icons.lock_open, size: 80, color: Colors.blue), const SizedBox(height: 48.0), // 帳號輸入框 TextField( controller: _userController, decoration: const InputDecoration( labelText: '用戶帳號', border: OutlineInputBorder(), prefixIcon: Icon(Icons.person), ), keyboardType: TextInputType.text, ), const SizedBox(height: 16.0), // 密碼輸入框 TextField( controller: _pwdController, obscureText: true, decoration: const InputDecoration( labelText: '密碼', border: OutlineInputBorder(), prefixIcon: Icon(Icons.lock), ), onSubmitted: (_) => _logon(), // 允許按 Enter 鍵登入 ), const SizedBox(height: 24.0), // 錯誤訊息顯示 if (_errorMessage != null) Padding( padding: const EdgeInsets.only(bottom: 12.0), child: Text( _errorMessage!, style: const TextStyle(color: Colors.red, fontWeight: FontWeight.bold), textAlign: TextAlign.center, ), ), // 登入按鈕 ElevatedButton( onPressed: _isLoading ? null : _logon, style: ElevatedButton.styleFrom( minimumSize: const Size(double.infinity, 50), ), child: _isLoading ? const SizedBox( height: 20, width: 20, child: CircularProgressIndicator(strokeWidth: 3.0), ) : const Text( '登入', style: TextStyle(fontSize: 18), ), ), ], ), ), ), ); } }