From 72ca9ca94e72d21871d8746983e15c9e58a27f0b Mon Sep 17 00:00:00 2001 From: YuanXuan Date: Thu, 28 Aug 2025 10:57:54 +0800 Subject: [PATCH] =?UTF-8?q?=E7=B2=BE=E7=AE=80=E7=BD=91=E7=BB=9C=E6=A3=80?= =?UTF-8?q?=E6=9F=A5=E5=99=A8=E7=95=8C=E9=9D=A2=E8=AE=BE=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 简化统计信息区域:突出显示错误数量,成功时显示绿色状态 - 重新设计日志列表项:使用紧凑的行布局,突出重要信息 - 添加HTTP方法颜色编码:GET蓝色、POST绿色、PUT橙色、DELETE红色 - 优化错误显示:错误请求有红色边框,显示错误图标 - 移除搜索栏默认显示:节省界面空间,用户需要时可通过头部按钮打开 - 改进视觉层级:状态码、耗时、URL等关键信息更突出 - 提升排错效率:一眼就能看出请求状态和关键信息 --- lib/src/widgets/inspector_panel.dart | 330 +++++++++++++++------------ 1 file changed, 179 insertions(+), 151 deletions(-) diff --git a/lib/src/widgets/inspector_panel.dart b/lib/src/widgets/inspector_panel.dart index ff8abbe..2a1ad6a 100644 --- a/lib/src/widgets/inspector_panel.dart +++ b/lib/src/widgets/inspector_panel.dart @@ -26,7 +26,7 @@ class _YxInspectorPanelState extends State { String _searchKeyword = ''; bool _showOnlyErrors = false; bool _isFullScreen = false; - + // 页面导航状态 NetworkLogEntry? _selectedLog; bool _showDetailPage = false; @@ -73,7 +73,7 @@ class _YxInspectorPanelState extends State { listenable: widget.controller, builder: (context, child) { Widget content; - + if (_showDetailPage && _selectedLog != null) { // 显示详情页面 content = Column( @@ -246,77 +246,89 @@ class _YxInspectorPanelState extends State { Widget _buildStatistics() { final stats = widget.controller.getStatistics(); + final totalRequests = stats['totalRequests'] as int; + final errorRequests = stats['errorRequests'] as int; return Container( - padding: const EdgeInsets.all(16), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + decoration: BoxDecoration( + color: widget.theme.backgroundColor, + border: Border( + bottom: BorderSide( + color: widget.theme.secondaryTextColor.withValues(alpha: 0.2), + width: 1, + ), + ), + ), child: Row( children: [ - Expanded( - child: _buildStatItem( - '总计', - stats['totalRequests'].toString(), - Icons.list, - widget.theme.primaryColor, + // 简化统计 - 只显示关键信息 + Text( + '总请求: $totalRequests', + style: TextStyle( + fontSize: 14, + color: widget.theme.textColor, + fontWeight: FontWeight.w500, ), ), - Expanded( - child: _buildStatItem( - '成功', - stats['successRequests'].toString(), - Icons.check_circle, - widget.theme.successColor, + const SizedBox(width: 16), + if (errorRequests > 0) ...[ + Icon( + Icons.error_outline, + size: 16, + color: widget.theme.errorColor, ), - ), - Expanded( - child: _buildStatItem( - '失败', - stats['errorRequests'].toString(), - Icons.error, - widget.theme.errorColor, + const SizedBox(width: 4), + Text( + '错误: $errorRequests', + style: TextStyle( + fontSize: 14, + color: widget.theme.errorColor, + fontWeight: FontWeight.w600, + ), ), - ), - Expanded( - child: _buildStatItem( - '成功率', - stats['successRate'], - Icons.percent, - widget.theme.warningColor, + ] else ...[ + Icon( + Icons.check_circle_outline, + size: 16, + color: widget.theme.successColor, + ), + const SizedBox(width: 4), + Text( + '全部成功', + style: TextStyle( + fontSize: 14, + color: widget.theme.successColor, + fontWeight: FontWeight.w500, + ), + ), + ], + const Spacer(), + // 快速过滤按钮 + if (errorRequests > 0) + TextButton.icon( + onPressed: () { + setState(() { + _showOnlyErrors = !_showOnlyErrors; + }); + }, + icon: Icon( + _showOnlyErrors ? Icons.clear : Icons.filter_list, + size: 16, + ), + label: Text(_showOnlyErrors ? '显示全部' : '仅错误'), + style: TextButton.styleFrom( + foregroundColor: widget.theme.errorColor, + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + minimumSize: Size.zero, + tapTargetSize: MaterialTapTargetSize.shrinkWrap, + ), ), - ), ], ), ); } - Widget _buildStatItem( - String label, - String value, - IconData icon, - Color color, - ) { - return Column( - children: [ - Icon(icon, color: color, size: 20), - const SizedBox(height: 4), - Text( - value, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: color, - ), - ), - Text( - label, - style: TextStyle( - fontSize: 12, - color: widget.theme.secondaryTextColor, - ), - ), - ], - ); - } - Widget _buildSearchBar() { return Container( padding: const EdgeInsets.symmetric(horizontal: 16), @@ -348,18 +360,6 @@ class _YxInspectorPanelState extends State { }, ), ), - const SizedBox(width: 8), - FilterChip( - label: const Text('仅显示错误'), - selected: _showOnlyErrors, - onSelected: (selected) { - setState(() { - _showOnlyErrors = selected; - }); - }, - selectedColor: widget.theme.errorColor.withValues(alpha: 0.2), - backgroundColor: widget.theme.cardColor, - ), ], ), ); @@ -397,98 +397,109 @@ class _YxInspectorPanelState extends State { } Widget _buildLogItem(NetworkLogEntry log) { - return Card( - margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), - color: widget.theme.cardColor, + return Container( + margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 2), + decoration: BoxDecoration( + color: widget.theme.cardColor, + borderRadius: BorderRadius.circular(6), + border: Border.all( + color: log.isSuccess + ? Colors.transparent + : widget.theme.errorColor.withValues(alpha: 0.3), + width: log.isSuccess ? 0 : 1, + ), + ), child: InkWell( onTap: () { _showLogDetail(log); }, - borderRadius: BorderRadius.circular(8), + borderRadius: BorderRadius.circular(6), child: Padding( - padding: const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10), + child: Row( children: [ - // 第一行:方法、状态、时间 - Row( - children: [ - Container( - width: 8, - height: 8, - decoration: BoxDecoration( - color: log.statusColor, - shape: BoxShape.circle, - ), - ), - const SizedBox(width: 8), - Text( - log.method, - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 14, - color: widget.theme.textColor, - ), - ), - const SizedBox(width: 8), - Expanded( - child: Text( - log.statusText, - style: TextStyle( - color: log.statusColor, - fontWeight: FontWeight.bold, - fontSize: 12, - ), - ), - ), - Text( - log.formattedTime, - style: TextStyle( - fontSize: 12, - color: widget.theme.secondaryTextColor, - ), - ), - ], + // 状态指示器 + Container( + width: 6, + height: 6, + decoration: BoxDecoration( + color: log.statusColor, + shape: BoxShape.circle, + ), ), - const SizedBox(height: 8), - // 第二行:URL + const SizedBox(width: 8), + + // 方法标签 + Container( + padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), + decoration: BoxDecoration( + color: _getMethodColor(log.method).withValues(alpha: 0.1), + borderRadius: BorderRadius.circular(4), + ), + child: Text( + log.method, + style: TextStyle( + fontSize: 10, + fontWeight: FontWeight.bold, + color: _getMethodColor(log.method), + ), + ), + ), + const SizedBox(width: 8), + + // URL和状态 + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + log.displayUrl, + style: TextStyle( + fontSize: 13, + color: widget.theme.textColor, + fontWeight: FontWeight.w500, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + const SizedBox(height: 2), + Row( + children: [ + Text( + '${log.statusCode ?? "?"} • ${log.formattedDuration}', + style: TextStyle( + fontSize: 11, + color: log.statusColor, + fontWeight: FontWeight.w500, + ), + ), + if (log.errorMessage != null) ...[ + const SizedBox(width: 8), + Icon( + Icons.error_outline, + size: 12, + color: widget.theme.errorColor, + ), + ], + ], + ), + ], + ), + ), + + // 时间 Text( - log.displayUrl, + log.formattedTime.split(' ')[1], // 只显示时间部分 style: TextStyle( - fontSize: 12, + fontSize: 10, color: widget.theme.secondaryTextColor, ), - maxLines: 2, - overflow: TextOverflow.ellipsis, ), - const SizedBox(height: 8), - // 第三行:耗时和大小 - Row( - children: [ - Text( - '耗时: ${log.formattedDuration}', - style: TextStyle( - fontSize: 12, - color: widget.theme.secondaryTextColor, - ), - ), - const SizedBox(width: 16), - Text( - '大小: ${log.requestSize + log.responseSize} B', - style: TextStyle( - fontSize: 12, - color: widget.theme.secondaryTextColor, - ), - ), - const Spacer(), - Icon( - Icons.arrow_forward_ios, - size: 16, - color: widget.theme.secondaryTextColor.withValues( - alpha: 0.6, - ), - ), - ], + const SizedBox(width: 4), + Icon( + Icons.chevron_right, + size: 16, + color: widget.theme.secondaryTextColor.withValues(alpha: 0.5), ), ], ), @@ -496,4 +507,21 @@ class _YxInspectorPanelState extends State { ), ); } + + Color _getMethodColor(String method) { + switch (method.toUpperCase()) { + case 'GET': + return Colors.blue; + case 'POST': + return Colors.green; + case 'PUT': + return Colors.orange; + case 'DELETE': + return Colors.red; + case 'PATCH': + return Colors.purple; + default: + return widget.theme.secondaryTextColor; + } + } }