<%--
  Created by IntelliJ IDEA.
  User: user
  Date: 2020/2/18
  Time: 15:56
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!-- 声明该JSP页面的内容类型是HTML格式，字符编码采用UTF-8，表明页面中使用Java语言编写服务器端逻辑 -->

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"  %>
<!-- 引入JSTL（JavaServer Pages Standard Tag Library）的核心标签库，设置前缀为“c”，方便后续在JSP页面中使用其提供的各种标签进行逻辑判断、循环遍历等操作 -->

<html class="x-admin-sm">
<head>
    <!-- 设置页面的字符编码为UTF-8，确保页面在浏览器中能正确显示各种字符，避免出现乱码情况 -->
    <meta charset="UTF-8">
    <title></title>
    <!-- 设置页面渲染所使用的引擎为webkit，它能让页面在支持webkit的浏览器中以相应的渲染方式呈现，提供较好的页面展示效果 -->
    <meta name="renderer" content="webkit">
    <!-- 声明页面在IE浏览器中的兼容模式，使页面在IE浏览器中以其最高版本的模式进行渲染，若安装了Chrome Frame，则优先使用Chrome Frame来渲染，以增强兼容性和展示效果 -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

    <!-- 引入自定义的字体样式表，路径通过EL表达式结合pageContext对象获取项目相对路径，用于设置页面中文字的字体、字号、颜色等样式相关属性 -->
    <link rel="stylesheet" href="${pageContext.request.contextPath}/css/font.css">
    <!-- 引入自定义的xadmin样式表，通过EL表达式结合pageContext获取相对路径，用于构建页面整体的xadmin风格布局与样式，比如页面的整体色调、各组件的样式等 -->
    <link rel="stylesheet" href="${pageContext.request.contextPath}/css/xadmin.css">
    <!-- 引入Bootstrap框架的样式表，同样借助EL表达式结合pageContext获取路径，Bootstrap可以帮助快速搭建页面的响应式布局以及提供各种常用的UI组件样式 -->
    <link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.css">

    <!-- 引入jQuery库，其路径通过EL表达式结合pageContext获取项目相对路径，jQuery是一个常用的JavaScript库，方便在页面中操作DOM元素、处理事件、发起AJAX请求等 -->
    <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.1.1.js"></script>
    <!-- 引入layui框架的JavaScript文件，指定字符编码为utf-8，layui用于构建页面交互效果，提供了丰富的UI组件和交互功能，便于开发者打造具有良好用户体验的页面 -->
    <script src="${pageContext.request.contextPath}/lib/layui/layui.js" charset="utf-8"></script>
    <!-- 引入自定义的xadmin相关的JavaScript文件，通过EL表达式结合pageContext获取路径，这个文件可能包含了针对xadmin页面特有的交互逻辑和功能实现 -->
    <script type="text/javascript" src="${pageContext.request.contextPath}/js/xadmin.js"></script>
    <!-- 引入Bootstrap的JavaScript文件，通过EL表达式结合pageContext获取路径，用于实现Bootstrap框架相关的交互功能，例如一些组件的动态效果等 -->
    <script type="text/javascript" src="${pageContext.request.contextPath}/js/bootstrap.js"></script>
    <!-- 引入layer弹窗插件的JavaScript文件，通过EL表达式结合pageContext获取路径，layer插件常用于在页面中弹出提示框、确认框、加载层等交互效果，增强用户与页面的交互性 -->
    <script type="text/javascript" src="${pageContext.request.contextPath}/layer/layer.js"></script>

    <!--[if lt IE 9] -->
    <!-- 条件注释，针对IE浏览器版本小于9的情况，引入html5shiv库，其作用是让旧版本的IE浏览器能够支持HTML5的新标签，使得页面在这些旧浏览器中能正常解析HTML5相关的结构 -->
    <script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
    <!-- 引入respond.js库，用于让旧版本IE浏览器支持CSS3媒体查询，确保页面在不同设备尺寸下的样式适配能在旧IE浏览器中正常工作 -->
    <script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->

    <script>
        function changePageSize() {
            // 获取id为changePageSize的下拉框元素的值，这个值代表了用户期望设置的每页显示数据的条数，
            // 通过jQuery选择器$("#changePageSize")选中该下拉框元素，再使用.val()方法获取其当前选中的值
            var pageSize = $("#changePageSize").val();
            // 通过修改浏览器地址栏的URL向服务器发送请求，请求的路径是/visitor/findAll，传递参数page=1表示显示第一页，
            // size为获取到的下拉框的值，以此改变每页显示的条数，实现用户切换每页显示数据量的功能，
            // 这里利用了location.href属性来重定向页面到指定的URL
            location.href = "${pageContext.request.contextPath}/visitor/findAll?page=1&size="+ pageSize;
        }

        $("#serarch_btn").click(function () {
            // 获取id为keyword的输入框元素的值，通常这个值是用户输入的用于搜索的关键词，例如访客姓名、学号等，
            // 通过jQuery选择器$("#keyword")选中该输入框元素，再使用.val()方法获取其当前输入的值
            var keyword = $("#keyword").val();
            // 通过修改浏览器地址栏的URL向服务器发送请求，请求的路径是/visitor/findAll，传递参数page=1表示显示第一页，
            // size=5表示每页显示5条记录，keyword为获取到的搜索关键词，用于根据用户输入的关键词进行搜索并展示相应的访客信息，
            // 同样利用location.href属性来重定向页面到指定的带有搜索参数的URL
            location.href="${pageContext.request.contextPath}/visitor/findAll?page=1&size=5&keyword="+keyword;
        });

        $("#refresh").click(function () {
            // 尝试重置id为myform的表单元素（此处重置方式可能不准确，更准确的写法可能是$("#myform")[0].reset(); ），目的是将表单内的输入框等元素的值重置为初始状态，
            // 例如清空用户输入的搜索关键词等内容，不过当前写法依赖于具体的表单库是否支持这样直接调用reset方法，可能存在兼容性问题
            $("#myform").reset();
            // 通过修改浏览器地址栏的URL向服务器发送请求，请求的路径是/visitor/findAll，传递参数page=1表示显示第一页，
            // size=5表示每页显示5条记录，达到刷新页面数据的效果，即将页面恢复到初始的显示状态，展示第一页且每页显示5条记录的数据情况，
            // 借助location.href属性来实现页面重定向到相应的URL
            location.href="${pageContext.request.contextPath}/visitor/findAll?page=1&size=5";
        });
    </script>
</head>
<body>
<%-- 以下这部分代码被注释掉了，原本可能是用于展示页面导航相关元素，包含面包屑导航以及一个刷新按钮，点击按钮可刷新页面，但当前处于注释状态，不会在页面中显示生效 --%>
<%--<div class="x-nav">
      <span class="layui-breadcrumb">
        <a href="">首页</a>
        <a href="">演示</a>
        <a>
          <cite>导航元素</cite></a>
      </span>
<a class="layui-btn layui-btn-small" style="line-height:1.6em;margin-top:3px;float:right" onclick="location.reload()" title="刷新">
    <i class="layui-icon layui-icon-refresh" style="line-height:30px"></i></a>
</div>--%>

<!-- 使用layui-fluid类创建一个流体布局容器，使得内部的元素可以根据页面宽度自适应排列，常用于实现响应式布局 -->
<div class="layui-fluid">
    <!-- 创建一个layui的行元素，layui-col-space15表示设置列间距为15像素，用于对内部的列元素进行布局管理 -->
    <div class="layui-row layui-col-space15">
        <!-- 创建一个占12列的layui列元素，在layui的栅格系统中，一行默认分为12列，这里表示占满一整行 -->
        <div class="layui-col-md12">
            <!-- 创建一个layui卡片组件，用于将内部的内容以卡片的形式展示，通常有边框、阴影等样式效果，使页面结构更清晰美观 -->
            <div class="layui-card">
                <!-- 创建卡片的主体内容区域，用于放置表单相关元素 -->
                <div class="layui-card-body ">
                    <!-- 创建一个id为myform的表单，应用layui的表单样式类layui-form，并且设置列间距为5像素，用于布局表单内的各个元素 -->
                    <form id="myform" class="layui-form layui-col-space5">
                        <!-- 创建一个行内块元素，layui-show-xs-block表示在小屏幕（如手机端）下显示该元素，方便在不同屏幕尺寸下进行布局控制 -->
                        <div class="layui-inline layui-show-xs-block">
                            <!-- 创建一个文本输入框，设置自动补全关闭（autocomplete="off"），添加提示占位文本“请输入关键字”，指定name和id属性，
                            并且其值通过EL表达式从请求参数中获取名为keyword的值（如果有的话），方便实现根据用户输入的关键字进行搜索功能 -->
                            <input class="layui-input" type="text" autocomplete="off" placeholder="请输入关键字" name="keyword" id="keyword" value="${param.keyword}">
                        </div>
                        <!-- 创建一个按钮，应用layui的按钮样式类layui-btn，指定id为serarch_btn（此处可能有拼写错误，正确应为search_btn），
                        并设置了layui表单相关的提交和过滤属性（lay-submit和lay-filter），按钮内包含一个layui图标，点击该按钮可能触发表单提交或者搜索操作 -->
                        <div class="layui-inline layui-show-xs-block">
                            <button class="layui-btn"  id="serarch_btn" lay-submit="" lay-filter="sreach"><i class="layui-icon">&#xe615;</i></button>
                        </div>
                        <!-- 创建一个链接样式的按钮，应用layui的正常样式类layui-btn-normal，点击后跳转到指定路径（路径通过EL表达式结合pageContext生成，
                        用于获取所有访客信息并设置每页显示5条数据），按钮内包含一个layui图标，可能用于实现回到第一页且每页显示固定条数数据的功能，通常作为重置按钮的一种体现 -->
                        <div class="layui-inline layui-show-xs-block x-right">
                            <a class="layui-btn layui-btn-normal" href="${pageContext.request.contextPath}/visitor/findAll?page=1&size=5"><i class="layui-icon">&#xe669;</i></a>
                        </div>
                    </form>
                </div>
                <!-- 自定义的<xblock>标签，具体功能可能由相关的CSS或JavaScript根据业务逻辑来定义，在这里用于包裹导出按钮和总数据条数显示相关的元素 -->
                <xblock>
                    <!-- 创建一个链接样式按钮，点击时调用exportInfo函数并传入管理员权限值（从会话中获取），按钮显示为“导出”，包含一个layui图标，用于触发导出访客数据的相关操作 -->
                    <a onclick="exportInfo(${sessionScope.adminInfo.power})" class="layui-btn layui-btn-warm" href="javascript:;"><i class="layui-icon">&#xe67c;</i>导出</a>
                    <!-- 显示总的访客数据条数信息，设置了行高为40px的样式，靠右对齐（通过x-right类实现），用于向用户展示当前访客数据的总量情况 -->
                    <span class="x-right" style="line-height:40px">共有数据：${pageInfo.total} 条</span>
                </xblock>
                <!-- 创建另一个卡片主体内容区域，可能用于展示不同部分的内容，这里用于放置访客信息表格 -->
                <div class="layui-card-body">
                    <!-- 创建一个使用layui样式的表格，同时应用layui的表单样式，方便后续可能的表单相关交互操作（比如行内编辑等） -->
                    <table class="layui-table layui-form">
                        <thead>
                        <tr style="text-align: center">
                            <!-- 创建表格的表头行，设置文本居中显示 -->
                            <th style="text-align: center">ID</th>
                            <th style="text-align: center">姓名</th>
                            <th style="text-align: center">学号</th>
                            <th style="text-align: center">联系方式</th>
                            <th style="text-align: center">访问地址</th>
                            <th style="text-align: center">来访时间</th>
                            <th style="text-align: center">离开时间</th>
                            <th style="text-align: center">到访原因</th>
                            <!-- 通过JSTL的条件判断，如果管理员权限大于2，则显示操作列，用于放置针对访客记录的操作按钮（比如删除、修改等操作） -->
                            <c:if test="${sessionScope.adminInfo.power > 2}">
                                <th style="text-align: center">操作</th>
                            </c:if>
                        </tr>
                        </thead>
                        <tbody>
                        <%
                            // 在JSP脚本片段中定义一个局部变量j并初始化为1，用于给表格中的数据行编号，混合使用了JSP脚本片段和JSTL标签库来构建表格数据展示
                            int j = 1;
                        %>
                        <!-- 使用JSTL的forEach标签循环遍历pageInfo.list中的数据（通常是分页后的访客列表集合），每次循环将当前元素赋值给visitor变量，方便在表格中展示各个访客的详细信息 -->
                        <c:forEach items="${pageInfo.list}" var="visitor">
                        <tr id="light" style="text-align: center">
                            <!-- 在表格行数据中，第一列显示行号，通过JSP脚本片段输出变量j的值，并在每次循环后自增1，实现逐行编号的效果 -->
                            <td><%=j++%></td>
                            <!-- 通过EL表达式从名为visitor的对象中获取姓名属性值，展示访客的姓名信息 -->
                            <td>${visitor.name}</td>
                            <!-- 通过EL表达式从名为visitor的对象中获取学号属性值，展示访客的学号信息 -->
                            <td>${visitor.sno}</td>
                            <!-- 通过EL表达式从名为visitor的对象中获取联系方式属性值，展示访客的联系方式信息 -->
                            <td>${visitor.place}</td>
                            <!-- 通过EL表达式从名为visitor的对象中获取来访时间属性值，展示访客的来访时间信息 -->
                            <td>${visitor.begin_date}</td>
                            <!-- 通过JSTL的条件判断访客的离开时间是否为空，如果为空则显示“尚未离开”，用于提示访客当前是否还在访问中 -->
                            <c:if test="${visitor.end_date == null || visitor.end_date == ''}">
                                <td>尚未离开</td>
                            </c:if>
                            <!-- 如果离开时间不为空，则通过EL表达式获取并显示具体的离开时间 -->
                            <c:if test="${visitor.end_date!= ''}">
                                <td>${visitor.end_date}</td>
                            </c:if>
                            <td>${visitor.visit_result}</td>
                            <!-- 通过JSTL的条件判断，如果管理员权限大于2，则显示操作列中的具体操作按钮，这里定义一个链接，点击时调用toUpdate函数并传入访客的id，
                            按钮显示为一个图标，提示文本为“注销访客”，用于触发注销访客记录的相关操作 -->
                            <c:if test="${sessionScope.adminInfo.power > 2}">
                                <td class="td-manage">
                                    <a title="注销访客" onclick="toUpdate('${visitor.id}');"  href="javascript:;">
                                        <i class="layui-icon">&#xe642;</i>
                                    </a>
                                </td>
                            </c:if>
                            </c:forEach>
                        </tr>
                        </tbody>
                    </table>
                </div>
                <!-- 设置该元素向左浮动，常用于布局排版，使其在页面中向左对齐排列 -->
                <div class="pull-left">
                    <!-- 创建一个表单组，设置为行内表单样式，方便在一行内展示多个表单相关元素 -->
                    <div class="form-group form-inline">
                        <!-- 显示分页相关信息，如总页数、当前页码等，告知用户当前的分页情况 -->
                        共&nbsp;${pageInfo.pages}&nbsp;页&emsp;当前页：${pageInfo.pageNum}&nbsp;/&nbsp;${pageInfo.pages}&emsp; 每页
                        <!-- 创建一个下拉菜单，应用表单控件的样式类form-control，绑定了id为changePageSize，当下拉框选项改变时会调用changePageSize函数来改变每页显示条数 -->
                        <select class="form-control" id="changePageSize" onchange="changePageSize()">
                            <!-- 为下拉菜单添加各个选项，每个<option>标签代表一个可选择的每页显示条数的值，
                            初始显示的值通过EL表达式从pageInfo对象中获取相关属性值，用户可选择不同的选项来改变每页显示的数据量 -->
                            <option value="1">${pageInfo.size}</option>
                            <option value="5">5</option>
                            <option value="10">10</option>
                            // 这是一个下拉菜单中的选项（<option>）标签，表示当用户选择该项时，
                            // 对应的值为10，意味着每页显示10条数据，用于设置每页显示数据量的可选项之一

                            <option value="15">15</option>
                            // 同样是下拉菜单中的选项标签，选择该项则表示每页显示15条数据，是提供给用户选择每页数据条数的一个选项

                            <option value="20">20</option>
                            // 下拉菜单中的选项标签，若用户选择此项，每页将显示20条数据，作为可配置每页显示数量的一个选项

                        </select> 条
                            <!-- 结束下拉菜单标签，“条”字可能是用于在页面上更友好地提示用户该下拉菜单是用于选择每页显示数据的条数 -->
                    </div>
                    // 结束一个外层的div容器，这个div可能用于布局，包裹与每页显示条数选择相关的元素等

                </div>
                // 结束另一个外层的div容器，可能在页面布局层级中处于更上层，具体作用需结合整体页面结构来看

                <!-- 分页按钮逻辑控制 -->
                // 这是一个HTML注释，用于说明下面的代码块主要是用于控制分页按钮的显示逻辑，方便后续阅读和维护代码

                <c:choose>
                    // 使用JSTL（JavaServer Pages Standard Tag Library）的标签，开始一个条件选择结构，
                    // 类似于Java中的switch语句，用于根据不同条件执行不同的逻辑分支

                    <c:when test="${pageInfo.pages < 5}">
                    // 标签表示一个具体的条件分支，这里的条件是判断pageInfo对象中的pages属性（通常表示总页数）是否小于5，
                        // 如果满足该条件，则执行此分支内的代码

                        <c:set var="begin" value="1">
                        // 使用标签在JSP页面中设置一个名为“begin”的变量，值设置为1，
                            // 这个变量可能后续用于确定分页页码显示的起始范围等相关逻辑

                        </c:set>
                        <c:set var="end" value="${pageInfo.pages}">
                        // 同样使用标签设置一个名为“end”的变量，其值设置为pageInfo对象中的pages属性值（即总页数），
                            // 用于配合“begin”变量来确定分页页码显示的范围

                        </c:set>
                    </c:when>
                    <c:when test="${pageInfo.pageNum <= 3}">
                    // 另一个条件分支，判断pageInfo对象中的pageNum属性（通常表示当前页码）是否小于等于3，
                        // 如果满足该条件，则执行此分支内的代码，用于设置不同情况下分页页码显示的范围

                        <c:set var="begin" value="1">
                            // 设置名为“begin”的变量值为1，为后续确定分页页码显示范围做准备

                        </c:set>
                        <c:set var="end" value="5">
                            // 设置名为“end”的变量值为5，结合“begin”变量来确定在当前页码小于等于3这种情况下分页页码显示的范围

                        </c:set>
                    </c:when>
                    <c:when test="${pageInfo.pageNum > 3 and pageInfo.pageNum <= pageInfo.pages - 2}">
                    // 又一个条件分支，判断当前页码（pageInfo.pageNum）大于3并且小于等于总页数减2时执行此分支内的代码，
                        // 用于根据当前页码在特定区间时设置分页页码显示的范围

                        <c:set var="begin" value="${pageInfo.pageNum - 2}">
                            // 根据当前页码动态计算“begin”变量的值，将其设置为当前页码减2，以此来确定合适的分页页码显示起始范围

                        </c:set>
                        <c:set var="end" value="${pageInfo.pageNum + 2}">
                            // 根据当前页码动态计算“end”变量的值，设置为当前页码加2，与“begin”变量配合确定分页页码显示的范围

                        </c:set>
                    </c:when>
                    <c:otherwise>
                    // otherwise标签表示当上述所有条件都不满足时执行的代码分支，相当于Java中switch语句的default分支

                        <c:set var="begin" value="${pageInfo.pages - 4}">
                            // 设置名为“begin”的变量值为总页数减4，用于确定在其他情况之外的分页页码显示起始范围

                        </c:set>
                        <c:set var="end" value="${pageInfo.pages}">
                            // 设置名为“end”的变量值为总页数，与“begin”变量配合确定分页页码显示的范围

                        </c:set>
                    </c:otherwise>
                </c:choose>
    <div class="layui-card-body x-right" style="height: min-content">
    // 创建一个使用layui样式的卡片主体内容区域（layui-card-body），并应用了x-right类（可能用于控制布局靠右显示等），
    // 设置了高度样式为min-content，使该区域的高度根据其内部内容自适应，最小化高度占用

    <div class="page">
    // 创建一个自定义类名为“page”的<div>容器，可能用于专门放置分页相关的按钮等元素，进行布局分组

    <div>
    // 再创建一个内层的<div>容器，用于进一步细化分页按钮等元素的布局

    <a class="next" href="${pageContext.request.contextPath}/visitor/findAll?page=1&size=${pageInfo.pageSize}&keyword=${param.keyword}">首页</a>
    // 创建一个链接，应用了名为“next”的类（可能有对应的CSS样式用于外观控制），
    // href属性通过EL表达式拼接出具体的URL路径，用于跳转到访客信息列表的第一页，同时传递了每页显示条数（pageInfo.pageSize）和搜索关键词（param.keyword）等参数，
    // 链接显示的文本为“首页”，方便用户点击回到第一页

    <c:if test="${pageInfo.pageNum > 1}">
        // 使用JSTL的条件判断标签，判断pageInfo对象中的pageNum属性（当前页码）是否大于1，
        // 如果满足该条件，则执行此标签内包含的代码，用于判断是否显示上一页按钮

        <a class="prev" href="${pageContext.request.contextPath}/visitor/findAll?page=${pageInfo.pageNum - 1}&size=${pageInfo.pageSize}&keyword=${param.keyword}">上一页</a>
        // 创建一个链接，应用“prev”类（可能对应特定样式），href属性通过EL表达式拼接出URL路径，
        // 用于跳转到上一页（当前页码减1），同时传递每页显示条数和搜索关键词等参数，链接显示文本为“上一页”，方便用户进行翻页操作

    </c:if>
        <c:forEach var="i" begin="${begin}" end="${end}" step="1">
            // 使用JSTL的forEach循环标签，开始一个循环，循环变量为“i”，循环的起始值为之前设置的“begin”变量的值，
            // 结束值为“end”变量的值，步长为1，即依次遍历从“begin”到“end”范围的每一个值，用于生成分页页码链接

            <c:if test="${pageInfo.pageNum == i}">
            // 在循环内部，再次使用条件判断标签，判断当前页码（pageInfo.pageNum）是否等于循环变量“i”的值，
                // 如果相等，则执行此标签内的代码，用于对当前页码进行特殊样式显示等处理

                <span class="current">${i}</span>
                // 创建一个span标签，应用了“current”类（可能有对应的突出显示当前页码的样式），并通过EL表达式显示循环变量“i”的值，
                // 用于将当前页码以特定样式展示出来，与其他页码区分开

            </c:if>
            <c:if test="${pageInfo.pageNum!= i}">
            // 另一个条件判断标签，判断当前页码是否不等于循环变量“i”的值，如果不相等，则执行此标签内的代码，
                // 用于生成普通的页码链接（非当前页码的情况）

                <a class="num" href="${pageContext.request.contextPath}/visitor/findAll?page=${i}&size=${pageInfo.pageSize}&keyword=${param.keyword}">${i}</a>
                // 创建一个链接，应用“num”类（可能对应普通页码链接的样式），href属性通过EL表达式拼接出URL路径，
                // 用于跳转到对应页码（循环变量“i”表示的页码），同时传递每页显示条数和搜索关键词等参数，链接内通过EL表达式显示循环变量“i”的值作为页码显示内容，方便用户点击跳转到相应页码

            </c:if>
        </c:forEach>
            <!-- 下一页链接，当不是最后一页时显示 -->
            // 这是一个HTML注释，说明下面的代码是用于在不是最后一页的情况下显示下一页的链接

            <c:if test="${pageInfo.pageNum < pageInfo.pages}">
                // 使用JSTL的条件判断标签，判断当前页码（pageInfo.pageNum）是否小于总页数（pageInfo.pages），
                // 如果满足该条件，则执行此标签内的代码，用于判断是否显示下一页链接

                <a class="next" href="${pageContext.request.contextPath}/visitor/findAll?page=${pageInfo.pageNum + 1}&size=${pageInfo.pageSize}&keyword=${param.keyword}">下一页</a>
                // 创建一个链接（<a>标签），应用“next”类，href属性通过EL表达式拼接出URL路径，用于跳转到下一页（当前页码加1），
                // 同时传递每页显示条数和搜索关键词等参数，链接显示文本为“下一页”，方便用户进行翻页操作

            </c:if>
                <!-- 尾页链接 -->
                // 这是一个HTML注释，说明下面的代码是用于显示尾页的链接

                <a class="next" href="${pageContext.request.contextPath}/visitor/findAll?page=${pageInfo.pages}&size=${pageInfo.pageSize}&keyword=${param.keyword}">尾页</a>
                // 创建一个链接，应用“next”类，href属性通过EL表达式拼接出URL路径，用于跳转到最后一页（总页数对应的页码），
                // 同时传递每页显示条数和搜索关键词等参数，链接显示文本为“尾页”，方便用户直接跳转到最后一页

                </div>
                // 结束内层的<div>容器，该容器用于放置分页相关的各个链接按钮等元素

                </div>
                // 结束类名为“page”的<div>容器，其整体用于对分页相关元素进行布局分组

                </div>
                // 结束应用了layui样式和特定布局类（x-right等）的卡片主体内容区域的<div>容器

                </div>
                // 结束外层的一个<div>容器，其在页面布局层级中有相应的位置和作用（结合整体结构确定）

                </div>
                // 结束另一个外层的<div>容器，同样在页面布局中处于一定层级，与整体页面结构相关

                </div>
                // 结束可能是更外层的一个<div>容器，是页面布局中的一部分

                </div>
                // 结束最外层的一个div容器，完成整个页面主体部分的布局结构

                </div>
                // 结束包含页面主体流体布局（layui-fluid）的div容器，该容器实现了页面的整体流体布局效果

                </div>
                // 结束包含页面主体行布局（layui-row）的div容器，该行布局内设置了列间距等用于管理列元素的布局

                </div>
                // 结束包含页面主体列布局（layui-col-md12）的div容器，该列布局占满中等屏幕及以上尺寸下的一行

                </div>
                // 结束layui卡片（layui-card）组件的div容器，卡片组件用于以卡片形式展示内部内容，使页面结构更清晰美观

                </body>
                // 结束HTML页面的body部分，body内包含了页面实际展示的所有内容元素

                <script>
                // 开始JavaScript代码块，用于定义在页面中可执行的客户端脚本逻辑
                //导出Excel操作
                // 这是一个JavaScript函数的注释，说明下面定义的函数主要用于处理导出Excel相关的操作

function exportInfo(power) {
// 定义一个名为exportInfo的JavaScript函数，接收一个名为power的参数，该参数可能用于表示用户权限等相关信息，
// 用于在函数内部根据权限判断是否允许执行导出操作

// 检查当前用户的权限等级，如果权限小于3，则没有导出权限
    if (power < 3) {
        // 使用if条件语句判断传入的权限值（power）是否小于3，如果小于3则表示用户没有导出权限，执行下面的代码块

        // 使用layer插件显示提示信息，告知用户没有权限
        layer.msg('对不起，您没有权限导出访客记录');
        // 调用layer插件提供的msg方法，弹出一个提示框，显示“对不起，您没有权限导出访客记录”的提示信息，告知用户当前操作权限不足

        return false;
        // 函数执行到此处直接返回false，表示导出操作不被允许，终止函数后续的执行

    }
    // 弹出确认框询问用户是否确定要导出所有访客数据
    layer.confirm('确定导出所有访客数据吗？',function (index) {
        // 调用layer插件提供的confirm方法，弹出一个确认框，显示“确定导出所有访客数据吗？”的提示信息，
        // 同时传入一个回调函数，当用户点击确认框上的按钮时会执行该回调函数，回调函数接收一个参数index，用于后续操作确认框（如关闭等）

        // 当用户点击确定时，重定向到导出访客信息的URL
        location.href="${pageContext.request.contextPath}/visitor/visitorInfo";
        // 当用户在确认框中点击确定按钮后，通过修改浏览器的location.href属性，重定向到指定的URL路径，
        // 该路径通过EL表达式拼接出用于导出访客信息的具体地址，触发实际的导出操作（具体由服务器端逻辑处理）

        layer.close(index); // 关闭确认框
        // 调用layer插件提供的close方法，传入之前接收的index参数，用于关闭弹出的确认框，完成导出操作相关的交互流程

    });
}

// 注销访客记录
// 这是一个JavaScript函数的注释，说明下面定义的函数主要用于处理注销访客记录相关的操作
function toUpdate(id) {
// 定义一个名为toUpdate的JavaScript函数，接收一个名为id的参数，该参数通常用于表示要注销的访客记录的唯一标识，
// 用于在函数内部向服务器发送请求来更新对应访客记录的状态

    // 使用layer组件的confirm方法弹出确认框，询问用户是否确定要注销此访客记录
    layer.confirm('确定要注销此访客记录吗',function (index) {
        // 调用layer插件提供的confirm方法，弹出一个确认框，显示“确定要注销此访客记录吗”的提示信息，
        // 同时传入一个回调函数，当用户点击确认框上的按钮时会执行该回调函数，回调函数接收一个参数index，用于后续操作确认框（如关闭等）

        // 用户点击确定后关闭确认框
        layer.close(index);
        // 当用户在确认框中点击确定按钮后，调用layer插件提供的close方法，传入之前接收的index参数，关闭弹出的确认框

         // 发送异步请求到服务器端更新访客状态
        $.get("${pageContext.request.contextPath}/visitor/updateStatus",{"id":id},function (data) {
            // 使用jQuery库提供的$.get方法发送一个GET类型的异步请求，请求的URL地址通过EL表达式拼接出，指向用于更新访客状态的服务器端接口（/visitor/updateStatus），
            // 同时传递一个名为“id”的参数，其值为传入函数的id参数，表示要更新状态的访客记录的标识，
            // 并传入一个回调函数，当服务器端返回响应数据后会执行该回调函数，回调函数接收一个参数data，代表服务器返回的数据
            // 根据服务器返回的数据判断操作是否成功
            if (data) {
                // 使用if条件语句判断服务器返回的数据（data）是否为真值（具体真值的判断依据由服务器端返回的数据格式和逻辑决定），
                // 如果为真值，则表示更新操作成功，执行下面的代码块
                // 成功时显示成功消息，并在2秒后刷新页面
                layer.msg('注销成功');
                // 调用layer插件提供的msg方法，弹出一个提示框，显示“注销成功”的提示信息，告知用户操作已成功

                setTimeout(function () {window.location.href='${pageContext.request.contextPath}/visitor/findAll';},2000);
                // 使用JavaScript的setTimeout函数设置一个定时器，在2000毫秒（2秒）后执行传入的回调函数，
                // 回调函数内通过修改浏览器的window.location.href属性，重定向到指定的URL路径（/visitor/findAll），实现刷新页面的效果，
                // 重新加载访客信息列表页面，展示更新后的访客数据情况

            }else {
                // 如果服务器返回的数据为假值（不符合成功的判断条件），则表示更新操作失败，执行下面的代码块

                // 失败时显示错误消息，并在2秒后刷新页面
                layer.msg('系统繁忙，请联系系统管理员');
                // 调用layer插件提供的msg方法，弹出一个提示框，显示“系统繁忙，请联系系统管理员”的提示信息，告知用户操作失败及相应的解决建议

                setTimeout(function () {window.location.href='${pageContext.request.contextPath}/visitor/findAll';},2000);
                // 同样使用setTimeout函数设置定时器，在2秒后重定向到访客信息列表页面（/visitor/findAll），刷新页面，
                // 以便用户可以查看操作失败后的当前访客数据情况，或者再次尝试操作
            }
        });
    });
}
</script>
</body>
</html>
