| | |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | |
| | | <!-- 信息员 --> |
| | | <el-row> |
| | | <el-col :span="8"> |
| | | <el-form-item label="信息员" prop="infoName"> |
| | | <el-input |
| | | v-model="formData.infoName" |
| | | placeholder="请输入信息员" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="联系电话" prop="infophone"> |
| | | <el-input |
| | | v-model="formData.infophone" |
| | | placeholder="请输入信息员联系电话" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-col :span="20"> |
| | | <el-form-item label="获取组织名称" prop="acquisitiontissuename"> |
| | | <el-input |
| | | v-model="formData.acquisitiontissuename" |
| | | placeholder="请输入获取组织名称" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <!-- 上报阶段报告人 --> |
| | | <el-col :span="8"> |
| | | <el-form-item label="报告人签字" prop="reportername"> |
| | | <el-form-item label="上报阶段报告人" prop="reportername"> |
| | | <el-input |
| | | v-model="formData.reportername" |
| | | placeholder="报告人姓名" |
| | | :disabled="true" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="联系电话" prop="reporterphone"> |
| | | <el-form-item label="报告人联系电话" prop="reporterphone"> |
| | | <el-input |
| | | v-model="formData.reporterphone" |
| | | placeholder="报告人联系电话" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="报告时间" prop="reporttime"> |
| | | <el-date-picker |
| | | v-model="formData.reporttime" |
| | | type="date" |
| | | placeholder="选择报告时间" |
| | | value-format="yyyy-MM-dd " |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <!-- 报告信息员 --> |
| | | <el-col :span="8"> |
| | | <el-form-item label="报告信息员" prop="infoName"> |
| | | <el-input |
| | | v-model="formData.infoName" |
| | | placeholder="请输入报告信息员" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="信息员联系电话" prop="infophone"> |
| | | <el-input |
| | | v-model="formData.infophone" |
| | | placeholder="请输入信息员联系电话" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-row :gutter="20"> |
| | | <!-- <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="报告时间" prop="reporttime"> |
| | | <el-date-picker |
| | |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <!-- <el-col :span="12"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="部门ID" prop="deptid"> |
| | | <el-input |
| | | v-model="formData.deptid" |
| | | placeholder="请输入部门ID" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> --> |
| | | </el-row> |
| | | </el-col> |
| | | </el-row> --> |
| | | </el-card> |
| | | |
| | | <!-- 捐献信息部分 --> |
| | | <el-card header="捐献信息" class="form-section"> |
| | | <!-- <el-card header="捐献信息" class="form-section"> |
| | | <el-row :gutter="20"> |
| | | <!-- <el-col :span="8"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="捐献类别" prop="donationcategory"> |
| | | <el-select |
| | | v-model="formData.donationcategory" |
| | |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> --> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="案例上报时间" prop="donatetime"> |
| | | <el-date-picker |
| | |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <!-- 红十字会和联系人 --> |
| | | <el-row> |
| | | <el-col :span="8"> |
| | | <el-form-item align="left" label="红十字会" prop="redorganno"> |
| | | <!-- <org-selecter |
| | | ref="addCrossOrgSelect" |
| | | :org-type="'2'" |
| | | v-model="formData.redorganno" |
| | | /> --> |
| | | |
| | | <el-select |
| | | v-model="formData.redorganname" |
| | | placeholder="请选择红十字会机构名称" |
| | |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <!-- <el-col :span="12"> |
| | | <el-form-item label="获取组织编号" prop="acquisitiontissueno"> |
| | | <el-input |
| | | v-model="formData.acquisitiontissueno" |
| | | placeholder="请输入获取组织编号" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> --> |
| | | |
| | | <el-col :span="12"> |
| | | <el-form-item label="获取组织名称" prop="acquisitiontissuename"> |
| | | <el-input |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-card> |
| | | <!-- 上报阶段附件 --> |
| | | <el-card v-if="reportAttachments && reportAttachments.length > 0" class="form-section" shadow="never"> |
| | | <div slot="header" class="section-header"> |
| | | <i class="el-icon-paperclip" style="color: #409EFF; margin-right: 8px;"></i> |
| | | <span>上报阶段附件</span> |
| | | </div> |
| | | <div class="attachment-list"> |
| | | <el-tabs v-model="reportActiveTab" type="border-card"> |
| | | <el-tab-pane |
| | | v-for="category in reportCategories" |
| | | :key="category" |
| | | :label="category + '(' + getReportCategoryCount(category) + ')'" |
| | | :name="category" |
| | | > |
| | | <el-table :data="getReportCategoryFiles(category)" 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.fileName }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="文件类型" width="100"> |
| | | <template #default="scope"> |
| | | <el-tag size="small">{{ getFileType(scope.row.fileName) }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="创建时间" width="160"> |
| | | <template #default="scope"> |
| | | <span>{{ formatDateTime(scope.row.createTime) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width="120"> |
| | | <template #default="scope"> |
| | | <el-button size="mini" type="primary" @click="handleReportPreview(scope.row)">预览</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </div> |
| | | </el-card> |
| | | |
| | | <!-- 加载中占位 --> |
| | | <el-card v-else-if="reportAttachmentLoading" class="form-section" shadow="never"> |
| | | <div slot="header" class="section-header"> |
| | | <i class="el-icon-paperclip" style="color: #409EFF; margin-right: 8px;"></i> |
| | | <span>上报阶段附件</span> |
| | | </div> |
| | | <div style="text-align:center; padding:20px;">加载附件中...</div> |
| | | </el-card> |
| | | |
| | | <!-- 有 reportId 但无附件 --> |
| | | <el-card v-else-if="editData.reportId" class="form-section" shadow="never"> |
| | | <div slot="header" class="section-header"> |
| | | <i class="el-icon-paperclip" style="color: #409EFF; margin-right: 8px;"></i> |
| | | <span>上报阶段附件</span> |
| | | </div> |
| | | <div style="text-align:center; padding:20px; color:#909399;">暂无上报附件</div> |
| | | </el-card> |
| | | </el-card> --> |
| | | </el-form> |
| | | |
| | | <!-- 捐献者登记阶段附件(可编辑,存储于亲属确认表 assessannex) --> |
| | | <el-card header="登记阶段附件" class="form-section"> |
| | | <el-tabs v-model="activeRegisterType" type="card"> |
| | | <el-tab-pane |
| | | v-for="type in registerAttachmentTypes" |
| | | :key="type.value" |
| | | :label="type.label" |
| | | :name="type.value" |
| | | > |
| | | <div class="attachment-header"> |
| | | <span class="upload-title">{{ type.label }}</span> |
| | | <el-button |
| | | size="mini" |
| | | type="primary" |
| | | icon="el-icon-plus" |
| | | @click="openUploadDialog(type.value)" |
| | | > |
| | | 添加附件 |
| | | </el-button> |
| | | </div> |
| | | |
| | | <el-table |
| | | :data="getRegisterAttachments(type.value)" |
| | | size="small" |
| | | style="width: 100%" |
| | | > |
| | | <el-table-column label="文件名" min-width="200"> |
| | | <template slot-scope="scope"> |
| | | <i |
| | | class="el-icon-document" |
| | | style="color: #409eff; margin-right: 8px" |
| | | ></i> |
| | | <span>{{ scope.row.fileName }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="文件类型" width="90" 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="90" align="center"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ formatFileSize(scope.row.fileSize) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="上传时间" width="155" align="center"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ |
| | | formatDateTime(scope.row.uploadTime || scope.row.createTime) |
| | | }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width="145" 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="getRegisterAttachments(type.value).length === 0" |
| | | class="empty-attachment" |
| | | > |
| | | <el-empty |
| | | :description="`暂无${type.label}`" |
| | | :image-size="80" |
| | | ></el-empty> |
| | | </div> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </el-card> |
| | | |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button @click="handleClose">取消</el-button> |
| | |
| | | </el-button> |
| | | </div> |
| | | </el-dialog> |
| | | |
| | | <!-- 上传附件对话框 --> |
| | | <el-dialog |
| | | :title="`上传${getCurrentTypeLabel()}附件`" |
| | | :visible.sync="uploadDialogVisible" |
| | | width="480px" |
| | | :close-on-click-modal="false" |
| | | > |
| | | <el-upload |
| | | ref="uploadRef" |
| | | class="upload-demo" |
| | | drag |
| | | :action="uploadAction" |
| | | :headers="headers" |
| | | multiple |
| | | :file-list="tempFileList" |
| | | :before-upload="beforeUpload" |
| | | :on-change="handleFileChange" |
| | | :on-remove="handleTempRemove" |
| | | :on-success="handleUploadSuccess" |
| | | :auto-upload="false" |
| | | > |
| | | <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> |
| | | |
| | | <!-- 文件预览弹窗 --> |
| | | <FilePreviewDialog |
| | | :visible="previewVisible" |
| | | :file="currentPreviewFile" |
| | | @close="previewVisible = false" |
| | | @download="handleDownload" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | getDonatebaseinfo, |
| | | updateDonatebaseinfo |
| | | } from "@/api/project/donatebaseinfo"; |
| | | import { relativesEdit, relativesAdd, relativesList } from "@/api/businessApi"; |
| | | import OrgSelecter from "@/views/project/components/orgselect"; |
| | | import { donateInfo } from "@/api/businessApi/index"; |
| | | import LiAreaSelect from "@/components/Address"; |
| | | import FilePreviewDialog from "@/components/FilePreviewDialog"; |
| | | import { getToken } from "@/utils/auth"; |
| | | |
| | | export default { |
| | | name: "EditCaseModal", |
| | | components: { |
| | | OrgSelecter, |
| | | LiAreaSelect |
| | | LiAreaSelect, |
| | | FilePreviewDialog |
| | | }, |
| | | |
| | | // 添加所有需要的字典类型 |
| | |
| | | residenceAddress: {}, |
| | | registerAddress: {}, |
| | | formData: this.getDefaultFormData(), |
| | | reportAttachments: [], // 上报阶段的附件列表 |
| | | reportAttachmentLoading: false, // 加载状态 |
| | | reportActiveTab: "登记表附件", // 当前激活的附件分类 Tab |
| | | presetCategories: ["登记表附件", "证件照", "疾病诊断治疗"], // 预设分类 |
| | | // 登记阶段附件(可编辑,存储于亲属确认表 assessannex) |
| | | registerAttachmentTypes: [ |
| | | { value: "1", label: "人体器官潜在捐献者登记表附件" }, |
| | | { value: "5", label: "证件照" }, |
| | | { value: "6", label: "疾病诊断治疗" } |
| | | ], |
| | | registerAttachmentData: { "1": [], "5": [], "6": [] }, |
| | | otherAttachments: [], |
| | | confirmationRecord: null, |
| | | activeRegisterType: "1", |
| | | uploadAction: process.env.VUE_APP_BASE_API + "/common/upload", |
| | | headers: { Authorization: "Bearer " + getToken() }, |
| | | uploadDialogVisible: false, |
| | | uploadLoading: false, |
| | | tempFileList: [], |
| | | currentUploadType: "", |
| | | previewVisible: false, |
| | | currentPreviewFile: null, |
| | | rules: { |
| | | name: [ |
| | | { required: true, message: "请输入捐献者姓名", trigger: "blur" } |
| | |
| | | bloodtype: [ |
| | | { required: true, message: "请选择血型", trigger: "change" } |
| | | ], |
| | | donatetime: [ |
| | | { required: true, message: "请选择案例时间", trigger: "change" } |
| | | ], |
| | | // donatetime: [ |
| | | // { required: true, message: "请选择案例时间", trigger: "change" } |
| | | // ], |
| | | reporttime: [ |
| | | { required: true, message: "请选择报告时间", trigger: "change" } |
| | | ], |
| | |
| | | } |
| | | } |
| | | }, |
| | | reportCategories() { |
| | | if (!this.reportAttachments || this.reportAttachments.length === 0) |
| | | return []; |
| | | const cats = new Set(); |
| | | this.reportAttachments.forEach(item => { |
| | | const type = item.fileType || item.filetype || ""; |
| | | if (this.presetCategories.includes(type)) { |
| | | cats.add(type); |
| | | } else { |
| | | cats.add("未分类"); |
| | | } |
| | | }); |
| | | const order = ["登记表附件", "证件照", "疾病诊断治疗", "未分类"]; |
| | | return order.filter(c => cats.has(c)); |
| | | } |
| | | }, |
| | | watch: { |
| | | visible(newVal) { |
| | |
| | | }); |
| | | } else { |
| | | this.handleClose(); |
| | | } |
| | | }, |
| | | "editData.reportId": { |
| | | immediate: true, |
| | | handler(newVal) { |
| | | if (newVal) { |
| | | this.loadReportAttachments(newVal); |
| | | } else { |
| | | this.reportAttachments = []; |
| | | } |
| | | } |
| | | }, |
| | | editData: { |
| | |
| | | console.log(this.registerAddress, "registerAddress12"); |
| | | |
| | | this.calculateAge(data.birthday); |
| | | await this.loadRegisterAttachments(); |
| | | } catch (error) { |
| | | console.error("获取案例数据失败:", error); |
| | | this.$message.error("获取案例数据失败"); |
| | |
| | | this.formData.registercommunityname = address.qu; |
| | | }, |
| | | |
| | | // 加载登记阶段附件(读取亲属确认表 assessannex,与确认详情页共用同一份数据) |
| | | // 捐献确认信息统一通过 confirmationBaseInfoList 接口获取 |
| | | async loadRegisterAttachments() { |
| | | const infoid = this.editData && this.editData.id; |
| | | if (!infoid) { |
| | | this.resetAttachments(); |
| | | return; |
| | | } |
| | | try { |
| | | const res = await relativesList({ infoid }); |
| | | const record = this.parseConfirmationBaseInfo(res); |
| | | if (record && record.id) { |
| | | this.confirmationRecord = record; |
| | | this.parseAssessannex(record.assessannex); |
| | | } else { |
| | | this.confirmationRecord = null; |
| | | this.resetAttachments(); |
| | | } |
| | | } catch (e) { |
| | | console.warn("获取亲属确认附件失败:", e); |
| | | this.resetAttachments(); |
| | | } |
| | | }, |
| | | |
| | | // 解析 confirmationBaseInfoList 返回的确认基础信息(兼容数组 / rows / 单对象结构) |
| | | parseConfirmationBaseInfo(res) { |
| | | if (!res || res.code !== 200) return null; |
| | | const data = res.data; |
| | | if (!data) return null; |
| | | if (Array.isArray(data)) return data[0] || null; |
| | | if (Array.isArray(data.rows)) return data.rows[0] || null; |
| | | if (Array.isArray(data.list)) return data.list[0] || null; |
| | | return data; |
| | | }, |
| | | |
| | | resetAttachments() { |
| | | Object.keys(this.registerAttachmentData).forEach(key => { |
| | | this.registerAttachmentData[key] = []; |
| | | }); |
| | | this.otherAttachments = []; |
| | | }, |
| | | |
| | | parseAssessannex(assessannex) { |
| | | this.resetAttachments(); |
| | | if (!assessannex) return; |
| | | try { |
| | | const list = |
| | | typeof assessannex === "string" ? JSON.parse(assessannex) : assessannex; |
| | | if (!Array.isArray(list)) return; |
| | | list.forEach(item => { |
| | | const type = String(item.type || ""); |
| | | if (this.registerAttachmentData[type]) { |
| | | this.registerAttachmentData[type].push(item); |
| | | } else { |
| | | this.otherAttachments.push(item); |
| | | } |
| | | }); |
| | | } catch (e) { |
| | | console.warn("解析assessannex失败:", e); |
| | | } |
| | | }, |
| | | |
| | | getRegisterAttachments(type) { |
| | | return this.registerAttachmentData[type] || []; |
| | | }, |
| | | |
| | | // 序列化登记阶段附件,并保留确认阶段等其他附件 |
| | | serializeAssessannex() { |
| | | const all = [...this.otherAttachments]; |
| | | this.registerAttachmentTypes.forEach(t => { |
| | | all.push(...(this.registerAttachmentData[t.value] || [])); |
| | | }); |
| | | return JSON.stringify(all); |
| | | }, |
| | | |
| | | getCurrentTypeLabel() { |
| | | const type = this.registerAttachmentTypes.find( |
| | | t => t.value === this.currentUploadType |
| | | ); |
| | | return type ? type.label : ""; |
| | | }, |
| | | |
| | | 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; |
| | | 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; |
| | | }, |
| | | |
| | | handleUploadSuccess(response, file) { |
| | | if (response.code !== 200) { |
| | | this.$message.error(response.msg || "上传失败"); |
| | | return; |
| | | } |
| | | const newAttachment = { |
| | | id: Date.now(), |
| | | fileName: file.name, |
| | | fileUrl: response.url, |
| | | fileSize: file.size, |
| | | fileType: this.getFileExtension(file.name), |
| | | type: this.currentUploadType, |
| | | uploadTime: this.getCurrentTime(), |
| | | uploader: "当前用户" |
| | | }; |
| | | if (this.registerAttachmentData[this.currentUploadType]) { |
| | | this.registerAttachmentData[this.currentUploadType].push(newAttachment); |
| | | } |
| | | this.$message.success("上传成功"); |
| | | this.uploadLoading = false; |
| | | this.uploadDialogVisible = false; |
| | | this.tempFileList = []; |
| | | }, |
| | | |
| | | submitUpload() { |
| | | if (this.tempFileList.length === 0) { |
| | | this.$message.warning("请先选择要上传的文件"); |
| | | return; |
| | | } |
| | | this.uploadLoading = true; |
| | | this.$refs.uploadRef.submit(); |
| | | }, |
| | | |
| | | handleRemoveAttachment(type, index) { |
| | | this.$confirm("确定要删除这个附件吗?", "提示", { |
| | | confirmButtonText: "确定", |
| | | cancelButtonText: "取消", |
| | | type: "warning" |
| | | }) |
| | | .then(() => { |
| | | const container = this.registerAttachmentData[type]; |
| | | if (container && container[index]) { |
| | | container.splice(index, 1); |
| | | this.$message.success("附件删除成功"); |
| | | } |
| | | }) |
| | | .catch(() => {}); |
| | | }, |
| | | |
| | | 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.warning("文件路径不存在,无法下载"); |
| | | } |
| | | }, |
| | | |
| | | getFileType(fileName) { |
| | | if (!fileName) return "other"; |
| | | const extension = this.getFileExtension(fileName); |
| | | const imageTypes = ["jpg", "jpeg", "png"]; |
| | | const pdfTypes = ["pdf"]; |
| | | const officeTypes = ["doc", "docx"]; |
| | | if (imageTypes.includes(extension)) return "image"; |
| | | if (pdfTypes.includes(extension)) return "pdf"; |
| | | if (officeTypes.includes(extension)) return "office"; |
| | | return "other"; |
| | | }, |
| | | |
| | | getFileExtension(filename) { |
| | | return filename |
| | | .split(".") |
| | | .pop() |
| | | .toLowerCase(); |
| | | }, |
| | | |
| | | formatFileSize(size) { |
| | | if (!size) 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]; |
| | | }, |
| | | |
| | | 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")}`; |
| | | }, |
| | | |
| | | // 保存登记阶段附件到亲属确认表 assessannex |
| | | async saveAssessannex() { |
| | | const infoid = this.formData.id; |
| | | if (!infoid) return; |
| | | const assessannex = this.serializeAssessannex(); |
| | | try { |
| | | if (this.confirmationRecord && this.confirmationRecord.id) { |
| | | // 已存在确认表记录:仅更新附件字段,保留其余信息 |
| | | await relativesEdit({ ...this.confirmationRecord, assessannex }); |
| | | } else { |
| | | // 确认表记录不存在:新增完整记录(携带登记表基础信息) |
| | | await relativesAdd(this.buildConfirmationRecord(infoid, assessannex)); |
| | | } |
| | | } catch (e) { |
| | | console.warn("保存登记阶段附件失败:", e); |
| | | this.$message.warning("登记阶段附件保存失败,请重试"); |
| | | } |
| | | }, |
| | | |
| | | // 构建新增亲属确认表记录:携带捐献者基础信息,而非仅 infoid + assessannex |
| | | buildConfirmationRecord(infoid, assessannex) { |
| | | const f = this.formData; |
| | | return { |
| | | infoid, |
| | | caseNo: f.caseNo || "", |
| | | name: f.name || "", |
| | | sex: f.sex || "", |
| | | age: f.age != null ? f.age : "", |
| | | diagnosisname: f.diagnosisname || "", |
| | | treatmenthospitalname: f.treatmenthospitalname || "", |
| | | relativeconfirmationsign: "0", |
| | | state: 2, |
| | | assessannex |
| | | }; |
| | | }, |
| | | |
| | | handleClose() { |
| | | console.log("关闭弹框"); |
| | | this.isEdit = false; |
| | |
| | | this.formData = this.getDefaultFormData(); |
| | | this.residenceAddress = {}; |
| | | this.registerAddress = {}; |
| | | this.resetAttachments(); |
| | | this.$emit("closed"); |
| | | }, |
| | | |
| | |
| | | |
| | | const result = await updateDonatebaseinfo(submitData); |
| | | if (result.code === 200) { |
| | | await this.saveAssessannex(); |
| | | this.$message.success(this.isEdit ? "更新成功" : "新增成功"); |
| | | this.$emit("success", result.data); |
| | | console.log(1122); |
| | |
| | | |
| | | return data; |
| | | }, |
| | | /** 加载上报案例附件 */ |
| | | async loadReportAttachments(reportId) { |
| | | this.reportAttachmentLoading = true; |
| | | try { |
| | | const res = await donateInfo(reportId); |
| | | const data = res.data || res; |
| | | this.reportAttachments = (data.annexfilesList || []).map(item => ({ |
| | | ...item, |
| | | fileType: item.fileType || item.filetype || "" // 兼容字段大小写 |
| | | })); |
| | | } catch (error) { |
| | | console.error("加载上报附件失败:", error); |
| | | this.$message.error("加载上报附件失败"); |
| | | } finally { |
| | | this.reportAttachmentLoading = false; |
| | | } |
| | | }, |
| | | |
| | | /** 获取某分类文件数量 */ |
| | | getReportCategoryCount(category) { |
| | | return this.reportAttachments.filter(item => { |
| | | const type = item.fileType || ""; |
| | | if (category === "未分类") { |
| | | return !this.presetCategories.includes(type); |
| | | } |
| | | return type === category; |
| | | }).length; |
| | | }, |
| | | |
| | | /** 获取某分类文件列表 */ |
| | | getReportCategoryFiles(category) { |
| | | return this.reportAttachments.filter(item => { |
| | | const type = item.fileType || ""; |
| | | if (category === "未分类") { |
| | | return !this.presetCategories.includes(type); |
| | | } |
| | | return type === category; |
| | | }); |
| | | }, |
| | | |
| | | /** 预览上报附件(直接在新窗口打开) */ |
| | | handleReportPreview(file) { |
| | | const url = file.fileUrl || file.path; |
| | | if (url) { |
| | | window.open(url, "_blank"); |
| | | } else { |
| | | this.$message.warning("文件地址不存在"); |
| | | } |
| | | }, |
| | | |
| | | /** 获取文件类型(用于标签显示) */ |
| | | 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"]; |
| | | if (imageTypes.includes(extension)) return "image"; |
| | | if (pdfTypes.includes(extension)) return "pdf"; |
| | | if (officeTypes.includes(extension)) return "office"; |
| | | return "other"; |
| | | }, |
| | | |
| | | /** 日期时间格式化(复用) */ |
| | | formatDateTime(dateTime) { |
| | | if (!dateTime) return ""; |
| | | return this.$moment |
| | | ? this.$moment(dateTime).format("YYYY-MM-DD HH:mm:ss") |
| | | : dateTime; |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | |
| | | .form-section:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | .attachment-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 12px; |
| | | } |
| | | |
| | | .upload-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | } |
| | | |
| | | .empty-attachment { |
| | | padding: 12px 0; |
| | | } |
| | | </style> |