feat: 新增壁纸图库组件和编辑器功能优化
- 新增壁纸图库相关组件(WallpaperGalleryView/WallpaperSearchBar等) - 优化编辑器主题服务和系统UI管理 - 新增虚线边框和拖拽描边风格支持 - 完善今日诗词服务和阅读报告功能 - 修复多个UI问题和空指针异常 - 更新依赖库版本和SVG资源 - 优化交互动画和状态管理 - 补充文档和API测试脚本
This commit is contained in:
196
scripts/api_verify.dart
Normal file
196
scripts/api_verify.dart
Normal file
@@ -0,0 +1,196 @@
|
||||
// ============================================================
|
||||
// 闲言APP — 接口连通性验证脚本
|
||||
// 创建时间: 2026-05-02
|
||||
// 更新时间: 2026-05-02
|
||||
// 作用: 验证壁纸API + 今日诗词SDK的连通性和性能
|
||||
// 上次更新: 初始创建
|
||||
// ============================================================
|
||||
|
||||
// 使用方法: dart run scripts/api_verify.dart
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
void main() async {
|
||||
print('═══════════════════════════════════════════');
|
||||
print(' 闲言APP — 接口连通性验证');
|
||||
print(' ${DateTime.now().toIso8601String()}');
|
||||
print('═══════════════════════════════════════════\n');
|
||||
|
||||
// 1. 壁纸 API
|
||||
await _verifyWallpaperApi();
|
||||
|
||||
// 2. 今日诗词 SDK
|
||||
await _verifyJinrishiciSdk();
|
||||
|
||||
print('\n═══════════════════════════════════════════');
|
||||
print(' 验证完成');
|
||||
print('═══════════════════════════════════════════');
|
||||
}
|
||||
|
||||
Future<void> _verifyWallpaperApi() async {
|
||||
print('┌─────────────────────────────────────────┐');
|
||||
print('│ 🖼️ 壁纸 API 验证 │');
|
||||
print('└─────────────────────────────────────────┘\n');
|
||||
|
||||
final baseUrl = 'http://bz.wktyl.com';
|
||||
final endpoints = [
|
||||
{
|
||||
'name': 'Unsplash',
|
||||
'path': '/api_unsplash.php',
|
||||
'params': 'limit=5&page=1',
|
||||
},
|
||||
{
|
||||
'name': '360壁纸',
|
||||
'path': '/api_360_bing.php',
|
||||
'params': 'limit=5&page=1&source=360',
|
||||
},
|
||||
{
|
||||
'name': '必应壁纸',
|
||||
'path': '/api_360_bing.php',
|
||||
'params': 'limit=5&page=1&source=bing',
|
||||
},
|
||||
{'name': 'Pexels', 'path': '/api_pexels.php', 'params': 'limit=5&page=1'},
|
||||
{'name': 'Pixabay', 'path': '/api_pixabay.php', 'params': 'limit=5&page=1'},
|
||||
{
|
||||
'name': 'WallSt',
|
||||
'path': '/api_wallstreet.php',
|
||||
'params': 'limit=5&page=1',
|
||||
},
|
||||
];
|
||||
|
||||
for (final ep in endpoints) {
|
||||
final url = '$baseUrl${ep['path']}?${ep['params']}';
|
||||
await _testEndpoint(ep['name']!, url);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _verifyJinrishiciSdk() async {
|
||||
print('\n┌─────────────────────────────────────────┐');
|
||||
print('│ 📜 今日诗词 SDK 验证 │');
|
||||
print('└─────────────────────────────────────────┘\n');
|
||||
|
||||
// Step 1: Token
|
||||
final tokenUrl = 'https://v2.jinrishici.com/token';
|
||||
String? token;
|
||||
|
||||
final tokenResult = await _testEndpoint('Token 获取', tokenUrl);
|
||||
if (tokenResult != null) {
|
||||
try {
|
||||
final data = jsonDecode(tokenResult) as Map<String, dynamic>;
|
||||
token = data['data'] as String?;
|
||||
if (token != null) {
|
||||
print(' ✅ Token: ${token.substring(0, 20)}...');
|
||||
}
|
||||
} catch (e) {
|
||||
print(' ⚠️ Token 解析失败: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2: Sentence
|
||||
final sentenceUrl = 'https://v2.jinrishici.com/sentence';
|
||||
final headers = token != null ? {'X-User-Token': token} : <String, String>{};
|
||||
final sentenceResult = await _testEndpoint(
|
||||
'每日诗词',
|
||||
sentenceUrl,
|
||||
headers: headers,
|
||||
);
|
||||
|
||||
if (sentenceResult != null) {
|
||||
try {
|
||||
final data = jsonDecode(sentenceResult) as Map<String, dynamic>;
|
||||
final content = data['data']?['content'] as String?;
|
||||
final origin = data['data']?['origin'] as Map<String, dynamic>?;
|
||||
final title = origin?['title'] as String?;
|
||||
final author = origin?['author'] as String?;
|
||||
final dynasty = origin?['dynasty'] as String?;
|
||||
print(' 📝 内容: $content');
|
||||
print(' 📖 来源: 《$title》${dynasty ?? ''}·${author ?? ''}');
|
||||
} catch (e) {
|
||||
print(' ⚠️ 诗词解析失败: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3: Info (天气数据)
|
||||
final infoUrl = 'https://v2.jinrishici.com/info';
|
||||
final infoResult = await _testEndpoint('用户信息+天气', infoUrl, headers: headers);
|
||||
|
||||
if (infoResult != null) {
|
||||
try {
|
||||
final data = jsonDecode(infoResult) as Map<String, dynamic>;
|
||||
final infoData = data['data'] as Map<String, dynamic>?;
|
||||
final region = infoData?['region'] as String?;
|
||||
final weatherData = infoData?['weatherData'] as Map<String, dynamic>?;
|
||||
print(' 📍 地区: $region');
|
||||
if (weatherData != null) {
|
||||
print(' 🌡️ 温度: ${weatherData['temperature']}°C');
|
||||
print(' 🌤️ 天气: ${weatherData['weather']}');
|
||||
print(' 💧 湿度: ${weatherData['humidity']}%');
|
||||
print(' 🌬️ 风向: ${weatherData['windDirection']}');
|
||||
print(' 💨 风力: ${weatherData['windPower']}级');
|
||||
if (weatherData['pm25'] != null) {
|
||||
print(' 🫁 PM2.5: ${weatherData['pm25']}');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print(' ⚠️ 信息解析失败: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<String?> _testEndpoint(
|
||||
String name,
|
||||
String url, {
|
||||
Map<String, String>? headers,
|
||||
}) async {
|
||||
final sw = Stopwatch()..start();
|
||||
try {
|
||||
final client = HttpClient();
|
||||
client.connectionTimeout = const Duration(seconds: 10);
|
||||
|
||||
final request = await client.getUrl(Uri.parse(url));
|
||||
headers?.forEach((k, v) => request.headers.set(k, v));
|
||||
|
||||
final response = await request.close();
|
||||
final body = await response.transform(utf8.decoder).join();
|
||||
sw.stop();
|
||||
|
||||
final status = response.statusCode;
|
||||
final ms = sw.elapsedMilliseconds;
|
||||
final size = body.length;
|
||||
|
||||
final statusIcon = status == 200 ? '✅' : '❌';
|
||||
final perfIcon = ms < 500
|
||||
? '🟢'
|
||||
: ms < 2000
|
||||
? '🟡'
|
||||
: '🔴';
|
||||
|
||||
print(' $statusIcon $name');
|
||||
print(' URL: $url');
|
||||
print(
|
||||
' 状态码: $status | 响应时间: ${ms}ms $perfIcon | 大小: ${_formatSize(size)}',
|
||||
);
|
||||
|
||||
if (status != 200) {
|
||||
print(
|
||||
' 响应: ${body.substring(0, body.length > 200 ? 200 : body.length)}',
|
||||
);
|
||||
}
|
||||
|
||||
client.close();
|
||||
return status == 200 ? body : null;
|
||||
} catch (e) {
|
||||
sw.stop();
|
||||
print(' ❌ $name');
|
||||
print(' URL: $url');
|
||||
print(' 错误: $e (${sw.elapsedMilliseconds}ms)');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
String _formatSize(int bytes) {
|
||||
if (bytes < 1024) return '$bytes B';
|
||||
if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)} KB';
|
||||
return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB';
|
||||
}
|
||||
Reference in New Issue
Block a user