From 7abfb5437aebdba0c4f6b64cf5ce12880a0a944c Mon Sep 17 00:00:00 2001 From: yujialong <479214531@qq.com> Date: Tue, 17 Dec 2024 18:11:51 +0800 Subject: [PATCH] fix --- src/api/index.js | 2 + src/assets/img/drag.svg | 1 + src/pages/lesson/content/index.vue | 125 +++++++++++++++++----------- src/pages/lesson/detail/index.vue | 31 ++++++- src/pages/lesson/list/index.vue | 71 +++++++++++++--- src/pages/station/preview/index.vue | 43 +++++----- 6 files changed, 190 insertions(+), 83 deletions(-) create mode 100644 src/assets/img/drag.svg diff --git a/src/api/index.js b/src/api/index.js index fa374ea..4096ae7 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -520,6 +520,8 @@ export default { curriculumList: `nakadai/nakadai/curriculum/curriculumList`, createCurriculum: `nakadai/nakadai/curriculum/createCurriculum`, modifyCourse: `nakadai/nakadai/curriculum/modifyCourse`, + schoolCourseProject: `nakadai/nakadai/curriculum/schoolCourseProject`, + // schoolCourseProject: `nakadai/nakadai/curriculum/schoolCourseProject`, // 教师评语 addComment: `evaluation/cevaluation/comment/addComment`, diff --git a/src/assets/img/drag.svg b/src/assets/img/drag.svg new file mode 100644 index 0000000..3fba973 --- /dev/null +++ b/src/assets/img/drag.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1734423793915" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7651" width="16" height="16" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M362.666667 192m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z" fill="#666666" p-id="7652"></path><path d="M661.333333 192m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z" fill="#666666" p-id="7653"></path><path d="M362.666667 512m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z" fill="#666666" p-id="7654"></path><path d="M661.333333 512m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z" fill="#666666" p-id="7655"></path><path d="M362.666667 832m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z" fill="#666666" p-id="7656"></path><path d="M661.333333 832m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z" fill="#666666" p-id="7657"></path></svg> \ No newline at end of file diff --git a/src/pages/lesson/content/index.vue b/src/pages/lesson/content/index.vue index 9c18a0d..8fcfd73 100644 --- a/src/pages/lesson/content/index.vue +++ b/src/pages/lesson/content/index.vue @@ -1,6 +1,6 @@ <template> <div> - <el-card shadow="hover" class="mgb20"> + <el-card shadow="hover" class="m-b-20"> <div class="flex-between"> <el-page-header @back="back" :content="name + '/' + (sorting ? '编辑排序' : '内容设置')"></el-page-header> </div> @@ -33,30 +33,33 @@ </div> <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 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> + <draggable v-model="sections" :group="dragGroup" chosenClass="chosen" animation="1000" @update="updateSort"> + <li v-for="(section, i) in sections" :key="i"> + <div class="section-left"> + <img class="drag" src="@/assets/img/drag.svg" alt=""> + <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 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> + </draggable> </ul> </div> </div> @@ -198,14 +201,13 @@ import Upload from '@/components/upload'; import Oss from '@/components/upload/upload.js' import Util from '@/libs/util' import Source from './source' +import Draggable from 'vuedraggable' export default { + components: { Pdf, Upload, Source, Draggable }, data () { return { name: this.$route.query.name, - headers: { - token: sessionStorage.getItem('token') - }, id: this.$route.query.cid, originChapters: [], chapters: [], @@ -273,10 +275,13 @@ export default { sort: 'bottom' }, sourceVisible: false, - sections: [] + sections: [], + + dragGroup: { + pull: false, + }, }; }, - components: { Pdf, Upload, Source }, mounted () { this.insertScript(); this.id && this.getData(); @@ -291,7 +296,7 @@ export default { }, methods: { getData () { - this.$get(`${this.api.queryChaptersAndSubsections}/${this.id}`).then(res => { + this.$get(`${this.api.curriculumChapter}/${this.id}`).then(res => { const list = res.chapterList if (list.length) { list.forEach(e => { @@ -449,6 +454,24 @@ export default { this.getData() }).catch(() => { }) }, + // 拖拽后回调 + async updateSort (e) { + e.preventDefault() + console.log(33, this.sections) + const { chapters, sections, chapterId } = this + chapters.forEach((n, k) => { + n.sort = k + 1 + if (n.id === chapterId) n.subsectionList = sections + n.subsectionList.forEach((j, i) => { + j.sort = i + 1 + j.chapterId = n.id + }) + }) + await this.$post(this.api.reorder, { + chapterVOList: chapters + }) + this.getData() + }, // 目标章节选择回调 chapterChange (id) { const list = [] @@ -741,46 +764,45 @@ export default { sortChapter (row, type, disabled, index) { if (!disabled) { if (type == "up") { - let tempItem = this.chapters.splice(index - 1, 1)[0]; - this.chapters.splice(index, 0, tempItem); + let tempItem = this.chapters.splice(index - 1, 1)[0] + this.chapters.splice(index, 0, tempItem) } else { - let tempItem = this.chapters.splice(index + 1, 1)[0]; - this.chapters.splice(index, 0, tempItem); + let tempItem = this.chapters.splice(index + 1, 1)[0] + this.chapters.splice(index, 0, tempItem) } } }, sectionNameSubmit () { - if (!this.sectionForm.sectionName) return this.$message.warning("请填写小节名称"); - let data = { + if (!this.sectionForm.sectionName) return this.$message.warning("请填写小节名称") + this.$put(this.api.editSubsection, { id: this.sectionId, cid: this.id, chapterId: this.chapterId, name: this.sectionForm.sectionName - }; - this.$put(this.api.editSubsection, data).then(res => { + }).then(res => { this.$message.success("修改成功") this.sectionNameVisible = false - this.getData(); + this.getData() }).catch(err => { }) }, closePlayer () { - this.playAuth = ""; - this.player.pause(); + this.playAuth = "" + this.player.pause() }, closeIframe () { - this.iframeSrc = ""; + this.iframeSrc = "" this.videoSrc = '' - this.showMask = false; - this.showMask1 = false; - this.showMask2 = false; - this.previewing = false; + this.showMask = false + this.showMask1 = false + this.showMask2 = false + this.previewing = false }, back () { // 如果是预览则关闭预览 if (this.previewing) { - this.closeIframe(); + this.closeIframe() } else { - this.$router.push(this.$store.state.referrer || '/curriculum') + this.$router.push(this.$store.state.referrer || 'list') } }, } @@ -977,6 +999,11 @@ export default { background-color: #f9f9f9; } + .drag { + margin-right: 10px; + cursor: pointer; + } + .section-left, .section-right { display: inline-flex; diff --git a/src/pages/lesson/detail/index.vue b/src/pages/lesson/detail/index.vue index 0c853d9..0a12313 100644 --- a/src/pages/lesson/detail/index.vue +++ b/src/pages/lesson/detail/index.vue @@ -2,7 +2,7 @@ <div class="wrap"> <el-card shadow="hover" class="m-b-20"> <div class="flex-between"> - <el-page-header @back="back" :content="'新建课程'"></el-page-header> + <el-page-header @back="back" :content="(isCopy ? '复制' : cid ? '编辑' : '新建') + '课程'"></el-page-header> </div> </el-card> <div class="page"> @@ -268,7 +268,8 @@ <el-button type="text" @click="batchDelChecked">批量移除</el-button> </div> - <el-input placeholder="请输入项目名称" prefix-icon="el-icon-search" v-model="checkedKeyword" 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 checkeds"> @@ -314,6 +315,7 @@ export default { data () { return { cid: this.$route.query.cid, + isCopy: this.$route.query.copy, editorConfig, step: 2, form: { @@ -441,6 +443,12 @@ export default { }, // 获取课程系统 async getCourseSystem () { + + const r = await this.$post(this.api.schoolCourseProject, { + permissions: 0 + }) + + return const res = await this.$get(this.api.getSystemIdBySchool) const systems = res.data @@ -633,6 +641,23 @@ export default { this.checkAll = !this.projects.find(e => !e.check) // 同步全选框 this.checkedAll = JSON.parse(JSON.stringify(this.checkeds)) // 全部已选项目,另外保存 }, + // 批量移除 + async batchDelChecked (val) { + try { + const checked = this.checkeds.filter(e => e.check) + if (checked.length) { + checked.map(e => { + const cur = this.allSections.find(n => n.id === e.id) + if (cur) { + cur.check = false + } + }) + this.checkeds = this.checked.filter(e => !e.check) + } else { + Util.warningMsg('请选择数据') + } + } catch (e) { } + }, // 删除已选项目 delProject (i, e) { if (e.disabled) return @@ -774,7 +799,7 @@ export default { background: 'rgba(0, 0, 0, 0.7)' }) try { - const res = await this.$post(this.api[cid ? 'modifyCourse' : 'createCurriculum'], form) + const res = await this.$post(this.api[cid && !this.isCopy ? 'modifyCourse' : 'createCurriculum'], form) this.loadIns.close() if (next) { this.step = 2 diff --git a/src/pages/lesson/list/index.vue b/src/pages/lesson/list/index.vue index 38edc2f..55f1faf 100644 --- a/src/pages/lesson/list/index.vue +++ b/src/pages/lesson/list/index.vue @@ -89,10 +89,12 @@ </el-switch> </template> </el-table-column> - <el-table-column label="操作" width="150" align="center"> + <el-table-column label="操作" width="240" align="center"> <template slot-scope="scope"> + <el-button type="text" @click="preview(scope.row)">预览课程</el-button> <el-button type="text" @click="edit(scope.row)" v-auth>编辑</el-button> <el-button type="text" @click="config(scope.row)" v-auth>内容设置</el-button> + <el-button type="text" @click="copy(scope.row)">复制</el-button> <el-button type="text" @click="handleDelete(scope.row)" v-auth>删除</el-button> </template> </el-table-column> @@ -102,11 +104,27 @@ layout="total, prev, pager, next" :total="totals"></el-pagination> </div> </el-card> + + <el-dialog title="请选择上架范围" :visible.sync="onVisible" width="540px" :close-on-click-modal="false"> + <el-radio-group v-model="isSpecify"> + <el-radio :label="1">指定范围</el-radio> + <el-radio :label="0">无指定范围</el-radio> + </el-radio-group> + <el-tree class="m-t-10" ref="class" :data="classes" show-checkbox node-key="id" :props="{ + label: 'organizationName' + }"> + </el-tree> + <span slot="footer" class="dialog-footer"> + <el-button @click="onVisible = false">取消</el-button> + <el-button type="primary" @click="onSubmit">确定</el-button> + </span> + </el-dialog> </div> </template> <script> -import qs from 'qs' +import Setting from '@/setting' +import Util from '@/libs/util' export default { data () { return { @@ -130,7 +148,11 @@ export default { ProfessionalList: [], // 专业 multipleSelection: [], loading: false, - searchTimer: null + searchTimer: null, + + onVisible: false, + classes: [], + curRow: {}, }; }, watch: { @@ -142,8 +164,9 @@ export default { } }, mounted () { - this.getSubject(); - this.getData(); + this.getSubject() + this.getClass() + this.getData() }, methods: { // 获取列表数据 @@ -152,7 +175,7 @@ export default { ...this.form, pageNum: this.page, pageSize: this.pageSize, - supplierId: '' + platformId: Setting.platformId }).then(res => { this.courseData = res.page.records; this.totals = res.page.total @@ -214,10 +237,18 @@ export default { this.setReferrer() this.$router.push('detail') }, + // 预览 + preview (row) { + this.$router.push(`/station/preview?courseId=${row.cid || ''}&curriculumName=${encodeURIComponent(row.curriculumName)}&mallId=${row.mallId || ''}`) + }, // 编辑 edit (row) { this.setReferrer() - this.$router.push(`detail?cid=${row.cid}`); + this.$router.push(`detail?cid=${row.cid}`) + }, + // 复制 + async copy (row) { + this.$router.push(`detail?cid=${row.cid}©=1`) }, // 内容设置 config (row) { @@ -281,12 +312,30 @@ export default { this.getData() }, // 上下架 - changeSwitch (value, row) { - this.$post(`${this.api.isShelves}?cid=${row.cid}&isShelves=${value}`).then((res) => { + async changeSwitch (val, row) { + if (val) { + this.curRow = row + this.onVisible = true + } else { + await this.$post(`${this.api.isShelves}?cid=${row.cid}&isShelves=${val}`) this.getData() this.$message.success("修改上下架状态成功!") - }).catch((res) => { }) - } + } + }, + // 获取学生班级 + async getClass () { + const res = await this.$post(this.api.treeList) + this.classes = res.treeList + }, + // 上架提交 + async onSubmit () { + const check = this.$refs.class.getCheckedKeys() + if (!check.length) return Util.warningMsg('请选择班级') + console.log(this.$refs.class.getCheckedKeys()) + // await this.$post(`${this.api.isShelves}?cid=${row.cid}&isShelves=${value}`) + this.getData() + this.$message.success('修改上下架状态成功!') + }, } }; </script> diff --git a/src/pages/station/preview/index.vue b/src/pages/station/preview/index.vue index 4d341cb..87cb5e7 100644 --- a/src/pages/station/preview/index.vue +++ b/src/pages/station/preview/index.vue @@ -50,7 +50,7 @@ </div> </div> <div class="catalog"> - <div class="m-b-20"> + <div v-if="mallId" class="m-b-20"> <el-button v-if="!overdue" class="entry" type="primary" size="small" @click="showBuy">续费</el-button> <el-button v-if="practiceTheoreticalPaper" class="entry" type="primary" @click="entry(1)">进入理论</el-button> <el-button v-if="practicePracticeProject" class="entry" type="primary" @click="entry(0)">进入实训</el-button> @@ -449,11 +449,11 @@ export default { const { query } = this.$route this.fromAdmin ? this.$router.back() : - this.$router.push(`/station?keyword=${query.keyword || ''}&active=${query.active || 0}`) + this.mallId ? this.$router.push(`/station?keyword=${query.keyword || ''}&active=${query.active || 0}`) : this.$router.back() }, init () { - this.insertScript(); - this.getData(); + this.insertScript() + this.getData() this.addRecord() }, async getData () { @@ -476,15 +476,16 @@ export default { await this.$post(`${this.api.recordRecentUsage}?mallId=${this.mallId}`) }, // 查询是否过期 - getStatus () { - this.$get(this.api.whetherToRenewTheFee, { - mallId: this.mallId - }).then(({ isRenew }) => { + async getStatus () { + if (this.mallId) { + const { isRenew } = await this.$get(this.api.whetherToRenewTheFee, { + mallId: this.mallId + }) // 1正常显示资源,0显示续费,-1试用 this.overdue = isRenew - this.getChapter() this.getProgress() - }).catch(res => { }) + } + this.getChapter() }, // 获取章节小节 async getChapter () { @@ -823,15 +824,17 @@ export default { }, // 查询项目 queryProject () { - this.$get(this.api.getProjectBySystemId, { - systemId: this.systemIds, - cId: this.courseId, // 课程id - mallId: this.mallId, - permissions: 0 // 0: 练习,1: 考核 - }).then(res => { - this.projects = res.projects // 实训项目 - this.papers = res.exercisePaperList // 理论试卷 - }).catch(res => { }) + if (this.mallId) { + this.$get(this.api.getProjectBySystemId, { + systemId: this.systemIds, + cId: this.courseId, // 课程id + mallId: this.mallId, + permissions: 0 // 0: 练习,1: 考核 + }).then(res => { + this.projects = res.projects // 实训项目 + this.papers = res.exercisePaperList // 理论试卷 + }).catch(res => { }) + } }, // 进入实验 entryProject (projectId = '', paperId = '') { @@ -1073,7 +1076,7 @@ $height: 700px; } &:hover { - background-color: #ac89fd; + background-color: $main-color; } &.active {