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) { $lastTime = intval($last); $days = PartnerConfig::activeDays(); return ($at <= $lastTime + $days * 86400) || ($lastTime >= $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; } }