diff --git a/src/api/bloodInventory.ts b/src/api/bloodInventory.ts new file mode 100644 index 0000000..ac50764 --- /dev/null +++ b/src/api/bloodInventory.ts @@ -0,0 +1,32 @@ +/** + * @file bloodInventory.ts + * @description: 血量库存 + * @author: w + * @since: 2026-07-23 + */ +import request from '@/utils/request' + +// 查询过期血液 +export function queryExpiredBlood(query?: Object) { + return request({ + url: '/bus/bloodbank/stips/queryExpiredBlood', + method: 'get', + params: query + }) +} +// 查询列表数据,输血科,血液品种总量类型 +export function queryListByBlood(query?: Object) { + return request({ + url: '/bus/bloodbank/stips/queryListByBlood', + method: 'get', + params: query + }) +} +// 查询列表数据,医生站,血型总量类型 +export function queryListByDoctor(query?: Object) { + return request({ + url: '/bus/bloodbank/stips/queryListByDoctor', + method: 'get', + params: query + }) +} \ No newline at end of file diff --git a/src/api/doctor/application.ts b/src/api/doctor/application.ts index cfcfae1..e976b0a 100644 --- a/src/api/doctor/application.ts +++ b/src/api/doctor/application.ts @@ -143,4 +143,36 @@ export function queryhistoryList(query?: Object) { method: 'get', params: query }) +} +// 查询大量用血审批列表 +export function approvalQueryList(query?: Object) { + return request({ + url: '/bus/doctor/approval/queryList', + method: 'post', + data: query + }) +} +// 科主任审批 +export function auditArchiater(query?: Object) { + return request({ + url: '/bus/doctor/approval/auditArchiater', + method: 'get', + params: query + }) +} +// 医务部审批 +export function auditMedical(query?: Object) { + return request({ + url: '/bus/doctor/approval/auditMedical', + method: 'get', + params: query + }) +} +// 输血申请单状态闭环 +export function bloodCloseLoop(query?: Object) { + return request({ + url: '/bus/doctor/apply/bloodCloseLoop', + method: 'get', + params: query + }) } \ No newline at end of file diff --git a/src/api/system/user.ts b/src/api/system/user.ts index a852132..a20cc92 100644 --- a/src/api/system/user.ts +++ b/src/api/system/user.ts @@ -139,9 +139,10 @@ export function updateAuthRole(data: SysUserRoles): Promise { } // 查询部门下拉树结构 -export function deptTreeSelect(): Promise> { +export function deptTreeSelect(data?: object): Promise> { return request({ url: '/system/user/deptTree', - method: 'get' + method: 'get', + params: data }) } diff --git a/src/components/BloodStockNotify/index.vue b/src/components/BloodStockNotify/index.vue new file mode 100644 index 0000000..f6725a4 --- /dev/null +++ b/src/components/BloodStockNotify/index.vue @@ -0,0 +1,357 @@ + + + + + \ No newline at end of file diff --git a/src/hooks/useCommonDict.ts b/src/hooks/useCommonDict.ts index 7dbed5a..b303a3e 100644 --- a/src/hooks/useCommonDict.ts +++ b/src/hooks/useCommonDict.ts @@ -62,7 +62,8 @@ export function useCommonDict() { item_result: '', item_unit: item.unit, test_date: item.validTime, - sid: item.sid + sid: item.sid, + result_type: item.result_type })) return lisProject.value } diff --git a/src/layout/index.vue b/src/layout/index.vue index cb7f076..aa13192 100644 --- a/src/layout/index.vue +++ b/src/layout/index.vue @@ -10,6 +10,9 @@ + + + @@ -20,6 +23,8 @@ import { AppMain, Navbar, Settings, TagsView } from './components' import useAppStore from '@/store/modules/app' import useSettingsStore from '@/store/modules/settings' import { useSysParam } from '@/hooks/useSysParam' +// 异步懒加载,首屏不阻塞 +const BloodStockNotify = defineAsyncComponent(() => import('@/components/BloodStockNotify/index.vue')) const { initAllParams } = useSysParam() diff --git a/src/views/doctor/application/component/indication.vue b/src/views/doctor/application/component/indication.vue new file mode 100644 index 0000000..0bf30d0 --- /dev/null +++ b/src/views/doctor/application/component/indication.vue @@ -0,0 +1,124 @@ + + + + + \ No newline at end of file diff --git a/src/views/doctor/application/index copy.vue b/src/views/doctor/application/index copy.vue index a8b1be0..3c2465f 100644 --- a/src/views/doctor/application/index copy.vue +++ b/src/views/doctor/application/index copy.vue @@ -318,7 +318,7 @@ @@ -346,7 +346,7 @@ diff --git a/src/views/doctor/application/index.vue b/src/views/doctor/application/index.vue index 0ab084f..c378752 100644 --- a/src/views/doctor/application/index.vue +++ b/src/views/doctor/application/index.vue @@ -16,10 +16,12 @@ 审核 取消审核 作废 - 打印输血申请单 + 打印输血申请单 患者输血历史 - 打印大量输血审批单 - 打印输血知情同意书 + 打印大量输血审批单 + 打印输血知情同意书 @@ -38,7 +40,7 @@
住院号: - {{ xkTransfuseApply.beinhos_id }} + {{ xkPatientInfo.beinhos_id }}
姓名: @@ -79,8 +81,8 @@
{{ xkPatientInfo.abo || '-' }} 型
- - {{ xkPatientInfo.rh ? (xkPatientInfo.rh == '+' ? '阳性' : '阴性') : '-' }} RH + + {{ xkPatientInfo.rh == '+' ? '阳性' : xkPatientInfo.rh == '-' ? '阴性' : '未知' }} RH
@@ -236,15 +238,20 @@
- + +
- {{ item.label }} + {{ item.statusName }}
-
+ :class="{ arrow_finish: item.visible == 'Y' }">
@@ -265,7 +272,7 @@ @@ -553,6 +560,8 @@ @success="() => { getQueryOneInfo(xkTransfuseApply.bill_no); getSqdList() }" /> + + @@ -564,18 +573,19 @@ import DropdownTableSelect from '@/components/DropdownTableSelect/index.vue' import dayjs from 'dayjs' import { querysqList, getPatInfo, checkSelfBlood, checkCausalis, savePreApplyInfo, saveApplyInfo, queryApplyOne, queryApplyBeforeList, applyCheck, applyMedicCheck, - cancelApplyMedicCheck, cancelApplyCheck, cancelApply, invokeEMR + cancelApplyMedicCheck, cancelApplyCheck, cancelApply, invokeEMR, bloodCloseLoop } from '@/api/doctor/application' +import { printPat } from '@/api/doctor/assessment' import { queryOperation, getDeptType, checkLoginAffirm } from '@/api/common' import ReviewComments from './component/reviewComments.vue' +import Indication from './component/indication.vue' import PatientLisTable from '../components/PatientLisTable.vue' import CheckUser from '@/components/CheckUser/index.vue' import useUserStore from '@/store/modules/user' import router from '@/router/index.js' +import { printBase64PDF } from '@/utils/classCom.js' const userInfo = useUserStore() -// 解构全部公共变量与方法 -const { getParam } = useSysParam() const { getServerTime, @@ -592,19 +602,18 @@ const { const route = useRoute() -const aboFlag = ref('') const saveLoading = ref(false) const bloodFormRef = ref>() const queryForm = reactive({ day: 7, bill_status: '', - dept_code: userInfo.deptParam.deptId, + dept_code: '', doctor_code: userInfo.name, beinhos_id: '' }) const listScope = ref('3') - +const indicationRef = useTemplateRef('indicationRef') const radioChange = (val: string) => { switch (val) { case '1': @@ -718,29 +727,29 @@ const bloodFormRules = reactive({ //流程节点 const processList = ref([ - { label: '开单', operateTime: '2026-06-01 10:10:10' }, - { label: '上级医生审核', operateTime: '2026-06-02 13:10:10' }, - { label: '科主任审核', operateTime: '2026-06-01 15:10:10' }, - { label: '医务部审核', operateTime: '' }, - { label: '输血科审核', operateTime: '' }, - { label: '血型复核', operateTime: '' }, - { label: '交叉配血', operateTime: '' }, - { label: '临床发血', operateTime: '' }, + { statusName: '开单', occurDate: '' }, + { statusName: '上级医生审核', occurDate: '' }, + { statusName: '输血科审核', occurDate: '' }, + // { statusName: '医务部审核', occurDate: '' }, + // { statusName: '输血科审核', occurDate: '' }, + { statusName: '血型复核', occurDate: '' }, + { statusName: '交叉配血', occurDate: '' }, + { statusName: '临床发血', occurDate: '' }, ]) // 当前激活步骤下标 const currentStepIndex = computed(() => { const list = processList.value for (let i = 0; i < list.length; i++) { - if (!list[i].operateTime) return i + if (!list[i].occurDate) return i } return list.length - 1 }) // 节点状态类名 -const getNodeStatusClass = (item: { operateTime: string }, index: number) => { +const getNodeStatusClass = (item, index: number) => { const currIdx = currentStepIndex.value // 已完成:有时间 - if (item.operateTime) return 'finish' + if (item.visible == 'Y') return 'finish' // 当前待办节点 if (index === currIdx) return 'active' // 未开始 @@ -805,8 +814,8 @@ const getSqdList = () => { querysqList(queryForm).then((res) => { orderList.value = res.data if (res.data.length) { - const row = res.data.find(item => item.bill_no == xkTransfuseApply.value.bill_no) nextTick(() => { + const row = res.data.find(item => item.bill_no == xkTransfuseApply.value.bill_no) if (row) { orderRef.value.setCurrentRow(row) } @@ -836,6 +845,14 @@ const addHandle = () => { formRef.value?.clearValidate() }) }) + processList.value = [ + { statusName: '开单', occurDate: '' }, + { statusName: '上级医生审核', occurDate: '' }, + { statusName: '输血科审核', occurDate: '' }, + { statusName: '血型复核', occurDate: '' }, + { statusName: '交叉配血', occurDate: '' }, + { statusName: '临床发血', occurDate: '' }, + ] getLisProject() } const checkUserRef = useTemplateRef('checkUserRef') @@ -962,8 +979,25 @@ const shClose = () => { agreement_ink: 'Y' } } +const printLoading = ref(false) - +//打印输血评估单 +const printPg = (name: string) => { + printLoading.value = true + let billno = '' + if (name == 'INFORMED_CONSENT') { + billno = xkTransfuseApply.value.assess_bill_no + } else if (name == 'LARGE_APPLY') { + billno = xkTransfuseApply.value.bill_no + } + printPat({ billNo: billno, templateName: name }).then((res) => { + if (res.data) { + printBase64PDF(res.data) + } + }).finally(() => { + printLoading.value = false + }) +} //患者历史 const goHistoryBlood = () => { router.push({ @@ -1068,16 +1102,23 @@ const handleSubmit = async () => { xkTransfuseApplyTestitemList: lisProject.value, } + // 自体血校验 checkSelfBlood({ beinhos_id: xkTransfuseApply.value.beinhos_id }).then((res) => { if (res.code == 0) { + // 校验是否符合输血指征的规则 checkCausalis(data).then((res1) => { if (res1.code == 0) { + // 保存前校验 savePreApplyInfo(data).then((res2) => { if (res2.code == 0) { + // 保存申请单 saveApplyInfo(data).then((res3) => { + if (res3.data) { + getQueryOneInfo(res3.data) + getSqdList() + } if (res3.code == 0) { ElMessage.success('保存成功') - getSqdList() } }) } else if (res2.code == 1) { @@ -1097,15 +1138,21 @@ const handleSubmit = async () => { ).then(() => { getQueryOneInfo(res2.data) }).catch(() => { + // 保存申请单 saveApplyInfo(data).then((res3) => { - if (res3.code == 0) { + if (res3.data) { + getQueryOneInfo(res3.data) getSqdList() + } + if (res3.code == 0) { ElMessage.success('保存成功') } }) }) } }) + } else if (res1.code == 1) { + indicationRef.value.openDialog(res1.data, xkTransfuseApply.value.bill_no) } }) } @@ -1117,42 +1164,107 @@ const handleSubmit = async () => { } }) } +//输血指征校验弹窗确定 +const indicationComfirm = (arr) => { + const tempPatient = { ...xkPatientInfo.value, beinhos_id: xkTransfuseApply.value.beinhos_id } + + const data = { + transfuseApplyInfoOne: { + xkPatientInfo: tempPatient, + xkTransfuseApply: xkTransfuseApply.value + }, + xkTransfuseApplyBloodbreedList: bloodList.value, + xkTransfuseApplyTestitemList: lisProject.value, + xkTransfuseApplyCausalisList: arr + } + + saveApplyInfo(data).then((res) => { + if (res.data) { + getQueryOneInfo(res.data) + getSqdList() + } + if (res.code == 0) { + ElMessage.success('保存成功') + } + }) +} //获取申请单信息 const getQueryOneInfo = (bill_no: string) => { queryApplyOne({ billNo: bill_no }).then((res) => { xkPatientInfo.value = res.data.transfuseApplyInfoOne.xkPatientInfo xkTransfuseApply.value = res.data.transfuseApplyInfoOne.xkTransfuseApply bloodList.value = res.data.xkTransfuseApplyBloodbreedList - lisProject.value = res.data.xkTransfuseApplyTestitemList.map(item => { - return { - bill_no: item.bill_no, - item_name: item.item_name, - item_result: item.item_result, - item_unit: item.item_unit, - test_date: item.test_date, - sid: item.sid - } - }) + lisProject.value = mergeLisTestItem(lisProject.value, res.data.xkTransfuseApplyTestitemList) + }) + //获取申请单状态 + bloodCloseLoop({ billNo: bill_no }).then(res => { + if (res.code == 0) { + processList.value = res.data + } }) } //获取患者信息 -const getInfo = (billNo) => { +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 = res.data.xkTransfuseApplyTestitemList.map(item => { + lisProject.value = mergeLisTestItem(lisProject.value, res.data.xkTransfuseApplyTestitemList) + }) +} +//合并检查结果 +const mergeLisTestItem = (oldList: Array, apiList: Array) => { + const currentBillNo = xkTransfuseApply.value?.bill_no ?? '' + if (apiList.length === 0) { + // 过滤脏数据 + return oldList.filter(item => item?.item_name).map(item => { return { - bill_no: item.bill_no, - item_name: item.item_name, - item_result: item.item_result, - item_unit: item.item_unit, - test_date: item.test_date, - sid: item.sid + ...item, + item_result: '', + bill_no: currentBillNo } }) + } + + const oldMap = new Map() + oldList.forEach(item => { + if (item?.item_name) oldMap.set(item.item_name, item) + }) + + return apiList.map(apiItem => { + if (!apiItem || !apiItem.item_name) { + return { + bill_no: currentBillNo, + item_name: '', + item_result: '', + item_unit: '', + test_date: '', + sid: '', + result_type: '' + } + } + const apiData = { + bill_no: apiItem.bill_no ?? currentBillNo, + item_name: apiItem.item_name ?? '', + item_result: apiItem.item_result ?? '', + item_unit: apiItem.item_unit ?? '', + test_date: apiItem.test_date ?? '', + sid: apiItem.sid ?? '' + } + const localItem = oldMap.get(apiItem.item_name) + if (localItem) { + // 接口所有字段覆盖,仅复用旧result_type + return { + ...apiData, + result_type: localItem.result_type ?? '' + } + } + return { + ...apiData, + result_type: '' + } }) } @@ -1189,6 +1301,7 @@ const loadBillInfo = () => { // 只有主动跳转带过来的参数才执行查询 if (state?.isJump && state.billNo) { getInfo(state.billNo) + addHandle() needClearState = true // 标记本次有跳转参数,页面销毁时清空 } } @@ -1244,16 +1357,6 @@ onMounted(() => { getDictData('sqdzfyy', 'rhtype', 'abotype', 'nldw', 'billApplyStatus', 'sd', 'ks', 'depttype', 'bq', 'sxmd', 'sxzz', 'test_result', 'sqlx', 'lczd', 'xylx', 'operatype', 'nooperatype') getSqdList() loadBillInfo() - - // SQDSFKRLXGXX 参数说明如下: - // 输血申请时是否可从HIS系统中调出患者信息,是否可以录入修改患者血型? - // 以"/"分隔,"/"前指可以调出患者信息时是否可以修改患者血型(Y可以修改N不可以修改), - // "/"后指不可以调出患者信息时是否可以录入全部和只能录入"未知"患者血型(Y可以录入全部N只能录入"未知") - - if (getParam('SQDSFKRLXGXX')) { - const [a, b] = getParam('SQDSFKRLXGXX').split('/') - aboFlag.value = b - } }) // 监听路由变化 @@ -1441,10 +1544,11 @@ onBeforeUnmount(() => { width: 20%; display: flex; font-size: 14px; - // font-weight: 600; .label { - color: #000; + font-weight: 600; + font-size: 14px; + color: #333; min-width: 70px; text-align: right; margin-right: 8px; diff --git a/src/views/doctor/assessment/index.vue b/src/views/doctor/assessment/index.vue index 6956a20..cf250cf 100644 --- a/src/views/doctor/assessment/index.vue +++ b/src/views/doctor/assessment/index.vue @@ -57,7 +57,9 @@ - + + + @@ -81,7 +83,9 @@ - + + + @@ -263,6 +267,9 @@ const searchForm = ref({ beinhos_id: '' }) +const aboFlag = ref('') + + const printLoading = ref(false) const saveLoading = ref(false) @@ -324,21 +331,67 @@ const getBillInfo = () => { evaluationInfo.value.assessmentDate = res.data.xkTransfuseApplyBeforeList[0].assess_data baseInfo.value = res.data.xkPatientInfo bloodInfo.value = res.data.xkTransfuseApplyBeforeList[0] - lisProject.value = res.data.xkTransfuseApplyTestitemList.map(item => { - return { - bill_no: item.bill_no, - item_name: item.item_name, - item_result: item.item_result, - item_unit: item.item_unit, - test_date: item.test_date, - sid: item.sid - } - }) + lisProject.value = mergeLisTestItem(lisProject.value, res.data.xkTransfuseApplyTestitemList) splitAge(baseInfo.value.age) } }) } +//合并检查结果 +const mergeLisTestItem = (oldList: Array, apiList: Array) => { + const currentBillNo = evaluationInfo.value?.billNo ?? '' + if (apiList.length === 0) { + // 过滤脏数据 + return oldList.filter(item => item?.item_name).map(item => { + return { + ...item, + item_result: '', + bill_no: currentBillNo + } + }) + } + + const oldMap = new Map() + oldList.forEach(item => { + if (item?.item_name) oldMap.set(item.item_name, item) + }) + + return apiList.map(apiItem => { + if (!apiItem || !apiItem.item_name) { + return { + bill_no: currentBillNo, + item_name: '', + item_result: '', + item_unit: '', + test_date: '', + sid: '', + result_type: '' + } + } + const apiData = { + bill_no: apiItem.bill_no ?? currentBillNo, + item_name: apiItem.item_name ?? '', + item_result: apiItem.item_result ?? '', + item_unit: apiItem.item_unit ?? '', + test_date: apiItem.test_date ?? '', + sid: apiItem.sid ?? '' + } + const localItem = oldMap.get(apiItem.item_name) + if (localItem) { + // 接口所有字段覆盖,仅复用旧result_type + return { + ...apiData, + result_type: localItem.result_type ?? '' + } + } + return { + ...apiData, + result_type: '' + } + }) +} + + // 回显时拆分 年龄 + 单位 const splitAge = (ageStr: string) => { const unitList = dictData.value.nldw.map(item => item.value) @@ -477,18 +530,29 @@ const getProject = () => { item_name: item.pro_name, item_result: '', item_unit: item.unit, - test_date: dayjs().format('YYYY-MM-DD HH:mm:ss'), - sid: item.sid + test_date: '', + sid: item.sid, + result_type: item.result_type } }) }) } onMounted(() => { - getDictData('ks', 'test_result', 'nldw', 'anemia') + getDictData('ks', 'test_result', 'nldw', 'anemia', 'rhtype', 'abotype',) getProject() + // SQDSFKRLXGXX 参数说明如下: + // 输血申请时是否可从HIS系统中调出患者信息,是否可以录入修改患者血型? + // 以"/"分隔,"/"前指可以调出患者信息时是否可以修改患者血型(Y可以修改N不可以修改), + // "/"后指不可以调出患者信息时是否可以录入全部和只能录入"未知"患者血型(Y可以录入全部N只能录入"未知") + + if (getParam('SQDSFKRLXGXX')) { + const [a, b] = getParam('SQDSFKRLXGXX').split('/') + aboFlag.value = b + } + const tipText = `输血报销适用限制范围如下:
诊疗少白细胞红细胞限特殊适应症与急救、抢救请根据限制范围,结合当前病人情况,判断是否适用医保如为自费患者。
请到HIS-医保管理菜单-医保费用审核里` diff --git a/src/views/doctor/autologous/index copy.vue b/src/views/doctor/autologous/index copy.vue deleted file mode 100644 index f36be29..0000000 --- a/src/views/doctor/autologous/index copy.vue +++ /dev/null @@ -1,373 +0,0 @@ -/** -* @file index.vue -* @description: 储存室自体血登记 -* @author: w -* @since: 2026-07-08 -*/ - - - - - \ No newline at end of file diff --git a/src/views/doctor/autologous/index.vue b/src/views/doctor/autologous/index.vue index 9f17527..f19b25b 100644 --- a/src/views/doctor/autologous/index.vue +++ b/src/views/doctor/autologous/index.vue @@ -5,13 +5,305 @@ * @since: 2026-07-08 */ - \ No newline at end of file + \ No newline at end of file diff --git a/src/views/doctor/components/PatientLisTable.vue b/src/views/doctor/components/PatientLisTable.vue index 56c1e7c..607d96d 100644 --- a/src/views/doctor/components/PatientLisTable.vue +++ b/src/views/doctor/components/PatientLisTable.vue @@ -1,37 +1,40 @@