/// 时间: 2026-03-30 /// 功能: 已知bug列表页面 /// 介绍: 显示应用已知bug、解决方法和解决时间的底部弹窗页面 /// 最新变化: 新增bug列表页面,支持下拉刷新和滚动查看 import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../../../constants/app_constants.dart'; class BugListPage extends StatefulWidget { const BugListPage({super.key}); @override State createState() => _BugListPageState(); } class _BugListPageState extends State { // 模拟bug数据 final List> _bugs = [ { 'id': 1, 'title': '诗词答题页面偶现卡顿', 'description': '在快速切换诗词题目时,页面可能出现短暂卡顿现象', 'severity': 'medium', // high, medium, low 'status': 'pending', // pending, in_progress, resolved 'solution': '优化页面渲染逻辑,减少不必要的widget重建', 'resolveTime': '2026-04-15', 'reportTime': '2026-03-25', 'affectedUsers': '部分用户', }, { 'id': 2, 'title': '历史记录加载缓慢', 'description': '当历史记录数量较多时,加载速度较慢', 'severity': 'high', 'status': 'in_progress', 'solution': '实现分页加载和本地缓存优化', 'resolveTime': '2026-04-10', 'reportTime': '2026-03-20', 'affectedUsers': '大量用户', }, { 'id': 3, 'title': '主题切换不生效', 'description': '在某些设备上切换主题后,界面颜色没有立即更新', 'severity': 'low', 'status': 'resolved', 'solution': '修复主题状态管理问题,强制刷新界面', 'resolveTime': '2026-03-28', 'reportTime': '2026-03-15', 'affectedUsers': '少数用户', }, { 'id': 4, 'title': '收藏夹同步失败', 'description': '网络不稳定时,收藏夹数据同步可能失败', 'severity': 'medium', 'status': 'pending', 'solution': '增加重试机制和离线缓存功能', 'resolveTime': '2026-04-20', 'reportTime': '2026-03-22', 'affectedUsers': '部分用户', }, { 'id': 5, 'title': '字体大小设置异常', 'description': '调整字体大小后,部分页面文字显示不完整', 'severity': 'low', 'status': 'resolved', 'solution': '优化字体大小适配逻辑,确保所有页面正确显示', 'resolveTime': '2026-03-26', 'reportTime': '2026-03-18', 'affectedUsers': '少数用户', }, ]; final ScrollController _scrollController = ScrollController(); bool _isRefreshing = false; @override void dispose() { _scrollController.dispose(); super.dispose(); } Color _getSeverityColor(String severity) { switch (severity) { case 'high': return Colors.red; case 'medium': return Colors.orange; case 'low': return Colors.green; default: return Colors.grey; } } String _getSeverityText(String severity) { switch (severity) { case 'high': return '高'; case 'medium': return '中'; case 'low': return '低'; default: return '未知'; } } Color _getStatusColor(String status) { switch (status) { case 'resolved': return Colors.green; case 'in_progress': return Colors.blue; case 'pending': return Colors.orange; default: return Colors.grey; } } String _getStatusText(String status) { switch (status) { case 'resolved': return '已解决'; case 'in_progress': return '解决中'; case 'pending': return '待解决'; default: return '未知'; } } Future _refresh() async { setState(() { _isRefreshing = true; }); // 模拟网络请求延迟 await Future.delayed(const Duration(seconds: 1)); setState(() { _isRefreshing = false; }); HapticFeedback.lightImpact(); } @override Widget build(BuildContext context) { return Container( decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.vertical(top: Radius.circular(20)), ), child: Column( children: [ // 顶部拖拽条和标题 _buildHeader(), // bug列表 Expanded( child: RefreshIndicator( onRefresh: _refresh, color: AppConstants.primaryColor, child: ListView.builder( controller: _scrollController, physics: const AlwaysScrollableScrollPhysics(), padding: const EdgeInsets.all(16), itemCount: _bugs.length, itemBuilder: (context, index) { final bug = _bugs[index]; return _buildBugItem(bug); }, ), ), ), ], ), ); } Widget _buildHeader() { return Column( children: [ // 拖拽条 Container( width: 40, height: 4, margin: const EdgeInsets.only(top: 8), decoration: BoxDecoration( color: Colors.grey[300], borderRadius: BorderRadius.circular(2), ), ), // 标题栏 Container( padding: const EdgeInsets.all(16), child: Row( children: [ Icon( Icons.bug_report, color: AppConstants.primaryColor, size: 24, ), const SizedBox(width: 12), Expanded( child: Text( '已知问题列表', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: AppConstants.primaryColor, ), ), ), TextButton( onPressed: () => Navigator.pop(context), child: const Text('关闭'), ), ], ), ), const Divider(height: 1), ], ); } Widget _buildBugItem(Map bug) { return Container( margin: const EdgeInsets.only(bottom: 16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey[200]!), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.05), blurRadius: 5, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 顶部信息行 Container( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 标题和状态标签 Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Text( bug['title'] ?? '未知问题', style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Colors.black87, ), ), ), const SizedBox(width: 8), Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 4, ), decoration: BoxDecoration( color: _getStatusColor(bug['status']).withValues(alpha: 0.1), borderRadius: BorderRadius.circular(12), border: Border.all( color: _getStatusColor(bug['status']), width: 1, ), ), child: Text( _getStatusText(bug['status']), style: TextStyle( fontSize: 12, color: _getStatusColor(bug['status']), fontWeight: FontWeight.w500, ), ), ), ], ), const SizedBox(height: 8), // 问题描述 Text( bug['description'] ?? '暂无描述', style: const TextStyle( fontSize: 14, color: Colors.black54, height: 1.4, ), ), const SizedBox(height: 12), // 严重程度和影响用户 Row( children: [ Container( padding: const EdgeInsets.symmetric( horizontal: 6, vertical: 2, ), decoration: BoxDecoration( color: _getSeverityColor(bug['severity']).withValues(alpha: 0.1), borderRadius: BorderRadius.circular(8), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.priority_high, size: 12, color: _getSeverityColor(bug['severity']), ), const SizedBox(width: 4), Text( '${_getSeverityText(bug['severity'])}优先级', style: TextStyle( fontSize: 11, color: _getSeverityColor(bug['severity']), fontWeight: FontWeight.w500, ), ), ], ), ), const SizedBox(width: 12), Icon( Icons.people, size: 14, color: Colors.grey[600], ), const SizedBox(width: 4), Text( bug['affectedUsers'] ?? '未知用户', style: TextStyle( fontSize: 12, color: Colors.grey[600], ), ), ], ), ], ), ), // 分割线 const Divider(height: 1), // 解决方案区域 Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.grey[50], borderRadius: const BorderRadius.only( bottomLeft: Radius.circular(12), bottomRight: Radius.circular(12), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( Icons.lightbulb_outline, color: AppConstants.primaryColor, size: 16, ), const SizedBox(width: 8), Text( '解决方案', style: TextStyle( fontSize: 14, fontWeight: FontWeight.w600, color: AppConstants.primaryColor, ), ), ], ), const SizedBox(height: 8), Text( bug['solution'] ?? '暂无解决方案', style: const TextStyle( fontSize: 13, color: Colors.black54, height: 1.4, ), ), const SizedBox(height: 12), // 时间信息 Row( children: [ Icon( Icons.schedule, size: 14, color: Colors.grey[600], ), const SizedBox(width: 4), Text( '预计解决: ${bug['resolveTime'] ?? '待定'}', style: TextStyle( fontSize: 12, color: Colors.grey[600], ), ), const SizedBox(width: 16), Icon( Icons.report, size: 14, color: Colors.grey[600], ), const SizedBox(width: 4), Text( '报告时间: ${bug['reportTime'] ?? '未知'}', style: TextStyle( fontSize: 12, color: Colors.grey[600], ), ), ], ), ], ), ), ], ), ); } } // 显示bug列表的底部弹窗方法 void showBugListBottomSheet(BuildContext context) { showModalBottomSheet( context: context, backgroundColor: Colors.transparent, isScrollControlled: true, // 允许弹窗占据全屏高度 builder: (context) => Container( height: MediaQuery.of(context).size.height * 0.85, // 设置弹窗高度为屏幕的85% child: const BugListPage(), ), ); }