Commit 97faaadf authored by Liu Peng's avatar Liu Peng

修改bug

parent 36b33c94
<template> <template>
<div class="detail_content"> <div class="detail_content">
<div class="steps-content"> <div class="steps-content">
<a-form-model <a-form-model :model="step1FormModel" :label-col="{span: 8}" :wrapper-col="{span: 14}" :rules="step1FormRules" ref="step1FormModelRef" style="padding-top: 10px;padding-bottom: 10px">
:model="step1FormModel"
:label-col="{span: 8}" <a-form-model-item label="课程类型" prop="type">
:wrapper-col="{span: 14}" <a-radio-group name="courseType" default-value="SINGLE" v-model="step1FormModel.type" :disabled="isReadOnly">
:rules="step1FormRules" <a-radio value="SINGLE">
ref="step1FormModelRef" 单集
style="padding-top: 10px;padding-bottom: 10px" </a-radio>
> <a-radio value="SERIES">
系列
<a-form-model-item </a-radio>
label="课程类型"
prop="type" </a-radio-group>
> </a-form-model-item>
<a-radio-group
name="courseType" <a-form-model-item label="系列名称" prop="seriesId" v-if="step1FormModel.type == 'SERIES'">
default-value="SINGLE" <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" :disabled="isReadOnly">
v-model="step1FormModel.type" <a-select-option v-for="d in this.seriesData" :key="d.value">
:disabled="isReadOnly" {{ d.text }}
> </a-select-option>
<a-radio value="SINGLE"> </a-select>
单集
</a-radio> </a-form-model-item>
<a-radio value="SERIES">
系列 <a-form-model-item label="课程名称" prop="name">
</a-radio> <a-input v-model="step1FormModel.name" :disabled="isReadOnly" />
</a-form-model-item>
</a-radio-group>
</a-form-model-item> <a-form-model-item label="上传封面" prop="logoUrl">
<a-upload name="file" list-type="picture-card" class="avatar-uploader" :show-upload-list="false" :customRequest="uploadLogo" :before-upload="beforeUpload" @change="handleChange" :disabled="isReadOnly">
<a-form-model-item <img v-if="step1FormModel.logoUrl" width="200" height="200" style="width:auto!important" :src="step1FormModel.logoUrl" alt="logo" />
label="系列名称" <div v-else>
prop="seriesId" <a-icon :type="loading ? 'loading' : 'plus'" />
v-if="step1FormModel.type == 'SERIES'" <div class="ant-upload-text">
> 上传
<a-select </div>
:value="currentSeries" </div>
label-in-value </a-upload>
show-search </a-form-model-item>
placeholder="输入或查询系列"
:default-active-first-option="false" <a-form-model-item label="上传视频">
:show-arrow="false" <div v-for="(video,index) in videoSeries" :label="video.chaperName" :key="video.videoId" class="video-series">
:filter-option="false" <a-row type="flex" justify="start" align="middle">
:not-found-content="null" <a-col :span="6" class="video-image">
@search="handleSeriesSearch" <div class="video-image-background">
@change="handleSeriesChange" <img :src="video.coverUrl" width="100%" />
:disabled="isReadOnly" <div class="video-image-toolbar">
> <a-icon type="delete" @click="deleteVideo(video)" />
<a-select-option <a-icon type="edit" @click="editVideo(video)" />
v-for="d in this.seriesData" </div>
:key="d.value" <div class="video-image-cover"></div>
> <div class="video-image-play">
{{ d.text }} <a-icon type="play-circle" />
</a-select-option> </div>
</a-select> <div class="video-image-time">{{formatDuraton(video.duration)}}</div>
</div>
</a-form-model-item> </a-col>
<a-col :span="12">
<a-form-model-item <div class="video-desc">{{index+1}}</div>
label="课程名称" <div class="video-desc">{{video.name}}</div>
prop="name" </a-col>
> </a-row>
<a-input v-model="step1FormModel.name" :disabled="isReadOnly" />
</a-form-model-item>
<a-form-model-item
label="上传封面"
prop="logoUrl"
>
<a-upload
name="file"
list-type="picture-card"
class="avatar-uploader"
:show-upload-list="false"
:customRequest="uploadLogo"
:before-upload="beforeUpload"
@change="handleChange"
:disabled="isReadOnly"
>
<img
v-if="step1FormModel.logoUrl"
width="200"
height="200"
style="width:auto!important"
:src="step1FormModel.logoUrl"
alt="logo"
/>
<div v-else>
<a-icon :type="loading ? 'loading' : 'plus'" />
<div class="ant-upload-text">
上传
</div>
</div>
</a-upload>
</a-form-model-item>
<a-form-model-item label="上传视频">
<div
v-for="(video,index) in videoSeries"
:label="video.chaperName"
:key="video.videoId"
class="video-series"
>
<a-row
type="flex"
justify="start"
align="middle"
>
<a-col
:span="6"
class="video-image"
>
<div class="video-image-background">
<img
:src="video.coverUrl"
width="100%"
/>
<div class="video-image-toolbar">
<a-icon
type="delete"
@click="deleteVideo(video)"
/>
<a-icon
type="edit"
@click="editVideo(video)"
/>
</div>
<div class="video-image-cover"></div>
<div class="video-image-play">
<a-icon type="play-circle" />
</div>
<div class="video-image-time">{{formatDuraton(video.duration)}}</div>
</div> </div>
</a-col> <a-button @click="showVideoUploadModal" :disabled="isReadOnly">上传视频</a-button>
<a-col :span="12"> </a-form-model-item>
<div class="video-desc">{{index+1}}</div>
<div class="video-desc">{{video.name}}</div> <a-form-model-item label="课程简介" prop="introduce">
</a-col> <a-textarea row="2" v-model="step1FormModel.introduce" :disabled="isReadOnly" />
</a-row> </a-form-model-item>
</div> <a-form-model-item label="课程介绍" prop="detail">
<a-button @click="showVideoUploadModal" :disabled="isReadOnly">上传视频</a-button> <!-- <a-textarea
</a-form-model-item>
<a-form-model-item
label="课程简介"
prop="introduce"
>
<a-textarea
row="2"
v-model="step1FormModel.introduce"
:disabled="isReadOnly"
/>
</a-form-model-item>
<a-form-model-item
label="课程介绍"
prop="detail"
>
<!-- <a-textarea
row="4" row="4"
v-model="step1FormModel.detail" v-model="step1FormModel.detail"
/> --> /> -->
<a-upload <a-upload name="detailUpload" accept="image/*" list-type="picture-card" :file-list="detailPicList" :multiple="true" :customRequest="uploadDetailPic" :before-upload="beforUploadDetailPic" @change="uploadDetailPicChange" :remove="uploadDetailRemove" :disabled="isReadOnly">
name="detailUpload" <div v-if="detailPicList.length < 8">
accept="image/*" <a-icon type="plus" />
list-type="picture-card" <div>
:file-list="detailPicList" 上传图片
:multiple="true" </div>
:customRequest="uploadDetailPic" </div>
:before-upload="beforUploadDetailPic" </a-upload>
@change="uploadDetailPicChange" </a-form-model-item>
:remove="uploadDetailRemove"
:disabled="isReadOnly" <a-form-model-item label="上传附件">
> <div v-for="(attachment) in attachments" :label="attachment.title" :key="attachment.id" class="video-series">
<div v-if="detailPicList.length < 8"> <a-row type="flex" justify="start" align="middle">
<a-icon type="plus" /> <a-col :span="12">
<div> <div class="video-desc">
上传图片 <a-icon type="paper-clip" class="attachment-icon" />{{attachment.title}}</div>
</a-col>
</a-row>
</div> </div>
</div> <a-button @click="showAttachmentUploadModal" :disabled="isReadOnly">上传附件</a-button>
</a-upload> </a-form-model-item>
</a-form-model-item>
<a-form-model-item label="收费模式" prop="chargeModel">
<a-form-model-item label="上传附件"> <a-radio-group name="chargeModel" default-value="FREE" v-model="step1FormModel.chargeModel" :disabled="isReadOnly">
<div <a-radio value="FREE">
v-for="(attachment) in attachments" 免费
:label="attachment.title" </a-radio>
:key="attachment.id" <a-radio value="VIP_FREE">
class="video-series" 会员免费
> </a-radio>
<a-row <a-radio value="PAY">
type="flex" 付费点播
justify="start" </a-radio>
align="middle"
> </a-radio-group>
<a-col :span="12"> </a-form-model-item>
<div class="video-desc"> <a-form-model-item v-if="step1FormModel.chargeModel == 'PAY'" label="非会员价格" prop="price">
<a-icon <a-input prefix="¥" v-model="step1FormModel.price" />
type="paper-clip" </a-form-model-item>
class="attachment-icon" <a-form-model-item v-if="step1FormModel.chargeModel == 'PAY'" label="有效时间" prop="validPeriod">
/>{{attachment.title}}</div> <a-input suffix="小时" v-model="step1FormModel.validPeriod" />
</a-col> </a-form-model-item>
</a-row> <a-form-model-item v-if="step1FormModel.chargeModel == 'PAY'" label="会员价格" prop="vipPrice">
</div> <a-input prefix="¥" v-model="step1FormModel.vipPrice" />
<a-button @click="showAttachmentUploadModal" :disabled="isReadOnly">上传附件</a-button> </a-form-model-item>
</a-form-model-item> <a-form-model-item label="所属讲师">
<a-select placeholder="选择讲师" v-model="step1FormModel.teacherId" @change="handleTeacherChange" :disabled="isReadOnly">
<a-form-model-item
label="收费模式" <a-select-opt-group v-for="(org) in this.teachers" :key="org.id" :label="org.name">
prop="chargeModel" <a-select-option v-for="(t) in org.teachers" :key="t.id" :value="t.id">
> {{ t.name }}
<a-radio-group </a-select-option>
name="chargeModel" </a-select-opt-group>
default-value="FREE"
v-model="step1FormModel.chargeModel" </a-select>
:disabled="isReadOnly" </a-form-model-item>
> <a-form-model-item label="课程标签">
<a-radio value="FREE">
免费 <a-select mode="multiple" label-in-value placeholder="选择课程标签" v-model="selectedTags" @change="handleTagChange" :disabled="isReadOnly">
</a-radio> <a-select-option v-for="(t) in this.tags" :key="t.tagId" :value="t.tagId">
<a-radio value="VIP_FREE"> {{ t.tagName }}
会员免费 </a-select-option>
</a-radio> </a-select>
<a-radio value="PAY"> </a-form-model-item>
付费点播 <a-form-model-item label="可见范围" prop="allow">
</a-radio> <a-radio-group name="allow" default-value="ALL" v-model="step1FormModel.allow" :disabled="isReadOnly">
<a-radio value="ALL">
</a-radio-group> 全部
</a-form-model-item> </a-radio>
<a-form-model-item <a-radio value="SPECIFY">
v-if="step1FormModel.chargeModel == 'PAY'" 指定企业
label="非会员价格" </a-radio>
prop="price" </a-radio-group>
> </a-form-model-item>
<a-input
prefix="¥" <a-form-model-item v-if="step1FormModel.allow === 'SPECIFY'" label="指定企业">
v-model="step1FormModel.price" <a-select mode="multiple" placeholder="选择企业" v-model="step1FormModel.allowOrgIds" @change="handleEnterpriseChange">
/> <a-select-option v-for="(t) in this.enterprise" :key="t.id" :value="t.id">
</a-form-model-item> {{ t.name }}
<a-form-model-item </a-select-option>
v-if="step1FormModel.chargeModel == 'PAY'" </a-select>
label="有效时间" </a-form-model-item>
prop="validPeriod"
> <a-form-item :wrapper-col="{ span: 24 }">
<a-input <div class="btn-div">
suffix="小时" <a-button type="primary" @click="onSave" :disabled="isReadOnly">
v-model="step1FormModel.validPeriod" 保存
/> </a-button>
</a-form-model-item> <a-button class="cancel-btn" @click="onCancel">返回</a-button>
<a-form-model-item </div>
v-if="step1FormModel.chargeModel == 'PAY'" </a-form-item>
label="会员价格" </a-form-model>
prop="vipPrice"
>
<a-input
prefix="¥"
v-model="step1FormModel.vipPrice"
/>
</a-form-model-item>
<a-form-model-item label="所属讲师">
<a-select
placeholder="选择讲师"
v-model="step1FormModel.teacherId"
@change="handleTeacherChange"
:disabled="isReadOnly"
>
<a-select-opt-group
v-for="(org) in this.teachers"
:key="org.id"
:label="org.name"
>
<a-select-option
v-for="(t) in org.teachers"
:key="t.id"
:value="t.id"
>
{{ t.name }}
</a-select-option>
</a-select-opt-group>
</a-select>
</a-form-model-item>
<a-form-model-item label="课程标签">
<a-select
mode="multiple"
label-in-value
placeholder="选择课程标签"
v-model="selectedTags"
@change="handleTagChange"
:disabled="isReadOnly"
>
<a-select-option
v-for="(t) in this.tags"
:key="t.tagId"
:value="t.tagId"
>
{{ t.tagName }}
</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item
label="可见范围"
prop="allow"
>
<a-radio-group
name="allow"
default-value="ALL"
v-model="step1FormModel.allow"
:disabled="isReadOnly"
>
<a-radio value="ALL">
全部
</a-radio>
<a-radio value="SPECIFY">
指定企业
</a-radio>
</a-radio-group>
</a-form-model-item>
<a-form-model-item
v-if="step1FormModel.allow === 'SPECIFY'"
label="指定企业"
>
<a-select
mode="multiple"
placeholder="选择企业"
v-model="step1FormModel.allowOrgIds"
@change="handleEnterpriseChange"
>
<a-select-option
v-for="(t) in this.enterprise"
:key="t.id"
:value="t.id"
>
{{ t.name }}
</a-select-option>
</a-select>
</a-form-model-item>
<a-form-item :wrapper-col="{ span: 24 }">
<div class="btn-div">
<a-button
type="primary"
@click="onSave"
:disabled="isReadOnly"
>
保存
</a-button>
<a-button
class="cancel-btn"
@click="onCancel"
>返回</a-button>
</div>
</a-form-item>
</a-form-model>
</div> </div>
<template> <template>
<a-modal <a-modal :visible="videoUploadModalVisible" title="视频上传" @ok="videoUpload" @cancel="closeVideoUploadModal" :destroyOnClose="true" centered>
:visible="videoUploadModalVisible" <a-form>
title="视频上传" <a-form-item>
@ok="videoUpload" <a-input v-model="video.title" placeholder="视频标题" allowClear></a-input>
@cancel="closeVideoUploadModal" </a-form-item>
:destroyOnClose="true" <a-form-item>
centered <a-upload ref="videoUploaderRef" name="file" :multiple="false" :show-upload-list="true" :customRequest="uploadVideo" :before-upload="beforeVideoUpload">
> <a-button>
<a-form> <a-icon type="upload" />选择视频文件</a-button>
<a-form-item> </a-upload>
<a-input </a-form-item>
v-model="video.title" </a-form>
placeholder="视频标题" </a-modal>
allowClear
></a-input>
</a-form-item>
<a-form-item>
<a-upload
ref="videoUploaderRef"
name="file"
:multiple="false"
:show-upload-list="true"
:customRequest="uploadVideo"
:before-upload="beforeVideoUpload"
>
<a-button>
<a-icon type="upload" />选择视频文件</a-button>
</a-upload>
</a-form-item>
</a-form>
</a-modal>
</template> </template>
<template> <template>
<a-modal <a-modal :visible="attachmentUploadModalVisible" title="附件上传" @ok="saveAttachments" @cancel="closeAttachmentUploadModal" :destroyOnClose="true" centered>
:visible="attachmentUploadModalVisible" <a-form>
title="附件上传" <a-form-item>
@ok="saveAttachments" <a-input v-model="attachment.title" placeholder="附件标题" allowClear></a-input>
@cancel="closeAttachmentUploadModal" </a-form-item>
:destroyOnClose="true" <a-form-item>
centered <a-upload ref="attachmentUploaderRef" name="file" :multiple="false" :show-upload-list="true" :customRequest="uploadAttachment" :before-upload="beforeAttachmentUpload">
> <a-button>
<a-form> <a-icon type="upload" />选择附件文件</a-button>
<a-form-item> </a-upload>
<a-input </a-form-item>
v-model="attachment.title" </a-form>
placeholder="附件标题" </a-modal>
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> <template>
<a-modal <a-modal :visible="showVideoEditor" title="修改视频名称" @ok="updateVideoTitle" @cancel="closeVideoEditor" :destroyOnClose="true">
:visible="showVideoEditor" <a-form>
title="修改视频名称" <a-form-item>
@ok="updateVideoTitle" <a-input v-model="video2update.name" placeholder="输入视频标题" allowClear></a-input>
@cancel="closeVideoEditor" </a-form-item>
:destroyOnClose="true" </a-form>
> </a-modal>
<a-form>
<a-form-item>
<a-input
v-model="video2update.name"
placeholder="输入视频标题"
allowClear
></a-input>
</a-form-item>
</a-form>
</a-modal>
</template> </template>
</div> </div>
</template> </template>
<script> <script>
import { uploadFile } from "@/api/biz/resource";
import { disposereq } from "@/utils/util";
import { fetchList as teacherFetchList } from "@/api/biz/teacher";
import { import {
saveStep1, uploadFile
saveStep2, } from "@/api/biz/resource";
getDetail, import {
fetchAliyunAuth, disposereq
fetchAliyunPolicy, } from "@/utils/util";
refreshAliyunPolicy, import {
fetchVideoInfo, fetchList as teacherFetchList
saveCourse, } from "@/api/biz/teacher";
fetchSeriesList, import {
saveSeriesInfo, saveStep1,
deleteChaper, saveStep2,
updateChaperTitle, getDetail,
fetchAliyunAuth,
fetchAliyunPolicy,
refreshAliyunPolicy,
fetchVideoInfo,
saveCourse,
fetchSeriesList,
saveSeriesInfo,
deleteChaper,
updateChaperTitle,
} from "@/api/biz/course"; } from "@/api/biz/course";
import { fetchList as fetchTagList } from "@/api/biz/courseTag"; import {
import { fetchList as fetchEnterprise } from "@/api/biz/enterprise"; fetchList as fetchTagList
} from "@/api/biz/courseTag";
import {
fetchList as fetchEnterprise
} from "@/api/biz/enterprise";
export default { export default {
// 创建完毕 // 创建完毕
created() { created() {
//路由传过来的课程ID,新建是为空 //路由传过来的课程ID,新建是为空
let courseId = this.$route.query.id; let courseId = this.$route.query.id;
if (courseId) { if (courseId) {
this.getCourseDetail(courseId); this.getCourseDetail(courseId);
} }
fetchAliyunAuth().then((res) => { fetchAliyunAuth().then((res) => {
if (res.resp_code == 200) { if (res.resp_code == 200) {
this.data = res.datas; this.data = res.datas;
this.aliyunRegion = this.data.region; this.aliyunRegion = this.data.region;
this.aliyunUserId = this.data.userId; this.aliyunUserId = this.data.userId;
} else { } else {
this.$message.info(res.resp_msg); this.$message.info(res.resp_msg);
} }
});
fetchEnterprise({
pageIndex: 1,
pageSize: 1000,
}).then((res) => {
this.enterprise = res.data;
});
fetchTagList({
pageIndex: 1,
pageSize: 1000,
}).then((res) => {
const _tags = [];
res.data.forEach((d) => {
_tags.push({
tagId: d.id,
tagName: d.name,
}); });
});
this.tags = _tags; fetchEnterprise({
}); pageIndex: 1,
pageSize: 1000,
teacherFetchList({ }).then((res) => {
name: "", this.enterprise = res.data;
pageIndex: 1, });
pageSize: 1000,
}).then((res) => { fetchTagList({
if (res.code == 200) { pageIndex: 1,
this.teacherData = res.data; pageSize: 1000,
const _teachers = []; }).then((res) => {
res.data.forEach((d) => { const _tags = [];
const tg = _teachers.find((t) => t.id === d.orgId); res.data.forEach((d) => {
if (!tg) { _tags.push({
_teachers.push({ tagId: d.id,
id: d.orgId, tagName: d.name,
name: d.orgName, });
teachers: [d],
}); });
} else { this.tags = _tags;
tg.teachers.push(d);
}
}); });
this.teachers = _teachers;
}
});
},
// 即将更新渲染
beforeUpdate() {},
data() {
//第一步保存时系列字段验证
let validateSerial = (rule, value, callback) => {
if (
this.step1FormModel.type == "SERIES" &&
this.step1FormModel.seriesId == ""
) {
callback(new Error("请选择系列"));
} else {
callback();
}
};
//第一步保存时课程价格验证
let validatePrice = (rule, value, callback) => {
if (this.step1FormModel.chargeModel == "PAY") {
if (value == "") {
callback(new Error("不能为空"));
return;
}
if (value == "0") {
callback(new Error("不能为0"));
return;
}
let exp = /^(([1-9]\d*)|\d)(\.\d{1,2})?$/;
if (!exp.test(value)) {
callback(new Error("金额格式不正确"));
return;
}
callback();
} else {
callback();
}
};
//第一步保存时有效时间验证
let validateValidPeriod = (rule, value, callback) => {
if (this.step1FormModel.chargeModel == "PAY") {
if (value == "") {
callback(new Error("不能为空"));
return;
}
if (value == "0") {
callback(new Error("不能为0"));
return;
}
let exp = /^[0-9]*$/;
if (!exp.test(value)) {
callback(new Error("只能为空数字"));
return;
}
callback();
} else {
callback();
}
};
//第一步保存时会员价格验证
let validateVipPrice = (rule, value, callback) => {
if (this.step1FormModel.chargeModel == "PAY") {
if (value == "") {
callback(new Error("不能为空"));
return;
}
if (value == "0") {
callback(new Error("不能为0"));
return;
}
let exp = /^(([1-9]\d*)|\d)(\.\d{1,2})?$/;
if (!exp.test(value)) {
callback(new Error("金额格式不正确"));
return;
}
callback();
} else {
callback();
}
};
return {
isReadOnly:this.$route.query.isReadOnly=='true',
attachment: {
title: "",
},
attachments: [],
video2update: {},
enterprise: [],
currentSeries: {},
tags: [],
selectedTags: [],
videoSeries: [],
video: {
id: "",
img: "",
file: "",
fileName: "",
title: "",
},
showVideoEditor: false,
teachers: [],
seriesData: [],
onUploadProgress: undefined,
authProgress: 0,
uploadDisabled: true,
resumeDisabled: true,
pauseDisabled: true,
uploader: null,
statusText: "",
aliyunRegion: "",
aliyunUserId: "",
//第一步保存时验证规则定义
step1FormRules: {
name: [
{
required: true,
message: "不能为空",
trigger: "blur",
},
],
seriesId: [
{
validator: validateSerial,
trigger: "change",
},
],
price: [
{
validator: validatePrice,
trigger: "change",
},
],
validPeriod: [
{
validator: validateValidPeriod,
trigger: "change",
},
],
vipPrice: [
{
validator: validateVipPrice,
trigger: "change",
},
],
},
//第一步表单数据对象
step1FormModel: {
id: "",
name: "",
type: "SINGLE",
introduce: "",
detail: "",
logoUrl: "",
teacherId: "",
teacherName: "",
chargeModel: "FREE",
price: "",
vipPrice: "",
validPeriod: "",
seriesId: "",
seriesName: "",
allow: "ALL",
allowOrgIds: [],
tagIds: [],
tagNames: [],
},
//上传封面时的进度条
loading: false,
//选择系列弹出窗口的显示控制
seriesModalVisible: false,
//视频上传窗口
videoUploadModalVisible: false,
//附件上传窗口
attachmentUploadModalVisible: false,
teacherSearchPage: {
name: "",
pageIndex: 1,
pageSize: 10,
},
detailPicList:[],
};
},
methods: {
editVideo(video) {
this.video2update = video;
this.showVideoEditor = true;
},
updateVideoTitle() {
const data = {
chaperId: this.video2update.id,
chaperName: this.video2update.name,
};
updateChaperTitle(data).then((resp) => {
if (resp.resp_code === 200) {
this.$message.success("视频名称修改成功");
} else {
this.$message.error(`视频名称修改失败:${resp.resp_msg}`);
}
});
this.showVideoEditor = false; teacherFetchList({
name: "",
pageIndex: 1,
pageSize: 1000,
}).then((res) => {
if (res.code == 200) {
this.teacherData = res.data;
const _teachers = [];
res.data.forEach((d) => {
const tg = _teachers.find((t) => t.id === d.orgId);
if (!tg) {
_teachers.push({
id: d.orgId,
name: d.orgName,
teachers: [d],
});
} else {
tg.teachers.push(d);
}
});
this.teachers = _teachers;
}
});
}, },
closeVideoEditor() { // 即将更新渲染
this.showVideoEditor = false; beforeUpdate() {},
data() {
//第一步保存时系列字段验证
let validateSerial = (rule, value, callback) => {
if (
this.step1FormModel.type == "SERIES" &&
this.step1FormModel.seriesId == ""
) {
callback(new Error("请选择系列"));
} else {
callback();
}
};
//第一步保存时课程价格验证
let validatePrice = (rule, value, callback) => {
if (this.step1FormModel.chargeModel == "PAY") {
if (value == "") {
callback(new Error("不能为空"));
return;
}
if (value == "0") {
callback(new Error("不能为0"));
return;
}
let exp = /^(([1-9]\d*)|\d)(\.\d{1,2})?$/;
if (!exp.test(value)) {
callback(new Error("金额格式不正确"));
return;
}
callback();
} else {
callback();
}
};
//第一步保存时有效时间验证
let validateValidPeriod = (rule, value, callback) => {
if (this.step1FormModel.chargeModel == "PAY") {
if (value == "") {
callback(new Error("不能为空"));
return;
}
if (value == "0") {
callback(new Error("不能为0"));
return;
}
let exp = /^[0-9]*$/;
if (!exp.test(value)) {
callback(new Error("只能为空数字"));
return;
}
callback();
} else {
callback();
}
};
//第一步保存时会员价格验证
let validateVipPrice = (rule, value, callback) => {
if (this.step1FormModel.chargeModel == "PAY") {
if (value == "") {
callback(new Error("不能为空"));
return;
}
if (value == "0") {
callback(new Error("不能为0"));
return;
}
let exp = /^(([1-9]\d*)|\d)(\.\d{1,2})?$/;
if (!exp.test(value)) {
callback(new Error("金额格式不正确"));
return;
}
callback();
} else {
callback();
}
};
return {
isReadOnly: this.$route.query.isReadOnly == 'true',
attachment: {
title: "",
},
attachments: [],
video2update: {},
enterprise: [],
currentSeries: {},
tags: [],
selectedTags: [],
videoSeries: [],
video: {
id: "",
img: "",
file: "",
fileName: "",
title: "",
},
showVideoEditor: false,
teachers: [],
seriesData: [],
onUploadProgress: undefined,
authProgress: 0,
uploadDisabled: true,
resumeDisabled: true,
pauseDisabled: true,
uploader: null,
statusText: "",
aliyunRegion: "",
aliyunUserId: "",
//第一步保存时验证规则定义
step1FormRules: {
name: [{
required: true,
message: "不能为空",
trigger: "blur",
}, ],
seriesId: [{
validator: validateSerial,
trigger: "change",
}, ],
price: [{
validator: validatePrice,
trigger: "change",
}, ],
validPeriod: [{
validator: validateValidPeriod,
trigger: "change",
}, ],
vipPrice: [{
validator: validateVipPrice,
trigger: "change",
}, ],
},
//第一步表单数据对象
step1FormModel: {
id: "",
name: "",
type: "SINGLE",
introduce: "",
detail: "",
logoUrl: "",
teacherId: "",
teacherName: "",
chargeModel: "FREE",
price: "",
vipPrice: "",
validPeriod: "",
seriesId: "",
seriesName: "",
allow: "ALL",
allowOrgIds: [],
tagIds: [],
tagNames: [],
},
//上传封面时的进度条
loading: false,
//选择系列弹出窗口的显示控制
seriesModalVisible: false,
//视频上传窗口
videoUploadModalVisible: false,
//附件上传窗口
attachmentUploadModalVisible: false,
teacherSearchPage: {
name: "",
pageIndex: 1,
pageSize: 10,
},
detailPicList: [],
};
}, },
deleteVideo(video) { methods: {
let self = this; editVideo(video) {
this.$confirm({ this.video2update = video;
title: `确认要删除${video.name ? video.name : ""}吗?`, this.showVideoEditor = true;
content: "删除操作同时会删除已经上传的视频文件", },
onOk() { updateVideoTitle() {
if(video.id!=undefined){ const data = {
deleteChaper(video.id).then((resp) => { chaperId: this.video2update.id,
if (resp.resp_code === 200) { chaperName: this.video2update.name,
self.videoSeries.forEach((item, index) => { };
console.log(item, video); updateChaperTitle(data).then((resp) => {
if (item.id === video.id) { if (resp.resp_code === 200) {
self.videoSeries.splice(index, 1); this.$message.success("视频名称修改成功");
} } else {
this.$message.error(`视频名称修改失败:${resp.resp_msg}`);
}
});
this.showVideoEditor = false;
},
closeVideoEditor() {
this.showVideoEditor = false;
},
deleteVideo(video) {
let self = this;
this.$confirm({
title: `确认要删除${video.name ? video.name : ""}吗?`,
content: "删除操作同时会删除已经上传的视频文件",
onOk() {
if (video.id != undefined) {
deleteChaper(video.id).then((resp) => {
if (resp.resp_code === 200) {
self.videoSeries.forEach((item, index) => {
console.log(item, video);
if (item.id === video.id) {
self.videoSeries.splice(index, 1);
}
});
}
});
} else if (video.videoId != undefined) {
self.videoSeries.forEach((item, index) => {
console.log(item, video);
if (item.videoId === video.videoId) {
self.videoSeries.splice(index, 1);
}
});
}
},
onCancel() {},
});
},
formatDuraton(t) {
let time = Math.round(t);
if (time > -1) {
var hour = Math.floor(time / 3600);
var min = Math.floor(time / 60) % 60;
var sec = time % 60;
if (hour > 0) {
if (hour < 10) {
time = "0" + hour + ":";
} else {
time = hour + ":";
}
} else {
time = "";
}
if (min > 0) {
if (min < 10) {
time += "0";
}
time += min + ":";
} else {
time = "";
}
if (sec < 10) {
time += "0";
}
time += sec;
}
return time;
},
handleEnterpriseChange(value) {
this.step1FormModel.allowOrgIds = value;
},
handleSeriesSearch(value) {
this.fetchSeriesData(value, (data) => {
const _items = [];
data.forEach((d) => {
_items.push({
value: d.id,
text: d.name,
});
}); });
} this.seriesData = _items;
}); });
} else if(video.videoId!=undefined){ },
self.videoSeries.forEach((item, index) => { fetchSeriesData(value, callback) {
console.log(item, video); fetchSeriesList({
if (item.videoId === video.videoId) { name: value,
self.videoSeries.splice(index, 1); pageIndex: 1,
pageSize: 500,
}).then((res) => {
if (res.count === 0) {
callback([{
name: value,
id: -1,
}, ]);
} else {
const item = res.data.find((d) => d.name.trim() === value);
if (!item) {
//未找到完全匹配的
res.data.unshift({
name: value,
id: -1,
});
}
callback(res.data);
} }
}); });
}
}, },
onCancel() {}, handleSeriesChange(value) {
}); if (value.key === -1) {
}, //新建
formatDuraton(t) { saveSeriesInfo({
let time = Math.round(t); name: value.label,
if (time > -1) { }).then((res) => {
var hour = Math.floor(time / 3600); if (res.resp_code === 200) {
var min = Math.floor(time / 60) % 60; this.currentSeries = {
var sec = time % 60; key: res.datas,
if (hour > 0) { label: value.label,
if (hour < 10) { };
time = "0" + hour + ":"; }
} else { });
time = hour + ":"; } else {
} this.currentSeries = value;
} else { }
time = ""; },
} handleTagChange(values) {
if (min > 0) { this.selectedTags = values;
if (min < 10) { },
time += "0"; handleTeacherChange(value) {
} this.teachers.forEach((org) => {
time += min + ":"; const teacher = org.teachers.find((t) => t.id === value);
} else { if (teacher) {
time = ""; this.step1FormModel.teacherId = teacher.id;
} this.step1FormModel.teacherName = teacher.name;
if (sec < 10) { }
time += "0";
}
time += sec;
}
return time;
},
handleEnterpriseChange(value) {
this.step1FormModel.allowOrgIds = value;
},
handleSeriesSearch(value) {
this.fetchSeriesData(value, (data) => {
const _items = [];
data.forEach((d) => {
_items.push({
value: d.id,
text: d.name,
});
});
this.seriesData = _items;
});
},
fetchSeriesData(value, callback) {
fetchSeriesList({
name: value,
pageIndex: 1,
pageSize: 500,
}).then((res) => {
if (res.count === 0) {
callback([
{
name: value,
id: -1,
},
]);
} else {
const item = res.data.find((d) => d.name.trim() === value);
if (!item) {
//未找到完全匹配的
res.data.unshift({
name: value,
id: -1,
}); });
} },
callback(res.data); onSave() {
}
});
},
handleSeriesChange(value) {
if (value.key === -1) {
//新建
saveSeriesInfo({
name: value.label,
}).then((res) => {
if (res.resp_code === 200) {
this.currentSeries = {
key: res.datas,
label: value.label,
};
}
});
} else {
this.currentSeries = value;
}
},
handleTagChange(values) {
this.selectedTags = values;
},
handleTeacherChange(value) {
this.teachers.forEach((org) => {
const teacher = org.teachers.find((t) => t.id === value);
if (teacher) {
this.step1FormModel.teacherId = teacher.id;
this.step1FormModel.teacherName = teacher.name;
}
});
},
onSave() {
const {
allow,
allowOrgIds,
chargeModel,
detail,
introduce,
logoUrl,
name,
price,
teacherId,
teacherName,
type,
validPeriod,
vipPrice,
tagIds,
} = this.step1FormModel;
//验证
if(!name){
this.$message.info('请输入课程名称')
return
}
if(!logoUrl){
this.$message.info('请上传封面')
return
}
if(this.videoSeries.length == 0){
this.$message.info('请上传视频')
return
}
if(chargeModel=='PAY'){
if (price == "") {
this.$message.info("非会员价格不能为空");
return;
}
if (price == "0") {
this.$message.info("非会员价格不能为0");
return;
}
let exp = /^(([1-9]\d*)|\d)(\.\d{1,2})?$/;
if (!exp.test(price)) {
this.$message.info("非会员价格金额格式不正确");
return;
}
if (validPeriod == "") {
this.$message.info("有效时间不能为空");
return;
}
if (validPeriod == "0") {
this.$message.info("有效时间不能为0");
return;
}
let exp1 = /^[0-9]*$/;
if (!exp1.test(validPeriod)) {
this.$message.info("有效时间只能为空数字");
return;
}
if (vipPrice == "") { const {
this.$message.info("会员价格不能为空"); allow,
return; allowOrgIds,
} chargeModel,
if (vipPrice == "0") { detail,
this.$message.info("会员价格不能为0"); introduce,
return; logoUrl,
} name,
if (!exp.test(vipPrice)) { price,
this.$message.info("会员价格金额格式不正确"); teacherId,
return; teacherName,
} type,
} validPeriod,
// validateValidPeriod vipPrice,
// validateVipPrice tagIds,
const chaperList = []; } = this.step1FormModel;
this.videoSeries.forEach((chapter, index) => { //验证
chaperList.push(chapter); if (!name) {
}); this.$message.info('请输入课程名称')
return
const course = {
allow,
allowOrgIds,
chargeModel,
detail,
introduce,
logoUrl,
name,
price,
teacherId,
teacherName,
type,
validPeriod,
vipPrice,
chaperList,
tagIds,
attachmenIds: [],
};
if (this.currentSeries) {
course.seriesId = this.currentSeries.key;
course.seriesName = this.currentSeries.label
? this.currentSeries.label.trim()
: this.currentSeries.label;
}
const courseId = this.$route.query.id;
if (courseId) {
course.id = parseInt(courseId, 10);
}
const _tags = [];
this.selectedTags.forEach((t) => {
_tags.push(t.key);
});
course.tagIds = _tags;
this.attachments.forEach((a) => {
course.attachmenIds.push(a.id);
});
//课程介绍上传图片处理
if(this.detailPicList.length > 0){
let urlList = this.detailPicList.map(e => {
return e.url
})
course.detail = urlList.join(',')
}
saveCourse(course).then((res) => {
if (res.resp_code === 200) {
this.$message.success("课程保存成功");
} else {
this.$message.info(res.resp_msg);
}
});
},
//获取课程详情
getCourseDetail(id) {
getDetail(id)
.then((res) => {
if (res.resp_code == 200) {
this.step1FormModel = {
...res.datas,
};
//构建课程介绍图片list
// console.log(res.datas)
if(res.datas.detail){
var picUrlAry = res.datas.detail.split(',')
// console.log(picUrlAry)
var list = []
var index = -1
picUrlAry.forEach(e => {
var obj = {}
obj.uid = index+''
obj.name = obj.uid
obj.status = 'done'
obj.url = e
// console.log(obj)
index--
list.push(obj)
})
this.detailPicList = list
} }
if (this.step1FormModel.allowOrgList) { if (!logoUrl) {
const _enterprise = []; this.$message.info('请上传封面')
this.step1FormModel.allowOrgList.forEach((t) => { return
_enterprise.push(t.orgId);
});
this.step1FormModel.allowOrgIds = _enterprise;
} }
if (this.videoSeries.length == 0) {
this.$message.info('请上传视频')
return
}
if (chargeModel == 'PAY') {
if (price == "") {
this.$message.info("非会员价格不能为空");
return;
}
if (price == "0") {
this.$message.info("非会员价格不能为0");
return;
}
let exp = /^(([1-9]\d*)|\d)(\.\d{1,2})?$/;
if (!exp.test(price)) {
this.$message.info("非会员价格金额格式不正确");
return;
}
if (validPeriod == "") {
this.$message.info("有效时间不能为空");
return;
}
if (validPeriod == "0") {
this.$message.info("有效时间不能为0");
return;
}
let exp1 = /^[0-9]*$/;
if (!exp1.test(validPeriod)) {
this.$message.info("有效时间只能为空数字");
return;
}
if (this.step1FormModel.tagList) { if (vipPrice == "") {
this.step1FormModel.tagList.forEach((t) => { this.$message.info("会员价格不能为空");
this.selectedTags.push({ return;
key: t.tagId, }
label: t.tagName, if (vipPrice == "0") {
}); this.$message.info("会员价格不能为0");
}); return;
}
if (!exp.test(vipPrice)) {
this.$message.info("会员价格金额格式不正确");
return;
}
} }
// validateValidPeriod
// validateVipPrice
const chaperList = [];
this.videoSeries.forEach((chapter, index) => {
chaperList.push(chapter);
});
this.currentSeries = { const course = {
key: this.step1FormModel.seriesId, allow,
label: this.step1FormModel.seriesName, allowOrgIds,
chargeModel,
detail,
introduce,
logoUrl,
name,
price,
teacherId,
teacherName,
type,
validPeriod,
vipPrice,
chaperList,
tagIds,
attachmenIds: [],
}; };
if (this.currentSeries) {
course.seriesId = this.currentSeries.key;
course.seriesName = this.currentSeries.label ?
this.currentSeries.label.trim() :
this.currentSeries.label;
}
// console.log(res.datas); const courseId = this.$route.query.id;
if (courseId) {
course.id = parseInt(courseId, 10);
}
const _attachments = []; const _tags = [];
res.datas.attachmentList.forEach((a) => { this.selectedTags.forEach((t) => {
_attachments.push({ id: a.resourceId, title: a.resourceName }); _tags.push(t.key);
}); });
this.attachments = _attachments; course.tagIds = _tags;
const _videoSeries = []; this.attachments.forEach((a) => {
res.datas.chaperList.forEach((cc) => { course.attachmenIds.push(a.id);
_videoSeries.push({
...cc,
});
}); });
this.videoSeries = _videoSeries; //课程介绍上传图片处理
} else { if (this.detailPicList.length > 0) {
this.$message.info(res.resp_msg);
}
})
.catch((err) => {
disposereq(this, err);
});
},
//上传封面时上传中的回调 let urlList = this.detailPicList.map(e => {
handleChange(info) { return e.url
if (info.file.status === "uploading") { })
this.loading = true; course.detail = urlList.join(',')
return; }
} saveCourse(course).then((res) => {
}, if (res.resp_code === 200) {
//上传封面时上传前的验证 this.$message.success("课程保存成功");
beforeUpload(file) { } else {
const isJpgOrPng = this.$message.info(res.resp_msg);
file.type === "image/jpeg" || file.type === "image/png"; }
if (!isJpgOrPng) { });
this.$message.info("只能上传图片"); },
} //获取课程详情
const isLt2M = file.size / 1024 / 1024 < 10; getCourseDetail(id) {
if (!isLt2M) { getDetail(id)
this.$message.error("Image must smaller than 10MB!"); .then((res) => {
} if (res.resp_code == 200) {
return isJpgOrPng && isLt2M; this.step1FormModel = {
}, ...res.datas,
//返回课程列表 };
onCancel() { //构建课程介绍图片list
this.$router.push("/edu/biz/course/index"); // console.log(res.datas)
}, if (res.datas.detail) {
//上传封面 var picUrlAry = res.datas.detail.split(',')
uploadLogo(data) { // console.log(picUrlAry)
const formData = new FormData(); var list = []
formData.append("file", data.file); var index = -1
uploadFile(formData) picUrlAry.forEach(e => {
.then((res) => { var obj = {}
if (res.data.resp_code == 200) { obj.uid = index + ''
this.step1FormModel.logoUrl = res.data.datas.url; obj.name = obj.uid
} else { obj.status = 'done'
this.$message.info("上传失败"); obj.url = e
} // console.log(obj)
this.loading = false; index--
}) list.push(obj)
.catch((err) => { })
disposereq(this, err);
});
},
beforeVideoUpload(file) {
const { type } = file;
const title = file.name.substring(0, file.name.indexOf("."));
if( this.video.title==undefined || this.video.title==''){
this.video.title = title;
}
if (type.startsWith("video")) {
return true;
} else {
this.$message.error("请选择视频文件");
return false;
}
},
beforeAttachmentUpload(file) { this.detailPicList = list
const { type } = file; }
const title = file.name.substring(0, file.name.indexOf(".")); if (this.step1FormModel.allowOrgList) {
this.attachment.title = title; const _enterprise = [];
}, this.step1FormModel.allowOrgList.forEach((t) => {
_enterprise.push(t.orgId);
});
this.step1FormModel.allowOrgIds = _enterprise;
}
saveAttachments() { if (this.step1FormModel.tagList) {
if (this.attachment) { this.step1FormModel.tagList.forEach((t) => {
const { title, id } = this.attachment; this.selectedTags.push({
if (!title) { key: t.tagId,
this.$message.error("请填写附件标题"); label: t.tagName,
return; });
} });
if (!id) { }
this.$message.error("请上传附件文件");
return;
}
this.attachments.push({ this.currentSeries = {
title: title, key: this.step1FormModel.seriesId,
id: id, label: this.step1FormModel.seriesName,
}); };
this.attachment = {};
this.attachmentUploadModalVisible = false;
}
},
uploadAttachment(data) { // console.log(res.datas);
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 }) { const _attachments = [];
var Title = this.video.title; res.datas.attachmentList.forEach((a) => {
this.video.fileName = file.name; _attachments.push({
this.video.file = file.file; id: a.resourceId,
var userData = '{"Vod":{}}'; title: a.resourceName
if (this.uploader) { });
this.uploader.stopUpload(); });
this.authProgress = 0; this.attachments = _attachments;
this.statusText = "";
} const _videoSeries = [];
this.uploader = this.createUploader(); res.datas.chaperList.forEach((cc) => {
this.uploader.addFile(file, null, null, null, userData); _videoSeries.push({
this.uploadDisabled = false; ...cc,
this.pauseDisabled = true; });
this.resumeDisabled = true; });
this.authUpload(); this.videoSeries = _videoSeries;
}, } else {
authUpload() { this.$message.info(res.resp_msg);
// 然后调用 startUpload 方法, 开始上传 }
if (this.uploader !== null) { })
this.uploader.startUpload(); .catch((err) => {
this.uploadDisabled = true; disposereq(this, err);
this.pauseDisabled = false; });
}
},
createUploader(type) {
let self = this;
let uploader = new AliyunUpload.Vod({
timeout: 60000,
partSize: 1048576,
parallel: 5,
retryCount: 3,
retryDuration: 2,
region: self.aliyunRegion,
userId: self.aliyunUserId,
// 添加文件成功
addFileSuccess: function(uploadInfo) {
self.uploadDisabled = false;
self.resumeDisabled = false;
}, },
// 开始上传
onUploadstarted: function(uploadInfo) { //上传封面时上传中的回调
self.uploadVideoStatus = "uploading"; handleChange(info) {
if (!uploadInfo.videoId) { if (info.file.status === "uploading") {
fetchAliyunPolicy({ this.loading = true;
fileName: self.video.fileName,
title: self.video.title,
}).then((res) => {
if (res.resp_code == 200) {
const data = res.datas;
let uploadAuth = data.uploadAuth;
let uploadAddress = data.uploadAddress;
let videoId = data.videoId;
self.video.id = videoId;
uploader.setUploadAuthAndAddress(
uploadInfo,
uploadAuth,
uploadAddress,
videoId
);
} else {
self.$message.info(res.resp_msg);
return;
}
});
} else {
refreshAliyunPolicy(uploadInfo.videoId).then((res) => {
if (res.resp_code == 200) {
const data = res.datas;
let uploadAuth = data.uploadAuth;
let uploadAddress = data.uploadAddress;
let videoId = data.videoId;
self.video.id = videoId;
uploader.setUploadAuthAndAddress(
uploadInfo,
uploadAuth,
uploadAddress,
videoId
);
} else {
self.$message.info(res.resp_msg);
return; return;
} }
});
}
},
// 文件上传成功
onUploadSucceed: function(uploadInfo) {
self.$message.success("文件上传成功");
self.uploadVideoStatus = "success";
}, },
// 文件上传失败 //上传封面时上传前的验证
onUploadFailed: function(uploadInfo, code, message) { beforeUpload(file) {
self.$message.error("文件上传失败"); 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;
}, },
// 取消文件上传 //返回课程列表
onUploadCanceled: function(uploadInfo, code, message) { onCancel() {
self.$message.error("文件已暂停上传"); this.$router.push("/edu/biz/course/index");
}, },
// 文件上传进度,单位:字节, 可以在这个函数中拿到上传进度并显示在页面上 //上传封面
onUploadProgress: function(uploadInfo, totalSize, progress) { uploadLogo(data) {
let progressPercent = Math.ceil(progress * 100); const formData = new FormData();
self.authProgress = progressPercent; formData.append("file", data.file);
self.$refs.videoUploaderRef.onProgress( uploadFile(formData)
{ .then((res) => {
percent: progressPercent, if (res.data.resp_code == 200) {
}, this.step1FormModel.logoUrl = res.data.datas.url;
uploadInfo.file } else {
); this.$message.info("上传失败");
if (progressPercent === 100) { }
self.$refs.videoUploaderRef.onSuccess(null, uploadInfo.file); this.loading = false;
} })
.catch((err) => {
disposereq(this, err);
});
}, },
// 上传凭证超时 beforeVideoUpload(file) {
onUploadTokenExpired: function(uploadInfo) { const {
refreshAliyunPolicy(uploadInfo.videoId).then((res) => { type
if (res.resp_code == 200) { } = file;
const data = res.datas; const title = file.name.substring(0, file.name.indexOf("."));
let uploadAuth = data.uploadAuth; if (this.video.title == undefined || this.video.title == '') {
uploader.resumeUploadWithAuth(uploadAuth); this.video.title = title;
}
if (type.startsWith("video")) {
return true;
} else { } else {
self.$message.info(res.resp_msg); this.$message.error("请选择视频文件");
return; return false;
} }
});
self.$message.error("文件上传超时");
}, },
// 全部文件上传结束
onUploadEnd: function(uploadInfo) { beforeAttachmentUpload(file) {
// self.$message.success("文件上传完毕"); const {
type
} = file;
const title = file.name.substring(0, file.name.indexOf("."));
this.attachment.title = title;
}, },
});
return uploader;
},
//选择系列弹出窗口确认操作 saveAttachments() {
seriesSelected() { if (this.attachment) {
this.seriesModalClose(); const {
}, title,
//选择系列弹出窗口取消操作 id
seriesModalClose() { } = this.attachment;
this.seriesModalVisible = false; if (!title) {
}, this.$message.error("请填写附件标题");
//显示选择系列弹出窗口 return;
openSeriesModal() { }
this.seriesModalVisible = true; if (!id) {
}, this.$message.error("请上传附件文件");
//系列待选表格分页操作 return;
seriesHandleTableChange() {}, }
//系列待选表格选中操作
seriesSelectChange(selectedRowKeys) {},
//显示讲师待选窗口
showTeacherModal() {
this.teacherHandlSearch();
this.teacherModalVisible = true;
},
showVideoUploadModal() {
this.videoUploadModalVisible = true;
},
closeVideoUploadModal() {
this.videoUploadModalVisible = false;
this.video = {};
},
showAttachmentUploadModal() { this.attachments.push({
this.attachmentUploadModalVisible = true; title: title,
}, id: id,
closeAttachmentUploadModal() { });
this.attachmentUploadModalVisible = false; this.attachment = {};
this.attachment = {}; this.attachmentUploadModalVisible = false;
}, }
},
videoUpload() { uploadAttachment(data) {
if (this.video) { let self = this;
const { title, id } = this.video; const formData = new FormData();
if (!title) { formData.append("file", data.file);
this.$message.error("请填写视频标题"); uploadFile(formData)
return; .then((res) => {
} if (res.data.resp_code == 200) {
if (!id) { self.$refs.attachmentUploaderRef.onProgress({
this.$message.error("请上传视频文件"); percent: 100,
return; },
} data.file
fetchVideoInfo(id).then((res) => { );
if (res.resp_code == 200) { self.attachment.id = res.data.datas.id;
const { coverURL, duration } = res.datas; self.$refs.attachmentUploaderRef.onSuccess(null, data.file);
this.videoSeries.push({ } else {
name: title, this.$message.info("上传失败");
videoId: id, }
coverUrl: coverURL, this.loading = false;
duration, })
.catch((err) => {
disposereq(this, err);
});
},
uploadVideo({
file
}) {
this.video.fileName = file.name;
this.video.file = file.file;
var userData = '{"Vod":{}}';
if (this.uploader) {
this.uploader.stopUpload();
this.authProgress = 0;
this.statusText = "";
}
this.uploader = this.createUploader();
this.uploader.addFile(file, null, null, null, userData);
this.uploadDisabled = false;
this.pauseDisabled = true;
this.resumeDisabled = true;
this.authUpload();
},
authUpload() {
// 然后调用 startUpload 方法, 开始上传
if (this.uploader !== null) {
this.uploader.startUpload();
this.uploadDisabled = true;
this.pauseDisabled = false;
}
},
createUploader(type) {
let self = this;
let uploader = new AliyunUpload.Vod({
timeout: 60000,
partSize: 1048576,
parallel: 5,
retryCount: 3,
retryDuration: 2,
region: self.aliyunRegion,
userId: self.aliyunUserId,
// 添加文件成功
addFileSuccess: function (uploadInfo) {
self.uploadDisabled = false;
self.resumeDisabled = false;
},
// 开始上传
onUploadstarted: function (uploadInfo) {
self.uploadVideoStatus = "uploading";
if (!uploadInfo.videoId) {
fetchAliyunPolicy({
fileName: self.video.fileName,
title: self.video.title,
}).then((res) => {
if (res.resp_code == 200) {
const data = res.datas;
let uploadAuth = data.uploadAuth;
let uploadAddress = data.uploadAddress;
let videoId = data.videoId;
self.video.id = videoId;
uploader.setUploadAuthAndAddress(
uploadInfo,
uploadAuth,
uploadAddress,
videoId
);
} else {
self.$message.info(res.resp_msg);
return;
}
});
} else {
refreshAliyunPolicy(uploadInfo.videoId).then((res) => {
if (res.resp_code == 200) {
const data = res.datas;
let uploadAuth = data.uploadAuth;
let uploadAddress = data.uploadAddress;
let videoId = data.videoId;
self.video.id = videoId;
uploader.setUploadAuthAndAddress(
uploadInfo,
uploadAuth,
uploadAddress,
videoId
);
} else {
self.$message.info(res.resp_msg);
return;
}
});
}
},
// 文件上传成功
onUploadSucceed: function (uploadInfo) {
self.$message.success("文件上传成功");
self.uploadVideoStatus = "success";
},
// 文件上传失败
onUploadFailed: function (uploadInfo, code, message) {
self.$message.error("文件上传失败");
},
// 取消文件上传
onUploadCanceled: function (uploadInfo, code, message) {
self.$message.error("文件已暂停上传");
},
// 文件上传进度,单位:字节, 可以在这个函数中拿到上传进度并显示在页面上
onUploadProgress: function (uploadInfo, totalSize, progress) {
let progressPercent = Math.ceil(progress * 100);
self.authProgress = progressPercent;
self.$refs.videoUploaderRef.onProgress({
percent: progressPercent,
},
uploadInfo.file
);
if (progressPercent === 100) {
self.$refs.videoUploaderRef.onSuccess(null, uploadInfo.file);
}
},
// 上传凭证超时
onUploadTokenExpired: function (uploadInfo) {
refreshAliyunPolicy(uploadInfo.videoId).then((res) => {
if (res.resp_code == 200) {
const data = res.datas;
let uploadAuth = data.uploadAuth;
uploader.resumeUploadWithAuth(uploadAuth);
} else {
self.$message.info(res.resp_msg);
return;
}
});
self.$message.error("文件上传超时");
},
// 全部文件上传结束
onUploadEnd: function (uploadInfo) {
// self.$message.success("文件上传完毕");
},
}); });
this.video = {}; return uploader;
},
//选择系列弹出窗口确认操作
seriesSelected() {
this.seriesModalClose();
},
//选择系列弹出窗口取消操作
seriesModalClose() {
this.seriesModalVisible = false;
},
//显示选择系列弹出窗口
openSeriesModal() {
this.seriesModalVisible = true;
},
//系列待选表格分页操作
seriesHandleTableChange() {},
//系列待选表格选中操作
seriesSelectChange(selectedRowKeys) {},
//显示讲师待选窗口
showTeacherModal() {
this.teacherHandlSearch();
this.teacherModalVisible = true;
},
showVideoUploadModal() {
this.videoUploadModalVisible = true;
},
closeVideoUploadModal() {
this.videoUploadModalVisible = false; this.videoUploadModalVisible = false;
} this.video = {};
}); },
}
}, showAttachmentUploadModal() {
//查询讲师 this.attachmentUploadModalVisible = true;
getTeacherList(query) { },
this.teacherLoading = true; closeAttachmentUploadModal() {
teacherFetchList(query) this.attachmentUploadModalVisible = false;
.then((res) => { this.attachment = {};
if (res.code == 200) { },
this.teacherData = res.data;
var paper = { videoUpload() {
...this.teacherPagination, if (this.video) {
}; const {
paper.current = query.pageIndex; title,
paper.total = res.count; id
this.teacherPagination = paper; } = this.video;
} else { if (!title) {
this.$message.info(res.resp_msg); this.$message.error("请填写视频标题");
} return;
this.teacherLoading = false; }
}) if (!id) {
.catch((err) => { this.$message.error("请上传视频文件");
this.teacherLoading = false; return;
disposereq(this, err); }
}); fetchVideoInfo(id).then((res) => {
}, if (res.resp_code == 200) {
//显示添加章节窗口 console.log(this.step1FormModel.type)
showVideoModal() { const {
this.videoModalVisible = true; coverURL,
}, duration
//上传课程简介图片 } = res.datas;
uploadDetailPic(data){ if (this.step1FormModel.type === 'SINGLE') {
const formData = new FormData(); this.videoSeries = [{
let uid = data.file.uid name: title,
formData.append("file", data.file); videoId: id,
uploadFile(formData) coverUrl: coverURL,
.then(res => { duration,
if(res.data.resp_code == 200){ }];
this.detailPicList = this.detailPicList.map(e => { } else {
if(e.uid == uid){ this.videoSeries.push({
e.status = 'done' name: title,
e.url = res.data.datas.url videoId: id,
} coverUrl: coverURL,
return e duration,
}) });
}else{ }
this.video = {};
this.videoUploadModalVisible = false;
}
});
}
},
//查询讲师
getTeacherList(query) {
this.teacherLoading = true;
teacherFetchList(query)
.then((res) => {
if (res.code == 200) {
this.teacherData = res.data;
var paper = {
...this.teacherPagination,
};
paper.current = query.pageIndex;
paper.total = res.count;
this.teacherPagination = paper;
} else {
this.$message.info(res.resp_msg);
}
this.teacherLoading = false;
})
.catch((err) => {
this.teacherLoading = false;
disposereq(this, err);
});
},
//显示添加章节窗口
showVideoModal() {
this.videoModalVisible = true;
},
//上传课程简介图片
uploadDetailPic(data) {
const formData = new FormData();
let uid = data.file.uid
formData.append("file", data.file);
uploadFile(formData)
.then(res => {
if (res.data.resp_code == 200) {
this.detailPicList = this.detailPicList.map(e => {
if (e.uid == uid) {
e.status = 'done'
e.url = res.data.datas.url
}
return e
})
} else {
this.detailPicList.forEach(e => {
if (e.uid == uid) {
e.status = 'error'
}
})
}
}).catch(err => {
disposereq(this, err)
})
},
beforUploadDetailPic(file) {
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error('图片大小须小于2MB!');
}
return isLt2M;
},
uploadDetailPicChange(info) {
if (info.file.status == 'uploading') {
this.detailPicList.push(info.file)
}
},
uploadDetailRemove(file) {
let newList = []
this.detailPicList.forEach(e => { this.detailPicList.forEach(e => {
if(e.uid == uid){ if (e.uid != file.uid) {
e.status = 'error' newList.push(e)
} }
}) })
} this.detailPicList = newList
}).catch(err => { return true;
disposereq(this,err)
})
},
beforUploadDetailPic(file){
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error('图片大小须小于2MB!');
}
return isLt2M;
},
uploadDetailPicChange(info){
if(info.file.status == 'uploading'){
this.detailPicList.push(info.file)
}
},
uploadDetailRemove(file){
let newList = []
this.detailPicList.forEach(e => {
if(e.uid != file.uid){
newList.push(e)
} }
}) },
this.detailPicList = newList
return true;
}
},
}; };
</script> </script>
<style> <style>
.attachment-icon { .attachment-icon {
margin-right: 5px; 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%;
font-weight: bold; font-weight: bold;
font-size: 14px; font-size: 14px;
word-break: break-all; word-break: break-all;
text-overflow: ellipsis; text-overflow: ellipsis;
display: -webkit-box; display: -webkit-box;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
-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;
background-size: contain; background-size: contain;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.video-image { .video-image {
width: 120px; width: 120px;
height: 68px; height: 68px;
background: #d5d5d5 url("../../../assets/img/course/video-bg.png") no-repeat background: #d5d5d5 url("../../../assets/img/course/video-bg.png") no-repeat 50%;
50%; display: inline-block;
display: inline-block; position: relative;
position: relative; 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;
color: #fff; color: #fff;
width: 100%; width: 100%;
right: 0; right: 0;
bottom: 0; bottom: 0;
z-index: 2; z-index: 2;
height: 24px; height: 24px;
line-height: 24px; line-height: 24px;
padding: 0 3px; padding: 0 3px;
background-image: linear-gradient(-180deg, transparent, rgba(0, 0, 0, 0.8)); background-image: linear-gradient(-180deg, transparent, rgba(0, 0, 0, 0.8));
} }
.video-image-toolbar { .video-image-toolbar {
position: absolute; position: absolute;
text-align: right; text-align: right;
color: #fff; color: #fff;
width: 100%; width: 100%;
right: 0; right: 0;
top: 0; top: 0;
z-index: 2; z-index: 2;
height: 24px; height: 24px;
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;
left: 52px; left: 52px;
z-index: 3; z-index: 3;
color: #fff; color: #fff;
opacity: 0.4; opacity: 0.4;
} }
.video-image-cover { .video-image-cover {
position: absolute; position: absolute;
width: 100%; width: 100%;
height: 100%; height: 100%;
top: 0; top: 0;
left: 0; left: 0;
z-index: 1; z-index: 1;
} }
</style> </style>
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