当手术计费弹窗中点击"签发"耗材时,因耗材的locationId(发放库房)为空导致后端异常。 在DoctorStationAdviceAppServiceImpl.handDevice方法中,当locationId为null时,使用登录用户的科室ID作为默认值, 与NurseBillingAppService中的处理方式保持一致。
703 lines
25 KiB
JavaScript
Executable File
703 lines
25 KiB
JavaScript
Executable File
/**
|
||
* 打印工具类
|
||
* 集中管理所有打印相关功能
|
||
*/
|
||
|
||
import {hiprint} from 'vue-plugin-hiprint';
|
||
|
||
// 打印模板映射表 .
|
||
const TEMPLATE_MAP = {
|
||
// CLINIC_CHARGE: () => import('@/views/charge/cliniccharge/components/template.json'),
|
||
// DISPOSAL: () => import('@/views/clinicmanagement/disposal/components/disposalTemplate.json'),
|
||
//处方签
|
||
PRESCRIPTION: () => import('@/components/Print/Prescription.json'),
|
||
//处置单
|
||
DISPOSAL: () => import('@/components/Print/Disposal.json'),
|
||
//门诊日结
|
||
DAY_END: () => import('@/components/Print/DailyOutpatientSettlement.json'),
|
||
WESTERN_MEDICINE: () =>
|
||
import('@/views/pharmacymanagement/westernmedicine/components/templateJson.json'),
|
||
IN_HOSPITAL_DISPENSING: () =>
|
||
import('@/views/drug/inHospitalDispensing/components/templateJson.json'),
|
||
// 门诊挂号
|
||
OUTPATIENT_REGISTRATION: () => import('@/components/Print/OutpatientRegistration.json'),
|
||
// 门诊手术计费(含流程图)
|
||
OUTPATIENT_SURGERY_CHARGE: () => import('@/components/Print/OutpatientSurgeryCharge.json'),
|
||
//门诊收费
|
||
OUTPATIENT_CHARGE: () => import('@/components/Print/OutpatientBilling.json'),
|
||
//门诊病历
|
||
OUTPATIENT_MEDICAL_RECORD: () => import('@/components/Print/OutpatientMedicalRecord.json'),
|
||
//门诊输液贴
|
||
OUTPATIENT_INFUSION: () => import('@/components/Print/OutpatientInfusion.json'),
|
||
//手术记录
|
||
OPERATIVE_RECORD: () => import('@/components/Print/OperativeRecord.json'),
|
||
|
||
//红旗门诊病历
|
||
HQOUTPATIENT_MEDICAL_RECORD: () => import('@/components/Print/HQOutpatientMedicalRecord.json'),
|
||
//预交金
|
||
ADVANCE_PAYMENT: () => import('@/components/Print/AdvancePayment.json'),
|
||
//中药处方单
|
||
CHINESE_MEDICINE_PRESCRIPTION: () =>
|
||
import('@/components/Print/ChineseMedicinePrescription.json'),
|
||
//药房处方单
|
||
PHARMACY_PRESCRIPTION: () => import('@/components/Print/Pharmacy.json'),
|
||
//中药医生处方单
|
||
DOC_CHINESE_MEDICINE_PRESCRIPTION: () =>
|
||
import('@/components/Print/DocChineseMedicinePrescription.json'),
|
||
|
||
// ========== 新增模板(原LODOP迁移)==========
|
||
//腕带
|
||
WRIST_BAND: () => import('@/components/Print/WristBand.json'),
|
||
//分诊条
|
||
TRIAGE_TICKET: () => import('@/components/Print/TriageTicket.json'),
|
||
//输液标签
|
||
INJECT_LABEL: () => import('@/components/Print/InjectLabel.json'),
|
||
//床头卡
|
||
BED_CARD: () => import('@/components/Print/BedCard.json'),
|
||
//护理交接班
|
||
CHANGE_SHIFT_BILL: () => import('@/components/Print/ChangeShiftBill.json'),
|
||
//医嘱执行单
|
||
EXE_ORDER_SHEET: () => import('@/components/Print/ExeOrderSheet.json'),
|
||
//体温单
|
||
TEMPERATURE_SHEET: () => import('@/components/Print/TemperatureSheet.json'),
|
||
//会诊申请单
|
||
CONSULTATION: () => import('@/components/Print/Consultation.json'),
|
||
};
|
||
|
||
/**
|
||
* 极简打印方法
|
||
* @param {string} templateName 打印模板名称(常量或字符串)
|
||
* @param {Array|Object} data 打印数据
|
||
* @param {string} printerName 打印机名称(可选)
|
||
* @param {Object} options 打印选项(可选)
|
||
* @returns {Promise} 打印结果Promise
|
||
*/
|
||
export async function simplePrint(templateName, data, printerName, options = {}) {
|
||
try {
|
||
// 获取模板
|
||
const template = await loadTemplate(templateName);
|
||
|
||
// 执行打印,业务名称默认为模板名称
|
||
return await executePrint(data, template, printerName, options, templateName);
|
||
} catch (error) {
|
||
console.error('打印失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 加载打印模板
|
||
* @param {string} templateName 模板名称
|
||
* @returns {Promise<Object>} 模板对象
|
||
*/
|
||
async function loadTemplate(templateName) {
|
||
// 如果是常量形式,获取实际的键名
|
||
const templateKey = typeof templateName === 'symbol' ? templateName.description : templateName;
|
||
|
||
if (!TEMPLATE_MAP[templateKey]) {
|
||
throw new Error(`未找到打印模板: ${templateKey}`);
|
||
}
|
||
|
||
try {
|
||
const templateModule = await TEMPLATE_MAP[templateKey]();
|
||
return templateModule.default || templateModule;
|
||
} catch (error) {
|
||
console.error(`加载模板 ${templateKey} 失败:`, error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 带打印机选择的极简打印方法
|
||
* @param {string} templateName 打印模板名称
|
||
* @param {Array|Object} data 打印数据
|
||
* @param {Function} showPrinterDialog 显示打印机选择对话框的函数
|
||
* @param {Object} modal 消息提示对象
|
||
* @param {Function} callback 打印完成后的回调函数(可选)
|
||
* @returns {Promise} 打印结果Promise
|
||
*/
|
||
export async function simplePrintWithDialog(
|
||
templateName,
|
||
data,
|
||
showPrinterDialog,
|
||
modal,
|
||
callback
|
||
) {
|
||
try {
|
||
// 获取模板
|
||
const template = await loadTemplate(templateName);
|
||
|
||
// 执行打印
|
||
await selectPrinterAndPrint(data, template, showPrinterDialog, modal, callback, templateName);
|
||
} catch (error) {
|
||
modal.msgError(error.message || '打印失败');
|
||
if (callback) callback(error);
|
||
}
|
||
}
|
||
|
||
// 导出模板名称常量
|
||
export const PRINT_TEMPLATE = {
|
||
// CLINIC_CHARGE: 'CLINIC_CHARGE',
|
||
DAY_END: 'DAY_END',
|
||
WESTERN_MEDICINE: 'WESTERN_MEDICINE',
|
||
IN_HOSPITAL_DISPENSING: 'IN_HOSPITAL_DISPENSING',
|
||
//门诊挂号
|
||
OUTPATIENT_REGISTRATION: 'OUTPATIENT_REGISTRATION',
|
||
// 门诊手术计费
|
||
OUTPATIENT_SURGERY_CHARGE: 'OUTPATIENT_SURGERY_CHARGE',
|
||
//门诊收费
|
||
OUTPATIENT_CHARGE: 'OUTPATIENT_CHARGE',
|
||
//处方签
|
||
PRESCRIPTION: 'PRESCRIPTION',
|
||
//处置单
|
||
DISPOSAL: 'DISPOSAL',
|
||
//门诊病历
|
||
OUTPATIENT_MEDICAL_RECORD: 'OUTPATIENT_MEDICAL_RECORD',
|
||
//门诊输液贴
|
||
OUTPATIENT_INFUSION: 'OUTPATIENT_INFUSION',
|
||
//手术记录
|
||
OPERATIVE_RECORD: 'OPERATIVE_RECORD',
|
||
//红旗门诊病历
|
||
HQOUTPATIENT_MEDICAL_RECORD: 'HQOUTPATIENT_MEDICAL_RECORD',
|
||
//预交金
|
||
ADVANCE_PAYMENT: 'ADVANCE_PAYMENT',
|
||
//中药处方单
|
||
CHINESE_MEDICINE_PRESCRIPTION: 'CHINESE_MEDICINE_PRESCRIPTION',
|
||
//药房处方单
|
||
PHARMACY_PRESCRIPTION: 'PHARMACY_PRESCRIPTION',
|
||
//中药医生处方单
|
||
DOC_CHINESE_MEDICINE_PRESCRIPTION: 'DOC_CHINESE_MEDICINE_PRESCRIPTION',
|
||
|
||
// ========== 新增模板(原LODOP迁移)==========
|
||
//腕带
|
||
WRIST_BAND: 'WRIST_BAND',
|
||
//分诊条
|
||
TRIAGE_TICKET: 'TRIAGE_TICKET',
|
||
//输液标签
|
||
INJECT_LABEL: 'INJECT_LABEL',
|
||
//床头卡
|
||
BED_CARD: 'BED_CARD',
|
||
//护理交接班
|
||
CHANGE_SHIFT_BILL: 'CHANGE_SHIFT_BILL',
|
||
//医嘱执行单
|
||
EXE_ORDER_SHEET: 'EXE_ORDER_SHEET',
|
||
//体温单
|
||
TEMPERATURE_SHEET: 'TEMPERATURE_SHEET',
|
||
//会诊申请单
|
||
CONSULTATION: 'CONSULTATION',
|
||
};
|
||
|
||
/**
|
||
* 获取打印机列表
|
||
* @returns {Array} 打印机列表
|
||
*/
|
||
export function getPrinterList() {
|
||
try {
|
||
if (hiprint && hiprint.hiwebSocket && hiprint.hiwebSocket.connected) {
|
||
const printerList = hiprint.hiwebSocket.getPrinterList();
|
||
return printerList || [];
|
||
} else {
|
||
console.warn('打印服务未连接,返回空打印机列表');
|
||
return [];
|
||
}
|
||
} catch (error) {
|
||
console.error('获取打印机列表失败:', error);
|
||
return [];
|
||
}
|
||
}
|
||
|
||
import useUserStore from '@/store/modules/user';
|
||
import {ElMessage} from 'element-plus';
|
||
|
||
/**
|
||
* 获取当前登录用户ID
|
||
* @returns {string} 用户ID
|
||
*/
|
||
function getCurrentUserId() {
|
||
try {
|
||
// 从Pinia store中获取当前用户ID
|
||
const userStore = useUserStore();
|
||
return userStore.id || '';
|
||
} catch (e) {
|
||
console.error('获取用户ID失败:', e);
|
||
return '';
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 生成打印机缓存键
|
||
* @param {string} businessName 打印业务名称
|
||
* @returns {string} 缓存键
|
||
*/
|
||
function getPrinterCacheKey(businessName) {
|
||
const userId = getCurrentUserId();
|
||
return `selectedPrinter_${businessName || 'default'}_${userId}`;
|
||
}
|
||
|
||
/**
|
||
* 从缓存获取上次选择的打印机
|
||
* @param {string} businessName 打印业务名称
|
||
* @returns {string} 打印机名称
|
||
*/
|
||
export function getCachedPrinter(businessName = 'default') {
|
||
const cacheKey = getPrinterCacheKey(businessName);
|
||
return localStorage.getItem(cacheKey) || '';
|
||
}
|
||
|
||
/**
|
||
* 保存打印机选择到缓存
|
||
* @param {string} printerName 打印机名称
|
||
* @param {string} businessName 打印业务名称
|
||
*/
|
||
export function savePrinterToCache(printerName, businessName = 'default') {
|
||
if (printerName) {
|
||
const cacheKey = getPrinterCacheKey(businessName);
|
||
localStorage.setItem(cacheKey, printerName);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 执行打印操作
|
||
* @param {Array} data 打印数据
|
||
* @param {Object} template 打印模板
|
||
* @param {string} printerName 打印机名称(可选)
|
||
* @param {Object} options 打印选项(可选)
|
||
* @param {string} businessName 打印业务名称(可选)
|
||
* @returns {Promise} 打印结果Promise
|
||
*/
|
||
export function executePrint(data, template, printerName, options = {}, businessName = 'default') {
|
||
return new Promise((resolve, reject) => {
|
||
try {
|
||
// 调试信息
|
||
console.log('========== 打印诊断日志开始 ==========');
|
||
console.log('[1] hiprint对象检查:');
|
||
console.log(' - hiprint存在:', !!hiprint);
|
||
console.log(' - hiprint.PrintTemplate存在:', !!(hiprint && hiprint.PrintTemplate));
|
||
console.log(' - hiprint.hiwebSocket存在:', !!(hiprint && hiprint.hiwebSocket));
|
||
console.log(' - hiprint.hiwebSocket.connected:', hiprint?.hiwebSocket?.connected);
|
||
|
||
console.log('[2] 模板数据检查:');
|
||
console.log(' - 模板类型:', typeof template);
|
||
console.log(' - 模板存在:', !!template);
|
||
console.log(' - 模板panels存在:', !!(template && template.panels));
|
||
console.log(' - panels数量:', template?.panels?.length);
|
||
|
||
if (template?.panels?.[0]) {
|
||
const panel = template.panels[0];
|
||
console.log(' - panel.name:', panel.name, '(类型:', typeof panel.name, ')');
|
||
console.log(' - panel.index:', panel.index);
|
||
console.log(' - panel.printElements数量:', panel.printElements?.length);
|
||
|
||
// 检查每个元素的类型
|
||
if (panel.printElements) {
|
||
panel.printElements.forEach((el, idx) => {
|
||
console.log(` - 元素[${idx}]:`, el.printElementType?.type, '-', el.printElementType?.title);
|
||
});
|
||
}
|
||
}
|
||
|
||
const userStore = useUserStore();
|
||
console.log('[3] 医院名称:', userStore.hospitalName);
|
||
|
||
let processedTemplate;
|
||
try {
|
||
processedTemplate = JSON.parse(
|
||
JSON.stringify(template).replace(/{{HOSPITAL_NAME}}/g, userStore.hospitalName)
|
||
);
|
||
console.log('[4] 模板处理成功');
|
||
} catch (parseError) {
|
||
console.error('[4] 模板处理失败:', parseError);
|
||
throw new Error('模板处理失败: ' + parseError.message);
|
||
}
|
||
|
||
console.log('[5] 打印数据检查:');
|
||
console.log(' - 数据类型:', typeof data);
|
||
console.log(' - 数据存在:', !!data);
|
||
if (data && typeof data === 'object') {
|
||
console.log(' - 数据字段:', Object.keys(data));
|
||
}
|
||
|
||
// 创建打印模板
|
||
let hiprintTemplate;
|
||
try {
|
||
console.log('[6] 开始创建PrintTemplate...');
|
||
hiprintTemplate = new hiprint.PrintTemplate({ template: processedTemplate });
|
||
console.log('[6] PrintTemplate创建成功:', hiprintTemplate);
|
||
} catch (templateError) {
|
||
console.error('[6] 创建打印模板失败:', templateError);
|
||
console.error('错误堆栈:', templateError.stack);
|
||
console.error('模板内容:', JSON.stringify(processedTemplate, null, 2));
|
||
throw new Error('打印模板创建失败: ' + templateError.message);
|
||
}
|
||
|
||
const printOptions = {
|
||
title: '打印标题',
|
||
height: 210,
|
||
width: 148,
|
||
...options,
|
||
};
|
||
console.log('[7] 打印选项:', printOptions);
|
||
|
||
// 检查客户端是否连接
|
||
const isClientConnected = hiprint.hiwebSocket && hiprint.hiwebSocket.connected;
|
||
console.log('[8] 客户端连接状态:', isClientConnected);
|
||
|
||
// 如果指定了打印机且客户端已连接,添加到打印选项中
|
||
if (printerName && isClientConnected) {
|
||
printOptions.printer = printerName;
|
||
// 保存到缓存
|
||
savePrinterToCache(printerName, businessName);
|
||
console.log('[8] 使用指定打印机:', printerName);
|
||
}
|
||
|
||
// 打印成功回调
|
||
hiprintTemplate.on('printSuccess', function (e) {
|
||
console.log('[9] 打印成功:', e);
|
||
console.log('========== 打印诊断日志结束 ==========');
|
||
resolve({ success: true, event: e });
|
||
});
|
||
|
||
// 打印失败回调
|
||
hiprintTemplate.on('printError', function (e) {
|
||
console.error('[9] 打印失败:', e);
|
||
console.log('========== 打印诊断日志结束 ==========');
|
||
reject({ success: false, event: e, message: '打印失败' });
|
||
});
|
||
|
||
// 根据客户端连接状态选择打印方式
|
||
console.log('[10] 开始执行打印...');
|
||
if (isClientConnected && printerName) {
|
||
// 客户端已连接且指定了打印机,使用静默打印
|
||
console.log('[10] 使用print2静默打印');
|
||
try {
|
||
hiprintTemplate.print2(data, printOptions);
|
||
console.log('[10] print2调用完成');
|
||
} catch (print2Error) {
|
||
console.error('[10] print2调用失败:', print2Error);
|
||
console.error('[10] print2错误堆栈:', print2Error.stack);
|
||
throw new Error('print2打印失败: ' + print2Error.message);
|
||
}
|
||
} else {
|
||
// 客户端未连接或未指定打印机,使用浏览器打印预览(不需要客户端连接)
|
||
console.log('[10] 使用print浏览器打印预览');
|
||
console.log('[10] hiprintTemplate.print方法存在:', typeof hiprintTemplate.print === 'function');
|
||
try {
|
||
hiprintTemplate.print(data, printOptions, {
|
||
styleHandler: () => {
|
||
console.log('[10] styleHandler被调用');
|
||
return '<style>@media print { @page { margin: 0; } }</style>';
|
||
},
|
||
callback: (e) => {
|
||
console.log('[10] 打印回调被调用:', e);
|
||
}
|
||
});
|
||
console.log('[10] print调用完成');
|
||
} catch (printError) {
|
||
console.error('[10] print调用失败:', printError);
|
||
console.error('[10] print错误堆栈:', printError.stack);
|
||
throw new Error('print打印失败: ' + printError.message);
|
||
}
|
||
// 浏览器打印模式下,直接resolve(因为打印窗口已打开)
|
||
console.log('[10] 浏览器打印模式,直接返回成功');
|
||
console.log('========== 打印诊断日志结束 ==========');
|
||
resolve({ success: true, message: '打印窗口已打开' });
|
||
}
|
||
} catch (error) {
|
||
console.error('[ERROR] 打印过程中发生错误:', error);
|
||
console.error('[ERROR] 错误类型:', error?.constructor?.name);
|
||
console.error('[ERROR] 错误消息:', error?.message);
|
||
console.error('[ERROR] 错误堆栈:', error?.stack);
|
||
console.log('========== 打印诊断日志结束 ==========');
|
||
reject({ success: false, error: error, message: error?.message || '打印过程中发生错误' });
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 选择打印机并执行打印
|
||
* @param {Array} data 打印数据
|
||
* @param {Object} template 打印模板
|
||
* @param {Function} showPrinterDialog 显示打印机选择对话框的函数
|
||
* @param {Object} modal 消息提示对象
|
||
* @param {Function} callback 打印完成后的回调函数
|
||
* @param {string} businessName 打印业务名称(可选)
|
||
*/
|
||
export async function selectPrinterAndPrint(
|
||
data,
|
||
template,
|
||
showPrinterDialog,
|
||
modal,
|
||
callback,
|
||
businessName = 'default'
|
||
) {
|
||
try {
|
||
// 获取打印机列表
|
||
const printerList = getPrinterList();
|
||
|
||
if (printerList.length === 0) {
|
||
modal.msgWarning('未检测到可用打印机');
|
||
return;
|
||
}
|
||
|
||
// 获取缓存的打印机
|
||
const cachedPrinter = getCachedPrinter(businessName);
|
||
let selectedPrinter = '';
|
||
|
||
// 判断打印机选择逻辑
|
||
if (printerList.length === 1) {
|
||
selectedPrinter = printerList[0].name;
|
||
await executePrint(data, template, selectedPrinter, {}, businessName);
|
||
if (callback) callback();
|
||
} else if (cachedPrinter && printerList.some((printer) => printer.name === cachedPrinter)) {
|
||
selectedPrinter = cachedPrinter;
|
||
await executePrint(data, template, selectedPrinter, {}, businessName);
|
||
if (callback) callback();
|
||
} else {
|
||
// 调用显示打印机选择对话框的函数
|
||
showPrinterDialog(printerList, async (chosenPrinter) => {
|
||
try {
|
||
await executePrint(data, template, chosenPrinter, {}, businessName);
|
||
if (callback) callback();
|
||
} catch (error) {
|
||
modal.msgError(error.message || '打印失败');
|
||
}
|
||
});
|
||
}
|
||
} catch (error) {
|
||
modal.msgError(error.message || '获取打印机列表失败');
|
||
}
|
||
}
|
||
|
||
// 预览打印
|
||
export function previewPrint(elementDom) {
|
||
if (elementDom) {
|
||
// 初始化已在 main.js 中完成,无需重复调用
|
||
// hiprint.init();
|
||
const hiprintTemplate = new hiprint.PrintTemplate();
|
||
// printByHtml为预览打印
|
||
hiprintTemplate.printByHtml(elementDom, {});
|
||
} else {
|
||
ElMessage({
|
||
type: 'error',
|
||
message: '加载模版失败',
|
||
});
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 打印门诊挂号收据(使用浏览器打印,模板与补打挂号一致)
|
||
* @param {Object} data 打印数据
|
||
* @param {Object} options 打印选项
|
||
* @returns {Promise} 打印结果 Promise
|
||
*/
|
||
export function printRegistrationReceipt(data, options = {}) {
|
||
return new Promise((resolve, reject) => {
|
||
try {
|
||
// 构建打印内容的 HTML
|
||
const printContent = `
|
||
<div class="print-header">
|
||
<div class="header-content">
|
||
<div class="document-title">门诊预约挂号凭条</div>
|
||
<div class="print-time">打印时间:${data.printTime || new Date().toLocaleString()}</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="print-section">
|
||
<div class="section-title">患者基本信息</div>
|
||
<div class="info-row">
|
||
<span class="label">患者姓名:</span>
|
||
<span class="value">${data.patientName || '-'}</span>
|
||
</div>
|
||
<div class="info-row">
|
||
<span class="label">就诊卡号:</span>
|
||
<span class="value">${data.cardNo || data.busNo || '-'}</span>
|
||
</div>
|
||
<div class="info-row">
|
||
<span class="label">身份证号:</span>
|
||
<span class="value">${data.idCard ? maskIdCard(data.idCard) : '-'}</span>
|
||
</div>
|
||
<div class="info-row">
|
||
<span class="label">联系电话:</span>
|
||
<span class="value">${data.phone || '-'}</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="print-section">
|
||
<div class="section-title">挂号信息</div>
|
||
<div class="info-row">
|
||
<span class="label">就诊科室:</span>
|
||
<span class="value">${data.organizationName || '-'}</span>
|
||
</div>
|
||
<div class="info-row">
|
||
<span class="label">医生姓名:</span>
|
||
<span class="value">${data.practitionerName || '-'}</span>
|
||
</div>
|
||
<div class="info-row">
|
||
<span class="label">挂号类型:</span>
|
||
<span class="value">${data.healthcareName || '-'}</span>
|
||
</div>
|
||
<div class="info-row">
|
||
<span class="label">挂号时间:</span>
|
||
<span class="value">${data.visitTime || data.chargeTime || '-'}</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="print-section">
|
||
<div class="section-title">费用信息</div>
|
||
<table class="fee-table">
|
||
<thead>
|
||
<tr>
|
||
<th>项目</th>
|
||
<th>数量</th>
|
||
<th>单价</th>
|
||
<th>金额</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>挂号费</td>
|
||
<td>1</td>
|
||
<td>¥${parseFloat(data.price || 0).toFixed(2)}</td>
|
||
<td>¥${parseFloat(data.price || 0).toFixed(2)}</td>
|
||
</tr>
|
||
${parseFloat(data.activityPrice || 0) > 0 ? `
|
||
<tr>
|
||
<td>诊疗费</td>
|
||
<td>1</td>
|
||
<td>¥${parseFloat(data.activityPrice || 0).toFixed(2)}</td>
|
||
<td>¥${parseFloat(data.activityPrice || 0).toFixed(2)}</td>
|
||
</tr>` : ''}
|
||
${parseFloat(data.medicalRecordFee || 0) > 0 ? `
|
||
<tr>
|
||
<td>病历费</td>
|
||
<td>1</td>
|
||
<td>¥${parseFloat(data.medicalRecordFee || 0).toFixed(2)}</td>
|
||
<td>¥${parseFloat(data.medicalRecordFee || 0).toFixed(2)}</td>
|
||
</tr>` : ''}
|
||
</tbody>
|
||
<tfoot>
|
||
<tr>
|
||
<td colspan="3" class="total-label">合计:</td>
|
||
<td class="total-value">¥${parseFloat(data.totalPrice || data.amount || 0).toFixed(2)}</td>
|
||
</tr>
|
||
</tfoot>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- 流水号显示在左下角 -->
|
||
<div class="serial-number-bottom-left">
|
||
<span class="serial-label">流水号:</span>
|
||
<span class="serial-value">${data.serialNo || data.encounterId || '-'}</span>
|
||
</div>
|
||
|
||
<div class="print-footer">
|
||
<div class="reminder">温馨提示:请妥善保管此凭条,就诊时请携带。</div>
|
||
</div>
|
||
|
||
<!-- 二维码区域 -->
|
||
<div class="qr-code-section">
|
||
<div class="qr-code-container">
|
||
<div id="qrcode-print" class="qrcode-print"></div>
|
||
<div class="qr-code-label">扫码查看挂号信息</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
// 创建新窗口用于打印
|
||
const printWindow = window.open('', '_blank');
|
||
if (!printWindow) {
|
||
reject(new Error('无法打开打印窗口,请检查浏览器弹窗设置'));
|
||
return;
|
||
}
|
||
|
||
// 写入打印内容
|
||
printWindow.document.write(`
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>门诊预约挂号凭条</title>
|
||
<style>
|
||
body { font-family: Arial, sans-serif; padding: 20px; margin: 0; }
|
||
.print-header { margin-bottom: 20px; position: relative; }
|
||
.header-content { text-align: center; }
|
||
.document-title { font-size: 16px; font-weight: bold; margin-bottom: 10px; }
|
||
.print-time { font-size: 12px; color: #666; text-align: right; }
|
||
.print-section { margin-bottom: 20px; }
|
||
.section-title { font-size: 14px; font-weight: bold; margin-bottom: 10px; border-bottom: 1px solid #ddd; padding-bottom: 5px; }
|
||
.info-row { margin-bottom: 8px; font-size: 13px; }
|
||
.label { display: inline-block; width: 100px; font-weight: bold; }
|
||
.value { display: inline-block; }
|
||
.fee-table { width: 100%; border-collapse: collapse; margin-top: 10px; }
|
||
.fee-table th, .fee-table td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
||
.fee-table th { background-color: #f5f5f5; font-weight: bold; }
|
||
.total-label { font-weight: bold; text-align: right; }
|
||
.total-value { font-weight: bold; color: red; }
|
||
.serial-number-bottom-left { position: absolute; bottom: 20px; left: 20px; font-size: 14px; font-weight: bold; }
|
||
.serial-number-bottom-left .serial-label { font-weight: bold; margin-right: 5px; }
|
||
.serial-number-bottom-left .serial-value { font-weight: bold; color: #333; }
|
||
.print-content { position: relative; min-height: 500px; padding-bottom: 60px; }
|
||
.print-footer { margin-top: 20px; font-size: 12px; color: #666; }
|
||
.reminder { text-align: center; padding: 10px; background-color: #f9f9f9; border-radius: 4px; }
|
||
.qr-code-section { margin-top: 20px; display: flex; justify-content: center; align-items: center; padding: 15px; }
|
||
.qr-code-container { display: flex; flex-direction: column; align-items: center; gap: 10px; }
|
||
.qrcode-print { width: 120px; height: 120px; }
|
||
.qr-code-label { font-size: 12px; color: #666; text-align: center; }
|
||
@media print { body { padding: 0; } .qr-code-section { page-break-inside: avoid; } }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="print-content">
|
||
${printContent}
|
||
</div>
|
||
</body>
|
||
</html>
|
||
`);
|
||
|
||
printWindow.document.close();
|
||
printWindow.onload = function() {
|
||
setTimeout(() => {
|
||
printWindow.print();
|
||
resolve({ success: true, message: '打印窗口已打开' });
|
||
}, 250);
|
||
};
|
||
} catch (error) {
|
||
console.error('打印门诊挂号收据失败:', error);
|
||
reject(error);
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 脱敏身份证号
|
||
* @param {string} idCard 身份证号
|
||
* @returns {string} 脱敏后的身份证号
|
||
*/
|
||
function maskIdCard(idCard) {
|
||
if (!idCard) return '';
|
||
if (idCard.length >= 10) {
|
||
const prefix = idCard.substring(0, 6);
|
||
const suffix = idCard.substring(idCard.length - 4);
|
||
const stars = '*'.repeat(Math.max(0, idCard.length - 10));
|
||
return prefix + stars + suffix;
|
||
} else if (idCard.length >= 6) {
|
||
const prefix = idCard.substring(0, 3);
|
||
const suffix = idCard.substring(idCard.length - 1);
|
||
return prefix + '*'.repeat(idCard.length - 4) + suffix;
|
||
}
|
||
return idCard;
|
||
}
|
||
|
||
// 默认导出简化的打印方法
|
||
export default {
|
||
print: simplePrint,
|
||
printWithDialog: simplePrintWithDialog,
|
||
TEMPLATE: PRINT_TEMPLATE,
|
||
executePrint,
|
||
selectPrinterAndPrint,
|
||
getPrinterList,
|
||
getCachedPrinter,
|
||
savePrinterToCache,
|
||
};
|