| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- <template>
- <div class="file-selector">
- <!-- 文件选择对话框 -->
- <el-dialog
- v-model="dialogVisible"
- :title="dialogTitle"
- width="90%"
- :close-on-click-modal="false"
- class="file-selector-dialog"
- top="5vh"
- :before-close="handleClose"
- append-to-body
- :z-index="9999"
- >
- <!-- 直接嵌入文件管理页面组件 -->
- <div class="file-manager-container">
- <FileManager
- ref="fileManagerRef"
- :select-mode="true"
- :file-type="getFileTypeString()"
- :multiple="multiple"
- @file-selected="handleFileSelected"
- @files-selected="handleFilesSelected"
- />
- </div>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="handleClose">取消</el-button>
- <el-button type="primary" @click="confirmSelection" :disabled="multiple ? selectedFiles.length === 0 : !selectedFile">
- 确认选择{{ multiple ? `(${selectedFiles.length})` : '' }}
- </el-button>
- </div>
- </template>
- </el-dialog>
- </div>
- </template>
- <script setup lang="ts">
- import { ref, computed, nextTick } from 'vue';
- import { ElMessage } from 'element-plus';
- import FileManager from '@/views/file/info/index.vue';
- // Props
- interface Props {
- modelValue: boolean;
- // 允许的文件类型 [1: 图片, 2: 视频, 3: 音频, 4: 文档, 5: 其他]
- // 例如:[1] 仅显示图片类型,[1,2] 显示图片和视频类型
- allowedTypes?: number[];
- // 是否允许多选(单选/多选文件)
- multiple?: boolean;
- // 是否允许上传新文件
- allowUpload?: boolean;
- // 对话框标题
- title?: string;
- }
- const props = withDefaults(defineProps<Props>(), {
- allowedTypes: () => [1], // 默认只允许图片
- multiple: false,
- allowUpload: true,
- title: '选择文件'
- });
- // Emits
- const emit = defineEmits<{
- 'update:modelValue': [value: boolean];
- 'confirm': [files: any[]];
- }>();
- // 响应式数据
- const dialogVisible = computed({
- get: () => props.modelValue,
- set: (value) => emit('update:modelValue', value)
- });
- const dialogTitle = computed(() => {
- const typeText = getTypeText();
- return props.title || `选择${typeText}${props.multiple ? '(多选)' : ''}`;
- });
- const selectedFile = ref<any>(null);
- const selectedFiles = ref<any[]>([]);
- const fileManagerRef = ref();
- // 方法
- const getFileTypeString = () => {
- // 如果只有一种类型,返回对应的类型字符串
- if (props.allowedTypes.length === 1) {
- switch (props.allowedTypes[0]) {
- case 1:
- return 'image';
- case 2:
- return 'video';
- case 3:
- return 'audio';
- case 4:
- return 'document';
- default:
- return '';
- }
- }
- // 多种类型时返回空字符串,表示不限制
- return '';
- };
- const getTypeText = () => {
- if (props.allowedTypes.length === 1) {
- switch (props.allowedTypes[0]) {
- case 1:
- return '图片';
- case 2:
- return '视频';
- case 3:
- return '音频';
- case 4:
- return '文档';
- case 5:
- return '文件';
- default:
- return '文件';
- }
- }
- return '文件';
- };
- const handleClose = () => {
- selectedFile.value = null;
- selectedFiles.value = [];
- // 重置FileManager组件的选择状态
- nextTick(() => {
- if (fileManagerRef.value && fileManagerRef.value.clearSelection) {
- fileManagerRef.value.clearSelection();
- }
- });
- emit('update:modelValue', false);
- };
- // 处理文件选择(单选模式)
- const handleFileSelected = (file: any) => {
- if (props.multiple) return;
- selectedFile.value = file;
- console.log('选择的文件:', file);
- };
- // 处理多文件选择
- const handleFilesSelected = (files: any[]) => {
- if (!props.multiple) return;
- selectedFiles.value = files;
- console.log('选择的文件列表:', files);
- };
- // 确认选择
- const confirmSelection = () => {
- if (props.multiple) {
- if (selectedFiles.value.length === 0) {
- ElMessage.warning(`请选择至少一个${getTypeText()}`);
- return;
- }
- emit('confirm', selectedFiles.value);
- emit('update:modelValue', false);
- ElMessage.success(`成功选择${selectedFiles.value.length}个${getTypeText()}`);
- } else {
- if (!selectedFile.value) {
- ElMessage.warning(`请选择一个${getTypeText()}`);
- return;
- }
- emit('confirm', [selectedFile.value]);
- emit('update:modelValue', false);
- ElMessage.success(`${getTypeText()}选择成功`);
- }
- // 清空选择
- selectedFile.value = null;
- selectedFiles.value = [];
- };
- </script>
- <style scoped>
- .file-selector {
- display: inline-block;
- }
- /* 文件选择器对话框样式 */
- .file-selector-dialog :deep(.el-dialog__body) {
- padding: 0;
- height: 80vh;
- overflow: hidden;
- }
- .file-manager-container {
- height: 100%;
- overflow: hidden;
- }
- .dialog-footer {
- text-align: right;
- }
- /* 确保对话框样式正常 */
- .file-selector-dialog :deep(.el-dialog) {
- display: flex;
- flex-direction: column;
- max-height: 90vh;
- }
- .file-selector-dialog :deep(.el-dialog__header) {
- flex-shrink: 0;
- }
- .file-selector-dialog :deep(.el-dialog__footer) {
- border-top: 1px solid #ebeef5;
- padding: 15px 20px;
- flex-shrink: 0;
- }
- </style>
|