前言
- 学习视频:Java项目《谷粒商城》架构师级Java项目实战,对标阿里P6-P7,全网最强
- 学习文档:
-
接口文档:谷粒商城接口文档
- 本内容仅用于个人学习笔记,如有侵扰,联系删除
一、项目简介
1、项目背景
1.1、电商模式
1.2、谷粒商城
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
- 熟悉 git,maven
- 熟悉 linux,redis,docker 基本操作
- 了解 html,css,js,vue
- 熟练使用 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处理逻辑】
8、API 网关
客户端发送请求到服务器路途中,设置一个网关,请求都先到达网关,网关对请求进行统一认证(合法非法)和处理等操作。他是安检。
在微服务架构中,API gateway作为整体架构的重要组件,它抽象了微服务中都需要的公共功能,同时提供了客户端负载均衡,服务自动熔断,灰度发布,统一认证,限流流控,日志统计等丰富的功能,帮助我们解决很多API管理难题。
三、环境搭建
1、安装 linux 虚拟机
下载CentOS7的镜像
下载地址:Download
VMware中安装CentOS7请参考
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 安装文档:https://docs.docker.com/engine/install/centos/
docker仓库:https://hub-stage.docker.com/
# 安装前先更新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
# 安装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
# 启动docker
sudo systemctl start docker
# 设置开机自启动
sudo systemctl enable docker
# 检查docker版本
docker -v
# 检查docker有没有下载镜像
sudo docker images
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
3、docker 安装 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
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;
4、docker 安装 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.1、Maven
在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.2、Idea&VsCode
1、idea 安装 lombok、mybatisx 插件
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
下载git客户端,右键桌面Git GUI/bash Here。进入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、逆向工程使用
- 导入项目逆向工程
- 下载人人开源后台管理系统脚手架工程
-
导入工程,创建数据库
-
修改工程 shiro 依赖为 SpringSecurity
-
删除部分暂时不需要的业务
-
- 下载人人开源后台管理系统 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、创建各个微服务项目
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不成功
可以参考谷粒商城 - 个人笔记(基础篇一)
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
克隆到本地:
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/”
9、安装Node.js
1、官网下载安装 node.js,并使用 node -v 检查版本
命令行输入node -v
检查配置好了
node -v
npm config set registry http://registry.npm.taobao.org/
3、大家如果 npm install 安装依赖出现 chromedriver 之类问题,先在项目里运行下面命令
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简介
- 注册中心:
- 配置中心:
- 网关:
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 Boot | Spring Cloud | Spring Cloud Alibaba | Nocos | JDK |
---|---|---|---|---|
2.7.7 | 2021.0.5 | 2021.0.5.0 | 2.2.0 | 1.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
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
下载解压
如果是在docker安装的nacos可以参考谷粒商城 - 个人笔记(基础篇一)
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 中
-
首先,修改 pom.xml 文件,引入 Nacos Discovery Starter。放到common的pom.xml文件里
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
-
在应用的 /src/main/resources/application.properties 配置文 件中配置 Nacos Server 地址
# 指定应用程序的名称 spring.application.name=gulimall-product # 配置nacos注册中心地址 spring.cloud.nacos.discovery.server-addr=127.0.01:8848
- 使用 @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-providerserver.port=8000
11.1.5、注册更多的服务上去,测试使用 feign 远程调用
Nacos 使用三步
- 导包 nacos-discovery
- 写配置,指定 nacos 地址,指定应用的名字
- 开启服务注册发现功能@EnableDiscoveryClient
Nacos 具体流程:
1)、启动 Nacos Server
- 首先需要获取 Nacos Server,支持直接下载和源码构建两种方式。
- 直接下载:Nacos Server 下载页。解压zip,双击bin里的startup.cmd就启动了。
- 源码构建:进入 Nacos Github 项目页面,将代码 git clone 到本地自行编译打包,参考此文档。推荐使用源码构建方式以获取最新版本
- 启动 Server,进入解压后文件夹或编译打包好的文件夹,找到如下相对文件夹 nacos/bin,并对照操作系统实际情况之下如下命令。
- Linux/Unix/Mac 操作系统,执行命令
sh startup.sh -m standalone
- Windows 操作系统,执行命令
cmd startup.cmd
- Linux/Unix/Mac 操作系统,执行命令
2)、应用启动
- 增加配置,在 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
- 启动应用,支持 IDE 直接启动和编译打包后启动。
- IDE直接启动:找到 nacos-discovery-provider-example 项目的主类
ProviderApplication
,执行 main 方法启动应用。 - 打包编译后启动:在 nacos-discovery-provider-example 项目中执行
mvn clean package
将工程编译打包,然后执行java -jar nacos-discovery-provider-example.jar
启动应用。
- IDE直接启动:找到 nacos-discovery-provider-example 项目的主类
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 使用三步
- 导包 openfeign
- 开启@EnableFeignClients 功能
- 编写接口,进行远程调用
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>
在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网关。
官网地址: https://spring.io/projects/spring-cloud-gateway
参考手册:https://cloud.spring.io/spring-cloud-gateway/2.2.x/reference/html/
- 基于 Spring5,支持响应式编程和 SpringBoot2.0
- 支持使用任何请求属性进行路由匹配
- 特定于路由的断言和过滤器
- 集成 Hystrix 进行断路保护
- 集成服务发现功能
- 易于编写 Predicates 和 Filters
- 支持请求速率限制
- 支持路径重写
- 客户端会多次请求不同的微服务,增加了客户端的复杂性。
- 存在跨域请求,在一定场景下处理相对复杂。
- 认证复杂,每个服务都需要独立认证。
- 难以重构,随着项目的迭代,可能需要重新划分微服务。例如,可能将多个服务合并成一个或者将一个服务拆分成多个。如果客户端直接与微服务通信,那么重构将会很难实施。
- 某些微服务可能使用了防火墙 / 浏览器不友好的协议,直接访问会有一定的困难。
- 易于监控。可以在网关收集监控数据并将其推送到外部系统进行分析。
- 易于认证。可以在网关上进行认证,然后再将请求转发到后端的微服务,而无须在每个微服务中进行认证。
- 减少了客户端与各个微服务之间的交互次数。
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 将会对请求和响应进行修改处理。
一句话:满足某些断言(predicates)就路由到指定的地址(uri),使用指定的过滤器(filter)
11.3.3、使用
1)、HelloWorld
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- Cookie=mycookie,mycookievalue
- 各种 Predicates 同时存在于同一个路由时,请求必须同时满足所有的条件才被这个路由匹配。
- 一个请求满足多个路由的谓词条件时,请求只会被首个成功匹配的路由转发
创建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)
1、GatewayFilter
2、GlobalFilter
四、ES6
前后端对比
1、简介
2、什么是 ECMAScript
- web1.0 时代:
最初的网页以 HTML 为主,是纯静态的网页。网页是只读的,信息流只能从服务的到客户端单向流通。开发人员也只关心页面的样式和内容即可。
- web2.0 时代:
3、ES6 新特性
打开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
- `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)、箭头函数
一个参数时:
<!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、对象优化
- 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
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
<!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
<!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、模块化
- `export`命令用于规定模块的对外接口。
- `import`命令用于导入其他模块提供的功能。
const util = {
sum(a,b){
return a + b;
}
}
const util = {
sum(a,b){
return a + b;
}
}
export {util};
export const util = {
sum(a,b){
return a + b;
}
}
user.js
var name = "jack"
var age = 21
function add(a,b){
return a + b;
}
export {name,age,add}
// 无需声明对象的名字
export default {
sum(a,b){
return a + b;
}
}
import add from "./hello.js"
add.sum(1,2);
3)、import
main.js
import util from "./hello.js"
import {name,add} from "./user.js"
util.sum(1,2);
console.log(name);
add(1,3);
五、Vue
1、MVVM 思想
- M:即 Model,模型,包括数据和一些基本操作
- V:即 View,视图,页面渲染结果
- VM:即 View-Model,模型与视图间的双向操作(无需开发人员干涉)
- 只要我们 Model 发生了改变,View 上自然就会表现出来。
- 当用户修改了 View,Model 中的数据也会跟着改变。
2、Vue 简介
- 官网:https://cn.vuejs.org/
- 参考:https://cn.vuejs.org/v2/guide/
- Git 地址:https://github.com/vuejs
- 教程:https://v2.cn.vuejs.org/v2/guide/
3、入门案例
3.1、安装
- 直接 script 引入本地 vue 文件。需要通过官网下载 vue 文件。
- 通过 script 引入 CDN 代理。需要联网,生产环境可以使用这种方式
- 通过 npm 安装。这种方式也是官网推荐的方式,需要 nodejs 环境。
本课程就采用第三种方式
3.2、创建示例项目
3.3、HelloWorld
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>
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 定义的不同功能的指令。
4、概念
4.1、创建 Vue 实例
let app = new Vue({
});
4.2、模板或元素
<div id="app">
</div>
let vm = new Vue({
el: "#app"
})
4.3、数据
<div id="app">
<input type="text" v-model="name" />
</div>
let vm = new Vue({
el: "#app",
data: {
name: "刘德华"
}
})
- name 的变化会影响到`input`的值
- input 中输入的值,也会导致 vm 中的 name 发生改变
4.4、方法
<div id="app">
{
{num}}
<button v-on:click="add">加</button>
</div>
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:将数据输出到元素内部,如果输出的数据有 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.2、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>
<!-- 给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
<!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>
4)、v-bind 缩写
<span :class="{active:isActive,'text-danger':hasError}"
:style="{color: color1,fontSize: size}"
:user="userName">你好</span>
5.3、v-model
- input
- select
- textarea
- checkbox
- radio
- components(Vue 中的自定义组件)
<!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.4、v-on
<!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>
效果:右键“点赞”,不会触发默认的浏览器右击事件;右键“取消”,会触发默认的浏览器右击事件)
<!--只有在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.5、v-for
- 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>
效果:
- 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>
效果:
- 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>
效果:
<ul>
<li v-for="(item,index) in items" :key=”index”></li>
</ul>
<ul>
<li v-for="item in items" :key=”item.id”></li>
</ul>
最佳实践:
<!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.6、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 结合
<ul>
<li v-for="(user, index) in users" v-if="user.gender == '女'">
{
{index + 1}}. {
{user.name}} - {
{user.gender}} - {
{user.age}}
</li>
</ul>
效果:只显示女性
5.7、v-else 和 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、计算属性和侦听器
<!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>
效果:只要依赖的属性发生变化,就会重新计算这个属性
<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>
效果:
<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>
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>
// 在创建 Vue 实例之前全局定义过滤器:
Vue.filter('capitalize', function (value) {
return value.charAt(0).toUpperCase() + value.slice(1)
})
// 任何 vue 实例都可以使用:
<td>{
{user.name | capitalize}}</td>
<!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、组件化
<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必须是一个函数,不再是一个对象。
<!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>
const counter = {
template: '<button v-on:click="count++">你点了
我 {
{ count }} 次,我记住了.</button>',
data() {
return {
count: 0
}
}
};
let app = new Vue({
el: "#app",
components: {
counter: counter // 将定义的对象注册为组件
}
})
- components 就是当前 vue 对象子组件集合。
- 其 key 就是子组件名称
- 其值就是组件对象名
- 效果与刚才的全局注册是类似的,不同的是,这个 counter 组件只能在当前的 Vue 实例中使用
简写:
let app = new Vue({
el: "#app",
components: {
counter // 将定义的对象注册为组件
}
})
8、生命周期钩子函数
- 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>
效果:
9、vue 模块化开发
9.1、全局安装webpack
npm install webpack -g
9.2、全局安装vue脚手架
npm install -g @vue/cli-init
9.3、初始化vue项目
vue init webpack appname:vue 脚手架使用 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、模块化开发
- 运行流程
- 进入页面首先加载 index.html 和 main.js 文件。
- main.js 导入了一些模块【vue、app、router】,并且创建 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 单文件组件
<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>
{
"生成 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 模板"
}
}
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
3、将 App.vue 改为 element-ui 中的后台布局
- (1) 、参照文档 el-menu 添加 router 属性
- (2) 、参照文档 el-menu-item 指定 index 需要跳转的地址
官网: Element - The world's most popular Vue UI framework
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/107352.html