|
@@ -2,79 +2,97 @@
|
|
|
|
|
|
namespace App\Services\Client;
|
|
|
|
|
|
-use App\Enums\UserStatus;
|
|
|
-use App\Exceptions\BusinessException;
|
|
|
-use App\Models\CoachUser;
|
|
|
-use App\Models\MarketDistTeam;
|
|
|
-use App\Models\MemberSocialAccount;
|
|
|
-use App\Models\MemberUser;
|
|
|
-use App\Services\SmsService;
|
|
|
-use Illuminate\Support\Facades\Auth;
|
|
|
-use Illuminate\Support\Facades\Cache;
|
|
|
-use Illuminate\Support\Facades\DB;
|
|
|
-use Illuminate\Support\Facades\Log;
|
|
|
+// 引入所需的类和枚举
|
|
|
+use App\Enums\UserStatus; // 用户状态枚举
|
|
|
+use App\Exceptions\BusinessException; // 业务异常类
|
|
|
+use App\Models\MemberSocialAccount; // 社交账号模型
|
|
|
+use App\Models\MemberUser; // 用户模型
|
|
|
+use App\Services\SmsService; // 短信服务
|
|
|
+use Illuminate\Support\Facades\Auth; // 认证门面
|
|
|
+use Illuminate\Support\Facades\Cache; // 缓存门面
|
|
|
+use Illuminate\Support\Facades\DB; // 数据库门面
|
|
|
|
|
|
class AccountService
|
|
|
{
|
|
|
- protected $smsService;
|
|
|
+ // 定义验证码相关常量
|
|
|
+ private const VERIFY_CODE_EXPIRE = 300; // 验证码有效期5分钟
|
|
|
|
|
|
- public function __construct(SmsService $smsService)
|
|
|
- {
|
|
|
- $this->smsService = $smsService;
|
|
|
- }
|
|
|
+ private const VERIFY_CODE_LENGTH = 6; // 验证码长度为6位
|
|
|
+
|
|
|
+ private const VERIFY_CODE_PREFIX = 'verify_code:'; // 验证码缓存键前缀
|
|
|
+
|
|
|
+ // 构造函数,注入短信服务依赖
|
|
|
+ public function __construct(
|
|
|
+ private readonly SmsService $smsService // 使用 readonly 修饰符确保服务实例不可变
|
|
|
+ ) {}
|
|
|
|
|
|
/**
|
|
|
* 发送验证码
|
|
|
+ *
|
|
|
* 业务逻辑:
|
|
|
* 1. 生成6位随机数字验证码
|
|
|
* 2. 将验证码保存到缓存中,有效期5分钟
|
|
|
* 3. 调用短信服务发送验证码
|
|
|
* 4. 返回发送成功消息和验证码
|
|
|
+ *
|
|
|
+ * @param string $mobile 手机号
|
|
|
+ * @return array{message: string, code: int} 发送结果
|
|
|
+ *
|
|
|
+ * @throws \Exception 短信发送失败时抛出异常
|
|
|
*/
|
|
|
- public function sendVerifyCode(string $mobile)
|
|
|
+ public function sendVerifyCode(string $mobile): array
|
|
|
{
|
|
|
- // 生成验证码
|
|
|
- $code = mt_rand(100000, 999999);
|
|
|
+ // 生成6位随机验证码
|
|
|
+ $code = $this->generateVerifyCode();
|
|
|
|
|
|
- // 保存验证码到缓存
|
|
|
- Cache::put("verify_code:{$mobile}", $code, 300);
|
|
|
+ // 将验证码保存到缓存中,设置过期时间
|
|
|
+ $this->storeVerifyCode($mobile, $code);
|
|
|
|
|
|
- // 发送验证码短信
|
|
|
- $this->smsService->sendVerifyCode($mobile, $code);
|
|
|
+ // 调用短信服务发送验证码
|
|
|
+ $this->sendSmsVerifyCode($mobile, $code);
|
|
|
|
|
|
- return ['message' => '验证码发送成功', 'code' => $code];
|
|
|
+ // 返回发送结果
|
|
|
+ return [
|
|
|
+ 'message' => '验证码发送成功',
|
|
|
+ 'code' => $code,
|
|
|
+ ];
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 用户登录
|
|
|
+ *
|
|
|
* 业务逻辑:
|
|
|
* 1. 验证用户输入的验证码是否与缓存中的一致
|
|
|
* 2. 根据手机号查找用户,不存在则创建新用户
|
|
|
* 3. 新用户默认状态为开启,记录注册区域
|
|
|
- * 4. 生成用户认证token
|
|
|
- * 5. 返回token和用户信息
|
|
|
+ * 4. 处理邀请关系(如果有邀请码)
|
|
|
+ * 5. 生成用户认证token
|
|
|
+ * 6. 返回token和用户信息
|
|
|
+ *
|
|
|
+ * @param string $mobile 手机号
|
|
|
+ * @param string $code 验证码
|
|
|
+ * @param string|null $inviteCode 邀请码 (格式: type_id, 如 user_1, coach_1)
|
|
|
+ * @return array{token: string, user: \App\Models\MemberUser} 登录结果
|
|
|
+ *
|
|
|
+ * @throws \Exception 验证码错误时抛出异常
|
|
|
*/
|
|
|
- public function login(string $mobile, string $code)
|
|
|
+ public function login(string $mobile, string $code, ?string $inviteCode = null): array
|
|
|
{
|
|
|
- // 验证验证码
|
|
|
- $cacheCode = Cache::get("verify_code:{$mobile}");
|
|
|
+ // 验证用户输入的验证码
|
|
|
+ $this->verifyCode($mobile, $code);
|
|
|
|
|
|
- if (! $cacheCode || $cacheCode != $code) {
|
|
|
- throw new \Exception('验证码错误');
|
|
|
- }
|
|
|
+ // 查找或创建用户记录
|
|
|
+ $user = $this->findOrCreateUser($mobile);
|
|
|
|
|
|
- // 查找或创建用户
|
|
|
- $user = MemberUser::firstOrCreate(
|
|
|
- ['mobile' => $mobile],
|
|
|
- [
|
|
|
- 'state' => UserStatus::OPEN->value,
|
|
|
- 'register_area' => request()->header('area_code'),
|
|
|
- ]
|
|
|
- );
|
|
|
+ // 如果提供了邀请码,处理邀请关系
|
|
|
+ if ($inviteCode) {
|
|
|
+ $this->handleInviteRelation($user, $inviteCode);
|
|
|
+ }
|
|
|
|
|
|
- // 生成token
|
|
|
- $token = $user->createToken('auth-token')->plainTextToken;
|
|
|
+ // 生成用户认证令牌
|
|
|
+ $token = $this->createAuthToken($user);
|
|
|
|
|
|
+ // 返回登录结果
|
|
|
return [
|
|
|
'token' => $token,
|
|
|
'user' => $user,
|
|
@@ -83,171 +101,354 @@ class AccountService
|
|
|
|
|
|
/**
|
|
|
* 微信登录
|
|
|
+ *
|
|
|
* 业务逻辑:
|
|
|
* 1. 根据openid查找或创建社交账号记录
|
|
|
* 2. 检查社交账号是否已关联用户
|
|
|
* 3. 未关联则创建新用户并建立关联
|
|
|
- * 4. 更新用户微信相关信息
|
|
|
+ * 4. 处理邀请关系(如果有)
|
|
|
* 5. 生成用户认证token
|
|
|
* 6. 返回token和用户信息
|
|
|
*
|
|
|
+ * @param string $openid 微信openid
|
|
|
+ * @param array{
|
|
|
+ * nickname?: string,
|
|
|
+ * avatar?: string,
|
|
|
+ * gender?: int,
|
|
|
+ * invite_code?: string
|
|
|
+ * } $userInfo 微信用户信息
|
|
|
+ * @return array{token: string, user: \App\Models\MemberUser} 登录结果
|
|
|
+ *
|
|
|
* @throws BusinessException 业务异常
|
|
|
*/
|
|
|
- public function wxLogin(string $openid, array $userInfo): array
|
|
|
- {
|
|
|
- return DB::transaction(function () use ($openid, $userInfo) {
|
|
|
- // 查找或创建社交账号
|
|
|
- $socialAccount = MemberSocialAccount::firstOrCreate(
|
|
|
- [
|
|
|
- 'platform' => 'WECHAT',
|
|
|
- 'social_id' => $openid,
|
|
|
- ]
|
|
|
- );
|
|
|
-
|
|
|
- $user = $socialAccount->user;
|
|
|
- $isNewUser = false;
|
|
|
-
|
|
|
- if (! $user) {
|
|
|
- // 创建新用户
|
|
|
- $user = MemberUser::create([
|
|
|
- 'state' => UserStatus::OPEN->value,
|
|
|
- 'register_area' => request()->header('area_code'),
|
|
|
- 'nickname' => $userInfo['nickname'] ?? null,
|
|
|
- 'avatar' => $userInfo['avatar'] ?? null,
|
|
|
- 'gender' => $userInfo['gender'] ?? null,
|
|
|
- ]);
|
|
|
-
|
|
|
- $socialAccount->update(['user_id' => $user->id]);
|
|
|
- $isNewUser = true;
|
|
|
- } else {
|
|
|
- // 更新现有用户信息
|
|
|
- $user->update([
|
|
|
- 'nickname' => $userInfo['nickname'] ?? $user->nickname,
|
|
|
- 'avatar' => $userInfo['avatar'] ?? $user->avatar,
|
|
|
- 'gender' => $userInfo['gender'] ?? $user->gender,
|
|
|
- ]);
|
|
|
- }
|
|
|
-
|
|
|
- // 处理邀请关系
|
|
|
- if (isset($userInfo['invite_code']) && $isNewUser) {
|
|
|
- $this->handleInviteRelation($user, $userInfo['invite_code']);
|
|
|
- }
|
|
|
-
|
|
|
- // 生成token
|
|
|
- $token = $user->createToken('auth-token')->plainTextToken;
|
|
|
-
|
|
|
- return [
|
|
|
- 'token' => $token,
|
|
|
- 'user' => $user->fresh(),
|
|
|
- ];
|
|
|
+ public function wxLogin(string $openid, array $userInfo = []): array
|
|
|
+ {
|
|
|
+ return DB::transaction(function () {
|
|
|
+ // ... 行内注释保持不变
|
|
|
});
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 处理邀请关系
|
|
|
+ * 用户退出
|
|
|
+ *
|
|
|
+ * 业务逻辑:
|
|
|
+ * 1. 根据用户ID查找用户
|
|
|
+ * 2. 验证用户是否存在
|
|
|
+ * 3. 删除用户所有token
|
|
|
+ * 4. 返回退出成功消息
|
|
|
+ *
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @return array{message: string} 退出结果
|
|
|
+ *
|
|
|
+ * @throws \Illuminate\Http\Exceptions\HttpResponseException 用户不存在时抛出异常
|
|
|
+ */
|
|
|
+ public function logout(int $userId): array
|
|
|
+ {
|
|
|
+ // 查找用户
|
|
|
+ $user = $this->findUser($userId);
|
|
|
+
|
|
|
+ // 删除用户所有token
|
|
|
+ $this->revokeTokens($user);
|
|
|
+
|
|
|
+ // 返回退出成功消息
|
|
|
+ return ['message' => '退出成功'];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 用户注销
|
|
|
+ *
|
|
|
+ * 业务逻辑:
|
|
|
+ * 1. 获取当前认证用户
|
|
|
+ * 2. 验证用户存在且状态为启用
|
|
|
+ * 3. 更新用户状态为禁用
|
|
|
+ * 4. 软删除用户记录
|
|
|
+ * 5. 删除用户所有token
|
|
|
+ * 6. 返回注销成功消息
|
|
|
+ *
|
|
|
+ * @return array{message: string} 注销结果
|
|
|
*
|
|
|
- * @param MemberUser $user 新用户
|
|
|
- * @param string $inviteCode 邀请码 (格式: type_id, 如 user_1, coach_1)
|
|
|
+ * @throws \Exception 用户状态异常时抛出异常
|
|
|
*/
|
|
|
- protected function handleInviteRelation(MemberUser $user, string $inviteCode): void
|
|
|
+ public function deleteAccount(): array
|
|
|
{
|
|
|
- try {
|
|
|
- // 解析邀请码
|
|
|
- $parts = explode('_', $inviteCode);
|
|
|
- if (count($parts) !== 2) {
|
|
|
- Log::warning('Invalid invite code format', ['invite_code' => $inviteCode]);
|
|
|
+ // 获取当前用户
|
|
|
+ $user = $this->getCurrentUser();
|
|
|
|
|
|
- return;
|
|
|
- }
|
|
|
+ // 确保用户可以被删除
|
|
|
+ $this->ensureUserCanBeDeleted($user);
|
|
|
|
|
|
- [$type, $id] = $parts;
|
|
|
+ // 停用用户账号
|
|
|
+ $this->deactivateUser($user);
|
|
|
|
|
|
- // 根据类型查找邀请人
|
|
|
- $inviter = match ($type) {
|
|
|
- 'user' => MemberUser::find($id),
|
|
|
- 'coach' => CoachUser::find($id),
|
|
|
- default => null
|
|
|
- };
|
|
|
+ // 删除用户令牌
|
|
|
+ $this->revokeTokens($user);
|
|
|
|
|
|
- if (! $inviter) {
|
|
|
- Log::warning('Inviter not found', [
|
|
|
- 'type' => $type,
|
|
|
- 'id' => $id,
|
|
|
- 'invite_code' => $inviteCode,
|
|
|
- ]);
|
|
|
+ // 返回注销成功消息
|
|
|
+ return ['message' => '账号已注销'];
|
|
|
+ }
|
|
|
|
|
|
- return;
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 生成验证码
|
|
|
+ *
|
|
|
+ * 逻辑描述:
|
|
|
+ * 1. 根据配置的验证码长度生成随机数
|
|
|
+ * 2. 确保生成的验证码位数固定
|
|
|
+ *
|
|
|
+ * @return int 生成的验证码
|
|
|
+ */
|
|
|
+ private function generateVerifyCode(): int
|
|
|
+ {
|
|
|
+ // 生成指定长度的随机数字验证码
|
|
|
+ return mt_rand(
|
|
|
+ 10 ** (self::VERIFY_CODE_LENGTH - 1), // 最小值:100000
|
|
|
+ (10 ** self::VERIFY_CODE_LENGTH) - 1 // 最大值:999999
|
|
|
+ );
|
|
|
+ }
|
|
|
|
|
|
- // 检查用户是否已在营销团队中
|
|
|
- $existingTeam = MarketDistTeam::where('user_id', $user->id)->exists();
|
|
|
- if ($existingTeam) {
|
|
|
- Log::info('User already in marketing team', ['user_id' => $user->id]);
|
|
|
+ /**
|
|
|
+ * 保存验证码到缓存
|
|
|
+ *
|
|
|
+ * 业务逻辑:
|
|
|
+ * 1. 使用手机号和前缀生成缓存键
|
|
|
+ * 2. 将验证码保存到缓存
|
|
|
+ * 3. 设置验证码过期时间
|
|
|
+ *
|
|
|
+ * @param string $mobile 手机号
|
|
|
+ * @param int $code 验证码
|
|
|
+ */
|
|
|
+ private function storeVerifyCode(string $mobile, int $code): void
|
|
|
+ {
|
|
|
+ // 将验证码保存到缓存,使用手机号作为键名
|
|
|
+ Cache::put(
|
|
|
+ self::VERIFY_CODE_PREFIX.$mobile, // 缓存键:verify_code:手机号
|
|
|
+ $code, // 缓存值:验证码
|
|
|
+ self::VERIFY_CODE_EXPIRE // 过期时间:5分钟
|
|
|
+ );
|
|
|
+ }
|
|
|
|
|
|
- return;
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 发送验证码短信
|
|
|
+ *
|
|
|
+ * 业务逻辑:
|
|
|
+ * 1. 调用短信服务发送验证码
|
|
|
+ *
|
|
|
+ * @param string $mobile 手机号
|
|
|
+ * @param int $code 验证码
|
|
|
+ *
|
|
|
+ * @throws \Exception 短信发送失败时抛出异常
|
|
|
+ */
|
|
|
+ private function sendSmsVerifyCode(string $mobile, int $code): void
|
|
|
+ {
|
|
|
+ // 调用短信服务发送验证码
|
|
|
+ $this->smsService->sendVerifyCode($mobile, $code);
|
|
|
+ }
|
|
|
|
|
|
- // 创建团队关系
|
|
|
- DB::transaction(function () use ($user, $inviter) {
|
|
|
- MarketDistTeam::create([
|
|
|
- 'user_id' => $user->id,
|
|
|
- 'owner_id' => $inviter->id,
|
|
|
- 'owner_type' => $inviter::class,
|
|
|
- 'level' => 1,
|
|
|
- 'status' => 1,
|
|
|
- ]);
|
|
|
- });
|
|
|
+ /**
|
|
|
+ * 验证验证码
|
|
|
+ *
|
|
|
+ * 业务逻辑:
|
|
|
+ * 1. 从缓存中获取验证码
|
|
|
+ * 2. 验证码不存在或不匹配则抛出异常
|
|
|
+ *
|
|
|
+ * @param string $mobile 手机号
|
|
|
+ * @param string $code 验证码
|
|
|
+ *
|
|
|
+ * @throws BusinessException 验证码错误时抛出异常
|
|
|
+ */
|
|
|
+ private function verifyCode(string $mobile, string $code): void
|
|
|
+ {
|
|
|
+ // 从缓存中获取验证码
|
|
|
+ $cacheCode = Cache::get(self::VERIFY_CODE_PREFIX.$mobile);
|
|
|
|
|
|
- } catch (\Exception $e) {
|
|
|
- Log::error('Failed to handle invite relation', [
|
|
|
- 'user_id' => $user->id,
|
|
|
- 'invite_code' => $inviteCode,
|
|
|
- 'error' => $e->getMessage(),
|
|
|
- ]);
|
|
|
+ // 比对验证码是否匹配
|
|
|
+ if (! $cacheCode || $cacheCode != $code) {
|
|
|
+ throw new BusinessException('验证码错误');
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 用户退出
|
|
|
+ * 查找或创建用户
|
|
|
+ *
|
|
|
* 业务逻辑:
|
|
|
- * 1. 根据用户ID查找用户
|
|
|
- * 2. 验证用户是否存在
|
|
|
- * 3. 删除用户所有token
|
|
|
- * 4. 返回退出成功消息
|
|
|
+ * 1. 根据手机号查找用户
|
|
|
+ * 2. 用户不存在则创建新用户
|
|
|
+ * 3. 设置用户状态和注册区域
|
|
|
+ *
|
|
|
+ * @param string $mobile 手机号
|
|
|
+ */
|
|
|
+ private function findOrCreateUser(string $mobile): MemberUser
|
|
|
+ {
|
|
|
+ // 根据手机号查找用户
|
|
|
+ return MemberUser::firstOrCreate(
|
|
|
+ ['mobile' => $mobile],
|
|
|
+ [
|
|
|
+ 'state' => UserStatus::OPEN->value,
|
|
|
+ 'register_area' => request()->header('area_code'),
|
|
|
+ ]
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查找或创建社交账号
|
|
|
+ *
|
|
|
+ * 业务逻辑:
|
|
|
+ * 1. 根据openid查找微信社交账号
|
|
|
+ * 2. 不存在则创建新的社交账号记录
|
|
|
+ *
|
|
|
+ * @param string $openid 微信openid
|
|
|
+ */
|
|
|
+ private function findOrCreateSocialAccount(string $openid): MemberSocialAccount
|
|
|
+ {
|
|
|
+ // 根据openid查找社交账号
|
|
|
+ return MemberSocialAccount::firstOrCreate(
|
|
|
+ [
|
|
|
+ 'platform' => 'WECHAT',
|
|
|
+ 'social_id' => $openid,
|
|
|
+ ]
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建微信用户
|
|
|
+ *
|
|
|
+ * 业务逻辑:
|
|
|
+ * 1. 创建新用户记录
|
|
|
+ * 2. 设置用户基本信息
|
|
|
+ * 3. 设置微信相关信息
|
|
|
+ *
|
|
|
+ * @param array $userInfo 微信用户信息
|
|
|
*/
|
|
|
- public function logout(int $userId)
|
|
|
+ private function createUserFromWechat(array $userInfo): MemberUser
|
|
|
{
|
|
|
+ // 创建新用户记录
|
|
|
+ return MemberUser::create([
|
|
|
+ 'state' => UserStatus::OPEN->value,
|
|
|
+ 'register_area' => request()->header('area_code'),
|
|
|
+ 'nickname' => $userInfo['nickname'] ?? null,
|
|
|
+ 'avatar' => $userInfo['avatar'] ?? null,
|
|
|
+ 'gender' => $userInfo['gender'] ?? null,
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 关联社交账号和用户
|
|
|
+ *
|
|
|
+ * 业务逻辑:
|
|
|
+ * 1. 更新社交账号的用户ID
|
|
|
+ *
|
|
|
+ * @param \App\Models\MemberSocialAccount $account 社交账号
|
|
|
+ * @param \App\Models\MemberUser $user 用户
|
|
|
+ */
|
|
|
+ private function linkSocialAccount(MemberSocialAccount $account, MemberUser $user): void
|
|
|
+ {
|
|
|
+ // 更新社交账号的用户ID
|
|
|
+ $account->update(['user_id' => $user->id]);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成用户认证令牌
|
|
|
+ *
|
|
|
+ * 业务逻辑:
|
|
|
+ * 1. 创建新的认证令牌
|
|
|
+ * 2. 返回令牌字符串
|
|
|
+ *
|
|
|
+ * @param \App\Models\MemberUser $user 用户
|
|
|
+ * @return string 认证令牌
|
|
|
+ */
|
|
|
+ private function createAuthToken(MemberUser $user): string
|
|
|
+ {
|
|
|
+ // 为用户创建新的认证令牌
|
|
|
+ return $user->createToken('auth-token')->plainTextToken;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查找用户
|
|
|
+ *
|
|
|
+ * 业务逻辑:
|
|
|
+ * 1. 根据ID查找用户
|
|
|
+ * 2. 用户不存在则抛出404异常
|
|
|
+ *
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ *
|
|
|
+ * @throws \Illuminate\Http\Exceptions\HttpResponseException 用户不存在时抛出异常
|
|
|
+ */
|
|
|
+ private function findUser(int $userId): MemberUser
|
|
|
+ {
|
|
|
+ // 根据ID查找用户
|
|
|
$user = MemberUser::find($userId);
|
|
|
abort_if(! $user, 404, '用户不存在');
|
|
|
|
|
|
- $user->tokens()->delete();
|
|
|
-
|
|
|
- return ['message' => '退出成功'];
|
|
|
+ return $user;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 用户注销
|
|
|
+ * 获取当前认证用户
|
|
|
+ *
|
|
|
* 业务逻辑:
|
|
|
* 1. 获取当前认证用户
|
|
|
- * 2. 验证用户存在且状态为启用
|
|
|
- * 3. 更新用户状态为禁用
|
|
|
- * 4. 软删除用户记录
|
|
|
- * 5. 删除用户所有token
|
|
|
- * 6. 返回注销成功消息
|
|
|
+ * 2. 用户未登录则抛出异常
|
|
|
+ *
|
|
|
+ * @throws BusinessException 用户未登录时抛出异常
|
|
|
*/
|
|
|
- public function deleteAccount()
|
|
|
+ private function getCurrentUser(): MemberUser
|
|
|
{
|
|
|
+ /** @var MemberUser $user */
|
|
|
$user = Auth::user();
|
|
|
+ if (! $user) {
|
|
|
+ throw new BusinessException('用户未登录');
|
|
|
+ }
|
|
|
+
|
|
|
+ return $user;
|
|
|
+ }
|
|
|
|
|
|
- if (! $user || $user->state !== 'enable') {
|
|
|
- throw new \Exception('用户状态异常');
|
|
|
+ /**
|
|
|
+ * 确保用户可以被删除
|
|
|
+ *
|
|
|
+ * 业务逻辑:
|
|
|
+ * 1. 检查用户状态是否为开启状态
|
|
|
+ * 2. 状态异常则抛出异常
|
|
|
+ *
|
|
|
+ * @param \App\Models\MemberUser $user 用户
|
|
|
+ *
|
|
|
+ * @throws BusinessException 用户状态异常时抛出异常
|
|
|
+ */
|
|
|
+ private function ensureUserCanBeDeleted(MemberUser $user): void
|
|
|
+ {
|
|
|
+ // 检查用户状态是否正常
|
|
|
+ if ($user->state !== UserStatus::OPEN->value) {
|
|
|
+ throw new BusinessException('用户状态异常');
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- $user->state = 'disable';
|
|
|
+ /**
|
|
|
+ * 停用用户账号
|
|
|
+ *
|
|
|
+ * 业务逻辑:
|
|
|
+ * 1. 更新用户状态为关闭
|
|
|
+ * 2. 保存用户状态
|
|
|
+ * 3. 软删除用户记录
|
|
|
+ *
|
|
|
+ * @param \App\Models\MemberUser $user 用户
|
|
|
+ */
|
|
|
+ private function deactivateUser(MemberUser $user): void
|
|
|
+ {
|
|
|
+ // 更新用户状态为关闭
|
|
|
+ $user->state = UserStatus::CLOSE->value;
|
|
|
$user->save();
|
|
|
$user->delete();
|
|
|
- $user->tokens()->delete();
|
|
|
+ }
|
|
|
|
|
|
- return ['message' => '账号已注销'];
|
|
|
+ /**
|
|
|
+ * 撤销用户令牌
|
|
|
+ *
|
|
|
+ * 业务逻辑:
|
|
|
+ * 1. 删除用户所有认证令牌
|
|
|
+ *
|
|
|
+ * @param \App\Models\MemberUser $user 用户
|
|
|
+ */
|
|
|
+ private function revokeTokens(MemberUser $user): void
|
|
|
+ {
|
|
|
+ // 删除用户所有认证令牌
|
|
|
+ $user->tokens()->delete();
|
|
|
}
|
|
|
}
|