完善PR审查后出现的问题
This commit is contained in:
@@ -7,6 +7,7 @@ import 'package:http/http.dart' as http;
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import '../../widgets/desktop_constrained.dart';
|
||||
import '../../widgets/toast_helper.dart';
|
||||
|
||||
enum _NetworkTestTab { network, service, custom }
|
||||
|
||||
@@ -20,6 +21,13 @@ class NetworkTestPage extends StatefulWidget {
|
||||
class _NetworkTestPageState extends State<NetworkTestPage> {
|
||||
static final _panUri = Uri.parse('https://pan.gongyun.org');
|
||||
static final _infoUri = Uri.parse('https://www.gongyun.org/appnetinfo.html');
|
||||
static final _primaryIpLookupUri = Uri.parse('https://ipwho.is/');
|
||||
static final _secondaryIpLookupUri = Uri.parse('https://ipapi.co/json/');
|
||||
static const _probeHeaders = {'Cache-Control': 'no-cache'};
|
||||
static const _probeGetFallbackHeaders = {
|
||||
'Cache-Control': 'no-cache',
|
||||
'Range': 'bytes=0-0',
|
||||
};
|
||||
|
||||
_NetworkTestTab _tab = _NetworkTestTab.network;
|
||||
bool _networkLoading = false;
|
||||
@@ -44,8 +52,7 @@ class _NetworkTestPageState extends State<NetworkTestPage> {
|
||||
IconButton(
|
||||
tooltip: '说明',
|
||||
icon: const Icon(Icons.info_outline),
|
||||
onPressed: () =>
|
||||
launchUrl(_infoUri, mode: LaunchMode.externalApplication),
|
||||
onPressed: () => _openExternalUrl(_infoUri),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -71,7 +78,7 @@ class _NetworkTestPageState extends State<NetworkTestPage> {
|
||||
ButtonSegment(
|
||||
value: _NetworkTestTab.custom,
|
||||
icon: Icon(Icons.route_outlined),
|
||||
label: Text('自定义'),
|
||||
label: Text('自定义线路'),
|
||||
),
|
||||
],
|
||||
selected: {_tab},
|
||||
@@ -129,7 +136,7 @@ class _NetworkTestPageState extends State<NetworkTestPage> {
|
||||
context: context,
|
||||
builder: (dialogContext) => AlertDialog(
|
||||
title: const Text('自定义线路'),
|
||||
content: const Text('此功能暂不可用'),
|
||||
content: const Text('自定义线路为会员功能,当前版本暂未开放。'),
|
||||
actions: [
|
||||
FilledButton(
|
||||
onPressed: () => Navigator.of(dialogContext).pop(),
|
||||
@@ -140,7 +147,20 @@ class _NetworkTestPageState extends State<NetworkTestPage> {
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _openExternalUrl(Uri uri) async {
|
||||
try {
|
||||
final opened = await launchUrl(uri, mode: LaunchMode.externalApplication);
|
||||
if (!opened) {
|
||||
ToastHelper.failure('无法打开链接: $uri');
|
||||
}
|
||||
} catch (e) {
|
||||
ToastHelper.failure('无法打开链接: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _runNetworkTest() async {
|
||||
if (_networkLoading) return;
|
||||
|
||||
setState(() {
|
||||
_networkLoading = true;
|
||||
_networkError = null;
|
||||
@@ -171,6 +191,8 @@ class _NetworkTestPageState extends State<NetworkTestPage> {
|
||||
}
|
||||
|
||||
Future<void> _runServiceTest() async {
|
||||
if (_serviceLoading) return;
|
||||
|
||||
setState(() {
|
||||
_serviceLoading = true;
|
||||
_serviceError = null;
|
||||
@@ -246,7 +268,7 @@ class _NetworkTestPageState extends State<NetworkTestPage> {
|
||||
Future<_IpInfo> _fetchIpInfo() async {
|
||||
try {
|
||||
final response = await http
|
||||
.get(Uri.parse('https://ipwho.is/'))
|
||||
.get(_primaryIpLookupUri)
|
||||
.timeout(const Duration(seconds: 8));
|
||||
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||
final data = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
@@ -270,7 +292,7 @@ class _NetworkTestPageState extends State<NetworkTestPage> {
|
||||
|
||||
try {
|
||||
final response = await http
|
||||
.get(Uri.parse('https://ipapi.co/json/'))
|
||||
.get(_secondaryIpLookupUri)
|
||||
.timeout(const Duration(seconds: 8));
|
||||
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||
final data = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
@@ -307,7 +329,7 @@ class _NetworkTestPageState extends State<NetworkTestPage> {
|
||||
final response = await http
|
||||
.get(
|
||||
Uri.parse('https://status.gongyun.org/api/monitor?pageId=$pageId'),
|
||||
headers: const {'Cache-Control': 'no-cache'},
|
||||
headers: _probeHeaders,
|
||||
)
|
||||
.timeout(const Duration(seconds: 10));
|
||||
if (response.statusCode < 200 || response.statusCode >= 300) {
|
||||
@@ -367,13 +389,19 @@ class _NetworkTestPageState extends State<NetworkTestPage> {
|
||||
}) async {
|
||||
final stopwatch = Stopwatch()..start();
|
||||
try {
|
||||
final response = await http
|
||||
.get(uri, headers: const {'Cache-Control': 'no-cache'})
|
||||
var response = await http
|
||||
.head(uri, headers: _probeHeaders)
|
||||
.timeout(const Duration(seconds: 8));
|
||||
if (_shouldRetryProbeWithGet(response.statusCode)) {
|
||||
response = await http
|
||||
.get(uri, headers: _probeGetFallbackHeaders)
|
||||
.timeout(const Duration(seconds: 8));
|
||||
}
|
||||
stopwatch.stop();
|
||||
final isHealthy = healthyStatusCodes.isEmpty
|
||||
? response.statusCode >= 200 && response.statusCode < 500
|
||||
: healthyStatusCodes.contains(response.statusCode);
|
||||
final isHealthy = _isHealthyStatus(
|
||||
response.statusCode,
|
||||
healthyStatusCodes,
|
||||
);
|
||||
return _ProbeResult(
|
||||
reachable: isHealthy,
|
||||
latencyMs: stopwatch.elapsedMilliseconds,
|
||||
@@ -384,6 +412,17 @@ class _NetworkTestPageState extends State<NetworkTestPage> {
|
||||
}
|
||||
}
|
||||
|
||||
bool _shouldRetryProbeWithGet(int statusCode) {
|
||||
return statusCode == 403 || statusCode == 405 || statusCode == 501;
|
||||
}
|
||||
|
||||
bool _isHealthyStatus(int statusCode, Set<int> healthyStatusCodes) {
|
||||
if (healthyStatusCodes.isNotEmpty) {
|
||||
return healthyStatusCodes.contains(statusCode);
|
||||
}
|
||||
return statusCode >= 200 && statusCode < 500;
|
||||
}
|
||||
|
||||
Future<_StabilityResult> _testStability(Uri uri) async {
|
||||
final latencies = <int>[];
|
||||
var successCount = 0;
|
||||
@@ -438,7 +477,7 @@ class _NetworkPanel extends StatelessWidget {
|
||||
if (loading) const LinearProgressIndicator(),
|
||||
if (error != null) _ErrorText(error!),
|
||||
_InfoRow(
|
||||
label: '公云存储官网访问测试',
|
||||
label: '公云存储网盘访问测试',
|
||||
value: data == null ? '检测中' : (data.panReachable ? '正常' : '离线'),
|
||||
valueColor: _statusColor(context, data?.panReachable),
|
||||
),
|
||||
@@ -463,11 +502,14 @@ class _NetworkPanel extends StatelessWidget {
|
||||
title: '说明',
|
||||
children: const [
|
||||
_DescriptionLine('公云存储作为国际化云存储产品,已接入Cloudflare CDN作为全球加速引擎。'),
|
||||
_DescriptionLine(
|
||||
'当前网络 IP 地址、AS 与运营商信息通过第三方服务 ipwho.is 查询;如该服务不可用,将使用 ipapi.co 作为备用查询。',
|
||||
),
|
||||
_DescriptionLine(
|
||||
'由于部分国家/地区有法律法规限制与审查,可能会出现包括但不限于网络波动、网络丢包以及网络连接不稳定现象',
|
||||
),
|
||||
_DescriptionLine(
|
||||
'如诺出现网络连接问题您可将本页面内容向公云存储团队进行报告,团队会根据相关诊断线索进行排查与优化。',
|
||||
'如若出现网络连接问题,您可将本页面内容向公云存储团队报告,团队会根据相关诊断线索进行排查与优化。',
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user