秒杀项目之普通商品展示及增删改查

接着上期内容:秒杀项目之用户验证_爱嘤斯塔的博客-CSDN博客

一、框架搭建

1、页面跳转方法

login.js文件:

           success(e){
               // 成功的回调函数
            layer.msg(e.message,{icon: 6},()=>{
                if(e.code===200){
                    location.href="goods/goodsList"
                }
            });
           }

2、进入layui网站,设置首页的样式

Tab选项卡 - 页面元素 - Layui

新建goodsList.js文件,暂未写内容

goodsList.ftl:

<!DOCTYPE html>
<html lang="en">
<head>
    <#include "../common/head.ftl">
    <style>
        .layui-this{
            background: deepskyblue !important;
        }
    </style>

</head>
<body class="layui-container layui-bg-orange">
<div class="layui-tab">
    <ul class="layui-tab-title">
        <li class="layui-this">普通商品</li>
        <li>秒杀商品</li>
    </ul>
    <div class="layui-tab-content">
        <div class="layui-tab-item layui-show">
            <table id="normal_goods" lay-filter="normal_goods"></table>
        </div>
        <div class="layui-tab-item">内容2</div>
    </div>
</div>
<#--引入js-->
<script src="/static/asset/js/project/goodsList.js"></script>
</body>
</html>

呈现出的界面:

 3、后台生成器生成goods数据

在goodsMapper中加入注解

@Repository

4、PageBean 

package com.example.seckill.util;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;


@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageBean {

    private int total;
    private int page = 1;
    private int rows = 5;
    private boolean pagination = true;
    private String url;
    private Map<String, String[]> ms;

    public void setMs(Map<String, String[]> ms) {
        this.ms = ms;
    }

    public int calcStartIndex() {
        return (page - 1) * rows;
    }

    public int calcMaxPage() {
        return total % rows == 0 ? total / rows : total / rows + 1;
    }

    public int nextPage() {
        return Math.min(page + 1, calcMaxPage());
    }

    public int prevPage() {
        return Math.max(page - 1, 1);
    }

    public void setRequest(HttpServletRequest req) {
        setUrl(req.getRequestURL().toString());
        setMs(req.getParameterMap());
        String page = req.getParameter("page");
        if (page == null) {
            setPage(1);
        } else {
            setPage(Integer.parseInt(page));
        }
        String rows = req.getParameter("rows");
        if (rows == null) {
            setRows(5);
        } else {
            setRows(Integer.parseInt(rows));
        }
        String pagination = req.getParameter("pagination");
        if ("false".equals(pagination)) {
            setPagination(false);
        }
    }

}

5、Mybatis Plus02中的分页配置

MybatisPlusConfig :

package com.example.seckill.config;
 
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
@Configuration
public class MybatisPlusConfig {
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor() {
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//            加入分页拦截器
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
            return interceptor;
        }
}

6、编写得到数据方法

IGoodsService:

package com.example.seckill.service;

import com.example.seckill.pojo.Goods;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.seckill.util.PageBean;
import com.example.seckill.util.response.ResponseResult;

import java.util.List;

/**
 * <p>
 * 商品信息表 服务类
 * </p>
 *
 * @author lv
 * @since 2022-03-17
 */
public interface IGoodsService extends IService<Goods> {

    ResponseResult<List<Goods>> getGoodsList(Goods goods, PageBean pageBean);
}

GoodsServiceImpl :

package com.example.seckill.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.example.seckill.pojo.Goods;
import com.example.seckill.mapper.GoodsMapper;
import com.example.seckill.service.IGoodsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.seckill.util.PageBean;
import com.example.seckill.util.response.ResponseResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 * 商品信息表 服务实现类
 * </p>
 *
 * @author lv
 * @since 2022-03-17
 */
@Service
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements IGoodsService {

    @Autowired
    GoodsMapper goodsMapper;

    @Override
    public ResponseResult<List<Goods>> getGoodsList(Goods goods, PageBean pageBean) {
//        分页
        Page<Goods> page=PageDTO.of(pageBean.getPage(),pageBean.getRows());
//        模糊查询+条件
        QueryWrapper<Goods> wrapper=new QueryWrapper<>();
        if(StringUtils.isNotEmpty(goods.getGoodsName())){
              wrapper.like("goods_name","%"+goods.getGoodsName()+"%");
        }
//        进数据库查出结果
        Page<Goods> result=goodsMapper.selectPage(page,wrapper);
        return ResponseResult.success(result.getRecords(),page.getTotal());
    }
}

GoodsController :

package com.example.seckill.controller;

import com.example.seckill.pojo.Goods;
import com.example.seckill.service.IGoodsService;
import com.example.seckill.util.PageBean;
import com.example.seckill.util.response.ResponseResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * <p>
 * 商品信息表 前端控制器
 * </p>
 *
 * @author lv
 * @since 2022-03-17
 */
@RestController
@RequestMapping("/goods")
public class GoodsController {

    @Autowired
    private IGoodsService goodsService;

    @RequestMapping("/queryAll")
    public ResponseResult<List<Goods>> getGoodsList(Goods goods, HttpServletRequest request){
        PageBean pageBean=new PageBean();
        pageBean.setRequest(request);
        return goodsService.getGoodsList(goods,pageBean);
    }

}

后端查看数据成功: 

7、将图片放到static包中

8、前端得到数据

let layer

layui.define(()=>{
    let table=layui.table
    layer=layui.layer


    table.render({
        elem: '#normal_goods'
        ,height: 500
        ,url: '/goods/queryAll' //数据接口
        ,page: true //开启分页
        ,parseData(res){ //res 即为原始返回的数据
            return {
                "code": res.code===200?0:1, //解析接口状态
                "msg": res.message, //解析提示文本
                "count": res.total, //解析数据长度
                "data": res.data //解析数据列表
            };
        }
        ,cols: [[ //表头
            {field: 'gid', title: '商品编号', width:80, sort: true, fixed: 'left'}
            ,{field: 'goodsName', title: '商品名字'}
            ,{field: 'goodsTitle', title: '商品标题'}
            ,{field: 'goodsImg',
              title: '商品图片',
              width:200,
              templet: (goods)  => `<b onmouseover='showImg("${goods.goodsImg}",this)'>` + goods.goodsImg + `</b>` }
            ,{field: 'goodsDetail', title: '商品详情'}
            ,{field: 'goodsPrice', title: '商品价格', sort: true}
            ,{field: 'goodsStock', title: '商品库存', sort: true}
        ]]
    });

})
let showImg = (src,obj)=> {
    layer.tips(`<img src="${src}" width="100px">`, obj);
}

9、呈现界面

二、搜索功能

1、添加搜索界面

goodsList.ftl:

            <div class="layui-form-item">
                <label class="layui-form-label">搜索栏</label>
                <div class="layui-input-inline">
                    <input type="text" id="normal_name" name="text" placeholder="请输入搜索内容" class="layui-input">
                </div>
                <div class="layui-input-inline">
                    <button class="layui-btn layui-btn-primary" id="normal_search">🔍</button>
                    <button class="layui-btn layui-btn-primary" id="normal_add">增加</button>
                </div>
            </div>
<!DOCTYPE html>
<html lang="en">
<head>
    <#include "../common/head.ftl">
    <style>
        .layui-this{
            background: deepskyblue !important;
        }
    </style>

</head>
<body class="layui-container layui-bg-orange">
<div class="layui-tab">
    <ul class="layui-tab-title">
        <li class="layui-this">普通商品</li>
        <li>秒杀商品</li>
    </ul>
    <div class="layui-tab-content">
        <div class="layui-tab-item layui-show">

            <div class="layui-form-item">
                <label class="layui-form-label">搜索栏</label>
                <div class="layui-input-inline">
                    <input type="text" id="normal_name" name="text" placeholder="请输入搜索内容" class="layui-input">
                </div>
                <div class="layui-input-inline">
                    <button class="layui-btn layui-btn-primary" id="normal_search">🔍</button>
                    <button class="layui-btn layui-btn-primary" id="normal_add">增加</button>
                </div>
            </div>

            <table id="normal_goods" lay-filter="normal_goods"></table>
        </div>
        <div class="layui-tab-item">内容2</div>
    </div>
</div>
<#--引入js-->
<script src="/static/asset/js/project/goodsList.js"></script>
</body>
</html>

2、js实现搜索功能

goodsList.js:

page、limit重新设定名称,否则无法根据选择展示的几条数据而更改,如无法显示20条每页

    let $=layui.jquery

      //用于对分页请求的参数:page、limit重新设定名称
        request: {
            pageName: 'page' //页码的参数名称,默认:page
            ,limitName: 'rows' //每页数据量的参数名,默认:limit
        }

        $("#normal_search").click(()=>{
        let goodsName=$("#normal_name").val()
        // 【JS】自动化渲染的重载,重载表格
        normal_table.reload({
        where: {
            //设定异步数据接口的额外参数,height: 300
            goodsName
        },
            page:{
                curr:1 //current
            }
});
    })
let layer

layui.define(()=>{
    let table=layui.table
    layer=layui.layer
    let $=layui.jquery


    let normal_table=table.render({
        elem: '#normal_goods'
        ,height: 500
        ,url: '/goods/queryAll' //数据接口
        ,page: true //开启分页
        ,parseData(res){ //res 即为原始返回的数据
            return {
                "code": res.code===200?0:1, //解析接口状态
                "msg": res.message, //解析提示文本
                "count": res.total, //解析数据长度
                "data": res.data //解析数据列表
            };
        },
        //用于对分页请求的参数:page、limit重新设定名称
        request: {
            pageName: 'page' //页码的参数名称,默认:page
            ,limitName: 'rows' //每页数据量的参数名,默认:limit
        }
        ,cols: [[ //表头
            {field: 'gid', title: '商品编号', width:80, sort: true, fixed: 'left'}
            ,{field: 'goodsName', title: '商品名字'}
            ,{field: 'goodsTitle', title: '商品标题'}
            ,{field: 'goodsImg',
              title: '商品图片',
              width:200,
              templet: (goods)  => `<b onmouseover='showImg("${goods.goodsImg}",this)'>` + goods.goodsImg + `</b>` }
            ,{field: 'goodsDetail', title: '商品详情'}
            ,{field: 'goodsPrice', title: '商品价格', sort: true}
            ,{field: 'goodsStock', title: '商品库存', sort: true}
        ]]
    });

    $("#normal_search").click(()=>{
        let goodsName=$("#normal_name").val()
        // 【JS】自动化渲染的重载,重载表格
        normal_table.reload({
        where: {
            //设定异步数据接口的额外参数,height: 300
            goodsName
        },
            page:{
                curr:1 //current
            }
});
    })
})
let showImg = (src,obj)=> {
    layer.tips(`<img src="${src}" width="100px">`, obj);
}

三、商品的操作

1、给表格增加操作列

goodsList.ftl:放到表单后

            <script type="text/html" id="button_1">
                <a class="layui-btn layui-btn-xs" lay-event="normal_del">删除</a>
                <a class="layui-btn layui-btn-xs" lay-event="normal_edit">编辑</a>
            </script>

 goodsList.js:

{field: 'operate', title: '商品操作',toolbar: '#button_1'}

2、弹出框界面

goodsOperate.js:编辑框读取数据

let form, $

layui.define(() => {
    form = layui.form
    $ = layui.jquery

    loadFormData()
})

// 子界面引用父界面使用parent
function loadFormData() {
    if (parent.row) {
        form.val('goods_operate', $.extend({}, parent.row || {}));
    }
}
/*
将表单的对象转成一个值,丢出去
父界面想使用子界面直接调用getFormData方法即可
*/
function getFormData() {
    return form.val("goods_operate")
}


goodsOperate.ftl:

<!DOCTYPE html>
<html lang="zh">
<head>
    <link rel="stylesheet" href="/static/asset/js/layui/css/layui.css" media="all">
    <script src="/static/asset/js/layui/layui.js" charset="utf-8"></script>
</head>
<body>
<div>
    <div class="layui-container" style="padding-top: 20px">
        <form class="layui-form layui-form-pane" lay-filter="goods_operate">
            <input type="hidden" name="gid"/>
            <div class="layui-form-item">
                <label class="layui-form-label">商品名称</label>
                <div class="layui-input-block">
                    <input type="text" name="goodsName" placeholder="请输入标题" class="layui-input">
                </div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label">商品标题</label>
                <div class="layui-input-block">
                    <input type="text" name="goodsTitle" placeholder="请输入" class="layui-input">
                </div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label">商品图片</label>
                <div class="layui-input-block">
                    <select name="goodsImg">
                        <option value="">---请选择---</option>
                        <option value="/static/images/a.png">小米10</option>
                        <option value="/static/images/b.png">小米11</option>
                        <option value="/static/images/c.png">红米pro</option>
                    </select>
                </div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label">商品价格</label>
                <div class="layui-input-block">
                    <input type="text" name="goodsPrice" placeholder="请输入价格" class="layui-input">
                </div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label">商品库存</label>
                <div class="layui-input-block">
                    <input type="text" name="goodsStock" placeholder="请输入库存" class="layui-input">
                </div>
            </div>
            <div class="layui-form-item layui-form-text">
                <label class="layui-form-label">商品描述</label>
                <div class="layui-input-block">
                    <textarea name="goodsDetail" placeholder="请输入内容" class="layui-textarea"></textarea>
                </div>
            </div>
        </form>
    </div>
</div>
<script src="/static/asset/js/project/goodsOperate.js"></script>
</body>
</html>

3、后端增加、删除、修改方法

IGoodsService:

    ResponseResult<?> goodsInsert(Goods goods);

    ResponseResult<?> goodsEdit(Goods goods);

    ResponseResult<?> deleteGoodsById(Long goodsId);

GoodsServiceImpl:

    @Override
    public ResponseResult<?> goodsInsert(Goods goods) {
        boolean b=this.save(goods);
        if(b){
            return ResponseResult.success();
        }
        return ResponseResult.failure(ResponseResultCode.GOODS_ADD_ERROR);
    }

    @Override
    public ResponseResult<?> goodsEdit(Goods goods) {
        boolean b=this.updateById(goods);
        if(b){
            return ResponseResult.success();
        }
        return ResponseResult.failure(ResponseResultCode.GOODS_EDIT_ERROR);
    }

    @Override
    public ResponseResult<?> deleteGoodsById(Long goodsId) {
        boolean b = this.removeById(goodsId);
        if (b) {
            return ResponseResult.success();
        }
        return ResponseResult.failure(ResponseResultCode.UNKNOWN);
    }

GoodsController:

    @RequestMapping("/insert")
    public ResponseResult<?> goodsInsert(Goods goods){
        return goodsService.goodsInsert(goods);
    }

    @RequestMapping("/edit")
    public ResponseResult<?> goodsEdit(Goods goods){
        return goodsService.goodsEdit(goods);
    }

    @RequestMapping("/del/{gid}")
    public ResponseResult<?> deleteGoodsById(@PathVariable("gid") Long gid) {
        return goodsService.deleteGoodsById(gid);
    }

4、实现增加、删除、修改方法

goodList.js

let layer
var row

layui.define(()=>{
    let table=layui.table
    layer=layui.layer
    let $=layui.jquery


    let normal_table=table.render({
        elem: '#normal_goods'
        ,height: 500
        ,url: '/goods/queryAll' //数据接口
        ,page: true //开启分页
        ,parseData(res){ //res 即为原始返回的数据
            return {
                "code": res.code===200?0:1, //解析接口状态
                "msg": res.message, //解析提示文本
                "count": res.total, //解析数据长度
                "data": res.data //解析数据列表
            };
        },
        //用于对分页请求的参数:page、limit重新设定名称
        request: {
            pageName: 'page' //页码的参数名称,默认:page
            ,limitName: 'rows' //每页数据量的参数名,默认:limit
        }
        ,cols: [[ //表头
            {field: 'gid', title: '商品编号', width:80, sort: true, fixed: 'left'}
            ,{field: 'goodsName', title: '商品名字'}
            ,{field: 'goodsTitle', title: '商品标题'}
            ,{field: 'goodsImg',
              title: '商品图片',
              width:200,
              templet: (goods)  => `<b onmouseover='showImg("${goods.goodsImg}",this)'>` + goods.goodsImg + `</b>` }
            ,{field: 'goodsDetail', title: '商品详情'}
            ,{field: 'goodsPrice', title: '商品价格', sort: true}
            ,{field: 'goodsStock', title: '商品库存', sort: true}
            ,{field: 'operate', title: '商品操作',toolbar: '#button_1'}
        ]]
    });

    // 刷新表格
    let reloadTable=()=>{
        let goodsName=$("#normal_value").val()
        // 【JS】自动化渲染的重载,重载表格
        normal_table.reload({
            where: {
                //设定异步数据接口的额外参数,height: 300
                goodsName
            },
            page:{
                curr:1 //current
            }
        });
    }
    // 搜索
    $("#normal_search").click(reloadTable)

    // 增加
    $("#normal_add").click(()=>{
        row = null
        openDialog()
    })

    //工具条事件
    table.on('tool(normal_goods)', function(obj) { //注:tool 是工具条事件名,test 是 table 原始容器的属性 lay-filter="对应的值"
        let data = obj.data; //获得当前行数据
        let layEvent = obj.event; //获得 lay-event 对应的值(也可以是表头的 event 参数对应的值)
        let tr = obj.tr; //获得当前行 tr 的 DOM 对象(如果有的话)

        if (layEvent === 'normal_del') { //删除
            row = data//获得当前行的数据
            let url="/goods/del/"+data.gid
            layer.confirm('确定删除吗?',{title:'删除'}, function(index){
                //向服务端发送删除指令og
                $.getJSON(url,{gid:data.gid}, function(ret){
                    layer.close(index);//关闭弹窗
                    reloadTable()
                });
                layer.close(index);//关闭弹窗

            });
        }
        if (layEvent === 'normal_edit') { //编辑
            row = data
            openDialog()
        }
    })


    // 页面弹出
    let openDialog=()=>{
        // 如果是iframe层
        layer.open({
            type: 2,
            content: '/goods/goodsOperate', //这里content是一个URL,如果你不想让iframe出现滚动条,你还可以content: ['http://sentsin.com', 'no']
            area:['800px','600px'],
            btn: ['确定','取消'],
            yes(index,layero){
                let url="/goods/insert"
                // 拿到表格数据
                let data=$(layero).find("iframe")[0].contentWindow.getFormData()
                if(row) {
                    url="/goods/edit"
                }
                $.ajax({
                    url,
                    data,
                    datatype: "json",
                    success(res){
                        layer.closeAll()
                        reloadTable()
                        layer.msg(res.message)
                    }
                })

            }
        });
    }


})
// 图片显示
let showImg = (src,obj)=> {
    layer.tips(`<img src="${src}" width="100px">`, obj);
}

5、展示结果

增加:

 

编辑:

 

 

删除: 

 

本期内容结束~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值