1. 在ActivityDefinition实体类及相关DTO中添加inspectionTypeId字段
2. 新增检验类型分页查询接口及前端API调用 3. 优化检验申请模块的前后端交互逻辑 4.完成修改78 增加门诊医生开立检验申请单立检验申请单的检验项目写死的问题 5.对检验目录设置的查询,更新和保存进行修改完善。 6.对检验项目设置的页面使用vue3+elementui进行修改。
This commit is contained in:
@@ -193,6 +193,13 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
|
||||
DiagnosisTreatmentSelParam.setYbType(null); // 临时移除,防止HisQueryUtils处理
|
||||
}
|
||||
|
||||
// 临时保存inspectionTypeId值,手动添加带表别名的条件
|
||||
Long inspectionTypeIdValue = null;
|
||||
if (DiagnosisTreatmentSelParam != null && DiagnosisTreatmentSelParam.getInspectionTypeId() != null) {
|
||||
inspectionTypeIdValue = DiagnosisTreatmentSelParam.getInspectionTypeId();
|
||||
DiagnosisTreatmentSelParam.setInspectionTypeId(null); // 临时移除,防止HisQueryUtils处理
|
||||
}
|
||||
|
||||
// 构建查询条件
|
||||
QueryWrapper<DiagnosisTreatmentDto> queryWrapper = HisQueryUtils.buildQueryWrapper(DiagnosisTreatmentSelParam,
|
||||
searchKey, new HashSet<>(Arrays.asList("bus_no", "name", "py_str", "wb_str")), request);
|
||||
@@ -204,6 +211,13 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
|
||||
DiagnosisTreatmentSelParam.setYbType(ybTypeValue);
|
||||
}
|
||||
|
||||
// 如果需要按检验类型过滤,添加带表别名的条件
|
||||
if (inspectionTypeIdValue != null) {
|
||||
queryWrapper.eq("T1.inspection_type_id", inspectionTypeIdValue);
|
||||
// 恢复参数对象中的值
|
||||
DiagnosisTreatmentSelParam.setInspectionTypeId(inspectionTypeIdValue);
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
IPage<DiagnosisTreatmentDto> diseaseTreatmentPage
|
||||
= activityDefinitionManageMapper.getDiseaseTreatmentPage(new Page<DiagnosisTreatmentDto>(pageNo, pageSize), queryWrapper);
|
||||
@@ -336,6 +350,8 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
|
||||
// 显式设置新增的字段
|
||||
activityDefinition.setSortOrder(diagnosisTreatmentUpDto.getSortOrder());
|
||||
activityDefinition.setServiceRange(diagnosisTreatmentUpDto.getServiceRange());
|
||||
// 显式设置检验类型ID
|
||||
activityDefinition.setInspectionTypeId(diagnosisTreatmentUpDto.getInspectionTypeId());
|
||||
// 显式设置划价标记(避免前端字段/类型差异导致 copyProperties 后仍为默认值)
|
||||
activityDefinition.setPricingFlag(diagnosisTreatmentUpDto.getPricingFlag());
|
||||
|
||||
@@ -479,11 +495,13 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
|
||||
|
||||
ActivityDefinition activityDefinition = new ActivityDefinition();
|
||||
BeanUtils.copyProperties(diagnosisTreatmentUpDto, activityDefinition);
|
||||
|
||||
|
||||
// 显式设置新增的字段
|
||||
activityDefinition.setSortOrder(diagnosisTreatmentUpDto.getSortOrder());
|
||||
activityDefinition.setServiceRange(diagnosisTreatmentUpDto.getServiceRange());
|
||||
|
||||
// 显式设置检验类型ID
|
||||
activityDefinition.setInspectionTypeId(diagnosisTreatmentUpDto.getInspectionTypeId());
|
||||
|
||||
// 如果前端没有传入编码,则使用10位数基础采番
|
||||
if (StringUtils.isEmpty(activityDefinition.getBusNo())) {
|
||||
String code = assignSeqUtil.getSeq(AssignSeqEnum.ACTIVITY_DEFINITION_NUM.getPrefix(), 10);
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package com.openhis.web.datadictionary.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.lab.domain.InspectionType;
|
||||
import com.openhis.lab.service.IInspectionTypeService;
|
||||
import com.openhis.web.datadictionary.appservice.IDiagTreatMAppService;
|
||||
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentSelParam;
|
||||
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentUpDto;
|
||||
@@ -30,6 +33,9 @@ public class DiagnosisTreatmentController {
|
||||
@Resource
|
||||
private IDiagTreatMAppService diagTreatMAppService;
|
||||
|
||||
@Resource
|
||||
private IInspectionTypeService inspectionTypeService;
|
||||
|
||||
/**
|
||||
* 诊疗目录初期查询
|
||||
*
|
||||
@@ -188,4 +194,17 @@ public class DiagnosisTreatmentController {
|
||||
public R<?> updatePricingFlag(@RequestBody List<Long> ids, @RequestParam Integer pricingFlag) {
|
||||
return diagTreatMAppService.updatePricingFlag(ids, pricingFlag);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取检验类型列表(用于下拉框)
|
||||
*
|
||||
* @return 检验类型列表
|
||||
*/
|
||||
@GetMapping("/inspection-types")
|
||||
public R<?> getInspectionTypes() {
|
||||
LambdaQueryWrapper<InspectionType> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(InspectionType::getValidFlag, 1)
|
||||
.orderByAsc(InspectionType::getSortOrder);
|
||||
return R.ok(inspectionTypeService.list(queryWrapper));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,4 +130,13 @@ public class DiagnosisTreatmentDto {
|
||||
|
||||
/** 服务范围 */
|
||||
private String serviceRange;
|
||||
|
||||
/** 检验类型ID */
|
||||
@Dict(dictTable = "inspection_type", dictCode = "id", dictText = "name", deleteFlag = "valid_flag")
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long inspectionTypeId;
|
||||
private String inspectionTypeId_dictText;
|
||||
|
||||
/** 检验类型名称(用于前端 testType 字段) */
|
||||
private String testType;
|
||||
}
|
||||
|
||||
@@ -30,4 +30,7 @@ public class DiagnosisTreatmentSelParam {
|
||||
|
||||
/** 状态 */
|
||||
private Integer statusEnum;
|
||||
|
||||
/** 检验类型ID */
|
||||
private Long inspectionTypeId;
|
||||
}
|
||||
|
||||
@@ -128,4 +128,8 @@ public class DiagnosisTreatmentUpDto {
|
||||
|
||||
/** 服务范围 */
|
||||
private String serviceRange;
|
||||
|
||||
/** 检验类型ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long inspectionTypeId;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.openhis.web.lab.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.core.common.core.controller.BaseController;
|
||||
import com.core.common.core.domain.AjaxResult;
|
||||
import com.openhis.lab.domain.InspectionType;
|
||||
@@ -29,7 +30,25 @@ public class InspectionTypeController extends BaseController {
|
||||
private final TransactionTemplate transactionTemplate;
|
||||
|
||||
/**
|
||||
* 获取检验类型列表
|
||||
* 分页获取检验类型列表
|
||||
*
|
||||
* @param pageNo 页码
|
||||
* @param pageSize 每页数量
|
||||
* @param searchKey 搜索关键词
|
||||
*/
|
||||
@GetMapping("/page")
|
||||
public AjaxResult getPage(
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "100") Integer pageSize,
|
||||
@RequestParam(value = "searchKey", required = false) String searchKey) {
|
||||
log.info("【检验类型】分页查询请求 - pageNo: {}, pageSize: {}, searchKey: {}", pageNo, pageSize, searchKey);
|
||||
IPage<InspectionType> result = inspectionTypeService.getPage(pageNo, pageSize, searchKey);
|
||||
log.info("【检验类型】分页查询完成 - 总记录数: {}, 当前页记录数: {}", result.getTotal(), result.getRecords().size());
|
||||
return AjaxResult.success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取检验类型列表(不分页,兼容旧接口)
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public AjaxResult list(InspectionType inspectionType) {
|
||||
|
||||
@@ -30,16 +30,22 @@
|
||||
T1.pricing_flag,
|
||||
T1.sort_order,
|
||||
T1.service_range,
|
||||
T1.inspection_type_id,
|
||||
T2.type_code as item_type_code,
|
||||
T2.yb_type,
|
||||
T2.price_code,
|
||||
T2.price as retail_price,
|
||||
T4.amount as maximum_retail_price
|
||||
T4.amount as maximum_retail_price,
|
||||
T3.name as test_type
|
||||
FROM wor_activity_definition T1
|
||||
/* 只JOIN必要的价格表,使用INNER JOIN避免笛卡尔积 */
|
||||
INNER JOIN adm_charge_item_definition T2
|
||||
ON T1.id = T2.instance_id
|
||||
AND T2.instance_table = 'wor_activity_definition'
|
||||
/* 检验类型关联 */
|
||||
LEFT JOIN inspection_type T3
|
||||
ON T1.inspection_type_id = T3.id
|
||||
AND T3.valid_flag = 1
|
||||
/* 最高零售价使用LEFT JOIN,因为可能不存在 */
|
||||
LEFT JOIN adm_charge_item_def_detail T4
|
||||
ON T4.definition_id = T2.id
|
||||
@@ -97,9 +103,13 @@
|
||||
T1.children_json,
|
||||
T1.pricing_flag,
|
||||
T1.sort_order,
|
||||
T1.service_range
|
||||
T1.service_range,
|
||||
T1.inspection_type_id,
|
||||
T3.name as test_type
|
||||
FROM wor_activity_definition T1
|
||||
LEFT JOIN adm_charge_item_definition T2 ON T1.id = T2.instance_id
|
||||
/* 检验类型关联 */
|
||||
LEFT JOIN inspection_type T3 ON T1.inspection_type_id = T3.id AND T3.valid_flag = 1
|
||||
<where>
|
||||
T1.delete_flag = '0'
|
||||
AND T2.instance_table = 'wor_activity_definition'
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.openhis.lab.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.openhis.lab.domain.InspectionType;
|
||||
|
||||
@@ -11,4 +13,13 @@ import com.openhis.lab.domain.InspectionType;
|
||||
*/
|
||||
public interface IInspectionTypeService extends IService<InspectionType> {
|
||||
|
||||
/**
|
||||
* 分页查询检验类型列表
|
||||
*
|
||||
* @param pageNo 页码
|
||||
* @param pageSize 每页数量
|
||||
* @param searchKey 搜索关键词(可选)
|
||||
* @return 分页结果
|
||||
*/
|
||||
IPage<InspectionType> getPage(Integer pageNo, Integer pageSize, String searchKey);
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
package com.openhis.lab.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.openhis.lab.domain.InspectionType;
|
||||
import com.openhis.lab.mapper.InspectionTypeMapper;
|
||||
import com.openhis.lab.service.IInspectionTypeService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* 检验类型Service实现类
|
||||
@@ -15,4 +19,22 @@ import org.springframework.stereotype.Service;
|
||||
@Service
|
||||
public class InspectionTypeServiceImpl extends ServiceImpl<InspectionTypeMapper, InspectionType> implements IInspectionTypeService {
|
||||
|
||||
@Override
|
||||
public IPage<InspectionType> getPage(Integer pageNo, Integer pageSize, String searchKey) {
|
||||
Page<InspectionType> page = new Page<>(pageNo, pageSize);
|
||||
LambdaQueryWrapper<InspectionType> queryWrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
// 搜索关键词(按编码或名称模糊查询)
|
||||
if (StringUtils.hasText(searchKey)) {
|
||||
queryWrapper.and(wrapper -> wrapper
|
||||
.like(InspectionType::getCode, searchKey)
|
||||
.or()
|
||||
.like(InspectionType::getName, searchKey));
|
||||
}
|
||||
|
||||
// 按排序字段升序排列
|
||||
queryWrapper.orderByAsc(InspectionType::getSortOrder);
|
||||
|
||||
return this.page(page, queryWrapper);
|
||||
}
|
||||
}
|
||||
@@ -89,4 +89,7 @@ public class ActivityDefinition extends HisBaseEntity {
|
||||
|
||||
/** 服务范围 */
|
||||
private String serviceRange;
|
||||
|
||||
/** 检验类型ID(关联 inspection_type 表) */
|
||||
private Long inspectionTypeId;
|
||||
}
|
||||
@@ -949,7 +949,23 @@ export function deleteInspectionApplication(applyNo) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取检验类型列表(分类)
|
||||
* 分页获取检验类型列表(分类)
|
||||
* @param {Object} queryParams - 查询参数
|
||||
* @param {number} queryParams.pageNo - 页码
|
||||
* @param {number} queryParams.pageSize - 每页数量
|
||||
* @param {string} queryParams.searchKey - 搜索关键词
|
||||
*/
|
||||
export function getInspectionTypePage(queryParams) {
|
||||
return request({
|
||||
url: '/system/inspection-type/page',
|
||||
method: 'get',
|
||||
params: queryParams,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取检验类型列表(不分页,兼容旧接口)
|
||||
* @deprecated 建议使用 getInspectionTypePage 分页接口
|
||||
*/
|
||||
export function getInspectionTypeList() {
|
||||
return request({
|
||||
@@ -965,6 +981,7 @@ export function getInspectionTypeList() {
|
||||
* @param {number} queryParams.pageNo - 页码
|
||||
* @param {number} queryParams.pageSize - 每页数量
|
||||
* @param {string} queryParams.categoryCode - 目录类别编码(检验)
|
||||
* @param {string} queryParams.inspectionTypeId - 检验类型ID列表,多个用逗号分隔
|
||||
*/
|
||||
export function getInspectionItemList(queryParams) {
|
||||
return request({
|
||||
|
||||
@@ -490,7 +490,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {onMounted, reactive, ref, watch, nextTick} from 'vue'
|
||||
import {onMounted, reactive, ref, watch, computed, getCurrentInstance} from 'vue'
|
||||
import {ElMessage, ElMessageBox} from 'element-plus'
|
||||
import { DocumentChecked, Plus, Document, Printer, Delete, Check } from '@element-plus/icons-vue'
|
||||
import {
|
||||
@@ -502,9 +502,20 @@ import {
|
||||
} from '../api'
|
||||
import useUserStore from '@/store/modules/user.js'
|
||||
// 迁移到 hiprint
|
||||
import { simplePrint, PRINT_TEMPLATE, previewPrint } from '@/utils/printUtils.js'
|
||||
import { previewPrint } from '@/utils/printUtils.js'
|
||||
import {storeToRefs} from 'pinia'
|
||||
|
||||
// 获取当前组件实例和字典
|
||||
const { proxy } = getCurrentInstance()
|
||||
const { activity_category_code } = proxy.useDict('activity_category_code')
|
||||
|
||||
// 获取"检验"分类的字典值(与检验项目设置维护保持一致)
|
||||
const inspectionCategoryCode = computed(() => {
|
||||
const dictList = activity_category_code.value
|
||||
const inspectionItem = dictList?.find(item => item.label === '检验')
|
||||
return inspectionItem?.value || '22' // 默认使用数据库中检验的 category_code 值
|
||||
})
|
||||
|
||||
// Props
|
||||
const props = defineProps({
|
||||
patientInfo: {
|
||||
@@ -520,7 +531,6 @@ const props = defineProps({
|
||||
const emit = defineEmits(['save'])
|
||||
|
||||
// 响应式数据
|
||||
const showForm = ref(false)
|
||||
const loading = ref(false)
|
||||
const total = ref(0)
|
||||
const leftActiveTab = ref('application')
|
||||
@@ -532,11 +542,8 @@ const { id: userId, name: userName, nickName: userNickName } = storeToRefs(userS
|
||||
|
||||
// 修改 initData 函数
|
||||
async function initData() {
|
||||
console.log('【检验】开始初始化数据,当前patientInfo:', props.patientInfo)
|
||||
|
||||
// 先初始化患者信息(如果有)
|
||||
if (props.patientInfo && props.patientInfo.encounterId) {
|
||||
console.log('【检验】初始化患者信息')
|
||||
queryParams.encounterId = props.patientInfo.encounterId
|
||||
formData.visitNo = props.patientInfo.busNo || ''
|
||||
formData.patientId = props.patientInfo.patientId || ''
|
||||
@@ -550,20 +557,10 @@ async function initData() {
|
||||
formData.applyOrganizationId = props.patientInfo.orgId || ''
|
||||
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) => {
|
||||
formData.applyNo = newApplyNo;
|
||||
console.log('【检验】申请单号生成:', newApplyNo)
|
||||
});
|
||||
} else {
|
||||
console.log('【检验】没有有效的patientInfo,跳过患者信息初始化')
|
||||
formData.applyNo = newApplyNo
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -614,18 +611,6 @@ const formData = reactive({
|
||||
encounterId: ''
|
||||
})
|
||||
|
||||
// 表单验证规则
|
||||
const formRules = {
|
||||
natureofCost: [{ required: true, message: '请选择费用性质', trigger: 'change' }],
|
||||
applyTime: [{ required: true, message: '请选择申请日期', trigger: 'change' }],
|
||||
executeDepartment: [{ required: true, message: '请选择执行科室', trigger: 'change' }],
|
||||
clinicDesc: [{ required: true, message: '请输入诊断描述', trigger: 'blur' }],
|
||||
clinicDiag: [{ required: true, message: '请输入临床诊断', trigger: 'blur' }],
|
||||
medicalHistorySummary: [{ required: true, message: '请输入病史摘要', trigger: 'blur' }],
|
||||
purposeofInspection: [{ required: true, message: '请输入检验目的', trigger: 'blur' }],
|
||||
labApplyItemList: [{ required: true, message: '请至少选择一个检验项目', trigger: 'change' }]
|
||||
}
|
||||
|
||||
// 表单引用
|
||||
const formRef = ref()
|
||||
|
||||
@@ -664,39 +649,30 @@ const inspectionLoading = ref(false)
|
||||
async function loadInspectionData() {
|
||||
// 如果已经加载过数据,直接返回(避免重复请求)
|
||||
if (inspectionCategories.value.length > 0) {
|
||||
console.log('【检验】数据已缓存,跳过重复加载')
|
||||
return
|
||||
}
|
||||
|
||||
inspectionLoading.value = true
|
||||
const startTime = Date.now() // 性能监控开始时间
|
||||
|
||||
|
||||
try {
|
||||
console.log('【检验】开始并行请求数据')
|
||||
|
||||
// 并行请求:同时获取检验类型列表和检验项目列表
|
||||
const [typeRes, itemRes] = await Promise.all([
|
||||
// 添加错误处理和重试机制
|
||||
getInspectionTypeList().catch(error => {
|
||||
console.error('【检验】获取检验类型失败:', error)
|
||||
return { data: [] } // 返回空数据作为降级方案
|
||||
console.error('获取检验类型失败:', error)
|
||||
return { data: [] }
|
||||
}),
|
||||
getInspectionItemList({
|
||||
pageNo: 1,
|
||||
pageSize: 200, // 进一步优化:减少数据量,按需加载
|
||||
searchKey: '', // 添加搜索关键词参数
|
||||
categoryCode: 'inspection' // 明确指定检验类别
|
||||
getInspectionItemList({
|
||||
pageNo: 1,
|
||||
pageSize: 500,
|
||||
searchKey: '',
|
||||
categoryCode: inspectionCategoryCode.value
|
||||
}).catch(error => {
|
||||
console.error('【检验】获取检验项目失败:', error)
|
||||
return { data: { records: [] } } // 返回空数据作为降级方案
|
||||
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 = []
|
||||
@@ -708,40 +684,39 @@ async function loadInspectionData() {
|
||||
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 ||
|
||||
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)
|
||||
// 转换为字符串进行比较,避免类型不匹配问题
|
||||
const itemTypeId = String(item.inspectionTypeId || '')
|
||||
const typeId = String(type.id || '')
|
||||
const itemTypeName = String(item.inspectionTypeId_dictText || item.typeName || '').trim()
|
||||
const typeName = String(type.name || '').trim()
|
||||
|
||||
// 按检验类型ID匹配(优先使用 inspectionTypeId)
|
||||
const matchById = itemTypeId && typeId && itemTypeId === typeId
|
||||
const matchByName = itemTypeName && typeName && itemTypeName === typeName
|
||||
const matchByCode = String(item.typeCode || '') === String(type.code || '')
|
||||
|
||||
return matchById || matchByName || matchByCode
|
||||
})
|
||||
.map(item => ({
|
||||
itemId: item.id || item.activityId || Math.random().toString(36).substr(2, 9),
|
||||
itemId: item.id || item.activityId || Math.random().toString(36).substring(2, 11),
|
||||
itemName: item.name || item.itemName || '',
|
||||
itemPrice: item.retailPrice || item.price || 0,
|
||||
itemAmount: item.retailPrice || item.price || 0,
|
||||
sampleType: item.sampleType || '血液',
|
||||
sampleType: item.specimenCode_dictText || item.sampleType || '血液',
|
||||
unit: item.unit || '',
|
||||
itemQty: 1,
|
||||
serviceFee: 0,
|
||||
type: type.name,
|
||||
type: type.name || item.inspectionTypeId_dictText || '检验',
|
||||
isSelfPay: false,
|
||||
activityId: item.activityId,
|
||||
code: item.code || item.activityCode
|
||||
code: item.busNo || item.code || item.activityCode,
|
||||
inspectionTypeId: item.inspectionTypeId || null
|
||||
}))
|
||||
|
||||
return {
|
||||
@@ -755,41 +730,50 @@ async function loadInspectionData() {
|
||||
// 过滤掉没有项目的分类
|
||||
const validCategories = categories.filter(cat => cat.items.length > 0)
|
||||
|
||||
// 如果没有有效分类,但有项目数据,创建一个默认分类
|
||||
// 如果没有有效分类,但有项目数据,按项目自带的检验类型文本分组
|
||||
if (validCategories.length === 0 && allItems.length > 0) {
|
||||
const defaultItems = allItems
|
||||
.slice(0, 50) // 优化:限制显示数量
|
||||
.map(item => ({
|
||||
itemId: item.id || item.activityId || Math.random().toString(36).substr(2, 9),
|
||||
// 按检验类型文本分组
|
||||
const typeMap = new Map()
|
||||
allItems.forEach(item => {
|
||||
const typeName = item.inspectionTypeId_dictText || '其他检验'
|
||||
if (!typeMap.has(typeName)) {
|
||||
typeMap.set(typeName, [])
|
||||
}
|
||||
typeMap.get(typeName).push(item)
|
||||
})
|
||||
|
||||
// 创建分类
|
||||
typeMap.forEach((items, typeName) => {
|
||||
const mappedItems = items.map(item => ({
|
||||
itemId: item.id || item.activityId || Math.random().toString(36).substring(2, 11),
|
||||
itemName: item.name || item.itemName || '',
|
||||
itemPrice: item.retailPrice || item.price || 0,
|
||||
itemAmount: item.retailPrice || item.price || 0,
|
||||
sampleType: item.sampleType || '血液',
|
||||
sampleType: item.specimenCode_dictText || item.sampleType || '血液',
|
||||
unit: item.unit || '',
|
||||
itemQty: 1,
|
||||
serviceFee: 0,
|
||||
type: '检验',
|
||||
type: typeName,
|
||||
isSelfPay: false,
|
||||
activityId: item.activityId,
|
||||
code: item.code || item.activityCode
|
||||
code: item.busNo || item.code || item.activityCode,
|
||||
inspectionTypeId: item.inspectionTypeId || null
|
||||
}))
|
||||
|
||||
if (defaultItems.length > 0) {
|
||||
validCategories.push({
|
||||
key: 'default',
|
||||
label: '检验项目',
|
||||
expanded: true,
|
||||
items: defaultItems
|
||||
key: `type_${typeName}`,
|
||||
label: typeName,
|
||||
expanded: validCategories.length === 0,
|
||||
items: mappedItems
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (validCategories.length > 0) {
|
||||
inspectionCategories.value = validCategories
|
||||
activeCategory.value = validCategories[0].key
|
||||
console.log('【检验】数据加载成功,分类数量:', validCategories.length)
|
||||
} else {
|
||||
console.warn('【检验】未获取到有效的检验项目数据,使用备用数据')
|
||||
console.warn('未获取到有效的检验项目数据,使用备用数据')
|
||||
// 直接使用备用数据,不抛出错误
|
||||
inspectionCategories.value = [
|
||||
{
|
||||
@@ -864,14 +848,11 @@ const getFilteredItems = (categoryKey) => {
|
||||
function getInspectionList() {
|
||||
// 如果没有encounterId,不调用接口
|
||||
if (!queryParams.encounterId) {
|
||||
// console.warn('【检验】encounterId为空,不调用接口')
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
|
||||
// 调用分页API,传递分页参数和 encounterId
|
||||
// console.log('【检验】调用API,encounterId:', queryParams.encounterId, 'pageNo:', queryParams.pageNo, 'pageSize:', queryParams.pageSize)
|
||||
getApplyList({
|
||||
encounterId: queryParams.encounterId,
|
||||
pageNo: queryParams.pageNo,
|
||||
@@ -885,7 +866,7 @@ function getInspectionList() {
|
||||
// 处理数据:将同一个申请单的多个明细合并成一条记录
|
||||
inspectionList.value = mergeInspectionApplyRecords(res.data.records)
|
||||
total.value = res.data.total || 0
|
||||
}
|
||||
}
|
||||
// 如果返回的是普通数组
|
||||
else if (Array.isArray(res.data)) {
|
||||
// 处理数据:将同一个申请单的多个明细合并成一条记录
|
||||
@@ -901,14 +882,12 @@ function getInspectionList() {
|
||||
inspectionList.value = []
|
||||
total.value = 0
|
||||
}
|
||||
// console.log('【检验】获取数据成功,数量:', inspectionList.value.length, '总数:', total.value)
|
||||
} else {
|
||||
inspectionList.value = []
|
||||
total.value = 0
|
||||
ElMessage.error(res.message || '获取检验申请单列表失败')
|
||||
}
|
||||
}).catch((error) => {
|
||||
// console.error('获取检验申请单列表异常:', error)
|
||||
inspectionList.value = []
|
||||
total.value = 0
|
||||
ElMessage.error('获取检验申请单列表异常: ' + (error.message || ''))
|
||||
@@ -959,7 +938,6 @@ function formatAmount(amount) {
|
||||
|
||||
// 新增申请单
|
||||
async function handleNewApplication() {
|
||||
// console.log('点击新增按钮')
|
||||
resetForm()
|
||||
// 生成新的申请单号
|
||||
formData.applyNo = await generateApplicationNo()
|
||||
@@ -977,15 +955,11 @@ const checkApplicationNoExists = async (applyNo) => {
|
||||
// 后端返回格式:如果存在返回{applyNo: "..."},不存在返回null
|
||||
return response.code === 200 && response.data && response.data.applyNo;
|
||||
} catch (error) {
|
||||
// 隐藏具体的错误信息,仅记录在控制台
|
||||
console.debug('检查申请单号时发生错误:', error.message);
|
||||
// 如果API调用失败,假设单号不存在以避免阻塞
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// 生成申请单号
|
||||
let counter = 0;
|
||||
const generateApplicationNo = async () => {
|
||||
let applyNo;
|
||||
let isUnique = false;
|
||||
@@ -1028,8 +1002,6 @@ const generateApplicationNo = async () => {
|
||||
}
|
||||
|
||||
if (!isUnique) {
|
||||
console.warn(`经过${maxAttempts}次尝试仍未生成唯一申请单号,使用备用方案`);
|
||||
// 如果多次尝试后仍无法生成唯一单号,使用UUID的一部分作为备用方案
|
||||
const timestamp = Date.now().toString();
|
||||
const randomPart = Math.floor(Math.random() * 1000).toString().padStart(3, '0');
|
||||
const fallbackNo = 'F' + timestamp.slice(-17) + randomPart; // 使用F开头表示备用方案
|
||||
@@ -1080,12 +1052,6 @@ async function resetForm() {
|
||||
formRef.value?.clearValidate()
|
||||
}
|
||||
|
||||
// 返回列表
|
||||
function handleBack() {
|
||||
showForm.value = false
|
||||
getInspectionList()
|
||||
}
|
||||
|
||||
// 保存
|
||||
function handleSave() {
|
||||
// 重置验证错误状态
|
||||
@@ -1153,8 +1119,6 @@ function handleSave() {
|
||||
|
||||
|
||||
// 先检查申请单号是否已存在
|
||||
console.log('查询申请单号:', formData.applyNo)
|
||||
// 如果正在生成新申请单号,则跳过重复检查,直接保存
|
||||
if (isGeneratingNewApplyNo.value) {
|
||||
// 正在使用新生成的单号,直接保存
|
||||
isGeneratingNewApplyNo.value = false; // 重置标志
|
||||
@@ -1217,10 +1181,8 @@ function handleSave() {
|
||||
})
|
||||
|
||||
}
|
||||
// 执行保存操作
|
||||
const executeSave = (saveData) => {
|
||||
saveInspectionApplication(saveData).then((res) => {
|
||||
console.log('保存检验申请单结果:', res.code)
|
||||
if (res.code === 200) {
|
||||
ElMessage.success('保存成功')
|
||||
resetForm()
|
||||
@@ -1253,22 +1215,8 @@ const executeSave = (saveData) => {
|
||||
}
|
||||
|
||||
|
||||
// 表单保存
|
||||
function handleFormSave() {
|
||||
formRef.value?.validate((valid) => {
|
||||
if (valid) {
|
||||
formData.labApplyItemList = selectedInspectionItems.value.map(item => item.itemId)
|
||||
// console.log('保存检验申请单表单数据:', formData)
|
||||
ElMessage.success('保存成功')
|
||||
showForm.value = false
|
||||
getInspectionList()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 查看详情
|
||||
function handleView(row) {
|
||||
// console.log('点击查看按钮,数据:', row)
|
||||
// 加载表单数据
|
||||
Object.assign(formData, row)
|
||||
|
||||
@@ -1307,8 +1255,7 @@ function switchCategory(category) {
|
||||
|
||||
// 处理搜索
|
||||
function handleSearch() {
|
||||
// 搜索逻辑已在getFilteredItems中实现,这里可以添加额外的搜索逻辑
|
||||
// console.log('搜索关键词:', searchKeyword.value)
|
||||
// 搜索逻辑已在getFilteredItems中实现
|
||||
}
|
||||
|
||||
// 处理项目项点击(排除勾选框点击)
|
||||
@@ -1497,13 +1444,9 @@ watch(() => props.activeTab, async (newVal) => {
|
||||
|
||||
// 监听patientInfo变化,确保encounterId及时更新并重新加载数据
|
||||
watch(() => props.patientInfo, async (newVal) => {
|
||||
console.log('【检验】patientInfo变化:', newVal)
|
||||
console.log('【检验】接收到的完整patientInfo:', JSON.stringify(newVal, null, 2))
|
||||
|
||||
if (newVal && newVal.encounterId) {
|
||||
const oldEncounterId = queryParams.encounterId
|
||||
queryParams.encounterId = newVal.encounterId
|
||||
console.log('【检验】更新encounterId:', queryParams.encounterId)
|
||||
|
||||
// 初始化数据
|
||||
await initData();
|
||||
@@ -1530,9 +1473,7 @@ watch(() => selectedInspectionItems.value, (newVal) => {
|
||||
|
||||
// 组件挂载时预加载检验项目数据(不依赖patientInfo)
|
||||
onMounted(async () => {
|
||||
console.log('【检验】组件挂载,开始预加载检验项目数据')
|
||||
await loadInspectionData()
|
||||
console.log('【检验】检验项目数据预加载完成')
|
||||
})
|
||||
|
||||
// 暴露方法
|
||||
@@ -1604,6 +1545,9 @@ defineExpose({
|
||||
height: 650px;
|
||||
overflow-y: auto;
|
||||
padding: 20px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
/* 选择区域 */
|
||||
@@ -1631,6 +1575,7 @@ defineExpose({
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
@@ -1959,6 +1904,8 @@ defineExpose({
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 4px;
|
||||
background: #fafafa;
|
||||
max-height: 280px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.category-tree-item {
|
||||
@@ -2049,10 +1996,6 @@ defineExpose({
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.selected-header {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.selected-tree {
|
||||
flex: 1;
|
||||
}
|
||||
@@ -2181,39 +2124,8 @@ defineExpose({
|
||||
}
|
||||
}
|
||||
|
||||
/* 优化表单样式 */
|
||||
.application-form {
|
||||
padding: 20px;
|
||||
height: 700px;
|
||||
overflow-y: auto;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
/* 优化已选项目区样式 */
|
||||
.selected-items-area .selected-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.selected-items-area .selected-tree {
|
||||
max-height: 270px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* 优化搜索框样式 */
|
||||
.inspection-selector .el-input {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
/* 优化分类树样式 */
|
||||
.category-tree {
|
||||
max-height: 280px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user