谷粒商城 - 个人笔记(基础篇一)

前言


  1. 学习视频:Java项目《谷粒商城》架构师级Java项目实战,对标阿里P6-P7,全网最强
  2. 学习文档: 
    1. 谷粒商城-个人笔记(基础篇一)
    2. 谷粒商城-个人笔记(基础篇二)
    3. 谷粒商城-个人笔记(基础篇三)
    4. 谷粒商城-个人笔记(高级篇一)
    5. 谷粒商城-个人笔记(高级篇二)
    6. 谷粒商城-个人笔记(高级篇三)
    7. 谷粒商城-个人笔记(高级篇四)
    8. 谷粒商城-个人笔记(高级篇五)
  3.  接口文档:谷粒商城接口文档

  4. 本内容仅用于个人学习笔记,如有侵扰,联系删除

一、项目简介


1、项目背景

1.1、电商模式

市面上有 5 种常见的电商模式 B2B B2C C2B C2C O2O
1) B2B 模式
B2B (Business to Business) , 是指商家与商家建立的商业关系。 如:阿里巴巴
2) B2C 模式
B2C (Business to Consumer) , 就是我们经常看到的供应商直接把商品卖给用户,即 商对客 ”模式,也就是通常说的商业零售,直接面向消费者销售产品和服务。如:苏宁易购、京东、天猫、小米商城
3) C2B 模式
C2B (Customer to Business) ,即消费者对企业。先有消费者需求产生而后有企业生产,即先有消费者提出需求,后有生产企业按需求组织生产
4) C2C 模式
C2C (Customer to Consumer) ,客户之间自己把东西放上网去卖,如:淘宝,闲鱼
5) O2O 模式
O2O Online To Offline ,也即将线下商务的机会与互联网结合在了一起,让互联网成为线下交易的前台。线上快速支付,线下优质服务。如:饿了么,美团,淘票票,京东到家

1.2、谷粒商城

谷粒商城是一个 B2C 模式的电商平台,销售自营商品给客户。

2、项目架构图

2.1、项目微服务架构图

2.2、微服务划分图

2.3、微服务架构流程

前后分离开发,分为内网部署和外网部署,外网是面向公众访问的,部署前端项目,可以有手机APP,电脑网页;内网部署的是后端集群,前端在页面上操作发送请求到后端,在这途中会经过Nginx集群,Nginx把请求转交给API网关(SpringCloud gateway)(网关可以根据当前请求动态地路由到指定的服务,看当前请求是想调用商品服务还是购物车服务还是检索),从路由过来如果请求很多,可以负载均衡地调用商品服务器中一台(商品服务复制了多份),当商品服务器出现问题也可以在网关层面对服务进行熔断或降级(使用阿里的sentinel组件),网关还有其他的功能如认证授权、限流(只放行部分到服务器)等。

到达服务器后进行处理(SpringBoot为微服务),服务与服务可能会相互调用(使用feign组件),有些请求可能经过登录才能进行(基于OAuth2.0的认证中心。安全和权限使用SpringSecurity控制)

服务可能保存了一些数据或者需要使用缓存,我们使用Redis集群(分片+哨兵集群)。持久化使用MySQL,读写分离和分库分表。

服务和服务之间会使用消息队列(RabbitMQ),来完成异步解耦,分布式事务的一致性。有些服务可能需要全文检索,检索商品信息,使用ElaticSearch。

服务可能需要存取数据,使用阿里云的对象存储服务OSS。

项目上线后为了快速定位问题,使用ELK对日志进行处理,使用LogStash收集业务里的各种日志,把日志存储到ES中,用Kibana可视化页面从ES中检索出相关信息,帮助我们快速定位问题所在。

在分布式系统中,由于我们每个服务都可能部署在很多台机器,服务和服务可能相互调用,就得知道彼此都在哪里,所以需要将所有服务都注册到注册中心。服务从注册中心发现其他服务所在位置(使用阿里Nacos作为注册中心)。

每个服务的配置众多,为了实现改一处配置相同配置就同步更改,就需要配置中心,也使用阿里的Nacos,服务从配置中心中动态取配置。

服务追踪,追踪服务调用链哪里出现问题,使用SpringCloud提供的Sleuth、Zipkin、Metrics,把每个服务的信息交给开源的Prometheus进行聚合分析,再由Grafana进行可视化展示,提供Prometheus提供的AlterManager实时得到服务的告警信息,以短信/邮件的方式告知服务开发人员。

还提供了持续集成和持续部署。项目发布起来后,因为微服务众多,每一个都打包部署到服务器太麻烦,有了持续集成后开发人员可以将修改后的代码提交到github,运维人员可以通过自动化工具Jenkins Pipeline将github中获取的代码打包成docker镜像,最终是由k8s集成docker服务,将服务以docker容器的方式运行。

3项目技术&特色

  • 前后端分离开发,并开发基于vue的后台管理系统
  • SpringCloud全新的解决方案
  • 应用监控、限流、网关、熔断降级等分布式方案全方位涉及
  • 透彻讲解分布式事务、分布式锁等分布式系统的难点
  • 分析高并发场景的编码方式,线程池,异步编排等使用
  • 压力测试与性能优化
  • 各种集群技术的区别以及使用
  • CI/CD使用
  • .....

4、项目前置要求

  • 学习项目的前置知识
  • 熟悉 SpringBoot 以及常见整合方案
  • 了解 SpringCloud
  • 熟悉 gitmaven
  • 熟悉 linuxredisdocker 基本操作
  • 了解 htmlcssjsvue
  • 熟练使用 idea 开发项目

二、分布式基础概念


1、微服务

微服务架构风格,就像是把一套单独的应用程序开发为一套小服务,每个小服务运行在自己的进程中,并使用轻量级机制通信,通常是HTTP API。这些服务围绕业务能力来构建,并通过完全自动化机制来独立部署。这些服务使用不同的编程语言来书写,以及不同的数据存储技术,并保持最低限度的集中式管理。

简而言之,拒绝大型单体应用,基于业务边界进行微服化拆分,各个服务独立部署运行。

2、集群&分布式&节点

集群是个物理形态,分布式是个工作方式。

只要是一堆机器,就可以叫集群。他们是不是一起协作着干活,这个谁也不知道;

《分布式系统原理与范型》定义:“分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统”分布式系统(distributed system)是建立网络之上的软件系统。

分布式系统是指将不同的业务分布在不同的地方。

集群指的是将几台服务器集中在一起,实现同一业务。

例如:京东是一个分布式系统,众多业务运行在不同的机器,所有业务构成一个大型的业务集群。每一个小的业务,比如用户系统,访问压力大的时候一台服务器是不够的。我们就应该将用户系统部署到多个服务器,也就是每一个业务系统也可以做集群化。

分布式中的每一个节点,都可以做成集群。而集群不一定是分布式的。

节点:集群中的一个服务器。

3、远程调用

在分布式系统中,各个服务可能处于不同主机,但是服务之间不可避免的相互调用,我们称为远程调用。

SpringCloud 中使用 HTTP+JSON 的方式完成远程调用

4负载均衡

分布式系统中,A服务需要调用B服务,B服务在多台机器中存在,A服务用任意一个服务均可完成功能。

为了使每一个服务都不要太忙或者太闲,我们可以负载均衡的调用每一个服务器,提升网站的健壮性。

常见的负载均衡算法:

轮询:为第一个请求选择健康池中的第一个后端服务器,然后按顺序往后依次选择,直到最后一个,然后循环。

最小连接:优先选择连接数最少,也就是压力最小的后端服务器,在会话较长的情况下可以考虑采取这种方式。

散列:根据请求源的IP的散列(hash)来选择要转发的服务器。这种方式可以一定程度上保证特定用户能连接到相同的服务器。如果你的应用需要处理状态而要求用户能连接到和之前相同的服务器,可以考虑采取这种方式。

5、服务注册/发现&注册中心

A服务调用B服务,A服务并不知道B服务当前在哪几台服务器有,哪些是正常的,哪些服务已经下线。解决这个问题可以引入注册中心。

如果某些服务下线,我们其他人可以实时的感知到其他服务的状态,从而避免服务不可用的状态.

6、配置中心

每一个服务最终都有大量的配置,并且每个服务都可能部署在多台机器上。我们经常需要变更配置,我们可以让每个服务在配置中心获取自己的配置。 

配置中心用来集中式的管理微服务的配置信息。

7、服务熔断&服务降级

在微服务架构中,微服务之间通过网络进行通信,存在相互依赖,当其中一个服务不可用时,有可能会造成雪崩效应。要防止这样的情况,必须要有容错机制来保护服务。

RPC

情景:订单服务 --> 商品服务 --> 库存服务

库存服务出现故障导致响应慢,导致商品服务需要等待,可能等到10s后库存服务才能响应。库存服务的不可用导致商品服务阻塞,商品服务等的期间,订单服务也处于阻塞。一个服务不可用导致整个服务链都阻塞。如果是高并发,第一个请求调用后阻塞10s得不到结果,第二个请求直接阻塞10s。更多的请求进来导致请求积压,全部阻塞,最终服务器的资源耗尽,导致雪崩。

解决方案:

1)、服务熔断

指定超时时间,库存服务3s没有响应就超时,如果经常失败,比如10s内100个请求都失败了。开启断路保护机制,下一次请求进来不调用库存服务了,因为上一次100%错误都出现了,我们直接在此中断,商品服务直接返回,返回一些默认数据或者null,而不调用库存服务了,这样就不会导致请求积压。

  • 设置服务的超时,当被调用的服务经常失败到达某个阈值,我们可以开启断路保护机制,后来的请求不再去调用这个服务。本地直接返回默认的数据

2)、服务降级

  • 在运维期间,当系统处于高峰期,系统资源紧张,我们可以让非核心业务降级运行。降级:某些服务不处理,或者处理简单【抛异常、返回NULL、调用Mock数据、调用Faaback处理逻辑】

8API 网关

客户端发送请求到服务器路途中,设置一个网关,请求都先到达网关,网关对请求进行统一认证(合法非法)和处理等操作。他是安检。

在微服务架构中,API gateway作为整体架构的重要组件,它抽象了微服务中都需要的公共功能,同时提供了客户端负载均衡,服务自动熔断,灰度发布,统一认证,限流流控,日志统计等丰富的功能,帮助我们解决很多API管理难题。

三、环境搭建


1、安装 linux 虚拟机

下载CentOS7的镜像

下载地址:Download

VMware中安装CentOS7请参考 

在VMware中安装CentOS7(超详细的图文教程)

VMware安装Centos7及静态IP网络配置详细教程

virtual box 安装Centos7请参考 

VirtualBox安装CentOS7 - 薛大坑 - 博客园

centos7安装好之后之后,记得关闭防火墙

systemctl stop firewalld

我们想要给虚拟机一个固定的ip地址,windows和虚拟机可以互相ping通。

方式1网络地址转换-端口转发(是在虚拟机中配置静态ip)

方式2:更改Vagrantfile,更改虚拟机ip

修改其中的config.vm.network "private_network",ip:"192.168.119.127",这个ip需要在windows的ipconfig中查到vitualbox的网卡ip,然后更改下最后一个数字就行(不能是1)。配置完后重启虚拟机。在虚拟机中ip addr就可以查看到地址了。互相ping也能ping通。

2、安装 docker

虚拟化容器技术。 Docker 基于镜像,可以秒级启动各种容器。每一种容器都是一个完整的运行
环境,容器之间互相隔离。

docker容器文件挂载与端口映射

虚拟机安装docker

Docker 安装文档:https://docs.docker.com/engine/install/centos/

docker仓库:https://hub-stage.docker.com/

1 、卸载系统之前的 docker
# 安装前先更新yum,不然有可能出现本机无法连接虚拟机的mysql、redis等
sudo yum update

# 卸载系统之前的docker 
sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
2 、安装 Docker-CE
# 安装docker需要依赖的包                  
sudo yum install -y yum-utils

# 配置镜像
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 安装docker    
sudo yum install docker-ce docker-ce-cli containerd.io
3 、启动 docker
# 启动docker
sudo systemctl start docker
4 、设置 docker 开机自启
# 设置开机自启动
sudo systemctl enable docker
5 、测试 docker 常用命令,注意切换到 root 用户下
# 检查docker版本
docker -v

# 检查docker有没有下载镜像
sudo docker images
6 、配置 docker 镜像加速( 阿里云加速镜像

https://cr.console.aliyun.com/cn-qingdao/instances/mirrors

# 配置镜像加速
sudo mkdir -p /etc/docker

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://chqac97z.mirror.aliyuncs.com"]
}
EOF

sudo systemctl daemon-reload

sudo systemctl restart docker

3docker 安装 mysql

用docker安装上mysql,去docker仓库里搜索mysql

1、下载镜像文件

sudo docker pull mysql:5.7

2、创建实例并启动

# --name指定容器名字 -v目录挂载 -p指定端口映射  -e设置mysql参数 -d后台运行
sudo 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

docker容器文件挂载与端口映射 

参数说明:
  • -p 3306:3306:将容器的 3306 端口映射到主机的 3306 端口
  • -v /mydata/mysql/conf:/etc/mysql:将配置文件夹挂载到主机
  • -v /mydata/mysql/log:/var/log/mysql:将日志文件夹挂载到主机
  • -v /mydata/mysql/data:/var/lib/mysql/:将配置文件夹挂载到主机
  • -e MYSQL_ROOT_PASSWORD=root:初始化 root 用户的密码

列出当前正在运行的 Docker 容器 

[root@localhost vagrant]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
6a685a33103f        mysql:5.7           "docker-entrypoint.s…"   32 seconds ago      Up 30 seconds       0.0.0.0:3306->3306/tcp, 33060/tcp   mysql

MySQL 配置 

# 进入mysql容器
docker exec -it mysql bin/bash
exit;

# 进入mysql配置文件,修改mysql字符编码
vi /mydata/mysql/conf/my.conf 

[client]
default-character-set=utf8

[mysql]
default-character-set=utf8

[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve

# 重新启动mysql
docker restart mysql
注意:解决 MySQL 连接慢的问题
在配置文件中加入如下,并重启 mysql
[mysqld]
skip-name-resolve
解释:
skip-name-resolve :跳过域名解析

3、通过容器的 mysql 命令行工具连接

docker exec -it mysql mysql -uroot -proot

4、设置 root 远程访问

grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option;
flush privileges;

4docker 安装 redis

1、下载镜像文件

docker pull redis

2、创建实例并启动

如果直接挂载的话docker会以为挂载的是一个目录,所以我们先创建一个文件然后再挂载,在虚拟机中。

# 在虚拟机中
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

3、使用 redis 镜像执行 redis-cli 命令连接  

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

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

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

docker restart redis

5、开发环境统一

5.1Maven

在maven的config.xml中配置阿里云镜像

    <mirror>
      <id>alimaven</id>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url> 
      <mirrorOf>central</mirrorOf> 
   </mirror>

配置 jdk1.8 编译项目

  <profiles>
	<profile>
		<id>jdk-1.8</id>

      		<activation>
        			<activeByDefault>true</activeByDefault>
			        <jdk>1.8</jdk>
      		</activation>
		<properties>
			<maven.compiler.source>1.8</maven.compiler.source>
			<maven.compiler.target>1.8</maven.compiler.target>
			<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
		</properties>
	</profile>

5.2Idea&VsCode 

1、idea 安装 lombokmybatisx 插件

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

    Vscode 安装开发必备插件

  • Vetur —— 语法高亮、智能感知、Emmet 包含格式化功能, Alt+Shift+F (格式化全文),Ctrl+K Ctrl+F(格式化选中代码,两个 Ctrl需要同时按着)
  • EsLint —— 语法纠错
  • Auto Close Tag —— 自动闭合 HTML/XML 标签
  • Auto Rename Tag —— 自动完成另一侧标签的同步修改
  • JavaScript(ES6) code snippets — — ES6 语 法 智 能 提 示 以 及 快 速 输 入 , 除 js 外 还 支 .ts.jsx.tsx.html.vue,省去了配置其支持各种包含 js 代码文件的时间
  • HTML CSS Support —— 让 html 标签上写 class 智能提示当前项目所支持的样式
  • HTML Snippets —— html 快速自动补全
  • Open in browser —— 浏览器快速打开
  • Live Server —— 以内嵌服务器方式打开
  • Chinese (Simplified) Language Pack for Visual Studio Code —— 中文语言包

5.3、安装配置 git

1 、下载 git https://git-scm.com

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

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

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

3、配置 ssh 免密登录

https://gitee.com/help/articles/4181#article-header0

进入 git bash;使用:ssh-keygen -t rsa -C "xxxxx@xxxxx.com"命令。 连续三次回车。
一般用户目录下会有

或者 cat ~/.ssh/id_rsa.pub
登录进入 gitee,在设置里面找到 SSH KEY 将.pub 文件的内容粘贴进去
使用 ssh -T git@gitee.com 测试是否成功即可

Git+码云教程:https://gitee.com/help/articles/4104

5.4、逆向工程使用

  1. 导入项目逆向工程
  2. 下载人人开源后台管理系统脚手架工程
    • 导入工程,创建数据库
    • 修改工程 shiro 依赖为 SpringSecurity
    • 删除部分暂时不需要的业务
  3. 下载人人开源后台管理系统 vue 端脚手架工程
    • vscode 导入前端项目
    • 前后端联调测试基本功能

6、创建项目微服务

6.1、从 gitee 初始化一个项目

在码云新建仓库,仓库名gulimall,选择语言java,在.gitignore选中maven,许可证选Apache-2.0,开发模型选生成/开发模型,开发时在dev分支,发布时在master分支,创建。

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

https://gitee.com/wang_tianshun/gulimall.git

然后New Module –> Spring Initializer –> com.atguigu.gulimall , Artifact填 gulimall-product。Next—选择web,springcloud routing里选中openFeign。

1)、依次创建出以下服务:

  • 商品服务-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了。

2)、修改总项目的.gitignore

target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
.mvn/wrapper/maven-wrapper.jar

**/mvnw
**/mvnw.cmd
**/.mvn
**/target

.idea

**/.gitignore

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

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

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

3)、在IDEA中安装插件:Gitee

 FILE -> Settings ->Plusgins -> 搜索Gitee -> Install -> 重启IDEA

4)、提交代码到码云

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

6.2、创建各个微服务项目

1 )、了解人人开源项目,快速搭建后台脚手架
2 )、修改代码调整为我们的业务逻辑
3 )、创建各个微服务以及数据库

7、数据库

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

安装powerDesigner软件。http://forspeed.onlinedown.net/down/powerdesigner1029.zip

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

密码:2wre

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

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

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

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

注意重启虚拟机和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

然后接着去navicat直接我们的操作,在左侧root上右键建立数据库:字符集选utf8mb4,他能兼容utf8且能解决一些乱码的问题。分别建立了下面数据库

如果是连接云服务器上部署的docker里的mysql,navicat连接mysql不成功

可以参考https://blog.csdn.net/wts563540/article/details/123037704

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

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

1)、gulimall_oms.sql 

drop table if exists oms_order;

drop table if exists oms_order_item;

drop table if exists oms_order_operate_history;

drop table if exists oms_order_return_apply;

drop table if exists oms_order_return_reason;

drop table if exists oms_order_setting;

drop table if exists oms_payment_info;

drop table if exists oms_refund_info;

/*==============================================================*/
/* Table: oms_order                                             */
/*==============================================================*/
create table oms_order
(
   id                   bigint not null auto_increment comment 'id',
   member_id            bigint comment 'member_id',
   order_sn             char(32) comment '订单号',
   coupon_id            bigint comment '使用的优惠券',
   create_time          datetime comment 'create_time',
   member_username      varchar(200) comment '用户名',
   total_amount         decimal(18,4) comment '订单总额',
   pay_amount           decimal(18,4) comment '应付总额',
   freight_amount       decimal(18,4) comment '运费金额',
   promotion_amount     decimal(18,4) comment '促销优化金额(促销价、满减、阶梯价)',
   integration_amount   decimal(18,4) comment '积分抵扣金额',
   coupon_amount        decimal(18,4) comment '优惠券抵扣金额',
   discount_amount      decimal(18,4) comment '后台调整订单使用的折扣金额',
   pay_type             tinyint comment '支付方式【1->支付宝;2->微信;3->银联; 4->货到付款;】',
   source_type          tinyint comment '订单来源[0->PC订单;1->app订单]',
   status               tinyint comment '订单状态【0->待付款;1->待发货;2->已发货;3->已完成;4->已关闭;5->无效订单】',
   delivery_company     varchar(64) comment '物流公司(配送方式)',
   delivery_sn          varchar(64) comment '物流单号',
   auto_confirm_day     int comment '自动确认时间(天)',
   integration          int comment '可以获得的积分',
   growth               int comment '可以获得的成长值',
   bill_type            tinyint comment '发票类型[0->不开发票;1->电子发票;2->纸质发票]',
   bill_header          varchar(255) comment '发票抬头',
   bill_content         varchar(255) comment '发票内容',
   bill_receiver_phone  varchar(32) comment '收票人电话',
   bill_receiver_email  varchar(64) comment '收票人邮箱',
   receiver_name        varchar(100) comment '收货人姓名',
   receiver_phone       varchar(32) comment '收货人电话',
   receiver_post_code   varchar(32) comment '收货人邮编',
   receiver_province    varchar(32) comment '省份/直辖市',
   receiver_city        varchar(32) comment '城市',
   receiver_region      varchar(32) comment '区',
   receiver_detail_address varchar(200) comment '详细地址',
   note                 varchar(500) comment '订单备注',
   confirm_status       tinyint comment '确认收货状态[0->未确认;1->已确认]',
   delete_status        tinyint comment '删除状态【0->未删除;1->已删除】',
   use_integration      int comment '下单时使用的积分',
   payment_time         datetime comment '支付时间',
   delivery_time        datetime comment '发货时间',
   receive_time         datetime comment '确认收货时间',
   comment_time         datetime comment '评价时间',
   modify_time          datetime comment '修改时间',
   primary key (id)
);

alter table oms_order comment '订单';

/*==============================================================*/
/* Table: oms_order_item                                        */
/*==============================================================*/
create table oms_order_item
(
   id                   bigint not null auto_increment comment 'id',
   order_id             bigint comment 'order_id',
   order_sn             char(32) comment 'order_sn',
   spu_id               bigint comment 'spu_id',
   spu_name             varchar(255) comment 'spu_name',
   spu_pic              varchar(500) comment 'spu_pic',
   spu_brand            varchar(200) comment '品牌',
   category_id          bigint comment '商品分类id',
   sku_id               bigint comment '商品sku编号',
   sku_name             varchar(255) comment '商品sku名字',
   sku_pic              varchar(500) comment '商品sku图片',
   sku_price            decimal(18,4) comment '商品sku价格',
   sku_quantity         int comment '商品购买的数量',
   sku_attrs_vals       varchar(500) comment '商品销售属性组合(JSON)',
   promotion_amount     decimal(18,4) comment '商品促销分解金额',
   coupon_amount        decimal(18,4) comment '优惠券优惠分解金额',
   integration_amount   decimal(18,4) comment '积分优惠分解金额',
   real_amount          decimal(18,4) comment '该商品经过优惠后的分解金额',
   gift_integration     int comment '赠送积分',
   gift_growth          int comment '赠送成长值',
   primary key (id)
);

alter table oms_order_item comment '订单项信息';

/*==============================================================*/
/* Table: oms_order_operate_history                             */
/*==============================================================*/
create table oms_order_operate_history
(
   id                   bigint not null auto_increment comment 'id',
   order_id             bigint comment '订单id',
   operate_man          varchar(100) comment '操作人[用户;系统;后台管理员]',
   create_time          datetime comment '操作时间',
   order_status         tinyint comment '订单状态【0->待付款;1->待发货;2->已发货;3->已完成;4->已关闭;5->无效订单】',
   note                 varchar(500) comment '备注',
   primary key (id)
);

alter table oms_order_operate_history comment '订单操作历史记录';

/*==============================================================*/
/* Table: oms_order_return_apply                                */
/*==============================================================*/
create table oms_order_return_apply
(
   id                   bigint not null auto_increment comment 'id',
   order_id             bigint comment 'order_id',
   sku_id               bigint comment '退货商品id',
   order_sn             char(32) comment '订单编号',
   create_time          datetime comment '申请时间',
   member_username      varchar(64) comment '会员用户名',
   return_amount        decimal(18,4) comment '退款金额',
   return_name          varchar(100) comment '退货人姓名',
   return_phone         varchar(20) comment '退货人电话',
   status               tinyint(1) comment '申请状态[0->待处理;1->退货中;2->已完成;3->已拒绝]',
   handle_time          datetime comment '处理时间',
   sku_img              varchar(500) comment '商品图片',
   sku_name             varchar(200) comment '商品名称',
   sku_brand            varchar(200) comment '商品品牌',
   sku_attrs_vals       varchar(500) comment '商品销售属性(JSON)',
   sku_count            int comment '退货数量',
   sku_price            decimal(18,4) comment '商品单价',
   sku_real_price       decimal(18,4) comment '商品实际支付单价',
   reason               varchar(200) comment '原因',
   description述         varchar(500) comment '描述',
   desc_pics            varchar(2000) comment '凭证图片,以逗号隔开',
   handle_note          varchar(500) comment '处理备注',
   handle_man           varchar(200) comment '处理人员',
   receive_man          varchar(100) comment '收货人',
   receive_time         datetime comment '收货时间',
   receive_note         varchar(500) comment '收货备注',
   receive_phone        varchar(20) comment '收货电话',
   company_address      varchar(500) comment '公司收货地址',
   primary key (id)
);

alter table oms_order_return_apply comment '订单退货申请';

/*==============================================================*/
/* Table: oms_order_return_reason                               */
/*==============================================================*/
create table oms_order_return_reason
(
   id                   bigint not null auto_increment comment 'id',
   name                 varchar(200) comment '退货原因名',
   sort                 int comment '排序',
   status               tinyint(1) comment '启用状态',
   create_time          datetime comment 'create_time',
   primary key (id)
);

alter table oms_order_return_reason comment '退货原因';

/*==============================================================*/
/* Table: oms_order_setting                                     */
/*==============================================================*/
create table oms_order_setting
(
   id                   bigint not null auto_increment comment 'id',
   flash_order_overtime int comment '秒杀订单超时关闭时间(分)',
   normal_order_overtime int comment '正常订单超时时间(分)',
   confirm_overtime     int comment '发货后自动确认收货时间(天)',
   finish_overtime      int comment '自动完成交易时间,不能申请退货(天)',
   comment_overtime     int comment '订单完成后自动好评时间(天)',
   member_level         tinyint(2) comment '会员等级【0-不限会员等级,全部通用;其他-对应的其他会员等级】',
   primary key (id)
);

alter table oms_order_setting comment '订单配置信息';

/*==============================================================*/
/* Table: oms_payment_info                                      */
/*==============================================================*/
create table oms_payment_info
(
   id                   bigint not null auto_increment comment 'id',
   order_sn             char(32) comment '订单号(对外业务号)',
   order_id             bigint comment '订单id',
   alipay_trade_no      varchar(50) comment '支付宝交易流水号',
   total_amount         decimal(18,4) comment '支付总金额',
   subject              varchar(200) comment '交易内容',
   payment_status       varchar(20) comment '支付状态',
   create_time          datetime comment '创建时间',
   confirm_time         datetime comment '确认时间',
   callback_content     varchar(4000) comment '回调内容',
   callback_time        datetime comment '回调时间',
   primary key (id)
);

alter table oms_payment_info comment '支付信息表';

/*==============================================================*/
/* Table: oms_refund_info                                       */
/*==============================================================*/
create table oms_refund_info
(
   id                   bigint not null auto_increment comment 'id',
   order_return_id      bigint comment '退款的订单',
   refund               decimal(18,4) comment '退款金额',
   refund_sn            varchar(64) comment '退款交易流水号',
   refund_status        tinyint(1) comment '退款状态',
   refund_channel       tinyint comment '退款渠道[1-支付宝,2-微信,3-银联,4-汇款]',
   refund_content       varchar(5000),
   primary key (id)
);

alter table oms_refund_info comment '退款信息';

2)、gulimall_pms.sql

drop table if exists pms_attr;

drop table if exists pms_attr_attrgroup_relation;

drop table if exists pms_attr_group;

drop table if exists pms_brand;

drop table if exists pms_category;

drop table if exists pms_category_brand_relation;

drop table if exists pms_comment_replay;

drop table if exists pms_product_attr_value;

drop table if exists pms_sku_images;

drop table if exists pms_sku_info;

drop table if exists pms_sku_sale_attr_value;

drop table if exists pms_spu_comment;

drop table if exists pms_spu_images;

drop table if exists pms_spu_info;

drop table if exists pms_spu_info_desc;

/*==============================================================*/
/* Table: pms_attr                                              */
/*==============================================================*/
create table pms_attr
(
   attr_id              bigint not null auto_increment comment '属性id',
   attr_name            char(30) comment '属性名',
   search_type          tinyint comment '是否需要检索[0-不需要,1-需要]',
   icon                 varchar(255) comment '属性图标',
   value_select         char(255) comment '可选值列表[用逗号分隔]',
   attr_type            tinyint comment '属性类型[0-销售属性,1-基本属性,2-既是销售属性又是基本属性]',
   enable               bigint comment '启用状态[0 - 禁用,1 - 启用]',
   catelog_id           bigint comment '所属分类',
   show_desc            tinyint comment '快速展示【是否展示在介绍上;0-否 1-是】,在sku中仍然可以调整',
   primary key (attr_id)
);

alter table pms_attr comment '商品属性';

/*==============================================================*/
/* Table: pms_attr_attrgroup_relation                           */
/*==============================================================*/
create table pms_attr_attrgroup_relation
(
   id                   bigint not null auto_increment comment 'id',
   attr_id              bigint comment '属性id',
   attr_group_id        bigint comment '属性分组id',
   attr_sort            int comment '属性组内排序',
   primary key (id)
);

alter table pms_attr_attrgroup_relation comment '属性&属性分组关联';

/*==============================================================*/
/* Table: pms_attr_group                                        */
/*==============================================================*/
create table pms_attr_group
(
   attr_group_id        bigint not null auto_increment comment '分组id',
   attr_group_name      char(20) comment '组名',
   sort                 int comment '排序',
   descript             varchar(255) comment '描述',
   icon                 varchar(255) comment '组图标',
   catelog_id           bigint comment '所属分类id',
   primary key (attr_group_id)
);

alter table pms_attr_group comment '属性分组';

/*==============================================================*/
/* Table: pms_brand                                             */
/*==============================================================*/
create table pms_brand
(
   brand_id             bigint not null auto_increment comment '品牌id',
   name                 char(50) comment '品牌名',
   logo                 varchar(2000) comment '品牌logo地址',
   descript             longtext comment '介绍',
   show_status          tinyint comment '显示状态[0-不显示;1-显示]',
   first_letter         char(1) comment '检索首字母',
   sort                 int comment '排序',
   primary key (brand_id)
);

alter table pms_brand comment '品牌';

/*==============================================================*/
/* Table: pms_category                                          */
/*==============================================================*/
create table pms_category
(
   cat_id               bigint not null auto_increment comment '分类id',
   name                 char(50) comment '分类名称',
   parent_cid           bigint comment '父分类id',
   cat_level            int comment '层级',
   show_status          tinyint comment '是否显示[0-不显示,1显示]',
   sort                 int comment '排序',
   icon                 char(255) comment '图标地址',
   product_unit         char(50) comment '计量单位',
   product_count        int comment '商品数量',
   primary key (cat_id)
);

alter table pms_category comment '商品三级分类';

/*==============================================================*/
/* Table: pms_category_brand_relation                           */
/*==============================================================*/
create table pms_category_brand_relation
(
   id                   bigint not null auto_increment,
   brand_id             bigint comment '品牌id',
   catelog_id           bigint comment '分类id',
   brand_name           varchar(255),
   catelog_name         varchar(255),
   primary key (id)
);

alter table pms_category_brand_relation comment '品牌分类关联';

/*==============================================================*/
/* Table: pms_comment_replay                                    */
/*==============================================================*/
create table pms_comment_replay
(
   id                   bigint not null auto_increment comment 'id',
   comment_id           bigint comment '评论id',
   reply_id             bigint comment '回复id',
   primary key (id)
);

alter table pms_comment_replay comment '商品评价回复关系';

/*==============================================================*/
/* Table: pms_product_attr_value                                */
/*==============================================================*/
create table pms_product_attr_value
(
   id                   bigint not null auto_increment comment 'id',
   spu_id               bigint comment '商品id',
   attr_id              bigint comment '属性id',
   attr_name            varchar(200) comment '属性名',
   attr_value           varchar(200) comment '属性值',
   attr_sort            int comment '顺序',
   quick_show           tinyint comment '快速展示【是否展示在介绍上;0-否 1-是】',
   primary key (id)
);

alter table pms_product_attr_value comment 'spu属性值';

/*==============================================================*/
/* Table: pms_sku_images                                        */
/*==============================================================*/
create table pms_sku_images
(
   id                   bigint not null auto_increment comment 'id',
   sku_id               bigint comment 'sku_id',
   img_url              varchar(255) comment '图片地址',
   img_sort             int comment '排序',
   default_img          int comment '默认图[0 - 不是默认图,1 - 是默认图]',
   primary key (id)
);

alter table pms_sku_images comment 'sku图片';

/*==============================================================*/
/* Table: pms_sku_info                                          */
/*==============================================================*/
create table pms_sku_info
(
   sku_id               bigint not null auto_increment comment 'skuId',
   spu_id               bigint comment 'spuId',
   sku_name             varchar(255) comment 'sku名称',
   sku_desc             varchar(2000) comment 'sku介绍描述',
   catalog_id           bigint comment '所属分类id',
   brand_id             bigint comment '品牌id',
   sku_default_img      varchar(255) comment '默认图片',
   sku_title            varchar(255) comment '标题',
   sku_subtitle         varchar(2000) comment '副标题',
   price                decimal(18,4) comment '价格',
   sale_count           bigint comment '销量',
   primary key (sku_id)
);

alter table pms_sku_info comment 'sku信息';

/*==============================================================*/
/* Table: pms_sku_sale_attr_value                               */
/*==============================================================*/
create table pms_sku_sale_attr_value
(
   id                   bigint not null auto_increment comment 'id',
   sku_id               bigint comment 'sku_id',
   attr_id              bigint comment 'attr_id',
   attr_name            varchar(200) comment '销售属性名',
   attr_value           varchar(200) comment '销售属性值',
   attr_sort            int comment '顺序',
   primary key (id)
);

alter table pms_sku_sale_attr_value comment 'sku销售属性&值';

/*==============================================================*/
/* Table: pms_spu_comment                                       */
/*==============================================================*/
create table pms_spu_comment
(
   id                   bigint not null auto_increment comment 'id',
   sku_id               bigint comment 'sku_id',
   spu_id               bigint comment 'spu_id',
   spu_name             varchar(255) comment '商品名字',
   member_nick_name     varchar(255) comment '会员昵称',
   star                 tinyint(1) comment '星级',
   member_ip            varchar(64) comment '会员ip',
   create_time          datetime comment '创建时间',
   show_status          tinyint(1) comment '显示状态[0-不显示,1-显示]',
   spu_attributes       varchar(255) comment '购买时属性组合',
   likes_count          int comment '点赞数',
   reply_count          int comment '回复数',
   resources            varchar(1000) comment '评论图片/视频[json数据;[{type:文件类型,url:资源路径}]]',
   content              text comment '内容',
   member_icon          varchar(255) comment '用户头像',
   comment_type         tinyint comment '评论类型[0 - 对商品的直接评论,1 - 对评论的回复]',
   primary key (id)
);

alter table pms_spu_comment comment '商品评价';

/*==============================================================*/
/* Table: pms_spu_images                                        */
/*==============================================================*/
create table pms_spu_images
(
   id                   bigint not null auto_increment comment 'id',
   spu_id               bigint comment 'spu_id',
   img_name             varchar(200) comment '图片名',
   img_url              varchar(255) comment '图片地址',
   img_sort             int comment '顺序',
   default_img          tinyint comment '是否默认图',
   primary key (id)
);

alter table pms_spu_images comment 'spu图片';

/*==============================================================*/
/* Table: pms_spu_info                                          */
/*==============================================================*/
create table pms_spu_info
(
   id                   bigint not null auto_increment comment '商品id',
   spu_name             varchar(200) comment '商品名称',
   spu_description      varchar(1000) comment '商品描述',
   catalog_id           bigint comment '所属分类id',
   brand_id             bigint comment '品牌id',
   weight               decimal(18,4),
   publish_status       tinyint comment '上架状态[0 - 下架,1 - 上架]',
   create_time          datetime,
   update_time          datetime,
   primary key (id)
);

alter table pms_spu_info comment 'spu信息';

/*==============================================================*/
/* Table: pms_spu_info_desc                                     */
/*==============================================================*/
create table pms_spu_info_desc
(
   spu_id               bigint not null comment '商品id',
   decript              longtext comment '商品介绍',
   primary key (spu_id)
);

alter table pms_spu_info_desc comment 'spu信息介绍';

3)、gulimall_sms.sql

drop table if exists sms_coupon;

drop table if exists sms_coupon_history;

drop table if exists sms_coupon_spu_category_relation;

drop table if exists sms_coupon_spu_relation;

drop table if exists sms_home_adv;

drop table if exists sms_home_subject;

drop table if exists sms_home_subject_spu;

drop table if exists sms_member_price;

drop table if exists sms_seckill_promotion;

drop table if exists sms_seckill_session;

drop table if exists sms_seckill_sku_notice;

drop table if exists sms_seckill_sku_relation;

drop table if exists sms_sku_full_reduction;

drop table if exists sms_sku_ladder;

drop table if exists sms_spu_bounds;

/*==============================================================*/
/* Table: sms_coupon                                            */
/*==============================================================*/
create table sms_coupon
(
   id                   bigint not null auto_increment comment 'id',
   coupon_type          tinyint(1) comment '优惠卷类型[0->全场赠券;1->会员赠券;2->购物赠券;3->注册赠券]',
   coupon_img           varchar(2000) comment '优惠券图片',
   coupon_name          varchar(100) comment '优惠卷名字',
   num                  int comment '数量',
   amount               decimal(18,4) comment '金额',
   per_limit            int comment '每人限领张数',
   min_point            decimal(18,4) comment '使用门槛',
   start_time           datetime comment '开始时间',
   end_time             datetime comment '结束时间',
   use_type             tinyint(1) comment '使用类型[0->全场通用;1->指定分类;2->指定商品]',
   note                 varchar(200) comment '备注',
   publish_count        int(11) comment '发行数量',
   use_count            int(11) comment '已使用数量',
   receive_count        int(11) comment '领取数量',
   enable_start_time    datetime comment '可以领取的开始日期',
   enable_end_time      datetime comment '可以领取的结束日期',
   code                 varchar(64) comment '优惠码',
   member_level         tinyint(1) comment '可以领取的会员等级[0->不限等级,其他-对应等级]',
   publish              tinyint(1) comment '发布状态[0-未发布,1-已发布]',
   primary key (id)
);

alter table sms_coupon comment '优惠券信息';

/*==============================================================*/
/* Table: sms_coupon_history                                    */
/*==============================================================*/
create table sms_coupon_history
(
   id                   bigint not null auto_increment comment 'id',
   coupon_id            bigint comment '优惠券id',
   member_id            bigint comment '会员id',
   member_nick_name     varchar(64) comment '会员名字',
   get_type             tinyint(1) comment '获取方式[0->后台赠送;1->主动领取]',
   create_time          datetime comment '创建时间',
   use_type             tinyint(1) comment '使用状态[0->未使用;1->已使用;2->已过期]',
   use_time             datetime comment '使用时间',
   order_id             bigint comment '订单id',
   order_sn             bigint comment '订单号',
   primary key (id)
);

alter table sms_coupon_history comment '优惠券领取历史记录';

/*==============================================================*/
/* Table: sms_coupon_spu_category_relation                      */
/*==============================================================*/
create table sms_coupon_spu_category_relation
(
   id                   bigint not null auto_increment comment 'id',
   coupon_id            bigint comment '优惠券id',
   category_id          bigint comment '产品分类id',
   category_name        varchar(64) comment '产品分类名称',
   primary key (id)
);

alter table sms_coupon_spu_category_relation comment '优惠券分类关联';

/*==============================================================*/
/* Table: sms_coupon_spu_relation                               */
/*==============================================================*/
create table sms_coupon_spu_relation
(
   id                   bigint not null auto_increment comment 'id',
   coupon_id            bigint comment '优惠券id',
   spu_id               bigint comment 'spu_id',
   spu_name             varchar(255) comment 'spu_name',
   primary key (id)
);

alter table sms_coupon_spu_relation comment '优惠券与产品关联';

/*==============================================================*/
/* Table: sms_home_adv                                          */
/*==============================================================*/
create table sms_home_adv
(
   id                   bigint not null auto_increment comment 'id',
   name                 varchar(100) comment '名字',
   pic                  varchar(500) comment '图片地址',
   start_time           datetime comment '开始时间',
   end_time             datetime comment '结束时间',
   status               tinyint(1) comment '状态',
   click_count          int comment '点击数',
   url                  varchar(500) comment '广告详情连接地址',
   note                 varchar(500) comment '备注',
   sort                 int comment '排序',
   publisher_id         bigint comment '发布者',
   auth_id              bigint comment '审核者',
   primary key (id)
);

alter table sms_home_adv comment '首页轮播广告';

/*==============================================================*/
/* Table: sms_home_subject                                      */
/*==============================================================*/
create table sms_home_subject
(
   id                   bigint not null auto_increment comment 'id',
   name                 varchar(200) comment '专题名字',
   title                varchar(255) comment '专题标题',
   sub_title            varchar(255) comment '专题副标题',
   status               tinyint(1) comment '显示状态',
   url                  varchar(500) comment '详情连接',
   sort                 int comment '排序',
   img                  varchar(500) comment '专题图片地址',
   primary key (id)
);

alter table sms_home_subject comment '首页专题表【jd首页下面很多专题,每个专题链接新的页面,展示专题商品信息】';

/*==============================================================*/
/* Table: sms_home_subject_spu                                  */
/*==============================================================*/
create table sms_home_subject_spu
(
   id                   bigint not null auto_increment comment 'id',
   name                 varchar(200) comment '专题名字',
   subject_id           bigint comment '专题id',
   spu_id               bigint comment 'spu_id',
   sort                 int comment '排序',
   primary key (id)
);

alter table sms_home_subject_spu comment '专题商品';

/*==============================================================*/
/* Table: sms_member_price                                      */
/*==============================================================*/
create table sms_member_price
(
   id                   bigint not null auto_increment comment 'id',
   sku_id               bigint comment 'sku_id',
   member_level_id      bigint comment '会员等级id',
   member_level_name    varchar(100) comment '会员等级名',
   member_price         decimal(18,4) comment '会员对应价格',
   add_other            tinyint(1) comment '可否叠加其他优惠[0-不可叠加优惠,1-可叠加]',
   primary key (id)
);

alter table sms_member_price comment '商品会员价格';

/*==============================================================*/
/* Table: sms_seckill_promotion                                 */
/*==============================================================*/
create table sms_seckill_promotion
(
   id                   bigint not null auto_increment comment 'id',
   title                varchar(255) comment '活动标题',
   start_time           datetime comment '开始日期',
   end_time             datetime comment '结束日期',
   status               tinyint comment '上下线状态',
   create_time          datetime comment '创建时间',
   user_id              bigint comment '创建人',
   primary key (id)
);

alter table sms_seckill_promotion comment '秒杀活动';

/*==============================================================*/
/* Table: sms_seckill_session                                   */
/*==============================================================*/
create table sms_seckill_session
(
   id                   bigint not null auto_increment comment 'id',
   name                 varchar(200) comment '场次名称',
   start_time           datetime comment '每日开始时间',
   end_time             datetime comment '每日结束时间',
   status               tinyint(1) comment '启用状态',
   create_time          datetime comment '创建时间',
   primary key (id)
);

alter table sms_seckill_session comment '秒杀活动场次';

/*==============================================================*/
/* Table: sms_seckill_sku_notice                                */
/*==============================================================*/
create table sms_seckill_sku_notice
(
   id                   bigint not null auto_increment comment 'id',
   member_id            bigint comment 'member_id',
   sku_id               bigint comment 'sku_id',
   session_id           bigint comment '活动场次id',
   subcribe_time        datetime comment '订阅时间',
   send_time            datetime comment '发送时间',
   notice_type          tinyint(1) comment '通知方式[0-短信,1-邮件]',
   primary key (id)
);

alter table sms_seckill_sku_notice comment '秒杀商品通知订阅';

/*==============================================================*/
/* Table: sms_seckill_sku_relation                              */
/*==============================================================*/
create table sms_seckill_sku_relation
(
   id                   bigint not null auto_increment comment 'id',
   promotion_id         bigint comment '活动id',
   promotion_session_id bigint comment '活动场次id',
   sku_id               bigint comment '商品id',
   seckill_price        decimal comment '秒杀价格',
   seckill_count        decimal comment '秒杀总量',
   seckill_limit        decimal comment '每人限购数量',
   seckill_sort         int comment '排序',
   primary key (id)
);

alter table sms_seckill_sku_relation comment '秒杀活动商品关联';

/*==============================================================*/
/* Table: sms_sku_full_reduction                                */
/*==============================================================*/
create table sms_sku_full_reduction
(
   id                   bigint not null auto_increment comment 'id',
   sku_id               bigint comment 'spu_id',
   full_price           decimal(18,4) comment '满多少',
   reduce_price         decimal(18,4) comment '减多少',
   add_other            tinyint(1) comment '是否参与其他优惠',
   primary key (id)
);

alter table sms_sku_full_reduction comment '商品满减信息';

/*==============================================================*/
/* Table: sms_sku_ladder                                        */
/*==============================================================*/
create table sms_sku_ladder
(
   id                   bigint not null auto_increment comment 'id',
   sku_id               bigint comment 'spu_id',
   full_count           int comment '满几件',
   discount             decimal(4,2) comment '打几折',
   price                decimal(18,4) comment '折后价',
   add_other            tinyint(1) comment '是否叠加其他优惠[0-不可叠加,1-可叠加]',
   primary key (id)
);

alter table sms_sku_ladder comment '商品阶梯价格';

/*==============================================================*/
/* Table: sms_spu_bounds                                        */
/*==============================================================*/
create table sms_spu_bounds
(
   id                   bigint not null auto_increment comment 'id',
   spu_id               bigint,
   grow_bounds          decimal(18,4) comment '成长积分',
   buy_bounds           decimal(18,4) comment '购物积分',
   work                 tinyint(1) comment '优惠生效情况[1111(四个状态位,从右到左);0 - 无优惠,成长积分是否赠送;1 - 无优惠,购物积分是否赠送;2 - 有优惠,成长积分是否赠送;3 - 有优惠,购物积分是否赠送【状态位0:不赠送,1:赠送】]',
   primary key (id)
);

alter table sms_spu_bounds comment '商品spu积分设置';

4)、gulimall_ums.sql 

drop table if exists ums_growth_change_history;

drop table if exists ums_integration_change_history;

drop table if exists ums_member;

drop table if exists ums_member_collect_spu;

drop table if exists ums_member_collect_subject;

drop table if exists ums_member_level;

drop table if exists ums_member_login_log;

drop table if exists ums_member_receive_address;

drop table if exists ums_member_statistics_info;

/*==============================================================*/
/* Table: ums_growth_change_history                             */
/*==============================================================*/
create table ums_growth_change_history
(
   id                   bigint not null auto_increment comment 'id',
   member_id            bigint comment 'member_id',
   create_time          datetime comment 'create_time',
   change_count         int comment '改变的值(正负计数)',
   note                 varchar(0) comment '备注',
   source_type          tinyint comment '积分来源[0-购物,1-管理员修改]',
   primary key (id)
);

alter table ums_growth_change_history comment '成长值变化历史记录';

/*==============================================================*/
/* Table: ums_integration_change_history                        */
/*==============================================================*/
create table ums_integration_change_history
(
   id                   bigint not null auto_increment comment 'id',
   member_id            bigint comment 'member_id',
   create_time          datetime comment 'create_time',
   change_count         int comment '变化的值',
   note                 varchar(255) comment '备注',
   source_tyoe          tinyint comment '来源[0->购物;1->管理员修改;2->活动]',
   primary key (id)
);

alter table ums_integration_change_history comment '积分变化历史记录';

/*==============================================================*/
/* Table: ums_member                                            */
/*==============================================================*/
create table ums_member
(
   id                   bigint not null auto_increment comment 'id',
   level_id             bigint comment '会员等级id',
   username             char(64) comment '用户名',
   password             varchar(64) comment '密码',
   nickname             varchar(64) comment '昵称',
   mobile               varchar(20) comment '手机号码',
   email                varchar(64) comment '邮箱',
   header               varchar(500) comment '头像',
   gender               tinyint comment '性别',
   birth                date comment '生日',
   city                 varchar(500) comment '所在城市',
   job                  varchar(255) comment '职业',
   sign                 varchar(255) comment '个性签名',
   source_type          tinyint comment '用户来源',
   integration          int comment '积分',
   growth               int comment '成长值',
   status               tinyint comment '启用状态',
   create_time          datetime comment '注册时间',
   primary key (id)
);

alter table ums_member comment '会员';

/*==============================================================*/
/* Table: ums_member_collect_spu                                */
/*==============================================================*/
create table ums_member_collect_spu
(
   id                   bigint not null comment 'id',
   member_id            bigint comment '会员id',
   spu_id               bigint comment 'spu_id',
   spu_name             varchar(500) comment 'spu_name',
   spu_img              varchar(500) comment 'spu_img',
   create_time          datetime comment 'create_time',
   primary key (id)
);

alter table ums_member_collect_spu comment '会员收藏的商品';

/*==============================================================*/
/* Table: ums_member_collect_subject                            */
/*==============================================================*/
create table ums_member_collect_subject
(
   id                   bigint not null auto_increment comment 'id',
   subject_id           bigint comment 'subject_id',
   subject_name         varchar(255) comment 'subject_name',
   subject_img          varchar(500) comment 'subject_img',
   subject_urll         varchar(500) comment '活动url',
   primary key (id)
);

alter table ums_member_collect_subject comment '会员收藏的专题活动';

/*==============================================================*/
/* Table: ums_member_level                                      */
/*==============================================================*/
create table ums_member_level
(
   id                   bigint not null auto_increment comment 'id',
   name                 varchar(100) comment '等级名称',
   growth_point         int comment '等级需要的成长值',
   default_status       tinyint comment '是否为默认等级[0->不是;1->是]',
   free_freight_point   decimal(18,4) comment '免运费标准',
   comment_growth_point int comment '每次评价获取的成长值',
   priviledge_free_freight tinyint comment '是否有免邮特权',
   priviledge_member_price tinyint comment '是否有会员价格特权',
   priviledge_birthday  tinyint comment '是否有生日特权',
   note                 varchar(255) comment '备注',
   primary key (id)
);

alter table ums_member_level comment '会员等级';

/*==============================================================*/
/* Table: ums_member_login_log                                  */
/*==============================================================*/
create table ums_member_login_log
(
   id                   bigint not null auto_increment comment 'id',
   member_id            bigint comment 'member_id',
   create_time          datetime comment '创建时间',
   ip                   varchar(64) comment 'ip',
   city                 varchar(64) comment 'city',
   login_type           tinyint(1) comment '登录类型[1-web,2-app]',
   primary key (id)
);

alter table ums_member_login_log comment '会员登录记录';

/*==============================================================*/
/* Table: ums_member_receive_address                            */
/*==============================================================*/
create table ums_member_receive_address
(
   id                   bigint not null auto_increment comment 'id',
   member_id            bigint comment 'member_id',
   name                 varchar(255) comment '收货人姓名',
   phone                varchar(64) comment '电话',
   post_code            varchar(64) comment '邮政编码',
   province             varchar(100) comment '省份/直辖市',
   city                 varchar(100) comment '城市',
   region               varchar(100) comment '区',
   detail_address       varchar(255) comment '详细地址(街道)',
   areacode             varchar(15) comment '省市区代码',
   default_status       tinyint(1) comment '是否默认',
   primary key (id)
);

alter table ums_member_receive_address comment '会员收货地址';

/*==============================================================*/
/* Table: ums_member_statistics_info                            */
/*==============================================================*/
create table ums_member_statistics_info
(
   id                   bigint not null auto_increment comment 'id',
   member_id            bigint comment '会员id',
   consume_amount       decimal(18,4) comment '累计消费金额',
   coupon_amount        decimal(18,4) comment '累计优惠金额',
   order_count          int comment '订单数量',
   coupon_count         int comment '优惠券数量',
   comment_count        int comment '评价数',
   return_order_count   int comment '退货数量',
   login_count          int comment '登录次数',
   attend_count         int comment '关注数量',
   fans_count           int comment '粉丝数量',
   collect_product_count int comment '收藏的商品数量',
   collect_subject_count int comment '收藏的专题活动数量',
   collect_comment_count int comment '收藏的评论数量',
   invite_friend_count  int comment '邀请的朋友数量',
   primary key (id)
);

alter table ums_member_statistics_info comment '会员统计信息';

 5)、gulimall_wms.sql

/*
SQLyog Ultimate v11.25 (64 bit)
MySQL - 5.7.27 : Database - gulimall_wms
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`gulimall_wms` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;

USE `gulimall_wms`;

/*Table structure for table `undo_log` */

DROP TABLE IF EXISTS `undo_log`;

CREATE TABLE `undo_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(100) NOT NULL,
  `context` varchar(128) NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(11) NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  `ext` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `undo_log` */

/*Table structure for table `wms_purchase` */

DROP TABLE IF EXISTS `wms_purchase`;

CREATE TABLE `wms_purchase` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `assignee_id` bigint(20) DEFAULT NULL,
  `assignee_name` varchar(255) DEFAULT NULL,
  `phone` char(13) DEFAULT NULL,
  `priority` int(4) DEFAULT NULL,
  `status` int(4) DEFAULT NULL,
  `ware_id` bigint(20) DEFAULT NULL,
  `amount` decimal(18,4) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='采购信息';

/*Data for the table `wms_purchase` */

/*Table structure for table `wms_purchase_detail` */

DROP TABLE IF EXISTS `wms_purchase_detail`;

CREATE TABLE `wms_purchase_detail` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `purchase_id` bigint(20) DEFAULT NULL COMMENT '采购单id',
  `sku_id` bigint(20) DEFAULT NULL COMMENT '采购商品id',
  `sku_num` int(11) DEFAULT NULL COMMENT '采购数量',
  `sku_price` decimal(18,4) DEFAULT NULL COMMENT '采购金额',
  `ware_id` bigint(20) DEFAULT NULL COMMENT '仓库id',
  `status` int(11) DEFAULT NULL COMMENT '状态[0新建,1已分配,2正在采购,3已完成,4采购失败]',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

/*Data for the table `wms_purchase_detail` */

/*Table structure for table `wms_ware_info` */

DROP TABLE IF EXISTS `wms_ware_info`;

CREATE TABLE `wms_ware_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `name` varchar(255) DEFAULT NULL COMMENT '仓库名',
  `address` varchar(255) DEFAULT NULL COMMENT '仓库地址',
  `areacode` varchar(20) DEFAULT NULL COMMENT '区域编码',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='仓库信息';

/*Data for the table `wms_ware_info` */

/*Table structure for table `wms_ware_order_task` */

DROP TABLE IF EXISTS `wms_ware_order_task`;

CREATE TABLE `wms_ware_order_task` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `order_id` bigint(20) DEFAULT NULL COMMENT 'order_id',
  `order_sn` varchar(255) DEFAULT NULL COMMENT 'order_sn',
  `consignee` varchar(100) DEFAULT NULL COMMENT '收货人',
  `consignee_tel` char(15) DEFAULT NULL COMMENT '收货人电话',
  `delivery_address` varchar(500) DEFAULT NULL COMMENT '配送地址',
  `order_comment` varchar(200) DEFAULT NULL COMMENT '订单备注',
  `payment_way` tinyint(1) DEFAULT NULL COMMENT '付款方式【 1:在线付款 2:货到付款】',
  `task_status` tinyint(2) DEFAULT NULL COMMENT '任务状态',
  `order_body` varchar(255) DEFAULT NULL COMMENT '订单描述',
  `tracking_no` char(30) DEFAULT NULL COMMENT '物流单号',
  `create_time` datetime DEFAULT NULL COMMENT 'create_time',
  `ware_id` bigint(20) DEFAULT NULL COMMENT '仓库id',
  `task_comment` varchar(500) DEFAULT NULL COMMENT '工作单备注',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='库存工作单';

/*Data for the table `wms_ware_order_task` */

/*Table structure for table `wms_ware_order_task_detail` */

DROP TABLE IF EXISTS `wms_ware_order_task_detail`;

CREATE TABLE `wms_ware_order_task_detail` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `sku_id` bigint(20) DEFAULT NULL COMMENT 'sku_id',
  `sku_name` varchar(255) DEFAULT NULL COMMENT 'sku_name',
  `sku_num` int(11) DEFAULT NULL COMMENT '购买个数',
  `task_id` bigint(20) DEFAULT NULL COMMENT '工作单id',
  `ware_id` bigint(20) DEFAULT NULL COMMENT '仓库id',
  `lock_status` int(1) DEFAULT NULL COMMENT '1-已锁定  2-已解锁  3-扣减',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='库存工作单';

/*Data for the table `wms_ware_order_task_detail` */

/*Table structure for table `wms_ware_sku` */

DROP TABLE IF EXISTS `wms_ware_sku`;

CREATE TABLE `wms_ware_sku` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `sku_id` bigint(20) DEFAULT NULL COMMENT 'sku_id',
  `ware_id` bigint(20) DEFAULT NULL COMMENT '仓库id',
  `stock` int(11) DEFAULT NULL COMMENT '库存数',
  `sku_name` varchar(200) DEFAULT NULL COMMENT 'sku_name',
  `stock_locked` int(11) DEFAULT '0' COMMENT '锁定库存',
  PRIMARY KEY (`id`),
  KEY `sku_id` (`sku_id`) USING BTREE,
  KEY `ware_id` (`ware_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品库存';

/*Data for the table `wms_ware_sku` */

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

 6)、pms_catelog.sql

DROP TABLE IF EXISTS `pms_category`;

CREATE TABLE `pms_category` (
  `cat_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '分类id',
  `name` char(50) DEFAULT NULL COMMENT '分类名称',
  `parent_cid` bigint(20) DEFAULT NULL COMMENT '父分类id',
  `cat_level` int(11) DEFAULT NULL COMMENT '层级',
  `show_status` tinyint(4) DEFAULT NULL COMMENT '是否显示[0-不显示,1显示]',
  `sort` int(11) DEFAULT NULL COMMENT '排序',
  `icon` char(255) DEFAULT NULL COMMENT '图标地址',
  `product_unit` char(50) DEFAULT NULL COMMENT '计量单位',
  `product_count` int(11) DEFAULT NULL COMMENT '商品数量',
  PRIMARY KEY (`cat_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1433 DEFAULT CHARSET=utf8mb4 COMMENT='商品三级分类';

/*Data for the table `pms_category` */

insert  into `pms_category`(`cat_id`,`name`,`parent_cid`,`cat_level`,`show_status`,`sort`,`icon`,`product_unit`,`product_count`) values (1,'图书、音像、电子书刊',0,1,1,0,NULL,NULL,0),(2,'手机',0,1,1,0,NULL,NULL,0),(3,'家用电器',0,1,1,0,NULL,NULL,0),(4,'数码',0,1,1,0,NULL,NULL,0),(5,'家居家装',0,1,1,0,NULL,NULL,0),(6,'电脑办公',0,1,1,0,NULL,NULL,0),(7,'厨具',0,1,1,0,NULL,NULL,0),(8,'个护化妆',0,1,1,0,NULL,NULL,0),(9,'服饰内衣',0,1,1,0,NULL,NULL,0),(10,'钟表',0,1,1,0,NULL,NULL,0),(11,'鞋靴',0,1,1,0,NULL,NULL,0),(12,'母婴',0,1,1,0,NULL,NULL,0),(13,'礼品箱包',0,1,1,0,NULL,NULL,0),(14,'食品饮料、保健食品',0,1,1,0,NULL,NULL,0),(15,'珠宝',0,1,1,0,NULL,NULL,0),(16,'汽车用品',0,1,1,0,NULL,NULL,0),(17,'运动健康',0,1,1,0,NULL,NULL,0),(18,'玩具乐器',0,1,1,0,NULL,NULL,0),(19,'彩票、旅行、充值、票务',0,1,1,0,NULL,NULL,0),(20,'生鲜',0,1,1,0,NULL,NULL,0),(21,'整车',0,1,1,0,NULL,NULL,0),(22,'电子书刊',1,2,1,0,NULL,NULL,0),(23,'音像',1,2,1,0,NULL,NULL,0),(24,'英文原版',1,2,1,0,NULL,NULL,0),(25,'文艺',1,2,1,0,NULL,NULL,0),(26,'少儿',1,2,1,0,NULL,NULL,0),(27,'人文社科',1,2,1,0,NULL,NULL,0),(28,'经管励志',1,2,1,0,NULL,NULL,0),(29,'生活',1,2,1,0,NULL,NULL,0),(30,'科技',1,2,1,0,NULL,NULL,0),(31,'教育',1,2,1,0,NULL,NULL,0),(32,'港台图书',1,2,1,0,NULL,NULL,0),(33,'其他',1,2,1,0,NULL,NULL,0),(34,'手机通讯',2,2,1,0,NULL,NULL,0),(35,'运营商',2,2,1,0,NULL,NULL,0),(36,'手机配件',2,2,1,0,NULL,NULL,0),(37,'大 家 电',3,2,1,0,NULL,NULL,0),(38,'厨卫大电',3,2,1,0,NULL,NULL,0),(39,'厨房小电',3,2,1,0,NULL,NULL,0),(40,'生活电器',3,2,1,0,NULL,NULL,0),(41,'个护健康',3,2,1,0,NULL,NULL,0),(42,'五金家装',3,2,1,0,NULL,NULL,0),(43,'摄影摄像',4,2,1,0,NULL,NULL,0),(44,'数码配件',4,2,1,0,NULL,NULL,0),(45,'智能设备',4,2,1,0,NULL,NULL,0),(46,'影音娱乐',4,2,1,0,NULL,NULL,0),(47,'电子教育',4,2,1,0,NULL,NULL,0),(48,'虚拟商品',4,2,1,0,NULL,NULL,0),(49,'家纺',5,2,1,0,NULL,NULL,0),(50,'灯具',5,2,1,0,NULL,NULL,0),(51,'生活日用',5,2,1,0,NULL,NULL,0),(52,'家装软饰',5,2,1,0,NULL,NULL,0),(53,'宠物生活',5,2,1,0,NULL,NULL,0),(54,'电脑整机',6,2,1,0,NULL,NULL,0),(55,'电脑配件',6,2,1,0,NULL,NULL,0),(56,'外设产品',6,2,1,0,NULL,NULL,0),(57,'游戏设备',6,2,1,0,NULL,NULL,0),(58,'网络产品',6,2,1,0,NULL,NULL,0),(59,'办公设备',6,2,1,0,NULL,NULL,0),(60,'文具/耗材',6,2,1,0,NULL,NULL,0),(61,'服务产品',6,2,1,0,NULL,NULL,0),(62,'烹饪锅具',7,2,1,0,NULL,NULL,0),(63,'刀剪菜板',7,2,1,0,NULL,NULL,0),(64,'厨房配件',7,2,1,0,NULL,NULL,0),(65,'水具酒具',7,2,1,0,NULL,NULL,0),(66,'餐具',7,2,1,0,NULL,NULL,0),(67,'酒店用品',7,2,1,0,NULL,NULL,0),(68,'茶具/咖啡具',7,2,1,0,NULL,NULL,0),(69,'清洁用品',8,2,1,0,NULL,NULL,0),(70,'面部护肤',8,2,1,0,NULL,NULL,0),(71,'身体护理',8,2,1,0,NULL,NULL,0),(72,'口腔护理',8,2,1,0,NULL,NULL,0),(73,'女性护理',8,2,1,0,NULL,NULL,0),(74,'洗发护发',8,2,1,0,NULL,NULL,0),(75,'香水彩妆',8,2,1,0,NULL,NULL,0),(76,'女装',9,2,1,0,NULL,NULL,0),(77,'男装',9,2,1,0,NULL,NULL,0),(78,'内衣',9,2,1,0,NULL,NULL,0),(79,'洗衣服务',9,2,1,0,NULL,NULL,0),(80,'服饰配件',9,2,1,0,NULL,NULL,0),(81,'钟表',10,2,1,0,NULL,NULL,0),(82,'流行男鞋',11,2,1,0,NULL,NULL,0),(83,'时尚女鞋',11,2,1,0,NULL,NULL,0),(84,'奶粉',12,2,1,0,NULL,NULL,0),(85,'营养辅食',12,2,1,0,NULL,NULL,0),(86,'尿裤湿巾',12,2,1,0,NULL,NULL,0),(87,'喂养用品',12,2,1,0,NULL,NULL,0),(88,'洗护用品',12,2,1,0,NULL,NULL,0),(89,'童车童床',12,2,1,0,NULL,NULL,0),(90,'寝居服饰',12,2,1,0,NULL,NULL,0),(91,'妈妈专区',12,2,1,0,NULL,NULL,0),(92,'童装童鞋',12,2,1,0,NULL,NULL,0),(93,'安全座椅',12,2,1,0,NULL,NULL,0),(94,'潮流女包',13,2,1,0,NULL,NULL,0),(95,'精品男包',13,2,1,0,NULL,NULL,0),(96,'功能箱包',13,2,1,0,NULL,NULL,0),(97,'礼品',13,2,1,0,NULL,NULL,0),(98,'奢侈品',13,2,1,0,NULL,NULL,0),(99,'婚庆',13,2,1,0,NULL,NULL,0),(100,'进口食品',14,2,1,0,NULL,NULL,0),(101,'地方特产',14,2,1,0,NULL,NULL,0),(102,'休闲食品',14,2,1,0,NULL,NULL,0),(103,'粮油调味',14,2,1,0,NULL,NULL,0),(104,'饮料冲调',14,2,1,0,NULL,NULL,0),(105,'食品礼券',14,2,1,0,NULL,NULL,0),(106,'茗茶',14,2,1,0,NULL,NULL,0),(107,'时尚饰品',15,2,1,0,NULL,NULL,0),(108,'黄金',15,2,1,0,NULL,NULL,0),(109,'K金饰品',15,2,1,0,NULL,NULL,0),(110,'金银投资',15,2,1,0,NULL,NULL,0),(111,'银饰',15,2,1,0,NULL,NULL,0),(112,'钻石',15,2,1,0,NULL,NULL,0),(113,'翡翠玉石',15,2,1,0,NULL,NULL,0),(114,'水晶玛瑙',15,2,1,0,NULL,NULL,0),(115,'彩宝',15,2,1,0,NULL,NULL,0),(116,'铂金',15,2,1,0,NULL,NULL,0),(117,'木手串/把件',15,2,1,0,NULL,NULL,0),(118,'珍珠',15,2,1,0,NULL,NULL,0),(119,'维修保养',16,2,1,0,NULL,NULL,0),(120,'车载电器',16,2,1,0,NULL,NULL,0),(121,'美容清洗',16,2,1,0,NULL,NULL,0),(122,'汽车装饰',16,2,1,0,NULL,NULL,0),(123,'安全自驾',16,2,1,0,NULL,NULL,0),(124,'汽车服务',16,2,1,0,NULL,NULL,0),(125,'赛事改装',16,2,1,0,NULL,NULL,0),(126,'运动鞋包',17,2,1,0,NULL,NULL,0),(127,'运动服饰',17,2,1,0,NULL,NULL,0),(128,'骑行运动',17,2,1,0,NULL,NULL,0),(129,'垂钓用品',17,2,1,0,NULL,NULL,0),(130,'游泳用品',17,2,1,0,NULL,NULL,0),(131,'户外鞋服',17,2,1,0,NULL,NULL,0),(132,'户外装备',17,2,1,0,NULL,NULL,0),(133,'健身训练',17,2,1,0,NULL,NULL,0),(134,'体育用品',17,2,1,0,NULL,NULL,0),(135,'适用年龄',18,2,1,0,NULL,NULL,0),(136,'遥控/电动',18,2,1,0,NULL,NULL,0),(137,'毛绒布艺',18,2,1,0,NULL,NULL,0),(138,'娃娃玩具',18,2,1,0,NULL,NULL,0),(139,'模型玩具',18,2,1,0,NULL,NULL,0),(140,'健身玩具',18,2,1,0,NULL,NULL,0),(141,'动漫玩具',18,2,1,0,NULL,NULL,0),(142,'益智玩具',18,2,1,0,NULL,NULL,0),(143,'积木拼插',18,2,1,0,NULL,NULL,0),(144,'DIY玩具',18,2,1,0,NULL,NULL,0),(145,'创意减压',18,2,1,0,NULL,NULL,0),(146,'乐器',18,2,1,0,NULL,NULL,0),(147,'彩票',19,2,1,0,NULL,NULL,0),(148,'机票',19,2,1,0,NULL,NULL,0),(149,'酒店',19,2,1,0,NULL,NULL,0),(150,'旅行',19,2,1,0,NULL,NULL,0),(151,'充值',19,2,1,0,NULL,NULL,0),(152,'游戏',19,2,1,0,NULL,NULL,0),(153,'票务',19,2,1,0,NULL,NULL,0),(154,'产地直供',20,2,1,0,NULL,NULL,0),(155,'水果',20,2,1,0,NULL,NULL,0),(156,'猪牛羊肉',20,2,1,0,NULL,NULL,0),(157,'海鲜水产',20,2,1,0,NULL,NULL,0),(158,'禽肉蛋品',20,2,1,0,NULL,NULL,0),(159,'冷冻食品',20,2,1,0,NULL,NULL,0),(160,'熟食腊味',20,2,1,0,NULL,NULL,0),(161,'饮品甜品',20,2,1,0,NULL,NULL,0),(162,'蔬菜',20,2,1,0,NULL,NULL,0),(163,'全新整车',21,2,1,0,NULL,NULL,0),(164,'二手车',21,2,1,0,NULL,NULL,0),(165,'电子书',22,3,1,0,NULL,NULL,0),(166,'网络原创',22,3,1,0,NULL,NULL,0),(167,'数字杂志',22,3,1,0,NULL,NULL,0),(168,'多媒体图书',22,3,1,0,NULL,NULL,0),(169,'音乐',23,3,1,0,NULL,NULL,0),(170,'影视',23,3,1,0,NULL,NULL,0),(171,'教育音像',23,3,1,0,NULL,NULL,0),(172,'少儿',24,3,1,0,NULL,NULL,0),(173,'商务投资',24,3,1,0,NULL,NULL,0),(174,'英语学习与考试',24,3,1,0,NULL,NULL,0),(175,'文学',24,3,1,0,NULL,NULL,0),(176,'传记',24,3,1,0,NULL,NULL,0),(177,'励志',24,3,1,0,NULL,NULL,0),(178,'小说',25,3,1,0,NULL,NULL,0),(179,'文学',25,3,1,0,NULL,NULL,0),(180,'青春文学',25,3,1,0,NULL,NULL,0),(181,'传记',25,3,1,0,NULL,NULL,0),(182,'艺术',25,3,1,0,NULL,NULL,0),(183,'少儿',26,3,1,0,NULL,NULL,0),(184,'0-2岁',26,3,1,0,NULL,NULL,0),(185,'3-6岁',26,3,1,0,NULL,NULL,0),(186,'7-10岁',26,3,1,0,NULL,NULL,0),(187,'11-14岁',26,3,1,0,NULL,NULL,0),(188,'历史',27,3,1,0,NULL,NULL,0),(189,'哲学',27,3,1,0,NULL,NULL,0),(190,'国学',27,3,1,0,NULL,NULL,0),(191,'政治/军事',27,3,1,0,NULL,NULL,0),(192,'法律',27,3,1,0,NULL,NULL,0),(193,'人文社科',27,3,1,0,NULL,NULL,0),(194,'心理学',27,3,1,0,NULL,NULL,0),(195,'文化',27,3,1,0,NULL,NULL,0),(196,'社会科学',27,3,1,0,NULL,NULL,0),(197,'经济',28,3,1,0,NULL,NULL,0),(198,'金融与投资',28,3,1,0,NULL,NULL,0),(199,'管理',28,3,1,0,NULL,NULL,0),(200,'励志与成功',28,3,1,0,NULL,NULL,0),(201,'生活',29,3,1,0,NULL,NULL,0),(202,'健身与保健',29,3,1,0,NULL,NULL,0),(203,'家庭与育儿',29,3,1,0,NULL,NULL,0),(204,'旅游',29,3,1,0,NULL,NULL,0),(205,'烹饪美食',29,3,1,0,NULL,NULL,0),(206,'工业技术',30,3,1,0,NULL,NULL,0),(207,'科普读物',30,3,1,0,NULL,NULL,0),(208,'建筑',30,3,1,0,NULL,NULL,0),(209,'医学',30,3,1,0,NULL,NULL,0),(210,'科学与自然',30,3,1,0,NULL,NULL,0),(211,'计算机与互联网',30,3,1,0,NULL,NULL,0),(212,'电子通信',30,3,1,0,NULL,NULL,0),(213,'中小学教辅',31,3,1,0,NULL,NULL,0),(214,'教育与考试',31,3,1,0,NULL,NULL,0),(215,'外语学习',31,3,1,0,NULL,NULL,0),(216,'大中专教材',31,3,1,0,NULL,NULL,0),(217,'字典词典',31,3,1,0,NULL,NULL,0),(218,'艺术/设计/收藏',32,3,1,0,NULL,NULL,0),(219,'经济管理',32,3,1,0,NULL,NULL,0),(220,'文化/学术',32,3,1,0,NULL,NULL,0),(221,'少儿',32,3,1,0,NULL,NULL,0),(222,'工具书',33,3,1,0,NULL,NULL,0),(223,'杂志/期刊',33,3,1,0,NULL,NULL,0),(224,'套装书',33,3,1,0,NULL,NULL,0),(225,'手机',34,3,1,0,NULL,NULL,0),(226,'对讲机',34,3,1,0,NULL,NULL,0),(227,'合约机',35,3,1,0,NULL,NULL,0),(228,'选号中心',35,3,1,0,NULL,NULL,0),(229,'装宽带',35,3,1,0,NULL,NULL,0),(230,'办套餐',35,3,1,0,NULL,NULL,0),(231,'移动电源',36,3,1,0,NULL,NULL,0),(232,'电池/移动电源',36,3,1,0,NULL,NULL,0),(233,'蓝牙耳机',36,3,1,0,NULL,NULL,0),(234,'充电器/数据线',36,3,1,0,NULL,NULL,0),(235,'苹果周边',36,3,1,0,NULL,NULL,0),(236,'手机耳机',36,3,1,0,NULL,NULL,0),(237,'手机贴膜',36,3,1,0,NULL,NULL,0),(238,'手机存储卡',36,3,1,0,NULL,NULL,0),(239,'充电器',36,3,1,0,NULL,NULL,0),(240,'数据线',36,3,1,0,NULL,NULL,0),(241,'手机保护套',36,3,1,0,NULL,NULL,0),(242,'车载配件',36,3,1,0,NULL,NULL,0),(243,'iPhone 配件',36,3,1,0,NULL,NULL,0),(244,'手机电池',36,3,1,0,NULL,NULL,0),(245,'创意配件',36,3,1,0,NULL,NULL,0),(246,'便携/无线音响',36,3,1,0,NULL,NULL,0),(247,'手机饰品',36,3,1,0,NULL,NULL,0),(248,'拍照配件',36,3,1,0,NULL,NULL,0),(249,'手机支架',36,3,1,0,NULL,NULL,0),(250,'平板电视',37,3,1,0,NULL,NULL,0),(251,'空调',37,3,1,0,NULL,NULL,0),(252,'冰箱',37,3,1,0,NULL,NULL,0),(253,'洗衣机',37,3,1,0,NULL,NULL,0),(254,'家庭影院',37,3,1,0,NULL,NULL,0),(255,'DVD/电视盒子',37,3,1,0,NULL,NULL,0),(256,'迷你音响',37,3,1,0,NULL,NULL,0),(257,'冷柜/冰吧',37,3,1,0,NULL,NULL,0),(258,'家电配件',37,3,1,0,NULL,NULL,0),(259,'功放',37,3,1,0,NULL,NULL,0),(260,'回音壁/Soundbar',37,3,1,0,NULL,NULL,0),(261,'Hi-Fi专区',37,3,1,0,NULL,NULL,0),(262,'电视盒子',37,3,1,0,NULL,NULL,0),(263,'酒柜',37,3,1,0,NULL,NULL,0),(264,'燃气灶',38,3,1,0,NULL,NULL,0),(265,'油烟机',38,3,1,0,NULL,NULL,0),(266,'热水器',38,3,1,0,NULL,NULL,0),(267,'消毒柜',38,3,1,0,NULL,NULL,0),(268,'洗碗机',38,3,1,0,NULL,NULL,0),(269,'料理机',39,3,1,0,NULL,NULL,0),(270,'榨汁机',39,3,1,0,NULL,NULL,0),(271,'电饭煲',39,3,1,0,NULL,NULL,0),(272,'电压力锅',39,3,1,0,NULL,NULL,0),(273,'豆浆机',39,3,1,0,NULL,NULL,0),(274,'咖啡机',39,3,1,0,NULL,NULL,0),(275,'微波炉',39,3,1,0,NULL,NULL,0),(276,'电烤箱',39,3,1,0,NULL,NULL,0),(277,'电磁炉',39,3,1,0,NULL,NULL,0),(278,'面包机',39,3,1,0,NULL,NULL,0),(279,'煮蛋器',39,3,1,0,NULL,NULL,0),(280,'酸奶机',39,3,1,0,NULL,NULL,0),(281,'电炖锅',39,3,1,0,NULL,NULL,0),(282,'电水壶/热水瓶',39,3,1,0,NULL,NULL,0),(283,'电饼铛',39,3,1,0,NULL,NULL,0),(284,'多用途锅',39,3,1,0,NULL,NULL,0),(285,'电烧烤炉',39,3,1,0,NULL,NULL,0),(286,'果蔬解毒机',39,3,1,0,NULL,NULL,0),(287,'其它厨房电器',39,3,1,0,NULL,NULL,0),(288,'养生壶/煎药壶',39,3,1,0,NULL,NULL,0),(289,'电热饭盒',39,3,1,0,NULL,NULL,0),(290,'取暖电器',40,3,1,0,NULL,NULL,0),(291,'净化器',40,3,1,0,NULL,NULL,0),(292,'加湿器',40,3,1,0,NULL,NULL,0),(293,'扫地机器人',40,3,1,0,NULL,NULL,0),(294,'吸尘器',40,3,1,0,NULL,NULL,0),(295,'挂烫机/熨斗',40,3,1,0,NULL,NULL,0),(296,'插座',40,3,1,0,NULL,NULL,0),(297,'电话机',40,3,1,0,NULL,NULL,0),(298,'清洁机',40,3,1,0,NULL,NULL,0),(299,'除湿机',40,3,1,0,NULL,NULL,0),(300,'干衣机',40,3,1,0,NULL,NULL,0),(301,'收录/音机',40,3,1,0,NULL,NULL,0),(302,'电风扇',40,3,1,0,NULL,NULL,0),(303,'冷风扇',40,3,1,0,NULL,NULL,0),(304,'其它生活电器',40,3,1,0,NULL,NULL,0),(305,'生活电器配件',40,3,1,0,NULL,NULL,0),(306,'净水器',40,3,1,0,NULL,NULL,0),(307,'饮水机',40,3,1,0,NULL,NULL,0),(308,'剃须刀',41,3,1,0,NULL,NULL,0),(309,'剃/脱毛器',41,3,1,0,NULL,NULL,0),(310,'口腔护理',41,3,1,0,NULL,NULL,0),(311,'电吹风',41,3,1,0,NULL,NULL,0),(312,'美容器',41,3,1,0,NULL,NULL,0),(313,'理发器',41,3,1,0,NULL,NULL,0),(314,'卷/直发器',41,3,1,0,NULL,NULL,0),(315,'按摩椅',41,3,1,0,NULL,NULL,0),(316,'按摩器',41,3,1,0,NULL,NULL,0),(317,'足浴盆',41,3,1,0,NULL,NULL,0),(318,'血压计',41,3,1,0,NULL,NULL,0),(319,'电子秤/厨房秤',41,3,1,0,NULL,NULL,0),(320,'血糖仪',41,3,1,0,NULL,NULL,0),(321,'体温计',41,3,1,0,NULL,NULL,0),(322,'其它健康电器',41,3,1,0,NULL,NULL,0),(323,'计步器/脂肪检测仪',41,3,1,0,NULL,NULL,0),(324,'电动工具',42,3,1,0,NULL,NULL,0),(325,'手动工具',42,3,1,0,NULL,NULL,0),(326,'仪器仪表',42,3,1,0,NULL,NULL,0),(327,'浴霸/排气扇',42,3,1,0,NULL,NULL,0),(328,'灯具',42,3,1,0,NULL,NULL,0),(329,'LED灯',42,3,1,0,NULL,NULL,0),(330,'洁身器',42,3,1,0,NULL,NULL,0),(331,'水槽',42,3,1,0,NULL,NULL,0),(332,'龙头',42,3,1,0,NULL,NULL,0),(333,'淋浴花洒',42,3,1,0,NULL,NULL,0),(334,'厨卫五金',42,3,1,0,NULL,NULL,0),(335,'家具五金',42,3,1,0,NULL,NULL,0),(336,'门铃',42,3,1,0,NULL,NULL,0),(337,'电气开关',42,3,1,0,NULL,NULL,0),(338,'插座',42,3,1,0,NULL,NULL,0),(339,'电工电料',42,3,1,0,NULL,NULL,0),(340,'监控安防',42,3,1,0,NULL,NULL,0),(341,'电线/线缆',42,3,1,0,NULL,NULL,0),(342,'数码相机',43,3,1,0,NULL,NULL,0),(343,'单电/微单相机',43,3,1,0,NULL,NULL,0),(344,'单反相机',43,3,1,0,NULL,NULL,0),(345,'摄像机',43,3,1,0,NULL,NULL,0),(346,'拍立得',43,3,1,0,NULL,NULL,0),(347,'运动相机',43,3,1,0,NULL,NULL,0),(348,'镜头',43,3,1,0,NULL,NULL,0),(349,'户外器材',43,3,1,0,NULL,NULL,0),(350,'影棚器材',43,3,1,0,NULL,NULL,0),(351,'冲印服务',43,3,1,0,NULL,NULL,0),(352,'数码相框',43,3,1,0,NULL,NULL,0),(353,'存储卡',44,3,1,0,NULL,NULL,0),(354,'读卡器',44,3,1,0,NULL,NULL,0),(355,'滤镜',44,3,1,0,NULL,NULL,0),(356,'闪光灯/手柄',44,3,1,0,NULL,NULL,0),(357,'相机包',44,3,1,0,NULL,NULL,0),(358,'三脚架/云台',44,3,1,0,NULL,NULL,0),(359,'相机清洁/贴膜',44,3,1,0,NULL,NULL,0),(360,'机身附件',44,3,1,0,NULL,NULL,0),(361,'镜头附件',44,3,1,0,NULL,NULL,0),(362,'电池/充电器',44,3,1,0,NULL,NULL,0),(363,'移动电源',44,3,1,0,NULL,NULL,0),(364,'数码支架',44,3,1,0,NULL,NULL,0),(365,'智能手环',45,3,1,0,NULL,NULL,0),(366,'智能手表',45,3,1,0,NULL,NULL,0),(367,'智能眼镜',45,3,1,0,NULL,NULL,0),(368,'运动跟踪器',45,3,1,0,NULL,NULL,0),(369,'健康监测',45,3,1,0,NULL,NULL,0),(370,'智能配饰',45,3,1,0,NULL,NULL,0),(371,'智能家居',45,3,1,0,NULL,NULL,0),(372,'体感车',45,3,1,0,NULL,NULL,0),(373,'其他配件',45,3,1,0,NULL,NULL,0),(374,'智能机器人',45,3,1,0,NULL,NULL,0),(375,'无人机',45,3,1,0,NULL,NULL,0),(376,'MP3/MP4',46,3,1,0,NULL,NULL,0),(377,'智能设备',46,3,1,0,NULL,NULL,0),(378,'耳机/耳麦',46,3,1,0,NULL,NULL,0),(379,'便携/无线音箱',46,3,1,0,NULL,NULL,0),(380,'音箱/音响',46,3,1,0,NULL,NULL,0),(381,'高清播放器',46,3,1,0,NULL,NULL,0),(382,'收音机',46,3,1,0,NULL,NULL,0),(383,'MP3/MP4配件',46,3,1,0,NULL,NULL,0),(384,'麦克风',46,3,1,0,NULL,NULL,0),(385,'专业音频',46,3,1,0,NULL,NULL,0),(386,'苹果配件',46,3,1,0,NULL,NULL,0),(387,'学生平板',47,3,1,0,NULL,NULL,0),(388,'点读机/笔',47,3,1,0,NULL,NULL,0),(389,'早教益智',47,3,1,0,NULL,NULL,0),(390,'录音笔',47,3,1,0,NULL,NULL,0),(391,'电纸书',47,3,1,0,NULL,NULL,0),(392,'电子词典',47,3,1,0,NULL,NULL,0),(393,'复读机',47,3,1,0,NULL,NULL,0),(394,'延保服务',48,3,1,0,NULL,NULL,0),(395,'杀毒软件',48,3,1,0,NULL,NULL,0),(396,'积分商品',48,3,1,0,NULL,NULL,0),(397,'桌布/罩件',49,3,1,0,NULL,NULL,0),(398,'地毯地垫',49,3,1,0,NULL,NULL,0),(399,'沙发垫套/椅垫',49,3,1,0,NULL,NULL,0),(400,'床品套件',49,3,1,0,NULL,NULL,0),(401,'被子',49,3,1,0,NULL,NULL,0),(402,'枕芯',49,3,1,0,NULL,NULL,0),(403,'床单被罩',49,3,1,0,NULL,NULL,0),(404,'毯子',49,3,1,0,NULL,NULL,0),(405,'床垫/床褥',49,3,1,0,NULL,NULL,0),(406,'蚊帐',49,3,1,0,NULL,NULL,0),(407,'抱枕靠垫',49,3,1,0,NULL,NULL,0),(408,'毛巾浴巾',49,3,1,0,NULL,NULL,0),(409,'电热毯',49,3,1,0,NULL,NULL,0),(410,'窗帘/窗纱',49,3,1,0,NULL,NULL,0),(411,'布艺软饰',49,3,1,0,NULL,NULL,0),(412,'凉席',49,3,1,0,NULL,NULL,0),(413,'台灯',50,3,1,0,NULL,NULL,0),(414,'节能灯',50,3,1,0,NULL,NULL,0),(415,'装饰灯',50,3,1,0,NULL,NULL,0),(416,'落地灯',50,3,1,0,NULL,NULL,0),(417,'应急灯/手电',50,3,1,0,NULL,NULL,0),(418,'LED灯',50,3,1,0,NULL,NULL,0),(419,'吸顶灯',50,3,1,0,NULL,NULL,0),(420,'五金电器',50,3,1,0,NULL,NULL,0),(421,'筒灯射灯',50,3,1,0,NULL,NULL,0),(422,'吊灯',50,3,1,0,NULL,NULL,0),(423,'氛围照明',50,3,1,0,NULL,NULL,0),(424,'保暖防护',51,3,1,0,NULL,NULL,0),(425,'收纳用品',51,3,1,0,NULL,NULL,0),(426,'雨伞雨具',51,3,1,0,NULL,NULL,0),(427,'浴室用品',51,3,1,0,NULL,NULL,0),(428,'缝纫/针织用品',51,3,1,0,NULL,NULL,0),(429,'洗晒/熨烫',51,3,1,0,NULL,NULL,0),(430,'净化除味',51,3,1,0,NULL,NULL,0),(431,'相框/照片墙',52,3,1,0,NULL,NULL,0),(432,'装饰字画',52,3,1,0,NULL,NULL,0),(433,'节庆饰品',52,3,1,0,NULL,NULL,0),(434,'手工/十字绣',52,3,1,0,NULL,NULL,0),(435,'装饰摆件',52,3,1,0,NULL,NULL,0),(436,'帘艺隔断',52,3,1,0,NULL,NULL,0),(437,'墙贴/装饰贴',52,3,1,0,NULL,NULL,0),(438,'钟饰',52,3,1,0,NULL,NULL,0),(439,'花瓶花艺',52,3,1,0,NULL,NULL,0),(440,'香薰蜡烛',52,3,1,0,NULL,NULL,0),(441,'创意家居',52,3,1,0,NULL,NULL,0),(442,'宠物主粮',53,3,1,0,NULL,NULL,0),(443,'宠物零食',53,3,1,0,NULL,NULL,0),(444,'医疗保健',53,3,1,0,NULL,NULL,0),(445,'家居日用',53,3,1,0,NULL,NULL,0),(446,'宠物玩具',53,3,1,0,NULL,NULL,0),(447,'出行装备',53,3,1,0,NULL,NULL,0),(448,'洗护美容',53,3,1,0,NULL,NULL,0),(449,'笔记本',54,3,1,0,NULL,NULL,0),(450,'超极本',54,3,1,0,NULL,NULL,0),(451,'游戏本',54,3,1,0,NULL,NULL,0),(452,'平板电脑',54,3,1,0,NULL,NULL,0),(453,'平板电脑配件',54,3,1,0,NULL,NULL,0),(454,'台式机',54,3,1,0,NULL,NULL,0),(455,'服务器/工作站',54,3,1,0,NULL,NULL,0),(456,'笔记本配件',54,3,1,0,NULL,NULL,0),(457,'一体机',54,3,1,0,NULL,NULL,0),(458,'CPU',55,3,1,0,NULL,NULL,0),(459,'主板',55,3,1,0,NULL,NULL,0),(460,'显卡',55,3,1,0,NULL,NULL,0),(461,'硬盘',55,3,1,0,NULL,NULL,0),(462,'SSD固态硬盘',55,3,1,0,NULL,NULL,0),(463,'内存',55,3,1,0,NULL,NULL,0),(464,'机箱',55,3,1,0,NULL,NULL,0),(465,'电源',55,3,1,0,NULL,NULL,0),(466,'显示器',55,3,1,0,NULL,NULL,0),(467,'刻录机/光驱',55,3,1,0,NULL,NULL,0),(468,'散热器',55,3,1,0,NULL,NULL,0),(469,'声卡/扩展卡',55,3,1,0,NULL,NULL,0),(470,'装机配件',55,3,1,0,NULL,NULL,0),(471,'组装电脑',55,3,1,0,NULL,NULL,0),(472,'移动硬盘',56,3,1,0,NULL,NULL,0),(473,'U盘',56,3,1,0,NULL,NULL,0),(474,'鼠标',56,3,1,0,NULL,NULL,0),(475,'键盘',56,3,1,0,NULL,NULL,0),(476,'鼠标垫',56,3,1,0,NULL,NULL,0),(477,'摄像头',56,3,1,0,NULL,NULL,0),(478,'手写板',56,3,1,0,NULL,NULL,0),(479,'硬盘盒',56,3,1,0,NULL,NULL,0),(480,'插座',56,3,1,0,NULL,NULL,0),(481,'线缆',56,3,1,0,NULL,NULL,0),(482,'UPS电源',56,3,1,0,NULL,NULL,0),(483,'电脑工具',56,3,1,0,NULL,NULL,0),(484,'游戏设备',56,3,1,0,NULL,NULL,0),(485,'电玩',56,3,1,0,NULL,NULL,0),(486,'电脑清洁',56,3,1,0,NULL,NULL,0),(487,'网络仪表仪器',56,3,1,0,NULL,NULL,0),(488,'游戏机',57,3,1,0,NULL,NULL,0),(489,'游戏耳机',57,3,1,0,NULL,NULL,0),(490,'手柄/方向盘',57,3,1,0,NULL,NULL,0),(491,'游戏软件',57,3,1,0,NULL,NULL,0),(492,'游戏周边',57,3,1,0,NULL,NULL,0),(493,'路由器',58,3,1,0,NULL,NULL,0),(494,'网卡',58,3,1,0,NULL,NULL,0),(495,'交换机',58,3,1,0,NULL,NULL,0),(496,'网络存储',58,3,1,0,NULL,NULL,0),(497,'4G/3G上网',58,3,1,0,NULL,NULL,0),(498,'网络盒子',58,3,1,0,NULL,NULL,0),(499,'网络配件',58,3,1,0,NULL,NULL,0),(500,'投影机',59,3,1,0,NULL,NULL,0),(501,'投影配件',59,3,1,0,NULL,NULL,0),(502,'多功能一体机',59,3,1,0,NULL,NULL,0),(503,'打印机',59,3,1,0,NULL,NULL,0),(504,'传真设备',59,3,1,0,NULL,NULL,0),(505,'验钞/点钞机',59,3,1,0,NULL,NULL,0),(506,'扫描设备',59,3,1,0,NULL,NULL,0),(507,'复合机',59,3,1,0,NULL,NULL,0),(508,'碎纸机',59,3,1,0,NULL,NULL,0),(509,'考勤机',59,3,1,0,NULL,NULL,0),(510,'收款/POS机',59,3,1,0,NULL,NULL,0),(511,'会议音频视频',59,3,1,0,NULL,NULL,0),(512,'保险柜',59,3,1,0,NULL,NULL,0),(513,'装订/封装机',59,3,1,0,NULL,NULL,0),(514,'安防监控',59,3,1,0,NULL,NULL,0),(515,'办公家具',59,3,1,0,NULL,NULL,0),(516,'白板',59,3,1,0,NULL,NULL,0),(517,'硒鼓/墨粉',60,3,1,0,NULL,NULL,0),(518,'墨盒',60,3,1,0,NULL,NULL,0),(519,'色带',60,3,1,0,NULL,NULL,0),(520,'纸类',60,3,1,0,NULL,NULL,0),(521,'办公文具',60,3,1,0,NULL,NULL,0),(522,'学生文具',60,3,1,0,NULL,NULL,0),(523,'财会用品',60,3,1,0,NULL,NULL,0),(524,'文件管理',60,3,1,0,NULL,NULL,0),(525,'本册/便签',60,3,1,0,NULL,NULL,0),(526,'计算器',60,3,1,0,NULL,NULL,0),(527,'笔类',60,3,1,0,NULL,NULL,0),(528,'画具画材',60,3,1,0,NULL,NULL,0),(529,'刻录碟片/附件',60,3,1,0,NULL,NULL,0),(530,'上门安装',61,3,1,0,NULL,NULL,0),(531,'延保服务',61,3,1,0,NULL,NULL,0),(532,'维修保养',61,3,1,0,NULL,NULL,0),(533,'电脑软件',61,3,1,0,NULL,NULL,0),(534,'京东服务',61,3,1,0,NULL,NULL,0),(535,'炒锅',62,3,1,0,NULL,NULL,0),(536,'煎锅',62,3,1,0,NULL,NULL,0),(537,'压力锅',62,3,1,0,NULL,NULL,0),(538,'蒸锅',62,3,1,0,NULL,NULL,0),(539,'汤锅',62,3,1,0,NULL,NULL,0),(540,'奶锅',62,3,1,0,NULL,NULL,0),(541,'锅具套装',62,3,1,0,NULL,NULL,0),(542,'煲类',62,3,1,0,NULL,NULL,0),(543,'水壶',62,3,1,0,NULL,NULL,0),(544,'火锅',62,3,1,0,NULL,NULL,0),(545,'菜刀',63,3,1,0,NULL,NULL,0),(546,'剪刀',63,3,1,0,NULL,NULL,0),(547,'刀具套装',63,3,1,0,NULL,NULL,0),(548,'砧板',63,3,1,0,NULL,NULL,0),(549,'瓜果刀/刨',63,3,1,0,NULL,NULL,0),(550,'多功能刀',63,3,1,0,NULL,NULL,0),(551,'保鲜盒',64,3,1,0,NULL,NULL,0),(552,'烘焙/烧烤',64,3,1,0,NULL,NULL,0),(553,'饭盒/提锅',64,3,1,0,NULL,NULL,0),(554,'储物/置物架',64,3,1,0,NULL,NULL,0),(555,'厨房DIY/小工具',64,3,1,0,NULL,NULL,0),(556,'塑料杯',65,3,1,0,NULL,NULL,0),(557,'运动水壶',65,3,1,0,NULL,NULL,0),(558,'玻璃杯',65,3,1,0,NULL,NULL,0),(559,'陶瓷/马克杯',65,3,1,0,NULL,NULL,0),(560,'保温杯',65,3,1,0,NULL,NULL,0),(561,'保温壶',65,3,1,0,NULL,NULL,0),(562,'酒杯/酒具',65,3,1,0,NULL,NULL,0),(563,'杯具套装',65,3,1,0,NULL,NULL,0),(564,'餐具套装',66,3,1,0,NULL,NULL,0),(565,'碗/碟/盘',66,3,1,0,NULL,NULL,0),(566,'筷勺/刀叉',66,3,1,0,NULL,NULL,0),(567,'一次性用品',66,3,1,0,NULL,NULL,0),(568,'果盘/果篮',66,3,1,0,NULL,NULL,0),(569,'自助餐炉',67,3,1,0,NULL,NULL,0),(570,'酒店餐具',67,3,1,0,NULL,NULL,0),(571,'酒店水具',67,3,1,0,NULL,NULL,0),(572,'整套茶具',68,3,1,0,NULL,NULL,0),(573,'茶杯',68,3,1,0,NULL,NULL,0),(574,'茶壶',68,3,1,0,NULL,NULL,0),(575,'茶盘茶托',68,3,1,0,NULL,NULL,0),(576,'茶叶罐',68,3,1,0,NULL,NULL,0),(577,'茶具配件',68,3,1,0,NULL,NULL,0),(578,'茶宠摆件',68,3,1,0,NULL,NULL,0),(579,'咖啡具',68,3,1,0,NULL,NULL,0),(580,'其他',68,3,1,0,NULL,NULL,0),(581,'纸品湿巾',69,3,1,0,NULL,NULL,0),(582,'衣物清洁',69,3,1,0,NULL,NULL,0),(583,'清洁工具',69,3,1,0,NULL,NULL,0),(584,'驱虫用品',69,3,1,0,NULL,NULL,0),(585,'家庭清洁',69,3,1,0,NULL,NULL,0),(586,'皮具护理',69,3,1,0,NULL,NULL,0),(587,'一次性用品',69,3,1,0,NULL,NULL,0),(588,'洁面',70,3,1,0,NULL,NULL,0),(589,'乳液面霜',70,3,1,0,NULL,NULL,0),(590,'面膜',70,3,1,0,NULL,NULL,0),(591,'剃须',70,3,1,0,NULL,NULL,0),(592,'套装',70,3,1,0,NULL,NULL,0),(593,'精华',70,3,1,0,NULL,NULL,0),(594,'眼霜',70,3,1,0,NULL,NULL,0),(595,'卸妆',70,3,1,0,NULL,NULL,0),(596,'防晒',70,3,1,0,NULL,NULL,0),(597,'防晒隔离',70,3,1,0,NULL,NULL,0),(598,'T区护理',70,3,1,0,NULL,NULL,0),(599,'眼部护理',70,3,1,0,NULL,NULL,0),(600,'精华露',70,3,1,0,NULL,NULL,0),(601,'爽肤水',70,3,1,0,NULL,NULL,0),(602,'沐浴',71,3,1,0,NULL,NULL,0),(603,'润肤',71,3,1,0,NULL,NULL,0),(604,'颈部',71,3,1,0,NULL,NULL,0),(605,'手足',71,3,1,0,NULL,NULL,0),(606,'纤体塑形',71,3,1,0,NULL,NULL,0),(607,'美胸',71,3,1,0,NULL,NULL,0),(608,'套装',71,3,1,0,NULL,NULL,0),(609,'精油',71,3,1,0,NULL,NULL,0),(610,'洗发护发',71,3,1,0,NULL,NULL,0),(611,'染发/造型',71,3,1,0,NULL,NULL,0),(612,'香薰精油',71,3,1,0,NULL,NULL,0),(613,'磨砂/浴盐',71,3,1,0,NULL,NULL,0),(614,'手工/香皂',71,3,1,0,NULL,NULL,0),(615,'洗发',71,3,1,0,NULL,NULL,0),(616,'护发',71,3,1,0,NULL,NULL,0),(617,'染发',71,3,1,0,NULL,NULL,0),(618,'磨砂膏',71,3,1,0,NULL,NULL,0),(619,'香皂',71,3,1,0,NULL,NULL,0),(620,'牙膏/牙粉',72,3,1,0,NULL,NULL,0),(621,'牙刷/牙线',72,3,1,0,NULL,NULL,0),(622,'漱口水',72,3,1,0,NULL,NULL,0),(623,'套装',72,3,1,0,NULL,NULL,0),(624,'卫生巾',73,3,1,0,NULL,NULL,0),(625,'卫生护垫',73,3,1,0,NULL,NULL,0),(626,'私密护理',73,3,1,0,NULL,NULL,0),(627,'脱毛膏',73,3,1,0,NULL,NULL,0),(628,'其他',73,3,1,0,NULL,NULL,0),(629,'洗发',74,3,1,0,NULL,NULL,0),(630,'护发',74,3,1,0,NULL,NULL,0),(631,'染发',74,3,1,0,NULL,NULL,0),(632,'造型',74,3,1,0,NULL,NULL,0),(633,'假发',74,3,1,0,NULL,NULL,0),(634,'套装',74,3,1,0,NULL,NULL,0),(635,'美发工具',74,3,1,0,NULL,NULL,0),(636,'脸部护理',74,3,1,0,NULL,NULL,0),(637,'香水',75,3,1,0,NULL,NULL,0),(638,'底妆',75,3,1,0,NULL,NULL,0),(639,'腮红',75,3,1,0,NULL,NULL,0),(640,'眼影',75,3,1,0,NULL,NULL,0),(641,'唇部',75,3,1,0,NULL,NULL,0),(642,'美甲',75,3,1,0,NULL,NULL,0),(643,'眼线',75,3,1,0,NULL,NULL,0),(644,'美妆工具',75,3,1,0,NULL,NULL,0),(645,'套装',75,3,1,0,NULL,NULL,0),(646,'防晒隔离',75,3,1,0,NULL,NULL,0),(647,'卸妆',75,3,1,0,NULL,NULL,0),(648,'眉笔',75,3,1,0,NULL,NULL,0),(649,'睫毛膏',75,3,1,0,NULL,NULL,0),(650,'T恤',76,3,1,0,NULL,NULL,0),(651,'衬衫',76,3,1,0,NULL,NULL,0),(652,'针织衫',76,3,1,0,NULL,NULL,0),(653,'雪纺衫',76,3,1,0,NULL,NULL,0),(654,'卫衣',76,3,1,0,NULL,NULL,0),(655,'马甲',76,3,1,0,NULL,NULL,0),(656,'连衣裙',76,3,1,0,NULL,NULL,0),(657,'半身裙',76,3,1,0,NULL,NULL,0),(658,'牛仔裤',76,3,1,0,NULL,NULL,0),(659,'休闲裤',76,3,1,0,NULL,NULL,0),(660,'打底裤',76,3,1,0,NULL,NULL,0),(661,'正装裤',76,3,1,0,NULL,NULL,0),(662,'小西装',76,3,1,0,NULL,NULL,0),(663,'短外套',76,3,1,0,NULL,NULL,0),(664,'风衣',76,3,1,0,NULL,NULL,0),(665,'毛呢大衣',76,3,1,0,NULL,NULL,0),(666,'真皮皮衣',76,3,1,0,NULL,NULL,0),(667,'棉服',76,3,1,0,NULL,NULL,0),(668,'羽绒服',76,3,1,0,NULL,NULL,0),(669,'大码女装',76,3,1,0,NULL,NULL,0),(670,'中老年女装',76,3,1,0,NULL,NULL,0),(671,'婚纱',76,3,1,0,NULL,NULL,0),(672,'打底衫',76,3,1,0,NULL,NULL,0),(673,'旗袍/唐装',76,3,1,0,NULL,NULL,0),(674,'加绒裤',76,3,1,0,NULL,NULL,0),(675,'吊带/背心',76,3,1,0,NULL,NULL,0),(676,'羊绒衫',76,3,1,0,NULL,NULL,0),(677,'短裤',76,3,1,0,NULL,NULL,0),(678,'皮草',76,3,1,0,NULL,NULL,0),(679,'礼服',76,3,1,0,NULL,NULL,0),(680,'仿皮皮衣',76,3,1,0,NULL,NULL,0),(681,'羊毛衫',76,3,1,0,NULL,NULL,0),(682,'设计师/潮牌',76,3,1,0,NULL,NULL,0),(683,'衬衫',77,3,1,0,NULL,NULL,0),(684,'T恤',77,3,1,0,NULL,NULL,0),(685,'POLO衫',77,3,1,0,NULL,NULL,0),(686,'针织衫',77,3,1,0,NULL,NULL,0),(687,'羊绒衫',77,3,1,0,NULL,NULL,0),(688,'卫衣',77,3,1,0,NULL,NULL,0),(689,'马甲/背心',77,3,1,0,NULL,NULL,0),(690,'夹克',77,3,1,0,NULL,NULL,0),(691,'风衣',77,3,1,0,NULL,NULL,0),(692,'毛呢大衣',77,3,1,0,NULL,NULL,0),(693,'仿皮皮衣',77,3,1,0,NULL,NULL,0),(694,'西服',77,3,1,0,NULL,NULL,0),(695,'棉服',77,3,1,0,NULL,NULL,0),(696,'羽绒服',77,3,1,0,NULL,NULL,0),(697,'牛仔裤',77,3,1,0,NULL,NULL,0),(698,'休闲裤',77,3,1,0,NULL,NULL,0),(699,'西裤',77,3,1,0,NULL,NULL,0),(700,'西服套装',77,3,1,0,NULL,NULL,0),(701,'大码男装',77,3,1,0,NULL,NULL,0),(702,'中老年男装',77,3,1,0,NULL,NULL,0),(703,'唐装/中山装',77,3,1,0,NULL,NULL,0),(704,'工装',77,3,1,0,NULL,NULL,0),(705,'真皮皮衣',77,3,1,0,NULL,NULL,0),(706,'加绒裤',77,3,1,0,NULL,NULL,0),(707,'卫裤/运动裤',77,3,1,0,NULL,NULL,0),(708,'短裤',77,3,1,0,NULL,NULL,0),(709,'设计师/潮牌',77,3,1,0,NULL,NULL,0),(710,'羊毛衫',77,3,1,0,NULL,NULL,0),(711,'文胸',78,3,1,0,NULL,NULL,0),(712,'女式内裤',78,3,1,0,NULL,NULL,0),(713,'男式内裤',78,3,1,0,NULL,NULL,0),(714,'睡衣/家居服',78,3,1,0,NULL,NULL,0),(715,'塑身美体',78,3,1,0,NULL,NULL,0),(716,'泳衣',78,3,1,0,NULL,NULL,0),(717,'吊带/背心',78,3,1,0,NULL,NULL,0),(718,'抹胸',78,3,1,0,NULL,NULL,0),(719,'连裤袜/丝袜',78,3,1,0,NULL,NULL,0),(720,'美腿袜',78,3,1,0,NULL,NULL,0),(721,'商务男袜',78,3,1,0,NULL,NULL,0),(722,'保暖内衣',78,3,1,0,NULL,NULL,0),(723,'情侣睡衣',78,3,1,0,NULL,NULL,0),(724,'文胸套装',78,3,1,0,NULL,NULL,0),(725,'少女文胸',78,3,1,0,NULL,NULL,0),(726,'休闲棉袜',78,3,1,0,NULL,NULL,0),(727,'大码内衣',78,3,1,0,NULL,NULL,0),(728,'内衣配件',78,3,1,0,NULL,NULL,0),(729,'打底裤袜',78,3,1,0,NULL,NULL,0),(730,'打底衫',78,3,1,0,NULL,NULL,0),(731,'秋衣秋裤',78,3,1,0,NULL,NULL,0),(732,'情趣内衣',78,3,1,0,NULL,NULL,0),(733,'服装洗护',79,3,1,0,NULL,NULL,0),(734,'太阳镜',80,3,1,0,NULL,NULL,0),(735,'光学镜架/镜片',80,3,1,0,NULL,NULL,0),(736,'围巾/手套/帽子套装',80,3,1,0,NULL,NULL,0),(737,'袖扣',80,3,1,0,NULL,NULL,0),(738,'棒球帽',80,3,1,0,NULL,NULL,0),(739,'毛线帽',80,3,1,0,NULL,NULL,0),(740,'遮阳帽',80,3,1,0,NULL,NULL,0),(741,'老花镜',80,3,1,0,NULL,NULL,0),(742,'装饰眼镜',80,3,1,0,NULL,NULL,0),(743,'防辐射眼镜',80,3,1,0,NULL,NULL,0),(744,'游泳镜',80,3,1,0,NULL,NULL,0),(745,'女士丝巾/围巾/披肩',80,3,1,0,NULL,NULL,0),(746,'男士丝巾/围巾',80,3,1,0,NULL,NULL,0),(747,'鸭舌帽',80,3,1,0,NULL,NULL,0),(748,'贝雷帽',80,3,1,0,NULL,NULL,0),(749,'礼帽',80,3,1,0,NULL,NULL,0),(750,'真皮手套',80,3,1,0,NULL,NULL,0),(751,'毛线手套',80,3,1,0,NULL,NULL,0),(752,'防晒手套',80,3,1,0,NULL,NULL,0),(753,'男士腰带/礼盒',80,3,1,0,NULL,NULL,0),(754,'女士腰带/礼盒',80,3,1,0,NULL,NULL,0),(755,'钥匙扣',80,3,1,0,NULL,NULL,0),(756,'遮阳伞/雨伞',80,3,1,0,NULL,NULL,0),(757,'口罩',80,3,1,0,NULL,NULL,0),(758,'耳罩/耳包',80,3,1,0,NULL,NULL,0),(759,'假领',80,3,1,0,NULL,NULL,0),(760,'毛线/布面料',80,3,1,0,NULL,NULL,0),(761,'领带/领结/领带夹',80,3,1,0,NULL,NULL,0),(762,'男表',81,3,1,0,NULL,NULL,0),(763,'瑞表',81,3,1,0,NULL,NULL,0),(764,'女表',81,3,1,0,NULL,NULL,0),(765,'国表',81,3,1,0,NULL,NULL,0),(766,'日韩表',81,3,1,0,NULL,NULL,0),(767,'欧美表',81,3,1,0,NULL,NULL,0),(768,'德表',81,3,1,0,NULL,NULL,0),(769,'儿童手表',81,3,1,0,NULL,NULL,0),(770,'智能手表',81,3,1,0,NULL,NULL,0),(771,'闹钟',81,3,1,0,NULL,NULL,0),(772,'座钟挂钟',81,3,1,0,NULL,NULL,0),(773,'钟表配件',81,3,1,0,NULL,NULL,0),(774,'商务休闲鞋',82,3,1,0,NULL,NULL,0),(775,'正装鞋',82,3,1,0,NULL,NULL,0),(776,'休闲鞋',82,3,1,0,NULL,NULL,0),(777,'凉鞋/沙滩鞋',82,3,1,0,NULL,NULL,0),(778,'男靴',82,3,1,0,NULL,NULL,0),(779,'功能鞋',82,3,1,0,NULL,NULL,0),(780,'拖鞋/人字拖',82,3,1,0,NULL,NULL,0),(781,'雨鞋/雨靴',82,3,1,0,NULL,NULL,0),(782,'传统布鞋',82,3,1,0,NULL,NULL,0),(783,'鞋配件',82,3,1,0,NULL,NULL,0),(784,'帆布鞋',82,3,1,0,NULL,NULL,0),(785,'增高鞋',82,3,1,0,NULL,NULL,0),(786,'工装鞋',82,3,1,0,NULL,NULL,0),(787,'定制鞋',82,3,1,0,NULL,NULL,0),(788,'高跟鞋',83,3,1,0,NULL,NULL,0),(789,'单鞋',83,3,1,0,NULL,NULL,0),(790,'休闲鞋',83,3,1,0,NULL,NULL,0),(791,'凉鞋',83,3,1,0,NULL,NULL,0),(792,'女靴',83,3,1,0,NULL,NULL,0),(793,'雪地靴',83,3,1,0,NULL,NULL,0),(794,'拖鞋/人字拖',83,3,1,0,NULL,NULL,0),(795,'踝靴',83,3,1,0,NULL,NULL,0),(796,'筒靴',83,3,1,0,NULL,NULL,0),(797,'帆布鞋',83,3,1,0,NULL,NULL,0),(798,'雨鞋/雨靴',83,3,1,0,NULL,NULL,0),(799,'妈妈鞋',83,3,1,0,NULL,NULL,0),(800,'鞋配件',83,3,1,0,NULL,NULL,0),(801,'特色鞋',83,3,1,0,NULL,NULL,0),(802,'鱼嘴鞋',83,3,1,0,NULL,NULL,0),(803,'布鞋/绣花鞋',83,3,1,0,NULL,NULL,0),(804,'马丁靴',83,3,1,0,NULL,NULL,0),(805,'坡跟鞋',83,3,1,0,NULL,NULL,0),(806,'松糕鞋',83,3,1,0,NULL,NULL,0),(807,'内增高',83,3,1,0,NULL,NULL,0),(808,'防水台',83,3,1,0,NULL,NULL,0),(809,'婴幼奶粉',84,3,1,0,NULL,NULL,0),(810,'孕妈奶粉',84,3,1,0,NULL,NULL,0),(811,'益生菌/初乳',85,3,1,0,NULL,NULL,0),(812,'米粉/菜粉',85,3,1,0,NULL,NULL,0),(813,'果泥/果汁',85,3,1,0,NULL,NULL,0),(814,'DHA',85,3,1,0,NULL,NULL,0),(815,'宝宝零食',85,3,1,0,NULL,NULL,0),(816,'钙铁锌/维生素',85,3,1,0,NULL,NULL,0),(817,'清火/开胃',85,3,1,0,NULL,NULL,0),(818,'面条/粥',85,3,1,0,NULL,NULL,0),(819,'婴儿尿裤',86,3,1,0,NULL,NULL,0),(820,'拉拉裤',86,3,1,0,NULL,NULL,0),(821,'婴儿湿巾',86,3,1,0,NULL,NULL,0),(822,'成人尿裤',86,3,1,0,NULL,NULL,0),(823,'奶瓶奶嘴',87,3,1,0,NULL,NULL,0),(824,'吸奶器',87,3,1,0,NULL,NULL,0),(825,'暖奶消毒',87,3,1,0,NULL,NULL,0),(826,'儿童餐具',87,3,1,0,NULL,NULL,0),(827,'水壶/水杯',87,3,1,0,NULL,NULL,0),(828,'牙胶安抚',87,3,1,0,NULL,NULL,0),(829,'围兜/防溅衣',87,3,1,0,NULL,NULL,0),(830,'辅食料理机',87,3,1,0,NULL,NULL,0),(831,'食物存储',87,3,1,0,NULL,NULL,0),(832,'宝宝护肤',88,3,1,0,NULL,NULL,0),(833,'洗发沐浴',88,3,1,0,NULL,NULL,0),(834,'奶瓶清洗',88,3,1,0,NULL,NULL,0),(835,'驱蚊防晒',88,3,1,0,NULL,NULL,0),(836,'理发器',88,3,1,0,NULL,NULL,0),(837,'洗澡用具',88,3,1,0,NULL,NULL,0),(838,'婴儿口腔清洁',88,3,1,0,NULL,NULL,0),(839,'洗衣液/皂',88,3,1,0,NULL,NULL,0),(840,'日常护理',88,3,1,0,NULL,NULL,0),(841,'座便器',88,3,1,0,NULL,NULL,0),(842,'婴儿推车',89,3,1,0,NULL,NULL,0),(843,'餐椅摇椅',89,3,1,0,NULL,NULL,0),(844,'婴儿床',89,3,1,0,NULL,NULL,0),(845,'学步车',89,3,1,0,NULL,NULL,0),(846,'三轮车',89,3,1,0,NULL,NULL,0),(847,'自行车',89,3,1,0,NULL,NULL,0),(848,'电动车',89,3,1,0,NULL,NULL,0),(849,'扭扭车',89,3,1,0,NULL,NULL,0),(850,'滑板车',89,3,1,0,NULL,NULL,0),(851,'婴儿床垫',89,3,1,0,NULL,NULL,0),(852,'婴儿外出服',90,3,1,0,NULL,NULL,0),(853,'婴儿内衣',90,3,1,0,NULL,NULL,0),(854,'婴儿礼盒',90,3,1,0,NULL,NULL,0),(855,'婴儿鞋帽袜',90,3,1,0,NULL,NULL,0),(856,'安全防护',90,3,1,0,NULL,NULL,0),(857,'家居床品',90,3,1,0,NULL,NULL,0),(858,'睡袋/抱被',90,3,1,0,NULL,NULL,0),(859,'爬行垫',90,3,1,0,NULL,NULL,0),(860,'妈咪包/背婴带',91,3,1,0,NULL,NULL,0),(861,'产后塑身',91,3,1,0,NULL,NULL,0),(862,'文胸/内裤',91,3,1,0,NULL,NULL,0),(863,'防辐射服',91,3,1,0,NULL,NULL,0),(864,'孕妈装',91,3,1,0,NULL,NULL,0),(865,'孕期营养',91,3,1,0,NULL,NULL,0),(866,'孕妇护肤',91,3,1,0,NULL,NULL,0),(867,'待产护理',91,3,1,0,NULL,NULL,0),(868,'月子装',91,3,1,0,NULL,NULL,0),(869,'防溢乳垫',91,3,1,0,NULL,NULL,0),(870,'套装',92,3,1,0,NULL,NULL,0),(871,'上衣',92,3,1,0,NULL,NULL,0),(872,'裤子',92,3,1,0,NULL,NULL,0),(873,'裙子',92,3,1,0,NULL,NULL,0),(874,'内衣/家居服',92,3,1,0,NULL,NULL,0),(875,'羽绒服/棉服',92,3,1,0,NULL,NULL,0),(876,'亲子装',92,3,1,0,NULL,NULL,0),(877,'儿童配饰',92,3,1,0,NULL,NULL,0),(878,'礼服/演出服',92,3,1,0,NULL,NULL,0),(879,'运动鞋',92,3,1,0,NULL,NULL,0),(880,'皮鞋/帆布鞋',92,3,1,0,NULL,NULL,0),(881,'靴子',92,3,1,0,NULL,NULL,0),(882,'凉鞋',92,3,1,0,NULL,NULL,0),(883,'功能鞋',92,3,1,0,NULL,NULL,0),(884,'户外/运动服',92,3,1,0,NULL,NULL,0),(885,'提篮式',93,3,1,0,NULL,NULL,0),(886,'安全座椅',93,3,1,0,NULL,NULL,0),(887,'增高垫',93,3,1,0,NULL,NULL,0),(888,'钱包',94,3,1,0,NULL,NULL,0),(889,'手拿包',94,3,1,0,NULL,NULL,0),(890,'单肩包',94,3,1,0,NULL,NULL,0),(891,'双肩包',94,3,1,0,NULL,NULL,0),(892,'手提包',94,3,1,0,NULL,NULL,0),(893,'斜挎包',94,3,1,0,NULL,NULL,0),(894,'钥匙包',94,3,1,0,NULL,NULL,0),(895,'卡包/零钱包',94,3,1,0,NULL,NULL,0),(896,'男士钱包',95,3,1,0,NULL,NULL,0),(897,'男士手包',95,3,1,0,NULL,NULL,0),(898,'卡包名片夹',95,3,1,0,NULL,NULL,0),(899,'商务公文包',95,3,1,0,NULL,NULL,0),(900,'双肩包',95,3,1,0,NULL,NULL,0),(901,'单肩/斜挎包',95,3,1,0,NULL,NULL,0),(902,'钥匙包',95,3,1,0,NULL,NULL,0),(903,'电脑包',96,3,1,0,NULL,NULL,0),(904,'拉杆箱',96,3,1,0,NULL,NULL,0),(905,'旅行包',96,3,1,0,NULL,NULL,0),(906,'旅行配件',96,3,1,0,NULL,NULL,0),(907,'休闲运动包',96,3,1,0,NULL,NULL,0),(908,'拉杆包',96,3,1,0,NULL,NULL,0),(909,'登山包',96,3,1,0,NULL,NULL,0),(910,'妈咪包',96,3,1,0,NULL,NULL,0),(911,'书包',96,3,1,0,NULL,NULL,0),(912,'相机包',96,3,1,0,NULL,NULL,0),(913,'腰包/胸包',96,3,1,0,NULL,NULL,0),(914,'火机烟具',97,3,1,0,NULL,NULL,0),(915,'礼品文具',97,3,1,0,NULL,NULL,0),(916,'军刀军具',97,3,1,0,NULL,NULL,0),(917,'收藏品',97,3,1,0,NULL,NULL,0),(918,'工艺礼品',97,3,1,0,NULL,NULL,0),(919,'创意礼品',97,3,1,0,NULL,NULL,0),(920,'礼盒礼券',97,3,1,0,NULL,NULL,0),(921,'鲜花绿植',97,3,1,0,NULL,NULL,0),(922,'婚庆节庆',97,3,1,0,NULL,NULL,0),(923,'京东卡',97,3,1,0,NULL,NULL,0),(924,'美妆礼品',97,3,1,0,NULL,NULL,0),(925,'礼品定制',97,3,1,0,NULL,NULL,0),(926,'京东福卡',97,3,1,0,NULL,NULL,0),(927,'古董文玩',97,3,1,0,NULL,NULL,0),(928,'箱包',98,3,1,0,NULL,NULL,0),(929,'钱包',98,3,1,0,NULL,NULL,0),(930,'服饰',98,3,1,0,NULL,NULL,0),(931,'腰带',98,3,1,0,NULL,NULL,0),(932,'太阳镜/眼镜框',98,3,1,0,NULL,NULL,0),(933,'配件',98,3,1,0,NULL,NULL,0),(934,'鞋靴',98,3,1,0,NULL,NULL,0),(935,'饰品',98,3,1,0,NULL,NULL,0),(936,'名品腕表',98,3,1,0,NULL,NULL,0),(937,'高档化妆品',98,3,1,0,NULL,NULL,0),(938,'婚嫁首饰',99,3,1,0,NULL,NULL,0),(939,'婚纱摄影',99,3,1,0,NULL,NULL,0),(940,'婚纱礼服',99,3,1,0,NULL,NULL,0),(941,'婚庆服务',99,3,1,0,NULL,NULL,0),(942,'婚庆礼品/用品',99,3,1,0,NULL,NULL,0),(943,'婚宴',99,3,1,0,NULL,NULL,0),(944,'饼干蛋糕',100,3,1,0,NULL,NULL,0),(945,'糖果/巧克力',100,3,1,0,NULL,NULL,0),(946,'休闲零食',100,3,1,0,NULL,NULL,0),(947,'冲调饮品',100,3,1,0,NULL,NULL,0),(948,'粮油调味',100,3,1,0,NULL,NULL,0),(949,'牛奶',100,3,1,0,NULL,NULL,0),(950,'其他特产',101,3,1,0,NULL,NULL,0),(951,'新疆',101,3,1,0,NULL,NULL,0),(952,'北京',101,3,1,0,NULL,NULL,0),(953,'山西',101,3,1,0,NULL,NULL,0),(954,'内蒙古',101,3,1,0,NULL,NULL,0),(955,'福建',101,3,1,0,NULL,NULL,0),(956,'湖南',101,3,1,0,NULL,NULL,0),(957,'四川',101,3,1,0,NULL,NULL,0),(958,'云南',101,3,1,0,NULL,NULL,0),(959,'东北',101,3,1,0,NULL,NULL,0),(960,'休闲零食',102,3,1,0,NULL,NULL,0),(961,'坚果炒货',102,3,1,0,NULL,NULL,0),(962,'肉干肉脯',102,3,1,0,NULL,NULL,0),(963,'蜜饯果干',102,3,1,0,NULL,NULL,0),(964,'糖果/巧克力',102,3,1,0,NULL,NULL,0),(965,'饼干蛋糕',102,3,1,0,NULL,NULL,0),(966,'无糖食品',102,3,1,0,NULL,NULL,0),(967,'米面杂粮',103,3,1,0,NULL,NULL,0),(968,'食用油',103,3,1,0,NULL,NULL,0),(969,'调味品',103,3,1,0,NULL,NULL,0),(970,'南北干货',103,3,1,0,NULL,NULL,0),(971,'方便食品',103,3,1,0,NULL,NULL,0),(972,'有机食品',103,3,1,0,NULL,NULL,0),(973,'饮用水',104,3,1,0,NULL,NULL,0),(974,'饮料',104,3,1,0,NULL,NULL,0),(975,'牛奶乳品',104,3,1,0,NULL,NULL,0),(976,'咖啡/奶茶',104,3,1,0,NULL,NULL,0),(977,'冲饮谷物',104,3,1,0,NULL,NULL,0),(978,'蜂蜜/柚子茶',104,3,1,0,NULL,NULL,0),(979,'成人奶粉',104,3,1,0,NULL,NULL,0),(980,'月饼',105,3,1,0,NULL,NULL,0),(981,'大闸蟹',105,3,1,0,NULL,NULL,0),(982,'粽子',105,3,1,0,NULL,NULL,0),(983,'卡券',105,3,1,0,NULL,NULL,0),(984,'铁观音',106,3,1,0,NULL,NULL,0),(985,'普洱',106,3,1,0,NULL,NULL,0),(986,'龙井',106,3,1,0,NULL,NULL,0),(987,'绿茶',106,3,1,0,NULL,NULL,0),(988,'红茶',106,3,1,0,NULL,NULL,0),(989,'乌龙茶',106,3,1,0,NULL,NULL,0),(990,'花草茶',106,3,1,0,NULL,NULL,0),(991,'花果茶',106,3,1,0,NULL,NULL,0),(992,'养生茶',106,3,1,0,NULL,NULL,0),(993,'黑茶',106,3,1,0,NULL,NULL,0),(994,'白茶',106,3,1,0,NULL,NULL,0),(995,'其它茶',106,3,1,0,NULL,NULL,0),(996,'项链',107,3,1,0,NULL,NULL,0),(997,'手链/脚链',107,3,1,0,NULL,NULL,0),(998,'戒指',107,3,1,0,NULL,NULL,0),(999,'耳饰',107,3,1,0,NULL,NULL,0),(1000,'毛衣链',107,3,1,0,NULL,NULL,0),(1001,'发饰/发卡',107,3,1,0,NULL,NULL,0),(1002,'胸针',107,3,1,0,NULL,NULL,0),(1003,'饰品配件',107,3,1,0,NULL,NULL,0),(1004,'婚庆饰品',107,3,1,0,NULL,NULL,0),(1005,'黄金吊坠',108,3,1,0,NULL,NULL,0),(1006,'黄金项链',108,3,1,0,NULL,NULL,0),(1007,'黄金转运珠',108,3,1,0,NULL,NULL,0),(1008,'黄金手镯/手链/脚链',108,3,1,0,NULL,NULL,0),(1009,'黄金耳饰',108,3,1,0,NULL,NULL,0),(1010,'黄金戒指',108,3,1,0,NULL,NULL,0),(1011,'K金吊坠',109,3,1,0,NULL,NULL,0),(1012,'K金项链',109,3,1,0,NULL,NULL,0),(1013,'K金手镯/手链/脚链',109,3,1,0,NULL,NULL,0),(1014,'K金戒指',109,3,1,0,NULL,NULL,0),(1015,'K金耳饰',109,3,1,0,NULL,NULL,0),(1016,'投资金',110,3,1,0,NULL,NULL,0),(1017,'投资银',110,3,1,0,NULL,NULL,0),(1018,'投资收藏',110,3,1,0,NULL,NULL,0),(1019,'银吊坠/项链',111,3,1,0,NULL,NULL,0),(1020,'银手镯/手链/脚链',111,3,1,0,NULL,NULL,0),(1021,'银戒指',111,3,1,0,NULL,NULL,0),(1022,'银耳饰',111,3,1,0,NULL,NULL,0),(1023,'足银手镯',111,3,1,0,NULL,NULL,0),(1024,'宝宝银饰',111,3,1,0,NULL,NULL,0),(1025,'裸钻',112,3,1,0,NULL,NULL,0),(1026,'钻戒',112,3,1,0,NULL,NULL,0),(1027,'钻石项链/吊坠',112,3,1,0,NULL,NULL,0),(1028,'钻石耳饰',112,3,1,0,NULL,NULL,0),(1029,'钻石手镯/手链',112,3,1,0,NULL,NULL,0),(1030,'项链/吊坠',113,3,1,0,NULL,NULL,0),(1031,'手镯/手串',113,3,1,0,NULL,NULL,0),(1032,'戒指',113,3,1,0,NULL,NULL,0),(1033,'耳饰',113,3,1,0,NULL,NULL,0),(1034,'挂件/摆件/把件',113,3,1,0,NULL,NULL,0),(1035,'玉石孤品',113,3,1,0,NULL,NULL,0),(1036,'项链/吊坠',114,3,1,0,NULL,NULL,0),(1037,'耳饰',114,3,1,0,NULL,NULL,0),(1038,'手镯/手链/脚链',114,3,1,0,NULL,NULL,0),(1039,'戒指',114,3,1,0,NULL,NULL,0),(1040,'头饰/胸针',114,3,1,0,NULL,NULL,0),(1041,'摆件/挂件',114,3,1,0,NULL,NULL,0),(1042,'琥珀/蜜蜡',115,3,1,0,NULL,NULL,0),(1043,'碧玺',115,3,1,0,NULL,NULL,0),(1044,'红宝石/蓝宝石',115,3,1,0,NULL,NULL,0),(1045,'坦桑石',115,3,1,0,NULL,NULL,0),(1046,'珊瑚',115,3,1,0,NULL,NULL,0),(1047,'祖母绿',115,3,1,0,NULL,NULL,0),(1048,'葡萄石',115,3,1,0,NULL,NULL,0),(1049,'其他天然宝石',115,3,1,0,NULL,NULL,0),(1050,'项链/吊坠',115,3,1,0,NULL,NULL,0),(1051,'耳饰',115,3,1,0,NULL,NULL,0),(1052,'手镯/手链',115,3,1,0,NULL,NULL,0),(1053,'戒指',115,3,1,0,NULL,NULL,0),(1054,'铂金项链/吊坠',116,3,1,0,NULL,NULL,0),(1055,'铂金手镯/手链/脚链',116,3,1,0,NULL,NULL,0),(1056,'铂金戒指',116,3,1,0,NULL,NULL,0),(1057,'铂金耳饰',116,3,1,0,NULL,NULL,0),(1058,'小叶紫檀',117,3,1,0,NULL,NULL,0),(1059,'黄花梨',117,3,1,0,NULL,NULL,0),(1060,'沉香木',117,3,1,0,NULL,NULL,0),(1061,'金丝楠',117,3,1,0,NULL,NULL,0),(1062,'菩提',117,3,1,0,NULL,NULL,0),(1063,'其他',117,3,1,0,NULL,NULL,0),(1064,'橄榄核/核桃',117,3,1,0,NULL,NULL,0),(1065,'檀香',117,3,1,0,NULL,NULL,0),(1066,'珍珠项链',118,3,1,0,NULL,NULL,0),(1067,'珍珠吊坠',118,3,1,0,NULL,NULL,0),(1068,'珍珠耳饰',118,3,1,0,NULL,NULL,0),(1069,'珍珠手链',118,3,1,0,NULL,NULL,0),(1070,'珍珠戒指',118,3,1,0,NULL,NULL,0),(1071,'珍珠胸针',118,3,1,0,NULL,NULL,0),(1072,'机油',119,3,1,0,NULL,NULL,0),(1073,'正时皮带',119,3,1,0,NULL,NULL,0),(1074,'添加剂',119,3,1,0,NULL,NULL,0),(1075,'汽车喇叭',119,3,1,0,NULL,NULL,0),(1076,'防冻液',119,3,1,0,NULL,NULL,0),(1077,'汽车玻璃',119,3,1,0,NULL,NULL,0),(1078,'滤清器',119,3,1,0,NULL,NULL,0),(1079,'火花塞',119,3,1,0,NULL,NULL,0),(1080,'减震器',119,3,1,0,NULL,NULL,0),(1081,'柴机油/辅助油',119,3,1,0,NULL,NULL,0),(1082,'雨刷',119,3,1,0,NULL,NULL,0),(1083,'车灯',119,3,1,0,NULL,NULL,0),(1084,'后视镜',119,3,1,0,NULL,NULL,0),(1085,'轮胎',119,3,1,0,NULL,NULL,0),(1086,'轮毂',119,3,1,0,NULL,NULL,0),(1087,'刹车片/盘',119,3,1,0,NULL,NULL,0),(1088,'维修配件',119,3,1,0,NULL,NULL,0),(1089,'蓄电池',119,3,1,0,NULL,NULL,0),(1090,'底盘装甲/护板',119,3,1,0,NULL,NULL,0),(1091,'贴膜',119,3,1,0,NULL,NULL,0),(1092,'汽修工具',119,3,1,0,NULL,NULL,0),(1093,'改装配件',119,3,1,0,NULL,NULL,0),(1094,'导航仪',120,3,1,0,NULL,NULL,0),(1095,'安全预警仪',120,3,1,0,NULL,NULL,0),(1096,'行车记录仪',120,3,1,0,NULL,NULL,0),(1097,'倒车雷达',120,3,1,0,NULL,NULL,0),(1098,'蓝牙设备',120,3,1,0,NULL,NULL,0),(1099,'车载影音',120,3,1,0,NULL,NULL,0),(1100,'净化器',120,3,1,0,NULL,NULL,0),(1101,'电源',120,3,1,0,NULL,NULL,0),(1102,'智能驾驶',120,3,1,0,NULL,NULL,0),(1103,'车载电台',120,3,1,0,NULL,NULL,0),(1104,'车载电器配件',120,3,1,0,NULL,NULL,0),(1105,'吸尘器',120,3,1,0,NULL,NULL,0),(1106,'智能车机',120,3,1,0,NULL,NULL,0),(1107,'冰箱',120,3,1,0,NULL,NULL,0),(1108,'汽车音响',120,3,1,0,NULL,NULL,0),(1109,'车载生活电器',120,3,1,0,NULL,NULL,0),(1110,'车蜡',121,3,1,0,NULL,NULL,0),(1111,'补漆笔',121,3,1,0,NULL,NULL,0),(1112,'玻璃水',121,3,1,0,NULL,NULL,0),(1113,'清洁剂',121,3,1,0,NULL,NULL,0),(1114,'洗车工具',121,3,1,0,NULL,NULL,0),(1115,'镀晶镀膜',121,3,1,0,NULL,NULL,0),(1116,'打蜡机',121,3,1,0,NULL,NULL,0),(1117,'洗车配件',121,3,1,0,NULL,NULL,0),(1118,'洗车机',121,3,1,0,NULL,NULL,0),(1119,'洗车水枪',121,3,1,0,NULL,NULL,0),(1120,'毛巾掸子',121,3,1,0,NULL,NULL,0),(1121,'脚垫',122,3,1,0,NULL,NULL,0),(1122,'座垫',122,3,1,0,NULL,NULL,0),(1123,'座套',122,3,1,0,NULL,NULL,0),(1124,'后备箱垫',122,3,1,0,NULL,NULL,0),(1125,'头枕腰靠',122,3,1,0,NULL,NULL,0),(1126,'方向盘套',122,3,1,0,NULL,NULL,0),(1127,'香水',122,3,1,0,NULL,NULL,0),(1128,'空气净化',122,3,1,0,NULL,NULL,0),(1129,'挂件摆件',122,3,1,0,NULL,NULL,0),(1130,'功能小件',122,3,1,0,NULL,NULL,0),(1131,'车身装饰件',122,3,1,0,NULL,NULL,0),(1132,'车衣',122,3,1,0,NULL,NULL,0),(1133,'安全座椅',123,3,1,0,NULL,NULL,0),(1134,'胎压监测',123,3,1,0,NULL,NULL,0),(1135,'防盗设备',123,3,1,0,NULL,NULL,0),(1136,'应急救援',123,3,1,0,NULL,NULL,0),(1137,'保温箱',123,3,1,0,NULL,NULL,0),(1138,'地锁',123,3,1,0,NULL,NULL,0),(1139,'摩托车',123,3,1,0,NULL,NULL,0),(1140,'充气泵',123,3,1,0,NULL,NULL,0),(1141,'储物箱',123,3,1,0,NULL,NULL,0),(1142,'自驾野营',123,3,1,0,NULL,NULL,0),(1143,'摩托车装备',123,3,1,0,NULL,NULL,0),(1144,'清洗美容',124,3,1,0,NULL,NULL,0),(1145,'功能升级',124,3,1,0,NULL,NULL,0),(1146,'保养维修',124,3,1,0,NULL,NULL,0),(1147,'油卡充值',124,3,1,0,NULL,NULL,0),(1148,'车险',124,3,1,0,NULL,NULL,0),(1149,'加油卡',124,3,1,0,NULL,NULL,0),(1150,'ETC',124,3,1,0,NULL,NULL,0),(1151,'驾驶培训',124,3,1,0,NULL,NULL,0),(1152,'赛事服装',125,3,1,0,NULL,NULL,0),(1153,'赛事用品',125,3,1,0,NULL,NULL,0),(1154,'制动系统',125,3,1,0,NULL,NULL,0),(1155,'悬挂系统',125,3,1,0,NULL,NULL,0),(1156,'进气系统',125,3,1,0,NULL,NULL,0),(1157,'排气系统',125,3,1,0,NULL,NULL,0),(1158,'电子管理',125,3,1,0,NULL,NULL,0),(1159,'车身强化',125,3,1,0,NULL,NULL,0),(1160,'赛事座椅',125,3,1,0,NULL,NULL,0),(1161,'跑步鞋',126,3,1,0,NULL,NULL,0),(1162,'休闲鞋',126,3,1,0,NULL,NULL,0),(1163,'篮球鞋',126,3,1,0,NULL,NULL,0),(1164,'板鞋',126,3,1,0,NULL,NULL,0),(1165,'帆布鞋',126,3,1,0,NULL,NULL,0),(1166,'足球鞋',126,3,1,0,NULL,NULL,0),(1167,'乒羽网鞋',126,3,1,0,NULL,NULL,0),(1168,'专项运动鞋',126,3,1,0,NULL,NULL,0),(1169,'训练鞋',126,3,1,0,NULL,NULL,0),(1170,'拖鞋',126,3,1,0,NULL,NULL,0),(1171,'运动包',126,3,1,0,NULL,NULL,0),(1172,'羽绒服',127,3,1,0,NULL,NULL,0),(1173,'棉服',127,3,1,0,NULL,NULL,0),(1174,'运动裤',127,3,1,0,NULL,NULL,0),(1175,'夹克/风衣',127,3,1,0,NULL,NULL,0),(1176,'卫衣/套头衫',127,3,1,0,NULL,NULL,0),(1177,'T恤',127,3,1,0,NULL,NULL,0),(1178,'套装',127,3,1,0,NULL,NULL,0),(1179,'乒羽网服',127,3,1,0,NULL,NULL,0),(1180,'健身服',127,3,1,0,NULL,NULL,0),(1181,'运动背心',127,3,1,0,NULL,NULL,0),(1182,'毛衫/线衫',127,3,1,0,NULL,NULL,0),(1183,'运动配饰',127,3,1,0,NULL,NULL,0),(1184,'折叠车',128,3,1,0,NULL,NULL,0),(1185,'山地车/公路车',128,3,1,0,NULL,NULL,0),(1186,'电动车',128,3,1,0,NULL,NULL,0),(1187,'其他整车',128,3,1,0,NULL,NULL,0),(1188,'骑行服',128,3,1,0,NULL,NULL,0),(1189,'骑行装备',128,3,1,0,NULL,NULL,0),(1190,'平衡车',128,3,1,0,NULL,NULL,0),(1191,'鱼竿鱼线',129,3,1,0,NULL,NULL,0),(1192,'浮漂鱼饵',129,3,1,0,NULL,NULL,0),(1193,'钓鱼桌椅',129,3,1,0,NULL,NULL,0),(1194,'钓鱼配件',129,3,1,0,NULL,NULL,0),(1195,'钓箱鱼包',129,3,1,0,NULL,NULL,0),(1196,'其它',129,3,1,0,NULL,NULL,0),(1197,'泳镜',130,3,1,0,NULL,NULL,0),(1198,'泳帽',130,3,1,0,NULL,NULL,0),(1199,'游泳包防水包',130,3,1,0,NULL,NULL,0),(1200,'女士泳衣',130,3,1,0,NULL,NULL,0),(1201,'男士泳衣',130,3,1,0,NULL,NULL,0),(1202,'比基尼',130,3,1,0,NULL,NULL,0),(1203,'其它',130,3,1,0,NULL,NULL,0),(1204,'冲锋衣裤',131,3,1,0,NULL,NULL,0),(1205,'速干衣裤',131,3,1,0,NULL,NULL,0),(1206,'滑雪服',131,3,1,0,NULL,NULL,0),(1207,'羽绒服/棉服',131,3,1,0,NULL,NULL,0),(1208,'休闲衣裤',131,3,1,0,NULL,NULL,0),(1209,'抓绒衣裤',131,3,1,0,NULL,NULL,0),(1210,'软壳衣裤',131,3,1,0,NULL,NULL,0),(1211,'T恤',131,3,1,0,NULL,NULL,0),(1212,'户外风衣',131,3,1,0,NULL,NULL,0),(1213,'功能内衣',131,3,1,0,NULL,NULL,0),(1214,'军迷服饰',131,3,1,0,NULL,NULL,0),(1215,'登山鞋',131,3,1,0,NULL,NULL,0),(1216,'雪地靴',131,3,1,0,NULL,NULL,0),(1217,'徒步鞋',131,3,1,0,NULL,NULL,0),(1218,'越野跑鞋',131,3,1,0,NULL,NULL,0),(1219,'休闲鞋',131,3,1,0,NULL,NULL,0),(1220,'工装鞋',131,3,1,0,NULL,NULL,0),(1221,'溯溪鞋',131,3,1,0,NULL,NULL,0),(1222,'沙滩/凉拖',131,3,1,0,NULL,NULL,0),(1223,'户外袜',131,3,1,0,NULL,NULL,0),(1224,'帐篷/垫子',132,3,1,0,NULL,NULL,0),(1225,'睡袋/吊床',132,3,1,0,NULL,NULL,0),(1226,'登山攀岩',132,3,1,0,NULL,NULL,0),(1227,'户外配饰',132,3,1,0,NULL,NULL,0),(1228,'背包',132,3,1,0,NULL,NULL,0),(1229,'户外照明',132,3,1,0,NULL,NULL,0),(1230,'户外仪表',132,3,1,0,NULL,NULL,0),(1231,'户外工具',132,3,1,0,NULL,NULL,0),(1232,'望远镜',132,3,1,0,NULL,NULL,0),(1233,'旅游用品',132,3,1,0,NULL,NULL,0),(1234,'便携桌椅床',132,3,1,0,NULL,NULL,0),(1235,'野餐烧烤',132,3,1,0,NULL,NULL,0),(1236,'军迷用品',132,3,1,0,NULL,NULL,0),(1237,'救援装备',132,3,1,0,NULL,NULL,0),(1238,'滑雪装备',132,3,1,0,NULL,NULL,0),(1239,'极限户外',132,3,1,0,NULL,NULL,0),(1240,'冲浪潜水',132,3,1,0,NULL,NULL,0),(1241,'综合训练器',133,3,1,0,NULL,NULL,0),(1242,'其他大型器械',133,3,1,0,NULL,NULL,0),(1243,'哑铃',133,3,1,0,NULL,NULL,0),(1244,'仰卧板/收腹机',133,3,1,0,NULL,NULL,0),(1245,'其他中小型器材',133,3,1,0,NULL,NULL,0),(1246,'瑜伽舞蹈',133,3,1,0,NULL,NULL,0),(1247,'甩脂机',133,3,1,0,NULL,NULL,0),(1248,'踏步机',133,3,1,0,NULL,NULL,0),(1249,'武术搏击',133,3,1,0,NULL,NULL,0),(1250,'健身车/动感单车',133,3,1,0,NULL,NULL,0),(1251,'跑步机',133,3,1,0,NULL,NULL,0),(1252,'运动护具',133,3,1,0,NULL,NULL,0),(1253,'羽毛球',134,3,1,0,NULL,NULL,0),(1254,'乒乓球',134,3,1,0,NULL,NULL,0),(1255,'篮球',134,3,1,0,NULL,NULL,0),(1256,'足球',134,3,1,0,NULL,NULL,0),(1257,'网球',134,3,1,0,NULL,NULL,0),(1258,'排球',134,3,1,0,NULL,NULL,0),(1259,'高尔夫',134,3,1,0,NULL,NULL,0),(1260,'台球',134,3,1,0,NULL,NULL,0),(1261,'棋牌麻将',134,3,1,0,NULL,NULL,0),(1262,'轮滑滑板',134,3,1,0,NULL,NULL,0),(1263,'其他',134,3,1,0,NULL,NULL,0),(1264,'0-6个月',135,3,1,0,NULL,NULL,0),(1265,'6-12个月',135,3,1,0,NULL,NULL,0),(1266,'1-3岁',135,3,1,0,NULL,NULL,0),(1267,'3-6岁',135,3,1,0,NULL,NULL,0),(1268,'6-14岁',135,3,1,0,NULL,NULL,0),(1269,'14岁以上',135,3,1,0,NULL,NULL,0),(1270,'遥控车',136,3,1,0,NULL,NULL,0),(1271,'遥控飞机',136,3,1,0,NULL,NULL,0),(1272,'遥控船',136,3,1,0,NULL,NULL,0),(1273,'机器人',136,3,1,0,NULL,NULL,0),(1274,'轨道/助力',136,3,1,0,NULL,NULL,0),(1275,'毛绒/布艺',137,3,1,0,NULL,NULL,0),(1276,'靠垫/抱枕',137,3,1,0,NULL,NULL,0),(1277,'芭比娃娃',138,3,1,0,NULL,NULL,0),(1278,'卡通娃娃',138,3,1,0,NULL,NULL,0),(1279,'智能娃娃',138,3,1,0,NULL,NULL,0),(1280,'仿真模型',139,3,1,0,NULL,NULL,0),(1281,'拼插模型',139,3,1,0,NULL,NULL,0),(1282,'收藏爱好',139,3,1,0,NULL,NULL,0),(1283,'炫舞毯',140,3,1,0,NULL,NULL,0),(1284,'爬行垫/毯',140,3,1,0,NULL,NULL,0),(1285,'户外玩具',140,3,1,0,NULL,NULL,0),(1286,'戏水玩具',140,3,1,0,NULL,NULL,0),(1287,'电影周边',141,3,1,0,NULL,NULL,0),(1288,'卡通周边',141,3,1,0,NULL,NULL,0),(1289,'网游周边',141,3,1,0,NULL,NULL,0),(1290,'摇铃/床铃',142,3,1,0,NULL,NULL,0),(1291,'健身架',142,3,1,0,NULL,NULL,0),(1292,'早教启智',142,3,1,0,NULL,NULL,0),(1293,'拖拉玩具',142,3,1,0,NULL,NULL,0),(1294,'积木',143,3,1,0,NULL,NULL,0),(1295,'拼图',143,3,1,0,NULL,NULL,0),(1296,'磁力棒',143,3,1,0,NULL,NULL,0),(1297,'立体拼插',143,3,1,0,NULL,NULL,0),(1298,'手工彩泥',144,3,1,0,NULL,NULL,0),(1299,'绘画工具',144,3,1,0,NULL,NULL,0),(1300,'情景玩具',144,3,1,0,NULL,NULL,0),(1301,'减压玩具',145,3,1,0,NULL,NULL,0),(1302,'创意玩具',145,3,1,0,NULL,NULL,0),(1303,'钢琴',146,3,1,0,NULL,NULL,0),(1304,'电子琴/电钢琴',146,3,1,0,NULL,NULL,0),(1305,'吉他/尤克里里',146,3,1,0,NULL,NULL,0),(1306,'打击乐器',146,3,1,0,NULL,NULL,0),(1307,'西洋管弦',146,3,1,0,NULL,NULL,0),(1308,'民族管弦乐器',146,3,1,0,NULL,NULL,0),(1309,'乐器配件',146,3,1,0,NULL,NULL,0),(1310,'电脑音乐',146,3,1,0,NULL,NULL,0),(1311,'工艺礼品乐器',146,3,1,0,NULL,NULL,0),(1312,'口琴/口风琴/竖笛',146,3,1,0,NULL,NULL,0),(1313,'手风琴',146,3,1,0,NULL,NULL,0),(1314,'双色球',147,3,1,0,NULL,NULL,0),(1315,'大乐透',147,3,1,0,NULL,NULL,0),(1316,'福彩3D',147,3,1,0,NULL,NULL,0),(1317,'排列三',147,3,1,0,NULL,NULL,0),(1318,'排列五',147,3,1,0,NULL,NULL,0),(1319,'七星彩',147,3,1,0,NULL,NULL,0),(1320,'七乐彩',147,3,1,0,NULL,NULL,0),(1321,'竞彩足球',147,3,1,0,NULL,NULL,0),(1322,'竞彩篮球',147,3,1,0,NULL,NULL,0),(1323,'新时时彩',147,3,1,0,NULL,NULL,0),(1324,'国内机票',148,3,1,0,NULL,NULL,0),(1325,'国内酒店',149,3,1,0,NULL,NULL,0),(1326,'酒店团购',149,3,1,0,NULL,NULL,0),(1327,'度假',150,3,1,0,NULL,NULL,0),(1328,'景点',150,3,1,0,NULL,NULL,0),(1329,'租车',150,3,1,0,NULL,NULL,0),(1330,'火车票',150,3,1,0,NULL,NULL,0),(1331,'旅游团购',150,3,1,0,NULL,NULL,0),(1332,'手机充值',151,3,1,0,NULL,NULL,0),(1333,'游戏点卡',152,3,1,0,NULL,NULL,0),(1334,'QQ充值',152,3,1,0,NULL,NULL,0),(1335,'电影票',153,3,1,0,NULL,NULL,0),(1336,'演唱会',153,3,1,0,NULL,NULL,0),(1337,'话剧歌剧',153,3,1,0,NULL,NULL,0),(1338,'音乐会',153,3,1,0,NULL,NULL,0),(1339,'体育赛事',153,3,1,0,NULL,NULL,0),(1340,'舞蹈芭蕾',153,3,1,0,NULL,NULL,0),(1341,'戏曲综艺',153,3,1,0,NULL,NULL,0),(1342,'东北',154,3,1,0,NULL,NULL,0),(1343,'华北',154,3,1,0,NULL,NULL,0),(1344,'西北',154,3,1,0,NULL,NULL,0),(1345,'华中',154,3,1,0,NULL,NULL,0),(1346,'华东',154,3,1,0,NULL,NULL,0),(1347,'华南',154,3,1,0,NULL,NULL,0),(1348,'西南',154,3,1,0,NULL,NULL,0),(1349,'苹果',155,3,1,0,NULL,NULL,0),(1350,'橙子',155,3,1,0,NULL,NULL,0),(1351,'奇异果/猕猴桃',155,3,1,0,NULL,NULL,0),(1352,'车厘子/樱桃',155,3,1,0,NULL,NULL,0),(1353,'芒果',155,3,1,0,NULL,NULL,0),(1354,'蓝莓',155,3,1,0,NULL,NULL,0),(1355,'火龙果',155,3,1,0,NULL,NULL,0),(1356,'葡萄/提子',155,3,1,0,NULL,NULL,0),(1357,'柚子',155,3,1,0,NULL,NULL,0),(1358,'香蕉',155,3,1,0,NULL,NULL,0),(1359,'牛油果',155,3,1,0,NULL,NULL,0),(1360,'梨',155,3,1,0,NULL,NULL,0),(1361,'菠萝/凤梨',155,3,1,0,NULL,NULL,0),(1362,'桔/橘',155,3,1,0,NULL,NULL,0),(1363,'柠檬',155,3,1,0,NULL,NULL,0),(1364,'草莓',155,3,1,0,NULL,NULL,0),(1365,'桃/李/杏',155,3,1,0,NULL,NULL,0),(1366,'更多水果',155,3,1,0,NULL,NULL,0),(1367,'水果礼盒/券',155,3,1,0,NULL,NULL,0),(1368,'牛肉',156,3,1,0,NULL,NULL,0),(1369,'羊肉',156,3,1,0,NULL,NULL,0),(1370,'猪肉',156,3,1,0,NULL,NULL,0),(1371,'内脏类',156,3,1,0,NULL,NULL,0),(1372,'鱼类',157,3,1,0,NULL,NULL,0),(1373,'虾类',157,3,1,0,NULL,NULL,0),(1374,'蟹类',157,3,1,0,NULL,NULL,0),(1375,'贝类',157,3,1,0,NULL,NULL,0),(1376,'海参',157,3,1,0,NULL,NULL,0),(1377,'海产干货',157,3,1,0,NULL,NULL,0),(1378,'其他水产',157,3,1,0,NULL,NULL,0),(1379,'海产礼盒',157,3,1,0,NULL,NULL,0),(1380,'鸡肉',158,3,1,0,NULL,NULL,0),(1381,'鸭肉',158,3,1,0,NULL,NULL,0),(1382,'蛋类',158,3,1,0,NULL,NULL,0),(1383,'其他禽类',158,3,1,0,NULL,NULL,0),(1384,'水饺/馄饨',159,3,1,0,NULL,NULL,0),(1385,'汤圆/元宵',159,3,1,0,NULL,NULL,0),(1386,'面点',159,3,1,0,NULL,NULL,0),(1387,'火锅丸串',159,3,1,0,NULL,NULL,0),(1388,'速冻半成品',159,3,1,0,NULL,NULL,0),(1389,'奶酪黄油',159,3,1,0,NULL,NULL,0),(1390,'熟食',160,3,1,0,NULL,NULL,0),(1391,'腊肠/腊肉',160,3,1,0,NULL,NULL,0),(1392,'火腿',160,3,1,0,NULL,NULL,0),(1393,'糕点',160,3,1,0,NULL,NULL,0),(1394,'礼品卡券',160,3,1,0,NULL,NULL,0),(1395,'冷藏果蔬汁',161,3,1,0,NULL,NULL,0),(1396,'冰激凌',161,3,1,0,NULL,NULL,0),(1397,'其他',161,3,1,0,NULL,NULL,0),(1398,'叶菜类',162,3,1,0,NULL,NULL,0),(1399,'茄果瓜类',162,3,1,0,NULL,NULL,0),(1400,'根茎类',162,3,1,0,NULL,NULL,0),(1401,'鲜菌菇',162,3,1,0,NULL,NULL,0),(1402,'葱姜蒜椒',162,3,1,0,NULL,NULL,0),(1403,'半加工蔬菜',162,3,1,0,NULL,NULL,0),(1404,'微型车',163,3,1,0,NULL,NULL,0),(1405,'小型车',163,3,1,0,NULL,NULL,0),(1406,'紧凑型车',163,3,1,0,NULL,NULL,0),(1407,'中型车',163,3,1,0,NULL,NULL,0),(1408,'中大型车',163,3,1,0,NULL,NULL,0),(1409,'豪华车',163,3,1,0,NULL,NULL,0),(1410,'MPV',163,3,1,0,NULL,NULL,0),(1411,'SUV',163,3,1,0,NULL,NULL,0),(1412,'跑车',163,3,1,0,NULL,NULL,0),(1413,'微型车(二手)',164,3,1,0,NULL,NULL,0),(1414,'小型车(二手)',164,3,1,0,NULL,NULL,0),(1415,'紧凑型车(二手)',164,3,1,0,NULL,NULL,0),(1416,'中型车(二手)',164,3,1,0,NULL,NULL,0),(1417,'中大型车(二手)',164,3,1,0,NULL,NULL,0),(1418,'豪华车(二手)',164,3,1,0,NULL,NULL,0),(1419,'MPV(二手)',164,3,1,0,NULL,NULL,0),(1420,'SUV(二手)',164,3,1,0,NULL,NULL,0),(1421,'跑车(二手)',164,3,1,0,NULL,NULL,0),(1422,'皮卡(二手)',164,3,1,0,NULL,NULL,0),(1423,'面包车(二手)',164,3,1,0,NULL,NULL,0),(1431,'dsa323',1,2,1,NULL,NULL,NULL,NULL),(1432,'fdsffdsadddd大萨达',1431,3,1,NULL,NULL,NULL,NULL);

8、clone 人人开源

人人开源:https://gitee.com/renrenio

1587609877028

克隆到本地:

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

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

将拷贝下来的“renren-fast”删除“.git”后,拷贝到“gulimall”工程根目录下,然后将它作为gulimall的一个module

创建“gulimall_admin”的数据库,然后执行“renren-fast/db/mysql.sql”的sql脚本

修改“application-dev.yml”文件,默认为dev环境,修改连接mysql的url和用户名密码

spring:
    datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        druid:
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://192.168.119.127:3306/gulimall_admin?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
            username: root
            password: root

启动“gulimall_admin”,然后访问“http://localhost:8080/renren-fast/

1587616296253

9、安装Node.js

前端开发,少不了 node.js Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。
http://nodejs.cn/api/Node.js v20.12.0 文档: http://nodejs.cn/api/
我们关注与 node.js npm 功能就行;
NPM 是随同 NodeJS 一起安装的 包管理 工具, JavaScript-NPM Java-Maven

1、官网下载安装 node.js,并使用 node -v 检查版本

选择windows下载。下载完安装。

命令行输入node -v 检查配置好了 

node -v
2、配置 npm 使用淘宝镜像
npm config set registry http://registry.npm.taobao.org/

3、大家如果 npm install 安装依赖出现 chromedriver 之类问题,先在项目里运行下面命令

npm install chromedriver --chromedriver_cdnurl=http://cdn.npm.taobao.org/dist/chromedriver
然后再运行 npm install
PS D:\tmp\renren-fast-vue> npm config set registry http://registry.npm.taobao.org/
PS D:\tmp\renren-fast-vue> npm install
npm WARN ajv-keywords@1.5.1 requires a peer of ajv@>=4.10.0 but none is installed. You must install peer dependencies yourself.
npm WARN sass-loader@6.0.6 requires a peer of node-sass@^4.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.9 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.9: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

up to date in 17.227s
PS D:\tmp\renren-fast-vue> 
PS D:\tmp\renren-fast-vue> npm run dev

> renren-fast-vue@1.2.2 dev D:\tmp\renren-fast-vue
> webpack-dev-server --inline --progress --config build/webpack.dev.conf.js

 10% building modules 5/10 modules 5 active ...-0!D:\tmp\renren-fast-vue\src\main.js(node:19864) Warning: Accessing non-existent property 'cat' of module exports inside circular dependency
(Use `node --trace-warnings ...` to show where the warning was created)
(node:19864) Warning: Accessing non-existent property 'cd' of module exports inside circular dependency
(node:19864) Warning: Accessing non-existent property 'chmod' of module exports inside circular dependency
(node:19864) Warning: Accessing non-existent property 'cp' of module exports inside circular dependency
(node:19864) Warning: Accessing non-existent property 'dirs' of module exports inside circular dependency
(node:19864) Warning: Accessing non-existent property 'pushd' of module exports inside circular dependency
(node:19864) Warning: Accessing non-existent property 'popd' of module exports inside circular dependency
(node:19864) Warning: Accessing non-existent property 'echo' of module exports inside circular dependency
(node:19864) Warning: Accessing non-existent property 'tempdir' of module exports inside circular dependency
(node:19864) Warning: Accessing non-existent property 'pwd' of module exports inside circular dependency

然后取VScode的终端中输入 npm install,会报错,然后进行如下操作:

常见问题1:首先确保安装了python3.0以上版本,并配置全局变量

常见问题2:“Module build failed: Error: Cannot find module 'node-sass”

运行过程中,出现“Module build failed: Error: Cannot find module 'node-sass’报错问题”,解决方法

首先把项目文件夹下的package.json里面的node-sass4.9.0改成4.9.2(不改可能也没关系,不过我改了,防止踩坑)
然后项目文件夹下打开cmd命令窗口(和Visual Studio Code的终端命令是一样的)
执行:
npm i node-sass --sass_binary_site=https://npm.taobao.org/mirrors/node-sass/
执行成功看看有没有报错,如果没报错执行下面命令
npm install ,
没报错就是安装成功,然后使用npm run dev 就ok了
注:这么做得原理就是先单独从淘宝镜像吧nod-sass下载下来,然后再进行编译,因为这句命令好像是不成功的,(npm config set registry http://registry.npm.taobao.org/),默认从github下载,导致报错的
如果之前安装失败的。先清理 缓存
清理缓存:npm rebuild node-sass
                  npm uninstall node-sass

常见问题3:cnpm - 解决 " cnpm : 无法加载文件 C:\Users\93457\AppData\Roaming\npm\cnpm.ps1,因为在此系统上禁止运行脚本。有关详细信息 。。。 "

cnpm - 解决 " cnpm : 无法加载文件 C:\Users\93457\AppData\Roaming\npm\cnpm.ps1,因为在此系统上禁止运行脚本。有关详细信息 。。。 " - 武卡卡 - 博客园

常见问题4、npm install报错:chromedriver@2.27.2 install: node install.js

如果执行过npm install,先删除 node_modules 文件夹,不然运行的时候可能会报错
执行下面的命令
npm install chromedriver --chromedriver_cdnurl=http://cdn.npm.taobao.org/dist/chromedriver
再执行 npm install 即可正常下载

所有问题的根源都在“node_modules”,npm install之前,应该将这个文件夹删除,然后再进行安装和运行。

再次运行npm run dev恢复正常:

浏览器输入localhost:8001 就可以看到内容了,登录admin admin

10、IDEA项目准备 

10.1、逆向工程搭建 

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

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

1、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中刷新一下,让项目名变粗体,稍等下面进度条完成。

2、修改renren-generator模块的application.yml

url: jdbc:mysql://192.168.119.127: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_

3、运行RenrenApplication。

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

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

10.2、gulimall-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包https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore -->
<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修改项目名

然后在product项目中的pom.xml中加入下面内容

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

1、复制

  • renren-fast----utils包下的Query和PageUtils、R、Constant复制到common项目的java/com.atguigu.common.utils下

  • 把@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;

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

2、测试

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

整合MyBatis-Plus
     1)、导入依赖
          <dependency>
             <groupId>com.baomidou</groupId>
             <artifactId>mybatis-plus-boot-starter</artifactId>
             <version>3.4.0</version>
          </dependency>
      2)、配置
          1、配置数据源
              1)、导入数据库的驱动
              2)、在application.yml配置数据源相关信息
          2、配置MyBatis-Plus
              1)、使用mapperScan
              2)、告诉MyBatis-Plus,sql映射文件位置

MyBatis-Plus文档: https://baomidou.com/

在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

10.3、gulimall-product

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

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://192.168.119.127: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.119.127:3306/gulimall-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);
    }
}

10.4、gulimall-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.119.127: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项目对应目录下。

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

<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.119.127: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

http://localhost:8080/coupon/coupon/list

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

10.5、gulimall-member

重新使用代码生成器生成ums

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

代码生成器里:

url: jdbc:mysql://192.168.119.127: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项目目录

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

<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.119.127: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":[]}}

10.6、gulimall-order

修改代码生成器

url: jdbc:mysql://192.168.119.127: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.119.127: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

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

<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":[]}}

10.7、gulimall-ware

修改代码生成器

url: jdbc:mysql://192.168.119.127: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重新生成后去下载解压放置。

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

<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.119.127: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

启动gulimallWareApplication.java

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

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

11、SpringCloud Alibaba简介

  • 注册中心:
  • 配置中心:
  • 网关: 
简介
Spring Cloud Alibaba 致力于提供 微服务开发的 一站式解决方案 。此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。
依托 Spring Cloud Alibaba ,您只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里微服务解决方案,通过阿里中间件来迅速搭建分布式应用系统。

https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md

微服务-注册中心、配置中心、网关 

API网关 

SpringCloud的几大痛点:

SpringCloud部分组件停止维护和更新,给开发带来不便;

SpringCloud部门环境搭建复杂,没有完善的可视化界面,我们需要大量的二次开发和定制

SpringCloud配置复杂,难以上手,部分配置差别难以区分和合理应用

SpringCloud Alibab的优势:

阿里使用过的组件经历了考验,性能强悍,设计合理,现在开源出来大家用成套的产品搭配完善的可视化界面给开发运维带来极大的便利搭建简单,学习曲线低。

结合SpringCloud 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,即分布式事务解决方案

netflix把feign闭源了,spring cloud开了个open feign

项目中引入SpringCloud Alibaba依赖

注意:版本号要与SpringBoot版本号对应,具体看官方文档

官方GitHub项目地址及版本说明:spring-cloud-alibaba

这里先放上我目前搭建的较新的微服务脚手架版本,如下(springboot3.0开始不支持jdk8)

Spring BootSpring CloudSpring Cloud AlibabaNocosJDK
2.7.72021.0.52021.0.5.02.2.01.8

1. Spring Boot 与 Spring Cloud 版本对应说明

(1)官方文档地址:https://spring.io/projects/spring-cloud

上述链接页面往下拉,即可看到下图,左边是 spring cloud 版本,右边是 spring boot 版本

 2. Spring Cloud Alibaba

官方GitHub项目地址及版本说明:spring-cloud-alibaba

毕业版本依赖关系(推荐使用)


由于 Spring Boot 3.0,Spring Boot 2.7~2.4 和 2.4 以下版本之间变化较大,目前企业级客户老项目相关 Spring Boot 版本仍停留在 Spring Boot 2.4 以下,为了同时满足存量用户和新用户不同需求,社区以 Spring Boot 3.0 和 2.4 分别为分界线,同时维护 2022.x、2021.x、2.2.x 三个分支迭代。如果不想跨分支升级,如需使用新特性,请升级为对应分支的新版本。 为了规避相关构建过程中的依赖冲突问题,我们建议可以通过 云原生应用脚手架 进行项目创建。

 

上图是官方对版本依赖的描述,总结就是现 spring cloud alibaba 有三大版本,分别对应 spring boot 版本 >=3.0、2.4 - 2.7、<= 2.4 

 3. 组件版本关系

每个 Spring Cloud Alibaba 版本及其自身所适配的各组件对应版本如下表所示(注意,Spring Cloud Dubbo 从 2021.0.1.0 起已被移除出主干,不再随主干演进): 

 注意 nacos 的版本选择要对应上 spring cloud alibaba 的版本,否则可能会引起冲突项目无法启动,引起不必要的麻烦

在common的pom.xml中加入

    <!--依赖管理,在dependencies引入SpringCloud Alibaba相关依赖不需要引入版本号了-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2021.0.5.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

上面是依赖管理,相当于以后再dependencies里引spring cloud alibaba就不用写版本号, 全用dependencyManagement进行管理

11.1、Nacos ​

Nacos 是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理
平台。他是使用 java 编写。需要依赖 java 环境
Nacos 文档地址:

https://github.com/alibaba/spring-cloud-alibaba/tree/master/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example

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

11.1.1、下载 nacos-server

 nacos下载地址:  https://github.com/alibaba/nacos/releases

下载解压 

Windows下nacos的安装与配置

 如果是在docker安装的nacos可以参考https://blog.csdn.net/wts563540/article/details/123151034 

11.1.2、启动 nacos-server
  • 修改配置
  • 双击 bin 中的 startup.cmd 文件
  • 访问 http://localhost:8848/nacos/
  • 使用默认的 nacos/nacos 进行登录

1)、配置数据库信息

进入conf文件夹,编辑application.properties

2)、配置密钥(密钥为Base64编码的字符串,且原始密钥长度不得低于32字符)

具体参考官方文档说明:

Authorization

3)、修改启动文件

修改bin目录下的startup.cmd

默认是集群模式“cluster”,修改为单机模式“standalone”

 

4)、将配置导入mysql

创建nacos_config库(默认数据库名称,如若修改,请在application.properties中修改数据库名称)

运行sql文件导入

5)、启动

bin目录下cmd,运行“startup.cmd” 文件

 

6)、效果: 

11.1.3、将微服务注册到 nacos
  1. 首先,修改 pom.xml 文件,引入 Nacos Discovery Starter。放到common的pom.xml文件里

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    
  2. 在应用的 /src/main/resources/application.properties 配置文 件中配置 Nacos Server 地址
    # 指定应用程序的名称
    spring.application.name=gulimall-product
    # 配置nacos注册中心地址
    spring.cloud.nacos.discovery.server-addr=127.0.01:8848
    
  3. 使用 @EnableDiscoveryClient 注解开启服务注册与发现功能
     @SpringBootApplication
     @EnableDiscoveryClient
     public class ProviderApplication {
    
     	public static void main(String[] args) {
     		SpringApplication.run(Application.class, args);
     	}
    
     }
11.1.4、启动应用,观察 nacos 服务列表是否已经注册上服务
注意:每一个应用都应该有名字,这样才能注册上去。修改 application.properties 文件
spring.application.name=service-provider
server.port=8000

11.1.5、注册更多的服务上去,测试使用 feign 远程调用

 Nacos 使用三步


  1. 导包 nacos-discovery
  2. 写配置,指定 nacos 地址,指定应用的名字
  3. 开启服务注册发现功能@EnableDiscoveryClient

Nacos 具体流程:

1)、启动 Nacos Server

  1.  首先需要获取 Nacos Server,支持直接下载和源码构建两种方式。
    1.  直接下载:Nacos Server 下载页。解压zip,双击bin里的startup.cmd就启动了。
    2. 源码构建:进入 Nacos Github 项目页面,将代码 git clone 到本地自行编译打包,参考此文档推荐使用源码构建方式以获取最新版本
  2. 启动 Server,进入解压后文件夹或编译打包好的文件夹,找到如下相对文件夹 nacos/bin,并对照操作系统实际情况之下如下命令。
    1. Linux/Unix/Mac 操作系统,执行命令 sh startup.sh -m standalone
    2. Windows 操作系统,执行命令 cmd startup.cmd

2)、应用启动

  1. 增加配置,在 nacos-discovery-provider-example 项目的 /src/main/resources/application.properties 中添加基本配置信息
    # 指定服务端口号
    server.port=18082
    # 指定应用程序的名称
    spring.application.name=service-provider
    # 配置nacos注册中心地址
    spring.cloud.nacos.discovery.server-addr=127.0.01:8848
  2. 启动应用,支持 IDE 直接启动和编译打包后启动。
    1. IDE直接启动:找到 nacos-discovery-provider-example 项目的主类 ProviderApplication,执行 main 方法启动应用。
    2. 打包编译后启动:在 nacos-discovery-provider-example 项目中执行 mvn clean package 将工程编译打包,然后执行 java -jar nacos-discovery-provider-example.jar启动应用。

3)、验证

  查询服务:在浏览器输入此地址 

  http://127.0.0.1:8848/nacos/

  账号密码:nacos/nacos

  点击 服务管理 --> 服务列表,可以看到服务节点已经成功注册到 Nacos Server。

  在coupon的gulimallCouponApplication.java加上@EnableDiscoveryClient,导入包,然后重启项目。

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

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://192.168.127.119: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

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


Feign 使用三步


  1. 导包 openfeign
  2. 开启@EnableFeignClients 功能
  3. 编写接口,进行远程调用

1)、SpringCloud feign 声明式远程调用

简介

feign是一个声明式的HTTP客户端,他的目的就是让远程调用更加简单。Feign提供了HTTP请求的模板,通过编写简单的接口和插入注释,就可以定义好HTTP请求的参数、格式、地址等信息。

Feign整合了Rbibbon(负载均衡)Hystrix(服务熔断),可以让我们不再需要显式地使用这两个组件。

SpringCloudFeign在NetflixFeign的基础上扩展了对SpringMVC注解的支持,在其实现下,我们只需要创建一个接口并用注解的方式来配置它,即可完成对服务提供方的接口绑定。简化了SpringCloudRibbon自行封装服务调用客户端的开发量。

2)、使用

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

<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要调用东西的

package com.atguigu.gulimall.member;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/*
* 想要远程调用的步骤:
* 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
@SpringBootApplication
public class gulimallMemberApplication {

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

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

package com.atguigu.gulimall.member.feign;

import com.atguigu.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

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

然后我们在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}}

我们调用接口发现报错,下面看一下报错原因以及如何解决。

1、报错原因

这是因为由于SpringCloud Feign在Hoxton.M2 RELEASED版本之后不再使用Ribbon而是使用spring-cloud-loadbalancer,所以不引入spring-cloud-loadbalancer会报错。

2、解决方法

降低SpringBoot和SpringCloud的版本或者加上如下依赖:

<!--使用Spring Cloud LoadBalancer 进行客户端负载均衡-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>

需要在nacos注册发现依赖中把Ribbon 进行客户端负载均衡去掉

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

扩展

coupon里的R.ok()是什么

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;
    }
}

coupon里的控制层就是new了个couponEntity然后放到hashmap(R)里而已。

11.2、配置中心

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

官方教程:https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/nacos-example/nacos-config-example/readme-zh.md

1)pom.xml 引入 Nacos Config Starter放到common中

<dependency>
     <groupId>com.alibaba.cloud</groupId>
     <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
 </dependency>
2) 、在应用的 /src/main/resources/bootstrap.properties 置文件中配置 Nacos Config 元数据

        

        在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

原来的方式:

@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,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的配置内容优先于项目本地的配置内容。

【启动报错信息如下 】

Description:
No spring.config.import property has been defined

启动时,控制台已经很明确的给出了一个标准的解决方案:

Add a spring.config.import=nacos: property to your configuration.
If configuration is not required add spring.config.import=optional:nacos: instead.
To disable this check, set spring.cloud.nacos.config.import-check.enabled=false.

 经过查阅官方资料,确认从2021.0.5版本起,Spring Cloud将不再默认启用bootstrap 包,所以针对该问题,解决方案有两种:

  • application.yml中添加以下配置,用以指定引入的配置文件。
spring:
  config:
    import: nacos:xxxx.yaml
  • pom或build.gradle中引入boostrap依赖包:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
    <version>4.0.1</version>
</dependency>

implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap:4.0.1'

配置中心进阶

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

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

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

    • 开发、测试、开发可以用命名空间分割。properties每个空间有一份。

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

      # 可以选择对应的命名空间 # 写上对应环境的命名空间ID
      spring.cloud.nacos.config.namespace=5c4ae9f0-64ee-4a74-a020-37ad68eb471c
      
    • 也可以为每个微服务配置一个命名空间,微服务互相隔离

    • 配置集:一组相关或不相关配置项的集合。

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

  • 配置分组:默认所有的配置集都属于DEFAULT_GROUP。双十一,618,双十二

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

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

加载多配置集

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

bootstrap.properties

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'}]

 使用nacos作为配置中心统一管理配置流程

1、如何使用nacos作为配置中心统一管理配置
    1)、引入依赖
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            </dependency>
    2)、创建一个bootstrap.properties
         #服务名称
         spring.application.name=gulimall-coupon
         #配置中心的地址
         spring.cloud.nacos.config.server-addr=127.0.0.1:8848
    3)、需要给配置中心默认添加一个叫数据集(Data Id)gulimall-coupon.properties.默认规则,应用名.properties
    4)、给 应用名.properties 添加任何配置
    5)、动态获取配置
         @RefreshScope:动态获取并刷新配置
         @Value("${配置项的名}"):获取到配置
         如果配置中心和当前应用的配置文件中都配置了相同的项,优先使用配置中心的配置
2、细节
     1)、命名空间,配置隔离
         默认:public(保留空间);默认新增的所有配置都在public空间
         1、开发、测试、生产;利用命名空间做环境隔离
             注意:在bootstrap.properties配置上,需要使用哪个命名空间下的配置
             spring.cloud.nacos.config.namespace=65875baf-002a-4bd1-a3b8-9547b7ba1fe2
         2、每一个微服务之间互相隔离配置,每一个微服务都创建自己的命名空间,只加载自己命名和空间下的所有配置
     2)、配置集:所有配置的集合
     3)、配置集ID:类似文件名
         DataID:类似文件名
     4)、配置分组
         默认所有的配置集都属于:DEFAULT_GROUP
     项目中的使用:每个微服务创建自己的命名空间,使用配置分组区分的环境,dev,test,prop
 3、同时加载多个配置集
     1)、微服務任何配置信息,任何配置文件都可以放在配置中心中
     2)、只需要在bootstrap.properties说明加载配置中心哪些配置文件即可
     3)、@Value、@ConfigurationPropeties...以前SpringBoot任何方法从配置文件中获取,都能使用配置中心有的优先使用配置中心的

11.3、网关(Gateway)

11.3.1、简介

网关作为流量的入口,常用功能包括路由转发、权限校验、限流控制等。而springCloud gateway作为SpringCloud官方推出的第二代网关框架,取代了Zuul网关。

网关提供 API 全托管服务,丰富的 API 管理功能,辅助企业管理大规模的 API ,以降低管理
成本和安全风险,包括协议适配、协议转发、安全策略、防刷、流量、监控日志等功能。
Spring Cloud Gateway 旨在提供一种简单而有效的方式来对 API 进行路由,并为他们提供切
面,例如:安全性,监控 / 指标 和弹性等。

 官网地址: https://spring.io/projects/spring-cloud-gateway

参考手册:https://cloud.spring.io/spring-cloud-gateway/2.2.x/reference/html/

Spring Cloud Gateway 特点:
  • 基于 Spring5,支持响应式编程和 SpringBoot2.0
  • 支持使用任何请求属性进行路由匹配
  • 特定于路由的断言和过滤器
  • 集成 Hystrix 进行断路保护
  • 集成服务发现功能
  • 易于编写 Predicates Filters
  • 支持请求速率限制
  • 支持路径重写
思考:
为什么使用 API 网关?
API 网关出现的原因是微服务架构的出现,不同的微服务一般会有不同的网络地址,而外部
客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服
务通信,会有以下的 问题
  • 客户端会多次请求不同的微服务,增加了客户端的复杂性。
  • 存在跨域请求,在一定场景下处理相对复杂。
  • 认证复杂,每个服务都需要独立认证。
  • 难以重构,随着项目的迭代,可能需要重新划分微服务。例如,可能将多个服务合并成一个或者将一个服务拆分成多个。如果客户端直接与微服务通信,那么重构将会很难实施。
  • 某些微服务可能使用了防火墙 / 浏览器不友好的协议,直接访问会有一定的困难。
以上这些问题可以借助 API 网关解决。 API 网关是介于客户端和服务器端之间的中间层,所有的外部请求都会先经过 API 网关这一层。也就是说, API 的实现方面更多的考虑业务逻辑,而安全、性能、监控可以交由 API 网关来做,这样既提高业务灵活性又不缺安全性:
使用 API 网关后的优点如下:
  • 易于监控。可以在网关收集监控数据并将其推送到外部系统进行分析。
  • 易于认证。可以在网关上进行认证,然后再将请求转发到后端的微服务,而无须在每个微服务中进行认证。
  • 减少了客户端与各个微服务之间的交互次数
11.3.2、核心概念
  • 路由:路由是网关最基础的部分,路由信息有一个 ID 、一个目的 URL 、一组断言和一组
    Filter 组成。如果断言路由为真,则说明请求的 URL 和配置匹配
  • 断言 Java8 中的断言函数。 Spring Cloud Gateway 中的断言函数输入类型是 Spring5.0
    架中的 ServerWebExchange Spring Cloud Gateway 中的断言函数允许开发者去定义匹配
    来自于 http request 中的任何信息,比如请求头和参数等。
  • 过滤器:一个标准的 Spring webFilter Spring cloud gateway 中的 filter 分为两种类型的
    Filter ,分别是 Gateway Filter Global Filter 。过滤器 Filter 将会对请求和响应进行修改
    处理。
工作原理:

​​

客户端发送请求给网关,弯管 HandlerMapping 判断是否请求满足某个路由,满足就发给网关的 WebHandler 。这个 WebHandler 将请求交给一个过滤器链,请求到达目标服务之前,会执行所有过滤器的 pre 方法。请求到达目标服务处理之后再依次执行所有过滤器的 post 方法。

一句话:满足某些断言(predicates)就路由到指定的地址(uri),使用指定的过滤器(filter

11.3.3、使用
1)HelloWorld
1、创建网关项目,引入网关
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
2、编写网关配置文件
spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - Cookie=mycookie,mycookievalue
3、注意
  • 各种 Predicates 同时存在于同一个路由时,请求必须同时满足所有的条件才被这个路由匹配。
  • 一个请求满足多个路由的谓词条件时,请求只会被首个成功匹配的路由转发
4、测试
可以使用 postman 进行测试网关的路由功能

创建gulimall-gateway

使用initilizer,Group:com.atguigu.gulimall,Artifact: gulimall-gateway,package:com.atguigu.gulimall.gateway。 搜索gateway选中。

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

开启注册服务发现@EnableDiscoveryClient

@EnableDiscoveryClient
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class GulimallGatewayApplication {

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

}

配置nacos注册中心地址applicaion.properties

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

bootstrap.properties 填写配置中心地址

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里创建命名空间gateway,然后在命名空间里创建文件guilmall-gateway.yml

spring:
    application:
        name: gulimall-gateway

在项目里创建application.yml

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:
            - RewritePath=/api/(?<segment>.*),/renren-fast/$\{segment}


## 前端项目,/api
## 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

2)、断言(Predicates 

3)、过滤器(filters 

1GatewayFilter 

2GlobalFilter 

四、ES6


前后端对比

​​

1、简介

ECMAScript 6.0 (以下简称 ES6 ECMAScript 是一种由 Ecma 国际 ( 前身为欧洲计算机制造商
协会 , 英文名称是 European Computer Manufacturers Association) 通过 ECMA-262 标准化的脚本
程序设计语言) JavaScript 语言的下一代标准 ,已经在 2015 6 月正式发布了,并且从 ECMAScript 6 开始,开始采用年号来做版本。即 ECMAScript 2015 ,就是 ECMAScript6
它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
每年一个新版本

2、什么是 ECMAScript

来看下前端的发展历程:
  • web1.0 时代:

最初的网页以 HTML 为主,是纯静态的网页。网页是只读的,信息流只能从服务的到客户端单向流通。开发人员也只关心页面的样式和内容即可。

  • web2.0 时代:
- 1995 年,网景工程师 Brendan Eich 花了 10 天时间设计了 JavaScript 语言。
- 1996 年,微软发布了 JScript ,其实是 JavaScript 的逆向工程实现。
- 1996 11 月, JavaScript 的创造者 Netscape 公司,决定将 JavaScript 提交给标准化组织 ECMA ,希望这种语言能够成为国际标准。
- 1997 年, ECMA 发布 262 号标准文件( ECMA-262 )的第一版,规定了浏览器脚本语言的标准,并将这种语言称为 ECMAScript ,这个版本就是 1.0 版。 JavaScript JScript 都是
`ECMAScript` 的标准实现者,随后各大浏览器厂商纷纷实现了 `ECMAScript` 标准。
所以, ECMAScript 是浏览器脚本语言的规范,而各种我们熟知的 js 语言,如 JavaScript 则是
规范的具体实现

3ES6 新特性

打开VSCode—打开文件夹—新建es6文件夹—新建文件1、let.html—shift+!+Enter生成模板。填入下面内容后,右键open with live server

3.1、安装vue

# 最新稳定版
$ npm install vue

3.2、let 声明变量

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>

<script>
    // var 声明的变量往往会越域
    // 1、let 声明的变量有严格局部作用域
    {
        var a = 1;
        let b = 2;
    }
    console.log(a); // 1
    // console.log(b); // ReferenceError: b is not defined
    // var 可以声明多次
    // 2、let 只能声明一次
    var m = 1
    var m = 2
    let n = 3
    // let n = 4
    console.log(m) // 2
    console.log(n) // Identifier 'n' has already been declared
    // var 会变量提升
    // 3、let 不存在变量提升
    console.log(x); // undefined
    var x = 10;
    console.log(y); //ReferenceError: y is not defined
    let y = 20;
</script>

</body>
</html>
  • var在{}之外也起作用
  • let在{}之外不起作用
  • var多次声明同一变量不会报错,let多次声明会报错,只能声明一次。
  • var 会变量提升(打印和定义可以顺序反)。let 不存在变量提升(顺序不能反)

3.3、const 声明常量(只读变量)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
<script>
  // 1. 声明之后不允许改变
  // 2. 一但声明必须初始化,否则会报错
  const a = 1;
  a = 3; //Uncaught TypeError: Assignment to constant variable.
</script>
</body>
</html>
  • let的const声明之后不允许改变

3.4、解构表达式

1)、数组解构

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

    <script>
        // 1、数组解构
        let arr = [1,2,3];
        // 以前我们想获取其中的值,只能通过角标。ES6 可以这样:
        const [x,y,z] = arr;// x,y,z 将与 arr 中的每个位置对应来取值
        // 然后打印
        console.log(x,y,z);

    </script>
</body>

</html>

2)、对象解构 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

    <script>
        
        // 2、对象解构
        const person = {
            name: "jack",
            age: 21,
            language: ['java', 'js', 'css']
        }
        // 解构表达式获取值,将 person 里面每一个属性和左边对应赋值
        const { name, age, language } = person;
        // 等价于下面
        // const name = person.name;
        // const age = person.age;
        // const language = person.language;
        // 可以分别打印
        console.log(name);
        console.log(age);
        console.log(language);
        // 扩展:如果想要将 name 的值赋值给其他变量,可以如下,nn 是新的变量名
        const { name: nn, age, language } = person;
        console.log(nn);
        console.log(age);
        console.log(language);
    </script>
</body>

</html>
  • 支持let arr = [1,2,3]; let [a,b,c] = arr;这种语法
  • 支持对象解析:const { name: abc, age, language } = person; 冒号代表改名

3.5、字符串扩展

1)、几个新的 API

ES6 为字符串扩展了几个新的 API
  • `includes()`:返回布尔值,表示是否找到了参数字符串。
  • `startsWith()`:返回布尔值,表示参数字符串是否在原字符串的头部。
  • `endsWith()`:返回布尔值,表示参数字符串是否在原字符串的尾部。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>

    /**
     * 1)、几个新的 API
     */

    let str = "hello.vue";
    console.log(str.startsWith("hello")); //true
    console.log(str.endsWith(".vue")); //true
    console.log(str.includes("e")); //true
    console.log(str.includes("hello")); //true

</script>
</body>
</html>

2)、字符串模板

模板字符串相当于加强版的字符串,用反引号 `,除了作为普通字符串,还可以用来定义多行字符串,还可以在字符串中加入变量和表达式。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>

<script>

    /**
     * 2)、字符串模板
     * @type {string}
     */
    // 1、多行字符串
    let ss = `
      <div>
      <span>hello world<span>
      </div>
      `
    console.log(ss)

    // 2、字符串插入变量和表达式。变量名写在 ${} 中,${} 中可以放入 JavaScript 表达式。
    let name = "张三";
    let age = 18;
    let info = `我是${name},今年${age}了`;
    console.log(info)

    // 3、字符串中调用函数
    function fun() {
        return "这是一个函数"
    }
    let sss = `O(∩_∩)O 哈哈~,${fun()}`;
    console.log(sss); // O(∩_∩)O 哈哈~,这是一个函数
</script>
</body>
</html>
  • 字符串函数
  • 支持一个字符串为多行
  • 占位符功能 ${}

3.6、函数优化

1)、函数参数默认值

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

<script>
    /**
     * 1)、函数参数默认值
     */
    //在 ES6 以前,我们无法给一个函数参数设置默认值,只能采用变通写法:
    function add(a, b) {
        // 判断 b 是否为空,为空就给默认值 1
        b = b || 1;
        return a + b;
    }

    // 传一个参数
    console.log(add(10));

    //现在可以这么写:直接给参数写上默认值,没传就会自动使用默认值
    function add2(a, b = 1) {
        return a + b;
    }

    // 传一个参数
    console.log(add2(10));

</script>
</body>

</html>

2)、不定参数

不定参数用来表示不确定参数个数,形如, ... 变量名, ... 加上一个具名参数标识符组成
具名参数 只能放在参数列表的最后 ,并且 有且只有一个不定参数
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

<script>

    /**
     * 2)、不定参数
     */
    function fun(...values) {
        console.log(values.length)
    }
    fun(1, 2) //2
    fun(1, 2, 3, 4) //4

</script>
</body>

</html>

3)、箭头函数

ES6 中定义函数的简写方式

一个参数时:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

<script>
   
    /**
     * 3)、箭头函数
     */
    // 1、一个参数时:

    //以前声明一个方法
    // var print = function (obj) {
    // console.log(obj);
    // }
    // 可以简写为:
    var print = obj => console.log(obj);
    // 测试调用
    print(100);


</script>
</body>

</html>
  • 多个参数:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

<script>
   
    /**
     * 3)、箭头函数
     */
    // 1、一个参数时:

    //以前声明一个方法
    // var print = function (obj) {
    // console.log(obj);
    // }
    // 可以简写为:
    var print = obj => console.log(obj);
    // 测试调用
    print(100);


    // 2、多个参数:
    // 2.1、两个参数的情况:
    var sum = function (a, b) {
        return a + b;
    }
    // 简写为:
    //当只有一行语句,并且需要返回结果时,可以省略 {} , 结果会自动返回。
    var sum2 = (a, b) => a + b;
    //测试调用
    console.log(sum2(10, 10));//20

    // 2.2、代码不止一行,可以用`{}`括起来
    var sum3 = (a, b) => {
        c = a + b;
        return c;
    };
    //测试调用
    console.log(sum3(10, 20));//30
   
</script>
</body>

</html>

4)、实战:箭头函数结合解构表达式

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

<script>
 

    /**
     * 4)、实战:箭头函数结合解构表达式
     */
    //需求,声明一个对象,hello 方法需要对象的个别属性
    // 以前的方式:
    const person = {
            name: "jack",
            age: 21,
            language: ['java', 'js', 'css']
        }
    function hello(person) {
        console.log("hello," + person.name)
    }
    //测试
    hello(person)

    //现在的方式
    var hello2 = ({ name }) => { console.log("hello2," + name) };
    //测试
    hello2(person);
</script>
</body>

</html>
  • 原来想要函数默认值得这么写b = b || 1; 现在可以直接写了function add2(a, b = 1) {
  • 函数不定参数function fun(...values) {
  • 支持箭头函数(lambda表达式),还支持使用{}结构传入对象的成员

3.7、对象优化

1 )、新增的 API
ES6 Object 拓展了许多新的方法,如:
  • keys(obj):获取对象的所有 key 形成的数组
  • values(obj):获取对象的所有 value 形成的数组
  • entries(obj):获取对象的所有 key value 形成的二维数组。格式:`[[k1,v1],[k2,v2],...]`
  • assign(dest, ...src) :将多个 src 对象的值 拷贝到 dest 中。(第一层为深拷贝,第二层为浅 拷贝)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

    <script>
        /**
         * 1)、新增的 API
         * ES6 给 Object 拓展了许多新的方法,如:
         * - keys(obj):获取对象的所有 key 形成的数组
         * - values(obj):获取对象的所有 value 形成的数组
         * - entries(obj):获取对象的所有 key 和 value 形成的二维数组。格式:`[[k1,v1],[k2,v2],...]` - assign(dest, ...src) :将多个 src 对象的值 拷贝到 dest 中。(第一层为深拷贝,第二层为浅拷贝)
         */
        const person = {
            name: "jack",
            age: 21,
            language: ['java', 'js', 'css']
        }
        console.log(Object.keys(person));//["name", "age", "language"]
        console.log(Object.values(person));//["jack", 21, Array(3)]
        console.log(Object.entries(person));//[Array(2), Array(2), Array(2)]

        const target = { a: 1 };
        const source1 = { b: 2 };
        const source2 = { c: 3 };
        //Object.assign 方法的第一个参数是目标对象,后面的参数都是源对象。
        Object.assign(target, source1, source2);
        console.log(target)//{a: 1, b: 2, c: 3}

    </script>
</body>

</html>

 2)、声明对象简写

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

    <script>
       
        /**
         * 2)、声明对象简写
         */
        const age = 23
        const name = "张三"
        // 传统
        const person1 = { age: age, name: name }
        console.log(person1)
        // ES6:属性名和属性值变量名一样,可以省略
        const person2 = { age, name }
        console.log(person2) //{age: 23, name: "张三"}

    </script>
</body>

</html>

3)、对象的函数属性简写

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

    <script>
        
        /**
         * 3)、对象的函数属性简写
         */
        let person3 = {
            name: "jack",
            // 以前:
            eat: function (food) {
                console.log(this.name + "在吃" + food);
            },
            // 箭头函数this不能使用,对象.属性
            eat2: food => console.log(person3.name + "在吃" + food),
            eat3(food) {
                console.log(this.name + "在吃" + food);
            }
        }

        person3.eat("香蕉"); // jack在吃香蕉

        person3.eat2("苹果") // jack在吃苹果

        person3.eat3("橘子"); // jack在吃橘子

    </script>
</body>

</html>

 4)、对象拓展运算符

拓展运算符( ... )用于取出参数对象所有可遍历属性然后拷贝到当前对象。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

    <script>
    
        /**
         * 4)、对象拓展运算符
         * 拓展运算符(...)用于取出参数对象所有可遍历属性然后拷贝到当前对象。
         */
        // 1、拷贝对象(深拷贝)
        let person4 = { name: "Amy", age: 15 }
        let someone = { ...person4 }
        console.log(someone) //{name: "Amy", age: 15}
        // 2、合并对象
        let age1 = { age: 15 }
        let name1 = { name: "Amy" }
        let person5 = { ...age1, ...name1 } //如果两个对象的字段名重复,后面对象字段值会覆盖前面对象的字段值
        console.log(person2) //{age1: 15, name1: "Amy"}

    </script>
</body>

</html>
  • 可以获取map的键值对等Object.keys()、values、entries
  • Object.assgn(target,source1,source2) 合并
  • const person2 = { age, name }//声明对象简写
  • …代表取出该对象所有属性拷贝到当前对象。let someone = { …p1 }

3.8、map reduce

数组 中新增了 map reduce 方法。

1)、map

map():接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>

    <script>
        /**
         * 1)、map
         */
        //map():接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回。
        arr = ['1','20','-5','3'];
        console.log(arr)
        arr = arr.map(s => parseInt(s)); 
        console.log(arr) // [1,20,-5,3]

        //  arr = arr.map((item)=>{
        //     return item*2
        //  });
         arr = arr.map(item => item*2);
         console.log(arr); // [2,40,-10,6]

    </script>
</body>
</html>

2)、reduce

语法:
arr.reduce(callback,[initialValue])
reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值(或者上一次回调函数的返回值),当前元素值,当前索引,调用 reduce 的数组。
callback (执行数组中每个值的函数,包含四个参数)
1 previousValue (上一次调用回调返回的值,或者是提供的初始值( initialValue ))
2 currentValue (数组中当前被处理的元素)
3 index (当前元素在数组中的索引)
4 array (调用 reduce 的数组)
initialValue (作为第一次调用 callback 的第一个参数。)
示例:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>

<script>
   
    /**
     * reduce
     */
    //reduce() 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,
    //arr.reduce(callback,[initialValue])
    /**
     *  1、previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
     *  2、currentValue (数组中当前被处理的元素)
     *  3、index (当前元素在数组中的索引)
     *  4、array (调用 reduce 的数组)
     * initialValue (作为第一次调用 callback 的第一个参数。)
     */
    const arr1 = [1,20,-5,3];
    //没有初始值:
    console.log(arr1.reduce((a,b)=>a+b)); //19

    let result = arr1.reduce((a, b) => {
        console.log("上一次处理后:" + a);
        console.log("当前正在处理:" + b);
        return a + b;
    }, 100);
    console.log(result)
    /**
     * 结果:
     * 上一次处理后:100
     * 当前正在处理:2
     * 上一次处理后:102
     * 当前正在处理:40
     * 上一次处理后:142
     * 当前正在处理:-10
     * 上一次处理后:132
     * 当前正在处理:6
     * 138
      */
</script>
</body>
</html>
  • map处理,arr = arr.map(item=> item*2);
  • reduce。arr.reduce((原来的值,处理后的值即return的值)=>{}

3.9、Promise

JavaScript 的世界中,所有代码都是单线程执行的。由于这个 缺陷 ,导致 JavaScript 的所有网络操作,浏览器事件,都必须是异步执行。异步执行可以用回调函数实现。一旦有一连串的 ajax 请求 a,b,c,d... 后面的请求依赖前面的请求结果,就需要层层嵌套。这种缩进和层层嵌套的方式,非常容易造成上下文代码混乱,我们不得不非常小心翼翼处理内层函数与外层函数的数据,一旦内层函数使用了上层函数的变量,这种混乱程度就会加剧...... 总之,这种` 层叠上下文 ` 的层层嵌套式,着实增加了神经的紧张程度。
案例:用户登录,并展示该用户的各科成绩。在页面发送两次请求:
1. 查询用户,查询成功说明可以登录
2. 查询用户成功,查询科目
3. 根据科目的查询结果,获取去成绩
分析:此时后台应该提供三个接口,一个提供用户查询接口,一个提供科目的接口,一个提供各科成绩的接口,为了渲染方便,最好响应 json 数据。在这里就不编写后台接口了,而是提供三个 json 文件,直接提供 json 数据,模拟后台接口:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</head>

<body>

<script>
    //1、查出当前用户信息
    //2、按照当前用户的id查出他的课程
    //3、按照当前课程id查出分数

    /**
     * 方式一:使用ajax嵌套方式
     */
    // $.ajax({
    //     url: "mock/user.json",
    //     success(data) {
    //         console.log("查询用户:", data);
    //         $.ajax({
    //             url: `mock/user_corse_${data.id}.json`,
    //             success(data) {
    //                 console.log("查询到课程:", data);
    //                 $.ajax({
    //                     url: `mock/corse_score_${data.id}.json`,
    //                     success(data) {
    //                         console.log("查询到分数:", data);
    //                     },
    //                     error(error) {
    //                         console.log("出现异常了:" + error);
    //                     }
    //                 });
    //             },
    //             error(error) {
    //                 console.log("出现异常了:" + error);
    //             }
    //         });
    //     },
    //     error(error) {
    //         console.log("出现异常了:" + error);
    //     }
    // });
    /**
     * 查询用户成功: Objectid: 1name: "zhangsan"password: "123456"[[Prototype]]: Object
     * 用户查询成功~~~: Objectid: 1name: "zhangsan"password: "123456"[[Prototype]]: Object
     * 查询用户课程成功: Object
     * 上一步的结果 Objectid: 10name: "chinese"[[Prototype]]: Object
     * 课程查询成功~~~: Object
     * 查询课程得分成功: Object
     * 课程成绩查询成功~~~: Object
     */

    /**
     * 方式二
     * 1、Promise可以封装异步操作
     */
    // let p = new Promise((resolve, reject) => {
    //     //1、异步操作
    //     $.ajax({
    //         url: "mock/user.json",
    //         success: function (data) {
    //             console.log("查询用户成功:", data)
    //             resolve(data);
    //         },
    //         error: function (err) {
    //             reject(err);
    //         }
    //     });
    // });
    //
    // p.then((obj) => {
    //     return new Promise((resolve, reject) => {
    //         $.ajax({
    //             url: `mock/user_corse_${obj.id}.json`,
    //             success: function (data) {
    //                 console.log("查询用户课程成功:", data)
    //                 resolve(data);
    //             },
    //             error: function (err) {
    //                 reject(err)
    //             }
    //         });
    //     })
    // }).then((data) => {
    //     console.log("上一步的结果", data)
    //     $.ajax({
    //         url: `mock/corse_score_${data.id}.json`,
    //         success: function (data) {
    //             console.log("查询课程得分成功:", data)
    //         },
    //         error: function (err) {
    //         }
    //     });
    // })
    /**
     * 结果:
     * 查询用户成功: Object
     * 查询用户课程成功: Object
     * 上一步的结果 Object
     * 查询课程得分成功: Object
     */

    /**
     * 方式三:对方式二进行优化,抽取公共方法,使得代码更简洁,优雅
     */
    function get(url, data) {
        return new Promise((resolve, reject) => {
            $.ajax({
                url: url,
                data: data,
                success: function (data) {
                    resolve(data);
                },
                error: function (err) {
                    reject(err)
                }
            })
        });
    }

    get("mock/user.json")
        .then((data) => {
            console.log("用户查询成功~~~:", data)
            return get(`mock/user_corse_${data.id}.json`);
        })
        .then((data) => {
            console.log("课程查询成功~~~:", data)
            return get(`mock/corse_score_${data.id}.json`);
        })
        .then((data) => {
            console.log("课程成绩查询成功~~~:", data)
        })
        .catch((err) => {
            console.log("出现异常", err)
        });
    /**
     * 结果:
     * 用户查询成功~~~: Object
     * 课程查询成功~~~: Object
     * Object
     */
</script>
</body>

</html>

corse_score_10.json 得分

{
    "id": 100,
    "score": 90
}

user.json 用户

{
    "id": 1,
    "name": "zhangsan",
    "password": "123456"
}

user_corse_1.json 课程

{
    "id": 10,
    "name": "chinese"
}

以前嵌套ajax的时候很繁琐。

  • 把Ajax封装到Promise中,赋值给let p
  • 在Ajax中成功使用resolve(data),失败使用reject(err)
  • p.then().catch()

3.10、模块化

1 )、什么是模块化
模块化就是把代码进行拆分,方便重复利用。类似 java 中的导包:要使用一个包,必须先导包。而 JS 中没有包的概念,换来的是 模块
模块功能主要由两个命令构成: `export` `import`
  • `export`命令用于规定模块的对外接口。
  • `import`命令用于导入其他模块提供的功能。
2 )、 export
比如我定义一个 js 文件 :hello.js ,里面有一个对象
const util = {
    sum(a,b){
        return a + b;
    }
}
我可以使用 export 将这个对象导出:
const util = {
    sum(a,b){
        return a + b;
    }
}
export {util};
当然,也可以简写为:
export const util = {
    sum(a,b){
        return a + b;
    }
}
`export`不仅可以导出对象,一切 JS 变量都可以导出。比如:基本类型变量函数数组对象
当要导出多个值时,还可以简写。比如我有一个文件: user.js

user.js

var name = "jack"
var age = 21
function add(a,b){
    return a + b;
}

export {name,age,add}
省略名称
上面的导出代码中,都明确指定了导出的变量名,这样其它人在导入使用时就必须准确写出
变量名,否则就会出错。
因此 js 提供了 `default` 关键字,可以对导出的变量名进行省略
例如:
// 无需声明对象的名字
export default {
    sum(a,b){
        return a + b;
    }
}
这样,当使用者导入时,可以任意起名字
import add from "./hello.js"

add.sum(1,2);

3)、import

使用 `export` 命令定义了模块的对外接口以后,其他 JS 文件就可以通过 `import` 命令加载这个模块。
例如我要使用上面导出的 util

main.js

import util from "./hello.js"
import {name,add} from "./user.js"

util.sum(1,2);
console.log(name);
add(1,3);

五、Vue


1MVVM 思想

  • M:即 Model,模型,包括数据和一些基本操作
  • V:即 View,视图,页面渲染结果
  • VM:即 View-Model,模型与视图间的双向操作(无需开发人员干涉)
MVVM 之前,开发人员从后端获取需要的数据模型,然后要通过 DOM 操作 Model 渲染到 View 中。而后当用户操作视图,我们还需要通过 DOM 获取 View 中的数据,然后同步到Model 中。
MVVM 中的 VM 要做的事情就是把 DOM 操作完全封装起来,开发人员不用再关心 Model
View 之间是如何互相影响的:
  • 只要我们 Model 发生了改变,View 上自然就会表现出来。
  • 当用户修改了 ViewModel 中的数据也会跟着改变。
把开发人员从繁琐的 DOM 操作中解放出来,把关注点放在如何操作 Model 上。

2Vue 简介

Vue ( 读音 /vjuː/ ,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。 Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
尤雨溪, Vue.js 创作者, Vue Technology 创始人,致力于 Vue 的研究开发。

3、入门案例

3.1、安装

官网文档提供了 3 中安装方式:
  1. 直接 script 引入本地 vue 文件。需要通过官网下载 vue 文件。
  2. 通过 script 引入 CDN 代理。需要联网,生产环境可以使用这种方式
  3. 通过 npm 安装。这种方式也是官网推荐的方式,需要 nodejs 环境。

        本课程就采用第三种方式

3.2、创建示例项目

1 、新建文件夹 vue2 ,并使用 vscode 打开
2 、使用 vscode 控制台, npm install -y ;项目会生成 package-lock.json 文件,类似于 maven 项目的 pom.xml 文件。
3 、使用 npm install vue ,给项目安装 vue ;项目下会多 node_modules 目录,并且在下面有
一个 vue 目录。

 

3.3、HelloWorld

hello.html 中,我们编写一段简单的代码。
h2 中要输出一句话: `xx 非常帅 ` 。前面的 `xx` 是要渲染的数据。

 

3.4、vue 声明式渲染

页面代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <h1>{{name}},非常帅!!!</h1>
</div>
<script src="./node_modules/vue/dist/vue.min.js"></script>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            name: "张三"
        }
    });
</script>
</body>
</html>
  • 首先通过 new Vue()来创建 Vue 实例
  • 然后构造函数接收一个对象,对象中有一些属性:
  • el:是 element 的缩写,通过 id 选中要渲染的页面元素,本例中是一个 div
  • data:数据,数据是一个对象,里面有很多属性,都可以渲染到视图中
  • name:这里我们指定了一个 name 属性
  • 页面中的`h2`元素中,我们通过{{name}}的方式,来渲染刚刚定义的 name 属性。
打开页面查看效果:

更神奇的在于,当你修改 name 属性时,页面会跟着变化: 

3.5、双向绑定

我们对刚才的案例进行简单修改:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <input type="text" v-model="num">
    <h2>
        {{name}},非常帅!!!有{{num}}个人为他点赞。
    </h2>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
    // 创建 vue 实例
    let app = new Vue({
        el: "#app", // el 即 element,该 vue 实例要渲染的页面元素
        data: { // 渲染页面需要的数据
            name: "张三",
            num: 5
        }
    });
</script>
</body>
</html>
双向绑定:
效果:我们修改表单项, num 会发生变化。我们修改 num ,表单项也会发生变化。为了实时观察到这个变化,我们将 num 输出到页面。
我们不需要关注他们为什么会建立起来关联,以及页面如何变化,我们只需要做好数据和 视图的关联即可( MVVM

3.6、事件处理

给页面添加一个按钮:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <input type="text" v-model="num">
    <button v-on:click="num++">关注</button>
    <h2>
        {{name}},非常帅!!!有{{num}}个人为他点赞。
    </h2>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
    // 创建 vue 实例
    let app = new Vue({
        el: "#app", // el 即 element,该 vue 实例要渲染的页面元素
        data: { // 渲染页面需要的数据
            name: "张三",
            num: 5
        }
    });
</script>
</body>
</html>

  • 这里用`v-on`指令绑定点击事件,而不是普通的`onclick`,然后直接操作 num
  • 普通 click 是无法直接操作 num 的。
  • 未来我们会见到更多 v-xxx,这些都是 vue 定义的不同功能的指令。
简单使用总结:
1 )、使用 Vue 实例管理 DOM
2 )、 DOM 与数据 / 事件等进行相关绑定
3 )、我们只需要关注数据,事件等处理,无需关心视图如何进行修改

4、概念

4.1、创建 Vue 实例

每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例 开始的:
let app = new Vue({
});
在构造函数中传入一个对象,并且在对象中声明各种 Vue 需要的数据和方法,包括:
- el
- data
- methods
等等
接下来我们一 一介绍。

4.2、模板或元素

每个 Vue 实例都需要关联一段 Html 模板, Vue 会基于此模板进行视图渲染。
我们可以通过 el 属性来指定。
例如一段 html 模板:
<div id="app">
</div>
然后创建 Vue 实例,关联这个 div
let vm = new Vue({
    el: "#app"
})
这样, Vue 就可以基于 id `app` div 元素作为模板进行渲染了。在这个 div 范围以外的部分是无法使用 vue 特性的。

4.3、数据

Vue 实例被创建时,它会尝试获取在 data 中定义的 所有属性 用于视图的渲染 ,并且 data 中的属性变化 data 发生改变,所有相关的视图都将重新渲染 ,这就是“ 响应式“系统。
html
<div id="app">
    <input type="text" v-model="name" />
</div>
JS:
let vm = new Vue({
    el: "#app",
    data: {
        name: "刘德华"
    }
})
  • name 的变化会影响到`input`的值
  • input 中输入的值,也会导致 vm 中的 name 发生改变

4.4、方法

Vue 实例中除了可以定义 data 属性,也可以定义方法,并且在 Vue 实例的作用范围内使用。
Html
<div id="app">
    {{num}}
    <button v-on:click="add">加</button>
</div>
JS
let vm = new Vue({
    el: "#app",
    data: {
        num: 0
    },
    methods: {
        add: function () {
            // this 代表的当前 vue 实例
            this.num++;
        }
    }
})

4.5、安装 vue-devtools 方便调试

  • 将软件包中的 vue-devtools 解压。
  • 打开 chrome 设置->扩展程序
  • 开启开发者模式,并加载插件 

  • 打开浏览器控制台,选择 vue

 4.6、安装 vscode vue 插件

安装这个插件就可以有语法提示 

5、指令

什么是指令?
  • 指令 (Directives) 是带有 `v-` 前缀的特殊特性。
  • 指令特性的预期值是:单个 JavaScript 表达式
  • 指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM

例如我们在入门案例中的 v-on,代表绑定事件。 

5.1、插值表达式

1)、花括号

格式: {{ 表达式 }}
说明:
  • 该表达式支持 JS 语法,可以调用 js 内置函数(必须有返回值)
  • 表达式必须有返回结果。例如 1 + 1,没有结果的表达式不允许使用,如:let a = 1 + 1;
  • 可以直接获取 Vue 实例中定义的数据或函数

2)、插值闪烁

使用 {{}} 方式在网速较慢时会出现问题。在数据未加载完成时,页面会显示出原始的 `{{}}` ,加载完毕后才显示正确数据,我们称为插值闪烁。
我们将网速调慢一些,然后刷新页面,试试看刚才的案例:

 3)、v-text v-html

可以使用 v-text v-html 指令来替代 {{}}
说明:
  • v-text:将数据输出到元素内部,如果输出的数据有 HTML 代码,会作为普通文本输出
  • v-html:将数据输出到元素内部,如果输出的数据有 HTML 代码,会被渲染

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
   
    <div id="app">
        v-text:<span v-text="hello"></span> <br />
        v-html:<span v-html="hello"></span>
    </div>
   
    <script src="./node_modules/vue/dist/vue.js"></script>
    <script>
        let vm = new Vue({
            el: "#app",
            data: {
                hello: "<h1>大家好</h1>"
            }
        })
    </script>
    
</body>
</html>

效果: 

并且不会出现插值闪烁,当没有数据时,会显示空白或者默认数据。 

5.2v-bind

html 属性不能使用双大括号形式绑定,我们使用 v-bind 指令给 HTML 标签属性绑定值;而且在将 `v-bind` 用于 `class` `style` 时, Vue.js 做了专门的增强。
1 )、绑定 class
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>

    <!-- 给html标签的属性绑定 -->
    <div id="app"> 

        <!-- class,style  {class名:加上?}-->
        <span v-bind:class="{active:isActive,'text-danger':hasError}">你好</span>

    </div>

    <script src="../node_modules/vue/dist/vue.js"></script>

    <script>
        let vm = new Vue({
            el:"#app",
            data:{
                link: "http://www.baidu.com",
                isActive:true,
                hasError:true
            }
        })
    </script>

</body>
</html>

2)、绑定 style 

`v-bind:style` 的对象语法十分直观,看着非常像 CSS ,但其实是一个 JavaScript 对象。 style属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case ,这种方式记得用单引号括起来) 来命名。
例如: font-size-->fontSize
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>

    <!-- 给html标签的属性绑定 -->
    <div id="app"> 

        <!-- class,style  {class名:加上?}-->
        <span v-bind:class="{active:isActive,'text-danger':hasError}"
          :style="{color: color1,fontSize: size}">你好</span>

    </div>

    <script src="../node_modules/vue/dist/vue.js"></script>

    <script>
        let vm = new Vue({
            el:"#app",
            data:{
                link: "http://www.baidu.com",
                isActive:true,
                hasError:true,
                color1:'red',
                size:'36px'
            }
        })
    </script>

</body>
</html>

结果:<div style="color: red; font-size: 36px;"></div> 

3)、绑定其他任意属性 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>

<!-- 给html标签的属性绑定 -->
<div id="app">

    <a v-bind:href="link">gogogo</a>

    <!-- class,style  {class名:加上?}-->
    <span v-bind:class="{active:isActive,'text-danger':hasError}"
          :style="{color: color1,fontSize: size}" v-bind:user="userName">>你好</span>
    
</div>

<script src="../node_modules/vue/dist/vue.js"></script>

<script>
    let vm = new Vue({
        el:"#app",
        data:{
            link: "http://www.baidu.com",
            isActive:true,
            hasError:true,
            color1:'red',
            size:'36px',
            userName: 'zhangsan'
        }
    })
</script>

</body>
</html>
效果:
<div id="app" user="zhangsan" style="color: red; font-size: 36px;"></div>

4)、v-bind 缩写 

    <span :class="{active:isActive,'text-danger':hasError}"
          :style="{color: color1,fontSize: size}"
          :user="userName">你好</span>

5.3v-model

刚才的 v-text v-html v-bind 可以看做是单向绑定,数据影响了视图渲染,但是反过来就不行。接下来学习的 v-model 双向绑定,视图( View )和模型( Model )之间会互相影响。
既然是双向绑定,一定是在视图中可以修改数据,这样就限定了视图的元素类型。目前
v-model 的可使用元素有:
  • input
  • select
  • textarea
  • checkbox
  • radio
  • componentsVue 中的自定义组件)
基本上除了最后一项,其它都是表单的输入项。
示例:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>

    <!-- 表单项,自定义组件 -->
    <div id="app">

        精通的语言:
            <input type="checkbox" v-model="language" value="Java"> java<br/>
            <input type="checkbox" v-model="language" value="PHP"> PHP<br/>
            <input type="checkbox" v-model="language" value="Python"> Python<br/>
        选中了 {{language.join(",")}}
    </div>
    
    <script src="../node_modules/vue/dist/vue.js"></script>

    <script>
        let vm = new Vue({
            el:"#app",
            data:{
                language: []
            }
        })
    </script>

</body>
</html>

 多个`CheckBox`对应一个 model 时,model 的类型是一个数组,单个 checkbox 值默认是boolean 类型

  • radio 对应的值是 input value
  • `text` `textarea` 默认对应的 model 是字符串
  • `select`单选对应字符串,多选对应也是数组

效果: 

5.4v-on

1) 、基本用法
v-on 指令用于给页面元素绑定事件。
语法: v-on: 事件名 ="js 片段或函数名 "
示例:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <!--事件中直接写 js 片段-->
    <button v-on:click="num++">点赞</button>
    <!--事件指定一个回调函数,必须是 Vue 实例中定义的函数-->
    <button v-on:click="decrement">取消</button>
    <h1>有{{ num }}个赞</h1>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    let vm = new Vue({
        el: "#app",
        data: {
            num: 100
        },
        methods: {
            decrement() {
                this.num--; //要使用 data 中的属性,必须 this.属性名
            }
        }
    })
</script>
</body>
</html>

另外,事件绑定可以简写,例如`v-on:click='add'`可以简写为`@click='add'`

2)、事件修饰符

在事件处理程序中调用event.preventDefault()或event.stopPropagation()是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理DOM事件细节。

为了解决这个问题,Vue.js为`v-on` 提供了事件修饰符。修饰符是由点开头的指令后缀来表示的。

  • .stop:阻止事件冒泡到父元素
  • .prevent:阻止默认事件发生
  • .capture:使用事件捕获模式
  • .self:只有元素自身触发事件才执行。(冒泡或捕获的都不执行)
  • .once:只执行一次
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <!--右击事件,并阻止默认事件发生-->
    <button v-on:contextmenu.prevent="num++">点赞</button>
    <br/>
    <!--右击事件,不阻止默认事件发生-->
    <button v-on:contextmenu="decrement($event)">取消</button>
    <br/>
    <h1>有{{ num }}个赞</h1>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    let app = new Vue({
        el: "#app",
        data: {
            num: 100
        },
        methods: {
            decrement(ev) {
                // ev.preventDefault();
                this.num--;
            }
        }
    })
</script>
</body>
</html>

 效果:右键“点赞”,不会触发默认的浏览器右击事件;右键“取消”,会触发默认的浏览器右击事件)

3) 、按键修饰符
在监听键盘事件时,我们经常需要检查常见的键值。 Vue 允许为 `v-on` 在监听键盘事件时添加按键修饰符:
<!--只有在keyCode是13时调用vm.submit()-->
<input v-on:keyup.13="submit">

 记住所有的keyCode比较困难,所以Vue为最常用的按键提供了别名:

  <!--同上-->
  <input v-on:keyup.enter ="submit">
  <!--缩写语法-->
  <input @keyup.enter ="submit">

 全部的按键别名:

  • .enter
  • .tab
  • .delete
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

 4)、组合按钮

可以用如下修饰符来实现仅在按下键时才出发鼠标或键盘事件的监听器。

  • .ctrl
  • .alt
  • .shift
  <!--Alt + C-->
  <input @keyup.alt.67="clear">
  <!--Ctrl + Click-->
  <div @click.ctrl="doSomething">Do something</div>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div id="app">
                
        <!--事件中直接写js片段-->
        <button v-on:click="num++">点赞</button>
        <!--事件指定一个回调函数,必须是Vue实例中定义的函数-->
        <button @click="cancle">取消</button>
        <!--  -->
        <h1>有{{num}}个赞</h1>


        <!-- 事件修饰符 -->
        <div style="border: 1px solid red;padding: 20px;" v-on:click.once="hello">
            大div
            <div style="border: 1px solid blue;padding: 20px;" @click.stop="hello">
                小div <br />
                <a href="http://www.baidu.com" @click.prevent.stop="hello">去百度</a>
            </div>
        </div>



        <!-- 按键修饰符: -->
        <input type="text" v-model="num" v-on:keyup.up="num+=2" @keyup.down="num-=2" @click.ctrl="num=10"><br />

        提示:

    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>

    <script>
        new Vue({
            el:"#app",
            data:{
                num: 1
            },
            methods:{
                cancle(){
                    this.num--;
                },
                hello(){
                    alert("点击了")
                }
            }
        })
    </script>
</body>

</html>

5.5v-for  

遍历数据渲染页面是非常常用的需求, Vue 中通过 v-for 指令来实现。
1) 、遍历数组
语法: v-for="item in items"
  • items:要遍历的数组,需要在 vue data 中定义好。
  • item:迭代得到的当前正在遍历的元素

示例: 

<div id="app">
    <ul>
        <li v-for="user in users">
            {{user.name}} - {{user.gender}} - {{user.age}}
        </li>
    </ul>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    let app = new Vue({
        el: "#app",
        data: {
            users: [
                { name: '柳岩', gender: '女', age: 21 },
                { name: '张三', gender: '男', age: 18 },
                { name: '范冰冰', gender: '女', age: 24 },
                { name: '刘亦菲', gender: '女', age: 18 },
                { name: '古力娜扎', gender: '女', age: 25 }
            ]
        },
})
</script>

 效果:

2) 、数组角标
在遍历的过程中,如果我们需要知道数组角标,可以指定第二个参数:
语法: v-for="(item,index) in items"
  • items:要迭代的数组
  • item:迭代得到的数组元素别名
  • index:迭代到的当前元素索引,从 0 开始。
示例:
<div id="app">
    <ul>
        <li v-for="user in users">
            {{user.name}} - {{user.gender}} - {{user.age}}
        </li>
    </ul>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    let app = new Vue({
        el: "#app",
        data: {
            users: [
                { name: '柳岩', gender: '女', age: 21 },
                { name: '张三', gender: '男', age: 18 },
                { name: '范冰冰', gender: '女', age: 24 },
                { name: '刘亦菲', gender: '女', age: 18 },
                { name: '古力娜扎', gender: '女', age: 25 }
            ]
        },
    })
</script>

效果: 

3) 、遍历对象
v-for 除了可以迭代数组,也可以迭代对象。语法基本类似
语法:
v-for="value in object"
v-for="(value,key) in object"
v-for="(value,key,index) in object"
  • 1 个参数时,得到的是对象的属性值
  • 2 个参数时,第一个是属性值,第二个是属性名
  • 3 个参数时,第三个是索引,从 0 开始

 示例:

<div id="app">
    <ul>
        <li v-for="(value, key, index) in user">
            {{index + 1}}. {{key}} - {{value}}
        </li>
    </ul>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    let vm = new Vue({
        el: "#app",
        data: {
            user: { name: '张三', gender: '男', age: 18 }
        }
    })
</script>

效果: 

 

4) Key
用来标识每一个元素的唯一特征,这样 Vue 可以使用“就地复用”策略 有效的提高渲染的 效率。
示例:
<ul>
    <li v-for="(item,index) in items" :key=”index”></li>
</ul>
<ul>
    <li v-for="item in items" :key=”item.id”></li>
</ul>

最佳实践: 

如果 items 是数组,可以使用 index 作为每个元素的唯一标识
如果 items 是对象数组,可以使用 item.id 作为每个元素的唯一标识

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

    <div id="app">
        <ul>
            <li v-for="(user,index) in users" :key="user.name" v-if="user.gender == '女'">
                <!-- 1、显示user信息:v-for="item in items" -->
               当前索引:{{index}} ==> {{user.name}}  ==>   {{user.gender}} ==>{{user.age}} <br>
                <!-- 2、获取数组下标:v-for="(item,index) in items" -->
                <!-- 3、遍历对象:
                        v-for="value in object"
                        v-for="(value,key) in object"
                        v-for="(value,key,index) in object" 
                -->
                对象信息:
                <span v-for="(v,k,i) in user">{{k}}=={{v}}=={{i}};</span>
                <!-- 4、遍历的时候都加上:key来区分不同数据,提高vue渲染效率 -->
            </li>

            
        </ul>

        <ul>
            <li v-for="(num,index) in nums" :key="index"></li>
        </ul>
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>
    <script>         
        let app = new Vue({
            el: "#app",
            data: {
                users: [{ name: '柳岩', gender: '女', age: 21 },
                { name: '张三', gender: '男', age: 18 },
                { name: '范冰冰', gender: '女', age: 24 },
                { name: '刘亦菲', gender: '女', age: 18 },
                { name: '古力娜扎', gender: '女', age: 25 }],
                nums: [1,2,3,4,4]
            },
        })
    </script>
</body>

</html>

5.6v-if v-show

1) 、基本用法
v-if ,顾名思义,条件判断。当得到结果为 true 时,所在的元素才会 被渲染
v-show ,当得到结果为 true 时,所在的元素才会 被显示
语法: v-if=" 布尔表达式 ", v-show=" 布尔表达式 ",
示例:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <!-- 
        v-if,顾名思义,条件判断。当得到结果为true时,所在的元素才会被渲染。
        v-show,当得到结果为true时,所在的元素才会被显示。 
    -->
    <div id="app">
        <button v-on:click="show = !show">点我呀</button>
        <!-- 1、使用v-if显示 -->
        <h1 v-if="show">if=看到我....</h1>
        <!-- 2、使用v-show显示 -->
        <h1 v-show="show">show=看到我</h1>
    </div>

    <script src="../node_modules/vue/dist/vue.js"></script>
        
    <script>
        let app = new Vue({
            el: "#app",
            data: {
                show: true
            }
        })
    </script>

</body>

</html>

 2)、与 v-for 结合

v-if v-for 出现在一起时, v-for 优先级更高。也就是说,会先遍历,再判断条件。
修改 v-for 中的案例,添加 v-if
<ul>
    <li v-for="(user, index) in users" v-if="user.gender == '女'">
        {{index + 1}}. {{user.name}} - {{user.gender}} - {{user.age}}
    </li>
</ul>

 效果:只显示女性

5.7v-else v-else-if

v-else 元素必须紧跟在带 `v-if` 或者 `v-else-if` 的元素的后面,否则它将不会被识别。
示例:
<div id="app">
    <button v-on:click="random=Math.random()">点我呀
    </button><span>{{random}}</span>
    <h1 v-if="random >= 0.75">
        看到我啦?!v-if >= 0.75
    </h1>
    <h1 v-else-if="random > 0.5">
        看到我啦?!v-else-if > 0.5
    </h1>
    <h1 v-else-if="random > 0.25">
        看到我啦?!v-else-if > 0.25
    </h1>
    <h1 v-else>
        看到我啦?!v-else
    </h1>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    let app = new Vue({
        el: "#app",
        data: {
            random: 1
        }
    })
</script>

6、计算属性和侦听器

1) 、计算属性( computed
某些结果是基于之前数据实时计算出来的,我们可以利用计算属性。来完成
示例:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <!-- 某些结果是基于之前数据实时计算出来的,我们可以利用计算属性。来完成 -->
        <ul>
            <li>西游记; 价格:{{xyjPrice}},数量:<input type="number" v-model="xyjNum"> </li>
            <li>水浒传; 价格:{{shzPrice}},数量:<input type="number" v-model="shzNum"> </li>
            <li>总价:{{totalPrice}}</li>
            {{msg}}
        </ul>
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>

    <script>
        //watch可以让我们监控一个值的变化。从而做出相应的反应。
        new Vue({
            el: "#app",
            data: {
                xyjPrice: 99.98,
                shzPrice: 98.00,
                xyjNum: 1,
                shzNum: 1,
                msg: ""
            },
            computed: {
                totalPrice(){
                    return this.xyjPrice*this.xyjNum + this.shzPrice*this.shzNum
                }
            } 
        })
    </script>

</body>

</html>

 效果:只要依赖的属性发生变化,就会重新计算这个属性

2) 、侦听( watch
watch 可以让我们监控一个值的变化。从而做出相应的反应。
示例

<div id="app">
    <ul>
        <li>西游记:价格{{xyjPrice}},数量:
        <input type="number" v-model="xyjNum"></li>
        <li>水浒传:价格{{shzPrice}},数量:
        <input type="number" v-model="shzNum"></li>
        <li>总价:{{totalPrice}}</li>
        {{msg}}
    </ul>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    let app = new Vue({
        el: "#app",
        data: {
            xyjPrice: 56.73,
            shzPrice: 47.98,
            xyjNum: 1,
            shzNum: 1,
            msg:""
        },
        computed: {
            totalPrice(){
                return this.xyjPrice*this.xyjNum + this.shzPrice*th
                is.shzNum;
            }
        },
        watch: {
            xyjNum(newVal, oldVal){
                if(newVal >= 3){
                    this.msg = "西游记没有更多库存了";
                    this.xyjNum = 3;
                }else{
                      this.msg = "";
                }
            }
        }
    })
</script>

 效果:

3) 、过滤器( filters
过滤器不改变真正的 `data` ,而只是改变渲染的结果,并返回过滤后的版本。在很多不同的情况
下,过滤器都是有用的,比如尽可能保持 API 响应的干净,并在前端处理数据的格式。
示例:展示用户列表性别显示男女
<body>
    <div id="app">
        <table>
            <tr v-for="user in userList">
                <td>{{user.id}}</td>
                <td>{{user.name}}</td>
                <!-- 使用代码块实现,有代码侵入 -->
                <td>{{user.gender===1? "男":"女"}}</td>
            </tr>
        </table>
    </div>
</body>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
    let app = new Vue({
        el: "#app",
            data: {
                userList: [
                    { id: 1, name: 'jacky', gender: 1 },
                    { id: 2, name: 'peter', gender: 0 }
                ]
            }
    });
</script>
(1) 、局部过滤器
注册在当前 vue 实例中,只有当前实例能用
let app = new Vue({
    el: "#app",
    data: {
        userList: [
            { id: 1, name: 'jacky', gender: 1 },
            { id: 2, name: 'peter', gender: 0 }
        ]
    },
    // filters 定义局部过滤器,只可以在当前 vue 实例中使用
    filters: {
        genderFilter(gender) {
            return gender === 1 ? '男~' : '女~'
        }
    }
});
<!-- | 管道符号:表示使用后面的过滤器处理前面的数据 -->
<td>{{user.gender | genderFilter}}</td>
(2) 、全局过滤器
// 在创建 Vue 实例之前全局定义过滤器:
Vue.filter('capitalize', function (value) {
    return value.charAt(0).toUpperCase() + value.slice(1)
})
// 任何 vue 实例都可以使用:
<td>{{user.name | capitalize}}</td>
过滤器常用来处理文本格式化的操作。过滤器可以用在两个地方: 双花括号插值和 v-bind 表达式
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <!-- 过滤器常用来处理文本格式化的操作。过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 -->
    <div id="app">
        <ul>
            <li v-for="user in userList">
                {{user.id}} ==> {{user.name}} ==> {{user.gender == 1?"男":"女"}} ==>
                {{user.gender | genderFilter}} ==> {{user.gender | gFilter}}
            </li>
        </ul>
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>

    <script>

        Vue.filter("gFilter", function (val) {
            if (val == 1) {
                return "男~~~";
            } else {
                return "女~~~";
            }
        })

        let vm = new Vue({
            el: "#app",
            data: {
                userList: [
                    { id: 1, name: 'jacky', gender: 1 },
                    { id: 2, name: 'peter', gender: 0 }
                ]
            },
            filters: {
                 filters 定义局部过滤器,只可以在当前vue实例中使用
                genderFilter(val) {
                    if (val == 1) {
                        return "男";
                    } else {
                        return "女";
                    }
                }
            }
        })
    </script>
</body>

</html>

效果:

7、组件化

在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。
例如可能会有相同的头部导航。
但是如果每个页面都独自开发,这无疑增加了我们开发的成本。所以我们会把页面的不同部分拆分
成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。
vue 里,所有的 vue 实例都是组件

1) 、全局组件
我们通过 Vue component 方法来定义一个全局组件。
<div id="app">
<!--使用定义好的全局组件-->
<counter></counter>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
    // 定义全局组件,两个参数:1,组件名称。2,组件参数
    Vue.component("counter", {
        template: '<button v-on:click="count++">你点了
        我 {{ count }} 次,我记住了.</button>',
        data() {
            return {
                count: 0
            }
        }
    })
    let app = new Vue({
        el: "#app"
    })
</script>

  • 组件其实也是一个Vue实例,因此它在定义时也会接收:data、methods、生命周期函数等 
  • 不同的时组件不会与页面的元素绑定,否则就无法复用了,因此没了el属性。
  • 但是组件渲染需要html模板,所以增加了template属性,值就是HTML模板
  • 全局组件定义完毕,任何vue实例都可以直接在HTML中通过组件名称来使用组件了
  • data必须是一个函数,不再是一个对象。
2) 、组件的复用
定义好的组件,可以任意复用多次:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

    <div id="app">
        <button v-on:click="count++">我被点击了 {{count}} 次</button>

        <counter></counter>
        <counter></counter>
        <counter></counter>
        <counter></counter>
        <counter></counter>

        <button-counter></button-counter>
    </div>
    <script src="../node_modules/vue/dist/vue.js"></script>


    <script>
        //1、全局声明注册一个组件
        Vue.component("counter", {
            template: `<button v-on:click="count++">我被点击了 {{count}} 次</button>`,
            data() {
                return {
                    count: 1
                }
            }
        });

        //2、局部声明一个组件
        const buttonCounter = {
            template: `<button v-on:click="count++">我被点击了 {{count}} 次~~~</button>`,
            data() {
                return {
                    count: 1
                }
            }
        };

        new Vue({
            el: "#app",
            data: {
                count: 1
            },
            components: {
                'button-counter': buttonCounter
            }
        })
    </script>
</body>

</html>
组件的 data 属性必须是函数!
一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝;
否则:

3) 、局部组件
一旦全局注册,就意味着即便以后你不再使用这个组件,它依然会随着 Vue 的加载而加载。
因此,对于一些并不频繁使用的组件,我们会采用局部注册。
我们先在外部定义一个对象,结构与创建组件时传递的第二个参数一致:
const counter = {
    template: '<button v-on:click="count++">你点了
    我 {{ count }} 次,我记住了.</button>',
    data() {
        return {
            count: 0
        }
    }
};
然后在 Vue 中使用它:
let app = new Vue({
    el: "#app",
    components: {
        counter: counter // 将定义的对象注册为组件
    }
})
  • components 就是当前 vue 对象子组件集合。
    • 其 key 就是子组件名称
    • 其值就是组件对象名
  • 效果与刚才的全局注册是类似的,不同的是,这个 counter 组件只能在当前的 Vue 实例中使用

简写:

let app = new Vue({
    el: "#app",
    components: {
        counter // 将定义的对象注册为组件
    }
})

8、生命周期钩子函数

1) 、生命周期
每个 Vue 实例在被创建时都要经过一系列的初始化过程 :创建实例,装载模板,渲染模板等等。Vue 为生命周期中的每个状态都设置了钩子函数(监听函数)。每当 Vue 实例处于不同的生命周期时,对应的函数就会被触发调用。
生命周期:你不需要立马弄明白所有的东西。

2) 、钩子函数
  • beforeCreated:我们在用 Vue 时都要进行实例化,因此,该函数就是在 Vue 实例化时调 用,也可以将他理解为初始化函数比较方便一点,在 Vue1.0 时,这个函数的名字就是init
  • created:在创建实例之后进行调用。
  • beforeMount:页面加载完成,没有渲染。如:此时页面还是{{name}}
  • mounted:我们可以将他理解为原生 js 中的 window.οnlοad=function({.,.}),或许大家也在jquery,所以也可以理解为 jquery 中的$(document).ready(function(){….}),他的功能就是:在 dom 文档渲染完毕之后将要执行的函数,该函数在 Vue1.0 版本中名字为compiled。 此时页面中的{{name}}已被渲染成张三
  • beforeDestroy:该函数将在销毁实例前进行调用 。
  • destroyed:改函数将在销毁实例时进行调用。
  • beforeUpdate:组件更新之前。
  • updated:组件更新之后。
示例
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <span id="num">{{num}}</span>
        <button @click="num++">赞!</button>
        <h2>{{name}},有{{num}}个人点赞</h2>
    </div>

    <script src="../node_modules/vue/dist/vue.js"></script>
    
    <script>
        let app = new Vue({
            el: "#app",
            data: {
                name: "张三",
                num: 100
            },
            methods: {
                show() {
                    return this.name;
                },
                add() {
                    this.num++;
                }
            },
            beforeCreate() {
                console.log("=========beforeCreate=============");
                console.log("数据模型未加载:" + this.name, this.num);
                console.log("方法未加载:" + this.show());
                console.log("html模板未加载:" + document.getElementById("num"));
            },
            created: function () {
                console.log("=========created=============");
                console.log("数据模型已加载:" + this.name, this.num);
                console.log("方法已加载:" + this.show());
                console.log("html模板已加载:" + document.getElementById("num"));
                console.log("html模板未渲染:" + document.getElementById("num").innerText);
            },
            beforeMount() {
                console.log("=========beforeMount=============");
                console.log("html模板未渲染:" + document.getElementById("num").innerText);
            },
            mounted() {
                console.log("=========mounted=============");
                console.log("html模板已渲染:" + document.getElementById("num").innerText);
            },
            beforeUpdate() {
                console.log("=========beforeUpdate=============");
                console.log("数据模型已更新:" + this.num);
                console.log("html模板未更新:" + document.getElementById("num").innerText);
            },
            updated() {
                console.log("=========updated=============");
                console.log("数据模型已更新:" + this.num);
                console.log("html模板已更新:" + document.getElementById("num").innerText);
            }
        });
    </script>
</body>

</html>

效果:

9vue 模块化开发

9.1、全局安装webpack

npm install webpack -g

9.2、全局安装vue脚手架

npm install -g @vue/cli-init

9.3、初始化vue项目

vue init webpack appnamevue 脚手架使用 webpack 模板初始化一个 appname 项目

9.4、启动vue项目

项目的package.json 只能够有scripts,代表我们能执行的命令

npm start = npm run dev :启动项目

npm run build: 将项目打包

遇到的问题:

'vue' 不是内部或外部命令,也不是可运行的程序 或批处理文件

解决办法:

安装:vue

npm install -g vue
npm install -g  @vue/cli 

然后就出现标题的问题了
解决方案如下:

1.npm config list 查看一下npm 的配置信息,下图

​​

然后找到这个红色线里面的路径,看看有没有vue.md的文件:

然后把这个路径添加的系统环境变量的path里面,如下图:

​​

最后在来检查一波

vue --version 
--3.8.2

9.5、模块化开发

1) 、项目结构

 

  • 运行流程
    • 进入页面首先加载 index.html main.js 文件。
    • main.js 导入了一些模块【vueapprouter】,并且创建 vue 实例,关联 index.html页面的<div id=”app”>元素。使用了 router,导入了 App 组件。并且使用<App/>标签引用了这个组件
    • 第一次默认显示 App 组件。App 组件有个图片和<router-view>,所以显示了图片。
    • 但是由于<router-view>代表路由的视图,默认是访问/#/路径(router 路径默认使用 HASH 模式)。在 router 中配置的/是显示 HelloWorld 组件。
    • 所以第一次访问,显示图片和 HelloWorld 组件。
    • 我们尝试自己写一个组件,并且加入路由。点击跳转。需要使用<router-link to="/foo">Go to Foo</router-link>标签

 2)Vue 单文件组件

Vue 单文件组件模板有三个部分;
<template>
    <div class="hello">
        <h1>{{ msg }}</h1>
    </div>
</template>
<script>
    export default {
        name: 'HelloWorld',
        data () {
        return {
             msg: 'Welcome to Your Vue.js App'
        }
    }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
    h1, h2 {
        font-weight: normal;
    }
</style>
Template :编写模板
Script vue 实例配置
Style :样式
3) vscode 添加用户代码片段(快速生成 vue 模板)
文件 --> 首选项 --> 用户代码片段 --> 点击新建代码片段 -- 取名 vue.json 确定
{
"生成 vue 模板": {
"prefix": "vue",
"body": [
"<template>",
"<div></div>",
"</template>",
"",
"<script>",
"//这里可以导入其他文件(比如:组件,工具 js,第三方插件 js,json
文件,图片文件等等)",
"//例如:import 《组件名称》 from '《组件路径》';",
"",
"export default {",
"//import 引入的组件需要注入到对象中才能使用",
"components: {},",
"props: {},",
"data() {",
"//这里存放数据",
"return {",
"",
"};",
"},",
"//计算属性 类似于 data 概念",
"computed: {},",
"//监控 data 中的数据变化",
"watch: {},",
"//方法集合",
"methods: {",
"",
"},",
"//生命周期 - 创建完成(可以访问当前 this 实例)",
"created() {",
"",
"},",
"//生命周期 - 挂载完成(可以访问 DOM 元素)",
"mounted() {",
"",
"},",
"beforeCreate() {}, //生命周期 - 创建之前",
"beforeMount() {}, //生命周期 - 挂载之前",
"beforeUpdate() {}, //生命周期 - 更新之前",
"updated() {}, //生命周期 - 更新之后",
"beforeDestroy() {}, //生命周期 - 销毁之前",
"destroyed() {}, //生命周期 - 销毁完成",
"activated() {}, //如果页面有 keep-alive 缓存功能,这个函数会触发
",
"}",
"</script>",
"<style lang='scss' scoped>",
"//@import url($3); 引入公共 css 类",
"$4",
"</style>"
],
"description": "生成 vue 模板"
}
}
4) 、导入 element-ui 快速开发
1 、安装 element-ui
2 、在 main.js 中引入 element-ui 就可以全局使用了。
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)

3、将 App.vue 改为 element-ui 中的后台布局

4 、添加测试路由、组件,测试跳转逻辑
  • (1) 、参照文档 el-menu 添加 router 属性
  • (2) 、参照文档 el-menu-item 指定 index 需要跳转的地址

官网: Element - The world's most popular Vue UI framework

10、Babel

Babel 是一个 JavaScript 编译器,我们可以使用 es 的最新语法编程,而不用担心浏览器兼
容问题。他会自动转化为浏览器兼容的代码

11、Webpack

自动化项目构建工具。 gulp 也是同类产品

  • 97
    点赞
  • 398
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值