提交 dadb1266 authored 作者: 王鹏飞's avatar 王鹏飞

chore: update

上级 b4a2b124
......@@ -12,32 +12,36 @@ const form = reactive({
name: '0',
classification: ''
})
defineProps({
isShowBatchImport: {
type: Boolean
}
})
interface Emits {
(e: 'update:isShowBatchImport', isShowBatchImport: boolean): void
(e: 'update:modelValue', modelValue: boolean): void
(e: 'update'): void
}
const uploadMultipleVideoRef = ref()
const handleConfirm = () => {
emit('update:isShowBatchImport', false)
emit('update:modelValue', false)
emit('update')
}
const handleCancel = () => {
if (closeStatus.value !== false) {
emit('update:isShowBatchImport', false)
const fileList = uploadMultipleVideoRef.value?.uploader?._uploadList || []
if (fileList.length) {
for (const item of fileList) {
if (item.state === 'Uploading') {
return ElMessage.error('请先完成上传')
}
}
}
emit('update:modelValue', false)
}
// 上传视频成功
const uploadVideo = (data: any) => {
const { file, videoId } = data
const params = {
name: data.name.slice(0, data.name.lastIndexOf('.')),
name: file.name.slice(0, file.name.lastIndexOf('.')),
source: '2',
classification: form.classification,
knowledge_points: '',
source_id: data.videoId,
source_id: videoId,
cover: ''
}
createVideo(params).then(() => {
......@@ -49,7 +53,7 @@ const handleClose = (val: any) => {
}
</script>
<template>
<el-dialog :model-value="isShowBatchImport" title="批量导入视频" :before-close="handleCancel">
<el-dialog title="批量导入视频" :close-on-click-modal="false" :before-close="handleCancel">
<el-form :model="form" label-suffix=":">
<el-form-item label="视频分类" prop="classification">
<el-tree-select
......@@ -64,7 +68,7 @@ const handleClose = (val: any) => {
/>
</el-form-item>
<el-form-item label="视频文件" prop="source_id" v-if="form.classification !== ''">
<UploadMultipleVideo @upload="uploadVideo" @canClose="handleClose" />
<UploadMultipleVideo @upload="uploadVideo" @canClose="handleClose" ref="uploadMultipleVideoRef" />
</el-form-item>
<el-form-item label="视频名称" prop="name">
<el-radio-group v-model="form.name">
......@@ -73,11 +77,8 @@ const handleClose = (val: any) => {
</el-form-item>
</el-form>
<template #footer>
<span>
{{ closeStatus }}
<el-button type="primary" @click="handleConfirm" :disabled="closeStatus === false">保存</el-button>
<el-button @click="handleCancel" :disabled="closeStatus === false">取消</el-button>
</span>
</template>
</el-dialog>
</template>
......
<script setup lang="ts">
import VideoDetail from './VideoDetail.vue'
import { getCreateAuth, updateAuth } from '@/api/base'
import { ElMessage } from 'element-plus'
const idShowMore = ref(false)
const props = defineProps({
createFlag: {
type: Number
}
})
/**
* upload 上传状态 {code: -1(待上传)0(成功) 1(开始上传) 2(上传失败), msg: '上传信息'}
* progress 上传进度
**/
interface IUpload {
id?: number
code: number
name?: string
msg?: string
progress?: number
videoId?: string
// uploadInfo 包含要上传的文件信息
interface UploadInfo {
bucket: string
checkpoint: { file: File; name: string; fileSize: number; partSize: number; uploadId: string }
endpoint: string
file: File
fileHash: string
isImage: boolean
loaded: number
object: string
region: string
retry: boolean
ri: string
state: string
userData: string
videoId: string
videoInfo: any
progress: number
}
let uploadData = $ref<IUpload>({ code: -1 })
let uploadData1 = $ref<IUpload[]>([])
const emit = defineEmits(['upload', 'canClose'])
const form: any = reactive({
timeout: '',
partSize: '',
parallel: '',
retryCount: '',
retryDuration: '',
region: 'cn-shanghai',
userId: '1303984639806000',
file: null,
authProgress: 0,
uploader: null,
statusText: ''
})
const fileChange = (e: any) => {
if (props.createFlag === 1) {
form.file = e.target.files[0]
if (form.file.name.indexOf('.mp4') === -1) {
ElMessage.warning('请上传mp4格式视频')
return
}
var userData = '{"Vod":{}}'
if (form.uploader) {
form.uploader.stopUpload()
form.authProgress = 0
form.statusText = ''
}
form.uploader = createUploader()
form.uploader.addFile(form.file, null, null, null, userData)
form.uploader.startUpload()
} else {
console.log(e.target.files)
form.file = e.target.files
form.file.forEach((item: any) => {
if (item.name.indexOf('.mp4') === -1) {
ElMessage('请上传mp4格式视频')
} else {
var userData = '{"Vod":{}}'
if (form.uploader) {
form.uploader.stopUpload()
form.authProgress = 0
form.statusText = ''
}
setTimeout(() => {
form.uploader = createUploader()
form.uploader.addFile(item, null, null, null, userData)
form.uploader.startUpload()
}, 1000)
}
})
}
let uploader = createUploader()
let fileList = $ref<UploadInfo[]>([])
const fileChange = (event: Event) => {
const element = event.currentTarget as HTMLInputElement
let files: FileList | null = element.files
if (!files) return
for (const file of files) {
uploader.addFile(file, null, null, null, '{"Vod":{}}')
}
uploader.startUpload()
fileList = uploader._uploadList
}
let id = ref(0)
const createUploader: any = () => {
const w = window as any
// for
const uploader = new w.AliyunUpload.Vod({
timeout: form.timeout || 60000,
partSize: form.partSize || 1048576,
parallel: form.parallel || 5,
retryCount: form.retryCount || 3,
retryDuration: form.retryDuration || 2,
region: form.region,
userId: form.userId,
// 开始上传
onUploadstarted: function (uploadInfo: any) {
console.log(window.localStorage.fileData)
const fileData = JSON.parse(window.localStorage.fileData || '{}')
console.log(fileData.sourceId)
// 判断有没有上传过
const isFile = !!fileData.sourceId
if (!isFile) {
// 没上传过请求凭证上传
getCreateAuth({ title: uploadInfo.file.name, file_name: uploadInfo.file.name }).then((data: any) => {
window.localStorage.fileData = JSON.stringify({
uploadAuth: data.data.upload_auth,
uploadAddress: data.data.upload_address,
videoId: data.data.source_id,
fileName: uploadInfo.file.name,
fileSize: uploadInfo.file.size
})
uploader.setUploadAuthAndAddress(
uploadInfo,
data.data.upload_auth,
data.data.upload_address,
data.data.source_id
)
})
} else {
console.log(fileData, uploadInfo)
// 上传过判断一下上次上传的文件和本次上传的文件一不一样,一样的话继续上传
if (fileData.fileName === uploadInfo.file.name && fileData.fileSize === uploadInfo.file.size) {
uploader.setUploadAuthAndAddress(uploadInfo, fileData.uploadAuth, fileData.uploadAddress, fileData.videoId)
} else {
getCreateAuth({ title: uploadInfo.file.name, file_name: uploadInfo.file.name }).then((data: any) => {
uploader.setUploadAuthAndAddress(
uploadInfo,
data.data.upload_auth,
data.data.upload_address,
data.data.source_id
)
})
}
function updateFileList(uploadInfo: UploadInfo) {
if (!uploadInfo) return
fileList = fileList.map(item => {
if (item.ri === uploadInfo.ri) {
return { ...item, ...uploadInfo }
}
if (props.createFlag === 1) {
uploadData = {
code: 1,
name: uploadInfo.file.name,
msg: '开始上传'
}
} else {
uploadData1.push({
code: 1,
name: uploadInfo.file.name,
msg: '开始上传'
return item
})
emit('canClose', { closeStatus: false })
}
},
// 文件上传成功
onUploadSucceed: function (uploadInfo: any) {
const fileData = window.localStorage.fileData ? JSON.parse(window.localStorage.fileData) : {}
if (props.createFlag === 1) {
uploadData = {
code: 0,
name: uploadInfo.file.name,
videoId: fileData.videoId,
msg: '上传成功'
}
} else {
const findIndex = uploadData1.findIndex(item => item.name === uploadInfo.file.name)
uploadData1[findIndex] = {
code: 0,
name: uploadInfo.file.name,
videoId: fileData.videoId,
msg: '上传成功'
}
}
emit('upload', { videoId: fileData.videoId, name: uploadInfo.file.name })
emit('canClose', { closeStatus: true })
},
// 文件上传失败
// code:any, message:any
onUploadFailed: function (uploadInfo: any) {
if (props.createFlag === 1) {
uploadData = {
code: 2,
name: uploadInfo.file.name,
msg: '文件上传失败'
}
} else {
const findIndex = uploadData1.findIndex(item => item.id === id.value)
uploadData1[findIndex] = {
id: id.value,
code: 2,
name: uploadInfo.file.name,
msg: '文件上传失败'
}
}
},
// 文件上传进度,单位:字节, 可以在这个函数中拿到上传进度并显示在页面上
onUploadProgress: function (uploadInfo: any, totalSize: any, progress: any) {
let progressPercent = Math.ceil(progress * 100)
form.authProgress = progressPercent
if (props.createFlag === 1) {
uploadData.progress = progressPercent
} else {
const findIndex = uploadData1.findIndex(item => item.name === uploadInfo.file.name)
uploadData1[findIndex].progress = progressPercent
}
},
// 上传凭证超时
onUploadTokenExpired: function (uploadInfo: any) {
const fileData = JSON.parse(window.localStorage.fileData || '{}')
updateAuth({ source_id: fileData.videoId }).then(({ data }) => {
let uploadAuth = data.UploadAuth
window.localStorage.fileData = JSON.stringify({
uploadAuth: data.data.upload_auth,
uploadAddress: data.data.upload_address,
videoId: data.data.source_id,
fileName: uploadInfo.file.name,
fileSize: uploadInfo.file.size
}
function createUploader() {
return new window['AliyunUpload'].Vod({
//userID,必填,您可以使用阿里云账号访问账号中心(https://account.console.aliyun.com/),即可查看账号ID
userId: '1303984639806000',
//上传到视频点播的地域,默认值为'cn-shanghai',
//eu-central-1,ap-southeast-1
region: 'cn-shanghai',
//分片大小默认1 MB,不能小于100 KB(100*1024)
partSize: 1048576,
//并行上传分片个数,默认5
parallel: 5,
//网络原因失败时,重新上传次数,默认为3
retryCount: 3,
//网络原因失败时,重新上传间隔时间,默认为2秒
retryDuration: 2,
//开始上传
onUploadstarted: onUploadStarted,
//文件上传成功
onUploadSucceed: onUploadSucceed,
//文件上传失败
onUploadFailed: onUploadFailed,
//文件上传进度,单位:字节
onUploadProgress: onUploadProgress,
//上传凭证或STS token超时
onUploadTokenExpired: onUploadTokenExpired,
//全部文件上传结束
onUploadEnd: onUploadEnd
})
uploader.resumeUploadWithAuth(uploadAuth)
}
// 开始上传
function onUploadStarted(uploadInfo: UploadInfo) {
console.log('onUploadStarted', uploadInfo)
getCreateAuth({ title: uploadInfo.file.name, file_name: uploadInfo.file.name }).then(res => {
uploader.setUploadAuthAndAddress(uploadInfo, res.data.upload_auth, res.data.upload_address, res.data.source_id)
})
}
updateFileList(uploadInfo)
}
// 文件上传成功
function onUploadSucceed(uploadInfo: UploadInfo) {
console.log('onUploadSucceed', uploadInfo)
updateFileList(uploadInfo)
emit('upload', uploadInfo)
}
//文件上传失败
function onUploadFailed(uploadInfo: UploadInfo, code: number, message: string) {
console.log('onUploadFailed', uploadInfo, code, message)
updateFileList(uploadInfo)
}
//文件上传进度,单位:字节
function onUploadProgress(uploadInfo: UploadInfo, totalSize: number, loadedPercent: number) {
console.log('onUploadProgress', uploadInfo.file.name, uploadInfo, totalSize, loadedPercent)
updateFileList(uploadInfo)
}
//上传凭证或STS token超时
function onUploadTokenExpired(uploadInfo: UploadInfo) {
console.log('onUploadTokenExpired', uploadInfo)
updateAuth({ source_id: uploadInfo.videoId }).then(res => {
uploader.resumeUploadWithAuth(res.data.UploadAuth)
})
return uploader
updateFileList(uploadInfo)
}
// 全部文件上传结束
function onUploadEnd(uploadInfo: UploadInfo) {
console.log('onUploadEnd', uploadInfo)
updateFileList(uploadInfo)
}
const handleView = () => {
idShowMore.value = true
}
// 进度条
function percentage(value: number) {
return parseFloat((value ? value * 100 : 0).toFixed(2))
}
defineExpose({ uploader, fileList })
</script>
<template>
<div v-if="props.createFlag === 1">
<div class="upload-video">
<div class="upload-btn">
本地文件
<!-- accept=".mp4" -->
<input accept=".mp4" type="file" id="fileUpload" @change="fileChange($event)" />
</div>
<div class="demo-progress" v-if="uploadData.code === 1">
<el-progress style="width: 340px" :percentage="uploadData.progress" />
</div>
<div class="error video-info" v-if="uploadData.code === 2">
<div class="name">上传失败(请重新选择文件进行上传)</div>
</div>
<div class="video-info" v-if="uploadData.code === 0">
<div class="name">{{ uploadData.name }}</div>
</div>
</div>
<div class="tips">推荐视频格式:帧率为25fps\输出码率为4M\输出格式为mp4,建议采用格式工厂等工具处理后上传。</div>
</div>
<div v-else>
<div class="upload-video" style="display: flex; flex-direction: column; align-items: flex-start">
<div class="upload-btn">
本地文件
<input accept=".mp4" type="file" id="fileUpload" @change="fileChange($event)" multiple />
<input accept=".mp4" type="file" id="fileUpload" multiple @change="fileChange" />
</div>
<div class="tips">推荐视频格式:帧率为25fps\输出码率为4M\输出格式为mp4,建议采用格式工厂等工具处理后上传。</div>
<div v-for="(item, index) in uploadData1" :key="index" style="display: flex; flex-direction: column">
<div class="demo-progress" v-if="item.code === 1">
<span style="min-width: 340px">{{ item.name }}</span>
<el-progress style="width: 200px" :percentage="item.progress" />
<div v-for="(item, index) in fileList" :key="index">
<div>
<span>{{ item.file.name }}</span>
<el-progress style="width: 200px" :percentage="percentage(item.loaded)" />
</div>
<div class="error video-info" v-if="item.code === 2">
<div class="name">上传失败(请重新选择文件进行上传)</div>
</div>
<div class="video-info" v-if="item.code === 0">
<div class="name1">{{ item.name }}</div>
</div>
</div>
<el-link type="primary" v-if="uploadData1.length > 3" @click="handleView"
>{{ uploadData1.length }}个文件,查看更多</el-link
<el-link type="primary" v-if="fileList.length > 3" @click="handleView"
>{{ fileList.length }}个文件,查看更多</el-link
>
</div>
</div>
<VideoDetail :videoList="uploadData1" v-model:idShowMore="idShowMore" v-if="idShowMore === true" />
<VideoDetail :videoList="fileList" v-model="idShowMore" v-if="idShowMore === true" />
</template>
<style lang="scss">
.demo-progress {
......
<script lang="ts" setup>
const emit = defineEmits<Emits>()
interface UploadInfo {
bucket: string
checkpoint: { file: File; name: string; fileSize: number; partSize: number; uploadId: string }
endpoint: string
file: File
fileHash: string
isImage: boolean
loaded: number
object: string
region: string
retry: boolean
ri: string
state: string
userData: string
videoId: string
videoInfo: any
progress: number
}
interface Props {
videoList: UploadInfo[]
}
interface Emits {
(e: 'update:modelValue', modelValue: boolean): void
}
const props = defineProps<Props>()
const emit = defineEmits<Emits>()
const currentPage = ref(1)
const page = reactive({
size: 10,
currentPage: 1
})
interface IUpload {
id?: number
code: number
name?: string
msg?: string
progress?: number
videoId?: string
}
interface Props {
idShowMore: boolean
videoList: IUpload[]
}
interface Emits {
(e: 'update:idShowMore', isShowBatchImport: boolean): void
}
const handleCancel = () => {
emit('update:idShowMore', false)
emit('update:modelValue', false)
}
const handleSizeChange = (val: any) => {
page.size = val
......@@ -33,12 +41,12 @@ const handleCurrentChange = (val: any) => {
}
</script>
<template>
<el-dialog :model-value="idShowMore" title="更多视频文件" :before-close="handleCancel">
<el-dialog title="更多视频文件" :before-close="handleCancel">
<div
v-for="(item, index) in props.videoList.slice((page.currentPage - 1) * page.size, page.currentPage * page.size)"
:key="index"
>
{{ item.name }}
{{ item.file.name }}
</div>
<el-pagination
v-model:currentPage="currentPage"
......
......@@ -180,11 +180,7 @@ const handleBatchImport = () => {
</template>
</AppList>
</AppCard>
<BatchImportVideo
v-model:isShowBatchImport="isShowBatchImport"
v-if="isShowBatchImport === true"
@update="typeFilter"
/>
<BatchImportVideo v-model="isShowBatchImport" v-if="isShowBatchImport === true" @update="typeFilter" />
</template>
<style lang="scss" scoped>
.card-list {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论