谷粒学院项目

216 阅读7分钟

谷粒学院项目

项目前台设计

一:搭建项目前台系统环境

使用NUXT搭建项目前台系统环境

捕获.PNG

(1)项目结构介绍

捕获.PNG

捕获.PNG

nuxt中页面加载过程

捕获.PNG

二:整合项目前台前端页面

1.安装幻灯片插件

捕获.PNG

2.配置幻灯片插件

捕获.PNG

3.复制项目使用的静态资源

4.定义布局

<template>
  <div class="in-wrap">
    <!-- 公共头引入 -->
    <header id="header">
      <section class="container">
        <h1 id="logo">
          <a href="#" title="谷粒学院">
            <img src="~/assets/img/logo.png" width="100%" alt="谷粒学院">
          </a>
          </h1>
          <div class="h-r-nsl">
            <ul class="nav">
              <router-link to="/" tag="li" active-class="current" exact>
                <a>首页</a>
              </router-link>
              <router-link to="/course" tag="li" active-class="current">
                <a>课程</a>
              </router-link>
              <router-link to="/teacher" tag="li" active-class="current">
                <a>名师</a>
              </router-link>
              <router-link to="/article" tag="li" active-class="current">
                <a>文章</a>
              </router-link>
              <router-link to="/qa" tag="li" active-class="current">
                <a>问答</a>
              </router-link>
            </ul>
            <ul class="h-r-login">
              <li id="no-login">
                <a href="/sing_in" title="登录">
                  <em class="icon18 login-icon">&nbsp;</em>
                  <span class="vam ml5">登录</span>
                </a>
                |
                <a href="/sign_up" title="注册">
                  <span class="vam ml5">注册</span>
                </a>
              </li>
              <li class="mr10 undis" id="is-login-one">
                <a href="#" title="消息" id="headerMsgCountId">
                  <em class="icon18 news-icon">&nbsp;</em>
                </a>
                <q class="red-point" style="display: none">&nbsp;</q>
              </li>
              <li class="h-r-user undis" id="is-login-two">
                <a href="#" title>
                  <img src="~/assets/img/avatar-boy.gif" width="30" height="30" class="vam picImg" alt>
                  <span class="vam disIb" id="userName"></span>
                </a>
                <a href="javascript:void(0)" title="退出" onclick="exit();" class="ml5">退出</a>
              </li>
              <!-- /未登录显示第1 li;登录后显示第2,3 li -->
            </ul>
            <aside class="h-r-search">
              <form action="#" method="post">
                <label class="h-r-s-box">
                  <input type="text" placeholder="输入你想学的课程" name="queryCourse.courseName" value>
                  <button type="submit" class="s-btn">
                    <em class="icon18">&nbsp;</em>
                  </button>
                </label>
              </form>
            </aside>
          </div>
          <aside class="mw-nav-btn">
            <div class="mw-nav-icon"></div>
          </aside>
          <div class="clear"></div>
        </section>
      </header>
      <!-- /公共头引入 -->

      <nuxt/>

      <!-- 公共底引入 -->
      <footer id="footer">
        <section class="container">
          <div class>
            <h4 class="hLh30">
              <span class="fsize18 f-fM c-999">友情链接</span>
            </h4>
            <ul class="of flink-list">
              <li>
                <a href="http://www.atguigu.com/" title="尚硅谷" target="_blank">尚硅谷</a>
                </li>
            </ul>
            <div class="clear"></div>
          </div>
          <div class="b-foot">
            <section class="fl col-7">
              <section class="mr20">
                <section class="b-f-link">
                  <a href="#" title="关于我们" target="_blank">关于我们</a>|
                  <a href="#" title="联系我们" target="_blank">联系我们</a>|
                  <a href="#" title="帮助中心" target="_blank">帮助中心</a>|
                  <a href="#" title="资源下载" target="_blank">资源下载</a>|
                  <span>服务热线:010-56253825(北京) 0755-85293825(深圳)</span>
                  <span>Email:info@atguigu.com</span>
                </section>
                <section class="b-f-link mt10">
                  <span>©2018课程版权均归谷粒学院所有 京ICP备17055252号</span>
                </section>
              </section>
            </section>
            <aside class="fl col-3 tac mt15">
              <section class="gf-tx">
                <span>
                  <img src="~/assets/img/wx-icon.png" alt>
                </span>
              </section>
              <section class="gf-tx">
                <span>
                  <img src="~/assets/img/wb-icon.png" alt>
                </span>
              </section>
            </aside>
            <div class="clear"></div>
          </div>
        </section>
      </footer>
      <!-- /公共底引入 -->
    </div>
</template>
<script>
import "~/assets/css/reset.css";
import "~/assets/css/theme.css";
import "~/assets/css/global.css";
import "~/assets/css/web.css";
export default {};
</script>

5.定义首页面

<template>
  <div>
    <!-- 幻灯片 开始 -->
    <!-- 幻灯片 结束 -->
      <div id="aCoursesList">
        <!-- 网校课程 开始 -->
        <div>
          <section class="container">
            <header class="comm-title">
              <h2 class="tac">
                <span class="c-333">热门课程</span>
              </h2>
            </header>
            <div>
              <article class="comm-course-list">
                <ul class="of" id="bna">
                  <li>
                    <div class="cc-l-wrap">
                      <section class="course-img">
                        <img src="~/assets/photo/course/1442295592705.jpg" class="img-responsive" alt="听力口语">
                        <div class="cc-mask">
                          <a href="#" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
                        </div>
                      </section>
                      <h3 class="hLh30 txtOf mt10">
                        <a href="#" title="听力口语" class="course-title fsize18 c-333">听力口语</a>
                      </h3>
                      <section class="mt10 hLh20 of">
                        <span class="fr jgTag bg-green">
                          <i class="c-fff fsize12 f-fA">免费</i>
                        </span>
                        <span class="fl jgAttr c-ccc f-fA">
                          <i class="c-999 f-fA">9634人学习</i>
                          |
                          <i class="c-999 f-fA">9634评论</i>
                        </span>
                      </section>
                    </div>
                  </li>
                  <li>
                    <div class="cc-l-wrap">
                      <section class="course-img">
                        <img src="~/assets/photo/course/1442295581911.jpg" class="img-responsive" alt="Java精品课程">
                        <div class="cc-mask">
                          <a href="#" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
                        </div>
                      </section>
                      <h3 class="hLh30 txtOf mt10">
                        <a href="#" title="Java精品课程" class="course-title fsize18 c-333">Java精品课程</a>
                      </h3>
                      <section class="mt10 hLh20 of">
                        <span class="fr jgTag bg-green">
                          <i class="c-fff fsize12 f-fA">免费</i>
                        </span>
                        <span class="fl jgAttr c-ccc f-fA">
                          <i class="c-999 f-fA">501人学习</i>
                          |
                          <i class="c-999 f-fA">501评论</i>
                        </span>
                      </section>
                    </div>
                  </li> 
                  <li>
                    <div class="cc-l-wrap">
                      <section class="course-img">
                        <img src="~/assets/photo/course/1442295604295.jpg" class="img-responsive" alt="C4D零基础">
                        <div class="cc-mask">
                          <a href="#" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
                        </div>
                      </section>
                      <h3 class="hLh30 txtOf mt10">
                        <a href="#" title="C4D零基础" class="course-title fsize18 c-333">C4D零基础</a>
                      </h3>
                      <section class="mt10 hLh20 of">
                        <span class="fr jgTag bg-green">
                          <i class="c-fff fsize12 f-fA">免费</i>
                        </span>
                        <span class="fl jgAttr c-ccc f-fA">
                          <i class="c-999 f-fA">300人学习</i>
                          |
                          <i class="c-999 f-fA">300评论</i>
                        </span>
                      </section>
                    </div>
                  </li>
                  <li>
                    <div class="cc-l-wrap">
                      <section class="course-img">
                        <img src="~/assets/photo/course/1442302831779.jpg" class="img-responsive" alt="数学给宝宝带来的兴趣">
                        <div class="cc-mask">
                          <a href="#" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
                        </div>
                      </section>
                      <h3 class="hLh30 txtOf mt10">
                        <a href="#" title="数学给宝宝带来的兴趣" class="course-title fsize18 c-333">数学给宝宝带来的兴趣</a>
                      </h3>
                      <section class="mt10 hLh20 of"> 
                        <span class="fr jgTag bg-green">
                          <i class="c-fff fsize12 f-fA">免费</i>
                        </span>
                        <span class="fl jgAttr c-ccc f-fA">
                          <i class="c-999 f-fA">256人学习</i>
                          |
                          <i class="c-999 f-fA">256评论</i>
                        </span>
                      </section>
                    </div>
                  </li>
                  <li>
                    <div class="cc-l-wrap">
                      <section class="course-img">
                        <img
                          src="~/assets/photo/course/1442295455437.jpg"
                          class="img-responsive"
                          alt="零基础入门学习Python课程学习"
                        >
                        <div class="cc-mask">
                          <a href="#" title="开始学习" class="comm-btn c-btn-1">开始
                          学习</a>
                        </div>
                      </section>
                      <h3 class="hLh30 txtOf mt10"> 
                        <a
                          href="#"
                          title="零基础入门学习Python课程学习"
                          class="course-title fsize18 c-333"
                        >零基础入门学习Python课程学习</a>
                      </h3>
                      <section class="mt10 hLh20 of">
                        <span class="fr jgTag bg-green">
                          <i class="c-fff fsize12 f-fA">免费</i>
                        </span>
                        <span class="fl jgAttr c-ccc f-fA">
                          <i class="c-999 f-fA">137人学习</i>
                          |
                          <i class="c-999 f-fA">137评论</i>
                        </span>
                      </section>
                    </div>
                  </li>  
                  <li>
                    <div class="cc-l-wrap">
                      <section class="course-img">
                        <img
                          src="~/assets/photo/course/1442295570359.jpg"
                          class="img-responsive"
                          alt="MySql从入门到精通"
                        >
                        <div class="cc-mask">
                          <a href="#" title="开始学习" class="comm-btn c-btn-1">开始
                          学习</a>
                        </div>
                      </section>  
                      <h3 class="hLh30 txtOf mt10">
                        <a href="#" title="MySql从入门到精通" class="course-title
                        fsize18 c-333">MySql从入门到精通</a>
                      </h3>
                      <section class="mt10 hLh20 of">
                        <span class="fr jgTag bg-green">
                          <i class="c-fff fsize12 f-fA">免费</i>
                        </span>
                        <span class="fl jgAttr c-ccc f-fA">
                          <i class="c-999 f-fA">125人学习</i>
                          |
                          <i class="c-999 f-fA">125评论</i>
                        </span>
                      </section>
                    </div>
                  </li>
                  <li>
                    <div class="cc-l-wrap">
                      <section class="course-img">
                        <img
                          src="~/assets/photo/course/1442302852837.jpg"
                          class="img-responsive"
                          alt="搜索引擎优化技术"
                        >
                        <div class="cc-mask">
                          <a href="#" title="开始学习" class="comm-btn c-btn-1">开始
                          学习</a>
                        </div>
                      </section>
                      <h3 class="hLh30 txtOf mt10">
                        <a href="#" title="搜索引擎优化技术" class="course-title
                        fsize18 c-333">搜索引擎优化技术</a>
                      </h3>
                      <section class="mt10 hLh20 of">
                        <span class="fr jgTag bg-green">
                          <i class="c-fff fsize12 f-fA">免费</i>
                        </span>
                        <span class="fl jgAttr c-ccc f-fA">
                          <i class="c-999 f-fA">123人学习</i>
                          |
                          <i class="c-999 f-fA">123评论</i>
                        </span>
                      </section>
                    </div>
                  </li>
                  <li>
                    <div class="cc-l-wrap">
                      <section class="course-img">
                        <img
                          src="~/assets/photo/course/1442295379715.jpg"
                          class="img-responsive"
                          alt="20世纪西方音乐"
                        > 
                        <div class="cc-mask"> 
                          <a href="#" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
                        </div>
                      </section>  
                      <h3 class="hLh30 txtOf mt10">
                        <a href="#" title="20世纪西方音乐" class="course-title
                        fsize18 c-333">20世纪西方音乐</a>
                      </h3>
                      <section class="mt10 hLh20 of">
                        <span class="fr jgTag bg-green">
                          <i class="c-fff fsize12 f-fA">免费</i>
                        </span>
                        <span class="fl jgAttr c-ccc f-fA">
                          <i class="c-999 f-fA">34人学习</i>
                          |
                          <i class="c-999 f-fA">34评论</i>
                        </span>
                      </section>
                    </div>
                  </li>
                </ul> 
                <div class="clear"></div>
              </article>
              <section class="tac pt20">
                <a href="#" title="全部课程" class="comm-btn c-btn-2">全部课程</a>
              </section>
            </div>
          </section>
        </div>
        <!-- /网校课程 结束 -->
        <!-- 网校名师 开始 -->
        <div>
          <section class="container">
            <header class="comm-title">
              <h2 class="tac">
                <span class="c-333">名师大咖</span>
              </h2>
            </header>
            <div>
              <article class="i-teacher-list">
                <ul class="of">
                  <li>
                    <section class="i-teach-wrap">
                      <div class="i-teach-pic">
                        <a href="/teacher/1" title="姚晨">
                          <img alt="姚晨" src="~/assets/photo/teacher/1442297885942.jpg">
                        </a>
                      </div>
                      <div class="mt10 hLh30 txtOf tac">
                        <a href="/teacher/1" title="姚晨" class="fsize18 c-666">姚晨</a>
                      </div>
                      <div class="hLh30 txtOf tac">
                        <span class="fsize14 c-999">北京师范大学法学院副教授</span>
                      </div>
                      <div class="mt15 i-q-txt">
                        <p
                          class="c-999 f-fA"
                          >北京师范大学法学院副教授、清华大学法学博士。自2004年至今已有9年
                          的司法考试培训经验。长期从事司法考试辅导,深知命题规律,了解解题技巧。内容把握准确,授课重
                          点明确,层次分明,调理清晰,将法条法理与案例有机融合,强调综合,深入浅出。</p>
                      </div>
                    </section>
                  </li> 
                  <li>
                    <section class="i-teach-wrap">
                      <div class="i-teach-pic">
                        <a href="/teacher/1" title="谢娜">
                          <img alt="谢娜" src="~/assets/photo/teacher/1442297919077.jpg">
                        </a>  
                      </div>  
                      <div class="mt10 hLh30 txtOf tac">
                        <a href="/teacher/1" title="谢娜" class="fsize18 c-666">谢娜</a>
                      </div>
                      <div class="hLh30 txtOf tac">
                        <span class="fsize14 c-999">资深课程设计专家,专注10年AACTP美国培训协会认证导师</span>
                      </div>
                      <div class="mt15 i-q-txt">
                        <p
                          class="c-999 f-fA"
                          >十年课程研发和培训咨询经验,曾任国企人力资源经理、大型外企培训经
                          理,负责企业大学和培训体系搭建;曾任专业培训机构高级顾问、研发部总监,为包括广东移动、东莞
                          移动、深圳移动、南方电网、工商银行、农业银行、民生银行、邮储银行、TCL集团、清华大学继续教
                          育学院、中天路桥、广西扬翔股份等超过200家企业提供过培训与咨询服务,并担任近50个大型项目的
                          总负责人。</p>
                      </div>
                    </section>
                  </li>
                  <li>
                    <section class="i-teach-wrap">
                      <div class="i-teach-pic">  
                        <a href="/teacher/1" title="刘德华">
                          <img alt="刘德华" src="~/assets/photo/teacher/1442297927029.jpg">
                        </a>
                      </div>
                      <div class="mt10 hLh30 txtOf tac">
                        <a href="/teacher/1" title="刘德华" class="fsize18 c-666">刘德华</a>    
                      </div>    
                      <div class="hLh30 txtOf tac">
                        <span class="fsize14 c-999">上海师范大学法学院副教授</span>
                      </div> 
                      <div class="mt15 i-q-txt">
                        <p
                          class="c-999 f-fA"
                          >上海师范大学法学院副教授、清华大学法学博士。自2004年至今已有9年
                          的司法考试培训经验。长期从事司法考试辅导,深知命题规律,了解解题技巧。内容把握准确,授课重
                          点明确,层次分明,调理清晰,将法条法理与案例有机融合,强调综合,深入浅出。</p>
                      </div>
                    </section>
                  </li>
                  <li>
                    <section class="i-teach-wrap">
                      <div class="i-teach-pic">
                        <a href="/teacher/1" title="周润发">
                          <img alt="周润发" src="~/assets/photo/teacher/1442297935589.jpg">
                        </a>
                      </div>
                      <div class="mt10 hLh30 txtOf tac">    
                        <a href="/teacher/1" title="周润发" class="fsize18 c-666">周润发</a>
                      </div>  
                      <div class="hLh30 txtOf tac">
                        <span class="fsize14 c-999">考研政治辅导实战派专家,全国考研政
                        治命题研究组核心成员。</span>
                      </div>
                      <div class="mt15 i-q-txt">
                        <p
                        class="c-999 f-fA"
                        >法学博士,北京师范大学马克思主义学院副教授,专攻毛泽东思想概论、
                        邓小平理论,长期从事考研辅导。出版著作两部,发表学术论文30余篇,主持国家社会科学基金项目和
                        教育部重大课题子课题各一项,参与中央实施马克思主义理论研究和建设工程项目。</p>
                      </div>
                    </section>  
                  </li>
                </ul>
                <div class="clear"></div>
              </article>  
              <section class="tac pt20">
                <a href="#" title="全部讲师" class="comm-btn c-btn-2">全部讲师</a>
              </section>
            </div>
          </section>
        </div>
        <!-- /网校名师 结束 -->     
      </div>  
    </div>  
</template>  

<script>
export default {
}
</script>

6.整合幻灯片

捕获.PNG

捕获.PNG

Nuxt路由:

捕获.PNG

首页数据显示-banner接口:

1.创建service-cms模块

捕获.PNG

2.创建配置文件

# 服务端口
server.port=8004
# 服务名
spring.application.name=service-cms
# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/guli?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root
#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
#配置mapper xml文件的路径
mybatis-plus.mapper-locations=classpath:com/atguigu/cmsservice/mapper/xml/*.xml
#mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

3.创建数据库表,根据表使用代码生成器生成代码

捕获.PNG

4.后台对bannber管理的接口(crud操作)-----前台对bannber显示接口

捕获.PNG

(1)后台banner管理接口

package com.atguigu.educms.controller;


import com.atguigu.commonutils.R;
import com.atguigu.educms.entity.CrmBanner;
import com.atguigu.educms.service.CrmBannerService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * <p>
 * 后台banner管理接口
 * </p>
 *
 * @author testjava
 * @since 2022-10-17
 */
@RestController
@RequestMapping("/educms/banneradmin")
@CrossOrigin
public class BannerAdminController {

    @Autowired
    private CrmBannerService crmBannerService;

    // 1.分页查询banner
    @GetMapping("pageBanner/{page}/{limit}")
    public R pageBanner(@PathVariable long page, @PathVariable long limit) {
        Page<CrmBanner> crmBannerPage = new Page<>(page, limit);
        IPage<CrmBanner> crmBannerIPage = crmBannerService.page(crmBannerPage, null);
        return R.ok().data("items", crmBannerIPage.getRecords()).data("total", crmBannerIPage.getTotal());
    }

    // 2.添加banner
    @PostMapping("addBanner")
    public R addBanner(@RequestBody CrmBanner crmBanner) {
        crmBannerService.save(crmBanner);
        return R.ok();
    }

    // 3.修改banner
    @PostMapping("updateBanner")
    public R updateBanner(@RequestBody CrmBanner crmBanner) {
        crmBannerService.updateById(crmBanner);
        return R.ok();
    }

    // 4.删除banner
    @DeleteMapping("deleteBannerById/{id}")
    public R deleteBanner(@PathVariable String id) {
        crmBannerService.removeById(id);
        return R.ok();
    }
}

(2)前台banner管理接口

controller:

```
package com.atguigu.educms.controller;


import com.atguigu.commonutils.R;
import com.atguigu.educms.entity.CrmBanner;
import com.atguigu.educms.service.CrmBannerService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * <p>
 * 前台banner显示接口
 * </p>
 *
 * @author testjava
 * @since 2022-10-17
 */
@RestController
@RequestMapping("/educms/bannerfront")
@CrossOrigin
public class BannerFrontController {
    @Autowired
    private CrmBannerService crmBannerService;

    // 查询所有banner
    @GetMapping("getAllBanner")
    public R getAllBanner() {
        // 根据id进行降序排序,显示排列之后前两条数据
        QueryWrapper<CrmBanner> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id");
        // last方法,拼接sql语句
        wrapper.last("limit 2");
        List<CrmBanner> list = crmBannerService.selectAllBanner();
        return R.ok().data("list", list);
    }
}
```

service:

package com.atguigu.educms.service.impl;

import com.atguigu.educms.entity.CrmBanner;
import com.atguigu.educms.mapper.CrmBannerMapper;
import com.atguigu.educms.service.CrmBannerService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 * 首页banner表 服务实现类
 * </p>
 *
 * @author testjava
 * @since 2022-10-17
 */
@Service
public class CrmBannerServiceImpl extends ServiceImpl<CrmBannerMapper, CrmBanner> implements CrmBannerService {

    // 查询所有banner
    @Override
    public List<CrmBanner> selectAllBanner() {
        List<CrmBanner> crmBanners = baseMapper.selectList(null);
        return crmBanners;
    }
}

首页数据显示-热门课程和名师接口:

controller:

package com.atguigu.eduservice.controller.front;

import com.atguigu.commonutils.R;
import com.atguigu.eduservice.entity.EduCourse;
import com.atguigu.eduservice.entity.EduTeacher;
import com.atguigu.eduservice.service.EduCourseService;
import com.atguigu.eduservice.service.EduTeacherService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/eduservice/indexfront")
@CrossOrigin
public class IndexFrontController {

    @Autowired
    private EduCourseService eduCourseService;

    @Autowired
    private EduTeacherService eduTeacherService;

    // 查询前8条热门课程,查询前4条名师
    @GetMapping("index")
    public R index() {
        // 查询前8条热门课程
        QueryWrapper<EduCourse> wrapperCourse = new QueryWrapper<>();
        wrapperCourse.orderByDesc("view_count");
        wrapperCourse.last("limit 8");
        List<EduCourse> eduCourses = eduCourseService.list(wrapperCourse);
        // 查询前4条名师
        QueryWrapper<EduTeacher> wrapperTeacher = new QueryWrapper<>();
        wrapperTeacher.orderByDesc("id");
        wrapperTeacher.last("limit 4");
        List<EduTeacher> teachers = eduTeacherService.list(wrapperTeacher);
        return R.ok().data("eduCourses", eduCourses).data("teachers", teachers);
    }
}

首页数据显示-banner显示(前端):

1.前端页面准备工作

(1)使用命令,下载axios依赖

cnpm install axios

(2)封装axios

捕获.PNG

import axios from 'axios'

// 创建axios实例
const service = axios.create({
    baseURL: 'http://localhost:9001',
    timeout: 20000
})

export default service

(3)具体开发

捕获.PNG

banner.js

import request from '@/utils/request'

export default {
    
    // 查询前两条Banner的信息
    getListBanner() {
        return request({
            url: `/educms/bannerfront/getAllBanner`,
            method: 'get'
        })
    }
}

捕获.PNG

在index.vue中进行调用

捕获.PNG

在index.vue中进行显示

捕获.PNG

首页数据显示-热门课程和讲师显示(前端):

同上

Redis:

捕获.PNG

往项目中添加redis缓存:

捕获.PNG

捕获.PNG

捕获.PNG

捕获.PNG

执行过程:

捕获.PNG

添加注解:

捕获.PNG

第三步 启动Redis服务:

捕获.PNG

捕获.PNG

捕获.PNG

捕获.PNG

第四步 在service_cms配置文件中配置redis地址

登录业务介绍(单点登录)

古老方式:

捕获.PNG

单点登录:

捕获.PNG

单点登录实现方式:

捕获.PNG

捕获.PNG

session复制:其中一个模块登陆以后,将session复制到其它模块当中去(每个模块对应一个session)
缺点:当项目中有很多模块时,这种方式会造成资源的极大浪费.

捕获.PNG

捕获.PNG

捕获.PNG

捕获.PNG

捕获.PNG

JWT介绍:

捕获.PNG

JWT生成字符串介绍:

捕获.PNG

项目添加JWT工具类:

1:

捕获.PNG

2:JWT工具类

package com.atguigu.commonutils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * @author helen
 * @since 2019/10/16
 */
public class JwtUtils {

    // 常量
    public static final long EXPIRE = 1000 * 60 * 60 * 24; // 设置token过期时间
    public static final String APP_SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO"; // 密钥

    // 生成token字符串的方法
    public static String getJwtToken(String id, String nickname){

        String JwtToken = Jwts.builder()

                .setHeaderParam("typ", "JWT")
                .setHeaderParam( "alg", "HS256")

                .setSubject("guli-user")
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRE))

                .claim("id", id)
                .claim("nickname", nickname)

                .signWith(SignatureAlgorithm.HS256, APP_SECRET)
                .compact();

        return JwtToken;
    }

    /**
     * 判断token是否存在与有效
     * @param jwtToken
     * @return
     */
    public static boolean checkToken(String jwtToken) {
        if(StringUtils.isEmpty(jwtToken)) return false;
        try {
            Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 判断token是否存在与有效
     * @param request
     * @return
     */
    public static boolean checkToken(HttpServletRequest request) {
        try {
            String jwtToken = request.getHeader("token");
            if(StringUtils.isEmpty(jwtToken)) return false;
            Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 根据token字符串获取用户信息
     * @param request
     * @return
     */
    public static String getMemberIdByJwtToken(HttpServletRequest request) {
        String jwtToken = request.getHeader("token");
        if(StringUtils.isEmpty(jwtToken))
            return "";
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        Claims claims = claimsJws.getBody();
        return (String)claims.get("id");
    }
}

阿里云短信服务介绍:

捕获.PNG

捕获.PNG

捕获.PNG

TODO:

登录功能(接口):

捕获.PNG

捕获.PNG

3、编写controller和service

捕获.PNG

// 登录方法
@Override
public String login(UcenterMember ucenterMember) {
    // 获取登录手机号和密码(其实这里的手机号是邮箱,我们用邮箱来代替手机号)
    String mobile = ucenterMember.getMobile();
    String password = ucenterMember.getPassword();

    // 手机号和密码非空判断
    if (StringUtils.isEmpty(mobile) || StringUtils.isEmpty(password)) {
        throw new GuliException(20001, "登陆失败");
    }

    // 判断手机号是否正确
    QueryWrapper<UcenterMember> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("mobile", mobile);
    UcenterMember member = baseMapper.selectOne(queryWrapper);
    if (member == null) {
        // 现在数据库中没有这个手机号
        throw new GuliException(20001, "登陆失败");
    }

    // 判断密码
    // 因为存储到数据库中的密码肯定是加密的
    // 将前端传来的密码进行加密以后,在和数据库中的密码进行比较
    // 加密方式:MD5
    password = MD5.encrypt(password);
    if (!password.equals(member.getPassword())) {
        // 密码不一致
        throw new GuliException(20001, "登陆失败");
    }

    // 判断用户是否禁用
    if (member.getIsDisabled()) {
        // 用户禁用
        throw new GuliException(20001, "登陆失败");
    }

    // 登陆成功---使用jwt生成token字符串
    // member中才有完成信息  ucenterMember只有手机号和密码
    String jwtToken = JwtUtils.getJwtToken(member.getId(), member.getNickname());
    return jwtToken;
}

注册功能(接口):

捕获.PNG

package com.atguigu.educenter.entity.vo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
@ApiModel(value = "注册对象", description = "注册对象")
public class RegisterVo {
    @ApiModelProperty(value = "昵称")
    private String nickname;
    @ApiModelProperty(value = "手机号")
    private String mobile;
    @ApiModelProperty(value = "密码")
    private String password;
    @ApiModelProperty(value = "验证码")
    private String code;
}

捕获.PNG

捕获.PNG

3、编写service

// 注册方法
@Override
public void register(RegisterVo registerVo) {
    String code = registerVo.getCode(); // 验证码
    String email = registerVo.getMobile();// 手机号(其实是邮箱)
    String nickname = registerVo.getNickname();// 昵称
    String password = registerVo.getPassword();// 密码

    // 非空判断
    if (StringUtils.isEmpty(email) || StringUtils.isEmpty(code) || StringUtils.isEmpty(nickname) || StringUtils.isEmpty(password)) {
        throw new GuliException(20001, "注册失败");
    }

    // 判断用户输入的验证码和我们发送的验证码是否相同
    // 从redis中获取给用户发送的验证码
    String redis_code = redisTemplate.opsForValue().get(email);
    if (!code.equals(redis_code)) {
        throw new GuliException(20001, "注册失败");
    }

    // 判断手机号(邮箱)是否重复,如果重复的话,我们就不往数据库中加入了
    QueryWrapper<UcenterMember> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("mobile", email);
    Integer count = baseMapper.selectCount(queryWrapper);
    if (count >= 1) {
        // 表里有相同的手机号
        throw new GuliException(20001, "注册失败");
    }

    // 数据添加到数据库中
    UcenterMember ucenterMember = new UcenterMember();
    ucenterMember.setMobile(email);
    ucenterMember.setNickname(nickname);
    ucenterMember.setPassword(MD5.encrypt(password));
    ucenterMember.setIsDisabled(false);
    ucenterMember.setAvatar("https://guli-file-190513.oss-cn-beijing.aliyuncs.com/avatar/default.jpg");
    baseMapper.insert(ucenterMember);
}

根据token获取用户信息(接口):

捕获.PNG

// 根据token获取用户信息
@GetMapping("getMemberInfo")
public R getMemberInfo(HttpServletRequest request) {
    // 调用jwt工具类的方法,根据request对象获取头信息,返回用户id
    String memberId = JwtUtils.getMemberIdByJwtToken(request);
    UcenterMember member = memberService.getById(memberId);
    return R.ok().data("userInfo", member);
}

首页面登录和注册页面整合:

捕获.PNG

捕获.PNG

import Vue from 'vue'
import VueAwesomeSwiper from 'vue-awesome-swiper/dist/ssr'
import VueQriously from 'vue-qriously'
import ElementUI from 'element-ui' //element-ui的全部组件
import 'element-ui/lib/theme-chalk/index.css'//element-ui的css
Vue.use(ElementUI) //使用elementUI
Vue.use(VueQriously)
Vue.use(VueAwesomeSwiper)

捕获.PNG

捕获.PNG

捕获.PNG

捕获.PNG

注册前端整合:

捕获.PNG

捕获.PNG 捕获.PNG

捕获.PNG

4、最终注册页面实现

<template>
<div class="main">
<div class="title">
<a href="/login">登录</a>
<span>·</span>
<a class="active" href="/register">注册</a>
</div>
<div class="sign-up-container">
<el-form ref="userForm" :model="params">
<el-form-item class="input-prepend restyle" prop="nickname" :rules="[{required: true, message: '请输入你的昵称', trigger: 'blur' }]">
<div>
<el-input type="text" placeholder="你的昵称" v-model="params.nickname"/>
<i class="iconfont icon-user"/>
</div>
</el-form-item>
<el-form-item class="input-prepend restyle no-radius" prop="mobile"
:rules="[{ required: true, message: '请输入邮箱', trigger: 'blur' }]">
<div>
<el-input type="text" placeholder="邮箱" v-model="params.mobile"/>
<i class="iconfont icon-phone"/>
</div>
</el-form-item>
<el-form-item class="input-prepend restyle no-radius" prop="code" :rules="
[{ required: true, message: '请输入验证码', trigger: 'blur' }]">
<div style="width: 100%;display: block;float: left;position: relative">
<el-input type="text" placeholder="验证码" v-model="params.code"/>
<i class="iconfont icon-phone"/>
</div>
<div class="btn" style="position:absolute;right: 0;top: 6px;width:
40%;">
<a href="javascript:" type="button" @click="getCodeFun()"
:value="codeTest" style="border: none;background-color: none">{{codeTest}}</a>
</div>
</el-form-item>
<el-form-item class="input-prepend" prop="password" :rules="[{ required:
true, message: '请输入密码', trigger: 'blur' }]">
<div>
<el-input type="password" placeholder="设置密码" v-model="params.password"/>
<i class="iconfont icon-password"/>
</div>
</el-form-item>
<div class="btn">
<input type="button" class="sign-up-button" value="注册" @click="submitRegister()">
</div>
<p class="sign-up-msg">
 点击 “注册” 即表示您同意并愿意遵守简书
<br>
<a target="_blank" href="http://www.jianshu.com/p/c44d171298ce">用户协议</a><a target="_blank" href="http://www.jianshu.com/p/2ov8x3">隐私政策</a></p>
</el-form>
<!-- 更多注册方式 -->
<div class="more-sign">
<h6>社交帐号直接注册</h6>
<ul>
<li><a id="weixin" class="weixin" target="_blank"
href="http://huaan.free.idcfengye.com/api/ucenter/wx/login"><i
class="iconfont icon-weixin"/></a></li>
<li><a id="qq" class="qq" target="_blank" href="#"><i class="iconfont
icon-qq"/></a></li>
</ul>
</div>
</div>
</div>
</template>
<script>
import '~/assets/css/sign.css'
import '~/assets/css/iconfont.css'
import registerApi from '@/api/register'

export default {
layout: 'sign',
data() {
    return {
        params: { // 封装注册输入数据
            mobile: '', 
            code: '', // 验证码
            nickname: '',
            password: ''
        },
        sending: true, //是否发送验证码
        second: 60, //倒计时间
        codeTest: '获取验证码'
    }
 },
methods: {
    // 注册提交方法
    submitRegister(){
        registerApi.registerMember(this.parems)
            .then(response =>{
                // 提示信息
                 this.$message({
                            type: 'success',
                            message: '注册成功!'
                        });
                // 跳转到登陆页面
                this.$router.push({path:'/login'})
            })
    },

    // 倒计时方法
    timeDown() {
        let result = setInterval(() => {
        --this.second;
        this.codeTest = this.second
        if (this.second < 1) {
        clearInterval(result);
        this.sending = true;
        //this.disabled = false;
        this.second = 60;
        this.codeTest = "获取验证码"
        }
        }, 1000);
    },

    // 通过输入的邮箱,发送验证码
    getCodeFun(){
        registerApi.sendCode(this.params.mobile)
            .then(response =>{
                this.sending = false
                this.codeTest = 60
                // 调用倒计时的方法
                this.timeDown()
            })
    }

    // checkPhone (rule, value, callback) {
    //     //debugger
    //     if (!(/^1[34578]\d{9}$/.test(value))) {
    //     return callback(new Error('手机号码格式不正确'))
    //     }
    //     return callback()
    // }
 }
 }
</script>