51 KiB
依赖环境
- node >=16.0.0
- npm >=6.14.13
- vue 2.0
- jquery ^3.6.3
- xe-utils ^3.5.6
- element-ui ^2.15.9
阅读器对接流程
- 部署数字教材包
- 解析数字教材包中的 localViewData.js 文件
- 将教材目录信息入库
- 添加授课资源
- 查询授课资源列表
分工(包含学生 PC 端、学生移动端、教师 PC 端)
斯麦尔
- 数字教材包的加解密
- 数字教材包离线阅读解密
- 数字教材内容展示
- 数字教材页面交互,包括:目录、书签、笔记、高亮、授课资源。(业务平台提供数据接口)
- 数字教材授课资源交互,包括:资源上传、教师笔记添加、资源展示、资源与教材关联。(业务平台提供数据接口,业务平台提供教师资源阅读服务)
- 多类数字教材阅读行为回传。(业务平台提供数据接口)
业务方
-
数字教材包上传、解密
-
将教材目录信息入库
-
解析数字教材包中的 localViewData.js 文件
-
教师资源阅读服务(图片、音频、视频、WORD、EXCEL、PPT、PDF)
-
教师资源文件上传、数据存储
-
阅读器与业务系统交互接口
所需接口
- 笔记添加、编辑、删除、列表查询(学生)
- 授课资源添加、编辑、删除、列表查询(教师)
- 高亮添加、删除、列表查询(可根据教材内容排序)
- 书签添加、删除、列表查询
- 文件上传
- 授课资源列表查询
- 教师资源下载
- 授课资源阅读服务(WORD、EXCEL、PPT、PDF)
- 更新用户学习次数、学习时长
引入组件
1.组件包形式引用
在src文件夹中新建plugin文件夹,将组件包解压到plugin文件夹
在 main.js 中写入以下内容:
import Vue from 'vue'
import XML from './plugin/xml-digital-teaching/lib/index'
import './plugin/xml-digital-teaching/lib/theme/index.css'
import App from './App.vue'
Vue.use(XML)
new Vue({
render: (h) => h(App)
}).$mount('#app')
组件
xmlDigitalTeaching
数字教材阅读器组件,用于渲染数字教材
代码示例
<template>
<div class="xml-read">
<xml-digital-teaching
v-if="digitalTeaching"
ref="xmlDigitalTeaching"
:textBookData="textBookData"
:catalogList="catalogList"
:looseLeafData="looseLeafData"
:location="location"
:notesList="data.notes.list"
:bookmarkList="data.bookmark.list"
:resourcesList="data.resources.list"
:highlightList="data.highlight.list"
:isTrial="isTrial"
:isTrialIndex="isTrialIndex"
:userType="userType"
:setting="setting"
@updateReadLocation="updateReadLocation"
@addNote="addNote"
@editNote="editNote"
@deleteNote="deleteNote"
@deleteHighlight="deleteHighlight"
@addTeacherNote="addTeacherNote"
@editTeacherNote="editTeacherNote"
@deleteTeacherNote="deleteTeacherNote"
@addHighlight="addHighlight"
@updateNotes="updateNotes"
@addBookmark="addBookmark"
@deleteBookmark="deleteBookmark"
@downloadFile="downloadFile"
@addResources="addResources"
@deleteResource="deleteResource"
@editResources="editResources"
@settingChange="settingChange"
:action="action"
:headers="headers"
:isShowTeacherResource="true"
:continueReading="true"
:basisPath="basisPath"
:pageType="pageType"
:isOpenStudy="true"
officePreviewPath="https://idocview.xxxxxxx.com/view/url?url="
/>
</div>
</template>
<script>
export default {
data() {
return {
action: 'http://60.xxxx.137.15:8081/admin-api/teachingMaterial/resource/upload/16550/6940601956829184',
headers: {
Authorization: `eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjYyMDFlYjA3LTY4ZWUtNGJhOC1iMjc3LTk4MjU0ZGI0MzUwMSJ9.zvW8Rr8ShOvwH5i7Cvl9bgp4MtznyLusrY86LMLW7MplNOjRp6j8lx6zkAD4_CvNXVF7v7MsYcRhN90DvhTq1g`
},
digitalTeaching: true,
textBookData: LOCAL_VIEW_DETAIL,
catalogList: LOCAL_VIEW_CATALOG,
looseLeafData: LOCAL_VIEW_DATA,
location: '',
basisPath: 'https://www.xxxxx.com/file/1685523466073/',
pageType: 'pc',
isTrial: false,
isTrialIndex: 10,
userType: 'teacher',
data: {
notes: {
list: []
},
bookmark: {
list: []
},
highlight: {
list: []
},
resources: {
list: []
}
},
setting: {}
}
},
created() {
this.userType = this.$route.query.userType || 'student'
if (this.$route.query.type) {
this.pageType = this.$route.query.type
// this.isTrialIndex = Number(this.$route.query.isTrialIndex)
if (this.$route.query.isTrialIndex) {
this.isTrial = true
}
}
this.location = localStorage.getItem(this.textBookData.id)
setTimeout(() => {
this.getData()
// this.getSetting()
}, 800)
},
methods: {
// 学生笔记操作 start
addNote(model) {
this.addData('notes', model)
},
editNote(model) {
this.updateData('notes', model)
},
deleteNote(model, feedback) {
this.deleteData('notes', model)
feedback()
},
// 教师笔记操作 start
addTeacherNote(model, rollback) {
this.addData('resources', model)
},
editTeacherNote(model) {
this.updateData('resources', model)
},
deleteTeacherNote(model, feedback) {
this.deleteData('resources', model)
feedback()
},
// 高亮操作
addHighlight(model, rollback) {
this.addData('highlight', model)
},
// 高亮删除
deleteHighlight(model, rollback) {
this.deleteData('highlight', model)
console.log(model, 'model')
},
settingChange(key, value) {
// let newSetting = Object.assign({}, this.setting, { [key]: value })
// localStorage.setItem('setting_#_' + this.textBookData.id, JSON.stringify(newSetting))
// this.setting = JSON.parse(localStorage.getItem('setting_#_' + this.textBookData.id)) || {}
},
// 更新笔记
updateNotes(model) {
this.updateData('notes', model)
},
// 添加书签
addBookmark(e) {
this.addData('bookmark', e)
},
// 删除书签
deleteBookmark(e) {
this.deleteData('bookmark', e)
},
// 添加数据
addData(type, item) {
this.data[type].list.push(item)
let list = JSON.stringify(this.data)
localStorage.setItem('simulated-data_' + this.textBookData.id, list)
this.getData(type, item)
},
// 查询数据
getData(type, item) {
setTimeout(() => {
this.data = JSON.parse(localStorage.getItem('simulated-data_' + this.textBookData.id)) || {
notes: {
list: []
},
bookmark: {
list: []
},
highlight: {
list: []
},
resources: {
list: []
}
}
}, 300)
},
getSetting() {
this.setting = JSON.parse(localStorage.getItem('setting_#_' + this.textBookData.id)) || {}
},
// 更新数据
updateData(type, item) {
console.log(item)
let i = this.data[type].list.findIndex((items) => items.id == item.id)
this.data[type].list[i] = item
let list = JSON.stringify(this.data)
localStorage.setItem('simulated-data_' + this.textBookData.id, list)
this.getData(type, item)
},
// 删除数据
deleteData(type, item) {
console.log(item, 'deleteData')
let i = this.data[type].list.findIndex((items) => items.id == item.id)
this.data[type].list.splice(i, 1)
let list = JSON.stringify(this.data)
localStorage.setItem('simulated-data_' + this.textBookData.id, list)
this.getData(type, item)
},
// 下载资源文件
downloadFile(e) {},
// 更新阅读进度
updateReadLocation(newLocation) {
localStorage.setItem(this.textBookData.id, newLocation.location)
},
// 添加教师资源
addResources(e) {
this.addData('resources', e)
},
// 删除教师资源
deleteResource(e) {
this.deleteData('resources', e)
},
// 编辑教师资源
editResources(e) {
this.updateData('resources', e)
}
}
}
</script>
参数说明
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| systemEnvId | 使用阅读器系统 ID,由斯麦尔提供 | String | 无 |
| navBarHeight | 业务系统导航栏高度 | Number | 0 |
| classId | 班级唯一标识 | String | 无 |
| gradesName | 班级名称 | String | 无 |
| userType | 用户类型,可选 teacher、student | String | student |
| isShowTeacherResource | 是否显示教师资源 | Boolean | false |
| learningDuration | 已学习总时长 | Number | 0 |
| textBookData | 教材详细信息 | Object | 无 |
| catalogList | 教材目录列表 | Array | 无 |
| looseLeafData | 所有活页信息 | Object | 无 |
| basisPath | 资源文件在服务器基础路径 | String | 无 |
| location | 阅读开始位置 | String | 无 |
| notesList | 笔记列表 | Array | 无 |
| highlightList | 高亮列表 | Array | 无 |
| bookmarkList | 书签列表 | Array | 无 |
| highlightList | 高亮列表 | Array | 无 |
| resourcesList | 授课资源列表 | Array | 无 |
| pageType | 页面类型 h5、pc、pad | String | h5 |
| loadingMode | 阅读模式可选 roll:无限滚动、page:按章节 | String | roll |
| catalogLevel | 目录显示的最小层级 | Number | 3 |
| isTrial | 是否为试读模式 | Boolean | false |
| isTrialIndex | 试读百分比 | Number | 10 |
| trialChapterList | 可试读的章节,isTrialIndex 传 0 时生效,['xxxxx'] | Array | 无 |
| chapterId | 打开教材指定章节,章节 ID | String | 无 |
| continueReading | 是否以弹窗形式提示用户继续阅读,chapterId 为空时生效 | Boolean | false |
| downloadType | 下载资源方式 pop-up:弹窗提示,click:下载回调 | String | pop-up |
| isOpenHyperlink | 移动端是否可以直接打开超链接 | Boolean | false |
| linkOpenLabel | pc 端链接是否打开新标签 | Boolean | true |
| officePreviewPath | ffice 在线预览路径 格式:地址加参数名:https:www.xxx.com?src= | String | 微软在线预览 |
| trialText | 试读结束提示语,富文本格式 | String | 试读结束 |
| action | 文件上传地址,上传教师资源时必传 | String | 无 |
| headers | 设置上传的请求头部 | Object | 无 |
| data | 上传时附带的额外参数 | Object | 无 |
| fileSize | 最大上传文件大小,单位 M | Number | 300 |
| isOpenStudy | 是否开启学情统计和班级 | Boolean | true |
| teacherData | 教师端学情统计 | Object | teacherData |
| studentData | 学生端学情统计 | Object | studentData |
| getCatalogStudent | 获取目录学习情况 | Array | generalAPI |
| isAddMark | 是否可以添加书签、笔记 | Boolean | true |
| updateFREQUENCY | 音视频更新回调频率 | String | 10s |
| robotData | 智能云端应用调用参数 | Object | robotData |
| isOperation | 是否可以操作(用于点击后接口无响应,重复操作) | Boolean | true |
事件
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| updateReadLocation | 更新阅读进度 | newLocation:当前阅读位置信息 |
| addNote | 确认添加笔记 | notesInfo:添加笔记信息 |
| editNote | 更新笔记 | notesInfo:更新笔记信息 |
| deleteNote | 删除笔记 | notesInfo:删除笔记信息 |
| addBookmark | 添加书签 | bookmarkInfo:添加书签信息 |
| deleteBookmark | 删除书签 | bookmarkInfo:删除书签信息 |
| addHighlight | 添加高亮 | highlightInfo:添加高亮信息 |
| deleteHighlight | 删除高亮 | highlightInfo:删除高亮信息 |
| addTestPaper | 添加试卷 | testPaperInfo:添加试卷信息 |
| deleteTestPaper | 删除试卷 | testPaperInfo:删除试卷信息 |
| addResources | 添加授课资源 | resourcesInfo:添加授课资源信息 |
| editResources | 编辑授课资源 | resourcesInfo:添加授课资源信息 |
| deleteResource | 删除授课资源 | resourcesInfo:删除授课资源信息 |
| addTeacherNote | 添加教师笔记 | notesInfo:笔记信息 |
| editTeacherNote | 修改教师笔记 | notesInfo:笔记信息 |
| deleteTeacherNote | 删除教师笔记 | notesInfo:笔记信息 |
| downloadFile | 下载资源 | fileInfo:资源信息 |
| settingChange | 阅读设置 | |
| joinClass | 加入班级 | {code:输入的激活码} |
| learningStatistics | 更新学习统计 | statisticsInfo |
| changeClass | 切换班级 | 班级信息 |
| clickToRespond | 按钮点击回调 | {type:按钮类型,data:{}} |
保存阅读进度
updateReadLocation 监听实时更新当前阅读位置信息,下次进入将位置信息传入组件
添加笔记
addNote 确认添加笔记事件返回笔记 Id,对应的位置信息,选择内容,笔记内容,==添加成功更新笔记列表数据==
editNote 更新笔记事件返回笔记 Id,笔记内容等信息
deleteNote 删除笔记事件返回笔记 Id 等信息,==删除成功更新笔记列表数据==
添加书签
addBookmark 添加书签事件返回图书位置等信息,==添加成功更新书签列表数据==
deleteBookmark 删除书签事件返回书签 ID 等信息,==删除成功更新书签列表数据==
添加高亮
addHighlight 添加高亮事件返回图书位置等信息,==添加成功更新高亮列表数据==
deleteHighlight 删除高亮事件返回高亮 ID 等信息,==删除成功更新高亮列表数据==
教师端添加试题
addTestPaper 添加试题事件返回图书位置等信息,==添加成功更新资源列表数据==
deleteTestPaper 删除试题事件返回试题 ID 等信息,==删除成功更新资源列表数据==
教师端添加资源
addResources 添加资源事件返回图书位置等信息,==添加成功更新资源列表数据==
deleteResources 删除资源事件返回资源 ID 等信息,==删除成功更新资源列表数据==
下载资源
downloadFile 下载资源事件,返回资源文件信息
组件内部方法
| 方法名 | 说明 | 参数 |
|---|---|---|
| showToast | 提示框 | text:提示的文字 , type : warning、success、error |
| READER_MODE | 沉浸式阅读 | type: initial 初始值、immersive 沉浸式阅读 |
数据格式
textBookData.json
{
"createBy": null,
"createByName": null,
"createTime": "2023-01-10 22:44:25",
"delFlag": null,
"delTime": null,
"examineDesc": null,
"examineStatus": "0",
"id": "1612822675944177664",
"isbn": null,
"params": {},
"remark": null,
"searchValue": null,
"submitTime": null,
"textBooksAuthor": null,
"textBooksDesc": null,
"textBooksFileUrl": "",
"textBooksName": "测试所有组件",
"textBooksType": null,
"updateBy": null,
"updateByName": null,
"updateTime": "2023-01-12 13:56:07"
}
catalogList.json
{
"data": [
{
"children": [],
"id": "1612822676606877696",
"label": "章节1",
"level": null,
"orderNum": null,
"parentId": null
}
]
}
looseLeafData.json
{
"1612822676606877696": {
"createBy": "admin",
"createByName": null,
"createTime": "2023-01-10 22:44:26",
"delFlag": "0",
"delTime": null,
"examineDesc": null,
"examineStatus": "0",
"id": "1612822676606877696",
"looseLeafDesc": null,
"looseLeafFileUrl": "",
"looseLeafInfo": "[{\"data\": {\"pGroupData\": {\"textData\": {\"html\": \"<span>暂无内容</span><div><span>这是文本</span></div><div><span><br/></span></div>\"}}, \"extendParams\": {}}, \"xmlCompRef\": \"xml-single-text-group0.9220515733715631\", \"componentsName\": \"xml-single-text-group\"}, {\"data\": {\"pGroupData\": {\"titleTextData\": {\"html\": \"<p style=\\\"font-size: 16px;font-family: PingFang SC;font-weight: 400;color: #FFFFFF;margin-block-start: 5px;margin-block-end: 5px;\\\">这是标题</p>\"}}, \"extendParams\": {}}, \"xmlCompRef\": \"titleFirst0.15542352103317736\", \"componentsName\": \"titleFirst\"}, {\"data\": {\"pGroupData\": {\"imageData\": {\"imageList\": [{\"link\": \"\", \"title\": \"开发-2-背景\", \"source\": \"upload\", \"content\": \"说明\", \"uploadFileUrl\": \"./image/5fdb8395-fc66-44e3-91e6-e6167af9677c.jpg\"}], \"imageMode\": \"dan-tu\", \"showEffect\": \"hua-lang\", \"clickEffect\": \"dian-ji-fang-da\"}}, \"extendParams\": {}}, \"xmlCompRef\": \"xml-single-image-group0.9871052058974397\", \"componentsName\": \"xml-single-image-group\"}, {\"data\": {\"pGroupData\": {\"musicData\": {\"playMode\": \"dan-ci\", \"playStyle\": \"yuan-wen\", \"musicSetList\": [{\"link\": \"\", \"title\": \"周杰伦-红尘客栈\", \"source\": \"upload\", \"content\": \"内容\", \"materialId\": \"\", \"coverFileUrl\": \"./defaultCover/audio-player.png\", \"uploadFileUrl\": \"./audio/c69259f3-7bd0-4ab8-ba33-6ff626811829.mp3\"}], \"scheduleControl\": \"yes\"}}, \"extendParams\": {}}, \"xmlCompRef\": \"xml-single-music-group0.4729416469673975\", \"componentsName\": \"xml-single-music-group\"}, {\"data\": {\"pGroupData\": {\"videoData\": {\"link\": \"\", \"playMode\": \"xun-huan\", \"playStyle\": \"yuan-wen\", \"videoSetList\": [{\"link\": \"\", \"title\": \"1659943488674121\", \"source\": \"upload\", \"content\": \"内容\", \"materialId\": \"\", \"coverFileUrl\": \"\", \"uploadFileUrl\": \"./video/2d4e8a72-ab40-4e54-b213-41bc3a17e055.mp4\"}], \"scheduleControl\": \"yes\"}}, \"extendParams\": {}}, \"xmlCompRef\": \"xml-single-video-group0.9655721950423428\", \"componentsName\": \"xml-single-video-group\"}, {\"data\": {\"pGroupData\": {\"resourceData\": {\"resourceType\": \"zhan-nei\", \"resourceSetList\": [{\"link\": \"\", \"title\": \"java\", \"source\": \"upload\", \"content\": \"内容\", \"fileSize\": 26163, \"fileFormat\": \"zip\", \"materialId\": \"\", \"coverFileUrl\": \"./defaultCover/pdf-resource.png\", \"uploadFileUrl\": \"./resource/f76b7c64-57dc-4d6f-9fc2-88fc189def15.zip\"}]}}, \"extendParams\": {}}, \"xmlCompRef\": \"xml-single-resource-group0.6167344288655028\", \"componentsName\": \"xml-single-resource-group\"}, {\"data\": {\"pGroupData\": {\"ebookData\": {\"ebookSetList\": [{\"isbn\": \"isbn\", \"link\": \"\", \"name\": \"新冠诊疗方案-第9版\", \"author\": \"作者\", \"source\": \"upload\", \"content\": \"内容\", \"publisher\": \"出版社\", \"fileFormat\": \"pdf\", \"materialId\": \"\", \"coverFileUrl\": \"./defaultCover/epub.png\", \"uploadFileUrl\": \"./ebook/dbb05383-520c-4ff4-801c-c3bdd219c271.pdf\"}], \"resourceType\": \"inside\"}}, \"extendParams\": {}}, \"xmlCompRef\": \"xml-single-ebook-group0.12258282282201893\", \"componentsName\": \"xml-single-ebook-group\"}]",
"looseLeafModule": "1",
"looseLeafName": null,
"looseLeafType": null,
"params": {},
"remark": null,
"searchValue": null,
"submitTime": null,
"tmpLooseId": null,
"updateBy": "1",
"updateByName": null,
"updateTime": "2023-01-12 13:55:38"
}
}
newLocation
{
"chapterId": "章节ID",
"chaptName": "章节名",
"location": "", //当前阅读位置
"schedule": "", //当前阅读进度
"learningTime": "", //本次学习时长
"learningDuration": "", //总学习时长,需要每次进阅读器前传入历史阅读总时长
"chapterSchedule": "本章节学习进度",
"learningChapter": "本次阅读章数",
learningChapterList: [],//本次学习的章节id组
"firstLevelId":"一级章节id"
}
notesInfo
{
"blockIndex": 6, //选中内容块在教材中的索引
"chapterOrderNum": 2, //章排序字段
"id": 1717740841473, //主键
"location": "xml-digital-teaching/1780053976781262849/paragraphRedtheme50.4890346943653967", //所在块的位置信息(章id+块id+段id)
"locationChapterId": "1780053976781262849", //所在章节id
"markEfiCode": "mark(0/0:112,0/0:125)", //选中内容
"markId": "mark__2f63d588-f672-4a07-9541-c964b292e9a6", //笔记标记id
"noteContent": "输入的笔记内容",
"selectionText": "理论与实践、智能车竞赛任务",
"styleType": "mk-underline__dashed",
"textOrderNum": "6000000000112", //选中内容排序字段
"topChapterId": "1780053976781262849", //所在章节一级目录id
"topChapterLabel": "内容简介",
"type": "note__student"
}
notesList
[
{
"blockIndex": 6,
"chapterOrderNum": 2,
"id": 1717740841473,
"location": "xml-digital-teaching/1780053976781262849/paragraphRedtheme50.4890346943653967",
"locationChapterId": "1780053976781262849",
"markEfiCode": "mark(0/0:112,0/0:125)",
"markId": "mark__2f63d588-f672-4a07-9541-c964b292e9a6",
"noteContent": "输入的笔记内容",
"selectionText": "理论与实践、智能车竞赛任务",
"styleType": "mk-underline__dashed",
"textOrderNum": "6000000000112",
"topChapterId": "1780053976781262849",
"topChapterLabel": "内容简介",
"type": "note__student"
},
{
"blockIndex": 6,
"chapterOrderNum": 2,
"id": 1717740841473,
"location": "xml-digital-teaching/1780053976781262849/paragraphRedtheme50.4890346943653967",
"locationChapterId": "1780053976781262849",
"markEfiCode": "mark(0/0:112,0/0:125)",
"markId": "mark__2f63d588-f672-4a07-9541-c964b292e9a6",
"noteContent": "输入的笔记内容",
"selectionText": "理论与实践、智能车竞赛任务",
"styleType": "mk-underline__dashed",
"textOrderNum": "6000000000112",
"topChapterId": "1780053976781262849",
"topChapterLabel": "内容简介",
"type": "note__student"
}
]
bookmarkInfo
{
"bookmarkId": 1717740959575,
"bookmarkText": "版权信息",
"chapterId": "1780053976143728640",
"chapterOrderNum": 2,
"classId": "",
"creationTime": "2024-06-07T06:15:59.575Z",
"firstLevelId": "1780053976143728640",
"firstLevelLabel": "版权信息",
"id": 1717740959575,
"location": "xml-digital-teaching/1780053976143728640/splitlineTwentythreeLibrary0.5093659374044828",
"locationChapterId": "1780053976781262849",
"orderNum": 2,
"type": "bookmark"
}
bookmarkList
[
{
"bookmarkId": 1717740959575,
"bookmarkText": "版权信息",
"chapterId": "1780053976143728640",
"chapterOrderNum": 2,
"classId": "",
"creationTime": "2024-06-07T06:15:59.575Z",
"firstLevelId": "1780053976143728640",
"firstLevelLabel": "版权信息",
"id": 1717740959575,
"location": "xml-digital-teaching/1780053976143728640/splitlineTwentythreeLibrary0.5093659374044828",
"locationChapterId": "1780053976781262849",
"orderNum": 2,
"type": "bookmark"
},
{
"bookmarkId": 1717740959575,
"bookmarkText": "版权信息",
"chapterId": "1780053976143728640",
"chapterOrderNum": 2,
"classId": "",
"creationTime": "2024-06-07T06:15:59.575Z",
"firstLevelId": "1780053976143728640",
"firstLevelLabel": "版权信息",
"id": 1717740959575,
"location": "xml-digital-teaching/1780053976143728640/splitlineTwentythreeLibrary0.5093659374044828",
"locationChapterId": "1780053976781262849",
"orderNum": 2,
"type": "bookmark"
}
]
highlightInfo
{
"blockIndex": 8,
"chapterOrderNum": 3,
"id": 1717741063393,
"location": "xml-digital-teaching/1780053977133584385/xml-single-text-group0.3489658035103893",
"locationChapterId": "1780053977133584385",
"markEfiCode": "mark(1/0:104,1/0:120)",
"markId": "mark__ab53333b-07a7-4318-bd7c-b20d492103cf",
"selectionText": "汽车为研究对象的创意性科技竞赛,",
"styleType": "mk-hightlight__default",
"textOrderNum": "8000001000104",
"topChapterId": "1780053977133584385",
"topChapterLabel": "前言",
"type": "highlight__student"
}
highlightList
[
{
"blockIndex": 8,
"chapterOrderNum": 3,
"id": 1717741063393,
"location": "xml-digital-teaching/1780053977133584385/xml-single-text-group0.3489658035103893",
"locationChapterId": "1780053977133584385",
"markEfiCode": "mark(1/0:104,1/0:120)",
"markId": "mark__ab53333b-07a7-4318-bd7c-b20d492103cf",
"selectionText": "汽车为研究对象的创意性科技竞赛,",
"styleType": "mk-hightlight__default",
"textOrderNum": "8000001000104",
"topChapterId": "1780053977133584385",
"topChapterLabel": "前言",
"type": "highlight__student"
},
{
"blockIndex": 8,
"chapterOrderNum": 3,
"id": 1717741063393,
"location": "xml-digital-teaching/1780053977133584385/xml-single-text-group0.3489658035103893",
"locationChapterId": "1780053977133584385",
"markEfiCode": "mark(1/0:104,1/0:120)",
"markId": "mark__ab53333b-07a7-4318-bd7c-b20d492103cf",
"selectionText": "汽车为研究对象的创意性科技竞赛,",
"styleType": "mk-hightlight__default",
"textOrderNum": "8000001000104",
"topChapterId": "1780053977133584385",
"topChapterLabel": "前言",
"type": "highlight__student"
}
]
testPaperInfo
{
paperName: "试卷名称",
resourcesType:"paper",
location: "添加资源的位置信息",
textBookId: "教材Id",
chapterId:"章节Id",
orderNum:"排序字段"
questionList: [{
//单选题
"data": {
"pGroupData": {
"questionData": {
"showAnswer": "true",
"showAnalysis": "true",
"showRecommend": "true",
"questionSetList": [{
"id": //试题id,
"stem": {
"content": 题干,
"fileInfo": {
"fileUrl": //题干的文件路径,
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
},
"fileUrl": //文件地址,
"analysis": {
"content": //解析内容,
"fileInfo": {
"fileUrl": //解析文件路径
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
},
"duration": //音频时长,
"fileName": //文件名,
"fileType": //文件类型,
"subjectId": "",
"fileSuffix": //文件后缀,
"includeAudio": "1",
"questionType": "2",
"answerSequence": "",
"questionOption": [{
"title": "A",
"content": 选项内容,
"fileInfo": {
"fileUrl": 文件地址,
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
}, {
"title": "B",
"content": 选项内容,
"fileInfo": {
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
}, {
"title": "C",
"content": 选项内容,
"fileInfo": {
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
}, {
"title": "D",
"content": 选项内容,
"fileInfo": {
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
}],
"standardAnswer": [{
"title": "A",
"content": 标答内容,
"fileInfo": {
"fileUrl": //文件地址,
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
}],
"playbackControl": "0",
"knowledgePointVoList": []
}]
}
},
"extendParams": {}
},
}, {
//多选题
"data": {
"pGroupData": {
"questionData": {
"showAnswer": "true",
"showAnalysis": "true",
"showRecommend": "true",
"questionSetList": [{
"id": //试题id,
"stem": {
"content": 题干,
"fileInfo": {
"fileUrl": //题干的文件路径,
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
},
"fileUrl": //文件地址,
"analysis": {
"content": //解析内容,
"fileInfo": {
"fileUrl": //解析文件路径
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
},
"duration": //音频时长,
"fileName": //文件名,
"fileType": //文件类型,
"subjectId": "",
"fileSuffix": //文件后缀,
"includeAudio": "1",
"questionType": "2",
"answerSequence": "",
"questionOption": [{
"title": "A",
"content": 选项内容,
"fileInfo": {
"fileUrl": 文件地址,
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
}, {
"title": "B",
"content": 选项内容,
"fileInfo": {
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
}, {
"title": "C",
"content": 选项内容,
"fileInfo": {
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
}, {
"title": "D",
"content": 选项内容,
"fileInfo": {
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
}],
"standardAnswer": [{
"title": "A",
"content": 标答内容,
"fileInfo": {
"fileUrl": //文件地址,
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
}, {
"title": "C",
"content": //标答内容,
"fileInfo": {
"fileUrl": //文件地址,
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
}, {
"title": "D",
"content": //标答内容,
"fileInfo": {
"fileUrl": //文件地址,
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
}],
"playbackControl": "0",
"knowledgePointVoList": []
}]
}
},
"extendParams": {}
},
}, {
//判断题
"data": {
"pGroupData": {
"questionData": {
"showAnswer": "true",
"showAnalysis": "true",
"showRecommend": "true",
"questionSetList": [{
"id": //试题id,
"stem": {
"content": //题干内容,
"fileInfo": {
"fileUrl": //文件地址,
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
},
"fileUrl": 文件路径,
"analysis": {
"content": 解析内容,
"fileInfo": {
"fileUrl": //解析文件地址,
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
},
"fileType": //类型,
"subjectId": "",
"fileSuffix": //文件后缀,
"includeAudio": "1",
"questionType": "3",
"answerSequence": "",
"questionOption": "[]",
"standardAnswer": ["正确"] //标答,
"playbackControl": "0",
"knowledgePointVoList": []
}]
}
},
"extendParams": {}
},
}, {
//简答题
"data": {
"pGroupData": {
"questionData": {
"showAnswer": "true",
"showAnalysis": "true",
"showRecommend": "true",
"questionSetList": [{
"id": //试题id,
"stem": {
"content": 题干内容,
"fileInfo": {
"fileUrl": //文件地址,
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
},
"fileUrl": //文件地址,
"analysis": {
"content": //解析内容,
"fileInfo": {
"fileUrl": //解析文件地址,
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
},
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": //文件类型,
"subjectId": "",
"fileSuffix": //后缀,
"includeAudio": "1",
"questionType": "13",
"answerSequence": "",
"questionOption": "[]",
"standardAnswer": {
"content": 标答内容 "fileInfo": {
"fileUrl": //文件地址,
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
},
"playbackControl": "0",
"knowledgePointVoList": []
}]
}
},
"extendParams": {}
},
},
{
//填空题
"data": {
"pGroupData": {
"questionData": {
"showAnswer": "true",
"showAnalysis": "true",
"showRecommend": "true",
"questionSetList": [{
"id": 试题id,
"stem": {
"content": 题干 ",
"fileInfo": {
"fileUrl": //文件地址,
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
},
"fileUrl": //文件地址,
"analysis": {
"content": 解析内容,
"fileInfo": {
"fileUrl": //解析文件地址,
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"fileSuffix": "mp4" //文件后缀
}
},
"duration": //音频或者视频的时长,
"fileName": //文件名,
"fileType": "video/mp4" //文件类型,
"subjectId": "",
"fileSuffix": "mp4" //文件后缀,
"includeAudio": "1",
"questionType": "10",
"answerSequence": "A,B;",
"questionOption": "[]",
"standardAnswer": [{
"title": "A",
"content": //选项内容,
"fileInfo": {}
}, {
"title": "B",
"content": //选项内容,
"fileInfo": {}
}],
"playbackControl": "0",
"knowledgePointVoList": []
}]
}
},
"extendParams": {}
},
}
]
}
resourcesInfo
{
"blockIndex": 28,
"chapterId": "7038441430792015872",
"chapterOrderNum": 4,
"creationTime": "2024-06-07T06:20:11.119Z",
"duration": 0,
"fileExt": "jpg",
"fileUrl": "https://cmp-uploadfile-dev.oss-cn-beijing.aliyuncs.com/teaching_material/16574/7027199990597632.jpg",
"firstLevelId": "1607971683998171136",
"firstLevelLabel": "项目一 工业机器人概述",
"id": 1717741211119,
"isDownload": 0,
"isStudentShow": 0,
"location": "xml-digital-teaching/7038441430792015872/xml-single-text-group0.7097987508783292",
"locationChapterId": "1607971683998171136",
"markEfiCode": "mark(2/0/0:56,2/0/0:71)",
"markId": "mark__96d6b7b0-0c25-42cd-8244-c2a4a997b964",
"noteContent": "",
"orderNum": 0,
"resourcesName": "40.jpg",
"resourcesType": "image",
"selectionText": "美国机器人协会给机器人下的定义",
"textBookId": "1607971683880730624",
"textOrderNum": "28000002000056",
"type": "note__teacher"
}
resourcesList
[
{
"blockIndex": 28,
"chapterId": "7038441430792015872",
"chapterOrderNum": 4,
"creationTime": "2024-06-07T06:20:11.119Z",
"duration": 0,
"fileExt": "jpg",
"fileUrl": "https://cmp-uploadfile-dev.oss-cn-beijing.aliyuncs.com/teaching_material/16574/7027199990597632.jpg",
"firstLevelId": "1607971683998171136",
"firstLevelLabel": "项目一 工业机器人概述",
"id": 1717741211119,
"isDownload": 0,
"isStudentShow": 0,
"location": "xml-digital-teaching/7038441430792015872/xml-single-text-group0.7097987508783292",
"locationChapterId": "1607971683998171136",
"markEfiCode": "mark(2/0/0:56,2/0/0:71)",
"markId": "mark__96d6b7b0-0c25-42cd-8244-c2a4a997b964",
"noteContent": "",
"orderNum": 0,
"resourcesName": "40.jpg",
"resourcesType": "image",
"selectionText": "美国机器人协会给机器人下的定义",
"textBookId": "1607971683880730624",
"textOrderNum": "28000002000056",
"type": "note__teacher"
},
{
"blockIndex": 28,
"chapterId": "7038441430792015872",
"chapterOrderNum": 4,
"creationTime": "2024-06-07T06:20:11.119Z",
"duration": 0,
"fileExt": "jpg",
"fileUrl": "https://cmp-uploadfile-dev.oss-cn-beijing.aliyuncs.com/teaching_material/16574/7027199990597632.jpg",
"firstLevelId": "1607971683998171136",
"firstLevelLabel": "项目一 工业机器人概述",
"id": 1717741211119,
"isDownload": 0,
"isStudentShow": 0,
"location": "xml-digital-teaching/7038441430792015872/xml-single-text-group0.7097987508783292",
"locationChapterId": "1607971683998171136",
"markEfiCode": "mark(2/0/0:56,2/0/0:71)",
"markId": "mark__96d6b7b0-0c25-42cd-8244-c2a4a997b964",
"noteContent": "",
"orderNum": 0,
"resourcesName": "40.jpg",
"resourcesType": "image",
"selectionText": "美国机器人协会给机器人下的定义",
"textBookId": "1607971683880730624",
"textOrderNum": "28000002000056",
"type": "note__teacher"
}
]
fileInfo:
{
"content": "",
"coverFileUrl": "",
"fileFormat": "",
"fileSize": "",
"link": "",
"materialId": "",
"source": "",
"title": "",
"uploadFileUrl": ""
}
statisticsInfo
通用参数
//图片每放大预览调用一次;音视频每播放10秒调用一次;答题每提交答案调用一次
{
type:'学习类型',//image:图片,audio:音频,video:视频,question:答题
firstLevelId: '章节所在一级标题的Id',
firstLevelLabel: '章节所在一级标题的名称',
locationChapterId: '当前内容阅读所在目录id',
locationLabel: '当前内容阅读所在目录名称',
chapterId: '章节Id',
label: '章节名字',
xmlCompRef:'学习内容唯一ID',
location:'学习内容在教材中的位置信息',
}
特定参数
==音频==
{
"duration": "音频总时长",
"time": "当前播放时长"
}
==视频==
{
"duration": "视频总时长",
"time": "当前播放时长"
}
==试题==
{
"pass": "回答是否正确,true:正确;false:错误",
"question": "试题信息"
}
studentData:
{
nickname:'',//名字
className:'',//默认班级
img:'',//头像
learningProgress:'',//学习进度
learnNum :'',//学习次数
learnTime:'',//本次学习时长
totalLearnTime:'',//学习总时长
chapterNum:'',//本次学习章节数量
learnChapter:'',//总学习章节
noteNum:'',//笔记数量
bookmarkNum:'',//书签数量
lineationNum:'',//划线数量
imgLearnNum:0,//图片学习次数
musicTime:10,//音频学习时长
videoTime:10,//视频学习时长
completionRate:0,//试题完成率
accuracy:0,//试题正确率
"imageNum": 0, //学习图片个数
"testNum": 0, //试题学习个数
"musicNum": 0, //音频学习个数
"videoNum": 0, //视频学习个数
}
teacherData:
{
"nickname": "", //名字
"className": "", //默认班级
"img": "", //头像
"totalLearnTime": "", //授课时长
"learnNum": "", //授课次数
"learningProgress": "", //学习进度
"thisLearnTime": "", //本次授课时长
"studentList": [
{
"nickname": "", //名字
"className": "", //默认班级
"img": "", //头像
"learningProgress": "", //学习进度
"learnNum": "", //学习次数
"learnTime": "", //本次学习时长
"totalLearnTime": 0, //学习总时长
"chapterNum": "", //本次学习章节数量
"learnChapter": 0, //总学习章节
"noteNum": "", //笔记数量
"bookmarkNum": "", //书签数量
"lineationNum": "", //划线数量
"imgLearnNum": 0, //图片学习次数
"musicTime": 0, //音频学习时长
"videoTime": 0, //视频学习时长
"completionRate": 0, //试题完成率
"accuracy": 0, //试题正确率
"imageNum": 0, //学习图片个数
"testNum": 0, //试题学习个数
"musicNum": 0, //音频学习个数
"videoNum": 0, //视频学习个数
},
] //班级学员
}
robotData:
{
"appId": "", //应用ID
"token": "", //应用token
"baseUrl": "", //新建对话接口地址
"conversationUrl": "" //大模型对话接口
}
按钮类型
{
"value": 0,
"label": "点击学习情况"
}
generalAPI
<template>
<xml-digital-teaching :generalAPI="generalAPI" />
</template>
<script>
export default {
data() {
return {
generalAPI: {
isCatalogStudent: true, //是否开启查询章节学期情况
getCatalogStudent: (e) => this.getCatalogStudent(e)
}
}
},
methods: {
/**
* e.chapterId 章节id
*/
getCatalogStudent(e) {
return new Promise((resolve, reject) => {
let data = {
chapterId: '0', //章节id
studyTime: 0, //本章学习时间,单位秒
studyProgress: '100', //本章学习进度
testProgress: '0', //本章试题完成进度
accuracy: '', //本章试题正确率
testNum:'0',//本章试题完成个数
}
// 模拟异步操作
setTimeout(() => {
resolve({ data })
}, 1000)
})
}
}
}
</script>
阅读器功能
语音评测
1、传入配置
<script>
export default {
provide() {
return {
getXmlShadowingConfig: () => ({
APPID: 'xxxxx',
API_SECRET: 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
API_KEY: 'xxxxxxxxxxxxxxxxxxxxxxxxxx'
}),
}
},
}
</script>
工具方法
格式化教材数据
import XML from './plugin/xml-digital-teaching/lib/index'
XML.formatTextBook({
textBookData: this.textBookData,
catalogList: this.catalogList,
looseLeafData: this.looseLeafData,
isTrial: true
}).then((res) => {
console.log(res)
})
- 请求参数
| 参数 | 说明 | 类型 | 是否必填 |
|---|---|---|---|
| textBookData | 教材信息 | Object | true |
| catalogList | 目录 | Array | true |
| looseLeafData | 教材内容 | Object | true |
| isTrial | 是否试读 | Boolean | false |
| isTrialIndex | 试读百分比 | Number | false |
| trialChapterList | 可试读的章节,isTrialIndex 传 0 时生效,['xxxxx'] | Array | false |
- 返回值
| 参数 | 说明 | 类型 |
|---|---|---|
| componentList | 可阅读的块 | Array |
| catalogList | notUsable:为不可 阅读的章节 | Array |
| textBookResource | 教材各类资源统计 | Object |
