@@ -4,7 +4,7 @@
<!-- 顶部操作按钮区 -- >
<!-- 顶部操作按钮区 -- >
< el-header class = "top-action-bar" height = "50px" >
< el-header class = "top-action-bar" height = "50px" >
< el-row class = "action-buttons" type = "flex" justify = "end" :gutter = "10" >
< el-row class = "action-buttons" type = "flex" justify = "end" :gutter = "10" >
< el-button type = "success" size = "large" @click ="handleSave" class = "save-btn" >
< el-button type = "success" size = "large" @click ="handleSave" class = "save-btn" :loading = "saving" >
< el-icon > < Document / > < / el-icon >
< el-icon > < Document / > < / el-icon >
保存
保存
< / el-button >
< / el-button >
@@ -400,19 +400,35 @@
< span class = "card-title" > 检验项目选择 < / span >
< span class = "card-title" > 检验项目选择 < / span >
< / template >
< / template >
<!-- 搜索框 -- >
<!-- 搜索框 ( 自动完成 ) -- >
< el-input
< el-autocomplete
v-model = "searchKeyword"
v-model = "searchKeyword"
:fetch-suggestions = "querySearchInspectionItems"
placeholder = "搜索检验项目..."
placeholder = "搜索检验项目..."
size = "small"
size = "small"
clearable
clearable
prefix -icon = " Search "
prefix -icon = " Search "
@inpu t ="handleSearch"
@selec t ="handleSearchSelect "
@clear ="handleSearchClear"
value -key = " itemName "
class = "search-input"
class = "search-input"
/ >
:debounce = "300"
>
< template # default = "{ item }" >
< div class = "suggestion-item" >
< span class = "suggestion-name" > { { item . itemName } } < / span >
< el-tag size = "small" type = "info" class = "suggestion-category" > { { item . typeName || '检验' } } < / el-tag >
< span class = "suggestion-price" > ¥ { { item . itemPrice } } < / span >
< / div >
< / template >
< / el-autocomplete >
<!-- 分类树 -- >
<!-- 分类树 -- >
< el-scrollbar class = "category-tree" style = "max-height: 280px" >
< el-scrollbar
class = "category-tree"
style = "max-height: 280px"
@scroll ="handleScroll"
>
<!-- 无数据提示 -- >
<!-- 无数据提示 -- >
< el-empty v-if = "!inspectionLoading && inspectionCategories.length === 0" description="暂无检验项目数据" :image-size="80" / >
< el-empty v-if = "!inspectionLoading && inspectionCategories.length === 0" description="暂无检验项目数据" :image-size="80" / >
<!-- 数据列表 -- >
<!-- 数据列表 -- >
@@ -427,9 +443,19 @@
>
>
< span class = "category-tree-icon" > { { category . expanded ? '▼' : '▶' } } < / span >
< span class = "category-tree-icon" > { { category . expanded ? '▼' : '▶' } } < / span >
< span > { { category . label } } < / span >
< span > { { category . label } } < / span >
< span class = "category-count" > ( { { category . items . length } } ) < / span >
< span class = "category-count" > ( { { category . total || category . items. length } } ) < / span >
<!-- 加载状态图标 -- >
< el-icon v-if = "category.loading" class="is-loading" style="margin-left: 8px; color: #409eff;" >
< Loading / >
< / el-icon >
< / div >
< / div >
< div v-if = "category.expanded" class="category-tree-children" >
< div v-if = "category.expanded" class="category-tree-children" >
< ! - - 加载中占位 - - >
< div v-if = "category.loading && category.items.length === 0" class="loading-placeholder" >
< el -icon class = "is-loading" style = "margin-right: 8px;" > < Loading / > < / el-icon >
< span > 加载中 ... < / span >
< / div >
<!-- 项目列表 -- >
< div
< div
v-for = "item in getFilteredItems(category.key)"
v-for = "item in getFilteredItems(category.key)"
:key = "item.itemId"
:key = "item.itemId"
@@ -444,6 +470,22 @@
< span class = "item-itemName" > { { item . itemName } } < / span >
< span class = "item-itemName" > { { item . itemName } } < / span >
< span class = "item-price" > ¥ { { item . itemPrice } } < / span >
< span class = "item-price" > ¥ { { item . itemPrice } } < / span >
< / div >
< / div >
<!-- 加载更多 -- >
< div v-if = "category.hasMore && category.items.length > 0" class="load-more" >
< el -button
link
size = "small"
:loading = "category.loading"
@click.stop ="loadMoreItems(category.key)"
>
{ { category . loading ? '加载中...' : '加载更多' } }
< / el-button >
< span class = "load-info" > ( 已加载 { { category . items . length } } / { { category . total } } 条 ) < / span >
< / div >
<!-- 加载完成提示 -- >
< div v-if = "!category.hasMore && category.items.length > 0" class="no-more" >
已全部加载 ( 共 {{ category.total }} 条 )
< / div >
< / div >
< / div >
< / div >
< / div >
< / el -scrollbar >
< / el -scrollbar >
@@ -492,7 +534,7 @@
< script setup >
< script setup >
import { onMounted , reactive , ref , watch , computed , getCurrentInstance } from 'vue'
import { onMounted , reactive , ref , watch , computed , getCurrentInstance } 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 , Loading } from '@element-plus/icons-vue'
import {
import {
checkInspectionApplicationNo ,
checkInspectionApplicationNo ,
deleteInspectionApplication , getApplyList ,
deleteInspectionApplication , getApplyList ,
@@ -504,6 +546,7 @@ import useUserStore from '@/store/modules/user.js'
// 迁移到 hiprint
// 迁移到 hiprint
import { previewPrint } from '@/utils/printUtils.js'
import { previewPrint } from '@/utils/printUtils.js'
import { storeToRefs } from 'pinia'
import { storeToRefs } from 'pinia'
import { debounce } from 'lodash-es'
// 获取当前组件实例和字典
// 获取当前组件实例和字典
const { proxy } = getCurrentInstance ( )
const { proxy } = getCurrentInstance ( )
@@ -532,6 +575,7 @@ const emit = defineEmits(['save'])
// 响应式数据
// 响应式数据
const loading = ref ( false )
const loading = ref ( false )
const saving = ref ( false ) // 保存状态
const total = ref ( 0 )
const total = ref ( 0 )
const leftActiveTab = ref ( 'application' )
const leftActiveTab = ref ( 'application' )
const isGeneratingNewApplyNo = ref ( false ) // 标志:是否正在生成新申请单号
const isGeneratingNewApplyNo = ref ( false ) // 标志:是否正在生成新申请单号
@@ -624,7 +668,8 @@ const validationErrors = reactive({
clinicDiag : false ,
clinicDiag : false ,
medicalHistorySummary : false ,
medicalHistorySummary : false ,
purposeofInspection : false ,
purposeofInspection : false ,
labApplyItemList : false
labApplyItemList : false ,
applyTime : false
} )
} )
// 已选择的表格行
// 已选择的表格行
@@ -639,15 +684,21 @@ const searchKeyword = ref('')
// 活动分类
// 活动分类
const activeCategory = ref ( '' )
const activeCategory = ref ( '' )
// 检验项目分类( 动态从API获取)
// 检验项目分类( 动态从API获取,支持懒加载和分页 )
const inspectionCategories = ref ( [ ] )
const inspectionCategories = ref ( [ ] )
// 检验项目加载状态
// 检验项目加载状态(整体)
const inspectionLoading = ref ( false )
const inspectionLoading = ref ( false )
// 加载检验项目分类和项目
// 每页加载条数
const PAGE _SIZE = 50
// 搜索防抖时间(毫秒)
const SEARCH _DEBOUNCE _TIME = 300
// 加载检验类型分类列表(只加载分类,项目懒加载)
async function loadInspectionData ( ) {
async function loadInspectionData ( ) {
// 如果已经加载过数据 ,直接返回(避免重复请求)
// 如果已经加载过分类 ,直接返回
if ( inspectionCategories . value . length > 0 ) {
if ( inspectionCategories . value . length > 0 ) {
return
return
}
}
@@ -655,194 +706,244 @@ async function loadInspectionData() {
inspectionLoading . value = true
inspectionLoading . value = true
try {
try {
// 并行请求:同时 获取检验类型列表和检验项目列表
// 只 获取检验类型列表
const [ typeRes , itemRes ] = await Promise . all ( [
const typeRes = await getInspectionTypeList ( ) . catch ( error => {
getInspectionTypeList ( ) . catch ( error => {
console . error ( '获取检验类型失败:' , error )
console . error ( '获取检验类型失败:' , error )
return { data : [ ] }
return { data : [ ] }
})
} ) ,
getInspectionItemList ( {
pageNo : 1 ,
pageSize : 500 ,
searchKey : '' ,
categoryCode : inspectionCategoryCode . value
} ) . catch ( error => {
console . error ( '获取检验项目失败:' , error )
return { data : { records : [ ] } }
} )
] )
const typeList = typeRes . data || [ ]
const typeList = typeRes . data || [ ]
// 解析检验项目数据
// 创建分类结构,但不加载项目(懒加载)
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
}
// 按分类组织数据(与检验项目设置维护保持一致的字段映射)
const categories = typeList
const categories = typeList
. filter ( type => type . validFlag === 1 || type . validFlag === undefined )
. filter ( type => type . validFlag === 1 || type . validFlag === undefined )
. map ( ( type , index ) => {
. map ( ( type , index ) => ( {
const categoryItems = allItems
key : type . code || ` type_ ${ index } ` ,
. filter ( item => {
label : type . name || ` 分类 ${ index + 1 } ` ,
// 转换为字符串进行比较,避免类型不匹配问题
typeId : type . id , // 保存类型ID用于分页查询
const itemTypeId = String ( item . inspectionTypeId || '' )
expanded : index === 0 , // 默认展开第一个
const typeId = String ( type . id || '' )
loaded : false , // 是否已加载项目
const itemTypeName = String ( item . inspectionTypeId _dictText || item . typeName || '' ) . trim ( )
loading : false , // 是否正在加载
const typeName = String ( type . name || '' ) . trim ( )
items : [ ] , // 项目列表
pageNo : 1 , // 当前页码
pageSize : PAGE _SIZE , // 每页条数
total : 0 , // 总条数
hasMore : true // 是否还有更多数据
} ) )
// 按检验类型ID匹配( 优先使用 inspectionTypeId)
if ( categories . length > 0 ) {
const matchById = itemTypeId && typeId && itemTypeId === typeId
inspectionCategories . value = categories
const matchByName = itemTypeNam e && typeName && itemTypeName === typeName
activeCategory . valu e = categories [ 0 ] . key
const matchByCode = String ( item . typeCode || '' ) === String ( type . code || '' )
return matchById || matchByName || matchByCode
// 预加载第一个分类的项目
} )
await loadCategoryItems ( categories [ 0 ] . key )
. 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 . specimenCode _dictText || item . sampleType || '血液' ,
unit : item . unit || '' ,
itemQty : 1 ,
serviceFee : 0 ,
type : type . name || item . inspectionTypeId _dictText || '检验' ,
isSelfPay : false ,
activityId : item . activityId ,
code : item . busNo || item . code || item . activityCode ,
inspectionTypeId : item . inspectionTypeId || null
} ) )
return {
key : type . code || ` type_ ${ index } ` ,
label : type . name || ` 分类 ${ index + 1 } ` ,
expanded : index === 0 ,
items : categoryItems
}
} )
// 过滤掉没有项目的分类
const validCategories = categories . filter ( cat => cat . items . length > 0 )
// 如果没有有效分类,但有项目数据,按项目自带的检验类型文本分组
if ( validCategories . length === 0 && allItems . length > 0 ) {
// 按检验类型文本分组
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 . specimenCode _dictText || item . sampleType || '血液' ,
unit : item . unit || '' ,
itemQty : 1 ,
serviceFee : 0 ,
type : typeName ,
isSelfPay : false ,
activityId : item . activityId ,
code : item . busNo || item . code || item . activityCode ,
inspectionTypeId : item . inspectionTypeId || null
} ) )
validCategories . push ( {
key : ` type_ ${ typeName } ` ,
label : typeName ,
expanded : validCategories . length === 0 ,
items : mappedItems
} )
} )
}
if ( validCategories . length > 0 ) {
inspectionCategories . value = validCategories
activeCategory . value = validCategories [ 0 ] . key
} else {
} else {
console . warn ( '未获取到有效的检验项目数据,使用备用数据 ' )
console . warn ( '未获取到检验类型分类 ' )
// 直接使用备用数据,不抛出错误
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'
}
}
} catch ( error ) {
} catch ( error ) {
console . error ( '加载检验项目数据 失败:' , 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 {
} finally {
inspectionLoading . value = false
inspectionLoading . value = false
}
}
}
}
// 获取过滤后的项目
// 懒加载分类项目(分页)
async function loadCategoryItems ( categoryKey , loadMore = false ) {
const category = inspectionCategories . value . find ( c => c . key === categoryKey )
if ( ! category ) return
// 已加载完成且不是加载更多,或正在加载中,跳过
if ( ( category . loaded && ! loadMore ) || category . loading ) return
// 没有更多数据了,跳过
if ( loadMore && ! category . hasMore ) return
category . loading = true
try {
const params = {
pageNo : category . pageNo ,
pageSize : category . pageSize ,
categoryCode : inspectionCategoryCode . value ,
searchKey : searchKeyword . value || ''
}
// 如果有类型ID, 添加筛选条件
if ( category . typeId ) {
params . inspectionTypeId = category . typeId
}
const res = await getInspectionItemList ( params )
// 解析数据
let records = [ ]
let total = 0
if ( res . data && res . data . records ) {
records = res . data . records
total = res . data . total || 0
} else if ( res . data && Array . isArray ( res . data ) ) {
records = res . data
total = records . length
} else if ( Array . isArray ( res ) ) {
records = res
total = records . length
}
// 映射数据格式
const mappedItems = records . 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 . specimenCode _dictText || item . sampleType || '血液' ,
unit : item . unit || '' ,
itemQty : 1 ,
serviceFee : 0 ,
type : category . label ,
isSelfPay : false ,
activityId : item . activityId ,
code : item . busNo || item . code || item . activityCode ,
inspectionTypeId : item . inspectionTypeId || null
} ) )
// 更新分类数据
if ( loadMore ) {
// 追加数据
category . items . push ( ... mappedItems )
} else {
// 首次加载
category . items = mappedItems
}
category . total = total
category . hasMore = category . items . length < total
category . loaded = true
} catch ( error ) {
console . error ( ` 加载分类 [ ${ category . label } ] 项目失败: ` , error )
// 加载失败时设置空数据
if ( ! loadMore ) {
category . items = [ ]
category . total = 0
category . hasMore = false
category . loaded = true
}
} finally {
category . loading = false
}
}
// 加载更多项目
function loadMoreItems ( categoryKey ) {
const category = inspectionCategories . value . find ( c => c . key === categoryKey )
if ( ! category || ! category . hasMore || category . loading ) return
category . pageNo ++
loadCategoryItems ( categoryKey , true )
}
// 处理滚动事件(无限滚动)
function handleScroll ( { scrollTop , scrollHeight , clientHeight } ) {
// 距离底部 50px 时触发加载更多
if ( scrollHeight - scrollTop - clientHeight < 50 ) {
const expandedCategory = inspectionCategories . value . find ( c => c . expanded )
if ( expandedCategory && expandedCategory . hasMore && ! expandedCategory . loading ) {
loadMoreItems ( expandedCategory . key )
}
}
}
// 防抖搜索处理
const handleSearchDebounced = debounce ( ( ) => {
// 重新加载当前展开分类的数据
const expandedCategory = inspectionCategories . value . find ( c => c . expanded )
if ( expandedCategory ) {
// 重置分页状态
expandedCategory . pageNo = 1
expandedCategory . loaded = false
expandedCategory . hasMore = true
expandedCategory . items = [ ]
// 重新加载
loadCategoryItems ( expandedCategory . key )
}
} , SEARCH _DEBOUNCE _TIME )
// 获取过滤后的项目(本地搜索)
const getFilteredItems = ( categoryKey ) => {
const getFilteredItems = ( categoryKey ) => {
const category = inspectionCategories . value . find ( cat => cat . key === categoryKey )
const category = inspectionCategories . value . find ( cat => cat . key === categoryKey )
if ( ! category ) return [ ]
if ( ! category ) return [ ]
if ( ! searchKeyword . value ) {
// 如果正在加载,返回现有数据
if ( category . loading ) {
return category . items
return category . items
}
}
return category . items . filter ( item =>
// 本地过滤(安全检查 itemName)
item . itemName . toLowerCase ( ) . includes ( searchKeyword . value . toLowerCase ( ) )
if ( searchKeyword . value ) {
)
const keyword = searchKeyword . value . toLowerCase ( )
return category . items . filter ( item =>
item . itemName && item . itemName . toLowerCase ( ) . includes ( keyword )
)
}
return category . items
}
}
// 搜索建议查询(自动完成)
async function querySearchInspectionItems ( queryString , cb ) {
if ( ! queryString ) {
cb ( [ ] )
return
}
try {
const params = {
pageNo : 1 ,
pageSize : 20 , // 限制返回数量
categoryCode : inspectionCategoryCode . value ,
searchKey : queryString
}
const res = await getInspectionItemList ( params )
let suggestions = [ ]
if ( res . data && res . data . records ) {
// 映射数据格式,与 loadInspectionItemsByType 保持一致
suggestions = res . data . records . map ( item => ( {
itemId : item . id || item . activityId ,
itemName : item . name || item . itemName || '' ,
itemPrice : item . retailPrice || item . price || 0 ,
sampleType : item . specimenCode _dictText || item . sampleType || '血液' ,
unit : item . unit || '' ,
code : item . busNo || item . code || item . activityCode ,
activityId : item . activityId ,
inspectionTypeId : item . inspectionTypeId || null
} ) )
}
cb ( suggestions )
} catch ( error ) {
console . error ( '搜索检验项目失败:' , error )
cb ( [ ] )
}
}
// 搜索选择处理
function handleSearchSelect ( item ) {
// 直接添加到已选列表
if ( ! isItemSelected ( item ) ) {
selectedInspectionItems . value . push ( {
... item ,
itemName : item . itemName
} )
}
// 清空搜索关键词
searchKeyword . value = ''
}
// 搜索框清空处理
function handleSearchClear ( ) {
searchKeyword . value = ''
}
// 获取检验申请单列表
// 获取检验申请单列表
function getInspectionList ( ) {
function getInspectionList ( ) {
@@ -1054,6 +1155,9 @@ async function resetForm() {
// 保存
// 保存
function handleSave ( ) {
function handleSave ( ) {
// 如果正在保存,直接返回
if ( saving . value ) return
// 重置验证错误状态
// 重置验证错误状态
Object . keys ( validationErrors ) . forEach ( key => {
Object . keys ( validationErrors ) . forEach ( key => {
validationErrors [ key ] = false
validationErrors [ key ] = false
@@ -1061,29 +1165,28 @@ function handleSave() {
let hasErrors = false
let hasErrors = false
// 检查必填字段
// 检查必填字段,执行科室
// 检查必填字段,执行科室
if ( ! formData . executeDepartment ) {
if ( ! formData . executeDepartment ) {
validationErrors . executeDepartment = true
validationErrors . executeDepartment = true
hasErrors = true
hasErrors = true
}
}
// 检查必填字段,诊断描述
// 检查必填字段,诊断描述
if ( ! formData . clinicDesc . trim ( ) ) {
if ( ! formData . clinicDesc ? . trim ( ) ) {
validationErrors . clinicDesc = true
validationErrors . clinicDesc = true
hasErrors = true
hasErrors = true
}
}
// 检查必填字段,临床诊断
// 检查必填字段,临床诊断
if ( ! formData . clinicDiag . trim ( ) ) {
if ( ! formData . clinicDiag ? . trim ( ) ) {
validationErrors . clinicDiag = true
validationErrors . clinicDiag = true
hasErrors = true
hasErrors = true
}
}
// 检查必填字段,病史摘要
// 检查必填字段,病史摘要
if ( ! formData . medicalHistorySummary . trim ( ) ) {
if ( ! formData . medicalHistorySummary ? . trim ( ) ) {
validationErrors . medicalHistorySummary = true
validationErrors . medicalHistorySummary = true
hasErrors = true
hasErrors = true
}
}
// 检查必填字段,检验目的
// 检查必填字段,检验目的
if ( ! formData . purposeofInspection . trim ( ) ) {
if ( ! formData . purposeofInspection ? . trim ( ) ) {
validationErrors . purposeofInspection = true
validationErrors . purposeofInspection = true
hasErrors = true
hasErrors = true
}
}
@@ -1095,7 +1198,7 @@ function handleSave() {
return
return
}
}
// 检查必填字段,申请日期
// 检查必填字段,申请日期
if ( ! formData . applyTime || ( typeof formData . applyTime === 'string' && ! formData . applyTime . trim ( ) ) ) {
if ( ! formData . applyTime || ( typeof formData . applyTime === 'string' && ! formData . applyTime ? . trim ( ) ) ) {
validationErrors . applyTime = true
validationErrors . applyTime = true
hasErrors = true
hasErrors = true
}
}
@@ -1182,9 +1285,11 @@ function handleSave() {
}
}
const executeSave = ( saveData ) => {
const executeSave = ( saveData ) => {
saving . value = true
saveInspectionApplication ( saveData ) . then ( ( res ) => {
saveInspectionApplication ( saveData ) . then ( ( res ) => {
if ( res . code === 200 ) {
if ( res . code === 200 ) {
ElMessage . success ( '保存成功' )
ElMessage . success ( '保存成功' )
emit ( 'save' , res . data ) // 通知父组件保存成功
resetForm ( )
resetForm ( )
// 生成新的申请单号
// 生成新的申请单号
generateApplicationNo ( ) . then ( ( newApplyNo ) => {
generateApplicationNo ( ) . then ( ( newApplyNo ) => {
@@ -1211,6 +1316,8 @@ const executeSave = (saveData) => {
// 处理请求失败的其他错误
// 处理请求失败的其他错误
console . error ( '保存检验申请单时发生错误:' , error ) ;
console . error ( '保存检验申请单时发生错误:' , error ) ;
ElMessage . error ( '保存失败,请稍后重试' ) ;
ElMessage . error ( '保存失败,请稍后重试' ) ;
} ) . finally ( ( ) => {
saving . value = false
} )
} )
}
}
@@ -1222,10 +1329,10 @@ function handleView(row) {
// 根据检验项目名称找到对应的项目数据
// 根据检验项目名称找到对应的项目数据
selectedInspectionItems . value = [ ]
selectedInspectionItems . value = [ ]
const itemNames = row . inspectionItem . split ( '、' )
const itemNames = row . itemName ? . split ( '、' ) || row . inspectionItem? . split ( '、' ) || [ ]
inspectionCategories . value . forEach ( category => {
inspectionCategories . value . forEach ( category => {
category . items . forEach ( item => {
category . items . forEach ( item => {
if ( itemNames . includes ( item . n ame) ) {
if ( itemNames . includes ( item . itemN ame) ) {
selectedInspectionItems . value . push ( item )
selectedInspectionItems . value . push ( item )
}
}
} )
} )
@@ -1234,7 +1341,7 @@ function handleView(row) {
leftActiveTab . value = 'application'
leftActiveTab . value = 'application'
}
}
// 切换分类
// 切换分类(修改为懒加载)
function switchCategory ( category ) {
function switchCategory ( category ) {
if ( activeCategory . value === category ) {
if ( activeCategory . value === category ) {
// 如果点击的是当前激活的分类,则收起
// 如果点击的是当前激活的分类,则收起
@@ -1250,12 +1357,13 @@ function switchCategory(category) {
inspectionCategories . value . forEach ( cat => {
inspectionCategories . value . forEach ( cat => {
cat . expanded = cat . key === category
cat . expanded = cat . key === category
} )
} )
}
}
// 处理搜索
// 懒加载该分类的项目
function handleSearch ( ) {
const targetCategory = inspectionCategories . value . find ( c => c . key === category )
// 搜索逻辑已在getFilteredItems中实现
if ( targetCategory && ! targetCategory . loaded ) {
loadCategoryItems ( category )
}
}
}
}
// 处理项目项点击(排除勾选框点击)
// 处理项目项点击(排除勾选框点击)
@@ -1409,8 +1517,8 @@ function handleCellClick(row, column) {
// 根据检验项目名称解析已选项目
// 根据检验项目名称解析已选项目
selectedInspectionItems . value = [ ]
selectedInspectionItems . value = [ ]
if ( row . inspectionItem ) {
if ( row . itemName || row . inspectionItem) {
const itemNames = row . inspectionItem . split ( '、' )
const itemNames = ( row . itemName || row . inspectionItem ) .split ( '、' )
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 ) ) {
@@ -1956,6 +2064,39 @@ defineExpose({
border - top : 1 px solid # ebeef5 ;
border - top : 1 px solid # ebeef5 ;
}
}
/* 加载中占位样式 */
. loading - placeholder {
display : flex ;
align - items : center ;
justify - content : center ;
padding : 20 px ;
color : # 909399 ;
font - size : 14 px ;
}
/* 加载更多样式 */
. load - more {
display : flex ;
align - items : center ;
justify - content : center ;
padding : 10 px ;
border - top : 1 px dashed # ebeef5 ;
}
. load - info {
margin - left : 8 px ;
font - size : 12 px ;
color : # 909399 ;
}
/* 没有更多数据提示 */
. no - more {
text - align : center ;
padding : 10 px ;
font - size : 12 px ;
color : # c0c4cc ;
}
. inspection - tree - item {
. inspection - tree - item {
display : flex ;
display : flex ;
align - items : center ;
align - items : center ;