import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../core/theme/app_theme.dart'; import '../../models/inventory.dart'; import '../../providers/inventory_provider.dart'; import '../../widgets/data_table_card.dart'; class BatchTrackingScreen extends ConsumerStatefulWidget { const BatchTrackingScreen({super.key}); @override ConsumerState createState() => _BatchTrackingScreenState(); } class _BatchTrackingScreenState extends ConsumerState { int _page = 1; late Future> _future; @override void initState() { super.initState(); _fetch(); } void _fetch() { _future = ref .read(inventoryRepositoryProvider) .listBatches(page: _page, pageSize: 20) .then((r) => r.data); } void _refetch() { setState(() => _fetch()); } @override Widget build(BuildContext context) { return FutureBuilder>( future: _future, builder: (context, snap) { if (snap.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } if (snap.hasError) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('加载失败:${snap.error}', style: const TextStyle(color: AppTheme.danger)), const SizedBox(height: 12), ElevatedButton( onPressed: _refetch, child: const Text('重试')), ], ), ); } return _buildTable(snap.data ?? []); }, ); } Widget _buildTable(List records) { return DataTableCard( totalCount: records.length, page: _page, onPageChanged: (p) { setState(() { _page = p; _fetch(); }); }, toolbar: Row( children: [ const Text('已审核入库批次', style: TextStyle( fontSize: 13, color: AppTheme.textSecondary)), const Spacer(), IconButton( icon: const Icon(Icons.refresh, size: 18), onPressed: () { setState(() { _page = 1; _fetch(); }); }, tooltip: '刷新', ), ], ), columns: const [ DataColumn(label: Text('商品')), DataColumn(label: Text('规格')), DataColumn(label: Text('批次号')), DataColumn(label: Text('入库单号')), DataColumn(label: Text('供应商')), DataColumn(label: Text('仓库')), DataColumn(label: Text('入库日期')), DataColumn(label: Text('数量'), numeric: true), DataColumn(label: Text('单价'), numeric: true), ], rows: records.isEmpty ? [ const DataRow(cells: [ DataCell(SizedBox()), DataCell(Text('暂无批次记录', style: TextStyle(color: AppTheme.textSecondary))), DataCell(SizedBox()), DataCell(SizedBox()), DataCell(SizedBox()), DataCell(SizedBox()), DataCell(SizedBox()), DataCell(SizedBox()), DataCell(SizedBox()), ]) ] : records.map((r) { final hasBatch = r.batchNo != null && r.batchNo!.isNotEmpty; return DataRow(cells: [ DataCell( Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Text(r.productName ?? '-', style: const TextStyle( fontSize: 13, fontWeight: FontWeight.w500)), if (r.productCode != null) Text(r.productCode!, style: const TextStyle( fontSize: 11, color: AppTheme.textSecondary, fontFamily: 'monospace')), ], ), ), DataCell(Text(r.productSpec ?? '-', style: const TextStyle(fontSize: 12))), DataCell(hasBatch ? Container( padding: const EdgeInsets.symmetric( horizontal: 6, vertical: 2), decoration: BoxDecoration( color: AppTheme.primary.withOpacity(0.08), borderRadius: BorderRadius.circular(3), ), child: Text(r.batchNo!, style: const TextStyle( fontSize: 12, color: AppTheme.primary, fontFamily: 'monospace')), ) : const Text('-', style: TextStyle( color: AppTheme.textSecondary))), DataCell(Text(r.orderNo ?? '-', style: const TextStyle( fontSize: 12, color: AppTheme.primary, fontFamily: 'monospace'))), DataCell(Text(r.supplierName ?? '-', style: const TextStyle(fontSize: 12))), DataCell(Text(r.warehouseName ?? '-', style: const TextStyle(fontSize: 12))), DataCell(Text( r.orderDate?.substring(0, 10) ?? '-', style: const TextStyle(fontSize: 12))), DataCell(Text( '${r.quantity.toStringAsFixed(0)} ${r.productUnit ?? ''}', style: const TextStyle(fontWeight: FontWeight.w500))), DataCell(Text( '¥${r.unitPrice.toStringAsFixed(2)}', style: const TextStyle(fontSize: 13))), ]); }).toList(), ); } }