ProjectService.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. <?php
  2. namespace App\Services\Coach;
  3. use App\Enums\ProjectStatus;
  4. use App\Enums\TechnicianStatus;
  5. use App\Models\MemberUser;
  6. use App\Models\Project;
  7. use Illuminate\Support\Facades\DB;
  8. use Illuminate\Support\Facades\Log;
  9. class ProjectService
  10. {
  11. /**
  12. * 获取所有可以开通的项目列表
  13. *
  14. * @param int $userId 技师用户ID
  15. */
  16. public function getAvailableProjects(int $userId): array
  17. {
  18. try {
  19. // 加载用户和技师信息
  20. $user = MemberUser::with(['coach', 'coach.projects'])->findOrFail($userId);
  21. abort_if(! $user->coach, 404, '技师信息不存在');
  22. // 获取所有可开通的项目
  23. $projects = Project::where('state', ProjectStatus::OPEN->value)
  24. ->select([
  25. 'id',
  26. 'title',
  27. 'subtitle',
  28. 'cover',
  29. 'price',
  30. 'original_price',
  31. 'sales',
  32. 'duration',
  33. 'project_desc',
  34. 'service_desc',
  35. 'type',
  36. ])
  37. ->get();
  38. // 记录日志
  39. Log::info('获取可开通项目列表成功', [
  40. 'user_id' => $userId,
  41. 'coach_id' => $user->coach->id,
  42. 'project_count' => $projects->count(),
  43. ]);
  44. return [
  45. 'items' => $projects,
  46. 'total' => $projects->count(),
  47. ];
  48. } catch (\Exception $e) {
  49. Log::error('获取可开通项目列表失败', [
  50. 'user_id' => $userId,
  51. 'error' => $e->getMessage(),
  52. 'file' => $e->getFile(),
  53. 'line' => $e->getLine(),
  54. ]);
  55. throw $e;
  56. }
  57. }
  58. /**
  59. * 技师开通项目
  60. *
  61. * @param int $userId 技师用户ID
  62. * @param array $data 开通项目数据
  63. */
  64. public function openProject(int $userId, array $data): array
  65. {
  66. return DB::transaction(function () use ($userId, $data) {
  67. try {
  68. // 加载用户和技师信息
  69. $user = MemberUser::with(['coach', 'coach.projects'])->findOrFail($userId);
  70. abort_if(! $user->coach, 404, '技师信息不存在');
  71. // 验证项目是否存在且状态正常
  72. $project = Project::where('id', $data['project_id'])
  73. ->where('state', ProjectStatus::OPEN->value)
  74. ->first();
  75. abort_if(! $project, 404, '项目不存在或已下架');
  76. // 检查是否已开通该项目
  77. $existingProject = $user->coach->projects()
  78. ->where('project_id', $data['project_id'])
  79. ->first();
  80. abort_if($existingProject, 422, '已开通该项目');
  81. // 检查技师状态
  82. abort_if($user->coach->state !== TechnicianStatus::ACTIVE->value,
  83. 422, '技师状态异常,无法开通项目');
  84. // 创建技师项目关联
  85. $coachProject = $user->coach->projects()->create([
  86. 'project_id' => $data['project_id'],
  87. 'state' => ProjectStatus::OPEN->value,
  88. 'discount_amount' => 0.00,
  89. 'service_gender' => 0,
  90. 'service_distance' => 0,
  91. 'traffic_fee_type' => 2,
  92. 'traffic_fee' => 0,
  93. 'created_at' => now(),
  94. 'updated_at' => now(),
  95. ]);
  96. // 记录日志
  97. Log::info('技师开通项目成功', [
  98. 'user_id' => $userId,
  99. 'coach_id' => $user->coach->id,
  100. 'project_id' => $data['project_id'],
  101. 'project_name' => $project->name,
  102. ]);
  103. return [
  104. 'message' => '项目开通成功',
  105. 'project_id' => $project->id,
  106. 'project_name' => $project->name,
  107. ];
  108. } catch (\Exception $e) {
  109. Log::error('技师开通项目失败', [
  110. 'user_id' => $userId,
  111. 'data' => $data,
  112. 'error' => $e->getMessage(),
  113. 'file' => $e->getFile(),
  114. 'line' => $e->getLine(),
  115. ]);
  116. throw $e;
  117. }
  118. });
  119. }
  120. /**
  121. * 设置项目
  122. *
  123. * @param int $userId 技师用户ID
  124. * @param array $data 项目设置数据
  125. * @return array
  126. *
  127. * @throws \Exception
  128. */
  129. public function setProject(int $userId, array $data)
  130. {
  131. return DB::transaction(function () use ($userId, $data) {
  132. try {
  133. // 加载用户和技师信息
  134. $user = MemberUser::with(['coach', 'coach.projects'])->findOrFail($userId);
  135. abort_if(! $user->coach, 404, '技师信息不存在');
  136. // 检查项目是否存在
  137. $coachProject = $user->coach->projects()
  138. ->where('project_id', $data['project_id'])
  139. ->first();
  140. abort_if(! $coachProject, 404, '未开通该项目');
  141. // TODO:取值范围待定(从配置表中获取)
  142. // 验证服务距离的合理范围
  143. if (isset($data['service_distance']) && $data['service_distance'] > 0) {
  144. abort_if($data['service_distance'] > 50, 422, '服务距离不能超过50公里');
  145. }
  146. // 更新项目设置
  147. $coachProject->update([
  148. 'discount_amount' => $data['discount_amount'] ?? $coachProject->discount_amount,
  149. 'service_gender' => $data['service_gender'] ?? $coachProject->service_gender,
  150. 'service_distance' => $data['service_distance'] ?? $coachProject->service_distance,
  151. 'traffic_fee_type' => $data['traffic_fee_type'] ?? $coachProject->traffic_fee_type,
  152. 'traffic_fee' => $data['traffic_fee'] ?? $coachProject->traffic_fee,
  153. ]);
  154. // 记录日志
  155. Log::info('技师项目设置更新成功', [
  156. 'user_id' => $userId,
  157. 'coach_id' => $user->coach->id,
  158. 'project_id' => $data['project_id'],
  159. 'settings' => $data,
  160. ]);
  161. return [
  162. 'message' => '项目设置更新成功',
  163. 'project_id' => $coachProject->project_id,
  164. 'settings' => [
  165. 'discount_amount' => $coachProject->discount_amount,
  166. 'service_gender' => $coachProject->service_gender,
  167. 'service_distance' => $coachProject->service_distance,
  168. 'traffic_fee_type' => $coachProject->traffic_fee_type,
  169. 'traffic_fee' => $coachProject->traffic_fee,
  170. ],
  171. ];
  172. } catch (\Exception $e) {
  173. Log::error('技师项目设置更新失败', [
  174. 'user_id' => $userId,
  175. 'data' => $data,
  176. 'error' => $e->getMessage(),
  177. 'file' => $e->getFile(),
  178. 'line' => $e->getLine(),
  179. ]);
  180. throw $e;
  181. }
  182. });
  183. }
  184. }