Ver Fonte

feat:技师端-修改基本信息

刘学玺 há 4 meses atrás
pai
commit
5f38e730db

+ 43 - 3
app/Http/Controllers/Coach/AccountController.php

@@ -11,11 +11,11 @@ use Illuminate\Support\Facades\Auth;
 use App\Enums\TechnicianLocationType;
 use App\Services\Coach\AccountService;
 use App\Http\Requests\Coach\SetLocationRequest;
+use App\Http\Requests\Coach\SendVerifyCodeRequest;
 use App\Http\Requests\Coach\SubmitBaseInfoRequest;
 use App\Http\Requests\Coach\SubmitRealNameRequest;
-use App\Http\Requests\Coach\SubmitQualificationRequest;
 use App\Http\Requests\Coach\UpdateBasicInfoRequest;
-use App\Http\Requests\Coach\SendVerifyCodeRequest;
+use App\Http\Requests\Coach\SubmitQualificationRequest;
 
 /**
  * @group 技师端
@@ -503,13 +503,25 @@ class AccountController extends Controller
     /**
      * [账户]更新基础信息
      *
-     * @description 更新技师的基础信息,包括昵称、性别和手机号
+     * @description 更新技师的基础信息,包括昵称、性别和手机号。修改手机号时需要先获取验证码进行验证。
+     *
+     * 业务流程:
+     * 1. 验证提交的数据
+     * 2. 验证手机验证码(如果修改手机号)
+     * 3. 调用服务层处理更新
+     * 4. 返回更新结果
+     *
+     * 注意事项:
+     * - 可以单独更新某个字段,不需要同时提交所有字段
+     * - 修改手机号时必须提供验证码
+     * - 同一时间只能有一条待审核记录
      *
      * @authenticated 需要技师身份认证
      *
      * @bodyParam nickname string nullable 昵称(2-20个字符) Example: 张三
      * @bodyParam gender integer nullable 性别(1:男 2:女) Example: 1
      * @bodyParam mobile string nullable 手机号 Example: 13800138000
+     * @bodyParam code string required if:mobile 验证码(修改手机号时必填) Example: 123456
      *
      * @response {
      *   "status": true,
@@ -519,6 +531,34 @@ class AccountController extends Controller
      *     "updated_fields": ["nickname", "gender"]
      *   }
      * }
+     *
+     * @response {
+     *   "status": true,
+     *   "message": "基础信息修改申请已更新",
+     *   "data": {
+     *     "record_id": 1,
+     *     "updated_fields": ["mobile"]
+     *   }
+     * }
+     *
+     * @response 404 {
+     *   "message": "未找到有效的基础信息记录"
+     * }
+     * @response 422 {
+     *   "message": "没有需要更新的字段"
+     * }
+     * @response 422 {
+     *   "message": "验证码错误或已过期"
+     * }
+     * @response 422 {
+     *   "message": "验证错误",
+     *   "errors": {
+     *     "nickname": ["昵称不能少于2个字符"],
+     *     "gender": ["性别只能是1(男)或2(女)"],
+     *     "mobile": ["手机号格式不正确"],
+     *     "code": ["验证码不能为空"]
+     *   }
+     * }
      */
     public function updateBasicInfo(UpdateBasicInfoRequest $request)
     {

+ 10 - 1
app/Http/Requests/Coach/UpdateBasicInfoRequest.php

@@ -11,7 +11,7 @@ class UpdateBasicInfoRequest extends FormRequest
 {
     public function rules(): array
     {
-        return [
+        $rules = [
             'nickname' => 'nullable|string|min:2|max:20',
             'gender' => 'nullable|integer|in:1,2',
             'mobile' => [
@@ -21,6 +21,13 @@ class UpdateBasicInfoRequest extends FormRequest
                 'regex:/^1[3-9]\d{9}$/',
             ],
         ];
+
+        // 如果提交了手机号,则验证码必填
+        if ($this->has('mobile')) {
+            $rules['code'] = 'required|string|size:6';
+        }
+
+        return $rules;
     }
 
     public function messages(): array
@@ -33,6 +40,8 @@ class UpdateBasicInfoRequest extends FormRequest
             'gender.in' => '性别只能是1(男)或2(女)',
             'mobile.size' => '手机号必须是11位',
             'mobile.regex' => '手机号格式不正确',
+            'code.required' => '验证码不能为空',
+            'code.size' => '验证码必须是6位',
         ];
     }
 }

+ 32 - 3
app/Services/Coach/AccountService.php

@@ -419,7 +419,7 @@ class AccountService
      */
     public function setLocation($coachId, $latitude, $longitude, $type = TechnicianLocationType::COMMON->value, array $locationInfo = [])
     {
-        // 使用事务确保��一致性
+        // 使用事务确保一致性
         return DB::transaction(function () use ($coachId, $latitude, $longitude, $type, $locationInfo) {
             // 验证经纬度的有效性(-90≤纬度≤90,-180≤经度≤180)
             $this->validateCoordinates($latitude, $longitude);
@@ -1221,14 +1221,16 @@ class AccountService
      *
      * 业务流程:
      * 1. 获取最新的非拒绝记录
-     * 2. 如果是待审核状态,直接更新字段
-     * 3. 如果是已通过状态,创建新记录并复制字段
+     * 2. 验证手机验证码(如果修改手机号)
+     * 3. 如果是待审核状态,直接更新字段
+     * 4. 如果是已通过状态,创建新记录并复制字段
      *
      * @param CoachUser $coach 技师对象
      * @param array $data 待更新的数据,可包含:
      *        - nickname: ?string 昵称
      *        - gender: ?int 性别(1:男 2:女)
      *        - mobile: ?string 手机号
+     *        - code: ?string 验证码(修改手机号时必填)
      * @return array 返回结果
      */
     public function updateBasicInfo(CoachUser $coach, array $data): array
@@ -1242,6 +1244,11 @@ class AccountService
 
             abort_if(!$latestRecord, 404, '未找到有效的基础信息记录');
 
+            // 如果要修改手机号,验证验证码
+            if (isset($data['mobile'])) {
+                $this->verifyMobileCode($data['mobile'], $data['code']);
+            }
+
             // 提取要更新的字段
             $updateFields = array_intersect_key($data, [
                 'nickname' => '',
@@ -1284,6 +1291,28 @@ class AccountService
         });
     }
 
+    /**
+     * 验证手机验证码
+     *
+     * @param string $mobile 手机号
+     * @param string $code 验证码
+     * @throws \Illuminate\Http\Exceptions\HttpResponseException
+     */
+    private function verifyMobileCode(string $mobile, string $code): void
+    {
+        // 缓存键
+        $cacheKey = "sms_code:update:{$mobile}";
+
+        // 获取缓存中的验证码
+        $cacheCode = Redis::get($cacheKey);
+
+        // 验证码不存在或不匹配
+        abort_if(!$cacheCode || $cacheCode !== $code, 422, '验证码错误或已过期');
+
+        // 验证成功后删除验证码
+        Redis::del($cacheKey);
+    }
+
     /**
      * 发送验证码
      *