Browse Source

feat:技师端-获取技师详情

刘学玺 4 months ago
parent
commit
67fbabe181

+ 59 - 1
app/Http/Controllers/Coach/AccountController.php

@@ -142,7 +142,7 @@ class AccountController extends Controller
     }
 
     /**
-     * [账户]获取技师信息
+     * [账户]获取技师认证信息
      *
      * @description 获取技师的基本信息、资质信息和实名认证信息
      *
@@ -435,4 +435,62 @@ class AccountController extends Controller
 
         return $this->success($schedule);
     }
+
+    /**
+     * [账户]获取技师详细信息
+     *
+     * @description 获取当前登录技师的详细信息,包括基本信息、邀请码和钱包信息
+     *
+     * 业务流程:
+     * 1. 验证用户身份
+     * 2. 获取技师详细信息
+     * 3. 返回数据
+     *
+     * @authenticated 需要技师身份认证
+     *
+     * @response 200 {
+     *   "status": true,
+     *   "message": "获取成功",
+     *   "data": {
+     *     "id": 1,
+     *     "coach_no": "00000001",
+     *     "user_id": 100,
+     *     "mobile": "13800138000",
+     *     "nickname": "张三",
+     *     "avatar": "https://example.com/avatar.jpg",
+     *     "age": 25,
+     *     "gender": 1,
+     *     "work_years": 5,
+     *     "intention_city": "杭州",
+     *     "life_photos": [
+     *       "https://example.com/photo1.jpg",
+     *       "https://example.com/photo2.jpg"
+     *     ],
+     *     "introduction": "专业按摩师,从业5年",
+     *     "state": 1,
+     *     "state_text": "正常",
+     *     "invite_code": "coach_1",
+     *     "wallet": {
+     *       "balance": 1000,
+     *       "frozen": 200,
+     *       "total_income": 5000,
+     *       "today_income": 300,
+     *       "withdrawable": 800
+     *     },
+     *     "created_at": "2024-03-20 10:00:00",
+     *     "updated_at": "2024-03-20 10:00:00"
+     *   }
+     * }
+     * @response 404 {
+     *   "message": "技师信息不存在"
+     * }
+     */
+    public function detail()
+    {
+        // 获取技师详细信息
+        $data = $this->service->getCoachDetail();
+
+        // 返回成功响应
+        return $this->success($data, '获取成功');
+    }
 }

+ 1 - 0
app/Models/CoachInfoRecord.php

@@ -24,6 +24,7 @@ class CoachInfoRecord extends Model
      */
     protected $casts = [
         'portrait_images' => 'array',
+        'life_photos' => 'array'
     ];
 
     /**

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

@@ -7,10 +7,13 @@ use App\Enums\OrderStatus;
 use App\Models\MemberUser;
 use App\Models\CoachLocation;
 use App\Models\CoachSchedule;
+use App\Enums\TechnicianStatus;
+use App\Models\CoachInfoRecord;
 use Illuminate\Support\Facades\DB;
 use App\Enums\TechnicianAuthStatus;
 use App\Enums\TechnicianWorkStatus;
 use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Auth;
 use App\Enums\TechnicianLocationType;
 use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\Redis;
@@ -304,7 +307,7 @@ class AccountService
         return [
             'nickname' => $info->nickname,
             'avatar' => $info->avatar,  // 支持任意格式的图片数据
-            'life_photos' => json_decode($info->life_photos, true) ?? [],  // 生活照片数组
+            'life_photos' => $info->life_photos ?? [],  // 生活照片数组
             'gender' => $info->gender,
             'mobile' => $this->maskMobile($info->mobile),  // 手机号脱敏处理
             'birthday' => $info->birthday,
@@ -411,7 +414,7 @@ class AccountService
      * 1. 验证经纬度参数
      * 2. 验证位置类型
      * 3. 保存到Redis的地理位置数据结构
-     * 4. 同步保存到据库
+     * 4. 同步保存到据库
      *
      * @param int $coachId 技师ID
      * @param float $latitude 纬度
@@ -939,7 +942,7 @@ class AccountService
             $coach = $user->coach;
             abort_if(! $coach, 404, '技师信息不存在');
 
-            // 先尝试缓存获取
+            // 先尝试缓存获取
             $cacheKey = "coach:schedule:{$coach->id}";
             $cached = Redis::get($cacheKey);
             if ($cached) {
@@ -1073,4 +1076,104 @@ class AccountService
         // 参数顺序:key longitude latitude member
         return Redis::geoadd('coach_locations', $longitude, $latitude, $key);
     }
+
+    /**
+     * 获取技师详细信息
+     *
+     * 业务逻辑:
+     * 1. 获取技师最新基本信息(不包括审核拒绝的记录)
+     * 2. 获取技师邀请码信息
+     * 3. 获取钱包信息
+     * 4. 组装返回数据
+     *
+     * @return array 技师详细信息
+     * @throws \Exception 获取信息失败时抛出异常
+     */
+    public function getCoachDetail(): array
+    {
+        // 获取当前登录用户
+        /** @var MemberUser $user */
+        $user = Auth::user();
+
+        // 获取用户的技师信息
+        $coach = $user->coach;
+        abort_if(!$coach, 404, '技师信息不存在');
+
+        // 获取最新的技师信息记录(排除审核拒绝的记录)
+        $latestInfo = CoachInfoRecord::where('coach_id', $coach->id)
+            ->where('state', '<>', TechnicianAuthStatus::REJECTED->value)
+            ->latest()
+            ->first();
+        abort_if(!$latestInfo, 404, '技师基本信息不存在');
+
+        // 生成技师工号(例如:8位数字,不足前面补0)
+        $coachNo = str_pad($coach->id, 8, '0', STR_PAD_LEFT);
+
+        // 获取技师邀请码
+        $inviteCode = $this->generateInviteCode($coach->id);
+
+        // 获取钱包信息
+        $wallet = $this->getWalletInfo($coach->id);
+
+        // 获取基本信息
+        $baseInfo = $this->formatBaseInfo($latestInfo);
+
+        // 组装返回数据
+        return array_merge(
+            [
+                'coach_no' => $coachNo,
+                'invite_code' => $inviteCode,
+                'wallet' => $wallet,
+            ],
+            $baseInfo
+        );
+    }
+
+    /**
+     * 生成技师邀请码
+     *
+     * @param int $coachId 技师ID
+     * @return string 邀请码
+     */
+    private function generateInviteCode(int $coachId): string
+    {
+        return sprintf('C%d', $coachId);
+    }
+
+    /**
+     * 获取技师钱包信息
+     *
+     * 业务逻辑:
+     * 1. 获取技师钱包关联数据
+     * 2. 如果钱包不存在,返回默认值
+     * 3. 返回钱包概况数据
+     *
+     * @param int $coachId 技师ID
+     * @return array 钱包概况信息
+     */
+    private function getWalletInfo(int $coachId): array
+    {
+        // 获取技师对象及其钱包关联
+        $coach = CoachUser::with('wallet')->find($coachId);
+
+        // 如果钱包不存在,返回默认值
+        if (!$coach || !$coach->wallet) {
+            return [
+                'total_balance' => 0,         // 总余额
+                'available_balance' => 0,     // 可用余额
+                'frozen_amount' => 0,         // 冻结金额
+                'total_income' => 0,          // 累计收入
+                'total_expense' => 0,         // 累计支出
+            ];
+        }
+
+        // 返回钱包概况数据
+        return [
+            'total_balance' => $coach->wallet->total_balance ?? 0,           // 总余额
+            'available_balance' => $coach->wallet->available_balance ?? 0,   // 可用余额
+            'frozen_amount' => $coach->wallet->frozen_amount ?? 0,          // 冻结金额
+            'total_income' => $coach->wallet->total_income ?? 0,            // 累计收入
+            'total_expense' => $coach->wallet->total_expense ?? 0,          // 累计支出
+        ];
+    }
 }

+ 17 - 12
routes/api.php

@@ -1,23 +1,23 @@
 <?php
 
-use App\Http\Controllers\Client\AccountController;
+use Illuminate\Support\Facades\Route;
+use App\Http\Controllers\EnumController;
+use App\Http\Controllers\ScribeController;
+use App\Http\Controllers\UploadController;
+use App\Http\Controllers\Client\UserController;
 use App\Http\Controllers\Client\CoachController;
-use App\Http\Controllers\Client\CoachLocationController;
-use App\Http\Controllers\Client\CommentController;
-use App\Http\Controllers\Client\MarketDistTeamController;
 use App\Http\Controllers\Client\OrderController;
-use App\Http\Controllers\Client\ProjectController;
-use App\Http\Controllers\Client\UserAddressController;
-use App\Http\Controllers\Client\UserController;
 use App\Http\Controllers\Client\WalletController;
 use App\Http\Controllers\Client\WechatController;
+use App\Http\Controllers\Client\AccountController;
+use App\Http\Controllers\Client\CommentController;
+use App\Http\Controllers\Client\ProjectController;
+use App\Http\Controllers\Client\UserAddressController;
+use App\Http\Controllers\Client\CoachLocationController;
+use App\Http\Controllers\Client\MarketDistTeamController;
 use App\Http\Controllers\Coach\OrderController as CoachOrderController;
-use App\Http\Controllers\Coach\ProjectController as CoachProjectController;
 use App\Http\Controllers\Coach\WalletController as CoachWalletController;
-use App\Http\Controllers\EnumController;
-use App\Http\Controllers\ScribeController;
-use App\Http\Controllers\UploadController;
-use Illuminate\Support\Facades\Route;
+use App\Http\Controllers\Coach\ProjectController as CoachProjectController;
 
 // API文档相关
 Route::get('scribe/update-token/{mobile}', [ScribeController::class, 'updateAuthToken']);
@@ -176,6 +176,8 @@ Route::middleware(['auth:sanctum', 'coach'])->prefix('coach')->group(function ()
         Route::post('qualification', [App\Http\Controllers\Coach\AccountController::class, 'submitQualification']);
         Route::post('real-name', [App\Http\Controllers\Coach\AccountController::class, 'submitRealName'])
             ->middleware('throttle:3,1');  // 实名认证限制更严格
+
+        // 获取技师认证详情
         Route::get('info', [App\Http\Controllers\Coach\AccountController::class, 'info']);
         // 设置位置信息
         Route::post('location', [App\Http\Controllers\Coach\AccountController::class, 'setLocation'])
@@ -190,6 +192,9 @@ Route::middleware(['auth:sanctum', 'coach'])->prefix('coach')->group(function ()
         Route::get('work-status', [App\Http\Controllers\Coach\AccountController::class, 'getWorkStatus']);
         // 获取技师排班信息
         Route::get('schedule', [App\Http\Controllers\Coach\AccountController::class, 'getSchedule']);
+
+        // 获取技师详情
+        Route::get('detail', [App\Http\Controllers\Coach\AccountController::class, 'detail'])->name('coach.detail');
     });
 
     // 订单相关路由