367
门诊医生站:检验开单“免疫”类别下的检验项目取值错误,与后台维护数据不一致 357 门诊挂号:通过“预约签到”产生的记录,列表“挂号类型”未体现预约标识
This commit is contained in:
@@ -154,6 +154,8 @@ public class TicketAppServiceImpl implements ITicketAppService {
|
|||||||
dto.setDoctorId(raw.getDoctorId());
|
dto.setDoctorId(raw.getDoctorId());
|
||||||
dto.setDepartmentId(raw.getDepartmentId());
|
dto.setDepartmentId(raw.getDepartmentId());
|
||||||
dto.setRealPatientId(raw.getPatientId());
|
dto.setRealPatientId(raw.getPatientId());
|
||||||
|
dto.setOrderId(raw.getOrderId());
|
||||||
|
dto.setOrderNo(raw.getOrderNo());
|
||||||
|
|
||||||
// 性别处理:直接使用患者表中的 genderEnum
|
// 性别处理:直接使用患者表中的 genderEnum
|
||||||
Integer genderEnum = raw.getGenderEnum();
|
Integer genderEnum = raw.getGenderEnum();
|
||||||
|
|||||||
@@ -115,4 +115,15 @@ public class TicketDto {
|
|||||||
* 身份证号
|
* 身份证号
|
||||||
*/
|
*/
|
||||||
private String idCard;
|
private String idCard;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预约订单ID
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long orderId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预约订单号
|
||||||
|
*/
|
||||||
|
private String orderNo;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,4 +146,11 @@ public class CurrentDayEncounterDto {
|
|||||||
*/
|
*/
|
||||||
private Integer displayOrder;
|
private Integer displayOrder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否来自预约签到
|
||||||
|
* true: 预约签到
|
||||||
|
* false: 正常挂号
|
||||||
|
*/
|
||||||
|
private Boolean isFromAppointment;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,12 @@ public class EncounterFormData {
|
|||||||
@JsonSerialize(using = ToStringSerializer.class)
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
private Long organizationId;
|
private Long organizationId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预约订单ID(用于预约签到时关联预约订单)
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long orderId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置默认值
|
* 设置默认值
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -67,7 +67,8 @@
|
|||||||
T9.payment_id AS paymentId,
|
T9.payment_id AS paymentId,
|
||||||
T9.picture_url AS pictureUrl,
|
T9.picture_url AS pictureUrl,
|
||||||
T9.birth_date AS birthDate,
|
T9.birth_date AS birthDate,
|
||||||
COALESCE(T9.identifier_no, T9.patient_bus_no, '') AS identifierNo
|
COALESCE(T9.identifier_no, T9.patient_bus_no, '') AS identifierNo,
|
||||||
|
COALESCE(T9.order_id IS NOT NULL, false) AS isFromAppointment
|
||||||
from (
|
from (
|
||||||
SELECT T1.tenant_id AS tenant_id,
|
SELECT T1.tenant_id AS tenant_id,
|
||||||
T1.id AS encounter_id,
|
T1.id AS encounter_id,
|
||||||
@@ -93,7 +94,8 @@
|
|||||||
ai.picture_url AS picture_url,
|
ai.picture_url AS picture_url,
|
||||||
T8.birth_date AS birth_date,
|
T8.birth_date AS birth_date,
|
||||||
T8.bus_no AS patient_bus_no,
|
T8.bus_no AS patient_bus_no,
|
||||||
T18.identifier_no AS identifier_no
|
T18.identifier_no AS identifier_no,
|
||||||
|
T1.order_id AS order_id
|
||||||
FROM adm_encounter AS T1
|
FROM adm_encounter AS T1
|
||||||
LEFT JOIN adm_organization AS T2 ON T1.organization_id = T2.ID AND T2.delete_flag = '0'
|
LEFT JOIN adm_organization AS T2 ON T1.organization_id = T2.ID AND T2.delete_flag = '0'
|
||||||
LEFT JOIN adm_healthcare_service AS T3 ON T1.service_type_id = T3.ID AND T3.delete_flag = '0'
|
LEFT JOIN adm_healthcare_service AS T3 ON T1.service_type_id = T3.ID AND T3.delete_flag = '0'
|
||||||
|
|||||||
@@ -151,4 +151,9 @@ public class Encounter extends HisBaseEntity {
|
|||||||
*/
|
*/
|
||||||
@TableField("missed_time")
|
@TableField("missed_time")
|
||||||
private Date missedTime;
|
private Date missedTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预约订单ID
|
||||||
|
*/
|
||||||
|
private Long orderId;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -445,7 +445,13 @@
|
|||||||
prop="healthcareName"
|
prop="healthcareName"
|
||||||
:show-overflow-tooltip="true"
|
:show-overflow-tooltip="true"
|
||||||
width="200"
|
width="200"
|
||||||
/>
|
>
|
||||||
|
<template #default="scope">
|
||||||
|
<span>
|
||||||
|
{{ (scope.row.healthcareName || '').replace('挂号', '') }}{{ scope.row.isFromAppointment ? '预约' : '挂号' }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<!-- <el-table-column
|
<!-- <el-table-column
|
||||||
label="专家账号"
|
label="专家账号"
|
||||||
align="center"
|
align="center"
|
||||||
@@ -1776,6 +1782,7 @@ async function confirmCheckIn() {
|
|||||||
priorityEnum: 3, // 默认优先级
|
priorityEnum: 3, // 默认优先级
|
||||||
serviceTypeId: service.id,
|
serviceTypeId: service.id,
|
||||||
organizationId: patient.departmentId,
|
organizationId: patient.departmentId,
|
||||||
|
orderId: patient.orderId, // 预约订单ID(预约签到时需要传递)
|
||||||
},
|
},
|
||||||
encounterLocationFormData: {
|
encounterLocationFormData: {
|
||||||
locationId: null,
|
locationId: null,
|
||||||
|
|||||||
@@ -650,6 +650,7 @@ import {
|
|||||||
getOrgTree,
|
getOrgTree,
|
||||||
getInspectionPackageDetails
|
getInspectionPackageDetails
|
||||||
} from '../api'
|
} from '../api'
|
||||||
|
import { getLabActivityDefinitionPage } from '@/api/lab/labActivityDefinition'
|
||||||
import useUserStore from '@/store/modules/user.js'
|
import useUserStore from '@/store/modules/user.js'
|
||||||
// 迁移到 hiprint
|
// 迁移到 hiprint
|
||||||
import { previewPrint } from '@/utils/printUtils.js'
|
import { previewPrint } from '@/utils/printUtils.js'
|
||||||
@@ -1075,17 +1076,18 @@ const loadCategoryItems = async (categoryKey, loadMore = false) => {
|
|||||||
searchKey: searchKeyword.value || ''
|
searchKey: searchKeyword.value || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果有类型ID,添加筛选条件(从检验项目维护页面获取数据)
|
||||||
// 如果有类型 ID,添加筛选条件
|
// 如果有类型 ID,添加筛选条件
|
||||||
if (category.typeId) {
|
if (category.typeId) {
|
||||||
params.inspectionTypeId = category.typeId
|
params.inspectionTypeId = category.typeId
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await getInspectionItemList(params)
|
const res = await getLabActivityDefinitionPage(params)
|
||||||
|
|
||||||
// 解析数据
|
// 解析数据
|
||||||
let records = []
|
let records = []
|
||||||
let total = 0
|
let total = 0
|
||||||
if (res.data && res.data.records) {
|
if (res.code === 200 && res.data && res.data.records) {
|
||||||
records = res.data.records
|
records = res.data.records
|
||||||
total = res.data.total || 0
|
total = res.data.total || 0
|
||||||
} else if (res.data && Array.isArray(res.data)) {
|
} else if (res.data && Array.isArray(res.data)) {
|
||||||
@@ -1096,34 +1098,34 @@ const loadCategoryItems = async (categoryKey, loadMore = false) => {
|
|||||||
total = records.length
|
total = records.length
|
||||||
}
|
}
|
||||||
|
|
||||||
// 映射数据格式
|
// 映射数据格式(从检验项目维护页面的数据结构映射)
|
||||||
const mappedItems = records.map(item => {
|
const mappedItems = records.map(item => {
|
||||||
// BugFix: 套餐项目使用套餐金额,普通项目使用零售价
|
// 套餐项目处理:套餐项目使用套餐金额,普通项目使用零售价
|
||||||
// BugFix#404: 增加对空字符串的判断,避免空字符串被误认为有效套餐ID
|
// BugFix#404: 增加对空字符串的判断,避免空字符串被误认为有效套餐ID
|
||||||
const isPackage = item.feePackageId != null && item.feePackageId !== '' && item.feePackageId !== 'null'
|
const isPackage = item.feePackageId != null && item.feePackageId !== '' && item.feePackageId !== 'null'
|
||||||
const itemPrice = isPackage
|
const itemPrice = isPackage
|
||||||
? (item.packageAmount || item.retailPrice || item.price || 0)
|
? (parseFloat(item.packageAmount || 0) || parseFloat(item.retailPrice || 0) || parseFloat(item.price || 0))
|
||||||
: (item.retailPrice || item.price || 0)
|
: (parseFloat(item.retailPrice || 0) || parseFloat(item.price || 0))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
itemId: item.id || item.activityId || Math.random().toString(36).substring(2, 11),
|
itemId: item.id || Math.random().toString(36).substring(2, 11),
|
||||||
itemName: item.name || item.itemName || '',
|
itemName: item.name || '',
|
||||||
itemPrice: itemPrice,
|
itemPrice: itemPrice,
|
||||||
itemAmount: itemPrice,
|
itemAmount: itemPrice,
|
||||||
sampleType: item.specimenCode_dictText || item.sampleType || '血液',
|
sampleType: item.specimenCode || '血液',
|
||||||
unit: item.unit || '',
|
unit: item.permittedUnitCode_dictText || item.unit || '',
|
||||||
itemQty: 1,
|
itemQty: 1,
|
||||||
serviceFee: item.serviceFee || 0,
|
serviceFee: 0,
|
||||||
type: category.label,
|
type: category.label,
|
||||||
isSelfPay: false,
|
isSelfPay: false,
|
||||||
activityId: item.activityId,
|
code: item.busNo || '',
|
||||||
code: item.busNo || item.code || item.activityCode,
|
inspectionTypeId: item.inspectionTypeId ? Number(item.inspectionTypeId) : null,
|
||||||
inspectionTypeId: item.inspectionTypeId || category.typeId, // 如果项目没有inspectionTypeId,使用分类的typeId
|
activityId: item.id, // 保存 activityId 用于保存申请单时使用
|
||||||
// 套餐相关字段
|
// 套餐相关字段
|
||||||
isPackage: isPackage,
|
isPackage: isPackage,
|
||||||
feePackageId: item.feePackageId,
|
feePackageId: item.feePackageId,
|
||||||
packageName: item.packageName,
|
packageName: item.packageName,
|
||||||
children: isPackage ? [] : undefined, // 套餐项目预留children字段
|
children: isPackage ? [] : undefined,
|
||||||
hasChildren: isPackage
|
hasChildren: isPackage
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -1142,6 +1144,7 @@ const loadCategoryItems = async (categoryKey, loadMore = false) => {
|
|||||||
category.loaded = true
|
category.loaded = true
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.error('加载检验项目失败:', error)
|
||||||
// 加载失败时设置空数据
|
// 加载失败时设置空数据
|
||||||
if (!loadMore) {
|
if (!loadMore) {
|
||||||
category.items = []
|
category.items = []
|
||||||
@@ -1225,25 +1228,26 @@ const querySearchInspectionItems = async (queryString, cb) => {
|
|||||||
searchKey: queryString
|
searchKey: queryString
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await getInspectionItemList(params)
|
const res = await getLabActivityDefinitionPage(params)
|
||||||
|
|
||||||
let suggestions = []
|
let suggestions = []
|
||||||
if (res.data && res.data.records) {
|
if (res.code === 200 && res.data && res.data.records) {
|
||||||
// 映射数据格式,与 loadInspectionItemsByType 保持一致
|
// 映射数据格式,与 loadCategoryItems 保持一致
|
||||||
suggestions = res.data.records.map(item => ({
|
suggestions = res.data.records.map(item => ({
|
||||||
itemId: item.id || item.activityId,
|
itemId: item.id,
|
||||||
itemName: item.name || item.itemName || '',
|
itemName: item.name || '',
|
||||||
itemPrice: item.retailPrice || item.price || 0,
|
itemPrice: parseFloat(item.packageAmount || 0),
|
||||||
sampleType: item.specimenCode_dictText || item.sampleType || '血液',
|
sampleType: item.specimenCode || '血液',
|
||||||
unit: item.unit || '',
|
unit: item.permittedUnitCode_dictText || item.unit || '',
|
||||||
code: item.busNo || item.code || item.activityCode,
|
code: item.busNo || '',
|
||||||
activityId: item.activityId,
|
activityId: item.id,
|
||||||
inspectionTypeId: item.inspectionTypeId || null
|
inspectionTypeId: item.inspectionTypeId ? Number(item.inspectionTypeId) : null
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
cb(suggestions)
|
cb(suggestions)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.error('搜索检验项目失败:', error)
|
||||||
cb([])
|
cb([])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1656,62 +1660,17 @@ const isItemSelected = (item) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 切换检验项目选择
|
// 切换检验项目选择
|
||||||
// 切换检验项目选择状态(支持异步获取检验类型)
|
const toggleInspectionItem = (item) => {
|
||||||
// BugFix#CodeReview: 移除竞态条件风险,使用加载标志替代 setTimeout sleep
|
|
||||||
const toggleInspectionItem = async (item) => {
|
|
||||||
const index = selectedInspectionItems.value.findIndex(selected => selected.itemId === item.itemId)
|
const index = selectedInspectionItems.value.findIndex(selected => selected.itemId === item.itemId)
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
// 取消选择项目
|
|
||||||
selectedInspectionItems.value.splice(index, 1)
|
selectedInspectionItems.value.splice(index, 1)
|
||||||
|
|
||||||
// 检查剩余项目:如果为空则清空执行科室,否则保持不变
|
|
||||||
if (selectedInspectionItems.value.length === 0) {
|
|
||||||
formData.executeDepartment = ''
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// 选择新项目
|
// 创建新对象,包含 itemName 属性(等于 name 属性)
|
||||||
const newItem = {
|
const newItem = {
|
||||||
...item,
|
...item,
|
||||||
itemName: item.itemName,
|
itemName: item.itemName
|
||||||
// BugFix: 套餐项目需要初始化展开属性,否则点击无法展开
|
};
|
||||||
expanded: false,
|
selectedInspectionItems.value.push(newItem);
|
||||||
childrenLoaded: false,
|
|
||||||
loading: false,
|
|
||||||
children: item.isPackage ? [] : undefined
|
|
||||||
}
|
|
||||||
selectedInspectionItems.value.push(newItem)
|
|
||||||
|
|
||||||
// Bug #329: 根据检验项目所属类型自动设置执行科室默认值
|
|
||||||
const inspectionTypeId = item.inspectionTypeId
|
|
||||||
|
|
||||||
if (inspectionTypeId) {
|
|
||||||
// BugFix#CodeReview: 使用加载标志等待,替代 setTimeout sleep
|
|
||||||
// 确保执行科室列表已加载完成(最多等待5秒)
|
|
||||||
if (!isExecuteDepartmentLoaded.value) {
|
|
||||||
const maxWaitTime = 5000
|
|
||||||
const startTime = Date.now()
|
|
||||||
while (!isExecuteDepartmentLoaded.value && (Date.now() - startTime) < maxWaitTime) {
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 100))
|
|
||||||
}
|
|
||||||
if (!isExecuteDepartmentLoaded.value) {
|
|
||||||
console.warn('执行科室列表加载超时,跳过自动设置')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 异步获取执行科室(支持动态获取缺失的检验类型)
|
|
||||||
const defaultDeptCode = await getDefaultPerformDeptCode(inspectionTypeId)
|
|
||||||
|
|
||||||
if (defaultDeptCode) {
|
|
||||||
formData.executeDepartment = defaultDeptCode
|
|
||||||
} else {
|
|
||||||
// BugFix#CodeReview: 匹配失败时提示用户手动选择
|
|
||||||
console.warn('未找到检验类型对应的执行科室,typeId:', inspectionTypeId)
|
|
||||||
ElMessage.warning('未能自动匹配执行科室,请手动选择')
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.warn('检验项目没有 inspectionTypeId')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1720,61 +1679,12 @@ const removeInspectionItem = (item) => {
|
|||||||
const index = selectedInspectionItems.value.findIndex(selected => selected.itemId === item.itemId)
|
const index = selectedInspectionItems.value.findIndex(selected => selected.itemId === item.itemId)
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
selectedInspectionItems.value.splice(index, 1)
|
selectedInspectionItems.value.splice(index, 1)
|
||||||
|
|
||||||
// 检查剩余项目:如果为空则清空执行科室,否则保持不变
|
|
||||||
if (selectedInspectionItems.value.length === 0) {
|
|
||||||
formData.executeDepartment = ''
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清空所有选择
|
// 清空所有选择
|
||||||
const clearAllSelected = () => {
|
const clearAllSelected = () => {
|
||||||
selectedInspectionItems.value = []
|
selectedInspectionItems.value = []
|
||||||
formData.executeDepartment = ''
|
|
||||||
}
|
|
||||||
|
|
||||||
// BugFix#326: 展开/收起套餐明细
|
|
||||||
const togglePackageExpand = async (item) => {
|
|
||||||
if (!item.isPackage) return
|
|
||||||
|
|
||||||
item.expanded = !item.expanded
|
|
||||||
|
|
||||||
// 如果展开且未加载明细,则加载
|
|
||||||
// BugFix#404: 增加对有效套餐ID的校验,避免请求404
|
|
||||||
const feePackageIdStr = String(item.feePackageId || '').trim()
|
|
||||||
const validPackageId = feePackageIdStr && feePackageIdStr !== '' && feePackageIdStr !== 'null' && feePackageIdStr !== 'undefined'
|
|
||||||
console.log('togglePackageExpand debug:', {
|
|
||||||
feePackageId: item.feePackageId,
|
|
||||||
feePackageIdStr,
|
|
||||||
validPackageId,
|
|
||||||
isPackage: item.isPackage,
|
|
||||||
expanded: item.expanded,
|
|
||||||
childrenLoaded: item.childrenLoaded
|
|
||||||
})
|
|
||||||
if (item.expanded && !item.childrenLoaded && validPackageId) {
|
|
||||||
item.loading = true
|
|
||||||
try {
|
|
||||||
console.log('正在请求套餐明细, packageId:', feePackageIdStr)
|
|
||||||
const res = await getInspectionPackageDetails(feePackageIdStr)
|
|
||||||
console.log('套餐明细响应:', res)
|
|
||||||
if (res.code === 200 && res.data) {
|
|
||||||
item.children = res.data.map(detail => ({
|
|
||||||
detailId: detail.detailId,
|
|
||||||
itemName: detail.itemName,
|
|
||||||
unit: detail.unit,
|
|
||||||
unitPrice: detail.unitPrice,
|
|
||||||
quantity: detail.quantity
|
|
||||||
}))
|
|
||||||
item.childrenLoaded = true
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error('加载套餐明细失败:', e)
|
|
||||||
item.children = []
|
|
||||||
} finally {
|
|
||||||
item.loading = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分页大小改变
|
// 分页大小改变
|
||||||
@@ -1793,75 +1703,6 @@ const handleSelectionChange = (selection) => {
|
|||||||
selectedRows.value = selection
|
selectedRows.value = selection
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bug #326: 处理展开/收起
|
|
||||||
const handleExpandChange = (row, expandedRows) => {
|
|
||||||
// 更新展开状态
|
|
||||||
if (expandedRows.includes(row)) {
|
|
||||||
if (!expandedRowKeys.value.includes(row.applicationId)) {
|
|
||||||
expandedRowKeys.value.push(row.applicationId)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const index = expandedRowKeys.value.indexOf(row.applicationId)
|
|
||||||
if (index > -1) {
|
|
||||||
expandedRowKeys.value.splice(index, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断是否展开
|
|
||||||
const isExpanded = (applicationId) => {
|
|
||||||
return expandedRowKeys.value.includes(applicationId)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 切换展开状态
|
|
||||||
const toggleExpand = (row) => {
|
|
||||||
if (isExpanded(row.applicationId)) {
|
|
||||||
// 收起
|
|
||||||
expandedRowKeys.value = expandedRowKeys.value.filter(id => id !== row.applicationId)
|
|
||||||
} else {
|
|
||||||
// 展开
|
|
||||||
expandedRowKeys.value.push(row.applicationId)
|
|
||||||
// 如果没有加载过明细,加载明细数据
|
|
||||||
if (!row.childrenLoaded) {
|
|
||||||
loadInspectionItemDetails(row)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加载检验项目明细(套餐子项)
|
|
||||||
const loadInspectionItemDetails = async (row) => {
|
|
||||||
try {
|
|
||||||
const res = await getInspectionApplyDetail(row.applyNo)
|
|
||||||
if (res.code === 200 && res.data) {
|
|
||||||
const detail = res.data
|
|
||||||
if (detail.labApplyItemList && detail.labApplyItemList.length > 0) {
|
|
||||||
// 将明细数据转换为 children
|
|
||||||
row.children = detail.labApplyItemList.map(item => ({
|
|
||||||
itemId: item.itemId || item.id,
|
|
||||||
itemName: item.itemName || item.name,
|
|
||||||
sampleType: item.sampleType || '未知',
|
|
||||||
unit: item.unit || '',
|
|
||||||
itemPrice: item.itemPrice || item.price || 0,
|
|
||||||
itemQty: item.itemQty || 1,
|
|
||||||
itemAmount: item.itemAmount || item.price || 0
|
|
||||||
}))
|
|
||||||
row.childrenLoaded = true
|
|
||||||
// 标记是否有子项
|
|
||||||
row.hasChildren = row.children.length > 0
|
|
||||||
} else {
|
|
||||||
row.children = []
|
|
||||||
row.childrenLoaded = true
|
|
||||||
row.hasChildren = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('加载检验项目明细失败:', error)
|
|
||||||
row.children = []
|
|
||||||
row.childrenLoaded = true
|
|
||||||
row.hasChildren = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handlePrint = (row) => {
|
const handlePrint = (row) => {
|
||||||
// 切换到申请单TAB
|
// 切换到申请单TAB
|
||||||
leftActiveTab.value = 'application'
|
leftActiveTab.value = 'application'
|
||||||
@@ -1949,6 +1790,7 @@ const loadApplicationToForm = async (row) => {
|
|||||||
// 根据申请单号获取完整详情
|
// 根据申请单号获取完整详情
|
||||||
try {
|
try {
|
||||||
const res = await getInspectionApplyDetail(row.applyNo)
|
const res = await getInspectionApplyDetail(row.applyNo)
|
||||||
|
console.log('申请单详情API返回:', res) // 临时调试日志
|
||||||
if (res.code === 200 && res.data) {
|
if (res.code === 200 && res.data) {
|
||||||
const detail = res.data
|
const detail = res.data
|
||||||
// 加载完整的表单数据
|
// 加载完整的表单数据
|
||||||
@@ -1995,14 +1837,6 @@ const loadApplicationToForm = async (row) => {
|
|||||||
itemName: item.itemName || item.name || '',
|
itemName: item.itemName || item.name || '',
|
||||||
itemPrice: item.itemPrice || item.price || 0,
|
itemPrice: item.itemPrice || item.price || 0,
|
||||||
itemAmount: item.itemAmount || item.price || 0,
|
itemAmount: item.itemAmount || item.price || 0,
|
||||||
// BugFix: 套餐项目需要初始化展开属性,否则点击无法展开
|
|
||||||
// BugFix#404: 增加对空字符串的判断,避免空字符串被误认为有效套餐ID
|
|
||||||
isPackage: item.feePackageId != null && item.feePackageId !== '' && item.feePackageId !== 'null',
|
|
||||||
feePackageId: item.feePackageId,
|
|
||||||
expanded: false,
|
|
||||||
childrenLoaded: false,
|
|
||||||
loading: false,
|
|
||||||
children: (item.feePackageId != null && item.feePackageId !== '' && item.feePackageId !== 'null') ? [] : undefined
|
|
||||||
}))
|
}))
|
||||||
} else if (detail.inspectionItem || detail.itemName) {
|
} else if (detail.inspectionItem || detail.itemName) {
|
||||||
// 如果只有项目名称,尝试从本地分类中查找匹配项
|
// 如果只有项目名称,尝试从本地分类中查找匹配项
|
||||||
@@ -2010,14 +1844,7 @@ const loadApplicationToForm = async (row) => {
|
|||||||
inspectionCategories.value.forEach(category => {
|
inspectionCategories.value.forEach(category => {
|
||||||
category.items.forEach(item => {
|
category.items.forEach(item => {
|
||||||
if (itemNames.includes(item.itemName)) {
|
if (itemNames.includes(item.itemName)) {
|
||||||
selectedInspectionItems.value.push({
|
selectedInspectionItems.value.push({ ...item })
|
||||||
...item,
|
|
||||||
// BugFix: 套餐项目需要初始化展开属性
|
|
||||||
expanded: false,
|
|
||||||
childrenLoaded: false,
|
|
||||||
loading: false,
|
|
||||||
children: item.isPackage ? [] : undefined
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -2078,17 +1905,15 @@ watch(() => selectedInspectionItems.value, (newVal) => {
|
|||||||
}
|
}
|
||||||
}, { deep: true })
|
}, { deep: true })
|
||||||
|
|
||||||
// 监听执行科室选项加载完成,不自动设置默认值
|
// 监听执行科室字典数据,设置默认值为第一个选项
|
||||||
// Bug #329: 等待选择检验项目时根据检验类型自动设置
|
watch(() => inspection_lab_dept.value, (newVal) => {
|
||||||
watch(() => executeDepartmentOptions.value, (newVal) => {
|
if (newVal && newVal.length > 0 && !formData.executeDepartment) {
|
||||||
// 不再自动设置第一个值为默认值
|
formData.executeDepartment = newVal[0].value
|
||||||
|
}
|
||||||
}, { immediate: true })
|
}, { immediate: true })
|
||||||
|
|
||||||
// 组件挂载时预加载检验项目数据(不依赖patientInfo)
|
// 组件挂载时预加载检验项目数据(不依赖patientInfo)
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// Bug #329: 先加载执行科室列表,确保选择检验项目时能正确映射
|
|
||||||
await loadExecuteDepartmentList()
|
|
||||||
// 再加载检验类型分类
|
|
||||||
await loadInspectionData()
|
await loadInspectionData()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -2120,18 +1945,6 @@ defineExpose({
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bug #326: 展开内容样式 */
|
|
||||||
.expand-content {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.expand-empty {
|
|
||||||
padding: 10px;
|
|
||||||
text-align: center;
|
|
||||||
color: #999;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bug#334: 顶部操作按钮区 - 优化垂直空间利用率 */
|
/* Bug#334: 顶部操作按钮区 - 优化垂直空间利用率 */
|
||||||
.top-action-bar {
|
.top-action-bar {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -2229,26 +2042,11 @@ defineExpose({
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
height: calc(100vh - 200px);
|
|
||||||
min-height: 600px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.inspection-selector,
|
.inspection-selector,
|
||||||
.selected-items-area {
|
.selected-items-area {
|
||||||
flex: 1;
|
height: auto;
|
||||||
min-height: 300px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 检验项目选择区 - 固定高度 */
|
|
||||||
.inspection-selector {
|
|
||||||
max-height: 350px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 已选项目区 - 固定高度 */
|
|
||||||
.selected-items-area {
|
|
||||||
min-height: 300px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-title {
|
.card-title {
|
||||||
@@ -2256,144 +2054,6 @@ defineExpose({
|
|||||||
color: var(--el-text-color-primary);
|
color: var(--el-text-color-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 搜索输入框样式 */
|
|
||||||
.search-input {
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 分类树样式 */
|
|
||||||
.category-tree {
|
|
||||||
flex: 1;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.category-tree-item {
|
|
||||||
margin-bottom: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.category-tree-header {
|
|
||||||
padding: 8px 12px;
|
|
||||||
cursor: pointer;
|
|
||||||
border-radius: 4px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
transition: all 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.category-tree-header:hover {
|
|
||||||
background-color: #f5f7fa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.category-tree-header.active {
|
|
||||||
background-color: #e6f1ff;
|
|
||||||
color: #409EFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
.category-tree-icon {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #909399;
|
|
||||||
}
|
|
||||||
|
|
||||||
.category-count {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #909399;
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.category-tree-children {
|
|
||||||
padding-left: 24px;
|
|
||||||
margin-top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inspection-tree-item {
|
|
||||||
padding: 6px 12px;
|
|
||||||
cursor: pointer;
|
|
||||||
border-radius: 4px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
transition: all 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inspection-tree-item:hover {
|
|
||||||
background-color: #f5f7fa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inspection-tree-item.selected {
|
|
||||||
background-color: #e6f1ff;
|
|
||||||
color: #409EFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item-itemName {
|
|
||||||
flex: 1;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item-price {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #67c23a;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 已选项目列表样式 */
|
|
||||||
.selected-tree {
|
|
||||||
flex: 1;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-items-list {
|
|
||||||
margin-top: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-list-item {
|
|
||||||
padding: 8px 12px;
|
|
||||||
border-radius: 4px;
|
|
||||||
transition: all 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-list-item:hover {
|
|
||||||
background-color: #f5f7fa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-item-content {
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 加载状态样式 */
|
|
||||||
.loading-placeholder,
|
|
||||||
.load-more,
|
|
||||||
.no-more {
|
|
||||||
padding: 8px 12px;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #909399;
|
|
||||||
}
|
|
||||||
|
|
||||||
.load-info {
|
|
||||||
margin-left: 8px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #909399;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 展开内容样式 */
|
|
||||||
.expand-content {
|
|
||||||
padding: 12px 16px;
|
|
||||||
background-color: #f5f7fa;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.expand-empty {
|
|
||||||
padding: 20px;
|
|
||||||
text-align: center;
|
|
||||||
color: #909399;
|
|
||||||
font-size: 13px;
|
|
||||||
background-color: #f5f7fa;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-input {
|
.search-input {
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
@@ -2550,65 +2210,6 @@ defineExpose({
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BugFix#326: 套餐明细展开样式 */
|
|
||||||
.selected-item-wrapper {
|
|
||||||
margin-bottom: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.expand-icon {
|
|
||||||
cursor: pointer;
|
|
||||||
margin-right: 4px;
|
|
||||||
transition: transform 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.expand-icon:hover {
|
|
||||||
color: #409EFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
.package-details {
|
|
||||||
margin-left: 24px;
|
|
||||||
padding: 8px 12px;
|
|
||||||
background: #f5f7fa;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin-top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.package-details.loading {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
color: #909399;
|
|
||||||
}
|
|
||||||
|
|
||||||
.package-detail-item {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 4px 0;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #606266;
|
|
||||||
border-bottom: 1px dashed #e4e7ed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.package-detail-item:last-child {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detail-name {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detail-unit {
|
|
||||||
width: 50px;
|
|
||||||
text-align: center;
|
|
||||||
color: #909399;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detail-price {
|
|
||||||
width: 70px;
|
|
||||||
text-align: right;
|
|
||||||
color: #e6a23c;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inspection-details {
|
.inspection-details {
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
@@ -2846,100 +2447,6 @@ defineExpose({
|
|||||||
border-top: 1px solid #ebeef5;
|
border-top: 1px solid #ebeef5;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BugFix#326: 已选择区域树形结构样式(仿照项目选择区) */
|
|
||||||
.selected-tree-item {
|
|
||||||
border-bottom: 1px solid #ebeef5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-tree-item:last-child {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-tree-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 10px 12px;
|
|
||||||
cursor: default;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-tree-header:hover {
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-tree-item.is-package .selected-tree-header {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-tree-item.is-package .selected-tree-header:hover {
|
|
||||||
background-color: #e6f7ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-tree-item.is-package .selected-tree-header.expanded {
|
|
||||||
background-color: #e6f7ff;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-tree-icon {
|
|
||||||
margin-right: 8px;
|
|
||||||
font-size: 12px;
|
|
||||||
width: 12px;
|
|
||||||
text-align: center;
|
|
||||||
color: #51A3F3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-tree-children {
|
|
||||||
background: #fafafa;
|
|
||||||
border-top: 1px solid #ebeef5;
|
|
||||||
padding: 8px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-tree-detail {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 6px 12px 6px 32px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #606266;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-tree-detail:hover {
|
|
||||||
background-color: #f0f0f0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-tree-detail .detail-name {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-tree-detail .detail-unit {
|
|
||||||
width: 50px;
|
|
||||||
text-align: center;
|
|
||||||
color: #909399;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-tree-detail .detail-qty {
|
|
||||||
width: 40px;
|
|
||||||
text-align: center;
|
|
||||||
color: #909399;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected-tree-detail .detail-price {
|
|
||||||
width: 60px;
|
|
||||||
text-align: right;
|
|
||||||
color: #e6a23c;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.no-detail {
|
|
||||||
padding: 12px 32px;
|
|
||||||
color: #909399;
|
|
||||||
font-size: 12px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 加载中占位样式 */
|
/* 加载中占位样式 */
|
||||||
.loading-placeholder {
|
.loading-placeholder {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
Reference in New Issue
Block a user