迷你卡片

This commit is contained in:
Developer
2026-04-14 05:35:30 +08:00
parent 5ce8759a18
commit c26ff354ee
195 changed files with 38057 additions and 1842 deletions

View File

@@ -1,206 +0,0 @@
/*
* 文件: test_discover_api.dart
* 名称: 发现页API测试脚本
* 作用: 验证 api_discover.php 接口返回的新字段
* 创建时间: 2026-04-13
* 更新时间: 2026-04-13
*
* 运行方式: dart run scripts/test_discover_api.dart
*/
import 'dart:convert';
import 'dart:io';
const String baseUrl = 'https://eat.wktyl.com/api';
const String discoverEndpoint = '/api_discover.php';
void main(List<String> args) async {
print('========================================');
print(' 发现页 API 接口测试');
print(' 测试时间: ${DateTime.now().toString().split('.')[0]}');
print('========================================\n');
try {
await testBasicRequest();
await testCustomParams();
await testRefreshParam();
await testNewFields();
await testMultipleRequests();
print('\n✅ 所有测试完成!');
} catch (e, stackTrace) {
print('\n❌ 测试失败: $e');
print('Stack trace: $stackTrace');
}
}
Future<void> testBasicRequest() async {
print('📋 测试1: 基础请求(默认参数)');
print('----------------------------------------');
final url = Uri.parse('$baseUrl$discoverEndpoint?total=20');
final response = await _makeRequest(url);
if (response['code'] == 200) {
final data = response['data'] as Map<String, dynamic>;
print(' ✅ 请求成功');
print(' - 菜谱数量: ${(data['recipes'] as List).length}');
print(' - 食材数量: ${(data['ingredients'] as List).length}');
print(' - 分类数量: ${(data['categories'] as List).length}');
print(' - 标签数量: ${(data['tags'] as List).length}');
print(' - 营养成分数量: ${(data['nutrition_types'] as List).length}');
print(' - 用餐时段数量: ${(data['meal_times'] as List).length}');
print(' - 查询时间: ${response['_query_time']}');
print(' - 缓存状态: ${response['meta']?['cache_status'] ?? 'unknown'}');
} else {
print(' ❌ 请求失败: ${response['message']}');
}
print('');
}
Future<void> testCustomParams() async {
print('📋 测试2: 自定义参数请求');
print('----------------------------------------');
final url = Uri.parse(
'$baseUrl$discoverEndpoint?recipe=5&ingredient=3&category=4&tag=5&nutrition=2&meal_time=2',
);
final response = await _makeRequest(url);
if (response['code'] == 200) {
final data = response['data'] as Map<String, dynamic>;
print(' ✅ 请求成功');
print(' - 菜谱数量: ${(data['recipes'] as List).length} (预期: 5)');
print(' - 食材数量: ${(data['ingredients'] as List).length} (预期: 3)');
print(' - 分类数量: ${(data['categories'] as List).length} (预期: 4)');
print(' - 标签数量: ${(data['tags'] as List).length} (预期: 5)');
print(' - 营养成分数量: ${(data['nutrition_types'] as List).length} (预期: 2)');
print(' - 用餐时段数量: ${(data['meal_times'] as List).length} (预期: 2)');
} else {
print(' ❌ 请求失败: ${response['message']}');
}
print('');
}
Future<void> testRefreshParam() async {
print('📋 测试3: 强制刷新参数');
print('----------------------------------------');
final url = Uri.parse('$baseUrl$discoverEndpoint?total=10&_refresh=1');
final response = await _makeRequest(url);
if (response['code'] == 200) {
print(' ✅ 请求成功');
print(' - 缓存状态: ${response['meta']?['cache_status'] ?? 'unknown'}');
print(' - 请求次数: ${response['meta']?['request_count'] ?? 0}');
final cacheHeader = response['_cache_header'] ?? '';
print(' - X-Cache Header: $cacheHeader');
} else {
print(' ❌ 请求失败: ${response['message']}');
}
print('');
}
Future<void> testNewFields() async {
print('📋 测试4: 验证新字段');
print('----------------------------------------');
final url = Uri.parse('$baseUrl$discoverEndpoint?category=10');
final response = await _makeRequest(url);
if (response['code'] == 200) {
final data = response['data'] as Map<String, dynamic>;
final categories = data['categories'] as List;
print(' ✅ 分类数据验证:');
for (var i = 0; i < categories.length && i < 3; i++) {
final cat = categories[i] as Map<String, dynamic>;
print(' ---');
print(' 分类 ${i + 1}:');
print(' - id: ${cat['id']}');
print(' - name: ${cat['name']}');
print(' - type: ${cat['type']}');
print(' - count: ${cat['count']}');
print(' - recipe_count: ${cat['recipe_count']} (新字段)');
print(' - ingredient_count: ${cat['ingredient_count']} (新字段)');
print(' - parent_id: ${cat['parent_id']}');
print(' - parent_name: ${cat['parent_name']} (新字段)');
}
final tags = data['tags'] as List;
print(' ✅ 标签数据验证:');
for (var i = 0; i < tags.length && i < 3; i++) {
final tag = tags[i] as Map<String, dynamic>;
print(' ---');
print(' 标签 ${i + 1}:');
print(' - id: ${tag['id']}');
print(' - name: ${tag['name']}');
print(' - type: ${tag['type']}');
print(' - count: ${tag['count']} (已修复)');
}
} else {
print(' ❌ 请求失败: ${response['message']}');
}
print('');
}
Future<void> testMultipleRequests() async {
print('📋 测试5: 多次请求去重验证');
print('----------------------------------------');
final recipeIds = <int>{};
final categoryIds = <int>{};
for (var i = 0; i < 3; i++) {
final url = Uri.parse('$baseUrl$discoverEndpoint?total=15');
final response = await _makeRequest(url);
if (response['code'] == 200) {
final data = response['data'] as Map<String, dynamic>;
final recipes = data['recipes'] as List;
final categories = data['categories'] as List;
final newRecipeIds =
recipes.map((r) => (r as Map<String, dynamic>)['id'] as int).toSet();
final newCategoryIds =
categories.map((c) => (c as Map<String, dynamic>)['id'] as int).toSet();
final duplicateRecipes = recipeIds.intersection(newRecipeIds);
final duplicateCategories = categoryIds.intersection(newCategoryIds);
print(' 请求 ${i + 1}:');
print(' - 新菜谱: ${newRecipeIds.length}');
print(' - 重复菜谱: ${duplicateRecipes.length}');
print(' - 新分类: ${newCategoryIds.length}');
print(' - 重复分类: ${duplicateCategories.length}');
recipeIds.addAll(newRecipeIds);
categoryIds.addAll(newCategoryIds);
await Future.delayed(const Duration(milliseconds: 500));
} else {
print(' ❌ 请求 ${i + 1} 失败: ${response['message']}');
}
}
print(' ✅ 去重验证完成');
print(' - 总计菜谱ID: ${recipeIds.length}');
print(' - 总计分类ID: ${categoryIds.length}');
print('');
}
Future<Map<String, dynamic>> _makeRequest(Uri url) async {
final client = HttpClient();
try {
final request = await client.getUrl(url);
final response = await request.close();
final body = await response.transform(utf8.decoder).join();
final result = json.decode(body) as Map<String, dynamic>;
result['_cache_header'] = response.headers.value('X-Cache') ?? '';
return result;
} finally {
client.close();
}
}

View File

@@ -0,0 +1,146 @@
// 2026-04-14 | test_discover_image.dart | Discover图片数据验证 | 验证api_discover.php返回的cover/picId字段
// 运行: dart run scripts/test_discover_image.dart
import 'dart:convert';
import 'dart:io';
const String baseUrl = 'https://eat.wktyl.com/api';
Future<void> main() async {
print('=== Discover 图片数据验证 ===\n');
await testDiscoverApi();
await testDetailApi();
await testImageUrl();
}
Future<void> testDiscoverApi() async {
print('📡 测试 api_discover.php 接口');
final client = HttpClient();
try {
final url = Uri.parse('$baseUrl/api_discover.php?total=10');
print(' 请求URL: $url');
final request = await client.getUrl(url);
request.headers.set('Accept', 'application/json');
final response = await request.close();
final body = await response.transform(utf8.decoder).join();
if (body.isEmpty) {
print(' ❌ 响应体为空');
return;
}
final json = jsonDecode(body) as Map<String, dynamic>;
print(' code: ${json['code']}');
final data = json['data'] as Map<String, dynamic>?;
if (data == null) {
print(' ❌ data字段为null');
return;
}
final recipes = data['recipes'] as List?;
if (recipes == null || recipes.isEmpty) {
print(' ❌ recipes为空');
return;
}
print(' 菜谱数量: ${recipes.length}');
print('');
for (int i = 0; i < recipes.length && i < 5; i++) {
final recipe = recipes[i] as Map<String, dynamic>;
print(' ─── 菜谱 #${i + 1} ───');
print(' id: ${recipe['id']}');
print(' title: ${recipe['title']}');
print(' cover: ${recipe['cover']}');
print(' pic_id: ${recipe['pic_id']}');
print(' picId: ${recipe['picId']}');
print(' pic: ${recipe['pic']}');
final allKeys = recipe.keys.toList();
print(' 所有字段: $allKeys');
final cover = recipe['cover'] ?? '';
if (cover.isNotEmpty) {
final regex = RegExp(r'/pic/(\d+)[ab]?\.(jpg|png|webp)$');
final match = regex.firstMatch(cover.toString());
if (match != null) {
print(' ✅ 从cover提取picId: ${match.group(1)}');
} else {
print(' ⚠️ cover不匹配picId正则: $cover');
}
} else {
print(' ❌ cover为空');
}
print('');
}
} catch (e) {
print(' ❌ 请求失败: $e');
} finally {
client.close();
}
}
Future<void> testDetailApi() async {
print('\n📡 测试 api.php?act=detail 接口对比picId字段');
final client = HttpClient();
try {
final url = Uri.parse('$baseUrl/api.php?act=detail&id=32390');
print(' 请求URL: $url');
final request = await client.getUrl(url);
request.headers.set('Accept', 'application/json');
final response = await request.close();
final body = await response.transform(utf8.decoder).join();
if (body.isEmpty) return;
final json = jsonDecode(body) as Map<String, dynamic>;
final data = json['data'] as Map<String, dynamic>?;
if (data == null) return;
print(' id: ${data['id']}');
print(' title: ${data['title']}');
print(' cover: ${data['cover']}');
print(' pic_id: ${data['pic_id']}');
print(' picId: ${data['picId']}');
print(' pic: ${data['pic']}');
final allKeys = data.keys.toList();
print(' 所有字段: $allKeys');
} catch (e) {
print(' ❌ 请求失败: $e');
} finally {
client.close();
}
}
Future<void> testImageUrl() async {
print('\n📡 测试图片URL可访问性');
final client = HttpClient();
try {
final testUrls = [
'https://eat.wktyl.com/api/assets/pic/32390a.jpg',
'https://eat.wktyl.com/api/assets/pic/32390b.jpg',
'https://eat.wktyl.com/api/assets/pic/32390.jpg',
];
for (final url in testUrls) {
try {
final request = await client.getUrl(Uri.parse(url));
final response = await request.close();
print(
' $url${response.statusCode} (${response.contentLength} bytes)',
);
} catch (e) {
print(' $url → ❌ $e');
}
}
} finally {
client.close();
}
}

View File

@@ -0,0 +1,55 @@
/*
* 文件: test_ingredient_cache.dart
* 名称: 食材缓存测试脚本
* 作用: 验证食材缓存服务的读写功能
* 创建: 2026-04-14
*/
import 'dart:io';
void main() async {
print('========================================');
print('食材缓存测试脚本');
print('========================================\n');
// 测试 API 接口
await testIngredientApi();
print('\n========================================');
print('测试完成');
print('========================================');
}
Future<void> testIngredientApi() async {
final testIds = [849, 1248, 1, 1206, 1209];
for (final id in testIds) {
print('\n--- 测试食材 ID: $id ---');
try {
final client = HttpClient();
final request = await client.getUrl(
Uri.parse('https://eat.wktyl.com/api/api.php?act=ingredient_detail&id=$id'),
);
final response = await request.close();
final body = await response.transform(const SystemEncoding().decoder).join();
print('状态码: ${response.statusCode}');
print('响应长度: ${body.length} 字符');
if (body.isNotEmpty && body.startsWith('{')) {
print('✅ API 响应正常');
} else {
print('❌ API 响应异常');
}
client.close();
} catch (e) {
print('❌ 请求失败: $e');
}
// 延迟避免请求过快
await Future.delayed(const Duration(milliseconds: 500));
}
}

View File

@@ -1,23 +0,0 @@
/*
* 测试 qr 包 API
*/
import 'package:qr/qr.dart';
void main() {
final qrCode = QrCode.fromData(
data: 'https://example.com',
errorCorrectLevel: QrErrorCorrectLevel.M,
);
print('Module count: ${qrCode.moduleCount}');
print('QR Code type: ${qrCode.runtimeType}');
// 检查可用的方法和属性
final mirror = reflect(qrCode);
final instance = mirror.type;
print('Available methods:');
for (final method in instance.declarations.keys) {
print(' - $method');
}
}

View File

@@ -1,152 +0,0 @@
/*
* 文件: test_recipe_code.dart
* 作用: 测试菜谱code字段验证二维码海报功能所需数据
* 创建: 2026-04-13
*/
import 'dart:convert';
import 'dart:io';
const String baseUrl = 'http://eat.wktyl.com/api';
Future<void> main() async {
final client = HttpClient();
print('=== 菜谱 Code 字段测试 ===\n');
// 测试1: detail接口是否返回code字段
print('📋 测试1: detail接口 code字段');
try {
final url = Uri.parse('$baseUrl/api.php?act=detail&id=32892');
final request = await client.getUrl(url);
final response = await request.close();
final body = await response.transform(utf8.decoder).join();
final data = json.decode(body);
if (data['code'] == 200) {
final recipe = data['data'];
print(' ✅ 菜谱标题: ${recipe['title']}');
print(' ✅ Code字段: ${recipe['code']}');
print(' ✅ Pic_id: ${recipe['pic_id']}');
print(' ✅ Statistics: ${recipe['statistics']}');
} else {
print(' ❌ 接口返回错误: ${data['message']}');
}
} catch (e) {
print(' ❌ 请求失败: $e');
}
print('');
// 测试2: full接口是否返回code字段
print('📋 测试2: full接口 code字段');
try {
final url = Uri.parse('$baseUrl/api.php?act=full&id=32892');
final request = await client.getUrl(url);
final response = await request.close();
final body = await response.transform(utf8.decoder).join();
final data = json.decode(body);
if (data['code'] == 200) {
final recipe = data['data'];
print(' ✅ 菜谱标题: ${recipe['title']}');
print(' ✅ Code字段: ${recipe['code']}');
print(' ✅ Category: ${recipe['category']}');
print(' ✅ Allergens: ${recipe['allergens']}');
}
} catch (e) {
print(' ❌ 请求失败: $e');
}
print('');
// 测试3: what_to_eat detail接口通过code查询
print('📋 测试3: what_to_eat detail接口 code查询');
try {
final url =
Uri.parse('$baseUrl/api_what_to_eat.php?act=detail&code=CP032892');
final request = await client.getUrl(url);
final response = await request.close();
final body = await response.transform(utf8.decoder).join();
final data = json.decode(body);
if (data['code'] == 200) {
final recipe = data['data'];
print(' ✅ 通过code查询成功: ${recipe['title']}');
} else {
print(' ❌ code查询失败: ${data['message']}');
}
} catch (e) {
print(' ❌ 请求失败: $e');
}
print('');
// 测试4: mini接口是否返回code字段
print('📋 测试4: mini接口 code字段');
try {
final url = Uri.parse('$baseUrl/api.php?act=mini&id=32892');
final request = await client.getUrl(url);
final response = await request.close();
final body = await response.transform(utf8.decoder).join();
final data = json.decode(body);
if (data['code'] == 200) {
final recipe = data['data'];
print(' ✅ 菜谱标题: ${recipe['title']}');
print(' ✅ Code字段: ${recipe['code']}');
print(' ✅ 返回字段: ${recipe.keys.toList()}');
}
} catch (e) {
print(' ❌ 请求失败: $e');
}
print('');
// 测试5: feed recommend接口
print('📋 测试5: feed recommend接口');
try {
final url = Uri.parse('$baseUrl/api_feed.php?act=recommend&page=1&limit=3');
final request = await client.getUrl(url);
final response = await request.close();
final body = await response.transform(utf8.decoder).join();
final data = json.decode(body);
if (data['code'] == 200) {
final items = data['data'] as List;
print(' ✅ 推荐数量: ${items.length}');
for (final item in items) {
print(
' - ${item['title']} (code: ${item['code']}, views: ${item['statistics']?['view_count']})');
}
}
} catch (e) {
print(' ❌ 请求失败: $e');
}
print('');
// 测试6: filter_apply接口每日菜单规划用
print('📋 测试6: filter_apply接口 三餐推荐');
for (final meal in ['早餐', '中餐', '晚餐']) {
try {
final url = Uri.parse(
'$baseUrl/api_what_to_eat.php?act=filter_apply&count=2&meal_time=$meal');
final request = await client.getUrl(url);
final response = await request.close();
final body = await response.transform(utf8.decoder).join();
final data = json.decode(body);
if (data['code'] == 200) {
final items = data['data'] as List;
final titles = items.map((e) => e['title']).join(', ');
print('$meal: $titles');
}
} catch (e) {
print('$meal 请求失败: $e');
}
}
print('\n=== 测试完成 ===');
client.close();
}

View File

@@ -1,153 +0,0 @@
/*
* 文件: test_recipe_code_v2.dart
* 作用: 测试feed recommend和filter_apply接口的真实数据结构
* 创建: 2026-04-13
*/
import 'dart:convert';
import 'dart:io';
const String baseUrl = 'http://eat.wktyl.com/api';
Future<void> main() async {
final client = HttpClient();
// 测试1: feed recommend接口真实结构
print('📋 测试1: feed recommend接口');
try {
final url = Uri.parse('$baseUrl/api_feed.php?act=recommend&page=1&limit=3');
final request = await client.getUrl(url);
final response = await request.close();
final body = await response.transform(utf8.decoder).join();
final data = json.decode(body) as Map<String, dynamic>;
if (data['code'] == 200) {
final d = data['data'];
if (d is List) {
print(' data是List, 长度: ${d.length}');
for (final item in d) {
print(' - ${(item as Map)['title']}');
}
} else if (d is Map) {
print(' data是Map, keys: ${d.keys.toList()}');
final items = d['items'] ?? d['list'] ?? d['recipes'];
if (items is List) {
print(' 列表字段长度: ${items.length}');
for (final item in items) {
print(' - ${(item as Map)['title']}');
}
} else {
print(' data内容: ${d.toString().substring(0, 200)}...');
}
}
}
} catch (e) {
print(' ❌ 请求失败: $e');
}
print('');
// 测试2: filter_apply接口真实结构
print('📋 测试2: filter_apply接口');
try {
final url = Uri.parse(
'$baseUrl/api_what_to_eat.php?act=filter_apply&count=2&meal_time=早餐');
final request = await client.getUrl(url);
final response = await request.close();
final body = await response.transform(utf8.decoder).join();
final data = json.decode(body) as Map<String, dynamic>;
if (data['code'] == 200) {
final d = data['data'];
if (d is List) {
print(' data是List, 长度: ${d.length}');
for (final item in d) {
print(' - ${(item as Map)['title']}');
}
} else if (d is Map) {
print(' data是Map, keys: ${d.keys.toList()}');
final items = d['items'] ?? d['list'] ?? d['recipes'];
if (items is List) {
print(' 列表字段长度: ${items.length}');
for (final item in items) {
print(' - ${(item as Map)['title']}');
}
} else {
print(' data内容: ${d.toString().substring(0, 300)}...');
}
}
}
} catch (e) {
print(' ❌ 请求失败: $e');
}
print('');
// 测试3: filter_apply无meal_time参数
print('📋 测试3: filter_apply无meal_time');
try {
final url =
Uri.parse('$baseUrl/api_what_to_eat.php?act=filter_apply&count=3');
final request = await client.getUrl(url);
final response = await request.close();
final body = await response.transform(utf8.decoder).join();
final data = json.decode(body) as Map<String, dynamic>;
if (data['code'] == 200) {
final d = data['data'];
if (d is List) {
print(' data是List, 长度: ${d.length}');
for (final item in d) {
print(' - ${(item as Map)['title']}');
}
} else if (d is Map) {
print(' data是Map, keys: ${d.keys.toList()}');
final items = d['items'] ?? d['list'] ?? d['recipes'];
if (items is List) {
print(' 列表字段长度: ${items.length}');
for (final item in items) {
print(' - ${(item as Map)['title']}');
}
} else {
print(' data内容: ${d.toString().substring(0, 300)}...');
}
}
}
} catch (e) {
print(' ❌ 请求失败: $e');
}
print('');
// 测试4: filter_recipes接口 meal_time参数
print('📋 测试4: filter_recipes接口 meal_time参数');
try {
final url = Uri.parse(
'$baseUrl/api_filter.php?act=filter_recipes&meal_time=早餐&limit=3');
final request = await client.getUrl(url);
final response = await request.close();
final body = await response.transform(utf8.decoder).join();
final data = json.decode(body) as Map<String, dynamic>;
if (data['code'] == 200) {
final d = data['data'];
if (d is Map) {
print(' data是Map, keys: ${d.keys.toList()}');
final items = d['items'] ?? d['list'];
if (items is List) {
print(' 列表长度: ${items.length}');
for (final item in items) {
print(' - ${(item as Map)['title']}');
}
}
} else if (d is List) {
print(' data是List, 长度: ${d.length}');
}
}
} catch (e) {
print(' ❌ 请求失败: $e');
}
print('\n=== 测试完成 ===');
client.close();
}

View File

@@ -1,151 +0,0 @@
// 2026-04-13 | test_recipe_detail_api.dart | 详情页API测试 | 验证详情页API返回数据
// 运行: dart run scripts/test_recipe_detail_api.dart
import 'dart:convert';
import 'dart:io';
const String baseUrl = 'https://eat.wktyl.com/api';
Future<void> main() async {
print('=== 详情页API测试 ===\n');
// 先获取一个有效的recipe ID
print('📡 步骤1: 获取有效的recipe ID');
final discoverUrl = Uri.parse(
'$baseUrl/api_discover.php?total=10&recipe=10&ingredient=0&category=0&tag=0&nutrition=0&meal_time=0',
);
final discoverClient = HttpClient();
try {
final discoverRequest = await discoverClient.getUrl(discoverUrl);
final discoverResponse = await discoverRequest.close();
final discoverBody = await discoverResponse.transform(utf8.decoder).join();
final discoverJson = jsonDecode(discoverBody) as Map<String, dynamic>;
final discoverData = discoverJson['data'] as Map<String, dynamic>;
final recipes = discoverData['recipes'] as List;
if (recipes.isEmpty) {
print(' ❌ 没有找到recipe');
return;
}
final testId = recipes.first['id'];
print(' ✅ 找到recipe ID: $testId');
// 测试详情API
await testDetailApi(testId);
} catch (e) {
print(' ❌ 错误: $e');
} finally {
discoverClient.close();
}
}
Future<void> testDetailApi(int id) async {
print('\n📡 步骤2: 测试详情API (id=$id)');
final client = HttpClient();
try {
// 测试 api.php?act=full&id=xxx
final url = Uri.parse('$baseUrl/api.php?act=full&id=$id');
print(' 请求URL: $url');
final request = await client.getUrl(url);
final response = await request.close();
print(' 状态码: ${response.statusCode}');
final body = await response.transform(utf8.decoder).join();
print(' 响应长度: ${body.length} 字符');
final json = jsonDecode(body) as Map<String, dynamic>;
print(' code: ${json['code']}');
print(' message: ${json['message']}');
if (json['code'] != 200) {
print(' ❌ API返回错误');
return;
}
final data = json['data'] as Map<String, dynamic>?;
if (data == null) {
print(' ❌ data字段为null');
return;
}
print('\n ✅ 详情数据加载成功');
print(' ─────────────────────────────');
print(' id: ${data['id']}');
print(' code: ${data['code']}');
print(' pic_id: ${data['pic_id']}');
print(' title: ${data['title']}');
print(' intro: ${(data['intro'] as String?)?.substring(0, (data['intro'] as String?)?.length.clamp(0, 50) ?? 0)}...');
print(' content: ${(data['content'] as String?)?.substring(0, (data['content'] as String?)?.length.clamp(0, 50) ?? 0)}...');
print(' cover: ${data['cover']}');
print(' status: ${data['status']}');
print(' create_time: ${data['create_time']}');
print(' update_time: ${data['update_time']}');
print(' ─────────────────────────────');
// 检查关键字段
print('\n 关键字段检查:');
print(' - id存在: ${data.containsKey('id')}');
print(' - title存在: ${data.containsKey('title')}');
print(' - cover存在: ${data.containsKey('cover')}');
print(' - intro存在: ${data.containsKey('intro')}');
print(' - content存在: ${data.containsKey('content')}');
// 检查是否有ingredients
print(' - ingredients存在: ${data.containsKey('ingredients')}');
if (data['ingredients'] != null) {
final ingredients = data['ingredients'];
if (ingredients is List) {
print(' - ingredients数量: ${ingredients.length}');
} else if (ingredients is Map) {
print(' - ingredients是Map: ${ingredients.keys}');
}
}
// 检查是否有steps
print(' - steps存在: ${data.containsKey('steps')}');
if (data['steps'] != null) {
final steps = data['steps'];
if (steps is List) {
print(' - steps数量: ${steps.length}');
}
}
// 检查是否有nutrition
print(' - nutrition存在: ${data.containsKey('nutrition')}');
if (data['nutrition'] != null) {
print(' - nutrition: ${data['nutrition']}');
}
// 检查是否有tags
print(' - tags存在: ${data.containsKey('tags')}');
if (data['tags'] != null) {
final tags = data['tags'];
if (tags is List) {
print(' - tags数量: ${tags.length}');
}
}
// 检查是否有category
print(' - category存在: ${data.containsKey('category')}');
if (data['category'] != null) {
print(' - category: ${data['category']}');
}
// 检查是否有statistics
print(' - statistics存在: ${data.containsKey('statistics')}');
if (data['statistics'] != null) {
print(' - statistics: ${data['statistics']}');
}
print('\n 所有字段: ${data.keys.toList()}');
} catch (e, stackTrace) {
print(' ❌ 请求错误: $e');
print(' 堆栈: $stackTrace');
} finally {
client.close();
}
}