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; int _total = 0; late Future> _future; @override void initState() { super.initState(); _fetch(); } void _fetch() { _future = ref .read(inventoryRepositoryProvider) .listProducts(page: _page, pageSize: 20) .then((r) { _total = r.total; return 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: _total, 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), DataColumn(label: Text('状态')), DataColumn(label: Text('买家/时间')), ], 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()), DataCell(SizedBox()), DataCell(SizedBox()), ]) ] : records.map((r) { final batchText = (r.batchNo != null && r.batchNo!.isNotEmpty) ? r.batchNo! : null; 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(batchText != null ? Container( padding: const EdgeInsets.symmetric( horizontal: 6, vertical: 2), decoration: BoxDecoration( color: AppTheme.primary.withOpacity(0.08), borderRadius: BorderRadius.circular(3), ), child: Text(batchText, style: const TextStyle( fontSize: 12, color: AppTheme.primary, fontFamily: 'monospace')), ) : const Text('无批次', style: TextStyle( fontSize: 12, color: AppTheme.textSecondary))), DataCell(Text(r.orderNo ?? '-', style: const TextStyle( fontSize: 11, 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))), DataCell(_StatusBadge(r.isSoldOut)), DataCell(r.isSoldOut ? Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Text( r.buyerName?.isNotEmpty == true ? r.buyerName! : '未知买家', style: const TextStyle( fontSize: 12, fontWeight: FontWeight.w500), ), if (r.soldAt != null) Text(r.soldAt!.length > 10 ? r.soldAt!.substring(0, 10) : r.soldAt!, style: const TextStyle( fontSize: 11, color: AppTheme.textSecondary)), ], ) : const Text('-', style: TextStyle(color: AppTheme.textSecondary))), ]); }).toList(), ); } } class _StatusBadge extends StatelessWidget { final bool isSoldOut; const _StatusBadge(this.isSoldOut); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), decoration: BoxDecoration( color: isSoldOut ? AppTheme.textSecondary.withOpacity(0.12) : AppTheme.success.withOpacity(0.12), borderRadius: BorderRadius.circular(3), ), child: Text( isSoldOut ? '已卖出' : '在售', style: TextStyle( fontSize: 12, fontWeight: FontWeight.w600, color: isSoldOut ? AppTheme.textSecondary : AppTheme.success, ), ), ); } }