| | |
| | | /> |
| | | </div> |
| | | </el-card> |
| | | |
| | | <el-dialog |
| | | title="会议纪要" |
| | | :visible.sync="minutesDialogVisible" |
| | | width="600px" |
| | | width="700px" |
| | | > |
| | | <div v-if="currentRecord.meetingMinutes"> |
| | | <el-alert |
| | |
| | | <div class="minutes-content"> |
| | | <el-card> |
| | | <div |
| | | style="white-space: pre-line; line-height: 1.6; max-height: 400px; overflow-y: auto;" |
| | | style="white-space: pre-line; line-height: 1.6; max-height: 300px; overflow-y: auto;" |
| | | > |
| | | {{ currentRecord.meetingMinutes }} |
| | | </div> |
| | | </el-card> |
| | | </div> |
| | | |
| | | <!-- 会议纪要附件展示 --> |
| | | <div |
| | | class="minutes-attachments" |
| | | v-if=" |
| | | currentRecord.minutesAttachments && |
| | | currentRecord.minutesAttachments.length > 0 |
| | | " |
| | | > |
| | | <el-divider content-position="left">会议纪要附件</el-divider> |
| | | <div class="attachment-list"> |
| | | <div |
| | | v-for="file in currentRecord.minutesAttachments" |
| | | :key="file.id" |
| | | class="attachment-item" |
| | | > |
| | | <el-link |
| | | type="primary" |
| | | :href="file.url" |
| | | target="_blank" |
| | | class="file-link" |
| | | > |
| | | <i |
| | | :class="getFileIcon(file.type)" |
| | | style="margin-right: 8px;" |
| | | ></i> |
| | | {{ file.name }} |
| | | <span class="file-size">({{ formatFileSize(file.size) }})</span> |
| | | </el-link> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div |
| | | class="minutes-meta" |
| | | style="margin-top: 16px; color: #909399; font-size: 12px;" |
| | |
| | | {{ currentRecord.content }} |
| | | </div> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item |
| | | label="附件" |
| | | :span="2" |
| | | v-if="currentRecord.attachments && currentRecord.attachments.length" |
| | | <el-descriptions-item label="会议详情附件" :span="2"> |
| | | <div class="detail-attachments"> |
| | | <div |
| | | v-if=" |
| | | currentRecord.detailAttachments && |
| | | currentRecord.detailAttachments.length > 0 |
| | | " |
| | | class="attachment-grid" |
| | | > |
| | | <div |
| | | v-for="file in currentRecord.attachments" |
| | | v-for="file in currentRecord.detailAttachments" |
| | | :key="file.id" |
| | | class="attachment-card" |
| | | > |
| | | <el-card shadow="hover" class="file-card"> |
| | | <div class="file-content"> |
| | | <i :class="getFileIcon(file.type)" class="file-icon"></i> |
| | | <div class="file-info"> |
| | | <div class="file-name" :title="file.name"> |
| | | {{ file.name }} |
| | | </div> |
| | | <div class="file-meta"> |
| | | <span class="file-size">{{ |
| | | formatFileSize(file.size) |
| | | }}</span> |
| | | <span class="file-time">{{ |
| | | formatDateTime(file.uploadTime) |
| | | }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="file-actions"> |
| | | <el-button |
| | | type="text" |
| | | size="mini" |
| | | @click="handlePreview(file)" |
| | | >预览</el-button |
| | | > |
| | | <el-button |
| | | type="text" |
| | | size="mini" |
| | | @click="handleDownload(file)" |
| | | >下载</el-button |
| | | > |
| | | </div> |
| | | </el-card> |
| | | </div> |
| | | </div> |
| | | <div v-else class="no-attachment"> |
| | | <el-empty |
| | | description="暂无会议详情附件" |
| | | :image-size="50" |
| | | ></el-empty> |
| | | </div> |
| | | </div> |
| | | </el-descriptions-item> |
| | | |
| | | <!-- 会议概要附件 --> |
| | | <el-descriptions-item label="会议概要附件" :span="2"> |
| | | <div class="summary-attachments"> |
| | | <div |
| | | v-if=" |
| | | currentRecord.summaryAttachments && |
| | | currentRecord.summaryAttachments.length > 0 |
| | | " |
| | | class="attachment-list" |
| | | > |
| | | <div |
| | | v-for="file in currentRecord.summaryAttachments" |
| | | :key="file.id" |
| | | class="attachment-item" |
| | | > |
| | | <el-link type="primary" :href="file.url" target="_blank"> |
| | | <i class="el-icon-document"></i> {{ file.name }} |
| | | <el-link |
| | | type="primary" |
| | | :href="file.url" |
| | | target="_blank" |
| | | class="file-link" |
| | | > |
| | | <i |
| | | :class="getFileIcon(file.type)" |
| | | style="margin-right: 8px;" |
| | | ></i> |
| | | {{ file.name }} |
| | | <span class="file-size" |
| | | >({{ formatFileSize(file.size) }})</span |
| | | > |
| | | </el-link> |
| | | </div> |
| | | </div> |
| | | <div v-else class="no-attachment"> |
| | | <el-empty |
| | | description="暂无会议概要附件" |
| | | :image-size="50" |
| | | ></el-empty> |
| | | </div> |
| | | </div> |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | |
| | | <el-form-item label="会议地点" prop="location"> |
| | | <el-input v-model="editForm.location" placeholder="请输入会议地点" /> |
| | | </el-form-item> |
| | | <el-form-item label="会议详情附件"> |
| | | <div class="attachment-upload-section"> |
| | | <div class="section-title">会议相关资料</div> |
| | | <div class="upload-tip">上传会议讨论材料、背景资料等相关文件</div> |
| | | <el-upload |
| | | class="detail-upload" |
| | | action="#" |
| | | :auto-upload="false" |
| | | :on-change="handleDetailFileChange" |
| | | :file-list="editForm.detailAttachments" |
| | | :limit="10" |
| | | multiple |
| | | > |
| | | <el-button size="small" type="primary" icon="el-icon-upload"> |
| | | 上传详情附件 |
| | | </el-button> |
| | | <div slot="tip" class="el-upload__tip"> |
| | | 支持文档、图片等格式,单个文件不超过20MB |
| | | </div> |
| | | </el-upload> |
| | | <div |
| | | v-if=" |
| | | editForm.detailAttachments && |
| | | editForm.detailAttachments.length > 0 |
| | | " |
| | | class="uploaded-files" |
| | | > |
| | | <div |
| | | v-for="(file, index) in editForm.detailAttachments" |
| | | :key="file.uid || index" |
| | | class="file-item" |
| | | > |
| | | <span class="file-name">{{ file.name }}</span> |
| | | <el-button |
| | | type="text" |
| | | size="mini" |
| | | @click="handleRemoveDetailFile(index)" |
| | | style="color: #F56C6C;" |
| | | > |
| | | 删除 |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="会议概要" prop="summary"> |
| | | <el-input |
| | | v-model="editForm.summary" |
| | | type="textarea" |
| | | :rows="2" |
| | | placeholder="请输入会议概要" |
| | | maxlength="200" |
| | | show-word-limit |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <!-- 会议概要附件上传 --> |
| | | <el-form-item label="会议概要附件"> |
| | | <div class="attachment-upload-section"> |
| | | <div class="section-title">会议纪要材料</div> |
| | | <div class="upload-tip">上传会议纪要、决议文件等相关材料</div> |
| | | <el-upload |
| | | class="summary-upload" |
| | | action="#" |
| | | :auto-upload="false" |
| | | :on-change="handleSummaryFileChange" |
| | | :file-list="editForm.summaryAttachments" |
| | | :limit="5" |
| | | multiple |
| | | > |
| | | <el-button size="small" type="primary" icon="el-icon-upload"> |
| | | 上传概要附件 |
| | | </el-button> |
| | | <div slot="tip" class="el-upload__tip"> |
| | | 支持PDF、Word等文档格式,单个文件不超过10MB |
| | | </div> |
| | | </el-upload> |
| | | <div |
| | | v-if=" |
| | | editForm.summaryAttachments && |
| | | editForm.summaryAttachments.length > 0 |
| | | " |
| | | class="uploaded-files" |
| | | > |
| | | <div |
| | | v-for="(file, index) in editForm.summaryAttachments" |
| | | :key="file.uid || index" |
| | | class="file-item" |
| | | > |
| | | <span class="file-name">{{ file.name }}</span> |
| | | <el-button |
| | | type="text" |
| | | size="mini" |
| | | @click="handleRemoveSummaryFile(index)" |
| | | style="color: #F56C6C;" |
| | | > |
| | | 删除 |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-form-item> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="开始时间" prop="startTime"> |
| | |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item label="附件上传"> |
| | | <!-- 会议纪要附件上传 --> |
| | | <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="handleFileChange" |
| | | :file-list="editForm.attachments" |
| | | :on-change="handleMinutesFileChange" |
| | | :file-list="editForm.minutesAttachments" |
| | | :limit="5" |
| | | multiple |
| | | > |
| | | <el-button size="small" type="primary">点击上传</el-button> |
| | | <el-button size="small" type="primary" icon="el-icon-upload"> |
| | | 上传纪要附件 |
| | | </el-button> |
| | | <div slot="tip" class="el-upload__tip"> |
| | | 支持上传文档、图片等文件,单个文件不超过10MB |
| | | 支持图片、文档等格式,单个文件不超过10MB |
| | | </div> |
| | | </el-upload> |
| | | </div> |
| | | </el-form-item> |
| | | <el-form-item label="会议纪要" prop="meetingMinutes"> |
| | | <el-input |
| | |
| | | endTime: "", |
| | | summary: "", |
| | | content: "", |
| | | attachments: [] |
| | | attachments: [], |
| | | detailAttachments: [], // 会议详情附件 |
| | | summaryAttachments: [], // 会议概要附件 |
| | | minutesAttachments: [] // 会议纪要附件 |
| | | }, |
| | | // 表单验证规则 |
| | | editRules: { |
| | |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | getFileIcon(fileType) { |
| | | const iconMap = { |
| | | pdf: "el-icon-document", |
| | | doc: "el-icon-document", |
| | | docx: "el-icon-document", |
| | | xls: "el-icon-document", |
| | | xlsx: "el-icon-document", |
| | | ppt: "el-icon-document", |
| | | pptx: "el-icon-document", |
| | | jpg: "el-icon-picture", |
| | | jpeg: "el-icon-picture", |
| | | png: "el-icon-picture", |
| | | gif: "el-icon-picture", |
| | | zip: "el-icon-folder", |
| | | rar: "el-icon-folder" |
| | | }; |
| | | return iconMap[fileType] || "el-icon-document"; |
| | | }, |
| | | // 查看会议纪要 |
| | | handleViewMinutes(record) { |
| | |
| | | const meetingMinutes = hasMinutes |
| | | ? minutesExamples[Math.floor(Math.random() * minutesExamples.length)] |
| | | : ""; |
| | | |
| | | const hasDetailAttachments = Math.random() > 0.5; |
| | | const hasSummaryAttachments = Math.random() > 0.6; |
| | | const hasMinutesAttachments = Math.random() > 0.7; |
| | | return { |
| | | id: index + 1, |
| | | title: `关于${ |
| | |
| | | Math.floor(Math.random() * 4) |
| | | ] |
| | | }的会议`, |
| | | // 添加分类型附件 |
| | | detailAttachments: hasDetailAttachments ? [ |
| | | { |
| | | id: `detail-${index}-1`, |
| | | name: `会议材料-${index}.pdf`, |
| | | type: 'pdf', |
| | | size: 2048000, |
| | | url: '/api/files/meeting-material.pdf', |
| | | uploadTime: new Date(startTime.getTime() - 3600000).toISOString() |
| | | }, |
| | | { |
| | | id: `detail-${index}-2`, |
| | | name: `背景资料-${index}.docx`, |
| | | type: 'docx', |
| | | size: 1024000, |
| | | url: '/api/files/background.docx', |
| | | uploadTime: new Date(startTime.getTime() - 7200000).toISOString() |
| | | } |
| | | ] : [], |
| | | |
| | | summaryAttachments: hasSummaryAttachments ? [ |
| | | { |
| | | id: `summary-${index}-1`, |
| | | name: `会议纪要-${index}.pdf`, |
| | | type: 'pdf', |
| | | size: 512000, |
| | | url: '/api/files/meeting-summary.pdf', |
| | | uploadTime: new Date(startTime.getTime() + 3600000).toISOString() |
| | | } |
| | | ] : [], |
| | | |
| | | minutesAttachments: hasMinutesAttachments ? [ |
| | | { |
| | | id: `minutes-${index}-1`, |
| | | name: `补充材料-${index}.jpg`, |
| | | type: 'jpg', |
| | | size: 1024000, |
| | | url: '/api/files/supplement.jpg', |
| | | uploadTime: new Date(startTime.getTime() + 7200000).toISOString() |
| | | } |
| | | ] : [], |
| | | meetingType: |
| | | meetingTypes[Math.floor(Math.random() * meetingTypes.length)], |
| | | participants: uniqueParticipants, |
| | |
| | | }) |
| | | .catch(() => {}); |
| | | }, |
| | | // 新增方法:格式化文件大小 |
| | | formatFileSize(bytes) { |
| | | if (!bytes) return "0 B"; |
| | | const k = 1024; |
| | | const sizes = ["B", "KB", "MB", "GB"]; |
| | | const i = Math.floor(Math.log(bytes) / Math.log(k)); |
| | | return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i]; |
| | | }, |
| | | |
| | | // 分类型文件上传处理 |
| | | handleDetailFileChange(file, fileList) { |
| | | this.editForm.detailAttachments = fileList; |
| | | }, |
| | | |
| | | handleSummaryFileChange(file, fileList) { |
| | | this.editForm.summaryAttachments = fileList; |
| | | }, |
| | | |
| | | handleMinutesFileChange(file, fileList) { |
| | | this.editForm.minutesAttachments = fileList; |
| | | }, |
| | | |
| | | // 删除已上传的文件 |
| | | handleRemoveDetailFile(index) { |
| | | this.editForm.detailAttachments.splice(index, 1); |
| | | }, |
| | | |
| | | handleRemoveSummaryFile(index) { |
| | | this.editForm.summaryAttachments.splice(index, 1); |
| | | }, |
| | | |
| | | // 文件预览和下载 |
| | | handlePreview(file) { |
| | | // 实现文件预览逻辑 |
| | | this.$message.info(`预览文件: ${file.name}`); |
| | | }, |
| | | |
| | | handleDownload(file) { |
| | | // 实现文件下载逻辑 |
| | | const link = document.createElement("a"); |
| | | link.href = file.url; |
| | | link.download = file.name; |
| | | link.click(); |
| | | this.$message.success(`开始下载: ${file.name}`); |
| | | }, |
| | | // 保存记录 |
| | | async handleSave() { |
| | | try { |
| | |
| | | meetingMinutes: "", |
| | | minutesCreateTime: "", |
| | | minutesCreator: "", |
| | | attachments: [] |
| | | detailAttachments: [], |
| | | summaryAttachments: [], |
| | | minutesAttachments: [] |
| | | }; |
| | | } |
| | | } |
| | |
| | | justify-content: space-between; |
| | | } |
| | | } |
| | | /* 新增附件相关样式 */ |
| | | .attachment-upload-section { |
| | | border: 1px solid #ebeef5; |
| | | border-radius: 4px; |
| | | padding: 15px; |
| | | background-color: #fafafa; |
| | | } |
| | | |
| | | .section-title { |
| | | font-weight: bold; |
| | | margin-bottom: 8px; |
| | | color: #303133; |
| | | } |
| | | |
| | | .upload-tip { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | .uploaded-files { |
| | | margin-top: 10px; |
| | | } |
| | | |
| | | .file-item { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 8px; |
| | | border-bottom: 1px solid #f0f0f0; |
| | | } |
| | | |
| | | .file-item:last-child { |
| | | border-bottom: none; |
| | | } |
| | | |
| | | .file-name { |
| | | flex: 1; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .attachment-grid { |
| | | display: grid; |
| | | grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); |
| | | gap: 10px; |
| | | } |
| | | |
| | | .file-card { |
| | | transition: all 0.3s ease; |
| | | } |
| | | |
| | | .file-card:hover { |
| | | transform: translateY(-2px); |
| | | box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | .file-content { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .file-icon { |
| | | font-size: 24px; |
| | | color: #409EFF; |
| | | margin-right: 10px; |
| | | } |
| | | |
| | | .file-info { |
| | | flex: 1; |
| | | } |
| | | |
| | | .file-name { |
| | | font-size: 14px; |
| | | 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: center; |
| | | } |
| | | |
| | | .file-link { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .no-attachment { |
| | | text-align: center; |
| | | padding: 20px; |
| | | color: #909399; |
| | | } |
| | | |
| | | /* 响应式设计 */ |
| | | @media (max-width: 768px) { |
| | | .attachment-grid { |
| | | grid-template-columns: 1fr; |
| | | } |
| | | } |
| | | </style> |