《谷粒商城》项目前期准备及前端基础

一、项目简介

1.项目背景

        gulimall(谷粒商城) 项目是一套B2C(Business-to-Customer)的电商项目,包括前台商城系统以及后台管理系统,基于 SpringCloud + SpringCloudAlibaba + MP实现,采用 Docker 容器化部署。
  • 前台商城系统包括:用户登录、注册、商品搜索、商品详情、购物车、下订单流程、秒杀活动等模块。
  • 后台管理系统包括:系统管理、商品系统、优惠营销、库存系统、订单系统、用户系统、内容管理等七大模块。

2.项目架构图

        

3.项目微服务划分

        

二、环境搭建和项目准备

1.安装Linux(VM+FinalShell)

2.虚拟机网络设置

3.Linux安装Docker

4.docker安装mysql

  • 从docker hub拉取mysql:5.7的镜像进行安装
  • 创建实例并启动
    docker run 
    -p 3306:3306  #端口映射,左虚拟机右容器,这样通过访问Linux虚拟机的3306端口,就能访问到容器里的3306端口的mysql了
    --name mysql \  #起的容器名叫mysql
    #-v:数据卷挂载,[宿主机]:[容器]
    -v /mydata/mysql/log:/var/log/mysql \  #将Linux中的/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  #后台运行,以mysql:5.7版本镜像运行
  • 修改MySQL配置
    [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
    修改后restart mysql容器

5.docker安装redis

  • 从docker hub拉取redis:5.0.5的镜像进行安装
  • 创建容器并启动
    mkdir -p /mydata/redis/conf
    touch /mydata/redis/conf/redis.conf
    
    docker run -p 6379:6379 --name redis -v /mydata/redis/data:/data \
    -v /mydata/redis/conf/redis.conf:/etc/redis/redis.conf \
    -d redis redis-server /etc/redis/redis.conf
  • 修改配置开启 Redis AOF持久化
    appendonly yes

6.统一开发环境

(1)JDK-1.8
(2)maven-3.6.1并配置阿里云镜像
(3)idea安装lombok和mybatisx插件
(4)vscode并安装插件
(5)配置git并设置SSH免密登录

(6)项目结构创建并提交到码云

  • 创建微服务:商品服务(product)、仓储服务(ware)、订单服务(order)、优惠券服务(coupon)、用户服务(member)
    微服务 端口号
    gulimall-coupon 7000
    gulimall-member
    8000
    gulimall-order
    9000
    gulimall-product
    12000
    gulimall-ware
    11000
  • 每个微服务项目的共同部分:
    • 技术集:springWeb、openFeign
    • 包名:com.zyb.gulimall.xxx
    • 模块名:gulimall-xxx
(7)数据库初始化
        分别创建上述微服务对应的数据库:gulimall_xms

7.创建后台管理系统

        使用码云人人开源项目中的renren-fastrenren-fast-vue来快速搭建后台管理系统及其前端管理功能。
  • renren-fastrenren-fast-vue克隆到本地
  • 将renren-fast聚合到gulimall项目中
  • 搭建renren-fast运行环境
    • 创建后台管理数据库gulimall_admin
    • 修改renren-fast的配置文件
    • 运行
  • 在VScode中运行renren-fast-vue,并测试

8.项目基本增删改查的生成

        使用人人开源项目中的renren-generator来快速生成项目基本的增删改查。这里以gulimall-product项目为例。
  • renren-generator克隆到本地
  • 将renren-generator聚合到gulimall项目中
  • 修改配置文件中的数据库信息(想给哪个微服务生成增删改查就连接哪个数据库,这里连接的是gulimall_psm)
  • 修改generator.properties文件中的配置信息
  • 运行,访问localhost:80
        
  • 这里我们全选,逆向生成所有表格的代码,解压出来是这样的:
        
  • 将上面的main文件夹复制到gulimall-product中的main。
  • 可以看到代码有很多报错的地方,这是因为有一些依赖和公共的工具类我们还没导入。我们创建一个gulimall-common项目,将每个微服务的公共依赖和类放在这里面,让每个微服务都去依赖它就行:
    • gulimall-common的pom中添加公共依赖

    • 将renren-fast中的公共工具类复制到gulimall-common

9.整合MP并测试gulimall-product项目

(1)整合MP
  • 导入MP依赖(已在gulimall-common中导入)和mysql驱动坐标mysql-connector-j
  • 配置数据库信息
    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver //根据mysql版本决定留不留cj
        url: jdbc:mysql://localhost:3306/db1?serverTimezone=UTC
        username: root
        password: ****
  • 配置全局生成策略控制,让每一个pojo都使用相同的主键生成策略
    mybatis-plus:
      global-config:
        db-config:
          id-type: auto
(2)测试

10.分布式组件

        

(1)SpringCloudAlibaba版本选择

  • 这里我的springboot是2.1.8.RELEASE,springcloud是Greenwich.SR3,所以springcloudalibaba选择2.1.0.RELEASE版本。
        
  • 在gulimall-common中导入springcloudalibaba 2.2.7.RELEASE版本依赖:
    <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>com.alibaba.cloud</groupId>
                    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                    <version>2.2.7.RELEASE</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
    </dependencyManagement>

(2)Nacos注册中心

  • 启动nacos服务:Nacos 本身就是一个 SprintBoot 项目,进入bin目录,执行命令直接启动nacos:
    ./startup.cmd -m standalone # 单机启动
  • 在gulimall-common中导入nacos客户端依赖,服务的注册发现(即用来将微服务注册到nacos注册中心,包括发现其他微服务)
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    【tips】因为每个微服务都需要注册到注册中心,即都需要这个公共依赖,所以直接把该依赖放到common中。以后有这种公共依赖都可以放到common中。
  • 在各个微服务中配置nacos服务地址微服务名称
    spring:
      cloud:
        nacos:
          discovery:
            server-addr: localhost:8848 # nacos服务地址
      application:
        name: gulimall-coupon
  • 上使用@EnableDiscoveryClient注解来务注册与发现能(把该微服务注册到nacos)
    @EnableDiscoveryClient
    @SpringBootApplication
    public class GulimallCouponApplication {

(3)Feign声明式远程调用

        比如member调用coupon中的方法。
  • 导入坐标:
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
  • 调用者member的启动类添加注释开启Feign功能
    @EnableFeignClients()
  • 在member中编写Feign客户端接口(用来基于 SpringMVC 的注解 @GetMapping 来声明远程调用的信息):
    @FeignClient("gulimall-coupon")//被调用者服务名
    public interface CouponFeignClient {
        //声明调用被调用服务的哪个请求的方法,所以这里既有完整请求路径"/coupon/coupon/member/list",又有对应的方法getMemberCoupons()
        @GetMapping("/coupon/coupon/member/list")
        public R getMemberCoupons();
    }
  • member调用coupon中的方法:
    @RequestMapping("/coupons")
    public R testFeigin(){
        MemberEntity memberEntity = new MemberEntity();
        memberEntity.setCity("beijing");
        
        //远程调用coupon服务的getMemberCoupons()方法
        R memberCoupons = couponFeignClient.getMemberCoupons();
        
        return R.ok().put("member",memberEntity).put("coupons",memberCoupons.get("coupons"));
    }
  • 调用流程:在浏览器输入localhost:8000/member/member/coupons后,会遇到couponFeignClient.getMemberCoupons()方法,然后去我们编写的couponFeignClient接口中找远程调用的信息:请求路径"/coupon/coupon/member/list"+方法getMemberCoupons(),来远程调用coupon服务。

(4)Nacos配置中心

        微服务的所有配置信息都可以在nacos配置中心配置,只需要在bootstrap.yml中说明要加载的配置文件信息即可。本项目使用nacos配置中心的规则:
            ①每个微服务创建自己的命名空间,使用配置分组来划分环境:dev/test/prod。
            ②不要将所有配置信息放在一个配置文件中,比如数据源的配置单独抽出来、mysql的、nacos的等都抽取成各自的配置文件,方便管理。
  • 在nacos中创建统一配置文件
  • 从nacos拉取配置
    • 在common中导入nacos-config坐标
      <!--nacos配置管理依赖-->
      <dependency>
          <groupId>com.alibaba.cloud</groupId>
          <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
      </dependency>
    • 创建 bootstrap.yml,配置nacos服务信息(这些配置信息决定了项目启动时去哪个nacos配置中心读取哪个配置文件)
      spring:
        application:
          name: gulimall-coupon # 服务名称
        cloud:
          nacos:
            server-addr: localhost:8848 # Nacos地址
            config:
              file-extension: yaml # 文件后缀
  • 动态获取配置
    • 在controller上使用@RefreshScope注解开启自动刷新配置(配置修改后不需要重启项目就能获取到)
      @RefreshScope //开启配置自动刷新,不需要重启项目
      @RestController
      @RequestMapping("coupon/coupon")
      public class CouponController {
    • 在变量声明上面使用@Value("${配置项}")注解获取配置文件中指定配置项的值
      @Value("${coupon.user.name}")
      private String name;
      @Value("${coupon.user.age}")
      private int age;
  • 可以使用命名空间实现配置隔离
    • 创建命名空间
    • 在微服务中配置要读取哪个命名空间下的配置

  • 可以使用分组实现同一配置文件的不同应用场景
    • 创建同一配置时指定分组
    • 在微服务中配置要读取哪个分组下的配置
  • ★同时加载多个配置文件:
        

(5)Gateway网关

        网关不光能进行权限控制,还支持路由和负载均衡以及限流控制!(用到再去笔记里看)

三、前端基础快速入门

1.ES6新特性

        ES6(ECMAScript 6.0)是浏览器脚本语言规范(标准),而各种我们熟知的 js 语言,如 JavaScript 则是规范的具体实现。类似与JDBC是规范,mysql各种驱动是具体实现。

(1)let 声明变量

        

(2)const声明常量(只读变量)

        

(3)解构表达式

  • 数组解构
        
  • 对象解构
        

(4)字符串扩展

  • ES6 为字符串扩展了几个新的 API:
    • includes():返回布尔值,表示是否包含参数字符串
    • startsWith():返回布尔值,表示是否以参数字符串开始
    • endsWith():返回布尔值,表示是否以参数字符串结尾

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

(5)函数优化

  • 函数参数默认值
        
  • 不定参数:不定参数用来表示不确定个数参数,形如...变量名,由...加上一个具名参数标识符组成。 具名参数只能放在参数列表的最后,并且有且只能有一个不定参数
        
  • 箭头函数
        
        

(6)对象优化

  • ES6 给 Object 拓展了许多新的方法:
    • keys(obj):获取对象的所有 key 形成的数组
    • values(obj):获取对象的所有 value 形成的数组
    • entries(obj):获取对象的所有 key 和 value 形成的二维数组。格式:[[k1,v1],[k2,v2],...]
    • assign(dest, ...src) :将多个 src 对象的值拷贝到 dest 中。(第一层为深拷贝,第二层为浅拷贝)

  • 声明对象简写
        
  • 对象的函数属性简写
        
  • 对象扩展运算符(...):用于取出参数对象所有可遍历属性然后拷贝到当前对象
        

(7)数组中新增了 map 和 reduce 方法

  • map():接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回。
        
  • 语法:arr.reduce(callback,[initialValue]) 
  • reduce 为数组中的每一个元素(不包括数组中被删除或从未被赋值的元素)依次执行回调函数,接收四个参数:初始值(或者上一次回调函数的返回值),当前元素值,当前索引,调用 reduce 的数组。
    • callback(执行数组中每个值的函数,包含四个参数)
      • previousValue(上一次调用回调返回的值,或者是提供的初始值initialValue)
      • currentValue (数组中当前被处理的元素)
      • index (当前元素在数组中的索引)
      • array (调用 reduce 的数组)
    • initialValue 作为第一次调用 callback 的第一个参数。

(8)promise

        JavaScript 中所有代码都是单线程执行的,导致 JavaScript 的所有网络操作、浏览器事件,都必须是异步执行。异步执行可以用回调函数实现。一旦有一连串的 ajax 请求,后面的请求依赖前面的请求结果,就需要层层嵌套。这种缩进和层层嵌套的方式,非常容易造成上下文代码混乱。
        案例:用户登录,并展示该用户的各科成绩。在页面发送两次请求:
  • 1. 查询用户,查询成功说明可以登录 
  • 2. 查询用户成功,查询科目 
  • 3. 根据科目的查询结果,获取成绩
【tips】完成这个案例后台应该提供三个接口(用户查询接口、科目接口、各科成绩接口),为了渲染方便,最好响应 json 数据。在这里就不编写后台接口了,而是提供三个 json 文件,直接提供 json 数据,模拟后台接口:
        
        promise可以解决这种层层嵌套的问题。
  • promise语法
    像下面这样,在 promise 中就封装了一段异步执行的结果

    使用箭头函数可以简写为:

  • 处理异步结果
    如果想要等待异步执行完成,做一些事情,可以通过 promise 的 then 方法来实现。 如果想要处理 promise 异步执行失败的事件,还可以跟上 catch

  • 使用promise改造上述案例


  • 优化处理:通常在企业开发中,会把 promise 封装成通用方法,如下:封装了一个通用的 get 请求方法

(9)模块化

  • 什么是模块化?
    模块化就是把代码进行拆分,方便重复利用,类似 java 中的导包。而 JS 中没有包的概念,与之对应的是模块。 
  • 模块功能主要由两个命令构成:
    • export命令:用于规定模块的对外接口,即将模块导出去。
      ①比如定义一个 js 文件hello.js,里面有一个util对象,可以使用 export 将这个对象导出,别的文件就可以用这个对象了:

      【tips】export不仅可以导出对象,一切 JS 变量都可以导出。比如:基本类型变量、函数、数组、 对象。
      ②上面的导出代码中,都明确指定了导出的变量名,别人在导入使用时就必须准确写出变量名,否则就会出错。 因此 js 提供了default关键字可以对导出的变量名进行省略,这样导入使用时就可以任意起名字了:

    • import命令:用于导入其他模块提供(导出)的功能。

      【tips】批量导入要加{}

2.Vue



全部评论

相关推荐

沉淀一会:**圣经 1.同学你面试评价不错,概率很大,请耐心等待;2.你的排名比较靠前,不要担心,耐心等待;3.问题不大,正在审批,不要着急签其他公司,等等我们!4.预计9月中下旬,安心过节;5.下周会有结果,请耐心等待下;6.可能国庆节前后,一有结果我马上通知你;7.预计10月中旬,再坚持一下;8.正在走流程,就这两天了;9.同学,结果我也不知道,你如果查到了也告诉我一声;10.同学你出线不明朗,建议签其他公司保底!11.同学你找了哪些公司,我也在找工作。
点赞 评论 收藏
分享
1 7 评论
分享
牛客网
牛客企业服务