Flutter for HarmonyOS】打造企业级仓库管理系统:多设备导航与核心业务功能深度解析!



文章目录

      • [1. 项目概览与数据模型设计](#1. 项目概览与数据模型设计)
        • [1.1 `Product` 类:商品数据的核心](#1.1 Product 类:商品数据的核心)
        • 解读:
      • [2. 响应式导航框架:多设备无缝体验](#2. 响应式导航框架:多设备无缝体验)
        • [2.1 `MainScreen` 的核心逻辑:`MediaQuery` 驱动](#2.1 MainScreen 的核心逻辑:MediaQuery 驱动)
        • 解读:
        • [2.2 多种导航模式 (`_buildDrawer`, `_buildSidebar`, `_buildBottomNavigation`)](#2.2 多种导航模式 (_buildDrawer, _buildSidebar, _buildBottomNavigation))
        • 解读:
      • [3. 核心功能模块一:仪表盘 (`DashboardScreen`)](#3. 核心功能模块一:仪表盘 (DashboardScreen))
      • [4. 核心功能模块二:商品管理 (`ProductsScreen`)](#4. 核心功能模块二:商品管理 (ProductsScreen))
        • [4.1 增删改查商品 (`_addProduct`, `_editProduct`, `_deleteProduct`)](#4.1 增删改查商品 (_addProduct, _editProduct, _deleteProduct))
        • 解读:
        • [4.2 搜索与 `DataTable` 展示](#4.2 搜索与 DataTable 展示)
        • 解读:
      • [5. 核心功能模块三:库存管理 (`InventoryScreen`) 📦](#5. 核心功能模块三:库存管理 (InventoryScreen) 📦)
        • [5.1 更新库存 (`_updateStock`)](#5.1 更新库存 (_updateStock))
        • 解读:
        • [5.2 库存状态显示 (`_getStockStatus`, `_getStockStatusColor`)](#5.2 库存状态显示 (_getStockStatus, _getStockStatusColor))
        • 解读:
      • [6. 部署到 HarmonyOS:Flutter 的跨平台魔力 ✨](#6. 部署到 HarmonyOS:Flutter 的跨平台魔力 ✨)
      • [7. 总结与展望](#7. 总结与展望)


1. 项目概览与数据模型设计

这个仓库管理系统旨在提供一个跨平台、响应式的解决方案,管理商品信息和库存状态。

  • 技术栈:Flutter 3.x、Dart 2.x

  • 主题:浅色模式,以蓝色为主色调,简洁专业。

  • 核心功能

    • 响应式导航:根据屏幕宽度动态切换导航方式(底部导航、侧边抽屉、固定侧边栏)。
    • 模块化页面:包括仪表盘、商品管理、库存管理和设置。
    • 商品数据模型Product 类定义商品属性。
    • 商品管理:增、删、改商品信息,支持搜索。
    • 库存管理:更新商品库存,显示库存状态(低库存警告),支持搜索。
    • DataTable 展示:清晰有效地展示商品和库存列表。
1.1 Product 类:商品数据的核心

Product 类是应用中存储每个商品信息的骨架。

dart 复制代码
// lib/main.dart (Product类)
class Product {
  final int id; // 商品唯一ID
  final String name; // 商品名称
  final String category; // 商品类别
  final int stock; // 库存数量
  final double price; // 价格
  final int minStock; // 最小库存(用于低库存预警)

  Product({
    required this.id,
    required this.name,
    required this.category,
    required this.stock,
    required this.price,
    this.minStock = 20, // 默认最小库存
  });
}
解读:
  • id 字段确保了每个商品的唯一性。
  • minStock 是一个重要的业务字段,用于在库存管理模块中判断商品是否处于低库存状态。

2. 响应式导航框架:多设备无缝体验

仓库管理系统往往需要在各种设备上运行,从移动设备到桌面大屏。因此,一个能智能适配屏幕尺寸的导航框架至关重要。

2.1 MainScreen 的核心逻辑:MediaQuery 驱动

MainScreen 作为应用的入口,通过 MediaQuery 判断屏幕宽度,动态构建不同的导航UI。

dart 复制代码
// lib/main.dart (_MainScreenState 的 build 方法片段)
class _MainScreenState extends State<MainScreen> {
  int _selectedIndex = 0; // 当前选中的导航项索引
  final List<NavigationItem> _navigationItems = [ /* ... 仪表盘、商品管理等导航项 ... */ ];

  // ... _onItemTapped 方法

  @override
  Widget build(BuildContext context) {
    // 根据屏幕宽度判断是否为移动设备
    final isMobile = MediaQuery.of(context).size.width < 600; // 小于600px视为移动端

    return Scaffold(
      appBar: AppBar( /* ... 标题和移动端的汉堡菜单 ... */ ),
      drawer: isMobile ? _buildDrawer() : null, // 移动端显示侧边抽屉
      body: Row( // 主体内容区域
        children: [
          if (!isMobile) _buildSidebar(), // 非移动端显示固定侧边栏
          Expanded( // 填充剩余空间显示当前页面
            child: Container(
              color: Colors.white,
              padding: const EdgeInsets.all(16),
              child: _navigationItems[_selectedIndex].screen, // 根据索引显示对应页面
            ),
          ),
        ],
      ),
      bottomNavigationBar: isMobile ? _buildBottomNavigation() : null, // 移动端显示底部导航栏
    );
  }
  // ... _buildDrawer, _buildSidebar, _buildBottomNavigation 方法
}
解读:
  • MediaQuery.of(context).size.width < 600 是判断设备类型(移动端/非移动端)的核心逻辑。
  • 根据 isMobile 的值,ScaffolddrawerbottomNavigationBar 属性被条件性地设置。
  • body 使用 Row 布局:非移动端时,左侧会渲染一个固定宽度的 _buildSidebar(),右侧的 Expanded 区域则显示当前选中的页面。这种模式非常适合桌面应用和大型平板。
2.2 多种导航模式 (_buildDrawer, _buildSidebar, _buildBottomNavigation)

无论是侧边抽屉、固定侧边栏还是底部导航栏,它们都共享 _navigationItems 列表,并通过 _onItemTapped 更新 _selectedIndex 来切换中间显示的内容。

dart 复制代码
// lib/main.dart (_buildDrawer 方法片段)
Widget _buildDrawer() {
  return Drawer(
    child: ListView(
      children: [
        const DrawerHeader(/* ... 用户信息 ... */),
        ..._navigationItems.map((item) {
          final index = _navigationItems.indexOf(item);
          return ListTile(
            leading: Icon(item.icon),
            title: Text(item.title),
            selected: _selectedIndex == index,
            onTap: () {
              _onItemTapped(index);
              Navigator.pop(context); // 点击后关闭抽屉
            },
          );
        }).toList(),
      ],
    ),
  );
}

// lib/main.dart (_buildSidebar 方法片段)
Widget _buildSidebar() {
  return Container(
    width: 240, // 固定侧边栏宽度
    decoration: BoxDecoration(color: Colors.white, border: Border(right: BorderSide(color: Colors.grey[200]!))),
    child: ListView(
      children: [
        Container(/* ... 用户信息 ... */),
        ..._navigationItems.map((item) {
          final index = _navigationItems.indexOf(item);
          return ListTile(
            leading: Icon(item.icon, color: _selectedIndex == index ? Colors.blue : Colors.grey),
            title: Text(item.title, style: TextStyle(color: _selectedIndex == index ? Colors.blue : Colors.black)),
            selected: _selectedIndex == index,
            onTap: () => _onItemTapped(index), // 点击切换页面
          );
        }).toList(),
      ],
    ),
  );
}

// lib/main.dart (_buildBottomNavigation 方法片段)
Widget _buildBottomNavigation() {
  return BottomNavigationBar(
    items: _navigationItems.map((item) => BottomNavigationBarItem(icon: Icon(item.icon), label: item.title)).toList(),
    currentIndex: _selectedIndex,
    selectedItemColor: Colors.blue,
    unselectedItemColor: Colors.grey,
    onTap: _onItemTapped,
  );
}
解读:
  • 所有导航组件都遍历 _navigationItems 列表来动态生成菜单项,实现了代码复用和维护便利性。
  • _onItemTapped 方法是所有导航模式切换页面的统一入口,它更新 _selectedIndex 并触发 setState 刷新 MainScreenbody 内容。

3. 核心功能模块一:仪表盘 (DashboardScreen)

仪表盘提供仓库概览,显示关键指标。

dart 复制代码
// lib/main.dart (DashboardScreen的build方法片段)
class DashboardScreen extends StatelessWidget {
  const DashboardScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(24),
      child: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Text('仓库管理系统', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
            const SizedBox(height: 24),
            Row( // 关键指标卡片
              children: [
                Expanded(child: Card( /* ... 总商品数卡片 ... */ )),
                const SizedBox(width: 16),
                Expanded(child: Card( /* ... 总库存卡片 ... */ )),
                const SizedBox(width: 16),
                Expanded(child: Card( /* ... 低库存商品卡片 ... */ )),
              ],
            ),
            const SizedBox(height: 24),
            Card( /* ... 最近操作列表 ... */ ),
          ],
        ),
      ),
    );
  }
}
解读:
  • 使用 Row 包裹 ExpandedCard 来创建响应式的多列布局,即使在窄屏上也能适应。
  • Card 用于展示各项指标,提升视觉整洁度。

4. 核心功能模块二:商品管理 (ProductsScreen)

商品管理模块实现商品的增删改查。

4.1 增删改查商品 (_addProduct, _editProduct, _deleteProduct)

添加和编辑功能通过 AlertDialog 中的 TextField 实现表单输入,删除功能则有确认提示。

dart 复制代码
// lib/main.dart (_ProductsScreenState 的 _addProduct 方法片段)
void _addProduct() {
  showDialog(
    context: context,
    builder: (context) {
      TextEditingController nameController = TextEditingController();
      // ... 其他控制器
      return AlertDialog(
        title: const Text('添加商品'),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            TextField(controller: nameController, decoration: const InputDecoration(labelText: '商品名称')),
            // ... 其他输入框
          ],
        ),
        actions: [
          TextButton(onPressed: () => Navigator.pop(context), child: const Text('取消')),
          ElevatedButton(
            onPressed: () {
              // ... 创建新Product对象
              setState(() => _products.add(newProduct)); // 添加到列表
              Navigator.pop(context);
            },
            child: const Text('添加'),
          ),
        ],
      );
    },
  );
}

// lib/main.dart (_ProductsScreenState 的 _editProduct 方法片段)
void _editProduct(Product product) {
  showDialog(
    context: context,
    builder: (context) {
      TextEditingController nameController = TextEditingController(text: product.name); // 预填充数据
      // ...
      return AlertDialog(
        title: const Text('编辑商品'),
        content: Column(/* ... 类似添加商品的输入框,但预填充 ... */),
        actions: [
          TextButton(onPressed: () => Navigator.pop(context), child: const Text('取消')),
          ElevatedButton(
            onPressed: () {
              setState(() { // 更新列表中的对应商品
                int index = _products.indexWhere((p) => p.id == product.id);
                if (index != -1) _products[index] = Product(/* ... 更新后的数据 ... */);
              });
              Navigator.pop(context);
            },
            child: const Text('保存'),
          ),
        ],
      );
    },
  );
}

// lib/main.dart (_ProductsScreenState 的 _deleteProduct 方法片段)
void _deleteProduct(int id) {
  showDialog(
    context: context,
    builder: (context) => AlertDialog(
      title: const Text('删除商品'),
      content: const Text('确定要删除这个商品吗?'),
      actions: [
        TextButton(onPressed: () => Navigator.pop(context), child: const Text('取消')),
        ElevatedButton(
          onPressed: () {
            setState(() => _products.removeWhere((p) => p.id == id)); // 从列表移除
            Navigator.pop(context);
          },
          style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
          child: const Text('删除'),
        ),
      ],
    ),
  );
}
解读:
  • 使用 showDialog 弹出模态对话框,包含 TextField 用于数据输入。
  • 添加和编辑功能复用类似的 UI 结构,编辑时通过 TextEditingControllertext 属性预填充现有数据。
  • setState 在每次数据变更后更新 UI。
  • 删除功能带有确认弹窗,防止误操作。
4.2 搜索与 DataTable 展示

商品列表使用 DataTable 进行展示,支持按名称和类别搜索。

dart 复制代码
// lib/main.dart (_ProductsScreenState 的 _getFilteredProducts 方法片段)
List<Product> _getFilteredProducts() {
  if (_searchController.text.isEmpty) return _products;
  return _products.where((product) {
    return product.name.toLowerCase().contains(_searchController.text.toLowerCase()) ||
           product.category.toLowerCase().contains(_searchController.text.toLowerCase());
  }).toList();
}

// lib/main.dart (_ProductsScreenState 的 build 方法片段)
@override
Widget build(BuildContext context) {
  List<Product> filteredProducts = _getFilteredProducts();
  return Container(
    padding: const EdgeInsets.all(24),
    child: SingleChildScrollView(
      child: Column(
        children: [
          Row( /* ... 标题和添加商品按钮 ... */ ),
          const SizedBox(height: 24),
          Card(
            elevation: 4,
            child: Padding(
              padding: const EdgeInsets.all(16),
              child: Column(
                children: [
                  TextField(controller: _searchController, decoration: const InputDecoration(labelText: '搜索商品', prefixIcon: Icon(Icons.search)), onChanged: (value) => setState(() {})),
                  const SizedBox(height: 16),
                  DataTable( // 数据表格展示
                    columns: const [
                      DataColumn(label: Text('ID')), DataColumn(label: Text('商品名称')), DataColumn(label: Text('类别')),
                      DataColumn(label: Text('库存')), DataColumn(label: Text('价格')), DataColumn(label: Text('操作')),
                    ],
                    rows: filteredProducts.map((product) { // 映射数据到DataRow
                      return DataRow(cells: [
                        DataCell(Text(product.id.toString())),
                        DataCell(Text(product.name)),
                        // ... 其他DataCell
                        DataCell(
                          Row(children: [ // 操作按钮
                            TextButton(onPressed: () => _editProduct(product), child: const Text('编辑')),
                            TextButton(onPressed: () => _deleteProduct(product.id), child: const Text('删除')),
                          ]),
                        ),
                      ]);
                    }).toList(),
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    ),
  );
}
解读:
  • _getFilteredProducts 方法根据搜索框内容过滤 _products 列表,支持不区分大小写的模糊搜索。
  • DataTable 提供了一个结构化的表格视图来展示数据,非常适合管理系统。
  • DataColumn 定义了表格的列头,DataRow 通过 DataCell 填充每一行的数据。
  • onChanged 触发 setState 刷新表格,实现实时搜索。

5. 核心功能模块三:库存管理 (InventoryScreen) 📦

库存管理模块专注于商品库存的更新和状态监控。

5.1 更新库存 (_updateStock)
dart 复制代码
// lib/main.dart (_InventoryScreenState 的 _updateStock 方法片段)
void _updateStock(Product product) {
  showDialog(
    context: context,
    builder: (context) {
      TextEditingController stockController = TextEditingController(text: product.stock.toString());
      return AlertDialog(
        title: const Text('更新库存'),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          children: [TextField(controller: stockController, decoration: const InputDecoration(labelText: '新库存数量'), keyboardType: TextInputType.number)],
        ),
        actions: [
          TextButton(onPressed: () => Navigator.pop(context), child: const Text('取消')),
          ElevatedButton(
            onPressed: () {
              setState(() {
                int index = _products.indexWhere((p) => p.id == product.id);
                if (index != -1) { // 创建一个带有新库存的Product副本
                  _products[index] = Product(
                    id: product.id, name: product.name, category: product.category,
                    stock: int.tryParse(stockController.text) ?? 0, // 更新库存
                    price: product.price, minStock: product.minStock,
                  );
                }
              });
              Navigator.pop(context);
            },
            child: const Text('更新'),
          ),
        ],
      );
    },
  );
}
解读:
  • 同样使用 showDialogTextField 进行库存数量输入。
  • 更新时会创建一个 Product 的新实例来替换旧实例,因为 Product 的属性是 final 的(不可变)。
5.2 库存状态显示 (_getStockStatus, _getStockStatusColor)

DataTable 中直观展示库存状态,并用颜色进行区分。

dart 复制代码
// lib/main.dart (_InventoryScreenState 的 _getStockStatus 方法片段)
String _getStockStatus(int stock, int minStock) {
  return stock < minStock ? '低库存' : '正常';
}

Color _getStockStatusColor(int stock, int minStock) {
  return stock < minStock ? Colors.red : Colors.green;
}

// lib/main.dart (_InventoryScreenState 的 build 方法片段)
@override
Widget build(BuildContext context) {
  // ... 其他UI,搜索框
  DataTable(
    columns: const [ /* ... ID, 商品名称, 当前库存, 最小库存, 状态, 操作 ... */ ],
    rows: filteredProducts.map((product) {
      return DataRow(cells: [
        // ... 其他DataCell
        DataCell(
          Text(
            _getStockStatus(product.stock, product.minStock),
            style: TextStyle(color: _getStockStatusColor(product.stock, product.minStock)), // 动态颜色
          ),
        ),
        DataCell(
          TextButton(onPressed: () => _updateStock(product), child: const Text('更新库存')),
        ),
      ]);
    }).toList(),
  );
}
解读:
  • _getStockStatus 根据当前库存和最小库存判断是"低库存"还是"正常"。
  • _getStockStatusColor 则根据状态返回红色(低库存)或绿色(正常),提供清晰的视觉警告。

6. 部署到 HarmonyOS:Flutter 的跨平台魔力 ✨

现在,我们将把这个 Flutter 仓库管理系统部署到 HarmonyOS 平台。得益于 Flutter 优秀的跨平台能力以及华为对 Flutter 生态的支持,这个过程变得越来越便捷!

前提条件

  1. Flutter SDK:确保您的开发环境中已安装 Flutter SDK,并推荐使用最新稳定版以获得最佳的 HarmonyOS 兼容性。
  2. DevEco Studio:已安装并配置好 HarmonyOS 开发环境。
  3. HarmonyOS SDK:在 DevEco Studio 中下载并配置好对应的 HarmonyOS SDK。
  4. Flutter for HarmonyOS 适配:请关注 Flutter for HarmonyOS 官方文档或社区指引,获取最准确和最新的部署方法。

部署步骤

  1. 创建或导入 Flutter 项目

    • 如果你还没有这个 Flutter 项目,请先通过命令行创建:flutter create my_warehouse_app
    • 在 DevEco Studio 中打开 Flutter 项目 :启动 DevEco Studio,选择 File -> Open,然后导航到你的 Flutter 项目的根目录并打开。
  2. DevEco Studio 自动识别与导入

    • DevEco Studio 会智能识别这是一个 Flutter 项目,并提示你将其导入为 HarmonyOS 应用。点击 ImportYes
    • 根据提示选择 HarmonyOS SDK 版本和模块类型(通常默认 entry 模块即可),DevEco Studio 会在你的 Flutter 项目内部创建 harmony 文件夹及必要的配置文件。
  3. 配置与同步

    • DevEco Studio 会自动进行项目同步,下载所有 HarmonyOS 相关的依赖和适配组件。确保网络连接稳定。
    • 对于调试目的,DevEco Studio 通常会处理调试签名。如果遇到签名问题,请在 DevEco Studio 的项目结构中检查并配置你的 HarmonyOS 模块的调试签名。
  4. 选择目标设备并运行

    • 在 DevEco Studio 顶部的设备选择下拉菜单中,选择一个可用的 HarmonyOS 模拟器或连接你的 HarmonyOS 真机设备。
    • 点击绿色的"运行"按钮。DevEco Studio 将会编译你的 Flutter 代码,将其集成到 HarmonyOS 项目中,然后构建并部署最终的 HarmonyOS 应用包(HAP)到你选择的设备上。
  5. 查看效果

    • 稍等片刻(首次构建可能需要较长时间),你的 Flutter 仓库管理系统应用就会在 HarmonyOS 模拟器或真机上启动并运行起来!

7. 总结与展望

这个仓库管理系统只是一个起点,你可以继续探索和扩展:

  • 数据持久化 :集成 shared_preferencessqflite,甚至连接后端数据库,确保数据永久存储。
  • 用户认证:添加登录功能,支持多用户管理。
  • 高级搜索与筛选:支持按日期、价格范围等进行高级搜索和筛选。
  • 报告与图表:在仪表盘中添加库存趋势、销售额等可视化图表。

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

相关推荐
向哆哆4 小时前
构建健康档案管理快速入口:Flutter × OpenHarmony 跨端开发实战
flutter·开源·鸿蒙·openharmony·开源鸿蒙
2601_949593655 小时前
基础入门 React Native 鸿蒙跨平台开发:BackHandler 返回键控制
react native·react.js·harmonyos
mocoding5 小时前
使用Flutter强大的图标库fl_chart优化鸿蒙版天气预报温度、降水量、湿度展示
flutter·华为·harmonyos
向哆哆5 小时前
构建智能健康档案管理与预约挂号系统:Flutter × OpenHarmony 跨端开发实践
flutter·开源·鸿蒙·openharmony·开源鸿蒙
Cobboo5 小时前
i单词上架鸿蒙应用市场之路:一次从 Android 到 HarmonyOS 的完整实战
android·华为·harmonyos
Swift社区5 小时前
Flutter 路由系统,对比 RN / Web / iOS 有什么本质不同?
前端·flutter·ios
kirk_wang5 小时前
Flutter艺术探索-Flutter依赖注入:get_it与provider组合使用
flutter·移动开发·flutter教程·移动开发教程
2601_949593655 小时前
高级进阶 React Native 鸿蒙跨平台开发:LinearGradient 动画渐变效果
react native·react.js·harmonyos
向哆哆6 小时前
Flutter × OpenHarmony:打造校园勤工俭学个人中心界面实战
flutter·开源·鸿蒙·openharmony
2601_949833396 小时前
flutter_for_openharmony口腔护理app实战+我的实现
开发语言·javascript·flutter