| | |
| | | <template> |
| | | <base-stage :stage-data="stageData" :case-info="caseInfo"> |
| | | <template #header> |
| | | <el-alert |
| | | :title="alertTitle" |
| | | :type="alertType" |
| | | :description="alertDescription" |
| | | show-icon |
| | | :closable="false" |
| | | /> |
| | | </template> |
| | | <div class="assessment-detail"> |
| | | |
| | | <el-row :gutter="20" style="margin-top: 20px;"> |
| | | <el-col :span="8"> |
| | | <el-card> |
| | | <div slot="header" class="card-header"> |
| | | <span>评估概况</span> |
| | | </div> |
| | | <div class="assessment-stats"> |
| | | <div class="stat-item"> |
| | | <span class="stat-label">评估状态:</span> |
| | | <el-tag :type="getStatusTag(stageData.status)"> |
| | | {{ getStatusText(stageData.status) }} |
| | | </el-tag> |
| | | </div> |
| | | <div class="stat-item"> |
| | | <span class="stat-label">评估医生:</span> |
| | | <span>{{ stageData.operator || '待分配' }}</span> |
| | | </div> |
| | | <div class="stat-item"> |
| | | <span class="stat-label">开始时间:</span> |
| | | <span>{{ formatTime(stageData.updateTime) }}</span> |
| | | </div> |
| | | <div class="stat-item"> |
| | | <span class="stat-label">完成时间:</span> |
| | | <span>{{ formatTime(stageData.completeTime) || '-' }}</span> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | |
| | | <el-col :span="16"> |
| | | <el-card> |
| | | <div slot="header" class="card-header"> |
| | | <span>评估项目进度</span> |
| | | </div> |
| | | <div class="progress-list"> |
| | | <div v-for="item in assessmentItems" :key="item.name" class="progress-item"> |
| | | <div class="progress-info"> |
| | | <span class="item-name">{{ item.name }}</span> |
| | | <span class="item-status"> |
| | | <el-tag :type="item.status === 'completed' ? 'success' : 'warning'" size="small"> |
| | | {{ item.status === 'completed' ? '已完成' : '待评估' }} |
| | | </el-tag> |
| | | </span> |
| | | </div> |
| | | <el-progress |
| | | :percentage="item.status === 'completed' ? 100 : 0" |
| | | :show-text="false" |
| | | :status="item.status === 'completed' ? 'success' : 'exception'" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-card style="margin-top: 20px;"> |
| | | <div slot="header" class="card-header"> |
| | | <span>评估详情记录</span> |
| | | <el-button type="primary" size="small" @click="handleViewReport"> |
| | | 查看评估报告 |
| | | </el-button> |
| | | <el-card class="organ-assessment-card"> |
| | | <div slot="header" class="clearfix"> |
| | | <span>器官评估表</span> |
| | | <!-- <el-button |
| | | v-if="isCoordinator && allOrgansAssessed" |
| | | style="float: right; margin-left: 10px" |
| | | type="primary" |
| | | size="mini" |
| | | @click="handleCompleteAssessment" |
| | | > |
| | | 确认完成评估 |
| | | </el-button> --> |
| | | <!-- <span v-if="!isCoordinator" class="jstitle"> |
| | | 当前角色:{{ currentDepartment }}评估人员 |
| | | </span> --> |
| | | </div> |
| | | <el-descriptions :column="2" border> |
| | | <el-descriptions-item label="生理指标评估"> |
| | | {{ assessmentDetails.physiological || '待评估' }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="器官功能评估"> |
| | | {{ assessmentDetails.organFunction || '待评估' }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="感染性疾病筛查"> |
| | | {{ assessmentDetails.infectionScreening || '待筛查' }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="恶性肿瘤筛查"> |
| | | {{ assessmentDetails.cancerScreening || '待筛查' }} |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="评估结论"> |
| | | <el-tag :type="assessmentDetails.conclusion ? 'success' : 'warning'"> |
| | | {{ assessmentDetails.conclusion || '评估中' }} |
| | | </el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="评估医生意见"> |
| | | {{ assessmentDetails.doctorOpinion || '待填写' }} |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | |
| | | <el-table |
| | | :data="organAssessmentList" |
| | | v-loading="assessmentLoading" |
| | | style="width: 100%" |
| | | :row-class-name="getRowClassName" |
| | | > |
| | | <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="department" |
| | | width="120" |
| | | /> |
| | | <el-table-column |
| | | label="评估人员" |
| | | align="center" |
| | | prop="assessor" |
| | | width="100" |
| | | /> |
| | | <el-table-column label="评估状态" align="center" width="100"> |
| | | <template slot-scope="scope"> |
| | | <el-tag |
| | | :type="scope.row.assessmentStatus === '1' ? 'success' : 'warning'" |
| | | size="small" |
| | | > |
| | | {{ scope.row.assessmentStatus === "1" ? "已评估" : "待评估" }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="功能状态" align="center" width="100"> |
| | | <template slot-scope="scope"> |
| | | <el-tag |
| | | :type="getFunctionStatusType(scope.row.functionStatus)" |
| | | size="small" |
| | | > |
| | | {{ getFunctionStatusText(scope.row.functionStatus) }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="评估意见" |
| | | align="center" |
| | | prop="assessmentOpinion" |
| | | min-width="150" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column label="评估时间" align="center" width="120"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ scope.row.assessmentTime || "-" }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column |
| | | label="操作" |
| | | align="center" |
| | | width="150" |
| | | class-name="small-padding fixed-width" |
| | | > |
| | | <template slot-scope="scope"> |
| | | <el-button |
| | | v-if="canAssessOrgan(scope.row)" |
| | | size="mini" |
| | | type="text" |
| | | @click="handleOrganAssess(scope.row)" |
| | | >{{ |
| | | scope.row.assessmentStatus === "1" ? "查看/修改" : "评估" |
| | | }}</el-button |
| | | > |
| | | <el-button v-else size="mini" type="text" disabled |
| | | >无权限</el-button |
| | | > |
| | | <el-button |
| | | v-if="isCoordinator" |
| | | size="mini" |
| | | type="text" |
| | | @click="handleViewOrganDetail(scope.row)" |
| | | >详情</el-button |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <!-- 器官评估详情 --> |
| | | <el-collapse |
| | | v-model="activeOrgans" |
| | | accordion |
| | | class="organ-detail-collapse" |
| | | > |
| | | <el-collapse-item |
| | | v-for="organ in organAssessmentList" |
| | | :key="organ.organType" |
| | | :name="organ.organType" |
| | | :title="getOrganTitle(organ)" |
| | | > |
| | | <organ-assessment-form |
| | | :organ-data="organ" |
| | | :readonly="!canAssessOrgan(organ)" |
| | | @save="handleSaveOrganAssessment" |
| | | /> |
| | | </el-collapse-item> |
| | | </el-collapse> |
| | | </el-card> |
| | | </base-stage> |
| | | |
| | | <!-- 附件预览弹窗 --> |
| | | <attachment-preview |
| | | :visible="attachmentVisible" |
| | | :attachment-list="attachmentList" |
| | | @close="attachmentVisible = false" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import BaseStage from './BaseStage.vue'; |
| | | // import { getAssessment, updateOrganAssessment, completeAssessment } from "@/api/case/assessment"; |
| | | import { |
| | | getAssessment, |
| | | updateOrganAssessment, |
| | | completeAssessment |
| | | } from "./api/mockAssessmentApi"; |
| | | |
| | | import OrganAssessmentForm from "./components/OrganAssessmentForm.vue"; |
| | | import AttachmentPreview from "./components/AttachmentPreview.vue"; |
| | | |
| | | export default { |
| | | name: 'MedicalAssessmentStage', |
| | | components: { BaseStage }, |
| | | props: { |
| | | stageData: { |
| | | type: Object, |
| | | default: () => ({}) |
| | | }, |
| | | caseInfo: { |
| | | type: Object, |
| | | default: () => ({}) |
| | | } |
| | | }, |
| | | computed: { |
| | | alertTitle() { |
| | | const status = this.stageData.status; |
| | | return status === 'completed' ? '医学评估完成' : |
| | | status === 'in_progress' ? '医学评估进行中' : '待开始医学评估'; |
| | | }, |
| | | alertType() { |
| | | const status = this.stageData.status; |
| | | return status === 'completed' ? 'success' : |
| | | status === 'in_progress' ? 'warning' : 'info'; |
| | | }, |
| | | alertDescription() { |
| | | const status = this.stageData.status; |
| | | return status === 'completed' ? '所有医学评估项目已完成,供者符合捐献条件' : |
| | | status === 'in_progress' ? '医学评估正在进行中,请关注评估进度' : '等待开始医学评估流程'; |
| | | } |
| | | }, |
| | | name: "AssessmentDetail", |
| | | components: { OrganAssessmentForm, AttachmentPreview }, |
| | | data() { |
| | | return { |
| | | assessmentItems: [ |
| | | { name: '生理指标评估', status: 'completed' }, |
| | | { name: '器官功能评估', status: 'completed' }, |
| | | { name: '感染性疾病筛查', status: 'completed' }, |
| | | { name: '恶性肿瘤筛查', status: 'completed' }, |
| | | { name: '遗传性疾病筛查', status: 'completed' }, |
| | | { name: '心理状态评估', status: 'completed' } |
| | | // 评估ID |
| | | assessmentId: undefined, |
| | | // 评估数据 |
| | | assessmentData: {}, |
| | | // 器官评估列表 |
| | | organAssessmentList: [], |
| | | // 附件列表 |
| | | attachmentList: [], |
| | | // 加载状态 |
| | | assessmentLoading: false, |
| | | // 当前用户信息 |
| | | currentUser: { |
| | | id: "001", |
| | | name: "张医生", |
| | | department: "心脏外科", |
| | | role: "department" // coordinator: 协调员, department: 科室人员 |
| | | }, |
| | | // 展开的器官 |
| | | activeOrgans: [], |
| | | // 附件预览可见性 |
| | | attachmentVisible: false, |
| | | // 字典选项 |
| | | genderOptions: [ |
| | | { value: "0", label: "男" }, |
| | | { value: "1", label: "女" } |
| | | ], |
| | | assessmentDetails: { |
| | | physiological: '各项生理指标正常,符合捐献要求', |
| | | organFunction: '主要器官功能良好,无禁忌症', |
| | | infectionScreening: '传染病筛查均为阴性', |
| | | cancerScreening: '无恶性肿瘤迹象', |
| | | conclusion: '适合器官捐献', |
| | | doctorOpinion: '供者身体状况良好,符合捐献医学标准' |
| | | } |
| | | 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: "皮肤" } |
| | | ] |
| | | }; |
| | | }, |
| | | methods: { |
| | | getStatusText(status) { |
| | | const map = { |
| | | 'completed': '已完成', |
| | | 'in_progress': '进行中', |
| | | 'pending': '未开始' |
| | | }; |
| | | return map[status] || '未知'; |
| | | computed: { |
| | | // 是否是协调员 |
| | | isCoordinator() { |
| | | return this.currentUser.role === "coordinator"; |
| | | }, |
| | | handleViewReport() { |
| | | this.$message.info('查看医学评估报告功能'); |
| | | // 当前科室 |
| | | currentDepartment() { |
| | | return this.currentUser.department; |
| | | }, |
| | | // 所有器官是否都已评估 |
| | | allOrgansAssessed() { |
| | | return this.organAssessmentList.every( |
| | | organ => organ.assessmentStatus === "1" |
| | | ); |
| | | } |
| | | }, |
| | | created() { |
| | | this.assessmentId = this.$route.query.id; |
| | | this.getAssessmentDetail(); |
| | | }, |
| | | methods: { |
| | | // 获取评估详情 - 使用Mock数据 |
| | | getAssessmentDetail() { |
| | | this.assessmentLoading = true; |
| | | getAssessment(this.assessmentId) |
| | | .then(response => { |
| | | if (response.code === 200) { |
| | | this.assessmentData = response.data.caseInfo; |
| | | this.organAssessmentList = response.data.organAssessments || []; |
| | | this.attachmentList = response.data.attachments || []; |
| | | } else { |
| | | this.$message.error("获取评估详情失败"); |
| | | } |
| | | this.assessmentLoading = false; |
| | | }) |
| | | .catch(error => { |
| | | console.error("获取评估详情失败:", error); |
| | | this.assessmentLoading = false; |
| | | this.$message.error("获取评估详情失败"); |
| | | }); |
| | | }, |
| | | // 状态过滤器 |
| | | statusFilter(status) { |
| | | const statusMap = { |
| | | "0": "warning", |
| | | "1": "primary", |
| | | "2": "success", |
| | | "3": "danger" |
| | | }; |
| | | return statusMap[status] || "info"; |
| | | }, |
| | | statusTextFilter(status) { |
| | | const statusMap = { |
| | | "0": "待评估", |
| | | "1": "评估中", |
| | | "2": "已完成", |
| | | "3": "已关闭" |
| | | }; |
| | | return statusMap[status] || "未知"; |
| | | }, |
| | | // 获取功能状态类型 |
| | | getFunctionStatusType(status) { |
| | | const typeMap = { |
| | | "1": "success", // 正常 |
| | | "2": "warning", // 轻度异常 |
| | | "3": "danger", // 重度异常 |
| | | "4": "info" // 无法评估 |
| | | }; |
| | | return typeMap[status] || "info"; |
| | | }, |
| | | // 获取功能状态文本 |
| | | getFunctionStatusText(status) { |
| | | const textMap = { |
| | | "1": "正常", |
| | | "2": "轻度异常", |
| | | "3": "重度异常", |
| | | "4": "无法评估" |
| | | }; |
| | | return textMap[status] || "未知"; |
| | | }, |
| | | // 检查是否有权限评估该器官 |
| | | canAssessOrgan(organ) { |
| | | if (this.isCoordinator) return true; |
| | | return organ.department === this.currentDepartment; |
| | | }, |
| | | // 获取行类名 |
| | | getRowClassName({ row }) { |
| | | return this.canAssessOrgan(row) ? "assessable-row" : "non-assessable-row"; |
| | | }, |
| | | // 获取器官标题 |
| | | getOrganTitle(organ) { |
| | | const organName = |
| | | this.organTypeOptions.find(opt => opt.value === organ.organType) |
| | | ?.label || organ.organType; |
| | | return `${organName}评估详情(${organ.department})`; |
| | | }, |
| | | // 器官评估 |
| | | handleOrganAssess(organ) { |
| | | this.activeOrgans = [organ.organType]; |
| | | }, |
| | | // 查看器官详情 |
| | | handleViewOrganDetail(organ) { |
| | | this.activeOrgans = [organ.organType]; |
| | | }, |
| | | // 保存器官评估 - 使用Mock API |
| | | handleSaveOrganAssessment(organData) { |
| | | updateOrganAssessment(organData) |
| | | .then(response => { |
| | | if (response.code === 200) { |
| | | this.$message.success("评估保存成功"); |
| | | // 刷新数据 |
| | | this.getAssessmentDetail(); |
| | | } |
| | | }) |
| | | .catch(error => { |
| | | console.error("保存评估失败:", error); |
| | | this.$message.error("保存失败"); |
| | | }); |
| | | }, |
| | | // 查看附件预览 |
| | | handleAttachmentPreview() { |
| | | this.attachmentVisible = true; |
| | | }, |
| | | // 完成评估 - 使用Mock API |
| | | handleCompleteAssessment() { |
| | | this.$confirm("确认完成所有器官评估吗?完成后将无法修改", "确认操作", { |
| | | confirmButtonText: "确定", |
| | | cancelButtonText: "取消", |
| | | type: "warning" |
| | | }).then(() => { |
| | | completeAssessment(this.assessmentId) |
| | | .then(response => { |
| | | if (response.code === 200) { |
| | | this.$message.success("评估完成确认成功"); |
| | | this.getAssessmentDetail(); |
| | | } |
| | | }) |
| | | .catch(error => { |
| | | console.error("完成评估失败:", error); |
| | | this.$message.error("操作失败"); |
| | | }); |
| | | }); |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .assessment-stats { |
| | | padding: 10px 0; |
| | | .assessment-detail { |
| | | padding: 20px; |
| | | } |
| | | |
| | | .stat-item { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 15px; |
| | | padding: 8px 0; |
| | | border-bottom: 1px solid #f0f0f0; |
| | | .basic-info-card { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .stat-label { |
| | | color: #606266; |
| | | font-weight: 500; |
| | | .organ-assessment-card { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .progress-list { |
| | | padding: 10px 0; |
| | | .organ-detail-collapse { |
| | | margin-top: 20px; |
| | | } |
| | | |
| | | .progress-item { |
| | | margin-bottom: 15px; |
| | | ::v-deep .assessable-row { |
| | | background-color: #f0f9ff; |
| | | } |
| | | |
| | | .progress-info { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 8px; |
| | | ::v-deep .non-assessable-row { |
| | | background-color: #fafafa; |
| | | } |
| | | |
| | | .item-name { |
| | | color: #606266; |
| | | font-size: 14px; |
| | | ::v-deep .el-descriptions__label { |
| | | width: 120px; |
| | | background-color: #f5f7fa; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .fixed-width .el-button { |
| | | margin: 0 2px; |
| | | } |
| | | .jstitle { |
| | | float: right; |
| | | font-size: 18px !important; |
| | | font-weight: 600; |
| | | color: #2645f7; |
| | | font-size: 12px; |
| | | } |
| | | </style> |