input('date', Carbon::today()->format('Y-m-d')); $status = $request->input('status'); $type = $request->input('type'); $keyword = $request->input('keyword'); $page = $request->input('page', 1); $pageSize = $request->input('page_size', 20); $query = Visit::with([ 'visitArea', 'visitTime', 'acceptDepartment', 'acceptAdmin', 'visitAudits', 'acceptAdminSign' ])->whereDate('date', $date); // 状态筛选 if ($status) { $query->where('audit_status', $status); } else { // 默认显示待进厂和已进厂的记录 $query->whereIn('audit_status', [Visit::AUDIT_STATUS_APPROVED, Visit::AUDIT_STATUS_ENTERED, Visit::AUDIT_STATUS_LEFT]); } // 类型筛选 if ($type) { $query->where('type', $type); } // 关键词搜索 if ($keyword) { $query->where(function ($q) use ($keyword) { $q->where('name', 'like', "%{$keyword}%") ->orWhere('mobile', 'like', "%{$keyword}%") ->orWhere('plate', 'like', "%{$keyword}%") ->orWhere('code', 'like', "%{$keyword}%"); }); } $visits = $query->orderBy('created_at', 'desc') ->paginate($pageSize, ['*'], 'page', $page); return $this->success($visits); } catch (\Exception $e) { Log::error('门岗端获取拜访列表失败:' . $e->getMessage()); return $this->fail([ResponseCode::ERROR_INSIDE, __('gate.get_visit_list_failed')]); } } /** * @OA\Get( * path="/api/gate/visits/{id}", * tags={"门岗端接口"}, * summary="拜访详情信息", * description="获取指定拜访的详细信息", * @OA\Parameter(name="id", in="path", @OA\Schema(type="integer"), required=true, description="拜访ID"), * @OA\Response( * response="200", * description="成功获取拜访详情", * @OA\JsonContent( * @OA\Property(property="code", type="integer", example=200), * @OA\Property(property="message", type="string", example="success"), * @OA\Property(property="data", type="object") * ) * ) * ) */ public function visitDetail($id) { try { $visit = Visit::with([ 'visitArea', 'visitTime', 'acceptDepartment', 'acceptAdmin', 'acceptGoodsAdmin', 'accompany', 'visitAudits', 'logs', 'acceptAdminSign' ])->find($id); if (!$visit) { return $this->fail([ResponseCode::ERROR_BUSINESS, __('gate.visit_not_found')]); } return $this->success($visit); } catch (\Exception $e) { Log::error('门岗端获取拜访详情失败:' . $e->getMessage()); return $this->fail([ResponseCode::ERROR_INSIDE, __('gate.get_visit_detail_failed')]); } } /** * @OA\Post( * path="/api/gate/visits/{id}/update", * tags={"门岗端接口"}, * summary="更新拜访信息", * description="门岗端更新拜访信息(绑定ID卡、修改状态、上传货车图片等)", * @OA\Parameter(name="id", in="path", @OA\Schema(type="integer"), required=true, description="拜访ID"), * @OA\RequestBody( * required=true, * @OA\JsonContent( * @OA\Property(property="action", type="string", description="操作类型:bind_card绑定ID卡,enter进厂,leave离厂,upload_vehicle上传货车图片"), * @OA\Property(property="person_no", type="string", description="人牌号(绑定ID卡时必填)"), * @OA\Property(property="car_no", type="string", description="停车牌号(绑定ID卡时必填)"), * @OA\Property(property="vehicle_images", type="array", description="货车图片ID数组(上传货车图片时必填)", @OA\Items(type="integer")), * @OA\Property(property="remark", type="string", description="备注信息") * ) * ), * @OA\Response( * response="200", * description="更新成功", * @OA\JsonContent( * @OA\Property(property="code", type="integer", example=200), * @OA\Property(property="message", type="string", example="操作成功"), * @OA\Property(property="data", type="object") * ) * ) * ) */ public function updateVisit(Request $request, $id) { try { $visit = Visit::find($id); if (!$visit) { return $this->fail([ResponseCode::ERROR_BUSINESS, __('gate.visit_not_found')]); } $action = $request->input('action'); $remark = $request->input('remark', ''); DB::beginTransaction(); switch ($action) { case 'bind_card': // 绑定ID卡 $personNo = $request->input('person_no'); $carNo = $request->input('car_no'); if (!$personNo) { return $this->fail([ResponseCode::ERROR_PARAMETER, __('gate.person_no_required')]); } $visit->person_no = $personNo; if ($carNo) { $visit->car_no = $carNo; } $visit->save(); // 记录日志 $this->createVisitLog($visit, VisitLog::TYPE_ENTER, __('gate.bind_card_log', ['person_no' => $personNo, 'car_no' => $carNo ?: ''])); break; case 'enter': // 进厂 if ($visit->audit_status != Visit::AUDIT_STATUS_APPROVED) { return $this->fail([ResponseCode::ERROR_BUSINESS, __('gate.only_approved_visits_can_enter')]); } $visit->audit_status = Visit::AUDIT_STATUS_ENTERED; $visit->save(); // 记录日志 $this->createVisitLog($visit, VisitLog::TYPE_ENTER, __('gate.enter_log') . ($remark ? ':' . $remark : '')); // 记录门岗日志 $this->createGateLog($visit, 'enter', $remark); break; case 'leave': // 离厂 if ($visit->audit_status != Visit::AUDIT_STATUS_ENTERED) { return $this->fail([ResponseCode::ERROR_BUSINESS, __('gate.only_entered_visitors_can_leave')]); } $visit->audit_status = Visit::AUDIT_STATUS_LEFT; $visit->save(); // 记录日志 $this->createVisitLog($visit, VisitLog::TYPE_LEAVE, __('gate.leave_log') . ($remark ? ':' . $remark : '')); // 记录门岗日志 $this->createGateLog($visit, 'leave', $remark); break; case 'upload_vehicle': // 上传货车图片 if ($visit->type != Visit::TYPE_LOGISTICS_CAR) { return $this->fail([ResponseCode::ERROR_BUSINESS, __('gate.only_logistics_cars_can_upload_images')]); } $vehicleImages = $request->input('vehicle_images', []); if (empty($vehicleImages)) { return $this->fail([ResponseCode::ERROR_BUSINESS, __('gate.vehicle_images_required')]); } // 验证图片ID是否存在于uploads表中 $existingImages = Upload::whereIn('id', $vehicleImages)->pluck('id')->toArray(); if (count($existingImages) !== count($vehicleImages)) { return $this->fail([ResponseCode::ERROR_BUSINESS, __('gate.invalid_vehicle_images')]); } // 存储货车图片ID数组到vehicle_images字段 $visit->vehicle_images = $vehicleImages; $visit->save(); // 记录日志 $this->createVisitLog($visit, VisitLog::TYPE_ENTER, __('gate.upload_vehicle_images_log', ['count' => count($vehicleImages)])); break; default: return $this->fail([ResponseCode::ERROR_BUSINESS, __('gate.invalid_action_type')]); } DB::commit(); return $this->success($visit); } catch (\Exception $e) { DB::rollBack(); Log::error('门岗端更新拜访信息失败:' . $e->getMessage()); return $this->fail([ResponseCode::ERROR_INSIDE, __('gate.operation_failed') . ':' . $e->getMessage()]); } } /** * 创建拜访日志 */ private function createVisitLog($visit, $type, $remark = '') { VisitLog::log($visit->id, $type, $remark); } /** * 创建门岗日志 */ private function createGateLog($visit, $action, $remark = '') { $personNo = $visit->person_no ? [$visit->person_no] : []; $carNo = $visit->car_no ? [$visit->car_no] : []; GateLog::create([ 'code' => $visit->code, 'remark' => $remark, 'person_no' => $personNo, 'car_no' => $carNo, 'created_at' => now(), 'updated_at' => now(), ]); } /** * @OA\Get( * path="/api/gate/visits/use-code", * tags={"门岗端接口"}, * summary="核销", * description="", * @OA\Parameter(name="admin_id", in="query", @OA\Schema(type="string"), required=false, description="管理员id"), * @OA\Parameter(name="code", in="query", @OA\Schema(type="string"), required=false, description="编码(二选一)"), * @OA\Parameter(name="idcard", in="query", @OA\Schema(type="string"), required=false, description="身份证(二选一)"), * @OA\Parameter(name="car_no", in="query", @OA\Schema(type="string"), required=false, description="停车牌"), * @OA\Parameter(name="person_no", in="query", @OA\Schema(type="string"), required=false, description="人牌"), * @OA\Parameter(name="type", in="query", @OA\Schema(type="string"), required=false, description="1进厂2离厂"), * @OA\Response( * response="200", * description="暂无" * ) * ) */ public function useCode() { $all = \request()->all(); $messages = [ 'type.required' => __('gate.validation.type_required'), 'admin_id.required' => __('gate.validation.admin_id_required') ]; $validator = Validator::make($all, [ 'type' => 'required', 'admin_id' => 'required' ], $messages); if ($validator->fails()) { return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } $code = \request('code'); $idcard = \request('idcard'); if (empty($idcard) && empty($code)) { return $this->fail([ResponseCode::ERROR_PARAMETER, __('gate.validation.code_or_idcard_required')]); } $check = Visit::where(function ($query) use ($idcard, $code) { if (!empty($idcard)) { $query->where('idcard', $idcard); } if (!empty($code)) { $query->where('code', $code); } })->first(); if (empty($check)) { return $this->fail([ResponseCode::ERROR_BUSINESS, __('gate.business.visit_not_found')]); } $remark = __('gate.operation.enter_factory'); if ($all['type'] == 2) { $remark = __('gate.operation.leave_factory'); } $gateLog = GateLog::add($all['admin_id'], $all['code'], $all['person_no'] ?? [], $all['car_no'] ?? [], $remark); if ($all['type'] == 1) { // 入场 Visit::where('code', $all['code'])->update(['audit_status' => 3, 'person_no' => $all['person_no'] ?? '', 'car_no' => $all['car_no'] ?? '']); } if ($all['type'] == 2) { Visit::where('code', $all['code'])->update(['audit_status' => 4]); } return $this->success($gateLog); } }