task_center_page.dart 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import 'package:flutter/material.dart';
  2. import 'package:provider/provider.dart';
  3. import '../models/task.dart';
  4. import '../providers/task_provider.dart';
  5. import '../widgets/common/app_card.dart';
  6. import '../widgets/common/app_progress.dart';
  7. import '../widgets/common/app_tag.dart';
  8. import '../theme/app_colors.dart';
  9. class TaskCenterPage extends StatefulWidget {
  10. const TaskCenterPage({super.key});
  11. @override
  12. State<TaskCenterPage> createState() => _TaskCenterPageState();
  13. }
  14. class _TaskCenterPageState extends State<TaskCenterPage> {
  15. @override
  16. void initState() {
  17. super.initState();
  18. Future.microtask(() {
  19. context.read<TaskProvider>().fetchTasks();
  20. });
  21. }
  22. @override
  23. Widget build(BuildContext context) {
  24. final provider = context.watch<TaskProvider>();
  25. return Scaffold(
  26. appBar: AppBar(
  27. title: const Text('任务中心'),
  28. ),
  29. body: Padding(
  30. padding: const EdgeInsets.all(16),
  31. child: provider.loading
  32. ? const Center(child: CircularProgressIndicator())
  33. : Column(
  34. children: [
  35. _buildFilterBar(provider),
  36. const SizedBox(height: 12),
  37. Expanded(
  38. child: ListView.builder(
  39. itemCount: provider.tasks.length,
  40. itemBuilder: (context, index) {
  41. final task = provider.tasks[index];
  42. return _buildTaskCard(task);
  43. },
  44. ),
  45. ),
  46. ],
  47. ),
  48. ),
  49. );
  50. }
  51. Widget _buildFilterBar(TaskProvider provider) {
  52. return Row(
  53. children: [
  54. DropdownButton<String>(
  55. value: provider.statusFilter ?? '',
  56. items: const [
  57. DropdownMenuItem(value: '', child: Text('全部')),
  58. DropdownMenuItem(value: 'pending', child: Text('等待中')),
  59. DropdownMenuItem(value: 'processing', child: Text('进行中')),
  60. DropdownMenuItem(value: 'completed', child: Text('已完成')),
  61. DropdownMenuItem(value: 'failed', child: Text('失败')),
  62. ],
  63. onChanged: (value) {
  64. provider.fetchTasks(status: value?.isEmpty == true ? null : value);
  65. },
  66. ),
  67. const Spacer(),
  68. Text('共 ${provider.total} 个任务'),
  69. ],
  70. );
  71. }
  72. Widget _buildTaskCard(Task task) {
  73. Color statusColor;
  74. String statusLabel;
  75. switch (task.status) {
  76. case 'processing':
  77. statusColor = AppColors.primary;
  78. statusLabel = '进行中';
  79. break;
  80. case 'completed':
  81. statusColor = Colors.green;
  82. statusLabel = '已完成';
  83. break;
  84. case 'failed':
  85. statusColor = Colors.red;
  86. statusLabel = '失败';
  87. break;
  88. default:
  89. statusColor = Colors.grey;
  90. statusLabel = '等待中';
  91. }
  92. return Padding(
  93. padding: const EdgeInsets.only(bottom: 12),
  94. child: AppCard(
  95. child: Padding(
  96. padding: const EdgeInsets.all(12),
  97. child: Row(
  98. children: [
  99. Expanded(
  100. child: Column(
  101. crossAxisAlignment: CrossAxisAlignment.start,
  102. children: [
  103. Text(
  104. task.name.isNotEmpty ? task.name : task.id,
  105. style: const TextStyle(
  106. fontSize: 16,
  107. fontWeight: FontWeight.bold,
  108. ),
  109. ),
  110. const SizedBox(height: 4),
  111. Text('文档: ${task.documentId}'),
  112. const SizedBox(height: 4),
  113. if (task.errorMessage != null &&
  114. task.errorMessage!.isNotEmpty)
  115. Text(
  116. task.errorMessage!,
  117. style: const TextStyle(
  118. fontSize: 12,
  119. color: Colors.redAccent,
  120. ),
  121. maxLines: 1,
  122. overflow: TextOverflow.ellipsis,
  123. ),
  124. const SizedBox(height: 8),
  125. AppProgress(
  126. value: task.progress / 100.0,
  127. height: 6,
  128. ),
  129. ],
  130. ),
  131. ),
  132. const SizedBox(width: 12),
  133. AppTag(label: statusLabel, color: statusColor),
  134. ],
  135. ),
  136. ),
  137. ),
  138. );
  139. }
  140. }