297 lines
8.3 KiB
PHP
297 lines
8.3 KiB
PHP
<?php
|
||
|
||
namespace App\Console\Commands\Dealer;
|
||
|
||
use App\Enums\DealerLvl;
|
||
use App\Enums\DealerOrderSettleState;
|
||
use App\Enums\DealerOrderStatus;
|
||
use App\Models\Dealer;
|
||
use App\Models\DealerManagerSalesLog;
|
||
use App\Models\DealerManageSubsidyLog;
|
||
use App\Models\DealerOrder;
|
||
use App\Models\DealerPurchaseLog;
|
||
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::where(
|
||
'settle_state',
|
||
DealerOrderSettleState::Pending
|
||
)->whereIn('status', [
|
||
DealerOrderStatus::Paid,
|
||
DealerOrderStatus::Shipped,
|
||
DealerOrderStatus::Completed,
|
||
])->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 = now();
|
||
|
||
// 获取下单经销商的所有上级经销商
|
||
$dealers = $this->getDealers($dealerOrder->userInfo);
|
||
|
||
// 当前链上的全部经销商(含下单经销商)
|
||
$chainDealers = [$dealerOrder->userInfo->dealer, ...$dealers];
|
||
|
||
// 签约经销商的进货日志
|
||
$this->handlePurchaseLogsOfContractedDealer($dealerOrder, $tz);
|
||
|
||
// 管理者的销售业绩
|
||
$this->handleManagerSalesLogs($dealerOrder, $chainDealers, $tz);
|
||
|
||
// 一级签约经销商和二级经销商的管理津贴
|
||
$this->handleManageSubsidyLogs($dealerOrder, $chainDealers, $tz);
|
||
|
||
// 将订单标记为已处理
|
||
// $dealerOrder->forceFill([
|
||
// 'settle_state' => DealerOrderSettleState::Processed,
|
||
// ])->save();
|
||
}
|
||
|
||
/**
|
||
* 生成签约经销商的进货日志
|
||
*
|
||
* @param \App\Models\DealerOrder $dealerOrder
|
||
* @param array $dealers
|
||
* @param string $tz
|
||
* @return void
|
||
*/
|
||
protected function handlePurchaseLogsOfContractedDealer(DealerOrder $dealerOrder, string $tz)
|
||
{
|
||
$dealer = $dealerOrder->userInfo->dealer;
|
||
|
||
// 采购业绩是否算自己的业绩
|
||
$valid = true;
|
||
|
||
if ($dealer->lvl->value < DealerLvl::Contracted->value) {
|
||
// 如果订单金额小于升级签约经销商的金额,则结束
|
||
if ($dealerOrder->total_amount < 26400) {
|
||
return;
|
||
}
|
||
|
||
$valid = false;
|
||
}
|
||
|
||
$log = new DealerPurchaseLog([
|
||
'user_id' => $dealer->user_id,
|
||
'lvl' => $dealer->lvl,
|
||
'order_id' => $dealerOrder->id,
|
||
'total_amount' => $dealerOrder->total_amount,
|
||
'path' => $valid ? $dealerOrder->userInfo->full_path : $dealerOrder->userInfo->path,
|
||
'remark' => $valid ? null : '升级签约',
|
||
]);
|
||
$log->setCreatedAt($tz);
|
||
$log->setUpdatedAt($tz);
|
||
$log->save();
|
||
}
|
||
|
||
/**
|
||
* 分配一级签约经销商和二级经销商的管理津贴
|
||
*
|
||
* @param \App\Models\DealerOrder $dealerOrder
|
||
* @param array $dealers
|
||
* @param string $tz
|
||
* @return void
|
||
*/
|
||
protected function handleManageSubsidyLogs(DealerOrder $dealerOrder, array $dealers, string $tz)
|
||
{
|
||
$logs = [];
|
||
|
||
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();
|
||
}
|
||
}
|