docker环境搭建
todo
docker 通用命令集
1 | 查看容器进程 |
docker 安装 mysql
1 | docker run -p 3306:3306 --name mysql -v /mydata/mysql/log:/var/log/mysql -v /mydata/mysql/data:/var/lib/mysql -v /mydata/mysql/conf:/etc/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7 |
命令解释:todo
使用mysql客户端工具连接服务器
账户名:root 密码: root
docker 安装以及操作 redis
1 | 创建redis 容器 |
可以下载redis的客户端(redis desktop manageer)
[redis desktop manageer]: https://redisdesktop.com/ “redis 桌面管理器”
进行界面操作
Maven
重新编辑 maven 的 setting.xml ,添加一下配置到文件中
1 | #配置阿里云镜像 |
1 | 配置jdk1.8编译项目 |
IDEA & VSCode
idea 配置 (后端开发工具)
1.安装lombok插件
快速生成类的构造函数,get/set 方法等
2.安装mybatisx插件
快速定位mapper 文件
VSCode 配置 (前端开发工具)
安装插件
1.Auto Close Tag
自动添加HTML/XML关闭标签
2.Auto Rename Tag
自动重命名成对的HTML/XML标签
3.Chinese (Simplified) Language Pack for Visual Studio Code插件
汉化插件
4.ESLint
检查ES 语法
5.HTML CSS Support
6.HTML Snippets
7.JavaScript (ES6) code snippets
ES 语法提示
8.Live Server
启动一个开发本地服务器与动态页面动态重新加载功能
9.open in browser
这允许您在默认浏览器或应用程序中打开当前文件。
10.Vetur
Vue 语法支持 ,Vue 工具
配置git-ssh
1.在电脑上安装git
todo
2.配置git的基本用户信息
1 | 全局配置git的用户名 |
3.配置ssh免登录
在控制台生成个人 ssh 私钥和公钥
1 | 生成私钥和公钥 连续三次回车确定 |
执行完成之后,目录下会生成 id_rsa (私钥)和 id_rsa.pub(公钥)两个文件。
然后登录gitee(码云) 或者 github ,在设置中找到SSH KEY配置,将 id_rsa.pub 里的内容复制粘贴到里面去。
最后 使用
1 | 码云测试是否添加成功 |
idea 搭建 后端服务项目环境
导入码云上的项目
复制仓库url,在idea新建选择 new > Project from Version Control .. > git 粘贴在URL 中,选择相应的工作目录。
如果没有配置gitee账号,需要自行登录。
在项目上新建相应的微服务项目
- 商品服务(product)
- 仓储服务(ware)
- 订单服务(order)
- 优惠卷服务(coupon)
- 用户服务(member)
创建微服务模块
1.右键主项目 > New > Module.. > Spring initializr 输入相关信息
2.每个服务统一包名和模块名称
com.组织名称.项目名称.模块名称….
3.选择微服务必要的maven 依赖
Spring Web
Spring Web Service
OpenFeign 用于微服务之间的互相调用
4.创建完成微服务模块,在父目录下 新建一个 pom 文件,内容如下:
1 | <modelVersion>4.0.0</modelVersion> |
把编辑好的父Pom 文件,添加到 Idea maven 插件 管理中,方便打包部署。
编辑.gitignore
编辑这个文件可以 忽略提交这些文件,在这个文件中追加如下内容:
1 | **/mvnw |
最后提交代码到码云,安装码云插件(gitee)。
数据库 搭建配置
1.安装 Power Designer 建模软件
[]: http://forspeed.rbread01.cn/down/powerdesigner1029.zip
注:表不做外键关联,因为数据量太大,外键会浪费数据库的性能。
2.根据业务进行数据建模,然后生成相应的 sql 语句
3.点击菜单栏 Database > generate Database > Preview , 查看生成的 sql 语句
4.每个服务模块建立一个数据库,然后分别执行相应的业务sql,创建表结构。
搭建后台管理系统
人人开源项目
注:在 git 搜索人人开源,使用别人的构建好的脚手架,进行快速开发
renren-fast 和 renren-fast-vue 能快速构建,后台管理系统。
renren-generator 快速生成代码层
引入后台项目中
1.打开git bash ,执行,克隆项目到文件夹中
1 | git clone https://gitee.com/renrenio/renren-fast.git |
2.删除克隆的项目中的 .git 文件夹,然后 renren-fast 复制整个文件夹到你的项目中,然后更改 父Pom 加上 该模块,更改后的配置为:
1 | <modelVersion>4.0.0</modelVersion> |
3.创建相应的数据库和表,执行项目中db文件夹下的sql文件(根据数据库选择相应的语句),执行完成之后,可以更改项目配置文件夹中关于db数据源的配置,然后启动项目。
构建前端项目
1.安装 Node.js
todo
2.配置好node,打开前端项目下的终端,执行
1 | # 安装包文件依赖 |
2.1 安装中出现了错误
1.node-gyp 这个包需要安装 python 作为依赖 所以我们需要安装python,在管理员powershell 中执行以下语句:
Error: Can’t find Python executable “python”, you can set the PYTHON env variable.
方法一:
1 | 安装windows-build-tools |
方法二:
使用管理员运行VSCode 再执行 npm install 命令
注:node-sass 安装报错
node-sass是一个项目依赖,在一个项目中在使用sass语法的时候,必须通过sass-loader来解析sass,从而使sass语法变成浏览器能够识别的CSS语法,而node-sass模块就是对sass-loader的支持模块,所以不安装node-sass,sass-loader就不能正常工作
要考虑到 node-sass 和 node.js 的版本兼容性
参考:https://www.npmjs.com/package/node-sass
3.成功之后,浏览器打开 localhost:8001,账号:admin 密码:admin 登录.(没验证码,一定是没有启动后端服务)
逆向工程搭建&使用
1.克隆项目下来
1 | git clone https://gitee.com/renrenio/renren-generator.git |
2.删除.git 配置 ,然后把文件复制到后台工程目录下,修改pom 文件,引入该项目。
3.修改逆向工程的application.yml 配置文件的数据源配置,修改为自己的
4.修改generator.properties 生成代码的基本配置,主要修改以下配置
1 | mainPath=com.centersept.supermall |
5.直接启动逆向工程,使用浏览器直接输入localhost 访问自动生成代码系统。
5.1 进入菜单 renren-fast , 选择全部的表,点击生成代码来生成代码。
5.2 解压生成的文件,把解压的main文件夹,复制到你生成的模块下。
6.导入代码之后,存在报错,还需要生成一个公共的模块,把公共代码导入进去,其他服务依赖这个公共模块。
6.1 每个模块加入一下依赖
1 | <dependency> |
7.从renren-fast 模块,把utils 和 xss 里的类copy 到 common 模块
7.1 修改pom 的依赖
1 | <!-- mybatis-plus--> |
8.修改逆向工程中的controller模板 Controller.java.vm, 注释掉shiro的注解
9.最后再次生成代码,复制粘贴到项目中。
配置&测试模块的CRUD
配置
1.配置数据源
1.1 common pom的依赖添加,导入数据库的驱动
1 | <!-- mysql 驱动--> |
1.2 生成application.yml 配置文件,将数据源配置进去
1 | spring: |
2.配置mybatis-plus
2.1 配置mybatisPlus ,在启动类加入注解,扫描mapper 接口,生成代理类,注入到spring 容器中,让spring 进行管理
1 | @MapperScan("com.centersept.supermall.product.dao") |
2.2 在配置文件追加一下内容
1 | mybatis-plus: |
测试是否能crud
在 test 文件夹下的测试类,添加以下内容测试。
1 |
|
逆向工程生成全部模块的业务代码
1.每个模块的pom 都加上common 模块的依赖
2.配置每个模块的数据库Url 为对应的库
3.每个模块的端口号都修改,从8000开始,+1000 递增,方便每个模块生成多个服务,直接在后面加1。
即 订单模块定义8000 开始,再加一个订单服务则对用端口为8001。仓储模块则使用9000。
分布式组件
Spring-cloud-netflix
todo
Spring-cloud-alibaba 分布式框架解决方案
SpringCloud Alibaba-Nacos: 注册中心(服务发现/注册 )
SpringCloud Alibaba-Nacos配置中心(动态配置管理)
SpringCloud- Ribbon:负载均衡
SpringCloud- Feign:声明式HTTP客户端(调用远程服务)
SpringCloud Alibaba-Sentinel:服务容错(限流、降级、熔断)
SpringCloud- Gateway: API 网关(webflux 编程模式)
SpringCloud- Sleuth:调用链监控
SpringCloud Alibaba-Seata:原Fescar, 即分布式事务解决方案
引入分布式框架Spring-cloud-alibaba
在公共模块common 的pom 加入 一下配置:
注:框架的版本和spring-boot的版本要同步,具体参考官方文档。
1 | <dependencyManagement> |
Nacos 注册中心
1.首先,修改 pom.xml 文件,引入在公共common模块引入 Nacos Discovery Starter。
1 | <dependency> |
2.Nacos server 配置
注:window下操作
2.1 https://github.com/alibaba/nacos/releases 下载 Nacos server , 我下载的是这个版本
2.2 下载完成后,解压,startup.cmd 启动
2.2.1 出现启动不了,窗口一闪的情况。
解决:你的jdk环境变量没有配置好,必须把jdk环境置顶,也就是上移,让系统优先选择。
最后,在微服务业务模块中加入以下配置
1 | spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 |
3.使用 @EnableDiscoveryClient 注解开启服务注册与发现功能,启动项目
1 |
|
4.使用浏览器登录 http://localhost:8848/nacos/ ,账号密码 nacos ,但是并没有我们注册的服务。
那是因为微服务模块配置文件没有配置apllication.name 这个属性,加入之后就可以发现了。
4.1 修改配置文件之后出现
1 | org.springframework.boot.context.properties.ConfigurationPropertiesBean |
因为 springboot版本和springcloud版本不兼容,换一个版本试试。换成Greenwich.SR3 版本的。
Nacos服务中心 部署到 docker
1.获取镜像
todo
OpenFeigh 测试远程调用
原理
todo
使用
1.引入依赖
1 | <dependency> |
2.项目接入feigh
2.1在优惠券服务取一个controller类文件,定义一个数据返回List
1 |
|
2.2 在会员模块下创建feigh包,这个文件夹用于声明feigh接口。
1 |
|
2.3 在会员服务的启动类中加入注解,开启远程调用
1 | @EnableFeignClients(basePackages = "com.centersept.supermall.member.feigh") |
也可以在可以在接口上加入@Component 注解,交给spring 注入。
2.4 在会员模块下的MemberController类中加入一下内容,远程调用优惠券服务
1 |
|
2.5 浏览器输入http://localhost:9000/member/member/coupons,测试是否连通。
Nacos 配置中心
简单配置实例
1.在common 模块引入nacos 配置中心的依赖
1 | <dependency> |
2.在应用的/src/main/resources/bootstrap.properties 配置文件中配置Nacos Config 元数据,现在 coupon 模块创建
3.在controller层 创建一个测试的用户代码,如下
1 |
|
注:user.name spring 会自动去读取计算机的名字
4.在 application.properties 中配置相应的属性,如下
1 | user.testname=超人 |
5.为了不让我们重新打包重启,则在配置中心加上配置。启动的如下日志已经提醒,从 nacos 配置中心获取配置信息的
1 | 2020-07-16 21:00:46.045 INFO 14188 --- [ main] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource {name='NACOS', propertySources=[NacosPropertySource {name='supermall-coupon.properties'}]} |
我们需要在 Nacos 配置中心配置相应的配置文件
6.打开Nacos 管理界面,点击配置列表,然后新建一个 DataId 为 supermall-coupon.properties 的命名,再然后把配置的内容写到配置内容栏里面,发布。
7.这个时候还没有结束,还需要在配置属性的类里面,加上@RefreshScope 注解,才能达到热更新的效果。
8.因为配置中心是bootstrap.properties 中配置加载的,所以相同的配置项,优先加载Nacos 配置中心的配置。
命名空间与配置分组
1.命名空间
配置隔离
默认:public
1.开发,测试,生产
配置命名空间
1.在命名空间中,分别添加开发,测试,生产 的命名空间。
2.打开配置列表,发现页面上已经有我们添加的命名空间。
3.然后我们在新的命名空间中添加我们的配置项。我们可以直接在public 的命名空间中,选择已经配置好的配置,然后克隆到其他命名空间就可以了。
4.如果我们要在不同环境切换配置命名空间,可以在bootstrap.properties 中 增加命名空间配置项
1 | spring.cloud.nacos.config.namespace=98af8d57-dd3a-4b68-b1a1-945ee78f1239 |
5.也可以每个微服务创建一个命名空间。
2.配置集
所有的配置的集合
3.配置集ID
类似配置文件名
4.配置分组
默认所有的配置集都属于:DEFAULT_GROUP
需要在boostrap.properties 加入以下配置
1 | #配置分组的命名 |
一般来说一个微服务使用命名空间来隔离,然后使用分组来隔离环境的配置。
加载多配置源
1.新建一个配置 ,把数据源的配置当道这个配置中来,Data ID 为 datasource.yml ,Group 为 dev, 配置格式为YAML 配置内容为以下内容:
1 | spring: |
2.mybatis 的配置,也可以创建一个出来进行加载,配置如下:
1 | mybatis-plus: |
3.新建一个其他的配置,统一进行管理
1 | spring: |
4.把这些创建好的配置,配置到项目中,在bootstrap.properties 中加入以下配置
1 | # datasource |
SpringCloud-Gateway 网关
网关作为流量的入口,常用功能包括路由转发、权限校验、限流控制等。而springcloud gateway
作为SpringCloud官方推出的第二代网关框架,取代了Zuul 网关(网飞)。
主要作用 :动态路由,鉴权
rps:32213 每秒请求数
组件:Route,Predicate,Filter
注:官方文档中有很多配置实例,可以直接上去查看。
1.创建gatewey 模块,加入网关模块,以及引入common 模块
2.加入nacos 依赖,然后配置nacos的配置,新建bootstrap.properties ,加入以下配置:
1 | spring.application.name=<你的应用名称> |
3.排除数据库配置,在启动类上加入
1 | @EnableDiscoveryClient |
4.测试路由断言
1 | spring: |
前端基础
技术栈简介
ES6 语法
JavaScript 是它的实现
前端基础
1.let 声明变量
var 声明的变量往往会越域
let 声明的变量有严格局部作用域
1 | var a - 1; |
var 会存在变量提升
let 不存在变量提升
1 | console.log(×); /l undefined |
2.const 声明常量(只读变量)
声明之后不允许改变
一旦声明必须初始化,否则报错
3.解构表达式
数组解构
1 | let arr = [1,12,3] |
对象解构
1 | const person = { |
4.字符串扩展
字符串API
1 | let str = "hello.wue""; |
字符串模板
1 | // 反引号 ` |
字符串插入变量
1 | //2、字符串插入变量和表达式。变量名写在${}中,${}中可以放入JavaScript表达式。 |
5.函数优化
5.1 函数参数默认值
1 | // 在ES6以前,我们无法给一个函数的设置默认值,只能采用变通写去: |
5.2 不定参数
1 | function fun(..values){ |
5.3 箭头函数
1 | // 原来声明一个函数 |
6.对象优化
1 | const person = { |
7.map 和 reduce
1 | //数组中新增了map和reduce 方法 |
8.Promise (异步编排)
问题:ajax 一步一步的递归调用
1 | // 1.Promise 可以封装异步操作 |
9.模块化
9.1 什么是模块化
模块化就是把代码进行拆分,方便重复利用。类似java中的导包,要使用一个包,必须先导包。而s中没有包的概念,换来的是模块。
模块功能主要由两个命令构成.’export”和”import’.
export:命令用于规定模块的对外接口。
import:命令用于导入其他模块提供的功能。
9.2 export 导出
给导入另外起名,使用以下格式
1 | export default { |
9.3 import 导入
vue
MVVM
todo
官网看引入教程
nodejs
开始搭建前端模块
Vue模块化开发
搭建Vue脚手架
1 | 全局安装webpack |
创建一个组件
1.在src/components 下创建vue 文件,内容是vue的基本三大属性
1 | <template> |
2.在src/router 下,编辑index.js,添加一下代码
1 | import hello from '@/components/{你的文件名}' |
引用ElementUI
安装依赖
1 | npm i element-ui |
引入依赖
在 main.js 中写入以下内容:
1 | import Vue from 'vue'; |
使用elementUI 提供的布局以及配置动态路由菜单
1.替换App.vue 中的内容
1 | <template> |
2.删除<el-main>中的内容,替换成
VSCode,加入vue代码片段
1.点击文件-首选项-用户代码-点击新建代码片段-取名vue.json,然后替换一下内容
1 | "Print to console": { |
商品服务
三级分类
查询树形展示三级分类数据
1.在PMS库中的pms_category表,导入菜单分类数据
2.然后在product模块中,对应的service文件中编写三级分类业务逻辑
1 | public List<CategoryEntity> menu() { |
配置网关路由与路径重写和网关统一配置跨域
1.启动前端代码,再启动后端服务,进入系统的系统管理->菜单管理,添加商品系统的一级目录,然后再添加这个一级目录的分类维护的子目录,path为product/category。
2.然后根据这个path的属性,在前端src/views/modules 下创建一个product文件夹,然后在这个文件夹下创建category.vue 文件,文件内容如下:
1 | <template> |
3.配置好请求,打开页面,发现请求404,我们要配置项目父目录下static->config的index.js 文件中的api请求接口路径,把所有服务请求都提交到网关服务去,修改如下:
1 | /** |
4.配置好之后,还需要配置网关模块的配置文件,修改如下:
1 | spring: |
5.再把后端管理项目加入到nacos 服务发现中,配置nacos服务发现,重启网关服务。
6.但是我们发现,请求给了403,看控制台报错是没有配置跨域策略,所以我们必须在网关配置跨域策略,加入以下文件
1 | import org.springframework.context.annotation.Bean; |
7.重新请求,发现还是403,看了错误显示跨域配置了多个值,导致的报错,经过查找发现,后台管理服务中也增加了跨域策略,所以我们需要删除它,在io.renren.config目录下的CorsConfig 。
树型展示三级分类数据
1.修改category.vue文件,如下
1 | <template> |
页面效果
修改过的页面内容如下:
1 | <template> |
逻辑删除
以下为官方操作文档路径
https://baomidou.com/guide/logic-delete.html#%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95%EF%BC%9A
1.使用mybatis-plus插件集成的便利性,修改application.yml,加上如下配置
1 | mybatis-plus: |
2.修改DO实体类,把逻辑删除的字段加上@TableLogic 注解
3.然后使用postman 调用请求接口,为了看到逻辑删除执行的语句,我们需要修改日志框架的日志级别为debug级别,配置文件加入以下配置
1 | logging: |
删除效果细化
category.vue 修改之后的内容为:
1 | <template> |
新增效果完成
category.vue 修改之后的内容为:
1 | <template> |
基本修改效果完成
category.vue 修改之后的内容为:
1 | <template> |
拖拽效果
1 | <template> |
拖拽数据收集
1 | <template> |
拖拽功能完成
1.后端代码增加接口 CategoryController
1 | /** |
2.单行修改频繁调用不够友好,需要使用按钮进行批量修改。单行提交代码省略。
最终菜单页面完成代码效果
1 | <template> |
品牌管理
使用逆向工程的前后端代码
1.在菜单管理中在商品服务下生成一个品牌管理的菜单,菜单路径为product/brand
2.使用逆向生成代码的两个文件 brand.vue 和 brand-add-or-update.vue 文件放到product 文件夹下。
3.由于做了权限设置,所以进入/utils/index.js 文件夹下修改 isAuth 方法的返回值一直为true。
效果优化与快速显示开关
关闭ESLint 语法检查
打开build文件夹下的webpack.base.conf.js,然后注释调createLintingRule中的方法体。
1.优化brand.vue 之后的代码
1 | <template> |
brand-add-or-update.vue 内容
1 | <template> |
云存储开通与使用
开通阿里云OSS
OSS 整合测试
普通Maven项目引入
1.在阿里云平台开通RAM服务,然后在RAM 服务下创建子账号,然后保存生成的AccessKey ID 和 AccessKey Secret 。
2.查看OSS官方文档,引入下面的maven依赖,根据文档示例写一个简单的demo 测试。
1 | <dependency> |
SpringCloud Alibaba OSS 引入
1.打开github 上的 demo示例,https://github.com/alibaba/aliyun-spring-boot/tree/master/aliyun-spring-boot-samples/aliyun-oss-spring-boot-sample.
2.加入以下以下maven依赖
1 | <dependency> |
3.然后在配置文件文件中加入以下配置
1 | // application.properties |
4.然后在业务在业务项目中使用以下代码进行OSS客户端注入访问
1 |
|
5.弄一个测试demo
1 | import com.aliyun.oss.OSSClient; |
OSS 获取服务端签名
1.建立一个新的模块,该模块是引入第三方服务的模块,命名super-mall-TTS
2.maven的pom加入以下内容
注:依赖的springboot的版本号一定要一致。
1 |
|
3.创建bootstrap.properties 文件加入nacos config 的配置。
4.创建一个生成签名的contorller
1 | import com.aliyun.oss.OSS; |
OSS 前后联调测试上传
1.引入以下三个文件,放在src/components/upload 文件夹下。
多文件上传组件 multiUpload.vue
1 | <template> |
请求OSS签名封装脚本 policy.js
1 | import http from '@/utils/httpRequest.js' |
单文件上传组件 singleUpload.vue
1 | <template> |
2.修改brand-add-or-update.vue
1 | <template> |
3.上传操作之后,点击保存,保存上传的路径
表单校验&自定义校验器
1.修改显示状态,返回后端的值,修改如下
1 | <el-form-item label="显示状态" prop="showStatus"> |
2.把表格显示的URL地址,转变为显示图片
1 | <el-table-column |
3.加入表单验证,修改brand-add-or-upadate.vue,内容如下:
1 | <template> |
JSR303表单验证
1.给Bean实体类添加校验注解(在javax.validation.constraints 中),并定义自己的message提示,举个栗子,在BrandEntity.java 中修改。
1 |
|
2.在对应的controller的保存接口上加上@Valid注解开启校验,但是返回的是默认的响应,不是我们想要的。
1 | /** |
3.自定义校验体,需要在入参中加入BindingResult类型的参数,就可以获取到校验的结果,自定义返回给前端。
1 | /** |
4.也可以使用BindingResultUtils 提供的方法,对入参进行校验。
统一异常处理
1.为了不增加代码的侵入性,我们可以自定义一个异常类,基于AOP做统一处理。
2.在对应的模块下,创建一个exception包,声明一个统一的异常类型,然后加上@RestControllerAdvice(basePackages = “com.atguigu.gulimall.product.controller”)类注解,方法上加入@ExceptionHandler(value = MethodArgumentNotValidException.class)对应处理的异常注解,然后在公共模块定义统一的异常代码枚举类。
统一异常类:
1 |
|
异常代码枚举:
1 | public enum BizCodeEnume { |
3.最后把controller侵入业务的代码删除调。
JSR303分组校验
1.定义校验分组接口,接口不需要实现类,仅仅是使用来标识分组。分别定义addGroup.java 和 upGroup.java分组,放到common模块下,放到valid的包下。
2.在bean实体类的字段上的校验注解中加入group属性,使用刚刚定义好的接口类型根据需求填充到group中。如,新增接口应该使用addGroup.class类标识,更新接口使用upGroup.class 标识。举了栗子:
1 | /** |
3.在对应的controller类上,加上@Validated 注解,开启校验功能,如下:
1 | /** |
注:默认没有指定分组的校验注解@NutBlank,在分组校验情况@Validated({AddGroup.class})下不生效。
JSR303自定义校验注解
1.在common模块引入javax.validation.validation-api maven依赖:
1 | <dependency> |
2.编写一个自定义的校验注解,在common模块中,valid包下新建一个注解类
1 |
|
3.新建一个ListValueConstraintValidator校验器,该校验器需要实现ConstraintValidator接口
1 | public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> { |
4.根据javax.validation 依赖规范,在resource 文件夹下新建ValidationMessages.properties文件,才能使String message() default “{com.centersept.supermall.common.valid.ListValue.message}”;生效。
1 | com.centersept.supermall.common.valid.ListValue.message=显示状态参数错误 |
5.修改BrandEntity实体类的showStatus属性注解值
1 |
|
6.为了只校验在修改状态的时候才判断该校验值,所以我们要重新声明一个请求方法
1 | /** |
7.最后再修改前端页面的请求地址。
SPU&SKU&规格参数&销售属性
SPU = Standard Product Unit (标准产品单位)
SPU是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述了一个产品的特性。
通俗点讲,属性值、特性相同的商品就可以称为一个SPU。
例如:
iphone4就是一个SPU,与商家,与颜色、款式、套餐都无关。
SKU=stock keeping unit(库存量单位)
SKU即库存进出计量的单位, 可以是以件、盒、托盘等为单位。
SKU是物理上不可分割的最小存货单元。在使用时要根据不同业态,不同管理模式来处理。在服装、鞋类商品中使用最多最普遍。
例如:
纺织品中一个SKU通常表示:规格、颜色、款式。
属性分组
前端组件抽取&父子组件交互
1.执行提供的sys_menus.sql文件。
1 | DROP TABLE IF EXISTS `sys_menu`; |
2.添加树型菜单公共组件,再modules下创建common文件夹,然后创建一个category.vue文件,内容如下:
注:使用this.&emit(‘{事件名称}’,[参数。。。])
1 | <template> |
3.如何在父页面引用子组件,然后响应子组件的冒泡事件。
1 | <template> |
获取分类属性分组
1.增加接口
AttrGroupController
1 | /** |
AttrGroupServiceImpl
1 | public PageUtils queryPage(Map<String, Object> params, Long catelogId) { |
3.修改前端文件
attrgroup.vue
1 | <template> |
分组新增&级联选择器
1.使用
2.为了返回的字段中不存在空字段值的参数返回到响应参数中,在字段变量上注解@JsonInclude(JsonInclude.Include.NON_EMPTY)
分组修改&级联选择器回显
1.this.$nextTick() 的用法是指:等到组件渲染完毕才调用next方法中的方法。
2.渲染级联回显
2.1 添加回显字段
1 |
|
2.2 增加方法
AttrGroupController
1 |
|
CategoryServiceImpl
1 |
|
3.使用
4.重置弹出框数据,
品牌分类关联与级联更新
1.引入MyBatisPlus插件实现分页
1.1 在product模块下,创建config包,包下建立插件配置类,使用分页插件,注入到Spring 中。
1 |
|
1.2 修改品牌查询方法,能够通过关键词进行多行检索。
1 | public PageUtils queryPage(Map<String, Object> params) { |
2.品牌分类以及关联
2.1编写品牌分类信息查询接口,CategoryBrandRelationController 增加以下方法:
1 | /** |
2.2 编写平台分类信息保存接口
CategoryBrandRelationServiceImpl
1 | public void saveDetail(CategoryBrandRelationEntity categoryBrandRelation) { |
CategoryBrandRelationController
1 | /** |
3.级联更新,如果更新品牌的名称,我们就需要同时更新关联的品牌数据
BrandServiceImpl.java
1 |
|
BrandController.java
1 | /** |
CategoryBrandRelationServiceImpl.java
1 |
|
CategoryBrandRelationDao.xml
1 | <update id="updateCategory"> |
CategoryBrandRelationDao.java
1 | void updateCategory( Long catId, String name); |
CategoryServiceImpl.java
1 | /** |
CategoryController.java
1 | /** |
平台属性
规格参数新增与VO
1.VO的概念
略(搜索 object的划分)
2.规格参数新增接口
2.1 新增规格参数VO类
2.2 业务逻辑
AttrServiceImpl.java
1 |
|
AttrController.java
1 | /** |
规格参数列表
1.新增规格列表查询接口
修改AttrController
1 |
|
修改AttrServiceImpl
1 | public PageUtils queryBaseAttrPage(Map<String, Object> params, Long catelogId) { |
因为要关联查询数据,分类信息和分组信息,新增响应类AttrRespVo
1 |
|
规格修改
1.查询属性详情
1.1 修改 /product/attr/info/{attrId} 接口
AttrController.java
1 | /** |
AttrServiceImpl.java
1 | public AttrRespVo getAttrInfo(Long attrId) { |
2.更新属性分组
AttrServiceImpl.java
1 |
|
AttrController.java
1 | /** |
销售属性维护
1.修改之前的所有方法,如果是基本属性需要关联修改,如果是销售属性就不需要,所以我们要定义一个常量作为判断。
AttrServiceImpl.java 修改部分方法
1 |
|
AttrController.java 修改
1 |
|
在common 模块添加常量类 ProductConstant
1 | public class ProductConstant { |
查询分组关联属性&删除关联
1.查询分组关联属性
AttrServiceImpl.java
1 | /** |
AttrGroupController 添加以下方法
1 |
|
2.删除关联
增加 AttrGroupRelationVo
1 |
|
AttrServiceImpl
1 | public void deleteRelation(AttrGroupRelationVo[] vos) { |
AttrGroupController 增加
1 |
|
AttrAttrgroupRelationDao
1 | void deleteBatchRelation( List<AttrAttrgroupRelationEntity> entities); |
AttrAttrgroupRelationDao.xml
1 | <delete id="deleteBatchRelation"> |
查询分组未关联属性
AttrGroupController
1 |
|
AttrServiceImpl
1 | /** |
新增分组与属性关联
AttrAttrgroupRelationServiceImpl.java
1 | public void saveBatch(List<AttrGroupRelationVo> vos) { |
AttrGroupController.java
1 |
|
新增商品
调试会员等级相关接口
1.在网关模块添加Member模块路由配置
routes.yml
1 | - id: member_route |
2.在会员页面调试新增接口,添加会员信息
获取分类关联的品牌
CategoryBrandRelationController
1 | /** |
CategoryBrandRelationServiceImpl
1 | public List<BrandEntity> getBrandsByCatId(Long catId) { |
注:前端部分页面引入pubsub-js
1.引入前端组件pubsub-js
现在项目根目录使用命令,下载pubsub-js
1 | npm install pubsub-js --save |
在spuuadd.vue ,category-cascader.vue,brand-select.vue 引入pubsub-js
1 | // 导入 |
修改部分使用this.PubSub 的地方,直接使用 PubSub。
获取分类下所有分组以及属性
AttrGroupRelationVo 添加实体类
1 |
|
AttrGroupController
1 |
|
AttrGroupServiceImpl
1 | /** |
修改spuadd.vue的showBaseAttrs()
1 | showBaseAttrs() { |
商品新增VO抽取
1 |
|
1 |
|
1 |
|
1 |
|
1 |
|
1 |
|
1 |
|
商品新增业务流程分析
SpuInfoServiceImpl 下增加预备方法
1 | public void saveSpuInfo(SpuSaveVo vo) { |
SpuInfoController
1 | /** |
保存SPU基本信息
新增修改 SpuInfoServiceImpl
1 |
|
SpuInfoDescServiceImpl
1 |
|
SpuImagesServiceImpl
1 |
|
ProductAttrValueServiceImpl
1 |
|
保存SKU基本信息
修改SpuInfoServiceImpl
1 |
|
SkuInfoServiceImpl
1 |
|
调用远程服务保存优惠等信息
1.product模块的处理
1.1 在product模块下创建feign包,新建一个CouponFeignService远程调用接口:
1 |
|
1.2 在common模块新建一个to包,在该包下新建涉及的TO类
1 |
|
1 |
|
1 |
|
1.3 修改SpuInfoServiceImpl
1 |
|
1.4 在启动类加入@EnableFeignClients(basePackages = “com.centersept.supermall.product.feign”)注解,开启远程调用功能。
2.处理coupon模块
2.1 在nacos上配置Coupon模块的配置文件,Coupon模块引入nacos的配置
2.2 修改SpuBoundsController 方法
1 | /** |
2.3 新增 SkuFullReductionController 和 SkuFullReductionServiceImpl 的方法
1 |
|
1 |
|
商品保存debug完成
- 使用Idea一键启动全部项目
1.1 打开 Edit Configuration… ,点击加号,选择Compound
1.2 在右边的界面点击加号添加需要运行的Application类
- 由于库表的id非自增的,修改 SpuInfoDescEntity 实体类 id 注解为 @TableId(type = IdType.INPUT)
商品保存其他问题
1.空图片的数据不需要保存到库中,需要做过滤
2.还有满减和折扣没有设置的,也需要过滤保存
3.还有会员价格。
商品管理
SPU检索
1.SPU管理界面查询接口
SpuInfoController
1 | /** |
SpuInfoServiceImpl
1 | public PageUtils queryPageByCondition(Map<String, Object> params) { |
2.时间格式化,在application.yml 加入以下配置:
1 | spring: |
SKU检索
1.SKU管理界面查询
SkuInfoController
1 | /** |
SkuInfoServiceImpl
1 | public PageUtils queryPageByCondition(Map<String, Object> params) { |
SPU规格维护
1.获取SPU规格接口编写
1.1 编写/product/attr/base/listforspu/{spuId}
AttrController
1 |
|
ProductAttrValueServiceImpl
1 | public List<ProductAttrValueEntity> baseAttrlistforspu(Long spuId) { |
2.修改商品规格
2.1 编写 /product/attr/update/{spuId} 接口
AttrController
1 |
|
ProductAttrValueServiceImpl
1 |
|
仓储服务
仓库管理
整合ware服务&获取仓库列表
1.仓库管理页面查询
WareInfoServiceImpl
1 | public PageUtils queryPage(Map<String, Object> params) { |
查询库存&创建采购需求
1.商品库存管理页面查询接口
修改 WareSkuServiceImpl 查询接口
1 | public PageUtils queryPage(Map<String, Object> params) { |
2.采购需求管理页面查询接口
修改 PurchaseDetailServiceImpl 查询方法
1 | public PageUtils queryPage(Map<String, Object> params) { |
合并采购需求
1.查询未领取得采购单
PurchaseController
1 |
|
PurchaseServiceImpl
1 |
|
2.合并采购单
2.1 Common 模块创建Ware模块枚举类WareConstant
1 | public class WareConstant { |
2.2 创建前端接收类MergeVo
1 |
|
2.3 PurchaseServiceImpl 添加合并接口逻辑
1 |
|
2.4 PurchaseController 增加接口
1 |
|
领取采购单
/ware/purchase/received 接口 PurchaseController
1 | /** |
编写领取逻辑 PurchaseServiceImpl
1 | /** |
PurchaseDetailService 根据puchaseId 查找数据接口
1 | public List<PurchaseDetailEntity> listDetailByPurchaseId(Long id) { |
完成采购
1.新建两个接收前端信息的VO类
PurchaseDoneVo
1 |
|
PurchaseItemDoneVo
1 |
|
添加/ware/purchase/done 完成采购单接口
PurchaseController
1 | @PostMapping("/done") |
- 业务逻辑
PurchaseServiceImpl
1 |
|
WareSkuServiceImpl
1 | public void addStock(Long skuId, Long wareId, Integer skuNum) { |
WareSkuDao 添加方法
1 | void addStock( Long skuId, Long wareId, Integer skuNum); |
WareSkuDao.xml
1 | <update id="addStock"> |
4.由于需要查询skuName ,需要调用Product模块的查询方法来获取
4.1 在feign包下新建 ProductFeignService
1 |
|
4.2 在启动类加入feign 开启注解
4.3 修改 WareSkuServiceImpl 逻辑
1 |
|
分布式基础篇-总结
- 分布式基础概念
微服务,注册中心,配置中心,远程调用,Feign的使用,网关
- 基础开发
SpringBoot 2.0 ,SpringCloud,Mybatis-Plus,Vue组件化,阿里云对象存储
- 环境
Vagrant / VM,Linux,Docker,MySQL,Redis,逆向工程&人人开源项目
开发规范
数据校验JSR303,全局异常处理,全局统一返回,全局跨域处理
枚举状态,业务状态码,VO与TO与PO的划分,逻辑删除
Lombok:@Data,@Slf4j