Commit d175c790 authored by Liu Peng's avatar Liu Peng

支持课程上传附件

parent 29808f01
...@@ -30,6 +30,33 @@ ...@@ -30,6 +30,33 @@
</a-radio-group> </a-radio-group>
</a-form-model-item> </a-form-model-item>
<a-form-model-item
label="系列名称"
prop="seriesId"
v-if="step1FormModel.type == 'SERIES'"
>
<a-select
:value="currentSeries"
label-in-value
show-search
placeholder="输入或查询系列"
:default-active-first-option="false"
:show-arrow="false"
:filter-option="false"
:not-found-content="null"
@search="handleSeriesSearch"
@change="handleSeriesChange"
>
<a-select-option
v-for="d in this.seriesData"
:key="d.value"
>
{{ d.text }}
</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item <a-form-model-item
label="课程名称" label="课程名称"
prop="name" prop="name"
...@@ -132,31 +159,28 @@ ...@@ -132,31 +159,28 @@
/> />
</a-form-model-item> </a-form-model-item>
<a-form-model-item <a-form-model-item label="上传附件">
label="系列名称" <div
prop="seriesId" v-for="(attachment) in attachments"
v-if="step1FormModel.type == 'SERIES'" :label="attachment.title"
> :key="attachment.id"
<a-select class="video-series"
:value="currentSeries"
label-in-value
show-search
placeholder="输入或查询系列"
:default-active-first-option="false"
:show-arrow="false"
:filter-option="false"
:not-found-content="null"
@search="handleSeriesSearch"
@change="handleSeriesChange"
> >
<a-select-option <a-row
v-for="d in this.seriesData" type="flex"
:key="d.value" justify="start"
align="middle"
> >
{{ d.text }} <a-col :span="12">
</a-select-option> <div class="video-desc">
</a-select> <a-icon
type="paper-clip"
class="attachment-icon"
/>{{attachment.title}}</div>
</a-col>
</a-row>
</div>
<a-button @click="showAttachmentUploadModal">上传附件</a-button>
</a-form-model-item> </a-form-model-item>
<a-form-model-item <a-form-model-item
...@@ -313,12 +337,13 @@ ...@@ -313,12 +337,13 @@
@ok="videoUpload" @ok="videoUpload"
@cancel="closeVideoUploadModal" @cancel="closeVideoUploadModal"
:destroyOnClose="true" :destroyOnClose="true"
centered
> >
<a-form> <a-form>
<a-form-item> <a-form-item>
<a-input <a-input
v-model="video.title" v-model="video.title"
placeholder="输入视频标题" placeholder="视频标题"
allowClear allowClear
></a-input> ></a-input>
</a-form-item> </a-form-item>
...@@ -339,6 +364,40 @@ ...@@ -339,6 +364,40 @@
</a-modal> </a-modal>
</template> </template>
<template>
<a-modal
:visible="attachmentUploadModalVisible"
title="附件上传"
@ok="saveAttachments"
@cancel="closeAttachmentUploadModal"
:destroyOnClose="true"
centered
>
<a-form>
<a-form-item>
<a-input
v-model="attachment.title"
placeholder="附件标题"
allowClear
></a-input>
</a-form-item>
<a-form-item>
<a-upload
ref="attachmentUploaderRef"
name="file"
:multiple="false"
:show-upload-list="true"
:customRequest="uploadAttachment"
:before-upload="beforeAttachmentUpload"
>
<a-button>
<a-icon type="upload" />选择附件文件</a-button>
</a-upload>
</a-form-item>
</a-form>
</a-modal>
</template>
<template> <template>
<a-modal <a-modal
:visible="showVideoEditor" :visible="showVideoEditor"
...@@ -361,6 +420,7 @@ ...@@ -361,6 +420,7 @@
</div> </div>
</template> </template>
<script> <script>
import { uploadFile } from "@/api/biz/resource"; import { uploadFile } from "@/api/biz/resource";
import { disposereq } from "@/utils/util"; import { disposereq } from "@/utils/util";
...@@ -433,7 +493,11 @@ export default { ...@@ -433,7 +493,11 @@ export default {
res.data.forEach((d) => { res.data.forEach((d) => {
const tg = _teachers.find((t) => t.id === d.orgId); const tg = _teachers.find((t) => t.id === d.orgId);
if (!tg) { if (!tg) {
_teachers.push({ id: d.orgId, name: d.orgName, teachers: [d] }); _teachers.push({
id: d.orgId,
name: d.orgName,
teachers: [d],
});
} else { } else {
tg.teachers.push(d); tg.teachers.push(d);
} }
...@@ -520,14 +584,23 @@ export default { ...@@ -520,14 +584,23 @@ export default {
} }
}; };
return { return {
attachment: {
title: "",
},
attachments: [],
video2update: {}, video2update: {},
enterprise: [], enterprise: [],
currentSeries: {}, currentSeries: {},
tags: [], tags: [],
selectedTags: [], selectedTags: [],
videoSeries: [], videoSeries: [],
videoTitle: "", video: {
video: { id: "", img: "", file: "", fileName: "", title: "" }, id: "",
img: "",
file: "",
fileName: "",
title: "",
},
showVideoEditor: false, showVideoEditor: false,
teachers: [], teachers: [],
seriesData: [], seriesData: [],
...@@ -542,11 +615,37 @@ export default { ...@@ -542,11 +615,37 @@ export default {
aliyunUserId: "", aliyunUserId: "",
//第一步保存时验证规则定义 //第一步保存时验证规则定义
step1FormRules: { step1FormRules: {
name: [{ required: true, message: "不能为空", trigger: "blur" }], name: [
seriesId: [{ validator: validateSerial, trigger: "change" }], {
price: [{ validator: validatePrice, trigger: "change" }], required: true,
validPeriod: [{ validator: validateValidPeriod, trigger: "change" }], message: "不能为空",
vipPrice: [{ validator: validateVipPrice, trigger: "change" }], trigger: "blur",
},
],
seriesId: [
{
validator: validateSerial,
trigger: "change",
},
],
price: [
{
validator: validatePrice,
trigger: "change",
},
],
validPeriod: [
{
validator: validateValidPeriod,
trigger: "change",
},
],
vipPrice: [
{
validator: validateVipPrice,
trigger: "change",
},
],
}, },
//第一步表单数据对象 //第一步表单数据对象
step1FormModel: { step1FormModel: {
...@@ -575,6 +674,8 @@ export default { ...@@ -575,6 +674,8 @@ export default {
seriesModalVisible: false, seriesModalVisible: false,
//视频上传窗口 //视频上传窗口
videoUploadModalVisible: false, videoUploadModalVisible: false,
//附件上传窗口
attachmentUploadModalVisible: false,
teacherSearchPage: { teacherSearchPage: {
name: "", name: "",
pageIndex: 1, pageIndex: 1,
...@@ -662,7 +763,10 @@ export default { ...@@ -662,7 +763,10 @@ export default {
this.fetchSeriesData(value, (data) => { this.fetchSeriesData(value, (data) => {
const _items = []; const _items = [];
data.forEach((d) => { data.forEach((d) => {
_items.push({ value: d.id, text: d.name }); _items.push({
value: d.id,
text: d.name,
});
}); });
this.seriesData = _items; this.seriesData = _items;
}); });
...@@ -674,12 +778,20 @@ export default { ...@@ -674,12 +778,20 @@ export default {
pageSize: 500, pageSize: 500,
}).then((res) => { }).then((res) => {
if (res.count === 0) { if (res.count === 0) {
callback([{ name: value, id: -1 }]); callback([
{
name: value,
id: -1,
},
]);
} else { } else {
const item = res.data.find((d) => d.name.trim() === value); const item = res.data.find((d) => d.name.trim() === value);
if (!item) { if (!item) {
//未找到完全匹配的 //未找到完全匹配的
res.data.unshift({ name: value, id: -1 }); res.data.unshift({
name: value,
id: -1,
});
} }
callback(res.data); callback(res.data);
} }
...@@ -688,9 +800,14 @@ export default { ...@@ -688,9 +800,14 @@ export default {
handleSeriesChange(value) { handleSeriesChange(value) {
if (value.key === -1) { if (value.key === -1) {
//新建 //新建
saveSeriesInfo({ name: value.label }).then((res) => { saveSeriesInfo({
name: value.label,
}).then((res) => {
if (res.resp_code === 200) { if (res.resp_code === 200) {
this.currentSeries = { key: res.datas, label: value.label }; this.currentSeries = {
key: res.datas,
label: value.label,
};
} }
}); });
} else { } else {
...@@ -748,6 +865,7 @@ export default { ...@@ -748,6 +865,7 @@ export default {
vipPrice, vipPrice,
chaperList, chaperList,
tagIds, tagIds,
attachmenIds: [],
}; };
if (this.currentSeries) { if (this.currentSeries) {
course.seriesId = this.currentSeries.key; course.seriesId = this.currentSeries.key;
...@@ -766,6 +884,11 @@ export default { ...@@ -766,6 +884,11 @@ export default {
_tags.push(t.key); _tags.push(t.key);
}); });
course.tagIds = _tags; course.tagIds = _tags;
this.attachments.forEach((a) => {
course.attachmenIds.push(a.id);
});
saveCourse(course).then((res) => { saveCourse(course).then((res) => {
if (res.resp_code === 200) { if (res.resp_code === 200) {
this.$message.success("课程保存成功"); this.$message.success("课程保存成功");
...@@ -779,7 +902,9 @@ export default { ...@@ -779,7 +902,9 @@ export default {
getDetail(id) getDetail(id)
.then((res) => { .then((res) => {
if (res.resp_code == 200) { if (res.resp_code == 200) {
this.step1FormModel = { ...res.datas }; this.step1FormModel = {
...res.datas,
};
if (this.step1FormModel.allowOrgList) { if (this.step1FormModel.allowOrgList) {
const _enterprise = []; const _enterprise = [];
...@@ -791,7 +916,10 @@ export default { ...@@ -791,7 +916,10 @@ export default {
if (this.step1FormModel.tagList) { if (this.step1FormModel.tagList) {
this.step1FormModel.tagList.forEach((t) => { this.step1FormModel.tagList.forEach((t) => {
this.selectedTags.push({ key: t.tagId, label: t.tagName }); this.selectedTags.push({
key: t.tagId,
label: t.tagName,
});
}); });
} }
...@@ -800,9 +928,19 @@ export default { ...@@ -800,9 +928,19 @@ export default {
label: this.step1FormModel.seriesName, label: this.step1FormModel.seriesName,
}; };
console.log(res.datas);
const _attachments = [];
res.datas.attachmentList.forEach((a) => {
_attachments.push({ id: a.resourceId, title: a.resourceName });
});
this.attachments = _attachments;
const _videoSeries = []; const _videoSeries = [];
res.datas.chaperList.forEach((cc) => { res.datas.chaperList.forEach((cc) => {
_videoSeries.push({ ...cc }); _videoSeries.push({
...cc,
});
}); });
this.videoSeries = _videoSeries; this.videoSeries = _videoSeries;
} else { } else {
...@@ -857,10 +995,8 @@ export default { ...@@ -857,10 +995,8 @@ export default {
}, },
beforeVideoUpload(file) { beforeVideoUpload(file) {
const { type } = file; const { type } = file;
if (!this.video.title) { const title = file.name.substring(0, file.name.indexOf("."));
this.$message.error("请填写视频标题"); this.video.title = title;
return false;
}
if (type.startsWith("video")) { if (type.startsWith("video")) {
return true; return true;
} else { } else {
...@@ -869,6 +1005,58 @@ export default { ...@@ -869,6 +1005,58 @@ export default {
} }
}, },
beforeAttachmentUpload(file) {
const { type } = file;
const title = file.name.substring(0, file.name.indexOf("."));
this.attachment.title = title;
},
saveAttachments() {
if (this.attachment) {
const { title, id } = this.attachment;
if (!title) {
this.$message.error("请填写附件标题");
return;
}
if (!id) {
this.$message.error("请上传附件文件");
return;
}
this.attachments.push({
title: title,
id: id,
});
this.attachment = {};
this.attachmentUploadModalVisible = false;
}
},
uploadAttachment(data) {
let self = this;
const formData = new FormData();
formData.append("file", data.file);
uploadFile(formData)
.then((res) => {
if (res.data.resp_code == 200) {
self.$refs.attachmentUploaderRef.onProgress(
{
percent: 100,
},
data.file
);
self.attachment.id = res.data.datas.id;
self.$refs.attachmentUploaderRef.onSuccess(null, data.file);
} else {
this.$message.info("上传失败");
}
this.loading = false;
})
.catch((err) => {
disposereq(this, err);
});
},
uploadVideo({ file }) { uploadVideo({ file }) {
var Title = this.video.title; var Title = this.video.title;
this.video.fileName = file.name; this.video.fileName = file.name;
...@@ -973,7 +1161,9 @@ export default { ...@@ -973,7 +1161,9 @@ export default {
let progressPercent = Math.ceil(progress * 100); let progressPercent = Math.ceil(progress * 100);
self.authProgress = progressPercent; self.authProgress = progressPercent;
self.$refs.videoUploaderRef.onProgress( self.$refs.videoUploaderRef.onProgress(
{ percent: progressPercent }, {
percent: progressPercent,
},
uploadInfo.file uploadInfo.file
); );
if (progressPercent === 100) { if (progressPercent === 100) {
...@@ -1030,9 +1220,26 @@ export default { ...@@ -1030,9 +1220,26 @@ export default {
this.videoUploadModalVisible = false; this.videoUploadModalVisible = false;
this.video = {}; this.video = {};
}, },
showAttachmentUploadModal() {
this.attachmentUploadModalVisible = true;
},
closeAttachmentUploadModal() {
this.attachmentUploadModalVisible = false;
this.attachment = {};
},
videoUpload() { videoUpload() {
if (this.video) { if (this.video) {
const { title, id } = this.video; const { title, id } = this.video;
if (!title) {
this.$message.error("请填写视频标题");
return;
}
if (!id) {
this.$message.error("请上传视频文件");
return;
}
fetchVideoInfo(id).then((res) => { fetchVideoInfo(id).then((res) => {
if (res.resp_code == 200) { if (res.resp_code == 200) {
const { coverURL, duration } = res.datas; const { coverURL, duration } = res.datas;
...@@ -1055,7 +1262,9 @@ export default { ...@@ -1055,7 +1262,9 @@ export default {
.then((res) => { .then((res) => {
if (res.code == 200) { if (res.code == 200) {
this.teacherData = res.data; this.teacherData = res.data;
var paper = { ...this.teacherPagination }; var paper = {
...this.teacherPagination,
};
paper.current = query.pageIndex; paper.current = query.pageIndex;
paper.total = res.count; paper.total = res.count;
this.teacherPagination = paper; this.teacherPagination = paper;
...@@ -1076,29 +1285,38 @@ export default { ...@@ -1076,29 +1285,38 @@ export default {
}, },
}; };
</script> </script>
<style> <style>
.attachment-icon {
margin-right: 5px;
}
.detail_content { .detail_content {
background-color: #f0f2f5; background-color: #f0f2f5;
width: 100%; width: 100%;
height: 100%; height: 100%;
box-sizing: border-box; box-sizing: border-box;
} }
.search_box { .search_box {
width: 100%; width: 100%;
box-sizing: border-box; box-sizing: border-box;
padding: 14px; padding: 14px;
background-color: #fff; background-color: #fff;
} }
.steps-content { .steps-content {
width: 100%; width: 100%;
background-color: #fff; background-color: #fff;
} }
.uploadImg { .uploadImg {
cursor: pointer; cursor: pointer;
} }
.table_top { .table_top {
padding-bottom: 14px; padding-bottom: 14px;
} }
.video-desc { .video-desc {
margin-left: 10px; margin-left: 10px;
height: 100%; height: 100%;
...@@ -1111,15 +1329,19 @@ export default { ...@@ -1111,15 +1329,19 @@ export default {
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
overflow: hidden; overflow: hidden;
} }
.video-series { .video-series {
margin-top: 5px; margin-top: 5px;
} }
.btn-div { .btn-div {
text-align: center; text-align: center;
} }
.cancel-btn { .cancel-btn {
margin-left: 15px; margin-left: 15px;
} }
.video-image-background { .video-image-background {
background-position: 50%; background-position: 50%;
background-repeat: no-repeat; background-repeat: no-repeat;
...@@ -1127,6 +1349,7 @@ export default { ...@@ -1127,6 +1349,7 @@ export default {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.video-image { .video-image {
width: 120px; width: 120px;
height: 68px; height: 68px;
...@@ -1137,6 +1360,7 @@ export default { ...@@ -1137,6 +1360,7 @@ export default {
cursor: pointer; cursor: pointer;
background-size: 60px; background-size: 60px;
} }
.video-image-time { .video-image-time {
position: absolute; position: absolute;
text-align: right; text-align: right;
...@@ -1163,6 +1387,7 @@ export default { ...@@ -1163,6 +1387,7 @@ export default {
line-height: 24px; line-height: 24px;
padding: 0 3px; padding: 0 3px;
} }
.video-image-play { .video-image-play {
position: absolute; position: absolute;
top: 20px; top: 20px;
...@@ -1171,6 +1396,7 @@ export default { ...@@ -1171,6 +1396,7 @@ export default {
color: #fff; color: #fff;
opacity: 0.4; opacity: 0.4;
} }
.video-image-cover { .video-image-cover {
position: absolute; position: absolute;
width: 100%; width: 100%;
...@@ -1179,4 +1405,4 @@ export default { ...@@ -1179,4 +1405,4 @@ export default {
left: 0; left: 0;
z-index: 1; z-index: 1;
} }
</style> </style>
\ No newline at end of file
<template> <template>
<div class="price-config-container"> <div class="price-config-container">
<div class="title-text">轮播图配置</div> <div class="title-text">轮播图配置</div>
<a-row <a-row type="flex" class="swiper-config">
type="flex" <a-col v-for="swiper in this.swipers" :key="swiper.id" :value="swiper.id">
class="swiper-config" <div class="swiper-div">
> <div class="img-container">
<a-col <img @click="updateSwiper(swiper)" class="image" v-if="swiper.imageUrl" :src="swiper.imageUrl" />
v-for="swiper in this.swipers" <div class="swiper-image-status">
:key="swiper.id" <a-tooltip v-if="swiper.status === 'ENABLE'" placement="bottom" title="已发布">
:value="swiper.id" <a-icon type="star" theme="filled" class="published-swiper" @click="changeSwiperStatus(swiper,false)" />
> </a-tooltip>
<div class="swiper-div"> <a-tooltip v-else placement="bottom" title="未发布">
<div class="img-container"> <a-icon type="star" @click="changeSwiperStatus(swiper,true)" />
<img </a-tooltip>
@click="updateSwiper(swiper)" <a-icon type="delete" @click="removeSwiper(swiper)" />
class="image" </div>
v-if="swiper.imageUrl" </div>
:src="swiper.imageUrl" <div class="course-name">
/> <span>{{swiper.courseName}}</span>
<div class="swiper-image-status"> </div>
<a-tooltip
v-if="swiper.status === 'ENABLE'"
placement="bottom"
title="已发布"
>
<a-icon
type="star"
theme="filled"
class="published-swiper"
@click="changeSwiperStatus(swiper,false)"
/>
</a-tooltip>
<a-tooltip
v-else
placement="bottom"
title="未发布"
>
<a-icon
type="star"
@click="changeSwiperStatus(swiper,true)"
/>
</a-tooltip>
<a-icon
type="delete"
@click="removeSwiper(swiper)"
/>
</div> </div>
</div> </a-col>
<div class="course-name">
<span>{{swiper.courseName}}</span>
</div>
</div>
</a-col>
<a-col> <a-col>
<div <div class="create-swiper-div" @click="displaySwiperCreator">
class="create-swiper-div" <div class="tool-bar-text">
@click="displaySwiperCreator" <a-icon type="plus" class="btn-icon" /><br>
> 创建轮播图
<div class="tool-bar-text"> </div>
<a-icon </div>
type="plus" </a-col>
class="btn-icon"
/><br>
创建轮播图
</div>
</div>
</a-col>
</a-row> </a-row>
<div class="title-text home-tags">首页分类标签</div> <div class="title-text home-tags">首页分类标签</div>
<a-row <a-row type="flex" class="swiper-config-hometags">
type="flex" <a-col :span="24">
class="swiper-config-hometags" <div>
> <a-tag v-for="(tag) in this.homeTags" :key="tag.id" color="blue" closable @close="deleteHomeTag(tag)">{{tag.name}}</a-tag>
<a-col :span="24"> <a-button icon="plus" @click="showHomeTagEditor" size="small">
<div> 添加标签
<a-tag </a-button>
v-for="(tag) in this.homeTags" </div>
:key="tag.id" </a-col>
color="blue"
closable
@close="deleteHomeTag(tag)"
>{{tag.name}}</a-tag>
<a-button
icon="plus"
@click="showHomeTagEditor"
size="small"
>
添加标签
</a-button>
</div>
</a-col>
</a-row> </a-row>
<div class="title-text rec-video">首页推荐视频</div> <div class="title-text rec-video">首页推荐视频</div>
<a-row <a-row type="flex" class="swiper-config">
type="flex" <a-col v-for="video in this.homeRecVideos" :key="video.id" :value="video.id">
class="swiper-config" <div class="swiper-div">
> <div class="img-container">
<a-col <img class="image" v-if="video.courseLogoUrl" :src="video.courseLogoUrl" />
v-for="video in this.homeRecVideos" <div class="swiper-image-status">
:key="video.id" <a-icon type="delete" @click="removeHomeRecVideo(video)" />
:value="video.id" </div>
> </div>
<div class="swiper-div"> <div class="course-name">
<div class="img-container"> <span>{{video.courseName}}</span>
<img </div>
class="image"
v-if="video.courseLogoUrl"
:src="video.courseLogoUrl"
/>
<div class="swiper-image-status">
<a-icon
type="delete"
@click="removeHomeRecVideo(video)"
/>
</div> </div>
</div> </a-col>
<div class="course-name">
<span>{{video.courseName}}</span>
</div>
</div>
</a-col>
<a-col> <a-col>
<div <div class="create-swiper-div" @click="openHomeVideoEditor">
class="create-swiper-div" <div class="tool-bar-text">
@click="openHomeVideoEditor" <a-icon type="plus" class="btn-icon" /><br>
> 添加视频
<div class="tool-bar-text"> </div>
<a-icon </div>
type="plus" </a-col>
class="btn-icon"
/><br>
添加视频
</div>
</div>
</a-col>
</a-row> </a-row>
<template> <template>
<a-modal <a-modal :visible="showSwiperCreator" :title="currentSwiper.courseId ? '编辑轮播图':'新建轮播图'" @ok="saveSwiper" @cancel="closeSwiperCreator" :destroyOnClose="true" centered>
:visible="showSwiperCreator" <a-form>
:title="currentSwiper.courseId ? '编辑轮播图':'新建轮播图'" <a-form-item label="编辑封面">
@ok="saveSwiper" <div class="siwper-editor">
@cancel="closeSwiperCreator" <a-upload name="file" :multiple="false" list-type="picture-card" :show-upload-list="false" :customRequest="uploadSwiperImg" :before-upload="beforeUpload">
:destroyOnClose="true"
centered
>
<a-form>
<a-form-item label="编辑封面">
<div class="siwper-editor">
<a-upload
name="file"
:multiple="false"
list-type="picture-card"
:show-upload-list="false"
:customRequest="uploadSwiperImg"
:before-upload="beforeUpload"
>
<img <img v-if="currentSwiper.imageUrl" :src="currentSwiper.imageUrl" :width="200" />
v-if="currentSwiper.imageUrl" <div v-else>
:src="currentSwiper.imageUrl" <a-icon :type="loading ? 'loading' : 'plus'" />
:width="200" <div class="ant-upload-text">
/> 上传封面
<div v-else> </div>
<a-icon :type="loading ? 'loading' : 'plus'" /> </div>
<div class="ant-upload-text"> </a-upload>
上传封面 </div>
</div> </a-form-item>
</div> <a-form-item label="关联课程">
</a-upload> <a-select show-search placeholder="查询课程" :default-active-first-option="false" :show-arrow="false" :filter-option="false" :not-found-content="null" @search="onCourseSearch" @change="onCourseChange" v-model="currentSwiper.courseId">
</div> <a-select-option v-for="course in this.courses" :key="course.id" :value="course.id">
</a-form-item> {{ course.name }}
<a-form-item label="关联课程"> </a-select-option>
<a-select </a-select>
show-search </a-form-item>
placeholder="查询课程" <a-form-item label="轮播图状态">
:default-active-first-option="false" <a-radio-group name="radioGroup" v-model="currentSwiper.status" default-value="DISABLE">
:show-arrow="false" <a-radio value="ENABLE">已发布</a-radio>
:filter-option="false" <a-radio value="DISABLE">未发布</a-radio>
:not-found-content="null" </a-radio-group>
@search="onCourseSearch" </a-form-item>
@change="onCourseChange" </a-form>
v-model="currentSwiper.courseId" </a-modal>
>
<a-select-option
v-for="course in this.courses"
:key="course.id"
:value="course.id"
>
{{ course.name }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="轮播图状态">
<a-radio-group
name="radioGroup"
v-model="currentSwiper.status"
default-value="DISABLE"
>
<a-radio value="ENABLE">已发布</a-radio>
<a-radio value="DISABLE">未发布</a-radio>
</a-radio-group>
</a-form-item>
</a-form>
</a-modal>
</template> </template>
<template> <template>
<a-modal <a-modal :visible="showHomeTagCreator" title="添加首页标签" @ok="saveHomeTags" @cancel="hideHomeTagEditor" :destroyOnClose="true" centered>
:visible="showHomeTagCreator" <a-form>
title="添加首页标签" <a-form-item label="选择首页标签">
@ok="saveHomeTags" <a-select mode="multiple" v-model="tags">
@cancel="hideHomeTagEditor" <a-select-option v-for="(t) in this.availTags" :key="t.id" :value="t.id">
:destroyOnClose="true" {{ t.name }}
centered </a-select-option>
> </a-select>
<a-form> </a-form-item>
<a-form-item label="选择首页标签"> </a-form>
<a-select </a-modal>
mode="multiple"
v-model="tags"
>
<a-select-option
v-for="(t) in this.availTags"
:key="t.id"
:value="t.id"
>
{{ t.name }}
</a-select-option>
</a-select>
</a-form-item>
</a-form>
</a-modal>
</template> </template>
<template> <template>
<a-modal <a-modal :visible="showHomeVideoEditor" title="添加推荐视频" @ok="saveHomeRecVideos" @cancel="hideHomeVideoEditor" :destroyOnClose="true" centered>
:visible="showHomeVideoEditor" <a-form>
title="添加推荐视频" <a-form-item label="选择推荐视频">
@ok="saveHomeRecVideos" <a-select mode="multiple" v-model="selectedVideos">
@cancel="hideHomeVideoEditor" <a-select-option v-for="(t) in this.availHomeRecVideos" :key="t.id" :value="t.id">
:destroyOnClose="true" {{ t.name }}
centered </a-select-option>
> </a-select>
<a-form> </a-form-item>
<a-form-item label="选择推荐视频"> </a-form>
<a-select </a-modal>
mode="multiple"
v-model="selectedVideos"
>
<a-select-option
v-for="(t) in this.availHomeRecVideos"
:key="t.id"
:value="t.id"
>
{{ t.name }}
</a-select-option>
</a-select>
</a-form-item>
</a-form>
</a-modal>
</template> </template>
</div> </div>
</template> </template>
<script> <script>
import { disposereq } from "@/utils/util";
import { import {
saveSwiper, disposereq
fetchAllSwiper, } from "@/utils/util";
fetchHomeTags, import {
fetchAvaliHomeTags, saveSwiper,
addHomeTag, fetchAllSwiper,
removeHomeTag, fetchHomeTags,
fetchRecVideos, fetchAvaliHomeTags,
fetchAvailRecVideos, addHomeTag,
addHomeRecVideos, removeHomeTag,
removeHomeRecVideos, fetchRecVideos,
removeSwiper, fetchAvailRecVideos,
changeSwiperStatus, addHomeRecVideos,
removeHomeRecVideos,
removeSwiper as deleteSwiper,
changeSwiperStatus,
} from "@/api/biz/settings"; } from "@/api/biz/settings";
import { uploadFile } from "@/api/biz/resource"; import {
import { fetchList as fetchCourseList } from "@/api/biz/course"; uploadFile
import { fetchList as fetchTagList } from "@/api/biz/courseTag"; } from "@/api/biz/resource";
import {
fetchList as fetchCourseList
} from "@/api/biz/course";
import {
fetchList as fetchTagList
} from "@/api/biz/courseTag";
export default { export default {
data() { data() {
return { return {
showHomeVideoEditor: false, showHomeVideoEditor: false,
homeRecVideos: [], homeRecVideos: [],
availHomeRecVideos: [], availHomeRecVideos: [],
selectedVideos: [], selectedVideos: [],
homeTags: [], homeTags: [],
tags: [], tags: [],
availTags: [], availTags: [],
swipers: [], swipers: [],
courses: [], courses: [],
showHomeTagCreator: false, showHomeTagCreator: false,
showSwiperCreator: false, showSwiperCreator: false,
swiper: {}, swiper: {},
currentSwiper: {}, currentSwiper: {},
loading: false, loading: false,
imageUrl: "", imageUrl: "",
uploadFile, uploadFile,
fullPageSize: 10000, fullPageSize: 10000,
}; };
},
created() {
fetchCourseList({
pageIndex: 1,
pageSize: this.fullPageSize,
status: "UP",
allow: "ALL",
}).then((resp) => {
this.courses = resp.data;
});
fetchAllSwiper().then((resp) => {
this.swipers = resp.datas;
});
this.fetchAllHomeTags();
this.fetchHomeRecVideos();
},
beforeUpdate() {},
methods: {
removeSwiper(swiper) {
console.log(swiper);
},
removeHomeRecVideo(video) {
removeHomeRecVideos(video.id).then((resp) => {
this.fetchHomeRecVideos();
});
},
saveHomeRecVideos() {
const recVideos = [];
this.selectedVideos.forEach((v) => {
recVideos.push({ courseId: v });
});
addHomeRecVideos(recVideos).then((resp) => {
this.fetchHomeRecVideos();
this.showHomeVideoEditor = false;
});
},
hideHomeVideoEditor() {
this.selectedVideos = [];
this.fetchHomeRecVideos();
this.showHomeVideoEditor = false;
},
openHomeVideoEditor() {
fetchAvailRecVideos({ pageIndex: 1, pageSize: 10000 }).then((resp) => {
this.availHomeRecVideos = resp.data;
});
this.showHomeVideoEditor = true;
},
fetchHomeRecVideos() {
fetchRecVideos().then((resp) => {
this.homeRecVideos = resp.datas;
});
}, },
deleteHomeTag(tag) { created() {
removeHomeTag(tag.id).then((resp) => { fetchCourseList({
this.fetchAllHomeTags(); pageIndex: 1,
}); pageSize: this.fullPageSize,
}, status: "UP",
showHomeTagEditor() { allow: "ALL",
fetchAvaliHomeTags({ }).then((resp) => {
pageIndex: 1, this.courses = resp.data;
pageSize: 10000, });
}).then((resp) => { fetchAllSwiper().then((resp) => {
this.availTags = resp.data; this.swipers = resp.datas;
}); });
this.showHomeTagCreator = true;
},
fetchAllHomeTags() {
fetchHomeTags().then((resp) => {
this.homeTags = resp.datas;
});
},
saveHomeTags() {
addHomeTag(this.tags).then((resp) => {
this.fetchAllHomeTags(); this.fetchAllHomeTags();
}); this.fetchHomeRecVideos();
this.tags = [];
this.showHomeTagCreator = false;
},
hideHomeTagEditor() {
this.tags = [];
this.showHomeTagCreator = false;
},
updateSwiper(swiper) {
this.currentSwiper = swiper;
this.showSwiperCreator = true;
},
changeSwiperStatus(swiper, status) {
changeSwiperStatus({
id: swiper.id,
status: status ? "ENABLE" : "DISABLE",
}).then((resp) => {
this.loadAllSwiper();
});
},
loadAllSwiper() {
fetchAllSwiper().then((resp) => {
this.swipers = resp.datas;
});
},
onCourseChange(value) {
this.currentSwiper.courseId = value;
},
onCourseSearch(value) {
const searchData = {
pageIndex: 1,
pageSize: this.fullPageSize,
status: "UP",
allow: "ALL",
};
if (value) {
searchData.name = value;
}
fetchCourseList(searchData).then((resp) => {
this.courses = resp.data;
});
},
onSwiperStatusChange(checked) {
this.currentSwiper.online = checked;
}, },
saveSwiper() { beforeUpdate() {},
const data = { methods: {
...this.currentSwiper, removeHomeRecVideo(video) {
}; removeHomeRecVideos(video.id).then((resp) => {
if (this.currentSwiper.id) { this.fetchHomeRecVideos();
data.id = this.currentSwiper.id; });
} },
saveHomeRecVideos() {
const recVideos = [];
this.selectedVideos.forEach((v) => {
recVideos.push({
courseId: v
});
});
addHomeRecVideos(recVideos).then((resp) => {
this.fetchHomeRecVideos();
this.showHomeVideoEditor = false;
});
},
hideHomeVideoEditor() {
this.selectedVideos = [];
this.fetchHomeRecVideos();
this.showHomeVideoEditor = false;
},
openHomeVideoEditor() {
fetchAvailRecVideos({
pageIndex: 1,
pageSize: 10000
}).then((resp) => {
this.availHomeRecVideos = resp.data;
});
this.showHomeVideoEditor = true;
},
fetchHomeRecVideos() {
fetchRecVideos().then((resp) => {
this.homeRecVideos = resp.datas;
});
},
deleteHomeTag(tag) {
removeHomeTag(tag.id).then((resp) => {
this.fetchAllHomeTags();
});
},
showHomeTagEditor() {
fetchAvaliHomeTags({
pageIndex: 1,
pageSize: 10000,
}).then((resp) => {
console.log(resp);
this.availTags = resp.data;
});
this.showHomeTagCreator = true;
},
fetchAllHomeTags() {
fetchHomeTags().then((resp) => {
this.homeTags = resp.datas;
});
},
saveHomeTags() {
addHomeTag(this.tags).then((resp) => {
this.fetchAllHomeTags();
});
this.tags = [];
this.showHomeTagCreator = false;
},
hideHomeTagEditor() {
this.tags = [];
this.showHomeTagCreator = false;
},
updateSwiper(swiper) {
this.currentSwiper = swiper;
this.showSwiperCreator = true;
},
changeSwiperStatus(swiper, status) {
changeSwiperStatus({
id: swiper.id,
status: status ? "ENABLE" : "DISABLE",
}).then((resp) => {
this.loadAllSwiper();
});
},
loadAllSwiper() {
fetchAllSwiper().then((resp) => {
this.swipers = resp.datas;
});
},
removeSwiper(swiper) {
deleteSwiper(swiper.id).then((resp) => {
this.loadAllSwiper();
});
},
onCourseChange(value) {
this.currentSwiper.courseId = value;
},
onCourseSearch(value) {
const searchData = {
pageIndex: 1,
pageSize: this.fullPageSize,
status: "UP",
allow: "ALL",
};
if (value) {
searchData.name = value;
}
fetchCourseList(searchData).then((resp) => {
this.courses = resp.data;
});
},
onSwiperStatusChange(checked) {
this.currentSwiper.online = checked;
},
saveSwiper() {
const data = {
...this.currentSwiper,
};
if (this.currentSwiper.id) {
data.id = this.currentSwiper.id;
}
saveSwiper(data).then((resp) => { saveSwiper(data).then((resp) => {
if (resp.resp_code === 200) { if (resp.resp_code === 200) {
this.loadAllSwiper(); this.loadAllSwiper();
this.showSwiperCreator = false; this.showSwiperCreator = false;
this.currentSwiper = {}; this.currentSwiper = {};
} else { } else {
this.$message.error(`创建轮播图失败:${resp.resp_msg}`); this.$message.error(`创建轮播图失败:${resp.resp_msg}`);
} }
}); });
},
closeSwiperCreator() {
this.currentSwiper = {};
this.loadAllSwiper();
this.showSwiperCreator = false;
},
displaySwiperCreator() {
this.showSwiperCreator = true;
},
uploadSwiperImg(data) {
const formData = new FormData();
formData.append("file", data.file);
this.loading = true;
uploadFile(formData)
.then((res) => {
if (res.data.resp_code == 200) {
this.currentSwiper.imageUrl = res.data.datas.url;
} else {
this.$message.error("上传封面失败");
}
this.loading = false;
})
.catch((err) => {
disposereq(this, err);
});
},
beforeUpload(file) {
const isJpgOrPng =
file.type === "image/jpeg" || file.type === "image/png";
if (!isJpgOrPng) {
this.$message.info("只能上传图片");
}
const isLt2M = file.size / 1024 / 1024 < 10;
if (!isLt2M) {
this.$message.error("Image must smaller than 10MB!");
}
return isJpgOrPng && isLt2M;
},
}, },
closeSwiperCreator() {
this.currentSwiper = {};
this.loadAllSwiper();
this.showSwiperCreator = false;
},
displaySwiperCreator() {
this.showSwiperCreator = true;
},
uploadSwiperImg(data) {
const formData = new FormData();
formData.append("file", data.file);
this.loading = true;
uploadFile(formData)
.then((res) => {
if (res.data.resp_code == 200) {
this.currentSwiper.imageUrl = res.data.datas.url;
} else {
this.$message.error("上传封面失败");
}
this.loading = false;
})
.catch((err) => {
disposereq(this, err);
});
},
beforeUpload(file) {
const isJpgOrPng =
file.type === "image/jpeg" || file.type === "image/png";
if (!isJpgOrPng) {
this.$message.info("只能上传图片");
}
const isLt2M = file.size / 1024 / 1024 < 10;
if (!isLt2M) {
this.$message.error("Image must smaller than 10MB!");
}
return isJpgOrPng && isLt2M;
},
},
}; };
</script> </script>
<style> <style>
.price-config-container { .price-config-container {
margin: 20px; margin: 20px;
background: rgb(255, 255, 255); background: rgb(255, 255, 255);
} }
.price-config-container .home-tags { .price-config-container .home-tags {
margin-top: 20px; margin-top: 20px;
} }
.price-config-container .rec-video { .price-config-container .rec-video {
padding-top: 60px; padding-top: 60px;
} }
.price-config-container .title-text { .price-config-container .title-text {
font-size: 16px; font-size: 16px;
font-weight: bold; font-weight: bold;
color: #000; color: #000;
} }
.price-config-container .swiper-config { .price-config-container .swiper-config {
margin-top: 10px; margin-top: 10px;
} }
.price-config-container .swiper-config .published-swiper { .price-config-container .swiper-config .published-swiper {
color: #f0943c; color: #f0943c;
} }
.price-config-container .swiper-config-hometags { .price-config-container .swiper-config-hometags {
padding-top: 20px; padding-top: 20px;
} }
.price-config-container .swiper-div { .price-config-container .swiper-div {
width: 150px; width: 150px;
height: 150px; height: 150px;
display: table; display: table;
float: left; float: left;
margin-right: 8px; margin-right: 8px;
margin-bottom: 8px; margin-bottom: 8px;
vertical-align: top; vertical-align: top;
cursor: pointer; cursor: pointer;
-webkit-transition: border-color 0.3s ease; -webkit-transition: border-color 0.3s ease;
transition: border-color 0.3s ease; transition: border-color 0.3s ease;
} }
.price-config-container .swiper-div .course-name { .price-config-container .swiper-div .course-name {
padding-top: 5px; padding-top: 5px;
word-break: break-all; word-break: break-all;
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden; overflow: hidden;
font-weight: bold; font-weight: bold;
font-size: 14px; font-size: 14px;
color: #303030; color: #303030;
line-height: 20px; line-height: 20px;
height: 60px; height: 60px;
} }
.price-config-container .create-swiper-div { .price-config-container .create-swiper-div {
width: 150px; width: 150px;
height: 150px; height: 150px;
display: table; display: table;
float: left; float: left;
margin-right: 8px; margin-right: 8px;
margin-bottom: 8px; margin-bottom: 8px;
text-align: center; text-align: center;
vertical-align: top; vertical-align: top;
background-color: #fafafa; background-color: #fafafa;
border: 1px dashed #d9d9d9; border: 1px dashed #d9d9d9;
border-radius: 4px; border-radius: 4px;
cursor: pointer; cursor: pointer;
-webkit-transition: border-color 0.3s ease; -webkit-transition: border-color 0.3s ease;
transition: border-color 0.3s ease; transition: border-color 0.3s ease;
} }
.price-config-container .create-swiper-div:hover { .price-config-container .create-swiper-div:hover {
border-color: #1890ff; border-color: #1890ff;
} }
.price-config-container .img-container { .price-config-container .img-container {
width: 250px; width: 250px;
height: 150px; height: 150px;
} }
.price-config-container .image { .price-config-container .image {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.price-config-container .tool-bar-text { .price-config-container .tool-bar-text {
display: table-cell; display: table-cell;
width: 100%; width: 100%;
height: 100%; height: 100%;
padding: 8px; padding: 8px;
text-align: center; text-align: center;
vertical-align: middle; vertical-align: middle;
} }
.price-config-container .tool-bar-text .btn-icon { .price-config-container .tool-bar-text .btn-icon {
font-size: 20px; font-size: 20px;
} }
.swiper-image-status { .swiper-image-status {
position: absolute; position: absolute;
text-align: right; text-align: right;
color: #fff; color: #fff;
width: 100%; width: 100%;
top: 0; top: 0;
z-index: 2; z-index: 2;
height: 24px; height: 24px;
line-height: 24px; line-height: 24px;
padding-right: 15px; padding-right: 15px;
font-size: 14px; font-size: 14px;
} }
</style> </style>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment