Browse Source

fixed:技师端-优化开通项目(添加关闭项目)

刘学玺 4 months ago
parent
commit
d98054d9ef

+ 8 - 10
app/Http/Controllers/Coach/ProjectController.php

@@ -65,18 +65,19 @@ class ProjectController extends Controller
     }
 
     /**
-     * [项目]开通项目
+     * [项目]开通/关闭项目
      *
-     * @description 技师开通新的服务项目,包含项目状态和开通资格检查
+     * @description 技师开通或关闭服务项目,包含项目状态和资格检查
      *
      * 业务流程:
-     * 1. 验证项目ID
-     * 2. 调用服务层处理开逻辑
-     * 3. 返回开通结果
+     * 1. 验证项目ID和操作类型
+     * 2. 调用服务层处理开逻辑
+     * 3. 返回操作结果
      *
      * @authenticated 需要技师身份认证
      *
      * @bodyParam project_id integer required 项目ID Example: 1
+     * @bodyParam action string required 操作类型(open:开通 close:关闭) Example: "open"
      *
      * @response {
      *   "status": true,
@@ -93,15 +94,12 @@ class ProjectController extends Controller
      *   "message": "项目不存在或已下架"
      * }
      * @response 422 {
-     *   "message": "已开通该项目"
-     * }
-     * @response 422 {
-     *   "message": "技师状态异常,无法开通项目"
+     *   "message": "技师状态异常,无法操作项目"
      * }
      */
     public function openProject(OpenProjectRequest $request)
     {
-        // 调用服务层处理开通逻辑并返回结果
+        // 调用服务层处理开通/关闭逻辑并返回结果
         return $this->success(
             $this->service->openProject(Auth::user()->coach, $request->validated())
         );

+ 4 - 0
app/Http/Requests/Coach/OpenProjectRequest.php

@@ -26,6 +26,7 @@ class OpenProjectRequest extends FormRequest
     {
         return [
             'project_id' => 'required|integer|exists:project,id',
+            'action' => 'required|string|in:open,close',
         ];
     }
 
@@ -40,6 +41,9 @@ class OpenProjectRequest extends FormRequest
             'project_id.required' => '项目ID不能为空',
             'project_id.integer' => '项目ID必须是整数',
             'project_id.exists' => '项目不存在',
+            'action.required' => '操作类型不能为空',
+            'action.string' => '操作类型必须是字符串',
+            'action.in' => '操作类型只能是开通或关闭',
         ];
     }
 }

+ 16 - 28
app/Models/CoachUser.php

@@ -228,36 +228,24 @@ class CoachUser extends Model
     }
 
     /**
-     * 验证技师是否已开通指定项目
+     * 创建或更新技师项目关联
      *
      * @param int $projectId 项目ID
-     * @param string|null $message 自定义错误消息
-     * @throws \Illuminate\Http\Exceptions\HttpResponseException 当已开通项目时抛出异常
-     */
-    public function validateProjectNotOpened(int $projectId, ?string $message = null): void
-    {
-        $existingProject = $this->projects()
-            ->where('project_id', $projectId)
-            ->first();
-
-        abort_if($existingProject, 422, $message ?? '已开通该项目');
+     * @param int $state 项目状态
+     * @return CoachProject 返回创建或更新的技师项目关联实例
+     */
+    public function updateOrCreateProjectRelation(int $projectId, int $state): CoachProject
+    {
+        return $this->projects()->updateOrCreate(
+            ['project_id' => $projectId],
+            [
+                'state' => $state,
+                'discount_amount' => 0.00,    // 默认折扣金额
+                'service_gender' => 0,        // 默认服务性别(不限)
+                'service_distance' => 0,      // 默认服务距离
+                'traffic_fee_type' => 2,      // 默认交通费类型(双程)
+            ]
+        );
     }
 
-    /**
-     * 创建技师项目关联
-     *
-     * @param int $projectId 项目ID
-     * @return CoachProject 返回创建的技师项目关联实例
-     */
-    public function createProjectRelation(int $projectId): CoachProject
-    {
-        return $this->projects()->create([
-            'project_id' => $projectId,
-            'state' => ProjectStatus::OPEN->value,
-            'discount_amount' => 0.00,    // 默认折扣金额
-            'service_gender' => 0,        // 默认服务性别(不限)
-            'service_distance' => 0,      // 默认服务距离
-            'traffic_fee_type' => 2,      // 默认交通费类型(双程)
-        ]);
-    }
 }

+ 8 - 7
app/Models/Project.php

@@ -58,22 +58,23 @@ class Project extends Model
     }
 
     /**
-     * 格式化项目开通结果
+     * 格式化项目操作结果
      *
-     * @param CoachProject $coachProject 技师项目关联实例
-     * @return array 格式化后的开通结果,包含:
+     * @param int $state 项目状态
+     * @param string|null $stateText 状态描述文本
+     * @return array 格式化后的操作结果,包含:
      *        - project_id: int 项目ID
      *        - project_name: string 项目名称
      *        - state: int 项目状态
-     *        - state_text: string 状态描述(已开通)
+     *        - state_text: string 状态描述
      */
-    public function formatOpenResult(CoachProject $coachProject): array
+    public function formatActionResult(int $state, ?string $stateText = null): array
     {
         return [
             'project_id' => $this->id,
             'project_name' => $this->title,
-            'state' => $coachProject->state,
-            'state_text' => '已开通',
+            'state' => $state,
+            'state_text' => $stateText ?? ($state === ProjectStatus::OPEN->value ? '已开通' : '已关闭'),
         ];
     }
 }

+ 43 - 23
app/Services/Coach/ProjectService.php

@@ -72,53 +72,73 @@ class ProjectService
     }
 
     /**
-     * 技师开通项目
+     * 技师开通/关闭项目
      *
      * 业务流程:
      * 1. 验证技师状态
      * 2. 验证项目状态
-     * 3. 检查是否已开通
-     * 4. 创建项目关联
-     * 5. 返回开通结果
-     *
-     * 注意事项:
-     * - 技师状态必须正常
-     * - 只能开通状态为开放的项目
-     * - 不能重复开通同一个项目
-     * - 使用事务确保数据一致性
-     * - 返回标准化的开通结果
+     * 3. 根据操作类型处理项目
+     * 4. 返回操作结果
      *
      * @param CoachUser $coach 技师对象
-     * @param array $data 开通项目数据,包含:
+     * @param array $data 项目操作数据,包含:
      *        - project_id: int 项目ID
-     * @return array 开通结果,包含:
+     *        - action: string 操作类型(open:开通 close:关闭)
+     * @return array 操作结果,包含:
      *        - project_id: int 项目ID
      *        - project_name: string 项目名称
      *        - state: int 项目状态
-     *        - state_text: string 状态描述(已开通)
+     *        - state_text: string 状态描述
      * @throws \Illuminate\Http\Exceptions\HttpResponseException 当验证失败时抛出异常
      */
     public function openProject(CoachUser $coach, array $data): array
     {
         return DB::transaction(function () use ($coach, $data) {
             // 检查技师状态是否正常
-            $coach->validateActiveStatus('技师状态异常,无法开通项目');
+            $coach->validateActiveStatus('技师状态异常,无法操作项目');
 
             // 验证项目是否存在且状态为开放
-            // 验证项目是否存在且状态正常
             $project = Project::validateOpenProject($data['project_id']);
 
-            // 检查是否已开通该项目
-            $coach->validateProjectNotOpened($data['project_id']);
-
-            // 创建技师项目关联
-            $coachProject = $coach->createProjectRelation($data['project_id']);
+            // 根据操作类型处理项目并获取状态
+            $state = match ($data['action']) {
+                'open' => $this->handleProjectOpen($coach, $data['project_id']),
+                'close' => $this->handleProjectClose($coach, $data['project_id']),
+            };
 
-            // 返回格式化的开通结果
-            return $project->formatOpenResult($coachProject);
+            // 返回格式化的操作结果
+            return $project->formatActionResult($state);
         });
     }
 
+    /**
+     * 处理项目开通
+     *
+     * @param CoachUser $coach 技师对象
+     * @param int $projectId 项目ID
+     * @return int 返回开通后的状态值
+     */
+    private function handleProjectOpen(CoachUser $coach, int $projectId): int
+    {
+        // 创建或更新项目关联为开通状态
+        $coach->updateOrCreateProjectRelation($projectId, ProjectStatus::OPEN->value);
+        return ProjectStatus::OPEN->value;
+    }
+
+    /**
+     * 处理项目关闭
+     *
+     * @param CoachUser $coach 技师对象
+     * @param int $projectId 项目ID
+     * @return int 返回关闭后的状态值
+     */
+    private function handleProjectClose(CoachUser $coach, int $projectId): int
+    {
+        // 创建或更新项目关联为关闭状态
+        $coach->updateOrCreateProjectRelation($projectId, ProjectStatus::CLOSE->value);
+        return ProjectStatus::CLOSE->value;
+    }
+
     /**
      * 设置项目
      *