feat(critical-value): 危急值处理记录闭环

This commit is contained in:
2026-06-17 12:25:27 +08:00
parent f79c5a2c26
commit fc892e96dc
10 changed files with 341 additions and 0 deletions

View File

@@ -4,3 +4,6 @@ export function confirmValue(id, params) { return request({ url: '/api/v1/critic
export function closeValue(id) { return request({ url: '/api/v1/critical-value/close/' + id, method: 'put' }) }
export function getStatistics() { return request({ url: '/api/v1/critical-value/statistics', method: 'get' }) }
export function getOverdueList() { return request({ url: '/api/v1/critical-value/overdue', method: 'get' }) }
export function getPendingHandleList() { return request({ url: '/api/v1/critical-value/pending-handle', method: 'get' }) }
export function handleCriticalValue(data) { return request({ url: '/api/v1/critical-value/handle', method: 'post', data: data }) }
export function getHandleHistory(criticalValueId) { return request({ url: '/api/v1/critical-value/history', method: 'get', params: { criticalValueId } }) }

View File

@@ -0,0 +1,207 @@
<template>
<div class="critical-value-handle-container">
<el-card v-loading="loading">
<template #header>
<div class="card-header">
<span>危急值处理</span>
<el-button type="primary" size="small" @click="handleQuery">刷新</el-button>
</div>
</template>
<el-table :data="tableData" border style="width: 100%">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="patientName" label="患者姓名" width="120" />
<el-table-column prop="itemName" label="危急项目" min-width="160" show-overflow-tooltip />
<el-table-column prop="resultValue" label="结果" width="100" align="center" />
<el-table-column prop="referenceRange" label="参考范围" width="120" />
<el-table-column prop="labDepartment" label="检验科室" width="120" />
<el-table-column prop="reportTime" label="报告时间" width="170" />
<el-table-column prop="status" label="状态" width="100" align="center">
<template #default="scope">
<el-tag v-if="scope.row.status === 'PENDING'" type="danger">待处理</el-tag>
<el-tag v-else-if="scope.row.status === 'RECEIVED'" type="warning">已接收</el-tag>
<el-tag v-else-if="scope.row.status === 'PROCESSING'" type="primary">处理中</el-tag>
<el-tag v-else-if="scope.row.status === 'CLOSED'" type="success">已关闭</el-tag>
<el-tag v-else type="info">{{ scope.row.status }}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center" fixed="right">
<template #default="scope">
<el-button v-if="scope.row.status !== 'CLOSED'" link type="primary" @click="handleProcess(scope.row)">处理</el-button>
<el-button link type="info" @click="handleHistory(scope.row)">历史</el-button>
</template>
</el-table-column>
</el-table>
<el-empty v-if="!loading && tableData.length === 0" description="暂无待处理危急值" />
</el-card>
<el-dialog v-model="processDialogVisible" title="危急值处理" width="600px" destroy-on-close :close-on-click-modal="false">
<el-form ref="processFormRef" :model="processForm" :rules="processRules" label-width="100px">
<el-form-item label="患者">
<el-input :model-value="currentRow?.patientName" disabled />
</el-form-item>
<el-form-item label="危急项目">
<el-input :model-value="currentRow?.itemName" disabled />
</el-form-item>
<el-form-item label="结果">
<el-input :model-value="currentRow?.resultValue" disabled />
</el-form-item>
<el-form-item label="处理类型" prop="handleType">
<el-select v-model="processForm.handleType" placeholder="请选择" style="width: 100%">
<el-option label="处理" value="HANDLE" />
<el-option label="复查" value="REVIEW" />
<el-option label="确认关闭" value="CONFIRM" />
</el-select>
</el-form-item>
<el-form-item label="处理人" prop="handlerName">
<el-input v-model="processForm.handlerName" placeholder="请输入处理人姓名" />
</el-form-item>
<el-form-item v-if="processForm.handleType === 'HANDLE'" label="处理结果" prop="handleResult">
<el-input v-model="processForm.handleResult" type="textarea" :rows="3" placeholder="请输入处理结果" />
</el-form-item>
<el-form-item v-if="processForm.handleType === 'REVIEW'" label="复查结果" prop="reviewResult">
<el-input v-model="processForm.reviewResult" type="textarea" :rows="3" placeholder="请输入复查结果" />
</el-form-item>
<el-form-item v-if="processForm.handleType === 'CONFIRM'" label="审核医生" prop="doctorName">
<el-input v-model="processForm.doctorName" placeholder="请输入审核医生姓名" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="processDialogVisible = false">取消</el-button>
<el-button type="primary" :loading="submitLoading" @click="submitProcess">确认</el-button>
</template>
</el-dialog>
<el-dialog v-model="historyDialogVisible" title="处理历史" width="700px" destroy-on-close>
<el-table :data="historyData" border style="width: 100%" size="small">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="handleType" label="类型" width="100" align="center">
<template #default="scope">
<el-tag v-if="scope.row.handleType === 'HANDLE'" type="primary">处理</el-tag>
<el-tag v-else-if="scope.row.handleType === 'REVIEW'" type="warning">复查</el-tag>
<el-tag v-else-if="scope.row.handleType === 'CONFIRM'" type="success">确认</el-tag>
<el-tag v-else type="info">{{ scope.row.handleType }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="handlerName" label="处理人" width="100" />
<el-table-column prop="handleResult" label="处理结果" min-width="150" show-overflow-tooltip />
<el-table-column prop="reviewResult" label="复查结果" min-width="150" show-overflow-tooltip />
<el-table-column prop="doctorName" label="审核医生" width="100" />
<el-table-column prop="handleTime" label="处理时间" width="170" />
</el-table>
<el-empty v-if="historyData.length === 0" description="暂无处理记录" />
<template #footer>
<el-button @click="historyDialogVisible = false">关闭</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { getPendingHandleList, handleCriticalValue, getHandleHistory } from '@/api/criticalvalue'
const loading = ref(false)
const submitLoading = ref(false)
const tableData = ref([])
const processDialogVisible = ref(false)
const historyDialogVisible = ref(false)
const processFormRef = ref(null)
const currentRow = ref(null)
const processForm = reactive({
handleType: 'HANDLE',
handlerName: '',
handleResult: '',
reviewResult: '',
doctorName: ''
})
const processRules = {
handleType: [{ required: true, message: '请选择处理类型', trigger: 'change' }],
handlerName: [{ required: true, message: '请输入处理人', trigger: 'blur' }],
handleResult: [{ required: true, message: '请输入处理结果', trigger: 'blur' }],
reviewResult: [{ required: true, message: '请输入复查结果', trigger: 'blur' }],
doctorName: [{ required: true, message: '请输入审核医生', trigger: 'blur' }]
}
const historyData = ref([])
function handleQuery() {
loading.value = true
getPendingHandleList().then(res => {
tableData.value = res.data || []
}).catch(() => {
ElMessage.error('查询失败')
}).finally(() => {
loading.value = false
})
}
function handleProcess(row) {
currentRow.value = row
processForm.handleType = 'HANDLE'
processForm.handlerName = ''
processForm.handleResult = ''
processForm.reviewResult = ''
processForm.doctorName = ''
processDialogVisible.value = true
}
function submitProcess() {
processFormRef.value?.validate(valid => {
if (!valid) return
submitLoading.value = true
const payload = {
criticalValueId: currentRow.value.id,
encounterId: currentRow.value.encounterId,
patientId: currentRow.value.patientId,
handleType: processForm.handleType,
handlerId: null,
handlerName: processForm.handlerName,
handleResult: processForm.handleResult,
reviewResult: processForm.reviewResult,
doctorId: null,
doctorName: processForm.doctorName
}
handleCriticalValue(payload).then(res => {
if (res.code === 200) {
ElMessage.success('处理成功')
processDialogVisible.value = false
handleQuery()
} else {
ElMessage.error(res.msg || '处理失败')
}
}).catch(() => {
ElMessage.error('处理失败')
}).finally(() => {
submitLoading.value = false
})
})
}
function handleHistory(row) {
getHandleHistory(row.id).then(res => {
historyData.value = res.data || []
historyDialogVisible.value = true
}).catch(() => {
ElMessage.error('查询历史失败')
})
}
onMounted(() => {
handleQuery()
})
</script>
<style scoped>
.critical-value-handle-container {
padding: 12px;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>