diff --git a/src/views/common/UploadFile.vue b/src/views/common/UploadFile.vue index 4d16395..45bcdce 100644 --- a/src/views/common/UploadFile.vue +++ b/src/views/common/UploadFile.vue @@ -15,6 +15,20 @@ + +
+
+ +
{{ previewFileName }}
+
+
+
+
点击更换文件
+
或拖拽新文件到此处
+
+
+
+
+ 点击或将文件拖拽到这里上传
@@ -53,7 +67,9 @@ export default { return { files: this.fileList, previewImageUrl: '', - previewImageName: '' + previewImageName: '', + previewFileName: '', + previewFileType: '' } }, methods: { @@ -85,13 +101,18 @@ export default { this.files = fileList; - // 生成图片预览 - if (file.raw && this.isImageFile(file.raw) && fileList.length === 1) { - this.generateImagePreview(file.raw); + // 生成预览 + if (file.raw && fileList.length === 1) { + if (this.isImageFile(file.raw)) { + // 图片预览 + this.generateImagePreview(file.raw); + } else if (this.isDocumentFile(file.raw)) { + // 文档预览 + this.generateDocumentPreview(file.raw); + } } else { - // 如果不是单张图片,清除预览 - this.previewImageUrl = ''; - this.previewImageName = ''; + // 如果不是单个文件,清除预览 + this.clearPreview(); } console.log('文件列表更新:', this.files.length, '个文件'); this.$emit('file-change', this.files); @@ -122,6 +143,8 @@ export default { // 生成预览 if (this.isImageFile(newFile)) { this.generateImagePreview(newFile); + } else if (this.isDocumentFile(newFile)) { + this.generateDocumentPreview(newFile); } this.$emit('file-change', this.files); @@ -132,13 +155,17 @@ export default { handleRemove(file, fileList) { this.files = fileList; - // 如果移除了图片,清除预览 - if (fileList.length === 0 || (fileList[0] && !this.isImageFile(fileList[0].raw))) { - this.previewImageUrl = ''; - this.previewImageName = ''; - } else if (fileList.length === 1 && fileList[0] && this.isImageFile(fileList[0].raw)) { - // 如果只剩一张图片,重新生成预览 - this.generateImagePreview(fileList[0].raw); + // 根据剩余文件重新生成预览 + if (fileList.length === 0) { + this.clearPreview(); + } else if (fileList.length === 1 && fileList[0] && fileList[0].raw) { + if (this.isImageFile(fileList[0].raw)) { + this.generateImagePreview(fileList[0].raw); + } else if (this.isDocumentFile(fileList[0].raw)) { + this.generateDocumentPreview(fileList[0].raw); + } + } else { + this.clearPreview(); } this.$emit('file-change', fileList); @@ -147,20 +174,55 @@ export default { isImageFile(file) { return file && file.type && file.type.startsWith('image/'); }, + // 判断是否为文档文件 + isDocumentFile(file) { + if (!file || !file.name) return false; + const fileExtension = file.name.split('.').pop().toLowerCase(); + return ['pdf', 'doc', 'docx', 'xls', 'xlsx'].includes(fileExtension); + }, // 生成图片预览 generateImagePreview(file) { const reader = new FileReader(); reader.onload = (e) => { this.previewImageUrl = e.target.result; this.previewImageName = file.name; + // 清除文档预览 + this.previewFileName = ''; + this.previewFileType = ''; }; reader.readAsDataURL(file); }, + // 生成文档预览 + generateDocumentPreview(file) { + const fileExtension = file.name.split('.').pop().toLowerCase(); + this.previewFileName = file.name; + this.previewFileType = fileExtension; + // 清除图片预览 + this.previewImageUrl = ''; + this.previewImageName = ''; + }, + // 清除预览 + clearPreview() { + this.previewImageUrl = ''; + this.previewImageName = ''; + this.previewFileName = ''; + this.previewFileType = ''; + }, + // 获取文件图标类型 + getFileIconClass() { + const iconMap = { + 'pdf': 'el-icon-document', + 'doc': 'el-icon-document', + 'docx': 'el-icon-document', + 'xls': 'el-icon-document', + 'xlsx': 'el-icon-document' + }; + return iconMap[this.previewFileType] || 'el-icon-document'; + }, // 清空所有文件 clearFiles() { this.files = []; - this.previewImageUrl = ''; - this.previewImageName = ''; + this.clearPreview(); this.$emit('file-change', []); } }, @@ -173,6 +235,15 @@ export default { this.files[0].raw && this.isImageFile(this.files[0].raw); }, + // 是否显示文件预览 + showFilePreview() { + return this.previewFileName && + this.previewFileType && + this.files.length === 1 && + this.files[0] && + this.files[0].raw && + this.isDocumentFile(this.files[0].raw); + }, accept() { return this.uploadType.split('、').map(type => `.${type}`).join(','); }, @@ -201,9 +272,14 @@ export default { 'gif': 'image/gif', 'bmp': 'image/bmp', 'webp': 'image/webp', - 'svg': 'image/svg+xml' + 'svg': 'image/svg+xml', + 'pdf': 'application/pdf', + 'doc': 'application/msword', + 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'xls': 'application/vnd.ms-excel', + 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }; - return this.allowedTypes.map(type => typeMap[type] || `image/${type}`); + return this.allowedTypes.map(type => typeMap[type] || ''); } }, watch: { @@ -211,11 +287,14 @@ export default { handler(newVal) { this.files = newVal; // 如果外部传入文件列表,也尝试生成预览 - if (newVal.length === 1 && newVal[0] && newVal[0].raw && this.isImageFile(newVal[0].raw)) { - this.generateImagePreview(newVal[0].raw); + if (newVal.length === 1 && newVal[0] && newVal[0].raw) { + if (this.isImageFile(newVal[0].raw)) { + this.generateImagePreview(newVal[0].raw); + } else if (this.isDocumentFile(newVal[0].raw)) { + this.generateDocumentPreview(newVal[0].raw); + } } else { - this.previewImageUrl = ''; - this.previewImageName = ''; + this.clearPreview(); } }, deep: true @@ -236,7 +315,7 @@ export default { .el-upload-dragger { width: 100%; - height: 180px; + height: 240px; border: 2px dashed #DCDFE6; border-radius: 8px; background-color: #FAFAFA; @@ -262,7 +341,7 @@ export default { flex-direction: column; align-items: center; justify-content: center; - padding: 20px; + padding: 5px; // 图片预览样式 .image-preview { @@ -271,12 +350,93 @@ export default { height: 100%; border-radius: 6px; overflow: hidden; + display: flex; + align-items: center; + justify-content: center; .preview-thumbnail { + max-width: 100%; + max-height: 100%; + width: auto; + height: auto; + object-fit: contain; + display: block; + } + + .preview-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.6); + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + transition: opacity 0.3s ease; + pointer-events: none; + + .preview-text { + text-align: center; + color: white; + pointer-events: none; + + .main-text { + font-size: 16px; + margin-bottom: 8px; + font-weight: 500; + } + + .tip-text { + font-size: 12px; + opacity: 0.9; + } + } + } + + &:hover .preview-overlay { + opacity: 1; + } + } + + // 文件预览样式 + .file-preview { + position: relative; + width: 100%; + height: 100%; + border-radius: 6px; + overflow: hidden; + + .file-icon-container { width: 100%; height: 100%; - object-fit: cover; - display: block; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + background: #f9fafc; + + .file-icon { + font-size: 64px; + color: #1F72EA; + margin-bottom: 16px; + } + + .file-name { + font-size: 14px; + color: #606266; + text-align: center; + padding: 0 20px; + word-break: break-all; + max-width: 100%; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + line-clamp: 2; + -webkit-box-orient: vertical; + } } .preview-overlay { diff --git a/src/views/enterpriseLibrary/personnel/components/child/BasicInfo.vue b/src/views/enterpriseLibrary/personnel/components/child/BasicInfo.vue index 57c4df0..dbc3053 100644 --- a/src/views/enterpriseLibrary/personnel/components/child/BasicInfo.vue +++ b/src/views/enterpriseLibrary/personnel/components/child/BasicInfo.vue @@ -30,7 +30,7 @@ - + @@ -49,7 +49,7 @@ - +
diff --git a/src/views/enterpriseLibrary/personnel/components/child/OtherInfo.vue b/src/views/enterpriseLibrary/personnel/components/child/OtherInfo.vue index 188590d..4c72be3 100644 --- a/src/views/enterpriseLibrary/personnel/components/child/OtherInfo.vue +++ b/src/views/enterpriseLibrary/personnel/components/child/OtherInfo.vue @@ -7,7 +7,7 @@ - + diff --git a/src/views/enterpriseLibrary/personnel/components/child/QualificationInfo.vue b/src/views/enterpriseLibrary/personnel/components/child/QualificationInfo.vue index a1a66d9..d204ead 100644 --- a/src/views/enterpriseLibrary/personnel/components/child/QualificationInfo.vue +++ b/src/views/enterpriseLibrary/personnel/components/child/QualificationInfo.vue @@ -8,7 +8,7 @@