order('add_time', 'asc')->where('status', 0)->find()) { return self::setErrorInfo('尚未出局,不可复投'); } $tree_leader = 1; $spread_last_point = self::where('uid', $spread_uid)->where('status', 0)->find(); while ($spread_last_point) { $tree_leader = $spread_last_point['tree_num']; $spread_last_point = self::where('tree_num', floor($spread_last_point['tree_num'] / 2))->where('status', 0)->find(); } $gp_point = 1; $gp_point_list = [$tree_leader * 2, $tree_leader * 2 + 1]; while (1) { $member_list = self::where('tree_num', 'in', $gp_point_list)->order('tree_num', 'asc')->select(); if (count($member_list) < count($gp_point_list)) { foreach ($gp_point_list as $k => $v) { if (!isset($member_list[$k]) || $v != $member_list[$k]['tree_num']) { $gp_point = $v; break; } } break; } $gp_point_list = []; foreach ($member_list as $v) { $gp_point_list[] = $v['tree_num'] * 2; $gp_point_list[] = $v['tree_num'] * 2 + 1; } } return [$gp_point, $tree_leader]; } /** * 进场 * @param int $uid * @param int $spread_uid * @return bool * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public static function insertTree(int $uid, int $spread_uid = 0): bool { $res = self::getTreePoint($uid, $spread_uid); if (!$res) return self::setErrorInfo(self::getErrorInfo()); list($point, $tree_leader) = $res; self::beginTrans(); try { $res = self::create([ 'uid' => $uid, 'tree_num' => $point, 'add_time' => time(), ]); $res = $res && self::sendToUper($point); $gp_point_list = [$tree_leader * 2, $tree_leader * 2 + 1]; $gp_point_all = $gp_point_list; $i = 9; while (--$i) { $set = []; foreach ($gp_point_list as $v) { $gp_point_all[] = $v * 2; $gp_point_all[] = $v * 2 + 1; $set[] = $v * 2; $set[] = $v * 2 + 1; } $gp_point_list = $set; } if (count($gp_point_all) == self::where('tree_num', 'in', $gp_point_all)->count()) { //出局 $info = self::where('tree_num', $tree_leader)->find(); $info->status = 1; $res = $res && $info->save(); } self::checkTrans($res); if ($res) { return true; } else { return self::setErrorInfo('加入失败'); } } catch (\Exception $e) { self::rollbackTrans(); return self::setErrorInfo($e->getMessage()); } } /** * 发奖 * @param int $point * @return bool * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public static function sendToUper(int $point): bool { $up_point = floor($point / 2); $info = self::where('tree_num', $up_point)->find(); $res = true; while ($info) { $info->get += 140; $res = $res && $info->save(); $up_point = floor($up_point / 2); $info = self::where('tree_num', $up_point)->where('status', 0)->find(); } return $res; } }