修改媒体库样式

This commit is contained in:
jacky 2024-05-08 16:26:23 +08:00
parent 96eaeaca93
commit 272d0fd312
7 changed files with 107 additions and 95 deletions

View File

@ -8,29 +8,39 @@
<div class="gva-btn-list"> <div class="gva-btn-list">
<upload-common :image-common="imageCommon" class="upload-btn-media-library" :category="props.category" <upload-common :image-common="imageCommon" class="upload-btn-media-library" :category="props.category"
@on-success="open" /> @on-success="getTableData" />
<el-tooltip effect="dark" content="图片超过 512K 或者 长宽 > 1080 会自动压缩后再上传" placement="top-start"> <el-tooltip effect="dark" content="图片超过 512K 或者 长宽 > 1080 会自动压缩后再上传" placement="top-start">
<upload-image :image-url="imageUrl" :file-size="512" :max-w-h="1080" :category="props.category" <upload-image :image-url="imageUrl" :file-size="512" :max-w-h="1080" :category="props.category"
@on-success="open" /> @on-success="getTableData" />
</el-tooltip> </el-tooltip>
<cropper-img btn-type="primary" :img-width="1080" :img-height="1080" category="media" crop-type="max"
@on-success="getTableData" />
<el-select v-model="search.category" clearable placeholder="请选择分类" style="width: 350px;"
@clear="() => { search.category = undefined }">
<el-option v-for="(item, key) in mediaFileCategoryOpts" :key="key" :label="item.label" :value="item.value" />
</el-select>
<el-input v-model="search.keyword" class="keyword" placeholder="请输入文件名或备注" clearable /> <el-input v-model="search.keyword" class="keyword" placeholder="请输入文件名或备注" clearable />
<el-button type="primary" plain icon="search" @click="open">查询</el-button> <el-button type="primary" plain icon="search" @click="getTableData">查询</el-button>
</div> </div>
<warning-bar title="点击“文件名/备注”可以编辑文件名或者备注内容。" /> <warning-bar title="点击“文件名/备注”可以编辑文件名或者备注内容。" />
<div class="media"> <div class="gva-media-card">
<div v-for="(item, key) in picList" :key="key" class="media-box"> <div v-for="(item, key) in picList" :key="key" class="media-box">
<div class="img-box-list"> <el-image v-if="isImageTag(item.tag)" :key="key" fit="contain" :src="getUrl(item.url)"
<el-image :key="key" fit="contain" :src="getUrl(item.url)" style="width: 138px; height: 138px;" style="width: 138px; height: 138px;" @click="chooseImg(item)">
@click="chooseImg(item)">
<template #error> <template #error>
<div class="img-box-list"> <div>
<el-icon> <el-icon>
<picture /> <picture />
</el-icon> </el-icon>
</div> </div>
</template> </template>
</el-image> </el-image>
<video-viewer v-else-if="isVideoTag(item.tag)" width="138px" height="138px" :url="item.url" />
<div v-else class="gva-media-box" style="width: 138px; height: 138px;">
<el-icon :size="25">
<Document />
</el-icon>
</div> </div>
<div class="img-title" @click="editFileNameFunc(item)">{{ item.name }}</div> <div class="img-title" @click="editFileNameFunc(item)">{{ item.name }}</div>
</div> </div>
@ -41,13 +51,16 @@
</template> </template>
<script setup> <script setup>
import { getUrl } from '@/utils/image' import { getUrl, isImageTag, isVideoTag } from '@/utils/image'
import { ref } from 'vue' import { ref } from 'vue'
import { getFileList, editFileName } from '@/api/mediaFile' import { getFileList, editFileName } from '@/api/mediaFile'
import UploadImage from '@/components/upload/image.vue' import UploadImage from '@/components/upload/image.vue'
import UploadCommon from '@/components/upload/common.vue' import UploadCommon from '@/components/upload/common.vue'
import CropperImg from '@/components/upload/cropperImg.vue'
import VideoViewer from '@/components/video/videoViewer.vue'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import WarningBar from '@/components/warningBar/warningBar.vue' import WarningBar from '@/components/warningBar/warningBar.vue'
import { getDictFunc } from '@/utils/format'
const imageUrl = ref('') const imageUrl = ref('')
const imageCommon = ref('') const imageCommon = ref('')
@ -57,15 +70,23 @@ const page = ref(1)
const total = ref(0) const total = ref(0)
const pageSize = ref(20) const pageSize = ref(20)
const mediaFileCategoryOpts = ref([])
//
const setOptions = async () => {
mediaFileCategoryOpts.value = await getDictFunc('mediaFileCategory')
}
//
setOptions()
// //
const handleSizeChange = (val) => { const handleSizeChange = (val) => {
pageSize.value = val pageSize.value = val
open() getTableData()
} }
const handleCurrentChange = (val) => { const handleCurrentChange = (val) => {
page.value = val page.value = val
open() getTableData()
} }
const emit = defineEmits(['on-select', 'on-before-upload', 'on-upload-success', 'on-upload-failure']) const emit = defineEmits(['on-select', 'on-before-upload', 'on-upload-success', 'on-upload-failure'])
@ -82,18 +103,22 @@ const chooseImg = (item) => {
drawer.value = false drawer.value = false
} }
const open = async () => { const getTableData = async () => {
search.value.category = props.category
const res = await getFileList({ page: page.value, pageSize: pageSize.value, ...search.value }) const res = await getFileList({ page: page.value, pageSize: pageSize.value, ...search.value })
if (res.code === 0) { if (res.code === 0) {
picList.value = res.data.list picList.value = res.data.list
total.value = res.data.total total.value = res.data.total
page.value = res.data.page page.value = res.data.page
pageSize.value = res.data.pageSize pageSize.value = res.data.pageSize
drawer.value = true
} }
} }
const open = async () => {
search.value.category = props.category
drawer.value = true
getTableData()
}
/** /**
* 编辑文件名或者备注 * 编辑文件名或者备注
* @param row * @param row
@ -115,7 +140,7 @@ const editFileNameFunc = async (row) => {
type: 'success', type: 'success',
message: '编辑成功!', message: '编辑成功!',
}) })
open() getTableData()
} }
}).catch(() => { }).catch(() => {
ElMessage({ ElMessage({
@ -127,30 +152,3 @@ const editFileNameFunc = async (row) => {
defineExpose({ open }) defineExpose({ open })
</script> </script>
<style lang="scss">
.media {
display: flex;
flex-wrap: wrap;
gap: 5px;
.media-box {
width: 148px;
background: #F0F2F5;
padding: 5px;
text-align: center;
border-radius: 5px;
box-sizing: border-box;
.img-title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
line-height: 28px;
text-align: center;
cursor: pointer;
font-size: 12px;
box-sizing: border-box;
}
}
}
</style>

View File

@ -58,7 +58,7 @@
<el-button type="primary" icon="search" @click="getImageList">查询</el-button> <el-button type="primary" icon="search" @click="getImageList">查询</el-button>
</div> </div>
<warning-bar title="点击“文件名/备注”可以编辑文件名或者备注内容。" style="width: 680px" /> <warning-bar title="点击“文件名/备注”可以编辑文件名或者备注内容。" style="width: 680px" />
<div class="media"> <div class="gva-media-card">
<div v-for="(item, key) in picList" :key="key" class="media-box"> <div v-for="(item, key) in picList" :key="key" class="media-box">
<div class="header-img-box-list"> <div class="header-img-box-list">
<el-image :key="key" :src="getUrl(item.url)" fit="contain" style="width: 100%;height: 100%;" <el-image :key="key" :src="getUrl(item.url)" fit="contain" style="width: 100%;height: 100%;"

View File

@ -11,7 +11,8 @@
</div> </div>
<el-drawer v-model="showDrawer" title="上传头像" direction="ltr" :show-close="false" :close-on-press-escape="false" <el-drawer v-model="showDrawer" title="上传头像" direction="ltr" :show-close="false" :close-on-press-escape="false"
:close-on-click-modal="false" :size="Math.max(800, Math.min(1500, props.imgWidth + 140))"> :close-on-click-modal="false" destroy-on-close append-to-body
:size="Math.max(800, Math.min(1500, props.imgWidth + 140))">
<template #header> <template #header>
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
<span class="text-lg">裁剪上传图片</span> <span class="text-lg">裁剪上传图片</span>
@ -159,6 +160,7 @@ const doConfirm = (cropData) => {
var height = img.height var height = img.height
if (width <= desiredWidth && height <= desiredHeight) { if (width <= desiredWidth && height <= desiredHeight) {
console.log('未超过,直接上传')
// //
uploadImage(cropData) uploadImage(cropData)
} else { } else {
@ -275,6 +277,7 @@ const handleSelectImg = (e) => {
// //
const open = async (data) => { const open = async (data) => {
console.log(Math.min(1500, props.imgWidth + 140))
showDrawer.value = true showDrawer.value = true
vueCropperImg.value = data vueCropperImg.value = data
} }

View File

@ -771,3 +771,28 @@ li {
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
line-height: 1.8rem; line-height: 1.8rem;
} }
.gva-media-card {
display: inline-flex;
flex-wrap: wrap;
gap:10px;
.media-box {
width: 148px;
background: var(--el-fill-color-lighter);
padding: 5px;
text-align: center;
border-radius: 5px;
box-sizing: border-box;
.img-title {
overflow: hidden;
line-height: 1.5rem;
text-align: center;
cursor: pointer;
font-size: 12px;
box-sizing: border-box;
padding: 0 5px;
}
}
}

View File

@ -114,3 +114,20 @@ export const checkImageWHEqual = (file, width, height) => {
img.src = _URL.createObjectURL(file) img.src = _URL.createObjectURL(file)
}) })
} }
export const isImageTag = (tag) => {
tag = tag.toLowerCase()
if (tag == 'jpg' || tag == 'png' || tag == 'webp' || tag == 'gif' || tag == 'jpeg') {
return true
}
return false
}
export const isVideoTag = (tag) => {
tag = tag.toLowerCase()
if (tag == 'mp4' || tag == 'ogg' || tag == 'webm') {
return true
}
return false
}

View File

@ -96,33 +96,25 @@
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="图片(首张图可用来做栏目列表用)" prop="imgs"> <el-form-item label="图片(首张图可用来做栏目列表用)" prop="imgs">
<ChooseImg ref="chooseImg" category="article_imgs" size="800px" @on-select="handleSelectImg" /> <ChooseImg ref="chooseImg" category="article_imgs" size="820px" @on-select="handleSelectImg" />
<template #label> <template #label>
<div style="margin-bottom: 10px;">图片首张图可用来做栏目列表用</div> <div style="margin-bottom: 10px;">图片首张图可用来做栏目列表用</div>
<div class="flex gap-3"> <div class="flex gap-3">
<el-button type="success" plain icon="folder" @click="handleChooseImg">媒体库</el-button> <el-button type="success" plain icon="folder" @click="handleChooseImg">媒体库</el-button>
<upload-common class="upload-btn-media-library" category="article_imgs" <upload-common class="upload-btn-media-library" category="article_imgs"
@on-success="handleImgUpload" /> @on-success="handleImgUpload" />
<el-tooltip effect="dark" content="图片超过 512K 或者 长宽 > 1080 会自动压缩后再上传" placement="top-start">
<upload-image :file-size="512" :max-w-h="1080" category="article_imgs"
@on-success="handleImgUpload" />
</el-tooltip>
</div> </div>
</template> </template>
<div class="media"> <div class="gva-media-card">
<div v-for="(item, key) in imgFileList" :key="key" class="media-box"> <div v-for="(item, key) in imgFileList" :key="key" class="media-box">
<div class="img-box-list">
<el-image :key="key" :src="getUrl(item.url)" fit="cover" :preview-src-list="[getUrl(item.url)]" <el-image :key="key" :src="getUrl(item.url)" fit="cover" :preview-src-list="[getUrl(item.url)]"
hide-on-click-modal style="width: 138px; height: 138px;"> hide-on-click-modal style="width: 138px; height: 138px;">
<template #error> <template #error>
<div class="img-box-list">
<el-icon> <el-icon>
<picture /> <picture />
</el-icon> </el-icon>
</div>
</template> </template>
</el-image> </el-image>
</div>
<div class="img-title"> <div class="img-title">
<el-button size="small" type="default" icon="delete" @click="handleImgRemove(item)">删除</el-button> <el-button size="small" type="default" icon="delete" @click="handleImgRemove(item)">删除</el-button>
</div> </div>
@ -484,10 +476,3 @@ const handleFormClose = () => {
// //
defineExpose({ openPage }) defineExpose({ openPage })
</script> </script>
<style type="scss">
.img-item {
width: 90px;
height: 90px;
}
</style>

View File

@ -20,10 +20,10 @@
<el-table :data="tableData"> <el-table :data="tableData">
<el-table-column align="left" fixed label="预览" width="150"> <el-table-column align="left" fixed label="预览" width="150">
<template #default="scope"> <template #default="scope">
<el-image v-if="isImage(scope.row.tag)" :src="getUrl(scope.row.url)" class="gva-image" fit="contain" <el-image v-if="isImageTag(scope.row.tag)" :src="getUrl(scope.row.url)" class="gva-image" fit="contain"
:preview-src-list="[getUrl(scope.row.url)]" :preview-teleported="true" :preview-src-list="[getUrl(scope.row.url)]" :preview-teleported="true"
style="width: 120px; height: 100px;" /> style="width: 120px; height: 100px;" />
<video-viewer v-else-if="isVideo(scope.row.tag)" width="120px" height="100px" :url="scope.row.url" /> <video-viewer v-else-if="isVideoTag(scope.row.tag)" width="120px" height="100px" :url="scope.row.url" />
<div v-else class="gva-media-box" style="width: 120px; height: 100px;"> <div v-else class="gva-media-box" style="width: 120px; height: 100px;">
<el-icon :size="25"> <el-icon :size="25">
<Document /> <Document />
@ -75,7 +75,7 @@
</template> </template>
<script setup> <script setup>
import { getUrl } from '@/utils/image' import { getUrl, isImageTag, isVideoTag } from '@/utils/image'
import { getFileList, deleteFile, editFileName } from '@/api/mediaFile' import { getFileList, deleteFile, editFileName } from '@/api/mediaFile'
import { downloadImage } from '@/utils/downloadImg' import { downloadImage } from '@/utils/downloadImg'
import UploadImage from '@/components/upload/image.vue' import UploadImage from '@/components/upload/image.vue'
@ -108,22 +108,6 @@ const search = ref({})
const tableData = ref([]) const tableData = ref([])
const fullscreenLoading = ref(false) const fullscreenLoading = ref(false)
const isImage = (tag) => {
tag = tag.toLowerCase()
if (tag == 'jpg' || tag == 'png' || tag == 'webp' || tag == 'gif') {
return true
}
return false
}
const isVideo = (tag) => {
tag = tag.toLowerCase()
if (tag == 'mp4' || tag == 'ogg' || tag == 'webm') {
return true
}
return false
}
// //
const handleSizeChange = (val) => { const handleSizeChange = (val) => {
pageSize.value = val pageSize.value = val