model = new Venue(); } /** * 获取场地列表 * @param array $where * @return array */ public function getPage(array $where = []) { $field = 'id,campus_id,venue_name,capacity,availability_status,time_range_type,time_range_start,time_range_end,fixed_time_ranges,created_at,updated_at,deleted_at'; $order = 'updated_at desc'; $search_model = $this->model->withSearch(["campus_id", "venue_name", "capacity", "availability_status", "time_range_type", "created_at", "updated_at"], $where)->with(['campus'])->field($field)->order($order); $list = $this->pageQuery($search_model); return $list; } /** * 获取场地信息 * @param int $id * @return array */ public function getInfo(int $id) { $field = 'id,campus_id,venue_name,capacity,availability_status,time_range_type,time_range_start,time_range_end,fixed_time_ranges,created_at,updated_at,deleted_at'; $info = $this->model->field($field)->where([['id', "=", $id]])->with(['campus'])->findOrEmpty()->toArray(); $info['availability_status'] = strval($info['availability_status']); $info['time_range_type'] = strval($info['time_range_type']); // 处理 fixed_time_ranges 字段的 JSON 解析,避免 null 值导致的错误 if ($info['fixed_time_ranges'] === null || $info['fixed_time_ranges'] === '') { $info['fixed_time_ranges'] = []; } else { $decoded = json_decode($info['fixed_time_ranges'], true); $info['fixed_time_ranges'] = (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) ? $decoded : []; } return $info; } /** * 添加场地 * @param array $data * @return mixed */ public function add(array $data) { if ($data['time_range_type'] === 'fixed') { $data['fixed_time_ranges'] = json_encode($data['fixed_time_ranges']); } $res = $this->model->create($data); return $res->id; } /** * 场地编辑 * @param int $id * @param array $data * @return bool */ public function edit(int $id, array $data) { if ($data['time_range_type'] === 'fixed') { $data['fixed_time_ranges'] = json_encode($data['fixed_time_ranges']); } $this->model->where([['id', '=', $id]])->update($data); return true; } /** * 删除场地 * @param int $id * @return bool */ public function del(int $id) { $model = $this->model->where([['id', '=', $id]])->find(); $res = $model->delete(); return $res; } /** * 获取校区列表 * @return array */ public function getCampusAll() { $campusModel = new Campus(); return $campusModel->select() ->where('campus_status', '=', 1) ->toArray(); } /** * 获取校区下的场地列表 * @param $campus_id * @return array * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function getVenueAll($campus_id) { return $this->model->where('availability_status', '=', 1) ->where('campus_id', $campus_id) ->select() ->toArray(); } /** * 获取场地那天的可预约时间 */ public function getVenueTime($date) { $timeSlots = []; foreach ($date as $item) { // 获取 time_range_type,默认为空 $timeRangeType = $item['time_range_type'] ?? ''; switch ($timeRangeType) { case 'fixed': // 固定时间段 if (!empty($item['fixed_time_ranges'])) { try { $fixedRanges = json_decode($item['fixed_time_ranges'], true); foreach ($fixedRanges as $range) { if (isset($range['start_time'], $range['end_time'])) { $timeSlots[] = "{$range['start_time']}-{$range['end_time']}"; } } } catch (\Exception $e) { // 记录错误日志 \think\facade\Log::error('解析固定时间段失败: ' . $e->getMessage()); } } break; case 'all': // 全天可用,但中午12:30-14:00不可用 // 上午:8:00 - 12:30(每小时) for ($hour = 8; $hour <= 12; $hour++) { $startTime = sprintf('%02d:%02d', $hour, 0); $endTime = sprintf('%02d:%02d', $hour + 1, 0); if ("12:30" === "$startTime") continue; $timeSlots[] = "$startTime-$endTime"; } // 下午:14:00 - 21:00(每小时) for ($hour = 14; $hour < 22; $hour++) { $startTime = sprintf('%02d:%02d', $hour, 0); $endTime = sprintf('%02d:%02d', $hour + 1, 0); $timeSlots[] = "$startTime-$endTime"; } break; case 'range': // 自定义时间范围 $start = $item['time_range_start'] ?? ''; $end = $item['time_range_end'] ?? ''; if ($start && $end) { $startParts = explode(':', $start); $endParts = explode(':', $end); if (count($startParts) === 2 && count($endParts) === 2) { $startTotalMinutes = intval($startParts[0]) * 60 + intval($startParts[1]); $endTotalMinutes = intval($endParts[0]) * 60 + intval($endParts[1]); if ($startTotalMinutes < $endTotalMinutes) { for ($minutes = $startTotalMinutes; $minutes < $endTotalMinutes; $minutes += 60) { $startHour = intdiv($minutes, 60); $startMinute = $minutes % 60; $endHour = intdiv($minutes + 60, 60); $endMinute = ($minutes + 60) % 60; $startTime = sprintf('%02d:%02d', $startHour, $startMinute); $endTime = sprintf('%02d:%02d', $endHour, $endMinute); $timeSlots[] = "$startTime-$endTime"; } } } } break; default: // 不支持的类型返回空数组 break; } } // $timeSlots去重 return array_unique($timeSlots); } }