【Django+Vue3 线上教育平台项目实战】构建课程详情页与集成视频播放功能

news2024/9/23 19:22:38

在这里插入图片描述


文章目录

  • 前言
  • 一、课程列表页面
    • a.后端代码
    • b.前端代码
  • 二、课程详情页面
    • a. 视频播放功能的集成
      • 1.获取上传视频的链接地址
      • 2.集成在前端页面中
        • 1>使用vue-alipayer视频播放组件
        • 2>使用video标签
    • b. 页面主要内容展示
      • 1.后端代码
        • 1>分析表
        • 2>核心逻辑
      • 2.前端代码
      • 3.效果图


前言

    随着数字化教育的兴起,构建一个高效、用户友好的线上教育平台至关重要。本文将探讨如何使用Django与Vue.js 3结合,实现一个包含课程列表和课程详情页(含视频播放功能)的线上教育平台部分。本文主要介绍了如何设计数据库模型、处理数据查询、构建动态前端界面,并集成视频播放功能,为用户带来流畅的学习体验。


一、课程列表页面

获取所有一级分类,获取所有二级分类,获取所有课程(课程分页处理),点击方向和分类时获取此方向或者此分类下的数据信息

页面展示:
在这里插入图片描述

a.后端代码

url配置信息:

    path('nav/cates/', CategoryView.as_view()), #课程列表页面 /project-方向/一级分类 ----- 侧边栏-获取一二级分类 -
    path('nav/category/', CateView.as_view()),  #课程列表页面 /project-二级分类
    #课程列表页面 / project
    path('courseSearch/', CourseSearch.as_view()),  # /project页面--搜索课程---

获取方向、分类及课程信息:

# 2.获取一、二级分类
class CategoryView(APIView):
    def get(self, request):
        # 查询所有一级分类:parent is null
        # query_set
        categories = CategoryModel.objects.filter(is_delete=0,parent__id__isnull=True)  #query_set

        clist = [] #侧边栏 二级分类显示几个
        for category in categories:
            # 获取一级下面所有的二级分类,操作显示二级分类数据条数
            sondata = category.son.all()[0:2] #query_set
            # d对二级数据进行序列化操作
            son = SonCategorySerializer(sondata, many=True)
            clist.append({"id": category.id, "name": category.name, "son": son.data})

        return Response({"code":"200", "data":clist})

# 2.2 categoryId指定类别时,展示categoryId的子分类
# 获取project页面的二级分类
class CateView(APIView):
    def get(self, request):
        categoryId = int(request.GET.get('categoryId'))
        print(categoryId)

        if categoryId:
            category = CategoryModel.objects.filter(is_delete=False, parent_id=categoryId).all()
        else:
            category = CategoryModel.objects.filter(is_delete=False, parent_id__isnull=False).all()
        cates = SonCategorySerializer(category, many=True)
        return Response({"cood": 200, "cateList": cates.data})

# 8.搜索课程
class CourseSearch(APIView):
    def get(self,request):
     topId = int(request.GET.get('topId'))
     cid = int(request.GET.get('cid'))
     page = int(request.GET.get('page'))
     pageSize = int(request.GET.get('pageSize'))
     print(page,pageSize)

     if topId:
         course = CourseModel.objects.filter(topid=topId)
     if cid:
         course = CourseModel.objects.filter(parent_id=cid)
     if not topId and not cid:
         course = CourseModel.objects.all()

     courseTotal = CourseSerializer(course,many=True)

     coursePage = Paginator(course, pageSize)
     courseList = CourseSerializer(coursePage.get_page(page),many=True)

     return Response({"code": 200,"pagetion":{"page":page,"pageSize":pageSize,"total":len(courseTotal.data)},'cousers': courseList.data})

b.前端代码

主要代码(方向、分类、课程的获取与展示)- src/views/Course.vue:

<div class="type">
    <div class="type-wrap">
		<!-- 方向: -->
        <div class="one warp">
            <span class="name">方向:</span>
            <ul class="items">
                <li :class="{cur: course.current_direction === 0}"><a href="" @click.prevent="course.current_direction=0">全部</a></li>
                <li :class="{cur: course.current_direction === direction.id}" v-for="direction in category.data"><a href="" @click.prevent="course.current_direction=direction.id">{{direction.name}}</a></li>
            </ul>
        </div>
		<!-- 分类 -->
        <div class="two warp">
            <span class="name">分类:</span>
            <ul class="items">
                <li :class="{cur: course.current_category === 0}"><a href="" @click.prevent="course.current_category=0">不限</a></li>
                <li :class="{cur: course.current_category === category.id}" v-for="category in category.cateList"><a href="" @click.prevent="course.current_category=category.id">{{category.name}}</a></li>
            </ul>
        </div>
    </div>
</div>
<!-- Main课程部分 -->
<div class="main">
    <div class="main-wrap">
        <div class="filter clearfix">
            <div class="sort l">
              <a href="" :class="{on:course.ordering==='-id'}" @click.prevent.stop="course.ordering=(course.ordering==='-id'?'':'-id')">最新</a>
              <a href="" :class="{on:course.ordering==='-students'}" @click.prevent.stop="course.ordering=(course.ordering==='-students'?'':'-students')">销量</a>
              <a href="" :class="{on:course.ordering==='-orders'}" @click.prevent.stop="course.ordering=(course.ordering==='-orders'?'':'-orders')">推荐</a>
            </div>
            <div class="other r clearfix"><a class="course-line l" href="" target="_blank">学习路线</a></div>
        </div>

        <ul class="course-list clearfix">
		  <!-- 遍历展示课程信息 -->
          <li class="course-card" v-for="course_info in category.course_list">
            <router-link :to="`/project/${course_info.id}`">
                <div class="img"><img :src="course_info.picurl" alt=""></div>
                <p class="title ellipsis2">{{course_info.name}}</p>
                <p class="one">
            		<span>{{ course_info.level }} · {{ course_info.sales }}人报名</span>
                </p>
                <p class="two clearfix">
                    <span class="price l red bold" v-if="course_info.price !== undefined">¥{{parseFloat(course_info.price).toFixed(2)}}</span>
                    <span class="price l red bold" v-else>¥{{parseFloat(course_info.price).toFixed(2)}}</span>
                    <span class="origin-price l delete-line" v-if="course_info.price !== undefined">¥{{parseFloat(course_info.price).toFixed(2)}}</span>
                    <el-popconfirm title="您确认添加当前课程加入购物车吗?" @confirm.prevent.stop="add_course_to_cart(course_info)" confirmButtonText="买买买!" cancelButtonText="误操作!">
                      <template #reference>
                        <span class="add-shop-cart r" @click.stop.prevent=""><img class="icon imv2-shopping-cart" src="../assets/cart2.svg">加购物车</span>
                      </template>
                    </el-popconfirm>
                </p>
            </router-link>
          </li>
        </ul>
        
		<!-- 分页功能 -->
        <div class="page">
			<div style="position: absolute;left: 50%;transform: translateX(-50%)">
				<el-pagination
				style="margin: auto" background layout="prev, pager, next"
				:total='category.pageTion.total'
				:page-size="category.pageTion.pageSize"
				@current-change="change"/>
			</div>
        </div>
        
    </div>
</div>
import category from "../api/cetory.js";//++

category.get_category();
category.search_course(0, 0,pageTion);
category.get_cate(0);

src/api/cetory.js:

import { reactive } from "vue";
import http from "../http";
const category = reactive({
    data: [],  // 方向 / 一级分类
    course_list: [], // 课程信息
    cateList: [], //二级分类
    pageTion: {}, // 分页

    get_category(id) {
        return http.get("/home/nav/cates/", { params: { cateid: id } }).then(response => {
            //课程列表页面-project-获取方向(一级分类)
            // console.log("response.data.data*************/home/nav/cates/******************");
            // console.log(response.data.data);
            this.data = response.data.data;
        })
    },

    get_cate(categoryId) {
        return http.get("/home/nav/category/", { params: { categoryId: categoryId } }).then(response => {
            //课程列表页面-project-获取二级分类
            // console.log("response.data*********************/home/nav/category/***************************");
            // console.log(response.data);
            this.cateList = response.data.cateList;
        })
    },
    // 分页、搜索对应方向或分类的课程topid-->方向,cid-->分类
    search_course(topId, cid, page) {
        const params = {
            topId: topId,
            cid: cid,
            page: page.page,
            pageSize: page.pageSize
        }
        return http.get(`/home/courseSearch/`, { params }).then(response => {
            console.log("response.data****************/home/courseSearch/*********************");
            console.log(response.data);
            this.course_list = response.data.cousers;
            this.pageTion = response.data.pagetion;
        })
    },
})

export default category;

二、课程详情页面

a. 视频播放功能的集成

这里以七牛云服务器 (存储视频)+ vue-alipayer视频播放组件为例实现视频播放功能

  • 七牛云官网地址:https://www.qiniu.com/
  • vue-alipayer视频播放组件地址:https://github.com/liho98/vue-aliplayer-v2
    • 演示效果:https://player.alicdn.com/aliplayer/index.html

1.获取上传视频的链接地址

具体操作步骤如下:

  • 1.七牛云注册登录:https://www.qiniu.com/
  • 2.点击对象存储:
    在这里插入图片描述
  • 3.创建存储空间:
    在这里插入图片描述
  • 4.创建成功:
    在这里插入图片描述
  • 5.上传一段视频用于在课程详情页面展示:
    在这里插入图片描述
  • 6.视频上传成功:
    在这里插入图片描述
  • 7.查看文件详情,可获得文件链接:
    在这里插入图片描述

2.集成在前端页面中

1>使用vue-alipayer视频播放组件
            <AliPlayerV3
              ref="player"
              class="h-64 md:h-96 w-full rounded-lg"
              style="height: 100%; width: 100%;"
              :source="course.info.course[0].video_url"
              :cover="course.info.course_cover"
              :options="options"
              @play="onPlay($event)"
              @pause="onPause($event)"
              @playing="onPlaying($event)"
            />

source属性绑定的值,存放视频播放地址。(通过向后端发送请求获取数据库中的数据)


页面效果如下图:
在这里插入图片描述

2>使用video标签

可参考菜鸟教程:https://www.runoob.com/html/html-videos.html
示例代码:

<video width="320" height="240" controls>
 <source src="http://sgigui51q.hb-bkt.clouddn.com/scenery.mp4" type="video/mp4">
</video> 

b. 页面主要内容展示

1.后端代码

1>分析表
  • 1.课程表CourseModel
    • 新加字段:total_jie(总节数)、hours(总时长)、vide_url(课程总介绍)、question常见问题
  • 2.课程章表
    • 字段:id、名称、课程id(外键)、总节数、时间(用于页面展示)、总时长(秒)
  • 3.课程节表
    • 字段:id、名称、课程id、章id(外键)、视频id、时间、时长(秒)
  • 4.教师表(课程表+teacher字段关联教师表)
    • 字段:id、姓名、头像、介绍、教授的课程
  • 5.用户表
    • 字段:id、用户名、手机号、密码、积分、头像、个性签名
  • 6.评价表
    • 字段:id、userid(外键)、courseid(外键)、评价、评分
  • 7.回复表
    • 字段:id、回复人id(用户id)、评价id(外键)、内容
2>核心逻辑
# 0.课程详情
class CourseDetailView(APIView):
    def get(self, request, id):
        r.delete_str("testdata")
        # 先取一下缓存
        test_data = r.get_str("testdata")
        if test_data:
            # 序列化 str-->json
            test_data = json.loads(test_data)
            return Response({"message":"test111111","data":test_data})

        course_list = CourseModel.objects.filter(id=id)
        ser = CourseSerializer(course_list, many=True)

        # 放入缓存 json-->str
        r.set_str('testdata',json.dumps(ser.data))

        return Response({"message":"test22222222222","code":"200","data":ser.data})

# 1.获取章节信息
class ChaptersView(APIView):
    def get(self, request, id):
        # 根据课程id查对应章节
        course = CourseModel.objects.filter(id=id).first()
        # course + chapters
        chapt = course.chapters.all()
        ser = ChaptersSerializer(chapt, many=True)
        return Response({"code": "200", "data": ser.data})

#2.评论及其回复
class CommentView(APIView):
    def get(self, request, id):
        # id---> 课程id ---对应查询课程下面的评论
        comments = CommentModel.objects.filter(course_id=id)
        comments_ser = CommentsSerializer(comments, many=True)
        return Response({"code": "200", "data": comments_ser.data})



2.前端代码

课程详情页面src/views/Info.vue:

<template>
    <div class="detail">
      <Header/>
      <!-- 主体内容 -->
      <div class="main">
        <!-- 课程详情 -上半部分 -->
        <div class="course-info">
          <div class="wrap-left">
          	<!-- 视频播放器 -->
            <AliPlayerV3
              ref="player"
              class="h-64 md:h-96 w-full rounded-lg"
              style="height: 100%; width: 100%;"
              :source="course.info.course[0].video_url"
              :cover="course.info.course_cover"
              :options="options"
              @play="onPlay($event)"
              @pause="onPause($event)"
              @playing="onPlaying($event)"
            />
          </div>
          <div class="wrap-right">
            <h3 class="course-name">{{course.info.course[0].name}}</h3>
            <p class="data">
              {{course.info.course[0].sales}}人在A学&nbsp;&nbsp;&nbsp;&nbsp;
              课程总时长:{{course.info.pub_lessons}}课时/{{course.info.lessons}}课时
              &nbsp;&nbsp;&nbsp;&nbsp;
              难度:{{course.info.course[0].level}}
            </p>
            
            <div class="sale-time" v-if="!course.info.discount.type">
              <p class="sale-type">课程价格 ¥{{parseFloat(course.info.course[0].price).toFixed(2)}}</p>
            </div>
            <p class="course-price" v-if="course.info.discount.price !== undefined">
              <span>活动价</span>
              <span class="discount">¥{{parseFloat(course.info.discount.price).toFixed(2)}}</span>
              <span class="original">¥{{parseFloat(course.info.price).toFixed(2)}}</span>
            </p>
            <p class="course-price" v-if="course.info.credit>0">
              <span>抵扣积分</span>
              <span class="discount">{{course.info.credit}}</span>
            </p>
            <div class="buy">
              <div class="buy-btn">
                <button class="buy-now">立即购买</button>
                <button class="free">免费试学</button>
              </div>
              <el-popconfirm title="您确认添加当前课程加入购物车吗?" @confirm="add_course_to_cart" confirmButtonText="买买买!" cancelButtonText="误操作!">
                <template #reference>
                  <div class="add-cart"><img src="../assets/cart-yellow.svg" alt="">加入购物车</div>
                </template>
              </el-popconfirm>
            </div>
          </div>
        </div>
        <!-- 课程标签、课程选项卡 -中间部分 -->
        <div class="course-tab">
          <ul class="tab-list">
            <li :class="course.tabIndex===1?'active':''" @click="course.tabIndex=1">详情介绍</li>
            <li :class="course.tabIndex===2?'active':''" @click="course.tabIndex=2">课程章节 <span :class="course.tabIndex!==2?'free':''" v-if="course.info.can_free_study">(试学)</span></li>
            <li :class="course.tabIndex===3?'active':''" @click="course.tabIndex=3">用户评论 </li>
            <li :class="course.tabIndex===4?'active':''" @click="course.tabIndex=4">常见问题</li>
          </ul>
        </div>
        <!-- 课程内容 -章节-下半部分 -->
        <!-- 章节:{{course.chapter_list[0].name}} -->
        <div class="course-content">
          <!-- 选项卡-内容 -->
          <div class="course-tab-list">
            <!-- 选项卡1:详情介绍 -->
            <div class="tab-item" v-if="course.tabIndex===1" v-html="course.info.course[0].describe"></div>
            <!-- 选项卡2:课程章节 -->
            <div class="tab-item" v-if="course.tabIndex===2">
              <div class="tab-item-title">
                <p class="chapter">课程章节</p>
                <p class="chapter-length">共{{course.chapter_list.length}}章 {{course.info.course[0].hours}}个课时</p>
              </div>
              <div class="chapter-item" v-for="chapter,index in course.chapter_list" :key="index">
                <p class="chapter-title"><img src="../assets/1.svg" alt="">第{{chapter.id}}章·{{chapter.name}}</p>
                <div class="chapter-title" style="padding-left: 2.4rem;" v-if="chapter.summary" v-html="chapter.summary"></div>
                <!-- jie:{{chapter.sections}} -->
                <ul class="lesson-list">
                  <li class="lesson-item"  v-for="lesson,index in chapter.sections" :key="index">
                    <p class="name">
                      <span class="index">{{chapter.orders}}-{{lesson.orders}}</span>
                      {{lesson.name}}
                      <span class="free" v-if="lesson.free_trail">免费</span>
                    </p>
                    <p class="time">{{lesson.duration}} <img src="../assets/chapter-player.svg"></p>
                    <button class="try"  v-if="lesson.free_trail">立即试学</button>
                    <button class="try" v-else>购买课程</button>
                  </li>
                </ul>
              </div>
            </div>
            <!-- 选项卡3:用户评论 -->
            <div class="tab-item" v-if="course.tabIndex===3">
              <h2>用户评论</h2>
                <div class="teacher-content">
                 <div class="cont1">
                   <img style="border-radius: 50%;" :src="course.comments_list[0].user.avatar">
                   <p class="teacher-name">{{course.comments_list[0].user.username}}</p>
                 </div>
                <div class="narrative" v-html="course.comments_list[0].message"></div>  
            </div>
            </div>

            <!-- 选项卡4:常见问题 -->
            <div class="tab-item" v-if="course.tabIndex===4">
              <h2>常见问题</h2>
              <div v-html="course.info.course[0].question"></div>
            </div>
          </div>

          <!-- 课程旁边的老师 -->
          <!-- 教师:{{course.info.course[0].teacher}} -->
          <div class="course-side">
             <div class="teacher-info">
               <h4 class="side-title"><span>授课老师</span></h4>
               <div class="teacher-content">
                 <div class="cont1">
                   <img style="border-radius: 50%;" :src="course.info.course[0].teacher.avatar">
                   <div class="name">
                     <p class="teacher-name">{{course.info.course[0].teacher.name}}</p>
                     <p class="teacher-title">{{course.info.course[0].teacher.get_role_display}}角色:教师,教授的课程:{{course.info.course[0].teacher.courses}}</p>
                   </div>
                 </div>
                 <div class="narrative" v-html="course.info.course[0].teacher.introduce"></div>
               </div>
             </div>
          </div>

        </div>
      </div>

      <Footer/>
    </div>
</template>

课程详情src/api/course.js:

  get_course() {
    // 获取课程详情
    return http.get(`/info/courses/${this.course_id}/`).then(response => {
      console.log("response.data:**************/info/courses/*******************");
      console.log(response.data);
      this.info.course = response.data.data;
      return this.get_course_chapters();
    })
  },
    get_course_chapters() {
    // 获取指定课程的章节列表
    return http.get(`/info/chapters/${this.course_id}/`).then(response => {
      // console.log("response.data---*******************/info/chapters********************");
      // console.log(response.data);
      this.chapter_list = response.data.data;
    })
  },
    get_comments_list() {
    // 获取对应课程下面的评论信息
    return http.get(`/info/comments/${this.course_id}/`).then(response => {
      console.log("response.data-----------/info/comments/*****************");
      console.log(response.data);
      console.log(response.data.data);
      this.comments_list = response.data.data;
    })
  },
  

3.效果图

  • 详情介绍
    在这里插入图片描述
  • 课程章节
    在这里插入图片描述
  • 用户评论
    在这里插入图片描述
  • 常见问题
    在这里插入图片描述

在这里插入图片描述

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

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

相关文章

网络编程笔记

网络编程 1. 概念 1.1 局域网 局域网&#xff1a;局域网将一定区域的各种计算机、外部设备和数据连接起来形成计算机通信的私有网络 广域网&#xff1a;又称广域网、外网、公网。是连接不同地区局域网或城域网计算机通信的远程公共网络 1.2 IP 本质是一个整形数&#xff…

electron实现右键菜单保存图片功能

1.创建窗口&#xff0c;加载页面&#xff0c;代码如下&#xff1a; //打开窗口const {ipcMain, BrowserWindow} require("electron") const saveImage require("../ipcMain/saveImage") let win null; ipcMain.handle(on-open-event, (event, args) &g…

Oralce笔记-解决Oracle18c中ORA-28001: 口令已经失效

远程已经连不上了&#xff0c;需要登陆到安装Oracle的机器&#xff0c;使用sqlplus直接连。 sqlplus / as sysdba 登陆进去后修改期限为无限制&#xff1a; ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED 对于已经告警提示密码已过期的数据库&#xff0c;需要…

顺序表<数据结构 C 版>

目录 线性表 顺序表 动态顺序表类型 初始化 销毁 打印 检查空间是否充足&#xff08;扩容&#xff09; 尾部插入 头部插入 尾部删除 头部删除 指定位置插入 指定位置删除 查找数据 线性表 线性表是n个相同特性的数据元素组成的有限序列&#xff0c;其是一种广泛运…

vue实现动态图片(gif)

目录 1. 背景 2. 分析 3. 代码实现 1. 背景 最近在项目中发现一个有意思的小需求&#xff0c;鼠标移入一个盒子里&#xff0c;然后盒子里的图就开始动起来&#xff0c;就像一个gif一样&#xff0c;然后鼠标移出&#xff0c;再按照原来的变化变回去&#xff0c;就像变形金刚…

掌握Vue.js:六步打造前端开发高手!

Vue.js&#xff0c;这个在前端开发界熠熠生辉的名字&#xff0c;以其轻巧、高效、易学的特性&#xff0c;成为了众多开发者构建动态交互式网页的首选框架。它不仅简化了前端开发的复杂性&#xff0c;还提供了一套丰富的组件库和工具链&#xff0c;使得开发者能够快速上手并构建…

微软Office PLUS办公插件下载安装指南

微软OfficePLUS插件下载安装指南 简介&#xff1a; OfficePLUS微软官方出品的Office插件 &#xff0c;OfficePLUS拥有30万高质量模板素材&#xff0c;能帮助Word、Excel、Powerpoint、PDF等多种办公软件提升效率&#xff0c;具有智能化、模板质量高、运行快、稳定性强等优点。…

【大语言模型】私有化搭建-企业知识库-知识问答系统

下面是我关于大语言模型学习的一点记录 目录 人工智能学习路线 MaxKB 系统(基于大语言模型的知识问答系统) 部署开源大语言模型LLM 1.CPU模式(没有好的GPU&#xff0c;算力和效果较差) 2.GPU模式&#xff08;需要有NVIDIA显卡支持&#xff09; Ollama网络配置 Ollama前…

docker私有仓库harbor安装

Harbor默认安装 下载harbor https://github.com/goharbor/harbor/releases/download/v2.11.0/harbor-offline-installer-v2.11.0.tgz 目前要求docker版本&#xff0c;docker 20.10.10-ce &#xff0c;和docker-compose 1.18.0 查看 docker-compose版本 docker-compose --ver…

卷积神经网络图像识别车辆类型

卷积神经网络图像识别车辆类型 1、图像 自行车: 汽车: 摩托车: 2、数据集目录 3、流程 1、获取数据,把图像转成矩阵,并随机划分训练集、测试集 2、把标签转为数值,将标签向量转换为二值矩阵 3、图像数据归一化,0-1之间的值 4、构造卷积神经网络 5、设置图像输入…

Mysql数据表的约束(下)

3.默认值约束(default) 与非空约束的命令一致,因为都属于列级约束,因此只需将not null改为default 默认值即可 删除默认值约束: 4.主键约束(primary key) 表示给一张表格设置了一个唯一标识,为了更快的去通过唯一的数据去准确的查找到每一条记录,一半咱们在创建表…

强化学习编程实战-5 基于时间差分的方法

第4章中&#xff0c;当模型未知时&#xff0c;由于状态转移概率P未知&#xff0c;动态规划中值函数的评估方法不再适用&#xff0c;用蒙特卡洛的方法聘雇值函数。 在蒙特卡洛方法评估值函数时&#xff0c;需要采样一整条轨迹&#xff0c;即需要从初始状态s0到终止状态的整个序列…

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(七)-通过无人机实现无线接入的独立部署

引言 本文是3GPP TR 22.829 V17.1.0技术报告&#xff0c;专注于无人机&#xff08;UAV&#xff09;在3GPP系统中的增强支持。文章提出了多个无人机应用场景&#xff0c;分析了相应的能力要求&#xff0c;并建议了新的服务级别要求和关键性能指标&#xff08;KPIs&#xff09;。…

【精品资料】模块化数据中心解决方案(33页PPT)

引言&#xff1a;模块化数据中心解决方案是一种创新的数据中心设计和部署策略&#xff0c;旨在提高数据中心的灵活性、可扩展性和效率。这种方案通过将数据中心的基础设施、计算、存储和网络资源封装到标准化的模块中&#xff0c;实现了快速部署、易于管理和高效运维的目标 方案…

FPGA入门-自用

写代码&#xff0c;并将引脚对应到板子相应的引脚上 下载程序到板子上 遇到错误了&#xff0c;不按想的来的了&#xff0c;进行仿真 查看网表图查看问题所在 简化了一些步骤&#xff1a;未使用引脚的设置&#xff0c;电压设置&#xff1b; 通过画网表结构图来构成电路 时钟 …

Android焦点之SurfaceFlinger的apply

接animate()的openSurfaceTransaction(),prepareSurfaces(),closeSurfaceTransaction() 1. mService.openSurfaceTransaction()&#xff0c;通过SurfaceControl来通知native开始一个Transaction&#xff1b; 2. mService.closeSurfaceTransaction()&#xff0c;通过SurfaceCo…

JVM系列 | 对象的创建与存储

JVM系列 | 对象的生命周期1 对象的创建与存储 文章目录 前言对象的创建过程内存空间的分配方式方式1 | 指针碰撞方式2 | 空闲列表 线程安全问题 | 避免空间冲突的方式方式1 | 同步处理&#xff08;加锁)方式2 | 本地线程分配缓存 对象的内存布局Part1 | 对象头Mark Word类型指针…

如何在Mac上恢复已删除的存档文件?

在本文中&#xff0c;我们将分享在 macOS 或 OS X 上运行的 MacBook、iMac 或 Mac mini 上恢复已删除存档文件的不同方法。 下载免费试用的 Mac 数据恢复软件以在 Mac 上恢复已删除的存档文件。 macOS 可以选择压缩您的文件。您只需选择文件&#xff0c;按住 Control 键单击&a…

实验场:在几分钟内使用 Bedrock Anthropic Models 和 Elasticsearch 进行 RAG 实验

作者&#xff1a;来自 Elastic Joe McElroy, Aditya Tripathi 我们最近发布了 Elasticsearch Playground&#xff0c;这是一个新的低代码界面&#xff0c;开发人员可以通过 A/B 测试 LLM、调整提示&#xff08;prompt&#xff09;和分块数据来迭代和构建生产 RAG 应用程序。今天…

基于Fail2ban及iptables的SSH端口爆破防御方案

君衍. 一、本篇介绍二、Fail2ban1、简介2、工作方式3、优缺点4、工作原理5、目录结构6、功能特点 三、更改默认SSH端口1、更改配置文件2、重启服务 四、SSH日志审计1、连接失败的IP2、失败IP次数排行3、连接成功的IP4、成功IP次数排行 五、Fail2ban1、安装2、配置3、日志查看4、…