halo-admin/src/components/Attachment/AttachmentDetailModal.vue

234 lines
6.7 KiB
Vue

<template>
<a-modal v-model="modalVisible" :width="isMobile() ? '100%' : '50%'" title="附件详情">
<a-row :gutter="24" type="flex">
<a-col :lg="9" :md="24" :sm="24" :xl="9" :xs="24">
<div class="attach-detail-img pb-3">
<a v-if="isImage" :href="attachment.path" target="_blank">
<img :src="attachment.path" class="w-full" loading="lazy" />
</a>
<div v-else>此文件不支持预览</div>
</div>
</a-col>
<a-col :lg="15" :md="24" :sm="24" :xl="15" :xs="24">
<a-list itemLayout="horizontal">
<a-list-item style="padding-top: 0">
<a-list-item-meta>
<template v-if="editable" slot="description">
<a-input ref="nameInput" v-model="attachment.name" @blur="handleUpdateName" />
</template>
<template v-else slot="description">{{ attachment.name }}</template>
<span slot="title">
附件名:
<a-button class="!p-0" type="link" @click="handleEditName">
<a-icon type="edit" />
</a-button>
</span>
</a-list-item-meta>
</a-list-item>
<a-list-item>
<a-list-item-meta :description="attachment.mediaType">
<span slot="title">附件类型:</span>
</a-list-item-meta>
</a-list-item>
<a-list-item>
<a-list-item-meta :description="attachment.type | typeText">
<span slot="title">存储位置:</span>
</a-list-item-meta>
</a-list-item>
<a-list-item>
<a-list-item-meta>
<template slot="description">
{{ attachment.size | fileSizeFormat }}
</template>
<span slot="title">附件大小:</span>
</a-list-item-meta>
</a-list-item>
<a-list-item v-if="isImage">
<a-list-item-meta :description="attachment.height + 'x' + attachment.width">
<span slot="title">图片尺寸:</span>
</a-list-item-meta>
</a-list-item>
<a-list-item>
<a-list-item-meta>
<template slot="description">
{{ attachment.createTime | moment }}
</template>
<span slot="title">上传日期:</span>
</a-list-item-meta>
</a-list-item>
<a-list-item>
<a-list-item-meta>
<template #description>
<a :href="attachment.path" target="_blank">{{ attachment.path }}</a>
</template>
<span slot="title">
普通链接:
<a-button class="!p-0" type="link" @click="handleCopyLink(`${encodeURI(attachment.path)}`)">
<a-icon type="copy" />
</a-button>
</span>
</a-list-item-meta>
</a-list-item>
<a-list-item v-if="isImage">
<a-list-item-meta>
<span slot="description">![{{ attachment.name }}]({{ attachment.path }})</span>
<span slot="title">
Markdown 格式:
<a-button
class="!p-0"
type="link"
@click="handleCopyLink(`![${attachment.name}](${encodeURI(attachment.path)})`)"
>
<a-icon type="copy" />
</a-button>
</span>
</a-list-item-meta>
</a-list-item>
</a-list>
</a-col>
</a-row>
<template #footer>
<slot name="extraFooter" />
<a-popconfirm cancelText="取消" okText="确定" title="你确定要删除该附件?" @confirm="handleDelete">
<ReactiveButton
:errored="deleteErrored"
:loading="deleting"
erroredText="删除失败"
icon="delete"
loadedText="删除成功"
text="删除"
type="danger"
@callback="handleDeletedCallback"
></ReactiveButton>
</a-popconfirm>
</template>
</a-modal>
</template>
<script>
import { mixin, mixinDevice } from '@/mixins/mixin.js'
import apiClient from '@/utils/api-client'
import { attachmentTypes } from '@/core/constant'
export default {
name: 'AttachmentDetailModal',
mixins: [mixin, mixinDevice],
filters: {
typeText(type) {
return type ? attachmentTypes[type].text : ''
}
},
props: {
visible: {
type: Boolean,
default: true
},
attachment: {
type: Object,
default: () => ({})
}
},
data() {
return {
editable: false,
deleting: false,
deleteErrored: false
}
},
computed: {
modalVisible: {
get() {
return this.visible
},
set(value) {
this.$emit('update:visible', value)
}
},
isImage() {
if (!this.attachment || !this.attachment.mediaType) {
return false
}
return this.attachment.mediaType.startsWith('image')
}
},
methods: {
/**
* Deletes the attachment
*/
async handleDelete() {
try {
this.deleting = true
await apiClient.attachment.delete(this.attachment.id)
} catch (error) {
this.$log.error(error)
this.deleteErrored = true
} finally {
setTimeout(() => {
this.deleting = false
}, 400)
}
},
/**
* Handles the deletion callback event
*/
handleDeletedCallback() {
this.$emit('delete', this.attachment)
this.deleteErrored = false
this.modalVisible = false
},
/**
* Shows the edit name input
*/
handleEditName() {
this.editable = !this.editable
if (this.editable) {
this.$nextTick(() => {
this.$refs.nameInput.focus()
})
}
},
/**
* Updates the attachment name
*/
async handleUpdateName() {
if (!this.attachment.name) {
this.$notification['error']({
message: '提示',
description: '附件名称不能为空!'
})
return
}
try {
// TODO 修改 sdk 的方法为 updateName
await apiClient.attachment.update(this.attachment.id, this.attachment.name)
} catch (error) {
this.$log.error(error)
} finally {
this.editable = false
}
},
/**
* Handles the copy link event
* @param {String} link
*/
handleCopyLink(link) {
this.$copyText(link)
.then(message => {
this.$log.debug('copy', message)
this.$message.success('复制成功!')
})
.catch(err => {
this.$log.debug('copy.err', err)
this.$message.error('复制失败!')
})
}
}
}
</script>