临床发血退血

This commit is contained in:
wuyy 2026-09-04 18:08:45 +08:00
parent 163cfda204
commit 2e00ada8cd
6 changed files with 544 additions and 65 deletions

View File

@ -298,6 +298,24 @@ export function printReport(query?: Object) {
params: query
})
}
// 临床发血获取血液信息
export function queryBloodInfo(query?: Object) {
return request({
url: '/bus/bloodbank/backin/queryBloodInfo',
method: 'get',
params: query
})
}
// 临床发血退血保存数据
export function txsaveData(query?: Object) {
return request({
url: '/bus/bloodbank/backin/saveData',
method: 'post',
data: query
})
}

View File

@ -157,4 +157,18 @@ export function useAutoSize() {
});
return autoSize;
}
/**
* 字节转 MB,保留n位小数
* @param size 字节 string|number
* @param digits 保留小数,默认2
* @returns {string} "0.03 MB"
*/
export function formatByteToMB(size: string | number, digits = 2): string {
const byte = Number(size)
if (isNaN(byte) || byte <= 0) return '0 MB'
const mb = byte / 1024 / 1024
return `${mb.toFixed(digits)} MB`
}

View File

@ -388,7 +388,8 @@
</el-row>
</el-form>
<el-table :data="matchTableData" border height="450" @row-click="dcRowclick" highlight-current-row>
<el-table :data="matchTableData" border height="450" @row-click="dcRowclick" highlight-current-row
show-overflow-tooltip>
<el-table-column prop="apply_no" label="申请单号" align="center" />
<el-table-column prop="dept_id" label="科室" align="center">
<template #default="scope">
@ -398,7 +399,7 @@
<el-table-column prop="patient_bed" label="床号" align="center" />
<el-table-column prop="patient_name" label="患者姓名" align="center" />
<el-table-column prop="beinhos_id" label="住院号/ID号" align="center" />
<el-table-column prop="blood_breed" label="血液品种" align="center">
<el-table-column prop="blood_breed" label="血液品种" align="center" width="200">
<template #default="{ row }">
{{bloodBreed.find(v => v.value == row.blood_breed)?.label || row.blood_breed}}
</template>

View File

@ -0,0 +1,424 @@
/**
* @file index.vue
* @description: 临床发血退血
* @author: w
* @since: 2026-09-04
*/
<template>
<div class="box-container">
<div class="card-box toolbar">
<el-button type="primary" plain @click="searchHandle">检索</el-button>
<el-button type="primary" plain @click="addHandle">新增单据</el-button>
<el-button type="success" plain :loading="saveLoading" @click="saveHandle">保存</el-button>
<el-button type="primary" plain @click="auditHandle">审核</el-button>
<el-button type="warning" plain @click="printHandle">打印</el-button>
</div>
<el-form :model="formData" label-width="auto" class="retreat-form">
<div class="card-box retreat-info">
<div class="section-title"> 退血主信息 </div>
<div class="status">未审核</div>
<el-row :gutter="10">
<el-col :span="4">
<el-form-item label="退血单号">
<el-input v-model="formData.bill_no" disabled />
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="经手人">
<SelectTable v-model:data="formData.handle_person" :tableData="userList" placeholder="" />
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="退回日期">
<el-date-picker v-model="formData.back_date" type="datetime" value-format="YYYY-MM-DD HH:mm:ss"
format="YYYY-MM-DD HH:mm:ss" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10">
<el-col :span="12">
<el-form-item label="备注">
<el-input v-model="formData.remark" />
</el-form-item>
</el-col>
</el-row>
</div>
<div class="content-row">
<div class="card-box scan-panel">
<div class="section-title">逐袋扫描</div>
<el-form-item label="血液流水号">
<el-input v-model="bloodInfo.blood_no" @keyup.enter="scanHandle" />
</el-form-item>
<el-form-item label="产品码">
<el-input v-model="bloodInfo.product_no" disabled />
</el-form-item>
<el-form-item label="血液品种">
<el-input v-model="bloodInfo.blood_breed" disabled />
</el-form-item>
<el-form-item label="血型">
<el-input v-model="bloodInfo.blood_type" disabled />
</el-form-item>
<el-form-item label="容量">
<div class="capacity-fields">
<el-input v-model="bloodInfo.capacity" disabled />
<el-input v-model="bloodInfo.unit" disabled />
</div>
</el-form-item>
<el-form-item label="有效日期">
<el-date-picker v-model="bloodInfo.valid_date" type="datetime" value-format="YYYY-MM-DD HH:mm"
format="YYYY-MM-DD HH:mm" disabled style="width:100%" />
</el-form-item>
<el-form-item label="退血原因">
<el-select v-model="reason" placeholder="请选择退血原因">
<el-option v-for="item in dictData.lctxyy" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</div>
<div class="card-box patient-panel">
<div class="section-title">患者信息</div>
<el-row :gutter="10">
<el-col :span="5">
<el-form-item label="住院号/ID号">
<el-input v-model="patientInfo.beinhos_id" disabled />
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="姓名">
<el-input v-model="patientInfo.patient_name" disabled />
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="性别">
<el-input v-model="patientInfo.patient_sex" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10">
<el-col :span="5">
<el-form-item label="年龄">
<el-input v-model="patientInfo.age" disabled />
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="血型">
<el-input v-model="patientInfo.abo_type" disabled />
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item label="科室">
<el-select v-model="patientInfo.dept_id" placeholder="" disabled>
<el-option v-for="item in dictData.ks" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<div class="table-title">已扫描列表</div>
<el-table :data="scannedList" border height="calc(100% - 130px)" show-overflow-tooltip>
<el-table-column prop="blood_no" label="血液流水号" min-width="140" align="center" />
<el-table-column prop="product_no" label="产品码" min-width="120" align="center" />
<el-table-column prop="blood_breed" label="血液品种" min-width="120" align="center">
<template #default="{ row }">
{{bloodBreed.find(v => v.value == row.blood_breed)?.label || row.blood_breed}}
</template>
</el-table-column>
<el-table-column prop="blood_type" label="血型" width="70" align="center" />
<el-table-column prop="capacity" label="容量" width="80" align="center" />
<el-table-column prop="unit" label="单位" width="60" align="center" />
<el-table-column prop="validDate" label="有效日期" min-width="130" align="center" />
<el-table-column prop="reason" label="退血原因" min-width="120" align="center">
<template #default="{ row }">
{{dictData.lctxyy.find(v => v.value == row.reason)?.label || row.reason}}
</template>
</el-table-column>
</el-table>
</div>
</div>
</el-form>
<el-dialog title="临床发血退血检索" v-model="visible" width="1200px" :close-on-click-modal="false" @closed="handleClose">
<div class="mb10">
<el-button type="primary" @click="handleSearch">检索</el-button>
<el-button type="success" @click="handleConfirm">确认</el-button>
</div>
<!-- 检索条件区 -->
<el-form :model="searchForm" label-width="auto" class="search-form">
<el-row :gutter="10">
<el-col :span="10">
<el-form-item label="检索时间">
<div class="date-range">
<el-date-picker v-model="searchForm.stime" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD"
style="width: 47%" />
<span class="separator">-</span>
<el-date-picker v-model="searchForm.etime" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD"
style="width: 47%" />
</div>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="单号">
<el-input v-model="searchForm.applyNo" placeholder="" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-table :data="tableData" border height="450" @row-click="jsRowclick" @row-dblclick="dblClickRow"
highlight-current-row show-overflow-tooltip>
<el-table-column prop="bill_no" label="出库单号" align="center" />
<el-table-column prop="occur_date" label="退血日期" align="center" width="150" />
<el-table-column prop="handle_person" label="经手人" align="center">
<template #default="scope">
{{userList.find(v => v.value == scope.row.handle_person)?.label || scope.row.handle_person}}
</template>
</el-table-column>
<el-table-column label="总金额" prop="money" align="center" />
<el-table-column prop="beinhos_id" label="住院号/ID号" align="center" width="150" />
<el-table-column label="患者姓名" prop="patient_name" align="center" />
</el-table>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import dayjs from 'dayjs'
import { ElMessage } from 'element-plus'
import { getDictData, formatDict, dictData, useCommonDict } from '@/hooks'
import { getBloodBreed, queryBloodInfoByBloodNo } from '@/api/common'
import { queryBloodInfo, txsaveData } from '@/api/blood'
const { userList, getUserData, getServerTime, bloodBreed, getBloodList, } = useCommonDict()
import useUserStore from '@/store/modules/user'
const userInfo = useUserStore()
const bloodInfo = ref({})
const formData = ref({
handle_person: userInfo.name,
back_date: dayjs().format('YYYY-MM-DD HH:mm:ss'),
})
const reason = ref('')
const patientInfo = ref({})
const saveLoading = ref(false)
const searchForm = ref({
stime: dayjs().format('YYYY-MM-DD'),
etime: dayjs().format('YYYY-MM-DD'),
})
const scannedList = ref<Array<Record<string, string>>>([])
const visible = ref(false)
const searchHandle = () => {
getTxList()
visible.value = true
}
const saveHandle = () => {
const data = {
xkBackinMain: {
...formData.value,
input_person: userInfo.name,
input_date: dayjs().format('YYYY-MM-DD HH:mm:ss'),
},
xkBackinDetailList: scannedList.value
}
saveLoading.value = true
txsaveData(data).then(res => {
if (res.code == 0) {
ElMessage.success("保存成功!")
}
}).finally(() => {
saveLoading.value = false
})
}
const auditHandle = () => {
}
const printHandle = () => {
}
const addHandle = () => {
formData.value = {}
bloodInfo.value = {}
scannedList.value = []
}
const getTxList = () => {
searchForm.value.stime = dayjs(searchForm.value.stime).format('YYYY-MM-DD') + ' 00:00:00'
searchForm.value.etime = dayjs(searchForm.value.etime).format('YYYY-MM-DD') + ' 23:59:59'
}
const handleSearch = () => {
getTxList()
}
const handleConfirm = () => {
if (!searchForm.value.billNo) return ElMessage.warning('请输入退血单号进行检索')
}
const jsRowclick = (row) => {
if (!row) return
getBloodInfo(row)
}
const dblClickRow = (row) => {
if (!row) return
getBloodInfo(row)
visible.value = false
}
const handleClose = () => {
}
const scanHandle = () => {
if (!reason.value) return ElMessage.warning('请选择退血原因')
if (!bloodInfo.value.blood_no) return
queryBloodInfoByBloodNo({ bloodNo: bloodInfo.value.blood_no }).then(res => {
if (res.data.length) {
const row = res.data[0]
getBloodInfo(row)
}
})
}
const getBloodInfo = (row) => {
queryBloodInfo({ bloodNo: row.blood_no, productNo: row.product_no }).then(res => {
bloodInfo.value = res.data.xkBloodInfo || {}
patientInfo.value = res.data.patientInfoList[0] || {}
const row = {
blood_no: bloodInfo.value.blood_no,
product_no: bloodInfo.value.product_no,
blood_breed: bloodInfo.value.blood_breed,
blood_type: bloodInfo.value.blood_type,
capacity: bloodInfo.value.capacity,
unit: bloodInfo.value.unit,
validDate: bloodInfo.value.valid_date,
reason: reason.value,
sid: scannedList.value.length + 1,
}
scannedList.value.push(row)
bloodInfo.value.blood_no = ''
})
}
onMounted(() => {
getUserData()
getBloodList()
getDictData('ks', 'lctxyy')
})
</script>
<style scoped lang="scss">
.box-container {
display: flex;
flex-direction: column;
}
.toolbar {
flex: none;
}
.retreat-form {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
}
.retreat-info {
position: relative;
flex: none;
}
.status {
position: absolute;
top: 34px;
right: 30px;
color: #409eff;
font-size: 18px;
font-weight: 700;
border: 2px solid #409eff;
border-radius: 5px;
padding: 10px;
}
.content-row {
flex: 1;
min-height: 0;
display: flex;
gap: 10px;
}
.scan-panel {
width: 350px;
flex: none;
}
.patient-panel {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
margin-bottom: 10px;
}
.capacity-fields {
display: flex;
gap: 5px;
width: 100%;
}
.capacity-fields .el-input:first-child {
flex: 1;
}
.capacity-fields .el-input:last-child {
width: 52px;
}
.table-title {
position: relative;
padding-left: 12px;
padding-bottom: 6px;
font-size: 15px;
font-weight: 600;
display: flex;
justify-content: space-between;
// align-items: center;
/* 左侧蓝色小竖线 */
&::before {
content: '';
position: absolute;
left: 0;
top: 2px;
bottom: 2px;
width: 4px;
height: 14px;
background-color: #409eff;
margin-right: 8px;
border-radius: 0 4px 4px 0;
}
}
.patient-panel :deep(.el-table) {
flex: 1;
min-height: 120px;
}
:deep(.el-form-item) {
margin-bottom: 8px;
}
</style>

View File

@ -592,8 +592,6 @@ import router from '@/router/index.js'
import { printBase64PDF } from '@/utils/classCom.js'
import { sendWebSocketMessage } from '@/utils/webSocket.js'
const userInfo = useUserStore()
const {
getServerTime,
userList,
@ -606,9 +604,7 @@ const {
getDiaList,
loadAllDict
} = useCommonDict()
const route = useRoute()
const saveLoading = ref(false)
const bloodFormRef = ref<InstanceType<typeof ElForm>>()
const queryForm = reactive({
@ -618,7 +614,6 @@ const queryForm = reactive({
doctor_code: userInfo.name,
beinhos_id: ''
})
const listScope = ref('3')
const indicationRef = useTemplateRef('indicationRef')
const radioChange = (val: string) => {
@ -643,7 +638,6 @@ const radioChange = (val: string) => {
}
getSqdList()
}
const pgcolumnList = ref([
{ label: '评估单号', prop: 'bill_no' },
{ label: '住院号', prop: 'beinhos_id' },
@ -651,14 +645,11 @@ const pgcolumnList = ref([
{ label: '评估日期(24h内有效)', prop: 'assess_data', width: 200 },
{ label: '评估人', prop: 'assess_person', width: 100, slotName: 'assess_person' },
])
const tableData = ref([])
const dictList = ref([
{ label: '代号', prop: 'value' },
{ label: '字典', prop: 'label' }
])
const xkPatientInfo = ref({}) //病人信息
const xkTransfuseApply = ref({
agreement_ink: 'Y',
@ -667,7 +658,6 @@ const xkTransfuseApply = ref({
apply_date: '',
apply_medic: userInfo.name
}) //输血申请信息
const formRef = useTemplateRef('formRef')
const formRules = reactive({
assess_bill_no: [{ required: true, message: '请选择评估单', trigger: 'change' }],
@ -675,6 +665,66 @@ const formRules = reactive({
use1_date: [{ required: true, message: '请选择预定输血日期', trigger: 'change' }],
dept_Type: [{ required: true, message: '请选择科室类型', trigger: 'change' }],
})
/** 数据快照,keep‑alive缓存页面,组件不会销毁;切换单据必须重写快照 */
const snapshotApply = ref<{
xkTransfuseApply: Record<string, any>
bloodList: any[]
lisProject: any[]
}>({
xkTransfuseApply: {},
bloodList: [],
lisProject: []
})
/** 更新快照:加载单据、新增单据、保存成功调用;记录当前基准状态 */
const updateSnapshot = () => {
snapshotApply.value.xkTransfuseApply = JSON.parse(JSON.stringify(xkTransfuseApply.value))
snapshotApply.value.bloodList = JSON.parse(JSON.stringify(bloodList.value))
snapshotApply.value.lisProject = JSON.parse(JSON.stringify(lisProject.value))
}
/**
* 判断表单是否存在未保存修改
* @returns true:有修改 false:无修改
*/
const isDataChanged = (): boolean => {
const currApply = JSON.parse(JSON.stringify(xkTransfuseApply.value))
const snapApply = JSON.parse(JSON.stringify(snapshotApply.value.xkTransfuseApply))
const currBlood = JSON.parse(JSON.stringify(bloodList.value))
const snapBlood = JSON.parse(JSON.stringify(snapshotApply.value.bloodList))
const currLis = JSON.parse(JSON.stringify(lisProject.value))
const snapLis = JSON.parse(JSON.stringify(snapshotApply.value.lisProject))
const applyStr = JSON.stringify(currApply)
const snapApplyStr = JSON.stringify(snapApply)
const bloodStr = JSON.stringify(currBlood)
const snapBloodStr = JSON.stringify(snapBlood)
const lisStr = JSON.stringify(currLis)
const snapLisStr = JSON.stringify(snapLis)
return applyStr !== snapApplyStr || bloodStr !== snapBloodStr || lisStr !== snapLisStr
}
/** 通用校验函数:审核/取消审核/作废共用,有变更直接返回true提示拦截 */
const checkDataChangeBeforeOperate = (): boolean => {
if (isDataChanged()) {
ElMessage.warning('表单数据已修改,请先保存后再操作')
return true
}
return false
}
// keep‑alive激活钩子:缓存页面,切回页面,如果当前有单据,重新刷新快照,防止快照为旧单据数据
onActivated(() => {
const currBill = xkTransfuseApply.value?.bill_no
const snapBill = snapshotApply.value?.xkTransfuseApply?.bill_no
if (currBill && currBill !== snapBill) {
nextTick(() => updateSnapshot())
}
})
// 根据单据状态获取单元格样式(背景色+白色文字)
const cellStyle = ({ row, column, rowIndex, columnIndex }) => {
if (column.label == '单据状态') {
@ -684,29 +734,23 @@ const cellStyle = ({ row, column, rowIndex, columnIndex }) => {
fontWeight: 500
}
}
}
const getBillStatusInfo = (code: string) => {
const statusList = dictData.value?.billApplyStatus ?? []
const target = statusList.find(item => item.value == code)
if (target) {
return { label: target.label, color: target.remark }
}
return { label: '未审核', color: '#909399' }
}
// 血液品种列表
const bloodList = ref([])
const orderList = ref([]) // 输血申请单列表
const orderRef = useTemplateRef('orderRef')
// 血液品种弹窗相关
const bloodDialogVisible = ref(false)
const editIndex = ref(-1)
const bloodForm = reactive({})
// 血液品种表单验证规则
const bloodFormRules = reactive({
blood_breed: [{ required: true, message: '请输入血液品种', trigger: 'blur' }],
@ -730,14 +774,11 @@ const bloodFormRules = reactive({
intent: [{ required: true, message: '请选择输血目的', trigger: 'change' }],
causalis: [{ required: true, message: '请选择输血指征', trigger: 'change' }],
})
//流程节点
const processList = ref([
{ statusName: '开单', occurDate: '' },
{ statusName: '上级医生审核', occurDate: '' },
{ statusName: '输血科审核', occurDate: '' },
// { statusName: '医务部审核', occurDate: '' },
// { statusName: '输血科审核', occurDate: '' },
{ statusName: '血型复核', occurDate: '' },
{ statusName: '交叉配血', occurDate: '' },
{ statusName: '临床发血', occurDate: '' },
@ -750,7 +791,6 @@ const currentStepIndex = computed(() => {
}
return list.length - 1
})
// 节点状态类名
const getNodeStatusClass = (item, index: number) => {
const currIdx = currentStepIndex.value
@ -799,11 +839,9 @@ const handleConfirm = () => {
visible.value = false
selectRow.value = {}
}
const handleRowClick = (row) => {
selectRow.value = row
}
const dblClickRow = (row) => {
getQueryOneInfo(row.bill_no)
visible.value = false
@ -819,7 +857,6 @@ const getList = () => {
jsTabdeList.value = res.data
})
}
// 查询申请单列表
const getSqdList = () => {
querysqList(queryForm).then((res) => {
@ -834,7 +871,6 @@ const getSqdList = () => {
}
})
}
const rowClick = (row) => {
getQueryOneInfo(row.bill_no)
}
@ -848,12 +884,12 @@ const addHandle = () => {
assess_bill_no: ''
}
bloodList.value = []
getServerTime().then(time => {
xkTransfuseApply.value.apply_date = time
xkTransfuseApply.value.use1_date = time
nextTick(() => {
formRef.value?.clearValidate()
updateSnapshot() //新增单据更新快照
})
})
processList.value = [
@ -876,10 +912,11 @@ const shForm = ref({
const shLoading = ref(false)
const reviewCommentsRef = useTemplateRef('reviewCommentsRef')
// 审核
// 如果是001 代表是临床科室,此时需要调用“上级医生审核” 审核接口,
// 如果是002 代表是输血科室,调用“申请单审核前校验”
const reviewHandle = () => {
if (!xkTransfuseApply.value.bill_no) return ElMessage.warning('该单据还未保存!')
// 变更校验,有修改直接拦截
if (checkDataChangeBeforeOperate()) return
shLoading.value = true
getDeptType({ userId: userInfo.name }).then(res => {
if (res.data == '001') {
@ -905,7 +942,6 @@ const handleSh = () => {
handleReviewConfirm()
}
}
const cancelreviewHandle = () => {
if (!xkTransfuseApply.value.bill_no) return ElMessage.warning('该单据还未保存!')
getDeptType({ userId: userInfo.name }).then(res => {
@ -934,13 +970,11 @@ const cancelreviewHandle = () => {
})
})
}
//作废
const reason = ref('')
const reasonText = ref('')
const zfShow = ref(false)
const invalidateHandle = () => {
// sqdzfyy
if (!xkTransfuseApply.value.bill_no) return ElMessage.warning('该单据还未保存!')
zfShow.value = true
}
@ -979,7 +1013,6 @@ const handleReviewConfirm = () => {
}
})
}
//审核意见
const shClose = () => {
shShow.value = false
@ -990,8 +1023,7 @@ const shClose = () => {
}
}
const printLoading = ref(false)
//打印输血评估单
//打印输血评估单
const printHandle = (name: string) => {
printLoading.value = true
let billno = ''
@ -1017,7 +1049,6 @@ const goHistoryBlood = () => {
}
})
}
// 打开新增弹窗
const openBloodDialog = () => {
editIndex.value = -1
@ -1025,7 +1056,6 @@ const openBloodDialog = () => {
bloodForm.apply_bloodtype = xkPatientInfo.value.abo
bloodDialogVisible.value = true
}
// 重置弹窗表单
const resetBloodForm = () => {
if (bloodFormRef.value) {
@ -1034,7 +1064,6 @@ const resetBloodForm = () => {
// 删除所有key,清空表单
Object.keys(bloodForm).forEach(key => delete bloodForm[key])
}
// 编辑血液品种
const editBlood = (row: any, index: number) => {
editIndex.value = index
@ -1044,7 +1073,6 @@ const editBlood = (row: any, index: number) => {
Object.assign(bloodForm, JSON.parse(JSON.stringify(row)))
bloodDialogVisible.value = true
}
// 删除单条血液品种
const deleteSingleBlood = (index: number) => {
ElMessageBox.confirm(
@ -1088,7 +1116,6 @@ const blHandle = () => {
}
})
}
//保存申请单
const handleSubmit = async () => {
formRef.value.validate((valid) => {
@ -1102,7 +1129,6 @@ const handleSubmit = async () => {
}
saveLoading.value = true
const tempPatient = { ...xkPatientInfo.value, beinhos_id: xkTransfuseApply.value.beinhos_id }
const data = {
transfuseApplyInfoOne: {
xkPatientInfo: tempPatient,
@ -1116,7 +1142,6 @@ const handleSubmit = async () => {
}),
xkTransfuseApplyTestitemList: lisProject.value,
}
// 自体血校验
checkSelfBlood({ beinhos_id: xkTransfuseApply.value.beinhos_id }).then((res) => {
if (res.code == 0) {
@ -1180,7 +1205,6 @@ const handleSubmit = async () => {
//输血指征校验弹窗确定
const indicationComfirm = (arr) => {
const tempPatient = { ...xkPatientInfo.value, beinhos_id: xkTransfuseApply.value.beinhos_id }
const data = {
transfuseApplyInfoOne: {
xkPatientInfo: tempPatient,
@ -1195,7 +1219,6 @@ const indicationComfirm = (arr) => {
xkTransfuseApplyTestitemList: lisProject.value,
xkTransfuseApplyCausalisList: arr
}
saveApplyInfo(data).then((res) => {
if (res.code == 0 && res.data) {
getQueryOneInfo(res.data)
@ -1205,11 +1228,9 @@ const indicationComfirm = (arr) => {
}
})
}
const sendMsg = (billNo: string) => {
const arr = bloodList.value.map(item => item.blood_breed)
const breedMap = new Map(bloodBreed.value.map(v => [v.value, v.label]));
const bloodText = arr.map(item => breedMap.get(item) ?? item).join('、');
const data = {
type: "APPLY_NOTICE",
@ -1230,6 +1251,10 @@ const getQueryOneInfo = (bill_no: string) => {
xkTransfuseApply.value = res.data.transfuseApplyInfoOne.xkTransfuseApply
bloodList.value = res.data.xkTransfuseApplyBloodbreedList
lisProject.value = mergeLisTestItem(lisProject.value, res.data.xkTransfuseApplyTestitemList)
// 回显单据,更新快照
nextTick(() => {
updateSnapshot()
})
})
//获取申请单状态
bloodCloseLoop({ billNo: bill_no }).then(res => {
@ -1238,15 +1263,16 @@ const getQueryOneInfo = (bill_no: string) => {
}
})
}
//获取患者信息
const getInfo = (billNo: string) => {
//PJD2026061623
getPatInfo({ bill_no: billNo }).then((res) => {
xkPatientInfo.value = res.data.transfuseApplyInfoOne.xkPatientInfo
xkTransfuseApply.value = res.data.transfuseApplyInfoOne.xkTransfuseApply
bloodList.value = res.data.xkTransfuseApplyBloodbreedList || []
lisProject.value = mergeLisTestItem(lisProject.value, res.data.xkTransfuseApplyTestitemList)
nextTick(() => {
updateSnapshot() //路由跳转加载单据更新快照
})
})
}
//合并检查结果
@ -1262,12 +1288,10 @@ const mergeLisTestItem = (oldList: Array<any>, apiList: Array<any>) => {
}
})
}
const oldMap = new Map<string, any>()
oldList.forEach(item => {
if (item?.item_name) oldMap.set(item.item_name, item)
})
return apiList.map(apiItem => {
if (!apiItem || !apiItem.item_name) {
return {
@ -1302,7 +1326,6 @@ const mergeLisTestItem = (oldList: Array<any>, apiList: Array<any>) => {
}
})
}
// 回显时拆分 年龄 + 单位
const splitAge = (ageStr: string) => {
const unitList = dictData.value.nldw.map(item => item.value)
@ -1318,9 +1341,6 @@ const splitAge = (ageStr: string) => {
xkPatientInfo.value.age = age
xkPatientInfo.value.nldw = unit
}
const pgList = ref([])
//获取评估申请单
const getPgList = () => {
@ -1328,7 +1348,6 @@ const getPgList = () => {
pgList.value = res.data
})
}
let needClearState = false // 标记是否需要清理state
// 加载单据
const loadBillInfo = () => {
@ -1344,15 +1363,12 @@ const loadBillInfo = () => {
const getPgInfo = (row) => {
getInfo(row.bill_no)
}
//手术名称
const operationList = ref([])
const operationColumn = [
{ label: '手术代号', prop: 'icd_code' },
{ label: '手术名称', prop: 'oper_name', width: 200 },
// { label: '手术级别', prop: 'oper_level' },
]
const getOperationInfo = (row) => {
if (row.oper_level) {
switch (row.oper_level) {
@ -1372,7 +1388,6 @@ const getOperationInfo = (row) => {
break;
}
}
}
//手术名称
const getSxList = () => {
@ -1380,8 +1395,6 @@ const getSxList = () => {
operationList.value = res.rows
})
}
onMounted(() => {
loadAllDict()
getServerTime().then(time => {
@ -1393,10 +1406,8 @@ onMounted(() => {
getSqdList()
loadBillInfo()
})
// 监听路由变化
watch(() => route.fullPath, loadBillInfo)
// 页面关闭/切换标签时再清空state,不影响同路由二次跳转
onBeforeUnmount(() => {
if (needClearState) {
@ -1405,6 +1416,7 @@ onBeforeUnmount(() => {
})
</script>
<style scoped lang="scss">
.box-container {
display: flex;

View File

@ -28,6 +28,9 @@
{{ row.report_no }}
</div>
</template>
<template #report_size="{ row }">
{{ formatByteToMB(row.report_size) }}
</template>
<template #action="{ row }">
<el-button type="primary" text @click="handleEdit(row)">编辑</el-button>
<el-button type="primary" text @click="handleDel(row)">删除</el-button>
@ -41,8 +44,9 @@
<el-input v-model="form.report_name" placeholder="请输入文件名" />
</el-form-item>
</el-form>
<el-upload ref="uploadRef" :limit="1" accept=".jrxml" action="#" :on-change="changeFile" :file-list="fileList"
:on-exceed="handleExceed" :on-remove="() => { fileList = [] }" :auto-upload="false" drag>
<el-upload ref="uploadRef" :limit="1" accept=".jrxml" :action="uploadUrl" :headers="headers"
:on-change="changeFile" :file-list="fileList" :on-exceed="handleExceed" :on-remove="() => { fileList = [] }"
drag>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<template #tip>
@ -65,15 +69,19 @@
import dayjs from 'dayjs'
import { queryList, addTemplate, updateTemplate, delTemplate } from '@/api/system/template'
import { getDictData, formatDict, dictData, useCommonDict } from '@/hooks'
import { formatByteToMB } from '@/utils/classCom'
import { ElMessage, ElMessageBox } from 'element-plus'
const { userList, getUserData, } = useCommonDict()
import Download from '@/plugins/download'
import { getToken } from '@/utils/auth'
const searchForm = reactive({})
const fileList = ref([])
const open = ref(false)
const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/upload")
const headers = ref({ Authorization: "Bearer " + getToken() })
const form = ref({})
const rules = ref({
report_name: [
@ -90,6 +98,8 @@ const columns = ref([
{ label: '模板ID', prop: 'report_id', align: 'center', visible: true, width: 100 },
{ label: '模板名称', prop: 'report_name', align: 'center', visible: true, },
{ label: '模板文件', prop: 'report_no', align: 'center', visible: true, slot: 'report_no' },
{ label: '文件大小', prop: 'report_size', align: 'center', visible: true, slot: 'report_size' },
{ label: '修改时间', prop: 'update_time', align: 'center', visible: true, },
{ label: '创建时间', prop: 'create_time', align: 'center', visible: true, },
])
const tableConfig = ref({