| | |
| | | assessmentData.caseNo |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="潜在捐献者姓名">{{ |
| | | assessmentData.donorName |
| | | assessmentData.name || assessmentData.donorName |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="性别"> |
| | | <dict-tag :options="genderOptions" :value="assessmentData.gender" /> |
| | | <dict-tag |
| | | :options="dict.type.sys_user_sex" |
| | | :value="assessmentData.sex" |
| | | /> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="年龄" |
| | | >{{ assessmentData.age }}岁</el-descriptions-item |
| | | > |
| | | <el-descriptions-item label="血型"> |
| | | <dict-tag |
| | | :options="bloodTypeOptions" |
| | | :value="assessmentData.bloodType" |
| | | /> |
| | | {{ assessmentData.bloodtype }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="证件号码">{{ |
| | | assessmentData.idCardNo |
| | | assessmentData.idcardno |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="疾病诊断">{{ |
| | | assessmentData.diagnosis |
| | | assessmentData.diagnosisname |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="所在医疗机构">{{ |
| | | assessmentData.hospitalName |
| | | assessmentData.treatmenthospitalname |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="主治医生">{{ |
| | | assessmentData.doctorName |
| | | <el-descriptions-item label="协调员">{{ |
| | | assessmentData.coordinatorName |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="申请评估时间">{{ |
| | | assessmentData.applyTime |
| | | <el-descriptions-item label="评估时间">{{ |
| | | assessmentData.assessTime |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="评估类型"> |
| | | <dict-tag |
| | | :options="assessmentTypeOptions" |
| | | :value="assessmentData.assessmentType" |
| | | /> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="评估状态"> |
| | | <el-tag :type="statusFilter(assessmentData.assessmentStatus)"> |
| | | {{ statusTextFilter(assessmentData.assessmentStatus) }} |
| | | <el-tag :type="statusFilter(assessmentData.assessState)"> |
| | | {{ statusTextFilter(assessmentData.assessState) }} |
| | | </el-tag> |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | |
| | | type="primary" |
| | | size="mini" |
| | | @click="handleCompleteAssessment" |
| | | :loading="saveLoading" |
| | | > |
| | | 确认完成评估 |
| | | </el-button> |
| | |
| | | 当前角色:{{ currentDepartment }}评估人员 |
| | | </span> |
| | | </div> |
| | | <el-row> |
| | | <el-form-item label-width="100px" label="评估器官"> |
| | | <el-checkbox-group v-model="organdecision"> |
| | | |
| | | <!-- 捐献决定表单 --> |
| | | <el-form> |
| | | <el-form-item label-width="100px" label="捐献决定"> |
| | | <el-checkbox-group |
| | | v-model="organdecision" |
| | | @change="handleOrganDecisionChange" |
| | | :disabled="!isEdit" |
| | | > |
| | | <el-checkbox |
| | | v-for="item in organselection" |
| | | :key="item" |
| | |
| | | </el-checkbox-group> |
| | | <el-input |
| | | v-if="organdecision.includes('其他')" |
| | | v-model="assessmentData.organdecisionOther" |
| | | v-model="organdecisionOther" |
| | | placeholder="请输入其他捐献决定的具体内容" |
| | | style="margin-top: 10px; width: 300px;" |
| | | :readonly="!isEdit" |
| | | @input="handleOtherDecisionInput" |
| | | ></el-input> |
| | | </el-form-item> |
| | | </el-row> |
| | | </el-form> |
| | | |
| | | <!-- 器官评估表格 --> |
| | | <el-table |
| | | :data="organAssessmentList" |
| | | :data="filteredOrganAssessmentList" |
| | | v-loading="assessmentLoading" |
| | | style="width: 100%" |
| | | :row-class-name="getRowClassName" |
| | | :expand-row-keys="expandedRowKeys" |
| | | @expand-change="handleExpandChange" |
| | | row-key="organType" |
| | | row-key="organno" |
| | | empty-text="当前捐献决定下暂无需要评估的器官" |
| | | > |
| | | <el-table-column type="expand" width="60"> |
| | | <el-table-column type="expand"> |
| | | <template slot-scope="scope"> |
| | | <div class="organ-expand-content" v-if="scope.row.expanded"> |
| | | <el-tabs |
| | |
| | | :assessment-data="assessment" |
| | | :assessment-index="index" |
| | | :readonly="!canAssessOrgan(scope.row)" |
| | | @save="handleSaveOrganAssessment" |
| | | @add-assessment="handleAddAssessment" |
| | | /> |
| | | </el-tab-pane> |
| | | |
| | | <!-- 添加评估按钮 --> |
| | | <el-tab-pane name="add" v-if="canAssessOrgan(scope.row)"> |
| | | <el-tab-pane |
| | | name="add" |
| | | v-if="canAssessOrgan(scope.row) && isEdit" |
| | | > |
| | | <template slot="label"> |
| | | <el-button |
| | | type="text" |
| | |
| | | <div class="assessment-summary"> |
| | | <el-descriptions title="评估结果汇总" :column="2" border> |
| | | <el-descriptions-item label="器官类型">{{ |
| | | scope.row.organName |
| | | scope.row.organname |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="评估科室">{{ |
| | | scope.row.department |
| | | <el-descriptions-item label="获取机构">{{ |
| | | scope.row.gainhospitalname |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="评估次数" :span="2"> |
| | | <el-tag type="info" |
| | |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | |
| | | <!-- 附件汇总 --> |
| | | <el-card header="所有评估附件" style="margin-top: 20px;"> |
| | | <el-table |
| | | :data="getAllAttachments(scope.row)" |
| | | size="small" |
| | | empty-text="暂无附件" |
| | | <!-- 评估详情汇总 --> |
| | | <el-card header="评估详情" style="margin-top: 20px;"> |
| | | <el-descriptions :column="1" border> |
| | | <el-descriptions-item label="获取前活检"> |
| | | <el-tag |
| | | :type=" |
| | | scope.row.isbiopsybefore === '1' |
| | | ? 'success' |
| | | : 'info' |
| | | " |
| | | > |
| | | <el-table-column label="附件名称" prop="fileName" /> |
| | | <el-table-column label="评估阶段" width="120"> |
| | | <template slot-scope="{ row }"> |
| | | 第{{ row.assessmentIndex + 1 }}次评估 |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="上传时间" |
| | | prop="uploadTime" |
| | | width="180" |
| | | /> |
| | | <el-table-column label="操作" width="120"> |
| | | <template slot-scope="{ row }"> |
| | | <el-button |
| | | type="text" |
| | | @click="handlePreviewAttachment(row)" |
| | | >预览</el-button |
| | | {{ scope.row.isbiopsybefore === "1" ? "是" : "否" }} |
| | | </el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="获取后活检"> |
| | | <el-tag |
| | | :type=" |
| | | scope.row.isbiopsyafter === '1' |
| | | ? 'success' |
| | | : 'info' |
| | | " |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | {{ scope.row.isbiopsyafter === "1" ? "是" : "否" }} |
| | | </el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="边缘器官"> |
| | | <el-tag |
| | | :type=" |
| | | scope.row.ismarginalorgan === '1' |
| | | ? 'warning' |
| | | : 'info' |
| | | " |
| | | > |
| | | {{ |
| | | scope.row.ismarginalorgan === "1" ? "是" : "否" |
| | | }} |
| | | </el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="病原菌阳性"> |
| | | <el-tag |
| | | :type=" |
| | | scope.row.ispathogenpositive === '1' |
| | | ? 'danger' |
| | | : 'info' |
| | | " |
| | | > |
| | | {{ |
| | | scope.row.ispathogenpositive === "1" ? "是" : "否" |
| | | }} |
| | | </el-tag> |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | </el-card> |
| | | </div> |
| | | </el-tab-pane> |
| | |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column |
| | | label="器官类型" |
| | | align="center" |
| | | prop="organType" |
| | | width="120" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <dict-tag |
| | | :options="organTypeOptions" |
| | | :value="scope.row.organType" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="器官类型" align="center" prop="organname" /> |
| | | |
| | | <el-table-column label="器官编号" align="center" prop="organnumber" /> |
| | | |
| | | <el-table-column |
| | | label="评估科室" |
| | | label="获取机构" |
| | | align="center" |
| | | prop="department" |
| | | width="120" |
| | | prop="gainhospitalname" |
| | | show-overflow-tooltip |
| | | /> |
| | | |
| | | <el-table-column label="评估人员" align="center" prop="assessor" /> |
| | | |
| | | <!-- 动态显示评估状态列 --> |
| | | <el-table-column |
| | |
| | | <el-table-column label="整体状态" align="center" width="100"> |
| | | <template slot-scope="scope"> |
| | | <el-tag |
| | | :type="scope.row.assessmentStatus === '1' ? 'success' : 'primary'" |
| | | :type=" |
| | | getOrganOverallStatus(scope.row) === 'completed' |
| | | ? 'success' |
| | | : getOrganOverallStatus(scope.row) === 'assessing' |
| | | ? 'primary' |
| | | : 'warning' |
| | | " |
| | | size="small" |
| | | > |
| | | {{ scope.row.assessmentStatus === "1" ? "已完成" : "评估中" }} |
| | | {{ getOrganOverallStatusText(scope.row) }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | v-if="canAssessOrgan(scope.row)" |
| | | v-if="canAssessOrgan(scope.row) && isEdit" |
| | | size="mini" |
| | | type="text" |
| | | @click="handleToggleExpand(scope.row)" |
| | | > |
| | | {{ |
| | | expandedRowKeys.includes(scope.row.organType) ? "收起" : "详情" |
| | | expandedRowKeys.includes(scope.row.organno) ? "收起" : "详情" |
| | | }} |
| | | </el-button> |
| | | <el-button |
| | | v-else-if="!isEdit" |
| | | size="mini" |
| | | type="text" |
| | | @click="handleToggleExpand(scope.row)" |
| | | > |
| | | {{ |
| | | expandedRowKeys.includes(scope.row.organno) ? "收起" : "查看" |
| | | }} |
| | | </el-button> |
| | | <el-button v-else size="mini" type="text" disabled |
| | |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | |
| | | <!-- 整体保存按钮 --> |
| | | <div class="footer-actions" v-if="isEdit"> |
| | | <el-button type="primary" @click="handleSaveAll" :loading="saveLoading">保存评估表</el-button> |
| | | <el-button @click="handleCancel">取消</el-button> |
| | | </div> |
| | | |
| | | <!-- 文件预览弹窗 --> |
| | | <FilePreviewDialog |
| | |
| | | |
| | | <script> |
| | | import { |
| | | getAssessment, |
| | | updateOrganAssessment, |
| | | completeAssessment |
| | | } from "./mockAssessmentApi"; |
| | | evaluateBaseInfolist, |
| | | assessedit, |
| | | assessAdd |
| | | } from "@/api/businessApi/index"; |
| | | import FilePreviewDialog from "@/components/FilePreviewDialog"; |
| | | import OrganAssessmentForm from "./components/OrganAssessmentForm.vue"; |
| | | |
| | | export default { |
| | | name: "AssessmentDetail", |
| | | components: { OrganAssessmentForm, FilePreviewDialog }, |
| | | dicts: ["sys_user_sex", "sys_Organ", "sys_0_1"], |
| | | data() { |
| | | return { |
| | | assessmentId: undefined, |
| | | assessmentData: {}, |
| | | organAssessmentList: [], |
| | | attachmentList: [], |
| | | // 是否编辑模式 |
| | | isEdit: false, |
| | | // 加载状态 |
| | | assessmentLoading: false, |
| | | organdecision: [], |
| | | saveLoading: false, |
| | | // 数据ID |
| | | infoid: undefined, |
| | | assessmentId: undefined, |
| | | // 主要数据 |
| | | assessmentData: {}, |
| | | organAssessmentList: [], // 所有器官数据 |
| | | // 展开行相关 |
| | | expandedRowKeys: [], |
| | | // 附件相关 |
| | | currentPreviewFile: null, |
| | | attachmentVisible: false, |
| | | |
| | | currentUser: { |
| | | id: "001", |
| | | name: "张医生", |
| | | department: "协调员", |
| | | role: "coordinator" |
| | | }, |
| | | //department:心脏、coordinator:协调员 |
| | | // 字典选项 |
| | | genderOptions: [ |
| | | { value: "0", label: "男" }, |
| | | { value: "1", label: "女" } |
| | | ], |
| | | bloodTypeOptions: [ |
| | | { value: "A", label: "A型" }, |
| | | { value: "B", label: "B型" }, |
| | | { value: "O", label: "O型" }, |
| | | { value: "AB", label: "AB型" } |
| | | ], |
| | | assessmentTypeOptions: [ |
| | | { value: "1", label: "初次评估" }, |
| | | { value: "2", label: "最终评估" } |
| | | ], |
| | | organTypeOptions: [ |
| | | { value: "heart", label: "心脏" }, |
| | | { value: "liver", label: "肝脏" }, |
| | | { value: "kidney", label: "肾脏" }, |
| | | { value: "lung", label: "肺脏" }, |
| | | { value: "pancreas", label: "胰腺" }, |
| | | { value: "intestine", label: "肠道" }, |
| | | { value: "cornea", label: "角膜" }, |
| | | { value: "skin", label: "皮肤" } |
| | | ], |
| | | // 捐献决定相关 |
| | | organdecision: [], |
| | | organdecisionOther: "", |
| | | organselection: [ |
| | | "肝脏", |
| | | "双肾", |
| | |
| | | "双眼组织", |
| | | "遗体", |
| | | "其他" |
| | | ] |
| | | ], |
| | | // 器官类型映射关系 |
| | | organDecisionMapping: { |
| | | 肝脏: ["肝脏"], |
| | | 双肾: ["左肾", "右肾"], |
| | | 左肾: ["左肾"], |
| | | 右肾: ["右肾"], |
| | | 心脏: ["心脏"], |
| | | 肺脏: ["肺脏"], |
| | | 胰腺: ["胰腺"], |
| | | 小肠: ["小肠"], |
| | | 双眼组织: ["角膜"], |
| | | 遗体: ["皮肤", "骨骼", "其他组织"], |
| | | 其他: [] // 其他类型不映射具体器官 |
| | | }, |
| | | // 用户信息 |
| | | currentUser: { |
| | | id: "001", |
| | | name: "张医生", |
| | | department: "心脏科", |
| | | role: "doctor" // coordinator, doctor |
| | | } |
| | | }; |
| | | }, |
| | | computed: { |
| | |
| | | currentDepartment() { |
| | | return this.currentUser.department; |
| | | }, |
| | | // 根据捐献决定过滤后的器官列表 |
| | | filteredOrganAssessmentList() { |
| | | if (!this.organdecision || this.organdecision.length === 0) { |
| | | return []; |
| | | } |
| | | |
| | | // 获取所有选中的器官类型 |
| | | const selectedOrgans = new Set(); |
| | | this.organdecision.forEach(decision => { |
| | | const organs = this.organDecisionMapping[decision] || []; |
| | | organs.forEach(organ => selectedOrgans.add(organ)); |
| | | }); |
| | | |
| | | // 过滤器官评估列表 |
| | | return this.organAssessmentList.filter(organ => |
| | | selectedOrgans.has(organ.organname) |
| | | ); |
| | | }, |
| | | // 检查所有过滤后的器官是否都已评估 |
| | | allOrgansAssessed() { |
| | | return this.organAssessmentList.every( |
| | | return this.filteredOrganAssessmentList.every( |
| | | organ => |
| | | organ.assessments && |
| | | organ.assessments.length > 0 && |
| | |
| | | ); |
| | | } |
| | | }, |
| | | watch: { |
| | | // 监听捐献决定变化,用于复杂逻辑处理 |
| | | organdecision: { |
| | | handler(newVal, oldVal) { |
| | | this.handleComplexDecisionChange(newVal, oldVal); |
| | | }, |
| | | deep: true |
| | | } |
| | | }, |
| | | created() { |
| | | this.infoid = this.$route.query.infoid; |
| | | this.assessmentId = this.$route.query.id; |
| | | this.isEdit = this.$route.query.assess === "true"; |
| | | this.getAssessmentDetail(); |
| | | }, |
| | | methods: { |
| | | // 获取默认评估数据结构 |
| | | getDefaultAssessment() { |
| | | // 整体保存方法 |
| | | async handleSaveAll() { |
| | | this.saveLoading = true; |
| | | try { |
| | | // 1. 准备主评估表数据 |
| | | const saveData = { |
| | | // 根据 id 是否存在决定是更新还是新增 |
| | | id: this.assessmentData.id || undefined, |
| | | infoid: this.infoid, |
| | | caseNo: this.assessmentData.caseNo, |
| | | donorno: this.assessmentData.donorno, |
| | | treatmenthospitalname: this.assessmentData.treatmenthospitalname, |
| | | treatmenthospitalno: this.assessmentData.treatmenthospitalno, |
| | | sex: this.assessmentData.sex, |
| | | age: this.assessmentData.age, |
| | | bloodtype: this.assessmentData.bloodtype, |
| | | idcardno: this.assessmentData.idcardno, |
| | | diagnosisname: this.assessmentData.diagnosisname, |
| | | coordinatorName: this.assessmentData.coordinatorName, |
| | | assessTime: this.assessmentData.assessTime || new Date().toISOString(), |
| | | assessState: this.assessmentData.assessState, |
| | | assessannex: this.assessmentData.assessannex, |
| | | // 捐献决定信息 |
| | | organdecision: this.organdecision.join(','), |
| | | organdecisionOther: this.organdecisionOther, |
| | | // 器官评估列表 |
| | | serviceMedicalevaluationorgans: this.organAssessmentList.map(organ => ({ |
| | | id: organ.id, |
| | | infoid: organ.infoid, |
| | | donorno: organ.donorno, |
| | | organno: organ.organno, |
| | | organname: organ.organname, |
| | | organnumber: organ.organnumber, |
| | | gainhospitalno: organ.gainhospitalno, |
| | | gainhospitalname: organ.gainhospitalname, |
| | | isbiopsybefore: organ.isbiopsybefore, |
| | | isbiopsyafter: organ.isbiopsyafter, |
| | | ismarginalorgan: organ.ismarginalorgan, |
| | | ispathogenpositive: organ.ispathogenpositive, |
| | | ispnf: organ.ispnf, |
| | | isdgf: organ.isdgf, |
| | | // 将 assessments 数组序列化到 assesscontent 字段 |
| | | assesscontent: JSON.stringify(organ.assessments) |
| | | })) |
| | | }; |
| | | |
| | | // 2. 根据 id 判断调用哪个 API |
| | | const saveMethod = this.assessmentData.id ? assessedit : assessAdd; |
| | | const response = await saveMethod(saveData); |
| | | |
| | | if (response.code === 200) { |
| | | this.$message.success('评估表保存成功!'); |
| | | // 保存成功后,更新本地的 assessmentData.id(对于新增情况) |
| | | if (!this.assessmentData.id && response.data && response.data.id) { |
| | | this.assessmentData.id = response.data.id; |
| | | } |
| | | } else { |
| | | this.$message.error('保存失败:' + (response.msg || '未知错误')); |
| | | } |
| | | } catch (error) { |
| | | console.error('保存评估表失败:', error); |
| | | this.$message.error('保存失败,请重试'); |
| | | } finally { |
| | | this.saveLoading = false; |
| | | } |
| | | }, |
| | | |
| | | // 取消按钮事件 |
| | | handleCancel() { |
| | | this.$router.go(-1); |
| | | }, |
| | | |
| | | // 捐献决定变更处理 |
| | | handleOrganDecisionChange(newDecision) { |
| | | // 自动处理相关逻辑 |
| | | this.autoHandleDecisionChange(newDecision); |
| | | // 强制重新渲染 |
| | | this.$forceUpdate(); |
| | | // 如果从有选择变为无选择,清空展开状态 |
| | | if (newDecision.length === 0) { |
| | | this.expandedRowKeys = []; |
| | | } |
| | | }, |
| | | |
| | | // 其他捐献决定输入处理 |
| | | handleOtherDecisionInput(value) { |
| | | // 输入时不做单独保存,等待整体保存 |
| | | }, |
| | | |
| | | // 自动处理决定变更逻辑 |
| | | autoHandleDecisionChange(newDecision) { |
| | | // 如果选择了"双肾",自动取消单独的"左肾"和"右肾"选择 |
| | | if (newDecision.includes("双肾")) { |
| | | this.organdecision = newDecision.filter( |
| | | item => item !== "左肾" && item !== "右肾" |
| | | ); |
| | | } |
| | | // 如果选择了"左肾"或"右肾",取消"双肾"选择 |
| | | else if (newDecision.includes("左肾") || newDecision.includes("右肾")) { |
| | | this.organdecision = newDecision.filter(item => item !== "双肾"); |
| | | } |
| | | |
| | | // 处理互斥逻辑 |
| | | this.handleExclusiveDecisions(); |
| | | }, |
| | | |
| | | // 处理互斥的捐献决定 |
| | | handleExclusiveDecisions() { |
| | | // 遗体捐献与其他器官捐献互斥(根据业务需求调整) |
| | | if (this.organdecision.includes("遗体")) { |
| | | // 可以设置只保留遗体捐献,或者根据业务需求处理 |
| | | } |
| | | }, |
| | | |
| | | // 复杂决策变化处理 |
| | | handleComplexDecisionChange(newVal, oldVal) { |
| | | // 处理新增的选择 |
| | | const addedDecisions = newVal.filter(item => !oldVal.includes(item)); |
| | | const removedDecisions = oldVal.filter(item => !newVal.includes(item)); |
| | | |
| | | // 对新增加的选择进行特殊处理 |
| | | addedDecisions.forEach(decision => { |
| | | this.handleNewDecision(decision); |
| | | }); |
| | | |
| | | // 对移除的选择进行清理 |
| | | removedDecisions.forEach(decision => { |
| | | this.handleRemovedDecision(decision); |
| | | }); |
| | | }, |
| | | |
| | | // 处理新增的捐献决定 |
| | | handleNewDecision(decision) { |
| | | // 根据映射关系自动创建对应的器官评估项 |
| | | this.autoCreateOrganAssessments(decision); |
| | | }, |
| | | |
| | | // 自动创建器官评估项 |
| | | autoCreateOrganAssessments(decision) { |
| | | const organsToCreate = this.organDecisionMapping[decision]; |
| | | |
| | | if (organsToCreate && organsToCreate.length > 0) { |
| | | organsToCreate.forEach(organName => { |
| | | this.ensureOrganExists(organName); |
| | | }); |
| | | |
| | | // 显示创建提示 |
| | | if (organsToCreate.length > 0) { |
| | | this.$message.success( |
| | | `已为【${decision}】创建${organsToCreate.length}个评估项` |
| | | ); |
| | | } |
| | | } else { |
| | | console.warn(`捐献决定【${decision}】没有配置器官映射关系`); |
| | | } |
| | | }, |
| | | |
| | | // 处理移除的捐献决定 |
| | | handleRemovedDecision(decision) { |
| | | // 根据业务需求添加清理逻辑 |
| | | const relatedOrgans = this.organDecisionMapping[decision] || []; |
| | | relatedOrgans.forEach(organ => { |
| | | // 可以在这里添加清理相关器官评估的逻辑 |
| | | }); |
| | | }, |
| | | |
| | | // 确保器官存在(带重复检查) |
| | | ensureOrganExists(organName) { |
| | | // 检查是否已存在同名器官评估项 |
| | | const exists = this.organAssessmentList.some( |
| | | organ => organ.organname === organName |
| | | ); |
| | | |
| | | if (!exists) { |
| | | // 创建新的器官评估项 |
| | | const newOrgan = { |
| | | id: `organ_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, |
| | | organno: `ORG${Date.now()}`, |
| | | organname: organName, |
| | | gainhospitalname: "待分配机构", |
| | | isbiopsybefore: "0", |
| | | isbiopsyafter: "0", |
| | | ismarginalorgan: "0", |
| | | ispathogenpositive: "0", |
| | | assessments: [this.getDefaultAssessment(0)], |
| | | activeAssessmentTab: "assessment_0", |
| | | expanded: false, |
| | | createTime: new Date().toISOString() |
| | | }; |
| | | |
| | | this.organAssessmentList = [...this.organAssessmentList, newOrgan]; |
| | | return true; |
| | | } |
| | | return false; |
| | | }, |
| | | |
| | | // 获取评估详情 |
| | | async getAssessmentDetail() { |
| | | this.assessmentLoading = true; |
| | | try { |
| | | const response = await evaluateBaseInfolist({ infoid: this.infoid }); |
| | | |
| | | if (response.code === 200) { |
| | | this.handleResponseData(response); |
| | | } else { |
| | | this.$message.error("获取详情失败:" + (response.msg || "未知错误")); |
| | | } |
| | | } catch (error) { |
| | | console.error("获取评估详情失败:", error); |
| | | this.$message.error("获取详情失败"); |
| | | } finally { |
| | | this.assessmentLoading = false; |
| | | } |
| | | }, |
| | | |
| | | // 处理接口响应数据 |
| | | handleResponseData(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; |
| | | } |
| | | } else { |
| | | detailData = response; |
| | | } |
| | | |
| | | // 映射字段到评估数据 |
| | | this.assessmentData = { |
| | | id: detailData.id || this.assessmentId, |
| | | infoid: detailData.infoid || this.infoid, |
| | | caseNo: detailData.caseNo || "", |
| | | name: detailData.name || detailData.donorName || "", |
| | | sex: detailData.sex || "", |
| | | age: detailData.age || "", |
| | | bloodtype: detailData.bloodtype || "", |
| | | idcardno: detailData.idcardno || "", |
| | | diagnosisname: detailData.diagnosisname || "", |
| | | treatmenthospitalname: detailData.treatmenthospitalname || "", |
| | | coordinatorName: detailData.coordinatorName || "", |
| | | assessTime: detailData.assessTime || "", |
| | | assessState: detailData.assessState || "1", |
| | | assessannex: detailData.assessannex || "" |
| | | }; |
| | | |
| | | // 处理捐献决定数据 |
| | | if (detailData.organdecision) { |
| | | this.organdecision = Array.isArray(detailData.organdecision) |
| | | ? detailData.organdecision |
| | | : (detailData.organdecision || "").split(","); |
| | | this.organdecisionOther = detailData.organdecisionOther || ""; |
| | | } |
| | | |
| | | // 处理器官评估数据 |
| | | this.processOrganAssessmentData(detailData); |
| | | }, |
| | | |
| | | // 处理器官评估数据 |
| | | processOrganAssessmentData(detailData) { |
| | | let organList = []; |
| | | |
| | | // 从接口数据中获取器官评估列表 |
| | | if (detailData.serviceMedicalevaluationorgans) { |
| | | if (Array.isArray(detailData.serviceMedicalevaluationorgans)) { |
| | | organList = detailData.serviceMedicalevaluationorgans; |
| | | } |
| | | } |
| | | |
| | | // 转换器官数据格式,支持多次评估 |
| | | this.organAssessmentList = organList.map(organ => { |
| | | const assessments = []; |
| | | |
| | | // 解析assesscontent字段中的多次评估数据 |
| | | if (organ.assesscontent) { |
| | | try { |
| | | const assessData = typeof organ.assesscontent === "string" |
| | | ? JSON.parse(organ.assesscontent) |
| | | : organ.assesscontent; |
| | | |
| | | if (Array.isArray(assessData)) { |
| | | assessments.push( |
| | | ...assessData.map((item, index) => ({ |
| | | ...item, |
| | | index: index, |
| | | status: item.status || "assessed" |
| | | })) |
| | | ); |
| | | } |
| | | } catch (error) { |
| | | console.warn("解析评估内容失败:", error); |
| | | assessments.push(this.getDefaultAssessment(0)); |
| | | } |
| | | } else { |
| | | assessments.push(this.getDefaultAssessment(0)); |
| | | } |
| | | |
| | | return { |
| | | ...organ, |
| | | assessments: assessments, |
| | | activeAssessmentTab: assessments.length > 0 ? "assessment_0" : "summary", |
| | | expanded: false |
| | | }; |
| | | }); |
| | | }, |
| | | |
| | | // 获取默认评估数据结构 |
| | | getDefaultAssessment(index) { |
| | | return { |
| | | index: index, |
| | | status: "pending", |
| | | assessmentTime: "", |
| | | assessor: "", |
| | | functionStatus: "", |
| | | assessmentOpinion: "", |
| | | attachments: [], |
| | | clinicalData: {}, |
| | | labResults: {} |
| | | labResults: {}, |
| | | createTime: new Date().toISOString() |
| | | }; |
| | | }, |
| | | |
| | | // 获取评估详情 |
| | | getAssessmentDetail() { |
| | | this.assessmentLoading = true; |
| | | getAssessment(this.assessmentId) |
| | | .then(response => { |
| | | if (response.code === 200) { |
| | | this.assessmentData = response.data.caseInfo; |
| | | this.organAssessmentList = this.transformOrganData( |
| | | response.data.organAssessments || [] |
| | | ); |
| | | } |
| | | this.assessmentLoading = false; |
| | | }) |
| | | .catch(error => { |
| | | console.error("获取评估详情失败:", error); |
| | | this.assessmentLoading = false; |
| | | }); |
| | | }, |
| | | |
| | | // 转换器官数据格式,支持多次评估 |
| | | transformOrganData(organList) { |
| | | return organList.map(organ => { |
| | | const organName = this.getOrganName(organ.organType); |
| | | |
| | | // 转换为多次评估的数据结构 |
| | | const assessments = []; |
| | | if (organ.firstAssessment) { |
| | | assessments.push({ ...organ.firstAssessment, index: 0 }); |
| | | } |
| | | if (organ.secondAssessment) { |
| | | assessments.push({ ...organ.secondAssessment, index: 1 }); |
| | | } |
| | | // 可以继续添加更多评估... |
| | | |
| | | // 设置器官名称和评估数据 |
| | | organ.organName = organName; |
| | | organ.assessments = assessments; |
| | | organ.activeAssessmentTab = |
| | | assessments.length > 0 ? "assessment_0" : "summary"; |
| | | organ.expanded = false; |
| | | |
| | | // 计算整体评估状态 |
| | | organ.assessmentStatus = this.calculateOverallStatus(organ); |
| | | |
| | | return organ; |
| | | }); |
| | | }, |
| | | |
| | | // 计算最大评估次数(用于表头显示) |
| | | // 计算最大评估次数 |
| | | getMaxAssessmentCount() { |
| | | const maxCount = Math.max( |
| | | ...this.organAssessmentList.map(organ => |
| | | organ.assessments ? organ.assessments.length : 0 |
| | | ) |
| | | ); |
| | | return Math.max(maxCount, 2); // 至少显示2列 |
| | | return Math.max(maxCount, 1); |
| | | }, |
| | | |
| | | // 计算整体评估状态 |
| | | calculateOverallStatus(organ) { |
| | | if (!organ.assessments || organ.assessments.length === 0) return "0"; |
| | | // 获取器官整体状态 |
| | | getOrganOverallStatus(organ) { |
| | | if (!organ.assessments || organ.assessments.length === 0) { |
| | | return "pending"; |
| | | } |
| | | |
| | | const allAssessed = organ.assessments.every( |
| | | assessment => assessment.status === "assessed" |
| | |
| | | assessment => assessment.status === "assessed" |
| | | ); |
| | | |
| | | if (allAssessed) return "1"; |
| | | if (someAssessed) return "2"; |
| | | return "0"; |
| | | if (allAssessed) return "completed"; |
| | | if (someAssessed) return "assessing"; |
| | | return "pending"; |
| | | }, |
| | | |
| | | getOrganOverallStatusText(organ) { |
| | | const status = this.getOrganOverallStatus(organ); |
| | | const statusMap = { |
| | | pending: "待评估", |
| | | assessing: "评估中", |
| | | completed: "已完成" |
| | | }; |
| | | return statusMap[status] || "未知"; |
| | | }, |
| | | |
| | | // 切换展开行 |
| | | handleToggleExpand(row) { |
| | | const key = row.organType; |
| | | const key = row.organno; |
| | | const index = this.expandedRowKeys.indexOf(key); |
| | | |
| | | if (index > -1) { |
| | |
| | | } else { |
| | | this.expandedRowKeys = [key]; |
| | | this.organAssessmentList.forEach(item => { |
| | | item.expanded = item.organType === key; |
| | | item.expanded = item.organno === key; |
| | | }); |
| | | } |
| | | }, |
| | | |
| | | // 展开行变化 |
| | | handleExpandChange(row, expandedRows) { |
| | | this.expandedRowKeys = expandedRows.map(item => item.organType); |
| | | this.expandedRowKeys = expandedRows.map(item => item.organno); |
| | | this.organAssessmentList.forEach(item => { |
| | | item.expanded = this.expandedRowKeys.includes(item.organType); |
| | | item.expanded = this.expandedRowKeys.includes(item.organno); |
| | | }); |
| | | }, |
| | | |
| | | // 添加新评估 |
| | | handleAddNewAssessment(organ) { |
| | | const newAssessment = { |
| | | ...this.getDefaultAssessment(), |
| | | index: organ.assessments.length |
| | | ...this.getDefaultAssessment(organ.assessments.length), |
| | | assessor: this.currentUser.name |
| | | }; |
| | | |
| | | organ.assessments.push(newAssessment); |
| | | organ.activeAssessmentTab = `assessment_${organ.assessments.length - 1}`; |
| | | |
| | | // 更新整体状态 |
| | | organ.assessmentStatus = this.calculateOverallStatus(organ); |
| | | |
| | | this.$message.success("已添加新的评估"); |
| | | }, |
| | | |
| | | // 处理添加评估事件 |
| | | handleAddAssessment(data) { |
| | | const { organData, currentIndex } = data; |
| | | const { organData } = data; |
| | | this.handleAddNewAssessment(organData); |
| | | }, |
| | | |
| | | // 保存评估 |
| | | handleSaveOrganAssessment(saveData) { |
| | | const { organData, assessmentData, assessmentIndex } = saveData; |
| | | |
| | | const organToUpdate = { |
| | | ...organData, |
| | | assessments: organData.assessments.map((assessment, index) => |
| | | index === assessmentIndex |
| | | ? { |
| | | ...assessmentData, |
| | | status: "assessed", |
| | | assessmentTime: new Date().toISOString(), |
| | | assessor: this.currentUser.name |
| | | } |
| | | : assessment |
| | | ) |
| | | }; |
| | | |
| | | // 更新整体状态 |
| | | organToUpdate.assessmentStatus = this.calculateOverallStatus( |
| | | organToUpdate |
| | | ); |
| | | |
| | | updateOrganAssessment(organToUpdate) |
| | | .then(response => { |
| | | if (response.code === 200) { |
| | | this.$message.success(`第${assessmentIndex + 1}次评估保存成功`); |
| | | this.getAssessmentDetail(); |
| | | |
| | | // 更新当前展开行的数据 |
| | | const index = this.organAssessmentList.findIndex( |
| | | item => item.organType === organData.organType |
| | | ); |
| | | if (index !== -1) { |
| | | this.organAssessmentList.splice(index, 1, organToUpdate); |
| | | } |
| | | } |
| | | }) |
| | | .catch(error => { |
| | | console.error("保存评估失败:", error); |
| | | this.$message.error("保存失败"); |
| | | }); |
| | | }, |
| | | |
| | | // 获取最新评估时间 |
| | |
| | | return assessed.sort( |
| | | (a, b) => new Date(b.assessmentTime) - new Date(a.assessmentTime) |
| | | )[0].assessmentTime; |
| | | }, |
| | | |
| | | // 获取所有附件 |
| | | getAllAttachments(organ) { |
| | | const attachments = []; |
| | | |
| | | if (organ.assessments) { |
| | | organ.assessments.forEach((assessment, index) => { |
| | | if (assessment.attachments) { |
| | | assessment.attachments.forEach(att => { |
| | | attachments.push({ |
| | | ...att, |
| | | assessmentIndex: index, |
| | | assessmentNumber: index + 1 |
| | | }); |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | return attachments; |
| | | }, |
| | | |
| | | // 预览附件 |
| | | handlePreviewAttachment(attachment) { |
| | | this.currentPreviewFile = { |
| | | fileName: attachment.fileName, |
| | | fileUrl: attachment.path || attachment.fileUrl, |
| | | fileType: this.getFileType(attachment.fileName) |
| | | }; |
| | | this.attachmentVisible = true; |
| | | }, |
| | | |
| | | // 获取文件类型 |
| | | getFileType(fileName) { |
| | | if (!fileName) return "other"; |
| | | |
| | | const extension = fileName |
| | | .split(".") |
| | | .pop() |
| | | .toLowerCase(); |
| | | const imageTypes = ["jpg", "jpeg", "png", "gif", "bmp", "webp"]; |
| | | const pdfTypes = ["pdf"]; |
| | | const officeTypes = ["doc", "docx", "xls", "xlsx", "ppt", "pptx"]; |
| | | |
| | | if (imageTypes.includes(extension)) return "image"; |
| | | if (pdfTypes.includes(extension)) return "pdf"; |
| | | if (officeTypes.includes(extension)) return "office"; |
| | | return "other"; |
| | | }, |
| | | |
| | | // 获取评估状态标签类型 |
| | |
| | | return textMap[status] || "未知"; |
| | | }, |
| | | |
| | | // 获取器官名称 |
| | | getOrganName(organType) { |
| | | const organ = this.organTypeOptions.find(opt => opt.value === organType); |
| | | return organ ? organ.label : organType; |
| | | }, |
| | | |
| | | // 检查评估权限 |
| | | canAssessOrgan(organ) { |
| | | console.log(organ,'organ'); |
| | | |
| | | if (this.isCoordinator) return true; |
| | | return organ.department === this.currentDepartment; |
| | | if (!this.isEdit) return false; |
| | | return ( |
| | | organ.gainhospitalname && |
| | | organ.gainhospitalname.includes(this.currentDepartment) |
| | | ); |
| | | }, |
| | | |
| | | // 获取行类名 |
| | |
| | | // 状态过滤器 |
| | | statusFilter(status) { |
| | | const statusMap = { |
| | | "0": "warning", |
| | | "1": "primary", |
| | | "2": "success", |
| | | "3": "danger" |
| | | "1": "warning", |
| | | "2": "primary", |
| | | "3": "success" |
| | | }; |
| | | return statusMap[status] || "info"; |
| | | }, |
| | | |
| | | statusTextFilter(status) { |
| | | const statusMap = { |
| | | "0": "待评估", |
| | | "1": "评估中", |
| | | "2": "已完成", |
| | | "3": "已关闭" |
| | | "1": "待评估", |
| | | "2": "评估中", |
| | | "3": "已完成" |
| | | }; |
| | | return statusMap[status] || "未知"; |
| | | }, |
| | | |
| | | // 查看附件 |
| | | handleAttachmentPreview() { |
| | | if (this.assessmentData.assessannex) { |
| | | try { |
| | | const annexData = typeof this.assessmentData.assessannex === "string" |
| | | ? JSON.parse(this.assessmentData.assessannex) |
| | | : this.assessmentData.assessannex; |
| | | |
| | | if (Array.isArray(annexData) && annexData.length > 0) { |
| | | this.currentPreviewFile = annexData[0]; |
| | | this.attachmentVisible = true; |
| | | } else { |
| | | this.$message.info("暂无附件可预览"); |
| | | } |
| | | } catch (error) { |
| | | this.$message.info("附件数据格式错误"); |
| | | } |
| | | } else { |
| | | this.$message.info("暂无附件"); |
| | | } |
| | | }, |
| | | |
| | | handleCompleteAssessment() { |
| | | this.$confirm("确认完成所有器官评估吗?完成后将无法修改", "确认操作", { |
| | | // 完成评估 |
| | | async handleCompleteAssessment() { |
| | | try { |
| | | await this.$confirm( |
| | | "确认完成所有器官评估吗?完成后将无法修改", |
| | | "确认操作", |
| | | { |
| | | confirmButtonText: "确定", |
| | | cancelButtonText: "取消", |
| | | type: "warning" |
| | | }).then(() => { |
| | | completeAssessment(this.assessmentId) |
| | | .then(response => { |
| | | } |
| | | ); |
| | | |
| | | // 更新评估状态为已完成 |
| | | const updateData = { |
| | | ...this.assessmentData, |
| | | assessState: "3", |
| | | assessTime: new Date().toISOString() |
| | | }; |
| | | |
| | | const response = await assessedit(updateData); |
| | | |
| | | if (response.code === 200) { |
| | | this.$message.success("评估完成确认成功"); |
| | | this.getAssessmentDetail(); |
| | | this.assessmentData.assessState = "3"; |
| | | this.isEdit = false; |
| | | } else { |
| | | this.$message.error("操作失败:" + (response.msg || "未知错误")); |
| | | } |
| | | }) |
| | | .catch(error => { |
| | | } catch (error) { |
| | | if (error !== "cancel") { |
| | | console.error("完成评估失败:", error); |
| | | this.$message.error("操作失败"); |
| | | }); |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }; |
| | |
| | | |
| | | .assessment-summary { |
| | | padding: 10px; |
| | | } |
| | | |
| | | /* 底部保存按钮样式 */ |
| | | .footer-actions { |
| | | margin-top: 20px; |
| | | text-align: center; |
| | | padding: 20px; |
| | | border-top: 1px solid #eaeaea; |
| | | } |
| | | |
| | | /* 响应式设计 */ |
| | |
| | | .fixed-width .el-button { |
| | | margin: 0 2px; |
| | | } |
| | | |
| | | /* 捐献决定样式优化 */ |
| | | .organ-decision-info { |
| | | margin: 10px 0; |
| | | padding: 10px; |
| | | background-color: #f8f9fa; |
| | | border-radius: 4px; |
| | | border-left: 4px solid #409eff; |
| | | } |
| | | |
| | | .decision-tag { |
| | | margin: 2px 5px; |
| | | } |
| | | </style> |