2101 lines
62 KiB
Vue
2101 lines
62 KiB
Vue
<template>
|
||
<el-container class="inspection-application-container">
|
||
|
||
<!-- 顶部操作按钮区 -->
|
||
<el-header class="top-action-bar" height="50px">
|
||
<el-row class="action-buttons" type="flex" justify="end" :gutter="10">
|
||
<el-button type="success" size="large" @click="handleSave" class="save-btn">
|
||
<el-icon><Document /></el-icon>
|
||
保存
|
||
</el-button>
|
||
<el-button type="primary" size="large" @click="handleNewApplication" class="new-btn">
|
||
<el-icon><Plus /></el-icon>
|
||
新增
|
||
</el-button>
|
||
</el-row>
|
||
</el-header>
|
||
|
||
<!-- 检验信息表格区 -->
|
||
<el-main class="inspection-section" style="width: 100%; max-width: 100%">
|
||
<el-card class="table-card" style="width: 100%">
|
||
<template #header>
|
||
<el-row class="card-header" type="flex" align="middle">
|
||
<el-icon><DocumentChecked /></el-icon>
|
||
<span>检验信息</span>
|
||
</el-row>
|
||
</template>
|
||
<el-table
|
||
ref="inspectionTableRef"
|
||
:data="inspectionList"
|
||
border
|
||
stripe
|
||
size="small"
|
||
max-height="300px"
|
||
style="width: 100%; min-width: 100%"
|
||
class="inspection-table"
|
||
@selection-change="handleSelectionChange"
|
||
@cell-click="handleCellClick"
|
||
>
|
||
<el-table-column type="selection" width="55" align="center" header-align="center" />
|
||
<el-table-column label="序号" width="60" align="center" header-align="center">
|
||
<template #default="{ $index }">
|
||
<span>{{ $index + 1 }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="申请单号" prop="applyNo" min-width="180" align="center" header-align="center" />
|
||
<el-table-column label="检验项目" prop="itemName" min-width="170px" align="center" header-align="center" />
|
||
<el-table-column label="申请医生" prop="applyDocName" width="120" align="center" header-align="center" />
|
||
<el-table-column label="急" width="60" align="center" header-align="center">
|
||
<template #default="scope">
|
||
<el-checkbox :model-value="scope.row.priorityCode" disabled />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="收费" width="60" align="center" header-align="center">
|
||
<template #default="scope">
|
||
<el-checkbox :model-value="scope.row.applyStatus" disabled />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="退费" width="60" align="center" header-align="center">
|
||
<template #default="scope">
|
||
<el-checkbox :model-value="scope.row.needRefund" disabled />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="执行" width="60" align="center" header-align="center">
|
||
<template #default="scope">
|
||
<el-checkbox :model-value="scope.row.needExecute" disabled />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="金额" prop="amount" width="90" align="center" header-align="center">
|
||
<template #default="scope">
|
||
¥{{ formatAmount(scope.row.itemAmount) }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="120" align="center" header-align="center">
|
||
<template #default="scope">
|
||
<el-row type="flex" align="middle" justify="center" :gutter="8">
|
||
<el-button link size="default" @click="handlePrint(scope.row)" :icon="Printer" title="打印" style="font-size: 16px"></el-button>
|
||
<el-button link size="default" @click="handleDelete(scope.row)" :icon="Delete" style="color: #f56c6c; font-size: 16px" title="删除"></el-button>
|
||
</el-row>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
<!-- 分页 -->
|
||
<el-row class="pagination-container" justify="center" style="margin-top: 10px">
|
||
<el-pagination
|
||
v-model:current-page="queryParams.pageNo"
|
||
v-model:page-size="queryParams.pageSize"
|
||
:page-sizes="[10, 20, 50, 100]"
|
||
:total="total"
|
||
layout="prev, pager, next, jumper, total"
|
||
:pager-count="5"
|
||
:hide-on-single-page="false"
|
||
@size-change="handleSizeChange"
|
||
@current-change="handleCurrentChange"
|
||
/>
|
||
</el-row>
|
||
</el-card>
|
||
</el-main>
|
||
|
||
<!-- 底部表单与项目选择区 -->
|
||
<el-main class="bottom-content-area">
|
||
<el-row :gutter="16">
|
||
<!-- 左侧:申请单表单区(65%) -->
|
||
<el-col :span="15" class="form-area">
|
||
<el-card class="form-card" style="width: 100%">
|
||
<el-tabs v-model="leftActiveTab" class="form-tabs">
|
||
<el-tab-pane label="申请单" name="application">
|
||
<el-form class="application-form" :model="formData" label-width="auto">
|
||
<el-form-item label="申请单号" style="margin-bottom: 1px">
|
||
<el-input v-model="formData.applyNo" readonly size="small" />
|
||
</el-form-item>
|
||
|
||
<!-- 患者信息行 -->
|
||
<el-row :gutter="20" style="margin-bottom: 1px">
|
||
<el-col :span="8">
|
||
<el-form-item label="姓名" required>
|
||
<el-input v-model="formData.patientName" readonly size="small" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="就诊卡号" required>
|
||
<el-input v-model="formData.medicalrecordNumber" readonly size="small" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="费用性质" required>
|
||
<el-select v-model="formData.natureofCost" placeholder="请选择费用性质" size="small" style="width: 100%">
|
||
<el-option label="自费医疗" value="self" />
|
||
<el-option label="医保" value="medical" />
|
||
<el-option label="公费医疗" value="public" />
|
||
<el-option label="商业保险" value="commercial" />
|
||
<el-option label="其他" value="other" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 申请信息行 -->
|
||
<el-row :gutter="20" style="margin-bottom: 1px">
|
||
<!--申请日期-->
|
||
<el-col :span="8">
|
||
<el-form-item label="申请日期" required>
|
||
<el-date-picker
|
||
v-model="formData.applyTime"
|
||
type="datetime"
|
||
placeholder="选择日期时间"
|
||
size="small"
|
||
format="YYYY-MM-DD HH:mm:ss"
|
||
value-format="YYYY-MM-DD HH:mm:ss"
|
||
style="width: 100%"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<!--申请科室-->
|
||
<el-col :span="8">
|
||
<el-form-item label="申请科室" required>
|
||
<el-input v-model="formData.applyDepartment" readonly size="small" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<!--申请医生-->
|
||
<el-col :span="8">
|
||
<el-form-item label="申请医生" required>
|
||
<el-input v-model="formData.applyDocName" readonly size="small" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 执行科室 -->
|
||
<el-form-item
|
||
label="执行科室"
|
||
required
|
||
style="margin-bottom: 1px"
|
||
:class="{ 'form-item-error': validationErrors.executeDepartment }"
|
||
:error="validationErrors.executeDepartment ? '请选择执行科室' : ''"
|
||
>
|
||
<el-select
|
||
v-model="formData.executeDepartment"
|
||
placeholder="请选择执行科室"
|
||
size="small"
|
||
style="width: 100%"
|
||
:class="{ 'is-error': validationErrors.executeDepartment }"
|
||
>
|
||
<el-option label="医学检验科" value="medical_lab" />
|
||
<el-option label="放射科" value="radiology" />
|
||
<el-option label="超声科" value="ultrasound" />
|
||
<el-option label="病理科" value="pathology" />
|
||
<el-option label="核医学科" value="nuclear_medicine" />
|
||
</el-select>
|
||
</el-form-item>
|
||
|
||
<!-- 诊断描述 -->
|
||
<el-row :gutter="20" style="margin-bottom: 1px">
|
||
<el-col :span="12">
|
||
<el-form-item
|
||
label="诊断描述"
|
||
required
|
||
:class="{ 'form-item-error': validationErrors.clinicDesc }"
|
||
:error="validationErrors.clinicDesc ? '请输入诊断描述' : ''"
|
||
>
|
||
<el-input
|
||
v-model="formData.clinicDesc"
|
||
type="textarea"
|
||
:rows="2"
|
||
size="small"
|
||
:class="{ 'is-error': validationErrors.clinicDesc }"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item
|
||
label="临床诊断"
|
||
required
|
||
:class="{ 'form-item-error': validationErrors.clinicDiag }"
|
||
:error="validationErrors.clinicDiag ? '请输入临床诊断' : ''"
|
||
>
|
||
<el-input
|
||
v-model="formData.clinicDiag"
|
||
type="textarea"
|
||
:rows="2"
|
||
size="small"
|
||
:class="{ 'is-error': validationErrors.clinicDiag }"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 禁忌症、病史摘要、检验目的、体格检查 -->
|
||
<el-row :gutter="20" style="margin-bottom: 1px">
|
||
<el-col :span="12">
|
||
<el-form-item label="禁忌症">
|
||
<el-input v-model="formData.contraindication" type="textarea" :rows="2" size="small" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item
|
||
label="病史摘要"
|
||
required
|
||
:class="{ 'form-item-error': validationErrors.medicalHistorySummary }"
|
||
:error="validationErrors.medicalHistorySummary ? '请输入病史摘要' : ''"
|
||
>
|
||
<el-input
|
||
v-model="formData.medicalHistorySummary"
|
||
type="textarea"
|
||
:rows="2"
|
||
size="small"
|
||
:class="{ 'is-error': validationErrors.medicalHistorySummary }"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item
|
||
label="检验目的"
|
||
required
|
||
:class="{ 'form-item-error': validationErrors.purposeofInspection }"
|
||
:error="validationErrors.purposeofInspection ? '请输入检验目的' : ''"
|
||
>
|
||
<el-input
|
||
v-model="formData.purposeofInspection"
|
||
type="textarea"
|
||
:rows="2"
|
||
size="small"
|
||
:class="{ 'is-error': validationErrors.purposeofInspection }"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="体格检查">
|
||
<el-input v-model="formData.physicalExam" type="textarea" :rows="2" size="small" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 检验项目和备注 -->
|
||
<el-row :gutter="20" style="margin-bottom: 1px">
|
||
<el-col :span="12">
|
||
<el-form-item label="检验项目">
|
||
<el-input v-model="formData.inspectionItemsText" type="textarea" :rows="2" size="small" readonly />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="备注">
|
||
<el-input v-model="formData.applyRemark" type="textarea" :rows="2" size="small" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 状态复选框组 -->
|
||
<el-card style="margin-bottom: 16px; padding: 16px; background: #f8f9fa; border-radius: 4px; border: 1px solid #e9ecef" shadow="never">
|
||
<template #header>
|
||
<span style="font-weight: bold; color: #1a2b6d; font-size: 14px">
|
||
状态设置
|
||
</span>
|
||
</template>
|
||
<el-row type="flex" :gutter="16" wrap>
|
||
<el-col :xs="12" :sm="6" :md="6" :lg="6">
|
||
<el-checkbox v-model="formData.priorityCode" :true-value="1" :false-value="0">急</el-checkbox>
|
||
</el-col>
|
||
<el-col :xs="12" :sm="6" :md="6" :lg="6">
|
||
<el-checkbox v-model="formData.applyStatus" :true-value="1" :false-value="0">收费</el-checkbox>
|
||
</el-col>
|
||
<el-col :xs="12" :sm="6" :md="6" :lg="6">
|
||
<el-checkbox v-model="formData.needRefund" :true-value="true" :false-value="false">退费</el-checkbox>
|
||
</el-col>
|
||
<el-col :xs="12" :sm="6" :md="6" :lg="6">
|
||
<el-checkbox v-model="formData.needExecute" :true-value="true" :false-value="false">执行</el-checkbox>
|
||
</el-col>
|
||
</el-row>
|
||
</el-card>
|
||
</el-form>
|
||
</el-tab-pane>
|
||
<el-tab-pane label="检验信息" name="inspectionInfo">
|
||
<el-card style="padding: 20px; height: 700px; overflow-y: auto; border: 1px solid #e4e7ed; border-radius: 4px; margin: 10px; width: 100%">
|
||
<el-form :model="formData" label-width="100px" style="margin-bottom: 20px">
|
||
<el-row :gutter="15">
|
||
<el-col :span="12">
|
||
<el-form-item label="检验医生">
|
||
<el-input v-model="formData.inspectionDoctor" size="small" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="检验时间">
|
||
<el-date-picker
|
||
v-model="formData.inspectionTime"
|
||
type="datetime"
|
||
placeholder="选择时间"
|
||
size="small"
|
||
format="YYYY-MM-DD HH:mm:ss"
|
||
value-format="YYYY-MM-DD HH:mm:ss"
|
||
style="width: 100%"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="审核医生">
|
||
<el-input v-model="formData.auditDoctor" size="small" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="审核时间">
|
||
<el-date-picker
|
||
v-model="formData.auditTime"
|
||
type="datetime"
|
||
placeholder="选择时间"
|
||
size="small"
|
||
format="YYYY-MM-DD HH:mm:ss"
|
||
value-format="YYYY-MM-DD HH:mm:ss"
|
||
style="width: 100%"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</el-form>
|
||
|
||
<!-- 检验信息详情表格 -->
|
||
<el-card style="margin-top: 20px; width: 100%" shadow="never">
|
||
<template #header>
|
||
<h4 style="margin: 0; font-weight: bold">检验信息详情</h4>
|
||
</template>
|
||
<el-table :data="selectedInspectionItems" border size="small" style="width: 100%; min-width: 100%" max-height="350">
|
||
<el-table-column label="项目名称" prop="itemName" width="200" />
|
||
<el-table-column label="样本类型" prop="sampleType" width="80" align="center" />
|
||
<el-table-column label="单位" prop="unit" width="60" align="center" />
|
||
<el-table-column label="总量" prop="itemQty" width="60" align="center">
|
||
<template #default="scope">
|
||
<span>{{ scope.row.itemQty || 1 }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="单价" prop="itemPrice" width="70" align="right">
|
||
<template #default="scope">
|
||
¥{{ scope.row.itemPrice }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="金额" prop="itemAmount" width="70" align="right">
|
||
<template #default="scope">
|
||
¥{{ scope.row.itemAmount }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="服务费" width="70" align="right">
|
||
<template #default="scope">
|
||
¥{{ scope.row.serviceFee || 0 }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="类型" prop="type" width="60" align="center" />
|
||
<el-table-column label="自费" width="50" align="center">
|
||
<template #default="scope">
|
||
<el-checkbox :model-value="scope.row.isSelfPay" disabled />
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</el-card>
|
||
</el-card>
|
||
</el-tab-pane>
|
||
</el-tabs>
|
||
</el-card>
|
||
</el-col>
|
||
<!-- 右侧:项目选择区(35%) -->
|
||
<el-col :span="9" class="selection-area">
|
||
<!-- 检验项目选择区(上部50%) -->
|
||
<el-card class="inspection-selector">
|
||
<template #header>
|
||
<span class="card-title">检验项目选择</span>
|
||
</template>
|
||
|
||
<!-- 搜索框 -->
|
||
<el-input
|
||
v-model="searchKeyword"
|
||
placeholder="搜索检验项目..."
|
||
size="small"
|
||
clearable
|
||
prefix-icon="Search"
|
||
@input="handleSearch"
|
||
class="search-input"
|
||
/>
|
||
|
||
<!-- 分类树 -->
|
||
<el-scrollbar class="category-tree" style="max-height: 280px">
|
||
<div
|
||
v-for="category in inspectionCategories"
|
||
:key="category.key"
|
||
class="category-tree-item"
|
||
>
|
||
<div
|
||
:class="['category-tree-header', { active: activeCategory === category.key }]"
|
||
@click="switchCategory(category.key)"
|
||
>
|
||
<span class="category-tree-icon">{{ category.expanded ? '▼' : '▶' }}</span>
|
||
<span>{{ category.label }}</span>
|
||
<span class="category-count">({{ category.items.length }})</span>
|
||
</div>
|
||
<div v-if="category.expanded" class="category-tree-children">
|
||
<div
|
||
v-for="item in getFilteredItems(category.key)"
|
||
:key="item.itemId"
|
||
:class="['inspection-tree-item', { selected: isItemSelected(item) }]"
|
||
@click="handleItemClick(item)"
|
||
>
|
||
<el-checkbox
|
||
:model-value="isItemSelected(item)"
|
||
@change="toggleInspectionItem(item)"
|
||
@click.stop
|
||
/>
|
||
<span class="item-itemName">{{ item.itemName }}</span>
|
||
<span class="item-price">¥{{ item.itemPrice }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</el-scrollbar>
|
||
</el-card>
|
||
|
||
<!-- 下部:已选项目区 -->
|
||
<el-card class="selected-items-area">
|
||
<template #header>
|
||
<el-row class="selected-header" type="flex" justify="space-between" align="middle">
|
||
<span class="card-title">已选择</span>
|
||
<el-button link @click="clearAllSelected" type="danger" size="small">清空</el-button>
|
||
</el-row>
|
||
</template>
|
||
|
||
<!-- 已选项目列表 -->
|
||
<el-scrollbar class="selected-tree" style="max-height: 300px">
|
||
<el-list v-if="selectedInspectionItems.length > 0" :data="selectedInspectionItems" class="selected-items-list">
|
||
<el-list-item
|
||
v-for="item in selectedInspectionItems"
|
||
:key="item.itemId"
|
||
class="selected-list-item"
|
||
>
|
||
<el-row class="selected-item-content" type="flex" align="middle" style="width: 100%">
|
||
<span class="item-itemName">{{ item.itemName }}</span>
|
||
<span class="item-price">¥{{ item.itemPrice }}</span>
|
||
<el-button
|
||
link
|
||
size="small"
|
||
style="color: #f56c6c; margin-left: auto"
|
||
@click="removeInspectionItem(item)"
|
||
>
|
||
删除
|
||
</el-button>
|
||
</el-row>
|
||
</el-list-item>
|
||
</el-list>
|
||
<el-empty v-if="selectedInspectionItems.length === 0" class="no-selection" description="暂无选择项目" />
|
||
</el-scrollbar>
|
||
</el-card>
|
||
</el-col>
|
||
</el-row>
|
||
</el-main>
|
||
</el-container>
|
||
</template>
|
||
|
||
<script setup>
|
||
import {onMounted, reactive, ref, watch} from 'vue'
|
||
import {ElMessage, ElMessageBox} from 'element-plus'
|
||
import { DocumentChecked, Plus, Document, Printer, Delete } from '@element-plus/icons-vue'
|
||
import {
|
||
checkInspectionApplicationNo,
|
||
deleteInspectionApplication, getApplyList,
|
||
saveInspectionApplication
|
||
} from '../api'
|
||
import useUserStore from '@/store/modules/user.js'
|
||
import {storeToRefs} from 'pinia'
|
||
|
||
// 在 onMounted 中调用初始化函数
|
||
onMounted(() => {
|
||
initData();
|
||
})
|
||
|
||
// Props
|
||
const props = defineProps({
|
||
patientInfo: {
|
||
type: Object,
|
||
required: true
|
||
},
|
||
activeTab: {
|
||
type: String
|
||
}
|
||
})
|
||
|
||
// Emits
|
||
const emit = defineEmits(['save'])
|
||
|
||
// 响应式数据
|
||
const showForm = ref(false)
|
||
const loading = ref(false)
|
||
const total = ref(0)
|
||
const leftActiveTab = ref('application')
|
||
const isGeneratingNewApplyNo = ref(false) // 标志:是否正在生成新申请单号
|
||
|
||
// 用户信息store
|
||
const userStore = useUserStore()
|
||
const { id: userId, name: userName, nickName: userNickName } = storeToRefs(userStore)
|
||
|
||
// 修改 initData 函数
|
||
function initData() {
|
||
// 然后执行原有的初始化逻辑
|
||
if (props.patientInfo) {
|
||
queryParams.encounterId = props.patientInfo.encounterId
|
||
formData.visitNo = props.patientInfo.busNo || ''
|
||
formData.patientId = props.patientInfo.patientId || ''
|
||
formData.patientName = props.patientInfo.patientName || ''
|
||
formData.medicalrecordNumber = props.patientInfo.identifierNo || ''
|
||
formData.applyDepartment = props.patientInfo.organizationName || ''
|
||
formData.applyDocName = userNickName.value || userName.value || ''
|
||
formData.applyDocCode = userId.value || ''
|
||
formData.specimenName = '血液'
|
||
formData.applyDeptCode = props.patientInfo.organizationName || ''
|
||
formData.applyOrganizationId = props.patientInfo.orgId || ''
|
||
formData.encounterId = props.patientInfo.encounterId
|
||
generateApplicationNo().then((newApplyNo) => {
|
||
formData.applyNo = newApplyNo;
|
||
});
|
||
}
|
||
|
||
// 只有在存在 encounterId 时才调用接口
|
||
if (queryParams.encounterId) {
|
||
getInspectionList()
|
||
}
|
||
}
|
||
|
||
// 查询参数
|
||
const queryParams = reactive({
|
||
pageNo: 1,
|
||
pageSize: 10,
|
||
encounterId: props.patientInfo.encounterId
|
||
})
|
||
|
||
// 检验申请单列表
|
||
const inspectionList = ref([])
|
||
|
||
// 表单数据
|
||
const formData = reactive({
|
||
applyOrganizationId: props.patientInfo.orgId,
|
||
applicationId: null,
|
||
applyNo: '',
|
||
patientId:'',
|
||
patientName: '',
|
||
medicalrecordNumber: '',
|
||
natureofCost: 'self',
|
||
applyTime: new Date(),
|
||
applyDepartment: '',
|
||
applyDocName: '',
|
||
executeDepartment: 'medical_lab',
|
||
clinicDesc: '',
|
||
contraindication: '',
|
||
clinicDiag: '',
|
||
medicalHistorySummary: '',
|
||
purposeofInspection: '',
|
||
physicalExam: '',
|
||
labApplyItemList: [],
|
||
inspectionItemsText: '',
|
||
applyRemark: '',
|
||
priorityCode: 0,
|
||
applyStatus: 1,
|
||
needRefund: false,
|
||
needExecute: false,
|
||
inspectionDoctor: '',
|
||
inspectionTime: null,
|
||
auditDoctor: '',
|
||
auditTime: null,
|
||
visitNo: '',
|
||
applyDocCode:'',
|
||
applyDeptCode: props.patientInfo.organizationName,
|
||
specimenName: '血液',
|
||
encounterId: props.patientInfo.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()
|
||
|
||
// 表格引用
|
||
const inspectionTableRef = ref()
|
||
|
||
// 验证错误状态
|
||
const validationErrors = reactive({
|
||
executeDepartment: false,
|
||
clinicDesc: false,
|
||
clinicDiag: false,
|
||
medicalHistorySummary: false,
|
||
purposeofInspection: false,
|
||
labApplyItemList: false
|
||
})
|
||
|
||
// 已选择的表格行
|
||
const selectedRows = ref([])
|
||
|
||
// 已选择的检验项目
|
||
const selectedInspectionItems = ref([])
|
||
|
||
// 搜索关键词
|
||
const searchKeyword = ref('')
|
||
|
||
// 活动分类
|
||
const activeCategory = ref('biochemical')
|
||
|
||
// 检验项目分类(树形结构)
|
||
let inspectionCategories = ref([
|
||
{
|
||
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 }
|
||
]
|
||
},
|
||
{
|
||
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 }
|
||
]
|
||
}
|
||
])
|
||
|
||
// 获取过滤后的项目
|
||
const getFilteredItems = (categoryKey) => {
|
||
const category = inspectionCategories.value.find(cat => cat.key === categoryKey)
|
||
if (!category) return []
|
||
|
||
if (!searchKeyword.value) {
|
||
return category.items
|
||
}
|
||
|
||
return category.items.filter(item =>
|
||
item.itemName.toLowerCase().includes(searchKeyword.value.toLowerCase())
|
||
)
|
||
}
|
||
|
||
|
||
|
||
// 获取检验申请单列表
|
||
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,
|
||
pageSize: queryParams.pageSize
|
||
}).then((res) => {
|
||
if (res.code === 200) {
|
||
// 处理分页响应数据
|
||
if (res.data && typeof res.data === 'object') {
|
||
// 如果返回的是分页对象 {records: [...], total: 100}
|
||
if (Array.isArray(res.data.records)) {
|
||
// 处理数据:将同一个申请单的多个明细合并成一条记录
|
||
inspectionList.value = mergeInspectionApplyRecords(res.data.records)
|
||
total.value = res.data.total || 0
|
||
}
|
||
// 如果返回的是普通数组
|
||
else if (Array.isArray(res.data)) {
|
||
// 处理数据:将同一个申请单的多个明细合并成一条记录
|
||
inspectionList.value = mergeInspectionApplyRecords(res.data)
|
||
total.value = res.data.length
|
||
}
|
||
// 如果返回的是其他对象结构
|
||
else {
|
||
inspectionList.value = []
|
||
total.value = 0
|
||
}
|
||
} else {
|
||
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 || ''))
|
||
}).finally(() => {
|
||
loading.value = false
|
||
})
|
||
}
|
||
|
||
// 合并检验申请单记录:将同一个申请单的多个明细合并成一条记录
|
||
function mergeInspectionApplyRecords(records) {
|
||
if (!records || records.length === 0) {
|
||
return []
|
||
}
|
||
|
||
// 使用Map按申请单号分组
|
||
const applyMap = new Map()
|
||
|
||
records.forEach(record => {
|
||
const applyNo = record.applyNo
|
||
if (applyMap.has(applyNo)) {
|
||
// 如果申请单已存在,合并检验项目
|
||
const existing = applyMap.get(applyNo)
|
||
existing.itemName = existing.itemName + '+' + record.itemName
|
||
// 累加金额,保留两位小数
|
||
const totalAmount = (parseFloat(existing.itemAmount) || 0) + (parseFloat(record.itemAmount) || 0)
|
||
existing.itemAmount = parseFloat(totalAmount.toFixed(2))
|
||
} else {
|
||
// 如果申请单不存在,直接添加
|
||
applyMap.set(applyNo, { ...record })
|
||
}
|
||
})
|
||
|
||
// 将Map转换为数组
|
||
return Array.from(applyMap.values())
|
||
}
|
||
|
||
// 格式化金额:确保显示两位小数
|
||
function formatAmount(amount) {
|
||
if (amount === null || amount === undefined || amount === '') {
|
||
return '0.00'
|
||
}
|
||
const num = parseFloat(amount)
|
||
if (isNaN(num)) {
|
||
return '0.00'
|
||
}
|
||
return num.toFixed(2)
|
||
}
|
||
|
||
// 新增申请单
|
||
async function handleNewApplication() {
|
||
// console.log('点击新增按钮')
|
||
resetForm()
|
||
// 生成新的申请单号
|
||
formData.applyNo = await generateApplicationNo()
|
||
// 确保申请医生是当前登录医生
|
||
formData.applyDocName = userNickName.value || userName.value || ''
|
||
leftActiveTab.value = 'application'
|
||
}
|
||
|
||
// 查询数据库中是否已存在指定申请单号
|
||
const checkApplicationNoExists = async (applyNo) => {
|
||
try {
|
||
// 这里调用API检查申请单号是否已存在
|
||
// 注意:你需要根据实际API接口调整此调用
|
||
const response = await checkInspectionApplicationNo(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;
|
||
let attempts = 0;
|
||
const maxAttempts = 10; // 最大尝试次数
|
||
|
||
// 循环直到生成唯一的申请单号
|
||
while (!isUnique && attempts < maxAttempts) {
|
||
const now = new Date();
|
||
|
||
// 生成20位申请单号:年(4位) + 月(2位) + 日(2位) + 时(2位) + 分(2位) + 秒(2位) + 毫秒(3位) + 随机数(3位)
|
||
const year = String(now.getFullYear()); // 取4位年份
|
||
const month = String(now.getMonth() + 1).padStart(2, '0'); // 月份从0开始,需要+1
|
||
const day = String(now.getDate()).padStart(2, '0');
|
||
const hours = String(now.getHours()).padStart(2, '0');
|
||
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||
const seconds = String(now.getSeconds()).padStart(2, '0');
|
||
const milliseconds = String(now.getMilliseconds()).padStart(3, '0'); // 毫秒取3位
|
||
|
||
// 生成3位随机数增加唯一性,避免并发冲突
|
||
const randomNum = Math.floor(Math.random() * 1000).toString().padStart(3, '0'); // 3位随机数
|
||
|
||
// 年(4)+月(2)+日(2)+时(2)+分(2)+秒(2)+毫秒(3)+随机数(3) = 20位
|
||
applyNo = `${year}${month}${day}${hours}${minutes}${seconds}${milliseconds}${randomNum}`;
|
||
|
||
// 确保生成的申请单号不为空
|
||
if (!applyNo || applyNo.trim() === '') {
|
||
console.debug('生成的申请单号为空,重新生成');
|
||
attempts++;
|
||
continue;
|
||
}
|
||
|
||
// 检查生成的单号是否已存在于数据库中
|
||
const existsInDatabase = await checkApplicationNoExists(applyNo);
|
||
|
||
// 只有当单号不在数据库中时,才是唯一的
|
||
isUnique = !existsInDatabase;
|
||
|
||
attempts++;
|
||
}
|
||
|
||
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开头表示备用方案
|
||
return fallbackNo;
|
||
}
|
||
|
||
return applyNo;
|
||
};
|
||
|
||
// 重置表单
|
||
async function resetForm() {
|
||
Object.assign(formData, {
|
||
applicationId: null,
|
||
applyOrganizationId: props.patientInfo.orgId || '',
|
||
patientName: props.patientInfo.patientName || '',
|
||
medicalrecordNumber: props.patientInfo.identifierNo || '',
|
||
natureofCost: 'self',
|
||
applyTime: new Date(),
|
||
applyDepartment: props.patientInfo.organizationName || '',
|
||
applyDeptCode: props.patientInfo.organizationName,
|
||
applyDocCode: userId.value || '',
|
||
applyDocName: userNickName.value || userName.value || '',
|
||
executeDepartment: 'medical_lab',
|
||
clinicDesc: '',
|
||
contraindication: '',
|
||
clinicDiag: '',
|
||
medicalHistorySummary: '',
|
||
purposeofInspection: '',
|
||
physicalExam: '',
|
||
labApplyItemList: [],
|
||
applyRemark: '',
|
||
priorityCode: 0,
|
||
applyStatus: 1,
|
||
needRefund: false,
|
||
needExecute: false,
|
||
patientId: props.patientInfo.patientId || '',
|
||
visitNo: '',
|
||
specimenName: '血液',
|
||
encounterId: props.patientInfo.encounterId || '',
|
||
})
|
||
selectedInspectionItems.value = []
|
||
|
||
// 重置验证错误状态
|
||
Object.keys(validationErrors).forEach(key => {
|
||
validationErrors[key] = false
|
||
})
|
||
|
||
formRef.value?.clearValidate()
|
||
}
|
||
|
||
// 返回列表
|
||
function handleBack() {
|
||
showForm.value = false
|
||
getInspectionList()
|
||
}
|
||
|
||
// 保存
|
||
function handleSave() {
|
||
// 重置验证错误状态
|
||
Object.keys(validationErrors).forEach(key => {
|
||
validationErrors[key] = false
|
||
})
|
||
|
||
let hasErrors = false
|
||
|
||
// 检查必填字段
|
||
// 检查必填字段,执行科室
|
||
if (!formData.executeDepartment) {
|
||
validationErrors.executeDepartment = true
|
||
hasErrors = true
|
||
}
|
||
// 检查必填字段,诊断描述
|
||
if (!formData.clinicDesc.trim()) {
|
||
validationErrors.clinicDesc = true
|
||
hasErrors = true
|
||
}
|
||
// 检查必填字段,临床诊断
|
||
if (!formData.clinicDiag.trim()) {
|
||
validationErrors.clinicDiag = true
|
||
hasErrors = true
|
||
}
|
||
// 检查必填字段,病史摘要
|
||
if (!formData.medicalHistorySummary.trim()) {
|
||
validationErrors.medicalHistorySummary = true
|
||
hasErrors = true
|
||
}
|
||
// 检查必填字段,检验目的
|
||
if (!formData.purposeofInspection.trim()) {
|
||
validationErrors.purposeofInspection = true
|
||
hasErrors = true
|
||
}
|
||
// 检查必填字段,检验项目
|
||
if (selectedInspectionItems.value.length === 0) {
|
||
validationErrors.labApplyItemList = true
|
||
hasErrors = true
|
||
ElMessage.error('请至少选择一项检验项目')
|
||
return
|
||
}
|
||
// 检查必填字段,申请日期
|
||
if(!formData.applyTime || (typeof formData.applyTime === 'string' && !formData.applyTime.trim())) {
|
||
validationErrors.applyTime = true
|
||
hasErrors = true
|
||
}
|
||
|
||
if (hasErrors) {
|
||
ElMessage.error('请填写所有必填字段')
|
||
return
|
||
}
|
||
|
||
// 准备保存数据
|
||
const prepareSaveData = () => {
|
||
return {
|
||
...formData,
|
||
labApplyItemList: selectedInspectionItems.value,
|
||
inspectionItemsText: selectedInspectionItems.value.map(item => item.itemName).join('+'),
|
||
amount: selectedInspectionItems.value.reduce((sum, item) => sum + item.itemAmount, 0),
|
||
serviceFee: selectedInspectionItems.value.reduce((sum, item) => sum + (item.serviceFee || 0), 0),
|
||
totalAmount: selectedInspectionItems.value.reduce((sum, item) => sum + item.itemAmount + (item.serviceFee || 0), 0)
|
||
}
|
||
}
|
||
|
||
|
||
// 先检查申请单号是否已存在
|
||
console.log('查询申请单号:', formData.applyNo)
|
||
// 如果正在生成新申请单号,则跳过重复检查,直接保存
|
||
if (isGeneratingNewApplyNo.value) {
|
||
// 正在使用新生成的单号,直接保存
|
||
isGeneratingNewApplyNo.value = false; // 重置标志
|
||
const saveData = prepareSaveData();
|
||
executeSave(saveData);
|
||
return;
|
||
}
|
||
|
||
checkInspectionApplicationNo(formData.applyNo).then((res) => {
|
||
if (res.code === 200 && res.data) {
|
||
// res.data有值表示申请单存在
|
||
// 注意:res.data可能是{applyNo: "..."}或包含其他字段
|
||
const exists = res.data && (res.data.applyNo || res.data.exists);
|
||
if (exists) {
|
||
// 申请单号已存在,提示用户
|
||
ElMessageBox.confirm(
|
||
'当前申请单号已重复,将重新为您生成新的申请单号',
|
||
'提示',
|
||
{
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning',
|
||
}
|
||
).then(() => {
|
||
// 设置标志,表示正在生成新申请单号
|
||
isGeneratingNewApplyNo.value = true;
|
||
// 重新生成申请单号
|
||
generateApplicationNo().then((newApplyNo) => {
|
||
if (newApplyNo && newApplyNo.trim() !== '') {
|
||
formData.applyNo = newApplyNo;
|
||
ElMessage.success('新申请单号已生成,请点击保存按钮继续,请核对数据');
|
||
// 不自动保存,等待用户再次点击保存
|
||
} else {
|
||
console.debug('生成的申请单号为空,不设置');
|
||
isGeneratingNewApplyNo.value = false;
|
||
}
|
||
});
|
||
}).catch((error) => {
|
||
// 用户点击取消或其他原因导致的拒绝
|
||
if (error !== 'cancel' && error !== 'close') {
|
||
console.error('MessageBox操作出错:', error);
|
||
}
|
||
console.debug('用户取消了重新生成申请单号');
|
||
});
|
||
} else {
|
||
// 申请单号不存在,继续保存操作
|
||
const saveData = prepareSaveData();
|
||
executeSave(saveData);
|
||
}
|
||
} else {
|
||
// 其他情况继续保存
|
||
const saveData = prepareSaveData();
|
||
executeSave(saveData);
|
||
}
|
||
}).catch((error) => {
|
||
console.error('检查申请单号时发生错误:', error);
|
||
// 如果检查过程出错,仍然继续保存操作,以免影响正常使用
|
||
const saveData = prepareSaveData();
|
||
executeSave(saveData);
|
||
})
|
||
|
||
}
|
||
// 执行保存操作
|
||
const executeSave = (saveData) => {
|
||
saveInspectionApplication(saveData).then((res) => {
|
||
console.log('保存检验申请单结果:', res.code)
|
||
if (res.code === 200) {
|
||
ElMessage.success('保存成功')
|
||
resetForm()
|
||
// 生成新的申请单号
|
||
generateApplicationNo().then((newApplyNo) => {
|
||
if (newApplyNo && newApplyNo.trim() !== '') {
|
||
formData.applyNo = newApplyNo;
|
||
} else {
|
||
console.debug('生成的申请单号为空,不设置');
|
||
}
|
||
});
|
||
leftActiveTab.value = 'application'
|
||
// 刷新列表
|
||
getInspectionList()
|
||
} else {
|
||
// 对于其他错误,也使用弹窗提示
|
||
ElMessageBox.alert(res.message || '保存失败', '错误', {
|
||
confirmButtonText: '确定',
|
||
type: 'error',
|
||
}).catch((error) => {
|
||
console.error('错误提示框操作出错:', error);
|
||
});
|
||
console.debug(res.message || '保存失败')
|
||
}
|
||
}).catch((error) => {
|
||
// 处理请求失败的其他错误
|
||
console.error('保存检验申请单时发生错误:', error);
|
||
ElMessage.error('保存失败,请稍后重试');
|
||
})
|
||
}
|
||
|
||
|
||
// 表单保存
|
||
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)
|
||
|
||
// 根据检验项目名称找到对应的项目数据
|
||
selectedInspectionItems.value = []
|
||
const itemNames = row.inspectionItem.split('、')
|
||
inspectionCategories.value.forEach(category => {
|
||
category.items.forEach(item => {
|
||
if (itemNames.includes(item.name)) {
|
||
selectedInspectionItems.value.push(item)
|
||
}
|
||
})
|
||
})
|
||
|
||
leftActiveTab.value = 'application'
|
||
}
|
||
|
||
// 切换分类
|
||
function switchCategory(category) {
|
||
if (activeCategory.value === category) {
|
||
// 如果点击的是当前激活的分类,则收起
|
||
activeCategory.value = ''
|
||
inspectionCategories.value.forEach(cat => {
|
||
if (cat.key === category) {
|
||
cat.expanded = false
|
||
}
|
||
})
|
||
} else {
|
||
// 否则切换到新的分类并展开
|
||
activeCategory.value = category
|
||
inspectionCategories.value.forEach(cat => {
|
||
cat.expanded = cat.key === category
|
||
})
|
||
}
|
||
}
|
||
|
||
// 处理搜索
|
||
function handleSearch() {
|
||
// 搜索逻辑已在getFilteredItems中实现,这里可以添加额外的搜索逻辑
|
||
// console.log('搜索关键词:', searchKeyword.value)
|
||
}
|
||
|
||
// 处理项目项点击(排除勾选框点击)
|
||
function handleItemClick(item) {
|
||
toggleInspectionItem(item)
|
||
}
|
||
|
||
// 判断项目是否已选择
|
||
function isItemSelected(item) {
|
||
return selectedInspectionItems.value.some(selected => selected.itemId === item.itemId)
|
||
}
|
||
|
||
// 切换检验项目选择
|
||
function toggleInspectionItem(item) {
|
||
const index = selectedInspectionItems.value.findIndex(selected => selected.itemId === item.itemId)
|
||
if (index > -1) {
|
||
selectedInspectionItems.value.splice(index, 1)
|
||
} else {
|
||
// 创建新对象,包含 itemName 属性(等于 name 属性)
|
||
const newItem = {
|
||
...item,
|
||
itemName: item.itemName
|
||
};
|
||
selectedInspectionItems.value.push(newItem);
|
||
}
|
||
}
|
||
|
||
// 移除检验项目
|
||
function removeInspectionItem(item) {
|
||
const index = selectedInspectionItems.value.findIndex(selected => selected.itemId === item.itemId)
|
||
if (index > -1) {
|
||
selectedInspectionItems.value.splice(index, 1)
|
||
}
|
||
}
|
||
|
||
// 清空所有选择
|
||
function clearAllSelected() {
|
||
selectedInspectionItems.value = []
|
||
}
|
||
|
||
// 分页大小改变
|
||
function handleSizeChange(size) {
|
||
queryParams.pageSize = size
|
||
getInspectionList()
|
||
}
|
||
|
||
// 分页页码改变
|
||
function handleCurrentChange(page) {
|
||
queryParams.pageNo = page
|
||
getInspectionList()
|
||
}
|
||
|
||
// 选择框变化
|
||
function handleSelectionChange(selection) {
|
||
selectedRows.value = selection
|
||
}
|
||
|
||
// 打印申请单
|
||
function handlePrint(row) {
|
||
// console.log('打印申请单:', row)
|
||
|
||
// 切换到申请单TAB
|
||
leftActiveTab.value = 'application'
|
||
|
||
// 加载要打印的数据
|
||
handleView(row)
|
||
|
||
// 等待DOM更新后执行打印
|
||
setTimeout(() => {
|
||
// 添加打印样式
|
||
const printStyle = document.createElement('style')
|
||
printStyle.innerHTML = `
|
||
@media print {
|
||
body * {
|
||
visibility: hidden;
|
||
}
|
||
.application-form,
|
||
.application-form * {
|
||
visibility: visible;
|
||
}
|
||
.application-form {
|
||
position: absolute;
|
||
left: 0;
|
||
top: 0;
|
||
width: 100%;
|
||
max-width: none;
|
||
box-shadow: none;
|
||
border: none;
|
||
margin: 0;
|
||
padding: 20px;
|
||
}
|
||
.el-tabs__header {
|
||
display: none;
|
||
}
|
||
.el-tabs__content {
|
||
padding: 0;
|
||
}
|
||
.section-header,
|
||
.pagination-container,
|
||
.inspection-selector,
|
||
.selected-items-area,
|
||
.actions {
|
||
display: none !important;
|
||
}
|
||
.application-form .el-input__inner,
|
||
.application-form .el-select .el-input__inner,
|
||
.application-form .el-textarea__inner {
|
||
border: 1px solid #ddd !important;
|
||
background: white !important;
|
||
}
|
||
.application-form .el-checkbox__input.is-checked .el-checkbox__inner {
|
||
background-color: #409eff;
|
||
border-color: #409eff;
|
||
}
|
||
}
|
||
`
|
||
document.head.appendChild(printStyle)
|
||
|
||
// 执行打印
|
||
window.print()
|
||
|
||
// 移除打印样式
|
||
setTimeout(() => {
|
||
document.head.removeChild(printStyle)
|
||
}, 1000)
|
||
|
||
ElMessage.success('正在准备打印...')
|
||
}, 100)
|
||
}
|
||
|
||
// 删除申请单
|
||
function handleDelete(row) {
|
||
ElMessageBox.confirm(
|
||
`确定要删除申请单 "${row.applyNo}" 吗?此操作将同时删除对应的医嘱。`,
|
||
'删除确认',
|
||
{
|
||
confirmButtonText: '确定删除',
|
||
cancelButtonText: '取消',
|
||
type: 'warning',
|
||
confirmButtonClass: 'el-button--danger'
|
||
}
|
||
).then(() => {
|
||
// 调用真实的 API 删除(传递 applyNo)
|
||
// 调用真实的API删除
|
||
deleteInspectionApplication(row.applyNo).then((res) => {
|
||
if (res.code === 200) {
|
||
ElMessage.success('删除成功')
|
||
// 刷新列表
|
||
getInspectionList()
|
||
} else {
|
||
ElMessage.error(res.message || '删除失败')
|
||
}
|
||
}).catch((error) => {
|
||
console.error('删除检验申请单异常:', error)
|
||
ElMessage.error('删除异常')
|
||
})
|
||
}).catch(() => {
|
||
// 用户取消删除
|
||
})
|
||
}
|
||
|
||
// 单元格点击 - 点击表格行时加载申请单详情
|
||
function handleCellClick(row, column) {
|
||
// 点击表格行时,将该申请单的数据加载到表单中
|
||
if (row && row.applicationId) {
|
||
// 切换到申请单 TAB
|
||
leftActiveTab.value = 'application'
|
||
|
||
// 加载表单数据
|
||
Object.assign(formData, {
|
||
applicationId: row.applicationId,
|
||
applyNo: row.applyNo,
|
||
patientName: row.patientName,
|
||
medicalrecordNumber: row.medicalrecordNumber,
|
||
natureofCost: row.natureofCost || 'self',
|
||
applyTime: row.applyTime,
|
||
applyDepartment: row.applyDepartment,
|
||
applyDocName: row.applyDocName,
|
||
executeDepartment: row.executeDepartment || 'medical_lab',
|
||
clinicDesc: row.clinicDesc,
|
||
contraindication: row.contraindication,
|
||
clinicDiag: row.clinicDiag,
|
||
medicalHistorySummary: row.medicalHistorySummary,
|
||
purposeofInspection: row.purposeofInspection,
|
||
physicalExam: row.physicalExam,
|
||
applyRemark: row.applyRemark,
|
||
priorityCode: row.priorityCode || 0,
|
||
applyStatus: row.applyStatus || 1,
|
||
needRefund: row.needRefund || false,
|
||
needExecute: row.needExecute || false,
|
||
inspectionDoctor: row.inspectionDoctor,
|
||
inspectionTime: row.inspectionTime,
|
||
auditDoctor: row.auditDoctor,
|
||
auditTime: row.auditTime,
|
||
visitNo: row.visitNo,
|
||
applyDocCode: row.applyDocCode,
|
||
applyDeptCode: row.applyDeptCode,
|
||
specimenName: row.specimenName,
|
||
encounterId: row.encounterId,
|
||
patientId: row.patientId,
|
||
applyOrganizationId: row.applyOrganizationId
|
||
})
|
||
|
||
// 根据检验项目名称解析已选项目
|
||
selectedInspectionItems.value = []
|
||
if (row.inspectionItem) {
|
||
const itemNames = row.inspectionItem.split('、')
|
||
inspectionCategories.value.forEach(category => {
|
||
category.items.forEach(item => {
|
||
if (itemNames.includes(item.itemName)) {
|
||
selectedInspectionItems.value.push({ ...item })
|
||
}
|
||
})
|
||
})
|
||
}
|
||
|
||
// 重置验证错误状态
|
||
Object.keys(validationErrors).forEach(key => {
|
||
validationErrors[key] = false
|
||
})
|
||
}
|
||
}
|
||
|
||
// 监听activeTab变化
|
||
watch(() => props.activeTab, async (newVal) => {
|
||
if (newVal === 'inspection') {
|
||
await initData()
|
||
// 默认展开生化分类
|
||
activeCategory.value = 'biochemical'
|
||
inspectionCategories.value.forEach(cat => {
|
||
cat.expanded = cat.key === 'biochemical'
|
||
})
|
||
}
|
||
})
|
||
|
||
// 监听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)
|
||
|
||
// 如果encounterId发生变化,重新加载检验申请单列表
|
||
if (oldEncounterId !== newVal.encounterId) {
|
||
getInspectionList()
|
||
}
|
||
|
||
// 更新科室编码
|
||
// const currentDeptCode = await getCurrentDeptCode();
|
||
// formData.applyDeptCode = currentDeptCode || '';
|
||
}
|
||
}, { deep: true, immediate: true })
|
||
|
||
// 监听已选择的检验项目,自动更新检验项目文本(用+号拼接)
|
||
watch(() => selectedInspectionItems.value, (newVal) => {
|
||
if (newVal && newVal.length > 0) {
|
||
formData.inspectionItemsText = newVal.map(item => item.itemName).join('+')
|
||
} else {
|
||
formData.inspectionItemsText = ''
|
||
}
|
||
}, { deep: true })
|
||
|
||
// 初始化
|
||
onMounted(async () => {
|
||
await initData();
|
||
getInspectionList();
|
||
})
|
||
|
||
// 暴露方法
|
||
defineExpose({
|
||
getList: getInspectionList
|
||
})
|
||
|
||
|
||
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
/* 页面容器 */
|
||
.inspection-application-container {
|
||
max-height: 750px;
|
||
overflow-y: auto;
|
||
padding: 0;
|
||
}
|
||
|
||
/* 顶部操作按钮区 */
|
||
.top-action-bar {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: flex-end;
|
||
border-bottom: 1px solid var(--el-border-color-light);
|
||
background: var(--el-bg-color);
|
||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||
}
|
||
|
||
.action-buttons {
|
||
display: flex;
|
||
gap: 10px;
|
||
}
|
||
|
||
/* 检验信息表格区 */
|
||
.inspection-section {
|
||
padding: 20px;
|
||
}
|
||
|
||
.table-card {
|
||
height: 300px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.card-header {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
font-weight: 600;
|
||
color: var(--el-text-color-primary);
|
||
}
|
||
|
||
/* 底部内容区域 */
|
||
.bottom-content-area {
|
||
padding: 20px;
|
||
}
|
||
|
||
/* 表单区域 */
|
||
.form-card {
|
||
height: 700px;
|
||
}
|
||
|
||
.form-tabs {
|
||
height: 100%;
|
||
}
|
||
|
||
.application-form {
|
||
height: 650px;
|
||
overflow-y: auto;
|
||
padding: 20px;
|
||
}
|
||
|
||
/* 选择区域 */
|
||
.selection-area {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 20px;
|
||
}
|
||
|
||
.inspection-selector,
|
||
.selected-items-area {
|
||
height: 350px;
|
||
}
|
||
|
||
.card-title {
|
||
font-weight: 600;
|
||
color: var(--el-text-color-primary);
|
||
}
|
||
|
||
.search-input {
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.selected-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
|
||
.pagination-container {
|
||
display: flex;
|
||
justify-content: center;
|
||
margin-top: 10px;
|
||
padding-top: 10px;
|
||
border-top: 1px solid var(--el-border-color-light);
|
||
}
|
||
|
||
:deep(.el-pagination) {
|
||
.el-pager li {
|
||
border-radius: 4px;
|
||
margin: 0 2px;
|
||
min-width: 32px;
|
||
height: 32px;
|
||
line-height: 30px;
|
||
border: 1px solid #dcdfe6;
|
||
background-color: #fff;
|
||
color: #606266;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.el-pager li:hover {
|
||
border-color: #409eff;
|
||
color: #409eff;
|
||
}
|
||
|
||
.el-pager li.is-active {
|
||
border-color: #409eff;
|
||
background-color: #409eff;
|
||
color: #fff;
|
||
}
|
||
|
||
.el-pagination__jump {
|
||
margin-left: 10px;
|
||
}
|
||
}
|
||
|
||
.inspection-form {
|
||
background: white;
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||
}
|
||
|
||
.form-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
border-bottom: 1px solid #eee;
|
||
padding: 15px 20px;
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.form-header .title {
|
||
display: flex;
|
||
align-items: center;
|
||
font-size: 16px;
|
||
font-weight: bold;
|
||
color: #1a2b6d;
|
||
}
|
||
|
||
.form-header .title i {
|
||
margin-right: 10px;
|
||
font-size: 24px;
|
||
}
|
||
|
||
.inspection-items-section {
|
||
border: 1px solid #ebeef5;
|
||
border-radius: 4px;
|
||
padding: 15px;
|
||
}
|
||
|
||
.selected-items {
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.item-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 10px;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.selected-list {
|
||
min-height: 40px;
|
||
border: 1px solid #ebeef5;
|
||
border-radius: 4px;
|
||
padding: 10px;
|
||
}
|
||
|
||
.item-selector {
|
||
margin-top: 20px;
|
||
}
|
||
|
||
.category-tabs {
|
||
display: flex;
|
||
border-bottom: 1px solid #ebeef5;
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.category-tab {
|
||
padding: 10px 20px;
|
||
cursor: pointer;
|
||
border-bottom: 2px solid transparent;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.category-tab:hover {
|
||
color: #409eff;
|
||
}
|
||
|
||
.category-tab.active {
|
||
color: #409eff;
|
||
border-bottom-color: #409eff;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.items-list {
|
||
max-height: 300px;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.inspection-item {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 10px 15px;
|
||
margin-bottom: 5px;
|
||
border: 1px solid #ebeef5;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.inspection-item:hover {
|
||
border-color: #409eff;
|
||
background-color: #ecf5ff;
|
||
}
|
||
|
||
.inspection-item.selected {
|
||
border-color: #409eff;
|
||
background-color: #ecf5ff;
|
||
}
|
||
|
||
.item-itemName {
|
||
font-weight: 500;
|
||
}
|
||
|
||
.item-price {
|
||
color: #e6a23c;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.inspection-details {
|
||
margin-top: 30px;
|
||
padding: 20px;
|
||
border: 1px solid #ebeef5;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.details-header {
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.details-header h3 {
|
||
margin: 0;
|
||
color: #1a2b6d;
|
||
font-size: 16px;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.inspection-selector {
|
||
border: 1px solid #ddd;
|
||
border-radius: 4px;
|
||
padding: 15px;
|
||
background: white;
|
||
}
|
||
|
||
.category-list {
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.category-item {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 8px 12px;
|
||
cursor: pointer;
|
||
border-radius: 4px;
|
||
transition: all 0.3s ease;
|
||
margin-bottom: 2px;
|
||
}
|
||
|
||
.category-item:hover {
|
||
background-color: #f5f5f5;
|
||
}
|
||
|
||
.category-item.active {
|
||
background-color: #e6f7ff;
|
||
color: #409eff;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.category-icon {
|
||
margin-right: 8px;
|
||
font-weight: bold;
|
||
width: 12px;
|
||
text-align: center;
|
||
}
|
||
|
||
.selected-summary {
|
||
margin: 10px 0;
|
||
padding: 10px;
|
||
background: #f5f5f5;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.selected-items {
|
||
margin-top: 5px;
|
||
}
|
||
|
||
.inspection-selector .items-list {
|
||
max-height: 200px;
|
||
overflow-y: auto;
|
||
border: 1px solid #ebeef5;
|
||
border-radius: 4px;
|
||
padding: 10px;
|
||
}
|
||
|
||
.inspection-selector .inspection-item {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 8px 12px;
|
||
margin-bottom: 5px;
|
||
border: 1px solid #f0f0f0;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
background: #fafafa;
|
||
}
|
||
|
||
.inspection-selector .inspection-item:hover {
|
||
border-color: #409eff;
|
||
background-color: #ecf5ff;
|
||
}
|
||
|
||
.inspection-selector .inspection-item.selected {
|
||
border-color: #409eff;
|
||
background-color: #ecf5ff;
|
||
font-weight: bold;
|
||
}
|
||
|
||
/* 检验信息表格样式 */
|
||
:deep(.inspection-table) {
|
||
border: 1px solid #e4e7ed;
|
||
border-radius: 4px;
|
||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
|
||
}
|
||
|
||
:deep(.inspection-table .el-table__header) {
|
||
th {
|
||
background: linear-gradient(to bottom, #f8fafc 0%, #f1f5f9 100%);
|
||
border-bottom: 2px solid #e2e8f0;
|
||
color: #1e293b;
|
||
font-weight: 600;
|
||
font-size: 13px;
|
||
padding: 12px 8px;
|
||
}
|
||
}
|
||
|
||
:deep(.inspection-table .el-table__body) {
|
||
td {
|
||
border-bottom: 1px solid #f1f5f9;
|
||
padding: 10px 8px;
|
||
font-size: 13px;
|
||
color: #475569;
|
||
}
|
||
}
|
||
|
||
:deep(.inspection-table .el-table__row:hover > td) {
|
||
background-color: #f8fafc !important;
|
||
}
|
||
|
||
:deep(.inspection-table .el-table__row--striped) {
|
||
background-color: #fafbfc;
|
||
}
|
||
|
||
:deep(.inspection-table .el-table__row--striped:hover > td) {
|
||
background-color: #f1f5f9 !important;
|
||
}
|
||
|
||
:deep(.inspection-table .el-checkbox) {
|
||
margin: 0;
|
||
}
|
||
|
||
:deep(.inspection-table .el-button--small) {
|
||
font-size: 12px;
|
||
padding: 4px 8px;
|
||
}
|
||
|
||
:deep(.inspection-table .el-button--link) {
|
||
color: #409eff;
|
||
transition: color 0.3s ease;
|
||
}
|
||
|
||
:deep(.inspection-table .el-button--link:hover) {
|
||
color: #66b1ff;
|
||
}
|
||
|
||
:deep(.inspection-table .el-button--link:last-child) {
|
||
color: #f56c6c;
|
||
}
|
||
|
||
:deep(.inspection-table .el-button--link:last-child:hover) {
|
||
color: #f78989;
|
||
}
|
||
|
||
:deep(.inspection-table .cell) {
|
||
line-height: 1.4;
|
||
}
|
||
|
||
/* 新的树形结构样式 */
|
||
.category-tree {
|
||
border: 1px solid #ebeef5;
|
||
border-radius: 4px;
|
||
background: #fafafa;
|
||
}
|
||
|
||
.category-tree-item {
|
||
border-bottom: 1px solid #ebeef5;
|
||
}
|
||
|
||
.category-tree-item:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.category-tree-header {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 12px 15px;
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
background: #fff;
|
||
border-radius: 4px;
|
||
margin: 2px;
|
||
}
|
||
|
||
.category-tree-header:hover {
|
||
background-color: #f5f5f5;
|
||
}
|
||
|
||
.category-tree-header.active {
|
||
background-color: #e6f7ff;
|
||
color: #409eff;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.category-tree-icon {
|
||
margin-right: 8px;
|
||
font-size: 12px;
|
||
width: 12px;
|
||
text-align: center;
|
||
color: #409eff;
|
||
}
|
||
|
||
.category-count {
|
||
margin-left: auto;
|
||
color: #999;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.category-tree-children {
|
||
background: #fff;
|
||
border-top: 1px solid #ebeef5;
|
||
}
|
||
|
||
.inspection-tree-item {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 8px 15px 8px 35px;
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
border-bottom: 1px solid #f0f0f0;
|
||
}
|
||
|
||
.inspection-tree-item:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.inspection-tree-item:hover {
|
||
background-color: #f5f5f5;
|
||
}
|
||
|
||
.inspection-tree-item.selected {
|
||
background-color: #ecf5ff;
|
||
border-left: 3px solid #409eff;
|
||
}
|
||
|
||
.inspection-tree-item .item-itemName {
|
||
flex: 1;
|
||
margin-left: 10px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.inspection-tree-item .item-price {
|
||
color: #e6a23c;
|
||
font-weight: bold;
|
||
margin-left: 10px;
|
||
}
|
||
|
||
/* 已选项目区样式 */
|
||
.selected-items-area {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.selected-header {
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.selected-tree {
|
||
flex: 1;
|
||
}
|
||
|
||
.selected-tree-item {
|
||
padding: 8px 0;
|
||
border-bottom: 1px solid #f0f0f0;
|
||
}
|
||
|
||
.selected-tree-item:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.selected-item-content {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 8px 12px;
|
||
background: #f8f9fa;
|
||
border-radius: 4px;
|
||
margin: 2px 0;
|
||
}
|
||
|
||
.selected-item-content .item-itemName {
|
||
flex: 1;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.selected-item-content .item-price {
|
||
color: #e6a23c;
|
||
font-weight: bold;
|
||
margin-right: 10px;
|
||
}
|
||
|
||
.no-selection {
|
||
text-align: center;
|
||
padding: 40px 20px;
|
||
color: #999;
|
||
}
|
||
|
||
/* 表单验证错误样式 */
|
||
.form-item-error .el-input__inner,
|
||
.form-item-error .el-textarea__inner {
|
||
border-color: #f56c6c !important;
|
||
}
|
||
|
||
.form-item-error .el-select .el-input__inner {
|
||
border-color: #f56c6c !important;
|
||
}
|
||
|
||
.is-error.el-input .el-input__inner,
|
||
.is-error.el-textarea .el-textarea__inner {
|
||
border-color: #f56c6c !important;
|
||
}
|
||
|
||
.error-message {
|
||
color: #f56c6c;
|
||
font-size: 12px;
|
||
margin-top: 4px;
|
||
line-height: 1;
|
||
}
|
||
|
||
/* 自定义消息框样式,确保其显示在最顶层 */
|
||
.custom-message-box {
|
||
z-index: 9999 !important;
|
||
}
|
||
|
||
/* 确保模态框相关元素具有高z-index */
|
||
.el-popup-parent--hidden {
|
||
overflow: hidden;
|
||
padding-right: 0 !important;
|
||
}
|
||
|
||
.v-modal {
|
||
z-index: 2000 !important;
|
||
}
|
||
|
||
/* 响应式布局 */
|
||
@media (max-width: 992px) {
|
||
.bottom-content-area {
|
||
flex-direction: column;
|
||
}
|
||
|
||
.form-area,
|
||
.selection-area {
|
||
width: 100%;
|
||
}
|
||
|
||
.el-col {
|
||
width: 100% !important;
|
||
max-width: 100% !important;
|
||
flex: 0 0 100% !important;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.inspection-section {
|
||
padding: 10px;
|
||
}
|
||
|
||
.bottom-content-area {
|
||
padding: 0 10px 10px 10px;
|
||
gap: 15px;
|
||
}
|
||
|
||
/* 表单字段纵向排列 */
|
||
.application-form .el-form-item {
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
/* 隐藏表格非关键列 */
|
||
.inspection-table .el-table__cell:nth-child(n+4):nth-child(-n+7) {
|
||
display: none;
|
||
}
|
||
|
||
.top-action-bar {
|
||
padding: 0 10px;
|
||
}
|
||
|
||
.action-buttons {
|
||
flex-direction: column;
|
||
gap: 5px;
|
||
}
|
||
|
||
.el-button--large {
|
||
width: 100%;
|
||
}
|
||
}
|
||
|
||
/* 优化表单样式 */
|
||
.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>
|