import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:tdesign_flutter/tdesign_flutter.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_application_model.dart'; import 'expense_application_list_controller.dart'; class ExpenseApplicationDetailPage extends ConsumerWidget { final String id; const ExpenseApplicationDetailPage({super.key, required this.id}); @override Widget build(BuildContext context, WidgetRef ref) { final app = mockExpenseApplications.firstWhere((e) => e.id == id, orElse: () => mockExpenseApplications.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(app), const SizedBox(height: 12), _buildInfoSection(app), const SizedBox(height: 12), if (app.approvalRecords.isNotEmpty || app.approvalChain.isNotEmpty) AppCard( child: ApprovalTimeline( records: app.approvalRecords, chain: app.approvalChain, currentApproverId: app.currentApproverId, ), ), ], ), ), ), ApprovalActions( status: app.status, userRole: UserRole.employee, onApprove: () {}, onReject: () {}, onEdit: () => context.push('/expense-apply/apply?id=${app.id}'), onWithdraw: () {}, ), ], ), ); } Widget _buildStatusHeader(ExpenseApplicationModel app) { final (icon, color, text) = switch (app.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 (app.status == 'pending') Text('当前审批人:${app.currentApproverId}', style: const TextStyle( fontSize: 12, color: AppColors.textSecondary)), ], ), ], ), ); } Widget _buildInfoSection(ExpenseApplicationModel app) { String urgencyLabel = switch (app.urgency) { 'urgent' => '紧急', 'normal' => '普通', _ => app.urgency, }; String dateRange = ''; if (app.estimatedStartDate != null && app.estimatedEndDate != null) { dateRange = '${app.estimatedStartDate!.toString().substring(0, 10)} ~ ${app.estimatedEndDate!.toString().substring(0, 10)}'; } else if (app.estimatedStartDate != null) { dateRange = app.estimatedStartDate!.toString().substring(0, 10); } else { dateRange = '-'; } return _buildDetailCard('基本信息', [ TDCell(title: '申请单号', note: app.applicationNo, showBottomBorder: true), TDCell(title: '申请人', note: '${app.applicantName} · ${app.deptName}', showBottomBorder: true), TDCell(title: '费用类型', note: app.expenseType, showBottomBorder: true), TDCell(title: '预估金额', note: '¥${app.estimatedAmount.toStringAsFixed(2)}', showBottomBorder: true), TDCell(title: '申请事由', note: app.purpose.isNotEmpty ? app.purpose : '-', showBottomBorder: true), TDCell(title: '紧急程度', note: urgencyLabel, showBottomBorder: true), TDCell(title: '预计日期范围', note: dateRange, showBottomBorder: false), ]); } 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, ]), ); } }