소스 검색

fixed:项目重构

刘学玺 4 달 전
부모
커밋
76686e3563

+ 1 - 1
.vscode/settings.json

@@ -19,7 +19,7 @@
             "token": "prod-token"
         }
     },
-    "window.zoomLevel" : 0.2,
+    "window.zoomLevel": 0.2,
     "git.autofetch": true,
     "git.autofetchPeriod": 60,
     "git.autoStash": true,

+ 91 - 0
app/Enums/ProjectStatus.php

@@ -0,0 +1,91 @@
+<?php
+
+namespace App\Enums;
+
+/**
+ * 项目状态枚举类
+ */
+enum ProjectStatus: int
+{
+    /**
+     * 项目状态:开启
+     */
+    case OPEN = 1;
+
+    /**
+     * 项目状态:关闭
+     */
+    case CLOSE = 2;
+
+    /**
+     * 获取状态的显示文本
+     *
+     * @return string 状态的中文描述
+     */
+    public function label(): string
+    {
+        return match ($this) {
+            self::OPEN => '开启',
+            self::CLOSE => '关闭',
+        };
+    }
+
+    /**
+     * 获取状态的整数值
+     *
+     * @return int 状态值
+     */
+    public function value(): int
+    {
+        return $this->value;
+    }
+
+    /**
+     * 检查当前状态是否与指定状态相同
+     *
+     * @param  self  $status  要比较的状态
+     * @return bool 如果状态相同返回 true,否则返回 false
+     */
+    public function is(self $status): bool
+    {
+        return $this === $status;
+    }
+
+    /**
+     * 根据整数值创建对应的状态枚举实例
+     *
+     * @param  int  $value  状态值
+     * @return self|null 返回对应的状态枚举实例,如果值无效则返回 null
+     */
+    public static function fromValue(int $value): ?self
+    {
+        return match ($value) {
+            self::OPEN->value => self::OPEN,
+            self::CLOSE->value => self::CLOSE,
+            default => null
+        };
+    }
+
+    /**
+     * 获取所有状态的值数组
+     *
+     * @return array 包含所有状态值的数组
+     */
+    public static function values(): array
+    {
+        return array_column(self::cases(), 'value');
+    }
+
+    /**
+     * 获取所有状态的键值对数组
+     *
+     * @return array 状态值作为键,显示文本作为值的关联数组
+     */
+    public static function all(): array
+    {
+        return [
+            self::OPEN->value => self::OPEN->label(),
+            self::CLOSE->value => self::CLOSE->label(),
+        ];
+    }
+}

+ 91 - 0
app/Enums/ProjectType.php

@@ -0,0 +1,91 @@
+<?php
+
+namespace App\Enums;
+
+/**
+ * 项目类型枚举类
+ */
+enum ProjectType: int
+{
+    /**
+     * 项目类型:上门
+     */
+    case VISIT = 1;
+
+    /**
+     * 项目类型:加钟
+     */
+    case OVERTIME = 2;
+
+    /**
+     * 获取类型的显示文本
+     *
+     * @return string 类型的中文描述
+     */
+    public function label(): string
+    {
+        return match ($this) {
+            self::VISIT => '上门',
+            self::OVERTIME => '加钟',
+        };
+    }
+
+    /**
+     * 获取类型的整数值
+     *
+     * @return int 类型值
+     */
+    public function value(): int
+    {
+        return $this->value;
+    }
+
+    /**
+     * 检查当前类型是否与指定类型相同
+     *
+     * @param  self  $type  要比较的类型
+     * @return bool 如果类型相同返回 true,否则返回 false
+     */
+    public function is(self $type): bool
+    {
+        return $this === $type;
+    }
+
+    /**
+     * 根据整数值创建对应的类型枚举实例
+     *
+     * @param  int  $value  类型值
+     * @return self|null 返回对应的类型枚举实例,如果值无效则返回 null
+     */
+    public static function fromValue(int $value): ?self
+    {
+        return match ($value) {
+            self::VISIT->value => self::VISIT,
+            self::OVERTIME->value => self::OVERTIME,
+            default => null
+        };
+    }
+
+    /**
+     * 获取所有类型的值数组
+     *
+     * @return array 包含所有类型值的数组
+     */
+    public static function values(): array
+    {
+        return array_column(self::cases(), 'value');
+    }
+
+    /**
+     * 获取所有类型的键值对数组
+     *
+     * @return array 类型值作为键,显示文本作为值的关联数组
+     */
+    public static function all(): array
+    {
+        return [
+            self::VISIT->value => self::VISIT->label(),
+            self::OVERTIME->value => self::OVERTIME->label(),
+        ];
+    }
+}

+ 12 - 3
app/Http/Controllers/Client/MarkDistTeamController.php → app/Http/Controllers/Client/MarketDistTeamController.php

@@ -5,13 +5,14 @@ namespace App\Http\Controllers\Client;
 use App\Http\Controllers\Controller;
 use App\Services\Client\MarketDistTeamService;
 use Auth;
+use Illuminate\Http\Request;
 
 /**
  * @group 用户端
  *
  * 团队相关的API接口
  */
-class MarkDistTeamController extends Controller
+class MarketDistTeamController extends Controller
 {
     protected MarketDistTeamService $service;
 
@@ -57,8 +58,16 @@ class MarkDistTeamController extends Controller
      *  }
      * }
      */
-    public function list()
+    public function index(Request $request)
     {
-        return $this->service->getTeamList(Auth::user()->id);
+        $validated = $request->validate([
+            'page' => 'nullable|integer|min:1',
+            'per_page' => 'nullable|integer|min:1|max:100',
+        ]);
+
+        return $this->service->getTeamList(
+            Auth::user()->id,
+            $validated['per_page'] ?? 15
+        );
     }
 }

+ 25 - 12
app/Http/Controllers/Client/ProjectController.php

@@ -21,7 +21,7 @@ class ProjectController extends Controller
     }
 
     /**
-     * 获取项目列表
+     * [项目]获取项目列表
      *
      * 根据区域代码获取项目列表
      *
@@ -29,7 +29,7 @@ class ProjectController extends Controller
      *
      * @queryParam area_code string 区域代码. Example: 330100
      * @queryParam project_cate_id integer 项目分类ID. Example: 1
-     * @queryParam type string 项目类型(normal:普通项目,add_time:加钟项目). Example: normal
+     * @queryParam type string 项目类型(1:普通项目,2:加钟项目). Example: 1
      *
      * @response {
      *   "code": 200,
@@ -56,15 +56,22 @@ class ProjectController extends Controller
      */
     public function index(Request $request)
     {
-        $areaCode = $request->input('area_code');
-        $projectCateId = $request->input('project_cate_id');
-        $type = $request->input('type');
 
-        return $this->service->getProjectList($areaCode, $projectCateId, $type);
+        $validated = $request->validate([
+            'area_code' => 'required|string',
+            'project_cate_id' => 'nullable|integer',
+            'type' => 'required|in:1,2',
+        ]);
+
+        return $this->service->getProjectList(
+            $validated['area_code'],
+            $validated['project_cate_id'] ?? null,
+            $validated['type']
+        );
     }
 
     /**
-     * 获取项目详情
+     * [项目]获取项目详情
      *
      * 获取指定项目的详细信息
      *
@@ -112,7 +119,7 @@ class ProjectController extends Controller
     }
 
     /**
-     * 获取技师项目列表
+     * [项目]获取技师项目列表
      *
      * 获取指定技师已开通的项目列表
      *
@@ -151,10 +158,16 @@ class ProjectController extends Controller
      */
     public function coachProjectList(Request $request)
     {
-        $coachId = $request->input('coach_id');
-        $areaCode = $request->input('area_code');
-        $projectCateId = $request->input('project_cate_id');
+        $validated = $request->validate([
+            'coach_id' => 'required|integer',
+            'area_code' => 'required|string',
+            'project_cate_id' => 'required|integer',
+        ]);
 
-        return $this->service->getCoachProjectList($coachId, $areaCode, $projectCateId);
+        return $this->service->getCoachProjectList(
+            $validated['coach_id'],
+            $validated['area_code'],
+            $validated['project_cate_id']
+        );
     }
 }

+ 5 - 4
app/Models/ProjectCate.php

@@ -10,16 +10,17 @@ use Slowlyo\OwlAdmin\Models\BaseModel as Model;
  */
 class ProjectCate extends Model
 {
-	use SoftDeletes;
+    use SoftDeletes;
 
-	protected $table = 'project_cate';
+    protected $table = 'project_cate';
 
     /**
      * @Author FelixYin
+     *
      * @description 项目分类关联服务
      */
-    public function services()
+    public function projects()
     {
         return $this->hasMany('App\Models\Project', 'cate_id', 'id');
     }
-}
+}

+ 2 - 2
app/Services/Client/MarketDistTeamService.php

@@ -72,7 +72,7 @@ class MarketDistTeamService
     /**
      * 获取团队列表
      */
-    public function getTeamList($userId)
+    public function getTeamList($userId, $perPage = 15)
     {
         try {
             // 获取当前用户
@@ -85,7 +85,7 @@ class MarketDistTeamService
             $teamList = $user->teams()->where('state', 1)
                 ->with(['user'])  // 关联用户
                 ->orderBy('created_at', 'desc')
-                ->get();
+                ->paginate($perPage);
 
             return response()->json([
                 'code' => 200,

+ 120 - 72
app/Services/Client/ProjectService.php

@@ -2,49 +2,90 @@
 
 namespace App\Services\Client;
 
+use App\Enums\ProjectStatus;
+use App\Enums\ProjectType;
 use App\Models\AgentInfo;
 use App\Models\CoachUser;
 use App\Models\Project;
 use App\Models\ProjectCate;
+use Illuminate\Support\Facades\Log;
 
 class ProjectService
 {
     /**
      * 获取项目列表
      */
-    public function getProjectList($areaCode, $projectCateId = null, $type = 'normal')
+    public function getProjectList($areaCode, $projectCateId = null, $type = ProjectType::VISIT)
     {
-        // 根据区域代码获取代理商
-        $agent = $this->findAvailableAgent($areaCode);
-
-        // 获取项目分类
-        $projectCate = ProjectCate::find($projectCateId);
-        // 获取项目列表
-        if ($agent) {
-            $agentCate = $agent->cates()->find($projectCate->id);
-            if ($type == 'normal') {
-                $projects = $agentCate->projects()->where('state', 'enable')->whereHas('basicInfo', fn ($q) => $q->where('type', 'normal'))->paginate(10);
+        try {
+
+            // 获取项目分类
+            $projectCate = ProjectCate::find($projectCateId);
+
+            abort_if(! $projectCate, 404, '项目分类不存在');
+            abort_if($projectCate->state != ProjectStatus::OPEN->value(), 404, '项目分类状态异常');
+
+            // 根据区域代码获取代理商
+            $agent = $this->findAvailableAgent($areaCode);
+
+            // 获取项目列表
+            if ($agent) {
+                $agentCate = $agent->cates()->where('project_cate_id', $projectCate->id)->first();
+                abort_if(! $agentCate || ($agentCate->state != ProjectStatus::OPEN->value()), 404, '当前区域未开通服务');
+
+                if (in_array($type, [ProjectType::VISIT->value()])) {
+                    $projects = $agentCate->projects()
+                        ->where('state', ProjectStatus::OPEN->value())
+                        ->with('basicInfo')
+                        ->whereHas('basicInfo', fn ($q) => $q->where('type', [ProjectType::VISIT->value()]))
+                        ->paginate(10);
+                    // 遍历项目,替换成代理商设置
+
+                }
+                if (in_array($type, [ProjectType::OVERTIME->value()])) {
+
+                    $projects = $agentCate->projects()
+                        ->where('state', ProjectStatus::OPEN->value())
+                        ->with('basicInfo')
+                        ->whereHas('basicInfo', fn ($q) => $q->whereIn('type', [ProjectType::VISIT->value(), ProjectType::OVERTIME->value()]))
+                        ->paginate(10);
+                    // 遍历项目,替换成代理商设置
+                }
             } else {
-                $projects = $agentCate->projects()->where('state', 'enable')->paginate(10);
+                if (in_array($type, [ProjectType::VISIT->value()])) {
+                    $projects = $projectCate?->projects()
+                        ->whereIn('type', [ProjectType::VISIT->value()])
+                        ->where('state', ProjectStatus::OPEN->value())
+                        ->paginate(10);
+                }
+                if (in_array($type, [ProjectType::OVERTIME->value()])) {
+                    $projects = $projectCate?->projects()
+                        ->whereIn('type', [ProjectType::VISIT->value(), ProjectType::OVERTIME->value()])
+                        ->where('state', ProjectStatus::OPEN->value())
+                        ->paginate(10);
+                }
             }
-        } else {
 
-            if ($type == 'normal') {
-                $projects = $projectCate?->services()->where('type', 'normal')->get();
-            } else {
-                $projects = $projectCate?->services;
-            }
-        }
+            return $projects;
 
-        return $projects;
+        } catch (\Exception $e) {
+            Log::error('获取项目列表失败', [
+                'error' => $e->getMessage(),
+                'areaCode' => $areaCode,
+                'projectCateId' => $projectCateId,
+                'type' => $type,
+            ]);
+            throw $e;
+        }
     }
 
     /**
      * 如果代理商存在,则返回代理商项目,否则返回系统项目
      *
-     * @param int $projectId 项目ID
-     * @param string $areaCode 区域代码
+     * @param  int  $projectId  项目ID
+     * @param  string  $areaCode  区域代码
      * @return Project 项目模型
+     *
      * @throws \Illuminate\Http\Exceptions\HttpResponseException 项目不存在时抛出404异常
      */
     public function getProjectDetail($projectId, $areaCode)
@@ -53,11 +94,18 @@ class ProjectService
         $project = Project::where('state', 'enable')->find($projectId);
         abort_if(! $project, 404, '项目不存在');
 
-       // 根据区域代码获取代理商
+        // 根据区域代码获取代理商
         $agent = $this->findAvailableAgent($areaCode);
         if ($agent) {
             // 查询代理商项目
-            $project = $agent->projects()->where('project_id', $projectId)->first();
+            $agentProject = $agent->projects()->where('project_id', $projectId)->first();
+            // 遍历代理商项目,替换系统项目
+            if ($agentProject) {
+                // 合并代理商项目的金额、时长、距离到系统项目
+                $project->price = $agentProject->price ?? $project->price;  // 金额
+                $project->duration = $agentProject->duration ?? $project->duration; // 时长
+                $project->distance = $agentProject->distance ?? $project->distance; // 距离
+            }
             $project->agent_id = $agent->id;
         }
 
@@ -69,55 +117,53 @@ class ProjectService
      */
     public function getCoachProjectList($coachId, $areaCode, $projectCateId)
     {
-        // 查询技师信息
-        $coach = CoachUser::where('id', $coachId)
-            ->where('state', 'enable')
-            ->find($coachId);
-
-        if (! $coach) {
-            throw new \Exception('技师不存在');
-        }
-
-        $coachInfo = $coach->info;
-        if (! $coachInfo) {
-            throw new \Exception('技师信息不存在');
-        }
-
-        if ($coachInfo->state !== 'approved') {
-            throw new \Exception('技师未通过审核');
-        }
-
-        $coachQual = $coach->qual;
-        if (! $coachQual) {
-            throw new \Exception('技师资格证书不存在');
-        }
-
-        if ($coachQual->state !== 'approved') {
-            throw new \Exception('技师资格证书未通过审核');
-        }
-
-        $coachReal = $coach->real;
-
-        if (! $coachReal) {
-            throw new \Exception('技师实名认证记录不存在');
-        }
-
-        if ($coachReal->state !== 'approved') {
-            throw new \Exception('技师实名认证未通过审核');
-        }
-
-        // 获取技师开通的项目ID列表
-        $projectIds = $coach->projects()->where('state', 'enable')->pluck('project_id');
-
-        // 根据区域代码获取代理商
-        $agent = $this->findAvailableAgent($areaCode);
+        try {
+            // 查询技师信息
+            $coach = CoachUser::where('id', $coachId)
+                ->where('state', 'enable')
+                ->with(['info', 'qual', 'real'])
+                ->first();
+
+            abort_if(! $coach, 404, '技师不存在');
+            abort_if(! $coach->info, 404, '技师信息不存在');
+            abort_if($coach->info->state !== 'approved', 404, '技师未通过审核');
+            abort_if(! $coach->qual, 404, '技师资格证书不存在');
+            abort_if($coach->qual->state !== 'approved', 404, '技师资格证书未通过审核');
+            abort_if(! $coach->real, 404, '技师实名认证记录不存在');
+            abort_if($coach->real->state !== 'approved', 404, '技师实名认证未通过审核');
+
+            // 获取技师开通的项目ID列表
+            $projectIds = $coach->projects()
+                ->where('state', 'enable')
+                ->pluck('project_id');
+
+            // 根据区域代码获取代理商
+            $agent = $this->findAvailableAgent($areaCode);
+
+            if ($agent) {
+                $agentCate = $agent->cates()
+                    ->where('project_cate_id', $projectCateId)
+                    ->first();
+
+                $projectIds = $agentCate->projects()
+                    ->whereIn('project_id', $projectIds)
+                    ->pluck('project_id');
+            }
 
-        if ($agent) {
-            $agentCate = $agent->cates()->where('project_cate_id', $projectCateId)->first();
-            $projectIds = $agentCate->projects()->whereIn('project_id', $projectIds)->pluck('project_id');
+            return $coach->projects()
+                ->with('basicInfo')
+                ->whereIn('project_id', $projectIds)
+                ->get();
+
+        } catch (\Exception $e) {
+            Log::error('获取技师项目列表失败', [
+                'error' => $e->getMessage(),
+                'coachId' => $coachId,
+                'areaCode' => $areaCode,
+                'projectCateId' => $projectCateId,
+            ]);
+            throw $e;
         }
-
-        return $coach->projects()->with('basicInfo')->whereIn('project_id', $projectIds)->get();
     }
 
     /**
@@ -129,7 +175,9 @@ class ProjectService
     private function findAvailableAgent($areaCode)
     {
         // 先查找当前区域的代理商
-        $agent = AgentInfo::where('area_code', $areaCode)
+        // 区域代码不足6位,右边补0
+        $fullAreaCode = str_pad($areaCode, 6, '0', STR_PAD_RIGHT);
+        $agent = AgentInfo::where('area_code', $fullAreaCode)
             ->where('state', 'enable')
             ->first();
 

+ 2 - 1
routes/api.php

@@ -3,6 +3,7 @@
 use App\Http\Controllers\Client\AccountController;
 use App\Http\Controllers\Client\CoachController;
 use App\Http\Controllers\Client\CoachLocationController;
+use App\Http\Controllers\Client\MarketDistTeamController;
 use App\Http\Controllers\Client\OrderController;
 use App\Http\Controllers\Client\ProjectController;
 use App\Http\Controllers\Client\UserAddressController;
@@ -117,6 +118,6 @@ Route::middleware('auth:sanctum')->group(function () {
 
     // 团队管理路由
     Route::prefix('team')->group(function () {
-        Route::get('list', [App\Http\Controllers\Client\MarkDistTeamController::class, 'list']);
+        Route::get('list', [MarketDistTeamController::class, 'index'])->name('team.list');
     });
 });