| | |
| | | <template> |
| | | <base-stage :stage-data="stageData" :case-info="caseInfo"> |
| | | <template #header> |
| | | <el-alert |
| | | :title="`捐献确认 - ${getStatusText()}`" |
| | | :type="getAlertType()" |
| | | :description="getAlertDescription()" |
| | | show-icon |
| | | :closable="false" |
| | | /> |
| | | </template> |
| | | |
| | | <el-row :gutter="20" style="margin-top: 20px;"> |
| | | <el-col :span="8"> |
| | | <el-card> |
| | | <div slot="header" class="card-header"> |
| | | <span>确认信息概览</span> |
| | | </div> |
| | | <div class="confirm-overview"> |
| | | <div class="overview-item"> |
| | | <span class="label">确认状态:</span> |
| | | <el-tag :type="getStatusTag(confirmationDetails.status)"> |
| | | {{ getStatusText(confirmationDetails.status) }} |
| | | </el-tag> |
| | | </div> |
| | | <div class="overview-item"> |
| | | <span class="label">确认时间:</span> |
| | | <span>{{ formatTime(confirmationDetails.confirmTime) }}</span> |
| | | </div> |
| | | <div class="overview-item"> |
| | | <span class="label">确认方式:</span> |
| | | <span>{{ confirmationDetails.method }}</span> |
| | | </div> |
| | | <div class="overview-item"> |
| | | <span class="label">协调员:</span> |
| | | <span>{{ confirmationDetails.coordinator }}</span> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="8"> |
| | | <el-card> |
| | | <div slot="header" class="card-header"> |
| | | <span>家属同意情况</span> |
| | | </div> |
| | | <el-descriptions :column="1" size="small"> |
| | | <el-descriptions-item label="主要家属"> |
| | | {{ familyConsent.mainRelative }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="同意状态"> |
| | | <el-tag :type="familyConsent.consented ? 'success' : 'warning'"> |
| | | {{ familyConsent.consented ? '已同意' : '待确认' }} |
| | | </el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="签字时间"> |
| | | {{ formatTime(familyConsent.signTime) }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="关系证明"> |
| | | {{ familyConsent.relationshipProof }} |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="8"> |
| | | <el-card> |
| | | <div slot="header" class="card-header"> |
| | | <span>法律文件</span> |
| | | </div> |
| | | <div class="document-list"> |
| | | <div v-for="doc in legalDocuments" :key="doc.name" class="document-item"> |
| | | <div class="doc-info"> |
| | | <i :class="doc.icon" style="color: #409EFF; margin-right: 8px;"></i> |
| | | <span>{{ doc.name }}</span> |
| | | </div> |
| | | <el-tag :type="doc.status === 'completed' ? 'success' : 'warning'" size="small"> |
| | | {{ doc.status === 'completed' ? '已签署' : '待签署' }} |
| | | </el-tag> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-card style="margin-top: 20px;"> |
| | | <div slot="header" class="card-header"> |
| | | <span>捐献意愿确认书</span> |
| | | <div class="confirmation-detail"> |
| | | <el-card class="detail-card"> |
| | | <!-- 基础信息 --> |
| | | <div slot="header" class="clearfix"> |
| | | <span class="detail-title">捐献确认基本信息</span> |
| | | <el-button |
| | | v-if="$route.query.confirm" |
| | | type="primary" |
| | | style="float: right; padding: 3px 0" |
| | | @click="handleSave" |
| | | > |
| | | 保存确认信息 |
| | | </el-button> |
| | | </div> |
| | | <div class="consent-content"> |
| | | <p>本人/家属确认,在充分了解器官捐献的相关信息后,自愿同意进行器官捐献。</p> |
| | | <el-divider /> |
| | | <el-descriptions :column="2" border> |
| | | <el-descriptions-item label="捐献者姓名">{{ caseInfo.donorName }}</el-descriptions-item> |
| | | <el-descriptions-item label="捐献者身份证号">{{ confirmationDetails.idNumber }}</el-descriptions-item> |
| | | <el-descriptions-item label="捐献器官类型">{{ confirmationDetails.organs }}</el-descriptions-item> |
| | | <el-descriptions-item label="捐献用途">{{ confirmationDetails.purpose }}</el-descriptions-item> |
| | | <el-descriptions-item label="签字人">{{ familyConsent.mainRelative }}</el-descriptions-item> |
| | | <el-descriptions-item label="签字日期">{{ formatTime(familyConsent.signTime) }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | </div> |
| | | |
| | | <el-form :model="form" ref="form" label-width="120px"> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="协调员1" prop="coordinator1"> |
| | | <el-input v-model="form.coordinator1" :readonly="!isEdit" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="协调员2" prop="coordinator2"> |
| | | <el-input v-model="form.coordinator2" :readonly="!isEdit" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="业务人员" prop="assignee"> |
| | | <el-input v-model="form.assignee" :readonly="!isEdit" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="确认状态" prop="confirmationStatus"> |
| | | <el-select |
| | | v-model="form.confirmationStatus" |
| | | :disabled="!isEdit" |
| | | style="width: 100%" |
| | | > |
| | | <el-option label="未确认" value="0" /> |
| | | <el-option label="家属确认" value="1" /> |
| | | <el-option label="不同意捐献" value="2" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="确认时间" prop="confirmationTime"> |
| | | <el-date-picker |
| | | v-model="form.confirmationTime" |
| | | type="datetime" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | style="width: 100%" |
| | | :disabled="!isEdit" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-form-item label="家属意见备注" prop="familyRemark"> |
| | | <el-input |
| | | type="textarea" |
| | | :rows="3" |
| | | v-model="form.familyRemark" |
| | | :readonly="!isEdit" |
| | | placeholder="记录家属的意见和沟通情况" |
| | | /> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | </base-stage> |
| | | |
| | | <!-- 附件列表 --> |
| | | <el-card class="attachment-card"> |
| | | <div slot="header" class="clearfix"> |
| | | <span class="detail-title">相关附件上传</span> |
| | | <el-button |
| | | v-if="isEdit" |
| | | type="primary" |
| | | size="mini" |
| | | @click="handleSaveAll" |
| | | :loading="saveLoading" |
| | | > |
| | | 保存所有附件 |
| | | </el-button> |
| | | </div> |
| | | |
| | | <!-- 附件类型选项卡 --> |
| | | <el-tabs v-model="activeAttachmentType" type="card"> |
| | | <el-tab-pane |
| | | v-for="type in attachmentTypes" |
| | | :key="type.value" |
| | | :label="type.label" |
| | | :name="type.value" |
| | | > |
| | | <div class="attachment-upload-section"> |
| | | <div class="upload-header"> |
| | | <span class="upload-title">{{ type.label }}</span> |
| | | <el-tooltip content="点击上传该类型附件" placement="top"> |
| | | <el-button |
| | | size="mini" |
| | | type="primary" |
| | | icon="el-icon-plus" |
| | | @click="openUploadDialog(type.value)" |
| | | :disabled="!isEdit" |
| | | > |
| | | 添加附件 |
| | | </el-button> |
| | | </el-tooltip> |
| | | </div> |
| | | |
| | | <!-- 附件列表 --> |
| | | <el-table |
| | | :data="getAttachmentsByType(type.value)" |
| | | v-loading="attachmentLoading" |
| | | style="width: 100%; margin-top: 15px;" |
| | | > |
| | | <el-table-column label="文件名称" min-width="200"> |
| | | <template slot-scope="scope"> |
| | | <div class="file-info"> |
| | | <i |
| | | class="el-icon-document" |
| | | style="margin-right: 8px; color: #409EFF;" |
| | | ></i> |
| | | <span>{{ scope.row.fileName }}</span> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column label="文件大小" width="100" align="center"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ formatFileSize(scope.row.fileSize) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column label="上传时间" width="160" align="center"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.uploadTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column label="上传人" width="100" align="center"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ scope.row.uploader }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column |
| | | label="操作" |
| | | width="120" |
| | | align="center" |
| | | v-if="isEdit" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-view" |
| | | @click="handlePreview(scope.row)" |
| | | >预览</el-button |
| | | > |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-delete" |
| | | style="color: #F56C6C;" |
| | | @click="handleRemoveAttachment(scope.row, type.value)" |
| | | >删除</el-button |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column label="操作" width="80" align="center" v-else> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="text" |
| | | icon="el-icon-view" |
| | | @click="handlePreview(scope.row)" |
| | | >预览</el-button |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <div |
| | | v-if="getAttachmentsByType(type.value).length === 0" |
| | | class="empty-attachment" |
| | | > |
| | | <el-empty description="暂无附件" :image-size="80"></el-empty> |
| | | </div> |
| | | </div> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </el-card> |
| | | <el-dialog |
| | | :title="`上传${getCurrentTypeLabel}附件`" |
| | | :visible.sync="uploadDialogVisible" |
| | | width="500px" |
| | | :close-on-click-modal="false" |
| | | > |
| | | <el-upload |
| | | ref="uploadRef" |
| | | class="upload-demo" |
| | | drag |
| | | action="#" |
| | | multiple |
| | | :file-list="tempFileList" |
| | | :before-upload="beforeUpload" |
| | | :on-change="handleFileChange" |
| | | :on-remove="handleTempRemove" |
| | | :auto-upload="false" |
| | | :http-request="handleHttpRequest" |
| | | > |
| | | <i class="el-icon-upload"></i> |
| | | <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> |
| | | <div class="el-upload__tip" slot="tip"> |
| | | 支持上传pdf、jpg、png、doc、docx格式文件,单个文件不超过10MB |
| | | </div> |
| | | </el-upload> |
| | | |
| | | <span slot="footer" class="dialog-footer"> |
| | | <el-button @click="uploadDialogVisible = false">取消</el-button> |
| | | <el-button |
| | | type="primary" |
| | | @click="submitUpload" |
| | | :loading="uploadLoading" |
| | | :disabled="tempFileList.length === 0" |
| | | > |
| | | 确认上传 |
| | | </el-button> |
| | | </span> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import BaseStage from './BaseStage.vue'; |
| | | import { |
| | | getConfirmationDetail, |
| | | updateConfirmation |
| | | } from "./api/mockConfirmationApi"; |
| | | |
| | | export default { |
| | | name: 'DonationConfirmStage', |
| | | components: { BaseStage }, |
| | | props: { |
| | | stageData: { |
| | | type: Object, |
| | | default: () => ({}) |
| | | }, |
| | | caseInfo: { |
| | | type: Object, |
| | | default: () => ({}) |
| | | } |
| | | }, |
| | | name: "ConfirmationDetail", |
| | | data() { |
| | | return { |
| | | confirmationDetails: { |
| | | status: 'completed', |
| | | confirmTime: '2023-12-03 11:00:00', |
| | | method: '家属书面同意', |
| | | coordinator: '赵协调员', |
| | | idNumber: '110101199001011234', |
| | | organs: '心脏、肝脏、肾脏、角膜', |
| | | purpose: '临床移植' |
| | | // 是否编辑模式 |
| | | isEdit: false, |
| | | // 表单数据 |
| | | form: { |
| | | id: undefined, |
| | | caseNo: "", |
| | | donorName: "", |
| | | gender: "", |
| | | age: "", |
| | | diagnosis: "", |
| | | hospitalName: "", |
| | | coordinator1: "", |
| | | coordinator2: "", |
| | | assignee: "", |
| | | confirmationStatus: "0", |
| | | confirmationTime: "", |
| | | familyRemark: "" |
| | | }, |
| | | familyConsent: { |
| | | mainRelative: '张三父亲', |
| | | consented: true, |
| | | signTime: '2023-12-03 10:45:00', |
| | | relationshipProof: '户口本关系证明' |
| | | }, |
| | | legalDocuments: [ |
| | | { name: '器官捐献同意书', icon: 'el-icon-document', status: 'completed' }, |
| | | { name: '家属关系证明', icon: 'el-icon-document', status: 'completed' }, |
| | | { name: '医疗免责声明', icon: 'el-icon-document', status: 'completed' }, |
| | | { name: '隐私保护协议', icon: 'el-icon-document', status: 'completed' } |
| | | // 附件列表 |
| | | // 附件相关数据 |
| | | activeAttachmentType: "1", |
| | | attachmentLoading: false, |
| | | uploadDialogVisible: false, |
| | | uploadLoading: false, |
| | | saveLoading: false, |
| | | tempFileList: [], |
| | | currentUploadType: "", |
| | | |
| | | // 附件类型定义 |
| | | attachmentTypes: [ |
| | | { value: "1", label: "人体器官潜在捐献者登记表" }, |
| | | { value: "2", label: "人体器官捐献亲属确认登记表" }, |
| | | { value: "3", label: "捐献者及直系亲属身份证、户口簿相关证明" }, |
| | | { value: "4", label: "公民身故后人体器官(角膜)遗体捐献告知书" }, |
| | | { value: "5", label: "脑死亡判定知情同意书" }, |
| | | { value: "6", label: "心死亡判定知情同意书" } |
| | | ], |
| | | |
| | | // 附件列表数据 |
| | | attachmentList: [ |
| | | // 模拟数据 - 实际项目中从接口获取 |
| | | { |
| | | id: 1, |
| | | type: "1", |
| | | typeName: "人体器官潜在捐献者登记表", |
| | | fileName: "潜在捐献者登记表_202512001.pdf", |
| | | fileSize: 2548321, |
| | | uploadTime: "2025-12-01 10:30:00", |
| | | uploader: "张三", |
| | | fileUrl: "/attachments/1.pdf" |
| | | }, |
| | | { |
| | | id: 2, |
| | | type: "1", |
| | | typeName: "人体器官潜在捐献者登记表", |
| | | fileName: "补充说明.docx", |
| | | fileSize: 512345, |
| | | uploadTime: "2025-12-01 14:20:00", |
| | | uploader: "李四", |
| | | fileUrl: "/attachments/2.docx" |
| | | } |
| | | ] |
| | | }; |
| | | }, |
| | | computed: { |
| | | isEdit() { |
| | | return this.$route.query.confirm === "true"; |
| | | }, |
| | | getCurrentTypeLabel() { |
| | | const type = this.attachmentTypes.find( |
| | | t => t.value === this.currentUploadType |
| | | ); |
| | | return type ? type.label : ""; |
| | | } |
| | | }, |
| | | created() { |
| | | const id = this.$route.query.id; |
| | | this.isEdit = this.$route.query.confirm === "true"; |
| | | if (id) { |
| | | this.getDetail(id); |
| | | } |
| | | this.getAttachmentList(); |
| | | }, |
| | | methods: { |
| | | getStatusText() { |
| | | const status = this.stageData.status; |
| | | return status === 'completed' ? '已完成' : |
| | | status === 'in_progress' ? '进行中' : '未开始'; |
| | | // 获取详情 |
| | | getDetail(id) { |
| | | getConfirmationDetail(id).then(response => { |
| | | if (response.code === 200) { |
| | | this.form = response.data; |
| | | } |
| | | }); |
| | | }, |
| | | getAlertType() { |
| | | const status = this.stageData.status; |
| | | return status === 'completed' ? 'success' : |
| | | status === 'in_progress' ? 'warning' : 'info'; |
| | | // 获取附件列表 |
| | | getAttachmentList() { |
| | | this.attachmentLoading = true; |
| | | // 模拟附件数据 |
| | | this.attachmentList = [ |
| | | { |
| | | id: 1, |
| | | type: "1", |
| | | typeName: "人体器官潜在捐献者登记表", |
| | | fileName: "潜在捐献者登记表_202512001.pdf", |
| | | uploadTime: "2025-12-01 10:30:00", |
| | | uploader: "张三", |
| | | fileSize: "2.5MB", |
| | | fileUrl: "/attachments/1.pdf" |
| | | }, |
| | | { |
| | | id: 2, |
| | | type: "2", |
| | | typeName: "人体器官捐献亲属确认登记表", |
| | | fileName: "亲属确认登记表_202512001.pdf", |
| | | uploadTime: "2025-12-01 14:20:00", |
| | | uploader: "李四", |
| | | fileSize: "1.8MB", |
| | | fileUrl: "/attachments/2.pdf" |
| | | }, |
| | | { |
| | | id: 3, |
| | | type: "3", |
| | | typeName: "捐献者及直系亲属身份证、户口簿相关证明", |
| | | fileName: "身份证明_202512001.zip", |
| | | uploadTime: "2025-12-01 16:45:00", |
| | | uploader: "王五", |
| | | fileSize: "5.2MB", |
| | | fileUrl: "/attachments/3.zip" |
| | | }, |
| | | { |
| | | id: 4, |
| | | type: "4", |
| | | typeName: "公民身故后人体器官(角膜)遗体捐献告知书", |
| | | fileName: "捐献告知书_202512001.pdf", |
| | | uploadTime: "2025-12-02 09:15:00", |
| | | uploader: "张三", |
| | | fileSize: "1.2MB", |
| | | fileUrl: "/attachments/4.pdf" |
| | | }, |
| | | { |
| | | id: 5, |
| | | type: "5", |
| | | typeName: "脑死亡判定知情同意书", |
| | | fileName: "脑死亡判定同意书_202512001.pdf", |
| | | uploadTime: "2025-12-02 11:30:00", |
| | | uploader: "李四", |
| | | fileSize: "0.8MB", |
| | | fileUrl: "/attachments/5.pdf" |
| | | }, |
| | | { |
| | | id: 6, |
| | | type: "6", |
| | | typeName: "心死亡判定知情同意书", |
| | | fileName: "心死亡判定同意书_202512001.pdf", |
| | | uploadTime: "2025-12-02 13:20:00", |
| | | uploader: "王五", |
| | | fileSize: "0.9MB", |
| | | fileUrl: "/attachments/6.pdf" |
| | | } |
| | | ]; |
| | | this.attachmentLoading = false; |
| | | }, |
| | | getAlertDescription() { |
| | | const status = this.stageData.status; |
| | | return status === 'completed' ? '捐献确认流程已完成,所有法律文件已签署' : |
| | | status === 'in_progress' ? '捐献确认流程正在进行中' : '等待开始捐献确认流程'; |
| | | // 下载附件 |
| | | handleDownload(row) { |
| | | // 实际项目中这里调用文件下载接口 |
| | | this.$message.success(`下载文件: ${row.fileName}`); |
| | | console.log("下载文件:", row.fileUrl); |
| | | }, |
| | | getStatusTag(status) { |
| | | const map = { |
| | | 'completed': 'success', |
| | | 'in_progress': 'warning', |
| | | 'pending': 'info' |
| | | }; |
| | | return map[status] || 'info'; |
| | | // 保存确认信息 |
| | | handleSave() { |
| | | this.$refs.form.validate(valid => { |
| | | if (valid) { |
| | | updateConfirmation(this.form).then(response => { |
| | | if (response.code === 200) { |
| | | this.$message.success("保存成功"); |
| | | this.isEdit = false; |
| | | this.$router.push("/case/confirmation"); |
| | | } |
| | | }); |
| | | } |
| | | }); |
| | | }, |
| | | // 根据类型获取附件 |
| | | getAttachmentsByType(type) { |
| | | return this.attachmentList.filter(item => item.type === type); |
| | | }, |
| | | |
| | | // 打开上传对话框 |
| | | openUploadDialog(type) { |
| | | this.currentUploadType = type; |
| | | this.tempFileList = []; |
| | | this.uploadDialogVisible = true; |
| | | this.$nextTick(() => { |
| | | if (this.$refs.uploadRef) { |
| | | this.$refs.uploadRef.clearFiles(); |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | // 上传前校验 |
| | | beforeUpload(file) { |
| | | const allowedTypes = [ |
| | | 'application/pdf', |
| | | 'image/jpeg', |
| | | 'image/png', |
| | | 'application/msword', |
| | | 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' |
| | | ]; |
| | | |
| | | const maxSize = 10 * 1024 * 1024; // 10MB |
| | | |
| | | // 校验文件类型 |
| | | const isTypeOk = allowedTypes.includes(file.type) || |
| | | file.name.endsWith('.pdf') || |
| | | file.name.endsWith('.jpg') || |
| | | file.name.endsWith('.jpeg') || |
| | | file.name.endsWith('.png') || |
| | | file.name.endsWith('.doc') || |
| | | file.name.endsWith('.docx'); |
| | | |
| | | if (!isTypeOk) { |
| | | this.$message.error('文件格式不支持,请上传pdf、jpg、png、doc或docx格式文件'); |
| | | return false; |
| | | } |
| | | |
| | | // 校验文件大小 |
| | | if (file.size > maxSize) { |
| | | this.$message.error('文件大小不能超过10MB'); |
| | | return false; |
| | | } |
| | | |
| | | return true; |
| | | }, |
| | | |
| | | // 文件选择变化 |
| | | handleFileChange(file, fileList) { |
| | | this.tempFileList = fileList; |
| | | }, |
| | | |
| | | // 移除临时文件 |
| | | handleTempRemove(file, fileList) { |
| | | this.tempFileList = fileList; |
| | | }, |
| | | |
| | | // 自定义上传请求 |
| | | handleHttpRequest(options) { |
| | | // 模拟上传过程 |
| | | return new Promise((resolve, reject) => { |
| | | this.uploadLoading = true; |
| | | |
| | | // 模拟上传延迟 |
| | | setTimeout(() => { |
| | | const newAttachment = { |
| | | id: Date.now(), |
| | | type: this.currentUploadType, |
| | | typeName: this.getCurrentTypeLabel, |
| | | fileName: options.file.name, |
| | | fileSize: options.file.size, |
| | | uploadTime: new Date().toISOString(), |
| | | uploader: '当前用户', // 实际项目中从用户信息获取 |
| | | fileUrl: URL.createObjectURL(options.file) // 临时URL,实际项目中为服务器返回的URL |
| | | }; |
| | | |
| | | this.attachmentList.push(newAttachment); |
| | | this.uploadLoading = false; |
| | | resolve({ code: 200, data: newAttachment }); |
| | | }, 1500); |
| | | }); |
| | | }, |
| | | |
| | | // 提交上传 |
| | | async submitUpload() { |
| | | if (this.tempFileList.length === 0) { |
| | | this.$message.warning('请先选择要上传的文件'); |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | // 依次上传所有文件 |
| | | for (const file of this.tempFileList) { |
| | | await this.$refs.uploadRef.submit(); |
| | | } |
| | | |
| | | this.$message.success('文件上传成功'); |
| | | this.uploadDialogVisible = false; |
| | | this.tempFileList = []; |
| | | } catch (error) { |
| | | this.$message.error('文件上传失败'); |
| | | console.error('上传失败:', error); |
| | | } |
| | | }, |
| | | |
| | | // 删除附件 |
| | | handleRemoveAttachment(attachment, type) { |
| | | this.$confirm('确定要删除这个附件吗?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | const index = this.attachmentList.findIndex(item => item.id === attachment.id); |
| | | if (index !== -1) { |
| | | this.attachmentList.splice(index, 1); |
| | | this.$message.success('附件删除成功'); |
| | | |
| | | // 实际项目中调用删除接口 |
| | | // this.deleteAttachment(attachment.id); |
| | | } |
| | | }).catch(() => {}); |
| | | }, |
| | | |
| | | // 预览附件 |
| | | handlePreview(attachment) { |
| | | // 实际项目中根据文件类型调用不同的预览方式 |
| | | if (attachment.fileName.endsWith('.pdf')) { |
| | | // PDF预览 |
| | | window.open(attachment.fileUrl, '_blank'); |
| | | } else if (attachment.fileName.match(/\.(jpg|jpeg|png)$/i)) { |
| | | // 图片预览 |
| | | this.$alert(`<img src="${attachment.fileUrl}" style="max-width: 100%;" alt="${attachment.fileName}">`, |
| | | '图片预览', { |
| | | dangerouslyUseHTMLString: true, |
| | | customClass: 'image-preview-dialog' |
| | | }); |
| | | } else { |
| | | // 其他文件类型提示下载 |
| | | this.$message.info('该文件类型暂不支持在线预览,请下载后查看'); |
| | | } |
| | | }, |
| | | |
| | | // 保存所有附件信息 |
| | | handleSaveAll() { |
| | | this.saveLoading = true; |
| | | |
| | | // 模拟保存过程 |
| | | setTimeout(() => { |
| | | this.$message.success('附件信息保存成功'); |
| | | this.saveLoading = false; |
| | | |
| | | // 实际项目中调用保存接口 |
| | | // this.saveAttachments(); |
| | | }, 1000); |
| | | }, |
| | | |
| | | // 文件大小格式化 |
| | | formatFileSize(size) { |
| | | if (size === 0) return '0 B'; |
| | | const k = 1024; |
| | | const sizes = ['B', 'KB', 'MB', 'GB']; |
| | | const i = Math.floor(Math.log(size) / Math.log(k)); |
| | | return parseFloat((size / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; |
| | | }, |
| | | |
| | | // 时间格式化 |
| | | parseTime(time) { |
| | | if (!time) return ''; |
| | | const date = new Date(time); |
| | | return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`; |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .confirm-overview { |
| | | padding: 10px 0; |
| | | .confirmation-detail { |
| | | padding: 20px; |
| | | } |
| | | |
| | | .overview-item { |
| | | .detail-card { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .attachment-card { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .detail-title { |
| | | font-size: 16px; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .fixed-width .el-button { |
| | | margin: 0 5px; |
| | | } |
| | | .confirmation-detail { |
| | | padding: 20px; |
| | | } |
| | | |
| | | .detail-card { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .attachment-card { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .detail-title { |
| | | font-size: 16px; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .attachment-upload-section { |
| | | padding: 10px; |
| | | } |
| | | |
| | | .upload-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 15px; |
| | | padding: 8px 0; |
| | | border-bottom: 1px solid #f0f0f0; |
| | | } |
| | | |
| | | .overview-item .label { |
| | | color: #606266; |
| | | font-weight: 500; |
| | | .upload-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | } |
| | | |
| | | .document-list { |
| | | padding: 10px 0; |
| | | } |
| | | |
| | | .document-item { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 12px; |
| | | padding: 8px 12px; |
| | | border: 1px solid #e4e7ed; |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | .doc-info { |
| | | .file-info { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .consent-content { |
| | | padding: 20px; |
| | | line-height: 1.6; |
| | | .empty-attachment { |
| | | text-align: center; |
| | | padding: 40px 0; |
| | | color: #909399; |
| | | } |
| | | |
| | | /* 图片预览对话框样式 */ |
| | | :deep(.image-preview-dialog) { |
| | | width: auto; |
| | | max-width: 90vw; |
| | | } |
| | | |
| | | :deep(.image-preview-dialog .el-message-box__content) { |
| | | text-align: center; |
| | | } |
| | | </style> |