diff --git a/src/api/modules/course.js b/src/api/modules/course.js index 197ee0e2..6e5f9dae 100644 --- a/src/api/modules/course.js +++ b/src/api/modules/course.js @@ -1,494 +1,500 @@ -/** - * 课程的操作,课程的添加,修改,列表查询,课程的审核发布等操作。 - * 针对于管理员,教师的功能 - * - **/ -import ajax from '@/utils/xajax.js' - -/** - * 保存课程基本信息,新增和更新都是此方式 - * @param {Object} data - *{ - course:{ - 课程的基本信息,具体字段内容另外提供 - name:课程名称 - type:课程类型,10微课,21在线课(直播);20:在线课( 录播);30:面授课;40:混合式, - summary:摘人 - overview: 课程简介 - coverImg:封面图 - sysType:系统分类,只存储最后一级, - resOwner1:资源归属一级的id - resOwner2:资源归属二级的id - resOwner3:资源归属三级的id - forUsers: 目标人群 - forScene:应用场景 - openObject: 开放权限 - value:课程价值 - tags:标签,多个使用-分隔 - keywords:关键字 - device: 1:PC端可见;2:移动端可见;3:多端可见 - status: 1:未提交(草稿);2:已提交; - published:true/false 是否发布 - enabled:true/false 启用、停用 - isTop: true/false 是否置顶 - source:整数,课程来源,1:内部;2;外部 - - }, - teachers:[ - { - teacherId:教师的id, - teacherName:教师的名称 - } - ] - } - */ -const saveBase = function(data) { - return ajax.postJson('/xboe/m/course/manage/save', data); -} - - - -/** - * 仅仅是保存课程信息,不包括教师信息 - * @param {Object} data - */ -const saveOnlyCourse = function(data) { - return ajax.postJson('/xboe/m/course/manage/save-only-course', data); -} - -/**提交课程*/ -const submitCourse = function(data) { - return ajax.postJson('/xboe/m/course/manage/submit', data); -} - -/**撤销已提交审核的课程*/ -const revokeSubmit = function(id) { - return ajax.post('/xboe/m/course/manage/revoke', {id}); -} - -/** - * 复制课程 - * @param {Object} - */ -const copyCourse = function(data) { - return ajax.post('/xboe/m/course/manage/copy',data); -} -/* -查询课程是否有重复名称 - */ -const isRedoName=function(){ - return ajax.get('/xboe/m/course/manage/isRedoName'); -} -/* -查询当前添加课程是否已有 -courseName 要添加的课程姓名 - */ -const isCourseName=function(courseName,courseId){ - return ajax.get(`/xboe/m/course/manage/isCourseName?courseName=${courseName}&courseId=${courseId}`); -} -/** - * 查询修改日志,列表,不分页 - * @param {Object} params - * { - num:数量,可以不传,默认是10条,最新的10条 - courseId:课程的id - name: 修改人 - } - */ -const findUpdateLogs = function(params) { - return ajax.post('/xboe/m/course/manage/upldate-logs',params); -} - -/** - * 根据id获取修改的详细信息 - * @param {Object} id - */ -const getUpdateLog = function(id) { - return ajax.get('/xboe/m/course/manage/upldate-log-detail?id='+id); -} - -/** - * 保存课程的一条学习内容信息,新增和更新都是此方式 - * @param {Object} data - * { - content:内容 { - courseId,csectionId章节id(微课为空),sortIndex排序顺序(微课为空),contentType 内容类型(图文41,连接52,作业60,考试61,评估62) - contentName,contentRefId无关联内容时为空(此字段内容后台会控制),content具体的内容 - } - - homework:作业信息 单个对象{ - courseId,contentId上面对象的id(后台会控制),name,content,file,deadTime, - submitMode:1表提交附件,2直接填写,3表两者都可以 - } - exam:考试信息 单个对象 - { - courseId,contentId上面对象的id(后台会控制),testName,testDuration考试时长, - paperType试卷类型 1自定义,2使用已有试卷 - paperId试题的id,使用已有试卷时保存选择试卷的id - showAnalysis是否显示解析,showAnswer否显示答案,times尝试次数 - arrange试题排序 0表不乱序,1试题乱序,2选项乱序,3全部乱序 - scoringType评分方式 1最高一次,2最后一次 - passLine及格线整数 - randomMode是否随机模式true/false - paperContent试卷的内容,json存储的对象{items:[]} - - } - assess:评估信息,list 多条记录. - [ - { courseId,contentId,assessId评估id(一期为空),question问题,qType问题类型} - ] - } - */ -const saveContent = function(data) { - return ajax.postJson('/xboe/m/course/content/save', data); -} - - -/** - * 更新课程内容的顺序 - * @param {String} cid //课程的id - * @param {Array} items - * [ - * { - * id:章的id - * index:整数,顺序值 - * items:[ - * {id:内容的id,index:顺序值} - * ] - * } - * ] - * @returns - */ -const updateContentOrders = function(cid,items) { - return ajax.postJson('/xboe/m/course/content/update-orders/'+cid, items); -} - -/** - * 课程的详细信息 - * @param {String} id - */ -const detail = function(id) { - return ajax.get('/xboe/m/course/manage/detail?id=' + id); -} -const getDictIds = function(pid,type) { - return ajax.get(`/xboe/m/course/manage/getDictIds?pid=${pid}&type=${type}`); -} -/** - * 更新内容的名称 - * @param {Object} data - * { - id:'', - name:'' - } - */ -const updateContentName = function(data) { - return ajax.post('/xboe/m/course/content/update-name', data); -} - -/** - * 删除一条学习内容 - * @param {Object} data - * { - id: 内容的id, - ctype:对应内容的类型contentType - erasable:是否物理删除,此值是课程信息中系统带过来的字段,直接使用它就可以了 - } - */ -const delContent = function(data) { - return ajax.post('/xboe/m/course/content/delete', data); -} - -/** - * 保存课程的章信息,新增和修改保存都是一个 - * @param {Object} data - * courseId:课程的id - * name:章节名称 - description:章节说明 - parentId: 上级id。如果没有可以填“-1”字符串 - orderIndex:显示顺序,顺序索引,整数 - */ -const saveSection = function(data) { - return ajax.post('/xboe/m/course/content/save-section', data); -} - -/** - * 删除章节目录,注意只有目录下没有学习内容时才允许删除 - * @param {Object} data - */ -const delSection = function(id) { - return ajax.post('/xboe/m/course/content/delete-section?id=' + id); -} - -/** - * 根据课程学习内容的id。获取作业信息,只有学习内容是作业时才会有信息 - * @param {Object} ccid - */ -const getHomework = function(ccid) { - return ajax.post('/xboe/m/course/content/homework?ccid=' + ccid); -} - -/** - * 根据课程学习内容的id。获取考试信息,只有学习内容是考试时才会有信息 - * @param {Object} ccid - */ -const getExam = function(ccid) { - return ajax.post('/xboe/m/course/content/exam?ccid=' + ccid); -} - -/** - * 根据课程学习内容的id。获取评估信息,评估内容可以获取 - * @param {Object} ccid - */ -const getAssess = function(ccid) { - return ajax.post('/xboe/m/course/content/assess?ccid=' + ccid); -} - -/** - * 管理列表查询 - * @param {Object} query - * pageIndex:第几页 - * pageSize:每页多少条 - * resOwner1:资源归属一级的id - resOwner2:资源归属二级的id - resOwner3:资源归属三级的id - types:授课方式,多个使用 - 分隔 - scenes:应用场景,多个使用 - 分隔 - publish:true/false 是否发布,空值或不传就是全部 - aid:创建人 aid - sysCreateUser: 创建人姓名 - keyword:查询关键词 - sysTypes:系统的分类,多级使用 - 分隔,注一期功能是分类的最后一级值,不支持多个的查询 - orderField:排序字段 id s - orderAsc:true/false 是否是正序,从小到大 - status:状态,多个使用 - 分隔 1代表待审核 5代表已审核 1 未提交 2 已提交 5 审核完成 - type:课程类型,10微课,21在线课(直播);20:在线课( 录播);30:面授课;40:混合式, - name 课程名称 - - */ -const pageList = function(query) { - return ajax.post('/xboe/m/course/manage/pagelist', query); -} - - -/**计算待审核课程*/ -const countWaitAudit = function() { - return ajax.get('/xboe/m/course/manage/wait-audit-num'); -} - -/** - * [已用courseAudit中的hrbpAuditList替换] - * 当前用户需要审核的课程列表 - * @param {Object} query 同pageList - */ -const auditList = function(query) { - return ajax.post('/xboe/m/course/manage/audit-pagelist', query); -} - - -/** - * 【已移到courseAudit中】 - * 教师需要审核的课程列表 - */ -const teacherAuditList = function(query) { - return ajax.post('/xboe/m/course/audit/teacher-course', query); -} - -/** - * 指定审核人,转审核人 - * 点击“转审” 弹出教师查询窗口,查询教师,填写备注,提交,调用此接口 - * @param {Object} data - * {courseId:课程id,teacherId:指定的审核人教师的id,teacherName:教师名称,remark:备注} - */ -const auditAppoint = function(data) { - return ajax.post('/xboe/m/course/audit/appoint', data); -} - -/** - * 获取审核信息,上面教师点击审核课程时,用于查询,上面“转审”时,用户填写的备注信息 - * @param {courseId:'课程id',teacherId:'可以不填写,系统会查询当前人'} data - */ -const getAuditInfo = function(data) { - return ajax.post('/xboe/m/course/audit/infos', data); -} - - -/** - * 管理员的课程审核处理 - * @param {Object} query {id:课程id,title:课程的名称, Boolean pass 是否通过,remark 备注} - */ -const audit = function(data) { - return ajax.post('/xboe/m/course/manage/audit', data); -} - -/** - * 审核记录列表,分页查询 - */ -const auditPageRecords = function(data) { - return ajax.post('/xboe/m/course/audit/page-records', data); -} - -/** - * 审核记录列表,要卖课程id,查询出审核列记录信息 - * { courseId:必须} - */ -const auditCourseRecords = function(data) { - return ajax.post('/xboe/m/course/audit/course-records',data); -} - -/** - * 管理员的课程发布,当前已经不再使用了 - * @param {Object} query {ids:课程id,多个使用逗号分隔,title:课程的名称, Boolean pass 是否发布} - */ -const publish = function(data) { - return ajax.post('/xboe/m/course/manage/publish', data); -} - -const auditAndPublish=function(data) { - return ajax.post('/xboe/m/course/manage/audit-publish', data); -} - -/** - * 设置top - * @param {Object} query {ids:课程id,多个使用逗号分隔,title:课程的名称,Boolean top 是否置顶} - */ -const setTop = function(data) { - return ajax.post('/xboe/m/course/manage/top', data); -} - -/** - * 管理员的设置启用停用 - * @param {Object} query {ids:课程id,多个使用逗号分隔,title:课程的名称, Boolean enabled 是否启用} - */ -const setEnabled = function(data) { - return ajax.post('/xboe/m/course/manage/enabled', data); -} - -/** - * 管理员的删除课程 - * erasable 此值是课程信息带过来的,直接传就可以 - * @param {Object} query {id:课程id,多个使用逗号分隔,Boolean erasable 是否物理删除,title:课程的名称, remark 备注} - */ -const del = function(data) { - return ajax.post('/xboe/m/course/manage/delete', data); -} -/* -详情 - */ -const detailFew=function(id){ - return ajax.get('/xboe/m/course/portal/detail-few?id=' + id); -} - -/* -直接审核,教师提交审核 - */ -const sumbits=function(data){ - return ajax.post('/xboe/m/course/manage/sumbits',data); -} -/* -教师授课记录 - */ -const teacherCourse=function(teacherId){ - return ajax.get('/xboe/m/course/manage/teacher-course?teacherId='+teacherId); -} -/* -教师授课记录导出 -@param teacherId 教师id - */ -const exportTeacherCourse=function(teacherId){ - return ajax.post('/xboe/m/course/manage/export-teacher-course?teacherId='+teacherId) -} -/* -*待审核课程记录导出 - * resOwner1:资源归属一级的id - resOwner2:资源归属二级的id - resOwner3:资源归属三级的id - types:授课方式,多个使用 - 分隔 - scenes:应用场景,多个使用 - 分隔 - publish:true/false 是否发布,空值或不传就是全部 - aid:创建人 aid - sysCreateUser: 创建人姓名 - keyword:查询关键词 - sysTypes:系统的分类,多级使用 - 分隔,注一期功能是分类的最后一级值,不支持多个的查询 - orderField:排序字段 id s - orderAsc:true/false 是否是正序,从小到大 - status:状态,多个使用 - 分隔 1代表待审核 5代表已审核 1 未提交 2 已提交 5 审核完成 - type:课程类型,10微课,21在线课(直播);20:在线课( 录播);30:面授课;40:混合式, - name 课程名称 - */ -const exportCourseAudit=function(query){ - return ajax.post('/xboe/m/course/manage/exportCourseAudit',query); -} -/* -参数同上待审核课程记录导出 - 课程的导出和已审核的课程导出 - */ -const exportCourse=function(query){ - return ajax.post('/xboe/m/course/manage/exportCourse',query); -} - -//判断受众id是否有关联 -const queryCrowd=function(query){ - return ajax.postJson('/xboe/m/course/manage/queryCrowd',query); -} - -/** - * 二次查询 - * @param{ - * ids - * } - * */ -const ids=function (data){ - return ajax.postJson('/xboe/m/course/manage/ids',data); -} - -const saveTip = function() { - return ajax.postJson('/xboe/m/course/manage/saveTip'); -} - - -export default { - saveBase, - submitCourse, - revokeSubmit, - copyCourse, - findUpdateLogs, - getUpdateLog, - detail, - getDictIds, - saveContent, - pageList, - setEnabled, - del, - publish, - saveSection, - getHomework, - countWaitAudit, - auditList, - teacherAuditList, - auditAppoint, - getAuditInfo, - audit, - auditPageRecords, - auditCourseRecords, - auditAndPublish, - getAssess, - setTop, - delSection, - getExam, - delContent, - updateContentName, - updateContentOrders, - saveOnlyCourse, - isRedoName, - isCourseName, - detailFew, - sumbits, - teacherCourse, - exportTeacherCourse, - exportCourseAudit, - exportCourse, - queryCrowd, - ids, - saveTip - -} +/** + * 课程的操作,课程的添加,修改,列表查询,课程的审核发布等操作。 + * 针对于管理员,教师的功能 + * + **/ +import ajax from '@/utils/xajax.js' + +/** + * 保存课程基本信息,新增和更新都是此方式 + * @param {Object} data + *{ + course:{ + 课程的基本信息,具体字段内容另外提供 + name:课程名称 + type:课程类型,10微课,21在线课(直播);20:在线课( 录播);30:面授课;40:混合式, + summary:摘人 + overview: 课程简介 + coverImg:封面图 + sysType:系统分类,只存储最后一级, + resOwner1:资源归属一级的id + resOwner2:资源归属二级的id + resOwner3:资源归属三级的id + forUsers: 目标人群 + forScene:应用场景 + openObject: 开放权限 + value:课程价值 + tags:标签,多个使用-分隔 + keywords:关键字 + device: 1:PC端可见;2:移动端可见;3:多端可见 + status: 1:未提交(草稿);2:已提交; + published:true/false 是否发布 + enabled:true/false 启用、停用 + isTop: true/false 是否置顶 + source:整数,课程来源,1:内部;2;外部 + + }, + teachers:[ + { + teacherId:教师的id, + teacherName:教师的名称 + } + ] + } + */ +const saveBase = function(data) { + return ajax.postJson('/xboe/m/course/manage/save', data); +} + + + +/** + * 仅仅是保存课程信息,不包括教师信息 + * @param {Object} data + */ +const saveOnlyCourse = function(data) { + return ajax.postJson('/xboe/m/course/manage/save-only-course', data); +} + +/**提交课程*/ +const submitCourse = function(data) { + return ajax.postJson('/xboe/m/course/manage/submit', data); +} + +/**撤销已提交审核的课程*/ +const revokeSubmit = function(id) { + return ajax.post('/xboe/m/course/manage/revoke', {id}); +} + +/** + * 复制课程 + * @param {Object} + */ +const copyCourse = function(data) { + return ajax.post('/xboe/m/course/manage/copy',data); +} +/* +查询课程是否有重复名称 + */ +const isRedoName=function(){ + return ajax.get('/xboe/m/course/manage/isRedoName'); +} +/* +查询当前添加课程是否已有 +courseName 要添加的课程姓名 + */ +const isCourseName=function(courseName,courseId){ + return ajax.get(`/xboe/m/course/manage/isCourseName?courseName=${courseName}&courseId=${courseId}`); +} +/** + * 查询修改日志,列表,不分页 + * @param {Object} params + * { + num:数量,可以不传,默认是10条,最新的10条 + courseId:课程的id + name: 修改人 + } + */ +const findUpdateLogs = function(params) { + return ajax.post('/xboe/m/course/manage/upldate-logs',params); +} + +/** + * 根据id获取修改的详细信息 + * @param {Object} id + */ +const getUpdateLog = function(id) { + return ajax.get('/xboe/m/course/manage/upldate-log-detail?id='+id); +} + +/** + * 保存课程的一条学习内容信息,新增和更新都是此方式 + * @param {Object} data + * { + content:内容 { + courseId,csectionId章节id(微课为空),sortIndex排序顺序(微课为空),contentType 内容类型(图文41,连接52,作业60,考试61,评估62) + contentName,contentRefId无关联内容时为空(此字段内容后台会控制),content具体的内容 + } + + homework:作业信息 单个对象{ + courseId,contentId上面对象的id(后台会控制),name,content,file,deadTime, + submitMode:1表提交附件,2直接填写,3表两者都可以 + } + exam:考试信息 单个对象 + { + courseId,contentId上面对象的id(后台会控制),testName,testDuration考试时长, + paperType试卷类型 1自定义,2使用已有试卷 + paperId试题的id,使用已有试卷时保存选择试卷的id + showAnalysis是否显示解析,showAnswer否显示答案,times尝试次数 + arrange试题排序 0表不乱序,1试题乱序,2选项乱序,3全部乱序 + scoringType评分方式 1最高一次,2最后一次 + passLine及格线整数 + randomMode是否随机模式true/false + paperContent试卷的内容,json存储的对象{items:[]} + + } + assess:评估信息,list 多条记录. + [ + { courseId,contentId,assessId评估id(一期为空),question问题,qType问题类型} + ] + } + */ +const saveContent = function(data) { + return ajax.postJson('/xboe/m/course/content/save', data); +} + + +/** + * 更新课程内容的顺序 + * @param {String} cid //课程的id + * @param {Array} items + * [ + * { + * id:章的id + * index:整数,顺序值 + * items:[ + * {id:内容的id,index:顺序值} + * ] + * } + * ] + * @returns + */ +const updateContentOrders = function(cid,items) { + return ajax.postJson('/xboe/m/course/content/update-orders/'+cid, items); +} + +/** + * 课程的详细信息 + * @param {String} id + */ +const detail = function(id) { + return ajax.get('/xboe/m/course/manage/detail?id=' + id); +} +const getDictIds = function(pid,type) { + return ajax.get(`/xboe/m/course/manage/getDictIds?pid=${pid}&type=${type}`); +} +/** + * 更新内容的名称 + * @param {Object} data + * { + id:'', + name:'' + } + */ +const updateContentName = function(data) { + return ajax.post('/xboe/m/course/content/update-name', data); +} + +/** + * 删除一条学习内容 + * @param {Object} data + * { + id: 内容的id, + ctype:对应内容的类型contentType + erasable:是否物理删除,此值是课程信息中系统带过来的字段,直接使用它就可以了 + } + */ +const delContent = function(data) { + return ajax.post('/xboe/m/course/content/delete', data); +} + +/** + * 保存课程的章信息,新增和修改保存都是一个 + * @param {Object} data + * courseId:课程的id + * name:章节名称 + description:章节说明 + parentId: 上级id。如果没有可以填“-1”字符串 + orderIndex:显示顺序,顺序索引,整数 + */ +const saveSection = function(data) { + return ajax.post('/xboe/m/course/content/save-section', data); +} + +/** + * 删除章节目录,注意只有目录下没有学习内容时才允许删除 + * @param {Object} data + */ +const delSection = function(id) { + return ajax.post('/xboe/m/course/content/delete-section?id=' + id); +} + +/** + * 根据课程学习内容的id。获取作业信息,只有学习内容是作业时才会有信息 + * @param {Object} ccid + */ +const getHomework = function(ccid) { + return ajax.post('/xboe/m/course/content/homework?ccid=' + ccid); +} + +/** + * 根据课程学习内容的id。获取考试信息,只有学习内容是考试时才会有信息 + * @param {Object} ccid + */ +const getExam = function(ccid) { + return ajax.post('/xboe/m/course/content/exam?ccid=' + ccid); +} + +/** + * 根据课程学习内容的id。获取评估信息,评估内容可以获取 + * @param {Object} ccid + */ +const getAssess = function(ccid) { + return ajax.post('/xboe/m/course/content/assess?ccid=' + ccid); +} + +/** + * 管理列表查询 + * @param {Object} query + * pageIndex:第几页 + * pageSize:每页多少条 + * resOwner1:资源归属一级的id + resOwner2:资源归属二级的id + resOwner3:资源归属三级的id + types:授课方式,多个使用 - 分隔 + scenes:应用场景,多个使用 - 分隔 + publish:true/false 是否发布,空值或不传就是全部 + aid:创建人 aid + sysCreateUser: 创建人姓名 + keyword:查询关键词 + sysTypes:系统的分类,多级使用 - 分隔,注一期功能是分类的最后一级值,不支持多个的查询 + orderField:排序字段 id s + orderAsc:true/false 是否是正序,从小到大 + status:状态,多个使用 - 分隔 1代表待审核 5代表已审核 1 未提交 2 已提交 5 审核完成 + type:课程类型,10微课,21在线课(直播);20:在线课( 录播);30:面授课;40:混合式, + name 课程名称 + + */ +const pageList = function(query) { + return ajax.post('/xboe/m/course/manage/pagelist', query); +} + + +/**计算待审核课程*/ +const countWaitAudit = function() { + return ajax.get('/xboe/m/course/manage/wait-audit-num'); +} + +/** + * [已用courseAudit中的hrbpAuditList替换] + * 当前用户需要审核的课程列表 + * @param {Object} query 同pageList + */ +const auditList = function(query) { + return ajax.post('/xboe/m/course/manage/audit-pagelist', query); +} + + +/** + * 【已移到courseAudit中】 + * 教师需要审核的课程列表 + */ +const teacherAuditList = function(query) { + return ajax.post('/xboe/m/course/audit/teacher-course', query); +} + +/** + * 指定审核人,转审核人 + * 点击“转审” 弹出教师查询窗口,查询教师,填写备注,提交,调用此接口 + * @param {Object} data + * {courseId:课程id,teacherId:指定的审核人教师的id,teacherName:教师名称,remark:备注} + */ +const auditAppoint = function(data) { + return ajax.post('/xboe/m/course/audit/appoint', data); +} + +/** + * 获取审核信息,上面教师点击审核课程时,用于查询,上面“转审”时,用户填写的备注信息 + * @param {courseId:'课程id',teacherId:'可以不填写,系统会查询当前人'} data + */ +const getAuditInfo = function(data) { + return ajax.post('/xboe/m/course/audit/infos', data); +} + + +/** + * 管理员的课程审核处理 + * @param {Object} query {id:课程id,title:课程的名称, Boolean pass 是否通过,remark 备注} + */ +const audit = function(data) { + return ajax.post('/xboe/m/course/manage/audit', data); +} + +/** + * 审核记录列表,分页查询 + */ +const auditPageRecords = function(data) { + return ajax.post('/xboe/m/course/audit/page-records', data); +} + +/** + * 审核记录列表,要卖课程id,查询出审核列记录信息 + * { courseId:必须} + */ +const auditCourseRecords = function(data) { + return ajax.post('/xboe/m/course/audit/course-records',data); +} + +/** + * 管理员的课程发布,当前已经不再使用了 + * @param {Object} query {ids:课程id,多个使用逗号分隔,title:课程的名称, Boolean pass 是否发布} + */ +const publish = function(data) { + return ajax.post('/xboe/m/course/manage/publish', data); +} + +const auditAndPublish=function(data) { + return ajax.post('/xboe/m/course/manage/audit-publish', data); +} + +/** + * 设置top + * @param {Object} query {ids:课程id,多个使用逗号分隔,title:课程的名称,Boolean top 是否置顶} + */ +const setTop = function(data) { + return ajax.post('/xboe/m/course/manage/top', data); +} + +/** + * 管理员的设置启用停用 + * @param {Object} query {ids:课程id,多个使用逗号分隔,title:课程的名称, Boolean enabled 是否启用} + */ +const setEnabled = function(data) { + return ajax.post('/xboe/m/course/manage/enabled', data); +} + +/** + * 管理员的删除课程 + * erasable 此值是课程信息带过来的,直接传就可以 + * @param {Object} query {id:课程id,多个使用逗号分隔,Boolean erasable 是否物理删除,title:课程的名称, remark 备注} + */ +const del = function(data) { + return ajax.post('/xboe/m/course/manage/delete', data); +} +/* +详情 + */ +const detailFew=function(id){ + return ajax.get('/xboe/m/course/portal/detail-few?id=' + id); +} + +/* +直接审核,教师提交审核 + */ +const sumbits=function(data){ + return ajax.post('/xboe/m/course/manage/sumbits',data); +} +/* +教师授课记录 + */ +const teacherCourse=function(teacherId){ + return ajax.get('/xboe/m/course/manage/teacher-course?teacherId='+teacherId); +} +/* +教师授课记录导出 +@param teacherId 教师id + */ +const exportTeacherCourse=function(teacherId){ + return ajax.post('/xboe/m/course/manage/export-teacher-course?teacherId='+teacherId) +} +/* +*待审核课程记录导出 + * resOwner1:资源归属一级的id + resOwner2:资源归属二级的id + resOwner3:资源归属三级的id + types:授课方式,多个使用 - 分隔 + scenes:应用场景,多个使用 - 分隔 + publish:true/false 是否发布,空值或不传就是全部 + aid:创建人 aid + sysCreateUser: 创建人姓名 + keyword:查询关键词 + sysTypes:系统的分类,多级使用 - 分隔,注一期功能是分类的最后一级值,不支持多个的查询 + orderField:排序字段 id s + orderAsc:true/false 是否是正序,从小到大 + status:状态,多个使用 - 分隔 1代表待审核 5代表已审核 1 未提交 2 已提交 5 审核完成 + type:课程类型,10微课,21在线课(直播);20:在线课( 录播);30:面授课;40:混合式, + name 课程名称 + */ +const exportCourseAudit=function(query){ + return ajax.post('/xboe/m/course/manage/exportCourseAudit',query); +} +/* +参数同上待审核课程记录导出 + 课程的导出和已审核的课程导出 + */ +const exportCourse=function(query){ + return ajax.post('/xboe/m/course/manage/exportCourse',query); +} + +//判断受众id是否有关联 +const queryCrowd=function(query){ + return ajax.postJson('/xboe/m/course/manage/queryCrowd',query); +} + +/** + * 二次查询 + * @param{ + * ids + * } + * */ +const ids=function (data){ + return ajax.postJson('/xboe/m/course/manage/ids',data); +} + +const saveTip = function() { + return ajax.postJson('/xboe/m/course/manage/saveTip'); +} + + + +// ai播放器相关 - 批量AI设置 +const benchAiSet=function(data){ + return ajax.postJson('/xboe/m/course/manage/benchAiSet',data); +} +export default { + saveBase, + submitCourse, + revokeSubmit, + copyCourse, + findUpdateLogs, + getUpdateLog, + detail, + getDictIds, + saveContent, + pageList, + setEnabled, + del, + publish, + saveSection, + getHomework, + countWaitAudit, + auditList, + teacherAuditList, + auditAppoint, + getAuditInfo, + audit, + auditPageRecords, + auditCourseRecords, + auditAndPublish, + getAssess, + setTop, + delSection, + getExam, + delContent, + updateContentName, + updateContentOrders, + saveOnlyCourse, + isRedoName, + isCourseName, + detailFew, + sumbits, + teacherCourse, + exportTeacherCourse, + exportCourseAudit, + exportCourse, + queryCrowd, + ids, + saveTip, + benchAiSet, + +} diff --git a/src/assets/images/course/courseAbstract.png b/src/assets/images/course/courseAbstract.png new file mode 100644 index 00000000..180aeaac Binary files /dev/null and b/src/assets/images/course/courseAbstract.png differ diff --git a/src/assets/images/course/courseNew.png b/src/assets/images/course/courseNew.png new file mode 100644 index 00000000..13d81fcd Binary files /dev/null and b/src/assets/images/course/courseNew.png differ diff --git a/src/assets/images/course/generationFailed.png b/src/assets/images/course/generationFailed.png new file mode 100644 index 00000000..5ca255d5 Binary files /dev/null and b/src/assets/images/course/generationFailed.png differ diff --git a/src/assets/images/course/languageIcon.png b/src/assets/images/course/languageIcon.png new file mode 100644 index 00000000..454e67cb Binary files /dev/null and b/src/assets/images/course/languageIcon.png differ diff --git a/src/assets/images/course/noData.png b/src/assets/images/course/noData.png new file mode 100644 index 00000000..822040e7 Binary files /dev/null and b/src/assets/images/course/noData.png differ diff --git a/src/assets/images/course/selectLanguage.png b/src/assets/images/course/selectLanguage.png new file mode 100644 index 00000000..f13efb3a Binary files /dev/null and b/src/assets/images/course/selectLanguage.png differ diff --git a/src/assets/images/course/wengaoTip.png b/src/assets/images/course/wengaoTip.png new file mode 100644 index 00000000..f83ce6fb Binary files /dev/null and b/src/assets/images/course/wengaoTip.png differ diff --git a/src/assets/styles/btn.scss b/src/assets/styles/btn.scss index e6ba1a8e..0cb69515 100644 --- a/src/assets/styles/btn.scss +++ b/src/assets/styles/btn.scss @@ -97,3 +97,29 @@ font-size: 14px; border-radius: 4px; } +// 已下架 +.custom-takeout{ + display: inline-block; + padding: 3px 13px; + border-radius: 20px; + font-size: 12px; + background: rgba(254, 249, 195, 1); + color: rgba(133, 77, 14, 1); + font-size: 12px; + font-weight: 500; + line-height: 17px; + letter-spacing: 0px; +} +// 已上架 +.custom-putaway{ + display: inline-block; + padding: 3px 13px; + border-radius: 20px; + font-size: 12px; + background: rgba(220, 252, 231, 1); + color: rgba(22, 101, 52, 1); + font-size: 12px; + font-weight: 500; + line-height: 17px; + letter-spacing: 0px; +} \ No newline at end of file diff --git a/src/components/Course/aiScript.vue b/src/components/Course/aiScript.vue new file mode 100644 index 00000000..365b6a43 --- /dev/null +++ b/src/components/Course/aiScript.vue @@ -0,0 +1,423 @@ + + + + + \ No newline at end of file diff --git a/src/components/Course/courseForm.vue b/src/components/Course/courseForm.vue index 4dcda9ca..97107927 100644 --- a/src/components/Course/courseForm.vue +++ b/src/components/Course/courseForm.vue @@ -208,6 +208,43 @@ placeholder="请尽量填写课程简介,用于列表中显示,可以让用户更容易了解课程信息"> + +
+
+ + + + +
+
+
+
+ AI摘要 + + + + +
+
+ AI文稿 + + + + +
+
+
+ AI翻译语种 + + + + + + +
+
+
+
@@ -390,6 +427,44 @@ placeholder="请尽量填写课程简介,用于列表中显示,可以让用户更容易了解课程信息"> + + +
+
+ + + + +
+
+
+
+ AI摘要 + + + + +
+
+ AI文稿 + + + + +
+
+
+ AI翻译语种 + + + + + + +
+
+
+
+
+
+ {{!currentLang ? 'AI翻译' : currentLangLabel}} +
+
    +
  • {{ item.label }}
  • +
+
+
+
|
+
+ 字幕 + + +
+
|
+
{{currentSpeed === 1 ? '倍速' : `${currentSpeed}x`}}
@@ -224,6 +252,7 @@ import volumeBar from "@/components/VideoPlayer/volume-bar.vue"; import progressBar from "@/components/VideoPlayer/progress-bar.vue"; import playerBarrageScreen from "@/components/VideoPlayer/player-barrage-screen.vue"; +import { mapGetters, mapMutations } from 'vuex'; export default { name: "barrage-videoplayer", @@ -301,12 +330,24 @@ export default { fullTimeFormat: "00:00:00", // 视频总长度的文字 barrageTimelineStart: 0, // 弹幕时间轴的起始时间点(手动调整进度条触发更新) isInit:false, // 是否初始化过 + // ai播放器相关 + isSubtitle: true, // 是否开启字幕 + currentLangLabel:'', // 当前字幕语言 }; }, + // ai播放器相关 + computed: { + ...mapGetters(['selectableLang','currentLang','courseInfo']), + isAiTranslate () { + return this.courseInfo?.aiSet == 1 && this.courseInfo?.aiTranslate == 1; + } + }, created() { - + // ai播放器相关 + this.SET_currentLang(''); }, mounted() { + console.log('---',this.isAiTranslate,this.courseInfo,'courseInfo'); this.videoDom = this.$refs.video; this.videoDom.focus({preventScroll: true}); let speedValue=localStorage.getItem('boe_video_speed'); @@ -317,7 +358,8 @@ export default { } setInterval(() => { - console.log('当前状态:',this.currentProgress,this.isDrag,this.videoDom.currentTime , this.videoDom.duration) + this.SET_duration(this.videoDom.duration); + console.log('当前状态:',localStorage.getItem('videoProgressData'),this.currentProgress,this.isDrag,this.videoDom.currentTime , this.videoDom.duration) // 视频播放时本地记录视频实时播放时长,视频设置了禁止拖动时执行 if(!this.isDrag){ var time = localStorage.getItem('videoProgressData') @@ -372,6 +414,7 @@ export default { //if() //console.log(this.videoDom.readyState,'this.videoDom.readyState'); }, 1000); + // 视频dom监听器,用于控制鼠标的显示 this.videoDom.addEventListener("mousemove", () => { this.isCursorStatic = false; @@ -411,6 +454,13 @@ export default { // }); }, methods: { + // ai播放器相关 + ...mapMutations({ + SET_currentLang: 'video/SET_currentLang', + SET_currentTime: 'video/SET_currentTime', + SET_selectableLang: 'video/SET_selectableLang', + SET_duration: 'video/SET_duration', + }), //当视频由于需要缓冲下一帧而停止,解决一直计时的问题 onWaiting(){ console.log('触发了onWairing'); @@ -624,6 +674,8 @@ export default { }, onAudioTimeUpdate() { const currentTime = this.$refs.video.currentTime; + // ai播放器相关 + this.SET_currentTime(currentTime) this.$emit('onTimeUpdate', currentTime); }, /** @@ -641,9 +693,77 @@ export default { this.$emit('onFullscreen',false);//全屏 } } + }, + /** ai播放器相关 + * 切换字幕 + */ + toggleSubtitle(value) { + if (this.videoDom && this.videoDom.textTracks && this.videoDom.textTracks.length >0) { + if (!value) { + // 关闭字幕 + this.videoDom.textTracks[this.videoDom.textTracks.length - 1].mode = 'hidden'; + } else { + // 打开字幕 + this.videoDom.textTracks[this.videoDom.textTracks.length - 1].mode = 'showing'; + } + } + }, + /** ai播放器相关 + * 切换字幕语言 + */ + changeLang(item) { + this.SET_currentLang(item.srclang); + this.currentLangLabel = item.label; + console.log("changeLang",item); + // 先移除所有字幕轨道 + Array.from(this.videoDom.querySelectorAll('track')).forEach(t => t.remove()); + if(!item.vttContent){ + console.log("字幕内容为空!") + return; + } + if(!item.srcUrl){ + try{ + const blob = new Blob([item.vttContent], { type: 'text/vtt' }); + item.srcUrl = URL.createObjectURL(blob); + }catch(e){ + console.log("字幕格式错误",e) + } + } + const trackEl = document.createElement('track'); + trackEl.kind = 'subtitles'; + trackEl.srclang = item.srclang; + trackEl.label = item.label; + trackEl.src = item.srcUrl; + trackEl.default = true; // 确保字幕默认启用 + // 使用箭头函数保持this上下文 + trackEl.addEventListener('load', () => { + console.log('字幕加载成功!'); + // console.log('#########Track cues:', trackEl.track.cues); + }); + + trackEl.addEventListener('error', () => { + console.error('字幕加载失败!'); + }); + + // 确保视频已加载到可添加轨道的状态 + if (this.videoDom.readyState >= 1) { + this.videoDom.appendChild(trackEl); + this.videoDom.textTracks[this.videoDom.textTracks.length - 1].mode = 'showing'; + } else { + this.videoDom.addEventListener('loadedmetadata', () => { + this.videoDom.appendChild(trackEl); + this.videoDom.textTracks[this.videoDom.textTracks.length - 1].mode = 'showing'; + }, { once: true }); + } + }, + seekToTime(time) { + if (!this.videoDom) return; + this.videoDom.currentTime = time + 0.01; + this.isPlaying = true; + this.videoDom.play(); + }, - } }, watch: { currentVolume: function () { @@ -668,9 +788,37 @@ export default { // } // }, src: function () { - // 当视频地址变更时,重载视频 + // 当视频地址变更时,先重置字幕再重载视频 + this.isPlaying = false; + // 重置字幕相关状态 + this.SET_currentLang(''); + this.currentLangLabel = ''; + + // 移除所有现有字幕轨道元素 + Array.from(this.videoDom.querySelectorAll('track')).forEach(t => t.remove()); + + // 更彻底地清除字幕:重置所有textTracks + Array.from(this.videoDom.textTracks).forEach(track => { + track.mode = 'hidden'; + // 尝试移除所有cues(浏览器支持的话) + if (track.cues) { + while (track.cues.length > 0) { + track.cues.remove(0); + } + } + }); + + // 重载视频 this.videoDom.load(); - this.isPlaying = false + + // 如果有默认语言且支持AI翻译,重新设置字幕 + if (this.isAiTranslate && this.selectableLang && this.selectableLang.length > 0) { + // 找到默认语言或第一个可用语言 + const defaultLang = this.selectableLang.find(lang => lang.srclang === 'zh-CN') || this.selectableLang[0]; + if (defaultLang) { + this.changeLang(defaultLang); + } + } }, }, }; @@ -907,6 +1055,12 @@ export default { color: #fff; margin-bottom: 0.5rem; } +.box-aiTranslate{ + display: flex; + align-items: center; + justify-content: center; + gap: 0.4rem; +} @media (device-width: 100vw) { .player-controls-btn .player-controls-icon { /* height: 26px; */ diff --git a/src/data/pages.js b/src/data/pages.js index 5ec52049..f5423b4b 100644 --- a/src/data/pages.js +++ b/src/data/pages.js @@ -117,6 +117,8 @@ export const iframes=[ {title:'嵌入测试', path:'/iframe/index',hidden:false,component:'portal/iframe'}, {title:'课件管理', path:'/iframe/course/coursewares',hidden:false,component:'course/Courseware'}, {title:'课程管理', path:'/iframe/course/manages',hidden:false,component:'course/ManageList'}, + {title:'ai摘要', path:'/iframe/course/aiAbstract',hidden:false,component:'course/aiSet/aiAbstract'}, + {title:'ai翻译', path:'/iframe/course/aiTranslate',hidden:false,component:'course/aiSet/aiTranslate'}, {title:'考试试题管理', path:'/iframe/exam/questions',hidden:false,component:'exam/Question'}, {title:'查看答卷', path:'/iframe/exam/viewanswer',hidden:false,component:'exam/viewAnswer'}, {title:'考试试卷管理', path:'/iframe/exam/papers',hidden:false,component:'exam/TestPaper'}, diff --git a/src/store/getters.js b/src/store/getters.js index 999ef0c6..a9956d27 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -28,5 +28,12 @@ const getters = { studyTaskCount:state => state.user.studyTaskCount, praisesUnicom:state =>state.pdf.praisesUnicom, favoritesUnicom:state =>state.pdf.favoritesUnicom, + // ai播放器相关 + selectAllLang:state => state.video.selectAllLang, + selectableLang:state => state.video.selectableLang, + currentLang:state => state.video.currentLang, + currentTime:state => state.video.currentTime, + courseInfo:state => state.video.courseInfo, + duration:state => state.video.duration, } export default getters diff --git a/src/store/index.js b/src/store/index.js index ff0d0868..a44d8dba 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -12,6 +12,7 @@ import resOwner from './modules/resOwner' import majorType from './modules/majorType' import orgDomain from './modules/orgDomain' import pdf from './modules/pdf' +import video from './modules/video' // ai播放器相关 Vue.use(Vuex) @@ -27,7 +28,8 @@ const store = new Vuex.Store({ resOwner, majorType, orgDomain, - pdf + pdf, + video }, getters }) diff --git a/src/store/modules/video.js b/src/store/modules/video.js new file mode 100644 index 00000000..7227e9e7 --- /dev/null +++ b/src/store/modules/video.js @@ -0,0 +1,171 @@ +// ai播放器相关 + +/** + * +selectAllLang: [ + { + key: 'ZH_CN', + srclang: 'zh-CN', + label: '中文', + name: '中文', + }, + { + key: 'EN_US', + srclang: 'en-US', + label: '英语', + name: 'English', + }, + { + key: 'JA_JP', + srclang: 'ja-JP', + label: '日语', + name: '日本語', + }, + { + key: 'KO_KR', + srclang: 'ko-KR', + label: '韩语', + name: '한국어', + }, + { + key: 'FR_FR', + srclang: 'fr-FR', + label: '法语', + name: 'français', + }, + { + key: 'DE_DE', + srclang: 'de-DE', + label: '德语', + name: 'Deutsch', + }, + { + key: 'ES_ES', + srclang: 'es-ES', + label: '西班牙语', + name: 'español', + }, + { + key: 'RU_RU', + srclang: 'ru-RU', + label: '俄语', + name: 'русский', + }, + { + key: 'PT_BR', + srclang: 'pt-BR', + label: '葡萄牙语', + name: 'português', + }, + { + key: 'IT_IT', + srclang: 'it-IT', + label: '意大利语', + name: 'italiano', + }, + { + key: 'AR_SA', + srclang: 'ar-SA', + label: '阿拉伯语', + name: 'العربية', + }, + { + key: 'TH_TH', + srclang: 'th-TH', + label: '泰语', + name: 'ไทย', + }, + { + key: 'VI_VN', + srclang: 'vi-VN', + label: '越南语', + name: 'tiếng Việt', + }, + { + key: 'ID_ID', + srclang: 'id-ID', + label: '印度尼西亚语', + name: 'Bahasa Indonesia', + }, + { + key: 'HI_IN', + srclang: 'hi-IN', + label: '印地语', + name: 'हिन्दी', + } + ], // 全部语言列表 +*/ + +const state = { + selectAllLang: [ + { + key: 'ZH_CN', + srclang: 'zh-CN', + label: '中文', + name: '中文', + }, + { + key: 'EN_US', + srclang: 'en-US', + label: '英语', + name: 'English', + }, + { + key: 'VI_VN', + srclang: 'vi-VN', + label: '越南语', + name: 'tiếng Việt', + }, + { + key: 'ES_ES', + srclang: 'es-ES', + label: '西班牙语', + name: 'español', + }, + ], // 一期语言列表 + selectableLang: [], // 可选语言列表+字幕信息 + currentLang: '', // 当前选中语言 + currentTime: -1, // 当前视频时间 + courseInfo: {}, + duration: 0, // 视频时长 +} + +const mutations = { + SET_currentLang: (state, lang) => { + state.currentLang = lang + }, + SET_selectableLang: (state, list = []) => { + let selectableLang = [] + list.forEach(item => { + let selectItem = state.selectAllLang.find(selectItem => selectItem.srclang === item.language) + if (selectItem) { + selectableLang.push({ + ...item, + ...selectItem, + }) + } + }) + state.selectableLang = selectableLang + }, + SET_currentTime: (state, time) => { + state.currentTime = time + }, + SET_courseInfo: (state, info) => { + state.courseInfo = info + }, + SET_duration: (state, duration) => { + state.duration = duration + }, +} + +const actions = { + +} + +export default { + namespaced: true, + state, + mutations, + actions +} + diff --git a/src/views/course/ManageList.vue b/src/views/course/ManageList.vue index d0c2b60d..f5eca22a 100644 --- a/src/views/course/ManageList.vue +++ b/src/views/course/ManageList.vue @@ -60,101 +60,108 @@
搜索 - 重置 + 重置
- - - 新建课程 - + + + + 新建课程 + 设置语种 + 开启AI处理 +
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +
@@ -287,6 +294,236 @@
+ + + + +
+
请选择课程所支持语种
+ + + +
+
+ 注:仅支持对已开启AI处理的课程进行批量语种设置;所选的课程中有{{languageSetting.aiSetNoNum}}个未开启AI处理的课程,以上配置仅对{{languageSetting.aiSetNum}}个已开启AI处理的课程生效。 +
+ +
+ + + +
+ +
+ + + + + AI处理: + + + {{ aiProcessSetting.aiSet === 1 ? '开启' : '关闭' }} + + +
+ +
+ +
+ + + + + AI摘要: + + + {{ aiProcessSetting.aiAbstract === 1 ? '开启' : '关闭' }} + + + +
+ + +
+ + + + + AI文稿: + + + {{ aiProcessSetting.aiDraft === 1 ? '开启' : '关闭' }} + + + +
+ + +
+ + + + + AI翻译语种: + + + + +
+
+ + +
+ 注:已跳过{{aiProcessSetting.aiSetNum}}个已开启AI处理的课程,仅更新剩余{{aiProcessSetting.aiSetNoNum}}个 +
+
+ + 取消 + 确认 + +
+ + + +
+ + +
+ + + + + AI功能状态: + + + {{ aiSetting.aiSet === 1 ? '已开放' : '未开放' }} + + +
+
+ +
+ AI摘要状态: + + {{ aiSetting.aiAbstract === 1 ? '已上架' : '已下架' }} + +
+ + {{ aiSetting.aiAbstract === 0 ? '上架' : '下架' }} + + 编辑 +
+
+ + +
+ AI文稿状态: + + {{ aiSetting.aiDraft === 1 ? '已上架' : '已下架' }} + +
+ + {{ aiSetting.aiDraft === 0 ? '上架' : '下架' }} + +
+
+ + +
+ AI翻译状态: + + {{ aiSetting.aiTranslate === 1 ? '已上架' : '已下架' }} + +
+ + {{ aiSetting.aiTranslate === 0 ? '上架' : '下架' }} + + 编辑 +
+
+ + +
+ 支持语种: +
+
+ {{ getLanguageName(lang) }} + 已下架 +
+
+ + + +
+
+
+ + 取消 + 确认 + +
@@ -299,7 +536,7 @@ import auditCourse2 from '@/components/Course/auditCourse2.vue'; import adminPage from '@/components/Administration/adminPage.vue'; import apiResowner from '../../api/modules/resowner.js'; import apiType from '../../api/modules/type.js' -import {courseType} from '../../utils/tools.js'; +import {courseType, deepCopy} from '../../utils/tools.js'; import apiCourse from '../../api/modules/course.js'; // import {resOwnerIndexName,sysTypeIndexName} from '@/utils/type.js'; import { mapGetters,mapActions } from 'vuex'; @@ -307,8 +544,9 @@ import apiUserbasic from "@/api/boe/userbasic.js" export default { name: 'manageCourse', components: {courseForm, manager, auditCourse1, auditCourse2,adminPage}, + // ai播放器相关 computed: { - ...mapGetters(['resOwnerMap','sysTypeMap','userInfo']), + ...mapGetters(['resOwnerMap','sysTypeMap','userInfo', 'selectAllLang']), }, data() { return { @@ -392,6 +630,32 @@ export default { }, extendRefId:'', extendRefType:'', + // ai播放器相关 + selectedCourses: [], //已选课程 + languageSetting: { // 设置语种弹框 + dlgShow: false, + languageCode: ['zh-CN', 'en-US'] // 默认选中的语种 + }, + aiProcessSetting: { // 开启AI处理弹框 + dlgShow: false, + aiSet: 1, + aiAbstract: 1, + aiDraft: 1, + languageCode: ['zh-CN', 'en-US'] // 默认选中的语种 + }, + aiSetting: { // AI设置弹框 + dlgShow: false, + courseId: '', + aiSet: 1, + aiAbstract: 1, // 1:上架 0:下架 + aiDraft: 1, // 1:上架 0:下架 + aiTranslate: 1, // 1:上架 0:下架 + languageCode: ['zh-CN', 'en-US', 'vi-VN'] // 支持的语种 + }, + aiSetTip: '是否将课程进行AI处理', //提示信息 + aiAbstractTip: '一键提炼课程视频核心要点,助力学员课前高效掌握重点,快速筛选学习资源', // 提示信息 + aiDraftTip: '分段展示视频内容并精准同步时间轴,实现视频进度与文稿双向定位,学习内容触手可及', //提示信息 + aiTranslateTip: '智能转换视频字幕与语音为多语种,支持全球学员按需切换语言,打破学习边界', // 提示信息 }; }, mounted() { @@ -426,6 +690,7 @@ export default { }, methods: { + getAudiences(){ apiUserbasic.getInAudienceIds().then(res=>{ if (res.status == 200) { @@ -449,6 +714,7 @@ export default { inputOn() { this.$forceUpdate(); }, + // 置顶 setTop(row) { let params = { @@ -885,6 +1151,140 @@ export default { saveNewCatalogZhang() { this.catalogs.addNewZhang = false; }, + + + // ai播放器相关 + getLanguageName(lang){ + return this.selectAllLang.find(item => item.srclang === lang)?.label || ''; + }, + handleSelectionChange(val){ + this.selectedCourses = val; + console.log(val); + }, + // 获取选中课程的AI信息 + getAIInfoByList(list = []) { + let selectNum = 0; // 选中的课程数量 + let aiSetNum = 0; // 已设置AI的课程数量 + let aiSetNoNum = 0; // 未设置AI的课程数量 + list.forEach(item => { + if(item.aiSet === 1){ + aiSetNum++; + }else{ + aiSetNoNum++; + } + }); + return { + selectNum, + aiSetNum, + aiSetNoNum + } + }, + // AI设置 + setAI(row) { + console.log('row', row); + this.aiSetting = { + dlgShow: true, + ...row + }; + }, + changeAIKey(key) { + this.aiSetting[key] = this.aiSetting[key] === 1 ? 0 : 1; + }, + // 确认AI设置 + confirmAISetting() { + const item = deepCopy(this.aiSetting); + item.languageStatus = item.aiSet; + item.languageCode = item.languageCode || []; + if (!item.languageCode.includes('zh-CN')) { + item.languageCode.unshift('zh-CN'); // 默认添加中文 去重 + } + this._benchAiSet([item], (res) => { + this.$message.success('AI设置保存成功'); + this.aiSetting.dlgShow = false; + // 可以选择是否刷新列表数据 + this.searchData(); + }, (res) => { + this.$message.error('AI设置保存失败!'); + }) + }, + setLanguage() { + if (this.selectedCourses.length > 0) { + this.languageSetting = {...{ + dlgShow: true, + languageCode: ['zh-CN', 'en-US'] // 默认选中的语种 + }, ...this.getAIInfoByList(this.selectedCourses)} + } + }, + enableAI() { + // 开启AI处理按钮点击事件 + if (this.selectedCourses.length > 0) { + this.aiProcessSetting = {...{ + dlgShow: true, + aiSet: 1, + aiAbstract: 1, + aiDraft: 1, + languageCode: ['zh-CN', 'en-US'] // 默认选中的语种 + }, ...this.getAIInfoByList(this.selectedCourses)} + } + }, + // 批量设置语种 - 确认 + confirmLanguageSetting() { + const courseList = deepCopy(this.selectedCourses); + let languageCode = deepCopy(this.languageSetting.languageCode || []); + if (!languageCode.includes('zh-CN')) { + languageCode.unshift('zh-CN'); // 默认添加中文 去重 + } + courseList.forEach(item => { + item.languageCode = languageCode; + item.aiTranslate = item.aiSet; + item.languageStatus = item.aiSet; + }) + this._benchAiSet(courseList, (res) => { + this.$message.success('设置语种成功!'); + this.languageSetting.dlgShow = false; + // 可以选择是否刷新列表数据 + this.searchData(); + }, (res) => { + this.$message.error('设置语种失败!'); + }) + }, + + // 批量开启AI处理 - 确认 + confirmAiProcess() { + // 获取AI处理配置 + let { aiSet, aiAbstract, aiDraft, languageCode } = this.aiProcessSetting; + const courseList = deepCopy(this.selectedCourses); + languageCode = languageCode || []; + if (!languageCode.includes('zh-CN')) { + languageCode.unshift('zh-CN'); // 默认添加中文 去重 + } + courseList.forEach(item => { + item.aiSet = aiSet; + item.aiAbstract = aiAbstract; + item.aiDraft = aiDraft; + item.aiTranslate = aiSet; + item.languageStatus = aiSet; + item.languageCode = languageCode; + }) + this._benchAiSet(courseList, (res) => { + this.$message.success('开启AI处理成功!'); + this.aiProcessSetting.dlgShow = false; + // 可以选择是否刷新列表数据 + this.searchData(); + }, (res) => { + this.$message.error('开启AI处理失败!'); + }) + }, + + _benchAiSet(courseList, successCB, failCB) { + apiCourse.benchAiSet({courseList}).then(res => { + if(res.status === 200){ + successCB && successCB(res); + }else{ + failCB && failCB(res); + } + }) + }, } }; @@ -953,4 +1353,22 @@ export default { .el-dialog__body { overflow: hidden; } + + .form-item{ + margin-bottom: 20px; + display: flex; + align-items: center; + gap: 10px; + } +.tips { + color: #f56c6c; + font-size: 12px; + margin: 10px 0; + line-height: 1.5; +} +.languages-list{ + display: flex; + flex-wrap: wrap; + gap: 20px; +} diff --git a/src/views/course/aiSet/aiAbstract.vue b/src/views/course/aiSet/aiAbstract.vue new file mode 100644 index 00000000..2efd2c32 --- /dev/null +++ b/src/views/course/aiSet/aiAbstract.vue @@ -0,0 +1,245 @@ + + + + + diff --git a/src/views/course/aiSet/aiTranslate.vue b/src/views/course/aiSet/aiTranslate.vue new file mode 100644 index 00000000..28f146b6 --- /dev/null +++ b/src/views/course/aiSet/aiTranslate.vue @@ -0,0 +1,388 @@ + + + + + diff --git a/src/views/portal/course/Index.vue b/src/views/portal/course/Index.vue index 9a5dd8ec..7083a819 100644 --- a/src/views/portal/course/Index.vue +++ b/src/views/portal/course/Index.vue @@ -203,8 +203,25 @@
开课时间:{{ cinfo.startTime }}
- -
+ +
+ +
+

课程摘要

+
{{ cinfo.summaryContent }}
+
+ + 暂无数据 +
+
+ + 摘要 +
{{ cinfo.teacher }} @@ -214,13 +231,13 @@ {{ formatNum(cinfo.studies) }}人学习
-
+
- {{ toScore(cinfo.score) }}分 + {{ toScore(cinfo.score) }}分
-
未评分
+
未评分
@@ -2655,3 +2672,43 @@ a.custom2 { } } + + diff --git a/src/views/study/coursenew.vue b/src/views/study/coursenew.vue index 3da4fe9c..5863a69e 100644 --- a/src/views/study/coursenew.vue +++ b/src/views/study/coursenew.vue @@ -373,6 +373,30 @@ >我的笔记
+ +
+ ai文稿 + +
@@ -625,6 +649,11 @@ :score="courseInfo.score" >
+ + +
+ +
@@ -637,6 +666,16 @@ > 内容简介
+ +
+ AI摘要 + +
+ +
+
+ {{ courseInfo.summaryContent || '' }} +
+
@@ -799,7 +847,8 @@