商城-商品管理-商品查询

  • 4.商品查询
    • 4.1.效果预览
    • 4.2.从0开始
    • 4.3.页面实现
      • 4.3.1.页面基本表格
      • 4.3.2.上下架状态按钮
    • 4.4.后台提供接口
      • 4.4.1.实体类
      • 4.4.2.controller
      • 4.4.3.service
      • 4.4.4.mapper
      • 4.4.5.Category中拓展查询名称的功能
    • 4.5.测试

4.商品查询

4.1.效果预览

接下来,我们实现商品管理的页面,先看下我们要实现的效果:

可以看出整体是一个table,然后有新增按钮。是不是跟昨天写品牌管理很像?

模板代码在分别在Goods.vue

4.2.从0开始

接下来,我们自己来实现一下,新建两个组件:MyGoods.vue和MyGoodsForm.vue

内容先随意:

<template><v-card>MyGoods</v-card>
</template><script>export default {name: "my-goods",data() {return {}}}
</script><style scoped></style>

然后修改menu.js,新建一个菜单:

修改router/index.js,添加一个路由:

预览一下:

4.3.页面实现

4.3.1.页面基本表格

商品列表页与品牌列表页几乎一样,我们可以直接去复制一份过来,然后进行一些修改。

首先,字段不一样,商品列表也展示的SPU信息,包含以下字段:

id:
title:标题
cname:商品分类名称
bname:品牌名称

完整代码:

<template><v-card><v-card-title><v-btn color="primary" @click="addGoods">新增商品</v-btn><!--搜索框,与search属性关联--><v-spacer/><v-text-field label="输入关键字搜索" v-model.lazy="search" append-icon="search" hide-details/></v-card-title><v-divider/><v-data-table:headers="headers":items="goodsList":search="search":pagination.sync="pagination":total-items="totalGoods":loading="loading"class="elevation-1"><template slot="items" slot-scope="props"><td>{{ props.item.id }}</td><td class="text-xs-center">{{ props.item.title }}</td><td class="text-xs-center">{{props.item.cname}}</td><td class="text-xs-center">{{ props.item.bname }}</td><td class="justify-center layout"><v-btn color="info" @click="editGoods(props.item)">编辑</v-btn><v-btn color="warning">删除</v-btn><v-btn >下架</v-btn></td></template></v-data-table><!--弹出的对话框--><v-dialog max-width="500" v-model="show" persistent><v-card><!--对话框的标题--><v-toolbar dense dark color="primary"><v-toolbar-title>{{isEdit ? '修改' : '新增'}}商品</v-toolbar-title><v-spacer/><!--关闭窗口的按钮--><v-btn icon @click="closeWindow"><v-icon>close</v-icon></v-btn></v-toolbar><!--对话框的内容,表单--><v-card-text class="px-5"><my-goods-form :oldGoods="oldGoods" /></v-card-text></v-card></v-dialog></v-card>
</template><script>// 导入自定义的表单组件import MyGoodsForm from './MyGoodsForm'export default {name: "my-goods",data() {return {search: '', // 搜索过滤字段totalGoods: 0, // 总条数goodsList: [], // 当前页品牌数据loading: true, // 是否在加载中pagination: {}, // 分页信息headers: [{text: 'id', align: 'center', value: 'id'},{text: '标题', align: 'center', sortable: false, value: 'title'},{text: '商品分类', align: 'center', sortable: false, value: 'cname'},{text: '品牌', align: 'center', value: 'bname', sortable: false,},{text: '操作', align: 'center', sortable: false}],show: false,// 控制对话框的显示oldGoods: {}, // 即将被编辑的商品信息isEdit: false, // 是否是编辑}},mounted() { // 渲染后执行// 查询数据this.getDataFromServer();},watch: {pagination: { // 监视pagination属性的变化deep: true, // deep为true,会监视pagination的属性及属性中的对象属性变化handler() {// 变化后的回调函数,这里我们再次调用getDataFromServer即可this.getDataFromServer();}},search: { // 监视搜索字段handler() {this.getDataFromServer();}}},methods: {getDataFromServer() { // 从服务的加载数的方法。// 发起请求this.$http.get("/item/spu/page", {params: {key: this.search, // 搜索条件page: this.pagination.page,// 当前页rows: this.pagination.rowsPerPage,// 每页大小sortBy: this.pagination.sortBy,// 排序字段desc: this.pagination.descending// 是否降序}}).then(resp => { // 这里使用箭头函数this.goodsList = resp.data.items;this.totalGoods = resp.data.total;// 完成赋值后,把加载状态赋值为falsethis.loading = false;})},addGoods() {// 修改标记this.isEdit = false;// 控制弹窗可见:this.show = true;// 把oldBrand变为nullthis.oldBrand = null;},editGoods(oldGoods){// 修改标记this.isEdit = true;// 控制弹窗可见:this.show = true;// 获取要编辑的brandthis.oldGoods = oldGoods;},closeWindow(){// 重新加载数据this.getDataFromServer();// 关闭窗口this.show = false;}},components:{MyGoodsForm}}
</script><style scoped></style>

主要的改动点:

  • 页面的v-data-table中的属性绑定修改。items指向goodsList,totalItems指向totalGoods

  • 页面渲染的字段名修改:字段改成商品的SPU字段:id、title,cname(商品分类名称),bname(品牌名称)

  • data属性修改了以下属性:

    • goodsList:当前页商品数据
    • totalGoods:商品总数
    • headers:头信息,需要修改头显示名称
    • oldGoods:准备要修改的商品
  • 加载数据的函数:getDataFromServer,请求的路径进行了修改,另外去除了跟排序相关的查询。SPU查询不排序

  • 新增商品的事件函数:清除了一些数据查询接口,只保留弹窗

查看效果:

因为没有编写查询功能,表格一直处于loading状态。

接下来看弹窗:

4.3.2.上下架状态按钮

另外,似乎页面少了对上下架商品的过滤,在原始效果图中是有的:

这在Vuetify中是一组按钮,我们查看帮助文档:

查看实例得到以下信息:

v-btn:一个按钮

v-btn-toggle:按钮组,内部可以有多个按钮,点击切换,有以下属性:

  • multiple:是否支持多选,默认是false
  • value:选中的按钮的值,如果是多选,结果是一个数组;单选,结果是点击的v-btn中的value值,因此按钮组的每个btn都需要指定value属性

改造页面:

首先在data中定义一个属性,记录按钮的值。

filter:{saleable: false, // 上架还是下架search: '', // 搜索过滤字段
}

这里我们的做法是定义一个filter属性,内部在定义search来关联过滤字段,saleable来关联上下架情况。

这样watch就必须监听filter,而不是只监听search了:

filter: {// 监视搜索字段handler() {this.getDataFromServer();},deep:true
}

另外,页面中与search有关的所有字段都需要修改成filter.search:

<!--搜索框,与search属性关联-->
<v-text-field label="输入关键字搜索" v-model.lazy="filter.search" append-icon="search" hide-details/>

然后,在页面中添加按钮组:

 <v-flex xs3>状态:<v-btn-toggle v-model="filter.saleable"><v-btn flat>全部</v-btn><v-btn flat :value="true">上架</v-btn><v-btn flat :value="false">下架</v-btn></v-btn-toggle>
</v-flex>

最后,不要忘了在查询时,将saleable携带上:

getDataFromServer() { // 从服务的加载数的方法。// 发起请求this.$http.get("/item/spu/page", {params: {key: this.filter.search, // 搜索条件saleable: this.filter.saleable, // 上下架page: this.pagination.page,// 当前页rows: this.pagination.rowsPerPage,// 每页大小}}).then(resp => { // 这里使用箭头函数this.goodsList = resp.data.items;this.totalGoods = resp.data.total;// 完成赋值后,把加载状态赋值为falsethis.loading = false;})
}

4.4.后台提供接口

页面已经准备好,接下来在后台提供分页查询SPU的功能:

4.4.1.实体类

SPU

@Table(name = "tb_spu")
public class Spu {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private Long brandId;private Long cid1;// 1级类目private Long cid2;// 2级类目private Long cid3;// 3级类目private String title;// 标题private String subTitle;// 子标题private Boolean saleable;// 是否上架private Boolean valid;// 是否有效,逻辑删除用private Date createTime;// 创建时间private Date lastUpdateTime;// 最后修改时间// 省略getter和setter
}

SPU详情

@Table(name="tb_spu_detail")
public class SpuDetail {@Idprivate Long spuId;// 对应的SPU的idprivate String description;// 商品描述private String specTemplate;// 商品特殊规格的名称及可选值模板private String specifications;// 商品的全局规格属性private String packingList;// 包装清单private String afterService;// 售后服务// 省略getter和setter
}

4.4.2.controller

先分析:

  • 请求方式:GET

  • 请求路径:/spu/page

  • 请求参数:

    • page:当前页
    • rows:每页大小
    • key:过滤条件
    • saleable:上架或下架
  • 返回结果:商品SPU的分页信息。

    • 要注意,页面展示的是商品分类和品牌名称,而数据库中保存的是id,怎么办?

      我们可以新建一个类,继承SPU,并且拓展cname和bname属性,写到ly-item-interface

      public class SpuBo extends Spu {String cname;// 商品分类名称String bname;// 品牌名称// 略 。。
      }
      

编写controller代码:

我们把与商品相关的一切业务接口都放到一起,起名为GoodsController,业务层也是这样

@RestController
public class GoodsController {@Autowiredprivate GoodsService goodsService;/*** 分页查询SPU* @param page* @param rows* @param key* @return*/@GetMapping("/spu/page")public ResponseEntity<PageResult<SpuBo>> querySpuByPage(@RequestParam(value = "page", defaultValue = "1") Integer page,@RequestParam(value = "rows", defaultValue = "5") Integer rows,@RequestParam(value = "key", required = false) String key) {// 分页查询spu信息PageResult<SpuBo> result = this.goodsService.querySpuByPageAndSort(page, rows, key);if (result == null || result.getItems().size() == 0) {return new ResponseEntity<>(HttpStatus.NOT_FOUND);}return ResponseEntity.ok(result);}
}

4.4.3.service

所有商品相关的业务(包括SPU和SKU)放到一个业务下:GoodsService。

@Service
public class GoodsService {@Autowiredprivate SpuMapper spuMapper;@Autowiredprivate CategoryService categoryService;@Autowiredprivate BrandMapper brandMapper;public PageResult<SpuBo> querySpuByPageAndSort(Integer page, Integer rows, Boolean saleable, String key) {// 1、查询SPU// 分页,最多允许查100条PageHelper.startPage(page, Math.min(rows, 100));// 创建查询条件Example example = new Example(Spu.class);Example.Criteria criteria = example.createCriteria();// 是否过滤上下架if (saleable != null) {criteria.orEqualTo("saleable", saleable);}// 是否模糊查询if (StringUtils.isNotBlank(key)) {criteria.andLike("title", "%" + key + "%");}Page<Spu> pageInfo = (Page<Spu>) this.spuMapper.selectByExample(example);List<SpuBo> list = pageInfo.getResult().stream().map(spu -> {// 2、把spu变为 spuBoSpuBo spuBo = new SpuBo();// 属性拷贝BeanUtils.copyProperties(spu, spuBo);// 3、查询spu的商品分类名称,要查三级分类List<String> names = this.categoryService.queryNameByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));// 将分类名称拼接后存入spuBo.setCname(StringUtils.join(names, "/"));// 4、查询spu的品牌名称Brand brand = this.brandMapper.selectByPrimaryKey(spu.getBrandId());spuBo.setBname(brand.getName());return spuBo;}).collect(Collectors.toList());return new PageResult<>(pageInfo.getTotal(), list);}
}

4.4.4.mapper

public interface SpuMapper extends Mapper<Spu> {}

4.4.5.Category中拓展查询名称的功能

页面需要商品的分类名称需要在这里查询,因此要额外提供查询分类名称的功能,

在CategoryService中添加功能:

public List<String> queryNameByIds(List<Long> ids) {return this.categoryMapper.selectByIdList(ids).stream().map(Category::getName).collect(Collectors.toList());
}

mapper的selectByIDList方法是来自于通用mapper。不过需要我们在mapper上继承一个通用mapper接口:

public interface CategoryMapper extends Mapper<Category>, SelectByIdListMapper<Category, Long> { // ...coding
}

4.5.测试

刷新页面,查看效果:

基本与预览的效果一致,OK!

商城-商品管理-商品查询相关推荐

  1. 商城-商品管理-商品修改

    商城-商品管理-商品修改 2.商品修改 2.1.编辑按钮点击事件 2.2.查询SpuDetail接口 2.3.查询sku 2.4.页面回显 2.5.页面提交 2.6.后台实现 2.6.1.Contro ...

  2. 商品管理 商品管理软件 用进销存软件做商品管理

    做生意的最不可少的软件就是进销存,告别手工记账,大大地提高运营效率. 如果光靠人工管理店铺,首先最基础的商品管理就很花时间. 商品管理是指一个零售商从分析顾客的需求入手,对商品组合.定价方法.促销活动 ...

  3. Vue实战之 9.商品管理 -- 商品列表

    1. 商品管理概述 商品管理模块用于维护电商平台的商品信息,包括商品的类型.参数.详情等.通过商品管理模块可以实现商品的添加.修改.展示和删除等功能. 2. 商品列表 实现商品列表布局效果 调用后台接 ...

  4. Vue实战电商系统-五商品管理

    Vue实战电商系统-五商品管理 商品管理 1.新建goods_cate子分支并上传码云 2.商品管理-商品分类 1.新建文件并配置路由 2.页面布局 3.获取分类列表数据 4.将数据渲染在树形表格控件 ...

  5. 易买网项目商品管理mysql_就易买网项目总结

    易买网项目总结 项目辅导教师-----原玉明 不知不觉又过了一个学期了,已然到了S2,懵懵懂懂的又要开始书写易买网项目了.回想当初书写易买网时的一无所知,到现在的略懂一二,我也学会了很多,有团队的合作 ...

  6. 电商后台商品管理和订单管理分享

    因负责公司的教育电商后台产品的重构和设计,在商品管理和订单管理上踩了一些坑,积累了一些自己的思考,现在整理出来,分享给大家. 对于后台产品经理来说,有面向业务方的内部后台系统,也有面向c端用户的后台支 ...

  7. 「超市管理系统——商品管理」 · Java Swing + MySQL JDBC开发

    项目下载:超市管理系统JavaSwing+MySQLJDBC开发_javamysql超市管理系统-互联网文档类资源-CSDN下载 1.9元付费赞助下载:超市管理系统JavaSwing+MySQLJDB ...

  8. 智慧零售erp通用版管理系统+门店管理+商品管理+厂商管理+财务管理+销售管理+仓储管理+Axure高保真交互ERP通用版零售行业web端简易版管理系统

    作品介绍:智慧零售erp通用版管理系统+门店管理+商品管理+厂商管理+财务管理+销售管理+仓储管理+Axure高保真交互ERP通用版零售行业web端简易版管理系统 原型交互及下载请点击:https:/ ...

  9. 智慧零售erp通用版管理系统+门店管理+商品管理+厂商管理+财务管理+销售管理+仓储管理+零售行业+web端管理系统+新零售管理后台+电商erp+收银系统+CRM系统+新零售o2o平台系统

    智慧零售erp通用版管理系统+门店管理+商品管理+厂商管理+财务管理+销售管理+仓储管理+零售行业+web端管理系统+新零售管理后台+电商erp+收银系统+CRM系统+新零售o2o平台系统 Axure ...

最新文章

  1. 树上问题 ---- Codeforces Round #722 (Div. 1) C. Trees of Tranquillity [dfs序区间的性质+最大不相交区间的性质]
  2. 第十一章 异常,日志,断言和调试
  3. OxyPlot 导出图片及 WPF 元素导出为图片的方法
  4. python找出有向图的所有环,Python:有向图中的所有简单路径
  5. 一路向左or一路向右
  6. 服务器中用于接收电子邮件,‎如何使用我的邮件服务器在 Odoo 中发送和接收电子邮件‎...
  7. js 各种事件 如:点击事件、失去焦点、键盘事件等
  8. java手机号正则验证(电信、联通、移动、香港)
  9. 搭建 LimeSurvey投票调查问卷系统
  10. 测试对比度的软件,WCAG颜色对比度检测工具,网页及App文字背景配色检测软件...
  11. 基于AVR-BootLoader,通过霜蝉远程串口可实现单片机的远程升级
  12. 一、音频基础知识 - 耳机接口标准
  13. QQ聊天记录统计可视化分析
  14. 如何在64位win7中使用未有签名的驱动程序
  15. 计算机无法读光盘,win7系统无法读取光盘数据怎么办 电脑光驱读不出光盘数据解决方法...
  16. 重装Windows 10系统
  17. linux网络驱动 poll,网络 – Linux网络驱动程序中的并发:probe()VS ndo_open(),ndo_start_xmit()VS NAPI poll()...
  18. 双屏、3屏拼接——A卡、N卡——Windows、Linux
  19. html 5 语音发送,HTML 5 语音合成
  20. 一天写多少行代码才算是好程序员?

热门文章

  1. 微信小程序入门四详情页面
  2. 当众社死,涨粉百万,社交牛逼症成新晋流量密码
  3. 2022-11-23 工作记录--Swiper/CSS-改变swiper滑动方向 + 修改文字的方向——解决 swiper反方向滑动时,超出一行省略号处理的文字也呈反方向
  4. Nacos系列3---源码刨析naming服务的server列表核心管理类ServerListManager
  5. android busybox脚本,在BusyBox中创建和控制启动脚本
  6. Java反射Filed、Method、Constructor类_02
  7. (30)整数直接与分数相乘
  8. 土耳其语翻译,本地化土耳其语翻译
  9. 计算机里的游戏怎么输入,电脑版悟饭游戏厅金手指怎么输入 | 手游网游页游攻略大全...
  10. 中国智能牙刷产业运行态势分析及前景规模调研报告2022-2027年