03课程发布模块课程预览

课程预览界面

界面原型

课程在发布前需要运营方进行审核,作为课程制作方即教学机构发布课程前可以通过课程预览功能查看课程详情界面,及时修改页面中的内容排版和违规问题

课程预览就是把课程的相关信息进行整合然后在课程预览界面进行展示,课程预览界面与将来要发布的课程详情界面一致

第一步: 教育机构在课程管理界面对该机构内所管理的课程进行检索

在这里插入图片描述

第二步: 点击某课程后的预览链接预览该课程的详情信息

在这里插入图片描述

第三步: 点击课程目录查看课程相关的课程计划信息

在这里插入图片描述

第四步: 在课程预览页面点击视频播放图片打开视频播放页面,通过视频播放页面可以选择相关的课程计划播放对应的视频

在这里插入图片描述

请求响应模型类

课程预览就是把课程的基本信息、营销信息、课程计划、师资等课程的相关信息进行整合,然后使用Freemarker将数据和模板结合渲染生成HTML页面

在这里插入图片描述

定义一个数据模型类用来整合课程的基本信息、营销信息、课程计划、师资等课程的相关信息

@Data
@ToString
public class CoursePreviewDto {
    // 课程基本信息,课程营销信息
    CourseBaseInfoDto courseBase;

    // 课程计划信息(章/节的基本信息和绑定的媒资信息)
    List<TeachplanDto> teachplans;

    //课程师资信息
}

接口定义

课程预览的效果与最终课程发布后查看到的效果是一致的,所以课程预览时会通过网站门户域名地址进行预览

在内容管理模块的接口工程中定义课程预览的接口,将查询到的课程信息与模板进行整合并在服务端渲染生成页面返回浏览器

  • 请求参数: 课程id表示要预览哪一门课程
  • 响应结果: 基于course_template.html静态页面创建resources/templates/course_template.ftl模板结合数据输出课程详情页面到浏览器

在这里插入图片描述

// 响应一个页面
@Controller
public class CoursePublishController {
    @Autowired
    CoursePublishService coursePublishService;

    @GetMapping("/coursepreview/{courseId}")
    public ModelAndView preview(@PathVariable("courseId") Long courseId){
        // 调用Service方法获取模板引擎需要的课程预览信息
        CoursePreviewDto coursePreviewInfo = coursePublishService.getCoursePreviewInfo(courseId);
        // 使用模板引擎将模板和数据进行整合
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("model",coursePreviewInfo);
        modelAndView.setViewName("course_template");
        return modelAndView;
    }
}

业务逻辑

编写CoursePublishService接口从数据库查询课程的基本信息、营销信息、课程计划等课程相关信息然后组成CoursePreviewDto对象

在这里插入图片描述

public interface CoursePublishService {
 /**
  * @description 获取课程预览信息
  * @param courseId 课程id
 */
   public CoursePreviewDto getCoursePreviewInfo(Long courseId);
}
@Service
public class CoursePublishServiceImpl implements CoursePublishService {
    @Autowired
    CourseBaseInfoService courseBaseInfoService;

    @Autowired
    TeachplanService teachplanService;

    @Override
    public CoursePreviewDto getCoursePreviewInfo(Long courseId) {
        // 查询课程基本信息、营销信息
        CourseBaseInfoDto courseBaseInfo = courseBaseInfoService.getCourseBaseInfo(courseId);

        // 查询课程计划信息
        List<TeachplanDto> teachplanTree= teachplanService.findTeachplanTree(courseId);

        // 组装查询到的信息 
        CoursePreviewDto coursePreviewDto = new CoursePreviewDto();
        coursePreviewDto.setCourseBase(courseBaseInfo);
        coursePreviewDto.setTeachplans(teachplanTree);
        return coursePreviewDto;
    }
}

定义模板

模型数据准备好后就将其填充到course_template.ftl上,填充时可以一边填充一边刷新调试,修改模板后需要编译

在这里插入图片描述

在调试模板时,对于缺少的课程信息可能是我们在添加课程时没有指定,我们可以在课程信息编辑界面进行补充,在模板中填充数据时如果数据为null会报错

在这里插入图片描述

视频播放界面

从课程详情页面进入视频播放页面后需要从后台获取课程计划信息以及课程计划中小节绑定的视频地址

在这里插入图片描述

配置公开接口

在nginx配置文件中进行配置,配置完后执行nginx.exe -s reload命令重新加载nginx的配置文件

# openapi 
location /open/content/ {     
	proxy_pass http://gatewayserver/content/open/; 
}  
location /open/media/ {
	proxy_pass http://gatewayserver/media/open/; 
} 

获取课程计划信息

# 请求
/open/content/course/whole/课程id

# 响应
课程预览模型

在内容管理模块的接口层定义CourseOpenController类,并定义获取课程计划信息接口

@Api(value = "课程公开查询接口", tags = "课程公开查询接口")
@Slf4j
@RestController
@RequestMapping("/open")
public class CourseOpenController {
    @Autowired
    private CoursePublishService coursePublishService;

    @GetMapping("/course/whole/{courseId}")
    public CoursePreviewDto getPreviewInfo(@PathVariable("courseId") Long courseId) {
        // 获取课程预览信息,包含课程计划信息
        CoursePreviewDto coursePreviewInfo = coursePublishService.getCoursePreviewInfo(courseId);
        return coursePreviewInfo;
    }
}

获取视频地址

# 请求
/open/media/preview/媒资文件id
# 响应
{"code":0,"msg":"success","result":"视频的url","successful":true}

在媒资管理服务media-api工程定义MediaOpenController类,定义根据媒资文件Id获取小节绑定视频地址的接口

@Api(value = "媒资文件管理接口",tags = "媒资文件管理接口")
@RestController
@RequestMapping("/open")
public class MediaOpenController {
    @Autowired
    MediaFileService mediaFileService;

    @ApiOperation("预览文件")
    @GetMapping("/preview/{mediaId}")
    public RestResponse<String> getPlayUrlByMediaId(@PathVariable String mediaId){
        // 获取文件的URL
        MediaFiles mediaFiles = mediaFileService.getFileById(mediaId);
        return RestResponse.success(mediaFiles.getUrl());
    }
}

media-service工程中编写Service接口及其实现类MediaFileServiceImpl

public interface MediaFileService {
    // 根据媒资文件Id获取文件对应URL
    MediaFiles getFileById(String mediaId);
}

@Service
@Slf4j
public class MediaFileServiceImpl implements MediaFileService {
    @Override
    public MediaFiles getFileById(String id) {
        MediaFiles mediaFiles = mediaFilesMapper.selectById(id);
        if (mediaFiles == null || StringUtils.isEmpty(mediaFiles.getUrl())) {
            XueChengPlusException.cast("视频还没有转码处理");
        }
        return mediaFiles;
    }
}

课程预览界面样式

配置Nginx

第一步:启动内容管理模块的接口工程,访问http://localhost:63040/content/coursepreview/74查看响应页面(不含样式)

在这里插入图片描述

第二步:对于课程预览界面中页面需要加载的样式和图片等静态资源无法直接访问,此时需要通过Nginx反向代理的方式访问课程预览接口

在这里插入图片描述

# 通过Nginx访问后台网关,然后由网关再将请求转发到具体的微服务,网关会把请求转发到具体的服务
upstream gatewayserver{
    server 127.0.0.1:63010 weight=10;
} 
server {
    listen       80;
    server_name  www.51xuecheng.cn localhost;
    ....
        location /api/ {
        proxy_pass http://gatewayserver/;
    } 
    .... 
 }

第三步:重启前端工程,修改网关地址

在这里插入图片描述

第四步: 启动网关,内容管理、媒资管理服务,进入课程列表点击预览按钮访问http://www.51xuecheng.cn/api/content/coursepreview/74,Nginx会加载页面需要的样式

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/487458.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

为jupyter安装和使用不同的python版本

安装好jupyter后&#xff0c;发现为默认的python3&#xff0c;想要切换到python3.10&#xff0c; 1.创建新环境python310 conda create -n python310 python3.10 2.进入新环境python310 conda activate python310 3.下载jupyter notebook conda install jupyter notebook…

802.1X网络访问控制协议

802.1X是一种由IEEE&#xff08;电气和电子工程师协会&#xff09;制定的网络访问控制协议&#xff0c;主要用于以太网和无线局域网&#xff08;WLAN&#xff09;中基于端口的网络接入控制。802.1X协议通过认证和授权机制&#xff0c;确保只有合法的用户和设备才能够接入网络&a…

Facebook如何使用增强技术提升广告效果?

AR in AD - case study 脸书2021年宣布了引入AR的新方法&#xff0c;以推动其应用套件中的产品发现和购买。但他们首先考虑是技术。据脸书称&#xff0c;技术一直是增强现实在其应用程序中更广泛使用的主要障碍。这就是为什么它现在正在做出改变&#xff0c;使企业主和广告商更…

OpenHarmony 源码解析之SystemUi—Statusbar(TS)

作者&#xff1a;董伟 简介 SystemUI应用是OpenHarmony中预置的系统应用&#xff0c;为用户提供系统相关信息展示及交互界面&#xff0c;包括系统状态、系统提示、系统提醒等&#xff0c;例如系统时间、电量信息。 本文主要分析batterycomponent、clockcomponent、wificompo…

2024年3月26日 十二生肖 今日运势

小运播报&#xff1a;2024年3月26日&#xff0c;星期二&#xff0c;农历二月十七 &#xff08;甲辰年丁卯月己丑日&#xff09;&#xff0c;法定工作日。 红榜生肖&#xff1a;鸡、鼠、猴 需要注意&#xff1a;马、狗、羊 喜神方位&#xff1a;东北方 财神方位&#xff1a;…

[HGAME 2023 week2]Designer

[HGAME 2023 week2]Designer 考点&#xff1a;XSS跨站脚本攻击&#xff0c;模板注入 代码审计 function auth(req, res, next) {const token req.headers["authorization"]if (!token) {return res.redirect("/")}try {const decoded jwt.verify(token,…

登录注册界面

T1、编程设计理工超市功能菜单并完成注册和登录功能的实现。 显示完菜单后&#xff0c;提示用户输入菜单项序号。当用户输入<注册>和<登录>菜单序号时模拟完成注册和登录功能&#xff0c;最后提示注册/登录成功并显示注册信息/欢迎XXX登录。当用户输入其他菜…

【随笔】Git -- 基本概念和使用方式(五)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

相机标定 手眼标定 网页版

欢迎使用&#xff0c;请移步ipv6 site (jah10527.github.io)

下载网页上的在线视频 网络视频 视频插件下载

只需要在浏览器上安装一个插件&#xff0c;就可以下载大部分的视频文件&#xff0c;几秒到一两个小时的视频&#xff0c;基本都不是问题。详细解决如下&#xff1a; 0、因为工作需要&#xff0c;需要获取某网站上的宣传视频&#xff0c;我像往常一样&#xff0c;查看视频的url…

C语言回顾笔记

1.变量 2.运算符 3.if判断 4.接力break 5.最大公约数 6.水仙花数 #include<stdio.h> int main(){int n;scanf("%d",&n);//根据输入的位数计算&#xff0c;如最小三位数100 int first 1;int i 1;while(i<n){first *10;i; }printf("first%d\n"…

数据分析POWER BI之power query

1.导入数据 ctrla全选--数据--获取数据--其他来源--来自表格/区域 导入数据&#xff0c;进入编辑模式 2.整理与清除 清除&#xff1a;删除所选列的非打印字符 转换--格式--清除 修整&#xff1a;删除前面和后面的空格 转换---格式---修整&#xff08;修整后前面后面的空格没有了…

代码随想录算法训练营第三十四天|1005. K次取反后最大化的数组和,135,分发糖果

1005. K 次取反后最大化的数组和 题目 给你一个整数数组 nums 和一个整数 k &#xff0c;按以下方法修改该数组&#xff1a; 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。 重复这个过程恰好 k 次。可以多次选择同一个下标 i 。 以这种方式修改数组后&#xff0c;返回数…

选项式API和组合式API的区别

选项式(options) API 和组合式(composition) API两种不同的风格书写&#xff0c;Vue3 的组件可以使用这两种api来编写。 选项式API和组合式API的区别 选项式API 选项式 API&#xff0c;具有相同功能的放在一起&#xff0c;可以用包含多个选项的对象来描述组件的逻辑&…

500元以内的运动耳机推荐有哪些?五大倍受欢迎的机型总汇

作为一个运动爱好者&#xff0c;我始终认为一款优秀的运动耳机不仅能够带来音乐的享受&#xff0c;更能为运动增添动力&#xff0c;但市面上的运动耳机种类繁多&#xff0c;价格不一&#xff0c;如何选择一款性价比高、功能实用的运动耳机成为了许多消费者的难题&#xff0c;今…

发布文章积分自动增加

controller ApiOperation(value "添加文章")PostMapping("/addwengzhang")public String addwengzhang(RequestBody WengDto wengDto) {if (wengDto.getContent() null || wengDto.getTitle() null) {return "参数不可为空";}User user user…

汽车ABS的bangbang控制和模糊PID控制

1、内容简介 略 82-可以交流、咨询、答疑 2、内容说明 摘要&#xff1a;本文旨在设计一种利用模糊控制理论优化的pid控制器&#xff0c;控制abs系统&#xff0c;达到对滑移率最佳控制范围的要求 &#xff0c;所提出的方案采用级联控制架构&#xff1a;设计用于外环中的车轮打…

[Java、Android面试]_12_java访问修饰符、抽象类和接口

文章目录 1. java访问修饰符2. 抽象类和接口2.1 抽象类2.2 接口2.3 抽象类和接口的区别 本人今年参加了很多面试&#xff0c;也有幸拿到了一些大厂的offer&#xff0c;整理了众多面试资料&#xff0c;后续还会分享众多面试资料。 整理成了面试系列&#xff0c;由于时间有限&…

(一)基于IDEA的JAVA基础8

使用多重if选择结构 多个if条件进行判断: 语法: if(条件1){ 执行语句1&#xff1b; }else if(条件2){ 执行语句2&#xff1b; }else if(条件3){ 执行语句3&#xff1b; }else if (条件4)…… 流程图: 我们来写个好玩的&#xff0c;对暗号: public class Test01 { …

【浅尝C++】类和对象第二弹=>类的6个默认成员函数/运算符重载详谈

&#x1f3e0;专栏介绍&#xff1a;浅尝C专栏是用于记录C语法基础、STL及内存剖析等。 &#x1f6a9;一些备注&#xff1a;之前的文章有点杂乱&#xff0c;这里将前面的知识点重新组织了&#xff0c;避免了过多冗余的废话。 &#x1f3af;每日努力一点点&#xff0c;技术变化看…