|
@@ -116,7 +116,7 @@ class UserService
|
|
|
];
|
|
|
} catch (\Exception $e) {
|
|
|
DB::rollBack();
|
|
|
- Log::error('用户注册失败', ['error' => $e->getMessage(), 'mobile' => $mobile]);
|
|
|
+ Log::error('用户注册', ['error' => $e->getMessage(), 'mobile' => $mobile]);
|
|
|
throw $e;
|
|
|
}
|
|
|
}
|
|
@@ -226,7 +226,7 @@ class UserService
|
|
|
* 申请成为技师
|
|
|
*
|
|
|
* 业务逻辑:
|
|
|
- * 1. 检查���户申请资格
|
|
|
+ * 1. 检查户申请资格
|
|
|
* 2. 创建或更新技师基础信息
|
|
|
* 3. 创建申请记录
|
|
|
*
|
|
@@ -236,7 +236,7 @@ class UserService
|
|
|
* @param string $work_years 工作年限
|
|
|
* @param string $intention_city 意向城市
|
|
|
* @param array $portrait_images 形象照片数组
|
|
|
- * @param string|null $description 个人介绍
|
|
|
+ * @param string|null $introduction 个人简介
|
|
|
* @return \App\Models\CoachInfoRecord 返回申请记录
|
|
|
*
|
|
|
* @throws \Exception 申请失败时抛出异常
|
|
@@ -248,35 +248,32 @@ class UserService
|
|
|
string $work_years,
|
|
|
string $intention_city,
|
|
|
array $portrait_images,
|
|
|
- ?string $description = null
|
|
|
+ ?string $introduction = null
|
|
|
): CoachInfoRecord {
|
|
|
try {
|
|
|
DB::beginTransaction();
|
|
|
|
|
|
- // 1. 获取并验证用户信息
|
|
|
+ // 1. 获取验证用户信息
|
|
|
$user = $this->getAndValidateUser();
|
|
|
|
|
|
- // 2. 获取或创建技师基础信息
|
|
|
- $coach = $this->getOrCreateCoach($user, $mobile, $gender);
|
|
|
-
|
|
|
- // 3. 创建申请记录
|
|
|
- $application = $this->createCoachApplication(
|
|
|
- $coach,
|
|
|
- $age,
|
|
|
+ // 2. 创建技师和基础信息记录
|
|
|
+ $infoRecord = $this->getOrCreateCoach(
|
|
|
+ $user,
|
|
|
$mobile,
|
|
|
$gender,
|
|
|
+ $age,
|
|
|
$work_years,
|
|
|
$intention_city,
|
|
|
$portrait_images,
|
|
|
- $description
|
|
|
+ $introduction
|
|
|
);
|
|
|
|
|
|
DB::commit();
|
|
|
|
|
|
// 记录成功日志
|
|
|
- $this->logApplicationSuccess($user, $coach, $application);
|
|
|
+ $this->logApplicationSuccess($user, $user->coach, $infoRecord);
|
|
|
|
|
|
- return $application;
|
|
|
+ return $infoRecord;
|
|
|
} catch (\Exception $e) {
|
|
|
DB::rollBack();
|
|
|
$this->logApplicationError($e, $mobile);
|
|
@@ -308,112 +305,108 @@ class UserService
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 获取或创建技师基础信息
|
|
|
+ * 获取或创建技师信息
|
|
|
*
|
|
|
* 业务逻辑:
|
|
|
- * 1. 获取用户关联的技师信息
|
|
|
- * 2. 如果存在技师信息:
|
|
|
- * - 验证现申请状态
|
|
|
- * - 更新基础信息
|
|
|
- * 3. 如果不存在技师信息:
|
|
|
- * - 创建新的技师记录
|
|
|
- *
|
|
|
- * @param \App\Models\MemberUser $user 用户模型
|
|
|
+ * 1. 检查用户是否已经是技师
|
|
|
+ * - 如果是技师,验证是否可以再次申请
|
|
|
+ * 2. 如果不是技师,创建技师记录
|
|
|
+ * 3. 创建新的申请记录
|
|
|
+ * - 创建技师申请记录,包含详细信息
|
|
|
+ * - 关联技师记录和申请记录
|
|
|
+ *
|
|
|
+ * @param MemberUser $user 用户模型
|
|
|
* @param string $mobile 手机号
|
|
|
* @param int $gender 性别(1:男/2:女)
|
|
|
- * @return \App\Models\Coach 返回技师模型
|
|
|
+ * @param int $age 年龄
|
|
|
+ * @param string $work_years 工作年限
|
|
|
+ * @param string $intention_city 意向城市
|
|
|
+ * @param array $portrait_images 形象照片
|
|
|
+ * @param string|null $introduction 个人简介
|
|
|
+ * @return CoachInfoRecord 返回申请记录
|
|
|
*
|
|
|
- * @throws \Illuminate\Http\Exceptions\HttpResponseException 验证失败时抛出异常
|
|
|
+ * @throws \Illuminate\Http\Exceptions\HttpResponseException 当技师已存在且不能再次申请时抛出异常
|
|
|
*/
|
|
|
- private function getOrCreateCoach(MemberUser $user, string $mobile, int $gender)
|
|
|
- {
|
|
|
+ private function getOrCreateCoach(
|
|
|
+ MemberUser $user,
|
|
|
+ string $mobile,
|
|
|
+ int $gender,
|
|
|
+ int $age,
|
|
|
+ string $work_years,
|
|
|
+ string $intention_city,
|
|
|
+ array $portrait_images,
|
|
|
+ ?string $introduction = null
|
|
|
+ ): CoachInfoRecord {
|
|
|
+ // 1. 获取用户关联的技师信息
|
|
|
$coach = $user->coach;
|
|
|
|
|
|
+ // 2. 如果已是技师,验证是否可以再次申请
|
|
|
if ($coach) {
|
|
|
- // 检查现有申请状态
|
|
|
+ // 验证现有申请状态,如果不能申请会抛出异常
|
|
|
$this->validateExistingApplication($coach);
|
|
|
- // 更新基础信息
|
|
|
- $coach->update([
|
|
|
- 'mobile' => $mobile,
|
|
|
- 'gender' => $gender,
|
|
|
+ } else {
|
|
|
+ // 3. 如果不是技师,创建技师记录,初始状态为待认证
|
|
|
+ $coach = $user->coach()->create([
|
|
|
+ 'state' => TechnicianStatus::PENDING->value,
|
|
|
]);
|
|
|
-
|
|
|
- return $coach->fresh();
|
|
|
}
|
|
|
|
|
|
- // 创建新的技师记录
|
|
|
- return $user->coach()->create([
|
|
|
- 'mobile' => $mobile,
|
|
|
- 'gender' => $gender,
|
|
|
- 'state' => TechnicianStatus::PENDING->value,
|
|
|
+ // 4. 创建技师申请记录,状态为待审核
|
|
|
+ $infoRecord = CoachInfoRecord::create([
|
|
|
+ 'coach_id' => $coach->id, // 关联技师ID
|
|
|
+ 'mobile' => $mobile, // 联系电话
|
|
|
+ 'gender' => $gender, // 性别
|
|
|
+ 'age' => $age, // 年龄
|
|
|
+ 'work_years' => $work_years, // 工作年限
|
|
|
+ 'intention_city' => $intention_city, // 意向城市
|
|
|
+ 'portrait_images' => $portrait_images, // 形象照片,让 Laravel 自动处理数组转换
|
|
|
+ 'introduction' => $introduction, // 个人简介
|
|
|
+ 'state' => TechnicianAuthStatus::AUDITING->value, // 申请状态:待审核
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 5. 更新技师记,关联申请信息
|
|
|
+ $coach->update([
|
|
|
+ 'info_record_id' => $infoRecord->id,
|
|
|
]);
|
|
|
+
|
|
|
+ return $infoRecord;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 验证现有申请状态
|
|
|
+ * 验证技师的现有申请状态
|
|
|
*
|
|
|
* 业务逻辑:
|
|
|
- * 1. 查询技师的申请记录
|
|
|
- * 2. 检查是否存在审核中或已通过的申请
|
|
|
- * 3. 根据状态返回相应的错误信息
|
|
|
+ * 1. 检查技师的最新申请记录状态
|
|
|
+ * 2. 如果申请记录状态为待审核或审核通过,不允许再次申请
|
|
|
+ * 3. 如果申请记录状态为审核拒绝,允许再次申请
|
|
|
*
|
|
|
- * @param \App\Models\Coach $coach 技师模型
|
|
|
+ * @param Coach $coach 技师模型
|
|
|
+ * @return bool 如果可以申请返回 true
|
|
|
*
|
|
|
- * @throws \Illuminate\Http\Exceptions\HttpResponseException 存在未��成申请时抛出异常
|
|
|
+ * @throws \Illuminate\Http\Exceptions\HttpResponseException 当不能申请时抛出异常
|
|
|
*/
|
|
|
- private function validateExistingApplication($coach): void
|
|
|
+ private function validateExistingApplication($coach): bool
|
|
|
{
|
|
|
- $existingApplication = CoachInfoRecord::where('coach_id', $coach->id)
|
|
|
- ->whereIn('state', [TechnicianAuthStatus::AUDITING, TechnicianAuthStatus::PASSED])
|
|
|
- ->first();
|
|
|
-
|
|
|
- if ($existingApplication) {
|
|
|
- $message = $existingApplication->state === TechnicianAuthStatus::PASSED
|
|
|
- ? '您已是技师,无需重复申请'
|
|
|
- : '您有正在审核的申请,请耐心等待';
|
|
|
- abort(422, $message);
|
|
|
+ // 获取最新的申请记录
|
|
|
+ $latestApplication = $coach->info;
|
|
|
+
|
|
|
+ // 如果没有申请记录,允许申请
|
|
|
+ if (! $latestApplication) {
|
|
|
+ return true;
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- /**
|
|
|
- * 创建技师申请记录
|
|
|
- *
|
|
|
- * 业务逻辑:
|
|
|
- * 1. 准备申请记录数据
|
|
|
- * 2. 处理形象照片数据
|
|
|
- * 3. 创建申请记录
|
|
|
- *
|
|
|
- * @param \App\Models\Coach $coach 技师模型
|
|
|
- * @param int $age 年龄
|
|
|
- * @param string $mobile 联系电话
|
|
|
- * @param int $gender 性别(1:男/2:女)
|
|
|
- * @param string $work_years 工作年限
|
|
|
- * @param string $intention_city 意向城市
|
|
|
- * @param array $portrait_images 形象照片数组
|
|
|
- * @param string|null $description 个人介绍
|
|
|
- * @return \App\Models\CoachInfoRecord 返回申请记录
|
|
|
- */
|
|
|
- private function createCoachApplication(
|
|
|
- $coach,
|
|
|
- int $age,
|
|
|
- string $mobile,
|
|
|
- int $gender,
|
|
|
- string $work_years,
|
|
|
- string $intention_city,
|
|
|
- array $portrait_images,
|
|
|
- ?string $description
|
|
|
- ): CoachInfoRecord {
|
|
|
- return CoachInfoRecord::create([
|
|
|
- 'coach_id' => $coach->id,
|
|
|
- 'age' => $age,
|
|
|
- 'mobile' => $mobile,
|
|
|
- 'gender' => $gender,
|
|
|
- 'work_years' => $work_years,
|
|
|
- 'intention_city' => $intention_city,
|
|
|
- 'portrait_images' => json_encode($portrait_images, JSON_UNESCAPED_UNICODE),
|
|
|
- 'description' => $description,
|
|
|
- 'state' => TechnicianAuthStatus::AUDITING,
|
|
|
- ]);
|
|
|
+ // 如果申请状态为待审核,不允许申请
|
|
|
+ if ($latestApplication->state === TechnicianAuthStatus::AUDITING->value) {
|
|
|
+ abort(422, '您有一个正在审核中的申请,请等待审核结果');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果申请状态为审核通过,不允许申请
|
|
|
+ if ($latestApplication->state === TechnicianAuthStatus::PASSED->value) {
|
|
|
+ abort(422, '您的申请已通过,无需再次申请');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 其他状态(如审核拒绝)允许再次申请
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -422,7 +415,7 @@ class UserService
|
|
|
* 业务逻辑:
|
|
|
* 1. 记录用户ID和技师ID
|
|
|
* 2. 记录申请记录ID和状态
|
|
|
- * 3. 记录联系方式
|
|
|
+ * 3. 记录联方式
|
|
|
*
|
|
|
* @param \App\Models\MemberUser $user 用户模型
|
|
|
* @param \App\Models\Coach $coach 技师模型
|
|
@@ -444,7 +437,7 @@ class UserService
|
|
|
*
|
|
|
* 业务逻辑:
|
|
|
* 1. 记录错误信息和堆栈跟踪
|
|
|
- * 2. 记录用户ID和联系方式
|
|
|
+ * 2. 记录用户ID和联方式
|
|
|
* 3. 记录错误发生的文件和行号
|
|
|
*
|
|
|
* @param \Exception $e 异常对象
|
|
@@ -467,9 +460,9 @@ class UserService
|
|
|
*
|
|
|
* 业务逻辑:
|
|
|
* 1. 获取当前户信息
|
|
|
- * 2. 根据用户类型生成邀请码
|
|
|
+ * 2. 根据用户型生成邀请码
|
|
|
* 3. 生成包含邀请参数的接
|
|
|
- * 4. 生成邀请二维码
|
|
|
+ * 4. 生成邀请维码
|
|
|
* 5. 记录邀请码生成日志
|
|
|
*
|
|
|
* @param string $type 邀请码类型(user/coach)
|
|
@@ -488,7 +481,7 @@ class UserService
|
|
|
// 2. 根据类型获取邀请人ID和角色
|
|
|
$inviteInfo = $this->getInviteInfo($user, $type);
|
|
|
if (! $inviteInfo) {
|
|
|
- throw new \Exception('无法生成邀请码,用户类型不匹配');
|
|
|
+ throw new \Exception('无法生邀请码,用户类型不匹配');
|
|
|
}
|
|
|
|
|
|
// 3. 生成邀请码
|
|
@@ -530,7 +523,7 @@ class UserService
|
|
|
*
|
|
|
* 业务逻辑:
|
|
|
* 1. 根据类型判断邀请人身份
|
|
|
- * 2. 用户类型:直接返回用信息
|
|
|
+ * 2. 户类型:直接返回用信息
|
|
|
* 3. 技师类型:
|
|
|
* - 验证技师状态
|
|
|
* - 返回技师信息
|
|
@@ -598,7 +591,7 @@ class UserService
|
|
|
/**
|
|
|
* 生成二维码
|
|
|
*
|
|
|
- * 业务逻辑:
|
|
|
+ * 业务逻:
|
|
|
* 1. 使用 QrCode 库生成 SVG 格式二维码
|
|
|
* 2. 设置二维码大小和边距
|
|
|
* 3. 转换为 base64 编码
|