parent
0a042d07c8
commit
245397841c
58 changed files with 8503 additions and 2443 deletions
After Width: | Height: | Size: 239 B |
After Width: | Height: | Size: 318 B |
After Width: | Height: | Size: 209 B |
@ -0,0 +1,286 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<el-card shadow="hover" class="m-b-20"> |
||||||
|
<div class="flex-between"> |
||||||
|
<el-page-header @back="goBack" :content="id ? '编辑课程' : '新增课程'"></el-page-header> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card shadow="hover" class="m-b-20"> |
||||||
|
<el-form :disabled="isDetail" label-width="80px" label-suffix=":" size="small"> |
||||||
|
<el-form-item label="课程名称"> |
||||||
|
<div class="d-inline-block"> |
||||||
|
<el-input placeholder="请输入课程名称" v-model="name" clearable maxlength="25"></el-input> |
||||||
|
</div> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="课程分类"> |
||||||
|
<div class="d-inline-block"> |
||||||
|
<el-select v-model="classificationId" placeholder="请选择课程分类"> |
||||||
|
<el-option v-for="item in classificationList" :key="item.id" :label="item.name" :value="item.id"></el-option> |
||||||
|
</el-select> |
||||||
|
</div> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="课程封面"> |
||||||
|
<el-upload |
||||||
|
class="avatar-uploader" |
||||||
|
accept=".jpg,.png,.jpeg" |
||||||
|
:on-remove="handleRemove" |
||||||
|
:on-error="uploadError" |
||||||
|
:on-success="uploadSuccess" |
||||||
|
:before-remove="beforeRemove" |
||||||
|
:limit="1" |
||||||
|
:on-exceed="handleExceed" |
||||||
|
:action="this.api.fileupload" |
||||||
|
:headers="headers" |
||||||
|
name="file" |
||||||
|
> |
||||||
|
<img v-if="coverUrl" :src="coverUrl" class="avatar"> |
||||||
|
<div class="uploader-default" v-else> |
||||||
|
<i class="el-icon-plus"></i> |
||||||
|
<p>上传封面</p> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div slot="tip" class="el-upload__tip"> |
||||||
|
<p>只能上传jpg/png文件</p> |
||||||
|
<p>课程封面图将按2:1显示,最佳分辨率1400*700</p> |
||||||
|
</div> |
||||||
|
</el-upload> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="课程介绍"> |
||||||
|
<quill :border="true" :readonly="isDetail" v-model="description" :height="400" /> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item> |
||||||
|
<el-button type="primary" size="small" v-throttle @click="save" v-show="!isDetail">{{ id ? '更新' : '创建' }}</el-button> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
</el-card> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import util from '@/libs/util' |
||||||
|
import Setting from '@/setting' |
||||||
|
|
||||||
|
import quill from '@/components/quill' |
||||||
|
|
||||||
|
export default { |
||||||
|
name: 'courseAddEdit', |
||||||
|
data() { |
||||||
|
return { |
||||||
|
headers: { |
||||||
|
token: util.local.get(Setting.tokenKey) |
||||||
|
}, |
||||||
|
schoolId: Setting.schoolId, |
||||||
|
id: '', |
||||||
|
isDetail: Boolean(this.$route.query.show), |
||||||
|
username: this.$store.state.name, |
||||||
|
classificationId: '', |
||||||
|
coverUrl: '', |
||||||
|
name: '', |
||||||
|
classificationList: [], |
||||||
|
uploadList: [], |
||||||
|
description: '', |
||||||
|
submiting: false |
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.id = this.$route.query.id |
||||||
|
this.getClassification() |
||||||
|
this.id && this.getData() |
||||||
|
}, |
||||||
|
components: { |
||||||
|
quill |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 返回 |
||||||
|
goBack() { |
||||||
|
this.$router.back(); |
||||||
|
}, |
||||||
|
save() { |
||||||
|
if (this.submiting) return false |
||||||
|
if (!this.name) return util.warningMsg('请填写课程名称'); |
||||||
|
if (!this.classificationId) return util.warningMsg('请选择课程分类'); |
||||||
|
if (!this.coverUrl) return util.warningMsg('请上传课程封面'); |
||||||
|
this.submiting = true |
||||||
|
|
||||||
|
let data = { |
||||||
|
id: this.id, |
||||||
|
classificationId: this.classificationId, |
||||||
|
coverUrl: this.coverUrl, |
||||||
|
description: this.description, |
||||||
|
name: this.name, |
||||||
|
|
||||||
|
schoolId: this.schoolId, |
||||||
|
founderId: this.userId, |
||||||
|
founderName: this.username, |
||||||
|
distinguish: 1 |
||||||
|
} |
||||||
|
if (this.id) { |
||||||
|
this.$put(this.api.editCourse, data).then(res => { |
||||||
|
this.submiting = false |
||||||
|
util.successMsg('修改成功'); |
||||||
|
this.$router.back() |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
this.submiting = false |
||||||
|
}); |
||||||
|
} else { |
||||||
|
this.$post(this.api.addCourse, data).then(res => { |
||||||
|
this.submiting = false |
||||||
|
this.$confirm('课程创建成功,是否马上进行课程内容设置?', '提示', { |
||||||
|
type: 'success', |
||||||
|
confirmButtonText: '马上设置', |
||||||
|
cancelButtonText: '稍后操作' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$router.push(`courseConfig?id=${res.data.courseId}`) |
||||||
|
}).catch(() => { |
||||||
|
this.$router.back() |
||||||
|
}); |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
this.submiting = false |
||||||
|
}); |
||||||
|
} |
||||||
|
}, |
||||||
|
getClassification() { |
||||||
|
this.$get(this.api.queryGlClassification).then(res => { |
||||||
|
this.classificationList = res.classificationList |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
}, |
||||||
|
getData() { |
||||||
|
this.$get(`${this.api.getCourse}/${this.id}`) |
||||||
|
.then(res => { |
||||||
|
let data = res.course |
||||||
|
this.name = data.name |
||||||
|
this.classificationId = data.classificationId |
||||||
|
this.description = data.description |
||||||
|
this.coverUrl = data.coverUrl |
||||||
|
this.uploadList.push({ |
||||||
|
name: 'cover.jpg', |
||||||
|
url: this.coverUrl |
||||||
|
}) |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
|
||||||
|
}); |
||||||
|
}, |
||||||
|
// 上传文件 |
||||||
|
handleExceed(files, fileList) { |
||||||
|
util.warningMsg('当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!'); |
||||||
|
}, |
||||||
|
uploadSuccess(res, file, fileList) { |
||||||
|
this.coverUrl = res.filesResult.fileUrl |
||||||
|
// this.uploadList.push({ name: file.name, url: response.message.fileUrl }); |
||||||
|
}, |
||||||
|
uploadError(err, file, fileList) { |
||||||
|
this.$message({ |
||||||
|
message: "上传出错,请重试!", |
||||||
|
type: "error", |
||||||
|
center: true |
||||||
|
}); |
||||||
|
}, |
||||||
|
beforeRemove(file, fileList) { |
||||||
|
return this.$confirm(`确定移除 ${file.name}?`); |
||||||
|
}, |
||||||
|
handleRemove(file, fileList) { |
||||||
|
let fileName = this.coverUrl.replace('https://liuwanr.oss-cn-shenzhen.aliyuncs.com/', '') |
||||||
|
this.$del(`${this.api.fileDeletion}?keys=${fileName}`).then(res => { |
||||||
|
this.coverUrl = '' |
||||||
|
}).catch(res => { |
||||||
|
}) |
||||||
|
}, |
||||||
|
uploadSure() { |
||||||
|
this.importVisible = false |
||||||
|
this.pageNo = 1 |
||||||
|
this.staffGradeId = '' |
||||||
|
this.keyword = '' |
||||||
|
this.getTeacher() |
||||||
|
}, |
||||||
|
goback() { |
||||||
|
if (this.isDetail) { |
||||||
|
this.$router.back() |
||||||
|
} else { |
||||||
|
this.$confirm('确定返回?未更新的信息将不会保存。', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$router.back() |
||||||
|
}) |
||||||
|
.catch(() => { |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
$avatar-width: 104px; |
||||||
|
/deep/ .avatar-uploader { |
||||||
|
.el-upload { |
||||||
|
position: relative; |
||||||
|
width: $avatar-width; |
||||||
|
border: 1px dashed #d9d9d9; |
||||||
|
border-radius: 2px; |
||||||
|
cursor: pointer; |
||||||
|
overflow: hidden; |
||||||
|
|
||||||
|
&:hover { |
||||||
|
border-color: #409EFF; |
||||||
|
} |
||||||
|
|
||||||
|
.uploader-default { |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
justify-content: center; |
||||||
|
width: $avatar-width !important; |
||||||
|
height: $avatar-width; |
||||||
|
text-align: center; |
||||||
|
background: rgba(0, 0, 0, 0.04); |
||||||
|
|
||||||
|
i { |
||||||
|
font-size: 20px; |
||||||
|
font-weight: bold; |
||||||
|
color: #8c939d; |
||||||
|
} |
||||||
|
|
||||||
|
p { |
||||||
|
margin-top: 10px; |
||||||
|
font-size: 14px; |
||||||
|
color: rgba(0, 0, 0, 0.65); |
||||||
|
line-height: 1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.avatar { |
||||||
|
width: $avatar-width; |
||||||
|
height: $avatar-width; |
||||||
|
display: block; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.el-upload__tip { |
||||||
|
margin-top: 0; |
||||||
|
|
||||||
|
p { |
||||||
|
font-size: 14px; |
||||||
|
color: rgba(0, 0, 0, 0.45); |
||||||
|
line-height: 1; |
||||||
|
|
||||||
|
&:first-child { |
||||||
|
margin-bottom: 5px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/deep/ .d-inline-block { |
||||||
|
width: 216px; |
||||||
|
|
||||||
|
.el-select, .el-input { |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,742 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<el-card shadow="hover" class="m-b-20"> |
||||||
|
<div class="flex-between"> |
||||||
|
<el-page-header @back="goBack" :content="'内容设置'"></el-page-header> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
<!--内容设置--> |
||||||
|
<el-card shadow="hover" class="m-b-20"> |
||||||
|
<div class="page"> |
||||||
|
<div class="relative"> |
||||||
|
<div class="p-title">内容设置</div> |
||||||
|
<div class="btns" style="top: -10px"> |
||||||
|
<template v-if="!sorting"> |
||||||
|
<el-button type="primary" size="small" round v-throttle @click="addChapter">添加章节</el-button> |
||||||
|
<el-button type="primary" size="small" round v-throttle @click="sort">编辑顺序</el-button> |
||||||
|
</template> |
||||||
|
<template v-else> |
||||||
|
<el-button type="primary" size="small" round v-throttle @click="cancelSort">取消</el-button> |
||||||
|
<el-button type="primary" size="small" round v-throttle @click="saveSort">保存</el-button> |
||||||
|
</template> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<el-divider></el-divider> |
||||||
|
<div class="page-content"> |
||||||
|
<div class="m-b-20" v-for="(chapter,index) in chapters" :key="chapter.id"> |
||||||
|
<div class="flex j-between a-center m-b-10"> |
||||||
|
<div>{{ chapter.name }}</div> |
||||||
|
<div> |
||||||
|
<template v-if="!sorting"> |
||||||
|
<el-button class="action-btn" type="primary" size="small" round v-throttle @click="editChapter(chapter)">修改章节名称</el-button> |
||||||
|
<el-button class="action-btn" type="primary" size="small" round v-throttle @click="addSection(chapter.id)">添加小节</el-button> |
||||||
|
<el-button class="action-btn" type="primary" size="small" round v-throttle @click="delChapter(chapter.id)">删除</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> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-table :data="chapter.subsectionList" class="table" stripe header-align="center"> |
||||||
|
<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="preview(scope.row)">查看</el-button> |
||||||
|
<el-button type="text" @click="delSection(scope.row)">删除</el-button> |
||||||
|
<el-button type="text" @click="editSectionName(scope.row,chapter.id)">修改小节名称</el-button> |
||||||
|
<el-button type="text" @click="switchFile(scope.row,chapter.id)">更换文件</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="24%" :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 size="small" @click="chapterVisible = false">取消</el-button> |
||||||
|
<el-button size="small" type="primary" @click="chapterSubmit">确定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
<el-dialog title="添加小节" :visible.sync="sectionVisible" width="24%" @close="closeSection" :close-on-click-modal="false"> |
||||||
|
<el-form label-width="80px"> |
||||||
|
<el-form-item label="资源添加"> |
||||||
|
<el-upload |
||||||
|
:before-upload="beforeUpload" |
||||||
|
:on-remove="handleRemove" |
||||||
|
:on-error="uploadError" |
||||||
|
:on-success="uploadSuccess" |
||||||
|
:before-remove="beforeRemove" |
||||||
|
:limit="1" |
||||||
|
:on-exceed="handleExceed" |
||||||
|
:action="this.api.fileupload" |
||||||
|
:file-list="uploadList" |
||||||
|
:headers="headers" |
||||||
|
name="file" |
||||||
|
> |
||||||
|
<el-button size="small"><img src="@/assets/img/upload.png" alt=""> 上传资源</el-button> |
||||||
|
</el-upload> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="小节名称"> |
||||||
|
<el-input placeholder="请输入小节名称" v-model="sectionName" maxlength="50"></el-input> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button size="small" @click="sectionVisible = false">取消</el-button> |
||||||
|
<el-button size="small" type="primary" @click="sectionSubmit">确定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
<el-dialog title="更换文件" :visible.sync="switchVisible" width="28%" :close-on-click-modal="false" @close="closeSwitch"> |
||||||
|
<div style="text-align: center"> |
||||||
|
<el-upload |
||||||
|
:before-upload="beforeUpload" |
||||||
|
:on-remove="handleRemove" |
||||||
|
:on-error="uploadError" |
||||||
|
:on-success="uploadSuccess" |
||||||
|
:before-remove="beforeRemove" |
||||||
|
:limit="1" |
||||||
|
:on-exceed="handleExceed" |
||||||
|
:action="this.api.fileupload" |
||||||
|
:file-list="uploadList" |
||||||
|
name="file" |
||||||
|
> |
||||||
|
<el-button size="small"><img src="@/assets/img/upload.png" alt=""> 上传资源</el-button> |
||||||
|
</el-upload> |
||||||
|
</div> |
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button size="small" @click="switchVisible = false">取消</el-button> |
||||||
|
<el-button size="small" type="primary" @click="switchSubmit">确定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
<el-dialog title="修改小节名称" :visible.sync="sectionNameVisible" width="24%" :close-on-click-modal="false"> |
||||||
|
<el-form> |
||||||
|
<el-form-item> |
||||||
|
<el-input placeholder="请输入小节名称" v-model="sectionName" maxlength="50"></el-input> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button size="small" @click="sectionNameVisible = false">取消</el-button> |
||||||
|
<el-button size="small" type="primary" @click="sectionNameSubmit">确定</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" 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> |
||||||
|
<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"></pdf> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import util from '@/libs/util' |
||||||
|
import Setting from '@/setting' |
||||||
|
import { Loading } from 'element-ui'; |
||||||
|
import pdf from '@/components/pdf' |
||||||
|
|
||||||
|
export default { |
||||||
|
name: 'contentSettings', |
||||||
|
data() { |
||||||
|
return { |
||||||
|
headers: { |
||||||
|
token: util.local.get(Setting.tokenKey) |
||||||
|
}, |
||||||
|
id: '', |
||||||
|
userId: this.$store.state.userLoginId, |
||||||
|
chapters: [], |
||||||
|
sorting: false, |
||||||
|
uploading: false, |
||||||
|
uploadList: [], |
||||||
|
chapterVisible: false, |
||||||
|
chapterId: '', |
||||||
|
chapterName: '', |
||||||
|
sectionVisible: false, |
||||||
|
sectionName: '', |
||||||
|
sectionId: '', |
||||||
|
switchVisible: false, |
||||||
|
sectionNameVisible: false, |
||||||
|
fileId: '', |
||||||
|
fileName: '', |
||||||
|
fileUrl: '', |
||||||
|
originalFileName: '', |
||||||
|
fileType: '', |
||||||
|
playAuth: '', |
||||||
|
player: null, |
||||||
|
previewImg: '', |
||||||
|
iframeSrc: '', |
||||||
|
curFile: {}, |
||||||
|
isAddSection: false, |
||||||
|
isWord: false, |
||||||
|
isPPT: false, |
||||||
|
isExcel: false, |
||||||
|
showMask: false, |
||||||
|
showMask1: false, |
||||||
|
showMask2: false, |
||||||
|
loadIns: null, |
||||||
|
pdfVisible: false, |
||||||
|
pdfSrc: '', |
||||||
|
previewing: false |
||||||
|
} |
||||||
|
}, |
||||||
|
components: { pdf }, |
||||||
|
mounted() { |
||||||
|
this.insertScript() |
||||||
|
this.id = this.$route.query.id |
||||||
|
this.id && this.getData() |
||||||
|
// 处理预览资源后返回弹框不会消失的问题 |
||||||
|
if (window.history && window.history.pushState) { |
||||||
|
history.pushState(null, null, document.URL); |
||||||
|
window.addEventListener("popstate", this.goBack, false); |
||||||
|
} |
||||||
|
}, |
||||||
|
destroyed() { |
||||||
|
window.removeEventListener("popstate", this.goBack, false); |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData() { |
||||||
|
this.$get(`${this.api.queryChaptersAndSubsections}/${this.id}`) |
||||||
|
.then(res => { |
||||||
|
this.chapters = res.chapterList |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
|
||||||
|
}); |
||||||
|
}, |
||||||
|
goBack() { |
||||||
|
if (this.previewing) { |
||||||
|
this.closeIframe() |
||||||
|
} else { |
||||||
|
history.back() |
||||||
|
} |
||||||
|
}, |
||||||
|
iframeOnload() { |
||||||
|
document.querySelector('#fileIframe').onload = e => { |
||||||
|
if (this.isPPT) { |
||||||
|
this.showMask = true |
||||||
|
} else { |
||||||
|
this.showMask = false |
||||||
|
} |
||||||
|
if (this.isWord) { |
||||||
|
this.showMask1 = true |
||||||
|
} else { |
||||||
|
this.showMask1 = false |
||||||
|
} |
||||||
|
if (this.isExcel) { |
||||||
|
this.showMask2 = true |
||||||
|
} else { |
||||||
|
this.showMask2 = false |
||||||
|
} |
||||||
|
this.loadIns.close() |
||||||
|
} |
||||||
|
}, |
||||||
|
insertScript() { |
||||||
|
const linkTag = document.createElement('link'); |
||||||
|
linkTag.rel = 'stylesheet'; |
||||||
|
linkTag.href = 'https://g.alicdn.com/de/prismplayer/2.8.2/skins/default/aliplayer-min.css'; |
||||||
|
document.body.appendChild(linkTag); |
||||||
|
|
||||||
|
const scriptTag = document.createElement('script'); |
||||||
|
scriptTag.type = 'text/javascript'; |
||||||
|
scriptTag.src = 'https://g.alicdn.com/de/prismplayer/2.8.2/aliplayer-min.js'; |
||||||
|
document.body.appendChild(scriptTag); |
||||||
|
}, |
||||||
|
// 上传文件 |
||||||
|
beforeUpload(file) { |
||||||
|
let type = this.transferType(file.name.substring(file.name.lastIndexOf('.') + 1)) |
||||||
|
if (type != '视频' && type != '图片' && type != 'pdf' && (file.size / 1024 / 1024) > 10) { |
||||||
|
util.errorMsg('请上传10M以内的文件') |
||||||
|
return false |
||||||
|
} |
||||||
|
this.uploading = true |
||||||
|
this.originalFileName = file.name |
||||||
|
if (this.isAddSection) this.sectionName = file.name.substring(0, file.name.lastIndexOf(".")) |
||||||
|
this.fileType = file.name.substring(file.name.lastIndexOf('.') + 1) |
||||||
|
}, |
||||||
|
handleExceed(files, fileList) { |
||||||
|
util.warningMsg( |
||||||
|
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!` |
||||||
|
); |
||||||
|
}, |
||||||
|
uploadSuccess(res, file, fileList) { |
||||||
|
this.uploading = false |
||||||
|
this.fileId = res.filesResult.fileId |
||||||
|
this.fileType = res.filesResult.fileType |
||||||
|
this.fileUrl = res.filesResult.fileUrl |
||||||
|
this.fileName = res.filesResult.ossFileName |
||||||
|
}, |
||||||
|
uploadError(err, file, fileList) { |
||||||
|
this.$message({ |
||||||
|
message: "上传出错,请重试!", |
||||||
|
type: "error", |
||||||
|
center: true |
||||||
|
}); |
||||||
|
}, |
||||||
|
beforeRemove(file, fileList) { |
||||||
|
if ((file.size / 1024 / 1024) < 10) { |
||||||
|
return this.$confirm(`确定移除 ${file.name}?`); |
||||||
|
} |
||||||
|
}, |
||||||
|
handleRemove(file, fileList) { |
||||||
|
this.uploadList = fileList |
||||||
|
}, |
||||||
|
uploadSure() { |
||||||
|
this.importVisible = false |
||||||
|
this.pageNo = 1 |
||||||
|
this.staffGradeId = '' |
||||||
|
this.keyword = '' |
||||||
|
this.getTeacher() |
||||||
|
}, |
||||||
|
goback() { |
||||||
|
this.$router.push('course') |
||||||
|
}, |
||||||
|
transferType(ext) { |
||||||
|
if ('jpg,jpeg,png,gif,svg,psd'.includes(ext)) return '图片' |
||||||
|
if ('mp4,3gp,mov,m4v,avi,dat,mkv,flv,vob,rmvb,rm,qlv'.includes(ext)) return '视频' |
||||||
|
return ext |
||||||
|
}, |
||||||
|
addChapter() { |
||||||
|
this.chapterName = '' |
||||||
|
this.chapterId = '' |
||||||
|
this.chapterVisible = true |
||||||
|
}, |
||||||
|
sort() { |
||||||
|
this.sorting = true |
||||||
|
}, |
||||||
|
cancelSort() { |
||||||
|
this.sorting = false |
||||||
|
}, |
||||||
|
saveSort() { |
||||||
|
this.chapters.forEach((n, k) => { |
||||||
|
n.sort = k + 1 |
||||||
|
n.subsectionList.forEach((j, i) => { |
||||||
|
j.sort = i + 1 |
||||||
|
}) |
||||||
|
}) |
||||||
|
let data = { |
||||||
|
chapterVOList: this.chapters |
||||||
|
} |
||||||
|
this.$post(this.api.reorder, data).then(res => { |
||||||
|
this.sorting = false |
||||||
|
this.getData() |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
}, |
||||||
|
editChapter(item) { |
||||||
|
this.chapterId = item.id |
||||||
|
this.chapterName = item.name |
||||||
|
this.chapterVisible = true |
||||||
|
}, |
||||||
|
delChapter(id) { |
||||||
|
this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$del(`${this.api.deleteChapter}/${id}`).then(res => { |
||||||
|
util.successMsg('删除成功'); |
||||||
|
this.getData() |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
}) |
||||||
|
.catch(() => { |
||||||
|
}); |
||||||
|
}, |
||||||
|
closeSection() { |
||||||
|
this.isAddSection = false |
||||||
|
}, |
||||||
|
addSection(id) { |
||||||
|
this.chapterId = id |
||||||
|
this.sectionName = '' |
||||||
|
this.fileUrl = '' |
||||||
|
this.uploadList = [] |
||||||
|
this.sectionId = '' |
||||||
|
this.isAddSection = true |
||||||
|
this.sectionVisible = true |
||||||
|
}, |
||||||
|
chapterSubmit() { |
||||||
|
if (!this.chapterName) return util.warningMsg('请填写章节名称') |
||||||
|
let data = { |
||||||
|
courseId: this.id, |
||||||
|
name: this.chapterName |
||||||
|
} |
||||||
|
if (this.chapterId) { |
||||||
|
data.id = this.chapterId |
||||||
|
this.$put(this.api.editChapter, data).then(res => { |
||||||
|
util.successMsg('修改成功'); |
||||||
|
this.chapterVisible = false |
||||||
|
this.getData() |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
}); |
||||||
|
} else { |
||||||
|
this.$post(this.api.addChapter, data).then(res => { |
||||||
|
util.successMsg('添加成功'); |
||||||
|
this.chapterVisible = false |
||||||
|
this.getData() |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
}); |
||||||
|
} |
||||||
|
}, |
||||||
|
sectionSubmit() { |
||||||
|
if (!this.sectionName) return util.warningMsg('请填写小节名称') |
||||||
|
if (this.uploading) return util.warningMsg('资源正在上传中,请稍候') |
||||||
|
if (!this.fileUrl && !this.fileId) return util.warningMsg('请上传资源') |
||||||
|
let data = { |
||||||
|
id: this.sectionId, |
||||||
|
courseId: this.id, |
||||||
|
chapterId: this.chapterId, |
||||||
|
name: this.sectionName, |
||||||
|
fileId: this.fileId, |
||||||
|
fileUrl: this.fileUrl, |
||||||
|
fileName: this.fileName, |
||||||
|
fileType: this.fileType, |
||||||
|
originalFileName: this.originalFileName |
||||||
|
} |
||||||
|
this.$post(this.api.addSubsection, data).then(res => { |
||||||
|
util.successMsg('添加成功'); |
||||||
|
this.sectionVisible = false |
||||||
|
this.getData() |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
}); |
||||||
|
}, |
||||||
|
closeSwitch() { |
||||||
|
this.fileId = '' |
||||||
|
this.fileName = '' |
||||||
|
this.fileType = '' |
||||||
|
this.fileUrl = '' |
||||||
|
this.sectionId = '' |
||||||
|
}, |
||||||
|
preview(row) { |
||||||
|
if (this.transferType(row.fileType) == '视频') { |
||||||
|
this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => { |
||||||
|
this.playAuth = res.data.playAuth |
||||||
|
if (this.player) { |
||||||
|
this.player.replayByVidAndPlayAuth(row.fileId, this.playAuth) |
||||||
|
} else { |
||||||
|
this.player = new Aliplayer({ |
||||||
|
id: 'player', |
||||||
|
width: '100%', |
||||||
|
autoplay: false, |
||||||
|
vid: row.fileId, |
||||||
|
playauth: this.playAuth, |
||||||
|
encryptType: 1 //当播放私有加密流时需要设置。 |
||||||
|
}) |
||||||
|
} |
||||||
|
}).catch(res => { |
||||||
|
}) |
||||||
|
} else if (this.transferType(row.fileType) == '图片') { |
||||||
|
this.previewImg = row.fileUrl |
||||||
|
} else if (row.fileType == 'pdf') { |
||||||
|
this.pdfSrc = row.fileUrl |
||||||
|
this.pdfVisible = true |
||||||
|
} else { |
||||||
|
this.$get(`${this.api.getSubsection}/${row.id}`).then(res => { |
||||||
|
this.previewing = true |
||||||
|
this.loadIns = Loading.service() |
||||||
|
this.$route.fullPath.includes('#file') || history.pushState({ file: true }, '文件预览', '#' + this.$route.fullPath + '#file') |
||||||
|
if (row.fileType == 'pptx') { |
||||||
|
this.isPPT = true |
||||||
|
this.isWord = false |
||||||
|
this.isExcel = false |
||||||
|
} else if (row.fileType == 'doc' || row.fileType == 'docx') { |
||||||
|
this.isPPT = false |
||||||
|
this.isWord = true |
||||||
|
this.isExcel = false |
||||||
|
} else if (row.fileType == 'xls' || row.fileType == 'xlsx') { |
||||||
|
this.isExcel = true |
||||||
|
this.isPPT = false |
||||||
|
this.isWord = false |
||||||
|
} else { |
||||||
|
this.isPPT = false |
||||||
|
this.isWord = false |
||||||
|
this.isExcel = false |
||||||
|
} |
||||||
|
this.iframeSrc = res.data.previewUrl |
||||||
|
this.$nextTick(() => { |
||||||
|
this.iframeOnload() |
||||||
|
}) |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
}); |
||||||
|
} |
||||||
|
}, |
||||||
|
editSectionName(row, chapterId) { |
||||||
|
this.chapterId = chapterId |
||||||
|
this.sectionId = row.id |
||||||
|
this.sectionName = row.name |
||||||
|
this.sectionNameVisible = true |
||||||
|
}, |
||||||
|
switchFile(row, chapterId, sectionId) { |
||||||
|
this.uploadList = [] |
||||||
|
this.curFile = { |
||||||
|
fileId: row.fileId, |
||||||
|
fileName: row.fileName, |
||||||
|
fileType: row.fileType, |
||||||
|
fileUrl: row.fileUrl |
||||||
|
} |
||||||
|
this.chapterId = chapterId |
||||||
|
this.sectionId = row.id |
||||||
|
this.sectionName = row.sectionName |
||||||
|
|
||||||
|
this.switchVisible = true |
||||||
|
}, |
||||||
|
switchSubmitFile() { |
||||||
|
let data = { |
||||||
|
id: this.sectionId, |
||||||
|
courseId: this.id, |
||||||
|
chapterId: this.chapterId, |
||||||
|
name: this.sectionName, |
||||||
|
fileId: this.fileId, |
||||||
|
fileName: this.fileName, |
||||||
|
fileType: this.fileType, |
||||||
|
fileUrl: this.fileUrl, |
||||||
|
originalFileName: this.originalFileName |
||||||
|
} |
||||||
|
this.$put(this.api.editSubsection, data).then(res => { |
||||||
|
util.successMsg('更换成功'); |
||||||
|
this.switchVisible = false |
||||||
|
this.getData() |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
}); |
||||||
|
}, |
||||||
|
switchSubmit() { |
||||||
|
if (this.uploading) return util.warningMsg('资源正在上传中,请稍候') |
||||||
|
if (!this.fileUrl && !this.fileId) return util.warningMsg('请上传资源') |
||||||
|
if (this.transferType(this.curFile.fileType) == '视频') { |
||||||
|
let data = { |
||||||
|
videoIdList: [this.sectionId] |
||||||
|
} |
||||||
|
this.$del(`${this.api.removeVideo}/${this.curFile.fileId}`).then(res => { |
||||||
|
this.switchSubmitFile() |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
} else { |
||||||
|
this.$del(`${this.api.fileDeletion}?keys=${this.curFile.fileName}`).then(res => { |
||||||
|
this.switchSubmitFile() |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
} |
||||||
|
}, |
||||||
|
delSection(row) { |
||||||
|
this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$del(`${this.api.deleteSubsection}/${row.id}`).then(res => { |
||||||
|
util.successMsg('删除成功'); |
||||||
|
this.getData() |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
}) |
||||||
|
.catch(() => { |
||||||
|
}); |
||||||
|
}, |
||||||
|
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) |
||||||
|
} else { |
||||||
|
let tempItem = this.chapters.splice(index + 1, 1)[0] |
||||||
|
this.chapters.splice(index, 0, tempItem) |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
sortSection(chapterIndex, type, disabled, index) { |
||||||
|
if (!disabled) { |
||||||
|
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.sectionName) return util.warningMsg('请填写小节名称') |
||||||
|
let data = { |
||||||
|
id: this.sectionId, |
||||||
|
courseId: this.id, |
||||||
|
chapterId: this.chapterId, |
||||||
|
name: this.sectionName |
||||||
|
} |
||||||
|
this.$put(this.api.editSubsection, data).then(res => { |
||||||
|
util.successMsg('修改成功'); |
||||||
|
this.sectionNameVisible = false |
||||||
|
this.getData() |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
}); |
||||||
|
}, |
||||||
|
closePlayer() { |
||||||
|
this.playAuth = '' |
||||||
|
this.player.pause() |
||||||
|
}, |
||||||
|
closeIframe() { |
||||||
|
this.iframeSrc = '' |
||||||
|
this.showMask = false |
||||||
|
this.showMask1 = false |
||||||
|
this.showMask2 = false |
||||||
|
this.previewing = false |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style scoped lang="scss"> |
||||||
|
.btns { |
||||||
|
position: absolute; |
||||||
|
top: 12px; |
||||||
|
right: 24px; |
||||||
|
|
||||||
|
.el-button { |
||||||
|
font-size: 14px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.sort-icon { |
||||||
|
font-size: 24px; |
||||||
|
cursor: pointer; |
||||||
|
|
||||||
|
&.disabled { |
||||||
|
color: #ccc; |
||||||
|
cursor: not-allowed |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.el-image-viewer__wrapper { |
||||||
|
transform: translateY(-10px); |
||||||
|
transition: transform .5s; |
||||||
|
|
||||||
|
&.active { |
||||||
|
transform: translateY(0) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.el-image-viewer__close { |
||||||
|
z-index: 10000; |
||||||
|
top: 15px; |
||||||
|
right: 15px; |
||||||
|
|
||||||
|
&.doc-close { |
||||||
|
i { |
||||||
|
color: #000 !important; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.player { |
||||||
|
position: absolute; |
||||||
|
top: 50%; |
||||||
|
left: 50%; |
||||||
|
transform: translate(-50%, -50%); |
||||||
|
width: 1200px !important; |
||||||
|
height: 600px !important; |
||||||
|
} |
||||||
|
|
||||||
|
.fileIframe { |
||||||
|
z-index: 1; |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
left: 0; |
||||||
|
bottom: 0; |
||||||
|
right: 0; |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
} |
||||||
|
|
||||||
|
.mask { |
||||||
|
z-index: 1000; |
||||||
|
position: fixed; |
||||||
|
background-color: rgb(57, 58, 61); |
||||||
|
} |
||||||
|
|
||||||
|
.word-mask { |
||||||
|
z-index: 1000; |
||||||
|
position: fixed; |
||||||
|
right: 0; |
||||||
|
width: 100%; |
||||||
|
background-color: rgb(243, 242, 241); |
||||||
|
} |
||||||
|
|
||||||
|
.word-mask1 { |
||||||
|
z-index: 1000; |
||||||
|
position: fixed; |
||||||
|
top: 0; |
||||||
|
right: 0; |
||||||
|
background-color: #2b579a; |
||||||
|
} |
||||||
|
|
||||||
|
.word-mask2 { |
||||||
|
z-index: 1000; |
||||||
|
position: fixed; |
||||||
|
background-color: transparent; |
||||||
|
} |
||||||
|
|
||||||
|
.excel-mask1 { |
||||||
|
z-index: 9; |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
left: 20%; |
||||||
|
width: 80%; |
||||||
|
background-color: #107c41; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,219 @@ |
|||||||
|
<template> |
||||||
|
<!-- 课程管理 --> |
||||||
|
<div style="padding-top: 24px"> |
||||||
|
<div class="tool"> |
||||||
|
<ul class="filter" style="align-items: flex-start"> |
||||||
|
<li> |
||||||
|
<label>课程分类:</label> |
||||||
|
<el-select v-model="classificationId" clearable placeholder="请选择课程分类" size="small" @change="getData"> |
||||||
|
<el-option label="不限" value=""></el-option> |
||||||
|
<el-option v-for="(item,index) in classificationList" :key="index" :label="item.name" :value="item.id"></el-option> |
||||||
|
</el-select> |
||||||
|
</li> |
||||||
|
<li> |
||||||
|
<label>搜索:</label> |
||||||
|
<el-input placeholder="请输入课程名称/创建人" suffix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input> |
||||||
|
</li> |
||||||
|
</ul> |
||||||
|
<div> |
||||||
|
<el-button type="primary" size="small" round @click="addCourse" v-auth="'course:课程管理:新增课程'">新增</el-button> |
||||||
|
<el-button type="primary" size="small" round @click="delAllData" v-auth="'course:课程管理:批量删除'">批量删除</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-table :data="courseData" class="table" ref="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id"> |
||||||
|
<el-table-column type="selection" width="80" align="center" :reserve-selection="true"></el-table-column> |
||||||
|
<el-table-column type="index" width="100" label="序号" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
{{ scope.$index + (current - 1) * pageSize + 1 }} |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="课程名称"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="gmtCreate" label="创建时间" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="founder" label="创建人" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="章节数" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
{{ scope.row.chapterNum ? scope.row.chapterNum : 0 }}章({{ scope.row.subsectionNum ? scope.row.subsectionNum : 0 }}小节) |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="classification" label="课程分类"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="操作" align="center" width="250"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text" @click="editCourse(scope.row)" v-auth="'course:课程管理:编辑信息'">编辑信息</el-button> |
||||||
|
<el-divider direction="vertical" v-auth="'course:课程管理:编辑信息'"></el-divider> |
||||||
|
<el-button type="text" @click="config(scope.row)" v-auth="'course:课程管理:配置资源'">内容设置</el-button> |
||||||
|
<el-divider direction="vertical" v-auth="'course:课程管理:配置资源'"></el-divider> |
||||||
|
<el-button type="text" @click="preview(scope.row)" v-auth="'course:课程管理:预览'">预览</el-button> |
||||||
|
<el-divider direction="vertical" v-auth="'course:课程管理:预览'"></el-divider> |
||||||
|
<el-button type="text" @click="handleDelete(scope.row)" v-auth="'course:课程管理:删除'">删除</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="可授权状态" align="center" width="120"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-switch |
||||||
|
v-model="scope.row.isEnable" |
||||||
|
:active-value="0" |
||||||
|
:inactive-value="1" |
||||||
|
style="margin: 0 5px" |
||||||
|
:active-text="scope.row.isEnable ? '关' : '开'" |
||||||
|
@change="switchOff($event,scope.row,scope.$index)" |
||||||
|
v-auth="'course:课程管理:禁用'" |
||||||
|
></el-switch> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination background layout="total, prev, pager, next" :total="totals" @current-change="handleCurrentChange" :current-page="current"> |
||||||
|
</el-pagination> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import util from '@/libs/util' |
||||||
|
|
||||||
|
export default { |
||||||
|
name: 'courseManagement', |
||||||
|
data() { |
||||||
|
return { |
||||||
|
schoolId: this.$store.state.schoolId, |
||||||
|
keyword: '', |
||||||
|
classificationId: '', |
||||||
|
courseData: [], |
||||||
|
multipleSelection: [], |
||||||
|
classificationList: [], |
||||||
|
current: 1, // 当前页码 |
||||||
|
pageSize: 10, |
||||||
|
totals: 0 |
||||||
|
}; |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
keyword: function(val) { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(() => { |
||||||
|
this.initData() |
||||||
|
}, 500) |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getClassification() |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData() { |
||||||
|
let data = { |
||||||
|
classificationId: this.classificationId, |
||||||
|
name: this.keyword |
||||||
|
} |
||||||
|
this.$get(`${this.api.queryCourseByCondition}/${this.current}/${this.pageSize}`, data).then(res => { |
||||||
|
this.courseData = res.courseList |
||||||
|
this.totals = res.total |
||||||
|
if (!this.courseData.length && this.totals) { |
||||||
|
this.current-- |
||||||
|
this.getData() |
||||||
|
} |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
}, |
||||||
|
initData() { |
||||||
|
this.current = 1 |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
getClassification() { |
||||||
|
this.$get(this.api.queryGlClassification).then(res => { |
||||||
|
this.classificationList = res.classificationList |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
}, |
||||||
|
changeType(type) { |
||||||
|
this.classificationId = type |
||||||
|
this.initData() |
||||||
|
}, |
||||||
|
preview(row) { |
||||||
|
this.$router.push(`/course/preview?id=${row.id}`) |
||||||
|
}, |
||||||
|
config(row) { |
||||||
|
this.$router.push(`/course/contentSettings?id=${row.id}`) |
||||||
|
}, |
||||||
|
addCourse() { |
||||||
|
this.$router.push('/course/add') |
||||||
|
}, |
||||||
|
editCourse(row) { |
||||||
|
this.$router.push(`/course/add?id=${row.id}`) |
||||||
|
}, |
||||||
|
handleDelete(row) { |
||||||
|
this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$del(`${this.api.deleteCourse}/${row.id}`).then(res => { |
||||||
|
util.successMsg('删除成功'); |
||||||
|
this.initData() |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
}) |
||||||
|
.catch(() => { |
||||||
|
}); |
||||||
|
}, |
||||||
|
getRowKeys(row) { |
||||||
|
return row.customerId; |
||||||
|
}, |
||||||
|
handleSelectionChange(val) { |
||||||
|
this.multipleSelection = val; |
||||||
|
}, |
||||||
|
delAllData() { |
||||||
|
if (this.multipleSelection.length != '') { |
||||||
|
let newArr = this.multipleSelection |
||||||
|
let delList = newArr.map(item => { |
||||||
|
return item.id |
||||||
|
}) |
||||||
|
this.$confirm(`此批量删除操作不可逆,是否确认删除${newArr[0].name}等${newArr.length}个选中项?`, '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
let data = { |
||||||
|
courseIds: delList.join() |
||||||
|
} |
||||||
|
this.$del(this.api.deleteCourses, data).then(res => { |
||||||
|
this.multipleSelection = []; |
||||||
|
this.$refs.table.clearSelection() |
||||||
|
util.successMsg('删除成功'); |
||||||
|
this.initData() |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
}).catch(() => { |
||||||
|
}); |
||||||
|
} else { |
||||||
|
util.errorMsg('请先选择数据 !'); |
||||||
|
} |
||||||
|
}, |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.current = val; |
||||||
|
this.getData(); |
||||||
|
}, |
||||||
|
switchOff(val, row, index) { |
||||||
|
this.$put(`${this.api.enableCourse}?courseId=${row.id}&isEnable=${val}`) |
||||||
|
.then(res => { |
||||||
|
this.getData() |
||||||
|
val == 1 ? util.warningMsg('该教学资源已隐藏,对学生端用户不可见') : util.successMsg('该教学资源已公开,对学生端用户可见') |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
/deep/ .tool { |
||||||
|
.filter { |
||||||
|
.el-input { |
||||||
|
min-width: 215px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,495 @@ |
|||||||
|
<template> |
||||||
|
<!-- 课程预览 --> |
||||||
|
<div> |
||||||
|
<el-card shadow="hover" class="m-b-20"> |
||||||
|
<div class="flex-between"> |
||||||
|
<el-page-header @back="goBack" :content="'课程预览'"></el-page-header> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
|
||||||
|
<el-card shadow="hover" class="m-b-20"> |
||||||
|
<div class="flex p-40"> |
||||||
|
<div class="cover" :class="{'is-word': showMask1}"> |
||||||
|
<img v-if="coverUrl" :src="coverUrl" alt="" width="100%" height="100%"> |
||||||
|
<template v-else-if="iframeSrc"> |
||||||
|
<iframe class="inner fileIframe" id="fileIframe" :src="iframeSrc" frameborder="0"></iframe> |
||||||
|
<template v-if="showMask"> |
||||||
|
<div class="mask" style="width: 500px;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-mask" style="height: 40px;"></div> |
||||||
|
<div class="word-mask2" style="top: 55px;left: 28%;width: 44%;height: calc(100% - 80px);"></div> |
||||||
|
</template> |
||||||
|
<template v-if="showMask2"> |
||||||
|
<div class="excel-mask1" style="height: 48px;"></div> |
||||||
|
</template> |
||||||
|
</template> |
||||||
|
<div class="pdf inner" v-else-if="pdfSrc"> |
||||||
|
<p class="arrow"> |
||||||
|
<span @click="changePdfPage(0)" class="turn el-icon-arrow-left" :class="{grey: currentPage==1}"></span> |
||||||
|
{{ currentPage }} / {{ pageCount }} |
||||||
|
<span @click="changePdfPage(1)" class="turn el-icon-arrow-right" :class="{grey: currentPage==pageCount}"></span> |
||||||
|
</p> |
||||||
|
<pdf |
||||||
|
class="pdf-wrap" |
||||||
|
:src="pdfSrc" |
||||||
|
:page="currentPage" |
||||||
|
@num-pages="pageCount=$event" |
||||||
|
@page-loaded="currentPage=$event" |
||||||
|
@loaded="loadPdfHandler"> |
||||||
|
</pdf> |
||||||
|
</div> |
||||||
|
<div class="inner" v-else-if="playAuth"> |
||||||
|
<div class="video_wid" id="player"></div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="catalog flex-1"> |
||||||
|
<div class="list"> |
||||||
|
<h4 class="title">{{ courseName }}</h4> |
||||||
|
<div class="desc-wrap"> |
||||||
|
<div class="desc" :class="{active: desShrink}" v-html="description"></div> |
||||||
|
<i class="arrow" :class="{active: desShrink}" v-if="description.length > 40"> |
||||||
|
<span>...</span> |
||||||
|
<img src="@/assets/img/arrow-down.png" alt="" @click="desShrink = !desShrink"> |
||||||
|
</i> |
||||||
|
</div> |
||||||
|
<div class="chapters"> |
||||||
|
<template v-if="videoList.length"> |
||||||
|
<div class="chapter" v-for="(item,index) in videoList" :key="index"> |
||||||
|
<div class="chapterName">{{ item.name }}</div> |
||||||
|
<div class="section" v-if="item.subsectionList.length"> |
||||||
|
<div class="sectionName" v-for="(section,i) in item.subsectionList" :key="i" @click="preview(section)">{{ section.name }}</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import util from '@/libs/util' |
||||||
|
import { mapState } from 'vuex'; |
||||||
|
import pdf from "vue-pdf"; |
||||||
|
import 'quill/dist/quill.core.css'; |
||||||
|
import 'quill/dist/quill.snow.css'; |
||||||
|
import 'quill/dist/quill.bubble.css'; |
||||||
|
|
||||||
|
export default { |
||||||
|
name: 'coursePreview', |
||||||
|
data() { |
||||||
|
return { |
||||||
|
id: this.$route.query.id, |
||||||
|
video: 'http://liuwanr.oss-cn-shenzhen.aliyuncs.com/mp4/20200519/1589871025648.mp4', |
||||||
|
videoSrc: '', |
||||||
|
videoList: [], |
||||||
|
courseName: '', |
||||||
|
description: '', |
||||||
|
coverUrl: '', |
||||||
|
playAuth: '', |
||||||
|
player: null, |
||||||
|
previewImg: '', |
||||||
|
iframeSrc: '', |
||||||
|
isWord: false, |
||||||
|
isPPT: false, |
||||||
|
isExcel: false, |
||||||
|
showMask: false, |
||||||
|
showMask1: false, |
||||||
|
showMask2: false, |
||||||
|
closePosi: { |
||||||
|
top: '80px' |
||||||
|
}, |
||||||
|
pdfVisible: false, |
||||||
|
pdfSrc: '', |
||||||
|
currentPage: 0, // pdf文件页码 |
||||||
|
pageCount: 0, // pdf文件总页数 |
||||||
|
fileType: 'pdf', // 文件类型 |
||||||
|
desShrink: false |
||||||
|
} |
||||||
|
}, |
||||||
|
components: { pdf }, |
||||||
|
mounted() { |
||||||
|
this.insertScript() |
||||||
|
this.getData() |
||||||
|
this.getChapter() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
goBack() { |
||||||
|
this.$router.back(); |
||||||
|
}, |
||||||
|
async getData() { |
||||||
|
let res = await this.$get(`${this.api.getCourse}/${this.id}`) |
||||||
|
this.courseName = res.course.name |
||||||
|
this.description = res.course.description |
||||||
|
this.coverUrl = res.course.coverUrl |
||||||
|
}, |
||||||
|
async getChapter() { |
||||||
|
let res = await this.$get(`${this.api.queryChaptersAndSubsections}/${this.id}`) |
||||||
|
this.videoList = res.chapterList |
||||||
|
}, |
||||||
|
insertScript() { |
||||||
|
const linkTag = document.createElement('link'); |
||||||
|
linkTag.rel = 'stylesheet'; |
||||||
|
linkTag.href = 'https://g.alicdn.com/de/prismplayer/2.8.2/skins/default/aliplayer-min.css'; |
||||||
|
document.body.appendChild(linkTag); |
||||||
|
|
||||||
|
const scriptTag = document.createElement('script'); |
||||||
|
scriptTag.type = 'text/javascript'; |
||||||
|
scriptTag.src = 'https://g.alicdn.com/de/prismplayer/2.8.2/aliplayer-min.js'; |
||||||
|
document.body.appendChild(scriptTag); |
||||||
|
}, |
||||||
|
transferType(ext) { |
||||||
|
if ('jpg,jpeg,png,gif,svg,psd'.includes(ext)) return '图片' |
||||||
|
if ('mp4,3gp,mov,m4v,avi,dat,mkv,flv,vob,rmvb,rm,qlv'.includes(ext)) return '视频' |
||||||
|
return ext |
||||||
|
}, |
||||||
|
preview(row) { |
||||||
|
this.player = null |
||||||
|
this.playauth = '' |
||||||
|
this.coverUrl = '' |
||||||
|
this.pdfSrc = '' |
||||||
|
this.iframeSrc = '' |
||||||
|
if (this.transferType(row.fileType) == '视频') { |
||||||
|
this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => { |
||||||
|
this.playAuth = res.playAuth |
||||||
|
this.$nextTick(() => { |
||||||
|
if (this.player) { |
||||||
|
this.player.replayByVidAndPlayAuth(row.fileId, this.playAuth) |
||||||
|
} else { |
||||||
|
this.player = new Aliplayer({ |
||||||
|
id: 'player', |
||||||
|
width: '100%', |
||||||
|
autoplay: false, |
||||||
|
vid: row.fileId, |
||||||
|
playauth: this.playAuth, |
||||||
|
encryptType: 1 //当播放私有加密流时需要设置。 |
||||||
|
}) |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
}).catch(res => { |
||||||
|
}) |
||||||
|
} else if (this.transferType(row.fileType) == '图片') { |
||||||
|
this.coverUrl = row.fileUrl |
||||||
|
} else if (row.fileType == 'pdf') { |
||||||
|
this.pdfSrc = row.fileUrl |
||||||
|
this.pdfVisible = true |
||||||
|
} else { |
||||||
|
this.$get(`${this.api.getSubsection}/${row.id}`).then(res => { |
||||||
|
if (row.fileType == 'pptx') { |
||||||
|
this.isPPT = true |
||||||
|
this.isWord = false |
||||||
|
this.isExcel = false |
||||||
|
} else if (row.fileType == 'doc' || row.fileType == 'docx') { |
||||||
|
this.isPPT = false |
||||||
|
this.isWord = true |
||||||
|
this.isExcel = false |
||||||
|
} else if (row.fileType == 'xls' || row.fileType == 'xlsx') { |
||||||
|
this.isExcel = true |
||||||
|
this.isPPT = false |
||||||
|
this.isWord = false |
||||||
|
} else { |
||||||
|
this.isPPT = false |
||||||
|
this.isWord = false |
||||||
|
this.isExcel = false |
||||||
|
} |
||||||
|
if (this.isPPT) { |
||||||
|
this.showMask = true |
||||||
|
} else { |
||||||
|
this.showMask = false |
||||||
|
} |
||||||
|
if (this.isWord) { |
||||||
|
this.showMask1 = true |
||||||
|
} else { |
||||||
|
this.showMask1 = false |
||||||
|
} |
||||||
|
if (this.isExcel) { |
||||||
|
this.showMask2 = true |
||||||
|
} else { |
||||||
|
this.showMask2 = false |
||||||
|
} |
||||||
|
this.iframeSrc = res.previewUrl |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
}); |
||||||
|
} |
||||||
|
}, |
||||||
|
closePlayer() { |
||||||
|
this.playAuth = '' |
||||||
|
this.player.pause() |
||||||
|
}, |
||||||
|
closeIframe() { |
||||||
|
this.iframeSrc = '' |
||||||
|
this.showMask = false |
||||||
|
this.showMask1 = false |
||||||
|
}, |
||||||
|
closePdf() { |
||||||
|
this.pdfSrc = '' |
||||||
|
this.currentPage = 1 |
||||||
|
}, |
||||||
|
changePdfPage(val) { |
||||||
|
if (val === 0 && this.currentPage > 1) { |
||||||
|
this.currentPage-- |
||||||
|
} |
||||||
|
if (val === 1 && this.currentPage < this.pageCount) { |
||||||
|
this.currentPage++ |
||||||
|
} |
||||||
|
}, |
||||||
|
loadPdfHandler(e) { |
||||||
|
this.currentPage = 1 |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
$height: 700px; |
||||||
|
.video_wid, .cover { |
||||||
|
position: relative; |
||||||
|
width: 76%; |
||||||
|
max-width: 1400px; |
||||||
|
height: $height !important; |
||||||
|
border: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.cover { |
||||||
|
img { |
||||||
|
border-radius: 8px; |
||||||
|
} |
||||||
|
|
||||||
|
&.is-word { |
||||||
|
overflow: hidden; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.fileIframe { |
||||||
|
height: $height !important; |
||||||
|
} |
||||||
|
|
||||||
|
.video_wid, .inner { |
||||||
|
width: 100%; |
||||||
|
height: 100% !important; |
||||||
|
border: 0; |
||||||
|
overflow: auto; |
||||||
|
} |
||||||
|
|
||||||
|
.cover.is-word { |
||||||
|
.inner { |
||||||
|
height: calc(100% + 38px) !important; |
||||||
|
margin-top: -38px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.video_wid:focus { |
||||||
|
outline: none; |
||||||
|
} |
||||||
|
|
||||||
|
.catalog { |
||||||
|
margin-left: 40px; |
||||||
|
} |
||||||
|
|
||||||
|
.list { |
||||||
|
height: $height; |
||||||
|
overflow-y: auto; |
||||||
|
padding: 24px 16px; |
||||||
|
background: #fff; |
||||||
|
|
||||||
|
.title { |
||||||
|
margin-bottom: 8px; |
||||||
|
color: rgba(0, 0, 0, 0.85); |
||||||
|
font-size: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
.desc-wrap { |
||||||
|
position: relative; |
||||||
|
|
||||||
|
.desc { |
||||||
|
font-size: 14px; |
||||||
|
color: rgba(0, 0, 0, 0.65); |
||||||
|
line-height: 22px; |
||||||
|
@include mul-ellipsis(2); |
||||||
|
|
||||||
|
&.active { |
||||||
|
display: block; |
||||||
|
overflow: visible; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.arrow { |
||||||
|
position: absolute; |
||||||
|
bottom: 2px; |
||||||
|
right: 0; |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
width: 46px; |
||||||
|
background-color: #fff; |
||||||
|
|
||||||
|
span { |
||||||
|
font-size: 14px; |
||||||
|
color: rgba(0, 0, 0, 0.65); |
||||||
|
} |
||||||
|
|
||||||
|
img { |
||||||
|
width: 16px; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
|
||||||
|
&.active { |
||||||
|
span { |
||||||
|
opacity: 0; |
||||||
|
} |
||||||
|
|
||||||
|
img { |
||||||
|
transform: rotate(180deg); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.chapters { |
||||||
|
margin-top: 16px; |
||||||
|
max-height: calc(100% - 53px); |
||||||
|
overflow: auto; |
||||||
|
} |
||||||
|
|
||||||
|
.chapter { |
||||||
|
margin-bottom: 20px; |
||||||
|
|
||||||
|
.chapterName { |
||||||
|
color: rgba(0, 0, 0, 0.85); |
||||||
|
font-size: 16px; |
||||||
|
} |
||||||
|
|
||||||
|
.section { |
||||||
|
padding: 5px 15px; |
||||||
|
margin-top: 8px; |
||||||
|
background: rgba(0, 0, 0, 0.02); |
||||||
|
|
||||||
|
.sectionName { |
||||||
|
margin: 10px 0; |
||||||
|
font-size: 14px; |
||||||
|
color: rgba(0, 0, 0, 0.65); |
||||||
|
cursor: pointer; |
||||||
|
@include ellipsis; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.el-image-viewer__wrapper { |
||||||
|
transform: translateY(-10px); |
||||||
|
transition: transform .5s; |
||||||
|
|
||||||
|
&.active { |
||||||
|
transform: translateY(0) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.el-image-viewer__close { |
||||||
|
z-index: 2000; |
||||||
|
top: 15px; |
||||||
|
right: 15px; |
||||||
|
|
||||||
|
&.doc-close { |
||||||
|
i { |
||||||
|
color: #000 !important; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.list::-webkit-scrollbar { |
||||||
|
width: 4px; |
||||||
|
} |
||||||
|
|
||||||
|
.list::-webkit-scrollbar-thumb { |
||||||
|
border-radius: 10px; |
||||||
|
background: rgba(0, 0, 0, 0.06); |
||||||
|
} |
||||||
|
|
||||||
|
.mask { |
||||||
|
z-index: 9; |
||||||
|
position: absolute; |
||||||
|
background-color: rgb(57, 58, 61); |
||||||
|
} |
||||||
|
|
||||||
|
.word-mask { |
||||||
|
z-index: 9; |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
right: 0; |
||||||
|
width: 100%; |
||||||
|
background-color: rgb(243, 242, 241); |
||||||
|
} |
||||||
|
|
||||||
|
.word-mask1 { |
||||||
|
z-index: 9; |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
right: 0; |
||||||
|
width: 100%; |
||||||
|
background-color: #185abd; |
||||||
|
} |
||||||
|
|
||||||
|
.word-mask2 { |
||||||
|
z-index: 9; |
||||||
|
position: absolute; |
||||||
|
background-color: transparent; |
||||||
|
} |
||||||
|
|
||||||
|
.excel-mask1 { |
||||||
|
z-index: 9; |
||||||
|
position: absolute; |
||||||
|
top: 0; |
||||||
|
left: 20%; |
||||||
|
width: 60%; |
||||||
|
background-color: #107c41; |
||||||
|
} |
||||||
|
|
||||||
|
/deep/ .pdf-dia { |
||||||
|
border-radius: 0 !important; |
||||||
|
|
||||||
|
.el-dialog__header { |
||||||
|
display: none; |
||||||
|
} |
||||||
|
|
||||||
|
.el-dialog__body { |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.el-dialog__headerbtn { |
||||||
|
top: 10px; |
||||||
|
|
||||||
|
.el-dialog__close { |
||||||
|
color: #fff; |
||||||
|
font-size: 16px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.pdf { |
||||||
|
.arrow { |
||||||
|
padding: 10px 0; |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
font-size: 16px; |
||||||
|
color: #fff; |
||||||
|
background-color: #333; |
||||||
|
|
||||||
|
.turn { |
||||||
|
margin: 0 10px; |
||||||
|
font-size: 18px; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.pdf-wrap { |
||||||
|
width: 80%; |
||||||
|
margin: 0 auto; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,66 @@ |
|||||||
|
<template> |
||||||
|
<!-- 理论课程管理 --> |
||||||
|
<div class="page"> |
||||||
|
<div class="tabs"> |
||||||
|
<a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == active}" @click="tabChange(index)">{{ item }}</a> |
||||||
|
</div> |
||||||
|
<div class="page-content"> |
||||||
|
<!-- 课程管理 --> |
||||||
|
<CourseManagement v-if="active == 'first'" /> |
||||||
|
<!-- 分类管理 --> |
||||||
|
<SortManagement v-else /> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import Setting from '@/setting'; |
||||||
|
import { mapState } from 'vuex' |
||||||
|
import CourseManagement from "./courseManagement"; |
||||||
|
import SortManagement from "./sortManagement"; |
||||||
|
|
||||||
|
export default { |
||||||
|
name: 'course', |
||||||
|
components: { |
||||||
|
CourseManagement, |
||||||
|
SortManagement |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
active: 'first', // 当前标签页 |
||||||
|
tabs: { |
||||||
|
first: '课程管理', |
||||||
|
second: '分类管理' |
||||||
|
}, |
||||||
|
showTabs: true |
||||||
|
} |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
...mapState('auth', [ |
||||||
|
'routes' |
||||||
|
]) |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
tabChange(index) { |
||||||
|
this.active = index; |
||||||
|
}, |
||||||
|
initTabs() { |
||||||
|
let btnPermissions = this.routes; |
||||||
|
let showStaff = btnPermissions.includes('课程资源管理:课程管理'); |
||||||
|
let showRole = btnPermissions.includes('课程资源管理:分类管理'); |
||||||
|
|
||||||
|
if (!showStaff || !showRole) { |
||||||
|
this.showTabs = false; |
||||||
|
} |
||||||
|
!showStaff && showRole && (this.active = 'second') |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
Setting.dynamicRoute && this.initTabs() |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
|
||||||
|
</style> |
@ -0,0 +1,166 @@ |
|||||||
|
<template> |
||||||
|
<!-- 分类管理 --> |
||||||
|
<div> |
||||||
|
<div class="tool"> |
||||||
|
<ul class="filter"> |
||||||
|
|
||||||
|
</ul> |
||||||
|
<div style="margin-top: 24px"> |
||||||
|
<el-button type="primary" size="small" round @click="addClass" v-auth="'course:分类管理:新增'">新增</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<el-table :data="classificationList" class="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id"> |
||||||
|
<el-table-column type="index" width="100" label="序号" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
{{ scope.$index + (pageNo - 1) * pageSize + 1 }} |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="课程分类名称"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="操作" align="center" width="300"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text" @click="editClass(scope.row)" v-auth="'course:分类管理:修改'">修改</el-button> |
||||||
|
<el-divider direction="vertical" v-auth="'course:分类管理:修改'"></el-divider> |
||||||
|
<el-button type="text" @click="handleDelete(scope.row)" v-auth="'course:分类管理:删除'">删除</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
|
||||||
|
<el-dialog :title="isAddclass ? '添加分类' : '编辑分类'" :visible.sync="classVisible" width="400px" :close-on-click-modal="false" @close="closeColumn"> |
||||||
|
<el-form> |
||||||
|
<el-form-item> |
||||||
|
<el-input placeholder="分类名称" v-model="className"></el-input> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<span slot="footer" class="dialog-footer"> |
||||||
|
<el-button size="small" @click="classVisible = false">取 消</el-button> |
||||||
|
<el-button size="small" type="primary" @click="classSubmit">确 定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import util from '@/libs/util' |
||||||
|
|
||||||
|
export default { |
||||||
|
name: 'sortManagement', |
||||||
|
data() { |
||||||
|
return { |
||||||
|
classificationList: [], |
||||||
|
multipleSelection: [], |
||||||
|
pageNo: 1, |
||||||
|
pageSize: 10, |
||||||
|
isAddclass: true, |
||||||
|
classVisible: false, |
||||||
|
curRow: {}, |
||||||
|
className: '' |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData() { |
||||||
|
this.$get(this.api.queryGlClassification).then(res => { |
||||||
|
this.classificationList = res.classificationList |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
}, |
||||||
|
addCourse() { |
||||||
|
this.$router.push('/addcourse') |
||||||
|
}, |
||||||
|
editCourse(row) { |
||||||
|
this.$router.push(`/addcourse?id=${row.id}`) |
||||||
|
}, |
||||||
|
handleDelete(row) { |
||||||
|
this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$del(`${this.api.deleteClassification}/${row.id}`).then(res => { |
||||||
|
util.successMsg('删除成功'); |
||||||
|
this.getData() |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
}) |
||||||
|
.catch(() => { |
||||||
|
}); |
||||||
|
}, |
||||||
|
getRowKeys(row) { |
||||||
|
return row.customerId; |
||||||
|
}, |
||||||
|
handleSelectionChange(val) { |
||||||
|
this.multipleSelection = val; |
||||||
|
}, |
||||||
|
closeColumn() { |
||||||
|
this.className = '' |
||||||
|
this.curRow = {} |
||||||
|
}, |
||||||
|
delAllData() { |
||||||
|
if (this.multipleSelection.length != '') { |
||||||
|
let newArr = this.multipleSelection |
||||||
|
let delList = newArr.map(item => { |
||||||
|
return item.id |
||||||
|
}) |
||||||
|
// 批量删除 |
||||||
|
this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
let data = delList.join() |
||||||
|
this.$del(this.api.deleteClassification, data).then(res => { |
||||||
|
this.multipleSelection = []; |
||||||
|
util.successMsg('删除成功'); |
||||||
|
this.getData() |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
}).catch(() => { |
||||||
|
}); |
||||||
|
} else { |
||||||
|
util.errorMsg('请先选择数据 !'); |
||||||
|
} |
||||||
|
}, |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.pageNo = val; |
||||||
|
this.getData(); |
||||||
|
}, |
||||||
|
addClass() { |
||||||
|
this.isAddClass = true |
||||||
|
this.classVisible = true |
||||||
|
}, |
||||||
|
editClass(row) { |
||||||
|
this.curRow = row |
||||||
|
this.className = row.name |
||||||
|
this.isAddClass = false |
||||||
|
this.classVisible = true |
||||||
|
}, |
||||||
|
classSubmit() { |
||||||
|
if (!this.className) return util.warningMsg('请填写分类名称') |
||||||
|
let data = { |
||||||
|
name: this.className |
||||||
|
} |
||||||
|
if (this.curRow.id) { |
||||||
|
data.id = this.curRow.id |
||||||
|
this.$put(this.api.editClassification, data).then(res => { |
||||||
|
util.successMsg('修改成功'); |
||||||
|
this.classVisible = false |
||||||
|
this.getData() |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
} else { |
||||||
|
this.$post(`${this.api.addClassification}/${this.className}?distinguish=1`).then(res => { |
||||||
|
util.successMsg('添加成功'); |
||||||
|
this.classVisible = false |
||||||
|
this.getData() |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
|
||||||
|
</style> |
@ -0,0 +1,397 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<div class='page'> |
||||||
|
<!-- |
||||||
|
<div class='tabs'> |
||||||
|
<a class='item' v-for='(item,index) in tabs' :key='index' :class='{active: index == activeName}' @click='tabChange(index)'>{{ item }}</a> |
||||||
|
</div> |
||||||
|
--> |
||||||
|
<div class='btn-wrap'> |
||||||
|
<template v-if='sorting'> |
||||||
|
<el-button class='action-btn' type='primary' size='small' round @click='cancelSort'>取消</el-button> |
||||||
|
<el-button class='action-btn' type='primary' size='small' round @click='sortSubmit'>保存</el-button> |
||||||
|
</template> |
||||||
|
<template v-if='!sorting'> |
||||||
|
<el-button class='action-btn' type='primary' size='small' round @click='openSort' v-auth>更改排序 |
||||||
|
</el-button> |
||||||
|
<el-button class='action-btn' type='primary' size='small' round @click='addColumn' v-auth>添加栏目 |
||||||
|
</el-button> |
||||||
|
</template> |
||||||
|
</div> |
||||||
|
<div class='page-content' style='padding-top: 24px; margin-top: 24px'> |
||||||
|
<div class='el-table'> |
||||||
|
<div class='list'> |
||||||
|
<div class='thead'> |
||||||
|
<span>栏目名称</span> |
||||||
|
<span><em :class='{hide: sorting}' style='font-style: normal'>操作</em></span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<el-tree :data='listData' node-key='id' default-expand-all @node-drop='handleDrop' |
||||||
|
:draggable='sorting' :allow-drop='allowDrop' :allow-drag='allowDrag'> |
||||||
|
<span class='custom-tree-node' slot-scope='{ node, data }'> |
||||||
|
<span class='name'>{{ node.label }}</span> |
||||||
|
<span class='action' v-show='!sorting'> |
||||||
|
<el-button type='text' @click.stop='editType(data)' v-auth>编辑</el-button> |
||||||
|
<el-divider direction='vertical' v-auth="'information:编辑'"></el-divider> |
||||||
|
<template v-if='node.level == 1' v-auth="'information:新增'"> |
||||||
|
<el-button type='text' @click.stop='addType(data)'>新增</el-button> |
||||||
|
<el-divider direction='vertical'></el-divider> |
||||||
|
</template> |
||||||
|
<el-button type='text' @click.stop='delData(data)' v-auth>删除</el-button> |
||||||
|
</span> |
||||||
|
</span> |
||||||
|
</el-tree> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-dialog :title="isAddColumn ? '添加栏目' : '编辑栏目'" :visible.sync='columnVisible' width='400px' |
||||||
|
:close-on-click-modal='false' @close='closeColumn'> |
||||||
|
<el-form> |
||||||
|
<el-form-item> |
||||||
|
<el-input placeholder='栏目名称' v-model='columnName'></el-input> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<span slot='footer' class='dialog-footer'> |
||||||
|
<el-button size='small' @click='columnVisible = false'>取 消</el-button> |
||||||
|
<el-button size='small' type='primary' @click='columnSubmit'>确 定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
|
||||||
|
<el-dialog :title="isAddType ? '添加分类' : '编辑分类'" :visible.sync='typeVisible' width='400px' |
||||||
|
:close-on-click-modal='false' @close='closeType'> |
||||||
|
<el-form> |
||||||
|
<el-form-item> |
||||||
|
<el-input placeholder='分类名称' v-model='typeName'></el-input> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
<span slot='footer' class='dialog-footer'> |
||||||
|
<el-button size='small' @click='typeVisible = false'>取 消</el-button> |
||||||
|
<el-button size='small' type='primary' @click='typeSubmit'>确 定</el-button> |
||||||
|
</span> |
||||||
|
</el-dialog> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import util from '@/libs/util' |
||||||
|
export default { |
||||||
|
name: 'columnManage', |
||||||
|
data() { |
||||||
|
return { |
||||||
|
activeName: 'first', |
||||||
|
tabs: { |
||||||
|
first: '栏目管理' |
||||||
|
}, |
||||||
|
name: this.$store.state.name, |
||||||
|
originalList: [], |
||||||
|
listData: [], |
||||||
|
multipleSelection: [], |
||||||
|
pageNo: 1, |
||||||
|
pageSize: 10, |
||||||
|
totals: 0, |
||||||
|
columnVisible: false, |
||||||
|
columnName: '', |
||||||
|
typeVisible: false, |
||||||
|
typeName: '', |
||||||
|
curRow: {}, |
||||||
|
sortObj: null, |
||||||
|
sorting: false, |
||||||
|
curParentId: '', |
||||||
|
isAddColumn: false, |
||||||
|
isAddType: false, |
||||||
|
defaultProps: { |
||||||
|
children: 'children', |
||||||
|
label: 'label' |
||||||
|
} |
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getData(); |
||||||
|
}, |
||||||
|
beforeRouteLeave(to, from, next) { |
||||||
|
if (JSON.stringify(this.originalList) !== JSON.stringify(this.listData)) { |
||||||
|
this.$confirm('确定返回?排序尚未保存。', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
next(); |
||||||
|
}) |
||||||
|
.catch(() => { |
||||||
|
}); |
||||||
|
} else { |
||||||
|
next(); |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData() { |
||||||
|
let data = { |
||||||
|
page: this.pageNo, |
||||||
|
size: this.pageSize |
||||||
|
}; |
||||||
|
this.$get(this.api.queryAllColumns, data).then(res => { |
||||||
|
let columnTree = res.columnTree; |
||||||
|
let total = columnTree.length; |
||||||
|
let list = []; |
||||||
|
columnTree.forEach((n, k) => { |
||||||
|
list.push({ |
||||||
|
id: n.id, |
||||||
|
label: n.name, |
||||||
|
level: n.level, |
||||||
|
parentId: n.parentId, |
||||||
|
sort: n.sort, |
||||||
|
children: [] |
||||||
|
}); |
||||||
|
n.secondColumn.forEach((j, i) => { |
||||||
|
list[k].children.push({ |
||||||
|
id: j.id, |
||||||
|
label: j.name, |
||||||
|
level: j.level, |
||||||
|
parentId: j.parentId, |
||||||
|
sort: j.sort |
||||||
|
}); |
||||||
|
}); |
||||||
|
total += n.secondColumn.length; |
||||||
|
}); |
||||||
|
this.listData = list; |
||||||
|
this.originalList = JSON.parse(JSON.stringify(this.listData)); |
||||||
|
this.totals = total; |
||||||
|
if (!this.listData.length && this.totals) { |
||||||
|
this.pageNo--; |
||||||
|
this.getData(); |
||||||
|
} |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
}, |
||||||
|
delData(row) { |
||||||
|
this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$del(`${this.api.deleteColumn}/${row.id}`).then(res => { |
||||||
|
util.successMsg('删除成功'); |
||||||
|
this.getData(); |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
}) |
||||||
|
.catch(() => { |
||||||
|
}); |
||||||
|
}, |
||||||
|
addColumn() { |
||||||
|
this.isAddColumn = true; |
||||||
|
this.columnVisible = true; |
||||||
|
}, |
||||||
|
sortSubmit() { |
||||||
|
let list = JSON.parse(JSON.stringify(this.listData)); |
||||||
|
list.forEach((n, k) => { |
||||||
|
n.name = n.label; |
||||||
|
n.parentId = 1; |
||||||
|
n.level = 1; |
||||||
|
n.sort = k + 1; |
||||||
|
n.children && n.children.forEach((j, i) => { |
||||||
|
j.name = j.label; |
||||||
|
j.parentId = n.id; |
||||||
|
j.level = 2; |
||||||
|
j.sort = i + 1; |
||||||
|
delete j.label; |
||||||
|
j.secondColumn = []; |
||||||
|
}); |
||||||
|
delete n.label; |
||||||
|
n.secondColumn = n.children; |
||||||
|
n.children = null; |
||||||
|
}); |
||||||
|
let data = { columnTree: list }; |
||||||
|
this.$post(this.api.columnReorder, data).then(res => { |
||||||
|
util.successMsg('保存成功'); |
||||||
|
this.sorting = false; |
||||||
|
this.getData(); |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
}, |
||||||
|
columnSubmit() { |
||||||
|
if (!this.columnName) return util.warningMsg('请填写栏目名称'); |
||||||
|
let data = { |
||||||
|
level: 1, |
||||||
|
parentId: 1, |
||||||
|
name: this.columnName |
||||||
|
}; |
||||||
|
if (this.curRow.id) { |
||||||
|
data.id = this.curRow.id; |
||||||
|
this.$put(this.api.editColumn, data).then(res => { |
||||||
|
util.warningMsg('修改成功'); |
||||||
|
this.columnVisible = false; |
||||||
|
this.getData(); |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
} else { |
||||||
|
this.$post(this.api.addColumn, data).then(res => { |
||||||
|
util.successMsg('添加成功'); |
||||||
|
this.columnVisible = false; |
||||||
|
this.getData(); |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
} |
||||||
|
}, |
||||||
|
addType(row) { |
||||||
|
this.isAddType = true; |
||||||
|
this.curRow = row; |
||||||
|
this.typeVisible = true; |
||||||
|
}, |
||||||
|
editType(row) { |
||||||
|
this.curRow = row; |
||||||
|
if (row.level == 1) { |
||||||
|
this.isAddColumn = false; |
||||||
|
this.columnVisible = true; |
||||||
|
this.columnName = row.label; |
||||||
|
} else { |
||||||
|
this.isAddType = false; |
||||||
|
this.typeVisible = true; |
||||||
|
this.typeName = row.label; |
||||||
|
} |
||||||
|
}, |
||||||
|
typeSubmit(row) { |
||||||
|
if (!this.typeName) return util.warningMsg('请填写分类名称'); |
||||||
|
let data = { |
||||||
|
level: 2, |
||||||
|
name: this.typeName |
||||||
|
}; |
||||||
|
if (this.curRow.level == 2) { |
||||||
|
data.id = this.curRow.id; |
||||||
|
data.parentId = this.curRow.parentId; |
||||||
|
this.$put(this.api.editColumn, data).then(res => { |
||||||
|
util.successMsg('修改成功'); |
||||||
|
this.typeVisible = false; |
||||||
|
this.getData(); |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
} else { |
||||||
|
data.parentId = this.curRow.id; |
||||||
|
this.$post(this.api.addColumn, data).then(res => { |
||||||
|
util.successMsg('新增成功'); |
||||||
|
this.typeVisible = false; |
||||||
|
this.getData(); |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
} |
||||||
|
}, |
||||||
|
cancelSort() { |
||||||
|
this.sorting = false; |
||||||
|
this.listData = JSON.parse(JSON.stringify(this.originalList)); |
||||||
|
this.sortObj.destroy(); |
||||||
|
}, |
||||||
|
openSort() { |
||||||
|
this.sorting = true; |
||||||
|
}, |
||||||
|
handleSelectionChange(val) { |
||||||
|
this.multipleSelection = val; |
||||||
|
}, |
||||||
|
onSearch() { |
||||||
|
this.pageNo = 1; |
||||||
|
this.getData(); |
||||||
|
}, |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.pageNo = val; |
||||||
|
this.getData(); |
||||||
|
}, |
||||||
|
closeColumn() { |
||||||
|
this.columnName = ''; |
||||||
|
this.curRow = {}; |
||||||
|
}, |
||||||
|
closeType() { |
||||||
|
this.typeName = ''; |
||||||
|
this.curRow = {}; |
||||||
|
}, |
||||||
|
handleDrop(draggingNode, dropNode, dropType, ev) { |
||||||
|
// console.log('tree drop: ', dropNode, dropType); |
||||||
|
}, |
||||||
|
allowDrop(draggingNode, dropNode, type) { |
||||||
|
if (dropNode.level == 2 && draggingNode.childNodes.length == 0) { |
||||||
|
return type !== 'inner'; |
||||||
|
} else if ((draggingNode.childNodes.length > 0 && dropNode.level == 2) || (draggingNode.childNodes.length > 0 && type == 'inner')) { |
||||||
|
return false; |
||||||
|
} else { |
||||||
|
return true; |
||||||
|
} |
||||||
|
}, |
||||||
|
allowDrag(draggingNode) { |
||||||
|
return draggingNode.data.label.indexOf('三级 3-2-2') === -1; |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang='scss' scoped> |
||||||
|
.btn-wrap { |
||||||
|
position: absolute; |
||||||
|
top: 15px; |
||||||
|
right: 15px; |
||||||
|
} |
||||||
|
|
||||||
|
.list { |
||||||
|
.thead { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: space-between; |
||||||
|
background: rgba(0, 0, 0, 0.04) !important; |
||||||
|
|
||||||
|
span { |
||||||
|
padding: 0.75rem 0.625rem; |
||||||
|
text-align: center; |
||||||
|
font-size: 14px; |
||||||
|
color: rgba(0, 0, 0, 0.85); |
||||||
|
font-weight: normal; |
||||||
|
box-sizing: border-box; |
||||||
|
|
||||||
|
&:first-child { |
||||||
|
padding-left: 23.5vw; |
||||||
|
@media(max-width: 1270px) { |
||||||
|
padding-left: 25.5%; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
&:last-child { |
||||||
|
width: 16%; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/deep/ .el-tree { |
||||||
|
.el-tree-node__expand-icon { |
||||||
|
margin-left: 22.5vw; |
||||||
|
@media(max-width: 1270px) { |
||||||
|
margin-left: 23.5%; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.el-tree-node__content { |
||||||
|
padding: 20px; |
||||||
|
border-bottom: 0.0625rem solid #EBEEF5; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.custom-tree-node { |
||||||
|
flex: 1; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: space-between; |
||||||
|
font-size: 14px; |
||||||
|
padding-right: 8px; |
||||||
|
|
||||||
|
.name { |
||||||
|
line-height: 44px; |
||||||
|
} |
||||||
|
|
||||||
|
.action { |
||||||
|
width: 8.5vw; |
||||||
|
text-align: left; |
||||||
|
@media(max-width: 1270px) { |
||||||
|
width: 16%; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.hide { |
||||||
|
opacity: 0; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,267 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<el-card shadow="hover" class="m-b-20"> |
||||||
|
<div class="flex-between"> |
||||||
|
<el-page-header @back="goBack" :content="'新增文章'"></el-page-header> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
<el-card shadow="hover" class="m-b-20"> |
||||||
|
<el-form label-width="90px" label-suffix=":" size="small"> |
||||||
|
<el-form-item label="封面图"> |
||||||
|
<el-upload |
||||||
|
class="avatar-uploader" |
||||||
|
accept=".jpg,.png,.jpeg" |
||||||
|
:on-remove="handleRemove" |
||||||
|
:on-error="uploadError" |
||||||
|
:on-success="uploadSuccess" |
||||||
|
:before-remove="beforeRemove" |
||||||
|
:limit="1" |
||||||
|
:on-exceed="handleExceed" |
||||||
|
:action="this.api.fileupload" |
||||||
|
:headers="headers" |
||||||
|
name="file" |
||||||
|
> |
||||||
|
<img v-if="coverUrl" :src="coverUrl" class="avatar"> |
||||||
|
<div class="uploader-default" v-else> |
||||||
|
<i class="el-icon-plus"></i> |
||||||
|
<p>上传封面</p> |
||||||
|
</div> |
||||||
|
</el-upload> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="作者"> |
||||||
|
<div class="d-inline-block"> |
||||||
|
<el-input placeholder="请输入作者" v-model="author" clearable></el-input> |
||||||
|
</div> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="日期"> |
||||||
|
<div class="d-inline-block"> |
||||||
|
<el-date-picker v-model="date" type="date" value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择日期"></el-date-picker> |
||||||
|
</div> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="文章标题"> |
||||||
|
<el-input placeholder="请输入文章标题" v-model="title" clearable></el-input> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="文章内容"> |
||||||
|
<quill :border="true" v-model="content" :uploading.sync="uploading" :height="400" /> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item> |
||||||
|
<el-button type="primary" v-throttle @click="saveData">确定</el-button> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
</el-card> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import quill from '@/components/quill' |
||||||
|
import util from '@/libs/util' |
||||||
|
import Setting from '@/setting' |
||||||
|
export default { |
||||||
|
name: 'addArticle', |
||||||
|
data() { |
||||||
|
return { |
||||||
|
headers: { |
||||||
|
token: util.local.get(Setting.tokenKey) |
||||||
|
}, |
||||||
|
columnId: this.$route.query.columnId, |
||||||
|
sort: this.$route.query.sort, |
||||||
|
id: '', |
||||||
|
coverUrl: '', |
||||||
|
uploadList: [], |
||||||
|
uploadDataList: [], |
||||||
|
author: '', |
||||||
|
date: '', |
||||||
|
title: '', |
||||||
|
content: '', |
||||||
|
submiting: false, |
||||||
|
uploading: false |
||||||
|
}; |
||||||
|
}, |
||||||
|
components: { |
||||||
|
quill |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.id = this.$route.query.id |
||||||
|
this.id && this.getData() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 返回 |
||||||
|
goBack() { |
||||||
|
this.$router.back(); |
||||||
|
}, |
||||||
|
getData() { |
||||||
|
this.$get(`${this.api.getArticle}/${this.id}`) |
||||||
|
.then(res => { |
||||||
|
let data = res.article |
||||||
|
this.coverUrl = data.coverUrl |
||||||
|
this.author = data.author |
||||||
|
this.date = data.date |
||||||
|
this.title = data.title |
||||||
|
this.content = data.content |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
|
||||||
|
}); |
||||||
|
}, |
||||||
|
saveData() { |
||||||
|
if(this.submiting) return false |
||||||
|
if(!this.coverUrl) return util.warningMsg('请上传封面图') |
||||||
|
if(!this.author) return util.warningMsg('请填写作者') |
||||||
|
if(!this.date) return util.warningMsg('请选择日期') |
||||||
|
if(!this.title) return util.warningMsg('请填写文章标题') |
||||||
|
if(!this.content) return util.warningMsg('请填写文章内容') |
||||||
|
if(this.uploading) return util.warningMsg('图片正在上传中,请稍等') |
||||||
|
this.submiting = true |
||||||
|
|
||||||
|
let data = { |
||||||
|
id: this.id, |
||||||
|
columnId: this.columnId, |
||||||
|
author: this.author, |
||||||
|
coverUrl: this.coverUrl, |
||||||
|
date: this.date, |
||||||
|
title: this.title, |
||||||
|
content: this.content, |
||||||
|
sort: this.sort |
||||||
|
} |
||||||
|
if(this.id){ |
||||||
|
this.$put(this.api.editArticle, data).then(res => { |
||||||
|
this.submiting = false |
||||||
|
util.successMsg('修改成功'); |
||||||
|
this.back() |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
this.submiting = false |
||||||
|
}) |
||||||
|
}else{ |
||||||
|
this.$post(this.api.addArticle, data).then(res => { |
||||||
|
this.submiting = false |
||||||
|
util.successMsg('创建成功'); |
||||||
|
this.back() |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
this.submiting = false |
||||||
|
}) |
||||||
|
} |
||||||
|
}, |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.currPage = val; |
||||||
|
}, |
||||||
|
handleExceed(files, fileList) { |
||||||
|
util.warningMsg(`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`); |
||||||
|
}, |
||||||
|
uploadSuccess(res, file, fileList) { |
||||||
|
if(this.coverUrl){ |
||||||
|
let fileName = this.coverUrl.replace('https://liuwanr.oss-cn-shenzhen.aliyuncs.com/','') |
||||||
|
this.$del(`${this.api.fileDeletion}?keys=${fileName}`).then(res => {}).catch(res => {}); |
||||||
|
} |
||||||
|
this.coverUrl = res.filesResult.fileUrl |
||||||
|
}, |
||||||
|
uploadError(err, file, fileList) { |
||||||
|
this.$message({ |
||||||
|
message: "上传出错,请重试!", |
||||||
|
type: "error", |
||||||
|
center: true |
||||||
|
}); |
||||||
|
}, |
||||||
|
beforeRemove(file, fileList) { |
||||||
|
return this.$confirm(`确定移除 ${file.name}?`); |
||||||
|
}, |
||||||
|
handleRemove(file, fileList) { |
||||||
|
let fileName = this.coverUrl.replace('https://liuwanr.oss-cn-shenzhen.aliyuncs.com/','') |
||||||
|
this.$del(`${this.api.fileDeletion}?keys=${fileName}`).then(res => { |
||||||
|
this.coverUrl = '' |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
uploadSure(){ |
||||||
|
this.BatchUpload = false |
||||||
|
this.pageNo = 1 |
||||||
|
this.keyword = '' |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
back(){ |
||||||
|
// this.$router.push(`/content?id=${this.columnId}`) |
||||||
|
this.$router.back() |
||||||
|
}, |
||||||
|
goback() { |
||||||
|
this.$confirm('确定返回?未更新的信息将不会保存。', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.back() |
||||||
|
}) |
||||||
|
.catch(() => {}); |
||||||
|
}, |
||||||
|
addSponsor(){ |
||||||
|
this.sponsorList.push('') |
||||||
|
}, |
||||||
|
delSponsor(index){ |
||||||
|
this.sponsorList.splice(index,1) |
||||||
|
}, |
||||||
|
addOrganizer(){ |
||||||
|
this.organzinerList.push('') |
||||||
|
}, |
||||||
|
delOrganizer(index){ |
||||||
|
this.organzinerList.splice(index,1) |
||||||
|
}, |
||||||
|
}, |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
$avatar-width: 104px; |
||||||
|
/deep/.avatar-uploader{ |
||||||
|
.el-upload { |
||||||
|
position: relative; |
||||||
|
width: $avatar-width; |
||||||
|
border: 1px dashed #d9d9d9; |
||||||
|
border-radius: 2px; |
||||||
|
cursor: pointer; |
||||||
|
overflow: hidden; |
||||||
|
&:hover { |
||||||
|
border-color: #409EFF; |
||||||
|
} |
||||||
|
.uploader-default{ |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
justify-content: center; |
||||||
|
width: $avatar-width !important; |
||||||
|
height: $avatar-width; |
||||||
|
text-align: center; |
||||||
|
background: rgba(0, 0, 0, 0.04); |
||||||
|
i{ |
||||||
|
font-size: 20px; |
||||||
|
font-weight: bold; |
||||||
|
color: #8c939d; |
||||||
|
} |
||||||
|
p{ |
||||||
|
margin-top: 10px; |
||||||
|
font-size: 14px; |
||||||
|
color: rgba(0, 0, 0, 0.65); |
||||||
|
line-height: 1; |
||||||
|
} |
||||||
|
} |
||||||
|
.avatar { |
||||||
|
width: $avatar-width; |
||||||
|
height: $avatar-width; |
||||||
|
display: block; |
||||||
|
} |
||||||
|
} |
||||||
|
.el-upload__tip{ |
||||||
|
margin-top: 0; |
||||||
|
p{ |
||||||
|
font-size: 14px; |
||||||
|
color: rgba(0, 0, 0, 0.45); |
||||||
|
line-height: 1; |
||||||
|
&:first-child{ |
||||||
|
margin-bottom: 5px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
/deep/.d-inline-block{ |
||||||
|
width: 216px; |
||||||
|
.el-select,.el-input{ |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,197 @@ |
|||||||
|
<template> |
||||||
|
<div class="page"> |
||||||
|
<!-- <div class="tabs">--> |
||||||
|
<!-- <a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == activeName}" @click="tabChange(index)">{{item}}</a>--> |
||||||
|
<!-- </div>--> |
||||||
|
<div class="btn-wrap"> |
||||||
|
<el-button class="action-btn" type="primary" size="small" @click="sortSubmit" v-auth="'content:保存排序'">保存排序</el-button> |
||||||
|
<el-button class="action-btn" type="primary" size="small" @click="delAllData" v-auth="'content:批量删除'">批量删除</el-button> |
||||||
|
<el-button class="action-btn" type="primary" size="small" @click="addArticle" v-auth="'content:新增文章'">新增文章</el-button> |
||||||
|
</div> |
||||||
|
<div class="page-content" style='padding-top: 24px'> |
||||||
|
<el-table ref="table" :data="listData" class="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id"> |
||||||
|
<el-table-column type="selection" width="80" align="center" :reserve-selection="true"></el-table-column> |
||||||
|
<el-table-column type="index" width="60" label="序号" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
{{scope.$index + (pageNo - 1) * pageSize + 1}} |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="title" label="标题"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="排序值" width="80" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-input size="small" class="sort-input" width="120" min="1" v-model.number="scope.row.sort" type="number" v-auth="'content:保存排序'"></el-input> |
||||||
|
<span>{{scope.row.sort}}</span> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="date" label="添加日期" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
{{transferDate(scope.row.date)}} |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="操作" align="center" width="170"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text" @click="editArticle(scope)" v-auth="'content:编辑'">编辑</el-button> |
||||||
|
<el-divider direction="vertical"></el-divider> |
||||||
|
<el-button type="text" @click="delData(scope.row)" v-auth="'content:删除'">删除</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="文章发布状态" width="120" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-switch |
||||||
|
class="off" |
||||||
|
v-model="scope.row.status" |
||||||
|
:active-value="0" |
||||||
|
:inactive-value="1" |
||||||
|
style="margin: 0 5px" |
||||||
|
:active-text="scope.row.status ? '关' : '开'" |
||||||
|
@change="switchOff($event,scope.row,scope.$index)" |
||||||
|
v-auth="'content:禁用'" |
||||||
|
></el-switch> |
||||||
|
<span>{{scope.row.status ? '禁用' : '启用'}}</span> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination background layout="total, prev, pager, next" :total="totals" @current-change="handleCurrentChange" :current-page="pageNo"> |
||||||
|
</el-pagination> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import util from '@/libs/util' |
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
activeName: 'first', |
||||||
|
tabs: { |
||||||
|
first: '栏目内容管理' |
||||||
|
}, |
||||||
|
listData: [], |
||||||
|
multipleSelection: [], |
||||||
|
pageNo: 1, |
||||||
|
pageSize: 10, |
||||||
|
totals: 0, |
||||||
|
}; |
||||||
|
}, |
||||||
|
props: { |
||||||
|
columnId: "" |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
columnId(){ |
||||||
|
this.getData() |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData(id){ |
||||||
|
let data = { |
||||||
|
columnId: this.columnId |
||||||
|
} |
||||||
|
this.$get(`${this.api.queryArticleByCondition}/${this.pageNo}/${this.pageSize}`,data).then(res => { |
||||||
|
this.listData = res.articleList |
||||||
|
this.totals = res.total |
||||||
|
if(!this.listData.length && this.totals){ |
||||||
|
this.pageNo-- |
||||||
|
this.getData() |
||||||
|
} |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
handleSelectionChange(val) { |
||||||
|
this.multipleSelection = val |
||||||
|
}, |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.pageNo = val |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
addArticle(){ |
||||||
|
this.$router.push(`/information/addarticle?columnId=${this.columnId}&sort=${this.listData.length+1}`) |
||||||
|
}, |
||||||
|
editArticle(scope){ |
||||||
|
this.$router.push(`/information/addarticle?columnId=${this.columnId}&id=${scope.row.id}&sort=${scope.$index+1}`) |
||||||
|
}, |
||||||
|
delData(row) { |
||||||
|
this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$del(`${this.api.deleteArticles}?articleIds=${row.id}`).then(res => { |
||||||
|
util.successMsg('删除成功'); |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}); |
||||||
|
}) |
||||||
|
.catch(() => {}); |
||||||
|
}, |
||||||
|
transferDate(date){ |
||||||
|
return date.replace(' 00:00:00','') |
||||||
|
}, |
||||||
|
delAllData() { |
||||||
|
if(this.multipleSelection.length != ''){ |
||||||
|
let newArr = this.multipleSelection |
||||||
|
let delList = newArr.map(item => { |
||||||
|
return item.id |
||||||
|
}) |
||||||
|
|
||||||
|
let title = newArr[0].title |
||||||
|
if(title.length > 14){ |
||||||
|
title = title.substr(0,14) + '……' |
||||||
|
} |
||||||
|
this.$confirm(`此批量删除操作不可逆,是否确认删除${title}等${newArr.length}个选中项?`, '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$del(`${this.api.deleteArticles}?articleIds=${delList.join(',')}`).then(res => { |
||||||
|
this.$refs.table.clearSelection() |
||||||
|
util.successMsg('删除成功'); |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}) |
||||||
|
}) |
||||||
|
.catch(() => {}); |
||||||
|
}else{ |
||||||
|
util.errorMsg('请先选择数据 !') |
||||||
|
} |
||||||
|
}, |
||||||
|
switchOff(val,row,index) { |
||||||
|
this.$put(`${this.api.enableArticle}/${row.id}/${val}`) |
||||||
|
.then(res => { |
||||||
|
val == 1 ? util.errorMsg('该文章已隐藏,对学生端用户不可见') : util.successMsg('该文章已发布,对学生端用户可见') |
||||||
|
}) |
||||||
|
.catch(err => {}) |
||||||
|
}, |
||||||
|
sortSubmit(){ |
||||||
|
if(this.listData.length){ |
||||||
|
if(this.listData.find(n => n.sort < 1)) return util.errorMsg('排序值最小为1') |
||||||
|
let data = {articleList: this.listData} |
||||||
|
this.$post(this.api.articleSort, data).then(res => { |
||||||
|
util.successMsg('保存成功') |
||||||
|
this.getContent(this.columnId) |
||||||
|
}) |
||||||
|
.catch(err => {}) |
||||||
|
}else{ |
||||||
|
util.errorMsg('数据为空') |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.btn-wrap{ |
||||||
|
text-align: right; |
||||||
|
} |
||||||
|
.sort-input{ |
||||||
|
/deep/.el-input__inner{ |
||||||
|
padding: 0 0 0 10px; |
||||||
|
} |
||||||
|
} |
||||||
|
.sort-input+span{ |
||||||
|
display: none; |
||||||
|
} |
||||||
|
.off+span{ |
||||||
|
display: none; |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,102 @@ |
|||||||
|
<template> |
||||||
|
<!-- 内容管理 --> |
||||||
|
<div> |
||||||
|
<el-row :gutter="20"> |
||||||
|
<el-col :span="3"> |
||||||
|
<div class="menu-con"> |
||||||
|
<el-menu |
||||||
|
ref="columnMenu" |
||||||
|
unique-opened |
||||||
|
text-color="#303133" |
||||||
|
:default-active="activeName" |
||||||
|
@select="handleSelect" |
||||||
|
> |
||||||
|
<template v-for="item in menuList"> |
||||||
|
<template v-if="item.secondColumn && item.secondColumn.length"> |
||||||
|
<el-submenu :index="item.id"> |
||||||
|
<template slot="title"> |
||||||
|
<span>{{ item.name }}</span> |
||||||
|
</template> |
||||||
|
<el-menu-item v-for="item2 in item.secondColumn" :index="item2.id">{{ item2.name }}</el-menu-item> |
||||||
|
</el-submenu> |
||||||
|
</template> |
||||||
|
<template v-else> |
||||||
|
<el-menu-item :index="item.id">{{ item.name }}</el-menu-item> |
||||||
|
</template> |
||||||
|
</template> |
||||||
|
</el-menu> |
||||||
|
</div> |
||||||
|
</el-col> |
||||||
|
<el-col :span="21"> |
||||||
|
<ContentList v-show="menuList.length" :columnId="columnId" /> |
||||||
|
</el-col> |
||||||
|
</el-row> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import ContentList from './contentList' |
||||||
|
import { mapActions } from 'vuex' |
||||||
|
export default { |
||||||
|
name: 'contentManage', |
||||||
|
components: { |
||||||
|
ContentList |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
menuList: [], |
||||||
|
activeName: this.$store.state.info.columnId, |
||||||
|
columnId: "" |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getMenuData(); |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
...mapActions('info', [ |
||||||
|
'setColumnId' |
||||||
|
]), |
||||||
|
getMenuData() { |
||||||
|
this.$get(this.api.queryAllColumns, { page: 1, size: 10000 }).then(res => { |
||||||
|
this.menuList = res.columnTree; |
||||||
|
if (this.menuList.length) { |
||||||
|
if (this.menuList[0].secondColumn && this.menuList[0].secondColumn.length) { |
||||||
|
this.columnId = this.menuList[0].secondColumn[0].id; |
||||||
|
} else { |
||||||
|
this.columnId = this.menuList[0].id; |
||||||
|
} |
||||||
|
if (!this.$store.state.info.columnId) { |
||||||
|
this.setColumnId(this.columnId); |
||||||
|
} else { |
||||||
|
this.columnId = this.$store.state.info.columnId; |
||||||
|
} |
||||||
|
} |
||||||
|
}).catch(err => { |
||||||
|
}); |
||||||
|
}, |
||||||
|
handleSelect(key, keyPath) { |
||||||
|
this.columnId = key; |
||||||
|
this.setColumnId(key); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.menu-con { |
||||||
|
height: calc(100vh - 250px); |
||||||
|
border-right: solid 1px #e6e6e6; |
||||||
|
background-color: #F2F6FC; |
||||||
|
overflow: hidden; |
||||||
|
.el-menu{ |
||||||
|
background-color: transparent; |
||||||
|
.el-submenu{ |
||||||
|
background-color: transparent; |
||||||
|
} |
||||||
|
.el-menu-item.is-active{ |
||||||
|
color: #ffffff; |
||||||
|
background-color: #9278FF; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,64 @@ |
|||||||
|
<template> |
||||||
|
<!-- 资讯管理 --> |
||||||
|
<div class="page"> |
||||||
|
<el-tabs v-model="tabsName" tab-position="left" @tab-click="handleClick"> |
||||||
|
<el-tab-pane name="1"> |
||||||
|
<span slot="label"><i class="el-icon-collection-tag"></i> 栏目管理</span> |
||||||
|
<columnManage v-if="tabsName === '1'" /> |
||||||
|
</el-tab-pane> |
||||||
|
<el-tab-pane name="2"> |
||||||
|
<span slot="label"><i class="el-icon-document"></i> 内容管理</span> |
||||||
|
<ContentManage v-if="tabsName === '2'" /> |
||||||
|
</el-tab-pane> |
||||||
|
</el-tabs> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import ColumnManage from './columnManage' |
||||||
|
import ContentManage from './contentManage' |
||||||
|
import { mapActions } from 'vuex' |
||||||
|
|
||||||
|
export default { |
||||||
|
components: { |
||||||
|
ColumnManage, |
||||||
|
ContentManage |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
tabsName: this.$store.state.info.tabsName, |
||||||
|
} |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
...mapActions('info', [ |
||||||
|
'setTabsName' |
||||||
|
]), |
||||||
|
handleClick(tab, event) { |
||||||
|
this.setTabsName(tab.name) |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.page .el-tabs--left { |
||||||
|
height: calc(100vh - 250px); |
||||||
|
|
||||||
|
/deep/ .el-tabs__item { |
||||||
|
height: 60px; |
||||||
|
line-height: 60px; |
||||||
|
} |
||||||
|
|
||||||
|
/deep/ el-tabs__active-bar { |
||||||
|
height: 60px; |
||||||
|
transform: translateY(60px); |
||||||
|
} |
||||||
|
|
||||||
|
.el-menu { |
||||||
|
border-right: 0; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,472 @@ |
|||||||
|
<template> |
||||||
|
<div> |
||||||
|
<el-card shadow="hover" class="m-b-20"> |
||||||
|
<div class="flex-between"> |
||||||
|
<el-page-header @back="goBack" :content="'创建赛事'"></el-page-header> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
<el-card shadow="hover" class="m-b-20"> |
||||||
|
<el-form label-width='170px' label-suffix=':' size='small'> |
||||||
|
<el-form-item label='竞赛封面(选填)'> |
||||||
|
<el-upload |
||||||
|
class='avatar-uploader' |
||||||
|
accept='.jpg,.png,.jpeg,.gif' |
||||||
|
:on-remove='handleRemove' |
||||||
|
:on-error='uploadError' |
||||||
|
:on-success='uploadSuccess' |
||||||
|
:before-remove='beforeRemove' |
||||||
|
:limit='1' |
||||||
|
:on-exceed='handleExceed' |
||||||
|
:action='this.api.fileupload' |
||||||
|
:headers="headers" |
||||||
|
name='file' |
||||||
|
> |
||||||
|
<img v-if='coverUrl' :src='coverUrl' class='avatar'> |
||||||
|
<div class='uploader-default' v-else> |
||||||
|
<i class='el-icon-plus'></i> |
||||||
|
<p>上传封面</p> |
||||||
|
</div> |
||||||
|
<div slot='tip' class='el-upload__tip'> |
||||||
|
<p>展示宽度为220,高度140,JPG/PNG/GIF,3MB以内</p> |
||||||
|
</div> |
||||||
|
</el-upload> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label='竞赛封面长图(选填)'> |
||||||
|
<el-upload |
||||||
|
class='avatar-uploader avatar-uploader-lg' |
||||||
|
accept='.jpg,.png,.jpeg,.gif' |
||||||
|
:on-remove='handleLgRemove' |
||||||
|
:on-error='uploadError' |
||||||
|
:on-success='uploadLgSuccess' |
||||||
|
:before-remove='beforeRemove' |
||||||
|
:limit='1' :on-exceed='handleExceed' |
||||||
|
:action='this.api.fileupload' |
||||||
|
:headers="headers" |
||||||
|
name='file' |
||||||
|
> |
||||||
|
<img v-if='carouselUrl' :src='carouselUrl' class='avatar-lg'> |
||||||
|
<div class='uploader-default' v-else> |
||||||
|
<i class='el-icon-plus'></i> |
||||||
|
<p>上传封面</p> |
||||||
|
</div> |
||||||
|
<div slot='tip' class='el-upload__tip'> |
||||||
|
<p>展示宽度为1920,高度300,JPG/PNG/GIF,3MB以内</p> |
||||||
|
</div> |
||||||
|
</el-upload> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label='竞赛名称'> |
||||||
|
<div class='d-inline-block'> |
||||||
|
<el-input placeholder='请输入竞赛名称' v-model='name' clearable></el-input> |
||||||
|
</div> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label='主办方'> |
||||||
|
<div class='inline-input'> |
||||||
|
<div class='input-wrap' v-for='(item,index) in sponsorList' :key='index'> |
||||||
|
<el-input placeholder='主办方名称' v-model='sponsorList[index]'></el-input> |
||||||
|
<i v-if='sponsorList.length > 1' class='remove' @click='delSponsor(index)'></i> |
||||||
|
<button v-if='index == 0' class='add-btn' @click='addSponsor'> |
||||||
|
<i class='el-icon-plus'></i> |
||||||
|
<span>添加</span> |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label='承办方(选填)'> |
||||||
|
<div class='inline-input'> |
||||||
|
<div class='input-wrap' v-for='(item,index) in undertakerList' :key='index'> |
||||||
|
<el-input placeholder='承办方名称' v-model='undertakerList[index]'></el-input> |
||||||
|
<i v-if='undertakerList.length > 1' class='remove' @click='delOrganizer(index)'></i> |
||||||
|
<button v-if='index == 0' class='add-btn' @click='addOrganizer'> |
||||||
|
<i class='el-icon-plus'></i> |
||||||
|
<span>添加</span> |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<button v-if='!undertakerList.length' class='add-btn' @click='addOrganizer'> |
||||||
|
<i class='el-icon-plus'></i> |
||||||
|
<span>添加</span> |
||||||
|
</button> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label='报名时间'> |
||||||
|
<el-date-picker v-model='signupTime' value-format='yyyy-MM-dd HH:mm:ss' type='datetimerange' |
||||||
|
range-separator='-' start-placeholder='开始日期' end-placeholder='结束日期' |
||||||
|
:picker-options='pickerOptions'></el-date-picker> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label='竞赛时间'> |
||||||
|
<el-date-picker v-model='playTime' value-format='yyyy-MM-dd HH:mm:ss' type='datetimerange' |
||||||
|
range-separator='-' start-placeholder='开始日期' end-placeholder='结束日期' |
||||||
|
:picker-options='pickerOptions'></el-date-picker> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label='竞赛详情'> |
||||||
|
<quill :border='true' v-model='description' :height='400' /> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item> |
||||||
|
<el-button size='small' v-throttle @click='save(1)'>保存</el-button> |
||||||
|
<el-button type='primary' size='small' v-throttle @click='save(0)'>发布</el-button> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
</el-card> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import util from '@/libs/util' |
||||||
|
import Setting from '@/setting' |
||||||
|
import quill from '@/components/quill'; |
||||||
|
|
||||||
|
export default { |
||||||
|
name: 'add', |
||||||
|
data() { |
||||||
|
return { |
||||||
|
headers: { |
||||||
|
token: util.local.get(Setting.tokenKey) |
||||||
|
}, |
||||||
|
schoolId: Setting.schoolId, |
||||||
|
id: '', |
||||||
|
coverUrl: '', |
||||||
|
carouselUrl: '', |
||||||
|
publishStatus: 0, |
||||||
|
userId: this.$store.state.userLoginId, |
||||||
|
username: this.$store.state.name, |
||||||
|
uploadList: [], |
||||||
|
uploadDataList: [], |
||||||
|
coverVisible: false, |
||||||
|
coverImageUrl: '', |
||||||
|
name: '', |
||||||
|
sponsor: '', |
||||||
|
sponsorList: [''], |
||||||
|
undertaker: '', |
||||||
|
undertakerList: [''], |
||||||
|
signUpStartTime: '', |
||||||
|
signUpEndTime: '', |
||||||
|
signupTime: '', |
||||||
|
playTime: '', |
||||||
|
playStartTime: '', |
||||||
|
playEndTime: '', |
||||||
|
description: '', |
||||||
|
pickerOptions: { |
||||||
|
disabledDate: time => { |
||||||
|
return time.getTime() < new Date().getTime() - 86400000; |
||||||
|
} |
||||||
|
}, |
||||||
|
submiting: false |
||||||
|
}; |
||||||
|
}, |
||||||
|
components: { |
||||||
|
quill |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
signupTime: function(val) { |
||||||
|
if (val) { |
||||||
|
this.signUpStartTime = val[0]; |
||||||
|
this.signUpEndTime = val[1]; |
||||||
|
} else { |
||||||
|
this.signUpStartTime = ''; |
||||||
|
this.signUpEndTime = ''; |
||||||
|
} |
||||||
|
}, |
||||||
|
playTime: function(val) { |
||||||
|
if (val) { |
||||||
|
this.playStartTime = val[0]; |
||||||
|
this.playEndTime = val[1]; |
||||||
|
} else { |
||||||
|
this.playStartTime = ''; |
||||||
|
this.playEndTime = ''; |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.id = this.$route.query.id; |
||||||
|
this.isDetail = Boolean(this.$route.query.show); |
||||||
|
this.id && this.getData(); |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
// 返回 |
||||||
|
goBack() { |
||||||
|
this.$router.back(); |
||||||
|
}, |
||||||
|
save(status) { |
||||||
|
if (this.submiting) return false; |
||||||
|
this.sponsor = this.sponsorList.filter(d => d).join(); |
||||||
|
this.undertaker = this.undertakerList.filter(d => d).join(); |
||||||
|
if (!this.name) return util.warningMsg('请填写竞赛名称'); |
||||||
|
if (status == 0) { |
||||||
|
if (!this.sponsor) return util.warningMsg('请填写主办方'); |
||||||
|
if (!this.signUpStartTime) return util.warningMsg('请选择报名时间'); |
||||||
|
} |
||||||
|
let now = new Date().getTime(); |
||||||
|
let signUpStartTime = new Date(this.signUpStartTime).getTime(); |
||||||
|
let signUpEndTime = new Date(this.signUpEndTime).getTime(); |
||||||
|
let playStartTime = new Date(this.playStartTime).getTime(); |
||||||
|
if (signUpStartTime && now > signUpStartTime) return util.warningMsg('报名时间不能早于当前时间'); |
||||||
|
if (!this.playStartTime && status == 0) return util.warningMsg('请选择竞赛时间'); |
||||||
|
if (playStartTime && playStartTime < signUpEndTime) return util.warningMsg('竞赛时间不能早于报名结束时间'); |
||||||
|
if (!this.description && status == 0) return util.warningMsg('请填写竞赛详情'); |
||||||
|
|
||||||
|
let data = { |
||||||
|
id: this.id, |
||||||
|
coverUrl: this.coverUrl, |
||||||
|
carouselUrl: this.carouselUrl, |
||||||
|
description: this.description, |
||||||
|
founderId: 1, |
||||||
|
founderName: this.username, |
||||||
|
name: this.name, |
||||||
|
playEndTime: this.playEndTime, |
||||||
|
playStartTime: this.playStartTime, |
||||||
|
publishStatus: status, |
||||||
|
signUpEndTime: this.signUpEndTime, |
||||||
|
signUpStartTime: this.signUpStartTime, |
||||||
|
sponsor: this.sponsor, |
||||||
|
undertaker: this.undertaker |
||||||
|
}; |
||||||
|
this.submiting = true; |
||||||
|
|
||||||
|
if (this.id) { |
||||||
|
this.$put(this.api.editContest, data).then(res => { |
||||||
|
this.submiting = false; |
||||||
|
util.successMsg('修改成功'); |
||||||
|
this.$router.back(); |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
this.submiting = false; |
||||||
|
}); |
||||||
|
} else { |
||||||
|
this.$post(this.api.addContest, data).then(res => { |
||||||
|
this.submiting = false; |
||||||
|
util.successMsg('创建成功'); |
||||||
|
this.$router.back(); |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
this.submiting = false; |
||||||
|
}); |
||||||
|
} |
||||||
|
}, |
||||||
|
getData() { |
||||||
|
this.$get(this.api.getContest + this.id) |
||||||
|
.then(res => { |
||||||
|
if (res.errmessage == 'success') { |
||||||
|
let info = res.ExperimentalTeaching; |
||||||
|
this.coverUrl = info.coverUrl; |
||||||
|
this.description = info.description; |
||||||
|
this.name = info.name; |
||||||
|
|
||||||
|
this.signupTime = [info.signUpStartTime, info.signUpEndTime]; |
||||||
|
this.playTime = [info.playStartTime, info.playEndTime]; |
||||||
|
} else { |
||||||
|
util.errorMsg('查询失败'); |
||||||
|
} |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
|
||||||
|
}); |
||||||
|
}, |
||||||
|
handleExceed(files, fileList) { |
||||||
|
util.warningMsg(`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`); |
||||||
|
}, |
||||||
|
uploadSuccess(res, file, fileList) { |
||||||
|
if (this.coverUrl) { |
||||||
|
let fileName = this.coverUrl.replace('https://liuwanr.oss-cn-shenzhen.aliyuncs.com/', ''); |
||||||
|
this.$del(`${this.api.fileDeletion}?keys=${fileName}`).then(res => { |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
} |
||||||
|
this.coverUrl = res.filesResult.fileUrl; |
||||||
|
}, |
||||||
|
uploadLgSuccess(res, file, fileList) { |
||||||
|
if (this.carouselUrl) { |
||||||
|
let fileName = this.carouselUrl.replace('https://liuwanr.oss-cn-shenzhen.aliyuncs.com/', ''); |
||||||
|
this.$del(`${this.api.fileDeletion}?keys=${fileName}`).then(res => { |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
} |
||||||
|
this.carouselUrl = res.filesResult.fileUrl; |
||||||
|
}, |
||||||
|
uploadError(err, file, fileList) { |
||||||
|
this.$message({ |
||||||
|
message: '上传出错,请重试!', |
||||||
|
type: 'error', |
||||||
|
center: true |
||||||
|
}); |
||||||
|
}, |
||||||
|
beforeRemove(file, fileList) { |
||||||
|
return this.$confirm(`确定移除 ${file.name}?`); |
||||||
|
}, |
||||||
|
handleRemove(file, fileList) { |
||||||
|
let fileName = this.coverUrl.replace('https://liuwanr.oss-cn-shenzhen.aliyuncs.com/', ''); |
||||||
|
this.$del(`${this.api.fileDeletion}?keys=${fileName}`).then(res => { |
||||||
|
this.coverUrl = ''; |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
}, |
||||||
|
handleLgRemove(file, fileList) { |
||||||
|
let fileName = this.carouselUrl.replace('https://liuwanr.oss-cn-shenzhen.aliyuncs.com/', ''); |
||||||
|
this.$del(`${this.api.fileDeletion}?keys=${fileName}`).then(res => { |
||||||
|
this.carouselUrl = ''; |
||||||
|
}).catch(res => { |
||||||
|
}); |
||||||
|
}, |
||||||
|
uploadSure() { |
||||||
|
this.BatchUpload = false; |
||||||
|
this.pageNo = 1; |
||||||
|
this.keyword = ''; |
||||||
|
this.getData(); |
||||||
|
}, |
||||||
|
goback() { |
||||||
|
this.$confirm('确定返回?未更新的信息将不会保存。', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$router.back(); |
||||||
|
}) |
||||||
|
.catch(() => { |
||||||
|
}); |
||||||
|
}, |
||||||
|
addSponsor() { |
||||||
|
this.sponsorList.push(''); |
||||||
|
}, |
||||||
|
delSponsor(index) { |
||||||
|
this.sponsorList.splice(index, 1); |
||||||
|
}, |
||||||
|
addOrganizer() { |
||||||
|
this.undertakerList.push(''); |
||||||
|
}, |
||||||
|
delOrganizer(index) { |
||||||
|
this.undertakerList.splice(index, 1); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style scoped lang='scss'> |
||||||
|
$upload-width: 220px; |
||||||
|
$upload-height: 140px; |
||||||
|
$upload-lg-height: 150px; |
||||||
|
/deep/ .avatar-uploader { |
||||||
|
.el-upload { |
||||||
|
position: relative; |
||||||
|
width: $upload-width; |
||||||
|
height: $upload-height; |
||||||
|
border: 1px dashed #d9d9d9; |
||||||
|
border-radius: 6px; |
||||||
|
cursor: pointer; |
||||||
|
overflow: hidden; |
||||||
|
|
||||||
|
&:hover { |
||||||
|
border-color: #cb221c; |
||||||
|
} |
||||||
|
|
||||||
|
.uploader-default { |
||||||
|
display: flex; |
||||||
|
height: $upload-height; |
||||||
|
flex-direction: column; |
||||||
|
justify-content: center; |
||||||
|
text-align: center; |
||||||
|
background: rgba(0, 0, 0, 0.04); |
||||||
|
|
||||||
|
i { |
||||||
|
font-size: 20px; |
||||||
|
font-weight: bold; |
||||||
|
color: #8c939d; |
||||||
|
} |
||||||
|
|
||||||
|
p { |
||||||
|
margin-top: 10px; |
||||||
|
font-size: 14px; |
||||||
|
color: rgba(0, 0, 0, 0.65); |
||||||
|
line-height: 1; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
&.avatar-uploader-lg { |
||||||
|
.el-upload { |
||||||
|
width: 100%; |
||||||
|
max-width: 960px; |
||||||
|
height: $upload-lg-height; |
||||||
|
|
||||||
|
.uploader-default { |
||||||
|
height: $upload-lg-height; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.avatar { |
||||||
|
display: block; |
||||||
|
width: $upload-width; |
||||||
|
height: $upload-height; |
||||||
|
} |
||||||
|
|
||||||
|
.avatar-lg { |
||||||
|
display: block; |
||||||
|
width: 100%; |
||||||
|
height: $upload-lg-height; |
||||||
|
} |
||||||
|
|
||||||
|
.el-upload__tip { |
||||||
|
margin-top: 0; |
||||||
|
|
||||||
|
p { |
||||||
|
font-size: 14px; |
||||||
|
color: rgba(0, 0, 0, 0.45); |
||||||
|
line-height: 1; |
||||||
|
|
||||||
|
&:first-child { |
||||||
|
margin-bottom: 5px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/deep/ .d-inline-block { |
||||||
|
width: 216px; |
||||||
|
|
||||||
|
.el-select, .el-input { |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.inline-input { |
||||||
|
.input-wrap { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
margin-bottom: 10px; |
||||||
|
|
||||||
|
.el-input { |
||||||
|
display: inline-block; |
||||||
|
width: 216px; |
||||||
|
margin-right: 8px; |
||||||
|
} |
||||||
|
|
||||||
|
.remove { |
||||||
|
width: 16px; |
||||||
|
height: 16px; |
||||||
|
background: url(../../assets/img/close.png) 0 0/cover no-repeat; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.add-btn { |
||||||
|
margin-left: 32px; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.add-btn { |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
width: 216px; |
||||||
|
line-height: 32px; |
||||||
|
font-size: 14px; |
||||||
|
color: rgba(0, 0, 0, 0.65); |
||||||
|
background-color: transparent; |
||||||
|
border: 1px dashed rgba(0, 0, 0, 0.15); |
||||||
|
border-radius: 4px; |
||||||
|
cursor: pointer; |
||||||
|
|
||||||
|
i { |
||||||
|
margin-right: 8px; |
||||||
|
font-size: 14px; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,279 @@ |
|||||||
|
<template> |
||||||
|
<div class="page"> |
||||||
|
<h6 class="p-title">筛选</h6> |
||||||
|
<div class="tool mul"> |
||||||
|
<ul class="filter"> |
||||||
|
<li> |
||||||
|
<label>创建时间:</label> |
||||||
|
<div class="single-choice"> |
||||||
|
<dl> |
||||||
|
<dd> |
||||||
|
<el-radio-group size="small" v-model="form.month" @change="changeType"> |
||||||
|
<el-radio v-for="(item,index) in dateList" :key="index" :label="item.id" border>{{item.name}}</el-radio> |
||||||
|
</el-radio-group> |
||||||
|
</dd> |
||||||
|
</dl> |
||||||
|
</div> |
||||||
|
</li> |
||||||
|
<li> |
||||||
|
<label>创建区间:</label> |
||||||
|
<el-date-picker v-model="date" align="right" unlink-panels size="small" type="daterange" start-placeholder="开始日期" end-placeholder="结束日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd" clearable></el-date-picker> |
||||||
|
</li> |
||||||
|
<li> |
||||||
|
<label>搜索:</label> |
||||||
|
<el-input placeholder="请输入竞赛名称/创建人" suffix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input> |
||||||
|
</li> |
||||||
|
</ul> |
||||||
|
<div> |
||||||
|
<el-button type="primary" size="small" round @click="add" v-auth>创建竞赛</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-table ref="table" :data="matchData" class="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id"> |
||||||
|
<el-table-column type="index" width="60" label="序号" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
{{scope.$index + (pageNo - 1) * pageSize + 1}} |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="竞赛名称"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="applicantNum" label="报名人数" width="100" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
{{scope.row.applicantNum ? scope.row.applicantNum : 0}} |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="status" label="状态" width="80" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
{{transferPublishStatus[scope.row.publishStatus]}} |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="time" label="竞赛时间" align="center" width="300"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
{{scope.row.playStartTime}} ~ {{scope.row.playEndTime}} |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="gmtCreate" label="创建时间" width="150" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="founder" width="100" label="创建人" align="center"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="操作" align="center" width="100"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text" @click="manage(scope.row)" v-auth>管理</el-button> |
||||||
|
<el-divider direction="vertical"></el-divider> |
||||||
|
<el-button type="text" @click="delData(scope.row)" v-auth>删除</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="发布状态" align="center" width="120"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-switch |
||||||
|
v-model="scope.row.publishStatus" |
||||||
|
:active-value="0" |
||||||
|
:inactive-value="1" |
||||||
|
style="margin: 0 10px 0 5px" |
||||||
|
:active-text="scope.row.publishStatus ? '关' : '开'" |
||||||
|
@change="switchOff($event,scope.row,scope.$index)" |
||||||
|
v-auth="'match:禁用'" |
||||||
|
></el-switch> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination background layout="total, prev, pager, next" :total="totals" @current-change="handleCurrentChange" :current-page="pageNo"> |
||||||
|
</el-pagination> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import util from '@/libs/util' |
||||||
|
export default { |
||||||
|
name: 'match', |
||||||
|
data() { |
||||||
|
return { |
||||||
|
keyword: '', |
||||||
|
statusList: [ |
||||||
|
{ |
||||||
|
value: '', |
||||||
|
name: '不限' |
||||||
|
}, |
||||||
|
{ |
||||||
|
value: 1, |
||||||
|
name: '待发布' |
||||||
|
}, |
||||||
|
{ |
||||||
|
value: 0, |
||||||
|
name: '已发布' |
||||||
|
} |
||||||
|
], |
||||||
|
matchData: [], |
||||||
|
form: { |
||||||
|
month: '', |
||||||
|
publishStatus: '', |
||||||
|
startTime: '', |
||||||
|
endTime: '' |
||||||
|
}, |
||||||
|
multipleSelection: [], |
||||||
|
dateList: [ |
||||||
|
{ |
||||||
|
id: '', |
||||||
|
name: '不限' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 1, |
||||||
|
name: '近一个月' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 3, |
||||||
|
name: '近三个月' |
||||||
|
}, |
||||||
|
{ |
||||||
|
id: 6, |
||||||
|
name: '近六个月' |
||||||
|
} |
||||||
|
], |
||||||
|
date: [], |
||||||
|
pageNo: 1, |
||||||
|
pageSize: 10, |
||||||
|
totals: 0, |
||||||
|
transferPublishStatus: ['已发布','未发布'] |
||||||
|
}; |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
'form.month': function(val){ |
||||||
|
if(val){ |
||||||
|
let unit = 24 * 60 * 60 * 1000 |
||||||
|
this.date = [util.formatDate('yyyy-MM-dd',new Date(new Date().getTime() - unit * 30 * val)),util.formatDate('yyyy-MM-dd',new Date(new Date().getTime() + unit))] |
||||||
|
}else{ |
||||||
|
this.date = [] |
||||||
|
} |
||||||
|
}, |
||||||
|
date: function(val){ |
||||||
|
if(val){ |
||||||
|
this.form.startTime = val[0] |
||||||
|
this.form.endTime = val[1] |
||||||
|
}else{ |
||||||
|
this.form.startTime = '' |
||||||
|
this.form.endTime = '' |
||||||
|
} |
||||||
|
this.initData() |
||||||
|
}, |
||||||
|
keyword: function(val) { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(() => { |
||||||
|
this.initData() |
||||||
|
},500) |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData() { |
||||||
|
let data = {} |
||||||
|
if(this.form.month) data.month = this.form.month |
||||||
|
if(this.keyword) data.name = this.keyword |
||||||
|
if(this.form.publishStatus !== '') data.publishStatus = this.form.publishStatus |
||||||
|
if(this.form.startTime) data.startTime = this.form.startTime |
||||||
|
if(this.form.endTime) data.endTime = this.form.endTime |
||||||
|
this.$get(`${this.api.queryContestByCondition}/${this.pageNo}/${this.pageSize }`,data).then(res => { |
||||||
|
this.matchData = res.contestList |
||||||
|
this.totals = res.total |
||||||
|
this.$refs.table.clearSelection() |
||||||
|
if(!this.matchData.length && this.totals){ |
||||||
|
this.pageNo-- |
||||||
|
this.getData() |
||||||
|
} |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
initData(){ |
||||||
|
this.pageNo = 1 |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
add(){ |
||||||
|
this.$router.push('add') |
||||||
|
}, |
||||||
|
manage(row){ |
||||||
|
this.$router.push(`manage?id=${row.id}`) |
||||||
|
}, |
||||||
|
|
||||||
|
changeType() { |
||||||
|
this.$refs.table.clearSelection() |
||||||
|
this.initData(); |
||||||
|
}, |
||||||
|
delData(row) { |
||||||
|
this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$del(`${this.api.deleteContest}/${row.id}`).then(res => { |
||||||
|
util.successMsg('删除成功'); |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}); |
||||||
|
}) |
||||||
|
.catch(() => {}); |
||||||
|
}, |
||||||
|
delAllData() { |
||||||
|
if(this.multipleSelection.length != ''){ |
||||||
|
let newArr = this.multipleSelection |
||||||
|
let delList = newArr.map(item => { |
||||||
|
return item.id |
||||||
|
}) |
||||||
|
|
||||||
|
this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
let data = delList |
||||||
|
this.$post(this.api.deleteContest,data).then(res => { |
||||||
|
this.multipleSelection = []; |
||||||
|
this.$refs.table.clearSelection() |
||||||
|
util.successMsg('删除成功'); |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}); |
||||||
|
}) |
||||||
|
.catch(() => {}); |
||||||
|
}else{ |
||||||
|
util.errorMsg('请先选择数据 !'); |
||||||
|
} |
||||||
|
}, |
||||||
|
handleSelectionChange(val) { |
||||||
|
this.multipleSelection = val; |
||||||
|
}, |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.pageNo = val; |
||||||
|
this.getData(); |
||||||
|
}, |
||||||
|
transferTime(date,type){ |
||||||
|
if(date == '0000-00-00 00:00:00') return '---' |
||||||
|
return date |
||||||
|
}, |
||||||
|
switchOff(val,row,index) { |
||||||
|
this.$put(`${this.api.publishContest}/${row.id}/${val}`) |
||||||
|
.then(res => { |
||||||
|
val == 1 ? util.warningMsg('该赛事信息已隐藏对学生端用户不可见') : util.successMsg('该赛事信息已对学生端用户公开') |
||||||
|
}) |
||||||
|
.catch(err => {}); |
||||||
|
}, |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
/deep/.tool{ |
||||||
|
.filter{ |
||||||
|
.el-input{ |
||||||
|
min-width: 190px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
@media(max-width: 1640px){ |
||||||
|
.page .page-content .tool .filter{ |
||||||
|
flex-wrap: wrap; |
||||||
|
margin-bottom: -15px; |
||||||
|
li{ |
||||||
|
min-width: 34%; |
||||||
|
margin-bottom: 15px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,61 @@ |
|||||||
|
<template> |
||||||
|
<!-- 赛事管理 --> |
||||||
|
<div> |
||||||
|
<el-card shadow="hover" class="m-b-20"> |
||||||
|
<div class="flex-between"> |
||||||
|
<el-page-header @back="goBack" :content="'赛事管理'"></el-page-header> |
||||||
|
</div> |
||||||
|
</el-card> |
||||||
|
<div class="page" style="margin-bottom: 24px"> |
||||||
|
<div class="tabs"> |
||||||
|
<a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == active}" @click="tabChange(index)">{{item}}</a> |
||||||
|
</div> |
||||||
|
<!-- 大赛详情 --> |
||||||
|
<MatchDetail v-if="active == 'first'" /> |
||||||
|
<!-- 竞赛进展 --> |
||||||
|
<MatchProgress v-else-if="active == 'second'" /> |
||||||
|
<!-- 报名人员 --> |
||||||
|
<MatchSignup v-else /> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import MatchDetail from './matchDetail' |
||||||
|
import MatchProgress from './matchProgress' |
||||||
|
import MatchSignup from './matchSignup' |
||||||
|
export default { |
||||||
|
name: 'matchManage', |
||||||
|
data() { |
||||||
|
return { |
||||||
|
active: 'first', |
||||||
|
tabs: { |
||||||
|
first: '大赛详情', |
||||||
|
second: '竞赛进展', |
||||||
|
third: '报名人员' |
||||||
|
}, |
||||||
|
}; |
||||||
|
}, |
||||||
|
components: { |
||||||
|
MatchDetail, |
||||||
|
MatchProgress, |
||||||
|
MatchSignup |
||||||
|
}, |
||||||
|
created() { |
||||||
|
|
||||||
|
}, |
||||||
|
methods: { |
||||||
|
goBack() { |
||||||
|
this.$router.back(); |
||||||
|
}, |
||||||
|
tabChange(index){ |
||||||
|
this.active = index |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style scoped> |
||||||
|
|
||||||
|
</style> |
@ -0,0 +1,421 @@ |
|||||||
|
<template> |
||||||
|
<!-- 大赛详情 --> |
||||||
|
<div style='padding: 24px'> |
||||||
|
<div class="page-content"> |
||||||
|
<el-form label-width="170px" label-suffix=":" size="small"> |
||||||
|
<el-form-item label="竞赛封面(选填)"> |
||||||
|
<el-upload |
||||||
|
class="avatar-uploader" |
||||||
|
accept=".jpg,.png,.jpeg,.gif" |
||||||
|
:on-remove="handleRemove" |
||||||
|
:on-error="uploadError" |
||||||
|
:on-success="uploadSuccess" |
||||||
|
:before-remove="beforeRemove" |
||||||
|
:limit="1" |
||||||
|
:on-exceed="handleExceed" |
||||||
|
:action="this.api.fileupload" |
||||||
|
name="file" |
||||||
|
> |
||||||
|
<img v-if="coverUrl" :src="coverUrl" class="avatar"> |
||||||
|
<div class="uploader-default" v-else> |
||||||
|
<i class="el-icon-plus"></i> |
||||||
|
<p>上传封面</p> |
||||||
|
</div> |
||||||
|
<div slot="tip" class="el-upload__tip"> |
||||||
|
<p>展示宽度为220,高度140,JPG/PNG/GIF,3MB以内</p> |
||||||
|
</div> |
||||||
|
</el-upload> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="竞赛封面长图(选填)"> |
||||||
|
<el-upload |
||||||
|
class="avatar-uploader avatar-uploader-lg" |
||||||
|
accept=".jpg,.png,.jpeg,.gif" |
||||||
|
:on-remove="handleLgRemove" |
||||||
|
:on-error="uploadError" |
||||||
|
:on-success="uploadLgSuccess" |
||||||
|
:before-remove="beforeRemove" |
||||||
|
:limit="1" |
||||||
|
:on-exceed="handleExceed" |
||||||
|
:action="this.api.fileupload" |
||||||
|
name="file" |
||||||
|
> |
||||||
|
<img v-if="carouselUrl" :src="carouselUrl" class="avatar-lg"> |
||||||
|
<div class="uploader-default" v-else> |
||||||
|
<i class="el-icon-plus"></i> |
||||||
|
<p>上传封面</p> |
||||||
|
</div> |
||||||
|
<div slot="tip" class="el-upload__tip"> |
||||||
|
<p>展示宽度为1920,高度300,JPG/PNG/GIF,3MB以内</p> |
||||||
|
</div> |
||||||
|
</el-upload> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="竞赛名称"> |
||||||
|
<div class="d-inline-block"> |
||||||
|
<el-input placeholder="请输入竞赛名称" v-model="name" clearable></el-input> |
||||||
|
</div> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="主办方"> |
||||||
|
<div class="inline-input"> |
||||||
|
<div class="input-wrap" v-for="(item,index) in sponsorList" :key="index"> |
||||||
|
<el-input placeholder="主办方名称" v-model="sponsorList[index]"></el-input> |
||||||
|
<i v-if="sponsorList.length > 1" class="remove" @click="delSponsor(index)"></i> |
||||||
|
<button v-if="index == 0" class="add-btn" @click="addSponsor"> |
||||||
|
<i class="el-icon-plus"></i> |
||||||
|
<span>添加</span> |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="承办方(选填)"> |
||||||
|
<div class="inline-input"> |
||||||
|
<div class="input-wrap" v-for="(item,index) in undertakerList" :key="index"> |
||||||
|
<el-input placeholder="承办方名称" v-model="undertakerList[index]"></el-input> |
||||||
|
<i v-if="undertakerList.length > 1" class="remove" @click="delOrganizer(index)"></i> |
||||||
|
<button v-if="index == 0" class="add-btn" @click="addOrganizer"> |
||||||
|
<i class="el-icon-plus"></i> |
||||||
|
<span>添加</span> |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<button v-if="!undertakerList.length" class="add-btn" @click="addOrganizer"> |
||||||
|
<i class="el-icon-plus"></i> |
||||||
|
<span>添加</span> |
||||||
|
</button> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="报名时间"> |
||||||
|
<el-date-picker v-model="signupTime" value-format="yyyy-MM-dd HH:mm:ss" type="datetimerange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="竞赛时间"> |
||||||
|
<el-date-picker v-model="playTime" value-format="yyyy-MM-dd HH:mm:ss" type="datetimerange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item label="竞赛详情"> |
||||||
|
<quill :border="true" v-model="description" :height="400" /> |
||||||
|
</el-form-item> |
||||||
|
<el-form-item> |
||||||
|
<el-button size="small" v-throttle @click="save(1)">保存</el-button> |
||||||
|
<el-button type="primary" v-if="publishStatus == 1" v-throttle @click="save(0)">发布</el-button> |
||||||
|
</el-form-item> |
||||||
|
</el-form> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import quill from '@/components/quill' |
||||||
|
import util from '@/libs/util' |
||||||
|
export default { |
||||||
|
name: 'matchDetail', |
||||||
|
data() { |
||||||
|
return { |
||||||
|
id: this.$route.query.id, |
||||||
|
coverUrl: '', |
||||||
|
carouselUrl: '', |
||||||
|
publishStatus: 0, |
||||||
|
uploadList: [], |
||||||
|
uploadDataList: [], |
||||||
|
name: '', |
||||||
|
sponsor: '', |
||||||
|
sponsorList: [''], |
||||||
|
undertaker: '', |
||||||
|
undertakerList: [], |
||||||
|
signUpStartTime: '', |
||||||
|
signUpEndTime: '', |
||||||
|
signupTime: '', |
||||||
|
playTime: '', |
||||||
|
playStartTime: '', |
||||||
|
playEndTime: '', |
||||||
|
description: '' |
||||||
|
}; |
||||||
|
}, |
||||||
|
components: { |
||||||
|
quill |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
signupTime: function(val){ |
||||||
|
if(val){ |
||||||
|
this.signUpStartTime = val[0] |
||||||
|
this.signUpEndTime = val[1] |
||||||
|
}else{ |
||||||
|
this.signUpStartTime = '' |
||||||
|
this.signUpEndTime = '' |
||||||
|
} |
||||||
|
}, |
||||||
|
playTime: function(val){ |
||||||
|
if(val){ |
||||||
|
this.playStartTime = val[0] |
||||||
|
this.playEndTime = val[1] |
||||||
|
}else{ |
||||||
|
this.playStartTime = '' |
||||||
|
this.playEndTime = '' |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getData() |
||||||
|
this.commitId() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
save(status) { |
||||||
|
this.sponsor = this.sponsorList.filter(d=>d).join() |
||||||
|
this.undertaker = this.undertakerList.filter(d=>d).join() |
||||||
|
|
||||||
|
if(!this.name) return util.warningMsg('请填写竞赛名称') |
||||||
|
if(status == 0){ |
||||||
|
if(!this.sponsor) return util.warningMsg('请填写主办方') |
||||||
|
if(!this.signUpStartTime) return util.warningMsg('请选择报名时间') |
||||||
|
} |
||||||
|
let now = new Date().getTime() |
||||||
|
let signUpStartTime = new Date(this.signUpStartTime).getTime() |
||||||
|
let signUpEndTime = new Date(this.signUpEndTime).getTime() |
||||||
|
let playStartTime = new Date(this.playStartTime).getTime() |
||||||
|
// if(signUpStartTime && now > signUpStartTime) return this.$$message.warning('报名时间不能早于当前时间') |
||||||
|
if(!this.playStartTime && status == 0) return util.warningMsg('请选择竞赛时间') |
||||||
|
if(playStartTime && playStartTime < signUpEndTime) return util.warningMsg('竞赛时间不能早于报名结束时间') |
||||||
|
if(!this.description && status == 0) return util.warningMsg('请填写竞赛详情') |
||||||
|
|
||||||
|
let data = { |
||||||
|
id: this.id, |
||||||
|
coverUrl: this.coverUrl, |
||||||
|
carouselUrl: this.carouselUrl, |
||||||
|
description: this.description, |
||||||
|
founderId: 1, |
||||||
|
name: this.name, |
||||||
|
playEndTime: this.playEndTime, |
||||||
|
playStartTime: this.playStartTime, |
||||||
|
publishStatus: status ? this.publishStatus : 0, |
||||||
|
signUpEndTime: this.signUpEndTime, |
||||||
|
signUpStartTime: this.signUpStartTime, |
||||||
|
sponsor: this.sponsor, |
||||||
|
undertaker: this.undertaker |
||||||
|
} |
||||||
|
if(this.id){ |
||||||
|
this.$put(this.api.editContest, data).then(res => { |
||||||
|
util.successMsg('修改成功'); |
||||||
|
this.$router.back() |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
}); |
||||||
|
}else{ |
||||||
|
this.$post(this.api.addContest, data).then(res => { |
||||||
|
util.successMsg('创建成功'); |
||||||
|
this.$router.back() |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
}); |
||||||
|
} |
||||||
|
}, |
||||||
|
getData() { |
||||||
|
this.$get(this.api.getContest + '/' + this.id) |
||||||
|
.then(res => { |
||||||
|
let data = res.contest |
||||||
|
this.coverUrl = data.coverUrl |
||||||
|
this.carouselUrl = data.carouselUrl |
||||||
|
this.description = data.description |
||||||
|
this.name = data.name |
||||||
|
this.playEndTime = data.playEndTime |
||||||
|
this.playStartTime = data.playStartTime |
||||||
|
this.publishStatus = data.publishStatus |
||||||
|
this.signUpEndTime = data.signUpEndTime |
||||||
|
this.signUpStartTime = data.signUpStartTime |
||||||
|
this.sponsor = data.sponsor |
||||||
|
this.undertaker = data.undertaker |
||||||
|
|
||||||
|
this.signupTime = [data.signUpStartTime,data.signUpEndTime] |
||||||
|
this.playTime = [data.playStartTime,data.playEndTime] |
||||||
|
this.sponsorList = data.sponsor.split(',') |
||||||
|
this.undertakerList = data.undertaker.split(',') |
||||||
|
}) |
||||||
|
.catch(err => { |
||||||
|
|
||||||
|
}); |
||||||
|
}, |
||||||
|
commitId(){ |
||||||
|
this.$store.commit("setMatchData", { matchId : this.id}) |
||||||
|
}, |
||||||
|
handleExceed(files, fileList) { |
||||||
|
util.warningMsg(`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`); |
||||||
|
}, |
||||||
|
uploadSuccess(res, file, fileList) { |
||||||
|
if(this.coverUrl){ |
||||||
|
let fileName = this.coverUrl.replace('https://liuwanr.oss-cn-shenzhen.aliyuncs.com/','') |
||||||
|
this.$del(`${this.api.fileDeletion}?keys=${fileName}`).then(res => {}).catch(res => {}); |
||||||
|
} |
||||||
|
this.coverUrl = res.filesResult.fileUrl |
||||||
|
}, |
||||||
|
uploadLgSuccess(res, file, fileList) { |
||||||
|
if(this.carouselUrl){ |
||||||
|
let fileName = this.carouselUrl.replace('https://liuwanr.oss-cn-shenzhen.aliyuncs.com/','') |
||||||
|
this.$del(`${this.api.fileDeletion}?keys=${fileName}`).then(res => {}).catch(res => {}); |
||||||
|
} |
||||||
|
this.carouselUrl = res.filesResult.fileUrl |
||||||
|
}, |
||||||
|
uploadError(err, file, fileList) { |
||||||
|
this.$message({ |
||||||
|
message: "上传出错,请重试!", |
||||||
|
type: "error", |
||||||
|
center: true |
||||||
|
}); |
||||||
|
}, |
||||||
|
beforeRemove(file, fileList) { |
||||||
|
return this.$confirm(`确定移除 ${file.name}?`); |
||||||
|
}, |
||||||
|
handleRemove(file, fileList) { |
||||||
|
let fileName = this.coverUrl.replace('https://liuwanr.oss-cn-shenzhen.aliyuncs.com/','') |
||||||
|
this.$del(`${this.api.fileDeletion}?keys=${fileName}`).then(res => { |
||||||
|
this.coverUrl = '' |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
handleLgRemove(file, fileList) { |
||||||
|
let fileName = this.carouselUrl.replace('https://liuwanr.oss-cn-shenzhen.aliyuncs.com/','') |
||||||
|
this.$del(`${this.api.fileDeletion}?keys=${fileName}`).then(res => { |
||||||
|
this.carouselUrl = '' |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
uploadSure(){ |
||||||
|
this.BatchUpload = false |
||||||
|
this.pageNo = 1 |
||||||
|
this.keyword = '' |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
goback() { |
||||||
|
this.$confirm('确定返回?未更新的信息将不会保存。', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$router.push('/match') |
||||||
|
}) |
||||||
|
.catch(() => {}); |
||||||
|
}, |
||||||
|
addSponsor(){ |
||||||
|
this.sponsorList.push('') |
||||||
|
}, |
||||||
|
delSponsor(index){ |
||||||
|
this.sponsorList.splice(index,1) |
||||||
|
}, |
||||||
|
addOrganizer(){ |
||||||
|
this.undertakerList.push('') |
||||||
|
}, |
||||||
|
delOrganizer(index){ |
||||||
|
this.undertakerList.splice(index,1) |
||||||
|
}, |
||||||
|
|
||||||
|
}, |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style scoped lang="scss"> |
||||||
|
$upload-width: 220px; |
||||||
|
$upload-height: 140px; |
||||||
|
$upload-lg-height: 150px; |
||||||
|
/deep/.avatar-uploader{ |
||||||
|
.el-upload { |
||||||
|
position: relative; |
||||||
|
width: $upload-width; |
||||||
|
height: $upload-height; |
||||||
|
border: 1px dashed #d9d9d9; |
||||||
|
border-radius: 6px; |
||||||
|
cursor: pointer; |
||||||
|
overflow: hidden; |
||||||
|
&:hover { |
||||||
|
border-color: #cb221c; |
||||||
|
} |
||||||
|
.uploader-default{ |
||||||
|
display: flex; |
||||||
|
height: $upload-height; |
||||||
|
flex-direction: column; |
||||||
|
justify-content: center; |
||||||
|
text-align: center; |
||||||
|
background: rgba(0, 0, 0, 0.04); |
||||||
|
i{ |
||||||
|
font-size: 20px; |
||||||
|
font-weight: bold; |
||||||
|
color: #8c939d; |
||||||
|
} |
||||||
|
p{ |
||||||
|
margin-top: 10px; |
||||||
|
font-size: 14px; |
||||||
|
color: rgba(0, 0, 0, 0.65); |
||||||
|
line-height: 1; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
&.avatar-uploader-lg{ |
||||||
|
.el-upload { |
||||||
|
width: 100%; |
||||||
|
max-width: 960px; |
||||||
|
height: $upload-lg-height; |
||||||
|
.uploader-default{ |
||||||
|
height: $upload-lg-height; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.avatar { |
||||||
|
display: block; |
||||||
|
width: $upload-width; |
||||||
|
height: $upload-height; |
||||||
|
} |
||||||
|
.avatar-lg { |
||||||
|
display: block; |
||||||
|
width: 100%; |
||||||
|
height: $upload-lg-height; |
||||||
|
} |
||||||
|
.el-upload__tip{ |
||||||
|
margin-top: 0; |
||||||
|
p{ |
||||||
|
font-size: 14px; |
||||||
|
color: rgba(0, 0, 0, 0.45); |
||||||
|
line-height: 1; |
||||||
|
&:first-child{ |
||||||
|
margin-bottom: 5px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/deep/.d-inline-block{ |
||||||
|
width: 216px; |
||||||
|
.el-select,.el-input{ |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
} |
||||||
|
.inline-input{ |
||||||
|
.input-wrap{ |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
margin-bottom: 10px; |
||||||
|
|
||||||
|
.el-input{ |
||||||
|
display: inline-block; |
||||||
|
width: 216px; |
||||||
|
margin-right: 8px; |
||||||
|
} |
||||||
|
.remove{ |
||||||
|
width: 16px; |
||||||
|
height: 16px; |
||||||
|
background: url(../../../assets/img/close.png) 0 0/cover no-repeat; |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
} |
||||||
|
.add-btn{ |
||||||
|
margin-left: 32px; |
||||||
|
} |
||||||
|
} |
||||||
|
.add-btn{ |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
width: 216px; |
||||||
|
line-height: 32px; |
||||||
|
font-size: 14px; |
||||||
|
color: rgba(0, 0, 0, 0.65); |
||||||
|
background-color: transparent; |
||||||
|
border: 1px dashed rgba(0, 0, 0, 0.15); |
||||||
|
border-radius: 4px; |
||||||
|
cursor: pointer; |
||||||
|
i{ |
||||||
|
margin-right: 8px; |
||||||
|
font-size: 14px; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,162 @@ |
|||||||
|
<template> |
||||||
|
<!-- 竞赛进展 --> |
||||||
|
<div class="page-content" style='padding: 24px'> |
||||||
|
<el-table ref="table" :data="listData" class="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id"> |
||||||
|
<el-table-column type="index" width="60" label="序号" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
{{scope.$index + (pageNo - 1) * pageSize + 1}} |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="标题"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-input placeholder="请输入标题" v-model="scope.row.title"></el-input> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="详情描述"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-input placeholder="请输入详情描述" type="textarea" v-model="scope.row.description"></el-input> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="name" label="状态" width="150"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-select v-model="scope.row.status" clearable placeholder="请选择状态"> |
||||||
|
<el-option v-for="(item,index) in statusList" :key="index" :label="item.name" :value="item.value"></el-option> |
||||||
|
</el-select> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="操作" align="center" width="170"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-button type="text" @click="saveData(scope.row)">保存</el-button> |
||||||
|
<el-button type="text" @click="handleDelete(scope.row)">删除</el-button> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="plus" @click="addData"> |
||||||
|
<i class="el-icon-circle-plus-outline"></i> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import util from '@/libs/util' |
||||||
|
export default { |
||||||
|
name: 'matchProgress', |
||||||
|
data() { |
||||||
|
return { |
||||||
|
id: this.$route.query.id, |
||||||
|
statusList: [ |
||||||
|
{ |
||||||
|
value: 0, |
||||||
|
name: '未完成' |
||||||
|
}, |
||||||
|
{ |
||||||
|
value: 1, |
||||||
|
name: '进行中' |
||||||
|
}, |
||||||
|
{ |
||||||
|
value: 2, |
||||||
|
name: '已完成' |
||||||
|
} |
||||||
|
], |
||||||
|
listData: [], |
||||||
|
multipleSelection: [], |
||||||
|
pageNo: 1, |
||||||
|
pageSize: 10, |
||||||
|
totals: 0 |
||||||
|
}; |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData() { |
||||||
|
this.$get(`${this.api.getContestProgress}/${this.id}`).then(res => { |
||||||
|
this.listData = res.contestProgressList |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
saveData(row){ |
||||||
|
let data = row |
||||||
|
if(data.title.length){ |
||||||
|
if(row.id){ |
||||||
|
this.$put(this.api.editContestProgress,data).then(res => { |
||||||
|
util.successMsg('修改成功') |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}); |
||||||
|
}else{ |
||||||
|
this.$post(this.api.addContestProgress,data).then(res => { |
||||||
|
util.successMsg('创建成功') |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}); |
||||||
|
} |
||||||
|
}else{ |
||||||
|
util.warningMsg('请填写标题') |
||||||
|
} |
||||||
|
}, |
||||||
|
entry(){ |
||||||
|
this.$router.push('/permission') |
||||||
|
}, |
||||||
|
handleSelectionChange(val) { |
||||||
|
this.multipleSelection = val; |
||||||
|
}, |
||||||
|
onSearch(){ |
||||||
|
this.pageNo = 1 |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.pageNo = val; |
||||||
|
this.getData(); |
||||||
|
}, |
||||||
|
handleDelete(row) { |
||||||
|
this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
this.$del(`${this.api.deleteContestProgress}/${row.id}`).then(res => { |
||||||
|
util.successMsg('删除成功'); |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}); |
||||||
|
}) |
||||||
|
.catch(() => {}); |
||||||
|
}, |
||||||
|
addData(){ |
||||||
|
if(this.listData.length){ |
||||||
|
if(this.listData[this.listData.length-1].id){ |
||||||
|
this.listData.push({ |
||||||
|
contestId: this.id, |
||||||
|
id: '', |
||||||
|
title: '', |
||||||
|
description: '', |
||||||
|
status: 0 |
||||||
|
}) |
||||||
|
}else{ |
||||||
|
util.warningMsg('请先保存新数据') |
||||||
|
} |
||||||
|
}else{ |
||||||
|
this.listData.push({ |
||||||
|
contestId: this.id, |
||||||
|
id: '', |
||||||
|
title: '', |
||||||
|
description: '', |
||||||
|
status: 0 |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style scoped lang="scss"> |
||||||
|
.box{ |
||||||
|
height: calc(100vh - 100px); |
||||||
|
overflow: auto; |
||||||
|
} |
||||||
|
.plus{ |
||||||
|
padding: 15px 0 0; |
||||||
|
text-align: center; |
||||||
|
cursor: pointer; |
||||||
|
i{ |
||||||
|
font-size: 24px; |
||||||
|
color: #cb221c; |
||||||
|
} |
||||||
|
} |
||||||
|
</style> |
@ -0,0 +1,154 @@ |
|||||||
|
<template> |
||||||
|
<!-- 报名人员 --> |
||||||
|
<div class="page-content" style='padding: 24px'> |
||||||
|
<div class="tool"> |
||||||
|
<ul class="filter"> |
||||||
|
<li> |
||||||
|
<label>搜索:</label> |
||||||
|
<el-input placeholder="请输入姓名/手机号" prefix-icon="el-icon-search" v-model="keyword" clearable size="mini"></el-input> |
||||||
|
</li> |
||||||
|
</ul> |
||||||
|
<div> |
||||||
|
<el-button type="primary" size="small" round @click="exportAll">全部导出</el-button> |
||||||
|
<el-button type="primary" size="small" round @click="exportBatch">批量导出</el-button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<el-table ref="table" :data="listData" class="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id"> |
||||||
|
<el-table-column type="selection" :selectable="row => row.isDisable!=0" width="80" align="center" :reserve-selection="true"></el-table-column> |
||||||
|
<el-table-column type="index" width="60" label="序号" align="center"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
{{scope.$index + (pageNo - 1) * pageSize + 1}} |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="school" label="学校"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="username" label="学生姓名"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="account" label="账号"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column prop="phone" label="手机号"> |
||||||
|
</el-table-column> |
||||||
|
<el-table-column label="操作" align="center" width="170"> |
||||||
|
<template slot-scope="scope"> |
||||||
|
<el-switch |
||||||
|
v-model="scope.row.isDisable" |
||||||
|
:active-text="scope.row.isDisable ? '开' : '关'" |
||||||
|
:active-value="1" |
||||||
|
:inactive-value="0" |
||||||
|
style="margin: 0 10px 0 5px" |
||||||
|
@change="switchOff($event,scope.row,scope.$index)" |
||||||
|
></el-switch> |
||||||
|
</template> |
||||||
|
</el-table-column> |
||||||
|
</el-table> |
||||||
|
<div class="pagination"> |
||||||
|
<el-pagination background layout="total, prev, pager, next" :total="totals" @current-change="handleCurrentChange" :current-page="pageNo"> |
||||||
|
</el-pagination> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import util from '@/libs/util' |
||||||
|
import Setting from '@/setting' |
||||||
|
export default { |
||||||
|
name: 'matchSignup', |
||||||
|
data() { |
||||||
|
return { |
||||||
|
token: util.local.get(Setting.tokenKey), |
||||||
|
id: this.$route.query.id, |
||||||
|
keyword: '', |
||||||
|
listData: [], |
||||||
|
multipleSelection: [], |
||||||
|
pageNo: 1, |
||||||
|
pageSize: 10, |
||||||
|
totals: 0 |
||||||
|
}; |
||||||
|
}, |
||||||
|
watch: { |
||||||
|
keyword: function(val) { |
||||||
|
clearTimeout(this.searchTimer) |
||||||
|
this.searchTimer = setTimeout(() => { |
||||||
|
this.getData() |
||||||
|
},500) |
||||||
|
} |
||||||
|
}, |
||||||
|
mounted() { |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
getData() { |
||||||
|
let data = { |
||||||
|
contestId: this.id |
||||||
|
} |
||||||
|
if(this.keyword) data.name = this.keyword |
||||||
|
this.$get(`${this.api.queryApplicantByCondition}/${this.pageNo}/${this.pageSize}`,data).then(res => { |
||||||
|
this.listData = res.data.applicantList |
||||||
|
this.totals = res.data.total |
||||||
|
this.$refs.table.clearSelection() |
||||||
|
}).catch(res => {}); |
||||||
|
}, |
||||||
|
handleSelectionChange(val) { |
||||||
|
this.multipleSelection = val; |
||||||
|
}, |
||||||
|
onSearch(){ |
||||||
|
this.pageNo = 1 |
||||||
|
this.getData() |
||||||
|
}, |
||||||
|
handleCurrentChange(val) { |
||||||
|
this.pageNo = val; |
||||||
|
this.getData(); |
||||||
|
}, |
||||||
|
switchOff(val,row,index) { |
||||||
|
this.$put(`${this.api.disableApplicant}/${row.id}/${val}`) |
||||||
|
.then(res => {}) |
||||||
|
.catch(err => {}); |
||||||
|
}, |
||||||
|
disalbeAllData() { |
||||||
|
if(this.multipleSelection.length != ''){ |
||||||
|
let newArr = this.multipleSelection |
||||||
|
let delList = newArr.map(item => { |
||||||
|
return item.id |
||||||
|
}) |
||||||
|
|
||||||
|
this.$confirm('确定要禁用吗?', '提示', { |
||||||
|
type: 'warning' |
||||||
|
}) |
||||||
|
.then(() => { |
||||||
|
console.log(11,delList.join()) |
||||||
|
this.$put(`${this.api.disableContests}?ids=${delList.join(',')}`).then(res => { |
||||||
|
this.multipleSelection = []; |
||||||
|
util.successMsg('禁用成功'); |
||||||
|
this.getData() |
||||||
|
}).catch(res => {}); |
||||||
|
}) |
||||||
|
.catch(() => {}); |
||||||
|
}else{ |
||||||
|
util.errorMsg('请先选择数据 !'); |
||||||
|
} |
||||||
|
}, |
||||||
|
exportAll(){ |
||||||
|
location.href = `${this.api.excelExport}/${this.id}/token=${this.token}` |
||||||
|
}, |
||||||
|
exportBatch(){ |
||||||
|
if(this.multipleSelection.length != ''){ |
||||||
|
let newArr = this.multipleSelection |
||||||
|
let data = newArr.map(item => { |
||||||
|
return item.id |
||||||
|
}) |
||||||
|
|
||||||
|
// return console.log(11,data) |
||||||
|
location.href = `${this.api.batchExport}?ids=${data.join(',')}/token=${this.token}` |
||||||
|
}else{ |
||||||
|
util.errorMsg('请先选择数据 !'); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
</script> |
||||||
|
|
||||||
|
<style scoped> |
||||||
|
|
||||||
|
</style> |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,41 @@ |
|||||||
|
import BasicLayout from '@/layouts/home' |
||||||
|
|
||||||
|
const meta = {} |
||||||
|
|
||||||
|
const pre = 'course-' |
||||||
|
|
||||||
|
export default { |
||||||
|
path: '/course', |
||||||
|
name: 'course', |
||||||
|
redirect: { |
||||||
|
name: `${pre}list` |
||||||
|
}, |
||||||
|
meta, |
||||||
|
component: BasicLayout, |
||||||
|
children: [ |
||||||
|
{ |
||||||
|
name: `${pre}list`, |
||||||
|
path: `list`, |
||||||
|
component: () => import('@/pages/course'), |
||||||
|
meta: { title: '理论课程管理' } |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: `${pre}add`, |
||||||
|
path: `add`, |
||||||
|
component: () => import('@/pages/course/courseManagement/add'), |
||||||
|
meta: { title: '新增课程' } |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: `${pre}preview`, |
||||||
|
path: `preview`, |
||||||
|
component: () => import('@/pages/course/courseManagement/preview'), |
||||||
|
meta: { title: '课程预览' } |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: `${pre}contentSettings`, |
||||||
|
path: `contentSettings`, |
||||||
|
component: () => import('@/pages/course/courseManagement/contentSettings'), |
||||||
|
meta: { title: '内容设置' } |
||||||
|
}, |
||||||
|
] |
||||||
|
}; |
@ -0,0 +1,29 @@ |
|||||||
|
import BasicLayout from '@/layouts/home' |
||||||
|
|
||||||
|
const meta = {} |
||||||
|
|
||||||
|
const pre = 'information-' |
||||||
|
|
||||||
|
export default { |
||||||
|
path: '/information', |
||||||
|
name: 'information', |
||||||
|
redirect: { |
||||||
|
name: `${pre}list` |
||||||
|
}, |
||||||
|
meta, |
||||||
|
component: BasicLayout, |
||||||
|
children: [ |
||||||
|
{ |
||||||
|
name: `${pre}list`, |
||||||
|
path: `list`, |
||||||
|
component: () => import('@/pages/information'), |
||||||
|
meta: { title: '资讯管理' } |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: `${pre}addArticle`, |
||||||
|
path: `addArticle`, |
||||||
|
component: () => import('@/pages/information/contentManage/addArticle'), |
||||||
|
meta: { title: '新增文章' } |
||||||
|
}, |
||||||
|
] |
||||||
|
}; |
@ -0,0 +1,35 @@ |
|||||||
|
import BasicLayout from '@/layouts/home' |
||||||
|
|
||||||
|
const meta = {} |
||||||
|
|
||||||
|
const pre = 'match-' |
||||||
|
|
||||||
|
export default { |
||||||
|
path: '/match', |
||||||
|
name: 'match', |
||||||
|
redirect: { |
||||||
|
name: `${pre}list` |
||||||
|
}, |
||||||
|
meta, |
||||||
|
component: BasicLayout, |
||||||
|
children: [ |
||||||
|
{ |
||||||
|
name: `${pre}list`, |
||||||
|
path: `list`, |
||||||
|
component: () => import('@/pages/match'), |
||||||
|
meta: { title: '赛事管理' } |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: `${pre}add`, |
||||||
|
path: `add`, |
||||||
|
component: () => import('@/pages/match/add'), |
||||||
|
meta: { title: '创建赛事' } |
||||||
|
}, |
||||||
|
{ |
||||||
|
name: `${pre}manage`, |
||||||
|
path: `manage`, |
||||||
|
component: () => import('@/pages/match/manage'), |
||||||
|
meta: { title: '管理赛事' } |
||||||
|
}, |
||||||
|
] |
||||||
|
}; |
@ -0,0 +1,26 @@ |
|||||||
|
/** |
||||||
|
* 资讯相关 |
||||||
|
* */ |
||||||
|
export default { |
||||||
|
namespaced: true, |
||||||
|
state: { |
||||||
|
tabsName: '2', |
||||||
|
columnId: "" |
||||||
|
}, |
||||||
|
mutations: { |
||||||
|
SET_TABS_NAME: (state, name) => { |
||||||
|
state.tabsName = name |
||||||
|
}, |
||||||
|
SET_COLUMN_ID: (state, id) => { |
||||||
|
state.columnId = id |
||||||
|
}, |
||||||
|
}, |
||||||
|
actions: { |
||||||
|
setTabsName({ state,commit },name) { |
||||||
|
commit('SET_TABS_NAME',name) |
||||||
|
}, |
||||||
|
setColumnId({ state,commit },id) { |
||||||
|
commit('SET_COLUMN_ID',id) |
||||||
|
}, |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
/** |
||||||
|
* 赛事相关 |
||||||
|
* */ |
||||||
|
export default { |
||||||
|
namespaced: true, |
||||||
|
state: { |
||||||
|
matchId: '', |
||||||
|
}, |
||||||
|
mutations: { |
||||||
|
SET_MATCH_ID: (state, id) => { |
||||||
|
state.matchId = id |
||||||
|
}, |
||||||
|
}, |
||||||
|
actions: { |
||||||
|
setMatchId({ state,commit },id) { |
||||||
|
commit('SET_MATCH_ID',id) |
||||||
|
}, |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue