1203 lines
37 KiB
Vue
1203 lines
37 KiB
Vue
<template>
|
||
<div class="app-container">
|
||
<el-row :gutter="20">
|
||
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="6">
|
||
<el-card>
|
||
<template #header>患者信息</template>
|
||
<el-row :gutter="10">
|
||
<el-col :span="10" :xs="24" :sm="10" :md="10">
|
||
<el-input
|
||
v-model="queryParams.searchKey"
|
||
placeholder="搜索患者"
|
||
clearable
|
||
class="search-input"
|
||
style="width: 100%"
|
||
@keydown.enter="getPatientList"
|
||
>
|
||
<template #append>
|
||
<el-button icon="Search" @click="getPatientList" />
|
||
</template>
|
||
</el-input>
|
||
</el-col>
|
||
<el-col :span="14" :xs="24" :sm="14" :md="14">
|
||
<el-date-picker
|
||
v-model="receptionTime"
|
||
@change="getPatientList"
|
||
type="daterange"
|
||
placeholder="挂号时间"
|
||
format="YYYY-MM-DD"
|
||
value-format="YYYY-MM-DD"
|
||
style="width: 100%"
|
||
/>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row>
|
||
<el-col :span="24" :xs="24">
|
||
<el-table
|
||
:data="patientList"
|
||
highlight-current-row
|
||
@row-click="handlePatientSelect"
|
||
style="width: 100%; height: calc(100vh - 300px)"
|
||
border
|
||
>
|
||
<el-table-column prop="encounterNo" label="就诊号" align="center" width="150" />
|
||
<el-table-column prop="patientName" label="姓名" align="center" />
|
||
<el-table-column prop="genderEnum_enumText" label="性别" align="center" />
|
||
<el-table-column prop="age" label="年龄" align="center" />
|
||
<el-table-column prop="receptionTime" label="挂号时间" align="center" />
|
||
</el-table>
|
||
<pagination
|
||
v-show="total > 0"
|
||
:total="total"
|
||
v-model:page="queryParams.pageNo"
|
||
v-model:limit="queryParams.pageSize"
|
||
@pagination="getPatientList"
|
||
:pager-count="1"
|
||
:layout="'total, prev, pager, next'"
|
||
/>
|
||
</el-col>
|
||
</el-row>
|
||
</el-card>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="18">
|
||
<el-row :gutter="20">
|
||
<el-col :xs="24" :sm="24" :md="12" class="mb8">
|
||
<el-button
|
||
type="primary"
|
||
plain
|
||
icon="Printer"
|
||
@click="printBottleLabel()"
|
||
:disabled="isCurrentPatient"
|
||
>
|
||
打印瓶签
|
||
</el-button>
|
||
<el-button
|
||
type="danger"
|
||
plain
|
||
icon="Printer"
|
||
@click="printBloodBarcode()"
|
||
:disabled="isCurrentPatient"
|
||
>
|
||
打印采血条码
|
||
</el-button>
|
||
<el-button
|
||
type="primary"
|
||
plain
|
||
icon="Printer"
|
||
@click="printPrescription()"
|
||
:disabled="isCurrentPatient"
|
||
>
|
||
打印处方
|
||
</el-button>
|
||
<el-button
|
||
type="danger"
|
||
plain
|
||
icon="Printer"
|
||
@click="printDisposal()"
|
||
:disabled="isCurrentPatient"
|
||
>
|
||
打印处置单
|
||
</el-button>
|
||
<el-button type="primary" plain @click.stop="getEnPrescription()"> 处方单 </el-button>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="6">
|
||
<el-form
|
||
ref="queryRef"
|
||
:model="queryParams"
|
||
inline-style="width: 100%"
|
||
label-width="150px"
|
||
:rules="rules"
|
||
>
|
||
<el-form-item label="处置类型" prop="serviceCategory" label-width="100px">
|
||
<el-select
|
||
v-model="queryParams.serviceCategory"
|
||
placeholder="请选择"
|
||
clearable
|
||
filterable
|
||
style="width: 100%"
|
||
@change="handleServiceCategoryChange"
|
||
:disabled="isCurrentPatient"
|
||
>
|
||
<el-option
|
||
v-for="item in activityCategoryList"
|
||
:key="item.value"
|
||
:label="item.label"
|
||
:value="item.value"
|
||
></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-form>
|
||
</el-col>
|
||
<el-col :xs="24" :sm="12" :md="6" class="mb8">
|
||
<el-button
|
||
type="primary"
|
||
icon="Check"
|
||
@click="handleBatchExecute()"
|
||
:disabled="isMultiple"
|
||
>
|
||
批量执行
|
||
</el-button>
|
||
<el-button
|
||
type="danger"
|
||
icon="Delete"
|
||
@click="handleBatchCancel()"
|
||
:disabled="isMultiple"
|
||
>
|
||
批量取消
|
||
</el-button>
|
||
</el-col>
|
||
</el-row>
|
||
<div class="cards-column">
|
||
<el-card class="half-card">
|
||
<template #header>处置项目</template>
|
||
<el-table
|
||
:data="activityList"
|
||
ref="activityListRef"
|
||
style="width: 100%; height: 100%"
|
||
border
|
||
v-loading="loading"
|
||
:span-method="operationSpanMethod"
|
||
@select="handleSelectionChange"
|
||
>
|
||
<el-table-column type="selection" align="center" width="50" />
|
||
<el-table-column label="组" align="center" width="40" prop="groupIcon" />
|
||
<!-- <el-table-column label="序号" align="center" prop="sortNumber" width="60" /> -->
|
||
<el-table-column align="center" prop="busNo" label="项目编号" width="150" />
|
||
<el-table-column align="center" prop="itemName" label="项目名称" />
|
||
<el-table-column
|
||
align="center"
|
||
prop="serviceStatus_enumText"
|
||
label="状态"
|
||
width="100"
|
||
>
|
||
<template #default="{ row }">
|
||
<el-tag type="primary" size="small">
|
||
{{
|
||
row.serviceStatus_enumText
|
||
? row.serviceStatus_enumText
|
||
: row.chargeStatus_enumText
|
||
}}
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
align="center"
|
||
prop="serviceCategory_dictText"
|
||
label="项目类型"
|
||
width="80"
|
||
>
|
||
<template #default="scope">
|
||
{{
|
||
scope.row.medCategory
|
||
? scope.row.medCategory_dictText
|
||
: scope.row.serviceCategory_dictText
|
||
}}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column align="center" prop="size" label="数量" width="100">
|
||
<template #default="scope">
|
||
<span v-if="scope.row.quantity !== 0 && scope.row.unitCode_dictText">
|
||
{{ scope.row.quantity + ' ' + scope.row.unitCode_dictText }}
|
||
</span>
|
||
<span v-else> - </span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column align="center" prop="size" label="规格" width="100" />
|
||
<el-table-column align="center" prop="executeNum" label="执行次数" width="90" />
|
||
<el-table-column align="center" label="已执行次数" width="120">
|
||
<template #default="scope">
|
||
{{ scope.row.performCount - scope.row.cancelCount }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
align="right"
|
||
header-align="center"
|
||
prop="unitPrice"
|
||
label="单价"
|
||
width="90"
|
||
>
|
||
<template #default="scope">
|
||
<span>
|
||
{{
|
||
scope.row.unitPrice ? scope.row.unitPrice.toFixed(2) + ' 元' : '0.00' + ' 元'
|
||
}}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
align="right"
|
||
header-align="center"
|
||
prop="totalPrice"
|
||
label="总价"
|
||
width="90"
|
||
>
|
||
<template #default="scope">
|
||
<span>
|
||
{{
|
||
scope.row.totalPrice
|
||
? scope.row.totalPrice.toFixed(2) + ' 元'
|
||
: '0.00' + ' 元'
|
||
}}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column
|
||
label="操作"
|
||
align="center"
|
||
width="150"
|
||
fixed="right"
|
||
class-name="no-hover-column"
|
||
>
|
||
<template #default="{ row }">
|
||
<!-- <el-button type="text" @click="handleExecute(row)"> 执行 </el-button> -->
|
||
<!-- <el-button type="danger" link @click="handleCancel(row)"> 取消 </el-button> -->
|
||
<el-button link type="primary" icon="EditPen" @click="getRecord(row)">
|
||
执行记录
|
||
</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</el-card>
|
||
<el-card class="half-card">
|
||
<template #header> 耗材使用 </template>
|
||
<el-table
|
||
:data="deviceList"
|
||
style="width: 100%; height: 100%"
|
||
ref="deviceListRef"
|
||
v-loading="loading"
|
||
border
|
||
>
|
||
<el-table-column type="selection" align="center" width="50" />
|
||
<el-table-column type="index" label="序号" align="center" width="60" />
|
||
<el-table-column prop="itemName" align="center" label="耗材名称" />
|
||
<el-table-column align="center" prop="serviceStatus_enumText" label="状态">
|
||
<template #default="{ row }">
|
||
<el-tag type="primary" size="small">
|
||
{{ row.dispenseStatus_enumText }}
|
||
</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="size" align="center" label="规格" />
|
||
<el-table-column prop="quantity" align="center" label="使用数量">
|
||
<template #default="scope">
|
||
<span>{{ scope.row.quantity + ' ' + scope.row.unitCode_dictText }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column align="center" header-align="center" prop="unitPrice" label="单价">
|
||
<template #default="{ row }">
|
||
<span>
|
||
{{ row.unitPrice ? row.unitPrice.toFixed(2) : '0.00' + ' 元' }}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column align="center" header-align="center" prop="totalPrice" label="总价">
|
||
<template #default="{ row }">
|
||
<span>
|
||
{{ row.totalPrice ? row.totalPrice.toFixed(2) : '0.00' + ' 元' }}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</el-card>
|
||
</div>
|
||
</el-col>
|
||
</el-row>
|
||
<PerformRecordDialog :open="openDialog" :recordList="recordList" @close="openDialog = false" />
|
||
<PrescriptionInfo
|
||
:open="openPrescriptionDialog"
|
||
:precriptionInfo="prescriptionInfo"
|
||
@close="openPrescriptionDialog = false"
|
||
/>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import {computed, getCurrentInstance, ref} from 'vue';
|
||
import {
|
||
cancel,
|
||
execute,
|
||
getDisposalList,
|
||
getEnPrescriptionInfo,
|
||
getList,
|
||
getPerformRecord,
|
||
printBloodCode,
|
||
} from './components/api';
|
||
import PerformRecordDialog from './components/performRecordDialog';
|
||
import PrescriptionInfo from '../../doctorstation/components/prescription/prescriptionInfo.vue';
|
||
import prescriptionTemplate from './components/prescriptionTemplate.json';
|
||
import bloodTemplate from './components/bloodTemplate.json';
|
||
import disposalTemplate from './components/disposalTemplate.json';
|
||
import {advicePrint, getAdjustPriceSwitchState, lotNumberMatch} from '@/api/public';
|
||
import {formatDateStr} from '@/utils';
|
||
import {hiprint} from 'vue-plugin-hiprint';
|
||
import useUserStore from '@/store/modules/user';
|
||
import {getGroupMarkers} from '@/utils/his';
|
||
|
||
import {PRINT_TEMPLATE, simplePrint} from '@/utils/printUtils.js';
|
||
import {ElMessage} from "element-plus";
|
||
// 患者搜索
|
||
const queryParams = ref({
|
||
pageNo: 1,
|
||
pageSize: 10,
|
||
});
|
||
const receptionTime = ref([
|
||
formatDateStr(new Date(), 'YYYY-MM-DD'),
|
||
formatDateStr(new Date(), 'YYYY-MM-DD'),
|
||
]);
|
||
|
||
const openPrescriptionDialog = ref(false);
|
||
const prescriptionInfo = ref([]);
|
||
|
||
const total = ref(0);
|
||
// 患者数据
|
||
const patientList = ref([]);
|
||
// 处置项目列表
|
||
const activityList = ref([]);
|
||
// 耗材列表
|
||
const deviceList = ref([]);
|
||
// 诊疗项目 + 耗材 打印处置单用
|
||
const deviceActivityList = ref([]);
|
||
const userStore = useUserStore();
|
||
const { proxy } = getCurrentInstance();
|
||
|
||
// 当前选中的患者
|
||
const currentPatient = ref({});
|
||
const recordList = ref([]);
|
||
const openDialog = ref(false);
|
||
const loading = ref(false);
|
||
const activityListRef = ref(null);
|
||
const deviceListRef = ref(null);
|
||
const rules = ref({
|
||
serviceCategory: [{ required: true, message: '请选择处置类型', trigger: 'blur' }],
|
||
});
|
||
//
|
||
const { activity_category_code } = proxy.useDict('activity_category_code');
|
||
const activityCategoryList = computed(() => {
|
||
const keywords = ['检验', '检查', '治疗'];
|
||
return (activity_category_code.value || []).filter((item) =>
|
||
keywords.some((k) => String(item.label || '').includes(k))
|
||
);
|
||
});
|
||
const activitySelectedList = ref([]);
|
||
const deviceSelectedList = ref([]);
|
||
// 是否有批量选择:无任何选择时禁用
|
||
const isMultiple = computed(() => {
|
||
// 未选择患者或为空对象时禁用
|
||
if (!currentPatient.value || Object.keys(currentPatient.value).length === 0) {
|
||
return true;
|
||
}
|
||
// 选中 处置列表
|
||
activitySelectedList.value = activityListRef.value?.getSelectionRows
|
||
? activityListRef.value.getSelectionRows()
|
||
: [];
|
||
|
||
// 选中 耗材列表
|
||
deviceSelectedList.value = deviceListRef.value?.getSelectionRows
|
||
? deviceListRef.value.getSelectionRows()
|
||
: [];
|
||
return deviceSelectedList.value.length === 0 && activitySelectedList.value.length === 0;
|
||
});
|
||
// 是否为当前患者
|
||
const isCurrentPatient = computed(() => {
|
||
return Object.keys(currentPatient.value).length === 0;
|
||
});
|
||
getPatientList();
|
||
function getPatientList() {
|
||
queryParams.value.receptionTimeSTime = receptionTime.value[0] + ' 00:00:00';
|
||
queryParams.value.receptionTimeETime = receptionTime.value[1] + ' 23:59:59';
|
||
getList(queryParams.value).then((res) => {
|
||
patientList.value = res.data.records;
|
||
total.value = res.data.total;
|
||
});
|
||
}
|
||
// 切换处置类型
|
||
function handleServiceCategoryChange(value) {
|
||
// 就诊id
|
||
let encounterId = currentPatient.value.encounterId;
|
||
// 处置类型
|
||
let serviceCategory = value;
|
||
// 如果就诊id和处置类型不为空,则获取处置列表
|
||
if (encounterId && serviceCategory) {
|
||
getDisposalList(encounterId, serviceCategory).then((res) => {
|
||
deviceList.value = res.data.records.filter((item) => {
|
||
return item.requestTable == 'wor_device_request';
|
||
});
|
||
activityList.value = res.data.records.filter((item) => {
|
||
return (
|
||
item.requestTable == 'wor_service_request' ||
|
||
item.requestTable == 'med_medication_request'
|
||
);
|
||
});
|
||
deviceActivityList.value = res.data.records.filter((item) => {
|
||
return item.deviceCategory == '7' || item.serviceCategory == '21';
|
||
});
|
||
});
|
||
}
|
||
}
|
||
|
||
function handlePatientSelect(row) {
|
||
loading.value = true;
|
||
currentPatient.value = row;
|
||
getAdjustPriceSwitchState().then((res) => {
|
||
if (res.data) {
|
||
lotNumberMatch({ encounterIdList: row.encounterId }).then(() => {
|
||
getAllList(row);
|
||
});
|
||
} else {
|
||
getAllList(row);
|
||
}
|
||
});
|
||
}
|
||
|
||
function getAllList(row) {
|
||
getDisposalList(row.encounterId).then((res) => {
|
||
deviceList.value = res.data.records.filter((item) => {
|
||
return item.requestTable == 'wor_device_request';
|
||
});
|
||
console.log('耗材列表=====>', JSON.stringify(deviceList.value));
|
||
activityList.value = res.data.records.filter((item) => {
|
||
return (
|
||
item.requestTable == 'wor_service_request' || item.requestTable == 'med_medication_request'
|
||
);
|
||
});
|
||
activityList.value = getGroupMarkers(activityList.value);
|
||
deviceActivityList.value = res.data.records.filter((item) => {
|
||
console.info('item=====>', JSON.stringify(item));
|
||
return item.deviceCategory == '7' || item.serviceCategory == '21';
|
||
});
|
||
loading.value = false;
|
||
});
|
||
}
|
||
// 批量操作校验
|
||
function handleBatchValidate(type) {
|
||
let params = [];
|
||
// 是否批量选择了数据
|
||
if (isMultiple.value) {
|
||
proxy.$modal.msgError('请选择要执行的项目');
|
||
return;
|
||
}
|
||
if (type === 'execute') {
|
||
let activityList = activitySelectedList.value
|
||
.filter((item) => {
|
||
return item.chargeStatus === 5;
|
||
})
|
||
.map((item) => {
|
||
return {
|
||
requestId: item.requestId,
|
||
dispenseId: item.dispenseId,
|
||
requestTable: item.requestTable,
|
||
chargeStatus: item.chargeStatus_enumText,
|
||
dispenseStatus: item.dispenseStatus_enumText,
|
||
name: item.itemName,
|
||
};
|
||
});
|
||
let deviceList = deviceSelectedList.value
|
||
.filter((item) => {
|
||
return item.dispenseStatus === 2;
|
||
})
|
||
.map((item) => {
|
||
return {
|
||
requestId: item.requestId,
|
||
dispenseId: item.dispenseId,
|
||
requestTable: item.requestTable,
|
||
chargeStatus: item.chargeStatus_enumText,
|
||
dispenseStatus: item.dispenseStatus_enumText,
|
||
name: item.itemName,
|
||
};
|
||
});
|
||
|
||
return [...activityList, ...deviceList];
|
||
} else if (type === 'cancel') {
|
||
let list = [...activitySelectedList.value, ...deviceSelectedList.value];
|
||
list.forEach((item) => {
|
||
params.push({
|
||
requestId: item.requestId,
|
||
dispenseId: item.dispenseId,
|
||
requestTable: item.requestTable,
|
||
});
|
||
});
|
||
return list;
|
||
}
|
||
}
|
||
// 批量执行
|
||
function handleBatchExecute() {
|
||
// 获取校验后数据
|
||
let params = handleBatchValidate('execute');
|
||
// 如果参数数组为空 不执行
|
||
if (params.length == 0) {
|
||
proxy.$modal.msgError('不存在需要执行的处置或耗材!');
|
||
return;
|
||
}
|
||
// 执行批量操作
|
||
execute(params).then((res) => {
|
||
if (res.code == 200) {
|
||
proxy.$modal.msgSuccess('执行成功');
|
||
handlePatientSelect(currentPatient.value);
|
||
} else {
|
||
proxy.$modal.msgError(res.message);
|
||
}
|
||
});
|
||
}
|
||
// 单个执行
|
||
function handleExecute(row) {
|
||
let data = {
|
||
requestId: row.requestId,
|
||
dispenseId: row.dispenseId,
|
||
requestTable: row.requestTable,
|
||
};
|
||
let params = activityList.value
|
||
.filter((item) => {
|
||
return (
|
||
(item.medCategory != null || item.medCategory != undefined) && item.groupId == row.groupId
|
||
);
|
||
})
|
||
.map((item) => {
|
||
return {
|
||
requestId: item.requestId,
|
||
dispenseId: item.dispenseId,
|
||
requestTable: item.requestTable,
|
||
};
|
||
});
|
||
let list = (
|
||
deviceListRef.value?.getSelectionRows ? deviceListRef.value.getSelectionRows() : []
|
||
).map((item) => {
|
||
return {
|
||
requestId: item.requestId,
|
||
dispenseId: item.dispenseId,
|
||
requestTable: item.requestTable,
|
||
};
|
||
});
|
||
params.push(...list);
|
||
execute(params).then((res) => {
|
||
if (res.code == 200) {
|
||
proxy.$modal.msgSuccess('执行成功');
|
||
handlePatientSelect(row);
|
||
} else {
|
||
proxy.$modal.msgError(res.message);
|
||
}
|
||
});
|
||
}
|
||
|
||
// 添加操作列的合并方法
|
||
function operationSpanMethod({ row, column, rowIndex, columnIndex }) {
|
||
// 操作列是最后一列,索引为11 (从0开始)
|
||
if (columnIndex === 12) {
|
||
const groupId = row.groupId;
|
||
// 如果没有groupId,则不合并
|
||
if (groupId === undefined || groupId === null) {
|
||
return [1, 1];
|
||
}
|
||
|
||
// 向上查找相同groupId的行,如果找到则隐藏当前行
|
||
for (let i = rowIndex - 1; i >= 0; i--) {
|
||
if (activityList.value[i].groupId === groupId) {
|
||
return [0, 0]; // 隐藏被合并的行
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 向下统计相同groupId的行数
|
||
let spanCount = 1;
|
||
for (let i = rowIndex + 1; i < activityList.value.length; i++) {
|
||
if (activityList.value[i].groupId === groupId) {
|
||
spanCount++;
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
|
||
return [spanCount, 1];
|
||
}
|
||
return [1, 1];
|
||
}
|
||
|
||
// 打印处方
|
||
function printPrescription() {
|
||
// 取出状态为已收费已发药的requestId
|
||
let requestIds = activityList.value
|
||
.filter((item) => {
|
||
return item.chargeStatus == 5 && item.dispenseStatus == 4;
|
||
})
|
||
.map((item) => {
|
||
return item.requestId;
|
||
})
|
||
.join(',');
|
||
if (requestIds.length == 0) {
|
||
proxy.$modal.msgWarning('没有可打印的处方!');
|
||
return;
|
||
}
|
||
advicePrint({ requestIds: requestIds, isPrescription: 1 }).then((res) => {
|
||
// 按 sortNumber 排序
|
||
const sortedList = res.data.adviceItemList.sort((a, b) => {
|
||
return (a.sortNumber || 0) - (b.sortNumber || 0);
|
||
});
|
||
|
||
// 为每个项目分配新的排序号,相同 groupId 的项目使用相同排序号
|
||
const groupIdToSortNumber = new Map();
|
||
let group = 1;
|
||
|
||
sortedList.forEach((item) => {
|
||
if (item.dispensePerDuration > 1) {
|
||
item.quantity = item.quantity / item.dispensePerDurations;
|
||
item.totalPrice = item.quantity * item.unitPrice;
|
||
}
|
||
item.contractName = res.data.contractName;
|
||
if (item.groupId) {
|
||
if (!groupIdToSortNumber.has(item.groupId)) {
|
||
groupIdToSortNumber.set(item.groupId, group++);
|
||
}
|
||
item.group = groupIdToSortNumber.get(item.groupId);
|
||
} else {
|
||
item.group = group++;
|
||
}
|
||
});
|
||
console.log('sortedList', sortedList);
|
||
|
||
const result = {
|
||
...res.data,
|
||
prescriptionList: sortedList,
|
||
};
|
||
// 将对象转换为 JSON 字符串
|
||
console.log(result, 'result');
|
||
// 模板对象获取
|
||
const printElements = JSON.parse(
|
||
JSON.stringify(prescriptionTemplate).replace(/{{HOSPITAL_NAME}}/g, userStore.hospitalName)
|
||
);
|
||
var hiprintTemplate = new hiprint.PrintTemplate({ template: printElements }); // 定义模板
|
||
hiprintTemplate.print2(result, {
|
||
title: '打印标题',
|
||
height: 210,
|
||
width: 148,
|
||
}); //开始打印
|
||
});
|
||
}
|
||
// 查看本次就诊处方单
|
||
function getEnPrescription() {
|
||
getEnPrescriptionInfo({ encounterId: currentPatient.value.encounterId }).then((res) => {
|
||
console.log('处方单 res', res);
|
||
let dataArr = res.data.records || [];
|
||
if (dataArr.length <= 0) {
|
||
ElMessage({
|
||
type: 'error',
|
||
message: '暂无处方单',
|
||
});
|
||
return;
|
||
}
|
||
prescriptionInfo.value = res.data.records;
|
||
openPrescriptionDialog.value = true;
|
||
});
|
||
}
|
||
|
||
// 打印处置单
|
||
function printDisposal() {
|
||
let requestIds = deviceActivityList.value && deviceActivityList.value.length > 0
|
||
? deviceActivityList.value
|
||
.map((item) => {
|
||
return item.requestId;
|
||
})
|
||
.join(',') : '';
|
||
if (requestIds !== '') {
|
||
advicePrint({ requestIds: requestIds }).then((res) => {
|
||
const result = res.data;
|
||
const printElements = JSON.parse(
|
||
JSON.stringify(disposalTemplate).replace(/{{HOSPITAL_NAME}}/g, userStore.hospitalName)
|
||
);
|
||
var hiprintTemplate = new hiprint.PrintTemplate({ template: printElements }); // 定义模板
|
||
hiprintTemplate.print2(result, {
|
||
height: 210,
|
||
width: 148,
|
||
});
|
||
});
|
||
} else {
|
||
ElMessage({
|
||
type: 'error',
|
||
message: '暂无处置单',
|
||
});
|
||
}
|
||
|
||
}
|
||
|
||
// 判断是否为组内的第一行
|
||
function isFirstRowInGroup(rowIndex) {
|
||
const row = activityList.value[rowIndex];
|
||
const groupId = row.groupId;
|
||
|
||
// 如果没有groupId,每行都显示操作按钮
|
||
if (groupId === undefined || groupId === null) {
|
||
return true;
|
||
}
|
||
|
||
// 检查是否为该groupId的第一行
|
||
for (let i = rowIndex - 1; i >= 0; i--) {
|
||
if (activityList.value[i].groupId === groupId) {
|
||
return false;
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
// 打印血条码
|
||
function printBloodBarcode() {
|
||
const selectedRows = activityListRef.value.getSelectionRows();
|
||
if (selectedRows.length === 0) {
|
||
proxy.$modal.msgWarning('未选择要打印的项目');
|
||
} else if (selectedRows.length > 1) {
|
||
proxy.$modal.msgWarning('只能选择一个项目');
|
||
} else {
|
||
printBloodCode({ requestId: selectedRows[0].requestId }).then((res) => {
|
||
const result = res.data;
|
||
const printElements = JSON.parse(
|
||
JSON.stringify(bloodTemplate).replace(/{{HOSPITAL_NAME}}/g, userStore.hospitalName)
|
||
);
|
||
var hiprintTemplate = new hiprint.PrintTemplate({ template: printElements }); // 定义模板
|
||
hiprintTemplate.print2(result, {
|
||
height: 210,
|
||
width: 148,
|
||
});
|
||
});
|
||
}
|
||
}
|
||
|
||
// 批量取消
|
||
function handleBatchCancel() {
|
||
// 获取校验后数据
|
||
let params = handleBatchValidate('cancel');
|
||
|
||
// 如果参数数组为空 不执行
|
||
if (params.length == 0) {
|
||
proxy.$modal.msgError('不存在需要执行的处置或耗材!');
|
||
return;
|
||
}
|
||
//
|
||
cancel(params).then((res) => {
|
||
if (res.code == 200) {
|
||
proxy.$modal.msgSuccess('操作成功');
|
||
handlePatientSelect(currentPatient.value);
|
||
} else {
|
||
proxy.$modal.msgError(res.message);
|
||
}
|
||
});
|
||
}
|
||
// 单个取消
|
||
function handleCancel(row) {
|
||
let data = {
|
||
requestId: row.requestId,
|
||
dispenseId: row.dispenseId,
|
||
requestTable: row.requestTable,
|
||
};
|
||
let params = activityList.value
|
||
.filter((item) => {
|
||
return item.groupId == row.groupId;
|
||
})
|
||
.map((item) => {
|
||
return {
|
||
requestId: item.requestId,
|
||
dispenseId: item.dispenseId,
|
||
requestTable: item.requestTable,
|
||
};
|
||
});
|
||
cancel(params).then((res) => {
|
||
if (res.code == 200) {
|
||
proxy.$modal.msgSuccess('操作成功');
|
||
handlePatientSelect(row);
|
||
} else {
|
||
proxy.$modal.msgError(res.message);
|
||
}
|
||
});
|
||
}
|
||
// 打印瓶贴
|
||
// function printBottleLabel() {
|
||
// let result = [];
|
||
// // 过滤出全部输液药品
|
||
// let selectRows = activityListRef.value.getSelectionRows();
|
||
// let printLiist = [];
|
||
// // 有选中的优先打印选中行,没有的话打印全部的输液药品
|
||
// if (selectRows.length > 0) {
|
||
// printLiist = selectRows.filter((item) => {
|
||
// return item.medCategory == '2' || item.medCategory == '1';
|
||
// });
|
||
// } else {
|
||
// printLiist = activityList.value.filter((item) => {
|
||
// return item.medCategory == '2' || item.medCategory == '1';
|
||
// });
|
||
// }
|
||
// // 按照groupId分组,但将多天的项目展开为独立项目
|
||
// let expandedList = [];
|
||
|
||
// printLiist.forEach((item) => {
|
||
// // 如果用药天数大于1,则创建多个项目
|
||
// if (item.dispensePerDuration && item.dispensePerDuration > 1) {
|
||
// // 为每一天创建一个项目
|
||
// for (let i = 0; i < item.dispensePerDuration; i++) {
|
||
// // 克隆项目并调整数量
|
||
// const clonedItem = {
|
||
// ...item,
|
||
// // 数量除以天数
|
||
// quantity: item.quantity ? item.quantity / item.dispensePerDuration : item.quantity,
|
||
// // 可以添加一个字段表示是第几天
|
||
// dayIndex: i + 1,
|
||
// totalDays: item.dispensePerDuration,
|
||
// data: item.itemName + ' ' + item.size + ' ' + item.methodCode_dictText,
|
||
// };
|
||
|
||
// // 获取当前时间做执行日期,如果用药天数大于1,依次累加
|
||
// const date = new Date();
|
||
// date.setDate(date.getDate() + i);
|
||
// clonedItem.performDateTime = formatDateStr(date, 'YYYY-MM-DD');
|
||
|
||
// // 将克隆的项目添加到展开列表中,不按groupId分组
|
||
// expandedList.push(clonedItem);
|
||
// }
|
||
// } else {
|
||
// // 天数为1或没有设置天数,直接使用原项目
|
||
// item.data = item.itemName + ' ' + item.size + ' ' + item.methodCode_dictText;
|
||
// expandedList.push(item);
|
||
// }
|
||
// });
|
||
|
||
// // 重新按groupId分组,但每个展开的项目都是独立的
|
||
// const groupedByGroupId = expandedList.reduce((acc, item) => {
|
||
// // 为展开的项目生成新的唯一groupId
|
||
// const groupId = item.dayIndex
|
||
// ? `${item.groupId || item.requestId}_day${item.dayIndex}`
|
||
// : item.groupId || item.requestId;
|
||
|
||
// if (!acc[groupId]) {
|
||
// acc[groupId] = [];
|
||
// }
|
||
// acc[groupId].push(item);
|
||
// return acc;
|
||
// }, {});
|
||
// const resultList = Object.values(groupedByGroupId);
|
||
// console.log(resultList, '23456789');
|
||
|
||
// result = resultList.map((item) => {
|
||
// return {
|
||
// patientName: currentPatient.value.patientName,
|
||
// prepareName: userStore.nickName,
|
||
// genderEnum_enumText: currentPatient.value.genderEnum_enumText,
|
||
// age: currentPatient.value.age,
|
||
// date: item[0].performDateTime,
|
||
// infuseData: item,
|
||
// };
|
||
// });
|
||
// const printElements = templateJson;
|
||
// var hiprintTemplate = new hiprint.PrintTemplate({ template: printElements }); // 定义模板
|
||
// console.log(result, '打印机列表');
|
||
// hiprintTemplate.print2(result, {
|
||
// // printer: 'Xprinter XP-365B',
|
||
// height: 210,
|
||
// width: 148,
|
||
// });
|
||
// // 直接打印回调
|
||
// // 发送任务到打印机成功
|
||
// hiprintTemplate.on('printSuccess', function (e) {
|
||
// console.log('打印成功');
|
||
// });
|
||
// // 发送任务到打印机失败
|
||
// hiprintTemplate.on('printError', function (e) {
|
||
// console.log('打印失败');
|
||
// });
|
||
// }
|
||
async function printBottleLabel() {
|
||
let result = [];
|
||
// 过滤出全部输液药品
|
||
let selectRows = activityListRef.value.getSelectionRows();
|
||
let printLiist = [];
|
||
// 有选中的优先打印选中行,没有的话打印全部的输液药品
|
||
if (selectRows.length > 0) {
|
||
printLiist = selectRows.filter((item) => {
|
||
return item.medCategory == '2' || item.medCategory == '1';
|
||
});
|
||
} else {
|
||
printLiist = activityList.value.filter((item) => {
|
||
return item.medCategory == '2' || item.medCategory == '1';
|
||
});
|
||
}
|
||
// 按照groupId分组,但将多天的项目展开为独立项目
|
||
let expandedList = [];
|
||
|
||
printLiist.forEach((item) => {
|
||
// 如果用药天数大于1,则创建多个项目
|
||
if (item.dispensePerDuration && item.dispensePerDuration > 1) {
|
||
// 为每一天创建一个项目
|
||
for (let i = 0; i < item.dispensePerDuration; i++) {
|
||
// 克隆项目并调整数量
|
||
const clonedItem = {
|
||
...item,
|
||
// 数量除以天数
|
||
quantity: item.quantity ? item.quantity / item.dispensePerDuration : item.quantity,
|
||
// 可以添加一个字段表示是第几天
|
||
dayIndex: i + 1,
|
||
totalDays: item.dispensePerDuration,
|
||
data: item.itemName + ' ' + item.size + ' ' + item.methodCode_dictText,
|
||
};
|
||
|
||
// 获取当前时间做执行日期,如果用药天数大于1,依次累加
|
||
const date = new Date();
|
||
date.setDate(date.getDate() + i);
|
||
clonedItem.performDateTime = formatDateStr(date, 'YYYY-MM-DD');
|
||
|
||
// 将克隆的项目添加到展开列表中,不按groupId分组
|
||
expandedList.push(clonedItem);
|
||
}
|
||
} else {
|
||
// 天数为1或没有设置天数,直接使用原项目
|
||
item.data = item.itemName + ' ' + item.size + ' ' + item.methodCode_dictText;
|
||
expandedList.push(item);
|
||
//将当前时间传到expandedList中
|
||
const date = new Date();
|
||
item.performDateTime = formatDateStr(date, 'YYYY-MM-DD');
|
||
}
|
||
});
|
||
|
||
// 重新按groupId分组,但每个展开的项目都是独立的
|
||
const groupedByGroupId = expandedList.reduce((acc, item) => {
|
||
// 为展开的项目生成新的唯一groupId
|
||
const groupId = item.dayIndex
|
||
? `${item.groupId || item.requestId}_day${item.dayIndex}`
|
||
: item.groupId || item.requestId;
|
||
|
||
if (!acc[groupId]) {
|
||
acc[groupId] = [];
|
||
}
|
||
acc[groupId].push(item);
|
||
return acc;
|
||
}, {});
|
||
const resultList = Object.values(groupedByGroupId);
|
||
console.log(resultList, '23456789');
|
||
|
||
result = resultList.map((item) => {
|
||
console.log(item, '111323item');
|
||
return {
|
||
patientName: currentPatient.value.patientName,
|
||
prepareName: userStore.nickName,
|
||
genderEnum_enumText: currentPatient.value.genderEnum_enumText,
|
||
age: currentPatient.value.age,
|
||
date: item[0].performDateTime,
|
||
infuseData: item,
|
||
};
|
||
});
|
||
console.log(result, '打印数据');
|
||
await simplePrint(PRINT_TEMPLATE.OUTPATIENT_INFUSION, result);
|
||
// console.log('打印成功');
|
||
// const printElements = templateJson;
|
||
// var hiprintTemplate = new hiprint.PrintTemplate({ template: printElements }); // 定义模板
|
||
// console.log(result, '打印机列表');
|
||
// hiprintTemplate.print2(result, {
|
||
// height: 210,
|
||
// width: 148,
|
||
// });
|
||
// 直接打印回调
|
||
// 发送任务到打印机成功
|
||
// hiprintTemplate.on('printSuccess', function (e) {
|
||
// console.log('打印成功');
|
||
// });
|
||
// // 发送任务到打印机失败
|
||
// hiprintTemplate.on('printError', function (e) {
|
||
// console.log('打印失败');
|
||
// });
|
||
}
|
||
|
||
// 选择框改变时的处理
|
||
function handleSelectionChange(selection, row) {
|
||
const isSelected = selection.some((item) => item.requestId === row.requestId);
|
||
activityList.value
|
||
.filter((item) => {
|
||
return item.groupId && item.groupId == row?.groupId;
|
||
})
|
||
.forEach((item) => {
|
||
activityListRef.value.toggleRowSelection(item, isSelected);
|
||
});
|
||
}
|
||
|
||
function getRecord(row) {
|
||
getPerformRecord({ reqId: row.requestId }).then((res) => {
|
||
recordList.value = res.data;
|
||
openDialog.value = true;
|
||
});
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.his-container {
|
||
height: 90vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
background-color: #f0f2f5;
|
||
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', Arial, sans-serif;
|
||
padding: 20px;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.right-section {
|
||
flex: 2;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 20px;
|
||
min-width: 600px;
|
||
}
|
||
|
||
.cards-column {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 12px;
|
||
height: calc(90vh - 140px);
|
||
min-height: 300px;
|
||
}
|
||
|
||
.half-card {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
min-height: 0;
|
||
}
|
||
|
||
.half-card :deep(.el-card__body) {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
min-height: 0;
|
||
}
|
||
|
||
.current-patient {
|
||
background: white;
|
||
border-radius: 12px;
|
||
padding: 20px;
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
|
||
.patient-info {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 15px;
|
||
}
|
||
|
||
.patient-avatar {
|
||
background: #e6f7ff;
|
||
border-radius: 50%;
|
||
padding: 5px;
|
||
}
|
||
|
||
.patient-details {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.patient-name {
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
color: #333;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.patient-gender,
|
||
.patient-age {
|
||
margin-left: 10px;
|
||
font-size: 16px;
|
||
color: #666;
|
||
font-weight: normal;
|
||
}
|
||
|
||
.patient-meta {
|
||
display: flex;
|
||
gap: 20px;
|
||
}
|
||
|
||
.meta-item {
|
||
display: flex;
|
||
align-items: center;
|
||
color: #666;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.meta-item i {
|
||
margin-right: 5px;
|
||
color: #1890ff;
|
||
}
|
||
|
||
.patient-status {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-end;
|
||
gap: 10px;
|
||
}
|
||
|
||
.total-cost {
|
||
display: flex;
|
||
align-items: center;
|
||
font-size: 14px;
|
||
color: #666;
|
||
}
|
||
|
||
.cost-value {
|
||
font-weight: 600;
|
||
color: #e53935;
|
||
font-size: 20px;
|
||
margin-left: 10px;
|
||
}
|
||
|
||
.treatment-section,
|
||
.material-section {
|
||
background: white;
|
||
border-radius: 12px;
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
|
||
padding: 20px 10px 5px 10px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
overflow: hidden;
|
||
flex: 1;
|
||
}
|
||
|
||
.section-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.section-title {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
|
||
.section-title h2 {
|
||
margin: 0;
|
||
font-size: 18px;
|
||
color: #333;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.section-title i {
|
||
font-size: 20px;
|
||
color: #1890ff;
|
||
}
|
||
|
||
.search-area {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
|
||
.search-input {
|
||
width: 200px;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
:deep(.no-hover-column) .cell:hover {
|
||
background-color: transparent !important;
|
||
}
|
||
|
||
:deep(.el-table__body) tr:hover td.no-hover-column {
|
||
background-color: inherit !important;
|
||
}
|
||
</style>
|