| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- <?php
- namespace app\common\service;
- use think\facade\Db;
- use think\facade\Log;
- class InvitationService
- {
- /**
- * 生成唯一邀请码
- */
- public function generateInvitationCode(): string
- {
- $maxAttempts = 10;
- $attempts = 0;
- while ($attempts < $maxAttempts) {
- // 方法1:使用数字+字母组合
- $chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'; // 去掉容易混淆的字符
- $code = '';
- for ($i = 0; $i < 6; $i++) {
- $code .= $chars[mt_rand(0, strlen($chars) - 1)];
- }
- // 方法2:或者使用更短的邀请码
- // $code = strtoupper(substr(md5(uniqid()), 0, 6));
- // 检查邀请码是否已存在
- $exists = Db::table('ba_user')
- ->where('invitation_code', $code)
- ->count();
- if (!$exists) {
- return $code;
- }
- $attempts++;
- // 如果冲突,尝试不同的算法
- if ($attempts >= 5) {
- $code = 'INV' . mt_rand(1000, 9999);
- $exists = Db::table('ba_user')
- ->where('invitation_code', $code)
- ->count();
- if (!$exists) {
- return $code;
- }
- }
- }
- // 如果还是冲突,使用时间戳+随机数
- return 'INV' . time() . mt_rand(10, 99);
- }
- /**
- * 处理用户注册邀请关系(完整版)
- */
- public function processRegistration(int $newUserId, string $invitationCode = ''): bool
- {
- try {
- // 1. 为注册用户生成自己的邀请码
- $userInvitationCode = $this->generateInvitationCode();
- // 2. 将邀请码保存到用户表
- Db::table('ba_user')
- ->where('id', $newUserId)
- ->update([
- 'invitation_code' => $userInvitationCode,
- 'update_time' => time()
- ]);
- // 3. 处理邀请关系(如果提供了邀请码)
- if (!empty($invitationCode)) {
- $this->processInvitationRelationship($newUserId, $invitationCode);
- }
- // 4. 初始化用户的佣金记录
- $this->initUserCommission($newUserId);
- Log::info("用户邀请码生成成功: 用户ID={$newUserId}, 邀请码={$userInvitationCode}");
- return true;
- } catch (\Throwable $e) {
- Log::error("处理用户注册邀请关系失败: " . $e->getMessage());
- return false;
- }
- }
- /**
- * 处理邀请关系(新用户使用别人的邀请码注册)
- */
- private function processInvitationRelationship(int $newUserId, string $invitationCode): void
- {
- try {
- // 查找邀请人(通过邀请码)
- $inviter = Db::table('ba_user')
- ->where('invitation_code', $invitationCode)
- ->field('id, username')
- ->find();
- if (!$inviter) {
- Log::warning("邀请码不存在: {$invitationCode}");
- return;
- }
- // 检查是否已存在邀请关系
- $exists = Db::table('ba_user_invitation')
- ->where('invitee_id', $newUserId)
- ->find();
- if ($exists) {
- return; // 已有邀请关系,直接返回
- }
- // 创建邀请关系记录
- Db::table('ba_user_invitation')->insert([
- 'inviter_id' => $inviter['id'],
- 'invitee_id' => $newUserId,
- 'invitation_code' => $invitationCode,
- 'create_time' => date('Y-m-d H:i:s')
- ]);
- // 更新邀请人统计
- $this->updateInviterStats($inviter['id']);
- Log::info("邀请关系创建成功: 邀请人ID={$inviter['id']}, 被邀请人ID={$newUserId}");
- } catch (\Throwable $e) {
- Log::error("处理邀请关系失败: " . $e->getMessage());
- }
- }
- /**
- * 更新邀请人统计
- */
- private function updateInviterStats(int $inviterId): void
- {
- try {
- // 统计邀请人数
- $invitationCount = Db::table('ba_user_invitation')
- ->where('inviter_id', $inviterId)
- ->count();
- // 获取当前佣金记录
- $commission = Db::table('ba_user_commission')
- ->where('user_id', $inviterId)
- ->find();
- if ($commission) {
- // 更新现有记录
- Db::table('ba_user_commission')
- ->where('user_id', $inviterId)
- ->update([
- 'invitation_count' => $invitationCount,
- // 'total_invitation' => $invitationCount,
- 'update_time' => date('Y-m-d H:i:s')
- ]);
- } else {
- // 创建新记录(如果邀请人还没有佣金记录)
- $promotionLink = $this->generatePromotionLink($inviterId);
- Db::table('ba_user_commission')->insert([
- 'user_id' => $inviterId,
- 'total_commission' => 0.00,
- 'current_commission' => 0.00,
- 'withdrawn_commission' => 0.00,
- 'frozen_commission' => 0.00,
- 'promotion_link' => $promotionLink,
- 'invitation_count' => $invitationCount,
- // 'total_invitation' => $invitationCount,
- 'update_time' => date('Y-m-d H:i:s')
- ]);
- }
- } catch (\Throwable $e) {
- Log::error("更新邀请人统计失败: " . $e->getMessage());
- }
- }
- /**
- * 初始化用户佣金记录
- */
- private function initUserCommission(int $userId): void
- {
- try {
- $exists = Db::table('ba_user_commission')
- ->where('user_id', $userId)
- ->find();
- if (!$exists) {
- $promotionLink = $this->generatePromotionLink($userId);
- Db::table('ba_user_commission')->insert([
- 'user_id' => $userId,
- 'total_commission' => 0.00,
- 'current_commission' => 0.00,
- 'withdrawn_commission' => 0.00,
- 'frozen_commission' => 0.00,
- 'promotion_link' => $promotionLink,
- 'invitation_count' => 0,
- 'update_time' => date('Y-m-d H:i:s')
- ]);
- }
- } catch (\Throwable $e) {
- Log::error("初始化用户佣金失败: " . $e->getMessage());
- }
- }
- /**
- * 生成推广链接
- */
- private function generatePromotionLink(int $userId): string
- {
- // 获取用户的邀请码
- $user = Db::table('ba_user')
- ->where('id', $userId)
- ->field('invitation_code')
- ->find();
- $invitationCode = $user['invitation_code'] ?? '';
- if (empty($invitationCode)) {
- // 如果用户还没有邀请码,先生成一个
- $invitationCode = $this->generateInvitationCode();
- Db::table('ba_user')
- ->where('id', $userId)
- ->update(['invitation_code' => $invitationCode]);
- }
- $domain = request()->domain();
- return $domain . '/#/user/register?invite=' . $invitationCode;
- }
- /**
- * 获取用户邀请统计
- */
- public function getUserInvitationStats(int $userId): array
- {
- try {
- // 获取用户的邀请码
- $user = Db::table('ba_user')
- ->where('id', $userId)
- ->field('invitation_code')
- ->find();
- // 获取总邀请人数
- $totalInvitations = Db::table('ba_user_invitation')
- ->alias('ui')
- ->leftJoin('ba_user u', 'u.id = ui.invitee_id')
- ->where('ui.inviter_id', $userId)
- ->field('u.id, u.username, u.email, u.mobile, u.create_time, ui.create_time as invite_time')
- ->order('ui.create_time', 'desc')
- ->select()
- ->toArray();
- // 获取今日邀请人数
- $todayStart = date('Y-m-d 00:00:00');
- $todayEnd = date('Y-m-d 23:59:59');
- $todayInvitations = Db::table('ba_user_invitation')
- ->alias('ui')
- ->leftJoin('ba_user u', 'u.id = ui.invitee_id')
- ->where('ui.inviter_id', $userId)
- ->whereBetween('ui.create_time', [$todayStart, $todayEnd])
- ->select()
- ->toArray();
- // 获取佣金信息
- $commission = Db::table('ba_user_commission')
- ->where('user_id', $userId)
- ->find();
- // 获取佣金流水
- $flows = Db::table('ba_commission_flow')
- ->where('user_id', $userId)
- ->order('create_time', 'desc')
- ->limit(20)
- ->select()
- ->toArray();
- return [
- 'invitation_code' => $user['invitation_code'] ?? '', // 用户的邀请码
- 'invitations' => $totalInvitations, // 所有邀请记录
- 'today_invitation' => count($todayInvitations), // 今日邀请人数
- 'total_invitation' => count($totalInvitations), // 总邀请人数
- 'commission' => $commission ?: [
- 'total_commission' => 0,
- 'current_commission' => 0,
- 'withdrawn_commission' => 0,
- 'frozen_commission' => 0,
- 'promotion_link' => $this->generatePromotionLink($userId),
- 'invitation_count' => 0,
- 'total_invitation' => 0
- ],
- 'flows' => $flows
- ];
- } catch (\Throwable $e) {
- Log::error("获取用户邀请统计失败: " . $e->getMessage());
- return [
- 'invitation_code' => '',
- 'invitations' => [],
- 'invitation_count' => 0,
- 'commission' => [
- 'total_commission' => 0,
- 'current_commission' => 0,
- 'withdrawn_commission' => 0,
- 'frozen_commission' => 0,
- 'promotion_link' => $this->generatePromotionLink($userId),
- 'invitation_count' => 0,
- 'total_invitation' => 0
- ],
- 'flows' => []
- ];
- }
- }
- /**
- * 获取下级用户列表
- */
- public function getSubordinateList(int $userId, int $page = 1, int $pageSize = 10): array
- {
- try {
- $query = Db::table('ba_user_invitation')
- ->alias('ui')
- ->leftJoin('ba_user u', 'u.id = ui.invitee_id')
- ->where('ui.inviter_id', $userId);
- $total = $query->count();
- $list = $query->field('u.id, u.username, u.nickname, u.email, u.mobile, u.create_time,
- u.last_login_time, u.status, ui.create_time as invite_time')
- ->page($page, $pageSize)
- ->order('ui.create_time', 'desc')
- ->select()
- ->toArray();
- return [
- 'list' => $list,
- 'total' => $total,
- 'page' => $page,
- 'page_size' => $pageSize,
- 'page_count' => ceil($total / $pageSize)
- ];
- } catch (\Throwable $e) {
- Log::error("获取下级用户列表失败: " . $e->getMessage());
- return [
- 'list' => [],
- 'total' => 0,
- 'page' => $page,
- 'page_size' => $pageSize,
- 'page_count' => 0
- ];
- }
- }
- }
|