增加了自动化视频以及修复了一些已知漏洞 (#1554)

* 解决bug:为角色添加权限时,如果有重复api权限,该角色所有权限均添加失败(包括登录)

* 支持视频上传和选用。视频首帧作为封面预览。

* 增加自动化代码视频选项

* 媒体库可上传视频
SelectImage组件增加参数file-type="image|video" 方便用户对媒体库可选内容做限制

* 自动化代码bug修复

---------

Co-authored-by: liuyahui <liuyahui@wjacloud.com>
Co-authored-by: Alan <alan.cd@qq.com>
This commit is contained in:
奇淼(piexlmax
2023-09-24 15:49:58 +08:00
committed by GitHub
parent c1c37901b5
commit 809e2496c0
12 changed files with 248 additions and 50 deletions

View File

@@ -4,16 +4,44 @@
class="update-image"
:style="{
'background-image': `url(${getUrl(modelValue)})`,
'position': 'relative',
}"
>
<el-icon
v-if="isVideoExt(modelValue || '')"
:size="32"
class="video video-icon"
style=""
><VideoPlay /></el-icon>
<video
v-if="isVideoExt(modelValue || '')"
class="avatar video-avatar video"
muted
preload="metadata"
style=""
@click="openChooseImg"
>
<source :src="getUrl(modelValue) + '#t=1'">
</video>
<span
v-if="modelValue"
class="update"
style="position: absolute;"
@click="openChooseImg"
>
<el-icon>
<edit />
<delete />
</el-icon>
重新上传</span>
删除</span>
<span
v-else
class="update text-gray-600"
@click="openChooseImg"
>
<el-icon>
<plus />
</el-icon>
上传</span>
</div>
<div
v-else
@@ -25,26 +53,42 @@
class="update-image"
:style="{
'background-image': `url(${getUrl(item)})`,
'position': 'relative',
}"
>
<el-icon
v-if="isVideoExt(item || '')"
:size="32"
class="video video-icon"
><VideoPlay /></el-icon>
<video
v-if="isVideoExt(item || '')"
class="avatar video-avatar video"
muted
preload="metadata"
@click="deleteImg(index)"
>
<source :src="getUrl(item) + '#t=1'">
</video>
<span
class="update"
style="position: absolute;"
@click="deleteImg(index)"
>
<el-icon>
<delete />
</el-icon>
删除图片</span>
删除</span>
</div>
<div class="add-image">
<span
class="update"
class="update text-gray-600"
@click="openChooseImg"
>
<el-icon>
<folder-add />
<Plus />
</el-icon>
上传图片</span>
上传</span>
</div>
</div>
@@ -101,12 +145,32 @@
<el-image
:key="key"
:src="getUrl(item.url)"
fit="cover"
style="width: 100%;height: 100%;"
@click="chooseImg(item.url)"
>
<template #error>
<div class="header-img-box-list">
<el-icon>
<picture />
<el-icon
v-if="isVideoExt(item.url || '')"
:size="32"
class="video video-icon"
><VideoPlay /></el-icon>
<video
v-if="isVideoExt(item.url || '')"
class="avatar video-avatar video"
muted
preload="metadata"
@click="chooseImg(item.url)"
>
<source :src="getUrl(item.url) + '#t=1'">
您的浏览器不支持视频播放
</video>
<div
v-else
class="header-img-box-list"
>
<el-icon class="lost-image">
<icon-picture />
</el-icon>
</div>
</template>
@@ -132,14 +196,14 @@
<script setup>
import { getUrl } from '@/utils/image'
import { getUrl, isVideoExt } from '@/utils/image'
import { onMounted, ref } from 'vue'
import { getFileList, editFileName } from '@/api/fileUploadAndDownload'
import UploadImage from '@/components/upload/image.vue'
import UploadCommon from '@/components/upload/common.vue'
import WarningBar from '@/components/warningBar/warningBar.vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Delete, FolderAdd } from '@element-plus/icons-vue'
import { Delete, FolderAdd, Plus, Picture as IconPicture } from '@element-plus/icons-vue'
const imageUrl = ref('')
const imageCommon = ref('')
@@ -157,6 +221,10 @@ const props = defineProps({
multiple: {
type: Boolean,
default: false
},
fileType: {
type: String,
default: ''
}
})
@@ -214,7 +282,30 @@ const editFileNameFunc = async(row) => {
const drawer = ref(false)
const picList = ref([])
const imageTypeList = ['png', 'jpg', 'jpge', 'gif', 'bmp', 'webp']
const videoTyteList = ['mp4', 'avi', 'rmvb', 'rm', 'asf', 'divx', 'mpg', 'mpeg', 'mpe', 'wmv', 'mkv', 'vob']
const listObj = {
image: imageTypeList,
video: videoTyteList
}
const chooseImg = (url) => {
console.log(url)
if (props.fileType) {
const typeSuccess = listObj[props.fileType].some(item => {
if (url.includes(item)) {
return true
}
})
if (!typeSuccess) {
ElMessage({
type: 'error',
message: '当前类型不支持使用'
})
return
}
}
if (props.multiple) {
multipleValue.value.push(url)
emits('update:modelValue', multipleValue.value)
@@ -224,6 +315,10 @@ const chooseImg = (url) => {
drawer.value = false
}
const openChooseImg = async() => {
if (props.modelValue && !props.multiple) {
emits('update:modelValue', '')
return
}
await getImageList()
drawer.value = true
}
@@ -245,6 +340,8 @@ const getImageList = async() => {
.multiple-img{
display: flex;
gap:8px;
width: 100%;
flex-wrap: wrap;
}
.add-image{
@@ -270,6 +367,7 @@ const getImageList = async() => {
border: 1px dashed #ccc;
background-repeat: no-repeat;
background-size: cover;
position: relative;
&:hover {
color: #fff;
background: linear-gradient(
@@ -288,12 +386,23 @@ const getImageList = async() => {
.update {
color: #fff;
}
.video {
opacity: 0.2;
}
}
.video-icon {
position: absolute; left: calc(50% - 16px); top: calc(50% - 16px);
}
video {
object-fit: cover; max-width:100%; border-radius: 20px;
}
.update {
height: 120px;
width: 120px;
text-align: center;
color: transparent;
position: absolute;
}
}
@@ -334,6 +443,16 @@ const getImageList = async() => {
width: unset;
height: unset;
}
.el-image {
position: relative;
}
.video-icon {
position: absolute; left: calc(50% - 16px); top: calc(50% - 16px);
}
video {
object-fit: cover; max-width:100%; min-height: 100%; border-radius: 8px;
}
}
}
}