Procházet zdrojové kódy

新增访客系统接口查询

wangshuangpan před 2 měsíci
rodič
revize
f35ed9250f

+ 104 - 0
pm-admin/src/main/java/com/pm/web/controller/fkxt/VisitorController.java

@@ -0,0 +1,104 @@
+package com.pm.web.controller.fkxt;
+
+import com.pm.common.core.controller.BaseController;
+import com.pm.common.core.domain.AjaxResult;
+import com.pm.common.core.page.TableDataInfo;
+import com.pm.common.utils.poi.ExcelUtilPageData;
+import com.pm.fkxt.service.IVisitorService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/subsystem/visitor")
+public class VisitorController extends BaseController {
+
+    @Autowired
+    private IVisitorService visitorService;
+
+    /**
+     * 查询访客登记信息列表
+     */
+    @GetMapping("/list")
+    public TableDataInfo visitorList() {
+        startPage();
+        List<Map<String, Object>> list = visitorService.selectVisitorInfoList(getPageData());
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出访客登记信息
+     */
+    @PostMapping("/export")
+    public void exportVisitor(HttpServletResponse response) {
+        List<Map<String, Object>> list = visitorService.selectVisitorInfoList(getPageData());
+        String filename = "访客登记信息";
+        String[] titles = {
+            "访客ID,visitor_id",
+            "访客姓名,visitor_name",
+            "访客电话,visitor_phone",
+            "身份证号,id_card",
+            "访客单位,company",
+            "访问目的,visit_purpose",
+            "被访人姓名,visited_person",
+            "被访部门,visited_dept",
+            "被访人电话,visited_phone",
+            "预约时间,appointment_time",
+            "访问开始时间,visit_start_time",
+            "访问结束时间,visit_end_time",
+            "实际开始时间,actual_start_time",
+            "实际结束时间,actual_end_time",
+            "访问状态,visit_status",
+            "访客卡号,card_no",
+            "入场门禁,entry_gate",
+            "出场门禁,exit_gate",
+            "审批状态,approval_status",
+            "审批人,approver",
+            "审批时间,approval_time"
+        };
+        ExcelUtilPageData.exportXLSX(response, null, null, filename, titles, list);
+    }
+
+    /**
+     * 查询门禁刷卡记录列表
+     */
+    @GetMapping("/access")
+    public TableDataInfo accessList() {
+        startPage();
+        List<Map<String, Object>> list = visitorService.selectAccessRecordList(getPageData());
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出门禁刷卡记录
+     */
+    @PostMapping("/access/export")
+    public void exportAccess(HttpServletResponse response) {
+        List<Map<String, Object>> list = visitorService.selectAccessRecordList(getPageData());
+        String filename = "门禁刷卡记录";
+        String[] titles = {
+            "记录ID,record_id",
+            "访客ID,visitor_id",
+            "访客姓名,visitor_name",
+            "卡号,card_no",
+            "门禁ID,gate_id",
+            "门禁名称,gate_name",
+            "门禁位置,gate_location",
+            "刷卡时间,swipe_time",
+            "刷卡类型,swipe_type",
+            "刷卡结果,swipe_result",
+            "设备序列号,device_sn",
+            "失败原因,fail_reason",
+            "体温,temperature",
+            "口罩检测,mask_detection",
+            "抓拍照片,photo_url"
+        };
+        ExcelUtilPageData.exportXLSX(response, null, null, filename, titles, list);
+    }
+}

+ 11 - 0
pm-system/src/main/java/com/pm/fkxt/mapper/VisitorMapper.java

@@ -0,0 +1,11 @@
+package com.pm.fkxt.mapper;
+
+import com.pm.common.config.PageData;
+
+import java.util.List;
+import java.util.Map;
+
+public interface VisitorMapper {
+    List<Map<String, Object>> selectVisitorInfoList(PageData pd);
+    List<Map<String, Object>> selectAccessRecordList(PageData pd);
+}

+ 11 - 0
pm-system/src/main/java/com/pm/fkxt/service/IVisitorService.java

@@ -0,0 +1,11 @@
+package com.pm.fkxt.service;
+
+import com.pm.common.config.PageData;
+
+import java.util.List;
+import java.util.Map;
+
+public interface IVisitorService {
+    List<Map<String, Object>> selectVisitorInfoList(PageData pd);
+    List<Map<String, Object>> selectAccessRecordList(PageData pd);
+}

+ 27 - 0
pm-system/src/main/java/com/pm/fkxt/service/impl/VisitorServiceImpl.java

@@ -0,0 +1,27 @@
+package com.pm.fkxt.service.impl;
+
+import com.pm.fkxt.mapper.VisitorMapper;
+import com.pm.fkxt.service.IVisitorService;
+import com.pm.common.config.PageData;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class VisitorServiceImpl implements IVisitorService {
+
+    @Autowired
+    private VisitorMapper visitorMapper;
+
+    @Override
+    public List<Map<String, Object>> selectVisitorInfoList(PageData pd) {
+        return visitorMapper.selectVisitorInfoList(pd);
+    }
+
+    @Override
+    public List<Map<String, Object>> selectAccessRecordList(PageData pd) {
+        return visitorMapper.selectAccessRecordList(pd);
+    }
+}

+ 93 - 0
pm-system/src/main/resources/mapper/subsystem/VisitorMapper.xml

@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.pm.fkxt.mapper.VisitorMapper">
+
+    <!-- 查询访客登记信息 -->
+    <select id="selectVisitorInfoList" parameterType="pd" resultType="java.util.HashMap">
+        SELECT
+        visitor_id,
+        visitor_name,
+        visitor_phone,
+        id_card,
+        company,
+        visit_purpose,
+        visited_person,
+        visited_dept,
+        visited_phone,
+        appointment_time,
+        visit_start_time,
+        visit_end_time,
+        actual_start_time,
+        actual_end_time,
+        visit_status,
+        card_no,
+        entry_gate,
+        exit_gate,
+        approval_status,
+        approver,
+        approval_time
+        FROM visitor_info
+        <where>
+            <if test="visitorName != null and visitorName != ''">
+                AND visitor_name LIKE CONCAT('%', #{visitorName}, '%')
+            </if>
+            <if test="visitedPerson != null and visitedPerson != ''">
+                AND visited_person LIKE CONCAT('%', #{visitedPerson}, '%')
+            </if>
+            <if test="visitStatus != null">
+                AND visit_status = #{visitStatus}
+            </if>
+            <if test="beginTime != null and beginTime != ''">
+                AND visit_start_time &gt;= #{beginTime}
+            </if>
+            <if test="endTime != null and endTime != ''">
+                AND visit_end_time &lt;= #{endTime}
+            </if>
+        </where>
+        ORDER BY visit_start_time DESC
+    </select>
+
+    <!-- 查询门禁刷卡记录 -->
+    <select id="selectAccessRecordList" parameterType="pd" resultType="java.util.HashMap">
+        SELECT
+        record_id,
+        visitor_id,
+        visitor_name,
+        card_no,
+        gate_id,
+        gate_name,
+        gate_location,
+        swipe_time,
+        swipe_type,
+        swipe_result,
+        device_sn,
+        fail_reason,
+        temperature,
+        mask_detection,
+        photo_url
+        FROM visitor_card_record
+        <where>
+            <if test="visitorId != null and visitorId != ''">
+                AND visitor_id = #{visitorId}
+            </if>
+            <if test="visitorName != null and visitorName != ''">
+                AND visitor_name LIKE CONCAT('%', #{visitorName}, '%')
+            </if>
+            <if test="gateLocation != null and gateLocation != ''">
+                AND gate_location LIKE CONCAT('%', #{gateLocation}, '%')
+            </if>
+            <if test="swipeType != null">
+                AND swipe_type = #{swipeType}
+            </if>
+            <if test="beginTime != null and beginTime != ''">
+                AND swipe_time &gt;= #{beginTime}
+            </if>
+            <if test="endTime != null and endTime != ''">
+                AND swipe_time &lt;= #{endTime}
+            </if>
+        </where>
+        ORDER BY swipe_time DESC
+    </select>
+</mapper>

+ 39 - 0
pm_ui/src/api/subsystem/visitor.js

@@ -0,0 +1,39 @@
+import request from '@/utils/request'
+
+// 查询访客登记信息列表
+export function listVisitorInfo(query) {
+    return request({
+        url: '/subsystem/visitor/list',
+        method: 'get',
+        params: query
+    })
+}
+
+// 导出访客登记信息
+export function exportVisitorInfo(query) {
+    return request({
+        url: '/subsystem/visitor/export',
+        method: 'post',
+        data: query,
+        responseType: 'blob'
+    })
+}
+
+// 查询门禁刷卡记录列表
+export function listAccessRecord(query) {
+    return request({
+        url: '/subsystem/visitor/access',
+        method: 'get',
+        params: query
+    })
+}
+
+// 导出门禁刷卡记录
+export function exportAccessRecord(query) {
+    return request({
+        url: '/subsystem/visitor/export',
+        method: 'post',
+        data: query,
+        responseType: 'blob'
+    })
+}

+ 392 - 0
pm_ui/src/views/fkxt/VisitorSystem.vue

@@ -0,0 +1,392 @@
+<template>
+  <div class="app-container">
+    <el-tabs v-model="activeTab">
+      <!-- 访客登记信息标签页 -->
+      <el-tab-pane label="访客登记" name="visitors">
+        <el-form :model="visitorQuery" ref="visitorQueryRef" :inline="true" label-width="80px">
+          <el-form-item label="访客姓名" prop="visitorName">
+            <el-input v-model="visitorQuery.visitorName" placeholder="请输入访客姓名" clearable />
+          </el-form-item>
+          <el-form-item label="被访人" prop="visitedPerson">
+            <el-input v-model="visitorQuery.visitedPerson" placeholder="请输入被访人" clearable />
+          </el-form-item>
+          <el-form-item label="状态" prop="visitStatus">
+            <el-select v-model="visitorQuery.visitStatus" placeholder="请选择状态" clearable width="80px">
+              <el-option label="预约" :value="0" />
+              <el-option label="已到达" :value="1" />
+              <el-option label="访问中" :value="2" />
+              <el-option label="已离开" :value="3" />
+              <el-option label="过期" :value="4" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="时间范围" prop="timeRange">
+            <el-date-picker
+                v-model="visitorQuery.timeRange"
+                type="daterange"
+                range-separator="至"
+                start-placeholder="开始日期"
+                end-placeholder="结束日期"
+                value-format="YYYY-MM-DD"
+            />
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="getVisitorList">搜索</el-button>
+            <el-button icon="Refresh" @click="resetVisitorQuery">重置</el-button>
+          </el-form-item>
+        </el-form>
+
+<!--        <el-row :gutter="10" class="mb8">-->
+<!--          <el-col :span="1.5">-->
+<!--            <el-button-->
+<!--                type="warning"-->
+<!--                plain-->
+<!--                icon="Download"-->
+<!--                @click="handleExportVisitor"-->
+<!--                v-hasPermi="['system:visitor:export']"-->
+<!--            >导出</el-button>-->
+<!--          </el-col>-->
+<!--        </el-row>-->
+
+        <el-table v-loading="visitorLoading" :data="visitorList" stripe border>
+          <el-table-column label="访客ID" prop="visitor_id"  />
+          <el-table-column label="访客姓名" prop="visitor_name"  />
+          <el-table-column label="电话" prop="visitor_phone"  />
+          <el-table-column label="单位" prop="company" />
+          <el-table-column label="访问目的" prop="visit_purpose"  />
+          <el-table-column label="被访人" prop="visited_person"  />
+          <el-table-column label="访问时间" >
+            <template #default="scope">
+              <div>预约: {{ parseTime(scope.row.visit_start_time) }} ~ {{ parseTime(scope.row.visit_end_time) }}</div>
+              <div v-if="scope.row.actual_start_time">实际: {{ parseTime(scope.row.actual_start_time) }} ~ {{ parseTime(scope.row.actual_end_time) }}</div>
+            </template>
+          </el-table-column>
+          <el-table-column label="状态" prop="visit_status" >
+            <template #default="scope">
+              <el-tag :type="statusTagType(scope.row.visit_status)">
+                {{ statusText(scope.row.visit_status) }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作"  fixed="right">
+            <template #default="scope">
+              <el-button link type="primary" icon="View" @click="handleVisitorDetail(scope.row)">详情</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+
+        <pagination
+            v-show="visitorTotal > 0"
+            :total="visitorTotal"
+            v-model:page="visitorQuery.pageNum"
+            v-model:limit="visitorQuery.pageSize"
+            @pagination="getVisitorList"
+        />
+      </el-tab-pane>
+
+      <!-- 刷卡记录标签页 -->
+      <el-tab-pane label="刷卡记录" name="access">
+        <el-form :model="accessQuery" ref="accessQueryRef" :inline="true" label-width="80px">
+          <el-form-item label="访客ID" prop="visitorId">
+            <el-input v-model="accessQuery.visitorId" placeholder="请输入访客ID" clearable />
+          </el-form-item>
+          <el-form-item label="访客姓名" prop="visitorName">
+            <el-input v-model="accessQuery.visitorName" placeholder="请输入访客姓名" clearable />
+          </el-form-item>
+          <el-form-item label="门禁位置" prop="gateLocation">
+            <el-input v-model="accessQuery.gateLocation" placeholder="请输入门禁位置" clearable />
+          </el-form-item>
+          <el-form-item label="刷卡类型" prop="swipeType">
+            <el-select v-model="accessQuery.swipeType" placeholder="请选择类型" clearable>
+              <el-option label="进入" :value="1" />
+              <el-option label="离开" :value="2" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="时间范围" prop="timeRange">
+            <el-date-picker
+                v-model="accessQuery.timeRange"
+                type="daterange"
+                range-separator="至"
+                start-placeholder="开始日期"
+                end-placeholder="结束日期"
+                value-format="YYYY-MM-DD"
+            />
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="getAccessList">搜索</el-button>
+            <el-button icon="Refresh" @click="resetAccessQuery">重置</el-button>
+          </el-form-item>
+        </el-form>
+
+<!--        <el-row :gutter="10" class="mb8">-->
+<!--          <el-col :span="1.5">-->
+<!--            <el-button-->
+<!--                type="warning"-->
+<!--                plain-->
+<!--                icon="Download"-->
+<!--                @click="handleExportAccess"-->
+<!--                v-hasPermi="['system:access:export']"-->
+<!--            >导出</el-button>-->
+<!--          </el-col>-->
+<!--        </el-row>-->
+
+        <el-table v-loading="accessLoading" :data="accessList" stripe border>
+          <el-table-column label="记录ID" prop="record_id" />
+          <el-table-column label="访客姓名" prop="visitor_name"  />
+          <el-table-column label="卡号" prop="card_no"  />
+          <el-table-column label="门禁名称" prop="gate_name"  />
+          <el-table-column label="门禁位置" prop="gate_location"  />
+          <el-table-column label="刷卡时间" prop="swipe_time" >
+            <template #default="scope">
+              <span>{{ parseTime(scope.row.swipe_time) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="类型" prop="swipe_type" >
+            <template #default="scope">
+              <el-tag :type="scope.row.swipe_type === 1 ? 'success' : 'danger'">
+                {{ scope.row.swipe_type === 1 ? '进入' : '离开' }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="结果" prop="swipe_result" >
+            <template #default="scope">
+              <el-tag :type="scope.row.swipe_result === 1 ? 'success' : 'danger'">
+                {{ scope.row.swipe_result === 1 ? '成功' : '失败' }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="体温" prop="temperature"  />
+          <el-table-column label="口罩" prop="mask_detection" >
+            <template #default="scope">
+              <el-tag :type="scope.row.mask_detection === 1 ? 'success' : 'danger'">
+                {{ scope.row.mask_detection === 1 ? '已佩戴' : '未佩戴' }}
+              </el-tag>
+            </template>
+          </el-table-column>
+        </el-table>
+
+        <pagination
+            v-show="accessTotal > 0"
+            :total="accessTotal"
+            v-model:page="accessQuery.pageNum"
+            v-model:limit="accessQuery.pageSize"
+            @pagination="getAccessList"
+        />
+      </el-tab-pane>
+    </el-tabs>
+
+    <!-- 访客详情抽屉 -->
+    <el-drawer
+        v-model="detailVisible"
+        title="访客详情"
+        direction="rtl"
+        size="40%"
+    >
+      <el-descriptions :column="2" border>
+        <el-descriptions-item label="访客ID">{{ currentVisitor.visitor_id }}</el-descriptions-item>
+        <el-descriptions-item label="姓名">{{ currentVisitor.visitor_name }}</el-descriptions-item>
+        <el-descriptions-item label="电话">{{ currentVisitor.visitor_phone }}</el-descriptions-item>
+        <el-descriptions-item label="身份证">{{ currentVisitor.id_card }}</el-descriptions-item>
+        <el-descriptions-item label="单位">{{ currentVisitor.company }}</el-descriptions-item>
+        <el-descriptions-item label="访问目的">{{ currentVisitor.visit_purpose }}</el-descriptions-item>
+        <el-descriptions-item label="被访人">{{ currentVisitor.visited_person }}</el-descriptions-item>
+        <el-descriptions-item label="部门">{{ currentVisitor.visited_dept }}</el-descriptions-item>
+        <el-descriptions-item label="被访电话">{{ currentVisitor.visited_phone }}</el-descriptions-item>
+        <el-descriptions-item label="预约时间">
+          {{ parseTime(currentVisitor.appointment_time) }}
+        </el-descriptions-item>
+        <el-descriptions-item label="访问时间">
+          {{ parseTime(currentVisitor.visit_start_time) }} ~ {{ parseTime(currentVisitor.visit_end_time) }}
+        </el-descriptions-item>
+        <el-descriptions-item label="实际时间" v-if="currentVisitor.actual_start_time">
+          {{ parseTime(currentVisitor.actual_start_time) }} ~ {{ parseTime(currentVisitor.actual_end_time) }}
+        </el-descriptions-item>
+        <el-descriptions-item label="状态">
+          <el-tag :type="statusTagType(currentVisitor.visit_status)">
+            {{ statusText(currentVisitor.visit_status) }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="卡号">{{ currentVisitor.card_no }}</el-descriptions-item>
+        <el-descriptions-item label="入场门禁">{{ currentVisitor.entry_gate }}</el-descriptions-item>
+        <el-descriptions-item label="出场门禁">{{ currentVisitor.exit_gate }}</el-descriptions-item>
+        <el-descriptions-item label="审批状态">
+          <el-tag :type="currentVisitor.approval_status === 1 ? 'success' : currentVisitor.approval_status === 2 ? 'danger' : 'info'">
+            {{ approvalText(currentVisitor.approval_status) }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="审批人">{{ currentVisitor.approver }}</el-descriptions-item>
+        <el-descriptions-item label="审批时间">
+          {{ parseTime(currentVisitor.approval_time) }}
+        </el-descriptions-item>
+      </el-descriptions>
+    </el-drawer>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, watch } from 'vue'
+import { listVisitorInfo, exportVisitorInfo } from '@/api/subsystem/visitor'
+import { listAccessRecord, exportAccessRecord } from '@/api/subsystem/visitor'
+
+const { proxy } = getCurrentInstance()
+const activeTab = ref('visitors')
+
+// 监听activeTab的变化
+watch(activeTab, (newVal) => {
+  if (newVal === 'access') {
+    // 当切换到刷卡记录标签页时,初始化并加载数据
+    resetAccessQuery()
+  }
+})
+
+// 访客登记查询相关
+const visitorQuery = reactive({
+  pageNum: 1,
+  pageSize: 10,
+  visitorName: null,
+  visitedPerson: null,
+  visitStatus: null,
+  timeRange: []
+})
+const visitorList = ref([])
+const visitorTotal = ref(0)
+const visitorLoading = ref(false)
+
+// 刷卡记录查询相关
+const accessQuery = reactive({
+  pageNum: 1,
+  pageSize: 10,
+  visitorId: null,
+  visitorName: null,
+  gateLocation: null,
+  swipeType: null,
+  timeRange: []
+})
+const accessList = ref([])
+const accessTotal = ref(0)
+const accessLoading = ref(false)
+
+// 访客详情相关
+const detailVisible = ref(false)
+const currentVisitor = ref({})
+
+// 状态标签类型
+const statusTagType = (status) => {
+  const types = ['info', 'success', 'warning', 'danger', 'danger']
+  return types[status] || 'info'
+}
+
+// 状态文本
+const statusText = (status) => {
+  const texts = ['预约', '已到达', '访问中', '已离开', '过期']
+  return texts[status] || '未知'
+}
+
+// 审批状态文本
+const approvalText = (status) => {
+  const texts = ['待审批', '已通过', '已拒绝']
+  return texts[status] || '未知'
+}
+
+// 查询访客登记列表
+function getVisitorList() {
+  visitorLoading.value = true
+  const params = {
+    ...visitorQuery,
+    pageNum: visitorQuery.pageNum,
+    pageSize: visitorQuery.pageSize
+  }
+  if (visitorQuery.timeRange && visitorQuery.timeRange.length === 2) {
+    params.beginTime = visitorQuery.timeRange[0]
+    params.endTime = visitorQuery.timeRange[1]
+  }
+  listVisitorInfo(params).then(response => {
+    visitorList.value = response.rows
+    visitorTotal.value = response.total
+    visitorLoading.value = false
+  })
+}
+
+// 重置访客登记查询
+function resetVisitorQuery() {
+  proxy.resetForm('visitorQueryRef')
+  visitorQuery.pageNum = 1
+  getVisitorList()
+}
+
+// 导出访客登记
+function handleExportVisitor() {
+  const params = {
+    ...visitorQuery,
+    pageNum: undefined,
+    pageSize: undefined
+  }
+  if (visitorQuery.timeRange && visitorQuery.timeRange.length === 2) {
+    params.beginTime = visitorQuery.timeRange[0]
+    params.endTime = visitorQuery.timeRange[1]
+  }
+  proxy.$modal.confirm('确认导出访客登记信息吗?').then(() => {
+    exportVisitorInfo(params).then(response => {
+      proxy.download(response.msg)
+    })
+  })
+}
+
+// 查询刷卡记录列表
+function getAccessList() {
+  accessLoading.value = true
+  const params = {
+    ...accessQuery,
+    pageNum: accessQuery.pageNum,
+    pageSize: accessQuery.pageSize
+  }
+  if (accessQuery.timeRange && accessQuery.timeRange.length === 2) {
+    params.beginTime = accessQuery.timeRange[0]
+    params.endTime = accessQuery.timeRange[1]
+  }
+  listAccessRecord(params).then(response => {
+    accessList.value = response.rows
+    accessTotal.value = response.total
+    accessLoading.value = false
+  })
+}
+
+// 重置刷卡记录查询
+function resetAccessQuery() {
+  proxy.resetForm('accessQueryRef')
+  accessQuery.pageNum = 1
+  getAccessList()
+}
+
+// 导出门禁刷卡记录
+function handleExportAccess() {
+  const params = {
+    ...accessQuery,
+    pageNum: undefined,
+    pageSize: undefined
+  }
+  if (accessQuery.timeRange && accessQuery.timeRange.length === 2) {
+    params.beginTime = accessQuery.timeRange[0]
+    params.endTime = accessQuery.timeRange[1]
+  }
+  proxy.$modal.confirm('确认导出门禁刷卡记录吗?').then(() => {
+    exportAccessRecord(params).then(response => {
+      proxy.download(response.msg)
+    })
+  })
+}
+
+// 查看访客详情
+function handleVisitorDetail(row) {
+  currentVisitor.value = row
+  detailVisible.value = true
+}
+
+// 初始化访客列表
+getVisitorList()
+</script>
+
+<style scoped>
+.el-descriptions {
+  margin: 20px;
+}
+</style>