156 行
5.8 KiB
PHP
156 行
5.8 KiB
PHP
<?php
|
|
|
|
namespace addons\shopro\service\partner;
|
|
|
|
use app\admin\model\shopro\order\Order as OrderModel;
|
|
|
|
/**
|
|
* 30 日活跃:含今天共 N 个自然日有本人合格订单
|
|
*/
|
|
class ActiveService
|
|
{
|
|
public function windowStart($endTime = null)
|
|
{
|
|
$days = PartnerConfig::activeDays();
|
|
$end = $endTime ?: time();
|
|
$endDay = strtotime(date('Y-m-d 00:00:00', $end));
|
|
return $endDay - ($days - 1) * 86400;
|
|
}
|
|
|
|
public function isActive($agent, $atTime = null)
|
|
{
|
|
if (!$agent) {
|
|
return false;
|
|
}
|
|
$last = is_array($agent) ? ($agent['last_self_order_time'] ?? null) : ($agent->last_self_order_time ?? null);
|
|
$userId = is_array($agent) ? ($agent['user_id'] ?? 0) : ($agent->user_id ?? 0);
|
|
$at = $atTime ?: time();
|
|
$start = $this->windowStart($at);
|
|
|
|
if ($last) {
|
|
return intval($last) >= $start;
|
|
}
|
|
if (!$userId) {
|
|
return false;
|
|
}
|
|
return $this->hasQualifiedOrder($userId, $start, $at);
|
|
}
|
|
|
|
/**
|
|
* 判断指定用户在时间窗口内是否有有效订单(本人自购或直推下级合格订单)
|
|
*/
|
|
public function hasQualifiedOrder($userId, $start, $end)
|
|
{
|
|
if (!$userId) {
|
|
return false;
|
|
}
|
|
$rateService = new RateService();
|
|
$directChildIds = \think\Db::name('user')->where('parent_user_id', $userId)->column('id');
|
|
$candidateUserIds = array_merge([$userId], $directChildIds);
|
|
|
|
$order = $rateService->qualifiedOrderQuery($start, $end)
|
|
->whereIn('o.user_id', $candidateUserIds)
|
|
->find();
|
|
return (bool) $order;
|
|
}
|
|
|
|
public function activeUserIds($start, $end, $extraWhere = [])
|
|
{
|
|
$createBaseQuery = function () use ($extraWhere) {
|
|
$q = \think\Db::name('shopro_commission_agent')
|
|
->where('status', 'in', ['normal', 'freeze'])
|
|
->where('level', '>=', 1);
|
|
foreach ($extraWhere as $field => $value) {
|
|
$q->where($field, $value);
|
|
}
|
|
return $q;
|
|
};
|
|
|
|
// 1. 优先通过 last_self_order_time 索引快速命中
|
|
$hitUserIds = $createBaseQuery()->where(function ($q) use ($start, $end) {
|
|
$q->where('last_self_order_time', '>=', $start)
|
|
->where('last_self_order_time', '<=', $end);
|
|
})->column('user_id');
|
|
|
|
// 2. 容错:查找 last_self_order_time 为空或为 0 的代理商
|
|
$nullUserIds = $createBaseQuery()->where(function ($q) {
|
|
$q->whereNull('last_self_order_time')->whereOr('last_self_order_time', 0);
|
|
})->column('user_id');
|
|
|
|
if (!empty($nullUserIds)) {
|
|
$rateService = new RateService();
|
|
// 2.1 自购订单命中
|
|
$orderHits = $rateService->qualifiedOrderQuery($start, $end)
|
|
->whereIn('o.user_id', $nullUserIds)
|
|
->group('o.user_id')
|
|
->column('max(o.paid_time)', 'o.user_id');
|
|
|
|
foreach ($orderHits as $uId => $lastTime) {
|
|
\think\Db::name('shopro_commission_agent')->where('user_id', $uId)->update(['last_self_order_time' => $lastTime]);
|
|
$hitUserIds[] = intval($uId);
|
|
}
|
|
|
|
// 2.2 直推下级订单命中(针对仍未命中的代理商)
|
|
$remainingNullIds = array_diff($nullUserIds, array_keys($orderHits));
|
|
if (!empty($remainingNullIds)) {
|
|
$userTable = \think\Db::name('user')->getTable();
|
|
$directHits = $rateService->qualifiedOrderQuery($start, $end)
|
|
->join($userTable . ' u', 'u.id = o.user_id')
|
|
->whereIn('u.parent_user_id', $remainingNullIds)
|
|
->group('u.parent_user_id')
|
|
->column('max(o.paid_time)', 'u.parent_user_id');
|
|
|
|
foreach ($directHits as $pId => $lastTime) {
|
|
\think\Db::name('shopro_commission_agent')->where('user_id', $pId)->update(['last_self_order_time' => $lastTime]);
|
|
$hitUserIds[] = intval($pId);
|
|
}
|
|
}
|
|
}
|
|
|
|
return array_values(array_unique(array_map('intval', $hitUserIds)));
|
|
}
|
|
|
|
/**
|
|
* 批量校准所有分销商的有效订单时间(自购及直推合格订单最大值回填)
|
|
*/
|
|
public function syncActiveTimes($sinceTime = null)
|
|
{
|
|
$rateService = new RateService();
|
|
$userTable = \think\Db::name('user')->getTable();
|
|
|
|
// 1. 本人自购最新合格订单时间
|
|
$selfQuery = $rateService->qualifiedOrderQuery($sinceTime)
|
|
->group('o.user_id')
|
|
->column('max(o.paid_time)', 'o.user_id');
|
|
|
|
// 2. 直推下级最新合格订单时间
|
|
$directQuery = $rateService->qualifiedOrderQuery($sinceTime)
|
|
->join($userTable . ' u', 'u.id = o.user_id')
|
|
->where('u.parent_user_id', '>', 0)
|
|
->group('u.parent_user_id')
|
|
->column('max(o.paid_time)', 'u.parent_user_id');
|
|
|
|
// 3. 汇总取最大值
|
|
$allUserIds = array_unique(array_merge(array_keys($selfQuery), array_keys($directQuery)));
|
|
$updated = 0;
|
|
|
|
foreach ($allUserIds as $uId) {
|
|
$selfTime = intval($selfQuery[$uId] ?? 0);
|
|
$directTime = intval($directQuery[$uId] ?? 0);
|
|
$maxTime = max($selfTime, $directTime);
|
|
|
|
if ($maxTime > 0) {
|
|
$agent = \think\Db::name('shopro_commission_agent')->where('user_id', $uId)->find();
|
|
if ($agent && $maxTime > intval($agent['last_self_order_time'] ?? 0)) {
|
|
\think\Db::name('shopro_commission_agent')->where('user_id', $uId)->update([
|
|
'last_self_order_time' => $maxTime,
|
|
]);
|
|
$updated++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $updated;
|
|
}
|
|
}
|