2026-09-28 15:48:35 +08:00
|
|
|
<?php
|
|
|
|
|
/**
|
|
|
|
|
* 简航 SimpleNav —— 一键“全部更新”(分批)。
|
2026-09-28 16:43:10 +08:00
|
|
|
* 批量刷新每个网站的名称与图标;
|
|
|
|
|
* · **保留** 用户自定义简称 short_name
|
|
|
|
|
* · **跳过** 用户自定义图标(icon_custom=1)——只刷新名称
|
2026-09-28 15:48:35 +08:00
|
|
|
* 前端按 offset 分批调用,避免一次请求超时。
|
2026-09-28 16:43:10 +08:00
|
|
|
* 返回:{ done, total, offset, updated, skipped, failed }
|
2026-09-28 15:48:35 +08:00
|
|
|
*/
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
require_once __DIR__ . '/_auth.php';
|
|
|
|
|
require_login();
|
2026-09-28 16:43:10 +08:00
|
|
|
send_no_cache();
|
2026-09-28 15:48:35 +08:00
|
|
|
|
|
|
|
|
header('Content-Type: application/json; charset=utf-8');
|
2026-09-28 16:43:10 +08:00
|
|
|
set_time_limit(90);
|
2026-09-28 15:48:35 +08:00
|
|
|
|
|
|
|
|
$offset = max(0, (int)($_GET['offset'] ?? 0));
|
2026-09-28 16:43:10 +08:00
|
|
|
$limit = min(12, max(1, (int)($_GET['limit'] ?? 3)));
|
2026-09-28 15:48:35 +08:00
|
|
|
$pdo = db();
|
|
|
|
|
|
|
|
|
|
$total = (int)$pdo->query('SELECT COUNT(*) FROM sites')->fetchColumn();
|
2026-09-28 16:43:10 +08:00
|
|
|
$rows = $pdo->query('SELECT id, url, icon_custom FROM sites ORDER BY id LIMIT ' . $limit . ' OFFSET ' . $offset)->fetchAll();
|
2026-09-28 15:48:35 +08:00
|
|
|
|
|
|
|
|
$updated = 0;
|
2026-09-28 16:43:10 +08:00
|
|
|
$skipped = 0;
|
|
|
|
|
$failed = 0;
|
2026-09-28 15:48:35 +08:00
|
|
|
$now = date('Y-m-d H:i:s');
|
|
|
|
|
|
|
|
|
|
foreach ($rows as $row) {
|
|
|
|
|
$url = norm_url((string)$row['url']);
|
2026-09-28 16:43:10 +08:00
|
|
|
$custom = (int)$row['icon_custom'] === 1;
|
|
|
|
|
|
2026-09-28 15:48:35 +08:00
|
|
|
$meta = fetch_site_meta($url);
|
|
|
|
|
$name = $meta['name'] !== '' ? $meta['name'] : $meta['title'];
|
|
|
|
|
|
|
|
|
|
$sets = ['updated_at=?'];
|
|
|
|
|
$args = [$now];
|
|
|
|
|
if ($name !== '') { $sets[] = 'name=?'; $args[] = $name; }
|
2026-09-28 16:43:10 +08:00
|
|
|
|
|
|
|
|
if ($custom) {
|
|
|
|
|
// 用户自定义图标:绝不覆盖
|
|
|
|
|
$skipped++;
|
|
|
|
|
} else {
|
2026-09-28 17:26:40 +08:00
|
|
|
// 键取自记录里存的那条 URL(不用 final_url),保证每次算出来都一样
|
|
|
|
|
$iconFile = download_best_icon($meta['icons'], icon_key($url));
|
2026-09-28 16:43:10 +08:00
|
|
|
if ($iconFile !== '') { $sets[] = 'icon=?'; $args[] = $iconFile; }
|
|
|
|
|
if ($iconFile !== '' || $name !== '') { $updated++; } else { $failed++; }
|
|
|
|
|
}
|
2026-09-28 15:48:35 +08:00
|
|
|
// 注意:这里绝不修改 short_name(用户自定义简称)
|
|
|
|
|
|
|
|
|
|
$args[] = (int)$row['id'];
|
|
|
|
|
try {
|
|
|
|
|
$pdo->prepare('UPDATE sites SET ' . implode(',', $sets) . ' WHERE id=?')->execute($args);
|
|
|
|
|
} catch (Throwable $e) {
|
|
|
|
|
$failed++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$next = $offset + count($rows);
|
|
|
|
|
echo json_encode([
|
|
|
|
|
'done' => $next >= $total || count($rows) === 0,
|
|
|
|
|
'total' => $total,
|
|
|
|
|
'offset' => $next,
|
|
|
|
|
'updated' => $updated,
|
2026-09-28 16:43:10 +08:00
|
|
|
'skipped' => $skipped,
|
2026-09-28 15:48:35 +08:00
|
|
|
'failed' => $failed,
|
|
|
|
|
], JSON_UNESCAPED_UNICODE);
|