<template>
|
<el-dialog v-model="isShow"
|
:title="title"
|
:width="width"
|
@close="handleClose"
|
class="attachment-dialog">
|
<!-- 工具栏 -->
|
<div v-if="editable"
|
class="toolbar">
|
<el-button type="primary"
|
size="small"
|
@click="handleUpload">
|
上传附件
|
</el-button>
|
</div>
|
<!-- 上传组件弹窗 -->
|
<el-dialog v-model="uploadDialogVisible"
|
title="上传附件"
|
width="50%"
|
@close="closeUpload">
|
<AttachmentUpload v-model:file-list="newFileList" />
|
<template #footer>
|
<el-button @click="saveUpload">保存</el-button>
|
<el-button @click="closeUpload">关闭</el-button>
|
</template>
|
</el-dialog>
|
<!-- 文件列表表格 -->
|
<div class="table-container">
|
<el-table :data="tableData"
|
border
|
class="attachment-table"
|
:height="tableData.length > 0 ? 'auto' : '120px'">
|
<el-table-column label="附件名称"
|
prop="originalFilename"
|
show-overflow-tooltip />
|
<el-table-column v-if="showActions"
|
fixed="right"
|
label="操作"
|
:width="120"
|
align="center">
|
<template #default="scope">
|
<el-button link
|
type="primary"
|
size="small"
|
class="download-link"
|
@click="downloadFile(scope.row.downloadURL)">
|
下载
|
</el-button>
|
<el-button v-if="editable"
|
link
|
type="danger"
|
size="small"
|
@click="handleDelete(scope.row)">
|
删除
|
</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
</div>
|
</el-dialog>
|
</template>
|
|
<script setup>
|
import { ref, computed, getCurrentInstance, onMounted, watch } from "vue";
|
import AttachmentUpload from "@/components/AttachmentUpload/file/index.vue";
|
import {
|
attachmentList,
|
deleteAttachment,
|
createAttachment,
|
} from "@/api/basicData/storageAttachment.js";
|
|
const props = defineProps({
|
visible: {
|
type: Boolean,
|
required: true,
|
},
|
recordType: {
|
type: String,
|
default: "",
|
required: true,
|
},
|
recordId: {
|
type: Number,
|
default: 0,
|
required: true,
|
},
|
title: {
|
type: String,
|
default: "附件",
|
},
|
width: {
|
type: String,
|
default: "50%",
|
},
|
showActions: {
|
type: Boolean,
|
default: true,
|
},
|
editable: {
|
type: Boolean,
|
default: true,
|
},
|
});
|
|
const emit = defineEmits(["close", "download", "upload", "delete"]);
|
|
const { proxy } = getCurrentInstance();
|
const tableData = ref([]);
|
const uploadDialogVisible = ref(false);
|
const newFileList = ref([]);
|
|
const isShow = computed({
|
get() {
|
return props.visible;
|
},
|
set(val) {
|
emit("update:visible", val);
|
},
|
});
|
|
const handleClose = () => {
|
isShow.value = false;
|
};
|
|
const handleUpload = () => {
|
uploadDialogVisible.value = true;
|
};
|
|
const saveUpload = async () => {
|
// 检查是否有新上传的文件
|
if (newFileList.value.length > 0) {
|
try {
|
await createAttachment({
|
application: "file",
|
recordType: props.recordType,
|
recordId: props.recordId,
|
storageBlobDTOs: [...newFileList.value, ...tableData.value],
|
});
|
newFileList.value = [];
|
// 刷新列表
|
setList();
|
} catch (error) {
|
proxy?.$modal?.msgError("上传失败");
|
}
|
}
|
uploadDialogVisible.value = false;
|
};
|
|
const closeUpload = () => {
|
newFileList.value = [];
|
uploadDialogVisible.value = false;
|
};
|
|
const handleDelete = async (row, index) => {
|
try {
|
await deleteAttachment([row.storageAttachmentId]);
|
proxy?.$modal?.msgSuccess("删除成功");
|
setList();
|
} catch (error) {
|
proxy?.$modal?.msgError("删除失败");
|
}
|
};
|
|
const setList = () => {
|
attachmentList({
|
recordType: props.recordType,
|
recordId: props.recordId,
|
}).then(res => {
|
if (res && res.data) {
|
tableData.value = res.data || [];
|
}
|
});
|
};
|
|
const downloadFile = url => {
|
window.open(url, "_blank");
|
};
|
onMounted(() => {
|
setList();
|
});
|
</script>
|
|
<style scoped>
|
.attachment-dialog {
|
border-radius: 12px;
|
}
|
|
.toolbar {
|
margin-bottom: 16px;
|
text-align: right;
|
}
|
|
.table-container {
|
max-height: 40vh;
|
overflow-y: auto;
|
min-height: 120px;
|
padding-bottom: 16px;
|
box-sizing: border-box;
|
will-change: scroll-position;
|
transform: translateZ(0);
|
-webkit-overflow-scrolling: touch;
|
}
|
|
:deep(.el-table) {
|
margin-bottom: 0;
|
}
|
|
:deep(.el-table__body-wrapper) {
|
overflow-y: auto;
|
will-change: transform;
|
transform: translateZ(0);
|
}
|
|
:deep(.el-table__body tr) {
|
transition: none;
|
}
|
|
:deep(.el-dialog__footer) {
|
padding-top: 12px;
|
border-top: 1px solid #e9ecef;
|
}
|
|
.attachment-table {
|
border-radius: 8px;
|
}
|
|
:deep(.el-dialog__header) {
|
background-color: #f8f9fa;
|
border-bottom: 1px solid #e9ecef;
|
padding: 16px 20px;
|
}
|
|
:deep(.el-dialog__title) {
|
font-size: 16px;
|
font-weight: 600;
|
}
|
|
:deep(.el-dialog__body) {
|
padding: 16px 20px;
|
}
|
|
:deep(.el-table__empty-text) {
|
color: #999;
|
}
|
</style>
|