网站的商桥怎么做国内产品设计公司前十名
news/
2025/9/29 10:21:48/
文章来源:
网站的商桥怎么做,国内产品设计公司前十名,搜索大全浏览器,全网营销解决方案内容管理模块 - 课程预览、提交审核 文章目录 内容管理模块 - 课程预览、提交审核一、课程预览1.1 需求分析1.2 freemarker 模板引擎1.2.1 Maven 坐标1.2.2 freemaker 相关配置信息1.2.3 添加模板 1.3 测试静态页面1.3.1 部署Nginx1.3.2 解决端口问题被占用问题1.3.3 配置host文…内容管理模块 - 课程预览、提交审核 文章目录 内容管理模块 - 课程预览、提交审核一、课程预览1.1 需求分析1.2 freemarker 模板引擎1.2.1 Maven 坐标1.2.2 freemaker 相关配置信息1.2.3 添加模板 1.3 测试静态页面1.3.1 部署Nginx1.3.2 解决端口问题被占用问题1.3.3 配置host文件1.3.4 文件服务器1.3.5 视频播放页面 1.4 课程预览 主页1.4.1 CoursePublishController1.4.2 Nginx 配置反向代理1.4.3 CoursePublishServiceImpl1.4.4 编写模板1.4.5 测试 1.5 课程预览 视频1.5.1 配置Nginx1.5.2 CourseOpenController1.5.3 MediaOpenController1.5.4 测试 二、提交课程审核2.1 需求分析2.2 数据模型2.2.1 课程预发布表 course_publish_pre 2.3 CoursePublishController2.4 CoursePublishServiceImpl2.5 测试 一、课程预览
课程预览就是把课程的相关信息进行整合在课程预览界面进行展示课程预览界面与课程发布的课程详情界面一致 1.1 需求分析
客户可以通过课程预览页面查看信息是否存在问题
如下课程预览的数据来源 下图显示了整个课程预览的流程图 也就是说现在怎么给前端返回一个页面呢 最最最原始的JSP可以一些模板引擎技术也可以 前端请求内容管理服务后后台服务系统要返回一个页面 最终要返回的页面如下图所示预览页面如果客户成功确认发布后发布后的页面和预览时的页面相同 说明如下
1、点击课程预览通过Nginx、后台服务网关请求内容管理服务进行课程预览。
2、内容管理服务查询课程相关信息进行整合并通过模板引擎技术在服务端渲染生成页面返回给浏览器。
3、通过课程预览页面点击”马上学习“打开视频播放页面。
4、视频播放页面通过Nginx请求后台服务网关查询课程信息展示课程计划目录请求媒资服务查询课程计划绑定的视频文件地址在线浏览播放视频。 在这里我们用到了两个技术一个Nginx一个freemarker freemarker可以在服务端生成网页然后返回给浏览器 Nginx是一个代理服务器所有的请求都请求到Nginx上由Nginx进行代理然后再由Nginx发送到后台服务上 1.2 freemarker 模板引擎 freemarker提供很多指令用于解析各种类型的数据模型 参考地址http://freemarker.foofun.cn/ref_directives.html 什么是模板引擎
早期采用的jsp技术就是一种模板引擎技术 1、浏览器请求web服务器
2、服务器渲染页面渲染的过程就是向jsp页面(模板)内填充数据(模型)。
3、服务器将渲染生成的页面返回给浏览器。
所以模板引擎就是模板数据输出Jsp页面就是模板页面中嵌入的jsp标签就是数据两者相结合输出html网页
模板引擎服务端生成页面的一项技术
常用的java模板引擎还有哪些
Jsp、Freemarker、Thymeleaf 、Velocity 等。
Freemarker官方地址http://freemarker.foofun.cn/ FreeMarker 是一款 模板引擎 即一种基于模板和要改变的数据 并用来生成输出文本(HTML网页电子邮件配置文件源代码等)的通用工具。 它不是面向最终用户的而是一个Java类库是一款程序员可以嵌入他们所开发产品的组件。FreeMarker 是免费的 基于Apache许可证2.0版本发布。 1.2.1 Maven 坐标
在content-api工程中添加如下所示的坐标
!-- Spring Boot 对结果视图 Freemarker 集成 --
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-freemarker/artifactId
/dependency1.2.2 freemaker 相关配置信息
freemaker 相关配置信息我们配置在了nacos的freemarker-config-dev.yaml配置文件中
spring:freemarker:enabled: truecache: false #关闭模板缓存方便测试settings:template_update_delay: 0suffix: .ftl #页面模板后缀名charset: UTF-8template-loader-path: classpath:/templates/ #页面模板位置(默认为 classpath:/templates/)resources:add-mappings: false #关闭项目中的静态资源映射(static、resources文件夹下的资源)在content-api工程的bootstrap配置文件引入freemarker-config-dev.yaml配置文件
#微服务配置
spring:application:name: content-api # 项目名cloud:nacos:server-addr: 192.168.101.65:8848 #Nacos地址discovery: #服务发现服务注册namespace: dev #命名空间group: xuecheng-plus-project #组别config: # 配置中心...............中间省略了好多配置shared-configs: #公用配置- data-id: freemarker-config-dev.yamlgroup: xuecheng-plus-commonrefresh: true
1.2.3 添加模板
模板其实就是一个HTML页面数据模型 ${name} 就是数据模型也就是后台的模型数据 !DOCTYPE html
html
headmeta charsetutf-8titleHello World!/title
/head
body
Hello ${name}!
/body
/html后台准备模型数据
// 不要使用RestController因为返回的是JSON数据这里我们一定不要返回JSON数据
Controller
public class FreemarkerController {/***ModelAndView 模型和数据*/GetMapping(/testfreemarker)public ModelAndView test(){ModelAndView modelAndView new ModelAndView();//指定模型数据modelAndView.addObject(name,小明);// 指定模型视图// 返回的是哪个视图且不用加后缀.ftl文件名test.ftl// 因为我们已经在配置文件中告诉框架我们文件的后缀名称是什么了spring.freemarker.suffix.ftlmodelAndView.setViewName(test);return modelAndView;}
}测试效果
还是能展示出来的 1.3 测试静态页面
准备Nginx和门户
1.3.1 部署Nginx
在本机部署Nginx
server {listen 80;server_name www.51xuecheng.cn localhost;#rewrite ^(.*) https://$server_name$1 permanent;#charset koi8-r;ssi on;ssi_silent_errors on;#access_log logs/host.access.log main;location / {alias D:/zhangjingqi/Note/xuecheng/Code/xc-ui-pc-static-portal/xc-ui-pc-static-portal/;index index.html index.htm;}#静态资源location /static/img/ { alias D:/zhangjingqi/Note/xuecheng/Code/xc-ui-pc-static-portal/xc-ui-pc-static-portal/img/;} location /static/css/ { alias D:/zhangjingqi/Note/xuecheng/Code/xc-ui-pc-static-portal/xc-ui-pc-static-portal/css/;} location /static/js/ { alias D:/itcast2022/xc_edu3.0/code_1/xc-ui-pc-static-portal/js/;} location /static/plugins/ { alias D:/zhangjingqi/Note/xuecheng/Code/xc-ui-pc-static-portal/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:/zhangjingqi/Note/xuecheng/Code/xc-ui-pc-static-portal/xc-ui-pc-static-portal/plugins/;} #error_page 404 /404.html;# redirect server error pages to the static page /50x.html#error_page 500 502 503 504 /50x.html;location /50x.html {root html;}# proxy the PHP scripts to Apache listening on 127.0.0.1:80##location ~ \.php$ {# proxy_pass http://127.0.0.1;#}# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000##location ~ \.php$ {# root html;# fastcgi_pass 127.0.0.1:9000;# fastcgi_index index.php;# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;# include fastcgi_params;#}# deny access to .htaccess files, if Apaches document root}修改过后将Nginx服务进行重启
1.3.2 解决端口问题被占用问题
刚开始的时候80端口一直被占用从任务浏览器中根本结束不掉对应的进程
然后根据下面两篇文章解决掉了
文章1
https://blog.csdn.net/qq_34272964/article/details/105207651
如果文章1不能解决的话看一下文章2我是文章2解决的
https://blog.csdn.net/weixin_43833851/article/details/130188302
启动Nginx访问80端口如果出现下图所示的界面说明端口问题已经被解决了 假如说按照1.3.1设置了Nginx配置的话打开网页会是如下页面 主要访问一下预览界面http://www.51xuecheng.cn/course/course_template.html 1.3.3 配置host文件
C:\Windows\System32\drivers\etc目录下有一个host文件 将下面的内容粘贴到里面即可
127.0.0.1 www.51xuecheng.cn 51xuecheng.cn ucenter.51xuecheng.cn teacher.51xuecheng.cn file.51xuecheng.cnCentos7操作系统的hosts文件在/etc目录下 当我们输入一个域名的时候最红需要找到这个域名对应的服务器也就是ip地址首先会从host文件中中找
比如我们输入 www.51xuecheng.cn域名首先会从host文件找然后找到了对应的ip是127.0.0.1
假如说在host文件中没有找到域名www.51xuecheng.cn对应的ip那就会再从dns服务器找请求到dns服务器进行解析在dns服务器中就记录了ip和域名的对应关系
1.3.4 文件服务器
在进行课程预览时需要展示课程的图片在线插放课程视频课程图片、视频这些都在MinIO文件系统存储下边统一由Nginx代理通过文件服务域名统一访问。如下图 我们使用的分布式文件系统MinIO来存储的文件并且MinIO有许多的结点
我们打算前端的请求都请求到Nginx然后由Nginx代理请求到MinIO中 比如获取一个图片我们可以先请求到Nginx然后再由Nginx请求到MinIO中获取图片 host文件配置如下所示信息
127.0.0.1 www.51xuecheng.cn file.51xuecheng.cnnginx.conf中配置文件服务器的代理地址
相当于nginx.conf中再来一套配置 其实请求/video的时候就会代理到 server 192.168.101.65:9000服务器去请求资源 #文件服务upstream fileserver{server 192.168.101.65:9000 weight10;} server {listen 80;server_name file.51xuecheng.cn;#charset koi8-r;ssi on;ssi_silent_errors on;#access_log logs/host.access.log main;location /video {proxy_pass http://fileserver;}location /mediafiles {proxy_pass http://fileserver;}} 配置完毕重新加载nginx配置文件 通过cmd进入nginx.exe所在目录,运行如下命令 nginx.exe -s reload访问http://file.51xuecheng.cn/mediafiles/2022/09/13/a16da7a132559daf9e1193166b3e7f52.jpg
如下所示效果 1.3.5 视频播放页面
首先在nginx.conf中配置视频播放页面的地址 location /course/preview/learning.html {alias D:/zhangjingqi/Note/xuecheng/Code/xc-ui-pc-static-portal/xc-ui-pc-static-portal/course/learning.html;} location /course/search.html { root D:/zhangjingqi/Note/xuecheng/Code/xc-ui-pc-static-portal/xc-ui-pc-static-portal;} location /course/learning.html { root D:/zhangjingqi/Note/xuecheng/Code/xc-ui-pc-static-portal/xc-ui-pc-static-portal;}重新加载配置文件
之后
下边需要配置learning.html页面的视频播放路径来测试视频播放页面找到learning.html页面中videoObject对象的定义处配置视频的播放地址 换成minio系统中一个可以播放的地址 1.4 课程预览 主页
课程预览接口要将课程信息进行整合在服务端渲染页面后返回浏览器。
下边对课程预览接口进行分析
1、请求参数
传入课程id表示要预览哪一门课程。
2、响应结果
输出课程详情页面到浏览器
响应页面到浏览器使用freemarker模板引擎技术实现首先从课程资料目录下获取课程预览页面course_template.html拷贝至内容管理的接口工程的resources/templates下并将其在本目录复制一份命名为course_template.ftl
也就是说下图中的整个页面都是模板内容 其实就是下图所示的四部分信息 1.4.1 CoursePublishController
Controller
public class CoursePublishController {AutowiredCoursePublishServiceImpl coursePublishService;GetMapping(/coursepreview/{courseId})public ModelAndView preview(PathVariable(courseId) Long courseId) {ModelAndView modelAndView new ModelAndView();// 从数据库查询模型的数据课程营销信息表、课程师资表、课程基本信息表、课程计划CoursePreviewDto coursePreviewInfo coursePublishService.getCoursePreviewInfo(courseId);// 指定模型数据modelAndView.addObject(model, coursePreviewInfo);// 指定模板modelAndView.setViewName(course_template);return modelAndView;}}
其中需要的课程预览模型类
/*** description 课程预览数据模型*/DataToString
public class CoursePreviewDto {//课程基本信息,课程营销信息CourseBaseInfoDto courseBase;//课程计划信息ListTeachplanDto teachplans;//师资信息暂时不加...}1.4.2 Nginx 配置反向代理
课程预览接口虽然可以正常访问但是页面没有样式查看浏览器请求记录发现图片、样式无法正常访问
这些静态资源全在门户下我们需要由Nginx反向代理访问课程预览接口通过门户的URL去访问课程预览
Nginx中如下所示配置 upstream gatewayserver{server 127.0.0.1:63010 weight10;} server {listen 80;server_name www.51xuecheng.cn localhost;....#apilocation /api/ {proxy_pass http://gatewayserver/;}
之后重新启动Nginx 访问地址 http://www.51xuecheng.cn/api/content/coursepreview/74
出现的场景如下图所示 现在的请求其实是下面所示的流程 1.4.3 CoursePublishServiceImpl
/*** 课程发布相关业务*/
Service
public class CoursePublishServiceImpl implements CoursePublishService {//课程基础信息课程营销信息表/课程基本信息表AutowiredCourseBaseInfoService courseBaseInfoService;//课程计划AutowiredTeachplanService teachplanService;/*** param courseId 课程id* description 获取课程预览信息*/Overridepublic CoursePreviewDto getCoursePreviewInfo(Long courseId) {// 从数据库查询模型的数据课程营销信息表、课程师资表、课程基本信息表、课程计划// 课程基本信息营销信息CourseBaseInfoDto courseBaseInfoDto courseBaseInfoService.getCourseBaseInfo(courseId);//课程计划信息ListTeachplanDto teachplanTree teachplanService.findTeachplanTree(courseId);// 组装返回信息CoursePreviewDto coursePreviewDto new CoursePreviewDto();coursePreviewDto.setCourseBase(courseBaseInfoDto);coursePreviewDto.setTeachplans(teachplanTree);return coursePreviewDto;}
}1.4.4 编写模板
模型数据准备好后下一步将模型数据填充到course_template.ftl上填充时注意不要一次填充太多一边填充一边刷新调试。 freemarker提供很多指令用于解析各种类型的数据模型 参考地址http://freemarker.foofun.cn/ref_directives.html !DOCTYPE html
html langzh-CNheadmeta charsetutf-8meta http-equivX-UA-Compatible contentIEedge!-- 上述3个meta标签*必须*放在最前面任何其他内容都*必须*跟随其后 --meta namedescription contentmeta nameauthor contentlink relicon href/static/img/asset-favicon.icotitle学成在线-${model.courseBase.name}/titlelink relstylesheet href/static/plugins/normalize-css/normalize.css/link relstylesheet href/static/plugins/bootstrap/dist/css/bootstrap.css/link relstylesheet href/static/css/page-learing-article.css/
/headbody data-spyscroll data-target#articleNavbar data-offset150
!-- 页面头部 --
!--#include virtual/include/header.html--
!--页面头部结束sss--
div idlearningAreadiv classarticle-bannerdiv classbanner-bg/divdiv classbanner-infodiv classbanner-leftp${model.courseBase.mtName!}span\ ${model.courseBase.stName!}/span/pp classtit${model.courseBase.name}/pp classpic#if model.courseBase.charge201000span classnew-pic免费/span#elsespan classnew-pic特惠价格${model.courseBase.price!}/spanspan classold-pic原价${model.courseBase.originalPrice!}/span/#if/pp classinfoa href# click.preventstartLearning()马上学习/aspanem难度等级/em#if model.courseBase.grade204001初级#elseif model.courseBase.grade204002中级#elseif model.courseBase.grade204003高级/#if/spanspanem课程时长/em2小时27分/spanspanem评分/em4.7分/spanspanem授课模式/em#if model.courseBase.teachmode200002录播#elseif model.courseBase.teachmode200003直播/#if/span/p/divdiv classbanner-ritpa hrefhttp://www.51xuecheng.cn/course/preview/learning.html?id${model.courseBase.id}target_blank#if model.courseBase.pic??img srchttp://file.51xuecheng.cn${model.courseBase.pic} alt width270 height156#elseimg src/static/img/widget-video.png alt width270 height156/#if/a/pp classvid-actspan i classi-heart/i收藏 23 /span span分享 i classi-weixin/iiclassi-qq/i/span/p/div/div/divdiv classarticle-contdiv classtit-lista hrefjavascript:; idarticleClass classactive课程介绍/aa hrefjavascript:; idarticleItem目录/aa hrefjavascript:; idartcleAsk问答/aa hrefjavascript:; idartcleNot笔记/aa hrefjavascript:; idartcleCod评价/a!--div classdown-fillspan资料下载/spanullijava视频资料/lilijava视频资料/lilijava视频资料/li/ul/div--/divdiv classarticle-boxdiv classarticleClass styledisplay: block!--div classrit-title评价/div--div classarticle-contdiv classarticle-left-boxdiv classcontentdiv classcontent-com suitdiv classtitlespan适用人群/span/divdiv classcont cktopdivp${model.courseBase.users!}/p/div!--span classon-off更多 i classi-chevron-bot/i/span--/div/divdiv classcontent-com coursediv classtitlespan课程制作/span/divdiv classcontdiv classimg-boximg src/static/img/widget-myImg.jpg alt/divdiv classinfo-boxp classname教学方emXX老师/em/p!-- p classlab高级前端开发工程师 10年开发经验/p--p classinfoJavaEE开发与教学多年精通JavaEE技术体系对流行框架JQuery、DWR、Struts1/2HibernateSpringMyBatis、JBPM、Lucene等有深入研究。授课逻辑严谨条理清晰注重学生独立解决问题的能力。/p!-- pspan难度等级/span中级/ppspan课程时长/span8-16小时/周共4周/ppspan如何通过/span通过所有的作业及考核作业共4份考核为一次终极考核/ppspan用户评分/span平均用户评分 em4.9/em a href#查看全部评价/a/ppspan课程价格/span特惠价格em999/em i 原价1999 /i/p--/div/div/divdiv classcontent-com aboutdiv classtitlespan课程介绍/span/divdiv classcont cktopdivp${model.courseBase.description!}/p/div!--span classon-off更多 i classi-chevron-bot/i/span--/div/divdiv classcontent-com probdiv classtitlespan常见问题/span/divdiv classcontulli classitemspan classon-offi classi-chevron-bot/i 我什么时候能够访问课程视频与作业/spandiv classdrop-downp课程安排灵活课程费用支付提供180天全程准入和资格证书。自定进度课程建议的最后期限但你不会受到惩罚错过期限只要你赚你的证书在180天内。以会话为基础的课程可能要求你在截止日期前保持正轨但如果你落后了你可以切换到以后的会议你完成的任何工作将与你转移。/p/div/lili classitemspan classon-offi classi-chevron-bot/i 如何需要额外的时间来完成课程会怎么样/spandiv classdrop-downp课程安排灵活课程费用支付提供180天全程准入和资格证书。自定进度课程建议的最后期限但你不会受到惩罚错过期限只要你赚你的证书在180天内。以会话为基础的课程可能要求你在截止日期前保持正轨但如果你落后了你可以切换到以后的会议你完成的任何工作将与你转移。/p/div/lili classitemspan classon-offi classi-chevron-bot/i 我支付次课程之后会得到什么/spandiv classdrop-downp课程安排灵活课程费用支付提供180天全程准入和资格证书。自定进度课程建议的最后期限但你不会受到惩罚错过期限只要你赚你的证书在180天内。以会话为基础的课程可能要求你在截止日期前保持正轨但如果你落后了你可以切换到以后的会议你完成的任何工作将与你转移。/p/div/lili classitemspan classon-offi classi-chevron-bot/i 退款条例是如何规定的/spandiv classdrop-downp课程安排灵活课程费用支付提供180天全程准入和资格证书。自定进度课程建议的最后期限但你不会受到惩罚错过期限只要你赚你的证书在180天内。以会话为基础的课程可能要求你在截止日期前保持正轨但如果你落后了你可以切换到以后的会议你完成的任何工作将与你转移。/p/div/lili classitemspan classon-offi classi-chevron-bot/i 有助学金/spandiv classdrop-downp课程安排灵活课程费用支付提供180天全程准入和资格证书。自定进度课程建议的最后期限但你不会受到惩罚错过期限只要你赚你的证书在180天内。以会话为基础的课程可能要求你在截止日期前保持正轨但如果你落后了你可以切换到以后的会议你完成的任何工作将与你转移。/p/div/li/ul/div/div/div/div!--侧边栏--!--#include virtual/include/course_detail_side.html--!--侧边栏--/div/divdiv classarticleItem styledisplay: nonediv classarticle-cont-catalogdiv classarticle-left-boxdiv classcontent#list model.teachplans as firstNodediv classitemdiv classtitle acti classi-chevron-top/i${firstNode.pname}spanclasstimex小时/span/divdiv classdrop-down styleheight: 260px;ul classlist-box#list firstNode.teachPlanTreeNodes as secondNodelia hrefhttp://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 classitemdiv classtitle acti classi-chevron-top/i第一阶段 HTTP协议基础详解span classtime8小时/span/divdiv classabout使用Java消息中间件处理异步消息成为了分布式系统中的必修课通过本门课程可以深入浅出的学习如何在Java中使用消息中间件并且一步一步打造更优雅的最佳实践方案。/divdiv classdrop-down styleheight: 260px;ul classlist-boxli classactive1.1 阅读分级政策细节 span97’33”/span/lili1.2 视频为什么分为 A 部分、B 部分、C 部分 span66’15”/span/lili1.3 视频软件安装介绍 span86’42”/span/lili1.4 阅读Emacs安装 span59’00”/span/lili1.5 作业1Emacs安装 span93’29”/span/lili阶段测试/li/ul/div/div--/div/div!--侧边栏--!--#include virtual/include/course_detail_side.html--!--侧边栏--/div/div#--div classarticleItem styledisplay: nonediv classarticle-cont-catalogdiv classarticle-left-boxdiv classcontentdiv classitemdiv classtitle acti classi-chevron-top/i第一阶段 HTTP协议基础详解span classtime8小时/span/divdiv classabout使用Java消息中间件处理异步消息成为了分布式系统中的必修课通过本门课程可以深入浅出的学习如何在Java中使用消息中间件并且一步一步打造更优雅的最佳实践方案。/divdiv classdrop-down styleheight: 260px;ul classlist-boxli classactive1.1 阅读分级政策细节 span97’33”/span/lili1.2 视频为什么分为 A 部分、B 部分、C 部分 span66’15”/span/lili1.3 视频软件安装介绍 span86’42”/span/lili1.4 阅读Emacs安装 span59’00”/span/lili1.5 作业1Emacs安装 span93’29”/span/lili阶段测试/li/ul/div/divdiv classitemdiv classtitlei classi-chevron-bot/i第二阶段 HTTP协议基础详解span classtime8小时/span/divdiv classabout使用Java消息中间件处理异步消息成为了分布式系统中的必修课通过本门课程可以深入浅出的学习如何在Java中使用消息中间件并且一步一步打造更优雅的最佳实践方案。/divdiv classdrop-downul classlist-boxli classactive1.1 阅读分级政策细节 span97’33”/span/lili1.2 视频为什么分为 A 部分、B 部分、C 部分 span66’15”/span/lili1.3 视频软件安装介绍 span86’42”/span/lili1.4 阅读Emacs安装 span59’00”/span/lili1.5 作业1Emacs安装 span93’29”/span/lili阶段测试/li/ul/div/divdiv classitemdiv classtitlei classi-chevron-bot/i第三阶段 HTTP协议基础详解span classtime3小时/span/divdiv classabout使用Java消息中间件处理异步消息成为了分布式系统中的必修课通过本门课程可以深入浅出的学习如何在Java中使用消息中间件并且一步一步打造更优雅的最佳实践方案。/divdiv classdrop-downul classlist-boxli classactive1.1 阅读分级政策细节 span97’33”/span/lili1.2 视频为什么分为 A 部分、B 部分、C 部分 span66’15”/span/lili1.3 视频软件安装介绍 span86’42”/span/lili1.4 阅读Emacs安装 span59’00”/span/lili1.5 作业1Emacs安装 span93’29”/span/lili阶段测试/li/ul/div/divdiv classitemdiv classtitlei classi-chevron-bot/i第四阶段 HTTP协议基础详解span classtime3小时/span/divdiv classabout使用Java消息中间件处理异步消息成为了分布式系统中的必修课通过本门课程可以深入浅出的学习如何在Java中使用消息中间件并且一步一步打造更优雅的最佳实践方案。/divdiv classdrop-downul classlist-boxli classactive1.1 阅读分级政策细节 span97’33”/span/lili1.2 视频为什么分为 A 部分、B 部分、C 部分 span66’15”/span/lili1.3 视频软件安装介绍 span86’42”/span/lili1.4 阅读Emacs安装 span59’00”/span/lili1.5 作业1Emacs安装 span93’29”/span/lili阶段测试/li/ul/div/divdiv classitemdiv classtitlei classi-chevron-bot/i第五阶段 HTTP协议基础详解span classtime3小时/span/divdiv classabout使用Java消息中间件处理异步消息成为了分布式系统中的必修课通过本门课程可以深入浅出的学习如何在Java中使用消息中间件并且一步一步打造更优雅的最佳实践方案。/divdiv classdrop-downul classlist-boxli classactive1.1 阅读分级政策细节 span97’33”/span/lili1.2 视频为什么分为 A 部分、B 部分、C 部分 span66’15”/span/lili1.3 视频软件安装介绍 span86’42”/span/lili1.4 阅读Emacs安装 span59’00”/span/lili1.5 作业1Emacs安装 span93’29”/span/lili阶段测试/li/ul/div/divdiv classitema href# classoverwrite毕业考核/a/div/div/div!--侧边栏ndash;gt;!--#include virtual/include/course_detail_side.htmlndash;gt;!--侧边栏ndash;gt;/div/div--div classartcleAsk styledisplay: nonediv classarticle-cont-askdiv classarticle-left-boxdiv classcontentdiv classcontent-titlepa classall全部/aa精选/aa我的/a/ppa classall全部/aspana1.1/aa1.2/aa1.3/aa1.4/aa1.5/a/spanahref$ classmore更多 i classi-chevron-bot/i/a/p/divdiv classitemdiv classitem-leftpimg src/static/img/widget-myImg.jpg width60px alt/pp毛老师/p/divdiv classitem-rightp classtitle如何用微服务重构应用程序?/ppspan我来回答/span/pp2017-3-20 spani/i回答2/spanspani/i浏览2/span/p/div/divdiv classitemdiv classitem-leftpimg src/static/img/widget-myImg.jpg width60px alt/pp毛老师/p/divdiv classitem-rightp classtitle如何用微服务重构应用程序?/pp在讨论如何将重构转化为微服务之前退后一步仔细观察微服务的内容和时间是很重要的。以下两个要点将会对任何微服务重构策略产生重大影响。 【最新 iclassnew心跳347890/i 的回答】/pp2017-3-20 span classaction-boxspaniclassi-answer/i回答 2/spanspani classi-browse/i浏览 12/span/span/p/div/divdiv classitemdiv classitem-leftpimg src/static/img/widget-myImg.jpg width60px alt/pp毛老师/p/divdiv classitem-rightp classtitle如何用微服务重构应用程序?/pp在讨论如何将重构转化为微服务之前退后一步仔细观察微服务的内容和时间是很重要的。以下两个要点将会对任何微服务重构策略产生重大影响。 【最新 iclassnew心跳347890/i 的回答】/pp2017-3-20 span classaction-boxspaniclassi-answer/i回答 2/spanspani classi-browse/i浏览 12/span/span/p/div/divdiv classitemdiv classitem-leftpimg src/static/img/widget-myImg.jpg width60px alt/pp毛老师/p/divdiv classitem-rightp classtitle如何用微服务重构应用程序?/pp在讨论如何将重构转化为微服务之前退后一步仔细观察微服务的内容和时间是很重要的。以下两个要点将会对任何微服务重构策略产生重大影响。 【最新 iclassnew心跳347890/i 的回答】/pp2017-3-20 span classaction-boxspaniclassi-answer/i回答 2/spanspani classi-browse/i浏览 12/span/span/p/div/divdiv classitemdiv classitem-leftpimg src/static/img/widget-myImg.jpg width60px alt/pp毛老师/p/divdiv classitem-rightp classtitle如何用微服务重构应用程序?/pp在讨论如何将重构转化为微服务之前退后一步仔细观察微服务的内容和时间是很重要的。以下两个要点将会对任何微服务重构策略产生重大影响。 【最新 iclassnew心跳347890/i 的回答】/pp2017-3-20 span classaction-boxspaniclassi-answer/i回答 2/spanspani classi-browse/i浏览 12/span/span/p/div/divdiv classitemdiv classitem-leftpimg src/static/img/widget-myImg.jpg width60px alt/pp毛老师/p/divdiv classitem-rightp classtitle如何用微服务重构应用程序?/pp在讨论如何将重构转化为微服务之前退后一步仔细观察微服务的内容和时间是很重要的。以下两个要点将会对任何微服务重构策略产生重大影响。 【最新 iclassnew心跳347890/i 的回答】/pp2017-3-20 span classaction-boxspaniclassi-answer/i回答 2/spanspani classi-browse/i浏览 12/span/span/p/div/divdiv classitemlasta href# classoverwrite显示更多问题/a/div/div/div!--侧边栏--!--#include virtual/include/course_detail_side.html--!--侧边栏--/div/divdiv classartcleNot styledisplay: none;div classarticle-cont-notediv classarticle-left-boxdiv classcontentdiv classcontent-titlepa classall全部/aa精选/aa我的/a/ppa classall全部/aspana1.1/aa1.2/aa1.3/aa1.4/aa1.5/a/spanahref$ classmore更多 i classi-chevron-bot/i/a/p/divdiv classitemdiv classitem-leftpimg src/static/img/widget-myImg.jpg width60px alt/pp毛老师/p/divdiv classitem-rightspan classvideo-timei classi-play/i210/spanpimg src/static/img/widget-demo.png width221 alt/pp classaction-box4小时前 span classactive-boxspaniclassi-coll/i采集/spanspani classi-laud/i赞/span/span/p/div/divdiv classitemdiv classitem-leftpimg src/static/img/widget-myImg.jpg width60px alt/pp毛老师/p/divdiv classitem-rightp在讨论如何将重构转化为微服务之前退后一步br仔细观察微服务的内容和时间是很重要的。br以下两个要点将会对任何微服务重构策略产生重大影响。 /pp classaction-box4小时前 span classactive-boxspaniclassi-edt/i编辑/spanspaniclassi-del/i删除/spanspani classi-laud/i赞/span/span/p/div/divdiv classitemdiv classitem-leftpimg src/static/img/widget-myImg.jpg width60px alt/pp毛老师/p/divdiv classitem-rightp在讨论如何将重构转化为微服务之前退后一步br仔细观察微服务的内容和时间是很重要的。br以下两个要点将会对任何微服务重构策略产生重大影响。 /pp classaction-box4小时前 span classactive-boxspaniclassi-edt/i编辑/spanspaniclassi-del/i删除/spanspani classi-laud/i赞/span/span/p/div/divdiv classitemdiv classitem-leftpimg src/static/img/widget-myImg.jpg width60px alt/pp毛老师/p/divdiv classitem-rightp在讨论如何将重构转化为微服务之前退后一步br仔细观察微服务的内容和时间是很重要的。br以下两个要点将会对任何微服务重构策略产生重大影响。 /pp classaction-box4小时前 span classactive-boxspaniclassi-edt/i编辑/spanspaniclassi-del/i删除/spanspani classi-laud/i赞/span/span/p/div/div/div/div!--侧边栏--!--#include virtual/include/course_detail_side.html--!--侧边栏--/div/divdiv classartcleCod styledisplay: none;div classarticle-contdiv classarticle-left-boxdiv classcomment-boxdiv classevaluatediv classeva-topdiv classtit课程评分/divdiv classstardiv classscorei5/i/div/divspan classstar-score i5/i 分/span/divdiv classeva-contdiv classtit学员评语/divdiv classtext-boxtextarea classform-control rows5placeholder扯淡、吐槽、表扬、鼓励......想说啥说啥/textareadiv classtext-rightspan发表评论/span/div/div/div/divdiv classcourse-evaluatediv classtop-tit评论spanlabelinput nameeval typeradio value checked/ 所有学生 /labellabelinput nameeval typeradio value/ 完成者 /label/span/divdiv classtop-contdiv classcont-top-leftdiv classstar-scordiv classstar-showdiv classscorei5/i/div/divdiv classscor4.9分/div/divdiv classall-scor总评分12343/div/divdiv classcont-top-rightdiv classstar-grade五星div classgradediv classgrade-percentspan/span/divdiv classpercent-numi95/i%/div/div/divdiv classstar-grade四星div classgradediv classgrade-percentspan/span/divdiv classpercent-numi5/i%/div/div/divdiv classstar-grade三星div classgradediv classgrade-percentspan/span/divdiv classpercent-numi0/i%/div/div/divdiv classstar-grade二星div classgradediv classgrade-percentspan/span/divdiv classpercent-numi2/i%/div/div/divdiv classstar-grade一星div classgradediv classgrade-percentspan/span/divdiv classpercent-numi1/i%/div/div/div/div/divdiv classcomment-item-boxdiv classtitle评论 span12453条评论/span/divdiv classitemdiv classitem-leftpimg src/static/img/widget-pic.png width60px alt/pp毛老师/p/divdiv classitem-centp很受用如果再深入下就更好了。虽然都是入门级别的但是也很使用后续就需要自己发挥了虽然都是入门级别的但是也很使用后续就需要自己发挥了虽然都是入门级别的但是也很使用后续就需要自己发挥了虽然都是入门级别的但是也很使用后续就需要自己发挥了/pp classtime2017-2-43/p/divdiv classitem-ritpdiv classstar-showdiv classscorei4/i/div/div/pp评分 span5星/span/p/div/divdiv classitemdiv classitem-leftpimg src/static/img/widget-pic.png width60px alt/pp毛老师/p/divdiv classitem-centp很受用如果再深入下就更好了。虽然都是入门级别的但是也很使用后续就需要自己发挥了虽然都是入门级别的但是也很使用后续就需要自己发挥了虽然都是入门级别的但是也很使用后续就需要自己发挥了虽然都是入门级别的但是也很使用后续就需要自己发挥了/pp classtime2017-2-43/p/divdiv classitem-ritpdiv classstar-showdiv classscorei5/i/div/div/pp评分 span5星/span/p/div/divdiv classitemdiv classitem-leftpimg src/static/img/widget-pic.png width60px alt/pp毛老师/p/divdiv classitem-centp很受用如果再深入下就更好了。虽然都是入门级别的但是也很使用后续就需要自己发挥了虽然都是入门级别的但是也很使用后续就需要自己发挥了虽然都是入门级别的但是也很使用后续就需要自己发挥了虽然都是入门级别的但是也很使用后续就需要自己发挥了/pp classtime2017-2-43/p/divdiv classitem-ritpdiv classstar-showdiv classscorei5/i/div/div/pp评分 span5星/span/p/div/divdiv classitemdiv classitem-leftpimg src/static/img/widget-pic.png width60px alt/pp毛老师/p/divdiv classitem-centp很受用如果再深入下就更好了。虽然都是入门级别的但是也很使用后续就需要自己发挥了虽然都是入门级别的但是也很使用后续就需要自己发挥了虽然都是入门级别的但是也很使用后续就需要自己发挥了虽然都是入门级别的但是也很使用后续就需要自己发挥了/pp classtime2017-2-43/p/divdiv classitem-ritpdiv classstar-showdiv classscorei5/i/div/div/pp评分 span5星/span/p/div/divdiv classget-more页面加载中.../div/div/div/div/div!--侧边栏--!--#include virtual/include/course_detail_side.html--!--侧边栏--/div/div/div/divdiv classpopup-coursediv classmask/div!--欢迎访问课程弹窗- start --div classpopup-course-boxdiv classtitle${model.courseBase.name} span classclose-popup-course-box×/span/divdiv classcontentp欢迎学习本课程本课程免费您可以立即学习也可加入我的课程表享受更优质的服务。/ppa href# click.preventaddCourseTable()加入我的课程表/a a href#click.preventstartLearngin()立即学习/a/p/div/div/divdiv classpopup-boxdiv classmask/div!--支付弹窗- start --div classpopup-pay-boxdiv classtitle${model.courseBase.name} span classclose-popup-pay-box×/span/divdiv classcontentimg :srcqrcode width200 height200 alt请点击支付宝支付按钮并完成扫码支付。/div classinfop classinfo-tit${model.courseBase.name}span课程有效期:${model.courseBase.validDays}天/span/pp classinfo-pic课程价格 : span${model.courseBase.originalPrice!}元/span/pp classinfo-new-pic优惠价格 : span${model.courseBase.price!}元/span/p/div/divdiv classfact-pic实际支付: span${model.courseBase.price!}元/span/divdiv classgo-paya href# click.preventwxPay()微信支付/aa href#click.preventaliPay()支付宝支付/aahref# click.preventquerypayresult()支付完成/aa href# click.preventstartLearngin()试学/a/div/div!--支付弹窗- end --div classpopup-comment-box/div/div!-- 页面底部 --!--底部版权--!--#include virtual/include/footer.html--!--底部版权--
/div
scriptvar courseId ${model.courseBase.id};var courseCharge ${model.courseBase.charge}/script
!--#include virtual/include/course_detail_dynamic.html--
/body
1.4.5 测试
首先修改一下前端“.env”文件 启动前后端项目进行联调 1.5 课程预览 视频
我们在“课程预览”模块右侧有一个目录点击目录之后可以查看对应的视频 1.5.1 配置Nginx
从路径就能看出来是公开的不管用户是否登录都能访问
#openapi
location /open/content/ {proxy_pass http://gatewayserver/content/open/;
}
location /open/media/ {proxy_pass http://gatewayserver/media/open/;
} 重新加载一下配置文件
nginx.exe -s reload1.5.2 CourseOpenController
在content-api模块创建此类
Api(value 课程公开查询接口, tags 课程公开查询接口)
RestController
RequestMapping(/open)
public class CourseOpenController {Autowiredprivate CourseBaseInfoService courseBaseInfoService;Autowiredprivate CoursePublishService coursePublishService;/*** 根据课程的id查询课程的信息*/GetMapping(/course/whole/{courseId})public CoursePreviewDto getPreviewInfo(PathVariable(courseId) Long courseId) {//获取课程预览信息return coursePublishService.getCoursePreviewInfo(courseId);}}1.5.3 MediaOpenController
在media-api工程中创建此类
Api(value 媒资文件管理接口, tags 媒资文件管理接口)
RestController
RequestMapping(/open)
public class MediaOpenController {AutowiredMediaFileService mediaFileService;ApiOperation(预览文件)GetMapping(/preview/{mediaId})public RestResponseString getPlayUrlByMediaId(PathVariable String mediaId) {MediaFiles mediaFiles mediaFileService.getFileById(mediaId);if (mediaFiles null || StringUtils.isEmpty(mediaFiles.getUrl())) {XueChengPlusException.cast(视频还没有转码处理);}return RestResponse.success(mediaFiles.getUrl());}}/*** 根据媒资id获取媒资信息*/
Override
public MediaFiles getFileById(String mediaId) {return mediaFilesMapper.selectById(mediaId);
}1.5.4 测试
这些如果关联视频的话都是可以播放的但是我只关联了一个视频 二、提交课程审核
在如下图所示区域 2.1 需求分析 来自黑马程序员资料 课程发布前要先审核审核通过方可发布 为什么课程审核通过才可以发布呢
这样做为了防止课程信息有违规情况课程信息不完善对网站用户体验也不好课程审核不仅起到监督作用也是帮助教学机构规范使用平台的手段。
如何控制课程审核通过才可以发布课程呢
在课程基本表course_base表设置课程审核状态字段包括未提交、已提交(未审核)、审核通过、审核不通过。
下边是课程状态的转化关系 真的非常的形象 说明如下
1、一门课程新增后它的审核状为”未提交“发布状态为”未发布“。
2、课程信息编辑完成教学机构人员执行”提交审核“操作。此时课程的审核状态为”已提交“。
3、当课程状态为已提交时运营平台人员对课程进行审核。
4、运营平台人员审核课程结果有两个审核通过、审核不通过。
5、课程审核过后不管状态是通过还是不通过教学机构可以再次修改课程并提交审核此时课程状态为”已提交“。此时运营平台人员再次审核课程。
6、课程审核通过教学机构人员可以发布课程发布成功后课程的发布状态为”已发布“。
7、课程发布后通过”下架“操作可以更改课程发布状态为”下架“
8、课程下架后通过”上架“操作可以再次发布课程上架后课程发布状态为“发布”。
2.2 数据模型
课程提交审核后还允许修改课程吗
如果不允许修改是不合理的因为提交审核后可以继续做下一个阶段的课程内容比如添加课程计划上传课程视频等。
如果允许修改那么课程审核时看到的课程内容从哪里来如果也从课程基本信息表、课程营销表、课程计划表查询那么存在什么问题呢
运营人员审核课程和教学机构编辑课程操作的数据是同一份此时会导致冲突。比如运营人员正在审核时教学机构把数据修改了 为了解决这个问题专门设计课程预发布表 提交课程审核将课程信息汇总后写入课程预发布表课程预发布表记录了教学机构在某个时间点要发布的课程信息。
课程审核人员从预发布表查询信息进行审核。
课程审核的同时可以对课程进行修改修改的内容不会写入课程预发布表。
课程审核通过执行课程发布将课程预发布表的信息写入课程发布表 相当于此时用户修改的内容和运营人员审核的内容给区分开了 提交审核课程后也修改了课程信息可以再次提交审核吗
是可以的只不过提交审核课程后必须等到课程审核完成才可以再次提交课程 表结构
提交审核将信息写入课程预发布表课程预发布表course_publish_pre结构如下 预发布表其实就是课程营销信息表、课程师资表、课程计划表、课程基本信息表的大综合 当预发布表的数据审核通过后就会将预发布表的数据拷贝一份到发布表中用户发布的内容其实就是发布表中的内容 更新课程基本信息表的课程审核状态为已经提交
课程审核后更新课程基本信息表的审核状态、课程预发布表的审核状态并将审核结果写入课程审核记录。
审核记录表结构如下 2.2.1 课程预发布表 course_publish_pre
Data
TableName(course_publish_pre)
public class CoursePublishPre implements Serializable {private static final long serialVersionUID 1L;/*** 主键*/private Long id;/*** 机构ID*/private Long companyId;/*** 公司名称*/private String companyName;/*** 课程名称*/private String name;/*** 适用人群*/private String users;/*** 标签*/private String tags;/*** 创建人*/private String username;/*** 大分类*/private String mt;/*** 大分类名称*/private String mtName;/*** 小分类*/private String st;/*** 小分类名称*/private String stName;/*** 课程等级*/private String grade;/*** 教育模式*/private String teachmode;/*** 课程图片*/private String pic;/*** 课程介绍*/private String description;/*** 课程营销信息json格式*/private String market;/*** 所有课程计划json格式*/private String teachplan;/*** 教师信息json格式*/private String teachers;/*** 提交时间*/TableField(fill FieldFill.INSERT)private LocalDateTime createDate;/*** 审核时间*/private LocalDateTime auditDate;/*** 状态*/private String status;/*** 备注*/private String remark;/*** 收费规则对应数据字典--203*/private String charge;/*** 现价*/private Float price;/*** 原价*/private Float originalPrice;/*** 课程有效期天数*/private Integer validDays;}2.3 CoursePublishController
1、查询课程基本信息、课程营销信息、课程计划信息等课程相关信息整合为课程预发布信息。
2、向课程预发布表course_publish_pre插入一条记录如果已经存在则更新审核状态为已提交。
3、更新课程基本表course_base课程审核状态为已提交。
约束
1、对已提交审核的课程不允许提交审核。
2、本机构只允许提交本机构的课程。
3、没有上传图片不允许提交审核。
4、没有添加课程计划不允许提交审核。
使用代码生成器生成课程发布表、课程预发布表的PO、Mpper并拷贝到相应的工程下。
首先在content-api工程下添加如下接口 ResponseBody
PostMapping (/courseaudit/commit/{courseId})
public void commitAudit(PathVariable(courseId) Long courseId){Long companyId 1232141425L;coursePublishService.commitAudit(companyId,courseId);}
2.4 CoursePublishServiceImpl
/*** description 提交审核* param courseId 课程id*/TransactionalOverridepublic void commitAudit(Long companyId, Long courseId) {// 课程基本信息CourseBaseInfoDto courseBaseInfo courseBaseInfoService.getCourseBaseInfo(courseId);if (courseBaseInfo null) {XueChengPlusException.cast(课程找不到);}//得到审核状态String auditStatus courseBaseInfo.getAuditStatus();//TODO 如果课程的审核状态为已提交则不允许提交if (202003.equals(auditStatus )) {XueChengPlusException.cast(课程已经提交申请请您耐心等待审核);}//TODO 本机构只能提交本机构的课程//TODO 如果课程的图片、计划信息没有填写不允许提交if (StringUtils.isEmpty(courseBaseInfo.getPic())) {XueChengPlusException.cast(请上传课程图片);}//查询课程计划CoursePreviewDto coursePreviewInfo coursePublishService.getCoursePreviewInfo(courseId);if (coursePreviewInfo null || coursePreviewInfo.getTeachplans().size() 0) {XueChengPlusException.cast(请上传课程计划);}//TODO 1.查询到课程基本信息、营销信息、计划等信息插入到课程预报布表CoursePublishPre coursePublishPre new CoursePublishPre();//TODO 1.1课程基本信息加部分营销信息BeanUtils.copyProperties(courseBaseInfo,coursePublishPre);// 设置机构idcoursePublishPre.setCompanyId(companyId);//课程营销信息CourseMarket courseMarket courseMarketMapper.selectById(courseId);//转为jsonString courseMarketJson JSON.toJSONString(courseMarket);//将课程营销信息json数据放入课程预发布表coursePublishPre.setMarket(courseMarketJson);//TODO 1.2查询课程计划信息ListTeachplanDto teachplanTree teachplanService.findTeachplanTree(courseId);if(teachplanTree.size()0){XueChengPlusException.cast(提交失败还没有添加课程计划);}//转jsonString teachplanTreeString JSON.toJSONString(teachplanTree);coursePublishPre.setTeachplan(teachplanTreeString);//TODO 1.3设置预发布记录状态,已提交coursePublishPre.setStatus(202003);//教学机构idcoursePublishPre.setCompanyId(companyId);//提交时间coursePublishPre.setCreateDate(LocalDateTime.now());CoursePublishPre coursePublishPreUpdate coursePublishPreMapper.selectById(courseId);if(coursePublishPreUpdate null){//添加课程预发布记录coursePublishPreMapper.insert(coursePublishPre);}else{coursePublishPreMapper.updateById(coursePublishPre);}//TODO 2.更新课程基本信息表的审核状态为已提交CourseBase courseBase courseBaseMapper.selectById(courseId);// 审核状态为已提交courseBase.setAuditStatus(202003);courseBaseMapper.updateById(courseBase);}
补充课程审核状态码
[{code:202001,desc:审核未通过},{code:202002,desc:未提交},{code:202003,desc:已提交},{code:202004,desc:审核通过}
]课程发布状态
[{code:203001,desc:未发布},{code:203002,desc:已发布},{code:203003,desc:下线}
]2.5 测试
首次提交审核 因为我们没有做审核模块所以我们直接修改数据库的数据即可作为审核通过
1、修改课程预发布表的状态status字段为审核通过202004。
2、修改课程基本表的审核状态auditStatus字段为审核通过202004。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/921689.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!