單機版 v.0.0.11 20250625
歌檔資料比對
This commit is contained in:
parent
9237edb228
commit
f83410d200
90
app/Console/Commands/CheckFtpSongs.php
Normal file
90
app/Console/Commands/CheckFtpSongs.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Models\Song;
|
||||
|
||||
class CheckFtpSongs extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'songs:check-ftp {disk : 如 DISK01,或 ALL 依序處理多個 DISK}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = '比對 songs.filename 與 FTP 檔案,找出缺失 / 多餘檔案';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$inputDisk = strtoupper($this->argument('disk'));
|
||||
|
||||
$disks = ($inputDisk === 'ALL')
|
||||
? ['DISK01', 'DISK02', 'DISK03', 'DISK04', 'DISK05', 'DISK09', 'DISK10']
|
||||
: [$inputDisk];
|
||||
foreach ($disks as $diskName) {
|
||||
$this->info("========== 🔍 處理 {$diskName} ==========");
|
||||
|
||||
$folder = $diskName;
|
||||
$prefix = $diskName;
|
||||
|
||||
$this->processDisk($folder, $prefix);
|
||||
$this->newLine();
|
||||
}
|
||||
|
||||
$this->info('🎉 所有比對完成!');
|
||||
return self::SUCCESS;
|
||||
}
|
||||
protected function processDisk(string $folder, string $prefix): void
|
||||
{
|
||||
$disk = Storage::disk('ftp_test');
|
||||
|
||||
$this->info("📂 FTP 目錄: {$folder}");
|
||||
$this->info("🎯 DB prefix: {$prefix}");
|
||||
|
||||
// 1) 取得 FTP 檔案清單
|
||||
$this->info('🔍 取得 FTP 檔案列表…');
|
||||
$ftpPaths = collect($disk->allFiles($folder))
|
||||
->map(fn ($p) => strtolower(str_replace('\\', '/', ltrim($p, '/'))))
|
||||
->filter(fn ($p) => Str::startsWith($p, strtolower($prefix)))
|
||||
->unique()
|
||||
->values();
|
||||
|
||||
$this->info("✅ FTP 檔案數:{$ftpPaths->count()}");
|
||||
|
||||
// 2) 資料庫 songs.filename
|
||||
$this->info('🗃️ 讀取資料庫 songs.filename…');
|
||||
$dbPaths = Song::query()
|
||||
->when($prefix, fn ($q) => $q->where('filename', 'like', $prefix . '%'))
|
||||
->pluck('filename')
|
||||
->map(fn ($p) => strtolower(str_replace('\\', '/', $p)))
|
||||
->unique()
|
||||
->values();
|
||||
|
||||
$this->info("✅ DB 記錄數:{$dbPaths->count()}");
|
||||
|
||||
// 3) 比對
|
||||
$missing = $dbPaths->diff($ftpPaths);
|
||||
$extra = $ftpPaths->diff($dbPaths);
|
||||
|
||||
// 4) 結果
|
||||
$this->warn("❌ 缺失檔案(DB 有 / FTP 無):{$missing->count()}");
|
||||
$missing->take(20)->each(fn ($p) => $this->line(" - $p"));
|
||||
if ($missing->count() > 20) $this->line(' …其餘省略');
|
||||
|
||||
$this->info("⚠️ 多餘檔案(FTP 有 / DB 無):{$extra->count()}");
|
||||
$extra->take(20)->each(fn ($p) => $this->line(" - $p"));
|
||||
if ($extra->count() > 20) $this->line(' …其餘省略');
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class CompareSongFiles extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'app:compare-song-files';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Command description';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user