# Flutter 实战:从零搭建一个美观实用的图书管理系统(附完整源码)

## 前言

图书管理系统是学习 Flutter 开发的经典练手项目,涵盖了状态管理、路由导航、表单验证、列表筛选等核心技能。本文带你从零搭建一个**界面精美、功能完备**的图书管理系统,采用 **Material Design 3** 设计风格,全中文界面,拿来即用。

## 项目概览

| 功能模块 | 说明 |
|----------|------|
| 📊 仪表盘 | 馆藏总量/可借数/借出中/已逾期 四个统计卡片 + 最近借阅 + 热门图书 |
| 📚 图书管理 | 网格/列表双视图、搜索、分类筛选、排序、增删改查 |
| 🔄 借阅管理 | 借出/逾期/已归还 状态筛选、归还操作、逾期自动检测 |
| 🏷️ 分类管理 | 6 大分类,自定义图标与颜色,编辑删除带保护 |

## 技术栈

- **Flutter 3.x** + Dart 3.x
- **状态管理**:Provider(MultiProvider + ProxyProvider)
- **UI 框架**:Material Design 3
- **依赖包**:`provider`、`uuid`、`intl`

## 项目结构

```
lib/
├── main.dart                         # 应用入口,MultiProvider 注入
├── app.dart                          # MaterialApp + 路由 + 主题
├── theme/
│   ├── app_theme.dart                # M3 主题配置
│   └── constants.dart                # 中文字符串常量
├── models/
│   ├── book.dart                     # 图书数据模型
│   ├── category.dart                 # 分类模型
│   ├── borrow_record.dart            # 借阅记录模型
│   └── dashboard_stats.dart          # 仪表盘统计模型
├── providers/
│   ├── book_provider.dart            # 图书 CRUD + 搜索筛选排序
│   ├── category_provider.dart        # 分类管理
│   ├── borrow_provider.dart          # 借阅归还操作
│   └── dashboard_provider.dart       # ProxyProvider 衍生统计
├── data/
│   └── mock_data.dart                # 19 本图书 + 6 分类 + 10 条借阅记录
├── screens/
│   ├── main_shell.dart               # 底部导航壳(IndexedStack)
│   ├── dashboard_screen.dart         # 首页仪表盘
│   ├── book_list_screen.dart         # 图书列表 + 搜索筛选
│   ├── book_detail_screen.dart       # 图书详情 + 借阅弹窗
│   ├── book_form_screen.dart         # 添加/编辑图书表单
│   ├── borrow_management_screen.dart # 借阅管理列表
│   └── category_management_screen.dart # 分类管理
└── widgets/
    ├── stats_card.dart               # 统计卡片组件
    ├── book_grid_card.dart           # 网格图书卡片
    ├── book_list_tile.dart           # 列表图书条目
    ├── search_and_filter_bar.dart    # 搜索 + 分类筛选栏
    ├── empty_state.dart              # 空状态占位组件
    ├── rating_stars.dart             # 星级评分组件
    └── borrow_status_badge.dart      # 借阅状态标签
```

## 核心实现详解

### 1. 状态管理架构

使用 Provider 实现清晰的分层状态管理,CategoryProvider → BookProvider → BorrowProvider 形成数据依赖链,DashboardStats 通过 ProxyProvider3 自动聚合统计:

```dart
MultiProvider(
  providers: [
    ChangeNotifierProvider(create: (_) => CategoryProvider()..seed()),
    ChangeNotifierProxyProvider<CategoryProvider, BookProvider>(
      create: (_) => BookProvider(),
      update: (_, catProvider, bookProvider) {
        if (bookProvider != null && bookProvider.books.isEmpty) {
          bookProvider.seed(catProvider);
        }
        return bookProvider!;
      },
    ),
    ChangeNotifierProxyProvider<BookProvider, BorrowProvider>(
      create: (_) => BorrowProvider(),
      update: (_, bookProvider, borrowProvider) {
        if (borrowProvider != null && borrowProvider.records.isEmpty) {
          borrowProvider.seed(bookProvider);
        }
        return borrowProvider!;
      },
    ),
    ProxyProvider3<BookProvider, CategoryProvider, BorrowProvider, DashboardStats>(
      update: (_, books, categories, borrows, __) =>
          computeDashboardStats(books.books, categories.categories, borrows.records),
    ),
  ],
  child: const LibraryApp(),
)
```

### 2. 数据模型设计

Book 模型使用不可变设计 + copyWith 模式,支持 JSON 序列化:

```dart
class Book {
  final String id;
  final String title;
  final String author;
  final String isbn;
  final String publisher;
  final DateTime publishDate;
  final String description;
  final String categoryId;
  final int totalCopies;
  final int availableCopies;
  final String shelfLocation;
  final double rating;
  final List<String> tags;

  bool get isAvailable => availableCopies > 0;

  Book copyWith({...});          // 不可变更新
  factory Book.fromJson(...);    // JSON 反序列化
  Map<String, dynamic> toJson(); // JSON 序列化
}
```

BorrowRecord 的借阅状态是**计算属性**而非存储字段,避免数据不一致:

```dart
enum BorrowStatus { borrowed, returned, overdue }

BorrowStatus get status {
  if (returnDate != null) return BorrowStatus.returned;
  if (DateTime.now().isAfter(dueDate)) return BorrowStatus.overdue;
  return BorrowStatus.borrowed;
}
```

### 3. 图书筛选与搜索

BookProvider 中的 `filteredBooks` 采用**计算属性**,链式处理分类筛选 → 关键词搜索 → 排序,不存冗余状态:

```dart
List<Book> get filteredBooks {
  var result = _books.toList();
  if (_selectedCategoryId != 'all') {
    result = result.where((b) => b.categoryId == _selectedCategoryId).toList();
  }
  if (_searchQuery.isNotEmpty) {
    final query = _searchQuery.toLowerCase();
    result = result.where((b) =>
      b.title.toLowerCase().contains(query) ||
      b.author.toLowerCase().contains(query) ||
      b.isbn.contains(query)
    ).toList();
  }
  // 排序逻辑...
  return result;
}
```

### 4. 借阅归还流程

借阅时同时更新 BorrowProvider 和 BookProvider 的可借数量:

```dart
// 借阅
context.read<BorrowProvider>().borrowBook(book.id, name, id, days: days);
context.read<BookProvider>().decrementAvailable(book.id);

// 归还
context.read<BorrowProvider>().returnBook(record.id);
context.read<BookProvider>().incrementAvailable(record.bookId);
```

### 5. Material Design 3 主题

```dart
ThemeData(
  useMaterial3: true,
  colorScheme: ColorScheme.fromSeed(seedColor: Color(0xFF1565C0)),
  cardTheme: CardThemeData(
    elevation: 0,
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.circular(12),
      side: BorderSide(color: colorScheme.outlineVariant),
    ),
  ),
  // ...
)
```

### 6. 底部导航 + 命名路由

MainShell 使用 `IndexedStack` 保持各页面状态,子页面通过 `onGenerateRoute` 导航:

```dart
// 底部导航 IndexedStack 保持状态
IndexedStack(
  index: _currentIndex,
  children: [DashboardScreen(), BookListScreen(), ...],
)

// 命名路由导航到详情页
Navigator.pushNamed(context, '/book/detail', arguments: book.id);
```

## 运行效果

启动后进入仪表盘首页,展示馆藏统计与热门图书。底部四个 Tab 分别对应首页、图书管理、借阅管理、分类管理。点击任意图书卡片进入详情页,可借阅图书;在借阅管理页可查看借阅状态并操作归还。

## 运行方式

```bash
# 1. 解压项目
unzip fluter.zip

# 2. 进入目录
cd fluter/my_app

# 3. 安装依赖
flutter pub get

# 4. 运行(支持 Windows / Web / Android / iOS)
flutter run -d windows   # Windows 桌面
flutter run -d edge      # 浏览器
```

## 项目地址

完整源码下载:直接查看我的主页资源,我也会把资源链接发在评论区

---

## 总结

这个项目虽然是一个界面原型,但涵盖了 Flutter 开发中**状态管理、路由设计、数据模型、组件化、主题定制**等核心技术点,非常适合 Flutter 初学者练手。你可以在此基础上:

- 接入 Firebase / SQLite 实现持久化存储
- 添加用户登录/权限管理
- 接入扫码 ISBN 自动填充图书信息
- 添加图表统计(fl_chart)

如果觉得有用,欢迎点赞收藏!有问题欢迎在评论区交流~

待源码资源通过后会在评论区发表链接

---

**关键词**:Flutter 图书管理系统、Provider 状态管理、Material Design 3、Dart、移动端开发
 

更多推荐