【谷粒商城】全网最全笔记(1 4)_谷粒商城服务部署文档

134 阅读32分钟
# 在虚拟机中
mkdir -p /mydata/redis/conf
touch /mydata/redis/conf/redis.conf

docker pull redis

docker run -p 6379:6379 --name redis \
-v /mydata/redis/data:/data \
-v /mydata/redis/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf

# 直接进去redis客户端。
docker exec -it redis redis-cli

默认是不持久化的。在配置文件中输入appendonly yes,就可以aof持久化了。修改完docker restart redis,docker -it redis redis-cli

vim /mydata/redis/conf/redis.conf
# 插入下面内容
appendonly yes
保存

docker restart redis

设置redis容器在docker启动的时候启动

docker update redis --restart=always

安装nginx docker

安装nginx为P124的内容

docker pull nginx:1.10
# 随便启动一个nginx实例,只是为了复制出配置,放到docker里作为镜像的统一配置
docker run -p 80:80 --name nginx -d nginx:1.10

# 把nginx里的东西复制出来
cd /mydata/nginx
docker container cp nginx:/etc/nginx .
然后在外部 /mydata/nginx/nginx 有了一堆文件
mv /mydata/nginx/nginx /mydata/nginx/conf
# 停掉nginx
docker stop nginx
docker rm nginx

# 创建新的nginx,使用刚才复制出来的配置文件
docker run -p 80:80 --name nginx \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/logs:/var/log/nginx \
-v /mydata/nginx/conf:/etc/nginx \
-d nginx:1.10

# 注意一下这个路径映射到了/usr/share/nginx/html,我们在nginx配置文件中是写/usr/share/nginx/html,不是写/mydata/nginx/html

docker update nginx --restart=always

测试

cd /mydata/nginx/html/
vim index.html
随便写写
测试 http://192.168.56.10:80

四、IDEA开发环境

maven

在settings中配置阿里云镜像,配置jdk1.8。这个基本都配置过,不贴了

IDEA安装插件lombok,mybatisX。IDEA设置里配置好maven

vsCode设置

下载vsCode用于前端管理系统。在vsCode里安装插件。

  • Auto Close Tag
  • Auto Rename Tag
  • Chinese
  • ESlint
  • HTML CSS Support
  • HTML Snippets
  • JavaScript ES6
  • Live Server
  • open in brower
  • Vetur

五、git代码相关

安装git

下载git客户端,右键桌面Git GUI/bash Here。去bash,

# 配置用户名
git config --global user.name "username"  //(名字,随意写)

# 配置邮箱
git config --global user.email "55333@qq.com" // 注册账号时使用的邮箱

# 配置ssh免密登录
ssh-keygen -t rsa -C "55333@qq.com"
三次回车后生成了密钥:公钥私钥
cat ~/.ssh/id_rsa.pub

也可以查看密钥
浏览器登录码云后,个人头像上点设置--ssh公钥---随便填个标题---复制
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6MWhGXSKdRxr1mGPZysDrcwABMTrxc8Va2IWZyIMMRHH9Qn/wy3PN2I9144UUqg65W0CDE/thxbOdn78MygFFsIG4j0wdT9sdjmSfzQikLHFsJ02yr58V6J2zwXcW9AhIlaGr+XIlGKDUy5mXb4OF+6UMXM6HKF7rY9FYh9wL6bun9f1jV4Ydlxftb/xtV8oQXXNJbI6OoqkogPKBYcNdWzMbjJdmbq2bSQugGaPVnHEqAD74Qgkw1G7SIDTXnY55gBlFPVzjLWUu74OWFCx4pFHH6LRZOCLlMaJ9haTwT2DB/sFzOG/Js+cEExx/arJ2rvvdmTMwlv/T+6xhrMS3 553736044@qq.com

# 测试
ssh -T git@gitee.com
测试成功,就可以无密给码云推送仓库了

码云

本课程老师选用的是gitee,你选择提交到github也可以

现有项目

项目刚出来的时候老师没把代码放出来,但现在好像把完整版的代码放出来了,所以你可以运行老师给的项目试一下。

但是老师的项目nacos等信息可能没有,还需要你自己搭建。一个好的方式是编译nacos的源码项目到IDEA中。而这种解决方案网上开源的同学们都是这么做的。

除此之外,基本老师给的项目里都全了,你要做的就是改改里面的配置信息等。

我的gitee只作为参考,主要注重记笔记了,或者隔了好久有的地方有差异了

但是把项目运行起来可不是简单的事,有很多东西需要自己配置

从0搭建

在码云新建仓库,仓库名gulimall,选择语言java,在.gitignore选中maven(就会忽略掉maven一些个人无需上传的配置文件),许可证选Apache-2.0,开发模型选生成/开发模型,开发时在dev分支,发布时在master分支,创建。

在IDEA中New–Project from version control–git–复制刚才项目的地址

IDEA然后New Module–Spring Initializer–com.atguigu.gulimall , Artifact填 gulimall-product。Next—选择web(web开发),springcloud routing里选中openFeign(rpc调用)。

依次创建出以下服务模块

  • 商品服务product
  • 存储服务ware
  • 订单服务order
  • 优惠券服务coupon
  • 用户服务member

共同点:

  • 导入web和openFeign
  • group:com.atguigu.gulimall
  • Artifact:gulimall-XXX
  • 每一个服务,包名com.atguigu.gulimall.XXX{product/order/ware/coupon/member}
  • 模块名:gulimall-XXX

然后右下角显示了springboot的service选项,选择他

从某个项目粘贴个pom.xml粘贴到项目目录,修改他

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.atguigu.gulimall</groupId>
	<artifactId>gulimall</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>gulimall</name>
	<description>聚合服务</description>

	<packaging>pom</packaging>

	<modules>
		<module>gulimall-coupon</module>
		<module>gulimall-member</module>
		<module>gulimall-order</module>
		<module>gulimall-product</module>
		<module>gulimall-ware</module>
	</modules>

</project>

在maven窗口刷新,并点击+号,找到刚才的pom.xml添加进来,发现多了个root。这样比如运行root的clean命令,其他项目也一起clean了。

修改总项目的.gitignore,把小项目里的垃圾文件在提交的时候忽略掉,比如HELP.md。。。

**/mvnw
**/mvnw.cmd
**/.mvn
**/target/
.idea
**/.gitignore

如果你是拉取的我的仓库(尚未公布),你也可以看到我仓库里是没有那些target目录的,非常精简

在version control/local Changes,点击刷新看Unversioned Files,可以看到变化。

全选最后剩下21个文件,选择右键、Add to VCS。

在IDEA中安装插件:gitee,重启IDEA。

在D额fault changelist右键点击commit,去掉右面的勾选Perform code analysis、CHECK TODO,然后点击COMMIT,有个下拉列表,点击commit and push才会提交到云端。此时就可以在浏览器中看到了。

  • commit只是保存更新到本地
  • push才是提交到gitee

六、数据库

课件提供了sql,但是里面只有表,没有数据,所以建议不要用课件里的。

另外视频评论区的sql文件有问题,后面和sql查询java-entity类对应不上

我自己修改过的sql上传到了:gitee.com/HanFerm/gul…

评论区有人提醒过:博主发的sql文件gulimall_admin里面的schedule_job表要清空,不然启动renrenfast模块会报获取定时任务CronTrigger出现异常

这个问题时间逆序确实不好排查,如果你遇到这个问题,可以按此方法尝试解决下。

使用的时候注意下数据库名和IDEA中设置是否匹配

如何改:加上类似下面的语句

CREATE DATABASE /\*!32312 IF NOT EXISTS\*/`guli_pms` /\*!40100 DEFAULT CHARACTER SET utf8mb4 \*/;

-- 根据需要改数据库名即可,表名无需改动
USE `gulimall_pms`;
-- 也集合P71的内容进行了修改

因为已经有人贡献sql文件了,所以我们不理会下面引用部分的内容了。

安装powerDesigner软件。forspeed.onlinedown.net/down/powerd…

其他软件:
www.lanzous.com/b015ag33e

密码:2wre

所有的数据库数据再复杂也不建立外键,因为在电商系统里,数据量大,做外键关联很耗性能。

name是给我们看的,code才是数据库里真正的信息。

选择primary和identity作为主键。然后点preview就可以看到生成这张表的语句。

点击菜单栏database–generate database—点击确定

找到视频评论区的sql文件,打开sqlyog软件,链接(linux里的mysql docker镜像)192.168.56.10,账号密码root。

注意重启虚拟机和docker后里面的容器就关了。

sudo docker ps
sudo docker ps -a
# 这两个命令的差别就是后者会显示 【已创建但没有启动的容器】

# 我们接下来设置我们要用的容器每次都是自动启动
sudo docker update redis --restart=always
sudo docker update mysql --restart=always
# 如果不配置上面的内容的话,我们也可以选择手动启动
sudo docker start mysql
sudo docker start redis
# 如果要进入已启动的容器
sudo docker exec -it mysql /bin/bash
# /bin/bash就是进入一般的命令行,如果改成redis就是进入了redis

然后接着去sqlyog执行我们的操作,在左侧root上右键建立数据库:字符集选utf8mb4,他能兼容utf8且能解决一些乱码的问题。分别建立了下面数据库(根据自己情况来)

gulimall-oms
gulimall-pms
gulimall-sms
gulimall-ums
gulimall-wms

然后打开对应的sql在对应的数据库中执行。依次执行。(注意sql文件里没有建库语句)

VSCode准备

点击执行sql脚本,依次选择评论区给的压缩包里的sql语句

七、人人项目npm

1 自己搭建的方式

在码云上搜索人人开源,我们使用renren-fast(后端)、renren-fast-vue(前端)项目。

gitee.com/renrenio

git clone https://gitee.com/renrenio/renren-fast.git

git clone https://gitee.com/renrenio/renren-fast-vue.git

下载到了桌面,我们把renren-fast移动到我们的项目文件夹(删掉.git文件),而renren-vue是用VSCode打开的(后面再弄)

在IDEA项目里的pom.xml添加一个renrnen-fast

<modules>
    <module>gulimall-coupon</module>
    <module>gulimall-member</module>
    <module>gulimall-order</module>
    <module>gulimall-product</module>
    <module>gulimall-ware</module>

    <module>renren-fast</module>
</modules>

然后打开renren-fast/db/mysql.sql,复制全部,在sqlyog中创建库guli-admin,粘贴刚才的内容执行。

然后修改项目里renren-fast中的application.yml,修改application-dev.yml中的数库库的url,通常把localhost修改为192.168.56.10即可。然后该对后面那个数据库

url: jdbc:mysql://192.168.56.10:3306/guli_admin?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: root

然后运行该java项目下的RenrenApplication

浏览器输入http://localhost:8080/renren-fast/ 得到{“msg”:“invalid token”,“code”:401}就代表无误

人人vue(npm)

用VSCode打开renren-fast-vue(如果自己搭建的话),如果是运行完整的代码,可以去课件里找gulimall-admin-vue-app

安装node:nodejs.cn/download/ 选择windows下载。下载完安装。

可以去这里找到v12的版本。(不要用12.0,可以用12.1)

npm.taobao.org/mirrors/nod…

NPM是随同NodeJS一起安装的包管理工具。JavaScript-NPM类似于java-Maven。

命令行输入node -v 检查配置好了,配置npm的镜像仓库地址,再执

node -v
npm config set registry http://registry.npm.taobao.org/

然后去VScode的项目终端中输入 npm install,是要去拉取依赖(package.json类似于pom.xml的dependency),但是会报错,然后进行如下操作:

启动fast-vue项目

结合下面的报错

P16 npm install报错问题

视频评论区没几个说对的,个人的各种分析写到了这里:

blog.csdn.net/hancoder/ar…

八、人人项目-逆向工程

逆向工程搭建

git clone https://gitee.com/renrenio/renren-generator.git

下载到桌面后,同样把里面的.git文件删除,然后移动到我们IDEA项目目录中,同样配置好pom.xml

<modules>
    <module>gulimall-coupon</module>
    <module>gulimall-member</module>
    <module>gulimall-order</module>
    <module>gulimall-product</module>
    <module>gulimall-ware</module>
    <module>renren-fast</module>
    <module>renren-generator</module>
</modules>

在maven中刷新一下,让项目名变粗体,稍等下面进度条完成。

修改application.yml

url: jdbc:mysql://192.168.56.10:3306/gulimall-pms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: root

然后修改generator.properties(这里乱码的百度IDEA设置properties编码)

# 主目录
mainPath=com.atguigu
#包名
package=com.atguigu.gulimall
#模块名
moduleName=product
#作者
author=hh
#email
email=55333@qq.com
#表前缀(类名不会包含表前缀) # 我们的pms数据库中的表的前缀都pms
# 如果写了表前缀,每一张表对于的javaBean就不会添加前缀了
tablePrefix=pms_

运行RenrenApplication。如果启动不成功,修改application中是port为801。访问http://localhost:801/

在网页上下方点击每页显示50个(pms库中的表),以让全部都显示,然后点击全部,点击生成代码。下载了压缩包

解压压缩包,把main放到gulimall-product的同级目录下。

common

然后在项目上右击(在项目上右击很重要)new modules— maven—然后在name上输入gulimall-common。

在pom.xml中也自动添加了<module>gulimall-common</module>

在common项目的pom.xml中添加

<!-- mybatisPLUS-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.3.2</version>
</dependency>
<!--简化实体类,用@Data代替getset方法-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.8</version>
</dependency>
<!-- httpcomponent包。发送http请求 -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpcore</artifactId>
    <version>4.4.13</version>
</dependency>
<dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.6</version>
</dependency>

我们把每个微服务里公共的类和依赖放到common里。

tips: shift+F6修改项目名

此外,说下maven依赖的问题。

  • <dependency>代表本项目依赖,子项目也依赖

  • 如果有个<optional>标签,代表本项目依赖,但是子项目不依赖,即不传递依赖

然后在product项目中的pom.xml中加入下面内容,作为common的子项目

<dependency>
    <groupId>com.atguigu.gulimall</groupId>
    <artifactId>gulimall-common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

  • 复制renren-fast----utils包下的Query和PageUtilsRConstant复制到common项目的java/com.atguigu.common.utils下。

关于R为什么可以序列化的疑问:

之前我在思考R类为什么可以RPC传输的问题,R类继承了hashmap,你会发现map里的table[]数组是transient的,也就是不序列化的。那么是如何网络传输的呢?

在探索的过程中我也被clone方法误导了一下,为了重试内容,我这里贴出来Clone的知识吧:HashMap实现了Clonable接口且重写了clone()方法,我们可以大致看出来就是先调用了父类的clone()方法,然后强转,最后把元素设置进去。

public class HashMap<K,V> extends AbstractMap<K,V>
 implements Map<K,V>, Cloneable, Serializable {
 // 不序列化
 transient Node<K,V>[] table;
 
 @Override
 public Object clone() {
     HashMap<K,V> result;
     try {
       /\*
 最终调用的是Object.clone(),注释说明内容:
 Object.clone()是一种浅拷贝,即对基础类型直接复制,和引用类型的成员变量值拷贝的仅仅的地址,也就是并不会递归式克隆。
 该方法关键字有几个信息:必须继承Cloneable才能调用clone()方法;只能在子类中才能调用super.clone();方法返回Object对象,需要强转
 protected native Object clone() throws CloneNotSupportedException;
 \*/  
         result = (HashMap<K,V>)super.clone();
     } catch (CloneNotSupportedException e) {
         // this shouldn't happen, since we are Cloneable
         throw new InternalError(e);
     }
     result.reinitialize();
     result.putMapEntries(this, false);
     return result;
 }

再回到原来的问题,table[]数组是transient的,那怎么序列化呢?我目前的认知是其实跟clone没有关系,而是与另一个序列化方法有关系:writeObject()

private void writeObject(java.io.ObjectOutputStream s)
 throws IOException {
 int buckets = capacity();
 // Write out the threshold, loadfactor, and any hidden stuff
 s.defaultWriteObject();
 s.writeInt(buckets);
 s.writeInt(size);
 // 这个方法会遍历元素写入流中
 internalWriteEntries(s);
}

看一下该方法,我们可以大概看出,其实写入流中时,并不写入数组(如果只有一个元素却要写入数组会很浪费空间),而是先往流中写入原来的map中的容量和结点元素的个数,这样另一端输出时就知道要接收多少Entry(Node结点)了。然后把数组中的元素一次写入到流中,另一端就彻底完成了map的复制(可以看看readObject()方法)。

  • 把@RequiresPermissions这些注解掉,因为是shiro的
  • 复制renren-fast中的xss包粘贴到common的com.atguigu.common目录下。

还复制了exception文件夹,对应的位置关系自己观察一下就行

  • 注释掉product项目下类中的//import org.apache.shiro.authz.annotation.RequiresPermissions;,他是shiro的东西
  • 注释renren-generator\src\main\resources\template/Controller中所有的@RequiresPermissions。## import org.apache.shiro.authz.annotation.RequiresPermissions;

总之什么报错就去fast里面找。重启逆向工程。重新在页面上得到压缩包。重新解压出来,不过只把里面的controller复制粘贴到product项目对应的目录就行。

测试

测试与整合商品服务里的mybatisplus

mp.baomidou.com/guide/quick…

在common的pom.xml中导入

<!-- 数据库驱动 https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.17</version>
</dependency>
<!--tomcat里一般都带-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
</dependency>

删掉common里xss/xssfiler和XssHttpServletRequestWrapper

在product项目的resources目录下新建application.yml

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://192.168.56.10:3306/gulimall-pms
    driver-class-name: com.mysql.jdbc.Driver

# MapperScan
# sql映射文件位置
mybatis-plus:
  mapper-locations: classpath:/mapper/\*\*/\*.xml
  global-config:
    db-config:
      id-type: auto

classpath 和 classpath* 区别:
classpath:只会到你的class路径中查找找文件;
classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找

classpath*的使用:当项目中有多个classpath路径,并同时加载多个classpath路径下(此种情况多数不会遇到)的文件,*就发挥了作用,如果不加*,则表示仅仅加载第一个classpath路径。

然而执行后能通过,但是数据库中文显示乱码,所以我模仿逆向工程,把上面的配置url改为

url: jdbc:mysql://192.168.56.10:3306/guli_pms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai

正常了。

然后在主启动类上加上注解@MapperScan()

@MapperScan("com.atguigu.gulimall.product.dao")
@SpringBootApplication
public class gulimallProductApplication {

    public static void main(String[] args) {

        SpringApplication.run(gulimallProductApplication.class, args);
    }
}

然后去测试,先通过下面方法给数据库添加内容

@SpringBootTest
class gulimallProductApplicationTests {
    @Autowired
    BrandService brandService;

    @Test
    void contextLoads() {
        BrandEntity brandEntity = new BrandEntity();
        brandEntity.setDescript("哈哈1哈");
        brandEntity.setName("华为");
        brandService.save(brandEntity);
        System.out.println("保存成功");
    }
}

在数据库中就能看到新增数据了

@SpringBootTest
class gulimallProductApplicationTests {
    @Autowired
    BrandService brandService;

    @Test
    void contextLoads() {
        BrandEntity brandEntity = new BrandEntity();
        brandEntity.setBrandId(1L);
        brandEntity.setDescript("修改");
        brandService.updateById(brandEntity);
    }
}

coupon

优惠券服务。重新打开generator逆向工程,修改generator.properties

# 主目录
mainPath=com.atguigu
#包名
package=com.atguigu.gulimall
#模块名
moduleName=coupon
#作者
autho=hh
#email
email=55333@qq.com
#表前缀(类名不会包含表前缀) # 我们的pms数据库中的表的前缀都pms
# 如果写了表前缀,每一张表对于的javaBean就不会添加前缀了
tablePrefix=sms_

修改yml数据库信息

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://192.168.56.10:3306/gulimall-sms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver

mybatis-plus:
  mapper-locations: classpath:/mapper/\*\*/\*.xml
  global-config:
    db-config:
      id-type: auto
      logic-delete-value: 1
      logic-not-delete-value: 0

server:
  port: 7000

端口号后面会设置,这里提前设置好了

启动生成RenrenApplication.java,运行后去浏览器80端口查看,同样让他一页全显示后选择全部后生成。生成后解压复制到coupon项目对应目录下。

让coupon也依赖于common,修改pom.xml

<dependency>
    <groupId>com.atguigu.gulimall</groupId>
    <artifactId>gulimall-common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

resources下src包先删除

添加application.yml

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://192.168.56.10:3306/gulimall-sms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver


mybatis-plus:
  mapper-locations: classpath:/mapper/\*\*/\*.xml
  global-config:
    db-config:
      id-type: auto
      logic-delete-value: 1
      logic-not-delete-value: 0

运行gulimallCouponApplication.java

隔了好几个月的注:直接clone别人的项目这里可能运行不起来。。。因为如后面依赖了nacos等服务,克隆的话这里暂时运行不起来。

http://localhost:7000/coupon/coupon/list

{"msg":"success","code":0,"page":{"totalCount":0,"pageSize":10,"totalPage":0,"currPage":1,"list":[]}}

member

重新使用逆向工程生成ums数据库相关的代码

模仿上面修改下面两个配置

代码生成器里:

    url: jdbc:mysql://192.168.56.10:3306/gulimall-ums?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai

# 主目录
mainPath=com.atguigu
#包名
package=com.atguigu.gulimall
#模块名
moduleName=member
#作者
author=hh
#email
email=55333@qq.com
#表前缀(类名不会包含表前缀) # 我们的pms数据库中的表的前缀都pms
# 如果写了表前缀,每一张表对于的javaBean就不会添加前缀了
tablePrefix=ums_

重启RenrenApplication.java,然后同样去浏览器获取压缩包解压到对应member项目目录

member也导入依赖

<dependency>
    <groupId>com.atguigu.gulimall</groupId>
    <artifactId>gulimall-common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

同样新建application.yml

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://192.168.56.10:3306/gulimall-ums?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver


mybatis-plus:
  mapper-locations: classpath:/mapper/\*\*/\*.xml
  global-config:
    db-config:
      id-type: auto
      logic-delete-value: 1
      logic-not-delete-value: 0

server:
  port: 8000

order端口是9000,product是10000,ware是11000。

以后比如order系统要复制多份,他的端口计算9001、9002。。。

重启web后,http://localhost:8000/member/growthchangehistory/list

{"msg":"success","code":0,"page":{"totalCount":0,"pageSize":10,"totalPage":0,"currPage":1,"list":[]}}

order

修改代码生成器

    url: jdbc:mysql://192.168.56.10:3306/gulimall-oms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai

#代码生成器,配置信息

# 主目录
mainPath=com.atguigu
#包名
package=com.atguigu.gulimall
#模块名
moduleName=order
#作者
author=hh
#email
email=55333@qq.com
#表前缀(类名不会包含表前缀) # 我们的pms数据库中的表的前缀都pms
# 如果写了表前缀,每一张表对于的javaBean就不会添加前缀了
tablePrefix=oms_

运行RenrenApplication.java重新生成后去下载解压放置。

application.yml

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://192.168.56.10:3306/gulimall-oms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver


mybatis-plus:
  mapper-locations: classpath:/mapper/\*\*/\*.xml
  global-config:
    db-config:
      id-type: auto
      logic-delete-value: 1
      logic-not-delete-value: 0
      
server:
  port: 9000

POMxml

<dependency>
    <groupId>com.atguigu.gulimall</groupId>
    <artifactId>gulimall-common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

启动gulimallOrderApplication.java

http://localhost:9000/order/order/list

{"msg":"success","code":0,"page":{"totalCount":0,"pageSize":10,"totalPage":0,"currPage":1,"list":[]}}

ware

修改代码生成器

    url: jdbc:mysql://192.168.56.10:3306/gulimall-wms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai


#代码生成器,配置信息

# 主目录
mainPath=com.atguigu
#包名
package=com.atguigu.gulimall
#模块名
moduleName=ware
#作者
author=hh
#email
email=55333@qq.com
#表前缀(类名不会包含表前缀) # 我们的pms数据库中的表的前缀都pms
# 如果写了表前缀,每一张表对于的javaBean就不会添加前缀了
tablePrefix=wms_

运行RenrenApplication.java重新生成后去下载解压放置。

application.yml

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://192.168.56.10:3306/gulimall-wms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver


mybatis-plus:
  mapper-locations: classpath:/mapper/\*\*/\*.xml
  global-config:
    db-config:
      id-type: auto
      logic-delete-value: 1
      logic-not-delete-value: 0
      
server:
  port: 11000

POMxml

<dependency>
    <groupId>com.atguigu.gulimall</groupId>
    <artifactId>gulimall-common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

启动gulimallWareApplication.java

http://localhost:11000/ware/wareinfo/list

{"msg":"success","code":0,"page":{"totalCount":0,"pageSize":10,"totalPage":0,"currPage":1,"list":[]}}

九、SpringCloud Alibaba简介

springcloud个人笔记:blog.csdn.net/hancoder/ar…

阿里18年开发的微服务一站式解决方案。github.com/alibaba/spr…

  • 注册中心:nacos
  • 配置中心:nacos
  • 网关:gateway
  • 远程调用:netflix把feign闭源了,spring cloud开了个openFeign

在common的pom.xml中加入

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.2.0.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

上面是dependencyManagement依赖管理,相当于以后在dependencies里引spring cloud alibaba就不用写版本号。注意他和普通依赖的区别,他只是备注一下,并没有加入依赖

十、Nacos-8848

springcloud个人笔记:blog.csdn.net/hancoder/ar…

一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。

nacos作为我们的注册中心和配置中心。

注册中心文档:github.com/alibaba/spr…

其他文档在该项目上层即可找到,下面读一读官网给的介绍就会用了。

安装启动nacos:下载–解压–双击bin/startup.cmd。http://127.0.0.1:8848/nacos/ 账号密码nacos

自己搭建nacos源码(推荐):blog.csdn.net/xiaotian518…

为了能git管理nacos及其内置的数据库,我们采用这种方式,方便你运行时也保留原有内置数据库内容

Linux/Unix/Mac 操作系统,执行命令 sh startup.sh -m standalone

使用nacos:

  • 在某个项目里properties里写spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848(yaml同理,指定nacos的地址)。再指定applicatin.name告诉注册到nacos中以什么命名

  • 依赖:放到common里,不写版本是因为父项目或spring-cloud里面有了版本管理

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

  • 使用 @EnableDiscoveryClient 注解开启服务注册与发现功能

@SpringBootApplication
@EnableDiscoveryClient // 
public class ProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @RestController
    class EchoController {
        @GetMapping(value = "/echo/{string}")
        public String echo(@PathVariable String string) {
            return string;
        }
    }
}

最后application.yml内容,配置了服务中心名和当前模块名字

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://192.168.56.10:3306/gulimall-sms?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
  application:
    name: gulimall-coupon


mybatis-plus:
  mapper-locations: classpath:/mapper/\*\*/\*.xml
  global-config:
    db-config:
      id-type: auto
      logic-delete-value: 1
      logic-not-delete-value: 0

server:
  port: 7000

然后依次给member、配置上面的yaml,改下name就行。再给每个项目配置类上加上注解@EnableDiscoveryClient

nacos测试:

测试member和coupon的远程调用

想要获取当前会员领取到的所有优惠券。先去注册中心找优惠券服务,注册中心调一台优惠券服务器给会员,会员服务器发送请求给这台优惠券服务器,然后对方响应。

  • 服务请求方发送了2次请求,先问nacos要地址,然后再请求

十一、Feign(远程调用)与注册中心

声明式远程调用

feign是一个声明式的HTTP客户端,他的目的就是让远程调用更加简单。给远程服务发的是HTTP请求。

会员服务想要远程调用优惠券服务,只需要给会员服务里引入openfeign依赖,他就有了远程调用其他服务的能力。

pom.xml

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

我们之前在member的pom.xml已经引用过了(微服务)。

在coupon中修改如下的内容

@RequestMapping("coupon/coupon")
public class CouponController {
    @Autowired
    private CouponService couponService;

    @RequestMapping("/member/list")
    public R membercoupons(){    //全系统的所有返回都返回R
        // 应该去数据库查用户对于的优惠券,但这个我们简化了,不去数据库查了,构造了一个优惠券给他返回
        CouponEntity couponEntity = new CouponEntity();
        couponEntity.setCouponName("满100-10");//优惠券的名字
        return R.ok().put("coupons",Arrays.asList(couponEntity));
    }

这样我们准备好了优惠券的调用内容

在member的配置类上加注解@EnableDiscoveryClient,告诉member是一个远程调用客户端,member要调用东西的

/\*
\* 想要远程调用的步骤:
\* 1 引入openfeign
\* 2 编写一个接口,接口告诉springcloud这个接口需要调用远程服务
\* 2.1 在接口里声明@FeignClient("gulimall-coupon")他是一个远程调用客户端且要调用coupon服务
\* 2.2 要调用coupon服务的/coupon/coupon/member/list方法
\* 3 开启远程调用功能 @EnableFeignClients,要指定远程调用功能放的基础包
\* \*/
@EnableFeignClients(basePackages="com.atguigu.gulimall.member.feign")//扫描接口方法注解
@EnableDiscoveryClient// 注册到nacos
@SpringBootApplication
public class gulimallMemberApplication {

	public static void main(String[] args) {
		SpringApplication.run(gulimallMemberApplication.class, args);
	}
}

那么要调用什么东西呢?就是我们刚才写的优惠券的功能,复制函数部分,在member的com.atguigu.gulimall.member.feign包下新建类:

@FeignClient("gulimall-coupon") //告诉spring cloud这个接口是一个远程客户端,要调用coupon服务(nacos中找到),具体是调用coupon服务的/coupon/coupon/member/list对应的方法
public interface CouponFeignService {
    // 远程服务的url
    @RequestMapping("/coupon/coupon/member/list")//注意写全优惠券类上还有映射//注意我们这个地方不是控制层,所以这个请求映射请求的不是我们服务器上的东西,而是nacos注册中心的
    public R membercoupons();//得到一个R对象
}

@FeignClient+@RequestMapping构成远程调用的坐标

其他类中看似只是调用了CouponFeignService.membercoupons(),而实际上该方法跑去nacos里和rpc里调用了才拿到东西返回

然后我们在member的控制层写一个测试请求

@RestController
@RequestMapping("member/member")
public class MemberController {
    @Autowired
    private MemberService memberService;

    @Autowired
    CouponFeignService couponFeignService;

    @RequestMapping("/coupons")
    public R test(){
        MemberEntity memberEntity = new MemberEntity();
        memberEntity.setNickname("会员昵称张三");
        R membercoupons = couponFeignService.membercoupons();//假设张三去数据库查了后返回了张三的优惠券信息

        //打印会员和优惠券信息
        return R.ok().put("member",memberEntity).put("coupons",membercoupons.get("coupons"));
    }

重新启动服务刷新容器

测试:http://localhost:8000/member/member/coupons

{
    "msg":"success",
    "code":0,
    "coupons":[
        {"id":null,"couponType":null,"couponImg":null,
         "couponName":"满100-10","num":null,"amount":null,"perLimit":null,
         "minPoint":null,"startTime":null,"endTime":null,"useType":null,
         "note":null,"publishCount":null,"useCount":null,"receiveCount":null,
         "enableStartTime":null,"enableEndTime":null,"code":null,
         "memberLevel":null,"publish":null}
    ],
    "member":{"id":null,"levelId":null,"username":null,"password":null,
              "nickname":"会员昵称张三","mobile":null,"email":null,
              "header":null,"gender":null,"birth":null,
              "city":null,"job":null,"sign":null,"sourceType":null,
              "integration":null,"growth":null,"status":null,"createTime":null}
}

上面讲的内容很重要,我们停留5分钟体会一下调用逻辑。

coupon里的R.ok()是什么,就是设置了个msg

public class R extends HashMap<String, Object> {//R继承了HashMap
    // ok是个静态方法,new了一个R对象,并且
    public static R ok(String msg) {
        R r = new R();
        r.put("msg", msg);//调用了super.put(key, value);,即hashmap的put
        return r;
    }
}

nacos作为配置中心

我们还可以用nacos作为配置中心。配置中心的意思是不在application.properties等文件中配置了,而是放到nacos配置中心公用,这样无需每台机器都改。

官方教程:github.com/alibaba/spr…

common中添加依赖 nacos配置中心

<dependency>
     <groupId>com.alibaba.cloud</groupId>
     <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
 </dependency>

在coupons项目中创建/src/main/resources/bootstrap.properties ,这个文件是springboot里规定的,他优先级别application.properties高

# 改名字,对应nacos里的配置文件名
spring.application.name=gulimall-coupon
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

还是原来我们使用配置的方式,只不过优先级变了,所以匹配到了nacos的配置

还是配合@Value注解使用

@RestController
@RequestMapping("coupon/coupon")
public class CouponController {
    @Autowired
    private CouponService couponService;

    @Value("${coupon.user.name}")//从application.properties中获取//不要写user.name,他是环境里的变量
    private String name;
    @Value("${coupon.user.age}")
    private Integer age;
    @RequestMapping("/test")
    public R test(){

        return R.ok().put("name",name).put("age",age);
    }

浏览器去nacos里的配置列表,点击+号,data ID:gulimall-coupon.properties,配置

# gulimall-coupon.properties
coupon.user.name="配置中心"      
coupon.user.age=12

然后点击发布。重启coupon(生产中加入@RefreshScope即可),http://localhost:7000/coupon/coupon/test

{"msg":"success","code":0,"name":"配置中心","age":12}

但是修改肿么办?实际生产中不能重启应用。在coupon的控制层上加@RefreshScope

@RefreshScope
@RestController
@RequestMapping("coupon/coupon")
public class CouponController {
    @Autowired
    private CouponService couponService;

    @Value("${coupon.user.name}")//从application.properties中获取//不要写user.name,他是环境里的变量
    private String name;
    @Value("${coupon.user.age}")
    private Integer age;
    
    @RequestMapping("/test")
    public R test(){
        return R.ok().put("name",name).put("age",age);
    }

重启后(让注解生效),在nacos浏览器里修改配置,修改就可以观察到能动态修改了

nacos的配置内容优先于项目本地的配置内容。

配置中心进阶

在nacos浏览器中还可以配置:

  • 命名空间:用作配置隔离。(一般每个微服务一个命名空间)

    • 默认public。默认新增的配置都在public空间下

    • 开发、测试、开发可以用命名空间分割。properties每个空间有一份。也可以为每个微服务配置一个命名空间,微服务互相隔离

    • 在bootstrap.properties里配置(测试完去掉,学习不需要)

    # 可以选择对应的命名空间 # 写上对应环境的命名空间ID
    spring.cloud.nacos.config.namespace=b176a68a-6800-4648-833b-be10be8bab00
    
    
  • 配置集:一组相关或不相关配置项的集合。

  • 配置集ID:类似于配置文件名,即Data ID

  • 配置分组:默认所有的配置集都属于DEFAULT_GROUP。双十一,618的优惠策略改分组即可

# 更改配置分组
spring.cloud.nacos.config.group=DEFAULT_GROUP

其他划分方案:

  • NameSpace:命名空间 默认为public,其作用可以用来实现环境隔离作用,比如我们的开发环境、测试环境、生产环境。

  • Group:默认分组为DEFAULT_GROUP,Group 可以将不同的微服务进行分组划分。

  • Service/DataId: 也就是微服务工程,一个微服务工程可以有多个集群中心,比如一个消费者工程可以使用两个中心,每个中心读取不同的配置文件,每个中心内可以有多个实例实现集群。。

最终方案:每个微服务创建自己的命名空间,然后使用配置分组区分环境(dev/test/prod)

加载多配置集

我们要把原来application.yml里的内容都分文件抽离出去。我们在nacos里创建好后,在coupons里指定要导入的配置即可。

bootstrap.properties

在其中用数组spring.cloud.nacos.config.extension-configs[]写明每个配置集

spring.application.name=gulimall-coupon

spring.cloud.nacos.config.server-addr=127.0.0.1:8848
# 可以选择对应的命名空间 # 写上对应环境的命名空间ID
spring.cloud.nacos.config.namespace=b176a68a-6800-4648-833b-be10be8bab00
# 更改配置分组
spring.cloud.nacos.config.group=dev

#新版本不建议用下面的了
#spring.cloud.nacos.config.ext-config[0].data-id=datasource.yml
#spring.cloud.nacos.config.ext-config[0].group=dev
#spring.cloud.nacos.config.ext-config[0].refresh=true
#spring.cloud.nacos.config.ext-config[1].data-id=mybatis.yml
#spring.cloud.nacos.config.ext-config[1].group=dev
#spring.cloud.nacos.config.ext-config[1].refresh=true
#spring.cloud.nacos.config.ext-config[2].data-id=other.yml
#spring.cloud.nacos.config.ext-config[2].group=dev
#spring.cloud.nacos.config.ext-config[2].refresh=true

spring.cloud.nacos.config.extension-configs[0].data-id=datasource.yml
spring.cloud.nacos.config.extension-configs[0].group=dev
spring.cloud.nacos.config.extension-configs[0].refresh=true

spring.cloud.nacos.config.extension-configs[1].data-id=mybatis.yml
spring.cloud.nacos.config.extension-configs[1].group=dev
spring.cloud.nacos.config.extension-configs[1].refresh=true

spring.cloud.nacos.config.extension-configs[2].data-id=other.yml
spring.cloud.nacos.config.extension-configs[2].group=dev
spring.cloud.nacos.config.extension-configs[2].refresh=true

输出内容有

2020-06-25 00:04:13.677  WARN 17936 --- [           main] c.a.c.n.c.NacosPropertySourceBuilder     : Ignore the empty nacos configuration and get it based on dataId[gulimall-coupon] & group[dev]

2020-06-25 00:04:13.681  INFO 17936 --- [           main] b.c.PropertySourceBootstrapConfiguration :
Located property source: [BootstrapPropertySource {name='bootstrapProperties-gulimall-coupon.properties,dev'}, BootstrapPropertySource {name='bootstrapProperties-gulimall-coupon,dev'}, BootstrapPropertySource {name='bootstrapProperties-other.yml,dev'}, BootstrapPropertySource {name='bootstrapProperties-mybatis.yml,dev'}, BootstrapPropertySource {name='bootstrapProperties-datasource.yml,dev'}]

十二、网关gateway-88

动态上下线:发送请求需要知道商品服务的地址,如果商品服务器有123服务器,1号掉线后,还得改,所以需要网关动态地管理,他能从注册中心中实时地感知某个服务上线还是下线。【先通过网关,网关路由到服务提供者】

拦截:请求也要加上询问权限,看用户有没有权限访问这个请求,也需要网关。

所以我们使用spring cloud的gateway组件做网关功能。

网关是请求流量的入口,常用功能包括路由转发,权限校验,限流控制等。springcloud gateway取代了zuul网关。

spring.io/projects/sp…

参考手册:cloud.spring.io/spring-clou…

三大核心概念:

  • Route: The basic building block of the gateway. It is defined by an ID, a destination URI, a collection of predicates断言, and a collection of filters. A route is matched if the aggregate predicate is true.发一个请求给网关,网关要将请求路由到指定的服务。路由有id,目的地uri,断言的集合,匹配了断言就能到达指定位置,
  • Predicate断言: This is a Java 8 Function Predicate. The input type is a Spring Framework ServerWebExchange. This lets you match on anything from the HTTP request, such as headers or parameters.就是java里的断言函数,匹配请求里的任何信息,包括请求头等。根据请求头路由哪个服务
  • Filter: These are instances of Spring Framework GatewayFilter that have been constructed with a specific factory. Here, you can modify requests and responses before or after sending the downstream request.过滤器请求和响应都可以被修改。

客户端发请求给服务端。中间有网关。先交给映射器,如果能处理就交给handler处理,然后交给一系列filer,然后给指定的服务,再返回回来给客户端。

有很多断言。

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - Cookie=mycookie,mycookievalue

-代表数组,可以设置Cookie等内容。只有断言成功了,才路由到指定的地址。

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - name: Cookie
          args:
            name: mycookie
            regexp: mycookievalue

创建微服务,使用initilizer,Group:com.atguigu.gulimall,Artifact: gulimall-gateway,package:com.atguigu.gulimall.gateway。 搜索gateway选中。

pom.xml里加上common依赖, 修改jdk版本,

在gateway服务中开启注册服务发现@EnableDiscoveryClient,配置nacos注册中心地址applicaion.properties。这样gateway也注册到了nacos中,其他服务就能找到nacos,网关也能通过nacos找到其他服务

spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
spring.application.name=gulimall-gateway
server.port=88

bootstrap.properties 填写nacos配置中心地址

spring.application.name=gulimall-gateway

spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.cloud.nacos.config.namespace=bfa85f10-1a9a-460c-a7dc-efa961b45cc1

本项目在nacos中的服务名

spring:
    application:
        name: gulimall-gateway

再去nacos里创建命名空间gateway(项目与项目用命名空间隔离),然后在命名空间里创建文件guilmall-gateway.yml

在项目里创建application.yml,根据条件转发到uri等

spring:
  cloud:
    gateway:
      routes:
        - id: test_route
          uri: https://www.baidu.com
          predicates:
            - Query=url,baidu

        - id: qq_route
          uri: https://www.qq.com
          predicates:
            - Query=url,qq

        - id: product_route
          uri: lb://gulimall-product
          predicates:
            - Path=/api/product/\*\*
          filters:
            - RewritePath=/api/(?<segment>.\*),/$\{segment}

        - id: third_party_route
          uri: lb://gulimall-third-party
          predicates:
            - Path=/api/thirdparty/\*\*
          filters:
            - RewritePath=/api/thirdparty/(?<segment>.\*),/$\{segment}

        - id: member_route
          uri: lb://gulimall-member
          predicates:
            - Path=/api/member/\*\*
          filters:
            - RewritePath=/api/(?<segment>.\*),/$\{segment}

        - id: ware_route
          uri: lb://gulimall-ware
          predicates:
            - Path=/api/ware/\*\*
          filters:
            - RewritePath=/api/(?<segment>.\*),/$\{segment}

        - id: admin_route
          uri: lb://renren-fast
          predicates:
            - Path=/api/\*\*
          filters:  # 这段过滤器和验证码有关,api内容缓存了/renren-fast,还得注意/renren-fast也注册到nacos中
            - RewritePath=/api/(?<segment>.\*),/renren-fast/$\{segment}



## 前端项目,/api前缀。开来到网关后断言先匹配到,过滤器修改url,比如跳转到renren微服务,所以要注意renren后端项目也注册到 nacos里
## http://localhost:88/api/captcha.jpg http://localhost:8080/renren-fast/captcha.jpg
## http://localhost:88/api/product/category/list/tree http://localhost:10000/product/category/list/tree


测试 localhost:8080/hello?url=baidu

网关使用的是Netty

十三、前端vue-8001和element-ui

ES6+Vue写到了另一博文里

blog.csdn.net/hancoder/ar…

十四、三级分类

vue项目开放端口太麻烦了,其他主机访问不了。防火墙输入策略和host什么的修改过,nacos等其他服务能正常访问,vue项目别的主机访问不了,不知道哪里有限制

可以在config/index.js配置vue项目的ip和端口

此处三级分类最起码得启动renren-fast、nacos、gateway、product

element-ui的使用

element.eleme.cn/#/zh-CN/com…

提供了tree组件,他的数据是以data属性显示的。而他的子菜单是由data里的children属性决定的,当然这个属性可以改

defaultProps: {
    children: "children",
    label: "name"
}

pms_category表说明

代表商品的分类

这里有sql和entity不对应的情况,有的sql文件改起来比较麻烦,下面这个sql应该是准确的。不明白的看前面的数据库章节

CREATE DATABASE /\*!32312 IF NOT EXISTS\*/`gulimall_pms` /\*!40100 DEFAULT CHARACTER SET utf8mb4 \*/;

USE `gulimall_pms`;

SET FOREIGN_KEY_CHES=0;

DROP TABLE IF EXISTS `pms_category`;
CREATE TABLE `pms_category`  (
    `cat_id` bigint(20) NOT NULL AUTO\_INCREMENT COMMENT '分类id',
    `name` char(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '分类名称',
    `parent_cid` bigint(20) NULL DEFAULT NULL COMMENT '父分类id',
    `cat_level` int(11) NULL DEFAULT NULL COMMENT '层级',
    `show_status` tinyint(4) NULL DEFAULT NULL COMMENT '是否显示[0-不显示,1显示]',
    `sort` int(11) NULL DEFAULT NULL COMMENT '排序',
    `icon` char(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '图标地址',
    `product_unit` char(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '计量单位',
    `product_count` int(11) NULL DEFAULT NULL COMMENT '商品数量',
    PRIMARY KEY (`cat_id`) USING BTREE, 
    INDEX `parent_cid`(`parent_cid`) USING BTREE
) ENGINE = InnoDB AUTO\_INCREMENT = 1437 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '商品三级分类' ROW_FORMAT = Dynamic;

  • cat_id:分类id,cat代表分类,bigint(20)
  • name:分类名称
  • parent_cid:在哪个父目录下
  • cat_level:分类层级
  • show_status:是否显示,用于逻辑删除
  • sort:同层级同父目录下显示顺序
  • ico图标,product_unit商品计量单位,
  • InnoDB表,自增大小1437,utf编码,动态行格式
sql注:

特立独行的猫那个sql文件里把表名大小写改了导致renren-fast启动不成功。如果启动不了的话,guli_admin数据库还是不要用他的了,还是接着用renren-fast项目下的db文件夹mysql.sql那个文件吧

http://localhost:8081/renren-fast/

{"msg":"invalid token","code":401}

验证码不显示问题

F12打开看了一下,验证码图片的端口还是8080,也就是说,你的renren-fast项目的端口更改了,而前端项目不知道你改过了。后面的笔记中有个【网关88】小节,去那里看吧

接着操作后台

localhost:8001 , 点击系统管理,菜单管理,新增

  • 目录
  • 商品系统
  • 一级菜单

刷新,看到左侧多了商品系统,添加的这个菜单其实是添加到了guli-admin.sys_menu表里

(新增了memu_id=31 parent_id=0 name=商品系统 icon=editor )

继续新增:

  • 菜单
  • 分类维护
  • 商品系统
  • product/category
  • menu

guli-admin.sys_menu表又多了一行,父id是刚才的商品系统id

菜单路由

在左侧点击【商品系统-分类维护】,希望在此展示3级分类。可以看到

  • url是http://localhost:8001/#/product-category
  • 填写的菜单路由是product/category
  • 对应的视图是src/view/modules/product/category.vue

再如sys-role具体的视图在renren-fast-vue/views/modules/sys/role.vue

所以要自定义我们的product/category视图的话,就是创建mudules/product/category.vue

输入vue快捷生成模板,然后去element.eleme.cn/#/zh-CN/com…

看如何使用多级目录

  • el-tree中的data是要展示的树形数据
  • props属性设置
  • @node-click单击函数
<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree>

<script>
  export default {
    data() {
      return {
        data: [{
          label: '一级 1',
          children: [{
            label: '二级 1-1',
            children: [{
              label: '三级 1-1-1'
            }]
          }]
        }, {
          label: '一级 2',
          children: [{
            label: '二级 2-1',
            children: [{
              label: '三级 2-1-1'
            }]
          }, {
            label: '二级 2-2',
            children: [{
              label: '三级 2-2-1'
            }]
          }]
        }, {
          label: '一级 3',
          children: [{
            label: '二级 3-1',
            children: [{
              label: '三级 3-1-1'
            }]
          }, {
            label: '二级 3-2',
            children: [{
              label: '三级 3-2-1'
            }]
          }]
        }],
        defaultProps: {
          children: 'children',
          label: 'label'
        }
      };
    },
    methods: {
      handleNodeClick(data) {
        console.log(data);
      }
    }
  };
</script>

网关88

在登录管理后台的时候,我们会发现,他要请求localhost:8080/renren-fast/product/category/list/tree这个url

但是报错404找不到,此处就解决登录页验证码不显示的问题。

他要给8080发请求读取数据,但是数据是在10000端口上,如果找到了这个请求改端口那改起来很麻烦。方法1是改vue项目里的全局配置,方法2是搭建个网关,让网关路由到10000(即将vue项目里的请求都给网关,网关经过url处理后,去nacos里找到管理后台的微服务,就可以找到对应的端口了,这样我们就无需管理端口,统一交给网关管理端口接口)

C+S+F全局搜索

static/config/index.js

 window.SITE\_CONFIG['baseUrl'] = 'http://localhost:88/api';
// 意思是说本vue项目中要请求的资源url都发给88/api,那么我们就让网关端口为88,然后匹配到/api请求即可,
// 网关可以通过过滤器处理url后指定给某个微服务
// renren-fast服务已经注册到了nacos中

接着让重新登录http://localhost:8001/#/login,验证码是请求88的,所以不显示。而验证码是来源于fast后台的