|
|
@@ -0,0 +1,237 @@
|
|
|
+<template>
|
|
|
+ <el-dialog
|
|
|
+ :title="title"
|
|
|
+ :visible.sync="dialogVisible"
|
|
|
+ width="70%"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ :z-index="9900"
|
|
|
+ :modal-append-to-body="true"
|
|
|
+ :append-to-body="true"
|
|
|
+ @close="handleClose"
|
|
|
+ >
|
|
|
+ <div class="multi-attachment-container">
|
|
|
+ <div v-if="attachments && attachments.length > 0" class="attachment-list">
|
|
|
+ <div
|
|
|
+ v-for="(filePath, index) in attachments"
|
|
|
+ :key="index"
|
|
|
+ class="attachment-item"
|
|
|
+ @click="handleAttachmentClick(filePath)"
|
|
|
+ >
|
|
|
+ <div class="attachment-icon">
|
|
|
+ <i :class="getFileIconClass(getFileName(filePath))"></i>
|
|
|
+ </div>
|
|
|
+ <div class="attachment-info">
|
|
|
+ <div
|
|
|
+ class="attachment-name"
|
|
|
+ @click="handleAttachmentClick(filePath)"
|
|
|
+ >
|
|
|
+ {{ getFileName(filePath) }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="attachment-actions">
|
|
|
+ <el-button
|
|
|
+ type="text"
|
|
|
+ icon="el-icon-download"
|
|
|
+ size="small"
|
|
|
+ @click.stop="downloadAttachment(filePath)"
|
|
|
+ >
|
|
|
+ 下载
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div v-else class="no-attachments">暂无附件</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div slot="footer" class="dialog-footer">
|
|
|
+ <el-button @click="handleClose">关闭</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ export default {
|
|
|
+ name: 'MultiAttachmentDialog',
|
|
|
+ props: {
|
|
|
+ visible: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ attachments: {
|
|
|
+ type: Array,
|
|
|
+ default: () => [],
|
|
|
+ },
|
|
|
+ title: {
|
|
|
+ type: String,
|
|
|
+ default: '查看附件',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ dialogVisible: {
|
|
|
+ get() {
|
|
|
+ return this.visible
|
|
|
+ },
|
|
|
+ set(val) {
|
|
|
+ this.$emit('update:visible', val)
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 从文件路径中提取文件名
|
|
|
+ getFileName(filePath) {
|
|
|
+ if (!filePath) return '未知文件'
|
|
|
+ const lastSlashIndex = filePath.lastIndexOf('/')
|
|
|
+ const lastBackslashIndex = filePath.lastIndexOf('\\')
|
|
|
+ const lastSeparatorIndex = Math.max(lastSlashIndex, lastBackslashIndex)
|
|
|
+ return lastSeparatorIndex > -1
|
|
|
+ ? filePath.substring(lastSeparatorIndex + 1)
|
|
|
+ : filePath
|
|
|
+ },
|
|
|
+
|
|
|
+ // 获取文件图标类名
|
|
|
+ getFileIconClass(fileName) {
|
|
|
+ const extension = fileName
|
|
|
+ .substring(fileName.lastIndexOf('.') + 1)
|
|
|
+ .toLowerCase()
|
|
|
+ switch (extension) {
|
|
|
+ case 'doc':
|
|
|
+ case 'docx':
|
|
|
+ return 'el-icon-document'
|
|
|
+ case 'xls':
|
|
|
+ case 'xlsx':
|
|
|
+ return 'el-icon-s-grid' // 使用更合适的表格图标
|
|
|
+ case 'pdf':
|
|
|
+ return 'el-icon-document-copy' // 使用更合适的PDF图标
|
|
|
+ case 'ppt':
|
|
|
+ case 'pptx':
|
|
|
+ return 'el-icon-picture' // 或使用el-icon-present
|
|
|
+ case 'jpg':
|
|
|
+ case 'jpeg':
|
|
|
+ case 'png':
|
|
|
+ case 'gif':
|
|
|
+ return 'el-icon-picture'
|
|
|
+ case 'zip':
|
|
|
+ case 'rar':
|
|
|
+ return 'el-icon-folder-opened'
|
|
|
+ default:
|
|
|
+ return 'el-icon-document'
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 处理附件点击
|
|
|
+ handleAttachmentClick(fileUrl) {
|
|
|
+ // 对文件URL进行Base64编码
|
|
|
+ const encodedUrl = encodeURIComponent(
|
|
|
+ Base64.encode(window.context.form + fileUrl)
|
|
|
+ )
|
|
|
+
|
|
|
+ // 构建 kkFileView 预览URL
|
|
|
+ // onlinePreview - 在线预览
|
|
|
+ // onlinePreview?type=pdf - 强制使用PDF模式预览
|
|
|
+ window.open(`${host}:8012/onlinePreview?url=${encodedUrl}`)
|
|
|
+ },
|
|
|
+
|
|
|
+ // 下载附件
|
|
|
+ downloadAttachment(filePath) {
|
|
|
+ const fileName = this.getFileName(filePath)
|
|
|
+ if (filePath) {
|
|
|
+ // 创建临时下载链接
|
|
|
+ const link = document.createElement('a')
|
|
|
+ // 如果文件路径不是完整URL,可能需要拼接基础URL
|
|
|
+ link.href = filePath.startsWith('http')
|
|
|
+ ? filePath
|
|
|
+ : window.context.form + filePath
|
|
|
+ link.download = fileName
|
|
|
+ document.body.appendChild(link)
|
|
|
+ link.click()
|
|
|
+ document.body.removeChild(link)
|
|
|
+ } else {
|
|
|
+ this.$message.warning('无法获取下载链接')
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 关闭弹窗
|
|
|
+ handleClose() {
|
|
|
+ this.$emit('close')
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+ .multi-attachment-container {
|
|
|
+ max-height: 60vh;
|
|
|
+ overflow-y: auto;
|
|
|
+ }
|
|
|
+
|
|
|
+ .attachment-list {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .attachment-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding: 12px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+
|
|
|
+ .attachment-icon {
|
|
|
+ width: 30px;
|
|
|
+ height: 30px;
|
|
|
+ background-color: $base-color-default;
|
|
|
+ color: white;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ border-radius: 4px;
|
|
|
+ margin-right: 12px;
|
|
|
+ font-size: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .attachment-info {
|
|
|
+ flex: 1;
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+
|
|
|
+ .attachment-name {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 500;
|
|
|
+ color: #303133;
|
|
|
+ margin-bottom: 4px;
|
|
|
+ white-space: nowrap;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ &:hover {
|
|
|
+ color: $base-color-default;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .attachment-meta {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #909399;
|
|
|
+ display: flex;
|
|
|
+ gap: 16px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .attachment-actions {
|
|
|
+ margin-left: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .no-attachments {
|
|
|
+ text-align: center;
|
|
|
+ padding: 40px 0;
|
|
|
+ color: #909399;
|
|
|
+ }
|
|
|
+
|
|
|
+ .pagination-container {
|
|
|
+ margin-top: 20px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ }
|
|
|
+
|
|
|
+ .dialog-footer {
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+</style>
|