Files
flutter-learn/lib/historys/chap0215_v1/main.dart
T

232 lines
6.5 KiB
Dart

import 'package:flutter/material.dart';
import './news_manager.dart';
import './placeholder_screens.dart';
import './login_page.dart'; // 確保引入登入頁面
/*
您的 Dart HTTP 客戶端可能無法完成與伺服器的 SSL/TLS 握手。這需要將您的整個 App 結構調整為使用 io.HttpClient
警告: 這是一個臨時且不安全的解決方案。 它會強制 Dart 客戶端信任所有憑證。只建議在無法控制伺服器憑證或開發環境中臨時使用。
還需要找時間查一下錯誤原因 20251214 modify by Gemini 3.0
*/
import 'dart:io';
class MyHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true; // 總是回傳 true (忽略 SSL 錯誤)
}
}
void main() {
// 在 main 函數中加入這行
HttpOverrides.global = MyHttpOverrides();
runApp(const ZenApp());
}
class ZenApp extends StatelessWidget {
const ZenApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '企業應用主選單',
theme: ThemeData(
primarySwatch: Colors.blue,
// 使用 Material 3 風格
useMaterial3: true,
),
// 設置主選單畫面為首頁
// home: const MainMenu(),
home: const LoginPage(),
);
}
}
// ------------------------------------
// 主選單的資料結構 (Data Model)
// ------------------------------------
class MenuItem {
final String title;
final IconData icon;
final Widget targetScreen;
const MenuItem({
required this.title,
required this.icon,
required this.targetScreen,
});
}
// 所有選單項目的列表
const List<MenuItem> menuItems = [
// 1. 新聞資訊 (使用您的 NewsManager)
MenuItem(
title: '公告事項',
icon: Icons.article,
targetScreen: NewsManager(),
),
// 2. 員工打卡
MenuItem(
title: '員工打卡',
icon: Icons.access_time_filled,
targetScreen: PlaceholderScreen(title: '員工打卡'),
),
// 2. 員工打卡
MenuItem(
title: '請假作業',
icon: Icons.access_time_filled,
targetScreen: PlaceholderScreen(title: '請假作業'),
), // 3. 待簽核事項
MenuItem(
title: '待簽核事項',
icon: Icons.pending_actions,
targetScreen: PlaceholderScreen(title: '待簽核事項'),
),
// 4. 待辦事項
MenuItem(
title: '待辦事項',
icon: Icons.checklist,
targetScreen: PlaceholderScreen(title: '待辦事項'),
),
// 5. 行事曆
MenuItem(
title: '行事曆',
icon: Icons.calendar_today,
targetScreen: PlaceholderScreen(title: '行事曆'),
),
// 6. 其他功能 (佔位)
MenuItem(
title: '會議通知',
icon: Icons.folder,
targetScreen: PlaceholderScreen(title: '會議通知'),
),
// 6. 其他功能 (佔位)
MenuItem(
title: '產品型錄',
icon: Icons.folder,
targetScreen: PlaceholderScreen(title: '產品型錄'),
),
// 6. 其他功能 (佔位)
MenuItem(
title: '通訊錄',
icon: Icons.folder,
targetScreen: PlaceholderScreen(title: '通訊錄'),
),
MenuItem(
title: '業績查詢',
icon: Icons.bar_chart,
targetScreen: PlaceholderScreen(title: '報告查詢'),
),
MenuItem(
title: 'Issue List',
icon: Icons.bar_chart,
targetScreen: PlaceholderScreen(title: 'Issue List'),
),
MenuItem(
title: '設定',
icon: Icons.settings,
targetScreen: PlaceholderScreen(title: '設定'),
),
];
// ------------------------------------
// 主選單畫面 (MainMenu) - 九宮格實作
// ------------------------------------
class MainMenu extends StatelessWidget {
const MainMenu({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('企業應用主選單'),
// 增加 App Bar 的高度,使其更符合 Material 3 風格 (可選)
toolbarHeight: 70,
// 可以在這裡加入登出按鈕
actions: [
IconButton(
icon: const Icon(Icons.logout),
onPressed: () {
// 登出:導航回登入頁面並清除所有歷史堆棧
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) => const LoginPage()),
(Route<dynamic> route) => false,
);
},
),
],
),
// 使用 Padding 讓 GridView 內容與邊緣保持距離
body: Padding(
padding: const EdgeInsets.all(12.0),
// 核心:使用 GridView.count 建立九宮格佈局
child: GridView.count(
// 每行顯示 3 個項目(實現九宮格的第一條件)
crossAxisCount: 3,
// 項目間的間距
crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
// 遍歷 menuItems 列表來構建每個選單項目
children: menuItems.map((item) {
return MainMenuItemTile(item: item);
}).toList(),
),
),
);
}
}
// ------------------------------------
// 單個選單項目的小部件 (MainMenuItemTile)
// ------------------------------------
class MainMenuItemTile extends StatelessWidget {
final MenuItem item;
const MainMenuItemTile({required this.item, super.key});
@override
Widget build(BuildContext context) {
return Card(
elevation: 4.0, // 增加陰影,更有質感
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
child: InkWell(
// 使用 InkWell 獲得點擊時的漣漪效果
onTap: () {
// 點擊後導航到對應的目標畫面
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => item.targetScreen,
),
);
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// 選單圖標
Icon(
item.icon,
size: 48.0,
color: Theme.of(context).primaryColor,
),
const SizedBox(height: 8.0),
// 選單名稱
Text(
item.title,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w600,
),
),
],
),
),
);
}
}