OrderController.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. <?php
  2. namespace App\Http\Controllers\Client;
  3. use App\Enums\OrderType;
  4. use Illuminate\Http\Request;
  5. use App\Http\Controllers\Controller;
  6. use Illuminate\Support\Facades\Auth;
  7. use App\Services\Client\OrderService;
  8. /**
  9. * @group 用户端
  10. *
  11. * 订单相关的API接口
  12. */
  13. class OrderController extends Controller
  14. {
  15. protected OrderService $service;
  16. public function __construct(OrderService $service)
  17. {
  18. $this->service = $service;
  19. }
  20. /**
  21. * [订单]订单初始化
  22. *
  23. * 初始化订单
  24. *
  25. * @authenticated
  26. *
  27. * @bodyParam coach_id int required 技师ID. Example: 6
  28. * @bodyParam area_code string required 区划代码. Example: 370602
  29. * @bodyParam project_id int required 项目ID. Example: 1
  30. * @bodyParam latitude int 纬度. Example: 37.4219983
  31. * @bodyParam longitude int 经度. Example: 122.1347344
  32. *
  33. * @response {
  34. * "status": "success",
  35. * "data": {}
  36. * }
  37. */
  38. public function initialize(Request $request)
  39. {
  40. $data = $request->only(['coach_id', 'area_code', 'project_id', 'latitude', 'longitude']);
  41. return $this->success($this->service->initialize(Auth::user()->id, $data));
  42. }
  43. /**
  44. * [订单]创建订单
  45. *
  46. * 创建订单
  47. *
  48. * @authenticated
  49. *
  50. * @bodyParam project_id int required 项目ID. Example: 1
  51. * @bodyParam address_id int required 地址ID. Example: 1
  52. * @bodyParam coach_id int required 技师ID. Example: 6
  53. * @bodyParam use_balance boolean 使用余额. Example: false
  54. * @bodyParam service_time datetime required 服务时间. Example: 2024-01-01 10:00:00
  55. * @bodyParam order_id int 订单ID. Example: null
  56. * @bodyParam payment_type number required 支付类型. Example: 1 (1:余额,2:微信,3:支付宝)
  57. * @bodyParam order_type int required 订单类型. Example: 1
  58. * @bodyParam distance float 距离. Example: 10
  59. * @bodyParam remark string 订单备注. Example: 请准时到达
  60. *
  61. * @response {
  62. * "status": "success",
  63. * "data": {}
  64. * }
  65. */
  66. public function create(Request $request)
  67. {
  68. $data = $request->only([
  69. 'project_id',
  70. 'address_id',
  71. 'coach_id',
  72. 'use_balance',
  73. 'order_id',
  74. 'service_time',
  75. 'payment_type',
  76. 'order_type',
  77. 'distance',
  78. 'remark'
  79. ]);
  80. return $this->success($this->service->createOrder(Auth::user()->id, $data));
  81. }
  82. /**
  83. * [订单]结束订单
  84. *
  85. * 结束订单
  86. *
  87. * @authenticated
  88. *
  89. * @bodyParam order_id int required 订单ID. Example: 1
  90. *
  91. * @response {
  92. * "status": "success",
  93. * "data": {}
  94. * }
  95. */
  96. public function finish(Request $request)
  97. {
  98. $userId = Auth::user()->id;
  99. $orderId = $request->input('order_id');
  100. return $this->success($this->service->finishOrder($userId, $orderId));
  101. }
  102. /**
  103. * [订单]确认技师离开
  104. *
  105. * 确认技师离开
  106. *
  107. * @authenticated
  108. *
  109. * @bodyParam order_id int required 订单ID. Example: 123
  110. *
  111. * @response {
  112. * "status": "success",
  113. * "data": {}
  114. * }
  115. */
  116. public function confirmLeave(Request $request)
  117. {
  118. $userId = Auth::user()->id;
  119. $orderId = $request->input('order_id');
  120. return $this->success($this->service->confirmLeave($userId, $orderId));
  121. }
  122. /**
  123. * [订单]取消订单
  124. *
  125. * 取消订单
  126. *
  127. * @authenticated
  128. *
  129. * @bodyParam order_id int required 订单ID. Example: 123
  130. * @bodyParam reason string required 取消原因. Example: 123
  131. *
  132. * @response {
  133. * "status": "success",
  134. * "data": {}
  135. * }
  136. */
  137. public function cancel(Request $request)
  138. {
  139. $userId = Auth::user()->id;
  140. $orderId = $request->input('order_id');
  141. $reason = $request->input('reason');
  142. return $this->success($this->service->cancelOrder($userId, $orderId, $reason));
  143. }
  144. /**
  145. * [订单]获取订单列表
  146. *
  147. * 获取订单列表
  148. *
  149. * @authenticated
  150. *
  151. * @queryParam tab int 订单标签页 Example: 0
  152. * 标签页说明:
  153. * 0: 全部订单
  154. * 1: 待付款 (状态: 1,16)
  155. * 2: 进行中 (状态: 2,3,4,5,6,7,8,9,10)
  156. * 3: 已完成 (状态: 12)
  157. * 4: 待评价 (状态: 11)
  158. * 5: 已取消 (状态: 13,14,15,17,18)
  159. *
  160. * @response {
  161. * "status": "success",
  162. * "data": []
  163. * }
  164. */
  165. public function list(Request $request)
  166. {
  167. $tab = $request->input('tab', 0);
  168. return $this->success($this->service->getOrderList(Auth::user()->id, $tab));
  169. }
  170. /**
  171. * [订单]获取订单详情
  172. *
  173. * 获取订单详情
  174. *
  175. * @authenticated
  176. *
  177. * @urlParam id required 订单ID. Example: 6
  178. *
  179. * @response {
  180. * "status": "success",
  181. * "data": {}
  182. * }
  183. */
  184. public function detail($id)
  185. {
  186. return $this->success($this->service->getOrderDetail(Auth::user()->id, $id));
  187. }
  188. /**
  189. * [订单]订单退款
  190. *
  191. * 订单退款
  192. *
  193. * @authenticated
  194. *
  195. * @urlParam id required 订单ID. Example: 1
  196. *
  197. * @response {
  198. * "status": "success",
  199. * "data": {}
  200. * }
  201. */
  202. public function refund($id)
  203. {
  204. return $this->success($this->service->refundOrder($id));
  205. }
  206. /**
  207. * [订单]获取代理商配置
  208. *
  209. * 获取代理商配置
  210. *
  211. * @authenticated
  212. *
  213. * @bodyParam agent_id int required 代理商ID. Example: 1
  214. *
  215. * @response {
  216. * "min_distance": 0,
  217. * "min_fee": 0,
  218. * "per_km_fee": 0
  219. * }
  220. */
  221. public function getAgentConfig(Request $request)
  222. {
  223. $agentId = $request->input('agent_id');
  224. return $this->success($this->service->getAgentConfig($agentId));
  225. }
  226. /**
  227. * [订单]获取技师配置
  228. *
  229. * 获取技师配置
  230. *
  231. * @authenticated
  232. *
  233. * @bodyParam coach_id int required 技师ID. Example: 1
  234. *
  235. * @response {
  236. * "delivery_fee_type": "round_trip",
  237. * "charge_delivery_fee": true
  238. * }
  239. */
  240. public function getCoachConfig(Request $request)
  241. {
  242. $coachId = $request->input('coach_id');
  243. return $this->success($this->service->getCoachConfig($coachId));
  244. }
  245. /**
  246. * [订单]计算订单金额
  247. *
  248. * 计算订单金额
  249. *
  250. * @authenticated
  251. *
  252. * @bodyParam address_id int required 地址ID. Example: 1
  253. * @bodyParam coach_id int required 技师ID. Example: 1
  254. * @bodyParam project_id int required 项目ID. Example: 1
  255. * @bodyParam agent_id int 代理商ID. Example: 1
  256. * @bodyParam use_balance boolean 使用余额. Example: 0
  257. * @bodyParam distance float 距离. Example: 0
  258. *
  259. * @response {
  260. * "total_amount": 0,
  261. * "balance_amount": 0,
  262. * "pay_amount": 0,
  263. * "coupon_amount": 0,
  264. * "tip_amount": 0,
  265. * "project_amount": 0,
  266. * "delivery_fee": 0
  267. * }
  268. */
  269. public function calculateOrderAmount(Request $request)
  270. {
  271. $userId = Auth::user()->id;
  272. $addressId = $request->input('address_id');
  273. $coachId = $request->input('coach_id');
  274. $projectId = $request->input('project_id');
  275. $agentId = $request->input('agent_id');
  276. $useBalance = $request->input('use_balance', 0);
  277. $distance = $request->input('distance', 0);
  278. return $this->success($this->service->calculateOrderAmount($userId, $addressId, $coachId, $projectId, $agentId, $useBalance, $distance));
  279. }
  280. /**
  281. * [订单]加钟
  282. *
  283. * 加钟
  284. *
  285. * @authenticated
  286. *
  287. * @bodyParam project_id int required 项目ID. Example: 1
  288. * @bodyParam use_balance boolean 使用余额. Example: false
  289. * @bodyParam order_id int 订单ID. Example: 15
  290. * @bodyParam payment_type number 支付类型. Example: 1 (1:余额,2:微信,3:支付宝)
  291. *
  292. * @response {
  293. * "status": "success",
  294. * "data": {}
  295. * }
  296. */
  297. public function addTime(Request $request)
  298. {
  299. $data = $request->only(['project_id', 'use_balance', 'order_id', 'payment_type']);
  300. $data['order_type'] = OrderType::OVERTIME->value;
  301. return $this->success($this->service->createOrder(Auth::user()->id, $data));
  302. }
  303. /**
  304. * [订单]指定技师
  305. *
  306. * @authenticated
  307. *
  308. * @bodyParam coach_id int required 技师ID. Example: 1
  309. * @bodyParam order_id int required 订单ID. Example: 1
  310. *
  311. * @response {
  312. * "status": "success",
  313. * "data": {}
  314. * }
  315. */
  316. public function assignCoach(Request $request)
  317. {
  318. $userId = Auth::user()->id;
  319. $coachId = $request->input('coach_id');
  320. $orderId = $request->input('order_id');
  321. $payment_type = $request->input('payment_type');
  322. $distance = $request->input('distance');
  323. return $this->success($this->service->assignCoach($userId, $orderId, $coachId, $payment_type, $distance));
  324. }
  325. /**
  326. * [订单]获取抢单列表
  327. *
  328. * 获取抢单列表
  329. *
  330. * @queryParam order_id int required 订单ID. Example: 7
  331. *
  332. * @response {
  333. * "data": [
  334. * {
  335. * "id": 1,
  336. * "coach_id": 1,
  337. * "nickname": "技师昵称",
  338. * "avatar": "头像地址",
  339. * "created_at": "2024-03-21 10:00:00"
  340. * }
  341. * ]
  342. * }
  343. */
  344. public function getOrderGrabList(Request $request)
  345. {
  346. $orderId = $request->input('order_id');
  347. return $this->success($this->service->getOrderGrabList($orderId));
  348. }
  349. /**
  350. * [订单]生成核销码
  351. *
  352. * 生成订单核销码,用于技师扫码开始服务
  353. *
  354. * @authenticated
  355. *
  356. * @urlParam id required 订单ID. Example: 1
  357. *
  358. * @response {
  359. * "qr_code": "order_123_1679876543_abcdef123456",
  360. * "expired_at": "2024-03-27 10:30:00"
  361. * }
  362. */
  363. public function generateCode($id)
  364. {
  365. return $this->success($this->service->generateVerificationCode(Auth::user()->id, $id));
  366. }
  367. /**
  368. * [订单]订单评价
  369. *
  370. * 用户评价订单
  371. *
  372. * @authenticated
  373. *
  374. * @bodyParam order_id int required 订单ID
  375. * @bodyParam service_score decimal 服务评分(1-5分,支持一位小数) Example: 4.5
  376. * @bodyParam appearance_score decimal 形象评分(1-5分,支持一位小数) Example: 4.5
  377. * @bodyParam attitude_score decimal 态度评分(1-5分,支持一位小数) Example: 4.5
  378. * @bodyParam professional_score decimal 专业评分(1-5分,支持一位小数) Example: 4.5
  379. * @bodyParam tags array 评价标签ID数组 Example: [1,2,3]
  380. * @bodyParam content string 评价内容 Example: 服务很专业,技师态度很好
  381. * @bodyParam images array 评价图片数组 Example: ["path/to/image1.jpg", "path/to/image2.jpg"]
  382. *
  383. * @response 200 {
  384. * "code": 200,
  385. * "message": "评价成功",
  386. * "data": null
  387. * }
  388. * @response 400 {
  389. * "code": 400,
  390. * "message": "订单不存在",
  391. * "data": null
  392. * }
  393. * @response 422 {
  394. * "code": 422,
  395. * "message": "评分必须在1-5分之间",
  396. * "data": null
  397. * }
  398. *
  399. * @throws \Exception
  400. */
  401. public function rate(Request $request)
  402. {
  403. $validated = $request->validate([
  404. 'order_id' => 'required|integer',
  405. 'service_score' => 'nullable|numeric|min:1|max:5',
  406. 'appearance_score' => 'nullable|numeric|min:1|max:5',
  407. 'attitude_score' => 'nullable|numeric|min:1|max:5',
  408. 'professional_score' => 'nullable|numeric|min:1|max:5',
  409. 'tags' => 'nullable|array',
  410. 'tags.*' => 'integer|exists:order_comment_tags,id',
  411. 'content' => 'nullable|string|max:1000',
  412. 'images' => 'nullable|array',
  413. 'images.*' => 'string'
  414. ]);
  415. $this->service->rateOrder(Auth::user()->id, $validated);
  416. return $this->success(null, '评价成功');
  417. }
  418. /**
  419. * [订单]获取评价标签列表
  420. *
  421. * 获取所有可用的评价标签列表,用于用户评价时选择
  422. *
  423. * @authenticated
  424. *
  425. * @response {
  426. * "data": [
  427. * {
  428. * "id": 1,
  429. * "tag_name": "打扫干净"
  430. * },
  431. * {
  432. * "id": 2,
  433. * "tag_name": "工装规范"
  434. * },
  435. * {
  436. * "id": 3,
  437. * "tag_name": "态度端正"
  438. * }
  439. * ]
  440. * }
  441. */
  442. public function commentTags()
  443. {
  444. return $this->success($this->service->getCommentTags());
  445. }
  446. /**
  447. * [订单]删除订单
  448. *
  449. * 用户删除订单,删除后订单将不在列表中显示
  450. *
  451. * @authenticated
  452. *
  453. * @urlParam id required 订单ID. Example: 1
  454. *
  455. * @response {
  456. * "status": "success",
  457. * "message": "订单删除成功",
  458. * "data": null
  459. * }
  460. *
  461. * @response 404 {
  462. * "message": "订单不存在"
  463. * }
  464. *
  465. * @response 422 {
  466. * "message": "当前订单状态不允许删除"
  467. * }
  468. */
  469. public function delete($id)
  470. {
  471. return $this->success($this->service->deleteOrder(Auth::user()->id, $id));
  472. }
  473. }