refactor(print): 更新打印功能实现并优化药品管理查询

- 替换旧的hiprint直接调用为统一的printUtils工具类
- 新增门诊手术计费打印模板支持(含流程图)
- 修改门诊收费结算单打印逻辑,使用新的打印工具类
- 修复门诊挂号打印模板注释说明
- 优化药品库房查询,过滤已删除的记录
- 更新药品管理接口URL路径配置
- 添加打印客户端连接状态检查,支持浏览器打印预览备选方案
- 改进打印错误处理和用户提示机制
This commit is contained in:
2026-03-04 11:05:12 +08:00
parent 8810c678c9
commit 6a8f82bb2e
6 changed files with 119 additions and 151 deletions

View File

@@ -42,6 +42,7 @@
AND T4.condition_value = T1.lot_number
THEN T4.amount
ELSE T3.price END AS sale_price, --售价
T3.price, --进价
T2.part_percent, --拆零比
T6.form_enum AS purpose_type_enum, --仓库类型
T6.name AS location_name, --仓库名称

View File

@@ -35,7 +35,9 @@ public class LocationServiceImpl extends ServiceImpl<LocationMapper, Location> i
@Override
public List<Location> getPharmacyList() {
return baseMapper
.selectList(new LambdaQueryWrapper<Location>().eq(Location::getFormEnum, LocationForm.PHARMACY.getValue()));
.selectList(new LambdaQueryWrapper<Location>()
.eq(Location::getFormEnum, LocationForm.PHARMACY.getValue())
.eq(Location::getDeleteFlag, DelFlag.NO.getCode()));
}
/**

View File

@@ -17,8 +17,10 @@ const TEMPLATE_MAP = {
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'),
//门诊病历
@@ -121,6 +123,8 @@ export const PRINT_TEMPLATE = {
IN_HOSPITAL_DISPENSING: 'IN_HOSPITAL_DISPENSING',
//门诊挂号
OUTPATIENT_REGISTRATION: 'OUTPATIENT_REGISTRATION',
// 门诊手术计费
OUTPATIENT_SURGERY_CHARGE: 'OUTPATIENT_SURGERY_CHARGE',
//门诊收费
OUTPATIENT_CHARGE: 'OUTPATIENT_CHARGE',
//处方签
@@ -242,8 +246,11 @@ export function executePrint(data, template, printerName, options = {}, business
...options,
};
// 如果指定了打印机,添加到打印选项中
if (printerName) {
// 检查客户端是否连接
const isClientConnected = window.hiprint.hiwebSocket && window.hiprint.hiwebSocket.connected;
// 如果指定了打印机且客户端已连接,添加到打印选项中
if (printerName && isClientConnected) {
printOptions.printer = printerName;
// 保存到缓存
savePrinterToCache(printerName, businessName);
@@ -259,8 +266,24 @@ export function executePrint(data, template, printerName, options = {}, business
reject({ success: false, event: e, message: '打印失败' });
});
// 执行打印
hiprintTemplate.print2(data, printOptions);
// 根据客户端连接状态选择打印方式
if (isClientConnected && printerName) {
// 客户端已连接且指定了打印机,使用静默打印
hiprintTemplate.print2(data, printOptions);
} else {
// 客户端未连接或未指定打印机,使用浏览器打印预览(不需要客户端连接)
console.log('打印客户端未连接,使用浏览器打印预览方式');
hiprintTemplate.print(data, printOptions, {
styleHandler: () => {
return '<style>@media print { @page { margin: 0; } }</style>';
},
callback: () => {
console.log('打印窗口已打开');
}
});
// 浏览器打印模式下直接resolve因为打印窗口已打开
resolve({ success: true, message: '打印窗口已打开' });
}
} catch (error) {
reject({ success: false, error: error, message: error.message || '打印过程中发生错误' });
}

View File

@@ -382,9 +382,9 @@ async function printReceipt(param) {
},
],
};
// 选择门诊挂号打印模板
// 选择门诊手术计费打印模板(含流程图)
console.log('printDataprintDataprintDataprintDataprintData', printData.data[0]);
await printUtils.print(PRINT_TEMPLATE.OUTPATIENT_REGISTRATION, printData.data[0]);
await printUtils.print(PRINT_TEMPLATE.OUTPATIENT_SURGERY_CHARGE, printData.data[0]);
console.log('打印成功');
} catch (error) {
console.error('打印失败:', error);

View File

@@ -158,8 +158,7 @@ import {computed, getCurrentInstance, nextTick, reactive, ref, watch} from 'vue'
import {Delete} from '@element-plus/icons-vue';
import {debounce} from 'lodash-es';
import useUserStore from '@/store/modules/user';
import {hiprint} from 'vue-plugin-hiprint';
import templateJson from './template.json';
import printUtils, {PRINT_TEMPLATE} from '@/utils/printUtils';
import image1 from '../../../../../assets/images/weixinzhifu.png';
import image2 from '../../../../../assets/images/zhifubaozhifu.png';
@@ -248,119 +247,67 @@ const emit = defineEmits(['close']);
let displayAmountTemp = 0;
// 打印小票
function printReceipt(param) {
async function printReceipt(param) {
let total = 0;
props.chargedItems.forEach((item) => {
total += item.totalPrice || 0;
});
// 构造一个新的对象,添加头 "data"
const result = {
data: [
{
...param,
// 基础支付类型
YB_FUND_PAY:
(param.detail?.find((t) => t.payEnum === 100000)?.amount?.toFixed(2) || '0.00') + ' 元',
SELF_PAY: (param.detail?.find((t) => t.payEnum === 200000)?.amount?.toFixed(2) || '0.00') + ' 元',
OTHER_PAY: param.detail?.find((t) => t.payEnum === 300000)?.amount ?? 0, // 其他(如医院负担金额)
try {
// 构造打印数据
const printData = {
data: [
{
...param,
// 基础支付类型
YB_FUND_PAY:
(param.detail?.find((t) => t.payEnum === 100000)?.amount?.toFixed(2) || '0.00') + ' 元',
SELF_PAY: (param.detail?.find((t) => t.payEnum === 200000)?.amount?.toFixed(2) || '0.00') + ' 元',
OTHER_PAY: param.detail?.find((t) => t.payEnum === 300000)?.amount ?? 0, // 其他(如医院负担金额)
// 基本医保统筹基金支出
YB_TC_FUND_AMOUNT:
(param.detail?.find((t) => t.payEnum === 110000)?.amount?.toFixed(2) || '0.00') + ' 元',
YB_BC_FUND_AMOUNT:
(param.detail?.find((t) => t.payEnum === 120000)?.amount?.toFixed(2) || '0.00') + ' 元',
YB_JZ_FUND_AMOUNT:
(param.detail?.find((t) => t.payEnum === 130000)?.amount?.toFixed(2) || '0.00') + ' 元',
// YB_OTHER_AMOUNT: param.detail.find((t) => t.payEnum === 140000)?.amount ?? 0, // 其他支出
// 基本医保统筹基金支出
YB_TC_FUND_AMOUNT:
(param.detail?.find((t) => t.payEnum === 110000)?.amount?.toFixed(2) || '0.00') + ' 元',
YB_BC_FUND_AMOUNT:
(param.detail?.find((t) => t.payEnum === 120000)?.amount?.toFixed(2) || '0.00') + ' 元',
YB_JZ_FUND_AMOUNT:
(param.detail?.find((t) => t.payEnum === 130000)?.amount?.toFixed(2) || '0.00') + ' 元',
// 职工基本医疗保险
// YB_TC_ZG_FUND_VALUE: param.detail.find((t) => t.payEnum === 110100)?.amount ?? 0, // 职工基本医疗保险
// YB_TC_JM_FUND_VALUE: param.detail.find((t) => t.payEnum === 110200)?.amount ?? 0, // 居民基本医疗保险(修正原错误注释)
// 医保结算返回值
FULAMT_OWNPAY_AMT:
(param.detail?.find((t) => t.payEnum === 1)?.amount?.toFixed(2) || '0.00') + ' 元',
INSCP_SCP_AMT: (param.detail?.find((t) => t.payEnum === 5)?.amount?.toFixed(2) || '0.00') + ' 元',
// 补充医疗保险基金支出细分
// YB_BC_JM_DB_VALUE: param.detail.find((t) => t.payEnum === 120100)?.amount ?? 0, // 全体参保人的居民大病保险
// YB_BC_DE_BZ_VALUE: param.detail.find((t) => t.payEnum === 120200)?.amount ?? 0, // 大额医疗费用补助
// YB_BC_ZG_DE_BZ_VALUE: param.detail.find((t) => t.payEnum === 120300)?.amount ?? 0, // 企业职工大额医疗费用补助
// YB_BC_GWY_BZ_VALUE: param.detail.find((t) => t.payEnum === 120400)?.amount ?? 0, // 公务员医疗补助
// 特殊支付方式
SELF_YB_ZH_PAY:
(param.detail?.find((t) => t.payEnum === 210000)?.amount?.toFixed(2) || '0.00') + ' 元',
// 其他支出细分
// OTHER_PAY_DD_FUND_VALUE: param.detail.find((t) => t.payEnum === 300001)?.amount ?? 0, // 兜底基金支出
// OTHER_PAY_YW_SH_FUND_VALUE: param.detail.find((t) => t.payEnum === 300002)?.amount ?? 0, // 意外伤害基金支出
// OTHER_PAY_LX_YL_FUND_VALUE: param.detail.find((t) => t.payEnum === 300003)?.amount ?? 0, // 离休人员医疗保障金支出
// OTHER_PAY_LX_YH_FUND_VALUE: param.detail.find((t) => t.payEnum === 300004)?.amount ?? 0, // 离休人员优惠金支出
// OTHER_PAY_CZ_FUND_VALUE: param.detail.find((t) => t.payEnum === 300005)?.amount ?? 0, // 财政基金支出
// OTHER_PAY_CZ_YZ_FUND_VALUE: param.detail.find((t) => t.payEnum === 300006)?.amount ?? 0, // 财政预支支出
// OTHER_PAY_ZG_DB_FUND_VALUE: param.detail.find((t) => t.payEnum === 300007)?.amount ?? 0, // 职工大病基金支出
// OTHER_PAY_EY_FUND_VALUE: param.detail.find((t) => t.payEnum === 300008)?.amount ?? 0, // 二乙基金支出
// OTHER_PAY_QX_JZ_FUND_VALUE: param.detail.find((t) => t.payEnum === 300009)?.amount ?? 0, // 倾斜救助支出
// OTHER_PAY_YL_JZ_FUND_VALUE: param.detail.find((t) => t.payEnum === 300010)?.amount ?? 0, // 医疗救助再救助基金
// HOSP_PART_AMT: param.detail.find((t) => t.payEnum === 300011)?.amount ?? 0, // 医院负担金额
Mr_QR_Code: param.regNo,
sex: props.patientInfo?.genderEnum_enumText || '',
age: props.patientInfo?.age || '',
personType: '职工医保',
fixmedinsName: (param.fixmedinsName || '') + '门诊收费明细',
name: props.patientInfo?.patientName || '', // 姓名
gender: props.patientInfo?.genderEnum_enumText || '', // 性别
encounterBusNo: props.patientInfo?.encounterBusNo || '', // 病例号
currentDate: currentDate.value, // 收费日期
chargedItems: props.chargedItems, // 收费项目
totalAmount: props.totalAmount.toFixed(2) + ' 元', // 应收金额
itemTotalAmount: total.toFixed(2) + ' 元', // 应收金额
displayAmount: displayAmountTemp + ' 元', // 实收金额
returnedAmount: returnedAmount.value + ' 元', // 应找零
userName: userStore.nickName,
},
],
};
// 医保结算返回值
FULAMT_OWNPAY_AMT:
(param.detail?.find((t) => t.payEnum === 1)?.amount?.toFixed(2) || '0.00') + ' 元',
// OVERLMT_SELFPAY: param.detail.find((t) => t.payEnum === 3)?.amount ?? 0, // 超限价自费费用
// PRESELFPAY_AMT: param.detail.find((t) => t.payEnum === 4)?.amount ?? 0, // 先行自付金额
INSCP_SCP_AMT: (param.detail?.find((t) => t.payEnum === 5)?.amount?.toFixed(2) || '0.00') + ' 元',
// ACT_PAY_DEDC: param.detail.find((t) => t.payEnum === 6)?.amount ?? 0, // 实际支付起付线
// POOL_PROP_SELFPAY: param.detail.find((t) => t.payEnum === 7)?.amount ?? 0, // 基本医疗保险统筹基金支付比例
// BALC: param.detail.find((t) => t.payEnum === 8)?.amount ?? 0, // 余额
// 特殊支付方式
SELF_YB_ZH_PAY:
(param.detail?.find((t) => t.payEnum === 210000)?.amount?.toFixed(2) || '0.00') + ' 元',
// SELF_YB_ZH_GJ_VALUE: param.detail.find((t) => t.payEnum === 210100)?.amount ?? 0, // 账户共济支付金额
// SELF_CASH_PAY: param.detail.find((t) => t.payEnum === 220000)?.amount ?? 0, // 个人现金支付金额
// SELF_VX_PAY: param.detail.find((t) => t.payEnum === 230000)?.amount ?? 0, // 微信支付金额
// SELF_ALI_PAY: param.detail.find((t) => t.payEnum === 240000)?.amount ?? 0, // 阿里支付金额
// 现金支付细分
// SELF_CASH_VALUE: param.detail.find((t) => t.payEnum === 220400)?.amount ?? 0, // 个人现金支付金额(现金)
// SELF_CASH_VX_VALUE: param.detail.find((t) => t.payEnum === 220100)?.amount ?? 0, // 个人现金支付金额(微信)
// SELF_CASH_ALI_VALUE: param.detail.find((t) => t.payEnum === 220200)?.amount ?? 0, // 个人现金支付金额(支付宝)
// SELF_CASH_UNION_VALUE: param.detail.find((t) => t.payEnum === 220300)?.amount ?? 0, // 个人现金支付金额(银联)
// 基金类型(扩展)
// BIRTH_FUND: param.detail.find((t) => t.payEnum === 510100)?.amount ?? 0, // 生育基金
// RETIREE_MEDICAL: param.detail.find((t) => t.payEnum === 340100)?.amount ?? 0, // 离休人员医疗保障基金
// URBAN_BASIC_MEDICAL: param.detail.find((t) => t.payEnum === 390100)?.amount ?? 0, // 城乡居民基本医疗保险基金
// URBAN_SERIOUS_ILLNESS: param.detail.find((t) => t.payEnum === 390200)?.amount ?? 0, // 城乡居民大病医疗保险基金
// MEDICAL_ASSISTANCE: param.detail.find((t) => t.payEnum === 610100)?.amount ?? 0, // 医疗救助基金
// GOVERNMENT_SUBSIDY: param.detail.find((t) => t.payEnum === 640100)?.amount ?? 0, // 政府兜底基金
// ACCIDENT_INSURANCE: param.detail.find((t) => t.payEnum === 390400)?.amount ?? 0, // 意外伤害基金
// CARE_INSURANCE: param.detail.find((t) => t.payEnum === 620100)?.amount ?? 0, // 照护保险基金
// FINANCIAL_FUND: param.detail.find((t) => t.payEnum === 360100)?.amount ?? 0, // 财政基金
// HOSPITAL_ADVANCE: param.detail.find((t) => t.payEnum === 999900)?.amount ?? 0, // 医院垫付
// SUPPLEMENTARY_INSURANCE: param.detail.find((t) => t.payEnum === 390300)?.amount ?? 0, // 城乡居民大病补充保险基金
// HEALTHCARE_PREPAYMENT: param.detail.find((t) => t.payEnum === 360300)?.amount ?? 0, // 保健预支基金
Mr_QR_Code: param.regNo,
sex: props.patientInfo?.genderEnum_enumText || '',
age: props.patientInfo?.age || '',
personType: '职工医保',
fixmedinsName: (param.fixmedinsName || '') + '门诊收费明细',
name: props.patientInfo?.patientName || '', // 姓名
gender: props.patientInfo?.genderEnum_enumText || '', // 性别
age: props.patientInfo?.age || '', // 年龄
encounterBusNo: props.patientInfo?.encounterBusNo || '', // 病例号
currentDate: currentDate.value, // 收费日期
chargedItems: props.chargedItems, // 收费项目
totalAmount: props.totalAmount.toFixed(2) + ' 元', // 应收金额
itemTotalAmount: total.toFixed(2) + ' 元', // 应收金额
displayAmount: displayAmountTemp + ' 元', // 实收金额
returnedAmount: returnedAmount.value + ' 元', // 应找零
userName: userStore.nickName,
},
],
};
const printElements = JSON.parse(
JSON.stringify(templateJson).replace(/{{HOSPITAL_NAME}}/g, userStore.hospitalName)
);
var hiprintTemplate = new hiprint.PrintTemplate({ template: printElements }); // 定义模板
hiprintTemplate.print2(result.data[0], {
printer: 'xp',
title: '门诊收费结算单',
});
// 使用printUtils进行打印
await printUtils.print(PRINT_TEMPLATE.OUTPATIENT_CHARGE, printData.data[0]);
console.log('打印成功');
} catch (error) {
console.error('打印失败:', error);
proxy.$modal.msgError('打印失败: ' + error.message);
}
}
const throttledGetList = debounce(submit, 300);
@@ -440,40 +387,37 @@ async function submit() {
/** 打印收费结算单 */
async function print() {
console.log('patientInfo', props.patientInfo);
console.log('category', props.category);
console.log('totalAmount', props.totalAmount);
console.log('chargeItemIds', props.chargeItemIds);
console.log('consumablesIdList', props.consumablesIdList);
console.log('userCardInfo', props.userCardInfo);
console.log('paymentId', props.paymentId);
console.log('details', props.details);
console.log('chargedItems', props.chargedItems);
const result = {
data: [
{
name: props.patientInfo.patientName, // 姓名
gender: props.patientInfo.genderEnum_enumText, // 性别
age: props.patientInfo.age, // 年龄
encounterBusNo: props.patientInfo.encounterBusNo, // 病例号
currentDate: currentDate.value, // 收费日期
chargedItems: props.chargedItems, // 收费项目
totalAmount: props.totalAmount.toFixed(2) + ' 元', // 应收金额
displayAmount: displayAmount.value + ' 元', // 实收金额
returnedAmount: returnedAmount.value + ' 元', // 应找零
},
],
};
console.log(result, '==result.data==');
const printElements = JSON.parse(
JSON.stringify(templateJson).replace(/{{HOSPITAL_NAME}}/g, userStore.hospitalName)
);
var hiprintTemplate = new hiprint.PrintTemplate({ template: printElements }); // 定义模板
const printerList = hiprintTemplate.getPrinterList();
console.log(hiprintTemplate, '打印机列表');
hiprintTemplate.print2(result.data[0], {
title: '门诊收费结算单',
let total = 0;
props.chargedItems.forEach((item) => {
total += item.totalPrice || 0;
});
try {
const printData = {
data: [
{
name: props.patientInfo.patientName, // 姓名
gender: props.patientInfo.genderEnum_enumText, // 性别
age: props.patientInfo.age, // 年龄
encounterBusNo: props.patientInfo.encounterBusNo, // 病例号
currentDate: currentDate.value, // 收费日期
chargedItems: props.chargedItems, // 收费项目
totalAmount: props.totalAmount.toFixed(2) + ' 元', // 应收金额
itemTotalAmount: total.toFixed(2) + ' 元', // 项目总金额
displayAmount: displayAmount.value + ' 元', // 实收金额
returnedAmount: returnedAmount.value + ' 元', // 应找零
userName: userStore.nickName,
},
],
};
// 使用printUtils进行打印
await printUtils.print(PRINT_TEMPLATE.OUTPATIENT_CHARGE, printData.data[0]);
console.log('打印成功');
} catch (error) {
console.error('打印失败:', error);
proxy.$modal.msgError('打印失败: ' + error.message);
}
}
const currentDate = ref(new Date().toLocaleString());

View File

@@ -91,8 +91,7 @@ export function getCount(queryParams) {
// 获取药房列表
export function getPharmacyList() {
return request({
url: '/app-common/inventory-pharmacy-list',
// '/app-common/pharmacy-list',
url: '/app-common/pharmacy-list',
method: 'get',
})
}
@@ -108,8 +107,7 @@ export function getPharmacyCabinetList() {
// 获取药库列表
export function getDispensaryList() {
return request({
url: '/app-common/inventory-cabinet-list',
// '/app-common/cabinet-list',
url: '/app-common/cabinet-list',
method: 'get',
})
}