AccountController.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. <?php
  2. namespace App\Http\Controllers\Coach;
  3. use Illuminate\Http\Request;
  4. use App\Traits\ResponseTrait;
  5. use App\Http\Controllers\Controller;
  6. use Illuminate\Support\Facades\Auth;
  7. use App\Enums\TechnicianLocationType;
  8. use App\Services\Coach\AccountService;
  9. use App\Http\Requests\Coach\SubmitBaseInfoRequest;
  10. use App\Http\Requests\Coach\SubmitRealNameRequest;
  11. use App\Http\Requests\Coach\SubmitQualificationRequest;
  12. /**
  13. * @group 技师端
  14. *
  15. * 技师账户相关的API接口
  16. */
  17. class AccountController extends Controller
  18. {
  19. use ResponseTrait;
  20. protected AccountService $service;
  21. public function __construct(AccountService $service)
  22. {
  23. $this->service = $service;
  24. }
  25. /**
  26. * [账户]提交基本信息
  27. *
  28. * @description 提交技师的基本个人信息
  29. *
  30. * @authenticated
  31. *
  32. * @bodyParam nickname string nullable 昵称(2-20个字符) Example: 张三
  33. * @bodyParam avatar string nullable 头像图片 Example: base64或其他格式的图片数据
  34. * @bodyParam gender string required 性别(1:男 2:女) Example: 1
  35. * @bodyParam mobile string required 手机号 Example: 13800138000
  36. * @bodyParam birthday date nullable 出生日期(年龄需满18岁) Example: 1990-01-01
  37. * @bodyParam work_years integer nullable 工作年限(0-99) Example: 5
  38. * @bodyParam intention_city string nullable 意向城市 Example: 北京
  39. * @bodyParam introduction string nullable 个人简介(10-255个字符) Example: 专业按摩师,从业5年
  40. *
  41. * @response {
  42. * "message": "基本信息提交成功"
  43. * }
  44. */
  45. public function submitBaseInfo(SubmitBaseInfoRequest $request)
  46. {
  47. $data = $request->validated();
  48. return $this->success($this->service->submitBaseInfo(Auth::user(), $data));
  49. }
  50. /**
  51. * [账户]提交资质信息
  52. *
  53. * @description 提交技师的资质认证信息,包括资质照片、营业执照和健康证
  54. *
  55. * @authenticated
  56. *
  57. * @bodyParam qual_type string required 资质类型(按摩师/理疗师等) Example: 高级按摩师
  58. * @bodyParam qual_photo string required 资质证书照片 Example: base64或其他格式的图片数据
  59. * @bodyParam business_license string required 营业执照照片 Example: base64或其他格式的图片数据
  60. * @bodyParam health_cert string required 健康证照片 Example: base64或其他格式的图片数据
  61. *
  62. * @response {
  63. * "message": "资质信息提交成功"
  64. * }
  65. */
  66. public function submitQualification(SubmitQualificationRequest $request)
  67. {
  68. $data = $request->validated();
  69. return $this->success($this->service->submitQualification(Auth::user(), $data));
  70. }
  71. /**
  72. * [账户]提交实名认证
  73. *
  74. * @description 提交技师的实名认证信息
  75. *
  76. * @authenticated
  77. *
  78. * @bodyParam real_name string nullable 姓名(2-20个字符) Example: 张三
  79. * @bodyParam id_card string nullable 身份证号(18位) Example: 370602199001011234
  80. * @bodyParam id_card_front_photo string required 身份证正面照片 Example: base64或其他格式的图片数据
  81. * @bodyParam id_card_back_photo string required 身份证反面照片 Example: base64或其他格式的图片数据
  82. * @bodyParam id_card_hand_photo string required 手持身份证照片 Example: base64或其他格式的图片数据
  83. *
  84. * @response {
  85. * "message": "实名认证信息提交成功"
  86. * }
  87. */
  88. public function submitRealName(SubmitRealNameRequest $request)
  89. {
  90. $data = $request->validated();
  91. return $this->success($this->service->submitRealName(Auth::user(), $data));
  92. }
  93. /**
  94. * [账户]获取技师信息
  95. *
  96. * @description 取技师的基本信息、资质信息和实名信息
  97. *
  98. * @authenticated
  99. *
  100. * @response {
  101. * "data": {
  102. * "base_info": {
  103. * "nickname": "张三",
  104. * "avatar": "http://example.com/avatar.jpg",
  105. * "gender": "1",
  106. * "mobile": "138****8000",
  107. * "birthday": "1990-01-01",
  108. * "work_years": 5,
  109. * "intention_city": "北京",
  110. * "introduction": "专业按摩师,从业5年",
  111. * "state": 1,
  112. * "audit_remark": "审核通过"
  113. * },
  114. * "qualification": {
  115. * "qual_type": "高级按摩师",
  116. * "qual_no": "XZ2024001",
  117. * "qual_photo": "http://example.com/cert.jpg",
  118. * "valid_start": "2024-01-01",
  119. * "valid_end": "2029-01-01",
  120. * "state": 1,
  121. * "audit_remark": "审核通过"
  122. * },
  123. * "real_name": {
  124. * "real_name": "张三",
  125. * "id_card": "370602****1234",
  126. * "id_card_front_photo": "http://example.com/front.jpg",
  127. * "id_card_back_photo": "http://example.com/back.jpg",
  128. * "id_card_hand_photo": "http://example.com/hold.jpg",
  129. * "state": 1,
  130. * "audit_remark": "审核通过"
  131. * }
  132. * }
  133. * }
  134. */
  135. public function info()
  136. {
  137. return $this->success($this->service->getCoachInfo(Auth::user()));
  138. }
  139. /**
  140. * [账户]设置技师位置信息
  141. *
  142. * @description 设置技师的当前位置或常用位置
  143. *
  144. * @authenticated
  145. *
  146. * @bodyParam latitude float required 纬度 Example: 39.9042
  147. * @bodyParam longitude float required 经度 Example: 116.4074
  148. * @bodyParam type int 位置类型(1:当前位置 2:常用位置) Example: 2
  149. *
  150. * @response {
  151. * "message": "位置信息设置成功"
  152. * }
  153. */
  154. public function setLocation(Request $request)
  155. {
  156. $validated = $request->validate([
  157. 'latitude' => 'required|numeric|between:-90,90',
  158. 'longitude' => 'required|numeric|between:-180,180',
  159. 'type' => 'sometimes|integer|in:1,2',
  160. ]);
  161. $result = $this->service->setLocation(
  162. Auth::user()->coach->id,
  163. $validated['latitude'],
  164. $validated['longitude'],
  165. $validated['type'] ?? TechnicianLocationType::COMMON->value
  166. );
  167. return $this->success(['message' => '位置信息设置成功']);
  168. }
  169. /**
  170. * [账户]获取技师位置信息
  171. *
  172. * @description 取技师的当前位置和常用位置信息
  173. *
  174. * @authenticated
  175. *
  176. * @response {
  177. * "data": {
  178. * "current": {
  179. * "address": "北京市朝阳区建国路93号万达广场"
  180. * },
  181. * "common": {
  182. * "address": "北京市海淀区中关村大街1号"
  183. * }
  184. * }
  185. *idid
  186. */
  187. public function getLocation()
  188. {
  189. $result = $this->service->getLocation(Auth::user()->id);
  190. return $this->success($result);
  191. }
  192. /**
  193. * [账户]设置排班时间
  194. *
  195. * @description 设置技师每天通用的排班时间段
  196. *
  197. * @authenticated
  198. *
  199. * @bodyParam time_ranges array required 时间段数组
  200. * @bodyParam time_ranges[].start_time string required 开始时间(HH:mm格式) Example: "09:00"
  201. * @bodyParam time_ranges[].end_time string required 结束时间(HH:mm格式) Example: "12:00"
  202. *
  203. * @response {
  204. * "status": true,
  205. * "message": "排班设置成功",
  206. * "data": {
  207. * "coach_id": 1,
  208. * "time_ranges": [
  209. * {
  210. * "start_time": "09:00",
  211. * "end_time": "12:00"
  212. * },
  213. * {
  214. * "start_time": "14:00",
  215. * "end_time": "18:00"
  216. * }
  217. * ]
  218. * }
  219. * }
  220. * @response 400 {
  221. * "message": "时间段格式错误"
  222. * }
  223. * @response 400 {
  224. * "message": "时间格式错误,应为HH:mm格式"
  225. * }
  226. * @response 400 {
  227. * "message": "结束时间必须大于开始时间"
  228. * }
  229. * @response 400 {
  230. * "message": "时间段之间不能重叠"
  231. * }
  232. */
  233. public function setSchedule(Request $request)
  234. {
  235. $validated = $request->validate([
  236. 'time_ranges' => 'required|array|min:1',
  237. 'time_ranges.*.start_time' => [
  238. 'required',
  239. 'string',
  240. 'regex:/^([01][0-9]|2[0-3]):[0-5][0-9]$/',
  241. ],
  242. 'time_ranges.*.end_time' => [
  243. 'required',
  244. 'string',
  245. 'regex:/^([01][0-9]|2[0-3]):[0-5][0-9]$/',
  246. ],
  247. ], [
  248. 'time_ranges.required' => '必须设置时间段',
  249. 'time_ranges.array' => '时间段必须是数组格式',
  250. 'time_ranges.min' => '至少设置一个时间段',
  251. 'time_ranges.*.start_time.required' => '开始时间不能为空',
  252. 'time_ranges.*.start_time.regex' => '开始时间格式错误,应为HH:mm格式',
  253. 'time_ranges.*.end_time.required' => '结束时间不能为空',
  254. 'time_ranges.*.end_time.regex' => '结束时间格式错误,应为HH:mm格式',
  255. ]);
  256. return $this->success(
  257. $this->service->setSchedule(Auth::user()->id, $validated['time_ranges'])
  258. );
  259. }
  260. /**
  261. * [账户]更改技师工作状态
  262. *
  263. * @description 更改技师的工作状态(休息中/工作中),工作状态会自动判断为空闲或忙碌
  264. *
  265. * @authenticated
  266. *
  267. * @bodyParam status int required 状态(1:休息中 2:工作中) Example: 2
  268. *
  269. * @response {
  270. * "status": true,
  271. * "message": "状态更新成功",
  272. * "data": {
  273. * "work_status": 2,
  274. * "work_status_text": "空闲中",
  275. * "updated_at": "2024-03-20 10:00:00"
  276. * }
  277. * }
  278. * @response 400 {
  279. * "message": "无效的状态值"
  280. * }
  281. * @response 422 {
  282. * "message": "当前状态不能更改为休息状态"
  283. * }
  284. */
  285. public function updateWorkStatus(Request $request)
  286. {
  287. $validated = $request->validate([
  288. 'status' => 'required|integer|in:1,2',
  289. ], [
  290. 'status.required' => '状态不能为空',
  291. 'status.integer' => '状态必须是整数',
  292. 'status.in' => '无效的状态值',
  293. ]);
  294. return $this->success(
  295. $this->service->updateWorkStatus(Auth::user()->id, $validated['status'])
  296. );
  297. }
  298. /**
  299. * [账户]获取技师工作状态
  300. *
  301. * @description 获取技师当前工作状态
  302. *
  303. * @authenticated
  304. *
  305. * @response {
  306. * "data": {
  307. * "work_status": 2,
  308. * "work_status_text": "空闲中",
  309. * "updated_at": "2024-03-22 10:00:00"
  310. * }
  311. * }
  312. * @response 404 {
  313. * "message": "技师不存在"
  314. * }
  315. */
  316. public function getWorkStatus()
  317. {
  318. return $this->success(
  319. $this->service->getWorkStatus(Auth::user()->coach->id)
  320. );
  321. }
  322. /**
  323. * [账户]获取技师排班信息
  324. *
  325. * @return \Illuminate\Http\JsonResponse
  326. *
  327. * @description 技师获取自己的排班时间段信息
  328. *
  329. * @response {
  330. * "status": true,
  331. * "message": "获取成功",
  332. * "data": {
  333. * "time_ranges": [
  334. * {
  335. * "start_time": "09:00",
  336. * "end_time": "12:00"
  337. * },
  338. * {
  339. * "start_time": "14:00",
  340. * "end_time": "18:00"
  341. * }
  342. * ],
  343. * "updated_at": "2024-03-20 10:00:00"
  344. * }
  345. * }
  346. */
  347. public function getSchedule()
  348. {
  349. $schedule = $this->service->getSchedule(Auth::id());
  350. return $this->success($schedule);
  351. }
  352. }