CSDN_02_课程管理功能详解_优化版
2026/9/16 10:05:02 网站建设 项目流程

课程管理功能详解:从课程创建到上架运营的技术实现

课程管理不是简单的 CRUD。运营人员需要维护课程基础信息、章节顺序、试看策略、视频和文档素材,还要处理审核上架、套餐售卖和讲师展示。织码在线教育系统将课程、章节、媒体资源、套餐和讲师拆分建模,再通过状态机与发布校验保证内容能够安全进入学习端。

一、课程模型:主表、章节与媒体资源分离

课程主表保存标题、封面、简介、富文本详情、分类、讲师、价格、状态和运营统计;章节表保存课程归属、排序、媒体类型、媒体 ID、时长和试看属性。媒体文件不直接塞进课程表,而是通过 VOD 视频 ID 或 OSS 文件 Key 关联,便于后续替换存储平台。

CREATETABLE`edu_course`(`id`bigintNOTNULL,`title`varchar(200)NOTNULL,`cover_url`varchar(500),`detail`longtextCOMMENT'富文本HTML',`category_id`bigint,`lecturer_id`bigint,`price`decimal(10,2)DEFAULT0,`status`tinyintDEFAULT0COMMENT'0草稿 1待审核 2上架 3下架 4驳回',`sort`intDEFAULT0,PRIMARYKEY(`id`),KEY`idx_status_sort`(`status`,`sort`),KEY`idx_category`(`category_id`),KEY`idx_lecturer`(`lecturer_id`));CREATETABLE`edu_course_chapter`(`id`bigintNOTNULL,`course_id`bigintNOTNULL,`title`varchar(200)NOTNULL,`sort`intDEFAULT0,`media_type`tinyintCOMMENT'1视频 2图文 3文档',`media_id`varchar(100),`duration`int,`is_free`tinyintDEFAULT0,PRIMARYKEY(`id`),KEY`idx_course_sort`(`course_id`,`sort`));

idx_status_sort服务于后台课程列表和学员端上架课程查询,idx_course_sort保障章节按课程和顺序快速读取。章节排序更新时应在事务内处理,避免同一课程出现重复顺序或显示跳跃。

二、生命周期管理:用状态机控制发布质量

课程状态为DRAFT -> REVIEW -> ONLINE -> OFFLINE,审核驳回进入REJECTED,修改后可再次提交。状态迁移只能由服务端执行,前端按钮只是操作入口。

@TransactionalpublicvoidpublishCourse(LongcourseId){Coursecourse=courseMapper.selectById(courseId);validateCourseBasic(course);List<Chapter>chapters=chapterMapper.selectByCourseId(courseId);if(chapters.isEmpty())thrownewBizException("请至少添加一个章节");for(Chapterchapter:chapters){if(chapter.isVideo()&&!"Normal".equals(vodService.getVideoStatus(chapter.getMediaId()))){thrownewBizException("章节视频未转码完成");}}course.setStatus(CourseStatus.REVIEW);courseMapper.updateById(course);auditLogService.log("COURSE_PUBLISH",courseId,"提交课程审核");}

上架校验至少包含基础字段、章节数量、章节媒体状态和审核权限。VOD 视频必须处于可播放状态,避免学员打开课程后得到失效地址。发布动作与操作日志放在同一事务中,便于审计和问题追踪。

三、WangEditor 5:富文本编辑与内容安全

课程详情使用 WangEditor 5 封装为 Vue 组件,工具栏和编辑器实例分离管理。图片采用 OSS 签名直传,视频先获取 VOD 上传凭证,再通过 VOD SDK 上传并回填播放信息。

consteditorConfig={MENU_CONF:{uploadImage:{asynccustomUpload(file,insertFn){constsign=awaitgetOSSSignature(file.name)awaitfetch(sign.uploadUrl,{method:'PUT',body:file})insertFn(sign.fileUrl,file.name,sign.fileUrl)}}}}onBeforeUnmount(()=>editorRef.value?.destroy())

富文本入库前必须做 XSS 清洗,只放行业务所需标签和属性。图片、视频和 iframe 的协议应限制为 HTTPS,禁止脚本事件属性;编辑器组件卸载时销毁实例,避免路由切换造成内存泄漏。

四、多媒体素材库:VOD 与 OSS 的职责分工

视频交给阿里云 VOD 处理上传、转码、截图和播放信息,图片与文档使用 OSS 对象存储。客户端从服务端获取临时凭证后直传云端,后端只保存素材元数据和资源状态,降低应用服务带宽压力。

@PostMapping("/upload-auth")publicResult<UploadAuthVO>uploadAuth(@RequestBodyUploadDTOdto){UploadAuthauth=vodService.createUploadAuth(dto.getFileName());mediaService.preCreate(dto.getFileName(),auth.getVideoId(),MediaStatus.UPLOADING);returnResult.success(auth);}@PostMapping("/callback")publicStringcallback(@RequestBodyVodCallbackcallback){if(callback.isSuccess())mediaService.markReady(callback);return"success";}

上传凭证需要短时有效,VOD 回调要校验来源或签名,并保证重复回调幂等。素材状态建议至少包含上传中、转码中、可用和失败,课程发布只允许引用可用资源。

五、课程套餐:商品关系与学习权限解耦

套餐由edu_course_packageedu_package_course组成,关联表用(package_id, course_id)唯一约束防止重复配置。订单支付成功后,系统批量创建套餐内课程的UserCourse权限,并保留订单来源和到期时间。

@TransactionalpublicvoidhandlePackageOrderPaid(Orderorder){List<Long>courseIds=packageCourseMapper.selectCourseIdsByPackageId(order.getProductId());userCourseMapper.batchInsert(courseIds.stream().map(courseId->UserCourse.builder().userId(order.getUserId()).courseId(courseId).source(OrderSource.PACKAGE).orderId(order.getId()).expireTime(order.getExpireTime()).build()).toList());}

支付回调可能重复到达,权限开通需要使用订单号和课程 ID 做幂等约束或 upsert。套餐权限与课程展示状态解耦:课程下架后是否保留已购用户访问,应由业务规则明确,而不是由前端判断。

六、讲师主页:聚合接口降低前端请求编排成本

讲师主页通过一个聚合接口返回讲师资料、已上架课程和统计数据,减少前端分别请求多个接口造成的瀑布流。课程列表必须过滤ONLINE状态,并按排序字段分页。

@GetMapping("/{id}")publicResult<LecturerHomeVO>home(@PathVariableLongid){LecturerHomeVOvo=newLecturerHomeVO();vo.setLecturer(lecturerMapper.selectById(id));vo.setCourses(courseMapper.selectByLecturerAndStatus(id,CourseStatus.ONLINE));vo.setStats(lecturerStatsService.getStats(id));returnResult.success(vo);}

聚合查询要关注 N+1 查询和统计口径一致性。课程数量、学习人数等高频数据可以采用缓存或异步统计;学员端只返回已上架课程,避免把草稿或审核中的内容暴露出去。

七、管理端体验:列表查询与批量操作

后台列表使用 Element Plus Table、筛选表单和分页组件,筛选条件至少包含课程名称与状态。批量上架前应逐条执行发布校验,不能因为批量接口而绕过单课程规则;批量操作结果最好返回成功项与失败原因。

constfetchList=async()=>{loading.value=truetry{constres=awaitapi.get('/admin/course/page',{keyword:filters.keyword,status:filters.status,current:page.current,size:page.size})list.value=res.data.records page.total=res.data.total}finally{loading.value=false}}

八、总结

课程管理模块的工程价值在于把内容运营规则固化为可执行流程:课程与章节分离保证模型扩展,状态机和发布校验保证上架质量,WangEditor 5 提供富文本生产能力,VOD + OSS 承担不同媒体类型,套餐关系支撑组合销售,讲师聚合接口改善内容展示。

如需私有化部署报价、远程产品演示,可访问官网 https://www.weavecodes.com/ ,私信作者领取企业落地案例。
程价值在于把内容运营规则固化为可执行流程:课程与章节分离保证模型扩展,状态机和发布校验保证上架质量,WangEditor 5 提供富文本生产能力,VOD + OSS 承担不同媒体类型,套餐关系支撑组合销售,讲师聚合接口改善内容展示。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询