临床发血退血
This commit is contained in:
parent
163cfda204
commit
2e00ada8cd
@ -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
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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`
|
||||
}
|
||||
@ -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>
|
||||
|
||||
424
src/views/blood/retreat/index.vue
Normal file
424
src/views/blood/retreat/index.vue
Normal 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>
|
||||
@ -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;
|
||||
|
||||
@ -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({
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user