众筹项目之后台管理系统-管理员维护(五)

目录

1. 分页显示管理员信息部分

1.1 目标

以分页的形式把管理员信息显示到页面上。特殊需求:兼顾关键词查询,让后端代
码不管有没有查询条件都能够以分页形式显示数据。

1.2 思路

1.2.1 流程图

在这里插入图片描述

1.2.2 技术点

让 SQL 语句针对 keyword 时有时无的情况进行适配
使用 SQL 中做字符串连接的函数:CONCAT("%",#{keyword},"%")

keyword 有值:“like %tom%”
keyword 无值:“like %%”
PageHelper 使用
引入依赖
在 SqlSessionFactoryBean 中配置 PageHelper
在 Java 代码中使用
PageHelper.startPage(pageNum, pageSize)
PageInfo pageInfo = new PageInfo(adminList );
显示页码
使用 jQuery 插件:Pagination

1.3 后端代码

1.3.1 查询 Admin 数据的 SQL 语句

在这里插入图片描述
在这里插入图片描述

  <select id="selectAdminByKeyword" resultMap="BaseResultMap">
   select id, login_acct, user_pswd, user_name, email, create_time
   from  t_admin
   where
    login_acct like concat("%",#{keyword},"%") or
    user_name like concat("%",#{keyword},"%") or
    email like concat("%",#{keyword},"%")
  </select>

1.3.2 AdminMapper 中的抽象方法

在这里插入图片描述
在这里插入图片描述

1.3.3 准备 PageHelper 环境

加入依赖
在这里插入图片描述

 <!-- MyBatis 分页插件 -->
    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper</artifactId>
        <version>4.0.0</version>
    </dependency>

配置 SqlSessionFactoryBean
在这里插入图片描述

<!-- 配置SqlSessionFactoryBean整合MyBatis-->
        <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
            <!-- 指定MyBatis全局配置文件位置-->
            <property name="configLocation" value="classpath:mybatis-config.xml"/>

            <!-- 指定Mapper.xml配置文件位置-->
            <property name="mapperLocations" value="classpath:mybatis/mapper/*Mapper.xml"/>

            <!-- 配置数据源-->
            <property name="dataSource" ref="dataSource"/>

            <!-- 配置插件 -->
            <property name="plugins">
                <array>
                    <!-- 配置PageHelper插件-->
                    <bean class="com.github.pagehelper.PageHelper">
                        <property name="properties">
                            <props>
                                <!-- 配置数据库方言,告诉PageHelper当前使用的数据库-->
                                <prop key="dialect">mysql</prop>

                                <!-- 配置页码的合理化修正,1~总页码之间修正页码 -->
                                <prop key="reasonable">true</prop>
                            </props>
                        </property>
                    </bean>
                </array>
            </property>
        </bean>

1.3.4 AdminService 方法

在这里插入图片描述

 @Override
    public PageInfo<Admin> getPageInfo(String keyword, Integer pageNum, Integer pageSize) {

        // 1.调用PageHelper的静态方法开启分页功能
        // 这里充分体现了PageHelper的"非侵入式"设计:原本要做的查询不必有任何修改
        PageHelper.startPage(pageNum, pageSize);

        // 2.执行查询
        List<Admin> list = adminMapper.selectAdminByKeyword(keyword);

        // ※辅助代码:打印 adminList 的全类名
        Logger logger = LoggerFactory.getLogger(AdminServiceImpl.class);

        logger.debug("adminList 的全类名是:"+ list.getClass().getName());
        
        // 3.为了方便页面使用将 adminList 封装为 PageInfo
        PageInfo<Admin> pageInfo = new PageInfo<>(list);

        // 3.封装到PageInfo对象中
        return new PageInfo<>(list);
    }

1.3.5 AdminHandler 方法

 @RequestMapping("/admin/get/page.html")
    public String getPageInfo(
            // 使用@RequestParam注解的defaltValue属性,指定默认值,在请求中没有携带对应参数时使用默认值
            // keyword默认值使用空字符串, 和SQL语句配合实现两种情况适配
            @RequestParam(value = "keyword", defaultValue = "") String keyword,

            // pageNum默认值使用1
            @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
            // pageSize默认值使用5
            @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
            ModelMap modelMap
    ){
        
        // 调用Service方法获取PageInfo对象
        PageInfo<Admin> pageInfo = adminService.getPageInfo(keyword, pageNum, pageSize);

        //将PageInfo对象存入模型
        modelMap.addAttribute(CrowdConstant.ATTR_NAME_PAGE_INFO, pageInfo);
        return "admin-page";
    }

1.4 前端代码

1.4.1 抽取页面公共部分

head 标签部分
<%@ include file="/WEB-INF/include-header.jsp" %>
nav 标签部分
<%@ include file="/WEB-INF/include-nav.jsp" %>
sidebar 部分
<%@ include file="/WEB-INF/include-sidebar.jsp" %>

1.4.2 创建 JSP 模板

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<!DOCTYPE html>
<html lang="zh-CN">
<%@include file="/WEB-INF/include-head.jsp" %>
<body>
<%@include file="/WEB-INF/include-nav.jsp" %>
<div class="container-fluid">
    <div class="row">
        <%@include file="/WEB-INF/include-sidebar.jsp" %>
        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">


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

</body>
</html>

1.4.3 准备 admin-page.jsp

在这里插入图片描述

1.4.4 在 admin-page 页面显示真实数据

加入 JSTL 依赖
在这里插入图片描述

<tbody>
                            <c:if test="${empty requestScope.pageInfo.list}">
                                <tr>
                                    <td colspan="6" align="center">抱歉!没有查询到您要的数据!</td>
                                </tr>
                            </c:if>
                            <c:if test="${!empty requestScope.pageInfo.list }">
                                <c:forEach items="${requestScope.pageInfo.list }" var="admin" varStatus="myStatus">
                                    <tr>
                                        <td>${myStatus.count }</td>
                                        <td><input type="checkbox"></td>
                                        <td>${admin.loginAcct }</td>
                                        <td>${admin.userName }</td>
                                        <td>${admin.email }</td>
                                        <td>
                                            <button type="button" class="btn btn-success btn-xs"><i class=" glyphicon glyphicon-check"></i></button>
                                            <%--旧代码--%>
                                            <%--<button type="button" class="btn btn-primary btn-xs"><i class=" glyphicon glyphicon-pencil"></i></button>--%>
                                            <%--新代码--%>
                                            <a href="admin/to/edit/page.html?adminId=${admin.id }&pageNum=${requestScope.pageInfo.pageNum }&keyword=${param.keyword }"class="btn btn-primary btn-xs"><i class=" glyphicon glyphicon-pencil"></i></a>
                                            <a href="admin/remove/${admin.id }/${requestScope.pageInfo.pageNum }/${param.keyword }.html" class="btn btn-danger btn-xs"><i class=" glyphicon glyphicon-remove"></i></a>
                                        </td>
                                    </tr>
                                </c:forEach>
                            </c:if>

                             
                            </tbody>

1.4.5 加入 Pagination 插件环境

解压 pagination_zh.zip 包
把相关文件加入到工程
在这里插入图片描述

在页面上引入样式文件和 JavaScript 文件
在这里插入图片描述

1.4.6 编写 Pagination 代码

<script type="text/javascript">
    $(function () {

        // 调用后面声明的函数对页码导航条进行初始化操作
        initPagination();
    });

    // 生成页码导航条的函数
    function initPagination() {

        // 获取总记录数
        var totalRecord = ${requestScope.pageInfo.total };

        // 声明一个JSON对象存储Pagination要设置的属性
        var properties = {
            num_edge_entries: 3,                                // 边缘页数
            num_display_entries: 5,                             // 主体页数
            callback: pageSelectCallback,                       // 指定用户点击”翻页“的按钮时跳转页面的回调函数
            items_per_page: ${requestScope.pageInfo.pageSize},  //每页要显示的数据的数量
            current_page: ${requestScope.pageInfo.pageNum - 1}, // Pagination内部使用pageIndex来管理页码,pageIndex从0开始,pageNum从1开始,所以要减一
            prev_text: "上一页",                                // 上一页按钮上显示的文本
            next_text: "下一页",                                // 下一页按钮上显示的文本
        };
        // 生成页码导航条
        $("#Pagination").pagination(totalRecord, properties);
    }

    // 回调函数的含义:声明出来以后不是自己调用,而是交给系统或框架调用
    // 用户点击"1、2、3"这样的页码时调用这个函数实现页面跳转
    // pageIndex是Pagination传给我们的那个"从0开始"的页码
    function pageSelectCallback(pageIndex, jQuery) {

        // 根据pageIndex计算得到pageNum
        var pageNum = pageIndex + 1;

        //跳转页面
        window.location.href = "admin/get/page.html?pageNum="+pageNum+"&keyword=${param.keyword}";

        // 由于每一个页码按钮都是超链接,所以在这个函数最后取消超链接的默认行为
        return false;
    }
</script>

1.4.7 修改 jquery.pagination.js 文件源码

问题分析如下图所示:
在这里插入图片描述
问题的解决:不让 Pagination 在页码导航条初始化完成时就调用回调函数!

else {
return false;
}
}
// 所有初始化完成,绘制链接
drawLinks();
// 回调函数
// opts.callback(current_page, this);
});
}

1.4.8 准备测试数据

@Test
    public void test(){
        for (int i = 0; i < 238; i++){
            adminMapper.insert(new Admin(null, "loginAcct" + i, "userPswd" + i, "userName" + i, "email" + i, null));
        }
    }

2. 分页

2.1 目标

将数据库中的Admin数据在页面上以分页形式显示。在后端将“带关键词”和“不带关键词”的分页合并为同一套代码。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3代码

2.3.1引入PageHelper

确认是否加入了依赖
在这里插入图片描述

在 SalSessionFactoryBean,配置MyBatis插件
在这里插入图片描述

<!-- 配置插件 -->
            <property name="plugins">
                <array>
                    <!-- 配置PageHelper插件-->
                    <bean class="com.github.pagehelper.PageHelper">
                        <property name="properties">
                            <props>
                                <!-- 配置数据库方言,告诉PageHelper当前使用的数据库-->
                                <prop key="dialect">mysql</prop>

                                <!-- 配置页码的合理化修正,1~总页码之间修正页码 -->
                                <prop key="reasonable">true</prop>
                            </props>
                        </property>
                    </bean>
                </array>
            </property>

2.3.2 AdminMapper中编写SQL语句

在这里插入图片描述

<select id="selectAdminByKeyword" resultMap="BaseResultMap">
   select id, login_acct, user_pswd, user_name, email, create_time
   from  t_admin
   where
    login_acct like concat("%",#{keyword},"%") or
    user_name like concat("%",#{keyword},"%") or
    email like concat("%",#{keyword},"%")
  </select>

2.3.3 AdminMapper接口中声明方法

在这里插入图片描述
在这里插入图片描述

2.3.4 AdminService方法

在这里插入图片描述

 @Override
    public PageInfo<Admin> getPageInfo(String keyword, Integer pageNum, Integer pageSize) {

        // 1.调用PageHelper的静态方法开启分页功能
        // 这里充分体现了PageHelper的"非侵入式"设计:原本要做的查询不必有任何修改
        PageHelper.startPage(pageNum, pageSize);

        // 2.执行查询
        List<Admin> list = adminMapper.selectAdminByKeyword(keyword);

        // ※辅助代码:打印 adminList 的全类名
        Logger logger = LoggerFactory.getLogger(AdminServiceImpl.class);

        logger.debug("adminList 的全类名是:"+ list.getClass().getName());

        // 3.为了方便页面使用将 adminList 封装为 PageInfo
        PageInfo<Admin> pageInfo = new PageInfo<>(list);

        // 3.封装到PageInfo对象中
        return new PageInfo<>(list);
    }

2.3.5 Adminhandler 方法

在这里插入图片描述

@RequestMapping("/admin/get/page.html")
    public String getPageInfo(
            // 使用@RequestParam注解的defaltValue属性,指定默认值,在请求中没有携带对应参数时使用默认值
            // keyword默认值使用空字符串, 和SQL语句配合实现两种情况适配
            @RequestParam(value = "keyword", defaultValue = "") String keyword,

            // pageNum默认值使用1
            @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
            // pageSize默认值使用5
            @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
            ModelMap modelMap
    ){
        
        // 调用Service方法获取PageInfo对象
        PageInfo<Admin> pageInfo = adminService.getPageInfo(keyword, pageNum, pageSize);

        //将PageInfo对象存入模型
        modelMap.addAttribute(CrowdConstant.ATTR_NAME_PAGE_INFO, pageInfo);
        return "admin-page";
    }

在这里插入图片描述

2.3.6页面显示主体

在这里插入图片描述

2.3.7在页面上使用Pagination实现页码导航条

在这里插入图片描述
在这里插入图片描述
在有需要的页面上进行引入:注意先后顺序!Pagination要在jQuery的后面!
在这里插入图片描述
HTML代码所需准备
使用Pagination要求的div标签替换原有的页码部分
在这里插入图片描述

3. 分页导航条

3.1 分页导航条-初始化函数

在这里插入图片描述
在这里插入图片描述

<link rel="stylesheet" href="css/pagination.css" />
<script type="text/javascript" src="jquery/jquery.pagination.js"></script>
<script type="text/javascript">
    $(function () {

        // 调用后面声明的函数对页码导航条进行初始化操作
        initPagination();
    });

    // 生成页码导航条的函数
    function initPagination() {

        // 获取总记录数
        var totalRecord = ${requestScope.pageInfo.total };

        // 声明一个JSON对象存储Pagination要设置的属性
        var properties = {
            num_edge_entries: 3,                                // 边缘页数
            num_display_entries: 5,                             // 主体页数
            callback: pageSelectCallback,                       // 指定用户点击”翻页“的按钮时跳转页面的回调函数
            items_per_page: ${requestScope.pageInfo.pageSize},  //每页要显示的数据的数量
            current_page: ${requestScope.pageInfo.pageNum - 1}, // Pagination内部使用pageIndex来管理页码,pageIndex从0开始,pageNum从1开始,所以要减一
            prev_text: "上一页",                                // 上一页按钮上显示的文本
            next_text: "下一页",                                // 下一页按钮上显示的文本
        };
        // 生成页码导航条
        $("#Pagination").pagination(totalRecord, properties);
    }

    
    }
</script>

3.2 分页导航条-回调函数

// 回调函数的含义:声明出来以后不是自己调用,而是交给系统或框架调用
    // 用户点击"1、2、3"这样的页码时调用这个函数实现页面跳转
    // pageIndex是Pagination传给我们的那个"从0开始"的页码
    function pageSelectCallback(pageIndex, jQuery) {

        // 根据pageIndex计算得到pageNum
        var pageNum = pageIndex + 1;

        //跳转页面
        window.location.href = "admin/get/page.html?pageNum="+pageNum+"&keyword=${param.keyword}";

        // 由于每一个页码按钮都是超链接,所以在这个函数最后取消超链接的默认行为
        return false;

3.3 分页导航条-修改库文件

在这里插入图片描述

把调用回调函数的一行注释掉:
在这里插入图片描述

在这里插入图片描述

总结

在这里插入图片描述

3. 关键词查询

在这里插入图片描述

3.1页面上调整查询表单

在这里插入图片描述

3.2在翻页时保持关键词查询条件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. 单条删除

4.1 目标

在页面上点击单条删除按钮,实现Admin对应记录的删除。

4.2 思路

在这里插入图片描述

4.3 代码

4.3.1 调整删除的按钮

在这里插入图片描述

<td>
                                            <button type="button" class="btn btn-success btn-xs"><i class=" glyphicon glyphicon-check"></i></button>
                                            <%--旧代码--%>
                                            <%--<button type="button" class="btn btn-primary btn-xs"><i class=" glyphicon glyphicon-pencil"></i></button>--%>
                                            <%--新代码--%>
                                            <a href="admin/to/edit/page.html?adminId=${admin.id }&pageNum=${requestScope.pageInfo.pageNum }&keyword=${param.keyword }"class="btn btn-primary btn-xs"><i class=" glyphicon glyphicon-pencil"></i></a>
                                            <a href="admin/remove/${admin.id }/${requestScope.pageInfo.pageNum }/${param.keyword }.html" class="btn btn-danger btn-xs"><i class=" glyphicon glyphicon-remove"></i></a>
                                        </td>

4.3.2 主体代码

在这里插入图片描述
在这里插入图片描述

4.4 解决删除完成后页面跳转问题

4.4.1 AdminHandler.java

@RequestMapping("/admin/remove/{adminId}/{pageNum}/{keyword}.html")
    public String remove(@PathVariable("adminId") Integer adminId,
                         @PathVariable("pageNum") Integer pageNum,
                         @PathVariable("keyword") String keyword
                         ){

        // 执行删除
        adminService.remove(adminId);

        // 页面跳转:回到分页页面
//        return null;

        // 尝试方案1:直接转发到admin-page.jsp会无法显示分页数据
//         return "admin-page";

        // 尝试方案2:转发到/admin/get/page.html地址,一旦刷新页面会重复执行删除浪费性能
//        return "forward:/admin/get/page.html";
        // 尝试方案3:重定向到/admin/get/page.html地址
        // 同时为了保存原本所在的页面和查询关键词再附加pageNum和keyword两个参数
        return "redirect:/admin/get/page.html?pageNum="+pageNum+"&keyword="+keyword;
    }

5. 新增

5.1 目标

将表单提交的Admin对象保存到数据库中。
要求1: loginAcct,不能重复
要求2:密码加密

5.2 思路

在这里插入图片描述

在这里插入图片描述

5.3 在t_admin表中给账号添加唯一约束

ALTER TABLE `project_crowd`.`t_admin` 
ADD UNIQUE INDEX(`login_acct`)

5.3.2 业务逻辑层

在这里插入图片描述


private Logger logger = LoggerFactory.getLogger(AdminServiceImpl.class);

 @Override
    public void saveAdmin(Admin admin) {

        // 1.密码加密
        String userPswd = admin.getUserPswd();
        userPswd = CrowdUtil.md5(userPswd);
        admin.setUserPswd(userPswd);

        // 2.生成创建时间
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String createTime = format.format(date);
        admin.setCreateTime(createTime);

        // 3.执行保存
        try {
            adminMapper.insert(admin);
        } catch (Exception e) {
            e.printStackTrace();

            logger.info("异常全类名" + e.getClass().getName());

            if (e instanceof DuplicateKeyException){
                throw new  LoginAcctAlreadyInUseException(CrowdConstant.MESSAGE_LOGIN_ACCT_ALREADY_IN_USE);
            }
        }
    }

5.3.3 异常映射处理器类

在这里插入图片描述

@ExceptionHandler(value = LoginAcctAlreadyInUseException.class)
    public ModelAndView resolveLoginAcctAlreadyInUseException(
            LoginAcctAlreadyInUseException exception,
            //当前请求对象
            HttpServletRequest request,
            //当前响应对象
            HttpServletResponse response
    ) throws IOException {

        // 只是指定当前异常对应的页面即可
        String viewName = "admin-add";

        return commonResolve(viewName, exception, request, response);
    }

5.3.4 自定义异常

在这里插入图片描述

package com.atguigu.crowd.exception;

/**
 * 保存或更新Admin时如果检测到登录账号重复抛出这个异常
 */
public class LoginAcctAlreadyInUseException extends RuntimeException {
    private static final long serialVersionUID = 1L;

    public LoginAcctAlreadyInUseException() {
    }

    public LoginAcctAlreadyInUseException(String message) {
        super(message);
    }

    public LoginAcctAlreadyInUseException(String message, Throwable cause) {
        super(message, cause);
    }

    public LoginAcctAlreadyInUseException(Throwable cause) {
        super(cause);
    }

    public LoginAcctAlreadyInUseException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

5.3.5 控制层

在这里插入图片描述


@RequestMapping("/admin/save.html")
    public String save(Admin admin){

        adminService.saveAdmin(admin);

        return "redirect:/admin/get/page.html?pageNum="+Integer.MAX_VALUE;
    }

5.3.6 准备表单页面

在这里插入图片描述

<%@ page contentType="text/html;charset=UTF-8" language="java"
         pageEncoding="UTF-8"  %>

<!DOCTYPE html>
<html lang="zh-CN">
<%@include file="/WEB-INF/include-head.jsp" %>

<body>
<%@include file="/WEB-INF/include-nav.jsp" %>
<div class="container-fluid">
    <div class="row">
        <%@include file="/WEB-INF/include-sidebar.jsp" %>
        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
            <ol class="breadcrumb">
                <li><a href="/admin/to/main/page.html">首页</a></li>
                <li><a href="/admin/get/page.html">数据列表</a></li>
                <li class="active">新增</li>
            </ol>
            <div class="panel panel-default">
                <div class="panel-heading">表单数据<div style="float:right;cursor:pointer;" data-toggle="modal" data-target="#myModal"><i class="glyphicon glyphicon-question-sign"></i></div></div>
                <div class="panel-body">
                    <form action="admin/save.html" method="post" role="form">
                        <p>${requestScope.exception.message }</p>
                        <div class="form-group">
                            <label for="exampleInputPassword1">登录账号</label>
                            <input name="loginAcct" type="text" class="form-control" id="exampleInputPassword1" placeholder="请输入登录账号">
                        </div>
                        <div class="form-group">
                            <label for="exampleInputPassword1">登录密码</label>
                            <input name="userPswd" type="text" class="form-control" id="exampleInputPassword1" placeholder="请输入登陆密码">
                        </div>
                        <div class="form-group">
                            <label for="exampleInputPassword1">用户昵称</label>
                            <input name="userName" type="text" class="form-control" id="exampleInputPassword1" placeholder="请输入用户昵称">
                        </div>
                        <div class="form-group">
                            <label for="exampleInputEmail1">邮箱地址</label>
                            <input name="email" type="email" class="form-control" id="exampleInputEmail1" placeholder="请输入邮箱地址">
                            <p class="help-block label label-warning">请输入合法的邮箱地址, 格式为: xxxx@xxxx.com</p>
                        </div>
                        <button type="submit" class="btn btn-success"><i class="glyphicon glyphicon-plus"></i> 新增</button>
                        <button type="reset" class="btn btn-danger"><i class="glyphicon glyphicon-refresh"></i> 重置</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

</body>
</html>

细节请参考代码中的这个文件!

5.3.7 跳转到这个页面

在这里插入图片描述

<mvc:view-controller path="/admin/to/add/page.html" view-name="admin-add"/>

在这里插入图片描述
在这里插入图片描述

5.3.8 页面上修改表单

5.4 调整修改按钮

在这里插入图片描述

<%--旧代码--%>
<%--<button type="button" class="btn btn-primary" style="float:right;" onclick="window.location.href='add.html'"><i class="glyphicon glyphicon-plus"></i> 新增</button>--%>
<%--新代码--%>
<a href="admin/to/add/page.html" class="btn btn-primary" style="float:right;"
><i class="glyphicon glyphicon-plus">新增</i></a>

5.5配置view-controller

在这里插入图片描述

<mvc:view-controller path="/admin/to/add/page.html" view-name="admin-add"/>

5.6准备表单页面

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.7 handler方法

在这里插入图片描述

@RequestMapping("/admin/save.html")
public String save(Admin admin){

    adminService.saveAdmin(admin);

    return "redirect:/admin/get/page.html?pageNum="+Integer.MAX_VALUE;
}

5.8 Service方法

在这里插入图片描述

@Service
public class AdminServiceImpl implements AdminService {

    @Autowired
    private AdminMapper adminMapper;

    private Logger logger = LoggerFactory.getLogger(AdminServiceImpl.class);

    @Override
    public void saveAdmin(Admin admin) {

        // 1.密码加密
        String userPswd = admin.getUserPswd();
        userPswd = CrowdUtil.md5(userPswd);
        admin.setUserPswd(userPswd);

        // 2.生成创建时间
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String createTime = format.format(date);
        admin.setCreateTime(createTime);

        // 3.执行保存
        try {
            adminMapper.insert(admin);
        } catch (Exception e) {
            e.printStackTrace();

            logger.info("异常全类名" + e.getClass().getName());

            if (e instanceof DuplicateKeyException){
                throw new  LoginAcctAlreadyInUseException(CrowdConstant.MESSAGE_LOGIN_ACCT_ALREADY_IN_USE);
            }
        }
    }

5.9 处理异常类

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

6. 更新

6.1 目标

修改现有Admin的数据。不修改密码,不修改创建时间。

6.2 思路

在这里插入图片描述

6.3 代码:回显表单

6.3.1 调整铅笔按钮

在这里插入图片描述

%--旧代码--%>
<%--<button type="button" class="btn btn-primary btn-xs"><i class=" glyphicon glyphicon-pencil"></i></button>--%>
<%--新代码--%>
<a href="admin/to/edit/page.html?adminId=${admin.id }&pageNum=${requestScope.pageInfo.pageNum }&keyword=${param.keyword }"class="btn btn-primary btn-xs"><i class=" glyphicon glyphicon-pencil"></i></a>
<a href="admin/remove/${admin.id }/${requestScope.pageInfo.pageNum }/${param.keyword }.html" class="btn btn-danger btn-xs"><i class=" glyphicon glyphicon-remove"></i></a>

6.3.2 handler方法

@RequestMapping("/admin/to/edit/page.html")
public String toEditPage(
        @RequestParam("adminId") Integer adminId,
        @RequestParam("pageNum") Integer pageNum,
        @RequestParam("keyword") String keyword,
        ModelMap modelMap
){

    // 1.根据adminId查询Admin对象
    Admin admin = adminService.getAdminById(adminId);

    // 2.将Admin对象存入模型
    modelMap.addAttribute("admin", admin);

    return "admin-edit";
}

6.3.3 AdminServiceImpl.java

@Override
public Admin getAdminById(Integer adminId) {
    return adminMapper.selectByPrimaryKey(adminId);
}

7. 前台页面

在这里插入图片描述

7.1 复制admin-add.jsp代码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7.2 执行更新admin-edit

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
说明:之所以要新建一个异常类,是为了在出现问题时(账号重复)不要跳转到Admin新增页面。
在这里插入图片描述
在这里插入图片描述
说明:不回到更新的表单页面是因为没有携带能够回显表单的数据。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于Spring Boot开发众筹平台前后台管理系统是一个非常有挑战性的项目。首先,我们需要创建一个新的Spring Boot项目,然后引入相关的依赖,包括Spring Web、Spring Data JPA、Thymeleaf等。接着,我们需要设计数据库表结构,包括用户表、项目表、订单表等,然后使用JPA创建对应的实体类和数据库操作方法。 在后台管理系统中,我们需要实现用户管理、项目管理、订单管理等功能。在用户管理中,我们可以实现用户的增删改查功能,包括对用户权限的管理。在项目管理中,我们可以对项目进行管理,包括项目的创建、编辑、删除等操作。在订单管理中,我们可以查看用户的订单信息,包括订单的状态、支付情况等。 在前台部分,我们需要实现用户注册、登录、项目展示、项目支持等功能。用户可以通过前台页面浏览众筹项目,并支持自己感兴趣的项目。同时,用户还可以在前台查看自己的订单情况,包括已支持的项目、订单状态等信息。 除了基本的功能,我们还需要考虑系统的性能、安全、可扩展性等方面。我们需要对代码进行优化,保证系统的性能。同时,我们需要保障系统的安全,包括用户信息的加密存储、权限控制等。另外,我们还需要考虑系统的可扩展性,确保系统在未来能够方便地进行功能扩展和升级。 最后,完整的源码和运行指导将会在项目开发完成后提供给用户,让用户能够快速部署和运行这个众筹平台前后台管理系统。同时,我们也会提供详细的文档说明,让用户能够更方便地了解系统的架构和实现细节。希望这个系统能够为众筹平台的管理和用户带来便利和价值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值