| | |
| | | <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" |
| | | type="success" |
| | | style="float: right;" |
| | | @click="handleSave" |
| | | :loading="saveLoading" |
| | | > |
| | | 保存确认信息 |
| | | </el-button> |
| | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="住院号" prop="caseNo"> |
| | | <el-input v-model="form.caseNo" :readonly="!isEdit" /> |
| | | <el-input v-model="form.caseNo" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="捐献者姓名" prop="donorName"> |
| | | <el-input v-model="form.donorName" :readonly="!isEdit" /> |
| | | <el-form-item label="捐献者姓名" prop="name"> |
| | | <el-input v-model="form.name" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="性别" prop="gender"> |
| | | <el-select |
| | | v-model="form.gender" |
| | | :disabled="!isEdit" |
| | | style="width: 100%" |
| | | > |
| | | <el-option label="男" value="0" /> |
| | | <el-option label="女" value="1" /> |
| | | <el-form-item label="性别" prop="sex"> |
| | | <el-select v-model="form.sex" style="width: 100%"> |
| | | <el-option label="男" value="1" /> |
| | | <el-option label="女" value="2" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="年龄" prop="age"> |
| | | <el-input v-model="form.age" :readonly="!isEdit" /> |
| | | <el-input v-model="form.age" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="疾病诊断" prop="diagnosis"> |
| | | <el-input v-model="form.diagnosis" :readonly="!isEdit" /> |
| | | <el-form-item label="疾病诊断" prop="diagnosisname"> |
| | | <el-input v-model="form.diagnosisname" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="所在医疗机构" prop="hospitalName"> |
| | | <el-input v-model="form.hospitalName" :readonly="!isEdit" /> |
| | | <el-form-item label="所在医疗机构" prop="treatmenthospitalname"> |
| | | <el-input v-model="form.treatmenthospitalname" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <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 label="协调员1" prop="coordinatedusernameo"> |
| | | <el-input v-model="form.coordinatedusernameo" /> |
| | | </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 label="协调员2" prop="coordinatedusernamet"> |
| | | <el-input v-model="form.coordinatedusernamet" /> |
| | | </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 label="业务人员" prop="responsibleusername"> |
| | | <el-input v-model="form.responsibleusername" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="确认状态" prop="confirmationStatus"> |
| | | <!-- <el-col :span="8"> |
| | | <el-form-item label="确认状态" prop="relativeconfirmationsign"> |
| | | <el-select |
| | | v-model="form.confirmationStatus" |
| | | |
| | | v-model="form.relativeconfirmationsign" |
| | | 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> --> |
| | | <el-col :span="8"> |
| | | <el-form-item label="确认时间" prop="confirmationTime"> |
| | | <el-form-item label="签字时间" prop="signdate"> |
| | | <el-date-picker |
| | | v-model="form.confirmationTime" |
| | | v-model="form.signdate" |
| | | type="datetime" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | value-format="yyyy-MM-dd" |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <!-- <el-col :span="8"> |
| | | <el-form-item label="血型" prop="bloodtype"> |
| | | <el-input v-model="form.bloodtype" /> |
| | | </el-form-item> |
| | | </el-col> --> |
| | | </el-row> |
| | | |
| | | <!-- <el-row :gutter="20"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="证件号码" prop="idcardno"> |
| | | <el-input v-model="form.idcardno" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> --> |
| | | |
| | | <!-- 亲属信息 --> |
| | | <!-- 亲属信息 --> |
| | | <el-divider content-position="left">亲属确认信息</el-divider> |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="6"> |
| | | <el-form-item label="亲属姓名" prop="relativeconfirmationsignname"> |
| | | <el-input |
| | | v-model="form.relativeconfirmationsignname" |
| | | placeholder="请输入亲属姓名" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="与捐赠者关系" prop="familyrelations"> |
| | | <el-select |
| | | v-model="form.familyrelations" |
| | | placeholder="请选择与捐赠者关系" |
| | | > |
| | | <el-option |
| | | v-for="dict in dict.type.sys_FamilyRelation || []" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="亲属身份证" prop="relativeidcardno"> |
| | | <el-input |
| | | v-model="form.relativeidcardno" |
| | | placeholder="请输入亲属证件号码" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="亲属电话" prop="relativephone"> |
| | | <el-input |
| | | v-model="form.relativephone" |
| | | placeholder="请输入亲属联系电话" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-form-item label="家属意见备注" prop="familyRemark"> |
| | | <el-row> |
| | | <el-form-item label-width="100px" label="捐献决定"> |
| | | <el-checkbox-group v-model="organdecision"> |
| | | <el-checkbox |
| | | v-for="item in organselection" |
| | | :key="item" |
| | | :label="item" |
| | | >{{ item }} |
| | | </el-checkbox> |
| | | </el-checkbox-group> |
| | | <el-input |
| | | v-if="organdecision.includes('其他')" |
| | | v-model="organdecisionOther" |
| | | placeholder="请输入其他捐献决定的具体内容" |
| | | style="margin-top: 10px; width: 300px;" |
| | | ></el-input> |
| | | </el-form-item> |
| | | </el-row> |
| | | |
| | | <el-form-item label="家属意见备注" prop="relativeRemark"> |
| | | <el-input |
| | | type="textarea" |
| | | :rows="3" |
| | | v-model="form.familyRemark" |
| | | :readonly="!isEdit" |
| | | v-model="form.relativeRemark" |
| | | placeholder="记录家属的意见和沟通情况" |
| | | /> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | | |
| | | <!-- 附件列表 --> |
| | | <!-- 附件信息 - 按类型分类 --> |
| | | <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> |
| | | |
| | | <!-- 附件类型选项卡 --> |
| | |
| | | :label="type.label" |
| | | :name="type.value" |
| | | > |
| | | <div class="attachment-upload-section"> |
| | | <div class="upload-header"> |
| | | <div class="attachment-section"> |
| | | <div class="attachment-header"> |
| | | <span class="upload-title">{{ type.label }}</span> |
| | | <el-tooltip content="点击上传该类型附件" placement="top"> |
| | | <el-button |
| | |
| | | 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"> |
| | | <!-- 当前类型的附件列表 --> |
| | | <div class="attachment-list"> |
| | | <el-table |
| | | :data="getAttachmentsByType(type.value)" |
| | | size="small" |
| | | v-loading="attachmentLoading" |
| | | style="width: 100%;" |
| | | > |
| | | <el-table-column label="文件名" min-width="200"> |
| | | <template slot-scope="scope"> |
| | | <i |
| | | class="el-icon-document" |
| | | style="margin-right: 8px; color: #409EFF;" |
| | | style="color: #409EFF; margin-right: 8px;" |
| | | ></i> |
| | | <span>{{ scope.row.fileName }}</span> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <span class="file-name">{{ scope.row.fileName }}</span> |
| | | </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="100" align="center"> |
| | | <template slot-scope="scope"> |
| | | <el-tag size="small">{{ |
| | | getFileType(scope.row.fileName) |
| | | }}</el-tag> |
| | | </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>{{ formatFileSize(scope.row.fileSize) }}</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="160" align="center"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ formatDateTime(scope.row.uploadTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column |
| | | label="操作" |
| | | width="120" |
| | | align="center" |
| | | v-if="isEdit" |
| | | <el-table-column label="操作" width="150" align="center"> |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | size="mini" |
| | | type="primary" |
| | | @click="handlePreview(scope.row)" |
| | | > |
| | | 预览 |
| | | </el-button> |
| | | <el-button |
| | | size="mini" |
| | | type="danger" |
| | | @click="handleRemoveAttachment(type.value, scope.$index)" |
| | | > |
| | | 删除 |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <!-- 空状态提示 --> |
| | | <div |
| | | v-if="getAttachmentsByType(type.value).length === 0" |
| | | class="empty-attachment" |
| | | > |
| | | <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> |
| | | <el-empty |
| | | :description="`暂无${type.label}附件`" |
| | | :image-size="80" |
| | | ></el-empty> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </el-card> |
| | | |
| | | <!-- 上传对话框 --> |
| | | <el-dialog |
| | | :title="`上传${getCurrentTypeLabel}附件`" |
| | | :visible.sync="uploadDialogVisible" |
| | |
| | | </el-button> |
| | | </span> |
| | | </el-dialog> |
| | | |
| | | <!-- 文件预览弹窗 --> |
| | | <FilePreviewDialog |
| | | :visible="previewVisible" |
| | | :file="currentPreviewFile" |
| | | @close="previewVisible = false" |
| | | @download="handleDownload" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { |
| | | getConfirmationDetail, |
| | | updateConfirmation |
| | | } from "./mockConfirmationApi"; |
| | | import { relativesList, relativesEdit } from "@/api/businessApi"; |
| | | import FilePreviewDialog from "@/components/FilePreviewDialog"; |
| | | |
| | | export default { |
| | | name: "ConfirmationDetail", |
| | | components: { |
| | | FilePreviewDialog |
| | | }, |
| | | dicts: ["sys_FamilyRelation"], |
| | | data() { |
| | | return { |
| | | // 是否编辑模式 |
| | |
| | | // 表单数据 |
| | | form: { |
| | | id: undefined, |
| | | infoid: undefined, |
| | | caseNo: "", |
| | | donorName: "", |
| | | gender: "", |
| | | name: "", |
| | | sex: "", |
| | | age: "", |
| | | diagnosis: "", |
| | | hospitalName: "", |
| | | coordinator1: "", |
| | | coordinator2: "", |
| | | assignee: "", |
| | | confirmationStatus: "0", |
| | | confirmationTime: "", |
| | | familyRemark: "" |
| | | diagnosisname: "", |
| | | treatmenthospitalname: "", |
| | | coordinatedusernameo: "", |
| | | coordinatedusernamet: "", |
| | | responsibleusername: "", |
| | | relativeconfirmationsign: "0", |
| | | signdate: "", |
| | | relativeconfirmationsignname: "", |
| | | familyrelations: "", |
| | | relativeidcardno: "", |
| | | relativephone: "", |
| | | relativeRemark: "", |
| | | assessannex: "" // JSON字符串存储所有附件 |
| | | }, |
| | | // 附件列表 |
| | | organdecision: [], |
| | | organdecisionOther: "", |
| | | organselection: [ |
| | | "肝脏", |
| | | "双肾", |
| | | "左肾", |
| | | "右肾", |
| | | "心脏", |
| | | "肺脏", |
| | | "胰腺", |
| | | "小肠", |
| | | "双眼组织", |
| | | "遗体", |
| | | "其他" |
| | | ], |
| | | // 加载状态 |
| | | loading: false, |
| | | saveLoading: false, |
| | | // 附件相关数据 |
| | | activeAttachmentType: "1", |
| | | attachmentLoading: false, |
| | | uploadDialogVisible: false, |
| | | uploadLoading: false, |
| | | saveLoading: false, |
| | | tempFileList: [], |
| | | currentUploadType: "", |
| | | // 预览相关 |
| | | previewVisible: false, |
| | | currentPreviewFile: null, |
| | | |
| | | // 附件类型定义 |
| | | attachmentTypes: [ |
| | |
| | | { 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" |
| | | } |
| | | ] |
| | | // 附件数据结构 - 按类型分开存储 |
| | | attachmentData: { |
| | | "1": [], // 类型1的附件列表 |
| | | "2": [], |
| | | "3": [], |
| | | "4": [], |
| | | "5": [], |
| | | "6": [] |
| | | } |
| | | }; |
| | | }, |
| | | computed: { |
| | | isEdit() { |
| | | return this.$route.query.confirm === "true"; |
| | | }, |
| | | getCurrentTypeLabel() { |
| | | const type = this.attachmentTypes.find( |
| | | t => t.value === this.currentUploadType |
| | |
| | | } |
| | | }, |
| | | created() { |
| | | const id = this.$route.query.id; |
| | | const infoid = this.$route.query.infoid; |
| | | this.isEdit = this.$route.query.confirm === "true"; |
| | | if (id) { |
| | | this.getDetail(id); |
| | | if (infoid) { |
| | | this.getDetail(infoid); |
| | | } |
| | | this.getAttachmentList(); |
| | | }, |
| | | methods: { |
| | | // 获取详情 |
| | | getDetail(id) { |
| | | getConfirmationDetail(id).then(response => { |
| | | async getDetail(infoid) { |
| | | this.loading = true; |
| | | try { |
| | | const response = await relativesList({ infoid }); |
| | | |
| | | if (response.code === 200) { |
| | | this.form = response.data; |
| | | this.handleDetailData(response); |
| | | } else { |
| | | this.$message.error("获取详情失败:" + (response.msg || "未知错误")); |
| | | } |
| | | }); |
| | | } catch (error) { |
| | | console.error("获取捐献确认详情失败:", error); |
| | | this.$message.error("获取详情失败"); |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | // 获取附件列表 |
| | | 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" |
| | | |
| | | // 处理详情数据 |
| | | handleDetailData(response) { |
| | | let detailData = null; |
| | | |
| | | // 根据接口实际返回的数据结构进行调整 |
| | | if (response.data) { |
| | | if (Array.isArray(response.data)) { |
| | | detailData = response.data[0] || {}; |
| | | } else if (response.data.rows && Array.isArray(response.data.rows)) { |
| | | detailData = response.data.rows[0] || {}; |
| | | } else if (Array.isArray(response.data.list)) { |
| | | detailData = response.data.list[0] || {}; |
| | | } else { |
| | | detailData = response.data; |
| | | } |
| | | ]; |
| | | this.attachmentLoading = false; |
| | | } else { |
| | | detailData = response; |
| | | } |
| | | |
| | | // 映射字段到表单 |
| | | this.form = { |
| | | ...this.form, |
| | | id: detailData.id || this.$route.query.id, |
| | | infoid: detailData.infoid || infoid, |
| | | caseNo: detailData.caseNo || "", |
| | | name: detailData.name || "", |
| | | sex: detailData.sex || "", |
| | | age: detailData.age || "", |
| | | diagnosisname: detailData.diagnosisname || "", |
| | | treatmenthospitalname: detailData.treatmenthospitalname || "", |
| | | coordinatedusernameo: detailData.coordinatedusernameo || "", |
| | | coordinatedusernamet: detailData.coordinatedusernamet || "", |
| | | responsibleusername: detailData.responsibleusername || "", |
| | | relativeconfirmationsign: detailData.relativeconfirmationsign || "0", |
| | | signdate: detailData.signdate, |
| | | relativeconfirmationsignname: |
| | | detailData.relativeconfirmationsignname || "", |
| | | familyrelations: detailData.familyrelations || "", |
| | | relativeidcardno: detailData.relativeidcardno || "", |
| | | relativephone: detailData.relativephone || "", |
| | | relativeRemark: detailData.relativeRemark || "", |
| | | assessannex: detailData.assessannex || "" |
| | | }; |
| | | |
| | | // 处理捐献决定数据 |
| | | if (detailData.organdecision) { |
| | | this.organdecision = Array.isArray(detailData.organdecision) |
| | | ? detailData.organdecision |
| | | : detailData.organdecision.split(","); |
| | | } |
| | | |
| | | // 处理附件数据 - 从assessannex字段解析JSON并按类型分类 |
| | | this.processAssessannexData(); |
| | | }, |
| | | // 下载附件 |
| | | handleDownload(row) { |
| | | // 实际项目中这里调用文件下载接口 |
| | | this.$message.success(`下载文件: ${row.fileName}`); |
| | | console.log("下载文件:", row.fileUrl); |
| | | }, |
| | | // 保存确认信息 |
| | | 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"); |
| | | } |
| | | |
| | | // 处理assessannex字段数据并按类型分类 |
| | | processAssessannexData() { |
| | | if (this.form.assessannex) { |
| | | try { |
| | | const annexData = |
| | | typeof this.form.assessannex === "string" |
| | | ? JSON.parse(this.form.assessannex) |
| | | : this.form.assessannex; |
| | | |
| | | // 清空现有数据 |
| | | Object.keys(this.attachmentData).forEach(key => { |
| | | this.attachmentData[key] = []; |
| | | }); |
| | | |
| | | // 按类型分类存储 |
| | | if (Array.isArray(annexData)) { |
| | | annexData.forEach(attachment => { |
| | | const type = attachment.type || "1"; // 默认到第一种类型 |
| | | if (this.attachmentData[type]) { |
| | | this.attachmentData[type].push(attachment); |
| | | } |
| | | }); |
| | | } |
| | | } catch (error) { |
| | | console.warn("assessannex数据解析失败:", error); |
| | | } |
| | | }); |
| | | } |
| | | }, |
| | | // 根据类型获取附件 |
| | | |
| | | // 根据类型获取附件列表 |
| | | getAttachmentsByType(type) { |
| | | return this.attachmentList.filter(item => item.type === type); |
| | | return this.attachmentData[type] || []; |
| | | }, |
| | | |
| | | // 打开上传对话框 |
| | |
| | | }); |
| | | }, |
| | | |
| | | // 上传前校验 |
| | | // 上传前校验[7](@ref) |
| | | beforeUpload(file) { |
| | | const allowedTypes = [ |
| | | 'application/pdf', |
| | | 'image/jpeg', |
| | | 'image/png', |
| | | 'application/msword', |
| | | 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' |
| | | "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'); |
| | | 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格式文件'); |
| | | this.$message.error( |
| | | "文件格式不支持,请上传pdf、jpg、png、doc或docx格式文件" |
| | | ); |
| | | return false; |
| | | } |
| | | |
| | | // 校验文件大小 |
| | | if (file.size > maxSize) { |
| | | this.$message.error('文件大小不能超过10MB'); |
| | | this.$message.error("文件大小不能超过10MB"); |
| | | return false; |
| | | } |
| | | |
| | |
| | | |
| | | // 自定义上传请求 |
| | | 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, |
| | | fileUrl: URL.createObjectURL(options.file), |
| | | fileSize: options.file.size, |
| | | fileType: this.getFileExtension(options.file.name), |
| | | type: this.currentUploadType, // 记录附件类型 |
| | | uploadTime: new Date().toISOString(), |
| | | uploader: '当前用户', // 实际项目中从用户信息获取 |
| | | fileUrl: URL.createObjectURL(options.file) // 临时URL,实际项目中为服务器返回的URL |
| | | uploader: "当前用户" |
| | | }; |
| | | |
| | | this.attachmentList.push(newAttachment); |
| | | // 添加到对应类型的附件列表 |
| | | if (this.attachmentData[this.currentUploadType]) { |
| | | this.attachmentData[this.currentUploadType].push(newAttachment); |
| | | } |
| | | |
| | | this.uploadLoading = false; |
| | | this.updateAssessannexField(); // 更新存储字段 |
| | | resolve({ code: 200, data: newAttachment }); |
| | | }, 1500); |
| | | }); |
| | |
| | | // 提交上传 |
| | | async submitUpload() { |
| | | if (this.tempFileList.length === 0) { |
| | | this.$message.warning('请先选择要上传的文件'); |
| | | this.$message.warning("请先选择要上传的文件"); |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | // 依次上传所有文件 |
| | | for (const file of this.tempFileList) { |
| | | await this.$refs.uploadRef.submit(); |
| | | } |
| | | |
| | | this.$message.success('文件上传成功'); |
| | | this.$message.success("文件上传成功"); |
| | | this.uploadDialogVisible = false; |
| | | this.tempFileList = []; |
| | | } catch (error) { |
| | | this.$message.error('文件上传失败'); |
| | | console.error('上传失败:', 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(() => {}); |
| | | handleRemoveAttachment(type, index) { |
| | | this.$confirm("确定要删除这个附件吗?", "提示", { |
| | | confirmButtonText: "确定", |
| | | cancelButtonText: "取消", |
| | | type: "warning" |
| | | }) |
| | | .then(() => { |
| | | if (this.attachmentData[type] && this.attachmentData[type][index]) { |
| | | this.attachmentData[type].splice(index, 1); |
| | | this.$message.success("附件删除成功"); |
| | | this.updateAssessannexField(); // 更新存储字段 |
| | | } |
| | | }) |
| | | .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' |
| | | }); |
| | | // 更新assessannex存储字段 |
| | | updateAssessannexField() { |
| | | // 将所有类型的附件合并为一个数组 |
| | | const allAttachments = []; |
| | | Object.values(this.attachmentData).forEach(attachments => { |
| | | allAttachments.push(...attachments); |
| | | }); |
| | | |
| | | // 更新到表单字段 |
| | | this.form.assessannex = JSON.stringify(allAttachments); |
| | | }, |
| | | |
| | | // 文件预览 |
| | | handlePreview(file) { |
| | | this.currentPreviewFile = { |
| | | fileName: file.fileName, |
| | | fileUrl: file.fileUrl, |
| | | fileType: this.getFileType(file.fileName) |
| | | }; |
| | | this.previewVisible = true; |
| | | }, |
| | | |
| | | // 文件下载 |
| | | handleDownload(file) { |
| | | const fileUrl = file.fileUrl; |
| | | const fileName = file.fileName; |
| | | |
| | | if (fileUrl) { |
| | | const link = document.createElement("a"); |
| | | link.href = fileUrl; |
| | | link.download = fileName; |
| | | link.style.display = "none"; |
| | | document.body.appendChild(link); |
| | | link.click(); |
| | | document.body.removeChild(link); |
| | | this.$message.success("开始下载文件"); |
| | | } else { |
| | | // 其他文件类型提示下载 |
| | | this.$message.info('该文件类型暂不支持在线预览,请下载后查看'); |
| | | this.$message.warning("文件路径不存在,无法下载"); |
| | | } |
| | | }, |
| | | |
| | | // 保存所有附件信息 |
| | | handleSaveAll() { |
| | | this.saveLoading = true; |
| | | // 获取文件类型 |
| | | getFileType(fileName) { |
| | | if (!fileName) return "other"; |
| | | const extension = this.getFileExtension(fileName); |
| | | const imageTypes = ["jpg", "jpeg", "png"]; |
| | | const pdfTypes = ["pdf"]; |
| | | const officeTypes = ["doc", "docx"]; |
| | | |
| | | // 模拟保存过程 |
| | | setTimeout(() => { |
| | | this.$message.success('附件信息保存成功'); |
| | | this.saveLoading = false; |
| | | if (imageTypes.includes(extension)) return "image"; |
| | | if (pdfTypes.includes(extension)) return "pdf"; |
| | | if (officeTypes.includes(extension)) return "office"; |
| | | return "other"; |
| | | }, |
| | | |
| | | // 实际项目中调用保存接口 |
| | | // this.saveAttachments(); |
| | | }, 1000); |
| | | // 获取文件扩展名 |
| | | getFileExtension(filename) { |
| | | return filename |
| | | .split(".") |
| | | .pop() |
| | | .toLowerCase(); |
| | | }, |
| | | |
| | | // 文件大小格式化 |
| | | formatFileSize(size) { |
| | | if (size === 0) return '0 B'; |
| | | if (!size) return "0 B"; |
| | | const k = 1024; |
| | | const sizes = ['B', 'KB', 'MB', 'GB']; |
| | | 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]; |
| | | 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')}`; |
| | | // 日期时间格式化 |
| | | formatDateTime(dateTime) { |
| | | if (!dateTime) return ""; |
| | | try { |
| | | const date = new Date(dateTime); |
| | | if (isNaN(date.getTime())) return dateTime; |
| | | |
| | | const year = date.getFullYear(); |
| | | const month = String(date.getMonth() + 1).padStart(2, "0"); |
| | | const day = String(date.getDate()).padStart(2, "0"); |
| | | const hours = String(date.getHours()).padStart(2, "0"); |
| | | const minutes = String(date.getMinutes()).padStart(2, "0"); |
| | | |
| | | return `${year}-${month}-${day} ${hours}:${minutes}`; |
| | | } catch (error) { |
| | | return dateTime; |
| | | } |
| | | }, |
| | | |
| | | // 获取当前时间 |
| | | getCurrentTime() { |
| | | const now = new Date(); |
| | | return `${now.getFullYear()}-${(now.getMonth() + 1) |
| | | .toString() |
| | | .padStart(2, "0")}-${now |
| | | .getDate() |
| | | .toString() |
| | | .padStart(2, "0")} ${now |
| | | .getHours() |
| | | .toString() |
| | | .padStart(2, "0")}:${now |
| | | .getMinutes() |
| | | .toString() |
| | | .padStart(2, "0")}:${now |
| | | .getSeconds() |
| | | .toString() |
| | | .padStart(2, "0")}`; |
| | | }, |
| | | |
| | | // 保存确认信息 |
| | | async handleSave() { |
| | | try { |
| | | await this.$refs.form.validate(); |
| | | this.saveLoading = true; |
| | | |
| | | // 确保附件数据是最新的 |
| | | this.updateAssessannexField(); |
| | | |
| | | const saveData = { |
| | | ...this.form, |
| | | organdecision: this.organdecision.join(","), |
| | | organdecisionOther: this.organdecisionOther |
| | | // assessannex字段已在updateAssessannexField中更新 |
| | | }; |
| | | |
| | | const response = await relativesEdit(saveData); |
| | | |
| | | if (response.code === 200) { |
| | | this.$message.success("保存成功"); |
| | | this.$router.push("/case/confirmation"); |
| | | } else { |
| | | this.$message.error("保存失败:" + (response.msg || "未知错误")); |
| | | } |
| | | } catch (error) { |
| | | if (error !== "cancel") { |
| | | console.error("保存失败:", error); |
| | | this.$message.error("保存失败"); |
| | | } |
| | | } finally { |
| | | this.saveLoading = false; |
| | | } |
| | | } |
| | | } |
| | | }; |
| | |
| | | .detail-title { |
| | | font-size: 16px; |
| | | font-weight: bold; |
| | | margin-right: 20px; |
| | | } |
| | | |
| | | .fixed-width .el-button { |
| | | margin: 0 5px; |
| | | } |
| | | .confirmation-detail { |
| | | padding: 20px; |
| | | .attachment-section { |
| | | padding: 15px; |
| | | } |
| | | |
| | | .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 { |
| | | .attachment-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 15px; |
| | | padding-bottom: 10px; |
| | | border-bottom: 1px solid #ebeef5; |
| | | } |
| | | |
| | | .upload-title { |
| | |
| | | color: #303133; |
| | | } |
| | | |
| | | .file-info { |
| | | display: flex; |
| | | align-items: center; |
| | | .attachment-list { |
| | | margin-top: 15px; |
| | | } |
| | | |
| | | .empty-attachment { |
| | |
| | | color: #909399; |
| | | } |
| | | |
| | | /* 图片预览对话框样式 */ |
| | | :deep(.image-preview-dialog) { |
| | | width: auto; |
| | | max-width: 90vw; |
| | | } |
| | | |
| | | :deep(.image-preview-dialog .el-message-box__content) { |
| | | text-align: center; |
| | | .file-name { |
| | | font-size: 13px; |
| | | color: #606266; |
| | | } |
| | | </style> |