dev_202412
yujialong 2 months ago
parent 9ea6496254
commit 38565b6669
  1. BIN
      src/assets/img/exts/excel.png
  2. 1
      src/components/Navbar.vue
  3. 2
      src/utils/api.js
  4. 524
      src/views/course/content/index.vue
  5. 207
      src/views/course/content/source.vue

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

@ -139,6 +139,5 @@ export default {
border-bottom: 0;
}
}
}
</style>

@ -156,6 +156,7 @@ export default {
courseProfessional: `nakadai/nakadai/subject/courseProfessional`, //课程专业
//课程管理
curriculumList: `nakadai/nakadai/curriculum/curriculumList`, //课程列表
curriculumTree: `nakadai/nakadai/curriculum/curriculumTree`,
createCurriculum: `nakadai/nakadai/curriculum/createCurriculum`, //创建课程
configureCourseProject: `nakadai/nakadai/curriculum/configureCourseProject`,
curriculumDetail: `nakadai/nakadai/curriculum/curriculumDetail`, //课程详情
@ -181,6 +182,7 @@ export default {
delTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/batchDeletion`,
findTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/findById`,
listTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/pageConditionalQueryCourse`,
boutiqueCurriculumTree: `occupationlab/occupationlab/theoreticalCourse/boutiqueCurriculumTree`,
saveTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/save`,
updateTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/update`,
disabledTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/disabledEvents`,

@ -13,10 +13,10 @@
<el-button type="primary" size="mini" @click="addChapter" v-auth="'/curriculum:内容设置:添加章节'">新增章节</el-button>
</div>
<ul class="chapters">
<li v-for="(chapter, i) in chapters" :key="i">
<span class="name ellipsis">{{ chapter.name }}</span>
<li v-for="(chapter, i) in chapters" :key="i" :class="{ active: chapterId === chapter.id }">
<span class="name ellipsis" @click="chapterClick(chapter)">{{ chapter.name }}</span>
<el-link :underline="false" type="primary" @click="editChapter(chapter)">修改名称</el-link>
<el-link class="del" underline="false" type="primary" @click="delChapter(chapter.id)">删除</el-link>
<el-link v-if="i" class="del" :underline="false" type="primary" @click="delChapter(chapter.id)">删除</el-link>
</li>
</ul>
</div>
@ -27,196 +27,145 @@
<div>
<el-button class="action-btn" @click="showSource" v-auth="'/curriculum:内容设置:修改章节名称'">添加系统资源</el-button>
<el-button class="action-btn" @click="addSection" v-auth="'/curriculum:内容设置:添加小节'">本地上传</el-button>
<el-button class="action-btn" @click="delChapter" v-auth="'/curriculum:内容设置:删除章节'">批量移动</el-button>
<el-button class="action-btn" @click="delChapter" v-auth="'/curriculum:内容设置:删除章节'">批量移除</el-button>
<el-button class="action-btn" @click="move" v-auth="'/curriculum:内容设置:删除章节'">批量移动</el-button>
<el-button class="action-btn" v-auth="'/curriculum:内容设置:删除章节'">批量移除</el-button>
</div>
</div>
</div>
</div>
<div class="page mgb20" style="display: none">
<div class="relative">
<div class="p-title">内容设置</div>
<div class="btns">
<template v-if="!sorting">
<el-button type="primary" round @click="addChapter" v-auth="'/curriculum:内容设置:添加章节'">添加章节</el-button>
<el-button type="primary" round @click="sort" v-auth="'/curriculum:内容设置:编辑排序'">编辑顺序</el-button>
</template>
<template v-else>
<el-button type="primary" round @click="move">批量移动</el-button>
<el-button type="primary" round @click="cancelSort">取消</el-button>
<el-button type="primary" round @click="saveSort">保存</el-button>
</template>
</div>
</div>
<el-divider></el-divider>
<div class="page-content">
<div class="mgb20" v-for="(chapter, index) in chapters" :key="chapter.id">
<div class="flex-between mgb10">
<div>{{ chapter.name }}</div>
<div>
<template v-if="!sorting">
<el-button class="action-btn" plain @click="editChapter(chapter)"
v-auth="'/curriculum:内容设置:修改章节名称'">修改章节名称</el-button>
<el-button class="action-btn" plain @click="addSection(chapter.id)"
v-auth="'/curriculum:内容设置:添加小节'">添加小节</el-button>
<el-button class="action-btn" plain @click="delChapter(chapter.id)"
v-auth="'/curriculum:内容设置:删除章节'">删除</el-button>
</template>
<template v-else>
<i class="el-icon-top sort-icon" :class="{ disabled: index == 0 }" style="margin-right: 5px"
@click="sortChapter(chapter, 'up', index == 0, index)"></i>
<i class="el-icon-bottom sort-icon" :class="{ disabled: index == chapters.length - 1 }"
@click="sortChapter(chapter, 'down', index == chapter.length - 1, index)"></i>
</template>
<ul class="sections">
<li v-for="(section, i) in sections" :key="i">
<div class="section-left">
<el-checkbox v-model="section.check"></el-checkbox>
<span class="serial">{{ i + 1 }}.</span>
<img v-if="section.fileType === 'pptx'" src="@/assets/img/exts/ppt.png" alt="">
<img v-else-if="section.fileType === 'mp4'" src="@/assets/img/exts/video.png" alt="">
<img v-else-if="section.fileType === 'doc' || section.fileType === 'docx'"
src="@/assets/img/exts/word.png" alt="">
<img v-else-if="section.fileType === 'xlsx' || section.fileType === 'xls'"
src="@/assets/img/exts/excel.png" alt="">
<img v-else-if="section.fileType === 'txt'" src="@/assets/img/exts/txt.png" alt="">
<img v-else-if="section.fileType === 'pdf'" src="@/assets/img/exts/pdf.png" alt="">
<img v-else src="@/assets/img/exts/pic.png" alt="">
<span class="name">{{ section.name }}</span>
</div>
</div>
<el-table :data="chapter.subsectionList" class="table" header-align="center" row-key="id">
<el-table-column v-if="sorting" width="55" align="center">
<template slot-scope="scope">
<el-checkbox v-model="scope.row.check"></el-checkbox>
</template>
</el-table-column>
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column prop="name" label="资源名称">
</el-table-column>
<el-table-column prop="fileType" label="资源类型" align="center">
<template slot-scope="scope">
{{ transferType(scope.row.fileType) }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="300">
<template slot-scope="scope">
<template v-if="!sorting">
<el-button type="text" @click="download(scope.row)" v-auth="'/curriculum:内容设置:下载'">下载</el-button>
<el-button type="text" @click="preview(scope.row)" v-auth="'/curriculum:内容设置:查看'">查看</el-button>
<el-button type="text" @click="delSection(scope.row)" v-auth="'/curriculum:内容设置:删除小节'">删除</el-button>
<el-button type="text" @click="editSectionName(scope.row, chapter.id)"
v-auth="'/curriculum:内容设置:修改小节名称'">修改小节名称</el-button>
<el-button type="text" @click="switchFile(scope.row, chapter.id)"
v-auth="'/curriculum:内容设置:更换文件'">更换文件</el-button>
</template>
<template v-else>
<i class="el-icon-top sort-icon" :class="{ disabled: scope.$index == 0 }" style="margin-right: 5px"
@click="sortSection(index, 'up', scope.$index == 0, scope.$index)"></i>
<i class="el-icon-bottom sort-icon"
:class="{ disabled: scope.$index == chapter.subsectionList.length - 1 }"
@click="sortSection(index, 'down', scope.$index == chapter.subsectionList.length - 1, scope.$index)"></i>
</template>
</template>
</el-table-column>
</el-table>
</div>
<el-dialog :title="chapterId ? '编辑章节' : '新增章节'" :visible.sync="chapterVisible" width="540px"
:close-on-click-modal="false">
<el-form>
<el-form-item>
<el-input placeholder="请输入章节名称,便于对小节归类" v-model="chapterName" maxlength="50"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="chapterVisible = false">取消</el-button>
<el-button type="primary" @click="chapterSubmit">确定</el-button>
</span>
</el-dialog>
<div class="section-actions">
<el-button type="text" @click="download(section)" v-auth="'/curriculum:内容设置:下载'">下载</el-button>
<el-button type="text" @click="preview(section)" v-auth="'/curriculum:内容设置:查看'">预览</el-button>
<el-button type="text" @click="editSectionName(section)"
v-auth="'/curriculum:内容设置:修改小节名称'">修改资源名称</el-button>
<el-button type="text" @click="switchFile(section)" v-auth="'/curriculum:内容设置:更换文件'">更换</el-button>
<el-button type="text" @click="delSection(section)" v-auth="'/curriculum:内容设置:删除小节'">移除</el-button>
</div>
</li>
</ul>
</div>
</div>
<el-dialog title="添加小节" :visible.sync="sectionVisible" width="540px" @close="closeSection"
:close-on-click-modal="false">
<el-form ref="form" :model="sectionForm" label-width="80px" @submit.native.prevent>
<el-form-item label="资源添加">
<Upload :max-size="100000" :file-list="uploadList" :on-remove="handleRemove" @beforeUpload="beforeUpload"
@onSuccess="uploadSuccess">
<template slot="tip">
<p>视频请上传MP4格式大小不超过150Moffice文件大小不要超过10M</p>
</template>
</Upload>
</el-form-item>
<el-form-item label="小节名称">
<el-input placeholder="请输入小节名称" v-model.trim="sectionForm.sectionName" maxlength="50"
@keyup.enter.native="sectionSubmit()"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="sectionVisible = false">取消</el-button>
<el-button type="primary" @click="sectionSubmit">确定</el-button>
</span>
</el-dialog>
<el-dialog :title="chapterId ? '编辑章节' : '新增章节'" :visible.sync="chapterVisible" width="540px"
:close-on-click-modal="false">
<el-form>
<el-form-item>
<el-input placeholder="请输入章节名称,便于对小节归类" v-model="chapterName" maxlength="50"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="chapterVisible = false">取消</el-button>
<el-button type="primary" @click="chapterSubmit">确定</el-button>
</span>
</el-dialog>
<el-dialog title="更换文件" :visible.sync="switchVisible" width="540px" :close-on-click-modal="false"
@close="closeSwitch">
<div style="text-align: center">
<Upload :max-size="100000" :file-list="uploadList" :on-remove="handleRemove" @beforeUpload="beforeUpload"
@onSuccess="uploadSuccess">
<div slot="tip"></div>
</Upload>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="switchVisible = false">取消</el-button>
<el-button type="primary" @click="switchSubmit">确定</el-button>
</span>
</el-dialog>
<el-dialog title="添加小节" :visible.sync="sectionVisible" width="540px" @close="closeSection"
:close-on-click-modal="false">
<el-form ref="form" :model="sectionForm" label-width="80px" @submit.native.prevent>
<el-form-item label="资源添加">
<Upload :max-size="100000" :file-list="uploadList" :on-remove="handleRemove" @beforeUpload="beforeUpload"
@onSuccess="uploadSuccess">
<template slot="tip">
<p>视频请上传MP4格式大小不超过150Moffice文件大小不要超过10M</p>
</template>
</Upload>
</el-form-item>
<el-form-item label="小节名称">
<el-input placeholder="请输入小节名称" v-model.trim="sectionForm.sectionName" maxlength="50"
@keyup.enter.native="sectionSubmit()"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="sectionVisible = false">取消</el-button>
<el-button type="primary" @click="sectionSubmit">确定</el-button>
</span>
</el-dialog>
<el-dialog title="修改小节名称" :visible.sync="sectionNameVisible" width="540px" :close-on-click-modal="false">
<el-form @submit.native.prevent>
<el-form-item>
<el-input placeholder="请输入小节名称" v-model="sectionForm.sectionName" maxlength="50"
@keyup.enter.native="sectionNameSubmit()"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="sectionNameVisible = false">取消</el-button>
<el-button type="primary" @click="sectionNameSubmit">确定</el-button>
</span>
</el-dialog>
<el-dialog title="更换文件" :visible.sync="switchVisible" width="540px" :close-on-click-modal="false"
@close="closeSwitch">
<div style="text-align: center">
<Upload :max-size="100000" :file-list="uploadList" :on-remove="handleRemove" @beforeUpload="beforeUpload"
@onSuccess="uploadSuccess">
<div slot="tip"></div>
</Upload>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="switchVisible = false">取消</el-button>
<el-button type="primary" @click="switchSubmit">确定</el-button>
</span>
</el-dialog>
<div v-show="previewImg" class="el-image-viewer__wrapper" :class="{ active: previewImg }" style="z-index: 2000">
<div class="el-image-viewer__mask"></div>
<span class="el-image-viewer__btn el-image-viewer__close" @click="previewImg = ''"><i
class="el-icon-circle-close" style="color: #fff"></i></span>
<div class="el-image-viewer__canvas">
<img :src="previewImg" class="el-image-viewer__img"
style="transform: scale(1) rotate(0deg);margin-top: -1px; max-height: 100%; max-width: 100%;">
</div>
</div>
<div v-show="iframeSrc || videoSrc" class="el-image-viewer__wrapper" :class="{ active: iframeSrc }"
style="z-index: 2000">
<div class="el-image-viewer__mask"></div>
<span class="el-image-viewer__btn el-image-viewer__close" :class="{ 'doc-close': isWord }"
:style="{ top: isWord ? '50px' : '5px' }" @click="closeIframe"><i class="el-icon-circle-close"
style="color: #fff"></i></span>
<div class="el-image-viewer__canvas">
<iframe v-if="iframeSrc" class="fileIframe" id="fileIframe" :src="iframeSrc" frameborder="0"></iframe>
<video v-if="videoSrc" class="video" width="1200" height="600" autoplay controls>
<source :src="videoSrc" type="video/mp4">
您的浏览器不支持 video 标签
</video>
<template v-if="showMask">
<div class="mask" style="width: 200px;height: 30px;top: 53px;right: 320px"></div>
<div class="mask" style="width: 175px;height: 30px;top: 53px;right: 5px"></div>
</template>
<template v-if="showMask1">
<div class="word-mask1" style="width: 200px;height: 50px;"></div>
<div class="word-mask" style="height: 40px;top: 48px;"></div>
<div class="word-mask2" style="top: 55px;left: 28%;width: 44%;height: calc(100% - 80px);"></div>
</template>
<template v-if="showMask2 && iframeSrc">
<div class="excel-mask1" style="height: 48px;"></div>
</template>
</div>
</div>
<div v-show="playAuth" class="el-image-viewer__wrapper" :class="{ active: playAuth }" style="z-index: 2000">
<div class="el-image-viewer__mask"></div>
<span class="el-image-viewer__btn el-image-viewer__close" @click="closePlayer"><i class="el-icon-circle-close"
style="color: #fff"></i></span>
<div class="player" id="player"></div>
</div>
<el-dialog title="修改小节名称" :visible.sync="sectionNameVisible" width="540px" :close-on-click-modal="false">
<el-form @submit.native.prevent>
<el-form-item>
<el-input placeholder="请输入小节名称" v-model="sectionForm.sectionName" maxlength="50"
@keyup.enter.native="sectionNameSubmit()"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="sectionNameVisible = false">取消</el-button>
<el-button type="primary" @click="sectionNameSubmit">确定</el-button>
</span>
</el-dialog>
<Pdf :visible.sync="pdfVisible" :src.sync="pdfSrc" />
<div v-show="previewImg" class="el-image-viewer__wrapper" :class="{ active: previewImg }" style="z-index: 2000">
<div class="el-image-viewer__mask"></div>
<span class="el-image-viewer__btn el-image-viewer__close" @click="previewImg = ''"><i class="el-icon-circle-close"
style="color: #fff"></i></span>
<div class="el-image-viewer__canvas">
<img :src="previewImg" class="el-image-viewer__img"
style="transform: scale(1) rotate(0deg);margin-top: -1px; max-height: 100%; max-width: 100%;">
</div>
</div>
<div v-show="iframeSrc || videoSrc" class="el-image-viewer__wrapper" :class="{ active: iframeSrc }"
style="z-index: 2000">
<div class="el-image-viewer__mask"></div>
<span class="el-image-viewer__btn el-image-viewer__close" :class="{ 'doc-close': isWord }"
:style="{ top: isWord ? '50px' : '5px' }" @click="closeIframe"><i class="el-icon-circle-close"
style="color: #fff"></i></span>
<div class="el-image-viewer__canvas">
<iframe v-if="iframeSrc" class="fileIframe" id="fileIframe" :src="iframeSrc" frameborder="0"></iframe>
<video v-if="videoSrc" class="video" width="1200" height="600" autoplay controls>
<source :src="videoSrc" type="video/mp4">
您的浏览器不支持 video 标签
</video>
<template v-if="showMask">
<div class="mask" style="width: 200px;height: 30px;top: 53px;right: 320px"></div>
<div class="mask" style="width: 175px;height: 30px;top: 53px;right: 5px"></div>
</template>
<template v-if="showMask1">
<div class="word-mask1" style="width: 200px;height: 50px;"></div>
<div class="word-mask" style="height: 40px;top: 48px;"></div>
<div class="word-mask2" style="top: 55px;left: 28%;width: 44%;height: calc(100% - 80px);"></div>
</template>
<template v-if="showMask2 && iframeSrc">
<div class="excel-mask1" style="height: 48px;"></div>
</template>
</div>
</div>
<div v-show="playAuth" class="el-image-viewer__wrapper" :class="{ active: playAuth }" style="z-index: 2000">
<div class="el-image-viewer__mask"></div>
<span class="el-image-viewer__btn el-image-viewer__close" @click="closePlayer"><i class="el-icon-circle-close"
style="color: #fff"></i></span>
<div class="player" id="player"></div>
</div>
<Pdf :visible.sync="pdfVisible" :src.sync="pdfSrc" />
<div class="player-download" id="playerDownload"></div>
<el-dialog title="资源移动" :visible.sync="moveVisible" :close-on-click-modal="false" width="330px">
@ -281,6 +230,8 @@ export default {
sectionForm: {
sectionName: ''
},
keyword: '',
searchTimer: null,
fileId: "",
fileName: "",
fileUrl: "",
@ -321,8 +272,8 @@ export default {
id: '',
sort: 'bottom'
},
moved: false, //
sourceVisible: false
sourceVisible: false,
sections: []
};
},
components: { Pdf, Upload, Source },
@ -340,45 +291,23 @@ export default {
},
methods: {
getData () {
this.$get(`${this.api.queryChaptersAndSubsections}/${this.id}`)
.then(res => {
this.chapters = res.chapterList;
})
.catch(err => {
});
this.$get(`${this.api.queryChaptersAndSubsections}/${this.id}`).then(res => {
const list = res.chapterList
if (list.length) {
if (this.chapterId) {
const cur = list.find(e => e.id === this.chapterId)
this.sections = cur ? cur.subsectionList : []
} else {
this.chapterClick(list[0])
}
}
this.chapters = list
}).catch(err => { })
},
//
handleSelectionChange (val) {
this.multipleSelection = val
},
back () {
//
if (this.previewing) {
this.closeIframe();
} else {
//
if (this.sorting) {
//
if (this.moved) {
this.$confirm(`编辑的内容未保存,是否保存?`, '提示', {
type: 'warning',
closeOnClickModal: false
}).then(() => {
this.saveSort()
this.moved = false
}).catch(() => {
this.sorting = false
this.chapters = JSON.parse(JSON.stringify(this.originChapters))
})
} else {
this.sorting = false
}
} else {
this.$router.push(this.$store.state.referrer || '/curriculum')
}
}
},
iframeOnload () {
document.querySelector("#fileIframe").onload = e => {
if (this.isPPT) {
@ -521,7 +450,7 @@ export default {
]
},
//
moveConfirm () {
async moveConfirm () {
let { id, sort } = this.moveForm
if (!id) return this.$message.warning('请选择目标章节')
if (sort === '') return this.$message.warning('请选择目标排序')
@ -542,27 +471,26 @@ export default {
delete e.children
if (e.id === id) e.subsectionList.splice(sort, 0, ...list)
})
this.moved = true
},
cancelSort () {
this.chapters = JSON.parse(JSON.stringify(this.originChapters))
this.sorting = false;
},
saveSort () {
this.chapters.forEach((n, k) => {
n.sort = k + 1;
chapters.forEach((n, k) => {
n.sort = k + 1
n.subsectionList.forEach((j, i) => {
j.sort = i + 1
j.chapterId = n.id
});
});
let data = {
})
})
await this.$post(this.api.reorder, {
chapterVOList: this.chapters
};
this.$post(this.api.reorder, data).then(res => {
this.sorting = false;
}).catch(res => { })
})
this.getData()
},
//
chapterClick (row) {
row.subsectionList.map(e => this.$set(e, 'check', false))
this.sections = row.subsectionList
this.chapterId = row.id
},
//
editChapter (item) {
this.chapterId = item.id;
this.chapterName = item.name;
@ -571,13 +499,12 @@ export default {
delChapter (id) {
this.$confirm("此删除操作不可逆,是否确认删除选中项?", "提示", {
type: "warning"
})
.then(() => {
this.$del(`${this.api.deleteChapter}/${id}`).then(res => {
this.$message.success("删除成功");
this.getData();
}).catch(res => { });
}).catch(() => { });
}).then(() => {
this.$del(`${this.api.deleteChapter}/${id}`).then(res => {
this.$message.success("删除成功")
this.getData()
}).catch(res => { })
}).catch(() => { })
},
closeSection () {
this.isAddSection = false;
@ -589,13 +516,12 @@ export default {
this.sourceVisible = true
},
addSection (id) {
this.chapterId = id;
this.sectionForm.sectionName = "";
this.fileUrl = "";
this.uploadList = [];
this.sectionId = "";
this.isAddSection = true;
this.sectionVisible = true;
this.sectionForm.sectionName = ''
this.fileUrl = ''
this.uploadList = []
this.sectionId = ''
this.isAddSection = true
this.sectionVisible = true
},
chapterSubmit () {
if (!this.chapterName) return this.$message.warning("请填写章节名称");
@ -735,23 +661,21 @@ export default {
});
}
},
editSectionName (row, chapterId) {
this.chapterId = chapterId;
editSectionName (row) {
this.sectionId = row.id;
this.sectionForm.sectionName = row.name;
this.sectionNameVisible = true;
},
switchFile (row, chapterId, sectionId) {
this.uploadList = [];
switchFile (row) {
this.uploadList = []
this.curFile = {
fileId: row.fileId,
fileName: row.fileName,
fileType: row.fileType,
fileUrl: row.fileUrl
};
this.chapterId = chapterId;
this.sectionId = row.id;
this.sectionForm.sectionName = row.sectionName;
}
this.sectionId = row.id
this.sectionForm.sectionName = row.sectionName
this.switchVisible = true;
},
@ -771,9 +695,7 @@ export default {
this.$message.success("更换成功");
this.switchVisible = false;
this.getData();
})
.catch(err => {
});
}).catch(err => { })
},
switchSubmit () {
if (this.uploading) return this.$message.warning("资源正在上传中,请稍候");
@ -791,9 +713,7 @@ export default {
this.getData();
}).catch(res => {
});
})
.catch(() => {
});
}).catch(() => { })
},
sortChapter (row, type, disabled, index) {
if (!disabled) {
@ -806,20 +726,6 @@ export default {
}
}
},
sortSection (chapterIndex, type, disabled, index) {
if (!disabled) {
this.moved = true
let list = this.chapters[chapterIndex].subsectionList;
if (type == "up") {
let tempItem = list.splice(index - 1, 1)[0];
list.splice(index, 0, tempItem);
} else {
let tempItem = list.splice(index + 1, 1)[0];
list.splice(index, 0, tempItem);
}
this.chapters[chapterIndex].subsectionList = list;
}
},
sectionNameSubmit () {
if (!this.sectionForm.sectionName) return this.$message.warning("请填写小节名称");
let data = {
@ -829,12 +735,10 @@ export default {
name: this.sectionForm.sectionName
};
this.$put(this.api.editSubsection, data).then(res => {
this.$message.success("修改成功");
this.sectionNameVisible = false;
this.$message.success("修改成功")
this.sectionNameVisible = false
this.getData();
})
.catch(err => {
});
}).catch(err => { })
},
closePlayer () {
this.playAuth = "";
@ -847,7 +751,15 @@ export default {
this.showMask1 = false;
this.showMask2 = false;
this.previewing = false;
}
},
back () {
//
if (this.previewing) {
this.closeIframe();
} else {
this.$router.push(this.$store.state.referrer || '/curriculum')
}
},
}
};
</script>
@ -987,9 +899,12 @@ export default {
.left {
width: 400px;
padding: 15px;
height: calc(100vh - 247px);
padding: 0 15px 15px 0;
margin-right: 20px;
border: 1px dashed #eee;
border-right: 1px solid #eee;
box-sizing: border-box;
overflow: auto;
.title {
font-size: 16px;
@ -1001,11 +916,15 @@ export default {
li {
display: flex;
padding: 5px 0;
padding: 5px 10px;
&.active {
background-color: #d5e7fb;
}
}
.name {
width: 71%;
width: 68%;
margin-right: 20px;
font-size: 14px;
color: #333;
@ -1023,6 +942,37 @@ export default {
.right {
flex: 1;
.sections {
margin-top: 20px;
li {
display: flex;
justify-content: space-between;
padding: 5px 10px;
margin-bottom: 10px;
background-color: #f9f9f9;
}
.section-left,
.section-right {
display: inline-flex;
align-items: center;
}
.serial {
margin: 0 8px;
font-size: 14px;
color: #858585;
}
.name {
margin-left: 10px;
font-size: 12px;
color: #333;
}
}
}
}
</style>

@ -12,18 +12,42 @@
</div>
<div class="course">
<div class="item">
<div v-for="(course, i) in course" :key="i" class="item">
<div class="line">
<i class="el-icon-caret-right arrow"></i>
<el-checkbox class="check" v-model="checked"></el-checkbox>
<img class="cover" src="" alt="">
<span class="course-name"></span>
<i :class="`el-icon-caret-right arrow ${course.shrink ? 'active' : ''}`"
@click="course.shrink = !course.shrink"></i>
<el-checkbox class="check" v-model="course.check" @change="checkCourse(course)"></el-checkbox>
<img v-if="course.coverUrl" class="cover" :src="course.coverUrl" alt="">
<span class="course-name">{{ course.curriculumName }}</span>
</div>
<div class="chapters">
<div class="line">
<i class="el-icon-caret-right arrow"></i>
<el-checkbox class="check" v-model="checked"></el-checkbox>
<span class="chapter-name"></span>
<div v-if="course.shrink" class="chapters">
<!-- 章节 -->
<div v-for="(chapter, j) in course.chapters" :key="j" class="">
<div class="line">
<i :class="`el-icon-caret-right arrow ${chapter.shrink ? 'active' : ''}`"
@click="chapter.shrink = !chapter.shrink"></i>
<el-checkbox class="check" v-model="chapter.check" @change="checkChapter(chapter, course)">{{
chapter.name
}}</el-checkbox>
</div>
<!-- 小节 -->
<div v-if="chapter.shrink" class="sections">
<div v-for="(section, k) in chapter.subsections" :key="k" class="line">
<img v-if="section.fileType === 'pptx'" src="@/assets/img/exts/ppt.png" alt="">
<img v-else-if="section.fileType === 'mp4'" src="@/assets/img/exts/video.png" alt="">
<img v-else-if="section.fileType === 'doc' || section.fileType === 'docx'"
src="@/assets/img/exts/word.png" alt="">
<img v-else-if="section.fileType === 'xlsx' || section.fileType === 'xls'"
src="@/assets/img/exts/excel.png" alt="">
<img v-else-if="section.fileType === 'txt'" src="@/assets/img/exts/txt.png" alt="">
<img v-else-if="section.fileType === 'pdf'" src="@/assets/img/exts/pdf.png" alt="">
<img v-else src="@/assets/img/exts/pic.png" alt="">
<el-checkbox class="check" v-model="section.check" @change="checkSection(section, chapter)">{{
section.name
}}</el-checkbox>
</div>
</div>
</div>
</div>
</div>
@ -31,22 +55,21 @@
</div>
<div class="right">
<template v-if="checked.length">
<div class="flex-between">
<div class="flex-between m-b-10">
<p class="total">已选资源{{ checked.length }}</p>
<el-button type="text" @click="batchDelChecked">批量移除</el-button>
</div>
<el-input placeholder="请输入资源名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
<el-input placeholder="请输入资源名称" prefix-icon="el-icon-search" v-model="checkedKeyword" clearable></el-input>
<div :class="['lines']">
<template v-for="(item, i) in checked">
<div v-if="item.stemText.includes(checkedKeyword) || item.knowledgePointName.includes(checkedKeyword)"
:key="i" class="line">
<div v-if="item.name.includes(checkedKeyword)" :key="i" class="line">
<div class="check-left">
<el-checkbox v-model="item.check"></el-checkbox>
<span class="serial">{{ i + 1 }}</span>
<el-tooltip effect="dark" :content="item.stemText" placement="top-start">
<p class="checked-name ellipsis">{{ item.stemText }}</p>
<el-tooltip effect="dark" :content="item.name" placement="top-start">
<p class="checked-name ellipsis">{{ item.name }}</p>
</el-tooltip>
</div>
<i class="el-icon-delete action-icon" @click="delChecked(item)"></i>
@ -71,6 +94,7 @@
<script>
import Setting from '@/setting'
import Util from '@/libs/util'
import _ from 'lodash'
export default {
props: ['visible'],
data () {
@ -84,11 +108,10 @@ export default {
},
keyword: '',
searchTimer: null,
checkedKeyword: '',
allSections: [],
course: [],
page: 1,
pageSize: 10,
total: 0,
checked: [],
submiting: false,
@ -98,7 +121,7 @@ export default {
watch: {
'keyword': function (val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(this.initQuesBank, 500)
this.searchTimer = setTimeout(this.getCourse, 500)
},
visible () {
this.sourceVisible = this.visible
@ -115,14 +138,26 @@ export default {
},
//
async getCourse () {
const sid = this.$store.state.dataPer.find(e => e.permissionName === '课程管理')
const { page } = await this.$post(this.api.curriculumList, {
pageNum: this.page,
pageSize: this.pageSize,
supplierId: sid ? sid.supplierId : ''
})
this.course = page.records
this.total = page.total
const { list } = await this.$post(`${this.api[this.active === 'tab1' ? 'curriculumTree' : 'boutiqueCurriculumTree']}?name=${this.keyword}`)
if (list.length) {
const all = []
list.forEach(e => {
e.shrink = false
e.check = false
e.chapters.forEach(n => {
n.shrink = false
n.check = false
all.push(...n.subsections)
n.subsections.forEach(m => {
m.check = false
})
})
})
list[0].shrink = true
list[0].chapters[0].shrink = true
this.allSections = all
}
this.course = list
},
initData () {
this.page = 1;
@ -130,6 +165,63 @@ export default {
},
tabChange (index) {
this.active = index
this.getCourse()
},
//
checkCourse (row) {
const { check } = row
const { checked } = this
row.chapters.forEach(e => {
e.check = check
e.subsections.forEach(n => {
n.check = check
const cur = checked.findIndex(m => m.id === n.id)
if (check) {
if (cur === -1) {
const section = _.cloneDeep(n)
section.check = false
checked.push(section)
}
} else {
cur !== -1 && checked.splice(cur, 1)
}
})
})
},
//
checkChapter (row, course) {
const { check } = row
const { checked } = this
row.subsections.forEach(n => {
n.check = check
const cur = checked.findIndex(m => m.id === n.id)
if (check) {
if (cur === -1) {
const section = _.cloneDeep(n)
section.check = false
checked.push(section)
}
} else {
cur !== -1 && checked.splice(cur, 1)
}
})
course.check = course.chapters.every(e => e.check)
},
//
async checkSection (row, chapter) {
const { check } = row
const { checked } = this
const cur = checked.findIndex(m => m.id === row.id)
if (check) {
if (cur === -1) {
const section = _.cloneDeep(row)
section.check = false
this.checked.push(section)
}
} else {
cur !== -1 && this.checked.splice(cur, 1)
}
chapter.check = chapter.subsections.every(e => e.check)
},
//
@ -138,13 +230,11 @@ export default {
const checked = this.checked.filter(e => e.check)
if (checked.length) {
checked.map(e => {
const cur = this.ques.find(n => n.questionVersionId === e.questionVersionId)
const cur = this.allSections.find(n => n.id === e.id)
if (cur) {
cur.check = false
}
})
this.quesAllCheck = false
this.checkedAllCheck = false
this.checked = this.checked.filter(e => !e.check)
} else {
Util.warningMsg('请选择数据')
@ -154,17 +244,15 @@ export default {
//
async delChecked (item) {
try {
const cur = this.ques.find(e => e.questionVersionId === item.questionVersionId)
const cur = this.allSections.find(e => e.id === item.id)
if (cur) cur.check = false
this.checked.splice(this.checked.findIndex(e => e.questionVersionId === item.questionVersionId), 1)
this.checked.splice(this.checked.findIndex(e => e.id === item.id), 1)
} catch (e) { }
},
//
async submit () {
try {
const res = await this.$post(this.api.selectQuestionsByTypeAndDifficulty, list)
let invalid = 0
let hasQues = 0
list.map((e, i) => {
@ -225,15 +313,15 @@ export default {
.left {
width: 700px;
height: calc(100vh - 125px);
padding: 0 20px;
overflow: auto;
padding: 15px;
margin-right: 20px;
border-right: 1px solid #eee;
box-sizing: border-box;
.course {
height: calc(100vh - 263px);
overflow: auto;
.item {
padding: 10px;
margin-bottom: 10px;
@ -241,8 +329,6 @@ export default {
}
}
.line {
display: flex;
align-items: center;
@ -250,8 +336,13 @@ export default {
.arrow {
font-size: 16px;
color: #333;
color: #9f9f9f;
cursor: pointer;
transition: .3s;
&.active {
transform: rotate(90deg);
}
}
.check {
@ -261,21 +352,43 @@ export default {
.cover {
width: 100px;
max-height: 80px;
margin-right: 15px;
}
.course-name {
font-size: 16px;
font-size: 14px;
color: #333;
}
.chapters {
padding-left: 21px;
margin-top: 10px;
.line {
margin-bottom: 10px;
}
}
.chapter-name {
font-size: 14px;
font-size: 13px;
color: #ccc;
}
.sections {
padding-left: 26px;
}
}
.right {
flex: 1;
padding: 15px;
.lines {
height: calc(100vh - 228px);
padding-right: 10px;
margin-top: 10px;
overflow: auto;
}
.line {
display: flex;
@ -290,13 +403,19 @@ export default {
white-space: nowrap;
}
.check-left {
display: inline-flex;
align-items: center;
}
.checked-name {
width: calc(100% - 210px);
width: 360px;
margin-right: 20px;
}
.action-icon {
font-size: 14px;
cursor: pointer;
}
}
}

Loading…
Cancel
Save