Laravel 8:字符串座位号转数组及批量更新座位状态
问题描述
在Laravel 8控制器处理座位预订时遇到两个问题:
- AJAX传入的座位号格式为
"B7D7G10",需要转换成"B7, D7, G10"的格式保存到bookings表的seat_number字段 - 目前仅能更新第一个座位的
available状态为0,无法批量更新所有选中座位
前端jQuery代码
$("#purchase").on("click",function() { var data = { seats: $(".seats-selected").text(), seats_id: $(".seats-selected").data('sid'), theatre_id: $("#theatres").data('tid'), movie_id: $(".movie_id").val(), movie: $("#m-title").text(), theatre: $("#theatres").text(), date: $("#date").text(), time: $("#time").val(), total_price: $("#total-p").text(), }; $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } }); $.ajax({ type: "POST", url: "/send-email", data: data, success: function(response) { alert("Your Theatre" + data.theatre + "\n" + data.seats_id + "\n" + data.date + "\n" + data.time + "\n" + data.total_price + "\n" ); } }); });
原Laravel控制器代码
$seats = $request->seats; $theatre_id = $request->theatre_id; $date = $request->date; $time = $request->time; $movie_id = $request->movie_id; $total_price = $request->total_price; $bookings = bookings::where('theatre_id', $theatre_id) ->where('date', $date) ->where('time', $time) ->where('movie_id', $movie_id) ->get(); $reserved_seats = $bookings->pluck('seat_number')->toArray(); $seat = seats::where('seat_number', $request->seats_id) ->where('theatre_id', $theatre_id) ->where('movie_id', $movie_id) ->first(); if ($seat && !in_array($seat->id, $reserved_seats)) { $seat->available = 0; $seat->save(); // add the booking to the bookings table $booking = new bookings; $booking->theatre_id = $theatre_id; $booking->movie_id = $movie_id; $booking->seat_number = explode(',',$seats); $booking->date = $date; $booking->time = $time; $booking->total_price = $total_price; $booking->user_id = auth()->id(); $booking->save();
解决方案
1. 拆分并格式化座位号
利用正则表达式拆分B7D7G10格式的字符串,提取每个独立座位号:
// 匹配大写字母开头+数字的座位号格式 preg_match_all('/[A-Z]\d+/', $request->seats, $matches); $seat_numbers = $matches[0]; // 得到数组:['B7', 'D7', 'G10'] // 转换成目标格式字符串 $formatted_seats = implode(', ', $seat_numbers); // 结果:"B7, D7, G10"
2. 批量更新座位状态
通过whereIn批量筛选并更新座位,同时避免重复预订:
// 提取所有已预订的座位号(处理数据库中逗号分隔的字符串) $reserved_seat_numbers = $bookings->flatMap(function($booking) { return explode(', ', $booking->seat_number); })->toArray(); // 筛选出未被预订的座位 $available_seats = array_diff($seat_numbers, $reserved_seat_numbers); if (!empty($available_seats)) { // 批量更新available字段为0 seats::whereIn('seat_number', $available_seats) ->where('theatre_id', $theatre_id) ->where('movie_id', $movie_id) ->update(['available' => 0]); }
3. 修正预订记录保存逻辑
替换原代码中错误的explode操作,使用格式化后的座位号字符串:
$booking = new bookings; $booking->theatre_id = $theatre_id; $booking->movie_id = $movie_id; $booking->seat_number = $formatted_seats; // 使用格式化后的字符串 $booking->date = $date; $booking->time = $time; $booking->total_price = $total_price; $booking->user_id = auth()->id(); $booking->save();
完整修正后的控制器代码
$seats = $request->seats; $theatre_id = $request->theatre_id; $date = $request->date; $time = $request->time; $movie_id = $request->movie_id; $total_price = $request->total_price; // 获取当前场次的已预订记录 $bookings = bookings::where('theatre_id', $theatre_id) ->where('date', $date) ->where('time', $time) ->where('movie_id', $movie_id) ->get(); // 提取所有已被预订的座位号 $reserved_seat_numbers = $bookings->flatMap(function($booking) { return explode(', ', $booking->seat_number); })->toArray(); // 拆分传入的座位号字符串 preg_match_all('/[A-Z]\d+/', $seats, $matches); $seat_numbers = $matches[0]; // 筛选可预订的座位 $available_seats = array_diff($seat_numbers, $reserved_seat_numbers); if (!empty($available_seats)) { // 批量更新座位状态 seats::whereIn('seat_number', $available_seats) ->where('theatre_id', $theatre_id) ->where('movie_id', $movie_id) ->update(['available' => 0]); // 格式化座位号为目标格式 $formatted_seats = implode(', ', $seat_numbers); // 保存新的预订记录 $booking = new bookings; $booking->theatre_id = $theatre_id; $booking->movie_id = $movie_id; $booking->seat_number = $formatted_seats; $booking->date = $date; $booking->time = $time; $booking->total_price = $total_price; $booking->user_id = auth()->id(); $booking->save(); }
内容的提问来源于stack exchange,提问作者BlockchainEnthusiast41
相关产品推荐
相关产品推荐

