diff --git a/app/Console/Commands/Dealer/OrderProcessCommand.php b/app/Console/Commands/Dealer/OrderProcessCommand.php index 25aba9d0..6fed95da 100644 --- a/app/Console/Commands/Dealer/OrderProcessCommand.php +++ b/app/Console/Commands/Dealer/OrderProcessCommand.php @@ -4,6 +4,7 @@ namespace App\Console\Commands\Dealer; use App\Models\Dealer; use App\Models\DealerManagerSalesLog; +use App\Models\DealerManageSubsidyLog; use App\Models\DealerOrder; use App\Models\UserInfo; use Illuminate\Console\Command; @@ -34,13 +35,16 @@ class OrderProcessCommand extends Command public function handle() { DealerOrder::chunkById(200, function ($orders) { - $orders->load(['userInfo.dealer', 'products']); + $orders->load([ + 'userInfo.dealer', + 'products.productManageSubsidyRules', + ]); foreach ($orders as $order) { try { DB::beginTransaction(); - $this->processOrder($order); + $this->handleDealerOrder($order); DB::commit(); } catch (Throwable $e) { @@ -57,31 +61,139 @@ class OrderProcessCommand extends Command /** * 处理经销商订单 * - * @param \App\Models\DealerOrder $order + * @param \App\Models\DealerOrder $dealerOrder * @return void */ - protected function processOrder(DealerOrder $order) + protected function handleDealerOrder(DealerOrder $dealerOrder) { - $tz = now(); + $tz = date('Y-m-d H:i:s'); - $dealers = $this->getDealers($userInfo = $order->userInfo); + // 获取下单经销商的所有上级经销商 + $dealers = $this->getDealers($userInfo = $dealerOrder->userInfo); - // 如果当前用户的上级有管理者,则需要增加管理者的商品销售业绩 - if ($manager = $this->firstManager([$userInfo->dealer, ...$dealers])) { - DealerManagerSalesLog::insert( - $order->products->map(function ($product) use ($manager, $tz) { - return [ - 'user_id' => $manager->user_id, + // 当前链上的全部经销商(含下单经销商) + $chainDealers = [$userInfo->dealer, ...$dealers]; + + // 处理管理者销售业绩 + $this->handleManagerSalesLogs($dealerOrder, $chainDealers, $tz); + // 分配管理津贴 + $this->handleManageSubsidyLogs($dealerOrder, $chainDealers, $tz); + } + + /** + * 分配管理津贴 + * + * @param \App\Models\DealerOrder $dealerOrder + * @param array $dealers + * @param string $tz + * @return void + */ + protected function handleManageSubsidyLogs(DealerOrder $dealerOrder, array $dealers, string $tz) + { + foreach ($dealerOrder->products as $product) { + if ($product->productManageSubsidyRules->isEmpty()) { + continue; + } + + // 管理津贴分配规则 + $rules = $product->productManageSubsidyRules->keyBy('lvl'); + + $last = null; + $ranking = 0; + + foreach ($dealers as $dealer) { + // 如果当前经销商等级没有对应的管理津贴分配规则,则忽略 + if (is_null($rule = $rules->get($dealer->lvl->value))) { + continue; + } + + // 同等级管理津贴最多给三次 + if ($last === null || $dealer->lvl->value > $last->lvl->value) { + $ranking = 1; + } elseif ($ranking < 3 && $dealer->lvl->value === $last->lvl->value) { + $ranking++; + } else { + continue; + } + + $subsidy = $rule->{"price_{$ranking}st"}; + + if (bccomp($subsidy, '0') === 1) { + $logs[] = [ + 'user_id' => $dealer->user_id, 'order_id' => $product->order_id, 'product_id' => $product->product_id, - 'lvl' => $manager->lvl, + 'lvl' => $dealer->lvl, 'sales_volume' => $product->qty, + 'total_amount' => bcmul($product->qty, $subsidy, 2), 'created_at' => $tz, 'updated_at' => $tz, ]; - })->all() - ); + } + + $last = $dealer; + } } + + DealerManageSubsidyLog::insert($logs); + } + + /** + * 过滤出可能会享受管理津贴的经销商(每个等级最多3人) + * + * @param array $dealers + * @return array + */ + protected function mapManageSubsidyDealers(array $dealers): array + { + $map = []; + $last = null; + $ranking = 1; + + foreach ($dealers as $dealer) { + if ($last === null || $dealer->lvl->value > $last->lvl->value) { + $last = $dealer; + $map[] = $last; + $ranking = 1; + } elseif ($ranking < 3 && $dealer->lvl->value === $last->lvl->value) { + $last = $dealer; + $map[] = $last; + $ranking++; + } + } + + return $map; + } + + /** + * 处理管理者销售业绩 + * + * @param \App\Models\DealerOrder $dealerOrder + * @param array $dealers + * @param string $tz + * @return void + */ + protected function handleManagerSalesLogs(DealerOrder $dealerOrder, array $dealers, string $tz): void + { + if (is_null($manager = $this->firstManager($dealers))) { + return; + } + + $logs = []; + + foreach ($dealerOrder->products as $product) { + $logs[] = [ + 'user_id' => $manager->user_id, + 'lvl' => $manager->lvl, + 'order_id' => $product->order_id, + 'product_id' => $product->product_id, + 'sales_volume' => $product->qty, + 'created_at' => $tz, + 'updated_at' => $tz, + ]; + } + + DealerManagerSalesLog::insert($logs); } /** @@ -105,7 +217,7 @@ class OrderProcessCommand extends Command * @param \App\Models\UserInfo $userInfo * @return array */ - protected function getDealers(UserInfo $userInfo) + protected function getDealers(UserInfo $userInfo): array { $ancestors = []; diff --git a/app/Models/DealerManageSubsidyLog.php b/app/Models/DealerManageSubsidyLog.php new file mode 100644 index 00000000..fee32e16 --- /dev/null +++ b/app/Models/DealerManageSubsidyLog.php @@ -0,0 +1,25 @@ + DealerLvl::class, + 'order_completed_at' => 'datetime', + ]; + + protected $fillable = [ + 'user_id', + 'lvl', + 'order_id', + 'product_id', + 'sales_volume', + 'total_amount', + 'order_completed_at', + 'remark', + ]; +} diff --git a/app/Models/DealerOrderProduct.php b/app/Models/DealerOrderProduct.php index 08f31745..c5383fa9 100644 --- a/app/Models/DealerOrderProduct.php +++ b/app/Models/DealerOrderProduct.php @@ -2,10 +2,15 @@ namespace App\Models; -use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class DealerOrderProduct extends Model { - use HasFactory; + /** + * 商品管理津贴规则 + */ + public function productManageSubsidyRules() + { + return $this->hasMany(DealerProductManageRule::class, 'product_id', 'product_id'); + } } diff --git a/database/migrations/2022_01_13_111606_create_dealer_manage_subsidy_logs_table.php b/database/migrations/2022_01_13_111606_create_dealer_manage_subsidy_logs_table.php new file mode 100644 index 00000000..e7c8887f --- /dev/null +++ b/database/migrations/2022_01_13_111606_create_dealer_manage_subsidy_logs_table.php @@ -0,0 +1,42 @@ +id(); + $table->unsignedBigInteger('user_id')->comment('经销商的用户ID'); + $table->tinyInteger('lvl')->comment('经销商等级'); + $table->unsignedBigInteger('order_id')->comment('订单ID'); + $table->unsignedBigInteger('product_id')->comment('商品ID'); + $table->unsignedBigInteger('sales_volume')->default(0)->comment('商品销量'); + $table->unsignedDecimal('total_amount', 10, 2)->default(0)->comment('补贴总金额'); + $table->timestamp('order_completed_at')->nullable()->comment('订单完成时间'); + $table->timestamps(); + + $table->unique(['user_id', 'order_id', 'product_id']); + $table->index('order_id'); + $table->index('product_id'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('dealer_manage_subsidy_logs'); + } +}