尚硅谷实战项目-谷粒学院-part two

9 篇文章 0 订阅
3 篇文章 0 订阅

添加课程基本信息

添加课程信息后端

1、使用代码生成器生成课程相关的代码

在这里插入图片描述

2、

细节问题:

  1. 创建vo实体类用于表单数据封装

  2. 把表单提交过来的数据添加数据库

    向两张表添加数据:课程表和课程描述表

  3. 把讲师和分类使用下列列表显示

    课程分类 做成二级联动效果

@Service
public class EduCourseServiceImpl extends ServiceImpl<EduCourseMapper, EduCourse> implements EduCourseService {

    @Autowired
    private EduCourseDescriptionService courseDescriptionService;


    //添加课程基本信息的方法
    @Override
    public void saveCourseInfo(CourseInfoVo courseInfoVo) {
        // 向课程表添加课程基本信息
        //CourseInfoVo对象转换eduCourse对象
        EduCourse eduCourse = new EduCourse();
        BeanUtils.copyProperties(courseInfoVo, eduCourse);
        int insert = baseMapper.insert(eduCourse);

        if (insert == 0){
            //添加失败
            throw new GuliException(20001,"添加课程信息失败");
        }

        //获取添加之后课程id
        String cid = eduCourse.getId();

        // 向课程简介表添加课程简介
        EduCourseDescription courseDescription = new EduCourseDescription();
        courseDescription.setDescription(courseInfoVo.getDescription());
        //设置描述id就是课程id
        courseDescription.setId(cid);
        courseDescriptionService.save(courseDescription);
    }
}

更改描述里面的策略:

在这里插入图片描述

添加课程信息前端

1、对菜单栏的内容进行增加

在这里插入图片描述

2、新建对应的页面并完善其内容

在这里插入图片描述

3、连接后端

在这里插入图片描述

细节问题:

添加之后,返回课程id

在这里插入图片描述

在这里插入图片描述

整合文本编辑器

1、复制文本编辑器组件,相关组件进行复制到项目里面

2、配置html变量

在这里插入图片描述

3、在index.html引入Js脚本

在这里插入图片描述

4、在页面使用文本编辑器

课程大纲列表

1、创建两个实体类:章节和小节,在章节实体类使用list表示小节

类似于上一节

修改课程信息

前端内容:

在这里插入图片描述

后端:

  //修改课程信息
    @Override
    public void updateCourseInfo(CourseInfoVo courseInfoVo) {
        //修改课程表
        EduCourse eduCourse = new EduCourse();
        BeanUtils.copyProperties(courseInfoVo,eduCourse);
        int update = baseMapper.updateById(eduCourse);
        if (update == 0){
            throw new GuliException(20001,"修改课程信息失败");
        }

        //修改描述表
        EduCourseDescription description = new EduCourseDescription();
        description.setId(courseInfoVo.getId());
        description.setDescription(courseInfoVo.getDescription());
        courseDescriptionService.updateById(description);

    }
删除课程信息

按钮已经有,后端也实现了,等项目做完需要将连上前端

阿里云视频

API:阿里云提供固定的地址,只需要调用这个固定的地址,向地址传递参数,实现功能

SDK:sdk对api方式进行封装,更方便使用。之前使用EasyExcel调用阿里云提供类或者接口里面的方法实现视频功能

阿里云视频点播SDK

1、获取视频播放地址

因为上传视频可以进行加密,加密之后,使用加密之后地址不能进行视频播放,在数据库存储不存地址,而是存储

根据视频id获取视频播放地址:

public class TestVod {
    public static void main(String[] args) throws Exception{
        //1 根据视频的ID获取视频播放地址
        // 创建初始化对象
        DefaultAcsClient client = InitObject.initVodClient("LTAI5tR617LEVVNgxTPz8dDk","AEcqAHfCr3ergCtyRCumbGso42pnJ3");

        // 创建获取视频地址request和response
        GetPlayInfoRequest request = new GetPlayInfoRequest();
        GetPlayInfoResponse response = new GetPlayInfoResponse();

        // 向request对象里面设置视频id
        request.setVideoId("fb75ed5eb8d440899bb551d15dc03d8e");

        // 使用初始化对象里面的方法,传递request,获取数据
        response = client.getAcsResponse(request);

        List<GetPlayInfoResponse.PlayInfo> playInfoList = response.getPlayInfoList();
        //播放地址
        for (GetPlayInfoResponse.PlayInfo playInfo : playInfoList) {
            System.out.print("PlayInfo.PlayURL = " + playInfo.getPlayURL() + "\n");
        }
        //Base信息
        System.out.print("VideoBase.Title = " + response.getVideoBase().getTitle() + "\n");
    }
}

2、获取视频播放凭证

public static void getPlayAuth()  throws Exception{
    //根据视频Id获取视频播放凭证
    //创建初始化对象
    DefaultAcsClient client = InitObject.initVodClient("LTAI5tR617LEVVNgxTPz8dDk","AEcqAHfCr3ergCtyRCumbGso42pnJ3");
    //创建获取视频凭证request和response
    GetVideoPlayAuthRequest request = new GetVideoPlayAuthRequest();
    GetVideoPlayAuthResponse response = new GetVideoPlayAuthResponse();

    //向request中设置视频id
    request.setVideoId("fb75ed5eb8d440899bb551d15dc03d8e");

    //调用初始化对象的方法得到凭证
    response = client.getAcsResponse(request);
    System.out.println("playauth:" +response.getPlayAuth());
}

3、上传视频到阿里云视频点播服务

在之前引入jar包时,aliyun-java-vod-upload-1.4.11.jar的导入出错,所以我用了1.4.14版本的,原因是这个包不是开源的,不能通过maven仓库下载。。

但是使用1.4.14版本官网说明如下,还需要更改oss包的版本,不然不兼容

在这里插入图片描述

下载了1.4.11的版本,但是还是报错

把官网中的需要的xml依赖复制过来,就可以运行了。。

测试成功

整合前端 视频上传

上传视频时,数据库里的video_source_id为空

删除视频

后端接口:

 //根据视频id删除阿里云视频
    @DeleteMapping("removeAlyVideo/{id}")
    public R removeAlyVideo(@PathVariable String id){
        try{
            //初始化对象
            DefaultAcsClient client = InitVodClient.initVodClient(
                    ConstantVodUtils.ACCESS_KEY_ID,
                    ConstantVodUtils.ACCESS_KEY_SECRET);
            //创建删除视频的request对象
            DeleteVideoRequest request = new DeleteVideoRequest();
            //向request设置视频id
            request.setVideoIds(id);
            //调用初始化对象的方法实现删除
            client.getAcsResponse(request);
            return R.ok();
        }catch (Exception e){
            e.printStackTrace();
            throw new GuliException(20001,"删除视频失败");
        }
    }

nacos配置

1、安装并启动nacos

使用docker安装nacos

docker run --env MODE=standalone --name mynacos -d -p 8848:8848 docker.io/nacos/nacos-server:1.3.1

2、在需要配置服务的配置文件中

# nacos服务地址
spring.cloud.nacos.discovery.server-addr=192.168.1.118:8848

3、在其主启动类上加上注解

@EnableDiscoveryClient

4、在nacos中查看是否注册成功

删除小节和删除视频

把互相调用的服务(service-edu和service-vod)在nacos中进行注册

1、引入依赖在service模块

  <!--服务调用-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

2、在调用端service-edu服务启动类添加注解

@EnableFeignClients

3、在调用端 创建interface,使用注解指定调用服务名称,定义调用的方法路径

SpringCloud调用接口流程

在这里插入图片描述

熔断机制的使用

1、添加熔断器依赖

   <!--hystrix依赖,主要是用 @HystrixCommand -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

2、在调用端配置文件中开启熔断器

#开启熔断机制
feign.hystrix.enabled=true
# 设置hystrix超时时间,默认1000ms
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=6000

3、在创建Interface之后,还需要创建interface对应实现类,在实现类实现方法,出错了输出内容

@Component
public class VodFileDegradeFeignClient implements VodClient {

    //出错之后会执行
    @Override
    public R removeAlyVideo(String id) {
        return R.error().message("删除视频出错了");
    }

    @Override
    public R deleteBatch(List<String> videoList) {
        return R.error().message("删除多个视频出错了");
    }
}

4、在Interface上面添加注释和属性

@Component
@FeignClient(name = "service-vod",fallback = VodFileDegradeFeignClient.class) //调用的服务名称
public interface VodClient {
...
}

搭建项目前台环境

服务端渲染

服务端渲染又称SSR (Server Side Render)是在服务端完成页面的内容,而不是在客户端通过AJAX获取数据。

服务器端渲染(SSR)的优势主要在于:更好的 SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面。

如果你的应用程序初始展示 loading 菊花图,然后通过 Ajax 获取内容,抓取工具并不会等待异步完成后再进行页面内容的抓取。也就是说,如果 SEO 对你的站点至关重要,而你的页面又是异步获取内容,则你可能需要服务器端渲染(SSR)解决此问题。

另外,使用服务器端渲染,我们可以获得更快的内容到达时间(time-to-content),无需等待所有的JavaScript 都完成下载并执行,产生更好的用户体验,对于那些「内容到达时间(time-to-content)与转化率直接相关」的应用程序而言,服务器端渲染(SSR)至关重要。

什么是NUXT

Nuxt.js 是一个基于 Vue.js 的轻量级应用框架,可用来创建服务端渲染 (SSR) 应用,也可充当静态站点引擎生成静态站点应用,具有优雅的代码结构分层和热加载等特性。

NUXT目录结构

在这里插入图片描述

在这里插入图片描述

整合项目首页面

固定路由:路径是固定的

动态路由:

创建方式:

如果我们需要根据id查询一条记录,就需要使用动态路由,NUXT的动态路由是以下划线开头的vue文件,参数名为下划线后边的文件名

首页数据banner接口
@Service
public class CrmBannerServiceImpl extends ServiceImpl<CrmBannerMapper, CrmBanner> implements CrmBannerService {

    //查询所有的banner
    @Override
    public List<CrmBanner> selectAllBanner() {
        //根据id进行降序排列,只显示前2条记录
        QueryWrapper<CrmBanner> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id");

        //last方法,拼接sql语句
        wrapper.last("limit 2");

        List<CrmBanner> list = baseMapper.selectList(null);
        return list;
    }
}

整合Redis

Redis特点:

1、基于key-value进行存储的

2、支持多种数据结构:string、list、hash、set、zset

3、支持持久化,通过内存进行存储的,也可以存到硬盘里面

4、支持过期时间,支持事务

一般来说,把经常进行查询,不经常修改的,不是特别重要的数据放到redis作为缓存

整合步骤:

1、引入相关依赖

<!-- redis -->
<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- spring2.X集成redis所需common-pool2-->
<dependency> 
    <groupId>org.apache.commons</groupId> 
    <artifactId>commons-pool2</artifactId> 
    <version>2.6.0</version>
</dependency>

2、配置类

@Configuration //配置类
@EnableCaching //开启缓存
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory
                                                               factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new
                Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setConnectionFactory(factory);
//key序列化方式
        template.setKeySerializer(redisSerializer);
//value序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
//value hashmap序列化
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        return template;
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new
                Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间600秒
        RedisCacheConfiguration config =
                RedisCacheConfiguration.defaultCacheConfig()
                        .entryTtl(Duration.ofSeconds(600))

                        .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))

                        .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                        .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }
}

3、在查询所有Banner的方法上面添加缓存注释 @Cacheable

第一次查询:首先查询数据库,把数据库查询的数据返回,并且返回数据放到缓存中

第二次查询:查询缓存,发现缓存有数据,直接返回

在这里插入图片描述

4、启动redis服务

使用docker安装的redis,配置文件容器里没有,需要添加映射

  1. 创建docker统一的外部配置文件
mkdir -p docker/redis/{conf,data}
  1. 在conf目录创建redis.conf的配置文件
touch /docker/redis/conf/redis.conf
  1. 更改配置文件redis.conf,将其中的内容更改
#bind
#127.0.0.1
deemonize no #daemonize no 默认情况下,redis不是在后台运行的,如果需要在后台运行,把该项的值更改为yes
  1. 创建启动容器,加载配置文件并持久化数据
docker run -d --privileged=true -p 6379:6379 -v /docker/redis/conf/redis.conf:/etc/redis/redis.conf -v /docker/redis/data:/data --name redis-test redis redis-server /etc/redis/redis.conf --appendonly yes
  1. 使用redis-cli命令启动
  2. 启动前端,使用相关命令可以得到

在这里插入图片描述

登录实现

单点登录

单点登录三种常见方式:

1、session广播机制实现 session复制到每个模块中

2、使用cookie + redis实现

  1. 在项目中任何一个模块进行登录,登录之后,把数据放到两个地方

    1. redis:在key中生成唯一随机值(ip,用户id等) 在value生成用户数据

    2. cookie:把redis里面生成key值放到cookie里面

  2. 访问项目中其他模块,发送请求带着cookie进行发送、获取cookie值,拿着cookie做事情,把cookie获取值,到redis进行查询,根据key进行查询,如果可以获取到数据就是登录。

3、使用token实现

token是按照一定规则生成的字符串,字符串可以包含用户信息

  1. 在项目某个模块进行登录,登录之后,按照规则生成字符串,把登录之后用户包含到生成字符串里面,把字符串返回
    1. 可以把字符串通过cookie返回
    2. 把字符串通过地址栏返回
  2. 再去访问项目其他模块,每次返回在地址栏带着生成字符串,在访问模块里面获取地址栏字符串,根据字符串获取用户信息。如果可以获取到就是登录

JWT:

JWT就是给我们规定好了规则,使用jwt规则可以生成字符串,包含用户信息

JWT生成字符串包含三部分:

第一部分:jwt头信息

第二部分:有效载荷 包含主题信息(用户信息)

第三部分:签名哈希 防伪标志

邮箱验证

因为现在阿里云的短信服务不能使用,所以改为邮箱验证

在这里插入图片描述

所需要的依赖:

 <dependencies>
        <dependency>
            <groupId >com.sun.mail</groupId >
            <artifactId >javax.mail</artifactId >
            <version >1.5.4</version >
        </dependency>
        <dependency >
            <groupId >javax.mail</groupId >
            <artifactId >mail</artifactId >
            <version >1.4.5</version >
        </dependency>
    </dependencies>

待完工。


Oauth2

分布式登录:

1、登录成功后,按照一定的规则生成字符串,字符串包含用户信息

2、把生成字符串通过路径传递,或者cookie

3、后面再发送请求时长,每次带着字符串进行发送,获取字符串,从字符串获取用户信息登录

Oauth2解决方案:

令牌机制,按照一定规则生成字符串,字符串包含用户信息

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
gulimall_pms 商品 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 '属性&
根据引用中提供的信息,谷粒商城是一个B2C模式的电商平台,主要销售自营商品给客户。B2C模式指的是商对客的模式,即商家直接向消费者销售商品和服务。谷粒商城使用微服务架构,这是一种将应用程序拆分成独立且可独立开发、部署和扩展的小型服务的架构。引用还提到谷粒商城的技术涵盖微服务架构、分布式、全栈、集群、部署和自动化运维等方面。 因此,从前慢-谷粒商城篇章6主要讨论的可能是谷粒商城的技术方面,包括微服务架构、分布式、全栈、集群、部署和自动化运维等内容。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [从前慢-谷粒商城篇章1](https://blog.csdn.net/m0_67391121/article/details/125383572)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [2020年谷粒商城md笔记](https://download.csdn.net/download/ZHUXIUQINGIT/12543161)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qtayu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值