day >= 20) { $startAt = $tz->copy()->setDay(5)->startOfDay(); $endAt = $tz->copy()->setDay(19)->endOfDay(); } elseif ($tz->day >= 5) { $startAt = $tz->copy()->subMonthNoOverflow()->set('day', 20)->startOfDay(); $endAt = $tz->copy()->set('day', 4)->endOfDay(); } else { $startAt = $tz->copy()->subMonthNoOverflow()->setDay(5)->startOfDay(); $endAt = $startAt->copy()->subMonthNoOverflow()->setDay(19)->endOfDay(); } $head = '【'.$startAt->format('Y/m/d').'-'.$endAt->format('Y/m/d').'】'; // 如果不是强制执行,则需检查是否已结算过 if (! $this->option('force') && Cache::has($this->cacheKey($startAt, $endAt))) { return $this->warn("{$head}管理津贴已结算"); } $this->info("{$head}------------[开始]管理津贴结算------------"); if ($this->option('force')) { $this->info("{$head}正在删除旧数据..."); DealerEarning::manageSubsidy()->where('start_at', $startAt)->where('end_at', $endAt)->delete(); $this->info("{$head}数据删除成功"); } $this->info("{$head}数据写入中..."); $this->settle($startAt, $endAt); $this->info("{$head}写入成功, 总耗时: ".$this->formatDuration($tz->diffInMilliseconds(now(), false))); $this->info("{$head}------------[结束]管理津贴结算------------".PHP_EOL); Cache::put($this->cacheKey($startAt, $endAt), 1, 24*3600*22); return 0; } /** * 管理津贴结算结算 * * @param \Illuminate\Support\Carbon $startAt * @param \Illuminate\Support\Carbon $endAt * @return void */ protected function settle(Carbon $startAt, Carbon $endAt): void { $subsidies = DealerManageSubsidyLog::select('user_id', DB::raw('sum(total_amount) as total_amount')) ->whereBetween('order_completed_at', [$startAt, $endAt]) ->groupBy('user_id') ->get(); // 手续费比例(百分比) $time = now()->toDateTimeString(); $feeRate = app_settings('dealer.fee_rate'); $data = []; foreach ($subsidies as $key => $subsidy) { if ($key > 0 && $key%500 === 0) { DealerEarning::insert($data); $data = []; $time = now()->toDateTimeString(); } $fee = bcmul(bcdiv($feeRate, '100', 10), $subsidy->total_amount, 3); $data[] = [ 'user_id' => $subsidy->user_id, 'total_amount' => $subsidy->total_amount, 'fee' => $fee, 'fee_rate' => $feeRate, 'type' => DealerEarningType::ManageSubsidy, 'start_at' => $startAt, 'end_at' => $endAt, 'status' => DealerEarningStatus::Pending, 'created_at' => $time, 'updated_at' => $time, ]; } DealerEarning::insert($data); } /** * 生成缓存的 key * * @param \Illuminate\Support\Carbon $startAt * @param \Illuminate\Support\Carbon $endAt * @return void */ protected function cacheKey(Carbon $startAt, Carbon $endAt) { $startAt->format('Ymd').'_'.$endAt->format('Ymd').'_dealer_manage_subsidy'; } /** * 格式化时间 * * @param float $milliseconds * @return string */ protected function formatDuration($milliseconds): string { if ($milliseconds < 0.01) { return round($milliseconds * 1000) . 'μs'; } elseif ($milliseconds >= 1000) { return round($milliseconds / 1000, 2) . 's'; } return $milliseconds . 'ms'; } }