fix: [attach] 短代码跨文章全局解析 + 缺失残留清理;损坏附件导入降级不中断;media 导入幂等;sablog:import 支持 sqlite 老库 + 5 个导入自动化测试

This commit is contained in:
ak
2026-08-11 19:16:16 +08:00
parent e735967218
commit 34ea046906
92 changed files with 340 additions and 12 deletions
+44 -8
View File
@@ -16,6 +16,19 @@ class AttachmentImporter
*/
public function create(int $postId, array $row, ?string $attachmentsDir, bool $syncNow): Media
{
$legacyId = (int) ($row['attachmentid'] ?? 0);
// 幂等:同一老附件已成功导入过则直接复用
$existing = Media::query()
->where('collection_name', 'attachments')
->where('custom_properties->legacy_attachmentid', $legacyId)
->latest('id')
->first();
if ($existing && ! $existing->getCustomProperty('pending_sync')) {
return $existing;
}
$post = Post::find($postId);
// 游离附件(articleid=0 或对应文章不存在)统一挂到 id=0 占位文章上
@@ -36,16 +49,39 @@ class AttachmentImporter
$source = $this->locateSource($row['filepath'] ?? null, $attachmentsDir);
if ($source && $syncNow) {
$media = $post->addMedia($source)
->preservingOriginal()
->withCustomProperties($properties)
->usingFileName(basename($row['filename']) ?: basename($source))
->toMediaCollection('attachments', MediaDisk::name());
try {
$media = $post->addMedia($source)
->preservingOriginal()
->withCustomProperties($properties)
->usingFileName(basename($row['filename']) ?: basename($source))
->toMediaCollection('attachments', MediaDisk::name());
$media->setCustomProperty('pending_sync', false);
$media->save();
$media->setCustomProperty('pending_sync', false);
$media->save();
return $media;
return $media;
} catch (\Throwable $e) {
// addMedia 可能已插入记录并保存文件,仅缩略图生成失败:找回该记录标记完成
$existing = Media::query()
->where('collection_name', 'attachments')
->where('custom_properties->legacy_attachmentid', (int) ($row['attachmentid'] ?? 0))
->latest('id')
->first();
if ($existing) {
$existing->setCustomProperty('pending_sync', false);
$existing->save();
return $existing;
}
// 文件损坏无法入库时降级为 pending,不中断整批导入
\Illuminate\Support\Facades\Log::warning('附件导入失败,已降级为待同步', [
'attachment' => $row['attachmentid'] ?? null,
'file' => $source,
'error' => $e->getMessage(),
]);
}
}
return $this->createPendingRecord($post->id, $row, $properties);