180 lines
6.1 KiB
Vue
180 lines
6.1 KiB
Vue
<template>
|
||
<div class="page-wrapper">
|
||
<el-alert type="info" show-icon :closable="false" >
|
||
<template #title>上传要求</template>
|
||
图片格式为{{allowUploadExt.join('、')}},文件大小不超过10MB。
|
||
</el-alert>
|
||
<div class="btn-container" style="margin-top:10px;">
|
||
<el-upload
|
||
action="/api/source-image/upload"
|
||
accept="image/jpeg,image/png,image/svg+xml,image/x-icon"
|
||
name="image"
|
||
:headers="{token: store.state.loginInfo.token}"
|
||
:before-upload="beforeUpload"
|
||
:on-success="uploadSuccess"
|
||
:on-error="uploadError"
|
||
auto-upload
|
||
:show-file-list="false"
|
||
style="display: inline-block;margin-right: 10px;">
|
||
<el-button type="primary" icon="Upload" :loading="isUploading">上传图片</el-button>
|
||
</el-upload>
|
||
<el-button type="danger" @click="deleteAll" style="vertical-align: bottom">批量删除</el-button>
|
||
</div>
|
||
<div class="table-container">
|
||
<el-table :data="sourceImageData" v-loading="loading" stripe @selection-change="dataSelect">
|
||
<el-table-column type="selection" width="55" />
|
||
<el-table-column prop="hash" label="md5" width="300" />
|
||
<el-table-column prop="size" label="文件大小" >
|
||
<template #default="scope">
|
||
{{ prettyBytes(scope.row.size) }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="mime" label="MIME" />
|
||
<el-table-column prop="label" label="标签" >
|
||
<template #default="scope">
|
||
<el-tag v-for="label in scope.row.label" :key="label" effect="plain">{{label}}</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="created_at" label="上传时间" >
|
||
<template #default="scope">
|
||
{{ datetimeFormat(scope.row.created_at) }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" >
|
||
<template #default="scope">
|
||
<el-button link icon="EditPen" type="primary" plain @click="modifyTags(scope.row)" title="修改标签"></el-button>
|
||
<el-button link icon="View" plain @click="preview(scope.row)" title="预览"></el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</div>
|
||
<div class="page-container">
|
||
<el-pagination background
|
||
:page-sizes="store.state.pageSizeOpts"
|
||
:layout="store.state.pageLayout"
|
||
:current-page="search.pageNum"
|
||
:total="total"
|
||
@size-change="pageSizeChange"
|
||
@current-change="pageChange">
|
||
</el-pagination>
|
||
</div>
|
||
<el-dialog v-model="modifyModal" title="修改标签" width="630px" @closed="loadData">
|
||
<el-transfer
|
||
v-model="curModifyLabels"
|
||
filterable
|
||
:render-content="renderFunc"
|
||
:titles="['可选标签', '已选标签']"
|
||
:format="{
|
||
noChecked: '${total}',
|
||
hasChecked: '${checked}/${total}',
|
||
}"
|
||
@change="tarnsferChange"
|
||
:data="labels"
|
||
></el-transfer>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
<script setup lang="ts">
|
||
import { ref, computed, h } from 'vue'
|
||
import { useStore } from 'vuex'
|
||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||
import prettyBytes from 'pretty-bytes'
|
||
import { MsgResult, Page } from '@/model/common.dto'
|
||
import { useBaseList } from '@/model/baselist'
|
||
import { SourceImageModel } from '@/model/api/source-image'
|
||
import http from '@/utils/http'
|
||
|
||
const store = useStore()
|
||
const { loading, total, search, setLoadData, pageChange, pageSizeChange, datetimeFormat } = useBaseList(new Page())
|
||
|
||
const allowUploadExt = ['jpg', 'jpeg', 'png', 'svg', 'ico']
|
||
const sourceImageData = ref<SourceImageModel[]>([])
|
||
const curModifyLabels = ref<string[]>([])
|
||
const labelList = ref<string[]>([])
|
||
const curId = ref<string | null>(null)
|
||
const modifyModal = ref(false)
|
||
const isUploading = ref(false)
|
||
|
||
function renderFunc(h: Function, option: any) {
|
||
return h('span', null, option.label)
|
||
}
|
||
const labels = computed(() => {
|
||
return labelList.value.map(item => {
|
||
return { key: item, label: item }
|
||
})
|
||
})
|
||
|
||
let selectedData: string[] = []
|
||
|
||
async function loadData(): Promise<void> {
|
||
loading.value = true
|
||
const data = await http.get<Page, any>('/api/v2/source-image/list', {params: search})
|
||
selectedData = []
|
||
loading.value = false
|
||
total.value = data.total
|
||
sourceImageData.value = data.data
|
||
}
|
||
setLoadData(loadData)
|
||
|
||
function deleteAll(): void {
|
||
if (!selectedData.length) {
|
||
ElMessage.warning('请选择要删除的数据')
|
||
return
|
||
}
|
||
ElMessageBox.confirm(`是否确认删除选中的${selectedData.length}条数据?`, '确认删除', {type: 'warning'}).then(async () => {
|
||
await http.delete('/api/v2/source-image/delete', {params: {_ids: selectedData}})
|
||
ElMessage.success('删除成功')
|
||
loadData()
|
||
}).catch(() => {})
|
||
}
|
||
function dataSelect(selection: SourceImageModel[]): void {
|
||
selectedData = selection.map(item => item._id)
|
||
}
|
||
function beforeUpload(file: File): boolean {
|
||
if (file.size > 10 << 20) {
|
||
ElMessage.warning('文件大小超过10MB')
|
||
return false
|
||
}
|
||
isUploading.value = true
|
||
return true
|
||
}
|
||
function uploadSuccess(response: MsgResult): void {
|
||
if (response.status) {
|
||
ElMessage.success(response.message)
|
||
loadData()
|
||
} else {
|
||
ElMessage.warning(response.message)
|
||
}
|
||
isUploading.value = false
|
||
}
|
||
function uploadError(error: Error): void {
|
||
isUploading.value = false
|
||
ElMessage.error(error.message)
|
||
}
|
||
function preview(row: SourceImageModel): void {
|
||
ElMessageBox({
|
||
title: '图片预览',
|
||
message: h('img', { style: `width:500px`, src: `/api/v2/common/randomBg?id=${row._id}` }, ''),
|
||
showCancelButton: false,
|
||
confirmButtonText: '关闭',
|
||
customStyle: {width: '530px', maxWidth: 'unset'}
|
||
}).catch(() => {})
|
||
}
|
||
function modifyTags(item: SourceImageModel): void {
|
||
curModifyLabels.value.length = 0
|
||
if (item.label) {
|
||
curModifyLabels.value.push(...item.label)
|
||
}
|
||
curId.value = item._id
|
||
modifyModal.value = true
|
||
}
|
||
async function tarnsferChange(newTargetKeys: string[], direction: 'right' | 'left', moveKeys: string[]) {
|
||
await http.post('/api/v2/source-image/updateLabel', {id: curId.value, labels: newTargetKeys})
|
||
}
|
||
|
||
// created
|
||
http.get<never, any>('/api/v2/common/config/image_label').then(data => {
|
||
labelList.value.push(...data)
|
||
loadData()
|
||
})
|
||
</script> |