完成-101-系统管理-》目录管理-》诊断目录:增加报卡类型字段

完成-78-增加门诊医生开立检验申请单的检验项目选择区的查询。
This commit is contained in:
wangjian963
2026-03-03 16:29:08 +08:00
parent 8810c678c9
commit 455f7938be
6 changed files with 275 additions and 71 deletions

View File

@@ -40,6 +40,11 @@ public class DiseaseManageDto {
private String typeCode; private String typeCode;
private String typeCode_dictText; private String typeCode_dictText;
/** 报表类型 */
@Dict(dictCode = "card_name_code")
private String reportTypeCode;
private String reportTypeCode_dictText;
/** 描述 */ /** 描述 */
private String description; private String description;

View File

@@ -40,6 +40,9 @@ public class DiseaseManageUpDto {
/** 类型 */ /** 类型 */
private String typeCode; private String typeCode;
/** 报表类型 */
private String reportTypeCode;
/** 描述 */ /** 描述 */
private String description; private String description;

View File

@@ -45,6 +45,9 @@ public class ConditionDefinition extends HisBaseEntity {
/** 类型 */ /** 类型 */
private String typeCode; private String typeCode;
/** 报表类型 */
private String reportTypeCode;
/** 描述 */ /** 描述 */
private String description; private String description;

View File

@@ -132,6 +132,13 @@
prop="typeCode_dictText" prop="typeCode_dictText"
:show-overflow-tooltip="true" :show-overflow-tooltip="true"
/> />
<el-table-column
label="报卡类型"
align="center"
key="reportTypeCode_dictText"
prop="reportTypeCode_dictText"
:show-overflow-tooltip="true"
/>
<el-table-column <el-table-column
label="医保编码 " label="医保编码 "
align="center" align="center"
@@ -273,6 +280,20 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row>
<el-col :span="12">
<el-form-item label="报卡类型" prop="reportTypeCode">
<el-select v-model="form.reportTypeCode" placeholder="请选择" clearable>
<el-option
v-for="dict in card_name_code"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24"> <el-row :gutter="24">
<el-col :span="16"> <el-col :span="16">
<el-form-item label="说明" prop="description"> <el-form-item label="说明" prop="description">
@@ -308,7 +329,7 @@ import {
} from './components/disease'; } from './components/disease';
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const { condition_type_code } = proxy.useDict('condition_type_code'); const { condition_type_code, card_name_code } = proxy.useDict('condition_type_code', 'card_name_code');
const diseaseList = ref([]); const diseaseList = ref([]);
const open = ref(false); const open = ref(false);
@@ -448,6 +469,7 @@ function reset() {
statusEnum: undefined, statusEnum: undefined,
sourceEnum: undefined, sourceEnum: undefined,
typeCode: undefined, typeCode: undefined,
reportTypeCode: undefined,
description: undefined, description: undefined,
ybFlag: undefined, ybFlag: undefined,
ybNo: undefined, ybNo: undefined,

View File

@@ -948,6 +948,32 @@ export function deleteInspectionApplication(applyNo) {
}); });
} }
/**
* 获取检验类型列表(分类)
*/
export function getInspectionTypeList() {
return request({
url: '/system/inspection-type/list',
method: 'get',
});
}
/**
* 获取检验项目列表(从诊疗目录中筛选检验类项目)
* @param {Object} queryParams - 查询参数
* @param {string} queryParams.searchKey - 搜索关键词
* @param {number} queryParams.pageNo - 页码
* @param {number} queryParams.pageSize - 每页数量
* @param {string} queryParams.categoryCode - 目录类别编码(检验)
*/
export function getInspectionItemList(queryParams) {
return request({
url: '/data-dictionary/diagnosis-treatment/information-page',
method: 'get',
params: queryParams,
});
}
// ========== 会诊相关接口 ========== // ========== 会诊相关接口 ==========
/** /**
* 获取会诊列表 * 获取会诊列表

View File

@@ -395,7 +395,7 @@
<!-- 右侧项目选择区35% --> <!-- 右侧项目选择区35% -->
<el-col :span="9" class="selection-area"> <el-col :span="9" class="selection-area">
<!-- 检验项目选择区上部50% --> <!-- 检验项目选择区上部50% -->
<el-card class="inspection-selector"> <el-card class="inspection-selector" v-loading="inspectionLoading" element-loading-text="正在加载检验项目...">
<template #header> <template #header>
<span class="card-title">检验项目选择</span> <span class="card-title">检验项目选择</span>
</template> </template>
@@ -413,6 +413,9 @@
<!-- 分类树 --> <!-- 分类树 -->
<el-scrollbar class="category-tree" style="max-height: 280px"> <el-scrollbar class="category-tree" style="max-height: 280px">
<!-- 无数据提示 -->
<el-empty v-if="!inspectionLoading && inspectionCategories.length === 0" description="暂无检验项目数据" :image-size="80" />
<!-- 数据列表 -->
<div <div
v-for="category in inspectionCategories" v-for="category in inspectionCategories"
:key="category.key" :key="category.key"
@@ -487,22 +490,19 @@
</template> </template>
<script setup> <script setup>
import {onMounted, reactive, ref, watch} from 'vue' import {onMounted, reactive, ref, watch, nextTick} from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus' import {ElMessage, ElMessageBox} from 'element-plus'
import { DocumentChecked, Plus, Document, Printer, Delete, Check } from '@element-plus/icons-vue' import { DocumentChecked, Plus, Document, Printer, Delete, Check } from '@element-plus/icons-vue'
import { import {
checkInspectionApplicationNo, checkInspectionApplicationNo,
deleteInspectionApplication, getApplyList, deleteInspectionApplication, getApplyList,
saveInspectionApplication saveInspectionApplication,
getInspectionTypeList,
getInspectionItemList
} from '../api' } from '../api'
import useUserStore from '@/store/modules/user.js' import useUserStore from '@/store/modules/user.js'
import {storeToRefs} from 'pinia' import {storeToRefs} from 'pinia'
// 在 onMounted 中调用初始化函数
onMounted(() => {
initData();
})
// Props // Props
const props = defineProps({ const props = defineProps({
patientInfo: { patientInfo: {
@@ -529,9 +529,12 @@ const userStore = useUserStore()
const { id: userId, name: userName, nickName: userNickName } = storeToRefs(userStore) const { id: userId, name: userName, nickName: userNickName } = storeToRefs(userStore)
// 修改 initData 函数 // 修改 initData 函数
function initData() { async function initData() {
// 然后执行原有的初始化逻辑 console.log('【检验】开始初始化数据当前patientInfo:', props.patientInfo)
if (props.patientInfo) {
// 先初始化患者信息(如果有)
if (props.patientInfo && props.patientInfo.encounterId) {
console.log('【检验】初始化患者信息')
queryParams.encounterId = props.patientInfo.encounterId queryParams.encounterId = props.patientInfo.encounterId
formData.visitNo = props.patientInfo.busNo || '' formData.visitNo = props.patientInfo.busNo || ''
formData.patientId = props.patientInfo.patientId || '' formData.patientId = props.patientInfo.patientId || ''
@@ -544,14 +547,21 @@ function initData() {
formData.applyDeptCode = props.patientInfo.organizationName || '' formData.applyDeptCode = props.patientInfo.organizationName || ''
formData.applyOrganizationId = props.patientInfo.orgId || '' formData.applyOrganizationId = props.patientInfo.orgId || ''
formData.encounterId = props.patientInfo.encounterId formData.encounterId = props.patientInfo.encounterId
console.log('【检验】患者信息初始化完成formData:', JSON.stringify({
patientName: formData.patientName,
medicalrecordNumber: formData.medicalrecordNumber,
applyDepartment: formData.applyDepartment,
applyDocName: formData.applyDocName
}, null, 2))
// 生成申请单号
generateApplicationNo().then((newApplyNo) => { generateApplicationNo().then((newApplyNo) => {
formData.applyNo = newApplyNo; formData.applyNo = newApplyNo;
console.log('【检验】申请单号生成:', newApplyNo)
}); });
} } else {
console.log('【检验】没有有效的patientInfo跳过患者信息初始化')
// 只有在存在 encounterId 时才调用接口
if (queryParams.encounterId) {
getInspectionList()
} }
} }
@@ -567,10 +577,10 @@ const inspectionList = ref([])
// 表单数据 // 表单数据
const formData = reactive({ const formData = reactive({
applyOrganizationId: props.patientInfo.orgId, applyOrganizationId: '',
applicationId: null, applicationId: null,
applyNo: '', applyNo: '',
patientId:'', patientId: '',
patientName: '', patientName: '',
medicalrecordNumber: '', medicalrecordNumber: '',
natureofCost: 'self', natureofCost: 'self',
@@ -596,10 +606,10 @@ const formData = reactive({
auditDoctor: '', auditDoctor: '',
auditTime: null, auditTime: null,
visitNo: '', visitNo: '',
applyDocCode:'', applyDocCode: '',
applyDeptCode: props.patientInfo.organizationName, applyDeptCode: '',
specimenName: '血液', specimenName: '血液',
encounterId: props.patientInfo.encounterId encounterId: ''
}) })
// 表单验证规则 // 表单验证规则
@@ -640,47 +650,173 @@ const selectedInspectionItems = ref([])
const searchKeyword = ref('') const searchKeyword = ref('')
// 活动分类 // 活动分类
const activeCategory = ref('biochemical') const activeCategory = ref('')
// 检验项目分类(树形结构 // 检验项目分类(动态从API获取
let inspectionCategories = ref([ const inspectionCategories = ref([])
{
key: 'biochemical', // 检验项目加载状态
label: '生化', const inspectionLoading = ref(false)
expanded: true,
items: [ // 加载检验项目分类和项目
{ itemId: 1, itemName: '肝功能', itemPrice: 31, itemAmount: 31, sampleType: '血清', unit: 'U/L', itemQty: 1, serviceFee: 0, type: '生化', isSelfPay: false }, async function loadInspectionData() {
{ itemId: 2, itemName: '肾功能', itemPrice: 28, itemAmount: 28, sampleType: '血清', unit: 'U/L', itemQty: 1, serviceFee: 0, type: '生化', isSelfPay: false }, // 如果已经加载过数据,直接返回(避免重复请求)
{ itemId: 3, itemName: '血糖', itemPrice: 15, itemAmount: 15, sampleType: '血清', unit: 'mmol/L', itemQty: 1, serviceFee: 0, type: '生化', isSelfPay: false } if (inspectionCategories.value.length > 0) {
] console.log('【检验】数据已缓存,跳过重复加载')
}, return
{
key: 'blood',
label: '临检',
expanded: false,
items: [
{ itemId: 4, itemName: '血常规+crp', itemPrice: 50, itemAmount: 50, sampleType: '全血', unit: '×10^9/L', itemQty: 1, serviceFee: 0, type: '血液', isSelfPay: false },
{ itemId: 5, itemName: '血常规(五分类)', itemPrice: 15, itemAmount: 15, sampleType: '全血', unit: '×10^9/L', itemQty: 1, serviceFee: 0, type: '血液', isSelfPay: false }
]
},
{
key: 'urine',
label: '尿液',
expanded: false,
items: [
{ itemId: 6, itemName: '尿常规', itemPrice: 20, itemAmount: 20, sampleType: '尿液', unit: '细胞/μl', itemQty: 1, serviceFee: 0, type: '尿液', isSelfPay: false }
]
},
{
key: 'immunity',
label: '免疫',
expanded: false,
items: [
{ itemId: 7, itemName: '总IgE测定', itemPrice: 30, itemAmount: 30, sampleType: '血清', unit: 'IU/ml', itemQty: 1, serviceFee: 0, type: '免疫', isSelfPay: false },
{ itemId: 8, itemName: '风湿', itemPrice: 119, itemAmount: 119, sampleType: '血清', unit: 'U/ml', itemQty: 1, serviceFee: 0, type: '免疫', isSelfPay: false }
]
} }
])
inspectionLoading.value = true
const startTime = Date.now() // 性能监控开始时间
try {
console.log('【检验】开始并行请求数据')
// 并行请求:同时获取检验类型列表和检验项目列表
const [typeRes, itemRes] = await Promise.all([
// 添加错误处理和重试机制
getInspectionTypeList().catch(error => {
console.error('【检验】获取检验类型失败:', error)
return { data: [] } // 返回空数据作为降级方案
}),
getInspectionItemList({
pageNo: 1,
pageSize: 200, // 进一步优化:减少数据量,按需加载
searchKey: '', // 添加搜索关键词参数
categoryCode: 'inspection' // 明确指定检验类别
}).catch(error => {
console.error('【检验】获取检验项目失败:', error)
return { data: { records: [] } } // 返回空数据作为降级方案
})
])
const endTime = Date.now()
console.log(`【检验】API请求完成耗时: ${endTime - startTime}ms`)
const typeList = typeRes.data || []
console.log('【检验】获取到检验类型数量:', typeList.length)
// 解析检验项目数据
let allItems = []
if (itemRes.data && itemRes.data.records) {
allItems = itemRes.data.records
} else if (itemRes.data && Array.isArray(itemRes.data)) {
allItems = itemRes.data
} else if (Array.isArray(itemRes)) {
allItems = itemRes
}
console.log('【检验】获取到检验项目数量:', allItems.length)
// 按分类组织数据
const categories = typeList
.filter(type => type.validFlag === 1 || type.validFlag === undefined)
.map((type, index) => {
const categoryItems = allItems
.filter(item => {
const isInspection = item.categoryCode_dictText === '检验' ||
item.categoryName === '检验' ||
item.categoryCode === 'inspection'
const matchType = item.typeName === type.name ||
item.inspectionTypeName === type.name ||
item.bigClassName === type.name ||
item.typeCode === type.code
return isInspection && (matchType || typeList.length === 1)
})
.map(item => ({
itemId: item.id || item.activityId || Math.random().toString(36).substr(2, 9),
itemName: item.name || item.itemName || '',
itemPrice: item.retailPrice || item.price || 0,
itemAmount: item.retailPrice || item.price || 0,
sampleType: item.sampleType || '血液',
unit: item.unit || '',
itemQty: 1,
serviceFee: 0,
type: type.name,
isSelfPay: false,
activityId: item.activityId,
code: item.code || item.activityCode
}))
return {
key: type.code || `type_${index}`,
label: type.name || `分类${index + 1}`,
expanded: index === 0,
items: categoryItems
}
})
// 如果没有分类数据,但有项目数据,创建一个默认分类
if (categories.length === 0 && allItems.length > 0) {
const defaultItems = allItems
.filter(item => item.categoryCode_dictText === '检验' ||
item.categoryName === '检验' ||
item.categoryCode === 'inspection' ||
true)
.slice(0, 50) // 优化:增加默认显示数量
.map(item => ({
itemId: item.id || item.activityId || Math.random().toString(36).substr(2, 9),
itemName: item.name || item.itemName || '',
itemPrice: item.retailPrice || item.price || 0,
itemAmount: item.retailPrice || item.price || 0,
sampleType: item.sampleType || '血液',
unit: item.unit || '',
itemQty: 1,
serviceFee: 0,
type: '检验',
isSelfPay: false,
activityId: item.activityId,
code: item.code || item.activityCode
}))
if (defaultItems.length > 0) {
categories.push({
key: 'default',
label: '检验项目',
expanded: true,
items: defaultItems
})
}
}
// 过滤掉没有项目的分类
const validCategories = categories.filter(cat => cat.items.length > 0)
if (validCategories.length > 0) {
inspectionCategories.value = validCategories
activeCategory.value = validCategories[0].key
} else {
throw new Error('未获取到有效的检验项目数据')
}
} catch (error) {
console.error('加载检验项目数据失败:', error)
// 加载失败时使用静态数据作为备用
inspectionCategories.value = [
{
key: 'biochemical',
label: '生化',
expanded: true,
items: [
{ itemId: 1, itemName: '肝功能', itemPrice: 31, itemAmount: 31, sampleType: '血清', unit: 'U/L', itemQty: 1, serviceFee: 0, type: '生化', isSelfPay: false },
{ itemId: 2, itemName: '肾功能', itemPrice: 28, itemAmount: 28, sampleType: '血清', unit: 'U/L', itemQty: 1, serviceFee: 0, type: '生化', isSelfPay: false },
{ itemId: 3, itemName: '血糖', itemPrice: 15, itemAmount: 15, sampleType: '血清', unit: 'mmol/L', itemQty: 1, serviceFee: 0, type: '生化', isSelfPay: false }
]
},
{
key: 'blood',
label: '临检',
expanded: false,
items: [
{ itemId: 4, itemName: '血常规+crp', itemPrice: 50, itemAmount: 50, sampleType: '全血', unit: '×10^9/L', itemQty: 1, serviceFee: 0, type: '血液', isSelfPay: false },
{ itemId: 5, itemName: '血常规(五分类)', itemPrice: 15, itemAmount: 15, sampleType: '全血', unit: '×10^9/L', itemQty: 1, serviceFee: 0, type: '血液', isSelfPay: false }
]
}
]
activeCategory.value = 'biochemical'
} finally {
inspectionLoading.value = false
}
}
// 获取过滤后的项目 // 获取过滤后的项目
const getFilteredItems = (categoryKey) => { const getFilteredItems = (categoryKey) => {
@@ -1374,23 +1510,30 @@ function handleCellClick(row, column) {
watch(() => props.activeTab, async (newVal) => { watch(() => props.activeTab, async (newVal) => {
if (newVal === 'inspection') { if (newVal === 'inspection') {
await initData() await initData()
// 默认展开生化分类 // 根据动态加载的分类设置默认展开
activeCategory.value = 'biochemical' if (inspectionCategories.value.length > 0) {
inspectionCategories.value.forEach(cat => { // 展开第一个分类
cat.expanded = cat.key === 'biochemical' activeCategory.value = inspectionCategories.value[0].key
}) inspectionCategories.value.forEach((cat, index) => {
cat.expanded = index === 0
})
}
} }
}) })
// 监听patientInfo变化,确保encounterId及时更新并重新加载数据 // 监听patientInfo变化,确保encounterId及时更新并重新加载数据
watch(() => props.patientInfo, async (newVal) => { watch(() => props.patientInfo, async (newVal) => {
// console.log('【检验】patientInfo变化:', newVal) console.log('【检验】patientInfo变化:', newVal)
console.log('【检验】接收到的完整patientInfo:', JSON.stringify(newVal, null, 2)) console.log('【检验】接收到的完整patientInfo:', JSON.stringify(newVal, null, 2))
if (newVal && newVal.encounterId) { if (newVal && newVal.encounterId) {
const oldEncounterId = queryParams.encounterId const oldEncounterId = queryParams.encounterId
queryParams.encounterId = newVal.encounterId queryParams.encounterId = newVal.encounterId
// console.log('【检验】更新encounterId:', queryParams.encounterId) console.log('【检验】更新encounterId:', queryParams.encounterId)
// 初始化数据
await initData();
// 如果encounterId发生变化重新加载检验申请单列表 // 如果encounterId发生变化重新加载检验申请单列表
if (oldEncounterId !== newVal.encounterId) { if (oldEncounterId !== newVal.encounterId) {
getInspectionList() getInspectionList()
@@ -1411,10 +1554,11 @@ watch(() => selectedInspectionItems.value, (newVal) => {
} }
}, { deep: true }) }, { deep: true })
// 初始化 // 组件挂载时预加载检验项目数据不依赖patientInfo
onMounted(async () => { onMounted(async () => {
await initData(); console.log('【检验】组件挂载,开始预加载检验项目数据')
getInspectionList(); await loadInspectionData()
console.log('【检验】检验项目数据预加载完成')
}) })
// 暴露方法 // 暴露方法
@@ -1523,6 +1667,7 @@ defineExpose({
border-top: 1px solid var(--el-border-color-light); border-top: 1px solid var(--el-border-color-light);
} }
:deep(.el-pagination) { :deep(.el-pagination) {
.el-pager li { .el-pager li {
border-radius: 4px; border-radius: 4px;