民宿管理系统5

管理员管理:

新增管理员信息:

前端效果:

前端代码:

复制代码
<body>
<div class="layui-fluid">
    <div class="layui-row">
        <div class="layui-form">


                  <div class="layui-form-item">
                    <label for="loginname" class="layui-form-label">
                      <span class="x-red">*</span>登录名</label>
                    <div class="layui-input-inline">
                      <input type="text" id="loginname" name="loginname" lay-verify="required|loginname" class="layui-input">
                    </div>
                  </div>


            <div class="layui-form-item">
                <label for="L_loginpassword" class="layui-form-label">
                    <span class="x-red">*</span>设置登录密码</label>
                <div class="layui-input-inline">
                    <input type="password" id="L_loginpassword" name="loginpassword" lay-verify="required|loginpassword" class="layui-input">
                </div>
            </div>

            <div class="layui-form-item">
                <label for="L_confirmloginpassword" class="layui-form-label">
                    <span class="x-red">*</span>确认密码</label>
                <div class="layui-input-inline">
                    <input type="password" id="L_confirmloginpassword" name="confirmloginpassword" lay-verify="required|confirmloginpassword" class="layui-input">
                </div>
            </div>

            <div class="layui-form-item">
                <label class="layui-form-label"></label>
                <button class="layui-btn" lay-filter="submit" lay-submit="">保存</button>
            </div>


        </div>
    </div>
</div>

<script>
    layui.use(['form', 'layer', 'upload'], function () {
        $ = layui.jquery;
        var form = layui.form,
            upload = layui.upload,
            layer = layui.layer;

        //自定义验证规则
        form.verify({
            loginname: function (value) {
                var code;
                $.ajax({
                    url: "/admin/checkloginname",
                    type: "GET",
                    async: false,  //关闭异步,当success返回结果后才执行ajax之后的内容
                    data: {"loginname": value},
                    success: function (s) {
                        code = s;
                    }
                });
                if (code != true) {
                    return '登录名重复,请重新输入!';
                }
            },
            loginpassword: [/(.+){6,12}$/, '密码必须6到12位'],
            confirmloginpassword: function () {
              if ($('#L_confirmloginpassword').val() != $('#L_loginpassword').val()) {
                return '两次密码不一致';
              }
            }
        });

        //监听提交
        form.on('submit(submit)', function (data) {
            console.log(data.field);
            $.ajax({
                url: "/admin/addadmin",
                type: "post",
                data: data.field,
                success: function (s) {
                    if (s == true) {
                        layer.alert("新增管理员信息成功!", {
                            icon: 6
                        }, function () {
                            parent.layer.closeAll();
                            parent.location.href = "/admin/sysindex";

                        });
                    } else {
                        layer.msg("登录名重复!", function () {
                        });
                    }
                },
                error: function () {
                    layer.msg("接口异常!", function () {
                    });
                }
            });
        });
    });
</script>

</body>

后端代码:

AdminController:
复制代码
/**
     * 新增管理员页面
     */
    @GetMapping("/addadminpage")
    public String addadminpage() {
        return "admin/addadminpage";
    }

    /**
     * 新增管理员,判断新增管理员登录名是否重复
     */
    @GetMapping("/checkloginname")
    @ResponseBody
    public boolean checkaddadminloginname(@RequestParam("loginname") String loginname) {
        return adminService.checkaddadminloginname(loginname);
    }

    /**
     * 新增管理员信息
     */
    @PostMapping("/addadmin")
    @ResponseBody
    public boolean addadmin(@RequestParam("loginname") String loginname,@RequestParam("loginpassword") String loginpassword,@RequestParam("confirmloginpassword") String confirmloginpassword) {
         return adminService.addadmin(loginname,loginpassword);
    }
AdminService:
复制代码
/**
     * 新增管理员,判断新增管理员登录名是否重复
     */
    boolean checkaddadminloginname(String loginname);

    /**
     * 新增管理员
     */
    boolean addadmin(String loginname, String loginpassword);
AdminServicelpml:
复制代码
/**
     * 新增管理员,判断新增管理员登录名是否重复
     */
    @Override
    public boolean checkaddadminloginname(String loginname) {

        Admin admin = adminMapper.selectaddadminloginname(loginname);
        return admin==null;
    }

    /**
     * 新增管理员
     */
    @Override
    public boolean addadmin(String loginname, String loginpassword) {
        Admin admin=new Admin();
        admin.setGname(loginname);
        admin.setGpassword(loginpassword);

        Admin admin1=adminMapper.selectaddadminloginname(loginname);
        if(admin1==null)
        return adminMapper.addadmin(admin);
        else return false;
AdminMapper:
复制代码
/**
     * 新增管理员,判断新增管理员登录名是否重复
     */
    Admin selectaddadminloginname(@Param("loginname")String loginname);

    /**
     * 新增管理员
     */
    boolean addadmin(Admin admin);
AdminMapper.xml:
复制代码
 <select id="selectaddadminloginname" resultType="com.homestay.pojo.Admin">
    select gname from admin
    where gname=#{loginname}
  </select>



  <insert id="addadmin">
    insert into admin(gname,gpassword)
    values (#{gname,jdbcType=VARCHAR},#{gpassword,jdbcType=VARCHAR})
  </insert>

测试:

登录名重复:
必填项为空:
两次密码不一样:
新增成功:

管理员分页查询:

前端效果:

前端代码:

复制代码
<body>
<div class="layui-fluid">
    <div class="layui-row layui-col-space15">
        <div class="layui-col-md12">
            <div class="layui-card">
                <div class="layui-card-body ">
                    <form class="layui-form layui-col-space5">
                        <div class="layui-inline layui-show-xs-block">
                            <input type="text" name="dname" placeholder="管理员名称" autocomplete="off" class="layui-input">
                        </div>
                        <div class="layui-inline layui-show-xs-block">
                            <button class="layui-btn" lay-submit="" lay-filter="search_btn">
                                <i class="layui-icon">&#xe615;</i>
                            </button>
                        </div>
                        <a class="layui-btn layui-btn-small" style="line-height:1.6em;margin-top:3px;float:right" onclick="reload();" title="刷新">
                            <i class="layui-icon layui-icon-refresh" style="line-height:30px"></i>
                        </a>
                    </form>
                </div>
                <div class="layui-card-body ">
                    <table id="departmenList" lay-filter="departmenList"></table>
                </div>
            </div>
        </div>
    </div>
</div>

<script type="text/html" id="departmenListBar">
    <a class="layui-btn layui-btn-xs" lay-event="edit" >编辑</a>
<!--    <a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del">删除</a>-->
</script>

<script type="text/javascript" th:inline="javascript">
    layui.use(['form', 'layer', 'table'], function () {
        var form = layui.form,
            layer = layui.layer,
            $ = layui.jquery,
            table = layui.table;
        var tableIns = table.render({
            elem: '#departmenList',
            url: '/admin/pagequaryadmin',
            method: 'get',
            title: '管理员列表',
            page: true,  //开启分页
            height: "full-110",  //高度最大化减去差值110,高度将始终铺满
            // toolbar: true,  //开启工具栏
            limit:10,  //每页显示的条数
            limits: [5,10,20,30],  //每页条数的选择项
            cols:
                [
                    [
                    {type: 'checkbox', field: 'gid', fixed: "left"},
                    {field: 'gid', title: '管理员id', align: "center", unresize: "true"},
                    {field: 'gname', title: '管理员名称', align: 'center', unresize: "true"},
                        {
                            field: 'gpassword',
                            title: '管理员密码',
                            align: 'center',
                            unresize: true,
                            hide: true  // 关键设置:隐藏列
                        },
                    {title: '操作', align: "center", unresize: "true", toolbar: "#departmenListBar"}
                    ]
                ]
        });

        //搜索
        form.on('submit(search_btn)', function (data) {
            tableIns.reload({
                url: '/admin/listbyname',
                where: data.field
                , page: {
                    curr: 1 //重新从第 1 页开始
                }
            });
            return false;
        });

        //监听工具条
        table.on('tool(departmenList)', function (obj) {
            var data = obj.data, //获得当前行数据
                layEvent = obj.event; //获得 lay-event 对应的值(也可以是表头的 event 参数对应的值)

            switch (layEvent) {
                case 'del':
                    layer.confirm('确定删除此管理员?', {icon: 3, title: '提示信息'}, function (index) {
                        $.post("/admin/department/delete",
                            {
                                "gid": data.gid
                            }, function (s) {
                                layer.msg(s.msg);
                            });
                        layer.close(index);
                        tableIns.reload();
                    });
                    break;
                // case 'edit':
                //     xadmin.open('管理员编辑', '/admin/checkadminpasswordpage?gid=' + data.gid, 450, 300);
                //     break;
                case 'edit':
                    // 构建传递的参数
                    var params = {
                        gid: data.gid,
                        gname: data.gname,
                        gpassword: data.gpassword
                    };
                    // 将参数转换为查询字符串
                    var queryString = $.param(params);
                    // 打开弹窗
                    layer.open({
                        type: 2,
                        title: '管理员编辑',
                        area: ['450px', '300px'],
                        content: '/admin/checkadminpasswordpage?' + queryString
                    });
                    break;
                default:
                    break;
            }
        });
    });


    function reload() {
        $.get("/admin/reload", function (data) {
            if (data) {
                location.reload();
            } else {
                parent.location.reload();
            }
        });
    }
</script>
</body>

后端代码:

AdminController:
复制代码
/**
     * 编辑管理员页面
     */
    @GetMapping("/updateadminpage")
    public String updateadminnpage() {
        return "admin/updateadminpage";
    }
    /**
     * 管理员分页查询
     * @return
     */
    @GetMapping("/pagequaryadmin")
    @ResponseBody
    public Result pagequaryadmin(@RequestParam Map<String,Object> map) {
        int page = Integer.parseInt(map.get("page").toString());
        int limit = Integer.parseInt(map.get("limit").toString());
        int start=(page-1)*limit;
        return adminService.getadminList(start,limit);
    }
AdminService:
复制代码
/**
     * 管理员分页查询
     * @param start
     * @param limit
     * @return
     */

    Result getadminList(int start, int limit);
AdminServicelpml:
复制代码
/**
     * 管理员分页查询
     * @param start
     * @param limit
     * @return
     */
    @Override
    public Result getadminList(int start, int limit) {
        int totaladmin=adminMapper.getTotaladmin();//获取管理员总数
        List<Admin> adminList=adminMapper.findadminList(start, limit);//获取管理员数据
        Result result = new Result();
        result.setCode(0);
        result.setMsg("查询成功");
        result.setCount(totaladmin);
        result.setData(adminList);
        return result;
    }
AdminMapper:
复制代码
/**
     * 获取管理员总数
     * @return
     */
    int getTotaladmin();

    /**
     * 获取管理员数据
     * @param start
     * @param limit
     * @return
     */
    List<Admin> findadminList(@Param("start")int  start,@Param("limit") int limit);
AdminMappe.xml:
复制代码
 <select id="getTotaladmin" resultType="java.lang.Integer">
  select count(*) from admin
  </select>




  <select id="findadminList" resultType="com.homestay.pojo.Admin">
    select
        <include refid="Base_Column_List"></include>
        from admin
    order by gid
    limit #{start},#{limit}
  </select>

测试:

选择5页:
选择10页:

搜索框模糊查询:

后端代码:

AdminController:

复制代码
/**
     * 模糊查询
     * @param map
     * @return
     */
    @GetMapping("/listbyname")
    @ResponseBody
    public Result listbyname(@RequestParam Map<String,Object> map) {
        int page = Integer.parseInt(map.get("page").toString());
        int limit = Integer.parseInt(map.get("limit").toString());
        int start=(page-1)*limit;
        String dname=map.get("dname").toString();
        return adminService.listbyname(start,limit,dname);
    }

AdminService:

复制代码
/**
     * 模糊查询
     * @param start
     * @param limit
     * @param dname
     * @return
     */
    Result listbyname(int start, int limit, String dname);

AdminServicelpml:

复制代码
/**
     * 模糊查询
     * @param start
     * @param limit
     * @param dname
     * @return
     */
    @Override
    public Result listbyname(int start, int limit, String dname) {
        int totaladmin=adminMapper.getTotaladminbyname(dname);//获取管理员总数
        List<Admin> adminList=adminMapper.findadminListbyname(start, limit,dname);//获取管理员数据
        Result result = new Result();
        result.setCode(0);
        result.setMsg("查询成功");
        result.setCount(totaladmin);
        result.setData(adminList);
        return result;
    }

AdminMapper:

复制代码
 /**
     * 模糊查询获取总数
     * @param dname
     * @return
     */
    int getTotaladminbyname(@Param("dname") String dname);

    /**
     * 模糊查询
     * @param start
     * @param limit
     * @param dname
     * @return
     */
    List<Admin> findadminListbyname(@Param("start")int  start,@Param("limit") int limit, @Param("dname") String dname);

AdminMapper.xml:

复制代码
    <select id="getTotaladminbyname" resultType="java.lang.Integer">
      select count(*)
      from admin
      where gname like concat('%',#{dname},'%')
    </select>


  <select id="findadminListbyname" resultType="com.homestay.pojo.Admin">
    select <include refid="Base_Column_List"></include>
        from admin
    where gname like concat('%',#{dname},'%')
    order by gid
    limit #{start},#{limit}
  </select>

测试:

编辑、删除管理员:

需要输入该管理员密码才能进行编辑信息,包括删除该管理员

前端效果:

检查管理员密码:

密码正确后:

前端代码:

检查密码页面:

复制代码
<body>
<div class="layui-fluid">
    <div class="layui-row">
        <div class="layui-form">

            <div class="layui-form-item">
                <label for="gid" class="layui-form-label">
                    <span class="x-red">*</span>管理员id: </label>
                    <div class="layui-input-inline">
                        <input type="text" id="gid" name="gid"  class="layui-input" readonly="readonly" th:value="${session.gid}">
                    </div>

            </div>


            <div class="layui-form-item">
                <label for="adminpassword" class="layui-form-label">
                    <span class="x-red">*</span>输入管理员密码</label>
                <div class="layui-input-inline">
                    <input type="password" id="adminpassword" name="adminpassword" lay-verify="required" class="layui-input">
                </div>
            </div>

            <div class="layui-form-item">
                <label class="layui-form-label"></label>
                <button class="layui-btn" lay-filter="submit" lay-submit="">确定</button>

            </div>


        </div>
    </div>
</div>

<script>

    layui.use(['form', 'layer', 'jquery'], function () {
        var form = layui.form,
            layer = layui.layer,
            $ = layui.jquery;

        form.on('submit(submit)', function (data) {
            var loadingIndex = layer.load(1);

            $.ajax({
                url: "/admin/checkadminpassword",
                type: "POST",
                data: data.field,
                dataType: "json",
                success: function (response) {
                    layer.close(loadingIndex);

                    // 调试输出
                    console.log('验证响应:', response);

                    // 兼容两种响应格式
                    if ((response && response.success) || response === true) {
                        layer.msg("验证成功", {icon: 1, time: 1000}, function() {
                            // 解决方案1:直接使用top窗口的xadmin
                            top.xadmin.open('修改管理员', '/admin/updateadmin');

                            // 解决方案2:先关闭当前弹窗再打开新窗口
                            var index = parent.layer.getFrameIndex(window.name);
                            parent.layer.close(index);
                            setTimeout(function() {
                                top.xadmin.open('修改管理员', '/admin/updateadmin',300,300);
                            }, 300);
                        });
                    } else {
                        layer.msg(response.message || "密码错误");
                    }
                },
                error: function(xhr) {
                    layer.close(loadingIndex);
                    console.error('请求失败:', xhr.responseText);
                    layer.msg("请求失败: " + (xhr.responseJSON?.message || xhr.statusText));
                }
            });
            return false;
        });
    });
</script>

</body>

编辑页面:

复制代码
<body >
<div class="layui-fluid"  style="padding: 65px;">
    <div class="layui-row">
        <div class="layui-form">

            <div class="layui-form-item">
                <label for="gid" class="layui-form-label">
                    <span class="x-red">*</span>管理员id: </label>
                <div class="layui-input-inline">
                    <input type="text" id="gid" name="gid"  class="layui-input" readonly="readonly" th:value="${session.gid}">
                </div>
            </div>


            <div class="layui-form-item">
                <label for="newadminname" class="layui-form-label" >新登录名</label>
                <div class="layui-input-inline">
                    <input type="text" id="newadminname" name="newadminname" class="layui-input"  th:value="${session.adminname}">
                </div>
            </div>


            <div class="layui-form-item">
                <label for="L_newPwd" class="layui-form-label">
                    <span class="x-red">*</span>新密码</label>
                <div class="layui-input-inline">
                    <input type="password" id="L_newPwd" name="newgpassword" lay-verify="required|newgpassword" class="layui-input" th:value="${session.adminpassword}">
                </div>
                <div class="layui-form-mid layui-word-aux">6到16个字符</div>
            </div>

            <div class="layui-form-item">
                <label for="L_confirmPwd" class="layui-form-label">
                    <span class="x-red">*</span>确认密码</label>
                <div class="layui-input-inline">
                    <input type="password" id="L_confirmPwd" name="confirmPwd" lay-verify="required|confirmPwd" class="layui-input">
                </div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label"></label>
                <button class="layui-btn" lay-filter="submit" lay-submit="">保存</button>
                <a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del">删除管理员</a>
            </div>
        </div>
    </div>
</div>

<script>

    layui.use(['form', 'layer', 'upload'], function () {
        $ = layui.jquery;
        var form = layui.form,
            upload = layui.upload,
            layer = layui.layer;

        // 删除按钮点击事件
        $('.layui-btn-danger').on('click', function() {
            layer.confirm('确定删除此管理员?', {icon: 3, title: '提示信息'}, function (index) {
                $.post("/admin/delete",
                    {
                        "gid": $('#gid').val()
                    },
                    function (success) {  // 直接接收布尔值
                        if (success) {
                            layer.msg('删除成功', {icon: 1});
                            // 删除成功后刷新父窗口
                            setTimeout(function() {
                                xadmin.father_reload();
                            }, 1000);
                        } else {
                            layer.msg('删除失败', {icon: 2});
                        }
                    }
                );
                layer.close(index);
            });
            return false; // 阻止默认行为
        });


        //自定义验证规则
        form.verify({
            newgpassword: [/(.+){6,12}$/, '密码必须6到12位'],
            confirmPwd: function () {
                if ($('#L_newPwd').val() != $('#L_confirmPwd').val()) {
                    return '两次密码不一致';
                }
            }
        });

        //监听提交
        form.on('submit(submit)', function (data) {
            console.log(data.field);
            $.ajax({
                url: "/admin/updateadmininformation",
                type: "post",
                data: data.field,
                success: function (s) {
                    if (s == true) {
                        layer.alert("修改成功!", {
                            icon: 6
                        }, function () {
                            parent.layer.closeAll();
                        });
                    } else {
                        layer.msg("登录名重复,修改失败!", function () {
                        });
                    }
                },
                error: function () {
                    layer.msg("接口异常!", function () {
                    });
                }
            });
        });
    });
</script>
</body>

后端代码:

AdminController:

复制代码
/**
     * 编辑管理员,检查密码页面
     */
    @GetMapping("/checkadminpasswordpage")
    public String checkadminpasswordpage(@RequestParam("gid") String gid,@RequestParam("gname")String gname,
                                         @RequestParam("gpassword")String gpassword, HttpSession session) {
        session.setAttribute("gid",gid);
        session.setAttribute("adminname",gname);
        session.setAttribute("adminpassword",gpassword);
        return "admin/updatecheckadminpasswordpage";
    }
    /**
     * 检查密码
     */
    @PostMapping("/checkadminpassword")
    @ResponseBody
    public boolean checkadminpassword(@RequestParam("gid") String gid,@RequestParam("adminpassword") String adminpassword) {
        return adminService.checkadminpassword(gid,adminpassword);
    }

    /**
     * 跳转修改弹窗
     * @return
     */
    @GetMapping("/updateadmin")
    public String updateadmin() {
        return "admin/updateadmin";
    }

    /**
     * 修改管理员信息
     * @param gid
     * @param newgpassword
     * @param newadminname
     * @return
     */
    @PostMapping("/updateadmininformation")
    @ResponseBody
    public boolean updateadmininformation(@RequestParam("gid")String gid,@RequestParam("newgpassword")String newgpassword,
                                          @RequestParam("newadminname")String  newadminname ) {
        return adminService.updateadmininformation(gid,newgpassword,newadminname);

    }
    /**
     * 删除管理员
     */
    @PostMapping("/delete")
    @ResponseBody
    public boolean delete(@RequestParam("gid")String gid) {
        return adminService.deleteadmin(gid);
    }

    @GetMapping("/reload")
    @ResponseBody
    public boolean reload() {
        return true;
    }

AdminService:

复制代码
/**
     * 编辑管理员时,检查密码
     * @param gid
     * @param adminpassword
     * @return
     */
    boolean checkadminpassword(String gid, String adminpassword);

    /**
     * 修改管理员信息
     * @param gid
     * @param newgpassword
     * @param newadminname
     * @return
     */
    boolean updateadmininformation(String gid, String newgpassword, String newadminname);

    /**
     * 删除管理员
     * @param gid
     * @return
     */
    boolean deleteadmin(String gid);

AdminServicelpml:

复制代码
/**
     * 编辑管理员时,检查密码
     * @param gid
     * @param adminpassword
     * @return
     */
    @Override
    public boolean checkadminpassword(String gid, String adminpassword) {
        String gpassword=adminMapper.selectaddminpassword(gid);
        if(adminpassword.equals(gpassword))
            return true;
        else return false;
    }

    /**
     * 修改管理员信息
     * @param gid
     * @param newgpassword
     * @param newadminname
     * @return
     */
    @Override
    public boolean updateadmininformation(String gid, String newgpassword, String newadminname) {
        //检查登录名是否重复
        try {
            int count=adminMapper.countadminid(gid,newadminname);
            if(count>0)
            {
                throw  new RuntimeException("登录名重复");
            }

        }
        catch (RuntimeException e) {
            return false;
        }

        //没有重复修改信息
        adminMapper.updateadmininformation(gid,newadminname,newgpassword);
        return true;
}



/**
     * 删除管理员
     * @param gid
     * @return
     */
    @Override
    public boolean deleteadmin(String gid) {
        return adminMapper.deleteadmin(gid);
    }

AdminMapper:

复制代码
/**
     * 编辑管理员时,检查密码是否正确
     * @param gid
     * @return
     */
    String selectaddminpassword(String gid);


    /**
     * 检查登录名是否重复
     * @param gid
     * @param newadminname
     * @return
     */
    int countadminid(@Param("gid") String gid,@Param("newadminname") String newadminname);

    /**
     * 修改信息
     * @param gid
     * @param newadminname
     * @param newgpassword
     */
    void updateadmininformation(@Param("gid") String gid,@Param("newadminname") String newadminname,@Param("newgpassword") String newgpassword);

    /**
     * 删除管理员
     * @param gid
     * @return
     */
    boolean deleteadmin(String gid);

AdminMapper.xml:

复制代码
 <select id="selectaddminpassword" resultType="java.lang.String">
    select gpassword
    from admin
    where gid=#{gid}
  </select>
 <select id="countadminid" resultType="java.lang.Integer">
    select count(*)
    from admin
    where gid!=#{gid} and gname=#{newadminname}
  </select>
  <update id="updateadmininformation">
    update admin
    set
        gpassword=#{newgpassword},
        gname=#{newadminname}
    where gid=#{gid}
  </update>
 <delete id="deleteadmin">
    delete from admin
    where gid = #{gid,jdbcType=INTEGER}
  </delete>

测试:

检查密码错误:
正确后:

提示:

密码两次不一样
登录名重复:
删除:
相关推荐
武昌库里写JAVA21 分钟前
Java 设计模式
java·vue.js·spring boot·课程设计·宠物管理
钢铁男儿28 分钟前
Python 函数装饰器和闭包(闭包)
java·网络·python
Clf丶忆笙42 分钟前
从零开始搭建第一个Spring Boot应用:从入门到精通
java·spring boot
东坡大表哥1 小时前
【Android】Android签名解析
android·java
杨不易呀1 小时前
Java面试:微服务与大数据场景下的技术挑战
java·大数据·微服务·面试·技术栈
magic 2451 小时前
SpringMVC——第三章:获取请求数据
java·数据库·springmvc
别催小唐敲代码2 小时前
解决跨域的4种方法
java·服务器·前端·json
何似在人间5752 小时前
LangChain4j +DeepSeek大模型应用开发——7 项目实战 创建硅谷小鹿
java·人工智能·ai·大模型开发
magic 2452 小时前
深入理解 Spring MVC:DispatcherServlet 与视图解析机制
java·servlet·状态模式·springmvc