更新若干功能

This commit is contained in:
2026-08-19 08:16:49 +08:00
parent 4979bb83d2
commit 72bc6502eb
56 changed files with 3627 additions and 343 deletions

View File

@@ -28,11 +28,11 @@ use Throwable;
*/
class MaterialService extends BaseService
{
/** 单次同步默认条数:一屏够看,又不至于把请求跑到超时 */
private const SYNC_DEFAULT_LIMIT = 200;
/** 单次同步默认条数:七牛列举 + 入库要压在网关超时之前 */
private const SYNC_DEFAULT_LIMIT = 80;
/** 单次同步上限,防止前端把 limit 传成十万 */
private const SYNC_MAX_LIMIT = 1000;
/** 单次同步上限;再大前端默认 10s、1panel 60s 都容易掐断 */
private const SYNC_MAX_LIMIT = 200;
/** 分批取值 / 分批回写的批大小 */
private const CHUNK_SIZE = 1000;
@@ -198,6 +198,7 @@ class MaterialService extends BaseService
$result = [
'inserted' => 0,
'updated' => 0,
'listed' => count($items),
'next_marker' => (string) ($page['next_marker'] ?? ''),
'finished' => (bool) ($page['finished'] ?? true),
];
@@ -217,7 +218,7 @@ class MaterialService extends BaseService
$seen[$key] = true;
$url = (string) ($item['url'] ?? '');
$hash = (string) ($item['hash'] ?? '');
$ext = strtolower((string) pathinfo($key, PATHINFO_EXTENSION));
$ext = FileModel::extOfKey($key);
$row = $byPath[$key] ?? $byUrl[$url] ?? ($hash !== '' ? ($byHash[$hash] ?? null) : null);
if ($row !== null) {
@@ -252,7 +253,10 @@ class MaterialService extends BaseService
];
}
if (!empty($pending)) {
FileModel::insert($pending);
// 上百行一条 INSERT 容易把 SQL 撑到数兆,拆开更稳也更快提交
foreach (array_chunk($pending, 50) as $slice) {
FileModel::insert($slice);
}
$result['inserted'] = count($pending);
}
return $result;
@@ -473,12 +477,33 @@ class MaterialService extends BaseService
private function existingIndexOf(array $items): array
{
$paths = array_values(array_unique(array_column($items, 'key')));
$urls = array_values(array_unique(array_filter(array_column($items, 'url'))));
$hashes = array_values(array_unique(array_filter(array_column($items, 'hash'))));
$select = ['id', 'name', 'url', 'path', 'ext', 'type', 'hash', 'oss_config_id'];
$byPath = [];
$byUrl = [];
$byHash = [];
// 先只走 path 索引OSS 拉取的对象都有真实 key一条 whereIn 比 path/url/hash 三路 OR 快得多
if (!empty($paths)) {
foreach (FileModel::where('deleted_at', 0)->whereIn('path', $paths)->get($select) as $row) {
$path = (string) $row->path;
if ($path !== '') {
$byPath[$path] = $row;
}
}
}
$missed = array_values(array_filter(
$items,
static fn ($item) => !isset($byPath[(string) ($item['key'] ?? '')])
));
if ($missed === []) {
return [$byPath, $byUrl, $byHash];
}
$urls = array_values(array_unique(array_filter(array_column($missed, 'url'))));
$hashes = array_values(array_unique(array_filter(array_column($missed, 'hash'))));
if ($urls === [] && $hashes === []) {
return [$byPath, $byUrl, $byHash];
}
$rows = FileModel::where('deleted_at', 0)
->where(function ($q) use ($paths, $urls, $hashes) {
$q->whereIn('path', $paths);
->where(function ($q) use ($urls, $hashes) {
if (!empty($urls)) {
$q->orWhereIn('url', $urls);
}
@@ -488,22 +513,14 @@ class MaterialService extends BaseService
});
}
})
->get(['id', 'name', 'url', 'path', 'ext', 'type', 'hash', 'oss_config_id']);
$byPath = [];
$byUrl = [];
$byHash = [];
->get($select);
foreach ($rows as $row) {
$path = (string) $row->path;
$url = (string) $row->url;
$hash = (string) $row->hash;
if ($path !== '') {
$byPath[$path] = $row;
}
if ($url !== '' && !isset($byUrl[$url])) {
$byUrl[$url] = $row;
}
if ($path === '' && $hash !== '' && !isset($byHash[$hash])) {
if ((string) $row->path === '' && $hash !== '' && !isset($byHash[$hash])) {
$byHash[$hash] = $row;
}
}