Course.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. <?php namespace App\Http\Controllers\Api;
  2. use App\Http\Controllers\Api\Api;
  3. use App\Models\Orders as Model;
  4. use App\Models\Product;
  5. use App\Models\Product\Skus as ProductSkus;
  6. use App\Http\Requests\Api\Course as Request;
  7. use App\Models\Business;
  8. use App\Models\CustomAddr;
  9. use App\Models\OrdersProduct;
  10. use App\Models\CourseSchedule;
  11. use App\Models\CourseReservation;
  12. use Illuminate\Support\Facades\DB;
  13. /**
  14. * 课程接口
  15. *
  16. * @author jun
  17. *
  18. * */
  19. class Course extends Api{
  20. /**
  21. * 预约课程 /api/course/reservation
  22. *
  23. * @param string $car_info 需要下单的产品ID
  24. * @param string $buyer_number 需要下单的数量
  25. *
  26. * */
  27. public function reservation(Request $request,Model $Model,OrdersProduct $OrdersProduct,CourseSchedule $CourseSchedule,CourseReservation $CourseReservation){
  28. // 接口验签
  29. // $this->verify_sign();
  30. // 验证参数
  31. $request->scene('reservation')->validate();
  32. // 检查登录
  33. $uid = $this->checkLogin();
  34. // 接收参数
  35. $ordersProductId = request('orders_product_id','');
  36. $scheduleId = request('schedule_id','');
  37. //订单课程预约信息
  38. $ordersProductInfo = $OrdersProduct->query()->where('id','=',$ordersProductId)->first();
  39. if (!$ordersProductInfo)
  40. return json_send(['code'=>'error','msg'=>'订单课程不存在','data'=>['error'=>'订单课程不存在']]);
  41. if ($ordersProductInfo['course_number'] <= $ordersProductInfo['reservation_number'])
  42. return json_send(['code'=>'error','msg'=>'您购买的课程节数已用完','data'=>['error'=>'您购买的课程节数已用完']]);
  43. //上课表信息
  44. $courseScheduleInfo = $CourseSchedule->query()->where('id','=',$scheduleId)->first();
  45. if (!$courseScheduleInfo)
  46. return json_send(['code'=>'error','msg'=>'预约课程不存在','data'=>['error'=>'预约课程不存在']]);
  47. if ($courseScheduleInfo['course_number'] <= $ordersProductInfo['reservation_number'])
  48. return json_send(['code'=>'error','msg'=>'此时段课程已预满','data'=>['error'=>'此时段课程已预满']]);
  49. $data = [
  50. 'orders_product_id' => $ordersProductId,
  51. 'schedule_id' => $scheduleId,
  52. 'uid' => $uid,
  53. 'order_id' => $ordersProductInfo['order_id'],
  54. 'product_id' => $ordersProductInfo['product_id'],
  55. 'course_id' => $courseScheduleInfo['course_id'],
  56. 'teacher_id' => $courseScheduleInfo['teacher_id'],
  57. 'start_time' => $courseScheduleInfo['start_time'],
  58. 'end_time' => $courseScheduleInfo['start_time'],
  59. ];
  60. DB::beginTransaction();
  61. // 写入数据
  62. try {
  63. // 更新订单预约数据
  64. $update = $OrdersProduct->query()->where('id','=',$ordersProductId)->update(['reservation_number'=>$ordersProductInfo['reservation_number']+1]);
  65. if (!$update)
  66. // 返回结果
  67. return json_send(['code'=>'success','msg'=>'预约失败','data'=>['id'=>null]]);
  68. // 更新课程表预约数据
  69. $updateSchedule = $CourseSchedule->query()->where('id','=',$scheduleId)->update(['reservation_number'=>$ordersProductInfo['reservation_number']+1]);
  70. if (!$updateSchedule){
  71. DB::rollBack();
  72. // 错误提示
  73. return json_send(['code'=>'error','msg'=>'预约失败','data'=>['error'=>'更新课程表预约数据失败']]);
  74. }
  75. //添加到预约课程表
  76. $reservationId = $CourseReservation->add($data);
  77. if( !$reservationId ) {
  78. // 回退数据
  79. DB::rollBack();
  80. // 错误提示
  81. return json_send(['code'=>'error','msg'=>'预约失败','data'=>['error'=>'添加预约失败']]);
  82. }
  83. // 提交数据
  84. DB::commit();
  85. // 返回结果
  86. return json_send(['code'=>'success','msg'=>'预约成功','data'=>['id'=>$reservationId]]);
  87. // 返回结果
  88. } catch (\Throwable $th) {
  89. // 回退数据
  90. DB::rollBack();
  91. // 判断结果,如果库存扣减失败的话
  92. if( stripos($th->getMessage(),'UNSIGNED') ) return json_send(['code'=>'error','msg'=>'预约失败','data'=>['error'=>'订单课程修改错误']]);
  93. // 下单失败提示
  94. return json_send(['code'=>'error','msg'=>'预约失败','data'=>['error'=>$th->getMessage().$th->getLine()]]);
  95. }
  96. }
  97. /**
  98. * 获取上课列表 /api/course/get_list
  99. *
  100. * @param int $page 页码,默认1
  101. * @param int $limit 每页条数,默认10条
  102. *
  103. * */
  104. public function get_list(Request $request,Model $Model,OrdersProduct $OrdersProduct){
  105. // 接口验签
  106. // $this->verify_sign();
  107. // 验证参数
  108. $request->scene('get_list')->validate();
  109. // 检查登录
  110. $uid = $this->checkLogin();
  111. // 接收参数
  112. $status = request('status',1);
  113. $limit = request('limit',10);
  114. // 显示
  115. $map = [
  116. ['orders_product.custom_uid','=',$uid],
  117. ];
  118. // 查询状态
  119. if( $status ) $map[] = ['orders_product.status','=',$status];
  120. $select = [
  121. 'orders_product.id as orders_product_id',
  122. 'orders_product.pay_total','orders_product.status',
  123. 'orders_product.price_total',
  124. 'orders_product.coupon_total',
  125. 'orders_product.pay_total',
  126. 'orders_product.course_id',
  127. 'orders_product.order_id',
  128. 'orders_product.course_number',
  129. 'orders_product.reservation_number',
  130. 'orders_product.product_id',
  131. 'course.name as course_name',
  132. 'course.address',
  133. 'course.desc',
  134. 'course.image',
  135. ];
  136. // 查询订单课程
  137. $Paginator = $OrdersProduct->query()
  138. ->join('course','orders_product.course_id','=','course.id')
  139. ->where($map)
  140. ->whereColumn('orders_product.reservation_number','<','orders_product.course_number')
  141. ->orderByDesc('orders_product.id')
  142. ->paginate($limit, $select);
  143. foreach ($Paginator->items() as &$orders_product) {
  144. $orders_product['image'] = path_compat($orders_product['image']);
  145. }
  146. // 获取数据
  147. $data['total'] = $Paginator->total();
  148. $data['current_page'] = $Paginator->currentPage();
  149. $data['per_page'] = $Paginator->perPage();
  150. $data['last_page'] = $Paginator->lastPage();
  151. $data['data'] = $Paginator->items();
  152. // 返回结果
  153. return json_send(['code'=>'success','msg'=>'获取成功','data'=>$data]);
  154. }
  155. /**
  156. * 获取排课列表 /api/course/get_schedule_list
  157. *
  158. * */
  159. public function get_schedule_list(Request $request,Model $Model,CourseSchedule $CourseSchedule){
  160. // 接口验签
  161. // $this->verify_sign();
  162. // 验证参数
  163. $request->scene('get_schedule_list')->validate();
  164. // 检查登录
  165. $uid = $this->checkLogin();
  166. // 接收参数
  167. $status = request('status',0);
  168. $limit = request('limit',10);
  169. $courseId = request('course_id',10);
  170. $ordersProductId = request('orders_product_id',10);
  171. // 显示一周的数据
  172. $start = strtotime(date('Y-m-d'));
  173. $end = strtotime(date('Y-m-d', strtotime('+7 day')),);
  174. $map = [
  175. ['course_schedule.course_id','=',$courseId],
  176. ['course_schedule.start_time','>',$start],
  177. ['course_schedule.end_time','<',$end],
  178. ];
  179. // 查询状态
  180. if( $status ) $map[] = ['course_schedule.status','=',$status];
  181. $select = [
  182. 'course_schedule.id',
  183. 'course_schedule.course_id',
  184. 'course_schedule.teacher_id',
  185. 'course_schedule.start_time',
  186. 'course_schedule.end_time',
  187. 'course_schedule.duration',
  188. 'course_schedule.course_number',
  189. 'course_schedule.reservation_number',
  190. 'course_teacher.name as teacher_name',
  191. 'course_teacher.desc as teacher_desc',
  192. 'course.name as course_name',
  193. 'course.image as course_image',
  194. 'course.desc as course_desc',
  195. 'course.address',
  196. ];
  197. // 查询订单课程
  198. $data = $CourseSchedule->query()
  199. ->join('course','course_schedule.course_id','=','course.id')
  200. ->join('course_teacher','course_schedule.teacher_id','=','course_teacher.id')
  201. ->where($map)
  202. ->orderByDesc('course_schedule.start_time')
  203. ->select($select)
  204. ->get();
  205. //用户已预约课程
  206. $courseReservation = CourseReservation::query()->where(['uid'=>$uid,'status'=>1])->select('schedule_id')->get()->toArray();
  207. $reservationIds = array_column($courseReservation,'schedule_id');
  208. $list = [];
  209. foreach ($data as &$dataItem) {
  210. $dataItem['course_image'] = path_compat($dataItem['course_image']);
  211. //按老师分组
  212. $list[$dataItem['teacher_id']]['teacher_id'] = $dataItem['teacher_id'];
  213. $list[$dataItem['teacher_id']]['teacher_name'] = $dataItem['teacher_name'];
  214. //判断排课是否已预约:1预约,0未预约
  215. if (in_array($dataItem['id'],$reservationIds)) {
  216. $dataItem['reservation_status'] = 1;
  217. }else{
  218. $dataItem['reservation_status'] = 0;
  219. }
  220. $list[$dataItem['teacher_id']]['list'][] = $dataItem;
  221. }
  222. $list = array_values($list);
  223. // 返回结果
  224. return json_send(['code'=>'success','msg'=>'获取成功','data'=>$list]);
  225. }
  226. /**
  227. * 预约列表 /api/course/reservation_list
  228. *
  229. * @param int $page 页码,默认1
  230. * @param int $limit 每页条数,默认10条
  231. *
  232. * */
  233. public function reservation_list(Request $request,Model $Model,OrdersProduct $OrdersProduct,CourseSchedule $CourseSchedule,CourseReservation $CourseReservation){
  234. // 接口验签
  235. // $this->verify_sign();
  236. // 验证参数
  237. $request->scene('reservation_list')->validate();
  238. // 检查登录
  239. $uid = $this->checkLogin();
  240. // 接收参数
  241. $status = request('status',0);
  242. $limit = request('limit',10);
  243. $map = [
  244. ['course_reservation.uid','=',$uid],
  245. ];
  246. // 查询状态
  247. if( $status ) $map[] = ['course_reservation.status','=',$status];
  248. $select = [
  249. 'course_reservation.*',
  250. 'course_teacher.name as teacher_name',
  251. 'course_teacher.desc as teacher_desc',
  252. 'course_teacher.pic as teacher_pic',
  253. 'course.name as course_name',
  254. 'course.address as course_address',
  255. ];
  256. $Paginator = $CourseReservation->query()
  257. ->join('course','course_reservation.course_id','=','course.id')
  258. ->join('course_teacher','course_reservation.teacher_id','=','course_teacher.id')
  259. ->where($map)
  260. ->orderByDesc('course_reservation.id')
  261. ->paginate($limit, $select);
  262. $time = time();
  263. foreach ($Paginator->items() as &$reservation) {
  264. $reservation['teacher_pic'] = path_compat($reservation['teacher_pic']);
  265. switch ($reservation['status']){
  266. case 1:
  267. if ($reservation['start_time'] <= $time){
  268. $reservation['status'] = 3;
  269. $reservation['status_name'] = '已完成';
  270. }else{
  271. $reservation['status_name'] = '待上课';
  272. }
  273. break;
  274. case 2:
  275. $reservation['status_name'] = '已取消';
  276. break;
  277. case 3:
  278. $reservation['status_name'] = '已完成';
  279. break;
  280. }
  281. }
  282. // 获取数据
  283. $data['total'] = $Paginator->total();
  284. $data['current_page'] = $Paginator->currentPage();
  285. $data['per_page'] = $Paginator->perPage();
  286. $data['last_page'] = $Paginator->lastPage();
  287. $data['data'] = $Paginator->items();
  288. // 返回结果
  289. return json_send(['code'=>'success','msg'=>'获取成功','data'=>$data]);
  290. }
  291. /**
  292. * 取消预约 /api/course/cancel_reservation
  293. *
  294. * @param int $page 页码,默认1
  295. * @param int $limit 每页条数,默认10条
  296. *
  297. * */
  298. public function cancel_reservation(Request $request,Model $Model,OrdersProduct $OrdersProduct,CourseSchedule $CourseSchedule,CourseReservation $CourseReservation){
  299. // 接口验签
  300. // $this->verify_sign();
  301. // 验证参数
  302. $request->scene('cancel_reservation')->validate();
  303. // 检查登录
  304. $uid = $this->checkLogin();
  305. // 接收参数
  306. $ordersProductId = request('orders_product_id','');
  307. $scheduleId = request('schedule_id','');
  308. $id = request('id','');
  309. //订单课程预约信息
  310. $time = time();
  311. $ordersProductInfo = $OrdersProduct->query()->where('id','=',$ordersProductId)->first();
  312. if (!$ordersProductInfo)
  313. return json_send(['code'=>'error','msg'=>'订单课程不存在','data'=>['error'=>'订单课程不存在']]);
  314. //上课表信息
  315. $courseScheduleInfo = $CourseSchedule->query()->where('id','=',$scheduleId)->first();
  316. if (!$courseScheduleInfo)
  317. return json_send(['code'=>'error','msg'=>'预约课程不存在','data'=>['error'=>'预约课程不存在']]);
  318. if ($courseScheduleInfo['start_time'] <= $time)
  319. return json_send(['code'=>'error','msg'=>'已过上课时间','data'=>['error'=>'已过上课时间']]);
  320. DB::beginTransaction();
  321. // 写入数据
  322. try {
  323. // 更新订单预约数据
  324. $update = $OrdersProduct->query()->where('id','=',$ordersProductId)->update(['reservation_number'=>$ordersProductInfo['reservation_number']-1]);
  325. if (!$update)
  326. // 返回结果
  327. return json_send(['code'=>'success','msg'=>'取消预约失败','data'=>['id'=>null]]);
  328. //添加到预约课程表
  329. // 更新订单预约数据
  330. $updateReservation = $CourseReservation->query()->where('id','=',$id)->update(['status'=>2]);
  331. if (!$updateReservation)
  332. // 返回结果
  333. return json_send(['code'=>'success','msg'=>'取消预约失败','data'=>['id'=>null]]);
  334. if( !$updateReservation ) {
  335. // 回退数据
  336. DB::rollBack();
  337. // 错误提示
  338. return json_send(['code'=>'error','msg'=>'取消预约失败','data'=>['error'=>'取消预约失败']]);
  339. }
  340. // 提交数据
  341. DB::commit();
  342. // 返回结果
  343. return json_send(['code'=>'success','msg'=>'取消预约成功','data'=>['id'=>$updateReservation]]);
  344. // 返回结果
  345. } catch (\Throwable $th) {
  346. // 回退数据
  347. DB::rollBack();
  348. // 判断结果,如果库存扣减失败的话
  349. if( stripos($th->getMessage(),'UNSIGNED') ) return json_send(['code'=>'error','msg'=>'取消预约失败','data'=>['error'=>'订单课程修改错误']]);
  350. // 下单失败提示
  351. return json_send(['code'=>'error','msg'=>'取消预约失败','data'=>['error'=>$th->getMessage().$th->getLine()]]);
  352. }
  353. }
  354. }