### 依赖环境

* 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



### 阅读器对接流程

1. 部署数字教材包
2. 解析数字教材包中的localViewData.js文件
3. 将教材目录信息入库
6. 添加授课资源
7. 查询授课资源列表



### 分工（包含学生PC端、学生移动端、教师PC端）

#### 斯麦尔

1. 数字教材包的加解密
2. 数字教材包离线阅读解密
3. 数字教材内容展示
4. 数字教材页面交互，包括：目录、书签、笔记、高亮、授课资源。（业务平台提供数据接口）
6. 数字教材授课资源交互，包括：资源上传、教师笔记添加、资源展示、资源与教材关联。（业务平台提供数据接口，业务平台提供教师资源阅读服务）
7. 多类数字教材阅读行为回传。（业务平台提供数据接口）

#### 业务方

1. 数字教材包上传、解密

2. 将教材目录信息入库

3. 解析数字教材包中的localViewData.js文件

4. 教师资源阅读服务（图片、音频、视频、WORD、EXCEL、PPT、PDF）

5. 教师资源文件上传、数据存储

6. 阅读器与业务系统[交互接口](#所需接口)

   

### 所需接口

1. 笔记添加、编辑、删除、列表查询（学生）
2. 授课资源添加、编辑、删除、列表查询（教师）
3. 高亮添加、删除、列表查询（可根据教材内容排序）
4. 书签添加、删除、列表查询
5. 文件上传
7. 授课资源列表查询
14. 教师资源下载
15. 授课资源阅读服务（WORD、EXCEL、PPT、PDF）
16. 更新用户学习次数、学习时长



### 引入组件

##### 1.组件包形式引用

![image-20230110174057846](C:\Users\FYF\AppData\Roaming\Typora\typora-user-images\image-20230110174057846.png)

~~~
在src文件夹中新建plugin文件夹，将组件包解压到plugin文件夹
~~~



在 main.js 中写入以下内容：

~~~javascript
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

数字教材阅读器组件，用于渲染数字教材

<img src="I:\国开\代码\digital-textbook-web\packages\xml-components\noteImages\image-20230110085842152.png" style="zoom: 80%;" />

##### 代码示例

~~~vue
<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"
      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>

~~~



##### 参数说明

| 参数                                 | 说明                                                         | 类型    | 默认值       |
| ------------------------------------ | ------------------------------------------------------------ | ------- | ------------ |
| classId                              | 班级唯一标识                                                 | String  | 无           |
| gradesName                           | 班级名称                                                     | String  | 无           |
| userType                             | 用户类型，可选teacher、student                               | String  | student      |
| isShowTeacherResource                | 是否显示教师资源                                             | Boolean | false        |
| learningDuration                     | 已学习总时长                                                 | Number  | 0            |
| [textBookData](#textBookData.json)   | 教材详细信息                                                 | String  | 无           |
| [catalogList](#catalogList.json)     | 教材目录列表                                                 | Array   | 无           |
| [looseLeafData](#looseLeafData.json) | 所有活页信息                                                 | String  | 无           |
| basisPath                            | 资源文件在服务器基础路径                                     | String  | 无           |
| location                             | 阅读开始位置                                                 | String  | 无           |
| [notesList](#notesList)              | 笔记列表                                                     | Array   | 无           |
| highlightList                        | 高亮列表                                                     | Array   | 无           |
| [bookmarkList](#bookmarkList)        | 书签列表                                                     | Array   | 无           |
| [highlightList](#highlightList)      | 高亮列表                                                     | Array   | 无           |
| [resourcesList](#resourcesList)      | 授课资源列表                                                 | Array   | 无           |
| pageType                             | 页面类型 h5、pc、pad                                         | String  | h5           |
| isTrial                              | 是否为试读模式                                               | Boolean | false        |
| isTrialIndex                         | 试读百分比                                                   | Number  | 10           |
| continueReading                      | 是否以弹窗形式提示用户是否继续阅读                           | Boolean | false        |
| downloadType                         | 下载资源方式 pop-up：弹窗提示,click:下载回调                 | String  | pop-up       |
| officePreviewPath                    | ffice 在线预览路径 格式：地址加参数名：https:www.xxx.com?src= | String  | 微软在线预览 |
| trialText                            | 试读结束提示语，富文本格式                                   | String  | 试读结束     |
| action                               | 文件上传地址，上传教师资源时必传                             | String  | 无           |
| headers                              | 设置上传的请求头部                                           | Object  | 无           |
| data                                 | 上传时附带的额外参数                                         | Object  | 无           |

##### 事件 

| 事件名             | 说明         | 回调参数                                         |
| ------------------ | ------------ | ------------------------------------------------ |
| updateReadLocation | 更新阅读进度 | [newLocation](#newLocation)：当前阅读位置信息    |
| addNote            | 确认添加笔记 | [notesInfo](#notesInfo):添加笔记信息             |
| editNote           | 更新笔记     | [notesInfo](#notesInfo):更新笔记信息             |
| deleteNote         | 删除笔记     | [notesInfo](#notesInfo):删除笔记信息             |
| addBookmark        | 添加书签     | [bookmarkInfo](#bookmarkInfo):添加书签信息       |
| deleteBookmark     | 删除书签     | [bookmarkInfo](#bookmarkInfo):删除书签信息       |
| addHighlight       | 添加高亮     | [highlightInfo](#highlightInfo):添加高亮信息     |
| deleteHighlight    | 删除高亮     | [highlightInfo](#highlightInfo):删除高亮信息     |
| addTestPaper       | 添加试卷     | [testPaperInfo](#testPaperInfo):添加试卷信息     |
| deleteTestPaper    | 删除试卷     | [testPaperInfo](#testPaperInfo):删除试卷信息     |
| addResources       | 添加授课资源 | [resourcesInfo](#resourcesInfo):添加授课资源信息 |
| editResources      | 编辑授课资源 | [resourcesInfo](#resourcesInfo):添加授课资源信息 |
| deleteResource     | 删除授课资源 | [resourcesInfo](#resourcesInfo):删除授课资源信息 |
| addTeacherNote     | 添加教师笔记 | [notesInfo](#notesInfo):笔记信息                 |
| editTeacherNote    | 修改教师笔记 | [notesInfo](#notesInfo):笔记信息                 |
| deleteTeacherNote  | 删除教师笔记 | [notesInfo](#notesInfo):笔记信息                 |
| downloadFile       | 下载资源     | [fileInfo](#fileInfo):资源信息                   |
| settingChange      | 阅读设置     |                                                  |

##### 保存阅读进度

> 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 |



##### 数据格式

###### textBookData.json

~~~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

~~~json
{
	"data": [
		{
			"children": [],
			"id": "1612822676606877696",
			"label": "章节1",
			"level": null,
			"orderNum": null,
			"parentId": null
		}
	]
}
~~~

###### looseLeafData.json

~~~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

~~~json
{
            location: '', //当前阅读位置
            schedule: '', //当前阅读进度
            learningTime: '', //本次学习时长
            learningDuration: '' //总学习时长
}
~~~



###### notesInfo

~~~json
{
        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

~~~json
[{
        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

~~~json
{
        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

~~~json
[{
        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

~~~json
{
        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

~~~json
[{
        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

~~~json
{
	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

~~~json
{
        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

~~~json
[{
        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：

~~~json
{
    content:'',
    coverFileUrl:'',
    fileFormat:'',
    fileSize:'',
    link:'',
    materialId:'',
    source:'',
    title:'',
    uploadFileUrl:''
}
~~~





