教学机构流程
所涉及到业务模块
1.内容管理
2.媒资管理
3.课程发布
所涉及到业务功能
1.内容管理
课程基础信息(乐天)添加、修改、删除、查询
课程计划信息(乐天)
添加、修改、删除、查询课程教师信息(zyq)添加、修改、删除、查询<br />课程审核(zyq)
2.媒资管理
文件上传(澳前)
3.课程发布
课程发布(鑫龙)
功能实现
课程基础信息查询

接口定义
传入参数:pageNo、pageSize、auditStatus与courseName
传出参数:以DTO的形式响应给前端
数据模式:课程基础信息表(course_base)
业务分析:
1.不需要开启事务2.判断关键数据pageNo,pageSize,companyId3.构建分页查询条件根据课程状态查询根据课程名称查询4.构建分页数据5.将查询得到的数据转换成DTO形式,进行数据封装(PageVo)响应给前端
课程基础信息新增


接口定义
传入参数:课程基本信息,营销信息
传出参数:要求以DTO的形式响应给前端

数据模式:课程基础信息表(course_base)、课程营销信息(course_market)
业务分析:
1.开启事务2.判断关键数据(1)前端标注不能为空选项的数据不能为空(2)后端数据库约束非空字段不能为空--如果关键数据有问题:终止方法和通知前端错误数据:抛出异常3.判断业务数据(1)判断charge是否存在,判断是否收费--->收费,添加价格;免费,价格设置默认值0(2)判断是否是同一家机构4.保存数据添加课程基本信息,根据课程id把课程价格插入到课程营销表先保存课程基础信息数据,再保存课程营销信息数据—————>原因:课程基础信息需要机构id5.将数据转换成CourseBaseDTO并把价格和收费标准赋值,响应给前端
课程基础信息修改
更新

传入传出参数:
数据模式:
业务分析:
1.判断关键数据
courseBasaeId,companyId
2.判断业务数据
判断课程信息是否存在
根据id来查询
判断课程是否同一家机构
判断课程数据是否删除
status 1-使用,0-删除
查询
传入传出参数:
数据模式:
业务分析:
1.判断关键数据
2.判断业务数据
课程基础信息
判断是否存在
判断是否同一家教学机构
判断是否删除
判断审核状态
3.修改课程审核状态
已提交
课程基础信息删除
传入传出参数:
courseBaseId
数据模式:courseBase
业务分析:
0.开启事务
1..判断关键数据
courseBaseId
companyid
2.判断业务数据
判断课程是否存在
判断是否是同一家机构
判断课程是否已经删除
判断课程的审核状态
未提交
审核未通过
只有这些状态才可以被删除
3.删除课程基础信息(根据id删除)
修改数据库的数据status
课程基础信息提交
传入传出参数:
数据模型:courseBase、courseMarket
业务分析:
0.不需要开启事务
1.判断关键数据
companyId courseId
2.判断业务数据
课程基础信息表
是否同一家机构
是否存在课程信息
是否已经被删除
审核状态只能为未提交或者审核未通过才能进行提交审核
3.修改数据判断结果,将审核状态改为已提交
课程计划信息查询
传入传出参数:
数据模型:courseBase、courseTeachplan
业务分析:
0.是否开启事务
不开-查询
1.判断关键数据
courseId companyId
2.判断业务数据
PS:课程计划是所属于课程基础信息
课程基础信息
判断是否存在
判断是否删除
判断是否是同一家教学机构
3.根据courseBaseId查询一门课程下的所有课程计划-List
4.通过java中的递归来生成课程计划的树形结构
5.转为dto数据并返回
课程计划信息新增和修改
传入传出参数:
数据模型:
业务分析:
修改
0.开启事务
1.判断关键数据
课程id
课程计划名称
父级id
是否免费
教学机构id
2.判断业务数据
课程基础信息
判断是否存在
判断是否是同一家教学机构
判断是否删除
判断审核状态:未提交、审核未通过
课程计划
判断是否存在
判断等级:教学机构只能操作二级和三级课程计划
3.将dto转为po并保存
为了数据的安全性,只让前端修改字段:
课程计划名称、是否免费、开始时间、结束时间、mediatype
4.将数据库最新的数据返回给前端(dto)
添加:
课程计划的添加
业务分析:
1.判断关键数据
companyId pname(课程计划的名称) courseId
parentId(需要后端的业务逻辑维护即可-此值必须要赋值)—根据父级数据来赋值
grade(需要后端的业务逻辑维护即可-此值必须要赋值)—根据父级数据来赋值
2.判断业务数据
课程基础信息
判断是否存在
判断是否是同一家教学机构
判断是否删除
判断课程审核状态
未提交和审核未通过才可以编辑课程计划
3.获得添加课程计划的父级数据
添加课程计划的parentid = 父级.id
添加课程计划的grade = 父级.grade+1
添加课程计划的orderby = 父级的子集数据个数+1 : select count() from teachplan parentid = ?
4.保存课程计划信息
5.返回数据库最新数据dto
添加课程计划获得父级数据方法
业务分析:
1.判断获得二级或三级课程计划的父级标识:
判断parentid是否为空
如果为空:应获得二级课程计划的父级数据
如果不为空:应获得三级课程计划的父级数据
2.获得父级数据
获得二级课程计划父级数据
判断父级数据是否存在
如果不存在—在后端创建出数据内容(一级课程计划)
如果存在—直接返回
获得三级课程计划父级数据
判断父级数据是否存在
如果不存在—抛出异常
如果存在—直接返回
课程计划信息删除
传入传出参数:
数据模型:
courseTeachplan、courseBase、teachPlanMedia
业务分析:
0.开启事务
1.判断关键
teachplanId companyId
判断课程基本信息是否存在
判断公司 Id是否和课程中的公司Id一致
2.判断业务数据
课程基础信息
判断是否存在、判断是否是同一家教学机构、判断是否删除、判断审核状态(未提交、审核未通过)
课程计划
判断删除的课程计划是几级数据
二级
判断是否存在子级数据,如果有不让删除
三级
如果是录播课程
判断课程计划是否有关联数据(查询TeachplanMedia表数据)
3.根据Id删除课程计划
课程教师信息查询
传入参数;courseBaseID
传出参数:List(VO)
数据模型:
course_teach
业务分析:
1.不开启事务
2.判断关键数据
courseBaseId,companyID
3.判断业务数据
(1)课程信息是否存在
(2)教师关联的课程信息是否存在
(3)教师数据是否存在
4.查询信息
5.以DTO的形式封装响应给前端
课程教师信息新增和修改
传入参数:ourseId、照片(photograph)、岗位(postion)、教师姓名(teacherName)
传出参数:List(VO)
数据模型:course_teach
业务分析:
1.开启事务
2.判断关键字
前端传过来必填的数据—->courseId、photograph、岗位、教师姓名
3.判断业务数据
(1)判断课程信息是否存在
(2)课程信息是否删除
(3)课程状态:未提交、未审核通过
(4)判断教师信息是否存在—若存在,则修改;不存在,则新增
4.以DTO的形式封装响应给前端
课程教师信息删除
传入参数:
courseId(课程id),courseTeacherId(课程教师id)
数据模型:course_teach
业务分析:
1.开启事务2.判断关键字课程ID(courseBaseId)、(课程教师id)CourseTeacherId3.判断业务数据(1)判断课程信息是否存在(teacher_name,course_id)(2)判断课程教师信息是否存在(物理删),存在就删除,不在抛出异常(3)课程状态(审核已通过、已发布、已提交)以上状态不能操作4.删除数据5.接收一个Boolean返回给前端
文件上传

流程:
1.前端想上传文件,需要请求媒资服务2.媒资服务结合阿里云的相关api请求阿里云服务3.阿里云返回相关数据(视频id 上传地址 上传凭证),媒资服务封装返回数据给前端4.前端根据返回数据进行使用阿里云执行分片文件上传5.若在上传过程中,上凭证失效(阿里云默认50分钟)上传失败。阿里云的前端js判断令牌失效,则调用媒资服务中刷新令牌的接口(传入视频id ),调用媒资服务返回最新的令牌
细节:
1.获得上传凭证
传入:视频文件名、视频标题
传出:视频id、视频上传凭证、视频上传地址
业务分析:
因为媒资上传只需要和阿里云服务进行数据交换,没有业务操作,只需在controller层进行编写即可
:::tips
1.加载nacos配置中心的数据
2.获得上传文件凭证:
1.初始化客户端
2.创建请求对象并获得相应对象
3.解析响应的数据
因为我们是与第三方的服务利用网络进行数据交互,那么因为网络问题会很容易出现错误,我们需要将上上述步骤进行try/catch处理
异常信息处理:
1、只记录错误的信息
2、将错误的信息隐藏并返回友好提示
:::
2.刷新上传凭证
传入:视频id
传出:上传凭证
:::tips
1.加载nacos配置中心的数据
2.获得上传文件凭证:
1.初始化客户端
2.创建请求对象并获得相应对象
3.解析响应的数据
因为我们是与第三方的服务利用网络进行数据交互,那么因为网络问题会很容易出现错误,我们需要将上上述步骤进行try/catch处理
异常信息处理:
1、只记录错误的信息
2、将错误的信息隐藏并返回友好提示
:::
3.媒资文件保存
传入:文件标识、文件名称、文件类型
传出:mediaDTO
:::info
- 是否需要开启事务(开启)
- 判断关键数据
- companyid filename fileid(videoId)
- 给信息数据赋值默认值:修改审核状态为未审核
- auditStatus:未审核
保存信息
a.信息存入数据库<br /> b.视频播放地址存入redis:设置过期时间50分钟(aliyun默认一小时),调用时判断redis中是否存在,存在则直接返回,不存在则调用生成视频url工具类AliyunVODUtil
-
课程发布
生产方
生产方系统交互图:
步骤描述:
1.前端对某审核通过的课程执行课程发布操作
2.查询课程基本信息、课程营销、课程计划、教师信息并保存到 课程发布中。
3.远程调用系统管理查询课程分类信息
4.保存课程发布数据和课程发布消息数据
5.消息发送方异步通知课程发布操作
6.消息发送成功后,将课程状态和消息发送状态进行修改
7.如果消息发送失败,定时器来查询消息状态为未发送的数据,并再次发送消息
传入传出参数:
数据模型:
概念图:
这里主要流程有三大块:业务层的数据操作、MQ的回调函数、定时任务
●前端发送课程发布的请求,控制层接收到请求后调用业务层操作课程发布表及课程发布信息表
●发送到交换机
○发送成功,交换机返回ack,业务层接收到ack后需要修改课程审核状态及课程发布信息表状态
○发送失败,交换机返回nack,不进行数据修改
流程:
1.前端发送课程发布请求2.调用service两个方法:操作数据库、修改数据库状态(1)操作数据库:将课程发布数据和课程发布消息数据分别保存在本地数据库的course_pub和course_pub_msg表中(1.1)保存数据后,调用相关方法发送消息给交换机,生产者每次给交换机发送消息时,这里会启用confirm callback回调函数===》消息发送成功返回ack,失败返回nack(1.2)若接收到ack后则调用数据库修改状态数据,若为nack则记录日志,人工处理。(2)修改数据库状态:课程基础信息表(course_base)、课程发布消息表(course_pub_msg)中修改课程已发布、消息已发送。3.生产者给交换机发送消息后,会由交换机再发消息给队列,在此过程中只有失败时会调用return callback回调机制===》记录错误信息,人工介入处理。4.定时器任务:实时查询课程发布消息数据状态,若有未发送的消息则会被重新发送。===》在confirm callback回调函数===》失败返回nack(消息未发送成功)===》人工处理后,消息此时仍为未发送状态===》定时器自动重新发送。
业务分析:
0.是否开启事务--开启1.判断关键数据courseId companyId2.判断业务数据课程基础信息判断是否存在判断是否是同一家机构判断是否删除判断审核状态:教学机构课程预览--未提交、审核未通过课程营销判断是否存在:根据courseid课程计划获得课程计划:根据courseId和companyId(树形结构)课程教师判断教师信息是否存在:一定要确保课程最少有一个教师信息课程分类数据并完善Coursepub数据调用system服务获得课程分类的名称3.保存数据的业务数据和消息数据业务数据:CoursePub数据进行保存消息数据:CoursePubMsg数据进行保存4.发送消息给MQ
修改本地数据的状态值:
0.判断消息是否已经修改1.修改课程发布消息表数据未发送-->已发送2.修改课程基础信息数据课程审核状态:已发布
消费方
消费方系统交互图:
步骤描述:
1.课程发布数据执行后,MQ将消息传递给消费方
2.消费方接受消息查看课程发布数据是否已经发布
3.消费方获得消息在课程发布状态为1时,会生成课程详情页
4.生成详情页后,将页面存放到cdn服务上
5.修改课程发布数据的状态is_pub=0
6.如果消费消息一致失败,经消息发送到mq制定的exchange中
概念图:
流程:
前情提要:生产方已经将消息放入到队列中。1.消费方需要对已经存储在队列中的消息进行消费行为,即执行上图commit到listener步骤。2.若消息接收成功,执行service步骤,这里主要业务为:(1)生成课程发布页面并上传到七牛云(2)修改课程发布状态数据若消息接收失败,则重试消息接收,这里已经在mq配置了相关的策略(消息重试策略、失败策略--》详见环境配置)。3.在执行service步骤的主要业务中:(1)需要修改课程发布状态数据-->这里为了判断消息的幂等性(为了解决因网络阻塞等原因导致消息未处理完时,消费方执行消失重试导致数据重复不一致)。(2)生成的课程发布页面的页面名称处理-->将课程发布数据的id设为对应页面的名称。
业务分析:
业务分析:是否开启事务--开启(涉及增删改操作)0.判断消息幂等性数据标识:CoursePub中的isPub(0:发布,1:未发布)获取课程发布状态的修改次数判断课程发布的状态是否修改,如果修改说明消费方已经处理完毕,无需操作1.生成课程详情页面1.1获得coursePub数据(这里只需要查询即可),构建数据模型1.2获得页面模板(Freemarker)1.3生成课程详情页面html内容2.将生成后的html页面上传到cdn服务上3.修改课程发布的状态数据将CoursePub中的isPub改为:0PS:由于项目环境使用的是SpringBoot对rabbitmq的封装,如果需要消息重试:抛出异常重试条件:1.不稳定因素引起的错误,需要进行重试2.如果是数据上的问题或其他框架的问题错误,只做错误的记录,不要重试
运营平台流程
所涉及到业务模块
1.内容管理
2.媒资管理
所涉及到业务功能
1.内容管理
课程审核(zyq)<br />课程基础信息查询(天乐)
2.媒资管理
媒资信息管理(澳前)添加、修改、删除、查询媒资审核(zyq)
3.课程发布
课程预览(鑫龙)
功能实现
课程基础信息查询
传入传出参数:
数据模式:courseBase、courseMarket
业务分析:
0.不需要开启事务
1.判断关键数据
分页数据
查询条件
2.构建mp分页对象
3.构建查询条件对象LambdaQueryWrapper
4.查询数据
5.获得数据并封装返回结果
6.封装PageVo数据
课程审核
传入传出参数:
数据模型:courseBase
业务分析:
0.开启事务
1.判断关键数据
auditMind auditStatus courseid
2.判断业务数据
课程基础信息
判断是否存在
判断是否删除
判断审核状态(必须为:已提交)
审核状态
运营平台只能给课程审核状态复制为:审核通过或者审核未通
3.修改课程审核信息
auditMind auditStatus auditNum(每次+1)
媒资信息查询
进入媒资管理系统后默认执行无参分页查询,也可以根据条件查询,每个机构只能看到自己的文件
传入:分页查询(PageRequestParams)、条件查询(QueryMediaMode)
传出:pageVO
请求头:机构令牌
数据模式:media
:::tips
业务分析:
1.判断关键数据:机构id
2.判断业务数据:是否属于同一个机构
3.查询 :根据传入的条件进行查询
4.返回pageVo
:::
媒资信息预览
点击预览视频,可以在线预览媒资信息
传入:MidiaId
传出:媒资的url地址
请求头:机构令牌
数据模式:media
:::tips
- 是否开启事务(否)
- 判断关键信息
- mediaId、companyId
- 判断业务数据
- 媒资信息是否存在
- 媒资信息是否是视频、文档、作业
- 获得媒资资源的路径地址url(从redis中获得)
-
媒资信息删除
点击删除按钮,可以删除媒资信息,因为会涉及到数据恢复,所以采用逻辑删除
传入:MediaId
请求头:机构令牌
数据模式:media、TeachplanMedia :::tips 是否开启事务(是)
- 判断关键信息
- mediaId、companyId
- 判断业务数据
- 媒资信息是否存在
- 媒资信息是否绑定课程计划
- 绑定媒资和课程计划数据:content(发送feign)
teachplan_media
- 绑定媒资和课程计划数据:content(发送feign)
- 删除媒资信息(先删除数据库后删除阿里云,要保证数据一致性,因为本地可以操作事务有回滚,远端没有提供,所以远端需要往下放) :::
媒资审核
传入传出参数:
数据模型:courseMedia
业务分析:
0.开启事务
1.判断关键数据
审核状态 审核意见 媒资ID
2.判断媒资信息
判断是否存在
判断是否是未审核状态// 判断运营的审核状态是否合法
3.修改媒资信息的审核状态
课程预览
课程预览交互流程如下:

课程预览:预览不需要生成文件—为了使发布数据正确
三方参与:浏览器、内容管理、系统管理
流程:
1.前端对某审核通过的课程执行课程预览操作(传入课程ID、请求头中有令牌获取公司id,返回 SpringMVC的ModelAndView对象)2.根据课程ID查询课程基本信息、课程营销、课程计划、教师信息,判断并封装课程发布数据(coursePub---主要与课程相关的保存为字段,其他保存为json)。3.内容管理远程调用系统管理根据大小分类的id获取分类名称并返回4.保存课程发布数据(0.开启事务 1.判断课程存在、未删除、同一家机构、课程状态不为已发布 2.保存为coursePub,构建map数据返回前端)。注:每次点击预览会形成课程发布数据,若课程发布数据存在,则修改最新数据5.获得页面的数据模型(课程发布、课程营销、课程计划、教师信息、课程分类等)与页面模版6.将数据模型与页面模版生成的静态页面返回给前端(返回 SpringMVC的ModelAndView对象,保证双视图解析器并存)
传入参数:课程id、请求头中的公司id
传出参数:MODLE+VIEW
数据模型:
其实就是课程发布表结构
在上图中的表结构中,主要字段为:
1.课程基本信息描述:course_id,company_id,name,users,mt,st 等
2.课程营销信息描述:market (json 数据)
3.课程计划信息描述:teachplan(课程计划树形结构 json 数据)
4.教师信息描述:teachers( json 数据)
业务分析:
1.开启事务2.判断关键字课程ID ,机构ID3.判断业务数据(1)课程基本信息是否存在是否同一家机构是否删除审核状态除了已发布状态(2)判断课程营销信息是否存在(3)判断课程计划信息是否存在查询条件:courseid、companyid(4)判断课程分类信息是否存在(通过Fegin远程调用系统服务进行查询)从系统管理服务中获得课程分类数据查询条件:courseCategoryId(mt、st)(5)判断教师信息是否存在查询条件:courseId4.操作课程发布信息表1.判断课程发布信息是否存在不存在,添加课程发布信息存在,更新(重新赋值最新课程发布ID进行数据修改)5.构建CoursePub数据courseBase teachplan courseMarket courseTeacher6.组装数据模型MODEL(需要JSON格式转换成Object)课程发布、课程营销、课程计划、教师信息、课程分类7.将数据模型与页面模版生成的静态页面返回给前端(返回 SpringMVC的ModelAndView对象,保证双视图解析器并存)
学员流程
所涉及到业务模块
1.课程搜索(zy)
2.课程选课(宵雨)
所涉及到业务功能
1.课程搜索
es课程搜索(zy)
功能实现
ES课程搜索
接口:
传入:分页查询(PageRequestParams)、条件查询(QueryMediaMode)
传出:pageVO
数据模型:Course_Pub 课程发布表
业务分析:
课程搜索:三部分(课程发布、将课程发布的数据同步到索引库、搜索索引库)
数据同步:
:::tips
1.课程管理服务将course_pub表数据写到MySQL数据库
2.使用Logstash将MySQL数据库Course_pub中已经发布的课程(is_pub=0)写到ES的索引库,每分钟执行一次
:::

搜索:
课程搜索主要涉及三个服务,浏览器前端、课程搜索服务、ES服务
1.浏览器向课程搜索服务发送请求,携带参数
2.课程搜索服务根据所传的参数进行封装,作为ES检索的条件进行联合查询(精准,过滤)
3.搜索请求向ES发送请求返回检索结果,查询高亮信息,进行组装数据为课程信息列表返回给前端
业务流程:
:::info
- 是否开启事务(否)
- 判断关键数据
- 分页条件 -> 不存在给默认值
- 创建出SearchRequest对象
- SearchRequest 设置索引库的名称
- 创建SearchSourceBuilder,设置查询条件
- 分页
- 查询方式
- 关键字 -> must()
- (课程等级,课程大和小分类)-> filter()
- 高亮(关键字)
- 排序
- (最新,热评,推荐)
- 获得响应数据SearchResponse
- 通过Client方法Search方法来获得Response
解析结果数据并封装PageVO中
获得大Hits<br /> 从大Hits获得总条数<br /> 从大Hits获得小Htis数组<br /> 遍历小Hits<br /> 从小Hist中获得<br /> 文档id<br /> 文档的源数据_source<br /> 文档的高亮
用户登录

一共有五个参与方:
客户端:用户登录成功后,我们会将登录令牌存储用户客户端的 Cookie 中。
前端:学成门户对应普通用户,后台管理工程对应平台运营,前台管理工程对应教育机构
网关:校验用户令牌
UAA认证服务:认证服务向用户中心查询用户
后端:通过向教学管理中心获取机构id,通过网关校验用户令牌成功后放行执行业务操作
流程描述:
(1)用户在学成在线登录,采取OAuth2.0 密码模式请求认证服务(UAA)
(2)认证服务(UAA)验证用户,并获取用户权限信息。
(3)认证服务(UAA)获取接入方权限信息,并验证接入方是否合法
(4)合法,生成令牌返回给接入方,其中包含了用户权限及接入方权限。
(5)接入方携带令牌对学成在线微服务资源进行访问。
(6)API网关对令牌解析、并验证接入方的权限是否能够访问本次请求的微服务。
(7)网关校验通过后,就可以访问学成在线后端资源服务。
4种角色
客户端:学成在线
资源拥有者:用户
认证服务器:认证服务(存储商户信息)
资源服务器:用户中心(存储用户资源信息)
UAA认证体系结构:
UAA(统一认证服务):承载了OAuth2.0接入方认证、登入用户的认证、授权以及生成令牌的职责,并连接“统一账号服务”,完成实际的用户认证、授权功能。
统一账号服务:提供登录账号、密码、角色、权限、资源等系统级信息的管理,不包含用户业务信息。
API网关:实现接入客户端权限拦截、令牌解析并转发当前登录用户信息(jsonToken)给业务微服务,
学生选课
订单支付前业务流程图

流程:
- 学员通过UAA认证系统登录成功
- 进入课程详情页面时需要调用以下两个后端服务
- 课程搜索服务
- 从索引库中查询课程内容,查询课程发布信息
- 学习中心微服务
- 从数据库中查询记录,查询学员课程学习记录
3.学员购买课程进入课程订单支付页面,调用订单微服务
- 创建订单需要远程调用课程搜索服务查询课程信息,判断课程是否存在
- 课程收费的话会创建订单新增或修改订单表
- 调用第三方支付系统创建订单支付表,保存订单支付记录
1. 查询学习记录

- 用户进入课程详情页,前端向学习中心查询当前用户课程记录
- 学习中心查询课程记录将结果返回给前端
- 前端根据返回的数据判断是否有该课程记录,来决定是否展示购买入口
接口
传入传出参数:
数据模型:
course_record(选课记录表)
- 规范字段描述:id,创建时间
- 用户信息描述:用户id, 用户名
- 课程信息描述:机构id,课程id,课程发布id,课程名称等
- 学习记录信息描述:学习计划章节id,学习计划章节名称等
- 是否支付标识 :paid
- 前提:课程必须为收费
- 判断依据:
- paid=1 课程已经支付
- paid=0 课程未支付
- 判断依据:
- 前提:课程必须为收费
业务分析:
- 判断关键数据
- 根据条件查询用户的学习记录
- 返回学习记录数据
- 如果有数据返回
- 如果没有返回空数据
2. 查询课程发布索引数据
接口:
传入传出参数
业务分析
- 判断关键数据 coursePubId 课程发布Id
- 创建es的请求对象
- 根据查询对象获得响应对象
- 从响应对象中获得课程发布索引数据
- 对索引数据进行封装并返回
3.学员选课-课程下单
数据模型
- 规范字段描述:id,创建、修改时间
- 用户信息描述:用户id, 用户名
- 课程信息描述:机构id,课程id,课程名称等
- 订单信息描述:订单号,定价,交易价,课程有效性,起始时间没结束时间,交易状态等
接口定义

0.是否开启事务(开启)1.判断关键数据● coursePubId、username2.判断业务数据● 课程发布数据-远程调用课程搜索服务○ 判断是否存在○ 判断是否收费(CoursePub表中的change)■ 只有收费课程需要创建订单■ 免费的课程则抛出异常3.构建用户订单数据○ 判断订单数据是否存在:CoursePubId(课程id)、username(用户名)■ 如果没有● 创建订单数据:订单状态为初始态■ 如果有● 判断订单状态:必须为初始态● 修改订单价格:修改为最新的价格数据CoursePub表中的price4.将结果数据转为DTO并返回
4.学员选课-订单支付

- 当用户在支付页面中,选择某支付方式并确认时,前端向订单服务请求创建支付接口
- 订单服务 通过订单id获取要支付的订单信息,并将订单信息组装为第三方支付的下单请求数据,调用第三方支付服务下单。
- 订单服务 接收第三方支付返回的支付二维码url,并将此url返回给前端
- 前端将url生成为二维码,展示给用户
订单支付数据模型
规范字段描述:id,创建时间
用户信息描述:用户账号
订单信息描述:订单号,机构id
订单支付信息:支付状态,支付方式,交易状态,支付系统订单号,支付方式,支付时间等
支付前的字段:用户账号,机构id,订单号,交易状态(未支付),订单金额(可以不加),创建时间(mp自动赋值)
支付后的字段:支付系统订单号,支付方式,支付时间,支付响应
接口定义

业务分析
PS:由于前端对于支付的链接地址返回内容有要求
不管成功与失败必须返回PayCodeUrlResult
service正常业务操作,如果遇到业务操作的异常,还是直接抛出
controller需要进行接受,并转化为PayCodeUrlResult,异常统一抛出
业务分析:0.是否开启事务(开启)1.判断关键数据orderNo username2.判断业务数据订单数据:orderNo username判断是否存在判断订单的状态:必须为初始态(未支付)3.创建订单支付数据判断订单支付数据是否存在不存在,创建订单支付(默认状态:0 PayCodeUrlResult.NOT_PAY)存在,不需要做操作根据表中的字段来赋值支付前的字段:user_name companyid orderid status(未支付) total_amount(可以不加) create_date(mp自动赋值)支付后的字段:pay_number pay_method pay_date pay_response4.和第三方支付系统交互获得支付的链接地址
5.学员选课-支付结果通知

业务流程:
- 当前业务是由第三方支付发起调用,发送支付成功通知
- 对业务进行操作
- 订单服务:
- 解析支付平台结果数据
- 更新本地订单状态和订单支付状态
- 远程调用创建学习记录
- 学习中心:
- 添加课程学习记录:默认第一章第一节
- 返回结果给第三方平台
一、订单服务
接口
无请求方式 /order/order-pay/wx-pay/notify-result
@RequestMapping(“order-pay/wx-pay/notify-result”)
业务分析
业务分析:1.判断关键数据并解析判断第三方支付是否成功:return_code 和 result_code 必须为SUCCESS2.判断消息的幂等性(第三方支付平台会有重复通知的消息)数据库的记录表:Orders(订单存在和订单支付状态:初始态-未支付)orderNo订单号,Status交易状态3.判断业务数据订单数据(已经在第二步操作完毕)PS:wx文档中强调--用户所支付的金额要和本地的订单金额一致订单支付数据判断订单支付数据是否存在和支付状态:未支付orderId,status4.操作本地数据库表订单数据修改订单的状态:已支付订单支付数据pay_number--第三方支付的订单号pay_method--支付方式(wx)pay_date--用户在第三方支付平台支付的金额的时间金额订单总金额 total_amount 订单应支付金额receipt_amount 订单实际支付金额 buyer_pay_amount交易状态 Statuspay_response--第三方支付平台通知的所有数据结果内容(xml)5.调用学习中心创建用户对于收费课程的学习记录数据
二、学习中心
订单支付成功后,需要在学习中心服务添加用户的学习记录
接口
post /learning/l/course-record/paid/{username}/{coursePubId}
传入参数
| username | String | 购课人的名称 |
|---|---|---|
| coursePubId | Long | 课程发布id |
业务分析
1.判断关键数据username coursePubId2.判断业务数据课程发布信息判断是否存在判断课程是否是收费的课程计划数据获得(Json转换)从课程发布信息中3.保存用户的学习记录构建前,查询并判断学习记录是否存在由于是先执行订单服务修改订单状态,在没有问题的情况下再创建学习记录不存在学习记录:创建学习记录默认章节为:第一章第一小节coursePub中获取课程计划teachplanJsonString通过JsonUtil转为DTO要给paid赋值为已经支付:1存在学习记录--收费课程支付后,要重置数据(用户体验不好,方便后期操作,但是可以解决大部分的问题)4.将新增的数据查询并转化为dto并返回PS:如果出现业务上出操作数据问题,本业务层直接抛出异常,无需返回RestResponse规范接口数据原因:本次的操作事务都是由Seata环境来控制,如果抛出异常,会是的整个的事务进行回滚操作
