diff --git a/app/Console/Commands/Dealer/ManageSubsidySettleCommand.php b/app/Console/Commands/Dealer/ManageSubsidySettleCommand.php index 5725b429..2610d69f 100644 --- a/app/Console/Commands/Dealer/ManageSubsidySettleCommand.php +++ b/app/Console/Commands/Dealer/ManageSubsidySettleCommand.php @@ -2,14 +2,14 @@ namespace App\Console\Commands\Dealer; -use App\Enums\DealerEarningStatus; -use App\Enums\DealerEarningType; use App\Enums\DealerLvl; +use App\Enums\DealerManageSubsidyStatus; use App\Models\Dealer; -use App\Models\DealerEarning; +use App\Models\DealerManageSubsidy; use Illuminate\Console\Command; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Facades\DB; class ManageSubsidySettleCommand extends Command { @@ -62,8 +62,10 @@ class ManageSubsidySettleCommand extends Command $head = '【'.$startAt->format('Y/m/d').'-'.$endAt->format('Y/m/d').'】'; + $cacheKey = $this->cacheKey($startAt, $endAt); + // 如果不是强制执行,则需检查是否已结算过 - if (! $this->option('force') && Cache::has($this->cacheKey($startAt, $endAt))) { + if (! $this->option('force') && Cache::has($cacheKey)) { return $this->warn("{$head}管理津贴已结算"); } @@ -71,7 +73,7 @@ class ManageSubsidySettleCommand extends Command if ($this->option('force')) { $this->info("{$head}正在删除旧数据..."); - DealerEarning::manageSubsidy()->where('start_at', $startAt)->where('end_at', $endAt)->delete(); + DealerManageSubsidy::where('start_at', $startAt)->where('end_at', $endAt)->delete(); $this->info("{$head}数据删除成功"); } @@ -81,7 +83,7 @@ class ManageSubsidySettleCommand extends Command $this->info("{$head}------------[结束]管理津贴结算------------".PHP_EOL); - Cache::put($this->cacheKey($startAt, $endAt), 1, $endAt->tomorrow()); + Cache::put($cacheKey, 1, $tz->addDays(17)); return 0; } @@ -99,7 +101,7 @@ class ManageSubsidySettleCommand extends Command $feeRate = app_settings('dealer.fee_rate'); $lastId = Cache::get( - $key = $this->cacheKey($startAt, $endAt).':last_id' + $cacheKey = $this->cacheKey($startAt, $endAt).':last_id' ); do { @@ -107,20 +109,19 @@ class ManageSubsidySettleCommand extends Command ->forPageAfterId($count, $lastId, 'id') ->get(); - $countDealers = $dealers->count(); + $dealersCount = $dealers->count(); - if ($countDealers == 0) { + if ($dealersCount == 0) { break; } $earnings = []; - $time = now()->toDateTimeString(); + $tz = now()->toDateTimeString(); foreach ($dealers as $dealer) { - $totalAmount = $dealer->manageSubsidyLogs() - ->whereBetween('order_completed_at', [$startAt, $endAt]) - ->sum('total_amount'); + [$totalAmount, $remark] = $this->calculateTotalAmount($dealer, $startAt, $endAt); + // 如果 补贴总金额 > 0,则添加管理者补贴记录 if (bccomp($totalAmount, '0', 2) === 1) { // 计算手续费 $fee = bcmul($totalAmount, bcdiv($feeRate, '100', 10), 2); @@ -128,31 +129,70 @@ class ManageSubsidySettleCommand extends Command $earnings[] = [ 'user_id' => $dealer->user_id, 'total_amount' => $totalAmount, + 'real_amount' => bcsub($totalAmount, $fee, 2), 'fee' => $fee, 'fee_rate' => $feeRate, - 'type' => DealerEarningType::ManageSubsidy, 'start_at' => $startAt, 'end_at' => $endAt, 'lvl' => $dealer->lvl, 'is_manager' => $dealer->is_manager, - 'status' => DealerEarningStatus::Pending, - 'description' => '管理津贴', - 'created_at' => $time, - 'updated_at' => $time, + 'status' => DealerManageSubsidyStatus::Pending, + 'remark' => $remark, + 'created_at' => $tz, + 'updated_at' => $tz, ]; } $lastId = $dealer->id; } - DealerEarning::insert($earnings); + DealerManageSubsidy::insert($earnings); - Cache::put($key, $lastId, $endAt); + Cache::put($cacheKey, $lastId, $endAt); unset($dealers, $earnings); - } while ($countDealers == $count); + } while ($dealersCount == $count); - Cache::forget($key); + Cache::forget($cacheKey); + } + + /** + * 计算补贴总金额 + * + * @param \App\Models\Dealer + * @param \Illuminate\Support\Carbon $startAt + * @param \Illuminate\Support\Carbon $endAt + * @return array + */ + protected function calculateTotalAmount(Dealer $dealer, Carbon $startAt, Carbon $endAt): array + { + $subsidyLogs = $dealer->manageSubsidyLogs() + ->with(['product']) + ->select([ + 'product_id', + DB::raw('sum(sales_volume) as sales_volume'), + DB::raw('sum(total_amount) as total_amount'), + ]) + ->whereBetween('order_completed_at', [$startAt, $endAt]) + ->groupBy('product_id') + ->get(); + + // 补贴总金额 + $totalAmount = 0; + // 备注信息 + $remark = ''; + + foreach ($subsidyLogs as $subsidyLog) { + $totalAmount = bcadd($totalAmount, $subsidyLog->total_amount, 2); + + if ($remark !== '') { + $remark .= "\n"; + } + + $remark .= "【{$subsidyLog->product->name}】销量: {$subsidyLog->sales_volume}, 补贴金额: {$subsidyLog->total_amount}"; + } + + return [$totalAmount, $remark]; } /** diff --git a/app/Enums/DealerEarningType.php b/app/Enums/DealerEarningType.php deleted file mode 100644 index 4b60878b..00000000 --- a/app/Enums/DealerEarningType.php +++ /dev/null @@ -1,9 +0,0 @@ - DealerLvl::None, + 'is_manager' => false, + ]; + + protected $casts = [ + 'lvl' => DealerLvl::class, + 'is_manager' => 'bool', + 'start_at' => 'datetime', + 'end_at' => 'datetime', + 'status' => DealerManageSubsidyStatus::class, + ]; + + protected $fillable = [ + 'user_id', + 'lvl', + 'is_manager', + 'total_amount', + 'real_amount', + 'fee', + 'fee_rate', + 'start_at', + 'end_at', + 'status', + 'remark', + ]; +} diff --git a/app/Models/DealerManageSubsidyLog.php b/app/Models/DealerManageSubsidyLog.php index 44a12fd2..52f7a939 100644 --- a/app/Models/DealerManageSubsidyLog.php +++ b/app/Models/DealerManageSubsidyLog.php @@ -29,4 +29,12 @@ class DealerManageSubsidyLog extends Model { return $this->belongsTo(Dealer::class, 'user_id', 'user_id'); } + + /** + * 此管理津贴所属的商品 + */ + public function product() + { + return $this->belongsTo(DealerProduct::class, 'product_id'); + } } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 9f18a523..d8724d65 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -46,6 +46,7 @@ class AppServiceProvider extends ServiceProvider 'admin_users' => \App\Models\Admin\Administrator::class, 'quota_v1_send_logs' => \App\Models\QuotaV1SendLog::class, 'dealer_manager_subsidy' => \App\Models\DealerManagerSubsidy::class, + 'dealer_manage_subsidy' => \App\Models\DealerManageSubsidy::class, ]); JsonResource::withoutWrapping(); diff --git a/database/migrations/2022_01_16_200142_create_dealer_manage_subsidies_table.php b/database/migrations/2022_01_16_200142_create_dealer_manage_subsidies_table.php new file mode 100644 index 00000000..6a0adcfa --- /dev/null +++ b/database/migrations/2022_01_16_200142_create_dealer_manage_subsidies_table.php @@ -0,0 +1,46 @@ +id(); + $table->unsignedBigInteger('user_id')->comment('经销商的用户ID'); + $table->tinyInteger('lvl')->comment('经销商等级'); + $table->boolean('is_manager')->default(false)->comment('是否是管理者'); + $table->unsignedDecimal('total_amount', 10, 2)->comment('总金额'); + $table->unsignedDecimal('real_amount', 10, 2)->comment('实际金额=总金额-手续费'); + $table->unsignedDecimal('fee', 10, 2)->default(0)->comment('手续费'); + $table->unsignedDecimal('fee_rate', 4, 2)->default(0)->comment('手续费率(百分比)'); + $table->timestamp('start_at')->comment('结算开始时间'); + $table->timestamp('end_at')->comment('结算结束时间'); + $table->tinyInteger('status')->default(0)->comment('状态: 0 待处理'); + $table->text('remark')->nullable()->comment('备注'); + $table->timestamps(); + + $table->unique(['user_id', 'start_at', 'end_at']); + $table->index(['start_at', 'end_at']); + $table->index('status'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('dealer_manage_subsidies'); + } +}