This commit is contained in:
Developer
2026-04-11 06:05:12 +08:00
parent 855c801fca
commit 346fc795f7
50 changed files with 7697 additions and 1448 deletions

View File

@@ -0,0 +1,32 @@
// 2026-04-11 | verify_categories_detail.dart | 分类数据详细验证 | 检查子分类parent_id字段
import 'dart:convert';
import 'dart:io';
const String baseUrl = 'http://eat.wktyl.com/api';
void main() async {
final uri = Uri.parse('$baseUrl/api.php').replace(queryParameters: {'act': 'categories'});
final client = HttpClient();
client.connectionTimeout = const Duration(seconds: 12);
final request = await client.getUrl(uri);
final response = await request.close();
final body = await response.transform(utf8.decoder).join();
client.close();
final json = jsonDecode(body) as Map<String, dynamic>;
final data = json['data'] as List;
for (final topCat in data) {
final m = topCat as Map<String, dynamic>;
print('=== Top: id=${m['id']}, name=${m['name']} ===');
final children = m['children'] as List?;
if (children != null && children.isNotEmpty) {
print(' children count: ${children.length}');
for (final child in children.take(5)) {
final cm = child as Map<String, dynamic>;
print(' child keys: ${cm.keys.join(', ')}');
print(' child: id=${cm['id'] ?? cm['cate_id']}, name=${cm['name'] ?? cm['cate_name']}, parent_id=${cm['parent_id']}');
}
}
}
}

View File

@@ -0,0 +1,27 @@
// 2026-04-11 | verify_eating_times.dart | 用餐时段数据验证 | 获取eating_times.json数据结构
import 'dart:convert';
import 'dart:io';
void main() async {
final uri = Uri.parse('http://eat.wktyl.com/api/assets/eating_times.json');
final client = HttpClient();
client.connectionTimeout = const Duration(seconds: 12);
final request = await client.getUrl(uri);
final response = await request.close();
final body = await response.transform(utf8.decoder).join();
client.close();
final json = jsonDecode(body);
if (json is List) {
print('Total items: ${json.length}');
for (final item in json.take(5)) {
final m = item as Map<String, dynamic>;
print('keys: ${m.keys.join(', ')}');
print('item: ${jsonEncode(m)}');
print('');
}
} else if (json is Map) {
print('Top-level keys: ${json.keys.join(', ')}');
print(jsonEncode(json).substring(0, 500));
}
}

View File

@@ -0,0 +1,54 @@
// 2026-04-11 | verify_filter_apply.dart | filter_apply接口验证 | 测试不同分类ID的筛选
import 'dart:convert';
import 'dart:io';
const String baseUrl = 'http://eat.wktyl.com/api';
void main() async {
await testFilterApply(category: '12', label: '中国菜(id=12)');
await testFilterApply(category: '13', label: '粤菜(id=13)');
await testFilterApply(category: '11', label: '菜谱(id=11)');
await testFilterApply(tag: '74', label: '粉蒸(tag=74)');
await testFilterApply(category: '12', tag: '74', label: '中国菜+粉蒸');
}
Future<void> testFilterApply({String? category, String? tag, required String label}) async {
print('$label');
final params = <String, String>{'act': 'filter_apply', 'count': '3'};
if (category != null) params['category'] = category;
if (tag != null) params['tag'] = tag;
final uri = Uri.parse('$baseUrl/api_what_to_eat.php').replace(queryParameters: params);
try {
final client = HttpClient();
client.connectionTimeout = const Duration(seconds: 12);
final request = await client.getUrl(uri);
final response = await request.close();
final body = await response.transform(utf8.decoder).join();
client.close();
final json = jsonDecode(body) as Map<String, dynamic>;
final code = json['code'];
final data = json['data'];
if (code == 200 && data != null) {
if (data is Map) {
final recipes = data['recipes'] as List?;
print(' ✅ code=$code, recipes=${recipes?.length ?? 0}');
if (recipes != null && recipes.isNotEmpty) {
for (final r in recipes.take(2)) {
final m = r as Map<String, dynamic>;
print(' - id=${m['id']}, title=${m['title']}');
}
}
} else if (data is List) {
print(' ✅ code=$code, data is List, count=${data.length}');
}
} else {
print(' ❌ code=$code, message=${json['message']}');
}
} catch (e) {
print(' ❌ error: $e');
}
print('');
}

View File

@@ -0,0 +1,40 @@
// 2026-04-11 | verify_recipe_images.dart | 菜谱图片URL验证 | 测试fallback链
import 'dart:io';
void main() async {
final client = HttpClient();
client.connectionTimeout = const Duration(seconds: 8);
final testIds = [1, 150, 1585];
final base = 'http://eat.wktyl.com/api/assets';
for (final id in testIds) {
print('\n--- Testing id=$id ---');
final urls = [
'$base/pic/${id}a.jpg',
'$base/pic/${id}b.jpg',
'$base/pic/$id.jpg',
];
for (final url in urls) {
try {
final req = await client.headUrl(Uri.parse(url));
final resp = await req.close();
print(' ${resp.statusCode == 200 ? "" : ""} $url${resp.statusCode}');
} catch (e) {
print('$url → error: $e');
}
}
}
// Test back.png
try {
final req = await client.headUrl(Uri.parse('$base/back.png'));
final resp = await req.close();
print('\n${resp.statusCode == 200 ? "" : ""} $base/back.png → ${resp.statusCode}');
} catch (e) {
print('\n❌ back.png → error: $e');
}
client.close();
}

View File

@@ -0,0 +1,185 @@
// 2026-04-11 | verify_what_to_eat_api.dart | 今天吃什么接口验证脚本 | 验证filter_apply/categories/tags接口连通性和数据格式
import 'dart:async';
import 'dart:convert';
import 'dart:io';
const String baseUrl = 'http://eat.wktyl.com/api';
const int timeoutSeconds = 12;
const String reset = '\x1B[0m';
const String green = '\x1B[32m';
const String red = '\x1B[31m';
const String yellow = '\x1B[33m';
const String blue = '\x1B[34m';
const String cyan = '\x1B[36m';
void main() async {
printHeader();
await testFilterApply();
await testCategories();
await testTags();
await testFilterSteps();
await testFilterApplyWithCategory();
printSummary();
}
void printHeader() {
print('$cyan═══════════════════════════════════════════════════$reset');
print('$cyan 🎲 今天吃什么 API 接口验证$reset');
print('$cyan═══════════════════════════════════════════════════$reset');
print('');
}
Future<Map<String, dynamic>?> apiGet(String endpoint, Map<String, String> params) async {
final uri = Uri.parse('$baseUrl$endpoint').replace(queryParameters: params);
final stopwatch = Stopwatch()..start();
try {
final client = HttpClient();
client.connectionTimeout = Duration(seconds: timeoutSeconds);
final request = await client.getUrl(uri);
final response = await request.close();
final body = await response.transform(utf8.decoder).join();
stopwatch.stop();
client.close();
if (response.statusCode != 200) {
print('$red ❌ HTTP ${response.statusCode} (${stopwatch.elapsedMilliseconds}ms)$reset');
return null;
}
final json = jsonDecode(body) as Map<String, dynamic>;
print('$green${stopwatch.elapsedMilliseconds}ms | code=${json['code']}$reset');
return json;
} on TimeoutException {
stopwatch.stop();
print('$red ❌ 超时 (${stopwatch.elapsedMilliseconds}ms)$reset');
return null;
} catch (e) {
stopwatch.stop();
print('$red ❌ 错误: $e (${stopwatch.elapsedMilliseconds}ms)$reset');
return null;
}
}
Future<void> testFilterApply() async {
print('$yellow▶ 测试 1: filter_apply (无筛选随机推荐)$reset');
final result = await apiGet('/api_what_to_eat.php', {'act': 'filter_apply', 'count': '5'});
if (result != null) {
final data = result['data'];
if (data is Map) {
final recipes = data['recipes'] as List?;
print(' recipes count: ${recipes?.length ?? 0}');
if (recipes != null && recipes.isNotEmpty) {
final first = recipes.first as Map<String, dynamic>;
print(' first recipe: id=${first['id']}, title=${first['title']}');
print(' fields: ${first.keys.take(15).join(', ')}...');
}
print(' total_matched: ${data['total_matched']}');
print(' filters_applied: ${data['filters_applied']}');
} else if (data is List) {
print(' data is List, count: ${data.length}');
if (data.isNotEmpty) {
final first = data.first as Map<String, dynamic>;
print(' first: id=${first['id']}, title=${first['title']}');
}
}
}
print('');
}
Future<void> testCategories() async {
print('$yellow▶ 测试 2: categories (分类列表)$reset');
final result = await apiGet('/api.php', {'act': 'categories'});
if (result != null) {
final data = result['data'];
if (data is List) {
print(' categories count: ${data.length}');
for (final cat in data.take(5)) {
final m = cat as Map<String, dynamic>;
print(' - id=${m['id'] ?? m['cate_id']}, name=${m['name'] ?? m['cate_name']}, parent_id=${m['parent_id']}');
final children = m['children'] as List?;
if (children != null && children.isNotEmpty) {
print(' children: ${children.length}');
for (final child in children.take(3)) {
final cm = child as Map<String, dynamic>;
print(' - id=${cm['id'] ?? cm['cate_id']}, name=${cm['name'] ?? cm['cate_name']}');
}
}
}
} else {
print(' data type: ${data.runtimeType}');
}
}
print('');
}
Future<void> testTags() async {
print('$yellow▶ 测试 3: tags (标签列表)$reset');
final result = await apiGet('/api.php', {'act': 'tags'});
if (result != null) {
final data = result['data'];
if (data is List) {
print(' tags count: ${data.length}');
for (final tag in data.take(5)) {
final m = tag as Map<String, dynamic>;
print(' - id=${m['id'] ?? m['tag_id']}, name=${m['name'] ?? m['tag_name']}');
}
} else {
print(' data type: ${data.runtimeType}');
}
}
print('');
}
Future<void> testFilterSteps() async {
print('$yellow▶ 测试 4: filter_steps (筛选步骤)$reset');
final result = await apiGet('/api_what_to_eat.php', {'act': 'filter_steps'});
if (result != null) {
final data = result['data'];
if (data is Map) {
print(' keys: ${data.keys.join(', ')}');
final steps = data['steps'] as List?;
if (steps != null) {
print(' steps count: ${steps.length}');
for (final step in steps.take(3)) {
final m = step as Map<String, dynamic>;
print(' - step: ${m['step']}, title: ${m['title']}, type: ${m['type']}');
final options = m['options'] as List? ?? m['available_options'] as List? ?? [];
print(' options: ${options.length}');
}
}
final available = data['available_options'] as List?;
if (available != null) {
print(' available_options count: ${available.length}');
}
}
}
print('');
}
Future<void> testFilterApplyWithCategory() async {
print('$yellow▶ 测试 5: filter_apply (带分类筛选)$reset');
final result = await apiGet('/api_what_to_eat.php', {'act': 'filter_apply', 'category': '1', 'count': '3'});
if (result != null) {
final data = result['data'];
if (data is Map) {
final recipes = data['recipes'] as List?;
print(' recipes count: ${recipes?.length ?? 0}');
if (recipes != null && recipes.isNotEmpty) {
for (final r in recipes.take(3)) {
final m = r as Map<String, dynamic>;
print(' - id=${m['id']}, title=${m['title']}');
}
}
} else if (data is List) {
print(' data is List, count: ${data.length}');
}
}
print('');
}
void printSummary() {
print('$cyan═══════════════════════════════════════════════════$reset');
print('$cyan 验证完成$reset');
print('$cyan═══════════════════════════════════════════════════$reset');
}