| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- <?php
- namespace App\Console\Commands;
- use App\Models\MpGenerateVideoTask;
- use App\Services\PointsService;
- use Illuminate\Console\Command;
- use Illuminate\Support\Facades\DB;
- class BackfillVideoTokensCommand extends Command
- {
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'points:backfill-video-tokens
- {--dry-run : 只统计将回填的记录数,不实际更新}
- {--limit= : 最多处理记录数(默认全部)}';
- /**
- * The console command description.
- *
- * @var string
- */
- protected $description = '回填视频积分明细缺失的 token(历史 bug:扣费时读取到未同步的 result_json 导致 tokens_consumed=0)';
- /**
- * Execute the console command.
- *
- * @param PointsService $pointsService
- * @return int
- */
- public function handle(PointsService $pointsService)
- {
- $dryRun = (bool)$this->option('dry-run');
- $limit = (int)$this->option('limit');
- if ($limit < 0) {
- $limit = 0;
- }
- $query = DB::table('mp_user_points_details as d')
- ->leftJoin('mp_generate_video_tasks as t', 't.id', '=', 'd.task_id')
- ->where('d.type', 'video')
- ->where('d.points_consumed', '>', 0)
- ->where('d.tokens_consumed', 0)
- ->select('d.id', 'd.task_id', 't.api_type', 't.result_json');
- $total = (clone $query)->count();
- $this->info("待回填明细总数: {$total}" . ($dryRun ? '(dry-run 模式,不更新)' : ''));
- if ($total <= 0) {
- return 0;
- }
- if ($limit > 0) {
- $query->limit($limit);
- $this->info("本次最多处理: {$limit} 条");
- }
- $updated = 0;
- $skipped = 0;
- $notFound = 0;
- $rows = $query->get();
- $bar = $this->output->createProgressBar($rows->count());
- $bar->start();
- foreach ($rows as $row) {
- $bar->advance();
- if (!$row->task_id || $row->result_json === null) {
- $skipped++;
- continue;
- }
- $task = new MpGenerateVideoTask();
- $task->api_type = (string)$row->api_type;
- $task->result_json = $row->result_json;
- try {
- $tokens = $pointsService->getVideoTokensConsumed($task);
- } catch (\Throwable $e) {
- dLog('points')->warning('视频 token 回填解析异常', [
- 'detail_id' => $row->id,
- 'task_id' => $row->task_id,
- 'error' => $e->getMessage(),
- ]);
- $skipped++;
- continue;
- }
- if ($tokens <= 0) {
- $skipped++;
- continue;
- }
- if (!$dryRun) {
- DB::table('mp_user_points_details')
- ->where('id', $row->id)
- ->update([
- 'tokens_consumed' => $tokens,
- 'updated_at' => date('Y-m-d H:i:s'),
- ]);
- }
- $updated++;
- }
- $bar->finish();
- $this->newLine(2);
- $this->info("可回填: {$updated} 条" . ($dryRun ? '(dry-run 未写入)' : ',已写入'));
- $this->info("跳过(任务缺失/无 token 数据): {$skipped} 条");
- if ($updated > 0 && !$dryRun) {
- dLog('points')->info('视频积分明细 token 历史回填完成', [
- 'updated' => $updated,
- 'skipped' => $skipped,
- ]);
- }
- return 0;
- }
- }
|