|
|
|
|
@@ -3,82 +3,102 @@
|
|
|
|
|
<div style="margin-bottom:16px">
|
|
|
|
|
<span style="font-size:18px;font-weight:bold">病历修改留痕</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div style="margin-bottom:12px;display:flex;gap:8px;flex-wrap:wrap">
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="q.emrId"
|
|
|
|
|
placeholder="病历ID"
|
|
|
|
|
clearable
|
|
|
|
|
style="width:120px"
|
|
|
|
|
/>
|
|
|
|
|
<el-input
|
|
|
|
|
v-model="q.operatorName"
|
|
|
|
|
placeholder="操作人"
|
|
|
|
|
clearable
|
|
|
|
|
style="width:120px"
|
|
|
|
|
/>
|
|
|
|
|
<el-button
|
|
|
|
|
type="primary"
|
|
|
|
|
@click="loadData"
|
|
|
|
|
>
|
|
|
|
|
查询
|
|
|
|
|
</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
<el-card shadow="never" style="margin-bottom:16px">
|
|
|
|
|
<el-form inline>
|
|
|
|
|
<el-form-item label="患者">
|
|
|
|
|
<el-input v-model="q.patientName" placeholder="患者姓名" clearable style="width:130px" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="医生">
|
|
|
|
|
<el-input v-model="q.doctorName" placeholder="医生姓名" clearable style="width:130px" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="操作人">
|
|
|
|
|
<el-input v-model="q.operatorName" placeholder="操作人" clearable style="width:120px" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="病历类型">
|
|
|
|
|
<el-select v-model="q.emrType" placeholder="全部" clearable style="width:130px">
|
|
|
|
|
<el-option label="入院记录" value="ADMISSION" />
|
|
|
|
|
<el-option label="首次病程" value="FIRST_COURSE" />
|
|
|
|
|
<el-option label="日常病程" value="DAILY_COURSE" />
|
|
|
|
|
<el-option label="出院记录" value="DISCHARGE" />
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item>
|
|
|
|
|
<el-button type="primary" @click="handleQuery">搜索</el-button>
|
|
|
|
|
<el-button @click="resetQuery">重置</el-button>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form>
|
|
|
|
|
</el-card>
|
|
|
|
|
<el-table
|
|
|
|
|
:data="tableData"
|
|
|
|
|
v-loading="loading"
|
|
|
|
|
:data="groupedData"
|
|
|
|
|
row-key="emrId"
|
|
|
|
|
border
|
|
|
|
|
stripe
|
|
|
|
|
default-expand-all
|
|
|
|
|
:tree-props="{ children: 'revisions' }"
|
|
|
|
|
>
|
|
|
|
|
<el-table-column
|
|
|
|
|
prop="emrId"
|
|
|
|
|
label="病历ID"
|
|
|
|
|
width="100"
|
|
|
|
|
/>
|
|
|
|
|
<el-table-column
|
|
|
|
|
prop="revisionNumber"
|
|
|
|
|
label="版本"
|
|
|
|
|
width="70"
|
|
|
|
|
align="center"
|
|
|
|
|
>
|
|
|
|
|
<el-table-column prop="emrTitle" label="病历标题" min-width="200">
|
|
|
|
|
<template #default="{row}">
|
|
|
|
|
<el-tag size="small">
|
|
|
|
|
V{{ row.revisionNumber }}
|
|
|
|
|
</el-tag>
|
|
|
|
|
<template v-if="row.isGroup">
|
|
|
|
|
<span style="font-weight:bold">{{ row.emrTitle || '病历 #' + row.emrId }}</span>
|
|
|
|
|
<el-tag size="small" style="margin-left:8px">{{ row.emrType }}</el-tag>
|
|
|
|
|
</template>
|
|
|
|
|
<template v-else>
|
|
|
|
|
<span style="color:#909399">V{{ row.revisionNumber }}</span>
|
|
|
|
|
</template>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column
|
|
|
|
|
prop="operatorName"
|
|
|
|
|
label="操作人"
|
|
|
|
|
width="100"
|
|
|
|
|
/>
|
|
|
|
|
<el-table-column
|
|
|
|
|
prop="operationType"
|
|
|
|
|
label="操作类型"
|
|
|
|
|
width="100"
|
|
|
|
|
/>
|
|
|
|
|
<el-table-column
|
|
|
|
|
prop="diffContent"
|
|
|
|
|
label="变更内容"
|
|
|
|
|
min-width="200"
|
|
|
|
|
show-overflow-tooltip
|
|
|
|
|
/>
|
|
|
|
|
<el-table-column
|
|
|
|
|
prop="createTime"
|
|
|
|
|
label="修改时间"
|
|
|
|
|
width="170"
|
|
|
|
|
/>
|
|
|
|
|
<el-table-column
|
|
|
|
|
label="操作"
|
|
|
|
|
width="100"
|
|
|
|
|
>
|
|
|
|
|
<el-table-column prop="patientName" label="患者" width="100">
|
|
|
|
|
<template #default="{row}">
|
|
|
|
|
<el-button
|
|
|
|
|
type="primary"
|
|
|
|
|
link
|
|
|
|
|
size="small"
|
|
|
|
|
@click="viewDetail(row)"
|
|
|
|
|
>
|
|
|
|
|
查看
|
|
|
|
|
</el-button>
|
|
|
|
|
<template v-if="row.isGroup">
|
|
|
|
|
{{ row.patientName || '-' }}
|
|
|
|
|
<span v-if="row.patientGender" style="color:#909399;margin-left:4px">({{ row.patientGender }})</span>
|
|
|
|
|
</template>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="doctorName" label="主治医生" width="100">
|
|
|
|
|
<template #default="{row}">
|
|
|
|
|
<template v-if="row.isGroup">{{ row.doctorName || '-' }}</template>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="departmentName" label="科室" width="100">
|
|
|
|
|
<template #default="{row}">
|
|
|
|
|
<template v-if="row.isGroup">{{ row.departmentName || '-' }}</template>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="encounterNo" label="就诊号" width="120">
|
|
|
|
|
<template #default="{row}">
|
|
|
|
|
<template v-if="row.isGroup">{{ row.encounterNo || '-' }}</template>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="operationType" label="操作类型" width="100">
|
|
|
|
|
<template #default="{row}">
|
|
|
|
|
<template v-if="!row.isGroup">
|
|
|
|
|
<el-tag :type="opTypeMap[row.operationType]?.type || 'info'" size="small">
|
|
|
|
|
{{ opTypeMap[row.operationType]?.label || row.operationType }}
|
|
|
|
|
</el-tag>
|
|
|
|
|
</template>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="operatorName" label="操作人" width="90">
|
|
|
|
|
<template #default="{row}">
|
|
|
|
|
<template v-if="!row.isGroup">{{ row.operatorName }}</template>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="diffContent" label="变更内容" min-width="200" show-overflow-tooltip>
|
|
|
|
|
<template #default="{row}">
|
|
|
|
|
<template v-if="!row.isGroup">{{ row.diffContent }}</template>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="createTime" label="时间" width="170">
|
|
|
|
|
<template #default="{row}">
|
|
|
|
|
<template v-if="!row.isGroup">{{ row.createTime }}</template>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column label="操作" width="80">
|
|
|
|
|
<template #default="{row}">
|
|
|
|
|
<template v-if="!row.isGroup">
|
|
|
|
|
<el-button type="primary" link size="small" @click="viewDetail(row)">详情</el-button>
|
|
|
|
|
</template>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
</el-table>
|
|
|
|
|
@@ -87,73 +107,105 @@
|
|
|
|
|
v-model:page-size="q.pageSize"
|
|
|
|
|
style="margin-top:12px;justify-content:flex-end"
|
|
|
|
|
:total="total"
|
|
|
|
|
layout="total,prev,pager,next"
|
|
|
|
|
layout="total, sizes, prev, pager, next"
|
|
|
|
|
@size-change="loadData"
|
|
|
|
|
@current-change="loadData"
|
|
|
|
|
/>
|
|
|
|
|
<el-dialog
|
|
|
|
|
v-model="detailVisible"
|
|
|
|
|
title="修订详情"
|
|
|
|
|
width="700px"
|
|
|
|
|
>
|
|
|
|
|
<el-descriptions
|
|
|
|
|
:column="2"
|
|
|
|
|
border
|
|
|
|
|
>
|
|
|
|
|
<el-descriptions-item label="版本">
|
|
|
|
|
V{{ detail.revisionNumber }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="操作人">
|
|
|
|
|
{{ detail.operatorName }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="操作类型">
|
|
|
|
|
{{ detail.operationType }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="时间">
|
|
|
|
|
{{ detail.createTime }}
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-dialog v-model="detailVisible" title="修订详情" width="700px">
|
|
|
|
|
<el-descriptions :column="2" border>
|
|
|
|
|
<el-descriptions-item label="版本">V{{ detail.revisionNumber }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="操作人">{{ detail.operatorName }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="操作类型">{{ detail.operationType }}</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="时间">{{ detail.createTime }}</el-descriptions-item>
|
|
|
|
|
</el-descriptions>
|
|
|
|
|
<div style="margin-top:12px">
|
|
|
|
|
<div style="font-weight:bold;margin-bottom:8px">
|
|
|
|
|
变更内容:
|
|
|
|
|
</div>
|
|
|
|
|
<div style="font-weight:bold;margin-bottom:8px">变更内容:</div>
|
|
|
|
|
<pre style="background:#f5f7fa;padding:12px;border-radius:4px;max-height:300px;overflow:auto">{{ detail.diffContent }}</pre>
|
|
|
|
|
</div>
|
|
|
|
|
<div style="margin-top:12px">
|
|
|
|
|
<div style="font-weight:bold;margin-bottom:8px">
|
|
|
|
|
内容快照:
|
|
|
|
|
</div>
|
|
|
|
|
<div style="font-weight:bold;margin-bottom:8px">内容快照:</div>
|
|
|
|
|
<pre style="background:#f5f7fa;padding:12px;border-radius:4px;max-height:300px;overflow:auto">{{ detail.snapshotContent }}</pre>
|
|
|
|
|
</div>
|
|
|
|
|
</el-dialog>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<script setup>
|
|
|
|
|
import {ref,onMounted} from 'vue'
|
|
|
|
|
import {useRoute} from 'vue-router'
|
|
|
|
|
import {getRevisionPage} from './api'
|
|
|
|
|
import {ElMessage} from 'element-plus'
|
|
|
|
|
const route=useRoute()
|
|
|
|
|
const tableData=ref([]);const total=ref(0)
|
|
|
|
|
const q=ref({pageNo:1,pageSize: 10,emrId:null,operatorName:''})
|
|
|
|
|
const detailVisible=ref(false);const detail=ref({})
|
|
|
|
|
const loadData=async()=>{
|
|
|
|
|
try{
|
|
|
|
|
// 清理空参数
|
|
|
|
|
const params={pageNo:q.value.pageNo,pageSize:q.value.pageSize}
|
|
|
|
|
if(q.value.emrId) params.emrId=q.value.emrId
|
|
|
|
|
if(q.value.operatorName) params.operatorName=q.value.operatorName
|
|
|
|
|
const r=await getRevisionPage(params)
|
|
|
|
|
console.log('修订历史响应:',r)
|
|
|
|
|
tableData.value=r.data?.records||r.data||[]
|
|
|
|
|
total.value=r.data?.total||tableData.value.length
|
|
|
|
|
}catch(e){
|
|
|
|
|
console.error('加载失败:',e)
|
|
|
|
|
import { ref, computed, onMounted } from 'vue'
|
|
|
|
|
import { useRoute } from 'vue-router'
|
|
|
|
|
import { getRevisionPage } from './api'
|
|
|
|
|
import { ElMessage } from 'element-plus'
|
|
|
|
|
|
|
|
|
|
const route = useRoute()
|
|
|
|
|
const loading = ref(false)
|
|
|
|
|
const rawData = ref([])
|
|
|
|
|
const total = ref(0)
|
|
|
|
|
const q = ref({ pageNo: 1, pageSize: 10, patientName: '', doctorName: '', operatorName: '', emrType: '', emrId: null })
|
|
|
|
|
const detailVisible = ref(false)
|
|
|
|
|
const detail = ref({})
|
|
|
|
|
|
|
|
|
|
const opTypeMap = {
|
|
|
|
|
CREATE: { label: '创建', type: 'success' },
|
|
|
|
|
EDIT: { label: '编辑', type: 'warning' },
|
|
|
|
|
APPROVE: { label: '审批', type: '' },
|
|
|
|
|
SIGN: { label: '签名', type: 'info' }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const groupedData = computed(() => {
|
|
|
|
|
const map = new Map()
|
|
|
|
|
for (const row of rawData.value) {
|
|
|
|
|
const key = row.emrId
|
|
|
|
|
if (!map.has(key)) {
|
|
|
|
|
map.set(key, {
|
|
|
|
|
emrId: key,
|
|
|
|
|
emrTitle: row.emrTitle,
|
|
|
|
|
emrType: row.emrType,
|
|
|
|
|
patientName: row.patientName,
|
|
|
|
|
patientGender: row.patientGender,
|
|
|
|
|
doctorName: row.doctorName,
|
|
|
|
|
departmentName: row.departmentName,
|
|
|
|
|
encounterNo: row.encounterNo,
|
|
|
|
|
isGroup: true,
|
|
|
|
|
revisions: []
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
map.get(key).revisions.push({ ...row, isGroup: false })
|
|
|
|
|
}
|
|
|
|
|
return Array.from(map.values())
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const loadData = async () => {
|
|
|
|
|
loading.value = true
|
|
|
|
|
try {
|
|
|
|
|
const params = { pageNo: q.value.pageNo, pageSize: q.value.pageSize }
|
|
|
|
|
if (q.value.patientName) params.patientName = q.value.patientName
|
|
|
|
|
if (q.value.doctorName) params.doctorName = q.value.doctorName
|
|
|
|
|
if (q.value.operatorName) params.operatorName = q.value.operatorName
|
|
|
|
|
if (q.value.emrType) params.emrType = q.value.emrType
|
|
|
|
|
if (q.value.emrId) params.emrId = q.value.emrId
|
|
|
|
|
const r = await getRevisionPage(params)
|
|
|
|
|
rawData.value = r.data?.records || []
|
|
|
|
|
total.value = r.data?.total || 0
|
|
|
|
|
} catch {
|
|
|
|
|
ElMessage.error('加载失败')
|
|
|
|
|
} finally {
|
|
|
|
|
loading.value = false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const viewDetail=(row)=>{detail.value=row;detailVisible.value=true}
|
|
|
|
|
onMounted(()=>{
|
|
|
|
|
if(route.query.emrId){q.value.emrId=route.query.emrId}
|
|
|
|
|
|
|
|
|
|
const handleQuery = () => { q.value.pageNo = 1; loadData() }
|
|
|
|
|
const resetQuery = () => {
|
|
|
|
|
q.value.patientName = ''
|
|
|
|
|
q.value.doctorName = ''
|
|
|
|
|
q.value.operatorName = ''
|
|
|
|
|
q.value.emrType = ''
|
|
|
|
|
q.value.emrId = null
|
|
|
|
|
q.value.pageNo = 1
|
|
|
|
|
loadData()
|
|
|
|
|
}
|
|
|
|
|
const viewDetail = (row) => { detail.value = row; detailVisible.value = true }
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
if (route.query.emrId) q.value.emrId = Number(route.query.emrId)
|
|
|
|
|
loadData()
|
|
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
|