修改超声和影像 审核时候保存PDF

This commit is contained in:
lxd 2024-11-14 10:33:02 +08:00
parent 4df8d76a42
commit 094a93b41b
6 changed files with 278 additions and 107 deletions

View File

@ -4,6 +4,7 @@ import request from '@/config/axios'
//分检操作使用 //分检操作使用
export interface updateexamineimageVO { export interface updateexamineimageVO {
regid:string
id: string // 主键 id: string // 主键
isDelete: string // 删除标记 isDelete: string // 删除标记
deletePerson: string//删除人 deletePerson: string//删除人

View File

@ -5,7 +5,7 @@ import remainingRouter from './modules/remaining'
// 创建路由实例 // 创建路由实例
const router = createRouter({ const router = createRouter({
history: createWebHistory(), // createWebHashHistory URL带#createWebHistory URL不带# history: createWebHistory(), // createWebHashHistory URL带#createWebHistory URL不带# liunx 病理 需要在这里加 '/bl/'
strict: true, strict: true,
routes: remainingRouter as RouteRecordRaw[], routes: remainingRouter as RouteRecordRaw[],
scrollBehavior: () => ({ left: 0, top: 0 }) scrollBehavior: () => ({ left: 0, top: 0 })

View File

@ -1,33 +1,31 @@
// 页面导出为pdf格式
import html2Canvas from 'html2canvas'; import html2Canvas from 'html2canvas';
import jsPDF from 'jspdf'; import jsPDF from 'jspdf';
const htmlToPdf = { const htmlToPdf = {
getPdf(title, id) { getPdfBase64(title, id) {
html2Canvas( return new Promise((resolve) => {
document.querySelector(id), html2Canvas(document.querySelector(id), {
{
allowTaint: false, allowTaint: false,
taintTest: false, taintTest: false,
logging: false, logging: false,
useCORS: true, useCORS: true,
dpi: window.devicePixelRatio * 4, //将分辨率提高到特定的DPI 提高四倍 dpi: window.devicePixelRatio * 4, // 将分辨率提高到特定的DPI 提高四倍
scale: 4, //按比例增加分辨率 scale: 4, // 按比例增加分辨率
} }).then((canvas) => {
).then((canvas) => { const pdf = new jsPDF('p', 'mm', 'a4'); // A4纸纵向
var pdf = new jsPDF('p', 'mm', 'a4'); //A4纸纵向 const ctx = canvas.getContext('2d'),
var ctx = canvas.getContext('2d'),
a4w = 190, a4w = 190,
a4h = 272, //A4大小210mm x 297mm四边各保留10mm的边距显示区域190x277 a4h = 272; // A4大小210mm x 297mm四边各保留10mm的边距显示区域190x277
imgHeight = Math.floor((a4h * canvas.width) / a4w), //按A4显示比例换算一页图像的像素高度 let imgHeight = Math.floor((a4h * canvas.width) / a4w), // 按A4显示比例换算一页图像的像素高度
renderedHeight = 0; renderedHeight = 0;
while (renderedHeight < canvas.height) { while (renderedHeight < canvas.height) {
var page = document.createElement('canvas'); const page = document.createElement('canvas');
page.width = canvas.width; page.width = canvas.width;
page.height = Math.min(imgHeight, canvas.height - renderedHeight); //可能内容不足一页 const pageHeight = Math.min(imgHeight, canvas.height - renderedHeight); // 可能内容不足一页
page.height = pageHeight;
//用getImageData剪裁指定区域并画到前面创建的canvas对象中 // 用getImageData剪裁指定区域并画到前面创建的canvas对象中
page page
.getContext('2d') .getContext('2d')
.putImageData( .putImageData(
@ -35,7 +33,7 @@ const htmlToPdf = {
0, 0,
renderedHeight, renderedHeight,
canvas.width, canvas.width,
Math.min(imgHeight, canvas.height - renderedHeight), pageHeight,
), ),
0, 0,
0, 0,
@ -47,15 +45,69 @@ const htmlToPdf = {
10, 10,
a4w, a4w,
Math.min(a4h, (a4w * page.height) / page.width), Math.min(a4h, (a4w * page.height) / page.width),
); //添加图像到页面保留10mm边距 ); // 添加图像到页面保留10mm边距
renderedHeight += imgHeight; renderedHeight += pageHeight;
if (renderedHeight < canvas.height) { if (renderedHeight < canvas.height) {
pdf.addPage(); //如果后面还有内容,添加一个空页 pdf.addPage(); // 如果后面还有内容,添加一个空页
} }
// delete page;
} }
pdf.save(title + '.pdf') const pdfBase64String = pdf.output('datauristring'); // 获取 base64 编码的 PDF 文件
resolve(pdfBase64String); // 解析 base64 字符串
});
});
},
getPdf(title, id) {
html2Canvas(document.querySelector(id), {
allowTaint: false,
taintTest: false,
logging: false,
useCORS: true,
dpi: window.devicePixelRatio * 4, // 将分辨率提高到特定的DPI 提高四倍
scale: 4, // 按比例增加分辨率
}).then((canvas) => {
const pdf = new jsPDF('p', 'mm', 'a4'); // A4纸纵向
const ctx = canvas.getContext('2d'),
a4w = 190,
a4h = 272; // A4大小210mm x 297mm四边各保留10mm的边距显示区域190x277
let imgHeight = Math.floor((a4h * canvas.width) / a4w), // 按A4显示比例换算一页图像的像素高度
renderedHeight = 0;
while (renderedHeight < canvas.height) {
const page = document.createElement('canvas');
page.width = canvas.width;
const pageHeight = Math.min(imgHeight, canvas.height - renderedHeight); // 可能内容不足一页
page.height = pageHeight;
// 用getImageData剪裁指定区域并画到前面创建的canvas对象中
page
.getContext('2d')
.putImageData(
ctx.getImageData(
0,
renderedHeight,
canvas.width,
pageHeight,
),
0,
0,
);
pdf.addImage(
page.toDataURL('image/jpeg', 1.0),
'JPEG',
10,
10,
a4w,
Math.min(a4h, (a4w * page.height) / page.width),
); // 添加图像到页面保留10mm边距
renderedHeight += pageHeight;
if (renderedHeight < canvas.height) {
pdf.addPage(); // 如果后面还有内容,添加一个空页
}
}
pdf.save(title + '.pdf'); // 保存 PDF 文件
}); });
}, },
}; };

View File

@ -107,11 +107,16 @@ const infoParams = defineProps({
diagDoctor: String, diagDoctor: String,
diagDate: String, diagDate: String,
reviewDoctor: String, reviewDoctor: String,
reviewDate: String reviewDate: String,
extraInfo: {
type: Object as PropType<any>, // 使 Object any
required: false
}
}) })
/** 数据内容 **/ /** 数据内容 **/
const orgInfo = ref<any>('') const orgInfo = ref<any>('')
const VITE_BASE_URL_YunJiaoPian = ref(import.meta.env.VITE_BASE_URL_YunJiaoPian) const VITE_BASE_URL_YunJiaoPian = ref(import.meta.env.VITE_BASE_URL_YunJiaoPian)
const age = computed(() => { const age = computed(() => {
@ -134,9 +139,18 @@ const age = computed(() => {
/** 钩子方法 **/ /** 钩子方法 **/
onMounted(async () => { onMounted(async () => {
if(!infoParams.extraInfo) //any
{
let userInfo = await getUserProfile() let userInfo = await getUserProfile()
if (userInfo && userInfo.orgId) if (userInfo && userInfo.orgId)
orgInfo.value = await ReportPrintStatisticsApi.getOrg(userInfo.orgId.trim()) orgInfo.value = await ReportPrintStatisticsApi.getOrg(userInfo.orgId.trim())
console.log('查询到机构' + orgInfo.value)
}else
{
orgInfo.value=infoParams.extraInfo;
}
}) })
/** 导出内容 **/ /** 导出内容 **/

View File

@ -311,6 +311,16 @@
</div> </div>
</el-dialog> </el-dialog>
<!--报告 保存的时候 存base64--> <!--报告 保存的时候 存base64-->
<!-- 隐藏的 div用于渲染 ReportInfoUS 组件 style="border-width: 1; height: 297mm; page-break-after: always"-->
<div style="position: fixed; top: 0; left: 0; z-index: -100">
<div id="hiddenPdfDiv" v-if="showPdfContent">
<PdfContent
v-bind="{ ...infoParams, showQRcode: false }"
style="border-width: 1; height: 400mm; width: 300mm; page-break-after: always;font-size: 20px;"
/>
</div>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -323,9 +333,14 @@ import PdfContent from '@/views/applyregistration/reportPrintStatistics/ReportIn
import { createVNode, render } from 'vue' import { createVNode, render } from 'vue'
import html2canvas from 'html2canvas' import html2canvas from 'html2canvas'
import { jsPDF } from 'jspdf' import { jsPDF } from 'jspdf'
import htmlToPdf from '@/utils/htmlPdf'
import { formatDate } from '@/utils/formatTime'
import { object } from 'vue-types'
import { ReportPrintStatisticsApi } from '@/api/applyregistration/reportPrintStatistics'
/** dicom */ /** dicom */
defineOptions({ name: 'DicomViewForm' }) defineOptions({ name: 'DicomViewForm' })
const showPdfContent = ref(false) //CT
const orgInfo = ref<any>('')
//pdfbase //pdfbase
const pdfBase64 = ref('') const pdfBase64 = ref('')
const dicomframe = ref() const dicomframe = ref()
@ -388,6 +403,7 @@ const save = async () => {
examineFormVO.value.diagFlag = radio1.value examineFormVO.value.diagFlag = radio1.value
examineFormVO.value.diagDoctor = Profilevo.value.doctorname examineFormVO.value.diagDoctor = Profilevo.value.doctorname
examineFormVO.value.diagDoctorId = Profilevo.value.doctorID examineFormVO.value.diagDoctorId = Profilevo.value.doctorID
// examineFormVO.value.reviewDoctor = Profilevo.value.username // examineFormVO.value.reviewDoctor = Profilevo.value.username
examineFormVO.value.reportstatus = '已分析' examineFormVO.value.reportstatus = '已分析'
// examineFormVO.value.diagDate=localDateTime // examineFormVO.value.diagDate=localDateTime
@ -419,7 +435,7 @@ const examine = async () => {
if (response) { if (response) {
message.alertSuccess('审核成功') message.alertSuccess('审核成功')
await getPatientexamlist(ID) await getPatientexamlist(ID)
exportPdfToBase64() await exportPdfCTToBase64()
emit('success') emit('success')
} }
} else if (applyFormVO.value.reportstatus === '已审核') { } else if (applyFormVO.value.reportstatus === '已审核') {
@ -430,54 +446,50 @@ const examine = async () => {
return return
} }
} }
//pdfbase64
const exportPdfToBase64 = async () => {
// DOMPdfContent
const tempDiv = document.createElement('div')
document.body.appendChild(tempDiv)
// 使createVNode // PDF
// DOM const exportPdfCTToBase64 = async () => {
const componentInstance = createVNode(PdfContent, { //
...applyFormVO.value, infoParams.value.regId = applyFormVO.value.regId
showQRcode: false infoParams.value.examId = applyFormVO.value.examId
infoParams.value.pname = applyFormVO.value.pname
infoParams.value.birthday = formatDate(applyFormVO.value.birthday, 'YYYY-MM-DD')
infoParams.value.orgId = applyFormVO.value.orgId
infoParams.value.gender = applyFormVO.value.gender
infoParams.value.examItemName = applyFormVO.value.examItemName
infoParams.value.deviceName = applyFormVO.value.deviceName
infoParams.value.deviceType = applyFormVO.value.deviceType
infoParams.value.billDoctorDepartment = applyFormVO.value.billDoctorDepartment
infoParams.value.examDescription = applyFormVO.value.examDescription
infoParams.value.diagResults = applyFormVO.value.diagResults
infoParams.value.diagDoctor = applyFormVO.value.diagDoctor
infoParams.value.diagDate = formatDate(applyFormVO.value.diagDate, 'YYYY-MM-DD')
infoParams.value.reviewDoctor = applyFormVO.value.reviewDoctor
if (applyFormVO.value.reviewDate !== null) {
infoParams.value.reviewDate = formatDate(applyFormVO.value.reviewDate, 'YYYY-MM-DD')
}
infoParams.value.extraInfo= orgInfo.value
//infoParams.value.reviewDate=applyFormVO.value.reviewDate.toString()
showPdfContent.value = true
nextTick(() => {
setTimeout(async () => {
try {
//PDF
const pdfBase64String = await htmlToPdf.getPdfBase64('CT报告单', '#hiddenPdfDiv')
await PatientexamlistApi.ftppdf({
id: ID.toString(),
imagebase: pdfBase64String,
model: '0',
folderPath: 'D:\\FLYPACS\\ftp' + '\\' + ID.toString()
}) })
} finally {
// 使renderDOM showPdfContent.value = false
render(componentInstance, tempDiv) }
}, 1000)
// Vue
await new Promise((resolve) => setTimeout(resolve, 0)) // 使setTimeoutnextTick
// 使html2canvasDOMcanvasscale
const canvas = await html2canvas(tempDiv, {
scale: 1, // scale
useCORS: true
}) })
// DOM
document.body.removeChild(tempDiv)
// 使jsPDFPDF
const imgData = canvas.toDataURL('image/jpeg', 0.8)
const pdf = new jsPDF({
orientation: 'landscape',
unit: 'mm',
format: 'a4' // PDFcanvas
})
const scalefactor = 1 //
const imgWidth = pdf.internal.pageSize.getWidth() * scalefactor
const imgHeight = ((canvas.height * imgWidth) / canvas.width) * scalefactor
pdf.addImage(imgData, 'jpeg', 0, 0, imgWidth, imgHeight)
const pdfBase64String = pdf.output('datauristring') // base64PDF
// pdfBase64
pdfBase64.value = pdfBase64String
await PatientexamlistApi.ftppdf({ id: ID.toString(), imagebase: pdfBase64String,model:"0",folderPath:"D:\\FLYPACS\\ftp"+"\\"+ID.toString() })
} }
const infoParams = ref({ const infoParams = ref({
id: '', id: '',
examId: '', examId: '',
@ -496,7 +508,11 @@ const infoParams = ref({
diagDoctor: '', diagDoctor: '',
diagDate: '', diagDate: '',
reviewDoctor: '', reviewDoctor: '',
reviewDate: '' reviewDate: '',
extraInfo: {
type: Object as PropType<any>, // 使 Object any
required: false
}
}) })
// //
const age = ref() const age = ref()
@ -717,7 +733,6 @@ const getPatientexamlist = async (id: number) => {
} else { } else {
savedisabled.value = true savedisabled.value = true
} }
} }
defineExpose({ open }) // open defineExpose({ open }) // open
@ -737,6 +752,7 @@ const getlogininfo = async () => {
if (Profilevo.value.isimageexamine === '1') { if (Profilevo.value.isimageexamine === '1') {
examinedisabled.value = true examinedisabled.value = true
} }
orgInfo.value= await ReportPrintStatisticsApi.getOrg( Profilevo.value.orgId.trim())
} }
/** 重置表单 */ /** 重置表单 */

View File

@ -488,6 +488,16 @@
</el-dialog> </el-dialog>
<videoForm ref="videoformRef" /> <videoForm ref="videoformRef" />
<!-- 隐藏的 div用于渲染 ReportInfoUS 组件 style="border-width: 1; height: 297mm; page-break-after: always"-->
<div style="position: fixed; top: 0; left: 0; z-index: -100">
<div id="hiddenUSPdfDiv" v-if="showPdfContent">
<PdfContent
v-bind="{ ...infoParams, showQRcode: false }"
style="border-width: 1; height: 400mm; width: 300mm; page-break-after: always;font-size: 20px;"
/>
</div>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -503,10 +513,15 @@ import htmlToPdf from '@/utils/htmlPdf'
import { Check, Delete, Edit, Message, Search, Star } from '@element-plus/icons-vue' import { Check, Delete, Edit, Message, Search, Star } from '@element-plus/icons-vue'
import type { TabsPaneContext } from 'element-plus' import type { TabsPaneContext } from 'element-plus'
import videoForm from './videoForm.vue' import videoForm from './videoForm.vue'
import { ReportPrintStatisticsApi } from '@/api/applyregistration/reportPrintStatistics'
import { formatDate } from '@/utils/formatTime'
import PdfContent from '@/views/applyregistration/reportPrintStatistics/ReportInfoUS.vue' // PDF
/** 超声组件 */ /** 超声组件 */
defineOptions({ name: 'Ultrasonic' }) defineOptions({ name: 'Ultrasonic' })
const showPdfContent = ref(false) //CT
const orgInfo = ref<any>('')
const Profilevo = ref<ProfileVO>({} as ProfileVO) // const Profilevo = ref<ProfileVO>({} as ProfileVO) //
const { t } = useI18n() // const { t } = useI18n() //
const message = useMessage() // const message = useMessage() //
@ -580,6 +595,73 @@ const handleButtonClick = (buttonName) => {
clickuptime(pid) clickuptime(pid)
} }
// PDF
const exportPdfUSToBase64 = async () => {
//
infoParams.value.regId = applyFormVO.value.regId
infoParams.value.examId = applyFormVO.value.examId
infoParams.value.pname = applyFormVO.value.pname
infoParams.value.birthday = formatDate(applyFormVO.value.birthday, 'YYYY-MM-DD')
infoParams.value.orgId = applyFormVO.value.orgId
infoParams.value.gender = applyFormVO.value.gender
infoParams.value.examItemName = applyFormVO.value.examItemName
infoParams.value.deviceName = applyFormVO.value.deviceName
infoParams.value.deviceType = applyFormVO.value.deviceType
infoParams.value.billDoctorDepartment = applyFormVO.value.billDoctorDepartment
infoParams.value.examDescription = applyFormVO.value.examDescription
infoParams.value.diagResults = applyFormVO.value.diagResults
infoParams.value.diagDoctor = applyFormVO.value.diagDoctor
infoParams.value.diagDate = formatDate(applyFormVO.value.diagDate, 'YYYY-MM-DD')
infoParams.value.reviewDoctor = applyFormVO.value.reviewDoctor
if (applyFormVO.value.reviewDate !== null) {
infoParams.value.reviewDate = formatDate(applyFormVO.value.reviewDate, 'YYYY-MM-DD')
}
infoParams.value.extraInfo= orgInfo.value
//infoParams.value.reviewDate=applyFormVO.value.reviewDate.toString()
showPdfContent.value = true
nextTick(() => {
setTimeout(async () => {
try {
//PDF
const pdfBase64String = await htmlToPdf.getPdfBase64('US报告单', '#hiddenUSPdfDiv')
await PatientexamlistApi.ftppdf({
id: ID.toString(),
imagebase: pdfBase64String,
model: '0',
folderPath: 'D:\\FLYPACS\\ftp' + '\\' + ID.toString()
})
} finally {
showPdfContent.value = false
}
}, 1000)
})
}
const infoParams = ref({
id: '',
examId: '',
regId: '',
orgId: '',
pname: '',
gender: '',
birthday: '',
billDoctorDepartment: '',
applicationDate: '',
examDescription: '',
diagResults: '',
examItemName: '',
deviceName: '',
deviceType: '',
diagDoctor: '',
diagDate: '',
reviewDoctor: '',
reviewDate: '',
extraInfo: {
type: Object as PropType<any>, // 使 Object any
required: false
}
})
//or //or
const updateexamineimage = ref<updateexamineimageVO[]>([]) const updateexamineimage = ref<updateexamineimageVO[]>([])
@ -639,13 +721,14 @@ const examine = async () => {
if (response) { if (response) {
message.alertSuccess('审核成功') message.alertSuccess('审核成功')
// ID // ID
getPatientexamlist(ID) await getPatientexamlist(ID)
isImageLoaded.value = false isImageLoaded.value = false
isImageLoaded2.value = false isImageLoaded2.value = false
isImageLoaded3.value = false isImageLoaded3.value = false
images.value = [] images.value = []
// //
loadimagelist() loadimagelist()
await exportPdfUSToBase64()
emit('success') emit('success')
} }
} else if (applyFormVO.value.reportstatus === '已审核') { } else if (applyFormVO.value.reportstatus === '已审核') {
@ -760,18 +843,21 @@ const upimageselect = async () => {
updateexamineimage.value = [] updateexamineimage.value = []
updateexamineimage.value.push({ updateexamineimage.value.push({
regid:regId.value,
id: selecteimagedoneid.toString(), id: selecteimagedoneid.toString(),
isDelete: '', isDelete: '',
deletePerson: '', deletePerson: '',
selected: '1' selected: '1'
}) })
updateexamineimage.value.push({ updateexamineimage.value.push({
regid:regId.value,
id: selecteimagedtwoid.toString(), id: selecteimagedtwoid.toString(),
isDelete: '', isDelete: '',
deletePerson: '', deletePerson: '',
selected: '1' selected: '1'
}) })
updateexamineimage.value.push({ updateexamineimage.value.push({
regid:regId.value,
id: selecteimagedthreeid.toString(), id: selecteimagedthreeid.toString(),
isDelete: '', isDelete: '',
deletePerson: '', deletePerson: '',
@ -790,6 +876,7 @@ const upimagedeleteor = async () => {
updateexamineimage.value = [] updateexamineimage.value = []
updateexamineimage.value.push({ updateexamineimage.value.push({
regid:regId.value,
id: deleteimageid.value, id: deleteimageid.value,
isDelete: '1', isDelete: '1',
deletePerson: Profilevo.value.username, deletePerson: Profilevo.value.username,
@ -1046,6 +1133,7 @@ const getlogininfo = async () => {
if (Profilevo.value.isexamine === '1') { if (Profilevo.value.isexamine === '1') {
examinedisabled.value = true examinedisabled.value = true
} }
orgInfo.value= await ReportPrintStatisticsApi.getOrg( Profilevo.value.orgId.trim())
} }
/** 重置表单 */ /** 重置表单 */