| | |
| | | prop="organizerName" |
| | | label="组织者" |
| | | width="120" |
| | | /> |
| | | ><template #default="scope"> |
| | | <span>{{ scope.organizerName || scope.createBy }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | align="center" |
| | | prop="locationName" |
| | |
| | | </div> |
| | | |
| | | <!-- 会议纪要附件展示 --> |
| | | <div class="detail-attachments"> |
| | | <div |
| | | class="minutes-attachments" |
| | | v-if=" |
| | | currentRecord.recordattachment && |
| | | parseAttachments(currentRecord.recordattachment).length > 0 |
| | | " |
| | | v-if="parseAttachments(currentRecord.recordattachment).length > 0" |
| | | class="attachment-grid" |
| | | > |
| | | <el-divider content-position="left">会议纪要附件</el-divider> |
| | | <div class="attachment-list"> |
| | | <div |
| | | v-for="file in parseAttachments(currentRecord.recordattachment)" |
| | | :key="file.id || file.name" |
| | | class="attachment-item" |
| | | class="attachment-card" |
| | | > |
| | | <el-link |
| | | type="primary" |
| | | :href="file.url" |
| | | target="_blank" |
| | | class="file-link" |
| | | <template v-if="isImageFile(file)"> |
| | | <!-- 图片使用 el-image 预览 --> |
| | | <el-image |
| | | class="image-attachment" |
| | | :src="getFileUrl(file)" |
| | | :preview-src-list="getImagePreviewList(file)" |
| | | fit="cover" |
| | | :style="{ width: imageSize, height: imageSize }" |
| | | lazy |
| | | > |
| | | <div slot="error" class="image-error"> |
| | | <i class="el-icon-picture-outline"></i> |
| | | <span>加载失败</span> |
| | | </div> |
| | | <div slot="placeholder" class="image-loading"> |
| | | <i class="el-icon-loading"></i> |
| | | </div> |
| | | </el-image> |
| | | <div class="image-info"> |
| | | <div class="file-name" :title="file.name"> |
| | | {{ file.name }} |
| | | </div> |
| | | <div class="file-actions"> |
| | | <el-button |
| | | type="text" |
| | | size="mini" |
| | | @click="handleDownload(file)" |
| | | icon="el-icon-download" |
| | | title="下载" |
| | | /> |
| | | <el-button |
| | | type="text" |
| | | size="mini" |
| | | @click="handlePreview(file)" |
| | | icon="el-icon-view" |
| | | title="预览" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <template v-else> |
| | | <!-- 非图片文件保持原有样式 --> |
| | | <el-card shadow="hover" class="file-card"> |
| | | <div class="file-content"> |
| | | <i |
| | | :class="getFileIcon(file.type || file.name)" |
| | | style="margin-right: 8px;" |
| | | class="file-icon" |
| | | ></i> |
| | | <div class="file-info"> |
| | | <div class="file-name" :title="file.name"> |
| | | {{ file.name }} |
| | | <span class="file-size" v-if="file.size" |
| | | >({{ formatFileSize(file.size) }})</span |
| | | </div> |
| | | <div class="file-meta"> |
| | | <span class="file-type">{{ |
| | | getFileTypeText(file) |
| | | }}</span> |
| | | <span class="file-size" v-if="file.size"> |
| | | {{ formatFileSize(file.size) }} |
| | | </span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="file-actions" v-if="file.url"> |
| | | <el-button |
| | | type="text" |
| | | size="mini" |
| | | @click="handleDownload(file)" |
| | | > |
| | | </el-link> |
| | | 下载 |
| | | </el-button> |
| | | <el-button |
| | | v-if="canPreview(file)" |
| | | type="text" |
| | | size="mini" |
| | | @click="handlePreview(file)" |
| | | > |
| | | 预览 |
| | | </el-button> |
| | | </div> |
| | | </el-card> |
| | | </template> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | </el-descriptions-item> |
| | | |
| | | <!-- 会议附件 --> |
| | | 我理解您的需求,您希望将会议附件中的图片文件以el-image的预览图形式展示,其他文件类型保持原有的展示方式。让我修改这部分代码: |
| | | <el-descriptions-item label="会议附件" :span="2"> |
| | | <div class="detail-attachments"> |
| | | <div |
| | |
| | | " |
| | | class="attachment-grid" |
| | | > |
| | | <!-- 图片附件 - 使用 el-image 预览形式 --> |
| | | <div |
| | | v-for="file in parseAttachments(currentRecord.attachment)" |
| | | :key="file.id || file.name" |
| | | class="attachment-card" |
| | | > |
| | | <template v-if="isImageFile(file)"> |
| | | <!-- 图片使用 el-image 预览 --> |
| | | <el-image |
| | | class="image-attachment" |
| | | :src="getFileUrl(file)" |
| | | :preview-src-list="getImagePreviewList(file)" |
| | | fit="cover" |
| | | :style="{ width: imageSize, height: imageSize }" |
| | | lazy |
| | | > |
| | | <div slot="error" class="image-error"> |
| | | <i class="el-icon-picture-outline"></i> |
| | | <span>加载失败</span> |
| | | </div> |
| | | <div slot="placeholder" class="image-loading"> |
| | | <i class="el-icon-loading"></i> |
| | | </div> |
| | | </el-image> |
| | | <div class="image-info"> |
| | | <div class="file-name" :title="file.name"> |
| | | {{ file.name }} |
| | | </div> |
| | | <div class="file-actions"> |
| | | <el-button |
| | | type="text" |
| | | size="mini" |
| | | @click="handleDownload(file)" |
| | | icon="el-icon-download" |
| | | title="下载" |
| | | /> |
| | | <el-button |
| | | type="text" |
| | | size="mini" |
| | | @click="handlePreview(file)" |
| | | icon="el-icon-view" |
| | | title="预览" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <template v-else> |
| | | <!-- 非图片文件保持原有样式 --> |
| | | <el-card shadow="hover" class="file-card"> |
| | | <div class="file-content"> |
| | | <i |
| | |
| | | {{ file.name }} |
| | | </div> |
| | | <div class="file-meta"> |
| | | <span class="file-size" v-if="file.size">{{ |
| | | formatFileSize(file.size) |
| | | <span class="file-type">{{ |
| | | getFileTypeText(file) |
| | | }}</span> |
| | | <span class="file-size" v-if="file.size"> |
| | | {{ formatFileSize(file.size) }} |
| | | </span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | type="text" |
| | | size="mini" |
| | | @click="handleDownload(file)" |
| | | >下载</el-button |
| | | > |
| | | 下载 |
| | | </el-button> |
| | | <el-button |
| | | v-if="canPreview(file)" |
| | | type="text" |
| | | size="mini" |
| | | @click="handlePreview(file)" |
| | | > |
| | | 预览 |
| | | </el-button> |
| | | </div> |
| | | </el-card> |
| | | </template> |
| | | </div> |
| | | </div> |
| | | <div v-else class="no-attachment"> |
| | |
| | | <el-dialog |
| | | :title="`${isEditing ? '编辑' : '新增'}会议`" |
| | | :visible.sync="editDialogVisible" |
| | | width="700px" |
| | | width="800px" |
| | | :before-close="handleEditClose" |
| | | > |
| | | <el-form |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="会议地点" prop="locationId"> |
| | | <el-form-item label="会议地点" prop="locationName"> |
| | | <el-select |
| | | v-model="editForm.locationId" |
| | | v-model="editForm.locationName" |
| | | placeholder="请选择会议地点" |
| | | style="width: 100%" |
| | | > |
| | | <el-option label="第一会议室" :value="1" /> |
| | | <el-option label="第二会议室" :value="2" /> |
| | | <el-option label="第三会议室" :value="3" /> |
| | | <el-option label="线上会议" :value="4" /> |
| | | <el-option label="第一会议室" value="第一会议室" /> |
| | | <el-option label="第二会议室" value="第二会议室" /> |
| | | <el-option label="第三会议室" value="第三会议室" /> |
| | | <el-option label="线上会议" value="线上会议" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | |
| | |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <!-- 修改会议附件部分 --> |
| | | <el-form-item label="会议附件"> |
| | | <div class="attachment-upload-section"> |
| | | <div class="upload-tip">上传会议相关资料文件</div> |
| | | <el-upload |
| | | class="attachment-upload" |
| | | action="#" |
| | | :auto-upload="false" |
| | | :on-change="handleAttachmentChange" |
| | | :file-list="editForm.attachmentFiles" |
| | | :limit="10" |
| | | multiple |
| | | <div class="attachment-section"> |
| | | <div class="attachment-header"> |
| | | <i class="el-icon-paperclip"></i> |
| | | <span class="attachment-title">会议附件上传</span> |
| | | <span class="attachment-tip" |
| | | >支持上传文档、图片等文件 (最多{{ attachmentLimit }}个)</span |
| | | > |
| | | <el-button size="small" type="primary" icon="el-icon-upload"> |
| | | 上传会议附件 |
| | | </el-button> |
| | | <div slot="tip" class="el-upload__tip"> |
| | | 支持文档、图片等格式,单个文件不超过20MB |
| | | </div> |
| | | </el-upload> |
| | | |
| | | <!-- 使用 UploadAttachment 组件 --> |
| | | <UploadAttachment |
| | | ref="uploadAttachment" |
| | | :file-list="attachmentFileList" |
| | | :limit="attachmentLimit" |
| | | :accept="attachmentAccept" |
| | | @change="handleAttachmentChange" |
| | | @upload-success="handleAttachmentUploadSuccess" |
| | | @upload-error="handleAttachmentUploadError" |
| | | @remove="handleAttachmentRemove" |
| | | /> |
| | | </div> |
| | | |
| | | <!-- 会议附件列表 --> |
| | | <div |
| | | v-if=" |
| | | editForm.attachmentFiles && editForm.attachmentFiles.length > 0 |
| | | " |
| | | class="uploaded-files" |
| | | class="attachment-list" |
| | | v-if="editForm.attachment && editForm.attachment.length > 0" |
| | | > |
| | | <div |
| | | v-for="(file, index) in editForm.attachmentFiles" |
| | | :key="file.uid || index" |
| | | class="file-item" |
| | | <div class="list-title"> |
| | | 已上传附件 ({{ editForm.attachment.length }}) |
| | | </div> |
| | | <el-table |
| | | :data="editForm.attachment" |
| | | style="width: 100%" |
| | | size="small" |
| | | border |
| | | > |
| | | <span class="file-name">{{ file.name }}</span> |
| | | <el-table-column label="文件名" min-width="200"> |
| | | <template #default="scope"> |
| | | <i |
| | | class="el-icon-document" |
| | | style="margin-right: 8px; color: #409EFF;" |
| | | ></i> |
| | | <span class="file-name">{{ scope.row.name }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="文件类型" width="100"> |
| | | <template #default="scope"> |
| | | <el-tag size="small">{{ |
| | | getFileType(scope.row.name) |
| | | }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="文件大小" width="100"> |
| | | <template #default="scope"> |
| | | <span>{{ formatFileSize(scope.row.size) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width="200"> |
| | | <template #default="scope"> |
| | | <el-button |
| | | type="text" |
| | | size="mini" |
| | | @click="handleRemoveAttachmentFile(index)" |
| | | style="color: #F56C6C;" |
| | | type="primary" |
| | | @click="handlePreviewAttachment(scope.row)" |
| | | > |
| | | 预览 |
| | | </el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="danger" |
| | | @click="handleRemoveMeetingAttachment(scope.$index)" |
| | | > |
| | | 删除 |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </el-form-item> |
| | | |
| | |
| | | </div> |
| | | </el-form-item> |
| | | |
| | | <!-- 修改会议纪要附件部分 --> |
| | | <el-form-item label="纪要附件"> |
| | | <div class="attachment-upload-section"> |
| | | <div class="upload-tip">上传与会议纪要相关的补充材料</div> |
| | | <el-upload |
| | | class="minutes-upload" |
| | | action="#" |
| | | :auto-upload="false" |
| | | :on-change="handleMinutesAttachmentChange" |
| | | :file-list="editForm.recordattachmentFiles" |
| | | :limit="5" |
| | | multiple |
| | | <div class="attachment-section"> |
| | | <div class="attachment-header"> |
| | | <i class="el-icon-paperclip"></i> |
| | | <span class="attachment-title">纪要附件上传</span> |
| | | <span class="attachment-tip" |
| | | >支持上传与纪要相关的补充材料 (最多{{ |
| | | minutesAttachmentLimit |
| | | }}个)</span |
| | | > |
| | | <el-button size="small" type="primary" icon="el-icon-upload"> |
| | | 上传纪要附件 |
| | | </el-button> |
| | | <div slot="tip" class="el-upload__tip"> |
| | | 支持图片、文档等格式,单个文件不超过10MB |
| | | </div> |
| | | </el-upload> |
| | | |
| | | <UploadAttachment |
| | | ref="uploadMinutesAttachment" |
| | | :file-list="minutesAttachmentFileList" |
| | | :limit="minutesAttachmentLimit" |
| | | :accept="minutesAttachmentAccept" |
| | | @change="handleMinutesAttachmentChange" |
| | | @upload-success="handleMinutesUploadSuccess" |
| | | @upload-error="handleMinutesUploadError" |
| | | @remove="handleMinutesAttachmentRemove" |
| | | /> |
| | | </div> |
| | | |
| | | <div |
| | | class="attachment-list" |
| | | v-if=" |
| | | editForm.recordattachment && editForm.recordattachment.length > 0 |
| | | " |
| | | > |
| | | <div class="list-title"> |
| | | 已上传纪要附件 ({{ editForm.recordattachment.length }}) |
| | | </div> |
| | | <el-table |
| | | :data="editForm.recordattachment" |
| | | style="width: 100%" |
| | | size="small" |
| | | border |
| | | > |
| | | <el-table-column label="文件名" min-width="200"> |
| | | <template #default="scope"> |
| | | <i |
| | | class="el-icon-document" |
| | | style="margin-right: 8px; color: #409EFF;" |
| | | ></i> |
| | | <span class="file-name">{{ scope.row.name }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="文件类型" width="100"> |
| | | <template #default="scope"> |
| | | <el-tag size="small">{{ |
| | | getFileType(scope.row.name) |
| | | }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="文件大小" width="100"> |
| | | <template #default="scope"> |
| | | <span>{{ formatFileSize(scope.row.size) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width="200"> |
| | | <template #default="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="primary" |
| | | @click="handlePreviewMinutesAttachment(scope.row)" |
| | | > |
| | | 预览 |
| | | </el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="danger" |
| | | @click="handleRemoveMinutesAttachment(scope.$index)" |
| | | > |
| | | 删除 |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </el-form-item> |
| | | |
| | |
| | | </el-button> |
| | | </span> |
| | | </el-dialog> |
| | | <!-- 文件预览弹窗 --> |
| | | <FilePreviewDialog |
| | | :visible="previewVisible" |
| | | :file="currentPreviewFile" |
| | | @close="previewVisible = false" |
| | | @download="handleDownload" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | meetingDel, |
| | | exporremeeting |
| | | } from "@/api/officeManagementApi"; |
| | | |
| | | import UploadAttachment from "@/components/UploadAttachment"; |
| | | import FilePreviewDialog from "@/components/FilePreviewDialog"; |
| | | import dayjs from "dayjs"; |
| | | export default { |
| | | name: "MeetingManagement", |
| | | components: { |
| | | UploadAttachment, |
| | | FilePreviewDialog |
| | | }, |
| | | data() { |
| | | return { |
| | | // 查询参数 |
| | |
| | | isEditing: false, |
| | | // 表格数据 |
| | | tableData: [], |
| | | imageSize: "100px", // 图片显示大小 |
| | | // 编辑表单数据 |
| | | editForm: this.getDefaultFormData(), |
| | | // 表单验证规则 |
| | |
| | | reminderMinutes: [ |
| | | { required: true, message: "请输入提前提醒时间", trigger: "blur" } |
| | | ] |
| | | } |
| | | }, |
| | | // 附件相关配置 |
| | | attachmentLimit: 10, |
| | | minutesAttachmentLimit: 5, |
| | | attachmentAccept: |
| | | ".pdf,.jpg,.jpeg,.png,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.zip,.rar", |
| | | minutesAttachmentAccept: ".pdf,.jpg,.jpeg,.png,.doc,.docx,.xls,.xlsx", |
| | | |
| | | // 文件预览相关 |
| | | previewVisible: false, |
| | | currentPreviewFile: null, |
| | | |
| | | // 附件文件列表 |
| | | attachmentFileList: [], |
| | | minutesAttachmentFileList: [], |
| | | |
| | | // 编辑表单数据 - 修改默认值 |
| | | editForm: this.getDefaultFormData() |
| | | }; |
| | | }, |
| | | mounted() { |
| | |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | // 修改获取文件类型方法 |
| | | getFileType(fileName) { |
| | | if (!fileName) return "other"; |
| | | const extension = fileName |
| | | .split(".") |
| | | .pop() |
| | | .toLowerCase(); |
| | | const imageTypes = ["jpg", "jpeg", "png", "gif", "bmp", "webp"]; |
| | | const pdfTypes = ["pdf"]; |
| | | const officeTypes = ["doc", "docx", "xls", "xlsx", "ppt", "pptx"]; |
| | | const zipTypes = ["zip", "rar"]; |
| | | |
| | | if (imageTypes.includes(extension)) return "image"; |
| | | if (pdfTypes.includes(extension)) return "pdf"; |
| | | if (officeTypes.includes(extension)) return "office"; |
| | | if (zipTypes.includes(extension)) return "archive"; |
| | | return "other"; |
| | | }, |
| | | // 判断是否为图片文件 |
| | | isImageFile(file) { |
| | | if (!file || !file.name) return false; |
| | | const imageExtensions = [ |
| | | "jpg", |
| | | "jpeg", |
| | | "png", |
| | | "gif", |
| | | "bmp", |
| | | "webp", |
| | | "svg" |
| | | ]; |
| | | const extension = file.name |
| | | .split(".") |
| | | .pop() |
| | | .toLowerCase(); |
| | | return imageExtensions.includes(extension); |
| | | }, |
| | | |
| | | // 获取文件URL |
| | | getFileUrl(file) { |
| | | return file.url || file.path || file.fileUrl || ""; |
| | | }, |
| | | |
| | | // 获取图片预览列表 |
| | | getImagePreviewList(file) { |
| | | const url = this.getFileUrl(file); |
| | | if (!url) return []; |
| | | return [url]; |
| | | }, |
| | | // 获取文件类型文本 |
| | | getFileTypeText(file) { |
| | | if (!file.name) return "文件"; |
| | | const ext = file.name |
| | | .split(".") |
| | | .pop() |
| | | .toLowerCase(); |
| | | const typeMap = { |
| | | pdf: "PDF文档", |
| | | doc: "Word文档", |
| | | docx: "Word文档", |
| | | xls: "Excel表格", |
| | | xlsx: "Excel表格", |
| | | ppt: "PPT演示", |
| | | pptx: "PPT演示", |
| | | zip: "压缩包", |
| | | rar: "压缩包", |
| | | txt: "文本文档", |
| | | jpg: "图片", |
| | | jpeg: "图片", |
| | | png: "图片", |
| | | gif: "图片" |
| | | }; |
| | | return typeMap[ext] || "文件"; |
| | | }, |
| | | |
| | | // 判断文件是否可以预览 |
| | | canPreview(file) { |
| | | if (!file.name) return false; |
| | | const previewableExtensions = ["pdf", "jpg", "jpeg", "png", "gif", "txt"]; |
| | | const extension = file.name |
| | | .split(".") |
| | | .pop() |
| | | .toLowerCase(); |
| | | return previewableExtensions.includes(extension); |
| | | }, |
| | | |
| | | // 文件预览 |
| | | handlePreview(file) { |
| | | this.currentPreviewFile = { |
| | | fileName: file.name, |
| | | fileUrl: this.getFileUrl(file), |
| | | fileType: this.getFileType(file.name) |
| | | }; |
| | | this.previewVisible = true; |
| | | }, |
| | | // 附件转换为上传文件列表 |
| | | parseAttachmentToFileList(attachments) { |
| | | if (!attachments || !Array.isArray(attachments)) return []; |
| | | return attachments.map((item, index) => ({ |
| | | uid: item.id || `attachment-${index}-${Date.now()}`, |
| | | name: item.name || item.fileName, |
| | | url: item.url || item.path || item.fileUrl, |
| | | size: item.size, |
| | | status: "success" |
| | | })); |
| | | }, |
| | | // 获取文件图标 |
| | | getFileIcon(fileName) { |
| | | if (!fileName) return "el-icon-document"; |
| | |
| | | } |
| | | }, |
| | | |
| | | // 格式化文件大小 |
| | | // 文件大小格式化 |
| | | formatFileSize(bytes) { |
| | | if (!bytes) return "0 B"; |
| | | if (!bytes || bytes === 0) return "0 B"; |
| | | const k = 1024; |
| | | const sizes = ["B", "KB", "MB", "GB"]; |
| | | const i = Math.floor(Math.log(bytes) / Math.log(k)); |
| | |
| | | try { |
| | | const response = await meetingInfo(id); |
| | | if (response.code === 200) { |
| | | this.currentRecord = response.data || {}; |
| | | const data = response.data || {}; |
| | | // 解析附件 |
| | | if (data.attachment && typeof data.attachment === "string") { |
| | | data.attachment = this.parseAttachments(data.attachment); |
| | | } |
| | | if ( |
| | | data.recordattachment && |
| | | typeof data.recordattachment === "string" |
| | | ) { |
| | | data.recordattachment = this.parseAttachments( |
| | | data.recordattachment |
| | | ); |
| | | } |
| | | this.currentRecord = data; |
| | | this.detailDialogVisible = true; |
| | | } else { |
| | | this.$message.error(response.msg || "获取详情失败"); |
| | |
| | | handleAdd() { |
| | | this.isEditing = false; |
| | | this.editForm = this.getDefaultFormData(); |
| | | this.attachmentFileList = []; |
| | | this.minutesAttachmentFileList = []; |
| | | this.editDialogVisible = true; |
| | | this.$nextTick(() => { |
| | | this.$refs.editForm && this.$refs.editForm.clearValidate(); |
| | |
| | | const response = await meetingInfo(id); |
| | | if (response.code === 200) { |
| | | this.isEditing = true; |
| | | this.currentRecord = response.data || {}; |
| | | this.editForm = { ...response.data }; |
| | | const data = response.data || {}; |
| | | |
| | | // 解析附件 |
| | | if (this.editForm.attachment) { |
| | | this.editForm.attachmentFiles = this.parseAttachments( |
| | | this.editForm.attachment |
| | | if (data.attachment) { |
| | | data.attachment = this.parseAttachments(data.attachment); |
| | | this.attachmentFileList = this.parseAttachmentToFileList( |
| | | data.attachment |
| | | ); |
| | | } |
| | | if (this.editForm.recordattachment) { |
| | | this.editForm.recordattachmentFiles = this.parseAttachments( |
| | | this.editForm.recordattachment |
| | | if (data.recordattachment) { |
| | | data.recordattachment = this.parseAttachments( |
| | | data.recordattachment |
| | | ); |
| | | this.minutesAttachmentFileList = this.parseAttachmentToFileList( |
| | | data.recordattachment |
| | | ); |
| | | } |
| | | |
| | | this.currentRecord = data; |
| | | this.editForm = { ...data }; |
| | | this.editDialogVisible = true; |
| | | this.detailDialogVisible = false; |
| | | this.$nextTick(() => { |
| | |
| | | } |
| | | }, |
| | | |
| | | // 文件上传处理 |
| | | handleAttachmentChange(file, fileList) { |
| | | this.editForm.attachmentFiles = fileList; |
| | | // 附件变化处理 |
| | | handleAttachmentChange(fileList) { |
| | | this.attachmentFileList = fileList; |
| | | }, |
| | | |
| | | handleMinutesAttachmentChange(file, fileList) { |
| | | this.editForm.recordattachmentFiles = fileList; |
| | | handleMinutesAttachmentChange(fileList) { |
| | | this.minutesAttachmentFileList = fileList; |
| | | }, |
| | | // 附件上传成功处理 |
| | | handleAttachmentUploadSuccess({ file, fileList, response }) { |
| | | if (response && response.code === 200) { |
| | | if (!this.editForm.attachment) { |
| | | this.editForm.attachment = []; |
| | | } |
| | | |
| | | console.log(file, "file"); |
| | | console.log(response, "response"); |
| | | |
| | | const attachmentObj = { |
| | | name: file.name, |
| | | url: response.data || file.url, |
| | | fileName: file.name, |
| | | size: file.size || 0, |
| | | type: this.getFileExtension(file.name), |
| | | createTime: dayjs().format("YYYY-MM-DD HH:mm:ss") |
| | | }; |
| | | console.log(this.editForm.attachment, "this.editForm.attachment"); |
| | | |
| | | this.editForm.attachment.push(attachmentObj); |
| | | console.log(this.editForm.attachment, "this.editForm.attachment"); |
| | | |
| | | this.$message.success("会议附件上传成功"); |
| | | } |
| | | }, |
| | | handleMinutesUploadSuccess({ file, fileList, response }) { |
| | | if (response && response.code === 200) { |
| | | if (!this.editForm.recordattachment) { |
| | | this.editForm.recordattachment = []; |
| | | } |
| | | |
| | | const attachmentObj = { |
| | | name: file.name, |
| | | url: response.data || file.url, |
| | | fileName: file.name, |
| | | size: file.size || 0, |
| | | type: this.getFileExtension(file.name), |
| | | createTime: dayjs().format("YYYY-MM-DD HH:mm:ss") |
| | | }; |
| | | this.editForm.recordattachment.push(attachmentObj); |
| | | this.$message.success("纪要附件上传成功"); |
| | | } |
| | | }, |
| | | // 附件上传错误处理 |
| | | handleAttachmentUploadError({ file, fileList, error }) { |
| | | console.error("会议附件上传失败:", error); |
| | | this.$message.error("文件上传失败,请重试"); |
| | | }, |
| | | |
| | | // 删除已上传的文件 |
| | | handleRemoveAttachmentFile(index) { |
| | | this.editForm.attachmentFiles.splice(index, 1); |
| | | handleMinutesUploadError({ file, fileList, error }) { |
| | | console.error("纪要附件上传失败:", error); |
| | | this.$message.error("文件上传失败,请重试"); |
| | | }, |
| | | // 附件移除处理 |
| | | handleAttachmentRemove(file) { |
| | | if (file.url && this.editForm.attachment) { |
| | | const index = this.editForm.attachment.findIndex( |
| | | item => |
| | | item.url === file.url || |
| | | item.path === file.url || |
| | | item.fileUrl === file.url |
| | | ); |
| | | if (index > -1) { |
| | | this.editForm.attachment.splice(index, 1); |
| | | } |
| | | } |
| | | }, |
| | | |
| | | handleMinutesAttachmentRemove(file) { |
| | | if (file.url && this.editForm.recordattachment) { |
| | | const index = this.editForm.recordattachment.findIndex( |
| | | item => |
| | | item.url === file.url || |
| | | item.path === file.url || |
| | | item.fileUrl === file.url |
| | | ); |
| | | if (index > -1) { |
| | | this.editForm.recordattachment.splice(index, 1); |
| | | } |
| | | } |
| | | }, |
| | | // 手动删除附件 |
| | | handleRemoveMeetingAttachment(index) { |
| | | if (this.editForm.attachment && this.editForm.attachment[index]) { |
| | | this.editForm.attachment.splice(index, 1); |
| | | this.attachmentFileList.splice(index, 1); |
| | | this.$message.success("会议附件删除成功"); |
| | | } |
| | | }, |
| | | |
| | | handleRemoveMinutesAttachment(index) { |
| | | if ( |
| | | this.editForm.recordattachment && |
| | | this.editForm.recordattachment[index] |
| | | ) { |
| | | this.editForm.recordattachment.splice(index, 1); |
| | | this.minutesAttachmentFileList.splice(index, 1); |
| | | this.$message.success("纪要附件删除成功"); |
| | | } |
| | | }, |
| | | // 文件预览 |
| | | handlePreviewAttachment(file) { |
| | | this.currentPreviewFile = { |
| | | fileName: file.name || file.fileName, |
| | | fileUrl: file.url || file.path || file.fileUrl, |
| | | fileType: this.getFileType(file.name) |
| | | }; |
| | | this.previewVisible = true; |
| | | }, |
| | | |
| | | handlePreviewMinutesAttachment(file) { |
| | | this.currentPreviewFile = { |
| | | fileName: file.name || file.fileName, |
| | | fileUrl: file.url || file.path || file.fileUrl, |
| | | fileType: this.getFileType(file.name) |
| | | }; |
| | | this.previewVisible = true; |
| | | }, |
| | | // 文件下载 |
| | | handleDownload(file) { |
| | | if (file.url) { |
| | | const link = document.createElement("a"); |
| | | link.href = file.url; |
| | | link.download = file.name; |
| | | link.download = file.name || file.fileName || "download"; |
| | | link.style.display = "none"; |
| | | document.body.appendChild(link); |
| | | link.click(); |
| | | this.$message.success(`开始下载: ${file.name}`); |
| | | document.body.removeChild(link); |
| | | this.$message.success("开始下载文件"); |
| | | } else { |
| | | this.$message.warning("文件地址不存在"); |
| | | this.$message.warning("文件地址不存在,无法下载"); |
| | | } |
| | | }, |
| | | |
| | | // 获取文件扩展名 |
| | | getFileExtension(filename) { |
| | | if (!filename) return ""; |
| | | return filename |
| | | .split(".") |
| | | .pop() |
| | | .toLowerCase(); |
| | | }, |
| | | // 保存记录 |
| | | async handleSave() { |
| | | try { |
| | |
| | | } |
| | | } |
| | | |
| | | // 检查是否有未上传完成的文件 |
| | | const pendingFiles = [ |
| | | ...this.attachmentFileList.filter(item => item.status !== "success"), |
| | | ...this.minutesAttachmentFileList.filter( |
| | | item => item.status !== "success" |
| | | ) |
| | | ]; |
| | | |
| | | if (pendingFiles.length > 0) { |
| | | this.$message.warning( |
| | | "还有文件未上传完成,请先上传所有文件或移除未上传的文件" |
| | | ); |
| | | return; |
| | | } |
| | | |
| | | this.saveLoading = true; |
| | | |
| | | // 处理附件 |
| | | // 准备数据 |
| | | const formData = { ...this.editForm }; |
| | | |
| | | if (formData.attachmentFiles) { |
| | | // 处理附件为JSON字符串 |
| | | if (formData.attachment && Array.isArray(formData.attachment)) { |
| | | formData.attachment = JSON.stringify( |
| | | formData.attachmentFiles.map(file => ({ |
| | | name: file.name, |
| | | url: file.url || "", |
| | | size: file.size || 0, |
| | | type: file.type || file.name.split(".").pop() |
| | | formData.attachment.map(item => ({ |
| | | name: item.name || item.fileName, |
| | | url: item.url || item.path || item.fileUrl, |
| | | size: item.size || 0, |
| | | type: |
| | | item.type || this.getFileExtension(item.name || item.fileName) |
| | | })) |
| | | ); |
| | | } |
| | | |
| | | if (formData.recordattachmentFiles) { |
| | | if ( |
| | | formData.recordattachment && |
| | | Array.isArray(formData.recordattachment) |
| | | ) { |
| | | formData.recordattachment = JSON.stringify( |
| | | formData.recordattachmentFiles.map(file => ({ |
| | | name: file.name, |
| | | url: file.url || "", |
| | | size: file.size || 0, |
| | | type: file.type || file.name.split(".").pop() |
| | | formData.recordattachment.map(item => ({ |
| | | name: item.name || item.fileName, |
| | | url: item.url || item.path || item.fileUrl, |
| | | size: item.size || 0, |
| | | type: |
| | | item.type || this.getFileExtension(item.name || item.fileName) |
| | | })) |
| | | ); |
| | | } |
| | | |
| | | // 清理文件列表字段 |
| | | // 清理临时字段 |
| | | delete formData.attachmentFiles; |
| | | delete formData.recordattachmentFiles; |
| | | |
| | |
| | | this.editDialogVisible = false; |
| | | this.currentRecord = {}; |
| | | this.editForm = this.getDefaultFormData(); |
| | | this.attachmentFileList = []; |
| | | this.minutesAttachmentFileList = []; |
| | | this.$nextTick(() => { |
| | | this.$refs.editForm && this.$refs.editForm.clearValidate(); |
| | | }); |
| | |
| | | console.log("排序变化:", sort); |
| | | }, |
| | | |
| | | // 获取默认表单数据 |
| | | // 默认表单数据 |
| | | getDefaultFormData() { |
| | | return { |
| | | id: null, |
| | |
| | | endTime: "", |
| | | summary: "", |
| | | content: "", |
| | | attachment: null, |
| | | attachmentFiles: [], |
| | | status: 1, // 默认待开始 |
| | | isRecurring: 0, |
| | | recurringPattern: null, |
| | | parentMeetingId: null, |
| | | reminderMinutes: 30, |
| | | attachment: [], // 改为数组 |
| | | recordcontent: "", |
| | | recordattachment: null, |
| | | recordattachmentFiles: [], |
| | | recordattachment: [], // 改为数组 |
| | | recorderBy: "", |
| | | remark: "", |
| | | approvalStatus: 0 // 默认待审核 |
| | | status: 1, |
| | | reminderMinutes: 30, |
| | | approvalStatus: 0 |
| | | }; |
| | | } |
| | | } |
| | |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .meeting-management { |
| | | padding: 20px; |
| | | } |
| | | |
| | | .attachment-section { |
| | | margin-bottom: 16px; |
| | | } |
| | | |
| | | .attachment-header { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-bottom: 16px; |
| | | padding: 8px 0; |
| | | border-bottom: 1px solid #ebeef5; |
| | | } |
| | | |
| | | .attachment-title { |
| | | font-weight: bold; |
| | | margin: 0 8px; |
| | | } |
| | | |
| | | .attachment-tip { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | } |
| | | |
| | | .attachment-list { |
| | | margin-top: 16px; |
| | | } |
| | | |
| | | .list-title { |
| | | font-weight: bold; |
| | | margin-bottom: 12px; |
| | | color: #303133; |
| | | } |
| | | /* 图片附件样式 */ |
| | | .image-attachment { |
| | | border-radius: 4px; |
| | | border: 1px solid #ebeef5; |
| | | cursor: pointer; |
| | | transition: all 0.3s; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .image-attachment:hover { |
| | | box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1); |
| | | transform: translateY(-2px); |
| | | } |
| | | |
| | | .image-info { |
| | | text-align: center; |
| | | padding: 4px 0; |
| | | } |
| | | |
| | | .image-info .file-name { |
| | | font-size: 12px; |
| | | color: #606266; |
| | | margin-bottom: 4px; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | max-width: 100px; |
| | | } |
| | | |
| | | .image-info .file-actions { |
| | | display: flex; |
| | | justify-content: center; |
| | | gap: 8px; |
| | | } |
| | | |
| | | .image-loading, |
| | | .image-error { |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | align-items: center; |
| | | height: 100%; |
| | | color: #909399; |
| | | font-size: 12px; |
| | | } |
| | | |
| | | .image-loading i, |
| | | .image-error i { |
| | | font-size: 20px; |
| | | margin-bottom: 4px; |
| | | } |
| | | |
| | | /* 文件卡片样式 */ |
| | | .file-card { |
| | | width: 100%; |
| | | min-height: 60px; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .file-content { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .file-icon { |
| | | font-size: 24px; |
| | | margin-right: 12px; |
| | | color: #409eff; |
| | | flex-shrink: 0; |
| | | } |
| | | |
| | | .file-info { |
| | | flex: 1; |
| | | min-width: 0; |
| | | } |
| | | |
| | | .file-name { |
| | | font-size: 13px; |
| | | font-weight: 500; |
| | | margin-bottom: 4px; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .file-meta { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | font-size: 12px; |
| | | color: #909399; |
| | | } |
| | | |
| | | .file-actions { |
| | | margin-top: 8px; |
| | | text-align: right; |
| | | } |
| | | |
| | | /* 附件网格布局 */ |
| | | .attachment-grid { |
| | | display: grid; |
| | | grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); |
| | | gap: 16px; |
| | | } |
| | | |
| | | .attachment-card { |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | /* 响应式调整 */ |
| | | @media (max-width: 768px) { |
| | | .attachment-grid { |
| | | grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); |
| | | gap: 12px; |
| | | } |
| | | |
| | | .image-attachment { |
| | | width: 80px !important; |
| | | height: 80px !important; |
| | | } |
| | | } |
| | | .file-name { |
| | | font-size: 13px; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | /* 其他样式保持不变 */ |
| | | .meeting-management { |
| | | padding: 20px; |
| | | } |
| | |
| | | .attachment-item { |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .minutes-content { |
| | | margin-bottom: 16px; |
| | | } |
| | |
| | | margin: 0 -20px; |
| | | } |
| | | } |
| | | |
| | | /* 响应式设计 */ |
| | | @media (max-width: 768px) { |
| | | .page-header { |
| | |
| | | justify-content: space-between; |
| | | } |
| | | } |
| | | |
| | | /* 新增附件相关样式 */ |
| | | .attachment-upload-section { |
| | | border: 1px solid #ebeef5; |