学成在线day08

news2024/12/1 5:45:23

部署静态页面

相关操作:https://mx67xggunk5.feishu.cn/wiki/FLozwxrrxihTJbkyTHgchDt4nUc

nginx的最终配置文件:

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    upstream fileserver{
        server 192.168.101.65:9000 weight=10;
    }
    server {
        listen       80;
        server_name  file.51xuecheng.cn;
        ssi on;
        ssi_silent_errors on;
        location /video {
            proxy_pass   http://fileserver;
        }
 
        location /mediafiles {
            proxy_pass   http://fileserver;
        }
    }
    server {
        listen       80;
        server_name  www.51xuecheng.cn localhost;
        ssi on;
        ssi_silent_errors on;
 
        location / { 
            alias   D:/Javanode/newxczx/xc-ui-pc-static-portal/;
            index  index.html index.htm;
        }
        location /static/img/ {  
                alias  D:/Javanode/newxczx/xc-ui-pc-static-portal/img/;
        } 
        location /static/css/ {  
                alias   D:/Javanode/newxczx/xc-ui-pc-static-portal/css/;
        } 
        location /static/js/ {  
                alias   D:/Javanode/newxczx/xc-ui-pc-static-portal/js/;
        } 
        location /static/plugins/ {  
                alias   D:/Javanode/newxczx/xc-ui-pc-static-portal/plugins/;
                add_header Access-Control-Allow-Origin http://ucenter.51xuecheng.cn;  
                add_header Access-Control-Allow-Credentials true;  
                add_header Access-Control-Allow-Methods GET;
        } 
        location /plugins/ {  
                alias   D:/Javanode/newxczx/xc-ui-pc-static-portal/plugins/;
        }
        location /course/preview/learning.html {
                alias D:/Javanode/newxczx/xc-ui-pc-static-portal/course/learning.html;
        } 
        location /course/search.html {  
                root   D:/Javanode/newxczx/xc-ui-pc-static-portal;
        } 
        location /course/learning.html {  
                root   D:/Javanode/newxczx/xc-ui-pc-static-portal;
        } 
    }
}

课程预览

接口开发

课程预览接口层:

由于要向模版中插入数据因此创建提个DTO进行存储:
 

@Data
public class CoursePreviewDto {
    //课程基本信息和课程营销信息
    CourseBaseInfoDto courseBase;
    //课程计划
    List<TeachplanDto> teachplans;
    //TODO 课程师资信息
}
    /**
     * 课程预览
     * @param courseId
     * @return
     */
 @GetMapping("/coursepreview/{courseId}")
 public ModelAndView preview(@PathVariable("courseId") Long courseId){
     CoursePreviewDto coursePreviewInfo = coursePublishService.getCoursePreviewInfo(courseId);
     ModelAndView modelAndView = new ModelAndView();
      modelAndView.addObject("model",coursePreviewInfo);
      modelAndView.setViewName("course_template");
        return modelAndView;
  }

service层:

    /**
     * @description 获取课程预览信息
     * @param courseId 课程id
     * @return com.xuecheng.content.model.dto.CoursePreviewDto
     * @author Mr.M
     * @date 2022/9/16 15:36
     */
    public CoursePreviewDto getCoursePreviewInfo(Long courseId);
    @Override
    public CoursePreviewDto getCoursePreviewInfo(Long courseId) {
        //查询数据库
        CoursePreviewDto coursePreviewInfo = new CoursePreviewDto();
        //查询课程详细信息
        CourseBaseInfoDto courseBaseInfo = courseBaseInfoService.getCourseBaseInfo(courseId);
        coursePreviewInfo.setCourseBase(courseBaseInfo);
        //查询课程计划
        List<TeachplanDto> teachplanTree = teachplanService.findTeachplanTree(courseId);
        coursePreviewInfo.setTeachplans(teachplanTree);
        return coursePreviewInfo;
    }

获取课程相关信息

课程预览界面的模版插槽(使用了freemark的模版插槽技术):将查询到的数据填充到代码中返回给前端,由于需要调用css等静态资源所以使用nginx服务器进行代理,将html代码进行结合,得到预览界面。

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="/static/img/asset-favicon.ico">
    <title>学成在线-${model.courseBase.name}</title>

    <link rel="stylesheet" href="/static/plugins/normalize-css/normalize.css" />
    <link rel="stylesheet" href="/static/plugins/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="/static/css/page-learing-article.css" />
</head>

<body data-spy="scroll" data-target="#articleNavbar" data-offset="150">
<!-- 页面头部 -->
<!--#include virtual="/include/header.html"-->
<!--页面头部结束sss-->
<div id="learningArea">
<div class="article-banner">
    <div class="banner-bg"></div>
    <div class="banner-info">
        <div class="banner-left">
            <p>${model.courseBase.mtName}<span>\ ${model.courseBase.stName}</span></p>
            <p class="tit">${model.courseBase.name}</p>
            <p class="pic">
                <#if model.courseBase.charge=='201000'>
                    <span class="new-pic">免费</span>
                <#else>
                    <span class="new-pic">特惠价格¥${model.courseBase.price!''}</span>
                    <span class="old-pic">原价¥${model.courseBase.originalPrice!''}</span>
                </#if>
            </p>
            <p class="info">
                <a href="#" @click.prevent="startLearning()">马上学习</a>
                <span><em>难度等级</em>
                <#if model.courseBase.grade=='204001'>
                    初级
                 <#elseif model.courseBase.grade=='204002'>
                    中级
                <#elseif model.courseBase.grade=='204003'>
                    高级
                </#if>
                </span>
                <span><em>课程时长</em>2小时27分</span>
                <span><em>评分</em>4.7分</span>
                <span><em>授课模式</em>
                 <#if model.courseBase.teachmode=='200002'>
                     录播
                 <#elseif model.courseBase.teachmode=='200003'>
                     直播
                 </#if>
                </span>
            </p>
        </div>
        <div class="banner-rit">
            <p>
                <a href="http://www.51xuecheng.cn/course/preview/learning.html?id=${model.courseBase.id}" target="_blank">
                    <#if model.courseBase.pic??>
                        <img src="http://file.51xuecheng.cn${model.courseBase.pic}" alt="" width="270" height="156">
                    <#else>
                        <img src="/static/img/widget-video.png" alt="" width="270" height="156">
                    </#if>

                </a>
            </p>
            <p class="vid-act"><span> <i class="i-heart"></i>收藏 23 </span> <span>分享 <i class="i-weixin"></i><i class="i-qq"></i></span></p>
        </div>
    </div>
</div>
<div class="article-cont">
    <div class="tit-list">
        <a href="javascript:;" id="articleClass" class="active">课程介绍</a>
        <a href="javascript:;" id="articleItem">目录</a>
        <a href="javascript:;" id="artcleAsk">问答</a>
        <a href="javascript:;" id="artcleNot">笔记</a>
        <a href="javascript:;" id="artcleCod">评价</a>
        <!--<div class="down-fill">
            <span>资料下载</span>
            <ul>
                <li>java视频资料</li>
                <li>java视频资料</li>
                <li>java视频资料</li>
            </ul>
        </div>-->
    </div>
    <div class="article-box">
        <div class="articleClass" style="display: block">
            <!--<div class="rit-title">评价</div>-->
            <div class="article-cont">
                <div class="article-left-box">
                    <div class="content">

                        <div class="content-com suit">
                            <div class="title"><span>适用人群</span></div>
                            <div class="cont cktop">
                                <div >
                                    <p>${model.courseBase.users!""}</p>
                                </div>
                                <!--<span class="on-off">更多 <i class="i-chevron-bot"></i></span>-->
                            </div>
                        </div>
                        <div class="content-com course">
                            <div class="title"><span>课程制作</span></div>
                            <div class="cont">
                                <div class="img-box"><img src="/static/img/widget-myImg.jpg" alt=""></div>
                                <div class="info-box">
                                    <p class="name">教学方:<em>XX老师</em></p>
                                    <!-- <p class="lab">高级前端开发工程师 10年开发经验</p>-->
                                    <p class="info">JavaEE开发与教学多年,精通JavaEE技术体系,对流行框架JQuery、DWR、Struts1/2,Hibernate,Spring,MyBatis、JBPM、Lucene等有深入研究。授课逻辑严谨,条理清晰,注重学生独立解决问题的能力。</p>
                                    <!-- <p><span>难度等级</span>中级</p>
                                     <p><span>课程时长</span>8-16小时/周,共4周</p>
                                     <p><span>如何通过</span>通过所有的作业及考核,作业共4份,考核为一次终极考核</p>
                                     <p><span>用户评分</span>平均用户评分 <em>4.9</em> <a href="#">查看全部评价</a></p>
                                     <p><span>课程价格</span>特惠价格<em>¥999</em> <i> 原价1999 </i></p>-->
                                </div>
                            </div>

                        </div>
                        <div class="content-com about">
                            <div class="title"><span>课程介绍</span></div>
                            <div class="cont cktop">
                                <div >
                                    <p>${model.courseBase.description!""}</p>
                                </div>
                                <!--<span class="on-off">更多 <i class="i-chevron-bot"></i></span>-->
                            </div>
                        </div>
                        <div class="content-com prob">
                            <div class="title"><span>常见问题</span></div>
                            <div class="cont">
                                <ul>
                                    <li class="item"><span class="on-off"><i class="i-chevron-bot"></i> 我什么时候能够访问课程视频与作业?</span>
                                        <div class="drop-down">
                                            <p>课程安排灵活,课程费用支付提供180天全程准入和资格证书。自定进度课程建议的最后期限,但你不会受到惩罚错过期限,只要你赚你的证书在180天内。以会话为基础的课程可能要求你在截止日期前保持正轨,但如果你落后了,你可以切换到以后的会议,你完成的任何工作将与你转移。</p>
                                        </div>
                                    </li>
                                    <li class="item"><span class="on-off"><i class="i-chevron-bot"></i> 如何需要额外的时间来完成课程会怎么样?</span>
                                        <div class="drop-down">
                                            <p>课程安排灵活,课程费用支付提供180天全程准入和资格证书。自定进度课程建议的最后期限,但你不会受到惩罚错过期限,只要你赚你的证书在180天内。以会话为基础的课程可能要求你在截止日期前保持正轨,但如果你落后了,你可以切换到以后的会议,你完成的任何工作将与你转移。</p>
                                        </div>
                                    </li>
                                    <li class="item"><span class="on-off"><i class="i-chevron-bot"></i> 我支付次课程之后会得到什么?</span>
                                        <div class="drop-down">
                                            <p>课程安排灵活,课程费用支付提供180天全程准入和资格证书。自定进度课程建议的最后期限,但你不会受到惩罚错过期限,只要你赚你的证书在180天内。以会话为基础的课程可能要求你在截止日期前保持正轨,但如果你落后了,你可以切换到以后的会议,你完成的任何工作将与你转移。</p>
                                        </div>
                                    </li>
                                    <li class="item"><span class="on-off"><i class="i-chevron-bot"></i> 退款条例是如何规定的?</span>
                                        <div class="drop-down">
                                            <p>课程安排灵活,课程费用支付提供180天全程准入和资格证书。自定进度课程建议的最后期限,但你不会受到惩罚错过期限,只要你赚你的证书在180天内。以会话为基础的课程可能要求你在截止日期前保持正轨,但如果你落后了,你可以切换到以后的会议,你完成的任何工作将与你转移。</p>
                                        </div>
                                    </li>
                                    <li class="item"><span class="on-off"><i class="i-chevron-bot"></i> 有助学金?</span>
                                        <div class="drop-down">
                                            <p>课程安排灵活,课程费用支付提供180天全程准入和资格证书。自定进度课程建议的最后期限,但你不会受到惩罚错过期限,只要你赚你的证书在180天内。以会话为基础的课程可能要求你在截止日期前保持正轨,但如果你落后了,你可以切换到以后的会议,你完成的任何工作将与你转移。</p>
                                        </div>
                                    </li>
                                </ul>
                            </div>
                        </div>
                    </div>
                </div>

                <!--侧边栏-->
                <!--#include virtual="/include/course_detail_side.html"-->
                <!--侧边栏-->

            </div>
        </div>
        <div class="articleItem" style="display: none">
            <div class="article-cont-catalog">
                <div class="article-left-box">
                    <div class="content">
                        <#list model.teachplans as firstNode>
                            <div class="item">
                                <div class="title act"><i class="i-chevron-top"></i>${firstNode.pname}<span class="time">x小时</span></div>
                                <div class="drop-down" style="height: 260px;">
                                    <ul class="list-box">
                                        <#list firstNode.teachPlanTreeNodes as secondNode>
                                            <li><a href="http://www.51xuecheng.cn/course/preview/learning.html?id=${model.courseBase.id}&chapter=${secondNode.teachplanMedia.teachplanId!''}" target="_blank">${secondNode.pname}</a></li>
                                        </#list>
                                    </ul>
                                </div>
                            </div>
                        </#list>
                       <#-- <div class="item">
                            <div class="title act"><i class="i-chevron-top"></i>第一阶段 HTTP协议基础详解<span class="time">8小时</span></div>
                            <div class="about">使用Java消息中间件处理异步消息成为了分布式系统中的必修课,通过本门课程可以深入浅出的学习如何在Java中使用消息中间件并且一步一步打造更优雅的最佳实践方案。</div>
                            <div class="drop-down" style="height: 260px;">
                                <ul class="list-box">
                                    <li class="active">1.1 阅读:分级政策细节 <span>97’33”</span></li>
                                    <li>1.2 视频:为什么分为 A 部分、B 部分、C 部分 <span>66’15”</span></li>
                                    <li>1.3 视频:软件安装介绍 <span>86’42”</span></li>
                                    <li>1.4 阅读:Emacs安装 <span>59’00”</span></li>
                                    <li>1.5 作业1:Emacs安装 <span>93’29”</span></li>
                                    <li>阶段测试</li>
                                </ul>
                            </div>
                        </div>-->


                    </div>
                </div>
                <!--侧边栏-->
                <!--#include virtual="/include/course_detail_side.html"-->
                <!--侧边栏-->
            </div>
        </div>
        <#--<div class="articleItem" style="display: none">
            <div class="article-cont-catalog">
                <div class="article-left-box">
                    <div class="content">
                        <div class="item">
                            <div class="title act"><i class="i-chevron-top"></i>第一阶段 HTTP协议基础详解<span class="time">8小时</span></div>
                            <div class="about">使用Java消息中间件处理异步消息成为了分布式系统中的必修课,通过本门课程可以深入浅出的学习如何在Java中使用消息中间件并且一步一步打造更优雅的最佳实践方案。</div>
                            <div class="drop-down" style="height: 260px;">
                                <ul class="list-box">
                                    <li class="active">1.1 阅读:分级政策细节 <span>97’33”</span></li>
                                    <li>1.2 视频:为什么分为 A 部分、B 部分、C 部分 <span>66’15”</span></li>
                                    <li>1.3 视频:软件安装介绍 <span>86’42”</span></li>
                                    <li>1.4 阅读:Emacs安装 <span>59’00”</span></li>
                                    <li>1.5 作业1:Emacs安装 <span>93’29”</span></li>
                                    <li>阶段测试</li>
                                </ul>
                            </div>
                        </div>
                        <div class="item">
                            <div class="title"><i class="i-chevron-bot"></i>第二阶段 HTTP协议基础详解<span class="time">8小时</span></div>
                            <div class="about">使用Java消息中间件处理异步消息成为了分布式系统中的必修课,通过本门课程可以深入浅出的学习如何在Java中使用消息中间件并且一步一步打造更优雅的最佳实践方案。</div>
                            <div class="drop-down">
                                <ul class="list-box">
                                    <li class="active">1.1 阅读:分级政策细节 <span>97’33”</span></li>
                                    <li>1.2 视频:为什么分为 A 部分、B 部分、C 部分 <span>66’15”</span></li>
                                    <li>1.3 视频:软件安装介绍 <span>86’42”</span></li>
                                    <li>1.4 阅读:Emacs安装 <span>59’00”</span></li>
                                    <li>1.5 作业1:Emacs安装 <span>93’29”</span></li>
                                    <li>阶段测试</li>
                                </ul>
                            </div>
                        </div>
                        <div class="item">
                            <div class="title"><i class="i-chevron-bot"></i>第三阶段 HTTP协议基础详解<span class="time">3小时</span></div>
                            <div class="about">使用Java消息中间件处理异步消息成为了分布式系统中的必修课,通过本门课程可以深入浅出的学习如何在Java中使用消息中间件并且一步一步打造更优雅的最佳实践方案。</div>
                            <div class="drop-down">
                                <ul class="list-box">
                                    <li class="active">1.1 阅读:分级政策细节 <span>97’33”</span></li>
                                    <li>1.2 视频:为什么分为 A 部分、B 部分、C 部分 <span>66’15”</span></li>
                                    <li>1.3 视频:软件安装介绍 <span>86’42”</span></li>
                                    <li>1.4 阅读:Emacs安装 <span>59’00”</span></li>
                                    <li>1.5 作业1:Emacs安装 <span>93’29”</span></li>
                                    <li>阶段测试</li>
                                </ul>
                            </div>
                        </div>
                        <div class="item">
                            <div class="title"><i class="i-chevron-bot"></i>第四阶段 HTTP协议基础详解<span class="time">3小时</span></div>
                            <div class="about">使用Java消息中间件处理异步消息成为了分布式系统中的必修课,通过本门课程可以深入浅出的学习如何在Java中使用消息中间件并且一步一步打造更优雅的最佳实践方案。</div>
                            <div class="drop-down">
                                <ul class="list-box">
                                    <li class="active">1.1 阅读:分级政策细节 <span>97’33”</span></li>
                                    <li>1.2 视频:为什么分为 A 部分、B 部分、C 部分 <span>66’15”</span></li>
                                    <li>1.3 视频:软件安装介绍 <span>86’42”</span></li>
                                    <li>1.4 阅读:Emacs安装 <span>59’00”</span></li>
                                    <li>1.5 作业1:Emacs安装 <span>93’29”</span></li>
                                    <li>阶段测试</li>
                                </ul>
                            </div>
                        </div>
                        <div class="item">
                            <div class="title"><i class="i-chevron-bot"></i>第五阶段 HTTP协议基础详解<span class="time">3小时</span></div>
                            <div class="about">使用Java消息中间件处理异步消息成为了分布式系统中的必修课,通过本门课程可以深入浅出的学习如何在Java中使用消息中间件并且一步一步打造更优雅的最佳实践方案。</div>
                            <div class="drop-down">
                                <ul class="list-box">
                                    <li class="active">1.1 阅读:分级政策细节 <span>97’33”</span></li>
                                    <li>1.2 视频:为什么分为 A 部分、B 部分、C 部分 <span>66’15”</span></li>
                                    <li>1.3 视频:软件安装介绍 <span>86’42”</span></li>
                                    <li>1.4 阅读:Emacs安装 <span>59’00”</span></li>
                                    <li>1.5 作业1:Emacs安装 <span>93’29”</span></li>
                                    <li>阶段测试</li>
                                </ul>
                            </div>

                        </div>
                        <div class="item">
                            <a href="#" class="overwrite">毕业考核</a>
                        </div>
                    </div>
                </div>
                <!--侧边栏&ndash;&gt;
                <!--#include virtual="/include/course_detail_side.html"&ndash;&gt;
                <!--侧边栏&ndash;&gt;
            </div>
        </div>-->
        <div class="artcleAsk" style="display: none">
            <div class="article-cont-ask">
                <div class="article-left-box">
                    <div class="content">
                        <div class="content-title">
                            <p><a class="all">全部</a><a>精选</a><a>我的</a></p>
                            <p><a class="all">全部</a><span><a>1.1</a><a>1.2</a><a>1.3</a><a>1.4</a><a>1.5</a></span><a href="$" class="more">更多 <i class="i-chevron-bot"></i></a></p>
                        </div>
                        <div class="item">
                            <div class="item-left">
                                <p><img src="/static/img/widget-myImg.jpg" width="60px" alt=""></p>
                                <p>毛老师</p>
                            </div>
                            <div class="item-right">
                                <p class="title">如何用微服务重构应用程序?</p>
                                <p><span>我来回答</span></p>
                                <p>2017-3-20 <span><i></i>回答2</span><span><i></i>浏览2</span></p>
                            </div>
                        </div>
                        <div class="item">
                            <div class="item-left">
                                <p><img src="/static/img/widget-myImg.jpg" width="60px" alt=""></p>
                                <p>毛老师</p>
                            </div>
                            <div class="item-right">
                                <p class="title">如何用微服务重构应用程序?</p>
                                <p>在讨论如何将重构转化为微服务之前,退后一步,仔细观察微服务的内容和时间是很重要的。以下两个要点将会对任何微服务重构策略产生重大影响。 【最新 <i class="new">心跳347890</i> 的回答】</p>
                                <p>2017-3-20 <span class="action-box"><span><i class="i-answer"></i>回答 2</span><span><i class="i-browse"></i>浏览 12</span></span>
                                </p>
                            </div>
                        </div>
                        <div class="item">
                            <div class="item-left">
                                <p><img src="/static/img/widget-myImg.jpg" width="60px" alt=""></p>
                                <p>毛老师</p>
                            </div>
                            <div class="item-right">
                                <p class="title">如何用微服务重构应用程序?</p>
                                <p>在讨论如何将重构转化为微服务之前,退后一步,仔细观察微服务的内容和时间是很重要的。以下两个要点将会对任何微服务重构策略产生重大影响。 【最新 <i class="new">心跳347890</i> 的回答】</p>
                                <p>2017-3-20 <span class="action-box"><span><i class="i-answer"></i>回答 2</span><span><i class="i-browse"></i>浏览 12</span></span>
                                </p>
                            </div>
                        </div>
                        <div class="item">
                            <div class="item-left">
                                <p><img src="/static/img/widget-myImg.jpg" width="60px" alt=""></p>
                                <p>毛老师</p>
                            </div>
                            <div class="item-right">
                                <p class="title">如何用微服务重构应用程序?</p>
                                <p>在讨论如何将重构转化为微服务之前,退后一步,仔细观察微服务的内容和时间是很重要的。以下两个要点将会对任何微服务重构策略产生重大影响。 【最新 <i class="new">心跳347890</i> 的回答】</p>
                                <p>2017-3-20 <span class="action-box"><span><i class="i-answer"></i>回答 2</span><span><i class="i-browse"></i>浏览 12</span></span>
                                </p>
                            </div>
                        </div>
                        <div class="item">
                            <div class="item-left">
                                <p><img src="/static/img/widget-myImg.jpg" width="60px" alt=""></p>
                                <p>毛老师</p>
                            </div>
                            <div class="item-right">
                                <p class="title">如何用微服务重构应用程序?</p>
                                <p>在讨论如何将重构转化为微服务之前,退后一步,仔细观察微服务的内容和时间是很重要的。以下两个要点将会对任何微服务重构策略产生重大影响。 【最新 <i class="new">心跳347890</i> 的回答】</p>
                                <p>2017-3-20 <span class="action-box"><span><i class="i-answer"></i>回答 2</span><span><i class="i-browse"></i>浏览 12</span></span>
                                </p>
                            </div>
                        </div>
                        <div class="item">
                            <div class="item-left">
                                <p><img src="/static/img/widget-myImg.jpg" width="60px" alt=""></p>
                                <p>毛老师</p>
                            </div>
                            <div class="item-right">
                                <p class="title">如何用微服务重构应用程序?</p>
                                <p>在讨论如何将重构转化为微服务之前,退后一步,仔细观察微服务的内容和时间是很重要的。以下两个要点将会对任何微服务重构策略产生重大影响。 【最新 <i class="new">心跳347890</i> 的回答】</p>
                                <p>2017-3-20 <span class="action-box"><span><i class="i-answer"></i>回答 2</span><span><i class="i-browse"></i>浏览 12</span></span>
                                </p>
                            </div>
                        </div>

                        <div class="itemlast">
                            <a href="#" class="overwrite">显示更多问题</a>
                        </div>
                    </div>
                </div>
                <!--侧边栏-->
                <!--#include virtual="/include/course_detail_side.html"-->
                <!--侧边栏-->
            </div>
        </div>
        <div class="artcleNot" style="display: none;">
            <div class="article-cont-note">
                <div class="article-left-box">
                    <div class="content">
                        <div class="content-title">
                            <p><a class="all">全部</a><a>精选</a><a>我的</a></p>
                            <p><a class="all">全部</a><span><a>1.1</a><a>1.2</a><a>1.3</a><a>1.4</a><a>1.5</a></span><a href="$" class="more">更多 <i class="i-chevron-bot"></i></a></p>
                        </div>
                        <div class="item">
                            <div class="item-left">
                                <p><img src="/static/img/widget-myImg.jpg" width="60px" alt=""></p>
                                <p>毛老师</p>
                            </div>
                            <div class="item-right">
                                <span class="video-time"><i class="i-play"></i>2`10`</span>
                                <p><img src="/static/img/widget-demo.png" width="221" alt=""></p>
                                <p class="action-box">4小时前 <span class="active-box"><span><i class="i-coll"></i>采集</span><span><i class="i-laud"></i>赞</span></span>
                                </p>
                            </div>
                        </div>
                        <div class="item">
                            <div class="item-left">
                                <p><img src="/static/img/widget-myImg.jpg" width="60px" alt=""></p>
                                <p>毛老师</p>
                            </div>
                            <div class="item-right">
                                <p>在讨论如何将重构转化为微服务之前,退后一步,<br>仔细观察微服务的内容和时间是很重要的。<br>以下两个要点将会对任何微服务重构策略产生重大影响。 </p>
                                <p class="action-box">4小时前 <span class="active-box"><span><i class="i-edt"></i>编辑</span><span><i class="i-del"></i>删除</span><span><i class="i-laud"></i>赞</span></span>
                                </p>
                            </div>
                        </div>
                        <div class="item">
                            <div class="item-left">
                                <p><img src="/static/img/widget-myImg.jpg" width="60px" alt=""></p>
                                <p>毛老师</p>
                            </div>
                            <div class="item-right">
                                <p>在讨论如何将重构转化为微服务之前,退后一步,<br>仔细观察微服务的内容和时间是很重要的。<br>以下两个要点将会对任何微服务重构策略产生重大影响。 </p>
                                <p class="action-box">4小时前 <span class="active-box"><span><i class="i-edt"></i>编辑</span><span><i class="i-del"></i>删除</span><span><i class="i-laud"></i>赞</span></span>
                                </p>
                            </div>
                        </div>
                        <div class="item">
                            <div class="item-left">
                                <p><img src="/static/img/widget-myImg.jpg" width="60px" alt=""></p>
                                <p>毛老师</p>
                            </div>
                            <div class="item-right">
                                <p>在讨论如何将重构转化为微服务之前,退后一步,<br>仔细观察微服务的内容和时间是很重要的。<br>以下两个要点将会对任何微服务重构策略产生重大影响。 </p>
                                <p class="action-box">4小时前 <span class="active-box"><span><i class="i-edt"></i>编辑</span><span><i class="i-del"></i>删除</span><span><i class="i-laud"></i>赞</span></span>
                                </p>
                            </div>
                        </div>
                    </div>
                </div>
                <!--侧边栏-->
                <!--#include virtual="/include/course_detail_side.html"-->
                <!--侧边栏-->
            </div>
        </div>
        <div class="artcleCod" style="display: none;">
            <div class="article-cont">
                <div class="article-left-box">
                    <div class="comment-box">
                        <div class="evaluate">
                            <div class="eva-top">
                                <div class="tit">课程评分 </div>
                                <div class="star">
                                    <div class="score"><i>5</i></div>
                                </div><span class="star-score"> <i>5</i> 分</span></div>
                            <div class="eva-cont">
                                <div class="tit">学员评语 </div>
                                <div class="text-box">
                                    <textarea class="form-control" rows="5" placeholder="扯淡、吐槽、表扬、鼓励......想说啥说啥!"></textarea>
                                    <div class="text-right"><span>发表评论</span></div>
                                </div>
                            </div>
                        </div>
                        <div class="course-evaluate">
                            <div class="top-tit">评论
                                <span>
                        <label><input name="eval" type="radio" value="" checked /> 所有学生 </label>
                        <label><input name="eval" type="radio" value="" /> 完成者 </label>
                    </span>
                            </div>
                            <div class="top-cont">
                                <div class="cont-top-left">
                                    <div class="star-scor">
                                        <div class="star-show">
                                            <div class="score"><i>5</i></div>
                                        </div>
                                        <div class="scor">4.9分</div>
                                    </div>
                                    <div class="all-scor">总评分:12343</div>
                                </div>
                                <div class="cont-top-right">
                                    <div class="star-grade">五星
                                        <div class="grade">
                                            <div class="grade-percent"><span></span></div>
                                            <div class="percent-num"><i>95</i>%</div>
                                        </div>
                                    </div>
                                    <div class="star-grade">四星
                                        <div class="grade">
                                            <div class="grade-percent"><span></span></div>
                                            <div class="percent-num"><i>5</i>%</div>
                                        </div>
                                    </div>
                                    <div class="star-grade">三星
                                        <div class="grade">
                                            <div class="grade-percent"><span></span></div>
                                            <div class="percent-num"><i>0</i>%</div>
                                        </div>
                                    </div>
                                    <div class="star-grade">二星
                                        <div class="grade">
                                            <div class="grade-percent"><span></span></div>
                                            <div class="percent-num"><i>2</i>%</div>
                                        </div>
                                    </div>
                                    <div class="star-grade">一星
                                        <div class="grade">
                                            <div class="grade-percent"><span></span></div>
                                            <div class="percent-num"><i>1</i>%</div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div class="comment-item-box">
                                <div class="title">评论 <span>12453条评论</span></div>
                                <div class="item">
                                    <div class="item-left">
                                        <p><img src="/static/img/widget-pic.png" width="60px" alt=""></p>
                                        <p>毛老师</p>
                                    </div>
                                    <div class="item-cent">
                                        <p>很受用,如果再深入下就更好了。虽然都是入门级别的,但是也很使用,后续就需要自己发挥了!虽然都是入门级别的,但是也很使用,后续就需要自己发挥了!虽然都是入门级别的,但是也很使用,后续就需要自己发挥了!虽然都是入门级别的,但是也很使用,后续就需要自己发挥了!</p>
                                        <p class="time">2017-2-43</p>
                                    </div>
                                    <div class="item-rit">
                                        <p>
                                        <div class="star-show">
                                            <div class="score"><i>4</i></div>
                                        </div>
                                        </p>
                                        <p>评分 <span>5星</span></p>
                                    </div>
                                </div>
                                <div class="item">
                                    <div class="item-left">
                                        <p><img src="/static/img/widget-pic.png" width="60px" alt=""></p>
                                        <p>毛老师</p>
                                    </div>
                                    <div class="item-cent">
                                        <p>很受用,如果再深入下就更好了。虽然都是入门级别的,但是也很使用,后续就需要自己发挥了!虽然都是入门级别的,但是也很使用,后续就需要自己发挥了!虽然都是入门级别的,但是也很使用,后续就需要自己发挥了!虽然都是入门级别的,但是也很使用,后续就需要自己发挥了!</p>
                                        <p class="time">2017-2-43</p>
                                    </div>
                                    <div class="item-rit">
                                        <p>
                                        <div class="star-show">
                                            <div class="score"><i>5</i></div>
                                        </div>
                                        </p>
                                        <p>评分 <span>5星</span></p>
                                    </div>
                                </div>
                                <div class="item">
                                    <div class="item-left">
                                        <p><img src="/static/img/widget-pic.png" width="60px" alt=""></p>
                                        <p>毛老师</p>
                                    </div>
                                    <div class="item-cent">
                                        <p>很受用,如果再深入下就更好了。虽然都是入门级别的,但是也很使用,后续就需要自己发挥了!虽然都是入门级别的,但是也很使用,后续就需要自己发挥了!虽然都是入门级别的,但是也很使用,后续就需要自己发挥了!虽然都是入门级别的,但是也很使用,后续就需要自己发挥了!</p>
                                        <p class="time">2017-2-43</p>
                                    </div>
                                    <div class="item-rit">
                                        <p>
                                        <div class="star-show">
                                            <div class="score"><i>5</i></div>
                                        </div>
                                        </p>
                                        <p>评分 <span>5星</span></p>
                                    </div>
                                </div>
                                <div class="item">
                                    <div class="item-left">
                                        <p><img src="/static/img/widget-pic.png" width="60px" alt=""></p>
                                        <p>毛老师</p>
                                    </div>
                                    <div class="item-cent">
                                        <p>很受用,如果再深入下就更好了。虽然都是入门级别的,但是也很使用,后续就需要自己发挥了!虽然都是入门级别的,但是也很使用,后续就需要自己发挥了!虽然都是入门级别的,但是也很使用,后续就需要自己发挥了!虽然都是入门级别的,但是也很使用,后续就需要自己发挥了!</p>
                                        <p class="time">2017-2-43</p>
                                    </div>
                                    <div class="item-rit">
                                        <p>
                                        <div class="star-show">
                                            <div class="score"><i>5</i></div>
                                        </div>
                                        </p>
                                        <p>评分 <span>5星</span></p>
                                    </div>
                                </div>
                                <div class="get-more">页面加载中...</div>
                            </div>
                        </div>
                    </div>
                </div>
                <!--侧边栏-->
                <!--#include virtual="/include/course_detail_side.html"-->
                <!--侧边栏-->
            </div>
        </div>
    </div>
</div>
    <div class="popup-course">
        <div class="mask"></div>
        <!--欢迎访问课程弹窗- start -->
        <div class="popup-course-box">
            <div class="title">${model.courseBase.name} <span class="close-popup-course-box">×</span></div>
            <div class="content">
                <p>欢迎学习本课程,本课程免费您可以立即学习,也可加入我的课程表享受更优质的服务。</p>
                <p><a href="#" @click.prevent="addCourseTable()">加入我的课程表</a>  <a href="#" @click.prevent="startLearngin()">立即学习</a></p>
            </div>
        </div>
    </div>
    <div class="popup-box">
        <div class="mask"></div>
        <!--支付弹窗- start -->
        <div class="popup-pay-box">
            <div class="title">${model.courseBase.name} <span class="close-popup-pay-box">×</span></div>
            <div class="content">
                <img :src="qrcode" width="200" height="200" alt="请点击支付宝支付按钮,并完成扫码支付。"/>

                <div class="info">
                    <p class="info-tit">${model.courseBase.name}<span>课程有效期:${model.courseBase.validDays}天</span></p>
                    <p class="info-pic">课程价格 : <span>¥${model.courseBase.originalPrice!''}元</span></p>
                    <p class="info-new-pic">优惠价格 : <span>¥${model.courseBase.price!''}元</span></p>
                </div>
            </div>
            <div class="fact-pic">实际支付: <span>¥${model.courseBase.price!''}元</span></div>
            <div class="go-pay"><a href="#" @click.prevent="wxPay()">微信支付</a><a href="#" @click.prevent="aliPay()">支付宝支付</a><a href="#" @click.prevent="querypayresult()">支付完成</a><a href="#" @click.prevent="startLearngin()">试学</a></div>
        </div>
        <!--支付弹窗- end -->
        <div class="popup-comment-box">

        </div>
    </div>
    <!-- 页面底部 -->
    <!--底部版权-->
    <!--#include virtual="/include/footer.html"-->
    <!--底部版权-->
</div>
<script>var courseId = "${model.courseBase.id}";var courseCharge = "${model.courseBase.charge}"</script>
<!--#include virtual="/include/course_detail_dynamic.html"-->
</body>

nginx的配置文件:

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    upstream fileserver{
        server 192.168.101.65:9000 weight=10;
    }
    #后台网关
    upstream gatewayserver{
        server 127.0.0.1:63010 weight=10;
    } 
    server {
        listen       80;
        server_name  file.51xuecheng.cn;
        ssi on;
        ssi_silent_errors on;
        location /video {
            proxy_pass   http://fileserver;
        }
 
        location /mediafiles {
            proxy_pass   http://fileserver;
        }
    }
    server {
        listen       80;
        server_name  www.51xuecheng.cn localhost;
        ssi on;
        ssi_silent_errors on;
 
        location / { 
            alias   D:/Javanode/newxczx/xc-ui-pc-static-portal/;
            index  index.html index.htm;
        }
        location /static/img/ {  
                alias  D:/Javanode/newxczx/xc-ui-pc-static-portal/img/;
        } 
        location /static/css/ {  
                alias   D:/Javanode/newxczx/xc-ui-pc-static-portal/css/;
        } 
        location /static/js/ {  
                alias   D:/Javanode/newxczx/xc-ui-pc-static-portal/js/;
        } 
        location /static/plugins/ {  
                alias   D:/Javanode/newxczx/xc-ui-pc-static-portal/plugins/;
                add_header Access-Control-Allow-Origin http://ucenter.51xuecheng.cn;  
                add_header Access-Control-Allow-Credentials true;  
                add_header Access-Control-Allow-Methods GET;
        } 
        location /plugins/ {  
                alias   D:/Javanode/newxczx/xc-ui-pc-static-portal/plugins/;
        }
        location /course/preview/learning.html {
                alias D:/Javanode/newxczx/xc-ui-pc-static-portal/course/learning.html;
        } 
        location /course/search.html {  
                root   D:/Javanode/newxczx/xc-ui-pc-static-portal;
        } 
        location /course/learning.html {  
                root   D:/Javanode/newxczx/xc-ui-pc-static-portal;
        } 
        location /open/content/ {
                proxy_pass http://gatewayserver/content/open/;
        } 
        location /open/media/ {
                proxy_pass http://gatewayserver/media/open/;
        } 
                #api
        location /api/ {
                proxy_pass http://gatewayserver/;
        } 

    }
}

同时该配置文件中还配置了网关,所有的请求都要通过网关服务进行转发。

视屏播放和获取课程计划信息

由于课程预览界面要播放视屏和获取课程分章节信息

课程视屏接口:

package com.xuecheng.media.api;

import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.base.model.RestResponse;
import com.xuecheng.media.model.po.MediaFiles;
import com.xuecheng.media.service.MediaFileService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

  @Autowired
  MediaFileService mediaFileService;

    @ApiOperation("预览文件")
    @GetMapping("/preview/{mediaId}")
    public RestResponse<String> getPlayUrlByMediaId(@PathVariable String mediaId){

        MediaFiles mediaFiles = mediaFileService.getFileById(mediaId);
        if(mediaFiles == null || StringUtils.isEmpty(mediaFiles.getUrl())){
            XueChengPlusException.cast("视频还没有转码处理");
        }
        return RestResponse.success(mediaFiles.getUrl());

    }


}
 /**
  * 根据文件id查询文件信息
  * @param mediaId
  * @return
  */
    MediaFiles getFileById(String mediaId);
    /**
     * 根据文件id得到文件信息
     * @param mediaId
     * @return
     */
    @Override
    public MediaFiles getFileById(String mediaId) {
        MediaFiles mediaFiles = mediaFilesMapper.selectById(mediaId);
        return mediaFiles;
    }

获取课程计划信息:

package com.xuecheng.content.api;

import com.xuecheng.content.model.dto.CoursePreviewDto;
import com.xuecheng.content.service.CourseBaseInfoService;
import com.xuecheng.content.service.CoursePublishService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

 @Autowired
 private CourseBaseInfoService courseBaseInfoService;

 @Autowired
 private CoursePublishService coursePublishService;


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

}
    /**
     * @description 获取课程预览信息
     * @param courseId 课程id
     * @return com.xuecheng.content.model.dto.CoursePreviewDto
     * @author Mr.M
     * @date 2022/9/16 15:36
     */
    public CoursePreviewDto getCoursePreviewInfo(Long courseId);
package com.xuecheng.content.service.impl;

import com.xuecheng.content.model.dto.CourseBaseInfoDto;
import com.xuecheng.content.model.dto.CoursePreviewDto;
import com.xuecheng.content.model.dto.TeachplanDto;
import com.xuecheng.content.service.CourseBaseInfoService;
import com.xuecheng.content.service.CoursePublishService;
import com.xuecheng.content.service.TeachplanService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class CoursePublishServiceImpl implements CoursePublishService {

    @Autowired
    private CourseBaseInfoService courseBaseInfoService;
    @Autowired
    private TeachplanService teachplanService;

    @Override
    public CoursePreviewDto getCoursePreviewInfo(Long courseId) {
        //查询数据库
        CoursePreviewDto coursePreviewInfo = new CoursePreviewDto();
        //查询课程详细信息
        CourseBaseInfoDto courseBaseInfo = courseBaseInfoService.getCourseBaseInfo(courseId);
        coursePreviewInfo.setCourseBase(courseBaseInfo);
        //查询课程计划
        List<TeachplanDto> teachplanTree = teachplanService.findTeachplanTree(courseId);
        coursePreviewInfo.setTeachplans(teachplanTree);
        return coursePreviewInfo;
    }
}

由于添加了这两个接口需要修改nginx的配置文件

配置这两个接口的跳转信息。

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

上面的全部配置文件已经包括这个依赖。

提交课程审核

CoursePublishController:
      /**
       * 课程审核
       * @param courseId
       * @return
       */
      @ResponseBody
      @PostMapping("/courseaudit/commit/{courseId}")
      public void commitAudit(@PathVariable("courseId") Long courseId){
          //TODO 获取机构id
          Long companyId = 1232141425L;
          coursePublishService.commitAudit(courseId,companyId);
      }

    //课程预发布表
    @Autowired
    private CoursePublishPreMapper coursePublishPreMapper;
    //课程基本信息复杂查询
    @Autowired
    private CourseBaseInfoService courseBaseInfoService;
    //课程计划
    @Autowired
    private TeachplanService teachplanService;
    //课程营销信息
    @Autowired
    private CourseMarketMapper courseMarketMapper;
    //课程基本信息
    @Autowired
    private CourseBaseMapper courseBaseMapper;   




 /**
     * 提交审核
     * @param courseId 课程id
     * @param companyId 机构id
     */
    @Override
    @Transactional
    public void commitAudit(Long courseId, Long companyId) {
        //根据课程id查询课程信息
        CourseBaseInfoDto courseBaseInfo = courseBaseInfoService.getCourseBaseInfo(courseId);
        //根据课程信息进行校验
        if(courseBaseInfo == null){
            XueChengPlusException.cast("课程不存在");
        }
        if(!courseBaseInfo.getCompanyId().equals(companyId)){
            XueChengPlusException.cast("不允许提交其它机构的课程");
        }
        if(courseBaseInfo.getAuditStatus().equals("202003")){
            XueChengPlusException.cast("课程已提交审核,请等待审核结果");
        }
        //课程图片是否填写
        if(StringUtils.isEmpty(courseBaseInfo.getPic())){
            XueChengPlusException.cast("提交失败,请上传课程图片");
        }
        //查询课程的营销信息
        CourseMarket courseMarket = courseMarketMapper.selectById(courseId);
        if(courseMarket == null){
            XueChengPlusException.cast("营销信息不存在");
        }
        //将课程营销信息转为JSON
        String courseMarketJson = JSON.toJSONString(courseMarket);
        //查询课程计划信息
        List<TeachplanDto> teachplanTree = teachplanService.findTeachplanTree(courseId);
        if(teachplanTree == null || teachplanTree.size() == 0){
            XueChengPlusException.cast("课程计划为空");
        }
        //将课程计划信息转为JSON
        String teachplanTreeJson = JSON.toJSONString(teachplanTree);

        //封装数据
        CoursePublishPre coursePublishPre = new CoursePublishPre();
        BeanUtils.copyProperties(courseBaseInfo,coursePublishPre);
        //设置预发布记录状态,已提交
        coursePublishPre.setStatus("202003");
        //将课程营销信息json数据放入课程预发布表
        coursePublishPre.setMarket(courseMarketJson);
        //将课程计划信息json数据放入课程预发布表
        coursePublishPre.setTeachplan(teachplanTreeJson);
        //教学机构id
        coursePublishPre.setCompanyId(companyId);
        //提交时间
        coursePublishPre.setCreateDate(LocalDateTime.now());

        //判断是否添加过
        CoursePublishPre coursePublishPreUpdate = coursePublishPreMapper.selectById(courseId);
        if(coursePublishPreUpdate == null){
            //添加课程预发布记录
            coursePublishPreMapper.insert(coursePublishPre);
        }else{
            coursePublishPreMapper.updateById(coursePublishPre);
        }


        //修改课程基本信息表中课程状态为202003-提交审核
        CourseBase courseBase = courseBaseMapper.selectById(courseId);
        courseBase.setAuditStatus("202003");
        int update = courseBaseMapper.updateById(courseBase);
        if(update <= 0){
            XueChengPlusException.cast("修改课程状态失败");
        }
    }

课程发布

教学机构人员在课程审核通过后即可发布课程,课程发布后会公开展示在网站上供学生查看、选课和学习。

在网站上展示课程信息需要解决课程信息显示的性能问题,如果速度慢(排除网速)会影响用户的体验性。

如何去快速搜索课程?

打开课程详情页面仍然去查询数据库可行吗?

为了提高网站的速度需要将课程信息进行缓存,并且要将课程信息加入索引库方便搜索,下图显示了课程发布后课程信息的流转情况

1、向内容管理数据库的课程发布表存储课程发布信息,更新课程基本信息表中发布状态为已发布。

2、向Redis存储课程缓存信息。

3、向Elasticsearch存储课程索引信息。

4、请求分布文件系统存储课程静态化页面(即html页面),实现快速浏览课程详情页面。

课程发布表的数据来源于课程预发布表,它们的结构基本一样,只是课程发布表中的状态是课程发布状态,如下图:

redis中的课程缓存信息是将课程发布表中的数据转为json进行存储。

elasticsearch中的课程索引信息是根据搜索需要将课程名称、课程介绍等信息进行索引存储。

MinIO中存储了课程的静态化页面文件(html网页),查看课程详情是通过文件系统去浏览课程详情页面。

课程发布接口

    /**
     * 课程发布
     * @param courseId
     */
    @ApiOperation("课程发布")
    @ResponseBody
    @PostMapping ("/coursepublish/{courseId}")
    public void coursepublish(@PathVariable("courseId") Long courseId){
        Long companyId = 1232141425L;
        coursePublishService.publish(companyId,courseId);
    }
    /**
     * 课程发布
     * @param companyId
     * @param courseId
     */
    @Override
    public void publish(Long companyId, Long courseId) {
        //约束校验
        //查询课程预发布表
        CoursePublishPre coursePublishPre = coursePublishPreMapper.selectById(courseId);
        if(coursePublishPre == null){
            XueChengPlusException.cast("请先提交课程审核,审核通过才可以发布");
        }
        //本机构只允许提交本机构的课程
        if(!coursePublishPre.getCompanyId().equals(companyId)){
            XueChengPlusException.cast("不允许提交其它机构的课程。");
        }


        //课程审核状态
        String auditStatus = coursePublishPre.getStatus();
        //审核通过方可发布
        if(!"202004".equals(auditStatus)){
            XueChengPlusException.cast("操作失败,课程审核通过方可发布。");
        }

        //保存课程发布信息
        saveCoursePublish(courseId);

        //保存消息表
        saveCoursePublishMessage(courseId);

        //删除课程预发布表对应记录
        coursePublishPreMapper.deleteById(courseId);
    }

    /**
     * @description 保存课程发布信息
     * @param courseId  课程id
     * @return void
     * @author Mr.M
     * @date 2022/9/20 16:32
     */
    private void saveCoursePublish(Long courseId){
        //整合课程发布信息
        //查询课程预发布表
        CoursePublishPre coursePublishPre = coursePublishPreMapper.selectById(courseId);
        if(coursePublishPre == null){
            XueChengPlusException.cast("课程预发布数据为空");
        }

        CoursePublish coursePublish = new CoursePublish();

        //拷贝到课程发布对象
        BeanUtils.copyProperties(coursePublishPre,coursePublish);
        coursePublish.setStatus("203002");
        CoursePublish coursePublishUpdate = coursePublishMapper.selectById(courseId);
        if(coursePublishUpdate == null){
            coursePublishMapper.insert(coursePublish);
        }else{
            coursePublishMapper.updateById(coursePublish);
        }
        //更新课程基本表的发布状态
        CourseBase courseBase = courseBaseMapper.selectById(courseId);
        courseBase.setStatus("203002");
        courseBaseMapper.updateById(courseBase);

    }

    /**
     * @description 保存消息表记录,稍后实现
     * @param courseId  课程id
     * @return void
     * @author Mr.M
     * @date 2022/9/20 16:32
     */
    private void saveCoursePublishMessage(Long courseId){


    }

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mysql之找回忘记的root密码

mysql之找回忘记的root密码 1.方法1&#xff0c;init-file重置密码2.方法2&#xff0c;–skip-grant-tables重置密码 1.方法1&#xff0c;init-file重置密码 使用init-file参数来对密码进行重新设置 1.停止mysql服务进程 首先将mysql的服务停用掉&#xff1b; 输入命令&#x…

ROS VSCode调试方法

VSCode 调试 Ros文档 1.编译参数设置 cd catkin_ws catkin_make -DCMAKE_BUILD_TYPEDebug2.vscode 调试插件安装 可在扩展中安装(Ctrl Shift X): 1.ROS 2.C/C 3.C Intelliense 4.Msg Language Support 5.Txt Syntax 3.导入已有或者新建ROS工作空间 3.1 导入工作…

力扣--LCR 152.验证二叉搜索树后序遍历

请实现一个函数来判断整数数组 postorder 是否为二叉搜索树的后序遍历结果。 提示&#xff1a; 数组长度 < 1000 postorder 中无重复数字代码 class Solution { public boolean verifyPostorder(int[] postorder) { if(postorder null){ return true; } return f(postor…

LeetCode 力扣 热题 100道(十一)字母异位词分组(C++)

给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 排序字符&#xff1a;对于每个字符串&#xff0c;我们将其字符排序&#xff0c;得到一个唯一的 "排序后的字母&qu…

【Anaconda】 创建环境报错:CondaHTTPError: HTTP 000 CONNECTION FAILED for url

问题描述 使用 Anaconda 创建环境时报错&#xff1a; CondaHTTPError: HTTP 000 CONNECTION FAILED for url <https://repo.anaconda.com/pkgs/free/noarch/repodata.json.bz2> Elapsed: -An HTTP error occurred when trying to retrieve this URL. HTTP errors are o…

CC-Link IEFB转Modbus TCP三菱FX5U与施耐德M580通讯案例

一. 案例背景 在现代工业自动化领域&#xff0c;企业为了构建高效、灵活的生产系统&#xff0c;往往会选用不同品牌的设备。在自动化控制场景中&#xff0c;施耐德M580系列PLC则以其强大的处理能力和先进的功能&#xff0c;在复杂的过程控制和大型系统集成方面表现出色&#xf…

【VUE3】新版Vue3+ElementPlus全家桶开发视频项目实战

VUE 介绍 Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。 Vue.js是一个MVVM(Model - View - ViewModel)的SPA框架。 Model:数…

常用函数的使用错题汇总

#include <iostream> #include <fstream> #include <string>int main() {std::ifstream fin("example.txt"); // 创建 ifstream 对象并打开文件// 检查文件是否成功打开if (!fin) {std::cerr << "Error opening file!" << s…

Android电视项目焦点跨层级流转

1. 背景 在智家电视项目中&#xff0c;主要操作方式不是触摸&#xff0c;而是遥控器&#xff0c;通过Focus进行移动&#xff0c;确定点击进行的交互&#xff0c;所以在电视项目中焦点、选中、确定、返回这几个交互比较重要。由于电视屏比较大&#xff0c;在一些复杂页面中会存…

Linux -初识 与基础指令1

博客主页&#xff1a;【夜泉_ly】 本文专栏&#xff1a;【Linux】 欢迎点赞&#x1f44d;收藏⭐关注❤️ 文章目录 &#x1f4da; 前言&#x1f5a5;️ 初识&#x1f510; 登录 root用户&#x1f465; 两种用户➕ 添加用户&#x1f9d1;‍&#x1f4bb; 登录 普通用户⚙️ 常见…

Oracle12.2 RAC集群管理修改IP地址(DNS解析)

Oracle12.2 RAC集群管理之修改IP地址 该章节实验是基于此章节基础上操作&#xff1a; Oracle LinuxR7安装Oracle 12.2 RAC集群实施&#xff08;DNS解析&#xff09;-CSDN博客 环境 改前IP&#xff1a; 172.30.21.101 hefei1 hefei1.hefeidb.com 172.30.21.102 hefei2 …

Git——本地仓库链接并推送到多个远程仓库

步骤 1. 新建仓库init 或 删除已有仓库远程链接 // 1.新建init git init// 2.已有仓库&#xff0c;查看链接的远程仓库 git remote -v// 3.已有远程连接仓库&#xff0c;需要删除连接 git remote rm origin(或对应远程仓库名) 2.新建远程仓库 在gitee、github等托管平台创建…

IDEA某个Impl下的引入的文件红色

IDEA某个Impl下的引入的文件红色&#xff0c;可以正常启动&#xff0c;而且文件是存在的 1.什么情况下会出现这个问题 我的是在不关闭项目的情况下就把电脑关机了&#xff0c;因为这样第二天开机&#xff0c;启动IDEA就会把昨天关机前所有开启的项目全部开启 &#xff0c;这样有…

docker使用(镜像、容器)

docker基础使用 文章目录 前言1.镜像操作1.1命令介绍1.2.案例实操1.2.1查找镜像1.2.2下载镜像1.2.3查看当前镜像 2.容器操作2.1命令2.1.1容器创建与启动2.1.2. 容器查看2.1.3. 容器操作2.1.4. 容器删除2.1.5. 容器日志2.1.6. 容器内文件操作2.1.7. 容器内命令执行2.1.8. 其他常…

6.STM32之通信接口《精讲》之IIC通信---硬件IIC(STM32自带的硬件收发器)

上一节&#xff0c;完成了对IIC软件的实验程序&#xff0c;也就是说只要我们编程能够模拟IIC协议规定的时序&#xff0c;所有IIC的外设就能解析IIC的读出我们数据&#xff0c;就能和相关IIC外设进行交互&#xff0c;然后&#xff0c;STM32自带硬件收发电路&#xff0c;接下来我…

springboot337校园失物招领系统pf(论文+源码)_kaic

校园失物招领网站的设计与实现 摘要 近年来&#xff0c;信息化管理行业的不断兴起&#xff0c;使得人们的日常生活越来越离不开计算机和互联网技术。首先&#xff0c;根据收集到的用户需求分析&#xff0c;对设计系统有一个初步的认识与了解&#xff0c;确定校园失物招领网站…

智能探针技术:实现可视、可知、可诊的主动网络运维策略

网络维护的重要性 网络运维是确保网络系统稳定、高效、安全运行的关键活动。在当今这个高度依赖信息技术的时代&#xff0c;网络运维的重要性不仅体现在技术层面&#xff0c;更关乎到企业运营的方方面面。网络运维具有保障网络的稳定性、提升网络运维性能、降低企业运营成本等…

mybatis笔记01——初始配置

JavaEE三层架构&#xff1a;表现层&#xff08;负责与用户的交互&#xff0c;通常实现了用户界面&#xff09;、业务逻辑层&#xff08;处理核心业务规则和逻辑&#xff0c;是应用程序的“心脏”。&#xff09;、数据访问层&#xff08;负责与数据源&#xff08;如数据库&#…

第7篇 寻找最大数___ARM C语言程序<三>

Q&#xff1a;可以将寻找到的最大数结果显示在DE1-SoC开发板的硬件外设如红色LED上吗&#xff1f; A&#xff1a;基本原理&#xff1a;对红色LED的Data寄存器进行写操作即可。DE1-SoC_Computer系统上连接到红色LED的并行端口的内存映射地址为0xFF200000&#xff0c;是一个18位…

力扣刷题TOP101:6.BM7 链表中环的入口结点

目录&#xff1a; 目的 思路 复杂度 记忆秘诀 python代码 目的 {1,2},{3,4,5}, 3 是环入口。 思路 这个任务是找到带环链表的环入口。可以看作是上一题龟兔赛跑&#xff08;Floyd 判圈算法&#xff09;的延续版&#xff1a;乌龟愤愤不平地举报兔子跑得太快&#xff0c;偷偷…