238 lines
6.5 KiB
PHP
238 lines
6.5 KiB
PHP
<?php
|
||
|
||
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;
|
||
use Illuminate\Support\Facades\DB;
|
||
use Throwable;
|
||
|
||
class OrderProcessCommand extends Command
|
||
{
|
||
/**
|
||
* The name and signature of the console command.
|
||
*
|
||
* @var string
|
||
*/
|
||
protected $signature = 'dealer:order-process';
|
||
|
||
/**
|
||
* The console command description.
|
||
*
|
||
* @var string
|
||
*/
|
||
protected $description = '处理结算状态是待处理的已付款经销商订单';
|
||
|
||
/**
|
||
* Execute the console command.
|
||
*
|
||
* @return int
|
||
*/
|
||
public function handle()
|
||
{
|
||
DealerOrder::chunkById(200, function ($orders) {
|
||
$orders->load([
|
||
'userInfo.dealer',
|
||
'products.productManageSubsidyRules',
|
||
]);
|
||
|
||
foreach ($orders as $order) {
|
||
try {
|
||
DB::beginTransaction();
|
||
|
||
$this->handleDealerOrder($order);
|
||
|
||
DB::commit();
|
||
} catch (Throwable $e) {
|
||
DB::rollBack();
|
||
|
||
report($e);
|
||
}
|
||
}
|
||
});
|
||
|
||
return 0;
|
||
}
|
||
|
||
/**
|
||
* 处理经销商订单
|
||
*
|
||
* @param \App\Models\DealerOrder $dealerOrder
|
||
* @return void
|
||
*/
|
||
protected function handleDealerOrder(DealerOrder $dealerOrder)
|
||
{
|
||
$tz = date('Y-m-d H:i:s');
|
||
|
||
// 获取下单经销商的所有上级经销商
|
||
$dealers = $this->getDealers($userInfo = $dealerOrder->userInfo);
|
||
|
||
// 当前链上的全部经销商(含下单经销商)
|
||
$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' => $dealer->lvl,
|
||
'sales_volume' => $product->qty,
|
||
'total_amount' => bcmul($product->qty, $subsidy, 2),
|
||
'created_at' => $tz,
|
||
'updated_at' => $tz,
|
||
];
|
||
}
|
||
|
||
$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);
|
||
}
|
||
|
||
/**
|
||
* 从给定的经销商中获取第一个管理者
|
||
*
|
||
* @param array $dealers
|
||
* @return \App\Models\Dealer|null
|
||
*/
|
||
protected function firstManager(array $dealers): ?Dealer
|
||
{
|
||
foreach ($dealers as $dealer) {
|
||
if ($dealer->is_manager) {
|
||
return $dealer;
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取给定用户的上级经销商
|
||
*
|
||
* @param \App\Models\UserInfo $userInfo
|
||
* @return array
|
||
*/
|
||
protected function getDealers(UserInfo $userInfo): array
|
||
{
|
||
$ancestors = [];
|
||
|
||
if (empty($pids = $userInfo->parent_ids)) {
|
||
return $ancestors;
|
||
}
|
||
|
||
$ancestors = UserInfo::with(['dealer'])
|
||
->whereIn('user_id', $pids)
|
||
->latest('depth')
|
||
->get(['user_id', 'depth']);
|
||
|
||
return $ancestors->map(function ($item) {
|
||
return $item->dealer;
|
||
})->all();
|
||
}
|
||
}
|