详细页优化
This commit is contained in:
32
scripts/debug_timestamp.dart
Normal file
32
scripts/debug_timestamp.dart
Normal file
@@ -0,0 +1,32 @@
|
||||
// 时间戳调试脚本
|
||||
void main() {
|
||||
final timestamp = 146085838541;
|
||||
|
||||
print('🔍 时间戳调试');
|
||||
print('原始值: $timestamp (${timestamp.toString().length}位)');
|
||||
|
||||
// 尝试不同的解析方式
|
||||
print('\n方式1: 当作毫秒 (直接使用)');
|
||||
final d1 = DateTime.fromMillisecondsSinceEpoch(timestamp);
|
||||
print('结果: ${d1.year}-${d1.month}-${d1.day} ${d1.hour}:${d1.minute}');
|
||||
|
||||
print('\n方式2: 当作秒 (×1000转毫秒)');
|
||||
final d2 = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
|
||||
print('结果: ${d2.year}-${d2.month}-${d2.day} ${d2.hour}:${d2.minute}');
|
||||
|
||||
print('\n方式3: 除以1000当作秒 (可能是微秒?)');
|
||||
final d3 = DateTime.fromMillisecondsSinceEpoch((timestamp / 1000).round() * 1000);
|
||||
print('结果: ${d3.year}-${d3.month}-${d3.day} ${d3.hour}:${d3.minute}');
|
||||
|
||||
// 2016年的正确时间戳
|
||||
print('\n--- 参考值 ---');
|
||||
final date2016 = DateTime(2016, 4, 18, 15, 35);
|
||||
print('2016-04-18 15:35 的毫秒时间戳: ${date2016.millisecondsSinceEpoch}');
|
||||
print('2016-04-18 15:35 的秒时间戳: ${date2016.millisecondsSinceEpoch ~/ 1000}');
|
||||
|
||||
// 检查是否差1000倍
|
||||
final correctMs = 1460858385000; // 13位
|
||||
print('\n如果是13位: $correctMs');
|
||||
final d4 = DateTime.fromMillisecondsSinceEpoch(correctMs);
|
||||
print('结果: ${d4.year}-${d4.month}-${d4.day} ${d4.hour}:${d4.minute}');
|
||||
}
|
||||
173
scripts/test_pic_id_api.dart
Normal file
173
scripts/test_pic_id_api.dart
Normal file
@@ -0,0 +1,173 @@
|
||||
// 2026-04-11 | test_pic_id_api | 测试API连通性+完整Fallback链
|
||||
// 用法: dart scripts/test_pic_id_api.dart
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
const String _baseUrl = 'http://eat.wktyl.com/api';
|
||||
const String _picBase = 'http://eat.wktyl.com/api/assets/pic';
|
||||
|
||||
void main() async {
|
||||
print('API 连通性 + 完整图片Fallback链测试\n');
|
||||
|
||||
await testApiConnectivity();
|
||||
await testPicIdField();
|
||||
await testFullFallbackChain();
|
||||
await testMultipleRecipes();
|
||||
|
||||
print('✅ 全部测试完成');
|
||||
}
|
||||
|
||||
Future<void> testApiConnectivity() async {
|
||||
print('📡 [1/4] API 基础连通性');
|
||||
|
||||
final endpoints = [
|
||||
('api.php?act=list&page=1&limit=3', '菜谱列表'),
|
||||
('api.php?act=categories&type=recipe', '分类列表'),
|
||||
('api.php?act=tags&limit=5', '标签列表'),
|
||||
('assets/back.png', '默认图back.png'),
|
||||
];
|
||||
|
||||
for (final (path, name) in endpoints) {
|
||||
try {
|
||||
final sw = Stopwatch()..start();
|
||||
final url = path.startsWith('assets')
|
||||
? '$_baseUrl/$path'
|
||||
: '$_baseUrl/$path';
|
||||
final result = await httpGet(url);
|
||||
sw.stop();
|
||||
|
||||
if (path.startsWith('assets')) {
|
||||
print(' ✅ $name (${sw.elapsedMilliseconds}ms, ${result.length}B)');
|
||||
} else if (result['code'] == 200) {
|
||||
print(' ✅ $name (${sw.elapsedMilliseconds}ms)');
|
||||
} else {
|
||||
print(' ❌ $name → code=${result['code']}');
|
||||
}
|
||||
} catch (e) {
|
||||
print(' ❌ $name → $e'.substring(0, 50));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> testPicIdField() async {
|
||||
print('[2/4] pic_id 字段解析');
|
||||
|
||||
try {
|
||||
final result = await httpGet('$_baseUrl/api.php?act=full&id=32891');
|
||||
final data = result['data'];
|
||||
if (data == null) {
|
||||
print('❌ 无数据');
|
||||
return;
|
||||
}
|
||||
|
||||
print('菜谱: ${data['title']} (#${data['id']})');
|
||||
print('pic_id: ${data['pic_id']}, recipe_id: ${data['id']}');
|
||||
|
||||
if (data['pic_id'] != null) {
|
||||
print('✅ pic_id 有效');
|
||||
} else {
|
||||
print('⚠️ pic_id 为null,回退使用 recipe_id');
|
||||
}
|
||||
} catch (e) {
|
||||
print('❌ 异常: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> testFullFallbackChain() async {
|
||||
print('[3/4] 完整Fallback链可达性测试 (pic_id=7640)');
|
||||
|
||||
const int picId = 7640;
|
||||
|
||||
final chain = [
|
||||
('① coverUrl', '', false),
|
||||
('② {picId}a.jpg', '$_picBase/${picId}a.jpg', true),
|
||||
('③ {picId}b.jpg', '$_picBase/${picId}b.jpg', true),
|
||||
('④ {picId}.jpg', '$_picBase/$picId.jpg', true),
|
||||
('⑤ back.png', '$_baseUrl/assets/back.png', true),
|
||||
('⑥ 本地error.png', 'assets/data/photos/error.png', false),
|
||||
('⑦ 空白占位', '', false),
|
||||
];
|
||||
|
||||
for (final (label, url, isNetwork) in chain) {
|
||||
if (url.isEmpty) {
|
||||
if (label.contains('本地')) {
|
||||
final file = File(url);
|
||||
if (file.existsSync()) {
|
||||
print('✅ $label → 文件存在');
|
||||
} else {
|
||||
print('❌ $label → 文件不存在');
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
final sw = Stopwatch()..start();
|
||||
|
||||
Uint8List? bytes;
|
||||
int statusCode;
|
||||
|
||||
if (isNetwork) {
|
||||
final client = HttpClient();
|
||||
client.connectionTimeout = const Duration(seconds: 6);
|
||||
final req = await client.getUrl(Uri.parse(url));
|
||||
final resp = await req.close();
|
||||
statusCode = resp.statusCode;
|
||||
final bb = await resp.fold<BytesBuilder>(
|
||||
BytesBuilder(),
|
||||
(b, d) => b..add(d),
|
||||
);
|
||||
bytes = bb.toBytes();
|
||||
client.close();
|
||||
} else {
|
||||
bytes = File(url).readAsBytesSync();
|
||||
statusCode = 200;
|
||||
}
|
||||
|
||||
sw.stop();
|
||||
|
||||
final ok = isNetwork
|
||||
? (statusCode == 200 && (bytes?.length ?? 0) > 100)
|
||||
: (bytes != null && bytes!.length > 0);
|
||||
|
||||
if (ok) {
|
||||
final sizeKB = ((bytes!.length) / 1024).toStringAsFixed(1);
|
||||
print('✅ $label → ${sw.elapsedMilliseconds}ms ($sizeKB KB)');
|
||||
} else {
|
||||
print('⚠️ $label → HTTP $statusCode (${bytes?.length ?? 0}B)');
|
||||
}
|
||||
} catch (e) {
|
||||
print('❌ $label → 异常');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> testMultipleRecipes() async {
|
||||
print('[4/4] 多菜谱 pic_id 对比');
|
||||
|
||||
for (final id in [32891, 32892, 32893]) {
|
||||
try {
|
||||
final r = await httpGet('$_baseUrl/api.php?act=full&id=$id');
|
||||
final d = r['data'];
|
||||
if (d == null) continue;
|
||||
|
||||
final rid = d['id'];
|
||||
final pid = d['pic_id'];
|
||||
final diff = (rid == pid) ? '⚠️相同' : '✅不同';
|
||||
|
||||
print('#$rid pic_id=$pid $diff');
|
||||
} catch (_) {}
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> httpGet(String url) async {
|
||||
final client = HttpClient();
|
||||
client.connectionTimeout = const Duration(seconds: 10);
|
||||
final request = await client.getUrl(Uri.parse(url));
|
||||
final response = await request.close();
|
||||
final body = await response.transform(utf8.decoder).join();
|
||||
client.close();
|
||||
return json.decode(body) as Map<String, dynamic>;
|
||||
}
|
||||
Reference in New Issue
Block a user