where('name', 'like', '%门岗%'); })->get(); return $this->success($admin); } /** * @OA\Get( * path="/api/admin/gate/visit-list", * tags={"门岗-拜访记录"}, * summary="拜访记录", * description="", * @OA\Parameter(name="keyword", in="query", @OA\Schema(type="string"), required=false, description="关键词"), * @OA\Parameter(name="audit_status", in="query", @OA\Schema(type="string"), required=false, description="审核状态-1待学习0待审核1通过(待进厂)2驳回3已进厂4已离厂"), * @OA\Parameter(name="start_date", in="query", @OA\Schema(type="string"), required=false, description="开始日期"), * @OA\Parameter(name="end_date", in="query", @OA\Schema(type="string"), required=false, description="结束日期"), * @OA\Parameter(name="page_size", in="query", @OA\Schema(type="string"), required=false, description="每页显示的条数"), * @OA\Parameter(name="page", in="query", @OA\Schema(type="string"), required=false, description="页码"), * @OA\Parameter(name="sort_name", in="query", @OA\Schema(type="string"), required=false, description="排序字段名字"), * @OA\Parameter(name="sort_type", in="query", @OA\Schema(type="string"), required=false, description="排序类型"), * @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="is_export", in="query", @OA\Schema(type="string"), required=false, description="是否导出0否1是,默认0"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", * description="暂无" * ) * ) */ public function visitList() { $all = request()->all(); $list = Visit::with('logs.admin', 'logs.user', 'visitTime', 'admin', 'visitArea', 'acceptAdmin.department', 'acceptAdminSignFile', 'acceptGoodsAdmin.department')->where(function ($query) use ($all) { if (isset($all['keyword'])) { $query->where('name', 'like', '%' . $all['keyword'] . '%'); } if (isset($all['audit_status'])) { $query->where('audit_status', $all['audit_status']); } if (isset($all['code'])) { $query->where('code', $all['code']); } if (isset($all['idcard'])) { $query->where('idcard', $all['idcard']); } // 普通访客:按预约到访日 date 落在查询区间内;长期访客:查询区间与长期有效区间 [start_date,end_date] 有交集即可出现在「今日」等列表中 if (!empty($all['start_date']) && !empty($all['end_date'])) { $qs = $all['start_date']; $qe = $all['end_date']; $query->where(function ($sub) use ($qs, $qe) { $sub->where(function ($q1) use ($qs, $qe) { $q1->where(function ($q2) { $q2->whereNull('long_time')->orWhere('long_time', 0); })->whereBetween('date', [$qs, $qe]); })->orWhere(function ($q1) use ($qs, $qe) { $q1->where('long_time', 1) ->whereNotNull('start_date') ->whereNotNull('end_date') ->where('start_date', '<=', $qe) ->where('end_date', '>=', $qs); }); }); } })->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc'); if (isset($all['is_export']) && !empty($all['is_export'])) { return (new FastExcel($list->limit(10000)->get()->toArray()))->download('门岗访客记录' . date('YmdHis') . '.csv', function ($info) { return [ '编码' => $info['code'] ?? '', '姓名' => $info['name'] ?? '', '类型' => $info['type_text'] ?? '', '审核状态' => $info['audit_status_text'] ?? '', '被访人' => ($info['accept_admin']['name']) ?? '', '预约日期' => $info['date'] ?? '', '证件号' => $info['idcard'] ?? '', '手机号' => $info['mobile'] ?? '', '单位名称' => $info['company_name'] ?? '', '到访时段开始' => ($info['visit_time']['start_time']) ?? '', '到访时段结束' => ($info['visit_time']['end_time']) ?? '', '创建时间' => $info['created_at'] ?? '', ]; }); } $list = $list->paginate($all['page_size'] ?? 20); return $this->success($list); } /** * @OA\Get( * path="/api/admin/gate/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="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 = [ 'code.required' => '编号必填', 'type.required' => '类型必填', 'admin_id.required' => '操作人必填' ]; $validator = Validator::make($all, [ 'code' => 'required', 'type' => 'required', 'admin_id' => 'required' ], $messages); if ($validator->fails()) { return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } $check = Visit::where('code', $all['code'])->first(); if (empty($check)) { return $this->fail([ResponseCode::ERROR_BUSINESS, '拜访记录不存在']); } if ($check->audit_status == 2 || $check->audit_status == 5) { return $this->fail([ResponseCode::ERROR_BUSINESS, '当前记录不可核销']); } // 物流访客:每次进/离厂都必须先上传当次车辆照片 if ((int)$check->type === 3) { $latestGateLog = GateLog::where('visit_id', $check->id)->orderByDesc('id')->first(); $fileIds = []; if (is_array($check->file)) { $fileIds = $check->file; } elseif (is_string($check->file) && !empty($check->file)) { $decoded = json_decode($check->file, true); if (is_array($decoded)) { $fileIds = $decoded; } } $hasPhoto = count($fileIds) > 0; if (!$hasPhoto) { return $this->fail([ResponseCode::ERROR_BUSINESS, '物流访客需先上传车辆照片后再核销']); } // 要求本次核销前有一次新的更新动作,避免重复使用上次照片直接核销 if (!empty($latestGateLog) && strtotime((string)$check->updated_at) <= strtotime((string)$latestGateLog->created_at)) { return $this->fail([ResponseCode::ERROR_BUSINESS, '物流访客本次进/离厂请先上传当次照片']); } } // 长期访客:校验当前日期在有效周期内 $today = Carbon::now()->format('Y-m-d'); if ((int)$check->long_time === 1) { if (empty($check->start_date) || empty($check->end_date)) { return $this->fail([ResponseCode::ERROR_BUSINESS, '长期访客未配置有效周期']); } if ($today < $check->start_date || $today > $check->end_date) { return $this->fail([ResponseCode::ERROR_BUSINESS, '当前不在长期访客有效周期内']); } $todayLastLog = GateLog::where('visit_id', $check->id)->where('biz_date', $today)->orderByDesc('id')->first(); if ((int)$all['type'] === 1 && $todayLastLog && (int)$todayLastLog->action === 1) { return $this->fail([ResponseCode::ERROR_BUSINESS, '今日已进厂,请先离厂后再进厂']); } if ((int)$all['type'] === 2 && (!$todayLastLog || (int)$todayLastLog->action !== 1)) { return $this->fail([ResponseCode::ERROR_BUSINESS, '今日无有效进厂记录,无法离厂']); } } $remark = '进厂'; if ($all['type'] == 2) { $remark = '离厂'; } $gateLog = GateLog::add($all['admin_id'], $all['code'], $all['person_no'] ?? [], $all['car_no'] ?? [], $remark, $check->id, (int)$all['type'], $today); if ($all['type'] == 1) { // 入场 Visit::where('code', $all['code'])->update(['audit_status' => 3, 'person_no' => $all['person_no'] ?? '', 'car_no' => $all['car_no'] ?? '']); // 通知被访人 $vars = ['date' => $check->date, 'name' => $check->name, 'phone_number' => $check->mobile]; $template_id = 'zPtka4'; $acceptAdmin = Admin::find($check->accept_admin_id); sms($acceptAdmin->mobile, $vars, $template_id); } if ($all['type'] == 2) { Visit::where('code', $all['code'])->update(['audit_status' => 4]); } return $this->success($gateLog); } }