文章目录

  • 商品分类管理
    • 实现功能
      • 实体类
      • controller
      • service
      • mapper
      • 跨域问题(cors)
  • 品牌查询
      • controller
        • PageResult
      • Service
    • 异步查询工具axios
      • axios的全局配置
      • 项目中使用
    • 完成分页和过滤
  • 品牌管理
  • 商品规格管理
  • 商品管理

商品分类管理

商城的核心自然是商品,而商品多了以后,肯定要进行分类,并且不同的商品会有不同的品牌信息,我们需要依次去完成:商品分类、品牌、商品的开发

  • 导入数据(sql)

实现功能

商品分类使用了树状结构,而这种结构的组件vuetify并没有为我们提供,这里自定义了一个树状组件。不要求实现或者查询组件的实现,只要求可以参照文档使用该组件即可:

在浏览器页面点击“分类管理”菜单:

根据这个路由路径到路由文件(src/route/index.js),可以定位到分类管理页面:

由路由文件知,页面是src/pages/item/Category.vue

实体类

leyou-item-interface中添加Category实体类:

@Table(name="tb_category")
public class Category {@Id@GeneratedValue(strategy=GenerationType.IDENTITY)private Long id;private String name;private Long parentId;private Boolean isParent; // 注意isParent生成的getter和setter方法需要手动加上Isprivate Integer sort;// getter和setter略
}

controller

编写一个controller一般需要知道四个内容:

- 请求方式:决定我们用GetMapping还是PostMapping
- 请求路径:决定映射路径
- 请求参数:决定方法的参数
- 返回值结果:决定方法的返回值

在刚才页面发起的请求中,我们就能得到绝大多数信息:

  • 请求方式:Get,插叙肯定是get请求
  • 请求路径:/api/item/category/list。其中/api是网关前缀,/item是网关的路由映射,真实的路径应该是/category/list
  • 请求参数:pid=0,根据tree组件的说明,应该是父节点的id,第一次查询为0,那就是查询一级类目
  • 返回结果:??
    根据前面tree组件的用法我们知道,返回的应该是json数组:对应的java类型可以是List集合,里面的元素就是类目对象了。也就是List
    ResponseEntity
@Controller
@RequestMapping("category")
public class CategoryController {@Autowiredprivate CategoryService categoryService;/*** 根据父id查询子节点* @param pid* @return*/@GetMapping("list")public ResponseEntity<List<Category>> queryCategoriesByPid(@RequestParam("pid") Long pid) {if (pid == null || pid.longValue() < 0) {// 响应400,相当于ResponseEntity.status(HttpStatus.BAD_REQUEST).build();return ResponseEntity.badRequest().build();}List<Category> categories = this.categoryService.queryCategoriesByPid(pid);if (CollectionUtils.isEmpty(categories)) {// 响应404return ResponseEntity.notFound().build();}return ResponseEntity.ok(categories);}
}

service

一般service层我们会定义接口和实现类,不过这里我们就偷懒一下,直接写实现类了:

@Service
public class CategoryService {@Autowiredprivate CategoryMapper categoryMapper;/*** 根据parentId查询子类目* @param pid* @return*/public List<Category> queryCategoriesByPid(Long pid) {Category record = new Category();record.setParentId(pid);return this.categoryMapper.select(record);}
}

mapper

我们使用通用mapper来简化开发:

public interface CategoryMapper extends Mapper<Category> {}

要注意,我们并没有在mapper接口上声明@Mapper注解,那么mybatis如何才能找到接口呢?

我们在启动类上添加一个扫描包功能:

@SpringBootApplication
@EnableDiscoveryClient
@MapperScan("com.leyou.item.mapper") // mapper接口的包扫描
public class LeyouItemServiceApplication {public static void main(String[] args) {SpringApplication.run(LeyouItemServiceApplication.class, args);}
}

跨域问题(cors)

跨域问题(cors)](https://blog.csdn.net/chenhangx/article/details/105413599)

品牌查询

路由路径:/item/brand

根据路由文件知,对应的页面是:src/pages/item/Brand.vue

`tb_brand`ENGINE=InnoDB AUTO_INCREMENT=325400 DEFAULT CHARSET=utf8 COMMENT='品牌表,一个品牌下有多个商品(spu),一对多关系';

这里需要注意的是,品牌和商品分类之间是多对多关系。因此我们有一张中间表,来维护两者间关系:

CREATE TABLE `tb_category_brand` (`category_id` bigint(20) NOT NULL COMMENT '商品类目id',`brand_id` bigint(20) NOT NULL COMMENT '品牌id',PRIMARY KEY (`category_id`,`brand_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商品分类和品牌的中间表,两者是多对多关系';

但是,你可能会发现,这张表中并没有设置外键约束,似乎与数据库的设计范式不符。为什么这么做?

  • 外键会严重影响数据库读写的效率
  • 数据删除时会比较麻烦

在电商行业,性能是非常重要的。我们宁可在代码中通过逻辑来维护表关系,也不设置外键。

controller

编写controller先思考四个问题,参照前端页面的控制台

  • 请求方式:查询,肯定是Get
  • 请求路径:分页查询,/brand/page
  • 请求参数:根据我们刚才编写的页面,有分页功能,有排序功能,有搜索过滤功能,因此至少要有5个参数:
    • page:当前页,int
    • rows:每页大小,int
    • sortBy:排序字段,String
    • desc:是否为降序,boolean
    • key:搜索关键词,String
  • 响应结果:分页结果一般至少需要两个数据
    • total:总条数
    • items:当前页数据
    • totalPage:有些还需要总页数

PageResult

这里我们封装一个类,来表示分页结果:

public class PageResult<T> {private Long total;// 总条数private Integer totalPage;// 总页数private List<T> items;// 当前页数据public PageResult() {}public PageResult(Long total, List<T> items) {this.total = total;this.items = items;}public PageResult(Long total, Long totalPage, List<T> items) {this.total = total;this.totalPage = totalPage;this.items = items;}public Long getTotal() {return total;}public void setTotal(Long total) {this.total = total;}public List<T> getItems() {return items;}public void setItems(List<T> items) {this.items = items;}public Long getTotalPage() {return totalPage;}public void setTotalPage(Long totalPage) {this.totalPage = totalPage;}
}

另外,这个PageResult以后可能在其它项目中也有需求,因此我们将其抽取到leyou-common中,提高复用性:
不要忘记在leyou-item-service工程的pom.xml中引入leyou-common的依赖

    <groupId>com.leyou.common</groupId><artifactId>leyou-common</artifactId>

Service

@Service
public class BrandService {@Autowiredprivate BrandMapper brandMapper;/*** 根据查询条件分页并排序查询品牌信息** @param key* @param page* @param rows* @param sortBy* @param desc* @return*/public PageResult<Brand> queryBrandsByPage(String key, Integer page, Integer rows, String sortBy, Boolean desc) {// 初始化example对象Example example = new Example(Brand.class);Example.Criteria criteria = example.createCriteria();// 根据name模糊查询,或者根据首字母查询if (StringUtils.isNotBlank(key)) {criteria.andLike("name", "%" + key + "%").orEqualTo("letter", key);}// 添加分页条件PageHelper.startPage(page, rows);// 添加排序条件if (StringUtils.isNotBlank(sortBy)) {example.setOrderByClause(sortBy + " " + (desc ? "desc" : "asc"));}List<Brand> brands = this.brandMapper.selectByExample(example);// 包装成pageInfoPageInfo<Brand> pageInfo = new PageInfo<>(brands);// 包装成分页结果集返回return new PageResult<>(pageInfo.getTotal(), pageInfo.getList());}
}

异步查询工具axios

异步查询数据,自然是通过ajax查询,大家首先想起的肯定是jQuery。但jQuery与MVVM的思想不吻合,而且ajax只是jQuery的一小部分。因此不可能为了发起ajax请求而去引用这么大的一个库。
Vue官方推荐的ajax请求框架叫做:axios
axios的Get请求语法:

axios.get("/item/category/list?pid=0") // 请求路径和请求参数拼接.then(function(resp){// 成功回调函数}).catch(function(){// 失败回调函数})
// 参数较多时,可以通过params来传递参数
axios.get("/item/category/list", {params:{pid:0}}).then(function(resp){})// 成功时的回调.catch(function(error){})// 失败时的回调

axios的POST请求语法:

比如新增一个用户

axios.post("/user",{name:"Jack",age:21}).then(function(resp){}).catch(function(error){})

注意,POST请求传参,不需要像GET请求那样定义一个对象,在对象的params参数中传参。post()方法的第二个参数对象,就是将来要传递的参数

PUT和DELETE请求与POST请求类似

axios的全局配置

而在我们的项目中,已经引入了axios,并且进行了简单的封装,在src下的http.js中:
http.js中对axios进行了一些默认配置:

import Vue from 'vue'
import axios from 'axios'
import config from './config'
// config中定义的基础路径是:http://api.leyou.com/api
axios.defaults.baseURL = config.api; // 设置axios的基础请求路径
axios.defaults.timeout = 2000; // 设置axios的请求时间Vue.prototype.$http = axios;// 将axios赋值给Vue原型的$http属性,这样所有vue实例都可使用该对象

项目中使用

我们在组件Brand.vue的getDataFromServer方法,通过$http发起get请求,测试查询品牌的接口,看是否能获取到数据:



可以看到,在请求成功的返回结果response中,有一个data属性,里面就是真正的响应数据。

响应结果中与我们设计的一致,包含3个内容:

  • total:总条数,目前是165
  • items:当前页数据
  • totalPage:总页数,我们没有返回

完成分页和过滤

品牌管理

商品规格管理

商品管理

乐优商城之后台管理系统相关推荐

  1. 乐优商城之后台管理系统的环境搭建(七)

    文章目录 (一)搭建管理后台的前端 (二)项目结构 (三)vuetify (四)使用域名访问后台页面 (五)nginx的介绍 (六)nginx的使用 (一)搭建管理后台的前端 把资料包中提供的leyo ...

  2. 【javaWeb微服务架构项目——乐优商城day03】——(搭建后台管理前端,Vuetify框架,使用域名访问本地项目,实现商品分类查询,cors解决跨域,品牌的查询)

    乐优商城day03 0.学习目标 1.搭建后台管理前端 1.1.导入已有资源 1.2.安装依赖 1.3.运行一下看看 1.4.目录结构 1.5.调用关系 2.Vuetify框架 2.1.为什么要学习U ...

  3. 乐优商城(填坑)——后台登录

    后台管理模块增加登录验证,与门户网站一样都是采用无状态登录. 一.新增全局函数 在main.js中新增用户验证: 二.修改路由 先显示登录页面 效果: 三.解决cookie写入问题 在http.js中 ...

  4. 乐优商城之项目搭建(四)

    文章目录 (一)项目分类 (二)电商行业 (三)专业术语 (四)项目介绍 (五)技术选型 (六)开发环境 (七)搭建后台环境:父工程 (八)搭建后台环境:eureka (九)搭建后台环境:zuul ( ...

  5. 乐优商城(10)--数据同步

    乐优商城(10)–数据同步 一.RabbitMQ 1.1.问题分析 目前已经完成了商品详情和搜索系统的开发.思考一下,是否存在问题? 商品的原始数据保存在数据库中,增删改查都在数据库中完成. 搜索服务 ...

  6. 乐优商城源码/数据库及笔记总结

    文章目录 1 源码 2 笔记 2.1 项目概述 2.2 微服务 3 项目优化 4 项目或学习过程中涉及到的设计模式 5 安全问题 6 高内聚低耦合的体现 7 项目中待优化的地方 1 源码 Github ...

  7. leyou商城项目搭建(1)-电商行业及乐优商城介绍

    leyou商城项目搭建(1)-电商行业介绍 1.了解电商行业 1.1.项目分类 1.1.1.传统项目 1.1.2.互联网项目 1.2.电商行业的发展 1.2.1.钱景 1.2.2.数据 1.2.3.技 ...

  8. 【javaWeb微服务架构项目——乐优商城day15】——会调用订单系统接口,实现订单结算功能,实现微信支付功能

    0.学习目标 会调用订单系统接口 实现订单结算功能 实现微信支付功能 源码笔记及资料: 链接:https://pan.baidu.com/s/1_opfL63P1pzH3rzLnbFiNw 提取码:v ...

  9. 乐优商城(四)商品规格管理

    文章目录 1. 商品规格 1.1 SPU 和 SKU 1.2 分析商品规格的关系 1.3 数据库设计 1.3.1 商品规格组表 1.3.2 商品规格参数表 2. 商品规格组 2.1 商品规格组前端 2 ...

最新文章

  1. 全球第一所人工智能大学成立:培养硕博研究生,全员全额奖学金
  2. 对象测试_测试|你挑恋爱对象的眼光准不准?
  3. VHDL电子密码锁设计
  4. javafx中css选择器_JavaFX技巧12:在CSS中定义图标
  5. 阿里云96页报告详解《云上转型》(10个案例、10大趋势/完整版PPT)
  6. jquery获取radio值
  7. Macaca简单入门
  8. 程序员们,你知道面试官是如何考察你的软素质吗?
  9. Python应用-[用Python实现一个socket echo程序 tcp socket的几个关闭状态]
  10. GB50052-2009供配电系统设计规范1
  11. 程序员必备 Windows 快捷操作大全
  12. 微信小程序实现自动定位
  13. 三个水桶等分8升水的问题
  14. ICM-20602 IMU ACCEL/GYRO/TEMP I2C/SPI LGA
  15. Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1。 当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少(蓝桥基础实战)
  16. Python:合成图片
  17. Linux Systemd服务
  18. 小米5s Plus安装类原生系统
  19. 基于卷积神经网络的手势识别研究论文
  20. 16进制颜色代码大全

热门文章

  1. 原创超简单代码(1.21.50)
  2. Application.streamingAssetsPath在android和ios和pc上的读取
  3. windows批处理:start的用法
  4. 计算2个时间段的重叠天数
  5. 清除U盘内所占的隐藏空间(U盘容量突然变小了)
  6. mysql 基础语法3
  7. 2014美国大学计算机专业排名,2014年美国大学计算机专业研究生排名
  8. 【php学习之路】微信公众帐号
  9. Excel VBA 小程序 - 文本型数字转为数值型数字
  10. 学好编程需要英语很好吗