import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:tdesign_flutter/tdesign_flutter.dart'; import 'package:go_router/go_router.dart'; import '../../core/theme/app_colors.dart'; import '../../shared/models/user_model.dart'; import '../../shared/widgets/app_card.dart'; import '../../shared/widgets/approval_timeline.dart'; import '../../shared/widgets/approval_actions.dart'; import 'expense_model.dart'; import 'expense_list_controller.dart'; class ExpenseDetailPage extends ConsumerWidget { final String id; const ExpenseDetailPage({super.key, required this.id}); @override Widget build(BuildContext context, WidgetRef ref) { final expense = mockExpenses.firstWhere((e) => e.id == id, orElse: () => mockExpenses.first); return Scaffold( appBar: TDNavBar( title: '报销单详情', titleColor: Colors.white, backgroundColor: const Color(0xFF00ABF3), centerTitle: false, ), body: Column(children: [ Expanded( child: SingleChildScrollView( padding: const EdgeInsets.all(12), child: Column(children: [ _buildStatusHeader(expense), const SizedBox(height: 12), _buildInfoSection(expense), const SizedBox(height: 12), _buildDetailSection(expense), const SizedBox(height: 12), if (expense.approvalRecords.isNotEmpty || expense.approvalChain.isNotEmpty) AppCard( child: ApprovalTimeline( records: expense.approvalRecords, chain: expense.approvalChain, currentApproverId: expense.currentApproverId, ), ), ]), ), ), ApprovalActions( status: expense.status, userRole: UserRole.employee, onApprove: () {}, onReject: () {}, onEdit: () => context.push('/expense/apply?id=${expense.id}'), onWithdraw: () {}, ), ]), ); } Widget _buildStatusHeader(ExpenseModel expense) { final (icon, color, text) = switch (expense.status) { 'approved' => (Icons.check_circle, AppColors.success, '已通过'), 'rejected' => (Icons.cancel, AppColors.error, '已拒绝'), 'draft' => (Icons.edit, AppColors.textHint, '草稿'), _ => (Icons.schedule, AppColors.warning, '待审批'), }; return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: color.withValues(alpha: 0.08), borderRadius: BorderRadius.circular(12)), child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(icon, color: color, size: 36), const SizedBox(width: 10), Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(text, style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600, color: color)), if (expense.status == 'pending') Text('当前审批人:${expense.currentApproverId}', style: const TextStyle(fontSize: 12, color: AppColors.textSecondary)), ]), ]), ); } Widget _buildInfoSection(ExpenseModel expense) { return _buildDetailCard('基本信息', [ TDCell(title: '报销单号', note: expense.reportNo, showBottomBorder: true), TDCell(title: '申请人', note: '${expense.applicantName} · ${expense.deptName}', showBottomBorder: true), TDCell(title: '报销类型', note: expense.expenseType, showBottomBorder: true), TDCell(title: '发票数量', note: '${expense.invoiceCount}张', showBottomBorder: true), TDCell(title: '总金额', note: '¥${expense.totalAmount.toStringAsFixed(2)}', showBottomBorder: expense.remark.isNotEmpty), if (expense.remark.isNotEmpty) TDCell(title: '备注', note: expense.remark, showBottomBorder: false), ]); } Widget _buildDetailSection(ExpenseModel expense) { if (expense.details.isEmpty) return const SizedBox.shrink(); return _buildDetailCard('报销明细', [ ...expense.details.map((d) => TDCell( titleWidget: Text(d.expenseDesc, style: const TextStyle(fontSize: 13, color: AppColors.textPrimary)), description: d.expenseDate.toString().substring(0, 10), note: '¥${d.totalAmount.toStringAsFixed(2)}', noteWidget: Text('¥${d.totalAmount.toStringAsFixed(2)}', style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w500, color: AppColors.primary)), showBottomBorder: true, )), Padding( padding: const EdgeInsets.fromLTRB(14, 12, 14, 12), child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text('合计', style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: AppColors.textPrimary)), Text('¥${expense.totalAmount.toStringAsFixed(2)}', style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w600, color: AppColors.primary)), ]), ), ]); } Widget _buildDetailCard(String title, List cells) { return Container( margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), decoration: BoxDecoration( color: AppColors.cardWhite, borderRadius: BorderRadius.circular(10), boxShadow: [BoxShadow(color: Colors.black.withValues(alpha: 0.04), blurRadius: 4, offset: const Offset(0, 1))], ), child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.fromLTRB(14, 12, 14, 8), child: Text(title, style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: AppColors.textPrimary)), ), ...cells, ]), ); } }