Initial commit
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,503 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="添加子媒体任务"
|
||||
:visible.sync="isShow"
|
||||
width="80%"
|
||||
center
|
||||
@close="$emit('close')"
|
||||
:show-close="false"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<div class="add-video-warp-box">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
|
||||
<div class="flex-item">
|
||||
<el-form-item label="父媒体ID:" prop="mediaId">
|
||||
<el-input v-model="form.mediaId" size="small"></el-input>
|
||||
<el-button type="primary" size="small" @click="findFatherInfo()"
|
||||
>查询父级媒体</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item label="父媒体标题:" prop="mediaTitle">
|
||||
<el-input
|
||||
:disabled="true"
|
||||
v-model="mediaTitle"
|
||||
size="small"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="flex-item">
|
||||
<el-form-item label="上传类型:" prop="mediaType">
|
||||
<el-select
|
||||
:disabled="true"
|
||||
v-model="form.mediaType"
|
||||
size="small"
|
||||
placeholder="请选择上传类型"
|
||||
clearable
|
||||
>
|
||||
<el-option value="video" label="视频"></el-option>
|
||||
<el-option value="video_adv" label="视频广告"></el-option>
|
||||
<el-option value="image" label="漫画"></el-option>
|
||||
<el-option value="text" label="小说"></el-option>
|
||||
<el-option value="drama" label="短剧"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="封面上传:" prop="cover" style="display: flex;">
|
||||
<base-upload
|
||||
:cover="form.cover"
|
||||
:action="action"
|
||||
@successCallback="successCallback"
|
||||
:id="form.sourceID"
|
||||
:hide="true"
|
||||
:width="'90px'"
|
||||
:height="'120px'"
|
||||
></base-upload>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="flex-item">
|
||||
<el-form-item label="集数:" prop="episodeNumber">
|
||||
<el-input
|
||||
:disabled="isPermission"
|
||||
v-model.number="form.episodeNumber"
|
||||
size="small"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="章节名:" prop="name">
|
||||
<el-input
|
||||
:disabled="isPermission"
|
||||
v-model="form.name"
|
||||
size="small"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="flex-item">
|
||||
<el-form-item label="是否激活:" prop="isActive">
|
||||
<el-select
|
||||
:disabled="isPermission"
|
||||
v-model="form.isActive"
|
||||
size="small"
|
||||
placeholder="请选择是否激活"
|
||||
>
|
||||
<el-option :value="true" label="是"></el-option>
|
||||
<el-option :value="false" label="否"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="收费类型:" prop="listenPermission">
|
||||
<el-select
|
||||
:disabled="isPermission"
|
||||
v-model="form.listenPermission"
|
||||
size="small"
|
||||
placeholder="请选择收费类型"
|
||||
>
|
||||
<el-option
|
||||
v-if="form.mediaType !== 'drama'"
|
||||
:value="0"
|
||||
label="会员"
|
||||
></el-option>
|
||||
<el-option :value="1" label="金币"></el-option>
|
||||
<el-option :value="2" label="免费"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:disabled="isPermission"
|
||||
label="购买价格:"
|
||||
prop="price"
|
||||
v-if="form.listenPermission == 1"
|
||||
>
|
||||
<el-input v-model.number="form.price" size="small"></el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="flex-item">
|
||||
<el-form-item
|
||||
label="上传视频:"
|
||||
v-if="
|
||||
form.mediaType === 'video' ||
|
||||
form.mediaType === 'video_adv' ||
|
||||
form.mediaType === 'drama'
|
||||
"
|
||||
>
|
||||
<input
|
||||
:disabled="isPermission"
|
||||
type="file"
|
||||
@change="changeFile"
|
||||
accept="video/*"
|
||||
id="inputFile"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
style="width: 1100px"
|
||||
label="上传图集:"
|
||||
prop="cover"
|
||||
v-if="form.mediaType === 'image'"
|
||||
>
|
||||
<!--上传图集-->
|
||||
<imgs-upload
|
||||
:cover="form.cover"
|
||||
:action="actionPics"
|
||||
@successCallback="successCallbackPic"
|
||||
:id="form.sourceID"
|
||||
:wSize="180"
|
||||
:hSize="320"
|
||||
:width="'100px'"
|
||||
:height="'100px'"
|
||||
></imgs-upload>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
style="width: 1100px"
|
||||
label="小说内容:"
|
||||
prop="text"
|
||||
v-if="form.mediaType === 'text'"
|
||||
>
|
||||
<!--小说-->
|
||||
<el-input
|
||||
:disabled="isPermission"
|
||||
type="textarea"
|
||||
:rows="10"
|
||||
placeholder="请输入小说内容"
|
||||
v-model="form.text"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="flex-item" v-if="form.mediaType === 'text'">
|
||||
<!--小说音频上传-->
|
||||
<el-upload
|
||||
accept="audio/mp3"
|
||||
class="upload-demo"
|
||||
:action="actionAudio"
|
||||
:headers="header"
|
||||
:on-success="handleTrialChange"
|
||||
:file-list="fileList"
|
||||
:limit="1"
|
||||
>
|
||||
<el-button size="small" type="success" class="uploadMp3"
|
||||
>点击上传</el-button
|
||||
>
|
||||
</el-upload>
|
||||
</div>
|
||||
<el-form-item class="bottomBtn">
|
||||
<el-button
|
||||
:disabled="isPermission"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="submitDate"
|
||||
>立即添加</el-button
|
||||
>
|
||||
<el-button size="small" @click="cancel">取消</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { validatorIndex } from "@/utils/validator";
|
||||
import baseConfig from "@/utils/serverUrlConfig";
|
||||
import local from "@/utils/localStroage";
|
||||
import API from "@/api";
|
||||
export default {
|
||||
props: ["isShow"],
|
||||
data() {
|
||||
return {
|
||||
isPermission: true,
|
||||
SeriesCover: [],
|
||||
trackId: "",
|
||||
show: false,
|
||||
// 封面上传地址
|
||||
action: baseConfig.baseServerUrl + "/vid/uploadStatic",
|
||||
//图集上传
|
||||
actionPics: baseConfig.baseServerUrl + "/vid/uploadStaticBatch",
|
||||
// 视频播放地址
|
||||
videoBaseUrl: baseConfig.playVideoUrl,
|
||||
// 音频上传地址
|
||||
actionAudio: baseConfig.baseServerUrl + "/vid/upload/audio",
|
||||
header: {
|
||||
Authorization: local.get("userInfo").token,
|
||||
},
|
||||
isFree: true,
|
||||
flag: false,
|
||||
player: "",
|
||||
files: null,
|
||||
// 表单数据
|
||||
mediaTitle: "", //父级媒体标题
|
||||
form: {
|
||||
mediaId: "", //父级媒体id
|
||||
mediaType: "video", //上传文件类型
|
||||
episodeNumber: "", // 第几集
|
||||
listenPermission: 0, // 收听权限 0:会员 1:金币购买 2:免费
|
||||
price: 0, // 价格
|
||||
cover: "", // 封面图
|
||||
name: "", // 章节名
|
||||
text: "", // 小说专用
|
||||
audioUrl: "", // 小说专用
|
||||
md5: "", // 媒体md5
|
||||
sourceID: "", // 视频唯一id,对应文件服
|
||||
videoUrl: "",
|
||||
filename: "",
|
||||
isActive: false, //是否激活
|
||||
urlSet: [], // 图集
|
||||
},
|
||||
rules: {
|
||||
title: [{ required: true, message: "请输入标题", trigger: "blur" }],
|
||||
mediaType: [
|
||||
{ required: true, message: "请选择上传类型", trigger: "blur" },
|
||||
],
|
||||
mediaId: [
|
||||
{ required: true, message: "请输入父级媒体ID", trigger: "blur" },
|
||||
],
|
||||
name: [{ required: true, message: "请输入章节名", trigger: "blur" }],
|
||||
price: [{ required: true, message: "请输入购买价格", trigger: "blur" }],
|
||||
text: [{ required: true, message: "请输入小说内容", trigger: "blur" }],
|
||||
episodeNumber: [
|
||||
{ required: true, message: "请输入集数", trigger: "blur" },
|
||||
{ validator: validatorIndex, trigger: "blur" },
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
// console.log('创建')
|
||||
},
|
||||
methods: {
|
||||
changeFile(event) {
|
||||
let files = event.target.files[0];
|
||||
this.files = files;
|
||||
},
|
||||
cancel() {
|
||||
this.cleanForm();
|
||||
this.$emit("close");
|
||||
},
|
||||
findFatherInfo() {
|
||||
if (this.form.mediaId === undefined || this.form.mediaId === "") {
|
||||
this.$message.error("请输入父级媒体id");
|
||||
return false;
|
||||
}
|
||||
API.getMediaInfo({ id: this.form.mediaId })
|
||||
.then((res) => {
|
||||
if (res.code === 200 && res.data) {
|
||||
console.log(res.data);
|
||||
if (res.data.isExist === true) {
|
||||
this.isPermission = false;
|
||||
this.form.mediaType = res.data.mediaType;
|
||||
this.mediaTitle = res.data.mediaTitle;
|
||||
if (res.data.mediaType === "drama") {
|
||||
this.form.listenPermission = 2;
|
||||
this.form.price = 0;
|
||||
}
|
||||
} else {
|
||||
this.$message.error("父级媒体不存在");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.isPermission = true;
|
||||
});
|
||||
},
|
||||
// 处理音频
|
||||
handleTrialChange(res) {
|
||||
if (res.data.code === 200) {
|
||||
this.form.audioUrl = res.data.data.fileName;
|
||||
} else {
|
||||
this.fileList = [];
|
||||
}
|
||||
},
|
||||
// 提交验证
|
||||
submitDate() {
|
||||
if (
|
||||
(this.form.mediaType === "video" || this.form.mediaType === "drama") &&
|
||||
!this.files
|
||||
) {
|
||||
this.$message.error("请选择视频");
|
||||
return false;
|
||||
}
|
||||
if (this.form.mediaType === "image" && this.form.urlSet.length <= 0) {
|
||||
this.$message.error("请选择漫画图集");
|
||||
return false;
|
||||
}
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
if (this.form.mediaType === "drama" && this.form.listenPermission === 0) {
|
||||
this.form.listenPermission = 2;
|
||||
}
|
||||
if (this.form.listenPermission !== 1) {
|
||||
this.form.price = 0;
|
||||
}
|
||||
let data = {
|
||||
files: this.files || null,
|
||||
form: this.form,
|
||||
time: new Date().getTime(),
|
||||
};
|
||||
this.$emit("addTaskSuccess", data);
|
||||
this.$emit("close");
|
||||
this.cleanForm();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
cleanForm() {
|
||||
this.files = null;
|
||||
let dom = document.querySelector("#inputFile");
|
||||
if (dom) {
|
||||
dom.value = "";
|
||||
}
|
||||
this.isPermission = true;
|
||||
this.mediaTitle = "";
|
||||
this.form = {
|
||||
mediaId: this.form.mediaId, //父级媒体id
|
||||
mediaType: "video", //上传文件类型
|
||||
episodeNumber: 1, // 第几集
|
||||
listenPermission: 0, // 收听权限 0:会员 1:金币购买 2:免费
|
||||
price: 0, // 价格
|
||||
name: "", // 章节名
|
||||
text: "", // 小说专用
|
||||
md5: "", // 媒体md5
|
||||
sourceID: "", // 视频唯一id,对应文件服
|
||||
videoUrl: "",
|
||||
filename: "",
|
||||
isActive: false, //是否激活
|
||||
urlSet: [], // 图集
|
||||
};
|
||||
},
|
||||
// 封面图上传成功回调
|
||||
successCallbackHeng(res) {
|
||||
this.form.horizontalCover = res.data.coverImg;
|
||||
},
|
||||
successCallbackShu(res) {
|
||||
this.form.verticalCover = res.data.coverImg;
|
||||
},
|
||||
// 封面图上传成功回调
|
||||
successCallbackPic(seriesCover) {
|
||||
this.form.urlSet = seriesCover;
|
||||
},
|
||||
// 封面图上传成功回调
|
||||
successCallback(res) {
|
||||
this.form.cover = res.data.coverImg;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.add-video-warp-box {
|
||||
/deep/ .el-select--small {
|
||||
width: 250px !important;
|
||||
}
|
||||
.bottomBtn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: 14px;
|
||||
}
|
||||
.flex-item {
|
||||
width: 90%;
|
||||
display: flex;
|
||||
.el-form-item {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
.el-upload .el-upload--picture-card {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
.el-textarea {
|
||||
width: 500px;
|
||||
}
|
||||
.el-input {
|
||||
width: 250px;
|
||||
}
|
||||
.uploader-drop {
|
||||
background: none;
|
||||
border-radius: 5px;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
.uploader-file {
|
||||
border-bottom: 1px dashed #ccc;
|
||||
}
|
||||
.uploader-btn {
|
||||
background: #e63765;
|
||||
color: white;
|
||||
padding: 5px 10px;
|
||||
font-size: 13px;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
&:hover {
|
||||
background: #eb5f84;
|
||||
}
|
||||
}
|
||||
.title {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
line-height: 30px;
|
||||
overflow: hidden;
|
||||
color: #666;
|
||||
margin-bottom: 15px;
|
||||
cursor: pointer;
|
||||
i {
|
||||
&:hover {
|
||||
color: #e63765;
|
||||
}
|
||||
}
|
||||
span {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
.upload-video {
|
||||
width: 300px !important;
|
||||
.circle-bar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
.el-progress-circle {
|
||||
margin: 0 auto;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
.video-box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.avatar-uploader {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
}
|
||||
.el-upload {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px dashed #d9d9d9;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
&:hover {
|
||||
border: 1px dashed #e63765;
|
||||
}
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.avatar-uploader-icon {
|
||||
font-size: 28px;
|
||||
color: #8c939d;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
line-height: 150px;
|
||||
text-align: center;
|
||||
&:hover {
|
||||
color: 1px dashed #e63765 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.show {
|
||||
left: 20px;
|
||||
transition: left 0.2s linear;
|
||||
}
|
||||
.upload-demo {
|
||||
display: flex;
|
||||
margin: 0 0 0 50px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,461 @@
|
||||
<template>
|
||||
<div class="movie_warp">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="isShow = true"
|
||||
class="taskBtn"
|
||||
>新增任务</el-button
|
||||
>
|
||||
<div class="movide_box">
|
||||
<div class="left">
|
||||
<h3>上传子媒体列表</h3>
|
||||
<!--视频分片上传-->
|
||||
<uploader
|
||||
:options="options"
|
||||
:fileStatusText="fileStatusText"
|
||||
class="uploader-example"
|
||||
ref="uploader"
|
||||
@file-added="fileAdd"
|
||||
@file-success="onFileSuccess"
|
||||
>
|
||||
<uploader-unsupport></uploader-unsupport>
|
||||
<uploader-list class="upload_list" style="height: 600px">
|
||||
<div class="file-panel" slot-scope="props">
|
||||
<ul class="file-list">
|
||||
<li v-for="file in props.fileList" :key="file.id">
|
||||
<uploader-file
|
||||
:class="'file_' + file.id"
|
||||
ref="files"
|
||||
:file="file"
|
||||
:list="true"
|
||||
>
|
||||
</uploader-file>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</uploader-list>
|
||||
</uploader>
|
||||
</div>
|
||||
<div class="right">
|
||||
<h3>任务上传列表</h3>
|
||||
<div class="right_content">
|
||||
<el-table :data="taskList" style="width: 100%" stripe>
|
||||
<el-table-column prop="type" label="类型" width="90" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tag
|
||||
v-if="scope.row.form && scope.row.form.mediaType === 'video'"
|
||||
>
|
||||
视频
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="
|
||||
scope.row.form && scope.row.form.mediaType === 'video_adv'
|
||||
"
|
||||
>
|
||||
视频广告
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="scope.row.form && scope.row.form.mediaType === 'image'"
|
||||
>
|
||||
漫画
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="scope.row.form && scope.row.form.mediaType === 'text'"
|
||||
>
|
||||
小说
|
||||
</el-tag>
|
||||
<el-tag
|
||||
v-if="scope.row.form && scope.row.form.mediaType === 'drama'"
|
||||
>
|
||||
短剧
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="name"
|
||||
label="章节名"
|
||||
min-width="180"
|
||||
align="center"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
{{ (scope.row.form && scope.row.form.name) || "未知" }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="size"
|
||||
label="文件大小"
|
||||
width="90"
|
||||
align="center"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
{{
|
||||
(scope.row.files && getSize(scope.row.files.size)) ||
|
||||
(scope.row.form.size && getSize(scope.row.form.size)) ||
|
||||
""
|
||||
}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="status"
|
||||
label="状态"
|
||||
width="120"
|
||||
align="center"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-tag type="info" v-if="scope.row.status == 'wait'"
|
||||
>等待上传</el-tag
|
||||
>
|
||||
<el-tag
|
||||
type="warning"
|
||||
v-else-if="scope.row.status == 'video_uploaded'"
|
||||
>视频上传中</el-tag
|
||||
>
|
||||
<el-tag
|
||||
type="warning"
|
||||
v-else-if="scope.row.status == 'video_success'"
|
||||
>视频上传完成</el-tag
|
||||
>
|
||||
<el-tag
|
||||
type="warning"
|
||||
v-else-if="scope.row.status == 'img_success'"
|
||||
>图集上传完成</el-tag
|
||||
>
|
||||
<el-tag
|
||||
type="warning"
|
||||
v-else-if="scope.row.status == 'text_success'"
|
||||
>小说上传完成</el-tag
|
||||
>
|
||||
<el-tag type="success" v-else-if="scope.row.status == 'success'"
|
||||
>上传成功</el-tag
|
||||
>
|
||||
<el-tag type="error" v-else-if="scope.row.status == 'error'"
|
||||
>上传失败</el-tag
|
||||
>
|
||||
<el-tag
|
||||
type="error"
|
||||
v-else-if="scope.row.status == 'error_post'"
|
||||
>提交失败</el-tag
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
fixed="right"
|
||||
label="操作"
|
||||
align="center"
|
||||
width="100"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
@click="deleteTask(scope.$index)"
|
||||
type="text"
|
||||
size="small"
|
||||
>删除</el-button
|
||||
>
|
||||
<el-button
|
||||
type="text"
|
||||
v-if="scope.row.status == 'error_post'"
|
||||
@click="rest(scope.row, scope.$index)"
|
||||
size="small"
|
||||
>重试</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<addVideo
|
||||
v-show="isShow"
|
||||
:isShow="isShow"
|
||||
@close="isShow = false"
|
||||
@addTaskSuccess="addTaskSuccess"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import baseConfig from "@/utils/serverUrlConfig";
|
||||
import local from "@/utils/localStroage.js";
|
||||
import addVideo from "./addMedia.vue";
|
||||
import API from "@/api";
|
||||
import SparkMD5 from "spark-md5";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
addVideo,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isShow: false,
|
||||
trackId: "",
|
||||
isUploading: false, //是否正在上传
|
||||
fileStatusText: {
|
||||
success: "上传成功",
|
||||
error: "上传失败",
|
||||
uploading: "正在上传",
|
||||
paused: "暂停上传",
|
||||
waiting: "等待上传",
|
||||
},
|
||||
attrs: {
|
||||
accept: [
|
||||
".mp4",
|
||||
".qlv",
|
||||
".qsv",
|
||||
".ogg",
|
||||
".flv",
|
||||
".avi",
|
||||
".wmv",
|
||||
".rmvb",
|
||||
], //接受文件类型
|
||||
},
|
||||
taskList: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
options() {
|
||||
return {
|
||||
target: baseConfig.baseServerUrl + "/vid/uploadDotStream", //上传地址
|
||||
testChunks: false, //是否开启服务器分片校验
|
||||
method: "application/json",
|
||||
headers: {
|
||||
// 额外请求头
|
||||
Authorization: local.get("userInfo")
|
||||
? local.get("userInfo").token
|
||||
: "",
|
||||
},
|
||||
fileParameterName: "upload", //文件名参数,默认为file
|
||||
query: this.uploadQuery, //额外参数
|
||||
singleFile: false, //单文件上传
|
||||
chunkSize: 2048000, //分片大小,默认1M
|
||||
simultaneousUploads: 6,
|
||||
maxChunkRetries: 9, //失败重试次数
|
||||
// 把英文时间转成中文
|
||||
parseTimeRemaining: function(timeRemaining, parsedTimeRemaining) {
|
||||
return parsedTimeRemaining
|
||||
.replace(/\syears?/, "年")
|
||||
.replace(/\days?/, "天")
|
||||
.replace(/\shours?/, "小时")
|
||||
.replace(/\sminutes?/, "分钟")
|
||||
.replace(/\sseconds?/, "秒");
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
deleteTask(index) {
|
||||
this.taskList.splice(index, 1);
|
||||
},
|
||||
async rest(row, index) {
|
||||
let from = row.form;
|
||||
let res = await API.uploadMedia(from);
|
||||
if (res.code === 200) {
|
||||
this.taskList[index].status = "success";
|
||||
return;
|
||||
}
|
||||
this.taskList[index].status = "error_post";
|
||||
},
|
||||
// 获取文件大小
|
||||
getSize(byte) {
|
||||
let MB = (byte / 1024 / 1024).toFixed(2);
|
||||
return MB + "M" || "未知";
|
||||
},
|
||||
addTaskSuccess(info) {
|
||||
let repeatFile = this.taskList.filter((file) => {
|
||||
return info.files && info.files.name == file.filename;
|
||||
});
|
||||
if (repeatFile.length) {
|
||||
this.$message({
|
||||
type: "error",
|
||||
message: "视频名重复,添加失败",
|
||||
});
|
||||
return;
|
||||
}
|
||||
info.status = "wait";
|
||||
if (info.files) {
|
||||
info.filename = info.files.name;
|
||||
this.$refs.uploader.uploader.addFile(info.files);
|
||||
this.taskList.push(info);
|
||||
} else if (info.form.text) {
|
||||
//小说上传完成
|
||||
info.status = "text_success";
|
||||
this.taskList.push(info);
|
||||
this.uploadPost();
|
||||
} else {
|
||||
//图集上传完成
|
||||
info.status = "img_success";
|
||||
this.taskList.push(info);
|
||||
this.uploadPost();
|
||||
}
|
||||
this.$message.success("任务添加成功");
|
||||
},
|
||||
//视频上传选中时
|
||||
fileAdd(file) {
|
||||
this.computeMD5(file);
|
||||
},
|
||||
//定义视频上传唯一标识符id
|
||||
generateTaskId() {
|
||||
const time = new Date().getTime();
|
||||
this.trackId = time;
|
||||
},
|
||||
computeMD5(file) {
|
||||
let fileReader = new FileReader();
|
||||
let blobSlice =
|
||||
File.prototype.slice ||
|
||||
File.prototype.mozSlice ||
|
||||
File.prototype.webkitSlice;
|
||||
let currentChunk = 0;
|
||||
const chunkSize = 10 * 1024 * 1000;
|
||||
let chunks = Math.ceil(file.size / chunkSize);
|
||||
let spark = new SparkMD5.ArrayBuffer();
|
||||
|
||||
//校验MD5 文件先暂停
|
||||
file.pause();
|
||||
|
||||
loadNext();
|
||||
// 实时展示MD5的计算进度
|
||||
this.$nextTick(() => {
|
||||
let dom = document.querySelector(
|
||||
`.file_${file.id} .uploader-file-status span`
|
||||
);
|
||||
fileReader.onload = (e) => {
|
||||
spark.append(e.target.result);
|
||||
if (currentChunk < chunks) {
|
||||
currentChunk++;
|
||||
loadNext();
|
||||
// 实时展示MD5的计算进度
|
||||
dom.innerHTML =
|
||||
"校验MD5 " + ((currentChunk / chunks) * 100).toFixed(0) + "%";
|
||||
} else {
|
||||
let md5 = spark.end();
|
||||
this.computeMD5Success(md5, file);
|
||||
}
|
||||
};
|
||||
});
|
||||
fileReader.onerror = function() {
|
||||
this.$message.error(`文件${file.name}读取出错,请检查该文件`);
|
||||
file.cancel();
|
||||
};
|
||||
|
||||
function loadNext() {
|
||||
let start = currentChunk * chunkSize;
|
||||
let end =
|
||||
start + chunkSize >= file.size ? file.size : start + chunkSize;
|
||||
fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end));
|
||||
}
|
||||
},
|
||||
computeMD5Success(md5, file) {
|
||||
file.fileMd5 = md5;
|
||||
file.resume();
|
||||
},
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
onFileSuccess(rootFile, file, response, chunk) {
|
||||
this.$refs.uploader.uploader.removeFile(file);
|
||||
let res = JSON.parse(response);
|
||||
let fileName = file.name;
|
||||
let fIndex = this.taskList.findIndex(
|
||||
(el) => el.files && el.files.name == fileName
|
||||
);
|
||||
if (res.code === 200) {
|
||||
if (fIndex > -1) {
|
||||
this.taskList[fIndex].status = "video_success";
|
||||
this.taskList[fIndex].form.filename = res.data.filename;
|
||||
this.taskList[fIndex].form.size = res.data.size;
|
||||
this.taskList[fIndex].form.md5 = res.data.md5;
|
||||
this.taskList[fIndex].form.mimeType = res.data.mimeType;
|
||||
this.taskList[fIndex].form.sourceID = res.data.sourceID;
|
||||
this.taskList[fIndex].form.videoUrl = res.data.sourceURL;
|
||||
this.taskList[fIndex].form.resolution = res.data.resolution;
|
||||
this.taskList[fIndex].form.playTime = res.data.playTime;
|
||||
this.taskList[fIndex].files = null;
|
||||
}
|
||||
this.uploadPost();
|
||||
} else {
|
||||
if (fIndex > -1) {
|
||||
this.taskList[fIndex].status = "error";
|
||||
this.$message.error(`文件${fileName}上传失败`);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
//上传帖子
|
||||
async uploadPost() {
|
||||
if (this.isUploading) return;
|
||||
const result = this.taskList.filter(
|
||||
(item) =>
|
||||
item.status == "img_success" ||
|
||||
item.status == "video_success" ||
|
||||
item.status == "text_success"
|
||||
);
|
||||
if (result.length == 0) {
|
||||
this.$message.success("当前任务执行完毕,等待视频上传完成");
|
||||
return;
|
||||
}
|
||||
let taskItem = result[0];
|
||||
let form = taskItem.form;
|
||||
// console.log(form)
|
||||
try {
|
||||
this.isUploading = true;
|
||||
let res = await API.subUploadMedia(form);
|
||||
if (res.code === 200) {
|
||||
taskItem.status = "success";
|
||||
return;
|
||||
}
|
||||
taskItem.status = "error_post";
|
||||
} catch (err) {
|
||||
taskItem.status = "error_post";
|
||||
} finally {
|
||||
this.isUploading = false;
|
||||
this.uploadPost();
|
||||
}
|
||||
},
|
||||
//视频上传额外参数
|
||||
uploadQuery(file, chunk) {
|
||||
return {
|
||||
pos: chunk.offset,
|
||||
id: file.fileMd5,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.movie_warp {
|
||||
h3 {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.movide_box {
|
||||
display: flex;
|
||||
height: 600px;
|
||||
|
||||
.left {
|
||||
flex: 1;
|
||||
min-width: 500px;
|
||||
|
||||
.upload_list {
|
||||
border: 1px dashed #ccc;
|
||||
background-color: #f5f5f5;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
margin-left: 20px;
|
||||
flex: 1;
|
||||
min-width: 500px;
|
||||
|
||||
.right_content {
|
||||
border: 1px dashed #ccc;
|
||||
height: 100%;
|
||||
overflow-y: scroll;
|
||||
|
||||
.right_item {
|
||||
height: 30px;
|
||||
background: #6aebb4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user