第五节——后台管理系统的实现
执键写春秋 569 1

5. 后台管理系统的实现

5.1 管理员登录

5.1.1 视图层页面

【src/main/resources/templates/admin/login.html】

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>管理员登录页面</title>
    <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}" />
<body>
<div class="container">
    <div class="bg-primary"  style="width:70%; height: 60px;padding-top: 1px;">
        <h3 align="center">管理员登录</h3>
    </div>
    <br>
    <br>
    <form th:action="@{/admin/login}" name="myform" method="post" th:object="${aUser}"  class="form-horizontal" role="form" >
        <div class="form-group has-success">
            <label class="col-sm-2 col-md-2 control-label">用户名</label>
            <div class="col-sm-4 col-md-4">
                <input type="text" class="form-control"
                       placeholder="请输入管理员名"
                       th:field="*{aname}"/>
                <span th:errors="*{aname}"></span>
            </div>
        </div>

        <div class="form-group has-success">
            <label class="col-sm-2 col-md-2 control-label">密码</label>
            <div class="col-sm-4 col-md-4">
                <input type="password" class="form-control"
                       placeholder="请输入您的密码" th:field="*{apwd}"/>
                <span th:errors="*{apwd}"></span>
            </div>
        </div>

        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                <button type="submit"class="btn btn-success" >登录</button>
                <button type="reset" class="btn btn-primary" >重置</button>
            </div>
        </div>
    </form>
</div>
</body>
</html>

第五节——后台管理系统的实现

5.1.2 实体层

package pers.xsc.online_shopping.entity;

public class AUser {
    private String aname;
    private String apwd;

    public AUser() {
    }

    public AUser(String aname, String apwd) {
        this.aname = aname;
        this.apwd = apwd;
    }

    public String getAname() {
        return aname;
    }

    public void setAname(String aname) {
        this.aname = aname;
    }

    public String getApwd() {
        return apwd;
    }

    public void setApwd(String apwd) {
        this.apwd = apwd;
    }

    @Override
    public String toString() {
        return "AUser{" +
                "aname='" + aname + '\'' +
                ", apwd='" + apwd + '\'' +
                '}';
    }
}

5.1.3 控制器层方法

package pers.xsc.online_shopping.controller.admin;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import pers.xsc.online_shopping.entity.AUser;
import pers.xsc.online_shopping.entity.User;
import pers.xsc.online_shopping.service.admin.AdminService;

import javax.servlet.http.HttpSession;

@Controller
@RequestMapping("/admin")
public class AdminController {
    @Autowired
    AdminService adminService;

    @RequestMapping("/toLogin")
    //跳转到admin/login.html视图上,并指定AUser作为视图表单需要绑定的javaBean
    public String toLogin(@ModelAttribute("aUser")AUser aUser){
        return "admin/login";
    }
    //管理员登录验证
    @RequestMapping("/login")
    public String Login(@ModelAttribute("aUser")AUser aUser, HttpSession httpSession){
    /**
      *@ModelAttribute("aUser")AUser aUser接收login.html
      *页面中的表单数据,并将数据作为adminService.login()的  
      *参数,该注解与表单中的th:object="${aUser}" 相照应,这个 
      *元素用于表单数据对象绑定,将表单绑定传送到后台controller 
      *的一个JavaBean参数,通常与th:field="*{XXX}"一起使用。同时路径的* 
      *跳转利用th:action="@{/XXX}"完成。
    **/
        return adminService.login(aUser,httpSession);
    }
}

5.1.4 业务层接口及其实现

package pers.xsc.online_shopping.service.admin;

import org.springframework.ui.Model;
import pers.xsc.online_shopping.entity.AUser;

import javax.servlet.http.HttpSession;

public interface AdminService {
    String login(AUser aUser, HttpSession httpSession);
}
package pers.xsc.online_shopping.service.admin.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import pers.xsc.online_shopping.entity.AUser;
import pers.xsc.online_shopping.exception.CustomException;
import pers.xsc.online_shopping.exception.ExceptionEnum;
import pers.xsc.online_shopping.mapper.admin.AdminMapper;
import pers.xsc.online_shopping.service.admin.AdminService;
import pers.xsc.online_shopping.utils.Constant;
import pers.xsc.online_shopping.utils.MD5Utils;
import pers.xsc.online_shopping.utils.ResultUtils;

import javax.servlet.http.HttpSession;

@Service
public class AdminServiceImpl implements AdminService {
    @Autowired
    AdminMapper adminMapper ;

    /**
     * 管理员登录验证方法
     * @param aUser 输入的管理员账号与密码
     * @param httpSession 将成功登录的管理员信息存入session
     * @return
     */
    @Override
    public String login(AUser aUser, HttpSession httpSession){
        if ((aUser.getAname()==null||aUser.equals(""))||(aUser.getApwd()==null||aUser.getApwd().equals(""))) {
            //抛出异常——PARAM_IS_BLANK(20003,"参数[用户名/密码]为空")
            throw new CustomException(ExceptionEnum.PARAM_IS_BLANK.getCode(),ExceptionEnum.PARAM_IS_BLANK.getMsg());
        }else {
            AUser aUser_find = adminMapper.login(aUser);
            aUser_find.setApwd(MD5Utils.getMD5StrByDigestUtils(aUser.getApwd()));
            if (StringUtils.isEmpty(aUser_find)) {
                //抛出异常——USER_LOGIN_ERROR(20002, "账号不存在或密码错误")
                throw new CustomException(ExceptionEnum.USER_LOGIN_ERROR.getCode(),ExceptionEnum.USER_LOGIN_ERROR.getMsg());
            } else {
                httpSession.setAttribute(Constant.ADMIN_USER, aUser_find);
                return "forward:/goods/selectAllGoodsByPage?currentPage=1&act=select";
            }
        }
    }
}

5.1.5 持久层

package pers.xsc.online_shopping.mapper.admin;

import org.apache.ibatis.annotations.Param;
import pers.xsc.online_shopping.entity.AUser;

public interface AdminMapper {
    AUser login(AUser aUser);
}

5.1.6 映射文件

【src/main/resources/mappers/AdminMapper.xml】

<?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="pers.xsc.online_shopping.mapper.admin.AdminMapper">
    <!-- 通用查询结果列-->
    <sql id="Base_Column_List">aname,apwd</sql>
    <!--验证用户登录-->
    <select id="login" parameterType="pers.xsc.online_shopping.entity.AUser" resultType="pers.xsc.online_shopping.entity.AUser">
        select <include refid="Base_Column_List"/> from auser_table where aname = #{aname} and apwd = #{apwd}
    </select>
</mapper>

5.2 商品列表管理

5.2.1 商品展示

5.2.1.1 视图层页面

【src/main/resources/templates/admin/selectGoods.html】

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <base th:href="@{/}">
    <meta charset="UTF-8">
    <title>主页</title>
    <link rel="stylesheet" href="css/bootstrap.min.css" />
    <script src="js/jquery.min.js"></script>
    <script type="text/javascript" th:inline="javascript">
        function deleteGoods(tid){
            $.ajax(
                {
                    //请求路径,要注意的是url和th:inline="javascript"
                    url : [[@{/goods/delete}]],
            //请求类型
            type : "post",
                //data表示发送的数据
                data : {
                id : tid
            },
            //成功响应的结果
            success : function(obj){//obj响应数据
                if(obj == "no"){
                    alert("该商品有关联不允许删除!");
                }else{
                    if(window.confirm("真的删除该商品吗?")){
                        window.location.href = obj;
                    }
                }
            },
            error : function() {
                alert("处理异常!");
            }
        }
        );
        }

    </script>
    <style>
        .table .text-center tr th,td{text-align: center;vertical-align: middle!important;}
    </style>
</head>
<body>
<!-- 加载header.html -->
<div th:include="admin/header"></div>
<br><br><br>
<div class="container">
    <div class="panel panel-primary">
        <div class="panel-heading">
            <h3 class="panel-title">商品列表</h3>
        </div>
        <div class="panel-body">
            <div class="table table-responsive">
                <table class="table table-bordered table-hover">
                    <tbody class="text-center">
                    <tr>
                        <th>商品ID</th>
                        <th>商品名称</th>
                        <th>商品简介</th>
                        <th>商品类型</th>
                        <th>商品图片</th>
                        <th>详情</th>
                        <th th:if="${act} == 'updateSelect'">操作</th>
                        <th th:if="${act} == 'deleteSelect'">操作</th>
                    </tr>
                    <tr th:each="gds:${allGoods}">
                        <td th:text="${gds.id}"></td>
                        <td th:text="${gds.gname}"></td>
                        <td th:text="${gds.description}" style ="width:230px;word-wrap:break-word;word-break:break-all;"></td>
                        <td th:text="${gds.typename}"></td>
                        <td>
                            <button th:text="${gds.gpicture} + '点击查看商品图片'" type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal">

                            </button>
                        </td>
                        <td>
                            <a th:href="@{goods/detail(id=${gds.id},act=detail)}" target="_blank">详情</a>
                        </td>
                        <td th:if="${act} == 'updateSelect'">
                            <a th:href="@{goods/detail(id=${gds.id},act=update)}" target="_blank">修改</a>
                        </td>
                        <td th:if="${act} == 'deleteSelect'">
                            <a th:href="'javascript:deleteGoods(' + ${gds.id} +')'" >删除</a>
                        </td>
                    </tr>
                    <tr th:if="${act} == 'select'">
                        <td colspan="7" align="right">
                            <ul class="pagination">
                                <li><a>第<span th:text="${currentPage}" ></span>页</a></li>
                                <li><a>共<span th:text="${totalPage}" ></span>页</a></li>
                                <li>
                                            <span th:if="${currentPage} != 1" >
                                                <a th:href="@{goods/selectAllGoodsByPage(act=select,currentPage=${currentPage - 1})}">上一页</a>
                                            </span>
                                    <span th:if="${currentPage} != ${totalPage}" >
                                                <a th:href="@{goods/selectAllGoodsByPage(act=select,currentPage=${currentPage + 1})}">下一页</a>
                                            </span>
                                </li>
                            </ul>
                        </td>
                    </tr>
                    <tr th:if="${act} == 'updateSelect'">
                        <td colspan="7" align="right">
                            <ul class="pagination">
                                <li><a>第<span th:text="${currentPage}" ></span>页</a></li>
                                <li><a>共<span th:text="${totalPage}" ></span>页</a></li>
                                <li>
                                            <span th:if="${currentPage} != 1" >
                                                <a th:href="@{goods/selectAllGoodsByPage(act=updateSelect,currentPage=${currentPage - 1})}">上一页</a>
                                            </span>
                                    <span th:if="${currentPage} != ${totalPage}" >
                                                <a th:href="@{goods/selectAllGoodsByPage(act=updateSelect,currentPage=${currentPage + 1})}">下一页</a>
                                            </span>
                                </li>
                            </ul>
                        </td>
                    </tr>
                    <tr th:if="${act} == 'deleteSelect'">
                        <td colspan="7" align="right">
                            <ul class="pagination">
                                <li><a>第<span th:text="${currentPage}" ></span>页</a></li>
                                <li><a>共<span th:text="${totalPage}" ></span>页</a></li>
                                <li>
                                            <span th:if="${currentPage} != 1" >
                                                <a th:href="@{goods/selectAllGoodsByPage(act=deleteSelect,currentPage=${currentPage - 1})}">上一页</a>
                                            </span>
                                    <span th:if="${currentPage} != ${totalPage}" >
                                                <a th:href="@{goods/selectAllGoodsByPage(act=deleteSelect,currentPage=${currentPage + 1})}">下一页</a>
                                            </span>
                                </li>
                            </ul>
                        </td>
                    </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </div>
    <!-- 模态框 -->
    <div class="modal fade" id="myModal">
        <div class="modal-dialog">
            <div class="modal-content">

                <!-- 模态框头部 -->
                <div class="modal-header">
                    <h4 class="modal-title"></h4>
                    <button type="button" class="close" data-dismiss="modal">&times;</button>
                </div>

                <!-- 模态框主体 -->
                <div class="modal-body" id="oDiv"  style=" background-image: url(images/modal_bg.jpg);background-repeat: no-repeat;background-size:100% 100%;">

                </div>

                <!-- 模态框底部 -->
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
                </div>

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

</div>
</div>
<script>
    $('.btn-primary').click(function(){
        $('.modal-title').html("");
        $('.modal-body').html("");
    //$('#myModal').on('shown.bs.modal', function () {
        var text1 = $(this).closest("tr").find("td:eq(1)").text();
        var text2 = $(this).closest("tr").find("td:eq(4)").text();
        $('.modal-title').prepend(text1);
        var newText2 = ("images/").concat(text2.replace("点击查看商品图片","")).replace(/\s+/g,"");
        //$('.img-thumbnail').attr('src',newText2);
        //$('.modal-body').prepend(newText2);
        //alert(newText2);
        var bigImg = document.createElement("img"); //创建一个img元素
        bigImg.src = newText2; //给img元素的src属性赋值
        bigImg.width= "350";  //320个像素 不用加px
        bigImg.height= "260";
        bigImg.style = "display: block;margin: auto;"
        var myp = document.getElementById('oDiv'); //获得dom对象
        myp.appendChild(bigImg); //为dom添加子元素img
    //})
    })

</script>
</body>
</html>

【src/main/resources/templates/admin/header.html】

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>导航页</title>
<base th:href="@{/}"><!-- 不用base就使用th:src="@{/js/jquery.min.js} -->
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<script src="js/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
    <script>
        /* 时间 */
        var arr_week=new Array("星期日","星期一","星期二","星期三","星期四","星期五","星期六");
        var strWeek=arr_week[new Date().getDay()];
        setInterval(" document.getElementById('time').innerHTML= new Date().toLocaleString() +'    '+ strWeek ",1000);
    </script>
</head>
<body>
    <div class="container-fruid">
        <div class="navbar navbar-default navbar-fixed-top" role="navigation"
            style="padding-left: 30px;">
            <ul class="nav navbar-nav">
                <li class="dropdown"><a href="##" data-toggle="dropdown"
                    class="dropdown-toggle">类型管理<span class="caret"></span></a>
                    <ul class="dropdown-menu">
                        <li><a th:href="@{type/selectAllTypeByPage?currentPage=1}">查询类型</a></li>
                        <li><a th:href="@{type/toAddType}">添加类型</a></li>
                    </ul>
                </li>
                <li class="dropdown"><a href="##" data-toggle="dropdown"
                    class="dropdown-toggle">商品管理<span class="caret"></span></a>
                    <ul class="dropdown-menu">
                        <li><a th:href="@{goods/selectAllGoodsByPage?currentPage=1&act=select}">查询商品</a></li>
                        <li><a th:href="@{goods/toAddGoods}">添加商品</a></li>
                        <li><a th:href="@{goods/selectAllGoodsByPage?currentPage=1&act=updateSelect}">修改商品</a></li>
                        <li><a th:href="@{goods/selectAllGoodsByPage?currentPage=1&act=deleteSelect}">删除商品</a></li>
                    </ul>
                </li>
                <li><a th:href="@{selectOrder?currentPage=1}">查询订单</a></li>
                <li><a th:href="@{selectUser?currentPage=1}">用户管理</a></li>
                <li><a th:href="@{admin/loginOut}">安全退出</a></li>
                <li><a href="javascript:void(0);" ><span  class="glyphicon glyphicon-user" th:text="'你好,'+${session.adminUser.aname}+'管理员'"></span></a></li>
                <li><a href="javascript:void(0);" ><span class="glyphicon glyphicon-time" id="time"></span></a></li>
                <li>
                    <a href="javascript:void(0);" >
                    <span>
                        <iframe width="500" height="20" frameborder="0" scrolling="no" hspace="0" src="https://i.tianqi.com/?c=code&a=getcode&id=11&icon=1"></iframe>
                    </span>
                    </a>
                </li>

            </ul>
        </div>
    </div>
</body>

</html>

5.2.1.2 实体层

package pers.xsc.online_shopping.entity;

import org.springframework.web.multipart.MultipartFile;

import java.util.Date;

public class Goods {
    private int id;
    private String gname;//商品名称
    private String description;//商品描述
    private double goprice;//商品原价
    private double grprice;//商品现价
    private int gstore;//商品库存
    private String  gpicture;//商品图片
    private MultipartFile fileName;//文件名
    private int goodstype_id;//商品类型ID
    private String typename;
    private int buyNumber;//加入购物车使用
    private int isAdvertisement;//是否广告
    private int isRecommend;//是否推荐
    private Date utime;//更新时间
    private Date etime;//入库时间



    public Goods() {
    }

    public int getBuyNumber() {
        return buyNumber;
    }

    public void setBuyNumber(int buyNumber) {
        this.buyNumber = buyNumber;
    }

    public MultipartFile getFileName() {
        return fileName;
    }

    public void setFileName(MultipartFile fileName) {
        this.fileName = fileName;
    }

    public String getTypename() {
        return typename;
    }

    public void setTypename(String typename) {
        this.typename = typename;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getGname() {
        return gname;
    }

    public void setGname(String gname) {
        this.gname = gname;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public double getGoprice() {
        return goprice;
    }

    public void setGoprice(double goprice) {
        this.goprice = goprice;
    }

    public double getGrprice() {
        return grprice;
    }

    public void setGrprice(double grprice) {
        this.grprice = grprice;
    }

    public int getGstore() {
        return gstore;
    }

    public void setGstore(int gstore) {
        this.gstore = gstore;
    }

    public String getGpicture() {
        return gpicture;
    }

    public void setGpicture(String gpicture) {
        this.gpicture = gpicture;
    }

    public int getGoodstype_id() {
        return goodstype_id;
    }

    public void setGoodstype_id(int goodstype_id) {
        this.goodstype_id = goodstype_id;
    }

    public int getIsAdvertisement() {
        return isAdvertisement;
    }

    public void setIsAdvertisement(int isAdvertisement) {
        this.isAdvertisement = isAdvertisement;
    }

    public int getIsRecommend() {
        return isRecommend;
    }

    public void setIsRecommend(int isRecommend) {
        this.isRecommend = isRecommend;
    }

    public Date getUtime() {
        return utime;
    }

    public void setUtime(Date utime) {
        this.utime = utime;
    }

    public Date getEtime() {
        return etime;
    }

    public void setEtime(Date etime) {
        this.etime = etime;
    }
}

5.2.1.3 控制层方法

package pers.xsc.online_shopping.controller.admin;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import pers.xsc.online_shopping.entity.Goods;
import pers.xsc.online_shopping.service.admin.GoodsService;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;

@Controller
@RequestMapping("/goods")
public class GoodsController {
    @Autowired
    private GoodsService goodsService;

    @RequestMapping("/selectAllGoodsByPage")
    public String selectAllGoodsByPage(Model model, int currentPage, String act){
        return goodsService.selectAllGoodsByPage(model, currentPage, act);
    }

5.2.1.4 业务层接口及实现

package pers.xsc.online_shopping.service.admin;

import org.springframework.ui.Model;
import pers.xsc.online_shopping.entity.Goods;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public interface GoodsService {
    String selectAllGoodsByPage(Model model, int currentPage, String act);
}
package pers.xsc.online_shopping.service.admin.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.web.multipart.MultipartFile;
import pers.xsc.online_shopping.entity.Goods;
import pers.xsc.online_shopping.mapper.admin.GoodsMapper;
import pers.xsc.online_shopping.mapper.admin.GoodsTypeMapper;
import pers.xsc.online_shopping.service.admin.GoodsService;
import pers.xsc.online_shopping.utils.ReFilenameUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;

@Service
public class GoodsServiceImpl implements GoodsService {
    @Autowired
    GoodsMapper goodsMapper;
    @Autowired
    GoodsTypeMapper goodsTypeMapper;
    @Override
    public String selectAllGoodsByPage(Model model, int currentPage, String act) {
        //共多少个商品
        int totalCount = goodsMapper.selectAllGoods();
        //计算共多少页
        int pageSize = 5;
        int totalPage = (int)Math.ceil(totalCount*1.0/pageSize);
        List<Goods> typeByPage = goodsMapper.selectAllGoodsByPage((currentPage-1)*pageSize, pageSize);
        model.addAttribute("allGoods", typeByPage);
        model.addAttribute("totalPage", totalPage);
        model.addAttribute("currentPage", currentPage);
        model.addAttribute("act", act);
        return "admin/selectGoods";
    }

}

5.2.1.5 持久层

package pers.xsc.online_shopping.mapper.admin;

import org.apache.ibatis.annotations.Param;
import pers.xsc.online_shopping.entity.Goods;
import pers.xsc.online_shopping.entity.GoodsType;

import java.util.List;
import java.util.Map;

public interface GoodsMapper {
    //分页查询
    List<Goods> selectAllGoodsByPage(@Param("startIndex") int startIndex, @Param("perPageSize") int perPageSize);
    //查询总记录数
    int selectAllGoods();
}

5.2.1.6 映射文件

<?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="pers.xsc.online_shopping.mapper.admin.GoodsMapper">


    <!-- 分页查询 -->
    <select id="selectAllGoodsByPage"  resultType="pers.xsc.online_shopping.entity.Goods">
        select gt.*,gy.typename
        from goods_table gt,goodstype_table gy
        where gt.goodstype_id = gy.id
        order by id asc limit #{startIndex}, #{perPageSize}
    </select>

    <select id="selectAllGoods" resultType="java.lang.Integer">
        select count(*) from goods_table
    </select>

</mapper>

5.2.1.7 效果图

第五节——后台管理系统的实现第五节——后台管理系统的实现第五节——后台管理系统的实现

5.2.1.8 模块小结

  • 头部导航栏header.html视图中显示“你好,XXX管理员”这里的“XXX”是利用session取值,${session.后台设置的存放用户信息的session名.aname},即${session.adminUser.aname},其中“adminUser”为全局常量——public static final String ADMIN_USER = "adminUser";

  • 分页查询:前台传回页码参数到控制层,再转到实现方法,利用(currentPage-1)*pageSize计算出起始商品ID,展示条数pageSize为固定,将两个参数传入持久层,利用sql语句的limit关键字完成分页查询。
  • 点击查看商品图片,然后弹出模态框进行展示关键:利用closest()方法获得匹配选择器的第一个祖先元素,利用find("td:eq(1")方法找到第二个子元素,再利用text()方法获得文本值,接着利用concat(text2.replace("点击查看商品图片","")).replace(/\s+/g,"")去掉无用字符串及空格,然后剩下的就是清空与回填操作。
    <script>
      $('.btn-primary').click(function(){
          $('.modal-title').html("");
          $('.modal-body').html("");
      //$('#myModal').on('shown.bs.modal', function () {
          var text1 = $(this).closest("tr").find("td:eq(1)").text();
          var text2 = $(this).closest("tr").find("td:eq(4)").text();
          $('.modal-title').prepend(text1);
          var newText2 = ("images/").concat(text2.replace("点击查看商品图片","")).replace(/\s+/g,"");
          //$('.img-thumbnail').attr('src',newText2);
          //$('.modal-body').prepend(newText2);
          //alert(newText2);
          var bigImg = document.createElement("img"); //创建一个img元素
          bigImg.src = newText2; //给img元素的src属性赋值
          bigImg.width= "350";  //320个像素 不用加px
          bigImg.height= "260";
          bigImg.style = "display: block;margin: auto;"
          var myp = document.getElementById('oDiv'); //获得dom对象
          myp.appendChild(bigImg); //为dom添加子元素img
      //})
      })
    


### 5.2.2 商品详情
#### 5.2.2.1 视图层页面
【src/main/resources/templates/admin/deatil.html】
商品详情页



商品详情

商品名称
商品简介
商品原价
商品折扣价
商品库存
商品入库时间
商品更新时间
商品图片
![屏幕截图 2021-08-13 133809](https://img-hello-world.oss-cn-beijing.aliyuncs.com/imgs/fc0c5f5d4cd06341994157d316e16fa9.jpg)
#### 5.2.2.2 控制器层方法

@RequestMapping("/detail") public String detail(Model model , Integer id , String act,HttpSession session){ if((AUser) session.getAttribute(Constant.ADMIN_USER) == null ){ throw new CustomException(ExceptionEnum.SESSION_FAILED.getCode(), ExceptionEnum.SESSION_FAILED.getMsg()); } return goodsService.detail(model,id,act); }

#### 5.2.2.3 业务层接口及实现方法

String detail(Model model, Integer id, String act);

@Override public String detail(Model model, Integer id, String act) { model.addAttribute("goods", goodsMapper.selectAGoods(id)); if("detail".equals(act)) return "admin/detail"; else { model.addAttribute("goodsType", goodsMapper.selectAllGoodsType()); return "admin/updateAGoods"; } }

#### 5.2.2.4 持久层

Goods selectAGoods(Integer id);

#### 5.2.2.5 映射文件
<select id="selectAGoods"  resultType="pers.xsc.online_shopping.entity.Goods">
    select
        gt.*, gy.typename
    from
        goods_table gt,goodstype_table gy
    where
        gt.goodstype_id = gy.id
      and gt.id = #{id}
</select>
### 5.2.3 商品更新
#### 5.2.3.1 视图层页面
【src/main/resources/templates/admin/updateAGoods.html】
商品类型添加页面



修改商品


        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                <button type="submit"class="btn btn-success" >修改</button>
                <button type="reset" class="btn btn-primary" >重置</button>
            </div>
        </div>
    </form>
</div>
``` ![屏幕截图 2021-08-14 141234](https://img-hello-world.oss-cn-beijing.aliyuncs.com/imgs/e24777836df44100b44519ecc66458e2.jpg)![屏幕截图 2021-08-14 141255](https://img-hello-world.oss-cn-beijing.aliyuncs.com/imgs/26b4d044fba76165c9402075a4250c33.jpg) #### 5.2.3.2 控制器层方法 ``` @RequestMapping("/addGoods") public String addGoods(@ModelAttribute("goods") Goods goods , HttpServletRequest request, String act) throws IOException { return goodsService.addGoods(goods,request,act); } ``` #### 5.2.3.3 业务层接口及实现 ``` String addGoods(Goods goods, HttpServletRequest request, String act) throws IOException; ``` ``` @Override public String addGoods(Goods goods, HttpServletRequest request, String act) throws IOException { MultipartFile myfile = goods.getFileName(); //如果选择了上传文件,将文件上传到指定的目录images if(!myfile.isEmpty()) { //上传文件路径(生产环境) //String path = request.getServletContext().getRealPath("/images/"); //获得上传文件原名 //上传文件路径(开发环境) String path = "F:/online_shopping/online_shopping/src/main/resources/static/images"; //获得上传文件原名 String fileName = myfile.getOriginalFilename(); //对文件重命名 String fileNewName = ReFilenameUtils.replaceFileName(fileName); File filePath = new File(path + File.separator + fileNewName); //如果文件目录不存在,创建目录 if(!filePath.getParentFile().exists()) { filePath.getParentFile().mkdirs(); } //将上传文件保存到一个目标文件中 myfile.transferTo(filePath); //将重命名后的图片名存到goods对象中,添加时使用 goods.setGpicture(fileNewName); goods.setEtime(new Date()); goods.setUtime(new Date()); } if("add".equals(act)) { int n = goodsMapper.addGoods(goods); if(n > 0)//成功 return "redirect:/goods/selectAllGoodsByPage?currentPage=1&act=select"; //失败 return "admin/addGoods"; }else {//修改 int n = goodsMapper.updateGoods(goods); if(n > 0)//成功 return "redirect:/goods/selectAllGoodsByPage?currentPage=1&act=updateSelect"; //失败 return "admin/UpdateAGoods"; } } ``` #### 5.2.3.4 持久层 ``` int updateGoods(Goods goods); ``` #### 5.2.3.5 映射文件 ``` update goods_table set gname = #{gname}, description = #{description}, goprice = #{goprice}, grprice = #{grprice}, gstore = #{gstore}, gpicture = #{gpicture}, isRecommend = #{isRecommend}, isAdvertisement = #{isAdvertisement}, goodstype_id = #{goodstype_id} where id = #{id} ``` ### 5.2.4 商品删除 #### 5.2.4.1 控制器层方法 ``` @RequestMapping("/delete") @ResponseBody public String delete(Integer id) { return goodsService.delete(id); } ``` #### 5.2.4.2 业务层接口及实现方法 ``` String delete(Integer id); ``` ``` @Override public String delete(Integer id) { if(goodsMapper.selectCartGoods(id).size() > 0 || goodsMapper.selectFocusGoods(id).size() > 0 || goodsMapper.selectOrderGoods(id).size() > 0) return "no"; else { goodsMapper.deleteAGoods(id); return "/goods/selectAllGoodsByPage?currentPage=1&act=deleteSelect"; } } ``` #### 5.2.4.3 持久层 ``` //以String类型为键,以Object类型为值的键值对;其中键是属性名[String],值则是其对应的值[多种类型利用父类Object表达]。 List> selectFocusGoods(Integer id); List> selectCartGoods(Integer id); List> selectOrderGoods(Integer id);
int  deleteAGoods(Integer id);
#### 5.2.4.4 映射文件
<delete id="deleteAGoods" parameterType="Integer">
    delete from goods_table where id=#{id}
</delete>
``` ### 5.2.5 商品添加 #### 5.2.5.1 视图层页面 【src/main/resources/templates/admin/addGoods.html】 ``` 商品类型添加页面



添加商品


``` ![屏幕截图 2021-08-14 144401](https://img-hello-world.oss-cn-beijing.aliyuncs.com/imgs/05593ccc94d3b79dc0cd454dad929ada.jpg) #### 5.2.5.2 控制器层方法 ``` @RequestMapping("/toAddGoods") public String toAddGoods(@ModelAttribute("goods") Goods goods,Model model){ goods.setIsAdvertisement(0); goods.setIsRecommend(1);
    return goodsService.toAddGoods(goods,model);
}
@RequestMapping("/addGoods")
public String addGoods(@ModelAttribute("goods") Goods goods , HttpServletRequest request, String act) throws IOException {
    return goodsService.addGoods(goods,request,act);
}
#### 5.2.5.3 业务层接口及实现
String addGoods(Goods goods, HttpServletRequest request, String act) throws IOException;

String toAddGoods(Goods goods, Model model);

@Override public String addGoods(Goods goods, HttpServletRequest request, String act) throws IOException { MultipartFile myfile = goods.getFileName(); //如果选择了上传文件,将文件上传到指定的目录images if(!myfile.isEmpty()) { //上传文件路径(生产环境) //String path = request.getServletContext().getRealPath("/images/"); //获得上传文件原名 //上传文件路径(开发环境) String path = "F:/online_shopping/online_shopping/src/main/resources/static/images"; //获得上传文件原名 String fileName = myfile.getOriginalFilename(); //对文件重命名 String fileNewName = ReFilenameUtils.replaceFileName(fileName); File filePath = new File(path + File.separator + fileNewName); //如果文件目录不存在,创建目录 if(!filePath.getParentFile().exists()) { filePath.getParentFile().mkdirs(); } //将上传文件保存到一个目标文件中 myfile.transferTo(filePath); //将重命名后的图片名存到goods对象中,添加时使用 goods.setGpicture(fileNewName); goods.setEtime(new Date()); goods.setUtime(new Date()); } if("add".equals(act)) { int n = goodsMapper.addGoods(goods); if(n > 0)//成功 return "redirect:/goods/selectAllGoodsByPage?currentPage=1&act=select"; //失败 return "admin/addGoods"; }else {//修改 int n = goodsMapper.updateGoods(goods); if(n > 0)//成功 return "redirect:/goods/selectAllGoodsByPage?currentPage=1&act=updateSelect"; //失败 return "admin/UpdateAGoods"; } } @Override public String toAddGoods(Goods goods, Model model) { model.addAttribute("goodsType", goodsTypeMapper.selectAllType()); return "admin/addGoods"; }

#### 5.2.5.4 持久层

int addGoods(Goods goods);

#### 5.2.5.5 映射文件
<insert id="addGoods" parameterType="pers.xsc.online_shopping.entity.Goods">
    insert into goods_table (id,gname,description,goprice,grprice,gstore,gpicture,isRecommend,isAdvertisement,goodstype_id,etime,utime)
    values (null, #{gname},#{description}, #{goprice}, #{grprice}, #{gstore}, #{gpicture},#{isRecommend}, #{isAdvertisement}, #{goodstype_id},#{etime},#{utime})
</insert>
## 5.3 商品类型管理
### 5.3.1 商品类型展示
#### 5.3.1.1 视图层页面
【src/main/resources/templates/admin/selectGoodsType.html】
查询类型页面



商品类型列表

类型ID 类型名称 类型描述 类型创建时间 类型更新时间 操作
删除
![屏幕截图 2021-08-14 142842](https://img-hello-world.oss-cn-beijing.aliyuncs.com/imgs/634d28f5b508795be4e536a780456670.jpg)
#### 5.3.1.2 实体层

package pers.xsc.online_shopping.entity;

import java.util.Date;

public class GoodsType { private int id; private String typename; private String description;//类型描述 private Date ctime;//创建时间 private Date utime;//更新时间

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getTypename() {
    return typename;
}

public void setTypename(String typename) {
    this.typename = typename;
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

public Date getCtime() {
    return ctime;
}

public void setCtime(Date ctime) {
    this.ctime = ctime;
}

public Date getUtime() {
    return utime;
}

public void setUtime(Date utime) {
    this.utime = utime;
}

}

#### 5.3.1.3 控制器层方法

package pers.xsc.online_shopping.controller.admin;

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import pers.xsc.online_shopping.entity.GoodsType; import pers.xsc.online_shopping.service.admin.GoodsTypeService;

import java.util.Date;

@Controller @RequestMapping("/type") public class TypeController { @Autowired GoodsTypeService goodsTypeService;

@RequestMapping("/selectAllTypeByPage")
public String selectAllTypeByPage(Model model , int currentPage){
    return goodsTypeService.selectAllTypeByPage(model,currentPage);
}

}

#### 5.3.1.4 业务层接口及实现

package pers.xsc.online_shopping.service.admin;

import org.springframework.ui.Model; import pers.xsc.online_shopping.entity.GoodsType;

public interface GoodsTypeService {

public String selectAllTypeByPage(Model model , int currentPage);

}

package pers.xsc.online_shopping.service.admin.impl;

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.ui.Model; import pers.xsc.online_shopping.entity.GoodsType; import pers.xsc.online_shopping.exception.CustomException; import pers.xsc.online_shopping.exception.ExceptionEnum; import pers.xsc.online_shopping.mapper.admin.GoodsMapper; import pers.xsc.online_shopping.mapper.admin.GoodsTypeMapper; import pers.xsc.online_shopping.service.admin.GoodsTypeService; import pers.xsc.online_shopping.utils.ResultUtils;

import java.util.List;

@Service public class GoodsTypeServiceImpl implements GoodsTypeService { @Autowired GoodsTypeMapper goodsTypeMapper;

@Override
public String selectAllTypeByPage(Model model, int currentPage) {
    //共多少个类型
    int totalCount = goodsTypeMapper.selectAll();
    //计算共多少页
    int pageSize = 5;
    int totalPage = (int)Math.ceil(totalCount*1.0/pageSize);
    List<GoodsType> typeByPage = goodsTypeMapper.selectAllTypeByPage((currentPage-1)*pageSize, pageSize);
    model.addAttribute("allTypes", typeByPage);
    model.addAttribute("totalPage", totalPage);
    model.addAttribute("currentPage", currentPage);
    return "admin/selectGoodsType";
}

}

#### 5.3.1.5 持久层

package pers.xsc.online_shopping.mapper.admin;

import org.apache.ibatis.annotations.Param; import pers.xsc.online_shopping.entity.GoodsType;

import java.util.List;

public interface GoodsTypeMapper { int selectAll(); List selectAllTypeByPage(@Param("startIndex") int startIndex, @Param("perPageSize") int perPageSize); }

#### 5.3.1.6 映射文件
<select id="selectAll"  resultType="integer">
    select count(*) from goodstype_table
</select>

<!-- 分页查询 -->
<select id="selectAllTypeByPage"  resultType="pers.xsc.online_shopping.entity.GoodsType">
    select * from goodstype_table  limit #{startIndex}, #{perPageSize}
</select>
``` ### 5.3.2 商品类型添加 #### 5.3.2.1 视图层页面 ``` 商品类型添加页面



添加类型


``` ![屏幕截图 2021-08-14 144444](https://img-hello-world.oss-cn-beijing.aliyuncs.com/imgs/8241dbd3f2ac213da7c4023de348c25d.jpg) #### 5.3.2.2 控制器层方法 ``` @RequestMapping("/toAddType") public String toAddType(@ModelAttribute("goodsType") GoodsType goodsType){ return "admin/addType"; }
@RequestMapping("/addType")
public String addType(@ModelAttribute("goodsType") GoodsType goodsType){
    goodsType.setCtime(new Date());
    goodsType.setUtime(new Date());
    return goodsTypeService.addType(goodsType);
}
#### 5.3.2.3 业务层接口及实现

public String addType(GoodsType goodsType);

@Override public String addType(GoodsType goodsType) {

    Integer ID = goodsTypeMapper.addType(goodsType);
    if(ID == null){
        throw new CustomException(ExceptionEnum.INSERT_ERROR.getCode(),ExceptionEnum.INSERT_ERROR.getMsg());
    }
    return "redirect:/type/selectAllTypeByPage?currentPage=1";
}
#### 5.3.2.4 持久层

int addType(GoodsType goodsType);

#### 5.3.2.5 映射文件

insert into goodstype_table(id,typename,description,ctime,utime) values (null,#{typename},#{description},#{ctime},#{utime})

## 5.4 订单管理
### 5.4.1 视图层页面
【src/main/resources/templates/admin/allOrder.html】
主页



订单列表

订单ID 用户邮箱 订单金额 订单状态 下单日期
![屏幕截图 2021-08-14 155225](https://img-hello-world.oss-cn-beijing.aliyuncs.com/imgs/1dbbca4fc889337b74644f416dcf11d0.jpg)
### 5.4.2 实体类

package pers.xsc.online_shopping.entity;

public class Order { private Integer id; private Integer usertable_id; private Double amount; private Integer status; private String otime;

public Integer getId() {
    return id;
}

public void setId(Integer id) {
    this.id = id;
}

public Integer getUsertable_id() {
    return usertable_id;
}

public void setUsertable_id(Integer usertable_id) {
    this.usertable_id = usertable_id;
}

public Double getAmount() {
    return amount;
}

public void setAmount(Double amount) {
    this.amount = amount;
}

public Integer getStatus() {
    return status;
}

public void setStatus(Integer status) {
    this.status = status;
}

public String getOtime() {
    return otime;
}

public void setOtime(String otime) {
    this.otime = otime;
}

}

### 5.4.3 控制器层方法

package pers.xsc.online_shopping.controller.admin;

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import pers.xsc.online_shopping.service.admin.OrderService;

@Controller public class OrderController { @Autowired OrderService orderService; @RequestMapping("/selectOrder") public String selectOrder(Model model , int currentPage){ return orderService.selectOrder(model,currentPage); }

}

### 5.4.4 业务层接口及实现

package pers.xsc.online_shopping.service.admin;

import org.springframework.ui.Model;

public interface OrderService { String selectOrder(Model model, int currentPage); }

package pers.xsc.online_shopping.service.admin.impl;

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.ui.Model; import pers.xsc.online_shopping.mapper.admin.OrderMapper; import pers.xsc.online_shopping.service.admin.OrderService;

import java.util.List; import java.util.Map;

@Service public class OrderServiceImpl implements OrderService { @Autowired OrderMapper orderMapper; @Override public String selectOrder(Model model, int currentPage) { //共多少个订单 int totalCount = orderMapper.selectAllOrder(); //计算共多少页 int pageSize = 5; int totalPage = (int)Math.ceil(totalCount1.0/pageSize); List<Map<String, Object>> orderByPage = orderMapper.selectOrderByPage((currentPage-1)pageSize, pageSize); model.addAttribute("allOrders", orderByPage); model.addAttribute("totalPage", totalPage); model.addAttribute("currentPage", currentPage); return "admin/allOrder"; } }

### 5.4.5 持久层

package pers.xsc.online_shopping.mapper.admin;

import org.apache.ibatis.annotations.Param;

import java.util.List; import java.util.Map;

public interface OrderMapper { int selectAllOrder();

List<Map<String, Object>> selectOrderByPage(@Param("startIndex") int startIndex, @Param("perPageSize") int perPageSize);

}

### 5.4.6 映射文件
``` ## 5.5 用户管理 ### 5.5.1 用户列表 #### 5.5.1.1 视图层页面 【src/main/resources/templates/admin/allUser.html】 ``` 主页



商品列表

用户ID 用户邮箱 删除
删除
#### 5.5.1.2 控制器层方法

package pers.xsc.online_shopping.controller.admin;

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import pers.xsc.online_shopping.entity.User; import pers.xsc.online_shopping.service.admin.UserService;

import javax.servlet.http.HttpSession;

@Controller public class UserController { @Autowired UserService userService;

@RequestMapping("/selectUser")
public String selectUser(Model model, int currentPage) {
    return userService.selectUser(model, currentPage);
}

}

#### 5.5.1.3 业务层接口及方法

package pers.xsc.online_shopping.service.admin;

import org.springframework.ui.Model;

public interface UserService { String selectUser(Model model, int currentPage); }

package pers.xsc.online_shopping.service.admin.impl;

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.ui.Model; import pers.xsc.online_shopping.entity.User; import pers.xsc.online_shopping.mapper.admin.UserMapper; import pers.xsc.online_shopping.service.admin.UserService;

import java.util.List;

@Service public class UserServiceImpl implements UserService { @Autowired UserMapper userMapper; @Override public String selectUser(Model model, int currentPage) { //共多少个用户 int totalCount = userMapper.selectAllUser(); //计算共多少页 int pageSize = 5; int totalPage = (int)Math.ceil(totalCount1.0/pageSize); List typeByPage = userMapper.selectUserByPage((currentPage-1)pageSize, pageSize); model.addAttribute("allUsers", typeByPage); model.addAttribute("totalPage", totalPage); model.addAttribute("currentPage", currentPage); return "admin/allUser"; } }

#### 5.5.1.4 持久层

package pers.xsc.online_shopping.mapper.admin;

import org.apache.ibatis.annotations.Param; import pers.xsc.online_shopping.entity.User;

import java.util.List;

public interface UserMapper { List selectUserByPage(@Param("startIndex") int startIndex, @Param("perPageSize") int perPageSize); int selectAllUser(); }

#### 5.5.1.5 映射文件
``` ### 5.5.2 用户删除 #### 5.5.2.1 控制器层方法 ``` @RequestMapping("/deleteUser") @ResponseBody public String deleteUser(Model model, int id) { return userService.deleteUser(model, id); } ``` #### 5.5.2.2 业务层接口及其实现 ``` public String deleteUser(Model model, int id); ``` ``` @Override public String deleteUser(Model model, int id) { if(userMapper.selectCartUser(id).size() > 0 ||userMapper.selectOrderUser(id).size() > 0) { return "no"; }else { userMapper.deleteUser(id); return "/selectUser?currentPage=1"; } } ``` #### 5.5.2.3 持久层 ``` List> selectCartUser(int id); List> selectOrderUser(int id); int deleteUser(int id); ``` #### 5.5.2.4 映射文件 ``` delete from user_table where id = #{id} ``` ## 5.6 安全退出 ### 5.6.1 控制器层方法 ``` @RequestMapping("/loginOut") public String loginOut(@ModelAttribute("aUser")AUser aUser, HttpSession session) { session.invalidate(); return "admin/login"; } ```
评论区

索引目录