import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../core/theme/app_colors.dart'; import '../../core/utils/date_utils.dart' as du; import '../../core/utils/responsive.dart'; import '../../shared/models/approval_status.dart'; import '../../shared/widgets/form_section.dart'; import '../../shared/widgets/form_field_row.dart'; import '../../shared/widgets/status_tag.dart'; import 'expense_model.dart'; final expenseDetailProvider = FutureProvider.autoDispose.family( (ref, id) async { await Future.delayed(const Duration(milliseconds: 300)); return ExpenseModel( id: id, reportNo: 'BX202605001', applicantId: 'u-001', applicantName: '张三', deptId: 'dept-001', deptName: '市场部', expenseType: '差旅费', totalAmount: 2580.00, invoiceCount: 3, status: 'pending', createTime: DateTime(2026, 5, 20), updateTime: DateTime(2026, 5, 20), details: [ ExpenseDetailModel( id: 'det-001', expenseId: id, expenseDate: DateTime(2026, 5, 19), expenseType: '交通费', expenseDesc: '北京-上海高铁', amount: 553.00, totalAmount: 553.00, ), ExpenseDetailModel( id: 'det-002', expenseId: id, expenseDate: DateTime(2026, 5, 19), expenseType: '住宿费', expenseDesc: '上海酒店住宿', amount: 800.00, totalAmount: 800.00, ), ], approvalRecords: [ ApprovalRecord( id: 'ar-001', bizId: id, bizType: 'expense', approverId: 'u-mgr', approverName: '李四', approvalLevel: 1, action: 'pending', opinion: '', approvalTime: DateTime(2026, 5, 21), ), ], ); }); class ExpenseDetailPage extends ConsumerWidget { final String id; const ExpenseDetailPage({super.key, required this.id}); @override Widget build(BuildContext context, WidgetRef ref) { final detailAsync = ref.watch(expenseDetailProvider(id)); final r = ResponsiveHelper.of(context); return Scaffold( appBar: AppBar(title: const Text('报销单详情')), body: detailAsync.when( loading: () => const Center(child: CircularProgressIndicator()), error: (_, __) => const Center(child: Text('加载失败')), data: (expense) => Align(alignment: Alignment.topCenter, child: ConstrainedBox( constraints: BoxConstraints(maxWidth: r.detailTwoColumns ? 700 : double.infinity), child: SingleChildScrollView( padding: const EdgeInsets.symmetric(vertical: 8), child: Column( children: [ FormSection( title: '基本信息', children: [ FormFieldRow( label: '单号', value: expense.reportNo, showArrow: false), FormFieldRow( label: '报销类型', value: expense.expenseType, showArrow: false), FormFieldRow( label: '报销金额', value: '¥${expense.totalAmount.toStringAsFixed(2)}', showArrow: false), FormFieldRow( label: '部门', value: expense.deptName, showArrow: false), FormFieldRow( label: '申请人', value: expense.applicantName, showArrow: false), FormFieldRow( label: '创建时间', value: du.DateUtils.formatDateTime( expense.createTime), showArrow: false), FormFieldRow( label: '状态', value: '', showArrow: false, onTap: null, ), // 状态用 StatusTag Padding( padding: const EdgeInsets.fromLTRB(14, 0, 14, 12), child: Row( children: [ const SizedBox( width: 72, child: Text('状态', style: TextStyle( color: AppColors.textSecondary, fontSize: 13))), StatusTag(status: expense.status), ], ), ), FormFieldRow( label: '备注', value: expense.remark.isEmpty ? '-' : expense.remark, showArrow: false), ], ), FormSection( title: '报销明细', children: expense.details.isEmpty ? [ const Padding( padding: EdgeInsets.all(14), child: Text('无明细', style: TextStyle( color: AppColors.textHint, fontSize: 13)), ) ] : expense.details .map((d) => Padding( padding: const EdgeInsets.symmetric( horizontal: 14, vertical: 8), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(d.expenseDesc, style: const TextStyle( fontSize: 13, color: AppColors .textPrimary)), Text(d.invoiceNo, style: const TextStyle( fontSize: 10, color: AppColors .textHint)), ], ), Text( '¥${d.totalAmount.toStringAsFixed(2)}', style: const TextStyle( color: AppColors.primary, fontSize: 14)), ], ), )) .toList(), ), ], ), ), ), ), ), ); } }