Course.php 16 KB

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