123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- <template>
- <a-upload
- v-model:file-list="videoFile"
- name="file"
- :show-upload-list="false"
- accept=".mp4"
- :action="baseURL + '/takelook/upload/file'"
- :max-count="1"
- class="uploader"
- :headers="{
- authorization: 'authorization-text'
- }"
- :disabled="videoFile.length > 0"
- @change="handleAvatarChange"
- @preview="handleVideoPreview"
- >
- <div
- class="add-item-icon scene-sign"
- v-if="videoFile.length > 0 && videoFile[0].response"
- @click.stop="handleVideoPreview"
- >
- <video class="avatar" :src="videoFile[0].response.data" alt="video" />
- <span class="delete-scene" @click.stop="deleteAvatar(videoFile[0])">
- <close-outlined class="delete-scene-icon" />
- </span>
- </div>
- <div class="add-item-icon" v-else>
- <a-button shape="circle" class="button" type="primary">
- <plus-outlined class="add-room-icon" />
- </a-button>
- </div>
- <a-modal
- :visible="showVideoPreview"
- :footer="null"
- width="800px"
- @cancel="showVideoPreview = false"
- >
- <video controls id="previewVideo"></video>
- </a-modal>
- </a-upload>
- </template>
- <script lang="ts" setup>
- import { ref } from 'vue'
- import { message, type UploadChangeParam } from 'ant-design-vue'
- import type { FileItem } from './album-list.vue'
- import { baseURL } from '@/env'
- import { watchEffect } from 'vue'
- import { nextTick } from 'vue'
- const emit = defineEmits(['sync'])
- const videoFile = ref<any[]>([])
- const props = defineProps<{ data: string | undefined }>()
- const showVideoPreview = ref(false)
- const previewSrc = ref('')
- watchEffect(() => {
- if (props.data?.length) {
- const tempData = {} as FileItem
- tempData.uid = `data-0`
- tempData.response = {
- data: props.data,
- ok: 0
- }
- if (!videoFile.value?.length) {
- console.log('mapper', tempData)
- videoFile.value = [tempData]
- }
- } else {
- videoFile.value = []
- }
- })
- const handleAvatarChange = (info: UploadChangeParam) => {
- if (info.file.status === 'done') {
- const { code, data } = info.file.response
- if (code === 0) {
- console.log('syncVideo', data)
- previewSrc.value = data
- emit('sync', data || '')
- }
- } else if (info.file.status === 'error') {
- message.error(`${info.file.name} file upload failed.`)
- }
- }
- const deleteAvatar = (item: any) => {
- const index = videoFile.value.findIndex(i => i.uid === item.uid)
- if (index > -1) {
- videoFile.value.splice(index, 1)
- }
- emit('sync', '')
- }
- const handleVideoPreview = () => {
- showVideoPreview.value = true
- nextTick(() => {
- const video = document.getElementById('previewVideo')
- if (video) {
- // debugger
- const src = previewSrc.value || videoFile.value[0].response.data
- console.log('src', src)
- ;(video as any).src = src
- }
- })
- }
- </script>
- <style lang="scss" scoped>
- .add-item-icon {
- width: 120px;
- height: 120px;
- display: flex;
- justify-content: center;
- align-items: center;
- border: 1px solid #ebedf0;
- overflow: hidden;
- .avatar {
- max-width: 100%;
- // border-radius: 50%;
- }
- .button {
- background: linear-gradient(144deg, #00aefb 0%, #0076f6 100%);
- width: 40px;
- height: 40px;
- }
- }
- .scene-sign {
- border-radius: 4px;
- overflow: hidden;
- position: relative;
- z-index: 10;
- img {
- width: 100%;
- height: 100%;
- display: block;
- object-fit: cover;
- }
- .title {
- position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- height: 24px;
- background: rgba(0, 0, 0, 0.5);
- padding: 5px;
- font-size: 12px;
- color: #fff;
- margin: 0;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- .delete-scene {
- z-index: 2;
- position: absolute;
- right: 0;
- top: 0;
- width: 52px;
- height: 52px;
- background-color: rgba(0, 0, 0, 0.5);
- color: #fa5555;
- font-size: 14px;
- border-radius: 50%;
- display: flex;
- align-items: flex-end;
- transform: translate(100%, -100%);
- transition: all 0.3s ease;
- opacity: 0;
- cursor: pointer;
- .delete-scene-icon {
- padding: 10px;
- }
- }
- &:hover .delete-scene {
- transform: translate(50%, -50%);
- opacity: 1;
- }
- .status-cover {
- z-index: 1;
- position: absolute;
- left: 0;
- top: 0;
- right: 0;
- bottom: 0;
- background-color: rgba(0, 0, 0, 0.5);
- display: flex;
- align-items: center;
- justify-content: center;
- p {
- color: #fff;
- }
- }
- }
- </style>
- <style lang="scss">
- #previewVideo {
- width: 100%;
- min-height: 500px;
- }
- </style>
|