心电工作站调整打印和申请上级审核

This commit is contained in:
lxd 2025-08-15 13:07:49 +08:00
parent 19ea04b0b2
commit bb3f5507a9
2 changed files with 127 additions and 301 deletions

View File

@ -89,6 +89,13 @@ export const EcgworkstationApi = {
url: `${import.meta.env.VITE_FILE_DOWNLOAD_URL}${filename}`,
responseType: 'blob'
})
},
// 申请上级审核
applySuperiorReview: async (id: number, orgid: string) => {
return await request.get({
url: `/system/ecgworkstation/apply-superior-review?id=${id}&orgid=${orgid}`
})
}
}

View File

@ -240,15 +240,16 @@
<span v-else type="success" size="small" class="status-tag"> 已申请 </span>
</template>
</el-table-column>
<el-table-column label="报告" min-width="80" align="center" show-overflow-tooltip>
<template #default="{ row }">
<el-button
type="primary"
type="success"
size="small"
class="view-report-btn"
@click="handleViewReport(row)"
class="new-report-btn"
@click="handleNewReport(row)"
>
<Icon icon="ep:view" />
<Icon icon="ep:document" />
</el-button>
</template>
</el-table-column>
@ -532,25 +533,25 @@
</template>
</el-dialog>
<!-- 报告查看弹窗 -->
<!-- 报告查看弹窗 -->
<el-dialog
v-model="reportViewVisible"
title="心电图报告查看"
width="85%"
top="5vh"
v-model="newReportViewVisible"
title="报告查看"
width="90%"
top="3vh"
:close-on-click-modal="false"
:close-on-press-escape="false"
@close="closeReportView"
@close="closeNewReportView"
>
<div class="report-view-container">
<div class="report-content" v-loading="reportLoading">
<div v-if="reportImageUrl" class="report-image-container">
<div class="new-report-view-container">
<div class="new-report-content" v-loading="newReportLoading">
<div v-if="newReportImageUrl" class="new-report-image-container">
<el-image
:src="reportImageUrl"
:preview-src-list="[reportImageUrl]"
:src="newReportImageUrl"
:preview-src-list="[newReportImageUrl]"
fit="contain"
class="medical-image"
@error="() => ElMessage.error('报告加载失败')"
class="new-medical-image"
@error="() => ElMessage.error('报告加载失败')"
:preview-teleported="true"
>
<template #error>
@ -562,15 +563,15 @@
</el-image>
</div>
<div v-else class="no-report">
<el-empty description="暂无报告数据" />
<el-empty description="暂无报告数据" />
</div>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeReportView">关闭</el-button>
<el-button type="primary" @click="handlePrintReport" :icon="Download">打印</el-button>
<el-button @click="closeNewReportView">关闭</el-button>
<el-button type="primary" @click="handlePrintNewReport">打印</el-button>
</div>
</template>
</el-dialog>
@ -618,11 +619,11 @@ const selectedFolderPath = ref('')
const currentFolderPath = ref('')
const folderNavigationHistory = ref<string[]>([])
//
const reportViewVisible = ref(false)
const reportImageUrl = ref('')
const currentReportRow = ref<EcgworkstationVO | null>(null)
const reportLoading = ref(false)
//
const newReportViewVisible = ref(false)
const newReportImageUrl = ref('')
const currentNewReportRow = ref<EcgworkstationVO | null>(null)
const newReportLoading = ref(false)
//
const filteredFolderList = computed(() => {
@ -1303,8 +1304,7 @@ const confirmFileSelect = async (file?: any) => {
//
console.log(currentRow.value)
await EcgworkstationApi.updateFilename({
orgid: currentRow.value.orgid,
examid: currentRow.value.examid,
...currentRow.value,
filename: result.targetFile
})
@ -1462,9 +1462,12 @@ const handleApply = async (row) => {
}
}
/** 查看报告 */
const handleViewReport = async (row) => {
/** 查看报告 */
const handleNewReport = async (row) => {
try {
newReportLoading.value = true
currentNewReportRow.value = row
//
const result = await EcgworkstationApi.getPdfUrl({
orgid: row.orgid,
@ -1482,276 +1485,120 @@ const handleViewReport = async (row) => {
}
if (pdfUrl) {
//
openReportWindow(pdfUrl, row)
// URL
newReportImageUrl.value = pdfUrl
newReportViewVisible.value = true
} else {
console.warn('API返回数据异常:', {
result,
resultType: typeof result,
hasData: !!result?.data
})
ElMessage.warning('报告未生成或查询失败')
ElMessage.warning('报告未生成或查询失败')
}
} catch (error) {
console.error('查询报告失败:', error)
console.error('错误详情:', {
message: error?.message,
response: error?.response,
status: error?.response?.status
})
ElMessage.error('查询报告失败,请重试')
console.error('查询新报告失败:', error)
ElMessage.error('查询新报告失败,请重试')
} finally {
newReportLoading.value = false
}
}
/** 打开报告窗口 */
const openReportWindow = (imageUrl, patientInfo) => {
const reportWindow = window.open(
'',
'_blank',
'width=1000,height=700,scrollbars=yes,resizable=yes'
)
if (!reportWindow) {
ElMessage.error('无法打开报告窗口,请检查浏览器设置')
return
}
const reportContent = `
<!DOCTYPE html>
<html>
<head>
<title>心电图报告</title>
<meta charset="UTF-8">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Microsoft YaHei', Arial, sans-serif;
background: #f5f5f5;
min-height: 100vh;
display: flex;
flex-direction: column;
}
.button-container {
text-align: center;
padding: 20px;
background: white;
border-bottom: 1px solid #e9ecef;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}
.content {
flex: 1;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
}
.image-container {
background: white;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
padding: 20px;
max-width: 95%;
max-height: 95%;
text-align: center;
}
.report-image {
max-width: 100%;
max-height: 100%;
object-fit: contain;
display: block;
border-radius: 4px;
margin: 0 auto;
}
.loading {
text-align: center;
color: #666;
font-size: 16px;
padding: 40px;
}
.error {
text-align: center;
color: #f56c6c;
font-size: 16px;
padding: 40px;
}
.btn {
padding: 12px 24px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 16px;
font-weight: 500;
transition: all 0.3s;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.btn-print {
background: #007bff;
color: white;
}
.btn-print:hover {
background: #0056b3;
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}
@media print {
body {
background: white;
}
.button-container {
display: none !important;
}
.content {
padding: 0 !important;
}
.image-container {
box-shadow: none !important;
padding: 0 !important;
max-width: 100% !important;
max-height: 100% !important;
}
.report-image {
width: 100% !important;
height: auto !important;
max-width: none !important;
max-height: none !important;
page-break-inside: avoid;
}
}
</style>
</head>
<body>
<div class="button-container">
<button class="btn btn-print" onclick="window.print()">
🖨 打印
</button>
</div>
<div class="content">
<div class="image-container">
<div class="loading" id="loading">正在加载心电图...</div>
<div class="error" id="error" style="display: none;">图片加载失败请重试</div>
<img
src="${imageUrl}"
alt="心电图"
class="report-image"
style="display: none;"
onload="document.getElementById('loading').style.display='none'; this.style.display='block';"
onerror="document.getElementById('loading').style.display='none'; document.getElementById('error').style.display='block';"
>
</div>
</div>
</body>
</html>
`
reportWindow.document.write(reportContent)
reportWindow.document.close()
reportWindow.focus()
/** 关闭新报告查看弹窗 */
const closeNewReportView = () => {
newReportViewVisible.value = false
newReportImageUrl.value = ''
currentNewReportRow.value = null
}
/** 打印报告 */
const handlePrintReport = () => {
if (!reportImageUrl.value) {
ElMessage.warning('没有可打印的报告')
/** 打印新报告 */
const handlePrintNewReport = () => {
if (!newReportImageUrl.value) {
ElMessage.warning('没有可打印的新报告')
return
}
//
const printWindow = window.open('', '_blank')
if (!printWindow) {
ElMessage.error('无法打开打印窗口,请检查浏览器设置')
return
}
//
//
const printContent = `
<!DOCTYPE html>
<html>
<head>
<title>心电图报告打印</title>
<title>新报告打印</title>
<style>
* {
body {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
width: 100%;
height: 100%;
overflow: hidden;
}
.print-container {
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background: white;
}
.print-image {
max-width: 100%;
max-height: 100%;
width: 100%;
height: 100%;
object-fit: contain;
display: block;
page-break-inside: avoid;
page-break-after: avoid;
page-break-before: avoid;
}
@media print {
.print-container {
width: 100%;
height: 100%;
@page {
size: landscape;
margin: 0;
}
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.print-image {
width: 100%;
height: auto;
max-width: none;
max-height: none;
height: 100%;
max-width: 100%;
max-height: 100%;
object-fit: contain;
page-break-inside: avoid;
page-break-after: avoid;
page-break-before: avoid;
}
}
</style>
</head>
<body>
<div class="print-container">
<img src="${reportImageUrl.value}" alt="心电图报告" class="print-image" onload="setTimeout(() => window.print(), 500);" onerror="alert('图片加载失败');">
</div>
<img src="${newReportImageUrl.value}" alt="新报告" class="print-image">
</body>
</html>
`
//
printWindow.document.write(printContent)
printWindow.document.close()
}
// iframe
const iframe = document.createElement('iframe')
iframe.style.display = 'none'
document.body.appendChild(iframe)
/** 关闭报告查看弹窗 */
const closeReportView = () => {
reportViewVisible.value = false
reportImageUrl.value = ''
currentReportRow.value = null
iframe.contentDocument?.write(printContent)
iframe.contentDocument?.close()
//
const img = iframe.contentDocument?.querySelector('img') as HTMLImageElement
if (img) {
img.onload = () => {
setTimeout(() => {
iframe.contentWindow?.print()
// iframe
setTimeout(() => {
document.body.removeChild(iframe)
}, 1000)
}, 500)
}
img.onerror = () => {
ElMessage.error('图片加载失败,无法打印')
document.body.removeChild(iframe)
}
}
}
/** 下载 */
@ -2161,7 +2008,8 @@ onMounted(async () => {
.collect-btn,
.upload-btn,
.download-btn,
.apply-btn {
.apply-btn,
.new-report-btn {
border-radius: 12px;
padding: 2px 8px;
font-weight: 500;
@ -2195,6 +2043,10 @@ onMounted(async () => {
background: linear-gradient(135deg, #ff9a56, #ff6b6b);
}
.new-report-btn {
background: linear-gradient(135deg, #8b5cf6, #a855f7);
}
.status-tag {
border-radius: 4px;
padding: 1px 6px;
@ -2972,58 +2824,26 @@ onMounted(async () => {
}
}
//
.report-view-container {
.report-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
background: #f8f9fa;
border-radius: 8px;
margin-bottom: 16px;
.patient-info {
display: flex;
flex-wrap: wrap;
gap: 16px;
.info-item {
font-size: 14px;
color: #606266;
font-weight: 500;
&:first-child {
color: #409eff;
font-weight: 600;
}
}
}
.report-actions {
display: flex;
gap: 8px;
}
}
.report-content {
min-height: 400px;
//
.new-report-view-container {
.new-report-content {
min-height: 500px;
display: flex;
justify-content: center;
align-items: center;
.report-image-container {
.new-report-image-container {
width: 100%;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
.medical-image {
width: 90%;
height: 70vh;
min-height: 500px;
max-height: 800px;
.new-medical-image {
width: 95%;
height: 75vh;
min-height: 600px;
max-height: 900px;
border: 1px solid #e4e7ed;
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
@ -3065,16 +2885,15 @@ onMounted(async () => {
//
@media (max-width: 768px) {
.report-view-container {
.report-header {
flex-direction: column;
gap: 12px;
.new-report-view-container {
.new-report-content {
min-height: 400px;
.patient-info {
justify-content: center;
.info-item {
font-size: 12px;
.new-report-image-container {
.new-medical-image {
width: 100%;
height: 60vh;
min-height: 400px;
}
}
}