ProjectService.php 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  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 App\Models\SettingGroup;
  8. use Illuminate\Support\Facades\DB;
  9. use Illuminate\Support\Facades\Log;
  10. class ProjectService
  11. {
  12. /**
  13. * 获取所有可以开通的项目列表
  14. *
  15. * @param int $userId 技师用户ID
  16. */
  17. public function getAvailableProjects(int $userId): array
  18. {
  19. try {
  20. // 加载用户和技师信息
  21. $user = MemberUser::with(['coach', 'coach.projects'])->findOrFail($userId);
  22. abort_if(! $user->coach, 404, '技师信息不存在');
  23. // 获取所有可开通的项目
  24. $projects = Project::where('state', ProjectStatus::OPEN->value)
  25. ->select([
  26. 'id',
  27. 'title',
  28. 'subtitle',
  29. 'cover',
  30. 'price',
  31. 'original_price',
  32. 'sales',
  33. 'duration',
  34. 'project_desc',
  35. 'service_desc',
  36. 'type',
  37. ])
  38. ->get();
  39. // 记录日志
  40. Log::info('获取可开通项目列表成功', [
  41. 'user_id' => $userId,
  42. 'coach_id' => $user->coach->id,
  43. 'project_count' => $projects->count(),
  44. ]);
  45. return [
  46. 'items' => $projects,
  47. 'total' => $projects->count(),
  48. ];
  49. } catch (\Exception $e) {
  50. Log::error('获取可开通项目列表失败', [
  51. 'user_id' => $userId,
  52. 'error' => $e->getMessage(),
  53. 'file' => $e->getFile(),
  54. 'line' => $e->getLine(),
  55. ]);
  56. throw $e;
  57. }
  58. }
  59. /**
  60. * 技师开通项目
  61. *
  62. * @param int $userId 技师用户ID
  63. * @param array $data 开通项目数据
  64. */
  65. public function openProject(int $userId, array $data): array
  66. {
  67. return DB::transaction(function () use ($userId, $data) {
  68. try {
  69. // 加载用户和技师信息
  70. $user = MemberUser::with(['coach', 'coach.projects'])->findOrFail($userId);
  71. abort_if(! $user->coach, 404, '技师信息不存在');
  72. // 验证项目是否存在且状态正常
  73. $project = Project::where('id', $data['project_id'])
  74. ->where('state', ProjectStatus::OPEN->value)
  75. ->first();
  76. abort_if(! $project, 404, '项目不存在或已下架');
  77. // 检查是否已开通该项目
  78. $existingProject = $user->coach->projects()
  79. ->where('project_id', $data['project_id'])
  80. ->first();
  81. abort_if($existingProject, 422, '已开通该项目');
  82. // 检查技师状态
  83. abort_if($user->coach->state !== TechnicianStatus::ACTIVE->value,
  84. 422, '技师状态异常,无法开通项目');
  85. // 创建技师项目关联
  86. $coachProject = $user->coach->projects()->create([
  87. 'project_id' => $data['project_id'],
  88. 'state' => ProjectStatus::OPEN->value,
  89. 'discount_amount' => 0.00,
  90. 'service_gender' => 0,
  91. 'service_distance' => 0,
  92. 'traffic_fee_type' => 2,
  93. 'traffic_fee' => 0,
  94. 'created_at' => now(),
  95. 'updated_at' => now(),
  96. ]);
  97. // 记录日志
  98. Log::info('技师开通项目成功', [
  99. 'user_id' => $userId,
  100. 'coach_id' => $user->coach->id,
  101. 'project_id' => $data['project_id'],
  102. 'project_name' => $project->name,
  103. ]);
  104. return [
  105. 'message' => '项目开通成功',
  106. 'project_id' => $project->id,
  107. 'project_name' => $project->name,
  108. ];
  109. } catch (\Exception $e) {
  110. Log::error('技师开通项目失败', [
  111. 'user_id' => $userId,
  112. 'data' => $data,
  113. 'error' => $e->getMessage(),
  114. 'file' => $e->getFile(),
  115. 'line' => $e->getLine(),
  116. ]);
  117. throw $e;
  118. }
  119. });
  120. }
  121. /**
  122. * 设置项目
  123. *
  124. * @param int $userId 技师用户ID
  125. * @param array $data 项目设置数据
  126. * @return array
  127. *
  128. * @throws \Exception
  129. */
  130. public function setProject(int $userId, array $data)
  131. {
  132. return DB::transaction(function () use ($userId, $data) {
  133. try {
  134. // 加载用户和技师信息
  135. $user = MemberUser::with(['coach', 'coach.projects'])->findOrFail($userId);
  136. abort_if(! $user->coach, 404, '技师信息不存在');
  137. // 检查项目是否存在
  138. $coachProject = $user->coach->projects()
  139. ->where('project_id', $data['project_id'])
  140. ->first();
  141. abort_if(! $coachProject, 404, '未开通该项目');
  142. // 获取全局项目设置分组
  143. $projectSettingGroup = SettingGroup::where('code', 'project')->first();
  144. abort_if(! $projectSettingGroup, 404, '项目设置分组不存在');
  145. // 获取项目设置中代金卷、交通费、顾客性别设置
  146. $projectSettingItems = $projectSettingGroup->items()->where('code', 'voucher')->orWhere('code', 'traffic_fee')->orWhere('code', 'gender')->get();
  147. // 检查代金卷金额是否存在,并且是否大于0
  148. if (isset($data['voucher']) && $data['voucher'] > 0) {
  149. $voucherSettingItem = $projectSettingItems->where('code', 'voucher')->first();
  150. abort_if(! $voucherSettingItem, 404, '代金卷设置不存在');
  151. // 从项目设置中验证代金卷金额的合理范围
  152. abort_if($data['voucher'] > $voucherSettingItem->max_value, 422, '代金卷金额不能超过'.$voucherSettingItem->max_value.'元');
  153. // 更新技师折扣金额配置
  154. $user->coach->settingValues()->updateOrCreate(
  155. ['item_id' => $projectSettingItems->where('code', 'voucher')->first()->id],
  156. ['value' => $data['voucher']],
  157. ['object_type' => $coachProject::class],
  158. ['object_id' => $coachProject->id],
  159. );
  160. }
  161. // 检查路费设置是否存在,并且是否大于0
  162. if (isset($data['traffic_fee']) && $data['traffic_fee'] >= 0) {
  163. $trafficFeeSettingItem = $projectSettingItems->where('code', 'traffic_fee')->first();
  164. abort_if(! $trafficFeeSettingItem, 404, '路费设置不存在');
  165. // 从项目设置中验证交通费类型的合理范围
  166. abort_if($data['traffic_fee'] > $trafficFeeSettingItem->max_value, 422, '交通费类型不能超过'.$trafficFeeSettingItem->max_value.'元');
  167. // 更新技师路费配置
  168. $user->coach->settingValues()->updateOrCreate(
  169. ['item_id' => $projectSettingItems->where('code', 'traffic_fee')->first()->id],
  170. ['value' => $data['traffic_fee']],
  171. ['object_type' => $coachProject::class],
  172. ['object_id' => $coachProject->id],
  173. );
  174. }
  175. // 检查顾客性别设置是否存在,并且是否大于0
  176. if (isset($data['gender']) && $data['gender'] >= 0) {
  177. $customerGenderSettingItem = $projectSettingItems->where('code', 'gender')->first();
  178. abort_if(! $customerGenderSettingItem, 404, '顾客性别设置不存在');
  179. // 从项目设置中验证顾客性别设置的合理范围
  180. abort_if($data['gender'] > $customerGenderSettingItem->max_value, 422, '顾客性别设置不能超过'.$customerGenderSettingItem->max_value.'元');
  181. // 更新技师顾客性别设置
  182. $user->coach->settingValues()->updateOrCreate(
  183. ['item_id' => $projectSettingItems->where('code', 'gender')->first()->id],
  184. ['value' => $data['gender']],
  185. ['object_type' => $coachProject::class],
  186. ['object_id' => $coachProject->id],
  187. );
  188. }
  189. // 记录日志
  190. Log::info('技师项目设置更新成功', [
  191. 'user_id' => $userId,
  192. 'coach_id' => $user->coach->id,
  193. 'project_id' => $data['project_id'],
  194. 'settings' => $data,
  195. ]);
  196. return [
  197. 'message' => '项目设置更新成功',
  198. 'coach_id' => $user->coach->id,
  199. 'settings' => $data,
  200. ];
  201. } catch (\Exception $e) {
  202. Log::error('技师项目设置更新失败', [
  203. 'user_id' => $userId,
  204. 'data' => $data,
  205. 'error' => $e->getMessage(),
  206. 'file' => $e->getFile(),
  207. 'line' => $e->getLine(),
  208. ]);
  209. throw $e;
  210. }
  211. });
  212. }
  213. }