谷粒商城-基础篇(详细流程梳理+代码)

  目前博主正在学习谷粒商城项目中,正在不断更新中…

  所有博客文件目录索引:博客目录索引(持续更新)

  在virtualbox创建centos7环境使用的是vagrant虚拟运行环境管理工具来进行构建的,可见该篇博客:虚拟运行环境管理工具Vagrant详细使用教程。

  效果如下:

  image-20221104104106097

  使用vagrant构建的centos7环境,默认的root没有设置密码,我们需要进行设置:

  快速构建Docker环境可见我之前博客(环境安装部分):快速使用Docker部署MySQL、Redis、Nginx

  Docker构建MySQL:

  image-20221107171836798

  在目录下创建文件:

  接着去拉取镜像并启动:

  Docker构建Redis:

  在mydata/redis目录下创建:文件如下

  image-20221107171852051

  其中配置已经修改了,包含如下:

  启动redis镜像,关键是设置其中的密码:

  后端

  后端开发工具:idea

  maven配置:Maven快速配置—配置文件

  idea插件安装:lombok、mybatisx、Gitee、jrebel(Java代码修改无需重启)插件和ResetfulTool(一套 RESTful 服务开发辅助工具集)

  JRebel插件使用详解(激活教程) 前端

  前端:vscode

  安装插件:

  Git的下载与配置可见我的博文(详细):Git详细使用指南(含详细命令、实操)

  包含添加密钥到码云。

  Gitee创建仓库:

  仓库名称、初始化仓库以及选择分支模型(生产/开发模型):

  image-20221104202253072

  IDEA导入仓库:

  image-20221104202424045

  image-20221104202501267

  创建完成如下:

  image-20221104202540327

  创建模块:商品服务(product)、仓储服务(ware)、订单服务(order)、优惠券服务(coupon)、用户服务(member)

  多模块相同组件:Springboot版本2.1.8.RELEASE、SpringCloud版本Greenwich.SR3

  构建完我们所需要的几个模块如下图(单个模块构建过程往下翻有示例):

  image-20221104204952962

  在当前目录下创建一个pom.xml(从之前模块中移过来),进行统一管理模块:

  如何导入这个聚合模块呢?右边Maven+号添加这个pom.xml即可:

  image-20221104205338439

  此时就会出现一个总的管理root:

  image-20221104205431563

  创建gulimall-product示例(版本说明)

  image-20221104202852229

  创建商品模块:

  image-20221104203052030

  组件选择:

  image-20221104203227039

  后来修正为视频一样的版本2.1.8 image-20221104203321866

  注意一下springboot与springcloud的版本:

  image-20221104203855679

  上面模块都构建好了之后,我们可以看到当前的版本控制管理有134个文件没有被管理:

  image-20221104205803489

  部分文件如.idea文件下的、target目录等我们在代码完成之后无需上传代码仓库,此时就需要在当前目录下的.gitignore中进行配置:

  一些配置信息如下:

  image-20221104210421967

  添加到版本控制操作:

  image-20221104210542835

  添加版本控制(add):

  image-20221104210642619

  提交到本地仓库(及push推送)

  image-20221104210830803

  image-20221104210856039

  OK,此时我们看下Gitee仓库状态,所有的代码已经进行了上传:

  image-20221104210934856

  下载安装数据库表设计工具

  PowerDesigner16.5:PowerDesigner安装+破解+汉化、PowerDesigner 安装破解

  image-20221105132711788

  下面是五个服务的表:

  image-20221105132801164

  创建数据库与表

  对应每一个微服务都操作一个数据库

  以商品系统为准,创建utf8mb4字符集的数据库:

  image-20221105113327318

  依次创建好数据库之后导入预先准备的sql(注意不要走navicat的直接导入可能会出现字段提示乱码问题,我们需要打开某个sql全选后在GUI中复制执行!):

  image-20221105113539929

  对于代码生成我们使用的是人人开源的项目:https://gitee.com/renrenio

  image-20221105133000390

  renren-fast作为后台管理系统后端服务renren-fast-vue作为后台管理系统页面renren-generator进行代码生成 后端系统服务

  renren-fast开源地址:https://gitee.com/renrenio/renren-fast

  将renren-fast添加到gulimall目录下:

  image-20221105133412940

  数据库创建``gulimall_admin`,并且导入项目中的db目录下的mysql.sql:

  image-20221105133650422

  将该模块项目导入到IDEA中,接着我们修改renren-fast中的application.yml文件中的数据库连接地址和用户名与密码:

  image-20221105135915706

  接着启动项目,启动成功如下图所示:

  image-20221105135943927

  在网页上进行测试一下:http://localhost:8080/renren-fast/

  image-20221105140008076

  为什么会有renren-fast后缀?主要是在application.yaml中配置了。

  前端服务

  renren-fast-vue开源地址:https://gitee.com/renrenio/renren-fast-vue

  下载克隆下来之后我们进入根目录下输入命令去导入依赖:

  关于node.js下载与npm包配置可见我的博客:Node.js学习笔记 认识Node.js以及npm使用 全部添加成功如下图所示:

  image-20221105140228797

  你可以在config目录下index.js里看到已经配置好了对应我们renren-fast也就是admin后台系统的api地址,我们无需进行改动:

  image-20221105140340497

  接着去运行命令启动前端服务并进行测试访问下后台管理系统:

  image-20221105140959356

  启动成功之后我们来访问下该页面:http://localhost:8001/

  image-20221105141023232

  成功登录后的效果如下所示:

  image-20221105141104723

  最终生成模块展示 renren-generator开源地址:https://gitee.com/renrenio/renren-generator

  下载克隆下来之后添加到gulimall中

  image-20221105141656240

  这个项目实际上提供了一个web服务,其能够连接对应的数据库通过页面中勾选指定的数据库来生成预先配置好的后端前端代码。

  对应逆向生成代码的操作可见下面示例章节!

  五个模块对应我们设置的开放端口为:

  初步搭建好的服务模块如下,右边的RestServices包含所有的服务:

  image-20221105194928531

  当前构建的环境代码:

  示例:在gulimall-product模块中添加逆向工程代码 application.yml:修改连接数据库的ip地址与数据库名、用户名与密码

  image-20221105142057146

  generator.properties:代码生成的配置项

  image-20221105142318175

  这个指的是引入的自定义工具类的包路径,如PageUtils、R等等。 启动该服务:http://localhost:80

  image-20221105142749697

  进入到网页之后,我们需要进行选中所有的表,然后进行生成代码:注意可能一个数据库会超过10条,那么我们选择一页显示50条,然后统一勾选

  image-20221105144049850

  生成代码的目录如下:

  image-20221105144226604

  我们将整个目录复制到工程的src目录下(去除掉resources下的src目录也就是前端代码):

  此时我们能够很明显的看到工程目录下java代码文件都是爆红,主要原因就是生成的代码中引入了一些当前工程没有引入的依赖(对于这这类可以生成不同模块的代码我们单独使用一个common包来进行引入一些第三方依赖):

  image-20221105144549127

  对于生成的代码解决方案:

  1、构建gulimall-common模块,引入生成代码所必须的一些工具类。

  image-20221105160424776

  pom.xml需要引入的第三方类:

  ②修改代码生成器中的controller代码模板(去除掉controller部分的shiro权限代码,谷粒商城将会使用的是springsecurity)

  image-20221105161013776

  2、针对当前模块自定义配置准备

  上面两步是针对之后所有逆向生成模块的额外步骤,接着我们来针对某个模块来进行配置,我们重新生成一下product代码放入到product模块中,接着做如下操作:

  ①pom.xml引入gulimall-common

  ②使用renren-generator来生成对应服务的逆向代码直接复制到src目录下

  ③在SpringBoot启动器上添加MapperScan包扫描路径

  image-20221105163233012

  ④编写配置,主要数据库源以及mp的配置:

  根据当前使用的springboot版本、Springcloud版本来选择对应的springcloud alibaba版本:Alibaba-SpringCloud Alibaba 版本说明

  image-20221105201810603

  对于2.1版本的springboot,我们需要选择2.1.2的springcloud alibaba,在谷粒商城视频里选择的是2.1.0,那我们这也就选择使用2.1.0,将其添加到模块中:

  image-20221105202024057

  由于每一个服务都需要添加到注册中心,那么将nacos注册发现统一集成到common模块当中:

  image-20221105211027850

  本地启动nacos服务,下载nacos-server1.1.3:https://github.com/alibaba/nacos/releases?page=4

  image-20221105211648331

  进入到bin目录,直接双击startup.cmd来进行启动:

  image-20221105212319934

  image-20221105212334156

  nacos访问服务端口默认是在8848端口:http://localhost:8848/nacos/

  最终集成的效果:

  image-20221105213832248

  查看下最终的nacos注册中心:

  image-20221105213912278

  示例:guli-coupon集成过程

  ①配置application.yaml

  在应用的 /src/main/resources/application.yaml配置文件中配置 Nacos Server 地址以及application.name也就是应用名称(才能够注册上):

  ②在启动器上开启服务注册发现注解:

  启动gulimall-coupon服务:

  image-20221105212644672

  查看下nacos注册中心是否已经注册上:

  image-20221105212707319

  实战目标:在营销服务中编写一个接口,接着在用户服务中编写一个用户优惠券接口,在这个接口中我们将会进行远程调用营销服务中的接口并进行返回(openfeign完成远程调用)。

  ①在gulimall-coupon服务中添加一个接口

  image-20221106145438411

  ②在gulimall-member服务中编写远程调用接口

  首先需要给gulimall-member服务中集成openfeign并进行开启feign包扫描进行加强:

  pom.xml引入:

  编写对应的feign接口:

  image-20221106145711008

  在启动器上添加自动包扫描:

  最后就是在控制器上添加一个接口其中就包含远程调用:

  image-20221106145744475

  测试下接口:

  image-20221106145812497

  介绍

  命名空间:可基于环境进行隔离、也可以根据单个微服务来进行隔离。

  配置集:指的就是单个命名空间下对应的group分组,场景如:单个服务在双11、618来进行分组隔离。

  实战

  由于我们的所有微服务都需要使用到配置中心,所以我们需要在gulimall-common模块中进行配置:

  image-20221106170009017

  接着我们就需要在对应需要使用配置中心配置信息的服务模块中添加bootstrap.properties文件:

  遵守的规则如下:

  当前谷粒商城规范:按照每个微服务来创建自己的命名空间,接着使用配置分组来区分环境如dev、test、prod。加载多配置集:对数据源、框架相关的配置来统一拆分成不同的配置文件。 image-20221106170216743

  对应在nacos管理面板上,我们需要进行添加一个单独服务的命名空间,并且去配置对应的配置文件其中包含有多环境的以及多配置信息文件:

  image-20221106170335368

  多环境:gulimall-coupon.properties。多配置(拆分):数据库、框架、单个微服务的相关配置。 对于上面多环境配置设置的目的就是我们当前来进行测试,对应测试的代码在controller中:

  image-20221106170628152

  启动nacos与gulimall-coupon来进行测试dev与pro环境:

  image-20221106170827651

  image-20221106170739798

  提示:上线之后我们可以配到配置中心去,线下写代码就直接配在本地即可(由于我使用了RestServices插件,读取配置中心的话对应的一些端口就需要我们自己去手动修改,同时也会很麻烦)。

  image-20221106171718008

  创建guilimall-gateway模块:

  image-20221106200558611

  image-20221106200739339

  image-20221106213406086

  ①pom.xml中引入公共模块

  由于引入了common模块,在common模块中还带了mybatis的依赖,所以需要对其进行排除(在启动器上):

  image-20221106213049034

  ②排除common组件的依赖

  ③编写注册中心的配置项

  image-20221106213118388

  bootstrap.properties:

  ④编写断言匹配url

  application.yml:

  image-20221106213226228

  对于其中的gateway断言我们进行了处理,之后我们来对其进行测试:

  image-20221106213301784

  image-20221106213321515

  在一般的电商平台上就包含有三级分类:

  image-20221107175627849

  在谷粒商城中,三级分类表是属于商品服务数据库中的表:

  image-20221107175846872

  核心字段:parent_cid(父类id)、sort(排序字段)我们的多级分类是根据父类id来进行划分的,一级分类就是为0,对应二级分类的parent_id就是0,同理三级分类的parent_id就是1。 默认在表中是没有数据的,我们需要来进行导入一些初始数据:

  将课件中的数据sql代码执行:

  image-20221107180109889

  完成效果

  目标:在gulimall-product模块中编写一个产品三级分类的递归数据结构获取的API接口。

  接口:http://localhost:10000/product/category/list/tree

  image-20221107180436181

  实现过程

  主要代码包含gulimall-product模块下:

  image-20221107180613802

  :控制器,对应产品分类的树型分类接口

  :产品分类实体中添加一个children集合属性,用于封装直接响应给前端,但是注意了这个属性我们需要加上@Field注解表示其不是数据库表中自带的属性,避免在使用mybatisplus查询时出现异常

  :定义接口方法

  :树型分类业务代码,其中就有涉及到一个递归处理操作

  其中的这个树型递归流程使用的是stream流来进行处理,filter过滤+map(填充子列表)+sorted(排序)最终使用collect来进行聚合。

  对于后台管理系统,原先是通过直接去访问renren-fast的服务地址来进行验证码、登录以及后台管理的一系列操作。

  对于分布式项目所有的请求都来通过统一的一个网关来进行路由到不同的服务,在这里我们首先来配置一下网关路由!

  后端服务(网关动态路由、集成跨域服务) renren-fast集成配置:

  首先将后台管理服务renren-fast也集成gulimall-common模块,让其也拥有服务注册的能力:

  image-20221107210940303

  :

  编写一个文件:用于进行服务注册以及配置中心地址配置、应用名

  在启动器上开启服务发现:

  gulimall-gateway集成配置:

  image-20221107211547120

  准备操作好了之后,我们就来进行服务模块的动态路由部分的编写,配置如下:

  由于所有的请求都会走我们的网关,那么我们就需要在网关处来进行跨域处理,我们编写一个跨域配置类:

  在网关处集成了跨域请求之后,我们需要去查看下网关路由的那些服务是否也有跨域请求,因为若是其他服务也有跨域请求处理的话,那么就会在响应头部分添加两次允许跨域的响应头信息,在renren-fast服务中就有,我们需要将其进行注释掉:

  image-20221108083325692

  至此,我们的后端服务就暂且集成完毕!

  前端服务 对于前端的话无需做很大的改动,只需要将全局的请求路径进行修改即可:

  image-20221107212342890

  对于后端服务来说,若是匹配到/api/**就会去进行动态路由匹配转发到后端管理服务去进行操作!

  测试 启动nacos注册中心、网关服务、后台管理服务:

  image-20221107212644845

  此时查看下nacos注册中心,看一下是否已经上线:

  image-20221107212715300

  没有问题,那么我们就启动前端管理系统项目,来进行一个验证码接口和登录接口的测试:

  image-20221107212750507

  验证码请求:

  image-20221107212837692

  login登录请求:

  image-20221107212927401

  前端产品分类页面创建 创建目录:

  image-20221107220115949

  创建一级菜单:

  image-20221107220245374

  看一下当前的分类效果:

  image-20221107220329158

  image-20221107220359275

  本质实际上就是在sys_menu表中加了两条记录:

  image-20221107220911035

  对应实际就会映射到这个文件:

  image-20221107220719533

  配置商品服务gulimall-product的动态路由地址 在gulimall-product服务中application.yml中配置商品服务的动态路由:

  image-20221108083620018

  提示:你可以看到对于产品服务的动态路由是配置到了renren-fast后台管理服务的路由之上,这是因为renren-fast的路由匹配是从就开始的,在gateway中去进行匹配是根据你配置的上下顺来来进行匹配转发的,而我们的商品服务动态路由则是匹配的,很明显商品服务的路由是后台管理服务的子路由,所以应该需要进行优先匹配,至此需要放置到其上面!

  简而言之:精确路由放在高优先级,模糊路由放在低优先级。

  前端产品分类接口实现(集成3.1.1查询接口) 对于树型组件的展示我们可以直接使用element ui的树型组件:

  image-20221108084204200

  代码如下:

  image-20221108084354774

  效果如下:

  image-20221108084430419

  接着我们要实现一个前端需求:

  效果如下:

  image-20221108150931991

  如何能够去添加右边的Append与Delete呢?这就使用到了vue中的插槽语法,修整后的代码如下:

  效果展示及思路 test

  思路逻辑:

  1、点击delete,进入message选择框。

  2、点击message选择框确认,发起删除请求,最后就是刷新菜单。

  注意:成功删除之后,原本展开那个分栏框依旧展开。(使用到了el-tree中的default-expanded-keys属性,只需要在刷新菜单后进行绑定即可) 后端代码(逻辑删除) 配置逻辑删除

  gulimall-product中的productEntity配置mybatisplus的逻辑删除注解:

  image-20221108151544467

  配置好了之后,我们去使用mp中baseMapper的查询与删除,默认会走的是逻辑删除及查询对应status=0的所有记录!

  删除代码逻辑

  :

  :当前仅仅直接实现了批量删除,对于引用的代码并没有进行编写

  前端代码 image-20221108151910526

  效果展示及思路 test

  思路:

  1、点击Append,出现弹窗,输入内容。

  2、点击确定,发起新增请求,请求结束刷新菜单,显示已经展开的分栏框。

  后端代码 直接就是之前逆向生成的代码,我们无需进行修改:

  image-20221108152546490

  前端代码 编辑分类:

  1、点击编辑回显分类信息,这个信息一定要从服务器中进行查询,否则可能会出现多个管理员去操作时显示的数据还是之前树型结构的。

  2、对于真正的编辑请求中携带的数据仅仅只是要进行修改的属性,其他不修改的一律不用携带。

  拖拽数据效果展示:

  el-tree的可拖拽节点:添加draggle属性

  对于是否能够拖到指定的层级位置,是要进行判定的。在当前的系统需求中来说是无法将某个分类拖动到第三级的标签中的。 对于拖拽的过程中是否允许:allowDrop(draggingNode, dropNode, type)方法,返回布尔类型,分别是拖动中的节点,目标节点以及拖动类型( 参数有三种情况:‘prev’、‘inner’ 和 ‘next’,分别表示放置在目标节点前、插入至目标节点和放置在目标节点后)

  拖拽成功可绑定触发事件:node-drop

  开启拖拽功能,只有开启才能够进行拖动。

  正在更新中…